/***************************************************************************
    date                 : Feb 09 2004
    version              : 0.10.0
    copyright            : (C) 2004 by Holger Danielsson
    email                : holger.danielsson@t-online.de
 ***************************************************************************/


/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "configstructure.h"

#include <kdialog.h>
#include <kconfig.h>
#include <klocale.h>
#include <kiconloader.h>

#include <tqlayout.h>
#include <tqtabwidget.h>
#include <tqgroupbox.h>
#include <tqvgroupbox.h>
#include <tqframe.h>
#include <tqstringlist.h>
#include <tqpushbutton.h>
#include <tqcombobox.h>
#include <tqspinbox.h>
#include <tqpainter.h>
#include <tqrect.h>
#include <tqlabel.h>

namespace KileStructure
{

//////////////////// KileCenteredTableItem ////////////////////

void KileCenteredTableItem::paint(TQPainter* p,const TQColorGroup& cg,const TQRect& cr,bool selected)
{
   int w = cr.width();
   int h = cr.height();

   if (selected && colSpan()==1 ) {
      p->fillRect( 0,0,w,h, cg.brush( TQColorGroup::Highlight ) );
      p->setPen( cg.highlightedText() );
   } else {
      p->fillRect( 0,0,w,h, TQt::white );
      p->setPen( TQt::black );
      /*
      TQFont f( p->font() );
      f.setBold(true);
      p->setFont(f);
      */
   }

   p->drawText( 2,0,w-4,h, TQt::AlignHCenter|AlignVCenter, text() );
}

//////////////////// KileTable ////////////////////

KileTable::KileTable(TQWidget *dialog, TQWidget *parent, const char *name) : TQTable(parent,name)
{
   setShowGrid(false);
   setSelectionMode(TQTable::NoSelection);
   setFocusStyle(TQTable::FollowStyle);

   verticalHeader()->hide();
   setLeftMargin(0);
   setVScrollBarMode(TQScrollView::AlwaysOff);
   setHScrollBarMode(TQScrollView::AlwaysOff);
   setFocusPolicy(TQ_NoFocus);

   horizontalHeader()->setResizeEnabled(false);
   horizontalHeader()->setClickEnabled(false);

   connect(this,TQT_SIGNAL(clickedCell(KileTable *,int,int)),dialog,TQT_SLOT(clickedTable(KileTable *,int,int)));
}

void KileTable::contentsMousePressEvent(TQMouseEvent *ev)
{
   ev->accept();
   emit( clickedCell( this,rowAt(ev->y()), columnAt(ev->x()) ));
}

//////////////////// ConfigStructure ////////////////////

ConfigStructure::ConfigStructure(TQWidget *parent, const char *name )
   : TQWidget(parent,name)
{
   m_entries << i18n( "Files" ) << i18n( "Labels" ) << i18n( "References" )
             << i18n( "Index" ) << i18n( "Graphics" ) << i18n( "Sectioning" );

   TQHBoxLayout *hbox = new TQHBoxLayout(this, 5,KDialog::spacingHint() );

   // Groupbox with entries
   TQVGroupBox *gb_entries= new TQVGroupBox(i18n("Entries"), this );
   TQWidget *widget1 = new TQWidget(gb_entries);
   TQVBoxLayout *vbox1 = new TQVBoxLayout(widget1, 5,KDialog::spacingHint() );

   // table with entries
   m_entriestable = new KileTable(this,widget1);
   m_entriestable->setNumCols(3);
   m_entriestable->setNumRows(6);
   m_entriestable->setColumnReadOnly(0,true);

   TQStringList list1;
   list1 << i18n( "Title" ) << i18n( "Visible" ) << i18n( "Open" );
   m_entriestable->setColumnLabels(list1);
   m_entriestable->horizontalHeader()->setLabel(1,SmallIcon("structure"), i18n( "Visible" ));
   m_entriestable->horizontalHeader()->setLabel(2,SmallIcon("structure"), i18n( "Node" ));

   for ( uint i=0; i<m_entries.count(); ++i ) {
       TQTableItem *item = new TQTableItem(m_entriestable,TQTableItem::Never, m_entries[i]);
       m_entriestable->setItem( i,0,item  );
       m_visible[i] = new TQCheckTableItem(m_entriestable,"");
       m_entriestable->setItem( i,1, m_visible[i]  );
       m_defaultopen[i] = new TQCheckTableItem(m_entriestable,"close");
       m_entriestable->setItem( i,2, m_defaultopen[i]  );
   }

   // groupbox with sectioning
   TQVGroupBox *gb_sectioning= new TQVGroupBox(i18n("Sectioning"), this );
   TQWidget *widget2 = new TQWidget(gb_sectioning);
   TQVBoxLayout *vbox2 = new TQVBoxLayout(widget2, 5,KDialog::spacingHint() );

   // document class
   TQWidget *widget3 = new TQWidget(widget2);
   TQHBoxLayout *hbox3 = new TQHBoxLayout(widget3, 5,KDialog::spacingHint() );
   TQLabel *label7 = new TQLabel(i18n("Document class:"), widget3);
   comboclasses = new TQComboBox(widget3);
   hbox3->addWidget(label7);
   hbox3->addSpacing(10);
   hbox3->addWidget(comboclasses);
   hbox3->setStretchFactor(comboclasses,1);

   // table with sectioning commands
   m_sectioningtable = new KileTable(this,widget2);
   m_sectioningtable->setNumCols(3);
   m_sectioningtable->setNumRows(5);
   m_sectioningtable->setColumnReadOnly(0,true);
   m_sectioningtable->setColumnReadOnly(1,true);

   TQStringList list2;
   list2 << i18n( "Level" ) << i18n( "LaTeX Command" ) << i18n( "Structure Node" );
   m_sectioningtable->setColumnLabels(list2);
   m_sectioningtable->horizontalHeader()->setLabel(2,SmallIcon("structure"),"Structure Node");

   // default structure level
   TQGroupBox *structGroup = new TQGroupBox(2, Qt::Horizontal, i18n("Structure View"), widget2);
   TQLabel *label9 = new TQLabel(i18n("Default expansion &level: "),structGroup);
   m_structurelevel = new TQSpinBox(1,5, 1, structGroup);
   label9->setBuddy(m_structurelevel);

   TQGroupBox *classGroup = new TQGroupBox(1,Qt::Horizontal,i18n("Document Classes"), widget2);
   TQWidget *widget4 = new TQWidget(classGroup);
   TQHBoxLayout *hbox4 = new TQHBoxLayout(widget4, 5,KDialog::spacingHint() );
   TQLabel *label10 = new TQLabel("Manage classes:",widget4);
   add = new TQPushButton(i18n("Add"), widget4);
   remove = new TQPushButton(i18n("Remove"), widget4);
   hbox4->addWidget(label10);
   hbox4->addStretch();
   hbox4->addWidget(add);
   hbox4->addWidget(remove);

   // add widgets to the left vertical layout
   vbox1->addWidget(m_entriestable);
   vbox1->addStretch();

   // add widgets to the right vertical layout
   vbox2->addWidget(widget3);
   vbox2->addSpacing(10);
   vbox2->addWidget(m_sectioningtable);
   vbox2->addSpacing(10);
   vbox2->addWidget(structGroup);
   vbox2->addWidget(classGroup);
   vbox2->addStretch();

   // add both groupboxes to horizontal layout
   hbox->addWidget(gb_entries);
   hbox->addWidget(gb_sectioning);
   hbox->setStretchFactor(gb_entries,3);
   hbox->setStretchFactor(gb_sectioning,4);

   // set default sectioning commands
   comboclasses->insertItem("latex");
   TQStringList *sectcommands = new TQStringList;
   *sectcommands << "part" << "chapter" << "section" << "subsection" << "subsubsection";
   m_docclasses["latex"] = sectcommands;
   showSectioning(m_docclasses["latex"]);
   remove->setEnabled(false);

    connect(m_structurelevel,TQT_SIGNAL(valueChanged(int)),this,TQT_SLOT(spinboxChanged(int)));
    connect(comboclasses,TQT_SIGNAL(activated(const TQString &)),this,TQT_SLOT(comboboxChanged(const TQString &)));
    connect(add,TQT_SIGNAL(clicked()),this,TQT_SLOT(clickedAdd()));

   add->setEnabled(false);
}

ConfigStructure::~ConfigStructure()
{
	TQMap<TQString, const TQStringList*>::Iterator it, end = m_docclasses.end();
	for(it = m_docclasses.begin() ; it != end ; ++it)
		delete *it;
}

void ConfigStructure::polish()
{
 //  TQWidget::polish();

   uint w = m_entriestable->sizeHint().width();
   m_entriestable->setColumnWidth(0,3*w/7);
   m_entriestable->setColumnWidth(1,2*w/7);
   m_entriestable->setColumnWidth(2,2*w/7+1);
   m_entriestable->setColumnStretchable(2,true);

   w = m_sectioningtable->sizeHint().width();
   m_sectioningtable->setColumnWidth(0,w/6);
   m_sectioningtable->setColumnWidth(1,3*w/6);
   m_sectioningtable->setColumnWidth(2,2*w/6+1);
   m_sectioningtable->setColumnStretchable(2,true);

}

void ConfigStructure::clickedTable(KileTable *table,int row, int col)
{
   if ( table==m_entriestable && row>=0 && row<6 ) {
      if ( col==1 )
         m_visible[row]->setChecked( !m_visible[row]->isChecked() );
      else if ( col == 2 ) {
         if ( m_defaultopen[row]->isChecked() ) {
            m_defaultopen[row]->setChecked(false);
            m_defaultopen[row]->setText("close");
         } else {
            m_defaultopen[row]->setChecked(true);
            m_defaultopen[row]->setText("open");
         }
      }
   }
}

void ConfigStructure::spinboxChanged(int)
{
    if ( m_docclasses.contains( comboclasses->currentText() )  ) {
       changeSectioning(m_docclasses[comboclasses->currentText()]);
    }
}

void ConfigStructure::comboboxChanged(const TQString &name)
{
    if ( m_docclasses.contains(name)  ) {
       showSectioning(m_docclasses[name]);
       remove->setEnabled( name != "latex" );
    }
}

void ConfigStructure::changeSectioning(const TQStringList *list)
{
   for (uint i=0; i<list->count(); ++i) {
      TQString label =  ( i < (uint)m_structurelevel->value() ) ? "open" : "close";
      m_sectioningtable->setText(i,2,label);
   }
}

void ConfigStructure::showSectioning(const TQStringList *list)
{
   TQString label1,label2,label3;
   for (uint i=0; i<5; ++i) {
      if ( i < list->count() ) {
         label1 = TQString("%1").arg(i+1);
         label2 = (*list)[i];
         label3 =  ( i < (uint)m_structurelevel->value() ) ? "open" : "close";
      } else {
         label1 = label2 = label3 = TQString();
      }
      KileCenteredTableItem *item1 = new KileCenteredTableItem(m_sectioningtable,
                                                   TQTableItem::Never,label1);
      m_sectioningtable->setItem( i,0,item1  );
      m_sectioningtable->setText( i,1,label2 );
      KileCenteredTableItem *item3 = new KileCenteredTableItem(m_sectioningtable,
                                                    TQTableItem::Never,label3);
      m_sectioningtable->setItem( i,2,item3 );
   }
}

void ConfigStructure::clickedAdd()
{
}

//////////////////// read/write configuration ////////////////////

void ConfigStructure::readConfig(KConfig *config)
{
   // config section
   config->setGroup( "Structure Entries" );
   for ( uint i=0; i<m_entries.count(); ++i ) {
      int defaultvalue = ( m_entries[i] == i18n( "Sectioning" ) ) ? KileStructure::Visible | KileStructure::Opened
                                                          : KileStructure::Visible;
      int num = config->readNumEntry(m_entries[i],defaultvalue);
      m_visible[i]->setChecked( (num & KileStructure::Visible) ? true : false );
      if ( num & KileStructure::Opened ) {
         m_defaultopen[i]->setChecked(true);
         m_defaultopen[i]->setText("open");
      }
   }

   config->setGroup( "Structure Sectioning" );
   TQStringList classlist = config->readListEntry("classes");
   classlist.sort();
   for ( uint i=0; i<classlist.count(); ++i ) {
      TQStringList list = config->readListEntry(classlist[i]);
      if ( list.count() > 0 ) {
         comboclasses->insertItem(classlist[i]);
         TQStringList *sectioningcommands = new TQStringList(list);
         m_docclasses[classlist[i]] = sectioningcommands;
     }
   }

   m_structurelevel->setValue(config->readNumEntry("DefaultLevel",3));
}

void ConfigStructure::writeConfig(KConfig *config)
{
   // config section
   config->setGroup( "Structure Entries" );
   for ( uint i=0; i<m_entries.count(); ++i ) {
      int num = ( m_visible[i]->isChecked() ) ?  KileStructure::Visible : KileStructure::None;
      if  ( m_defaultopen[i]->isChecked() )
         num += KileStructure::Opened;
      config->writeEntry(m_entries[i],num);
   }

   config->setGroup( "Structure Sectioning" );
   TQStringList classlist;
   for ( int i=0; i<comboclasses->count(); ++i ) {
      TQString entry = comboclasses->text(i);
      if ( entry != "latex" ) {
         classlist << entry;
         TQString entrylist = m_docclasses[entry]->join(",");
         config->writeEntry( entry, entrylist );
      }
   }
   config->writeEntry( "classes", classlist );

   config->writeEntry("DefaultLevel",m_structurelevel->value());
}

}
#include "configstructure.moc"
