File indexing completed on 2024-05-05 17:15:14

0001 /***************************************************************************************
0002 date                 : Sep 15 2004
0003 version              : 0.23
0004 copyright            : Thomas Fischer <t-fisch@users.sourceforge.net>
0005                        restructured, improved and completed by Holger Danielsson
0006                        (C) 2004 by Holger Danielsson (holger.danielsson@t-online.de)
0007 ****************************************************************************************/
0008 
0009 /***************************************************************************
0010  *                                                                         *
0011  *   This program is free software; you can redistribute it and/or modify  *
0012  *   it under the terms of the GNU General Public License as published by  *
0013  *   the Free Software Foundation; either version 2 of the License, or     *
0014  *   (at your option) any later version.                                   *
0015  *                                                                         *
0016  ***************************************************************************/
0017 
0018 #include "dialogs/quickdocumentdialog.h"
0019 
0020 #include <QCheckBox>
0021 #include <QGridLayout>
0022 #include <QHBoxLayout>
0023 #include <QItemDelegate>
0024 #include <QLabel>
0025 #include <QLayout>
0026 #include <QPainter>
0027 #include <QPalette>
0028 #include <QRegExp>
0029 #include <QStringList>
0030 #include <QStyle>
0031 #include <QTreeWidget>
0032 #include <QVBoxLayout>
0033 #include <QWidget>
0034 
0035 #include <KComboBox>
0036 #include <KConfig>
0037 #include <QLineEdit>
0038 #include <KLocalizedString>
0039 #include <KMessageBox>
0040 #include <QPushButton>
0041 #include <QTabWidget>
0042 #include <KConfigGroup>
0043 #include <QDialogButtonBox>
0044 
0045 #include "widgets/categorycombobox.h"
0046 #include "kiledebug.h"
0047 #include "kileconfig.h"
0048 
0049 namespace KileDialog
0050 {
0051 enum {
0052     qd_Base = 1,
0053     qd_Article = 2,
0054     qd_BookReport = 4,
0055     qd_KomaArticle = 8,
0056     qd_KomaBookReport = 16,
0057     qd_KomaAbstract = 32,
0058     qd_Prosper = 64,
0059     qd_Beamer = 128
0060 };
0061 
0062 // list with index numbers for the stringlist with all information of a document class
0063 enum {
0064     qd_Fontsizes,
0065     qd_Papersizes,
0066     qd_DefaultOptions,
0067     qd_SelectedOptions,
0068     qd_OptionsStart
0069 };
0070 
0071 //////////////////// EditableItemDelegate ////////////////////
0072 
0073 class EditableItemDelegate : public QItemDelegate {
0074 public:
0075     EditableItemDelegate(QObject *parent = 0) : QItemDelegate(parent) {}
0076 
0077     virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const override
0078     {
0079         drawBackground(painter, option, index);
0080 
0081         QColor textColor = option.palette.color(QPalette::Text);
0082         QString text = index.data(Qt::DisplayRole).toString();
0083         if (text == "<default>" || text == "<empty>") {
0084             textColor = Qt::gray;
0085         } else if (option.state & QStyle::State_Selected) {
0086             textColor = option.palette.color(QPalette::HighlightedText);
0087         }
0088         painter->setPen(textColor);
0089         painter->drawText(option.rect, Qt::AlignCenter | Qt::AlignVCenter, text);
0090         //drawDisplay(painter, option, option.rect, index.data(Qt::DisplayRole).toString());
0091         drawFocus(painter, option, option.rect);
0092     }
0093 };
0094 
0095 //////////////////// QuickDocument class ////////////////////
0096 
0097 QuickDocument::QuickDocument(KConfig *config, QWidget *parent, const char *name, const QString &caption) : Wizard(config, parent, name, caption)
0098 {
0099     KILE_DEBUG_MAIN << "==QuickDocument::setupGUI()============";
0100     QTabWidget *tabWidget = new QTabWidget(this);
0101     QVBoxLayout *mainLayout = new QVBoxLayout;
0102     setLayout(mainLayout);
0103     mainLayout->addWidget(tabWidget);
0104 
0105     tabWidget->addTab(setupClassOptions(tabWidget), i18n("Cla&ss Options"));
0106     tabWidget->addTab(setupPackages(tabWidget), i18n("&Packages"));
0107     tabWidget->addTab(setupProperties(tabWidget), i18n("&Document Properties"));
0108 
0109     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
0110     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
0111     okButton->setDefault(true);
0112     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0113     connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0114     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0115     connect(this, &QDialog::accepted, this, &QuickDocument::slotAccepted);
0116     mainLayout->addWidget(buttonBox);
0117 
0118     // read config file
0119     readConfig();
0120     m_lvClassOptions->resizeColumnToContents(0);
0121     m_lvPackages->resizeColumnToContents(0);
0122 }
0123 
0124 QuickDocument::~QuickDocument()
0125 {}
0126 
0127 //////////////////// GUI ////////////////////
0128 
0129 QWidget *QuickDocument::setupClassOptions(QTabWidget *tab)
0130 {
0131     KILE_DEBUG_MAIN << "\tsetupClassOptions";
0132     QLabel *label;
0133 
0134     QWidget *classOptions = new QWidget(tab);
0135     QGridLayout *gl = new QGridLayout();
0136     classOptions->setLayout(gl);
0137 
0138     // Document classes
0139     m_cbDocumentClass = new KileWidget::CategoryComboBox(classOptions);
0140     m_cbDocumentClass->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
0141     m_cbDocumentClass->setDuplicatesEnabled(false);
0142     gl->addWidget(m_cbDocumentClass, 0, 1);
0143     connect(m_cbDocumentClass, SIGNAL(activated(int)), this, SLOT(slotDocumentClassChanged(int)));
0144 
0145     label = new QLabel(i18n("Doc&ument class:"), classOptions);
0146     gl->addWidget(label, 0, 0);
0147     label->setBuddy(m_cbDocumentClass);
0148     label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
0149 
0150     m_btnDocumentClassAdd = new QPushButton(classOptions);
0151     m_btnDocumentClassAdd->setIcon(QIcon::fromTheme("list-add"));
0152     m_btnDocumentClassAdd->setWhatsThis(i18n("Add an entry to this combo box"));
0153     gl->addWidget(m_btnDocumentClassAdd, 0, 2);
0154     connect(m_btnDocumentClassAdd, SIGNAL(clicked()), this, SLOT(slotDocumentClassAdd()));
0155 
0156     m_btnDocumentClassDelete = new QPushButton(classOptions);
0157     m_btnDocumentClassDelete->setIcon(QIcon::fromTheme("list-remove"));
0158     m_btnDocumentClassDelete->setWhatsThis(i18n("Remove current entry from this combo box"));
0159     gl->addWidget(m_btnDocumentClassDelete, 0, 3);
0160     connect(m_btnDocumentClassDelete, SIGNAL(clicked()), this, SLOT(slotDocumentClassDelete()));
0161 
0162     // Fontsize
0163     m_cbTypefaceSize = new KileWidget::CategoryComboBox(classOptions);
0164     m_cbTypefaceSize->setDuplicatesEnabled(false);
0165     gl->addWidget(m_cbTypefaceSize, 1, 1);
0166 
0167     label = new QLabel(i18n("&Typeface size:"), classOptions);
0168     label->setBuddy(m_cbTypefaceSize);
0169     label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
0170     gl->addWidget(label, 1, 0);
0171 
0172     m_btnTypefaceSizeAdd = new QPushButton(classOptions);
0173     m_btnTypefaceSizeAdd->setIcon(QIcon::fromTheme("list-add"));
0174     m_btnTypefaceSizeAdd->setWhatsThis(i18n("Add an entry to this combo box"));
0175     gl->addWidget(m_btnTypefaceSizeAdd, 1, 2);
0176     connect(m_btnTypefaceSizeAdd, SIGNAL(clicked()), this, SLOT(slotTypefaceSizeAdd()));
0177 
0178     m_btnTypefaceSizeDelete = new QPushButton(classOptions);
0179     m_btnTypefaceSizeDelete->setIcon(QIcon::fromTheme("list-remove"));
0180     m_btnTypefaceSizeDelete->setWhatsThis(i18n("Remove current entry from this combo box"));
0181     gl->addWidget(m_btnTypefaceSizeDelete, 1, 3);
0182     connect(m_btnTypefaceSizeDelete, SIGNAL(clicked()), this, SLOT(slotTypefaceSizeDelete()));
0183 
0184     // Papersize
0185     m_cbPaperSize = new KileWidget::CategoryComboBox(classOptions);
0186     m_cbPaperSize->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
0187     m_cbPaperSize->setDuplicatesEnabled(false);
0188     gl->addWidget(m_cbPaperSize, 2, 1);
0189 
0190     m_lbPaperSize = new QLabel(i18n("Paper si&ze:"), classOptions);
0191     m_lbPaperSize->setBuddy(m_cbPaperSize);
0192     m_lbPaperSize->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
0193     gl->addWidget(m_lbPaperSize, 2, 0);
0194 
0195     m_btnPaperSizeAdd = new QPushButton(classOptions);
0196     m_btnPaperSizeAdd->setIcon(QIcon::fromTheme("list-add"));
0197     m_btnPaperSizeAdd->setWhatsThis(i18n("Add an entry to this combo box"));
0198     gl->addWidget(m_btnPaperSizeAdd, 2, 2);
0199     connect(m_btnPaperSizeAdd, SIGNAL(clicked()), this, SLOT(slotPaperSizeAdd()));
0200 
0201     m_btnPaperSizeDelete = new QPushButton(classOptions);
0202     m_btnPaperSizeDelete->setIcon(QIcon::fromTheme("list-remove"));
0203     m_btnPaperSizeDelete->setWhatsThis(i18n("Remove current entry from this combo box"));
0204     gl->addWidget(m_btnPaperSizeDelete, 2, 3);
0205     connect(m_btnPaperSizeDelete, SIGNAL(clicked()), this, SLOT(slotPaperSizeDelete()));
0206 
0207     // Encoding
0208     m_cbEncoding = new KileWidget::CategoryComboBox(classOptions);
0209     m_cbEncoding->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
0210     m_cbEncoding->setDuplicatesEnabled(false);
0211     gl->addWidget(m_cbEncoding, 3, 1);
0212 
0213     label = new QLabel(i18n("E&ncoding:"), classOptions);
0214     label->setBuddy(m_cbEncoding);
0215     label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
0216     gl->addWidget(label, 3, 0);
0217 
0218     // Class Options
0219     m_lvClassOptions = new QTreeWidget(classOptions);
0220     m_lvClassOptions->setHeaderLabels(QStringList() << i18n("Option")
0221                                       << i18n("Description"));
0222     m_lvClassOptions->setAllColumnsShowFocus(true);
0223     m_lvClassOptions->setRootIsDecorated(false);
0224     gl->addWidget(m_lvClassOptions, 4, 1, 1, 3);
0225     connect(m_lvClassOptions, SIGNAL(itemSelectionChanged()),
0226             this, SLOT(slotEnableButtons()));
0227     connect(m_lvClassOptions, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
0228             this, SLOT(slotOptionDoubleClicked(QTreeWidgetItem*,int)));
0229 
0230     label = new QLabel(i18n("Cl&ass options:"), classOptions);
0231     label->setBuddy(m_lvClassOptions);
0232     label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding);
0233     label->setAlignment(Qt::AlignTop);
0234     gl->addWidget(label, 4, 0);
0235 
0236     // button
0237     QWidget *frame = new QWidget(classOptions);
0238     QHBoxLayout *hl = new QHBoxLayout();
0239     hl->setContentsMargins(0, 0, 0, 0);
0240     frame->setLayout(hl);
0241     gl->addWidget(frame, 5, 1, 1, 3, Qt::AlignCenter);
0242 
0243     m_btnClassOptionsAdd = new QPushButton(i18n("&Add..."), frame);
0244     m_btnClassOptionsAdd->setIcon(QIcon::fromTheme("list-add"));
0245     m_btnClassOptionsAdd->setWhatsThis(i18n("Add a new class option"));
0246     hl->addWidget(m_btnClassOptionsAdd);
0247     connect(m_btnClassOptionsAdd, SIGNAL(clicked()), this, SLOT(slotClassOptionAdd()));
0248 
0249     m_btnClassOptionsEdit = new QPushButton(i18n("Ed&it..."), frame);
0250     m_btnClassOptionsEdit->setIcon(QIcon::fromTheme("document-properties"));
0251     m_btnClassOptionsEdit->setWhatsThis(i18n("Edit the current class option"));
0252     hl->addWidget(m_btnClassOptionsEdit);
0253     connect(m_btnClassOptionsEdit, SIGNAL(clicked()), this, SLOT(slotClassOptionEdit()));
0254 
0255     m_btnClassOptionsDelete = new QPushButton(i18n("De&lete"), frame);
0256     m_btnClassOptionsDelete->setIcon(QIcon::fromTheme("list-remove"));
0257     m_btnClassOptionsDelete->setWhatsThis(i18n("Remove the current class option"));
0258     hl->addWidget(m_btnClassOptionsDelete);
0259     connect(m_btnClassOptionsDelete, SIGNAL(clicked()), this, SLOT(slotClassOptionDelete()));
0260 
0261     return classOptions;
0262 }
0263 
0264 QWidget *QuickDocument::setupPackages(QTabWidget *tab)
0265 {
0266     KILE_DEBUG_MAIN << "\tsetupPackages";
0267 
0268     QWidget *packages = new QWidget(tab);
0269     QVBoxLayout *vl = new QVBoxLayout();
0270     packages->setLayout(vl);
0271 
0272     QLabel *label = new QLabel(i18n("LaTe&X packages:"), packages);
0273     vl->addWidget(label);
0274     m_lvPackages = new QTreeWidget(packages);
0275     vl->addWidget(m_lvPackages);
0276     m_lvPackages->setRootIsDecorated(true);
0277     m_lvPackages->setHeaderLabels(QStringList() << i18n("Package") << i18n("Value") << i18n("Description"));
0278     m_lvPackages->setAllColumnsShowFocus(true);
0279     m_lvPackages->setItemDelegateForColumn(1, new EditableItemDelegate());
0280     label->setBuddy(m_lvPackages);
0281     connect(m_lvPackages, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
0282             this, SLOT(slotCheckParent(QTreeWidgetItem*)));
0283     connect(m_lvPackages, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
0284             this, SLOT(slotCheckParent(QTreeWidgetItem*)));
0285     connect(m_lvPackages, SIGNAL(itemSelectionChanged()),
0286             this, SLOT(slotEnableButtons()));
0287     connect(m_lvPackages, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
0288             this, SLOT(slotPackageDoubleClicked(QTreeWidgetItem*)));
0289 
0290     QWidget *frame = new QWidget(packages);
0291     vl->addWidget(frame);
0292     QHBoxLayout *hl = new QHBoxLayout();
0293     hl->setContentsMargins(0, 0, 0, 0);
0294     frame->setLayout(hl);
0295     hl->addStretch();
0296 
0297     m_btnPackagesAdd = new QPushButton(i18n("&Add Package..."), frame);
0298     m_btnPackagesAdd->setIcon(QIcon::fromTheme("list-add"));
0299     m_btnPackagesAdd->setWhatsThis(i18n("Add a new package"));
0300     connect(m_btnPackagesAdd, SIGNAL(clicked()), this, SLOT(slotPackageAdd()));
0301     hl->addWidget(m_btnPackagesAdd);
0302     m_btnPackagesAddOption = new QPushButton(i18n("Add Op&tion..."), frame);
0303     m_btnPackagesAddOption->setIcon(QIcon::fromTheme("list-add"));
0304     m_btnPackagesAddOption->setWhatsThis(i18n("Add a new package option"));
0305     connect(m_btnPackagesAddOption, SIGNAL(clicked()), this, SLOT(slotPackageAddOption()));
0306     hl->addWidget(m_btnPackagesAddOption);
0307     m_btnPackagesEdit = new QPushButton(i18n("Ed&it..."), frame);
0308     m_btnPackagesEdit->setIcon(QIcon::fromTheme("document-properties"));
0309     m_btnPackagesEdit->setWhatsThis(i18n("Edit the current package option"));
0310     connect(m_btnPackagesEdit, SIGNAL(clicked()), this, SLOT(slotPackageEdit()));
0311     hl->addWidget(m_btnPackagesEdit);
0312     m_btnPackagesDelete = new QPushButton(i18n("De&lete"), frame);
0313     m_btnPackagesDelete->setIcon(QIcon::fromTheme("list-remove"));
0314     m_btnPackagesDelete->setWhatsThis(i18n("Remove the current package option"));
0315     connect(m_btnPackagesDelete, SIGNAL(clicked()), this, SLOT(slotPackageDelete()));
0316     hl->addWidget(m_btnPackagesDelete);
0317     m_btnPackagesReset = new QPushButton(i18n("&Reset to Defaults"), frame);
0318     m_btnPackagesReset->setIcon(QIcon::fromTheme("document-revert"));
0319     m_btnPackagesReset->setWhatsThis(i18n("Reset to the default list of packages"));
0320     connect(m_btnPackagesReset, SIGNAL(clicked()), this, SLOT(slotPackageReset()));
0321     hl->addWidget(m_btnPackagesReset);
0322     hl->addStretch();
0323 
0324     return packages;
0325 }
0326 
0327 QWidget *QuickDocument::setupProperties(QTabWidget *tab)
0328 {
0329     KILE_DEBUG_MAIN << "\tsetupProperties";
0330     QLabel *label;
0331 
0332     QWidget *personalInfoPage = new QWidget(tab);
0333     QVBoxLayout *vl = new QVBoxLayout();
0334     vl->setContentsMargins(0, 0, 0, 0);
0335     personalInfoPage->setLayout(vl);
0336 
0337     QWidget *personalInfo = new QWidget(personalInfoPage);
0338     QGridLayout *gl = new QGridLayout();
0339     personalInfo->setLayout(gl);
0340 
0341     m_leAuthor = new QLineEdit(personalInfo);
0342     gl->addWidget(m_leAuthor, 0, 1);
0343     label = new QLabel(i18n("&Author:"), personalInfo);
0344     gl->addWidget(label, 0, 0);
0345     label->setBuddy(m_leAuthor);
0346 
0347     m_leTitle = new QLineEdit(personalInfo);
0348     gl->addWidget(m_leTitle, 1, 1);
0349     label = new QLabel(i18n("&Title:"), personalInfo);
0350     gl->addWidget(label, 1, 0);
0351     label->setBuddy(m_leTitle);
0352 
0353     m_leDate = new QLineEdit(personalInfo);
0354     gl->addWidget(m_leDate, 2, 1);
0355     label = new QLabel(i18n("Dat&e:"), personalInfo);
0356     gl->addWidget(label, 2, 0);
0357     label->setBuddy(m_leDate);
0358 
0359     // set current date
0360     m_leDate->setText(QLocale().toString(QDate::currentDate(), QLocale::ShortFormat));
0361 
0362     vl->addWidget(personalInfo);
0363     vl->addStretch();
0364 
0365     return personalInfoPage;
0366 }
0367 
0368 //////////////////// read configuration ////////////////////
0369 
0370 void QuickDocument::readConfig()
0371 {
0372     KILE_DEBUG_MAIN << "==QuickDocument::readConfig()============";
0373 
0374     // read config for document class
0375     readDocumentClassConfig();
0376     // init the current document class
0377     initDocumentClass();
0378 
0379     // read config for packages
0380     readPackagesConfig();
0381     initHyperref();
0382 
0383     // read author
0384     m_leAuthor->setText(KileConfig::author());
0385 
0386 }
0387 
0388 //////////////////// write configuration ////////////////////
0389 
0390 void QuickDocument::writeConfig()
0391 {
0392     KILE_DEBUG_MAIN << "==QuickDocument::writeConfig()============";
0393 
0394     // write document class to config file
0395     writeDocumentClassConfig();
0396 
0397     // write packages to config file
0398     writePackagesConfig();
0399 
0400     // set author
0401     KileConfig::setAuthor(m_leAuthor->text());
0402 }
0403 
0404 ////////////////////////////// document class tab //////////////////////////////
0405 
0406 void QuickDocument::readDocumentClassConfig()
0407 {
0408     KILE_DEBUG_MAIN << "\tread config: document class";
0409 
0410     // read standard options
0411     m_userClasslist = KileConfig::userClasses();
0412     m_currentClass = KileConfig::documentClass();
0413     m_currentEncoding = KileConfig::encoding();
0414 
0415     // init standard classes
0416     QString stdFontsize = "10pt,11pt,12pt";
0417     QString stdPapersize = "a4paper,a5paper,b5paper,executivepaper,legalpaper,letterpaper";
0418     QString beamerThemes = "bars;boxes;classic;lined;plain;sidebar;sidebar (dark);sidebar (tab);"
0419                            "sidebar (dark,tab);shadow;split;tree;tree (bar)";
0420 
0421     initStandardClass("article", stdFontsize, stdPapersize,
0422                       "10pt,letterpaper,oneside,onecolumn,final",
0423                       KileConfig::optionsArticle());
0424     initStandardClass("book", stdFontsize, stdPapersize,
0425                       "10pt,letterpaper,twoside,onecolumn,final,openright",
0426                       KileConfig::optionsBook());
0427     initStandardClass("letter", stdFontsize, stdPapersize,
0428                       "10pt,letterpaper,oneside,onecolumn,final",
0429                       KileConfig::optionsLetter());
0430     initStandardClass("report", stdFontsize, stdPapersize,
0431                       "10pt,letterpaper,oneside,onecolumn,final,openany",
0432                       KileConfig::optionsReport());
0433     initStandardClass("scrartcl", stdFontsize, stdPapersize,
0434                       "11pt,a4paper,abstractoff,bigheadings,final,headnosepline,"
0435                       "footnosepline,listsindent,onelinecaption,notitlepage,onecolumn,"
0436                       "oneside,openany,parindent,tablecaptionbelow,tocindent",
0437                       KileConfig::optionsScrartcl());
0438     initStandardClass("scrbook", stdFontsize, stdPapersize,
0439                       "11pt,a4paper,bigheadings,final,headnosepline,footnosepline,"
0440                       "listsindent,nochapterprefix,onelinecaption,onecolumn,"
0441                       "openright,parindent,tablecaptionbelow,titlepage,tocindent,twoside",
0442                       KileConfig::optionsScrbook());
0443     initStandardClass("scrreprt", stdFontsize, stdPapersize,
0444                       "11pt,a4paper,abstractoff,bigheadings,final,headnosepline,"
0445                       "footnosepline,listsindent,nochapterprefix,onelinecaption,onecolumn,"
0446                       "oneside,openany,parindent,tablecaptionbelow,titlepage,tocindent",
0447                       KileConfig::optionsScrreprt());
0448     initStandardClass("prosper", QString(), QString(),
0449                       "final,slideBW,total,nocolorBG,ps,noaccumulate,ps2pdf",
0450                       KileConfig::optionsProsper());
0451     initStandardClass("beamer", "8pt,9pt,10pt,11pt,12pt,14pt,17pt,20pt", beamerThemes,
0452                       "11pt,blue,notes=show,sans,slidescentered",
0453                       KileConfig::optionsBeamer());
0454 
0455     // init all user classes
0456     for (int i = 0; i < m_userClasslist.count(); ++i) {
0457         KILE_DEBUG_MAIN << "\tinit user class: " << m_userClasslist[i];
0458         QStringList list;
0459         // read dour default entries for this user class
0460         KConfigGroup configGroup = config()->group(QString("QuickDocument/") + m_userClasslist[i]);
0461         list.append(configGroup.readEntry("fontsizesList"));
0462         list.append(configGroup.readEntry("pagesizesList"));
0463         list.append(configGroup.readEntry("defaultOptions"));
0464         list.append(configGroup.readEntry("selectedOptions"));
0465         // now read all user-defined options
0466         QStringList options = (configGroup.readEntry("options")).split(',');
0467         for (int j = 0; j < options.count(); ++j) {
0468             list.append(options[j] + " => " + configGroup.readEntry(options[j]));
0469         }
0470 
0471         // save all information of this class into the documentClass-dictionary
0472         m_dictDocumentClasses[ m_userClasslist[i] ] = list;
0473     }
0474 
0475     // set classes combobox (standard and user-defined classes)
0476     fillDocumentClassCombobox();
0477 
0478     // set encoding combobox
0479     fillCombobox(m_cbEncoding,
0480                  "ansinew,applemac,ascii,cp1252,cp1250,cp1251,cp1257,cp437,cp437de,cp850,cp858,"
0481                  "cp852,cp865,decmulti,koi8-r,latin1,latin2,latin3,latin4,latin5,latin9,latin10,next,utf8,utf8x,utfcyr",
0482                  m_currentEncoding);
0483 }
0484 
0485 void QuickDocument::fillDocumentClassCombobox()
0486 {
0487     QString stdClasses = "article,book,letter,report,-,scrartcl,scrbook,scrreprt,-";
0488     QString stdUserClasses = "beamer,prosper";
0489 
0490     // set classes combobox (standard and user-defined classes)
0491     QStringList classlist = stdUserClasses.split(',');
0492     for (int i = 0; i < m_userClasslist.count(); ++i) {
0493         classlist.append(m_userClasslist[i]);
0494     }
0495     classlist.sort();
0496     fillCombobox(m_cbDocumentClass, stdClasses + ',' + classlist.join(","), m_currentClass);
0497 }
0498 
0499 void QuickDocument::writeDocumentClassConfig()
0500 {
0501     KILE_DEBUG_MAIN << "\twrite config: document class";
0502 
0503     // first delete all marked document classes
0504     for (int i = 0; i < m_deleteDocumentClasses.count(); ++i) {
0505         KILE_DEBUG_MAIN << "\tdelete class: " << m_deleteDocumentClasses[i];
0506         config()->deleteGroup(QString("QuickDocument/") + m_deleteDocumentClasses[i]);
0507     }
0508 
0509     // write document classes and encoding
0510     QStringList userclasses;
0511     for (int i = 0; i < m_cbDocumentClass->count(); ++i) {
0512         if (!m_cbDocumentClass->itemText(i).isEmpty() && !isStandardClass(m_cbDocumentClass->itemText(i))) {
0513             userclasses.append(m_cbDocumentClass->itemText(i));
0514         }
0515     }
0516     KileConfig::setUserClasses(userclasses);
0517     KileConfig::setDocumentClass(m_cbDocumentClass->currentText());
0518     KileConfig::setEncoding(m_cbEncoding->currentText());
0519 
0520     // write checked options of standard classes
0521     KILE_DEBUG_MAIN << "\twrite standard classes";
0522     KileConfig::setOptionsArticle(m_dictDocumentClasses["article"][qd_SelectedOptions]);
0523     KileConfig::setOptionsBook(m_dictDocumentClasses["book"][qd_SelectedOptions]);
0524     KileConfig::setOptionsLetter(m_dictDocumentClasses["letter"][qd_SelectedOptions]);
0525     KileConfig::setOptionsReport(m_dictDocumentClasses["report"][qd_SelectedOptions]);
0526     KileConfig::setOptionsScrartcl(m_dictDocumentClasses["scrartcl"][qd_SelectedOptions]);
0527     KileConfig::setOptionsScrbook(m_dictDocumentClasses["scrbook"][qd_SelectedOptions]);
0528     KileConfig::setOptionsScrreprt(m_dictDocumentClasses["scrreprt"][qd_SelectedOptions]);
0529     KileConfig::setOptionsProsper(m_dictDocumentClasses["prosper"][qd_SelectedOptions]);
0530     KileConfig::setOptionsBeamer(m_dictDocumentClasses["beamer"][qd_SelectedOptions]);
0531 
0532     // write config of user packages
0533     QRegExp reg("(\\S+)\\s+=>\\s+(.*)");
0534     for (int i = 0; i < userclasses.count(); ++i) {
0535         // get the stringlist with all information
0536         KILE_DEBUG_MAIN << "\twrite user class: " << userclasses[i];
0537         QStringList list = m_dictDocumentClasses[userclasses[i]];
0538 
0539         // write the config group and the default entries
0540         KConfigGroup configGroup = config()->group(QString("QuickDocument/") + userclasses[i]);
0541         configGroup.writeEntry("fontsizesList", list[qd_Fontsizes]);
0542         configGroup.writeEntry("pagesizesList", list[qd_Papersizes]);
0543         configGroup.writeEntry("defaultOptions", list[qd_DefaultOptions]);
0544         configGroup.writeEntry("selectedOptions", list[qd_SelectedOptions]);
0545 
0546         // write user-defined options
0547         QString options;
0548         for (int j = qd_OptionsStart; j < list.count(); ++j) {
0549             int pos = reg.indexIn(list[j]);
0550             if (pos != -1) {
0551                 configGroup.writeEntry(reg.cap(1), reg.cap(2));
0552                 if (!options.isEmpty()) {
0553                     options += ',';
0554                 }
0555                 options += reg.cap(1);
0556             }
0557         }
0558         configGroup.writeEntry("options", options);
0559     }
0560 }
0561 
0562 void QuickDocument::initDocumentClass()
0563 {
0564     KILE_DEBUG_MAIN << "==QuickDocument::initDocumentClass()============";
0565     KILE_DEBUG_MAIN << "\tset class: " << m_currentClass;
0566 
0567     // get the stringlist of this class with all information
0568     QStringList classlist = m_dictDocumentClasses[m_currentClass];
0569 
0570     // First of all, we have to set the defaultOptions-dictionary and the
0571     // selectedOptions-dictionary for this class, before inserting options
0572     // into the listview. The function setClassOptions() will look
0573     // into both dictionaries to do some extra work.
0574     setDefaultClassOptions(classlist[qd_DefaultOptions]);
0575     setSelectedClassOptions(classlist[qd_SelectedOptions]);
0576 
0577     // set comboboxes for fontsizes and papersizes
0578     fillCombobox(m_cbTypefaceSize, classlist[qd_Fontsizes], m_currentFontsize);
0579     fillCombobox(m_cbPaperSize, classlist[qd_Papersizes], m_currentPapersize);
0580 
0581     // now we are ready to set the class options
0582     if (isStandardClass(m_currentClass)) {
0583         QStringList optionlist;
0584         initStandardOptions(m_currentClass, optionlist);
0585         setClassOptions(optionlist, 0);
0586     } else {
0587         setClassOptions(classlist, qd_OptionsStart);
0588     }
0589 
0590     // there is no papersize with class beamer, but a theme
0591     if (m_currentClass == "beamer")
0592         m_lbPaperSize->setText(i18n("&Theme:"));
0593     else
0594         m_lbPaperSize->setText(i18n("Paper si&ze:"));
0595 
0596     // enable/disable buttons to add or delete entries
0597     slotEnableButtons();
0598 }
0599 
0600 void QuickDocument::initStandardClass(const QString &classname,
0601                                       const QString &fontsize, const QString &papersize,
0602                                       const QString &defaultoptions, const QString &selectedoptions)
0603 {
0604     KILE_DEBUG_MAIN << "\tinit standard class: " << classname;
0605 
0606     // remember that this is a standard class
0607     m_dictStandardClasses[ classname ]  =  true;
0608 
0609     // save all entries
0610     QStringList list;
0611     list << fontsize << papersize << defaultoptions << selectedoptions;
0612 
0613     // save in documentClass-dictionary
0614     m_dictDocumentClasses[ classname ] = list;
0615 }
0616 
0617 // build all option for the current standard class
0618 void QuickDocument::initStandardOptions(const QString &classname, QStringList &optionlist)
0619 {
0620     // build the bitcode for all options of this class
0621     int options;
0622     if (classname == "article")
0623         options = qd_Base + qd_Article;
0624     else if (classname == "book")
0625         options = qd_Base + qd_Article + qd_BookReport;
0626     else if (classname == "letter")
0627         options = qd_Base;
0628     else if (classname == "report")
0629         options = qd_Base + qd_Article + qd_BookReport;
0630     else if (classname == "scrartcl")
0631         options = qd_Base + qd_Article + qd_KomaArticle + qd_KomaAbstract;
0632     else if (classname == "scrbook")
0633         options = qd_Base + qd_Article + qd_BookReport + qd_KomaArticle + qd_KomaBookReport;
0634     else if (classname == "scrreprt")
0635         options = qd_Base + qd_Article + qd_BookReport + qd_KomaArticle + qd_KomaAbstract + qd_KomaBookReport;
0636     else if (classname == "prosper")
0637         options = qd_Prosper;
0638     else if (classname == "beamer")
0639         options = qd_Beamer;
0640     else
0641         return;
0642 
0643     // insert all options into the list
0644     if (options & qd_Base) {
0645         optionlist
0646                 << QString("landscape => ") + i18n("Sets the document's orientation to landscape")
0647                 << QString("oneside => ") + i18n("Margins are set for single side output")
0648                 << QString("twoside => ") + i18n("Left and right pages differ in page margins")
0649                 << QString("draft => ") + i18n("Marks \"overfull hboxes\" on the output with black boxes")
0650                 << QString("final => ") + i18n("No special marks for \"overfull hboxes\" on the output")
0651                 << QString("leqno => ") + i18n("Puts formula numbers on the left side")
0652                 << QString("fleqn => ") + i18n("Aligns formulas on the left side")
0653                 ;
0654     }
0655 
0656     if (options & qd_Article) {
0657         optionlist
0658                 << QString("titlepage => ") + i18n("Puts title and abstract on an extra page")
0659                 << QString("notitlepage => ") + i18n("Puts title and abstract on the same page as the text")
0660                 << QString("onecolumn => ") + i18n("Puts the text in one column")
0661                 << QString("twocolumn => ") + i18n("Puts the text in two columns")
0662                 << QString("openbib => ") + i18n("Formats the bibliography in open style")
0663                 ;
0664     }
0665 
0666     if (options & qd_BookReport) {
0667         optionlist
0668                 << QString("openany => ") + i18n("Chapters may start on top of every page")
0669                 << QString("openright => ") + i18n("Chapters may only start on top of right pages")
0670                 ;
0671     }
0672 
0673     if (options & qd_KomaArticle) {
0674         optionlist
0675                 << QString("headinclude => ") + i18n("Cause the header to be counted as text")
0676                 << QString("headexclude => ") + i18n("Cause the header to be counted as border")
0677                 << QString("footinclude => ") + i18n("Cause the footer to be counted as text")
0678                 << QString("footexclude => ") + i18n("Cause the footer to be counted as border")
0679                 << QString("mpinclude => ") + i18n("Cause the margin-note to be counted to the text body")
0680                 << QString("mpexclude => ") + i18n("The normal margin is used for the margin-note area")
0681                 << QString("dvips => ") + i18n("Writes the paper size as a special into the DVI-file")
0682                 << QString("pdftex => ") + i18n("Writes the paper size into the pdftex page register")
0683                 << QString("pagesize => ") + i18n("Uses the correct mechanism with PDF- or DVI-file")
0684                 << QString("cleardoubleempty => ") + i18n("Enables the default for an empty left page")
0685                 << QString("cleardoubleplain => ") + i18n("An empty left page will set with the plain-pagestyle")
0686                 << QString("cleardoublestandard => ") + i18n("An empty left page will set with the empty-pagestyle")
0687                 << QString("headsepline => ") + i18n("Use a line to separate the header from the text body")
0688                 << QString("headnosepline => ") + i18n("Use no line to separate the header from the text body")
0689                 << QString("footsepline => ") + i18n("Use a line to separate the footer from the text body")
0690                 << QString("footnosepline => ") + i18n("Use no line to separate the footer from the text body")
0691                 << QString("parskip => ") + i18n("Normal paragraph spacing of one line")
0692                 << QString("parskip- => ") + i18n("Normal spacing, at least 1/3 of the last line is free")
0693                 << QString("parskip+ => ") + i18n("Normal spacing, at least 1/4 of the last line is free")
0694                 << QString("parskip* => ") + i18n("Normal spacing, no special provision for the last line")
0695                 << QString("halfparskip => ") + i18n("Paragraph spacing of half a line")
0696                 << QString("halfparskip- => ") + i18n("Spacing 1/2 line, at least 1/3 of the last line is free")
0697                 << QString("halfparskip+ => ") + i18n("Spacing 1/2 line, at least 1/4 of the last line is free")
0698                 << QString("halfparskip* => ") + i18n("Spacing 1/2 line, no special provision for the last line")
0699                 << QString("parindent => ") + i18n("No spacing between paragraphs, indent the first line by 1 em")
0700                 << QString("onelinecaption => ") + i18n("One-line captions are centered, multi-line left-justified")
0701                 << QString("noonelinecaption => ") + i18n("No special handling of one-line captions")
0702                 << QString("bigheading => ") + i18n("Normal great title font sizes")
0703                 << QString("normalheadings => ") + i18n("Small font sizes for titles")
0704                 << QString("smallheadings => ") + i18n("Even smaller font sizes for titles")
0705                 << QString("liststotoc => ") + i18n("Include lists of figures and tables in the TOC")
0706                 << QString("bibtotoc => ") + i18n("Include the bibliography in the TOC")
0707                 << QString("idxtotoc => ") + i18n("Include the index in the TOC")
0708                 << QString("liststotocnumbered => ") + i18n("Number the lists of figures and tables in the TOC")
0709                 << QString("bibtotocnumbered => ") + i18n("Number the bibliography in the TOC")
0710                 << QString("tocleft => ") + i18n("All numbers and titles are set in a left-justified column")
0711                 << QString("tocindent => ") + i18n("Different sectional units have different indentations")
0712                 << QString("listsleft => ") + i18n("All numbers and captions are set in a left-justified column")
0713                 << QString("listsindent => ") + i18n("All Numbers uses a fixed space")
0714                 << QString("pointednumbers => ") + i18n("Numbering of sectional units have a point at the end")
0715                 << QString("pointlessnumbers => ") + i18n("Numbering of sectional units have no point at the end")
0716                 << QString("tablecaptionabove => ") + i18n("Caption command acts like \\captionabove")
0717                 << QString("tablecaptionbelow => ") + i18n("Caption command acts like \\captionbelow")
0718                 << QString("origlongtable => ") + i18n("Captions of the longtable package should not be redefined")
0719                 ;
0720     }
0721 
0722     if (options & qd_KomaBookReport) {
0723         optionlist
0724                 << QString("chapterprefix => ") + i18n("Use a separate line for the chapter number")
0725                 << QString("nochapterprefix => ") + i18n("Use the same line for the chapter number and title")
0726                 << QString("appendixprefix => ") + i18n("Use a separate line for the appendix name")
0727                 << QString("noappendixprefix  => ") + i18n("No separate line for the appendix name")
0728                 ;
0729     }
0730 
0731     if (options & qd_KomaAbstract) {
0732         optionlist
0733                 << QString("abstracton => ") + i18n("Include the abstract's title")
0734                 << QString("abstractoff => ") + i18n("Exclude the abstract's title")
0735                 ;
0736     }
0737 
0738     if (options & qd_Prosper) {
0739         optionlist
0740                 << QString("draft => ") + i18n("The file is compiled in draft mode")
0741                 << QString("final => ") + i18n("The file is compiled in final mode")
0742                 << QString("slideColor => ") + i18n("Slides will use many colors")
0743                 << QString("slideBW => ") + i18n("Slides will use a restricted set of colors")
0744                 << QString("total => ") + i18n("Display the number of the current slide and the total number")
0745                 << QString("nototal => ") + i18n("Display only the number of the current slide")
0746                 << QString("nocolorBG => ") + i18n("The background of the slide is always white")
0747                 << QString("colorBG => ") + i18n("The color of the background depends on the current style")
0748                 << QString("ps => ") + i18n("The LaTeX file is compiled to produce a PostScript file")
0749                 << QString("pdf => ") + i18n("The LaTeX file is compiled to produce a PDF file")
0750                 << QString("accumulate => ") + i18n("Some macros interpret their argument in ps mode")
0751                 << QString("noaccumulate => ") + i18n("Some macros do not interpret their argument in ps mode")
0752                 << QString("distiller => ") + i18n("The PS file is to be translated into a PDF file using Adobe Distiller")
0753                 << QString("YandY => ") + i18n("The LaTeX file is to be processed with YandY LaTeX")
0754                 << QString("ps2pdf => ") + i18n("The PS file is to be translated into a PDF file using ps2pdf")
0755                 << QString("vtex => ") + i18n("The LaTeX file is to be processed with MicroPress VTeX")
0756                 << QString("noFooter => ") + i18n("Do not add any caption at the bottom of the slides")
0757                 ;
0758     }
0759 
0760     if (options & qd_Beamer) {
0761         optionlist
0762                 << QString("slidestop => ") + i18n("Place text of slides at the (vertical) top of the slides")
0763                 << QString("slidescentered => ") + i18n("Place text of slides at the (vertical) center of the slides")
0764                 << QString("draft => ") + i18n("Headlines, footlines, and sidebars are replaced by gray rectangles")
0765                 << QString("compress => ") + i18n("Make all navigation bars as small as possible")
0766                 << QString("usepdftitle=false => ") + i18n("Suppresses generation of some entries in the pdf information")
0767                 << QString("notheorems => ") + i18n("Switches off the definition of default blocks like theorem")
0768                 << QString("noamsthm => ") + i18n("Does not load amsthm and amsmath")
0769                 << QString("CJK => ") + i18n("Needed when using the CJK package for Asian fonts")
0770                 << QString("sans => ") + i18n("Use a sans-serif font during the presentation")
0771                 << QString("serif => ") + i18n("Use a serif font during the presentation")
0772                 << QString("mathsans => ") + i18n("Override the math font to be a sans-serif font")
0773                 << QString("mathserif => ") + i18n("Override the math font to be a serif font")
0774                 << QString("professionalfont => ") + i18n("Deactivate internal font replacements for math text")
0775                 << QString("handout => ") + i18n("Create a PDF handout")
0776                 << QString("trans => ") + i18n("For PDF transparency")
0777                 << QString("blue => ") + i18n("All structure elements are typeset in blue")
0778                 << QString("red => ") + i18n("All structure elements are typeset in red")
0779                 << QString("blackandwhite => ") + i18n("All structure elements are typeset in black and white")
0780                 << QString("brown => ") + i18n("All structure elements are typeset in brown")
0781                 << QString("notes=hide => ") + i18n(" Notes are not shown")
0782                 << QString("notes=show => ") + i18n(" Include notes in the output file")
0783                 << QString("notes=only => ") + i18n(" Include only notes and suppress frames")
0784                 ;
0785     }
0786 }
0787 
0788 // check for a standard class
0789 bool QuickDocument::isStandardClass(const QString &classname)
0790 {
0791     return m_dictStandardClasses.contains(classname);
0792 }
0793 
0794 // check for a default option
0795 bool QuickDocument::isDefaultClassOption(const QString &option)
0796 {
0797     return m_currentDefaultOptions.contains(option);
0798 }
0799 
0800 // check for an user option
0801 bool QuickDocument::isSelectedClassOption(const QString &option)
0802 {
0803     return m_currentSelectedOptions.contains(option);
0804 }
0805 
0806 // insert all default options of the current class into the defaultOptions-dictionary
0807 void QuickDocument::setDefaultClassOptions(const QString &defaultoptions)
0808 {
0809     QStringList list = defaultoptions.split(',');
0810     m_currentDefaultOptions.clear();
0811     for (int i = 0; i < list.count(); ++i) {
0812         if (!list[i].isEmpty()) {
0813             m_currentDefaultOptions[list[i]] = true;
0814         }
0815     }
0816 }
0817 
0818 // insert all checked options of the current class into the selectedOptions-dictionary
0819 void QuickDocument::setSelectedClassOptions(const QString &selectedoptions)
0820 {
0821     KILE_DEBUG_MAIN << "\tset options: " << selectedoptions;
0822 
0823     QStringList list = selectedoptions.split(',');
0824     uint nlist = list.count();
0825 
0826     m_currentFontsize  = (nlist >= 1) ? list[0] : "";
0827     m_currentPapersize = (nlist >= 2) ? list[1] : "";
0828 
0829     m_currentSelectedOptions.clear();
0830     for (uint i = 0; i < nlist; ++i) {
0831         if (! list[i].isEmpty())
0832             m_currentSelectedOptions[ list[i] ] = true;
0833     }
0834 }
0835 
0836 // show all options of the current class
0837 //  - split this string into option and description (option => description)
0838 //  - if the option is in the defaultOptions-dictionary, add 'default'
0839 //  - if the option is in the selectedOptions-dictionary, set the 'checked' symbol
0840 void QuickDocument::setClassOptions(const QStringList &list, uint start)
0841 {
0842     QRegExp reg("(\\S+)\\s+=>\\s+(.*)");
0843 
0844     m_lvClassOptions->clear();
0845     for (int i = start; i < list.count(); ++i) {
0846         int pos = reg.indexIn(list[i]);
0847         if (pos != -1) {
0848             QTreeWidgetItem *twi = new QTreeWidgetItem(m_lvClassOptions, QStringList(reg.cap(1)));
0849             twi->setFlags(twi->flags() | Qt::ItemIsUserCheckable);
0850 
0851             // see if it is a default option
0852             if (isDefaultClassOption(reg.cap(1))) {
0853                 twi->setText(1, reg.cap(2) + " [default]");
0854             }
0855             else {
0856                 twi->setText(1, reg.cap(2));
0857             }
0858 
0859             // check it if this option is set by th user
0860             twi->setCheckState(0, isSelectedClassOption(reg.cap(1)) ? Qt::Checked : Qt::Unchecked);
0861         }
0862     }
0863 }
0864 
0865 // get all options of the current class as a comma separated list
0866 //  - first entry: always the current fontsize
0867 //  - second entry: always the current papersize
0868 //  - followed by all other checked options
0869 QString QuickDocument::getClassOptions()
0870 {
0871     QString fontsize = stripDefault(m_cbTypefaceSize->currentText());
0872     QString papersize = stripDefault(m_cbPaperSize->currentText());
0873 
0874     QString options =  fontsize + ',' + papersize;
0875 
0876     QTreeWidgetItemIterator it(m_lvClassOptions);
0877     while (*it) {
0878         if ((*it)->checkState(0) == Qt::Checked) {
0879             options += ',' + (*it)->text(0);
0880         }
0881         ++it;
0882     }
0883 
0884     return options;
0885 }
0886 
0887 // Some changes were made in the listview: add, edit oder delete entries.
0888 // This means that the defaultOptions-dictionary, the selectedOptions-dictionary
0889 // and the list of all options may be                                                                     . So the documentClass-dictionary,
0890 // the defaultOptions-dictionary and the selectedOptions-dictionary must be updated.
0891 void QuickDocument::updateClassOptions()
0892 {
0893     KILE_DEBUG_MAIN << "==QuickDocument::updateClassOptions()============";
0894     KILE_DEBUG_MAIN << "\tclass: " << m_currentClass;
0895 
0896     QString defaultoptions;
0897     QStringList newlist;
0898     QStringList oldlist = m_dictDocumentClasses[m_currentClass];
0899 
0900     // read the first four static entries
0901     newlist << oldlist[qd_Fontsizes];
0902     newlist << oldlist[qd_Papersizes];
0903     newlist << QString();        // dummy entry: will be changed
0904     newlist << getClassOptions();
0905 
0906     // read all options
0907     QTreeWidgetItemIterator it(m_lvClassOptions);
0908     while (*it) {
0909         QString description = (*it)->text(1);
0910         if (description.right(10) == " [default]") {
0911             description = stripDefault(description);
0912             if (!defaultoptions.isEmpty()) {
0913                 defaultoptions += ',';
0914             }
0915             defaultoptions += (*it)->text(0);
0916         }
0917         newlist += (*it)->text(0) + " => " + description;
0918         ++it;
0919     }
0920 
0921     // update list entry with defaultoptions
0922     newlist[qd_DefaultOptions] = defaultoptions;
0923 
0924     // insert this changed list into the documentClass-dictionary
0925     m_dictDocumentClasses[m_currentClass] = newlist;
0926 
0927     // update other dictionaries
0928     setDefaultClassOptions(newlist[qd_DefaultOptions]);
0929     setSelectedClassOptions(newlist[qd_SelectedOptions]);
0930 }
0931 
0932 
0933 // Insert all entries from a comma separated list into a combobox.
0934 // If this entry matches a given text, this entry will be activated.
0935 void QuickDocument::fillCombobox(KileWidget::CategoryComboBox *combo, const QString &cslist, const QString &seltext)
0936 {
0937     bool documentclasscombo = (combo == m_cbDocumentClass);
0938 
0939     QString sep = (m_currentClass == "beamer" && combo == m_cbPaperSize) ? ";" : ",";
0940     QStringList list = cslist.split(sep, Qt::SkipEmptyParts);
0941     if (!documentclasscombo) {
0942         list.sort();
0943     }
0944 
0945     combo->clear();
0946     for (int i = 0; i < list.count(); ++i) {
0947         if (!documentclasscombo && isDefaultClassOption(list[i])) {
0948             combo->addItem(QString(list[i]) + " [default]");
0949         }
0950         else if (list[i] != "-") {
0951             combo->addItem(list[i]);
0952         }
0953         else {
0954             combo->addCategoryItem("");
0955         }
0956 
0957         // should this entry be selected?
0958         if (!seltext.isEmpty() && list[i] == seltext) {
0959             combo->setCurrentIndex(i);
0960         }
0961     }
0962 }
0963 
0964 // Add some entries from a comma separated list to a sorted combobox.
0965 // The new entries must match a regular expression or will be denied.
0966 bool QuickDocument::addComboboxEntries(KileWidget::CategoryComboBox *combo, const QString &title, const QString &entry)
0967 {
0968     // read current comboxbox entries
0969     QStringList combolist;
0970     for (int i = 0; i < combo->count(); ++i) {
0971         combolist += combo->itemText(i);
0972     }
0973 
0974     // add new entries (one or a comma separated list)
0975     QStringList list = entry.split(',');
0976     for (int i = 0; i < list.count(); ++i) {
0977         QString s = list[i].trimmed();
0978         // entries must match a regular expression
0979         if (combolist.indexOf(s) != -1) {
0980             KMessageBox::error(this, i18n("%1 '%2' already exists.", title, s));
0981         }
0982         else {
0983             combolist += s;
0984             KILE_DEBUG_MAIN << "\tinsert new " << title << ": " << s;
0985         }
0986     }
0987 
0988     // insert list, if there are more entries than before
0989     if (combolist.count() > combo->count()) {
0990         fillCombobox(combo, combolist.join(","), list[0]);
0991         return true;
0992     }
0993     else {
0994         return false;
0995     }
0996 }
0997 
0998 QString QuickDocument::getComboxboxList(KComboBox *combo)
0999 {
1000     QStringList list;
1001     for (int i = 0; i < combo->count(); ++i) {
1002         list += combo->itemText(i);
1003     }
1004 
1005     return (list.count() > 0) ? list.join(",") : QString();
1006 }
1007 
1008 // strip an optional default-tag from the string
1009 QString QuickDocument::stripDefault(const QString &s)
1010 {
1011     return (s.right(10) == " [default]") ? s.left(s.length() - 10) : s;
1012 }
1013 
1014 ////////////////////////////// packages tab //////////////////////////////
1015 
1016 void QuickDocument::readPackagesConfig()
1017 {
1018     KILE_DEBUG_MAIN << "\tread config: packages";
1019 
1020     if (! readPackagesListview())
1021         initPackages();
1022 }
1023 
1024 // init default values for packages tab
1025 void QuickDocument::initPackages()
1026 {
1027     KILE_DEBUG_MAIN << "read config: init standard packages";
1028     QTreeWidgetItem *cli;
1029     QTreeWidgetItem *clichild;
1030 
1031     m_lvPackages->clear();
1032     insertTreeWidget(m_lvPackages, "amsmath", i18n("Special math environments and commands (AMS)"));
1033     insertTreeWidget(m_lvPackages, "amsfonts", i18n("Collection of fonts and symbols for math mode (AMS)"));
1034     insertTreeWidget(m_lvPackages, "amssymb", i18n("Defines symbol names for all math symbols in MSAM and MSBM (AMS)"));
1035     insertTreeWidget(m_lvPackages, "amsthm", i18n("Improved theorem setup (AMS)"));
1036     insertTreeWidget(m_lvPackages, "caption", i18n("Extends caption capabilities for figures and tables"));
1037 
1038     cli = insertTreeWidget(m_lvPackages, "hyperref", i18n("Hypertext marks in LaTeX"));
1039     cli->setExpanded(true);
1040     clichild = insertTreeWidget(cli, "dvips", i18n("Use dvips as hyperref driver"));
1041     clichild->setCheckState(0, Qt::Checked);
1042     insertTreeWidget(cli, "pdftex", i18n("Use pdftex as hyperref driver"));
1043     insertEditableTreeWidget(cli, "bookmarks", i18n("Make bookmarks"), "true", "true");
1044     insertEditableTreeWidget(cli, "bookmarksnumbered", i18n("Put section numbers in bookmarks"), "false", "false");
1045     insertEditableTreeWidget(cli, "bookmarksopen", i18n("Open up bookmark tree"), QString(), QString());
1046     insertEditableTreeWidget(cli, "pdfauthor", i18n("Text for PDF Author field"), QString(), QString());
1047     insertEditableTreeWidget(cli, "pdfcreator", i18n("Text for PDF Creator field"), i18n("LaTeX with hyperref package"), i18n("LaTeX with hyperref package"));
1048     insertEditableTreeWidget(cli, "pdffitwindow", i18n("Resize document window to fit document size"), "false", "false");
1049     insertEditableTreeWidget(cli, "pdfkeywords", i18n("Text for PDF Keywords field"), QString(), QString());
1050     insertEditableTreeWidget(cli, "pdfproducer", i18n("Text for PDF Producer field"), QString(), QString());
1051     insertEditableTreeWidget(cli, "pdfstartview", i18n("Starting view of PDF document"), "/Fit", "/Fit");
1052     insertEditableTreeWidget(cli, "pdfsubject", i18n("Text for PDF Subject field"), QString(), QString());
1053     insertEditableTreeWidget(cli, "pdftitle", i18n("Text for PDF Title field"), QString(), QString());
1054 
1055     insertTreeWidget(m_lvPackages, "mathpazo", i18n("Use Palatino font as roman font (both text and math mode)"));
1056     insertTreeWidget(m_lvPackages, "mathptmx", i18n("Use Times font as roman font (both text and math mode)"));
1057     insertTreeWidget(m_lvPackages, "makeidx", i18n("Enable index generation"));
1058     insertTreeWidget(m_lvPackages, "multicol", i18n("Enables multicolumn environments"));
1059     insertTreeWidget(m_lvPackages, "pst-all", i18n("Load all pstricks packages"));
1060     insertTreeWidget(m_lvPackages, "rotating", i18n("Rotates text"));
1061     insertTreeWidget(m_lvPackages, "subfigure", i18n("Enables subfigures inside figures"));
1062     insertTreeWidget(m_lvPackages, "upgreek", i18n("Typesetting capital Greek letters"));
1063     insertTreeWidget(m_lvPackages, "xcolor", i18n("Extending LaTeX's color facilities"));
1064 
1065     cli = insertTreeWidget(m_lvPackages, "babel", i18n("Adds language specific support"));
1066     cli->setExpanded(true);
1067     cli->setCheckState(0, Qt::Checked);
1068     insertTreeWidget(cli, "acadian", "");
1069     insertTreeWidget(cli, "afrikaans", "");
1070     insertTreeWidget(cli, "american", "");
1071     insertTreeWidget(cli, "australian", "");
1072     insertTreeWidget(cli, "austrian", "");
1073     insertTreeWidget(cli, "bahasa", "");
1074     insertTreeWidget(cli, "basque", "");
1075     insertTreeWidget(cli, "brazil", "");
1076     insertTreeWidget(cli, "brazilian", "");
1077     insertTreeWidget(cli, "breton", "");
1078     insertTreeWidget(cli, "british", "");
1079     insertTreeWidget(cli, "bulgarian", "");
1080     insertTreeWidget(cli, "canadian", "");
1081     insertTreeWidget(cli, "canadien", "");
1082     insertTreeWidget(cli, "catalan", "");
1083     insertTreeWidget(cli, "croatian", "");
1084     insertTreeWidget(cli, "czech", "");
1085     insertTreeWidget(cli, "danish", "");
1086     insertTreeWidget(cli, "dutch", "");
1087     insertTreeWidget(cli, "english", "");
1088     insertTreeWidget(cli, "esperanto", "");
1089     insertTreeWidget(cli, "estonian", "");
1090     insertTreeWidget(cli, "finnish", "");
1091     insertTreeWidget(cli, "francais", "");
1092     insertTreeWidget(cli, "frenchb", "");
1093     insertTreeWidget(cli, "french", "");
1094     insertTreeWidget(cli, "galician", "");
1095     insertTreeWidget(cli, "german", "");
1096     insertTreeWidget(cli, "germanb", "");
1097     insertTreeWidget(cli, "greek", "");
1098     insertTreeWidget(cli, "polutonikogreek", "");
1099     insertTreeWidget(cli, "hebrew", "");
1100     insertTreeWidget(cli, "hungarian", "");
1101     insertTreeWidget(cli, "icelandic", "");
1102     insertTreeWidget(cli, "interlingua", "");
1103     insertTreeWidget(cli, "irish", "");
1104     insertTreeWidget(cli, "italian", "");
1105     insertTreeWidget(cli, "latin", "");
1106     insertTreeWidget(cli, "lowersorbian", "");
1107     insertTreeWidget(cli, "magyar", "");
1108     insertTreeWidget(cli, "naustrian", "");
1109     insertTreeWidget(cli, "newzealand", "");
1110     insertTreeWidget(cli, "ngerman", "");
1111     insertTreeWidget(cli, "norsk", "");
1112     insertTreeWidget(cli, "samin", "");
1113     insertTreeWidget(cli, "nynorsk", "");
1114     insertTreeWidget(cli, "polish", "");
1115     insertTreeWidget(cli, "portuges", "");
1116     insertTreeWidget(cli, "portuguese", "");
1117     insertTreeWidget(cli, "romanian", "");
1118     insertTreeWidget(cli, "russian", "");
1119     insertTreeWidget(cli, "scottish", "");
1120     insertTreeWidget(cli, "serbian", "");
1121     insertTreeWidget(cli, "slovak", "");
1122     insertTreeWidget(cli, "slovene", "");
1123     insertTreeWidget(cli, "spanish", "");
1124     insertTreeWidget(cli, "swedish", "");
1125     insertTreeWidget(cli, "turkish", "");
1126     insertTreeWidget(cli, "ukrainian", "");
1127     insertTreeWidget(cli, "uppersorbian", "");
1128     insertTreeWidget(cli, "welsh", "");
1129     insertTreeWidget(cli, "UKenglish", "");
1130     insertTreeWidget(cli, "USenglish", "");
1131 
1132     cli = insertTreeWidget(m_lvPackages, "fontenc", i18n("Use a font encoding scheme"));
1133     cli->setExpanded(true);
1134     cli->setCheckState(0, Qt::Checked);
1135     insertTreeWidget(cli, "HE8", "");
1136     insertTreeWidget(cli, "IL2", "");
1137     insertTreeWidget(cli, "LCH", "");
1138     insertTreeWidget(cli, "LCY", "");
1139     insertTreeWidget(cli, "LGR", "");
1140     insertTreeWidget(cli, "LHE", "");
1141     insertTreeWidget(cli, "LIT", "");
1142     insertTreeWidget(cli, "LO1", "");
1143     insertTreeWidget(cli, "LY1", "");
1144     insertTreeWidget(cli, "MTT", "");
1145     insertTreeWidget(cli, "OML", "");
1146     insertTreeWidget(cli, "OMS", "");
1147     insertTreeWidget(cli, "OT1", "");
1148     insertTreeWidget(cli, "OT2", "");
1149     insertTreeWidget(cli, "OT4", "");
1150     insertTreeWidget(cli, "PD1", "");
1151     insertTreeWidget(cli, "PU", "");
1152     insertTreeWidget(cli, "QX", "");
1153     insertTreeWidget(cli, "T1", "");
1154     insertTreeWidget(cli, "T2A", "");
1155     insertTreeWidget(cli, "T2B", "");
1156     insertTreeWidget(cli, "T2C", "");
1157     insertTreeWidget(cli, "T5", "");
1158     insertTreeWidget(cli, "TS1", "");
1159     insertTreeWidget(cli, "UT1", "");
1160     insertTreeWidget(cli, "X2", "");
1161 
1162     cli = insertTreeWidget(m_lvPackages, "graphicx", i18n("Support for including graphics"));
1163     cli->setExpanded(true);
1164     cli->setCheckState(0, Qt::Checked);
1165     insertTreeWidget(cli, "dvips", i18n("Specialize on graphic inclusion for dvips"));
1166     insertTreeWidget(cli, "pdftex", i18n("Specialize on graphic inclusion for pdftex"));
1167     insertTreeWidget(cli, "draft", i18n("Show only frames of graphics"));
1168 }
1169 
1170 // Try to read values from the config file:
1171 //  - main entry:  selected,open,empty,empty,description
1172 //  - child entry: selected,editable,defaultvalue,value,description
1173 
1174 bool QuickDocument::readPackagesListview()
1175 {
1176     KILE_DEBUG_MAIN << "\tread config: packages from config file";
1177 
1178     QStringList elements = KileConfig::packagesList();
1179 
1180     // clear packages dictionaries and listview
1181     m_dictPackagesEditable.clear();
1182     m_dictPackagesDefaultvalues.clear();
1183     m_lvPackages->clear();
1184 
1185     if (elements.empty())
1186         return false;
1187 
1188     // regular expression to split the string from the config file
1189     QRegExp reg("([^,]*),([^,]*),([^,]*),([^,]*),(.*)");
1190 
1191     KConfigGroup configGroup = config()->group("QuickDocument/Packages");
1192     for (QStringList::Iterator it = elements.begin(); it != elements.end(); ++it) {
1193         QTreeWidgetItem *item;
1194 
1195         // look, if this is a main or a child entry
1196         KILE_DEBUG_MAIN << "\tread config entry: " << *it;
1197         int pos = (*it).indexOf('!');
1198         if (pos == -1) {                      // main entry
1199             item = new QTreeWidgetItem(m_lvPackages, QStringList(*it));
1200             item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
1201             item->setCheckState(0, Qt::Unchecked);
1202             if (reg.exactMatch(configGroup.readEntry(*it))) {
1203                 if (reg.cap(1) == "1")          // selected state (entry 1)
1204                     item->setCheckState(0, Qt::Checked);
1205                 if (reg.cap(2) == "1")          // open state (entry 2)
1206                     item->setExpanded(true);
1207                 item->setText(2, reg.cap(5));    // description (entry 5)
1208             } else {
1209                 KILE_DEBUG_MAIN << "\twrong config entry for package " << item->text(0);
1210             }
1211         } else {                              // child entry
1212             QList<QTreeWidgetItem*> items = m_lvPackages->findItems((*it).left(pos), Qt::MatchExactly);
1213             if (items.count() > 0) {
1214                 item = items[0];
1215                 if (reg.exactMatch(configGroup.readEntry(*it))) {
1216                     QTreeWidgetItem *clichild;
1217                     if (reg.cap(2) == "1") {                                       // editable state
1218                         clichild = insertEditableTreeWidget(item, (*it).mid(pos + 1), reg.cap(5), reg.cap(4), reg.cap(3));
1219                     } else {
1220                         clichild = new QTreeWidgetItem(item, QStringList((*it).mid(pos + 1)));
1221                         clichild->setFlags(clichild->flags() | Qt::ItemIsUserCheckable);
1222                         clichild->setCheckState(0, Qt::Unchecked);
1223                         clichild->setText(2, reg.cap(5));                           // description
1224                     }
1225                     if (reg.cap(1) == "1")                                         // selected state
1226                         clichild->setCheckState(0, Qt::Checked);
1227                 } else {
1228                     KILE_DEBUG_MAIN << "\twrong config entry for package option " << item->text(0);
1229                 }
1230             } else {
1231                 KILE_DEBUG_MAIN << "\tlistview entry for package " << (*it).left(pos) << " not found";
1232             }
1233         }
1234     }
1235 
1236     return true;
1237 }
1238 
1239 void QuickDocument::writePackagesConfig()
1240 {
1241     KILE_DEBUG_MAIN << "\twrite config: packages";
1242 
1243     QStringList packagesList;
1244 
1245     KConfigGroup configGroup = config()->group("QuickDocument/Packages");
1246     for (int i = 0; i < m_lvPackages->topLevelItemCount(); ++i) {
1247         QTreeWidgetItem *currentItem = m_lvPackages->topLevelItem(i);
1248         KILE_DEBUG_MAIN << "\twrite config: " << currentItem->text(0);
1249         // add to packages list
1250         packagesList += currentItem->text(0);
1251 
1252         // determine config entry
1253         QString packageentry;
1254 
1255         // look for selected entries
1256         if (currentItem->checkState(0) == Qt::Checked)
1257             packageentry = "1,";
1258         else
1259             packageentry = "0,";
1260 
1261         // look if this listitem is opened
1262         if (currentItem->isExpanded())
1263             packageentry += "1,";
1264         else
1265             packageentry += "0,";
1266 
1267         // two dummy entries and finally the description
1268         packageentry += ",," + currentItem->text(2);
1269 
1270         // write listview entry
1271         configGroup.writeEntry(currentItem->text(0), packageentry);
1272 
1273         // look for children
1274         for (int j = 0; j < currentItem->childCount(); ++j) {
1275             QTreeWidgetItem *curchild = currentItem->child(j);
1276             // add child to packages list
1277             QString option = currentItem->text(0) + '!' + curchild->text(0);
1278             packagesList += option;
1279             KILE_DEBUG_MAIN << "\twrite config: " << option;
1280 
1281             // determine config entry
1282             QString optionentry;
1283 
1284             // look for selected options
1285             if (curchild->checkState(0) == Qt::Checked)
1286                 optionentry = "1,";
1287             else
1288                 optionentry = "0,";
1289 
1290             // look, if this child is editable
1291             if (m_dictPackagesEditable.contains(option)) {
1292                 optionentry += "1,";
1293                 if (m_dictPackagesDefaultvalues.contains(option))
1294                     optionentry += m_dictPackagesDefaultvalues[option] + ',';
1295                 else
1296                     optionentry += ',';
1297             } else
1298                 optionentry += "0,,";
1299 
1300             // add a value and a description
1301             optionentry += getPackagesValue(curchild->text(1))
1302                            + ',' + stripPackageDefault(option, curchild->text(2));
1303 
1304             // write listview entry
1305             configGroup.writeEntry(option, optionentry);
1306         }
1307     }
1308 
1309     // write the list of all packages
1310     KileConfig::setPackagesList(packagesList);
1311 }
1312 
1313 QTreeWidgetItem* QuickDocument::insertTreeWidget(QTreeWidget *treeWidget,
1314         const QString &entry,
1315         const QString &description)
1316 {
1317     QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget, QStringList() << entry << "" << description);
1318     item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
1319     item->setCheckState(0, Qt::Unchecked);
1320 
1321     return item;
1322 }
1323 
1324 QTreeWidgetItem* QuickDocument::insertTreeWidget(QTreeWidgetItem *parent,
1325         const QString &entry,
1326         const QString &description)
1327 {
1328     QTreeWidgetItem *item = new QTreeWidgetItem(parent, QStringList() << entry << "" << description);
1329     item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
1330     item->setCheckState(0, Qt::Unchecked);
1331 
1332     return item;
1333 }
1334 
1335 QTreeWidgetItem* QuickDocument::insertEditableTreeWidget(QTreeWidgetItem *parent,
1336         const QString &entry,
1337         const QString &description,
1338         const QString &value,
1339         const QString &defaultvalue)
1340 {
1341     QTreeWidgetItem *item = new QTreeWidgetItem(parent, QStringList() << entry << "" << description);
1342     item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
1343     item->setCheckState(0, Qt::Unchecked);
1344 
1345     QString option = parent->text(0) + '!' + entry;
1346     m_dictPackagesEditable[option] = true;
1347     if (!defaultvalue.isEmpty())
1348         m_dictPackagesDefaultvalues[option] = defaultvalue;
1349     setPackagesValue(item, option, value);
1350     if (!description.isEmpty())
1351         item->setText(2, addPackageDefault(option, description));
1352 
1353     return item;
1354 }
1355 
1356 void QuickDocument::setPackagesValue(QTreeWidgetItem *item, const QString &option, const QString &val)
1357 {
1358     QString defaultvalue = (m_dictPackagesDefaultvalues.contains(option))
1359                            ? m_dictPackagesDefaultvalues[option] : QString();
1360     QString value = (! val.isEmpty()) ? val : QString();
1361 
1362     if (value == defaultvalue)
1363         item->setText(1, i18n("<default>"));
1364     else if (value.isEmpty())
1365         item->setText(1, i18n("<empty>"));
1366     else
1367         item->setText(1, value);
1368 }
1369 
1370 QString QuickDocument::getPackagesValue(const QString &value)
1371 {
1372     return (value == i18n("<default>") || value == i18n("<empty>")) ? QString() : value;
1373 }
1374 
1375 bool QuickDocument::isTreeWidgetEntry(QTreeWidget *treeWidget, const QString &entry)
1376 {
1377     return treeWidget->findItems(entry, Qt::MatchExactly).count() != 0;
1378 }
1379 
1380 bool QuickDocument::isTreeWidgetChild(QTreeWidget *treeWidget, const QString &entry, const QString &option)
1381 {
1382     for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
1383         QTreeWidgetItem *currentItem = treeWidget->topLevelItem(i);
1384         if (currentItem->text(0) == entry) {
1385             for (int j = 0; j < currentItem->childCount(); ++j) {
1386                 QTreeWidgetItem *currentChild = currentItem->child(j);
1387                 if (currentChild->text(0) == option) {
1388                     return true;
1389                 }
1390             }
1391             return false;
1392         }
1393     }
1394     return false;
1395 }
1396 
1397 QString QuickDocument::addPackageDefault(const QString &option, const QString &description)
1398 {
1399     return (m_dictPackagesDefaultvalues.contains(option))
1400            ? description + " [" + m_dictPackagesDefaultvalues[option] + ']'
1401            : description + " [ ]";
1402 }
1403 
1404 QString QuickDocument::stripPackageDefault(const QString &option, const QString &description)
1405 {
1406     QRegExp reg("(.*) \\[([^\\[]*)\\]");
1407 
1408     if (description.right(4) == " [ ]")
1409         return description.left(description.length() - 4);
1410 
1411     if (! reg.exactMatch(description))
1412         return description;
1413 
1414     return (reg.cap(2).isEmpty() ||
1415             (m_dictPackagesDefaultvalues.contains(option) && m_dictPackagesDefaultvalues[option] == reg.cap(2))
1416            ) ? reg.cap(1) : description;
1417 }
1418 
1419 ////////////////////////////// hyperref tab //////////////////////////////
1420 
1421 void QuickDocument::initHyperref()
1422 {
1423     KILE_DEBUG_MAIN << "\tread config: init hyperref";
1424 
1425     QString driver =  "dvipdf,dvipdfm,dvips,dvipsone,"
1426                       "dviwindo,hypertex,latex2html,pdftex,"
1427                       "ps2pdf,tex4ht,textures,vtex";
1428     QStringList list = driver.split(',');
1429 
1430     m_dictHyperrefDriver.clear();
1431     for (int i = 0; i < list.count(); ++i) {
1432         m_dictHyperrefDriver[list[i]] = true;
1433     }
1434 }
1435 
1436 bool QuickDocument::isHyperrefDriver(const QString &name)
1437 {
1438     return m_dictHyperrefDriver.contains(name);
1439 }
1440 
1441 ////////////////////////////// check for existing exntries //////////////////////////////
1442 
1443 bool QuickDocument::isDocumentClass(const QString &name)
1444 {
1445     for (int i = 0; i < m_cbDocumentClass->count(); ++i) {
1446         if (m_cbDocumentClass->itemText(i) == name)
1447             return true;
1448     }
1449     return false;
1450 }
1451 
1452 bool QuickDocument::isDocumentClassOption(const QString &option)
1453 {
1454     return isTreeWidgetEntry(m_lvClassOptions, option);
1455 }
1456 
1457 bool QuickDocument::isPackage(const QString &package)
1458 {
1459     return isTreeWidgetEntry(m_lvPackages, package);
1460 }
1461 
1462 bool QuickDocument::isPackageOption(const QString &package, const QString &option)
1463 {
1464     return isTreeWidgetChild(m_lvPackages, package, option);
1465 }
1466 
1467 
1468 ////////////////////////////// print document template //////////////////////////////
1469 
1470 void QuickDocument::printTemplate()
1471 {
1472     KILE_DEBUG_MAIN << "==QuickDocument::printTemplate()============";
1473 
1474     // get current document class
1475     QString documentclass = m_cbDocumentClass->currentText();
1476     KILE_DEBUG_MAIN << "\tdocument class: " << documentclass;
1477 
1478     // build template
1479     m_td.tagBegin = "\\documentclass";
1480 
1481     // build options
1482     QString options;
1483     if (documentclass != "beamer") {
1484         if (!m_cbPaperSize->currentText().isEmpty())
1485             options += stripDefault(m_cbPaperSize->currentText()) + ',';
1486     }
1487 
1488     if (!m_cbTypefaceSize->currentText().isEmpty())
1489         options += stripDefault(m_cbTypefaceSize->currentText()) + ',';
1490 
1491     QTreeWidgetItemIterator it(m_lvClassOptions);
1492     while (*it) {
1493         if ((*it)->checkState(0) == Qt::Checked) {
1494             options += (*it)->text(0) + ',';
1495         }
1496         ++it;
1497     }
1498 
1499     if (! options.isEmpty())
1500         m_td.tagBegin += '[' + options.left(options.length() - 1) + ']';
1501     m_td.tagBegin += '{' + documentclass + "}\n\n";
1502 
1503 
1504     QString enc = m_cbEncoding->currentText();
1505     if (!enc.isEmpty())
1506     {
1507         if (enc.indexOf("utf") != -1)
1508             m_td.tagBegin += "\\usepackage{ucs}\n";
1509         m_td.tagBegin += "\\usepackage[" + enc + "]{inputenc}\n";
1510     }
1511     if (documentclass != "beamer") {
1512         printPackages();
1513         printHyperref();
1514     } else {
1515         printBeamerTheme();
1516         printPackages();
1517     }
1518 
1519     if (!m_leAuthor->text().isEmpty())
1520         m_td.tagBegin += "\\author{" + m_leAuthor->text() + "}\n";
1521     if (!m_leTitle->text().isEmpty())
1522         m_td.tagBegin += "\\title{" + m_leTitle->text() + "}\n";
1523     if (!m_leDate->text().isEmpty())
1524         m_td.tagBegin += "\\date{" + m_leDate->text() + "}\n";
1525     m_td.tagBegin += '\n';
1526 
1527     m_td.tagBegin += "\\begin{document}\n%E%C";
1528 
1529     m_td.tagEnd = "\n\\end{document}\n";
1530 
1531     KILE_DEBUG_MAIN << "m_td.tagBegin " << m_td.tagBegin;
1532     KILE_DEBUG_MAIN << "m_td.tagEnd " << m_td.tagEnd;
1533 }
1534 
1535 void QuickDocument::printPackages()
1536 {
1537     KILE_DEBUG_MAIN << "\tpackages";
1538 
1539     m_currentHyperref = false;
1540     m_hyperrefdriver.clear();
1541     m_hyperrefsetup.clear();
1542 
1543     for (int i = 0; i < m_lvPackages->topLevelItemCount(); ++i) {
1544         QTreeWidgetItem *cur = m_lvPackages->topLevelItem(i);
1545 
1546         if (cur->text(0) == "hyperref") {            // manage hyperref package
1547             m_currentHyperref = cur->checkState(0) == Qt::Checked;
1548             for (int j = 0; j < cur->childCount(); ++j) {
1549                 QTreeWidgetItem *curchild = cur->child(j);
1550                 if (curchild->checkState(0) == Qt::Checked) {              // manage hyperref option
1551                     if (isHyperrefDriver(curchild->text(0))) {     // either hyperref driver
1552                         if (! m_hyperrefdriver.isEmpty())
1553                             m_hyperrefdriver += ',';
1554                         m_hyperrefdriver += curchild->text(0);
1555                     } else {
1556                         QString value = curchild->text(1);          // or another option
1557                         if (value != i18n("<default>")) {
1558                             if (! m_hyperrefsetup.isEmpty())
1559                                 m_hyperrefsetup += ',';
1560                             m_hyperrefsetup += "%\n   " + curchild->text(0) + '=' + getPackagesValue(curchild->text(1));
1561                         }
1562                     }
1563                 }
1564             }
1565         } else if (cur->checkState(0) == Qt::Checked) {                  // manage other package options
1566             QString packageOptions;
1567             for (int j = 0; j < cur->childCount(); ++j) {
1568                 QTreeWidgetItem *curchild = cur->child(j);
1569                 if (curchild->checkState(0) == Qt::Checked) {
1570                     QString optiontext;
1571                     if (m_dictPackagesEditable.contains(cur->text(0) + '!' + curchild->text(0))) {
1572                         QString value = curchild->text(1);
1573                         if (value != i18n("<default>"))
1574                             optiontext = curchild->text(0) + '=' + getPackagesValue(curchild->text(1));
1575                     } else
1576                         optiontext = curchild->text(0);
1577 
1578                     if (! optiontext.isEmpty()) {
1579                         if (!packageOptions.isEmpty())
1580                             packageOptions += ',';
1581                         packageOptions += optiontext;
1582                     }
1583                 }
1584             }
1585 
1586             m_td.tagBegin += "\\usepackage";
1587             if (!packageOptions.isEmpty())
1588                 m_td.tagBegin += '[' + packageOptions + ']';
1589             m_td.tagBegin += '{' + cur->text(0) + "}\n";
1590         }
1591     }
1592     m_td.tagBegin += '\n';
1593 }
1594 
1595 void QuickDocument::printHyperref()
1596 {
1597     if (! m_currentHyperref)
1598         return;
1599 
1600     KILE_DEBUG_MAIN << "\thyperref";
1601 
1602     // output hyperref package
1603     m_td.tagBegin += "\\usepackage";
1604     if (! m_hyperrefdriver.isEmpty())
1605         m_td.tagBegin += '[' + m_hyperrefdriver + ']';
1606     m_td.tagBegin += "{hyperref}\n";
1607 
1608     // output hyperref options
1609     if (! m_hyperrefsetup.isEmpty()) {
1610         m_td.tagBegin += "\\hypersetup{" + m_hyperrefsetup + "%\n}\n";
1611     }
1612 
1613     m_td.tagBegin += '\n';
1614 
1615 
1616 }
1617 
1618 void QuickDocument::printBeamerTheme()
1619 {
1620     KILE_DEBUG_MAIN << "\tbeamer theme";
1621 
1622     QString theme = m_cbPaperSize->currentText();
1623     QRegExp reg("(\\w+)\\s+\\((.*)\\)$");
1624 
1625     if (reg.indexIn(theme) >= 0) {
1626         QStringList optionlist = reg.cap(2).split(',');
1627         m_td.tagBegin += "\\usepackage[" + optionlist.join(",") + "]{beamertheme" + reg.cap(1) + "}\n\n";
1628     }
1629     else {
1630         m_td.tagBegin += "\\usepackage{beamertheme" + theme + "}\n\n";
1631     }
1632 }
1633 
1634 ////////////////////////////// Slots //////////////////////////////
1635 
1636 void QuickDocument::slotAccepted()
1637 {
1638     // get current class options
1639     m_currentClass = m_cbDocumentClass->currentText();
1640     KILE_DEBUG_MAIN << "current class: " << m_currentClass;
1641 
1642     // save the checked options
1643     m_dictDocumentClasses[m_currentClass][qd_SelectedOptions] = getClassOptions();
1644     KILE_DEBUG_MAIN << "save options: " << m_dictDocumentClasses[m_currentClass][qd_SelectedOptions];
1645 
1646     // build template
1647     printTemplate();
1648 
1649     // update config file
1650     writeConfig();
1651 }
1652 
1653 ////////////////////////////// slots: document class
1654 void QuickDocument::slotDocumentClassAdd()
1655 {
1656     KILE_DEBUG_MAIN << "==QuickDocument::slotDocumentClassAdd()============";
1657     QStringList list;
1658     list << i18n("Document Class")
1659          << "label,edit,label,combobox,checkbox,checkbox"
1660          << i18n("Please enter the new document &class:")
1661          << QString()                                     // 3
1662          << i18n("&Set all options from this standard class (optional):")
1663          << ",article,book,letter,report,scrartcl,scrbook,scrreprt"    // 5
1664          << i18n("Use standard &fontsizes")                   // 6
1665          << i18n("Use standard &papersizes")                  // 7
1666          ;
1667 
1668     if (inputDialog(list, qd_CheckNotEmpty | qd_CheckDocumentClass)) {
1669         QString classname = list[3];
1670 
1671         QStringList classlist;
1672         if (list[5].isEmpty()) {            // no base class
1673             QString useFontsizes = (list[6] == "true")
1674                                    ? "10pt,11pt,12pt" : "";
1675             QString usePapersizes = (list[7] == "true")
1676                                     ? "a4paper,a5paper,b5paper,executivepaper,legalpaper,letterpaper" : "";
1677             KILE_DEBUG_MAIN << "\tadd document class: " << classname
1678                             << " fontsize=" << list[6] << " papersize=" << list[7];
1679 
1680             // set default entries for the documentClass-dictionary
1681             classlist <<  useFontsizes << usePapersizes << "" << "";
1682         }
1683         else {                              // based on a standard class
1684             // first get the first four parameters
1685             classlist = m_dictDocumentClasses[list[5]];
1686             // then add all baseclass options
1687             QStringList optionlist;
1688             initStandardOptions(list[5], optionlist);
1689             for (int i = 0; i < optionlist.count(); ++i) {
1690                 classlist.append(optionlist[i]);
1691             }
1692         }
1693 
1694         // insert the stringlist for this new document class
1695         m_dictDocumentClasses[classname] = classlist;
1696 
1697         fillDocumentClassCombobox();
1698 
1699         // add the new document class into the userClasslist and the documentClass-combobox
1700         m_userClasslist.append(classname);
1701 
1702         // activate the new document class
1703         m_cbDocumentClass->addItem(classname);
1704         m_cbDocumentClass->setCurrentIndex(m_cbDocumentClass->count() - 1);
1705         slotDocumentClassChanged(m_cbDocumentClass->count() - 1);
1706     }
1707 }
1708 
1709 void QuickDocument::slotDocumentClassDelete()
1710 {
1711     // get the name of the current class
1712     QString documentclass = m_cbDocumentClass->currentText();
1713 
1714     KILE_DEBUG_MAIN << "==QuickDocument::slotDocumentClassDelete()============";
1715     if (KMessageBox::warningContinueCancel(this, i18n("Do you want to remove \"%1\" from the document class list?", documentclass),
1716                                            i18n("Remove Document Class")) == KMessageBox::Continue) {
1717         KILE_DEBUG_MAIN << "\tlazy delete class: " << documentclass;
1718 
1719         // remove this document class from the documentClass-dictionary
1720         m_dictDocumentClasses.remove(documentclass);
1721 
1722         // mark this document class for deleting from config file (only with OK-Button)
1723         if (m_deleteDocumentClasses.indexOf(documentclass) == -1) {
1724             m_deleteDocumentClasses.append(documentclass);
1725         }
1726 
1727         // remove it from the list of userclasses
1728         m_userClasslist.removeAll(documentclass);
1729 
1730         // and finally remove it from the combobox
1731         int i = m_cbDocumentClass->currentIndex();
1732         m_cbDocumentClass->removeItem(i);
1733 
1734         // init a new document class
1735         m_currentClass = m_cbDocumentClass->currentText();
1736         KILE_DEBUG_MAIN << "\tchange class:  --> " << m_currentClass;
1737         initDocumentClass();
1738     }
1739 }
1740 
1741 void QuickDocument::slotDocumentClassChanged(int index)
1742 {
1743     KILE_DEBUG_MAIN << "==QuickDocument::slotDocumentClassChanged()============";
1744     if (m_cbDocumentClass->itemText(index).isEmpty()) {
1745         KILE_DEBUG_MAIN << "\tempty";
1746         return;
1747     }
1748 
1749     // get old and new document class
1750     QString oldclass = m_currentClass;
1751     m_currentClass = m_cbDocumentClass->itemText(index);
1752     KILE_DEBUG_MAIN << "\tchange class: " << oldclass << " --> " << m_currentClass;
1753 
1754     // save the checked options
1755     m_dictDocumentClasses[oldclass][qd_SelectedOptions] = getClassOptions();
1756     KILE_DEBUG_MAIN << "\tsave options: " << m_dictDocumentClasses[oldclass][qd_SelectedOptions];
1757 
1758     // init the new document class
1759     initDocumentClass();
1760 }
1761 
1762 void QuickDocument::slotTypefaceSizeAdd()
1763 {
1764     KILE_DEBUG_MAIN << "==QuickDocument::slotTypefaceSizeAdd()============";
1765     QStringList list;
1766     list << i18n("Add Fontsize")
1767          << "label,edit"
1768          << i18n("Please enter the &fontsizes (comma-separated list):")
1769          << QString()             // 3
1770          ;
1771 
1772     if (inputDialog(list, qd_CheckNotEmpty | qd_CheckFontsize)) {
1773         KILE_DEBUG_MAIN << "\tadd fontsize: " << list[3];
1774         addComboboxEntries(m_cbTypefaceSize, "fontsize", list[3]);
1775 
1776         // save the new list of fontsizes
1777         m_dictDocumentClasses[m_currentClass][qd_Fontsizes] = getComboxboxList(m_cbTypefaceSize);
1778 
1779         // enable/disable buttons to add or delete entries
1780         slotEnableButtons();
1781     }
1782 }
1783 
1784 void QuickDocument::slotTypefaceSizeDelete()
1785 {
1786     if (KMessageBox::warningContinueCancel(this, i18n("Do you want to remove \"%1\" from the fontsize list?", m_cbTypefaceSize->currentText()), i18n("Remove Fontsize")) == KMessageBox::Continue)
1787     {
1788         int i = m_cbTypefaceSize->currentIndex();
1789         m_cbTypefaceSize->removeItem(i);
1790 
1791         // save the new list of fontsizes
1792         m_dictDocumentClasses[m_currentClass][qd_Fontsizes] = getComboxboxList(m_cbTypefaceSize);
1793 
1794         // enable/disable buttons to add or delete entries
1795         slotEnableButtons();
1796     }
1797 }
1798 
1799 void QuickDocument::slotPaperSizeAdd()
1800 {
1801     KILE_DEBUG_MAIN << "==QuickDocument::slotPaperSizeAdd()============";
1802     QStringList list;
1803     list << i18n("Add Papersize")
1804          << "label,edit"
1805          << i18n("Please enter the &papersizes (comma-separated list):")
1806          << QString()                 // 3
1807          ;
1808 
1809     if (inputDialog(list, qd_CheckNotEmpty | qd_CheckPapersize)) {
1810         KILE_DEBUG_MAIN << "\tadd papersize: " << list[3];
1811         addComboboxEntries(m_cbPaperSize, "papersize", list[3]);
1812 
1813         // save the new list of papersizes
1814         m_dictDocumentClasses[m_currentClass][qd_Papersizes] = getComboxboxList(m_cbPaperSize);
1815 
1816         // enable/disable buttons to add or delete entries
1817         slotEnableButtons();
1818     }
1819 }
1820 
1821 void QuickDocument::slotPaperSizeDelete()
1822 {
1823     if (KMessageBox::warningContinueCancel(this, i18n("Do you want to remove \"%1\" from the papersize list?", m_cbPaperSize->currentText()), i18n("Remove Papersize")) == KMessageBox::Continue)
1824     {
1825         int i = m_cbPaperSize->currentIndex();
1826         m_cbPaperSize->removeItem(i);
1827 
1828         // save the new list of papersizes
1829         m_dictDocumentClasses[m_currentClass][qd_Papersizes] = getComboxboxList(m_cbPaperSize);
1830 
1831         // enable/disable buttons to add or delete entries
1832         slotEnableButtons();
1833     }
1834 }
1835 
1836 ////////////////////////////// slots: document class button //////////////////////////////
1837 
1838 void QuickDocument::slotClassOptionAdd()
1839 {
1840     KILE_DEBUG_MAIN << "==QuickDocument::slotClassOptionAdd()============";
1841     QStringList list;
1842     list << i18n("Add Option")
1843          << "label,edit,label,edit,checkbox"
1844          << i18n("Name of &option:")
1845          << QString()                  // 3
1846          << i18n("&Description:")
1847          << QString()                  // 5
1848          << i18n("&Select this option")    // 6
1849          ;
1850 
1851     if (inputDialog(list, qd_CheckNotEmpty | qd_CheckClassOption)) {
1852         // get results
1853         QString option = list[3];
1854         QString description = list[5];
1855         bool check = (list[6] == "true");
1856 
1857         // add class option
1858         KILE_DEBUG_MAIN << "\tadd option: " << option << " (" << description << ") checked=" << list[6];
1859         QTreeWidgetItem *twi = new QTreeWidgetItem(m_lvClassOptions, QStringList() << option << description);
1860         twi->setFlags(twi->flags() | Qt::ItemIsUserCheckable);
1861         twi->setCheckState(0, check ? Qt::Checked : Qt::Unchecked);
1862 
1863         // update dictionary
1864         updateClassOptions();
1865     }
1866 }
1867 
1868 void QuickDocument::slotClassOptionEdit()
1869 {
1870     if (m_lvClassOptions->selectedItems().count() == 0)
1871         return;
1872 
1873     QTreeWidgetItem *cur = m_lvClassOptions->selectedItems()[0];
1874 
1875     KILE_DEBUG_MAIN << "==QuickDocument::slotClassOptionEdit()============";
1876     QStringList list;
1877     list << i18n("Edit Option")
1878          << "label,edit-r,label,edit"
1879          << i18n("Name of &option:")
1880          << cur->text(0)
1881          << i18n("&Description:")
1882          << stripDefault(cur->text(1))           // 5
1883          ;
1884 
1885     //if ( inputDialog(list,qd_CheckNotEmpty | qd_CheckClassOption) ) {
1886     if (inputDialog(list)) {
1887         // get results
1888         //QString option = list[3];
1889         QString description = list[5];
1890 
1891         // set changed class option
1892         KILE_DEBUG_MAIN << "\tedit option: " << cur->text(0) << " (" << description << ")";
1893         //cur->setText(0, option);
1894         cur->setText(1, description);
1895 
1896         // update dictionary
1897         updateClassOptions();
1898     }
1899 }
1900 
1901 void QuickDocument::slotClassOptionDelete()
1902 {
1903     KILE_DEBUG_MAIN << "==QuickDocument::slotClassOptionDelete()============";
1904     if (m_lvClassOptions->selectedItems().count() > 0 && (KMessageBox::warningContinueCancel(this, i18n("Do you want to delete this class option?"), i18n("Delete")) == KMessageBox::Continue)) {
1905         QTreeWidgetItem *cur = m_lvClassOptions->selectedItems()[0];
1906 
1907         KILE_DEBUG_MAIN << "\tdelete option: " << cur->text(0) << " (" << cur->text(1) << ")";
1908         m_lvClassOptions->takeTopLevelItem(m_lvClassOptions->indexOfTopLevelItem(cur));
1909 
1910         // update dictionary
1911         updateClassOptions();
1912     }
1913 }
1914 
1915 void QuickDocument::slotOptionDoubleClicked(QTreeWidgetItem *item, int column)
1916 {
1917     Q_UNUSED(column);
1918 
1919     item->setCheckState(0, item->checkState(0) == Qt::Checked ? Qt::Unchecked : Qt::Checked);
1920 }
1921 
1922 ////////////////////////////// slots: packages //////////////////////////////
1923 
1924 void QuickDocument::slotPackageAdd()
1925 {
1926     KILE_DEBUG_MAIN << "==QuickDocument::slotPackageAdd()============";
1927     QStringList list;
1928     list << i18n("Add Package")
1929          << "label,edit,label,edit,checkbox"
1930          << i18n("&Package:")
1931          << QString()                        // 3
1932          << i18n("&Description:")
1933          << QString()                        // 5
1934          << i18n("&Select this package")         // 6
1935          ;
1936 
1937     if (inputDialog(list, qd_CheckNotEmpty | qd_CheckPackage)) {
1938         KILE_DEBUG_MAIN << "\tadd package: " << list[3] << " (" << list[5] << ") checked=" << list[6];
1939         QTreeWidgetItem *cli = new QTreeWidgetItem(m_lvPackages, QStringList() << list[3] << "" << list[5]);
1940         cli->setFlags(cli->flags() | Qt::ItemIsUserCheckable);
1941         cli->setCheckState(0, list[6] == "true" ? Qt::Checked : Qt::Unchecked);
1942     }
1943 }
1944 
1945 void QuickDocument::slotPackageAddOption()
1946 {
1947     if (m_lvPackages->selectedItems().count() == 0)
1948         return;
1949 
1950     QTreeWidgetItem *cur = m_lvPackages->selectedItems()[0];
1951 
1952     KILE_DEBUG_MAIN << "==QuickDocument::packageAddOption()============";
1953     QStringList list;
1954     list << i18n("Add Option")
1955          << "label,edit,checkbox,label,edit,label,edit,label,edit,checkbox"
1956          << i18n("&Option:") + " (" + i18n("package:") + ' ' + cur->text(0) + ')'
1957          << QString()                   // 3
1958          << i18n("&Editable")               // 4
1959          << i18n("De&fault value:")
1960          << QString()                   // 6
1961          << i18n("&Value:")
1962          << QString()                   // 8
1963          << i18n("&Description:")
1964          << QString()                   // 10
1965          << i18n("&Select this option")     // 11
1966          ;
1967 
1968     if (!cur->parent() && inputDialog(list, qd_CheckNotEmpty | qd_CheckPackageOption)) {
1969         KILE_DEBUG_MAIN << "\tadd option: " << list[3] << " (" << list[10] << ") checked=" << list[11];
1970 
1971         QTreeWidgetItem *cli;
1972         if (list[4] == "true") {
1973             cli = insertEditableTreeWidget(cur, list[3], list[10], list[8], list[6]);
1974         } else {
1975             cli = new QTreeWidgetItem(cur, QStringList() << list[3] << "" << list[10]);
1976             cli->setFlags(cli->flags() | Qt::ItemIsUserCheckable);
1977             cli->setCheckState(0, Qt::Unchecked);
1978         }
1979         if (list[11] == "true")
1980             cli->setCheckState(0, Qt::Checked);
1981         cur->setExpanded(true);
1982     }
1983 
1984 }
1985 
1986 void QuickDocument::slotPackageEdit()
1987 {
1988     if (m_lvPackages->selectedItems().count() == 0)
1989         return;
1990 
1991     QTreeWidgetItem *cur = m_lvPackages->selectedItems()[0];
1992 
1993     KILE_DEBUG_MAIN << "==QuickDocument::slotPackageEdit()============";
1994     bool editableOption;
1995     QString caption, labelText, optionname;
1996 
1997     if (cur->parent()) {
1998 //  checkmode = qd_CheckPackageOption;
1999         caption = i18n("Edit Option");
2000         labelText = i18n("Op&tion:")  + " (" + i18n("package:") + ' ' + cur->parent()->text(0) + ')';
2001         optionname = cur->parent()->text(0) + '!' + cur->text(0);
2002         editableOption = m_dictPackagesEditable.contains(optionname);
2003     } else {
2004 //  checkmode = qd_CheckPackage;
2005         caption = i18n("Edit Package");
2006         labelText = i18n("&Package:");
2007         optionname.clear();
2008         editableOption = false;
2009     }
2010 
2011     // create one of three different dialogs; edit package, edit editable option, edit option
2012     QStringList list;
2013     list << caption;
2014     if (editableOption) {
2015         QString defaultvalue = (m_dictPackagesDefaultvalues.contains(optionname))
2016                                ? m_dictPackagesDefaultvalues[optionname]
2017                                : QString();
2018         QString value = (cur->text(1) == i18n("<default>"))
2019                         ? defaultvalue : getPackagesValue(cur->text(1));
2020 
2021         list << "label,edit-r,label,edit-r,label,edit,label,edit"
2022              << labelText
2023              << cur->text(0)                           // 3
2024              << i18n("De&fault value:")
2025              << defaultvalue                           // 5
2026              << i18n("&Value:")
2027              << value                                  // 7
2028              << i18n("&Description:")
2029              << stripPackageDefault(optionname, cur->text(2))     // 9
2030              ;
2031     } else {
2032         list << "label,edit-r,label,edit"
2033              << labelText
2034              << cur->text(0)                           // 3
2035              << i18n("&Description:")
2036              << cur->text(2)                           // 5
2037              ;
2038     }
2039 
2040     if (inputDialog(list)) {
2041         if (editableOption) {
2042             KILE_DEBUG_MAIN << "\tedit package: "
2043                             << list[3]
2044                             << " (" << list[7] << ") "
2045                             << " (" << list[9] << ")";
2046             cur->setText(0, list[3]);
2047             setPackagesValue(cur, optionname, list[7]);
2048             cur->setText(2, addPackageDefault(optionname, list[9]));
2049         } else {
2050             KILE_DEBUG_MAIN << "\tedit package: " << list[3] << " (" << list[5] << ")";
2051             cur->setText(0, list[3]);
2052             cur->setText(2, list[5]);
2053         }
2054     }
2055 }
2056 
2057 void QuickDocument::slotPackageDelete()
2058 {
2059     if (m_lvPackages->selectedItems().count() == 0)
2060         return;
2061 
2062 
2063     QTreeWidgetItem *cur = m_lvPackages->selectedItems()[0];
2064 
2065     bool packageoption;
2066     QString message, optionname;
2067     if (cur->parent()) {
2068         packageoption = true;
2069         message = i18n("Do you want to delete this package option?");
2070         optionname = cur->parent()->text(0) + '!' + cur->text(0);
2071     } else {
2072         packageoption = false;
2073         message = i18n("Do you want to delete this package?");
2074         optionname = cur->text(0);
2075     }
2076 
2077     if (KMessageBox::warningContinueCancel(this, message, i18n("Delete")) == KMessageBox::Continue) {
2078         while (cur->childCount() > 0) {
2079             cur->takeChild(0);
2080         }
2081         m_lvPackages->takeTopLevelItem(m_lvPackages->indexOfTopLevelItem(cur));
2082 
2083         // also delete entries for editable package option
2084         if (packageoption && m_dictPackagesEditable.contains(optionname)) {
2085             m_dictPackagesEditable.remove(optionname);
2086             if (m_dictPackagesDefaultvalues.contains(optionname))
2087                 m_dictPackagesDefaultvalues.remove(optionname);
2088         }
2089     }
2090 }
2091 
2092 void QuickDocument::slotPackageReset()
2093 {
2094     if (KMessageBox::warningContinueCancel(this, i18n("Do you want to reset this package list?"), i18n("Reset Package List")) == KMessageBox::Continue)
2095     {
2096         KILE_DEBUG_MAIN << "\treset packages";
2097 
2098         initPackages();
2099         slotEnableButtons();
2100     }
2101 }
2102 
2103 void QuickDocument::slotCheckParent(QTreeWidgetItem *item)
2104 {
2105     if (item && item->checkState(0) == Qt::Checked && item->parent()) {
2106         item->parent()->setCheckState(0, Qt::Checked);
2107     }
2108 }
2109 
2110 void QuickDocument::slotPackageDoubleClicked(QTreeWidgetItem *item)
2111 {
2112     if (item && item->parent()) {
2113         QString option = item->parent()->text(0) + '!' + item->text(0);
2114         if (m_dictPackagesEditable.contains(option))
2115             slotPackageEdit();
2116     }
2117 }
2118 
2119 ////////////////////////////// button states //////////////////////////////
2120 
2121 void QuickDocument::slotEnableButtons()
2122 {
2123     bool enable;
2124 
2125     enable = (! isStandardClass(m_currentClass));
2126 
2127     // add/delete button
2128     m_btnDocumentClassDelete->setEnabled(enable);
2129     m_btnTypefaceSizeAdd->setEnabled(enable);
2130     m_btnTypefaceSizeDelete->setEnabled(enable && m_cbTypefaceSize->count() > 0);
2131     m_btnPaperSizeAdd->setEnabled(enable);
2132     m_btnPaperSizeDelete->setEnabled(enable && m_cbPaperSize->count() > 0);
2133 
2134     // class options
2135     m_btnClassOptionsAdd->setEnabled(enable);
2136     enable = (enable && (m_lvClassOptions->selectedItems().count() != 0));
2137     m_btnClassOptionsEdit->setEnabled(enable);
2138     m_btnClassOptionsDelete->setEnabled(enable);
2139 
2140     // packeges
2141     if (m_lvPackages->selectedItems().count() > 0 && m_lvPackages->selectedItems()[0]->text(0) != "hyperref") {
2142         m_btnPackagesEdit->setEnabled(true);
2143         m_btnPackagesDelete->setEnabled(true);
2144         if (m_lvPackages->selectedItems()[0]->parent())
2145             m_btnPackagesAddOption->setEnabled(false);
2146         else
2147             m_btnPackagesAddOption->setEnabled(true);
2148     } else {
2149         m_btnPackagesEdit->setEnabled(false);
2150         m_btnPackagesDelete->setEnabled(false);
2151         m_btnPackagesAddOption->setEnabled(false);
2152     }
2153 
2154 }
2155 
2156 ////////////////////////////// input dialog //////////////////////////////
2157 
2158 // A variable input dialog, whose widgets are determind by the entries of a stringlist.
2159 // Entry 1 is always the label for the main lineedit, entry 2 the main lineedit. All
2160 // other objects are optionale and their return values are not checked.
2161 //  0 :   caption    (input:  always)
2162 //  1 :   comma separated list of Qt widgets (label,checkbox,edit,edit-r)
2163 //  2ff : strings for Qt widgets
2164 
2165 bool QuickDocument::inputDialog(QStringList &list, int check)
2166 {
2167     QuickDocumentInputDialog *dialog = new QuickDocumentInputDialog(list, check, this, "inputDialog");
2168 
2169     bool result = false;
2170     if (dialog->exec()) {
2171         dialog->getResults(list);
2172         result = true;
2173     }
2174 
2175     delete dialog;
2176     return result;
2177 
2178 }
2179 
2180 QuickDocumentInputDialog::QuickDocumentInputDialog(const QStringList &list, int check,
2181         QuickDocument *parent, const char *name)
2182     : QDialog(parent)
2183     , m_parent(parent)
2184     , m_check(check)
2185 {
2186     setObjectName(name);
2187     setWindowTitle(list[0]);
2188     setModal(true);
2189     QVBoxLayout *mainLayout = new QVBoxLayout;
2190     setLayout(mainLayout);
2191 
2192     QWidget *page = new QWidget(this);
2193     mainLayout->addWidget(page);
2194     QVBoxLayout *vl = new QVBoxLayout();
2195     page->setLayout(vl);
2196 
2197     int firstlinedit = -1;
2198     m_description = list[1].split(',');
2199     for (int i = 0; i < m_description.count(); ++i) {
2200         // create the object
2201         if (m_description[i] == "label") {
2202             m_objectlist.append(new QLabel(list[i+2], page));
2203         }
2204         else if (m_description[i] == "checkbox") {
2205             m_objectlist.append(new QCheckBox(list[i+2], page));
2206         }
2207         else if (m_description[i] == "combobox") {
2208             KComboBox *combobox = new KComboBox(page);
2209             mainLayout->addWidget(combobox);
2210             combobox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
2211             combobox->setDuplicatesEnabled(false);
2212             combobox->addItems(list[i+2].split(',', Qt::KeepEmptyParts));
2213             if (i > 0 && m_description[i-1] == "label") {
2214                 static_cast<QLabel*>(m_objectlist[i-1])->setBuddy(combobox);
2215             }
2216             m_objectlist.append(combobox);
2217         }
2218         else {
2219             m_objectlist.append(new QLineEdit(list[i+2], page));
2220             if (m_description[i] == "edit-r") {
2221                 static_cast<QLineEdit*>(m_objectlist[i])->setReadOnly(true);
2222             }
2223             else if (firstlinedit == -1) {
2224                 firstlinedit = i;
2225             }
2226             if (i > 0 && m_description[i-1] == "label") {
2227                 static_cast<QLabel*>(m_objectlist[i-1])->setBuddy(m_objectlist[i]);
2228             }
2229         }
2230 
2231         // insert the new object into the layout
2232         vl->addWidget(m_objectlist[i]);
2233     }
2234 
2235     if (firstlinedit != -1) {
2236         m_objectlist[firstlinedit]->setFocus();
2237     }
2238     vl->addStretch(1);
2239 
2240     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
2241     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
2242     okButton->setDefault(true);
2243     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
2244     connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
2245     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
2246     connect(this, &QDialog::accepted, this, &QuickDocumentInputDialog::slotAccepted);
2247     mainLayout->addWidget(buttonBox);
2248 
2249     page->setMinimumWidth(350);
2250 }
2251 
2252 QuickDocumentInputDialog::~QuickDocumentInputDialog()
2253 {}
2254 
2255 void QuickDocumentInputDialog::getResults(QStringList &list)
2256 {
2257     for (int i = 0; i < m_description.count(); ++i) {
2258         if (m_description[i] == "label") {
2259             list[i+2] = static_cast<QLabel*>(m_objectlist[i])->text();
2260         }
2261         else if (m_description[i] == "checkbox") {
2262             list[i+2] = static_cast<QCheckBox*>(m_objectlist[i])->isChecked() ? "true" : "false";
2263         }
2264         else if (m_description[i] == "combobox") {
2265             list[i+2] = static_cast<KComboBox*>(m_objectlist[i])->currentText();
2266         }
2267         else  {
2268             list[i+2] = static_cast<QLineEdit*>(m_objectlist[i])->text().simplified();
2269         }
2270     }
2271 }
2272 
2273 // get the package name from string 'Option: (package: name)'
2274 QString QuickDocumentInputDialog::getPackageName(const QString &text)
2275 {
2276     QRegExp reg(i18n("package:") + " ([^\\)]+)");
2277     return (reg.indexIn(text) >= 0) ? reg.cap(1) : QString();
2278 }
2279 
2280 bool QuickDocumentInputDialog::checkListEntries(const QString &title, const QString &textlist,
2281         const QString &pattern)
2282 {
2283     // split entries (one or a comma separated list)
2284     QStringList list = textlist.split(',');
2285 
2286     for (int i = 0; i < list.count(); ++i) {
2287         QString s = list[i].trimmed();
2288         // entries must match a regular expression
2289         QRegExp reg(pattern);
2290         if (!reg.exactMatch(s)) {
2291             KMessageBox::error(this, i18n("%1 '%2' is not allowed.", title, s));
2292             return false;
2293         }
2294     }
2295     return true;
2296 }
2297 
2298 // check the main result of the input dialog
2299 void QuickDocumentInputDialog::slotAccepted()
2300 {
2301     if (m_check) {
2302         // get the label and main input string from the first label/linedit
2303         QString inputlabel = static_cast<QLabel*>(m_objectlist[0])->text();
2304         QString input = static_cast<QLineEdit*>(m_objectlist[1])->text().simplified();
2305 
2306         // should we check for an empty string
2307         if ((m_check & qd_CheckNotEmpty) && input.isEmpty()) {
2308             KMessageBox::error(this, i18n("An empty string is not allowed."));
2309             return;
2310         }
2311 
2312         // should we check for an existing document class
2313         if (m_check & qd_CheckDocumentClass) {
2314             if (m_parent->isDocumentClass(input)) {
2315                 KMessageBox::error(this, i18n("This document class already exists."));
2316                 return;
2317             }
2318 
2319             QRegExp reg("\\w+");
2320             if (!reg.exactMatch(input)) {
2321                 KMessageBox::error(this, i18n("This name is not allowed for a document class."));
2322                 return;
2323             }
2324         }
2325 
2326         // should we check for an existing document class option
2327         if ((m_check & qd_CheckClassOption) && m_parent->isDocumentClassOption(input)) {
2328             KMessageBox::error(this, i18n("This document class option already exists."));
2329             return;
2330         }
2331 
2332         // should we check for an existing package
2333         if ((m_check & qd_CheckPackage) && m_parent->isPackage(input)) {
2334             KMessageBox::error(this, i18n("This package already exists."));
2335             return;
2336         }
2337 
2338         // should we check for an existing package option
2339         if (m_check & qd_CheckPackageOption) {
2340             QString package = getPackageName(inputlabel);
2341             if (package.isEmpty()) {
2342                 KMessageBox::error(this, i18n("Could not identify the package name."));
2343                 return;
2344             }
2345             if (m_parent->isPackageOption(package, input)) {
2346                 KMessageBox::error(this, i18n("This package option already exists."));
2347                 return;
2348             }
2349         }
2350 
2351         // should we check for a (list of) fontsizes
2352         if ((m_check & qd_CheckFontsize) && !checkListEntries("Fontsize", input, "\\d+pt")) {
2353             return;
2354         }
2355 
2356         // should we check for a (list of) papersizes
2357         if ((m_check & qd_CheckPapersize) && !checkListEntries("Papersize", input, "\\w+")) {
2358             return;
2359         }
2360     }
2361 
2362 }
2363 
2364 } // namespace
2365