File indexing completed on 2024-05-19 09:38:21

0001 // clang-format off
0002 /*
0003  * KDiff3 - Text Diff And Merge Tool
0004  *
0005  * SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachim.eibl at gmx.de
0006  * SPDX-FileCopyrightText: 2018-2020 Michael Reeves reeves.87@gmail.com
0007  * SPDX-License-Identifier: GPL-2.0-or-later
0008  */
0009 // clang-format on
0010 #include "optiondialog.h"
0011 #include "OptionItems.h"
0012 #include "ui_FontChooser.h"
0013 #include "ui_scroller.h"
0014 
0015 #include "common.h"
0016 #include "defmac.h"
0017 #include "smalldialogs.h"
0018 #include "TypeUtils.h"
0019 
0020 #include <map>
0021 
0022 #include <KColorButton>
0023 #include <KHelpClient>
0024 #include <KLocalizedString>
0025 #include <KMessageBox>
0026 
0027 #include <QApplication>
0028 #include <QCheckBox>
0029 #include <QComboBox>
0030 #include <QDialogButtonBox>
0031 #include <QFontDatabase>
0032 #include <QFontDialog>
0033 #include <QFrame>
0034 #include <QGridLayout>
0035 #include <QGroupBox>
0036 #include <QLabel>
0037 #include <QLayout>
0038 #include <QLineEdit>
0039 #include <QPixmap>
0040 #include <QPlainTextEdit>
0041 #include <QPointer>
0042 #include <QPushButton>
0043 #include <QRadioButton>
0044 #include <QScrollArea>
0045 #include <QTextCodec>
0046 
0047 extern std::unique_ptr<Options> gOptions;
0048 
0049 class OptionCheckBox: public QCheckBox, public OptionBool
0050 {
0051   public:
0052     OptionCheckBox(const QString& text, bool bDefaultVal, const QString& saveName, bool* pbVar,
0053                    QWidget* pParent):
0054         QCheckBox(text, pParent),
0055         OptionBool(pbVar, bDefaultVal, saveName)
0056     {
0057     }
0058     void setToDefault() override { setChecked(getDefault()); }
0059     void setToCurrent() override { setChecked(getCurrent()); }
0060 
0061     using OptionBool::apply;
0062     void apply() override { apply(isChecked()); }
0063 
0064   private:
0065     Q_DISABLE_COPY(OptionCheckBox)
0066 };
0067 
0068 class OptionRadioButton: public QRadioButton, public OptionBool
0069 {
0070   public:
0071     OptionRadioButton(const QString& text, bool bDefaultVal, const QString& saveName, bool* pbVar,
0072                       QWidget* pParent):
0073         QRadioButton(text, pParent),
0074         OptionBool(pbVar, bDefaultVal, saveName)
0075     {
0076     }
0077 
0078     void setToDefault() override { setChecked(getDefault()); }
0079     void setToCurrent() override { setChecked(getCurrent()); }
0080 
0081     using OptionBool::apply;
0082     void apply() override { apply(isChecked()); }
0083 
0084   private:
0085     Q_DISABLE_COPY(OptionRadioButton)
0086 };
0087 
0088 FontChooser::FontChooser(QWidget* pParent):
0089     QGroupBox(pParent)
0090 {
0091     fontChooserUi.setupUi(this);
0092     fontChooserUi.exampleTextEdit->setFont(m_font);
0093     chk_connect_a(fontChooserUi.selectFont, &QPushButton::clicked, this, &FontChooser::slotSelectFont);
0094 }
0095 
0096 QFont FontChooser::font()
0097 {
0098     return m_font;
0099 }
0100 
0101 void FontChooser::setFont(const QFont& font, bool)
0102 {
0103     m_font = font;
0104     fontChooserUi.exampleTextEdit->setFont(m_font);
0105     QString style = m_font.styleName();
0106     if(style.isEmpty())
0107         style = i18nc("No text styling", "none");
0108 
0109     fontChooserUi.label->setText(i18nc("Font sample display, %1 = family, %2 = style, %3 = size", "Font: %1, %2, %3\n\nExample:", m_font.family(), style, m_font.pointSize()));
0110 }
0111 
0112 void FontChooser::slotSelectFont()
0113 {
0114     bool bOk;
0115     m_font = QFontDialog::getFont(&bOk, m_font);
0116     fontChooserUi.exampleTextEdit->setFont(m_font);
0117     QString style = m_font.styleName();
0118     if(style.isEmpty())
0119         style = i18nc("No text styling", "none");
0120 
0121     fontChooserUi.label->setText(i18nc("Font sample display, %1 = family, %2 = style, %3 = size", "Font: %1, %2, %3\n\nExample:", m_font.family(), style, m_font.pointSize()));
0122 }
0123 
0124 class OptionFontChooser: public FontChooser, public OptionFont
0125 {
0126   public:
0127     OptionFontChooser(const QFont& defaultVal, const QString& saveName, QFont* pVar, QWidget* pParent):
0128         FontChooser(pParent),
0129         OptionFont(pVar, defaultVal, saveName)
0130     {
0131     }
0132 
0133     void setToDefault() override { setFont(getDefault(), false); }
0134     void setToCurrent() override { setFont(getCurrent(), false); }
0135     using OptionFont::apply;
0136     void apply() override { apply(font()); }
0137 
0138   private:
0139     Q_DISABLE_COPY(OptionFontChooser)
0140 };
0141 
0142 class OptionColorButton: public KColorButton, public OptionColor
0143 {
0144   public:
0145     OptionColorButton(const QColor& defaultVal, const QString& saveName, QColor* pVar, QWidget* pParent):
0146         KColorButton(pParent), OptionColor(pVar, defaultVal, saveName)
0147     {
0148     }
0149 
0150     void setToDefault() override { setColor(getDefault()); }
0151     void setToCurrent() override { setColor(getCurrent()); }
0152     using OptionColor::apply;
0153     void apply() override { apply(color()); }
0154 
0155   private:
0156     Q_DISABLE_COPY(OptionColorButton)
0157 };
0158 
0159 class OptionLineEdit: public QComboBox, public OptionString
0160 {
0161   public:
0162     OptionLineEdit(const QString& defaultVal, const QString& saveName, QString* pVar,
0163                    QWidget* pParent):
0164         QComboBox(pParent),
0165         OptionString(pVar, defaultVal, saveName)
0166     {
0167         setMinimumWidth(50);
0168         setEditable(true);
0169         m_list.push_back(defaultVal);
0170         insertText();
0171     }
0172 
0173     void setToDefault() override
0174     {
0175         setEditText(getDefault());
0176     }
0177 
0178     void setToCurrent() override
0179     {
0180         setEditText(getCurrent());
0181     }
0182 
0183     using OptionString::apply;
0184     void apply() override
0185     {
0186         apply(currentText());
0187         insertText();
0188     }
0189 
0190     void write(ValueMap* config) const override
0191     {
0192         config->writeEntry(m_saveName, m_list);
0193     }
0194 
0195     void read(ValueMap* config) override
0196     {
0197         m_list = config->readEntry(m_saveName, QStringList(m_defaultVal));
0198         if(!m_list.empty()) setCurrent(m_list.front());
0199         clear();
0200         insertItems(0, m_list);
0201     }
0202 
0203   private:
0204     void insertText()
0205     { // Check if the text exists. If yes remove it and push it in as first element
0206         QString current = currentText();
0207         m_list.removeAll(current);
0208         m_list.push_front(current);
0209         clear();
0210         if(m_list.size() > 10)
0211             m_list.erase(m_list.begin() + 10, m_list.end());
0212         insertItems(0, m_list);
0213     }
0214 
0215     Q_DISABLE_COPY(OptionLineEdit)
0216     QStringList m_list;
0217 };
0218 
0219 class OptionIntEdit: public QLineEdit, public OptionNum<qint32>
0220 {
0221   public:
0222     OptionIntEdit(qint32 defaultVal, const QString& saveName, qint32* pVar, qint32 rangeMin, qint32 rangeMax,
0223                   QWidget* pParent):
0224         QLineEdit(pParent),
0225         OptionNum<qint32>(pVar, defaultVal, saveName)
0226     {
0227         QIntValidator* v = new QIntValidator(this);
0228         v->setRange(rangeMin, rangeMax);
0229         setValidator(v);
0230     }
0231 
0232     void setToDefault() override
0233     {
0234         //QString::setNum does not account for locale settings
0235         setText(OptionNum::toString(getDefault()));
0236     }
0237 
0238     void setToCurrent() override
0239     {
0240         setText(getString());
0241     }
0242 
0243     using OptionNum<qint32>::apply;
0244     void apply() override
0245     {
0246         const QIntValidator* v = static_cast<const QIntValidator*>(validator());
0247         setCurrent(qBound(v->bottom(), text().toInt(), v->top()));
0248 
0249         setText(getString());
0250     }
0251 
0252   private:
0253     Q_DISABLE_COPY(OptionIntEdit)
0254 };
0255 
0256 class OptionComboBox: public QComboBox, public OptionItemBase
0257 {
0258   public:
0259     OptionComboBox(qint32 defaultVal, const QString& saveName, qint32* pVarNum,
0260                    QWidget* pParent):
0261         QComboBox(pParent),
0262         OptionItemBase(saveName)
0263     {
0264         setMinimumWidth(50);
0265         m_pVarNum = pVarNum;
0266         m_pVarStr = nullptr;
0267         m_defaultVal = defaultVal;
0268         setEditable(false);
0269     }
0270 
0271     OptionComboBox(qint32 defaultVal, const QString& saveName, QString* pVarStr,
0272                    QWidget* pParent):
0273         QComboBox(pParent),
0274         OptionItemBase(saveName)
0275     {
0276         m_pVarNum = nullptr;
0277         m_pVarStr = pVarStr;
0278         m_defaultVal = defaultVal;
0279         setEditable(false);
0280     }
0281 
0282     void setToDefault() override
0283     {
0284         setCurrentIndex(m_defaultVal);
0285         if(m_pVarStr != nullptr)
0286         {
0287             *m_pVarStr = currentText();
0288         }
0289     }
0290 
0291     void setToCurrent() override
0292     {
0293         if(m_pVarNum != nullptr)
0294             setCurrentIndex(*m_pVarNum);
0295         else
0296             setText(*m_pVarStr);
0297     }
0298 
0299     using OptionItemBase::apply;
0300     void apply() override
0301     {
0302         if(m_pVarNum != nullptr)
0303         {
0304             *m_pVarNum = currentIndex();
0305         }
0306         else
0307         {
0308             *m_pVarStr = currentText();
0309         }
0310     }
0311 
0312     void write(ValueMap* config) const override
0313     {
0314         if(m_pVarStr != nullptr)
0315             config->writeEntry(m_saveName, *m_pVarStr);
0316         else
0317             config->writeEntry(m_saveName, *m_pVarNum);
0318     }
0319 
0320     void read(ValueMap* config) override
0321     {
0322         if(m_pVarStr != nullptr)
0323             setText(config->readEntry(m_saveName, currentText()));
0324         else
0325             *m_pVarNum = config->readEntry(m_saveName, *m_pVarNum);
0326     }
0327 
0328     void preserveImp() override
0329     {
0330         if(m_pVarStr != nullptr)
0331         {
0332             m_preservedStrVal = *m_pVarStr;
0333         }
0334         else
0335         {
0336             m_preservedNumVal = *m_pVarNum;
0337         }
0338     }
0339 
0340     void unpreserveImp() override
0341     {
0342         if(m_pVarStr != nullptr)
0343         {
0344             *m_pVarStr = m_preservedStrVal;
0345         }
0346         else
0347         {
0348             *m_pVarNum = m_preservedNumVal;
0349         }
0350     }
0351 
0352   private:
0353     Q_DISABLE_COPY(OptionComboBox)
0354     qint32* m_pVarNum;
0355     qint32 m_preservedNumVal = 0;
0356     QString* m_pVarStr;
0357     QString m_preservedStrVal;
0358     qint32 m_defaultVal;
0359 
0360     void setText(const QString& s)
0361     {
0362         // Find the string in the combobox-list, don't change the value if nothing fits.
0363         for(qint32 i = 0; i < count(); ++i)
0364         {
0365             if(itemText(i) == s)
0366             {
0367                 if(m_pVarNum != nullptr) *m_pVarNum = i;
0368                 if(m_pVarStr != nullptr) *m_pVarStr = s;
0369                 setCurrentIndex(i);
0370                 return;
0371             }
0372         }
0373     }
0374 };
0375 
0376 class OptionEncodingComboBox: public QComboBox, public OptionCodec
0377 {
0378     Q_OBJECT
0379     QVector<QByteArray> m_codecVec;
0380     QByteArray* mVarCodec;
0381 
0382   public:
0383     OptionEncodingComboBox(const QString& saveName, QByteArray* inVarCodec,
0384                            QWidget* pParent):
0385         QComboBox(pParent),
0386         OptionCodec(saveName)
0387     {
0388         mVarCodec = inVarCodec;
0389         insertCodec(i18n("Unicode, 8 bit"), "UTF-8");
0390         insertCodec(i18n("Unicode"), "iso-10646-UCS-2");
0391         insertCodec(i18n("Latin1"), "iso 8859-1");
0392 
0393         const QList<qint32> mibs = QTextCodec::availableMibs();
0394         QList<QByteArray> names;
0395         for(const qint32 mib: mibs)
0396         {
0397             names.append(QTextCodec::codecForMib(mib)->name());
0398         }
0399 
0400         for(const QByteArray& name: names)
0401         {
0402             insertCodec("", name);
0403         }
0404 
0405         setToolTip(i18nc("Tool Tip",
0406             "Change this if non-ASCII characters are not displayed correctly."));
0407     }
0408 
0409     void insertCodec(const QString& visibleCodecName, const QByteArray& name)
0410     {
0411         const QLatin1String codecName = QLatin1String(name);
0412 
0413         for(QtSizeType i = 0; i < m_codecVec.size(); ++i)
0414         {
0415             if(name == m_codecVec[i])
0416                 return; // don't insert any codec twice
0417         }
0418         // The m_codecVec.size will at this point return the value we need for the index.
0419         if(codecName == defaultName())
0420             saveDefaultIndex(m_codecVec.size());
0421         QString itemText = visibleCodecName.isEmpty() ? codecName : visibleCodecName + u8" (" + codecName + u8")";
0422         addItem(itemText, m_codecVec.size());
0423         m_codecVec.push_back(name);
0424     }
0425 
0426     void setToDefault() override
0427     {
0428         qint32 index = getDefaultIndex();
0429 
0430         setCurrentIndex(index);
0431         if(mVarCodec != nullptr)
0432         {
0433             *mVarCodec = m_codecVec[index];
0434         }
0435     }
0436 
0437     void setToCurrent() override
0438     {
0439         if(mVarCodec != nullptr)
0440         {
0441             for(qint32 i = 0; i < m_codecVec.size(); ++i)
0442             {
0443                 if(*mVarCodec == m_codecVec[i])
0444                 {
0445                     setCurrentIndex(i);
0446                     break;
0447                 }
0448             }
0449         }
0450     }
0451 
0452     using OptionCodec::apply;
0453     void apply() override
0454     {
0455         if(mVarCodec != nullptr)
0456         {
0457             *mVarCodec = m_codecVec[currentIndex()];
0458         }
0459     }
0460 
0461     void write(ValueMap* config) const override
0462     {
0463         if(mVarCodec != nullptr) config->writeEntry(m_saveName, (const char*)(*mVarCodec));
0464     }
0465 
0466     void read(ValueMap* config) override
0467     {
0468         QString codecName = config->readEntry(m_saveName, (const char*)m_codecVec[currentIndex()]);
0469         for(qint32 i = 0; i < m_codecVec.size(); ++i)
0470         {
0471             if(codecName == QLatin1String(m_codecVec[i]))
0472             {
0473                 setCurrentIndex(i);
0474                 if(mVarCodec != nullptr) *mVarCodec = m_codecVec[i];
0475                 break;
0476             }
0477         }
0478     }
0479 
0480   protected:
0481     void preserveImp() override { m_preservedVal = currentIndex(); }
0482     void unpreserveImp() override { setCurrentIndex(m_preservedVal); }
0483     qint32 m_preservedVal;
0484 };
0485 
0486 OptionDialog::OptionDialog(bool bShowDirMergeSettings, QWidget* parent):
0487     KPageDialog(parent)
0488 {
0489     setFaceType(List);
0490     setWindowTitle(i18n("Configure"));
0491     setStandardButtons(QDialogButtonBox::Help | QDialogButtonBox::RestoreDefaults | QDialogButtonBox::Apply | QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0492 
0493     setModal(true);
0494     setMinimumSize(600, 500);
0495 
0496     gOptions->init();
0497     setupFontPage();
0498     setupColorPage();
0499     setupEditPage();
0500     setupDiffPage();
0501     setupMergePage();
0502 
0503     if(bShowDirMergeSettings)
0504         setupDirectoryMergePage();
0505 
0506     setupRegionalPage();
0507     setupIntegrationPage();
0508 
0509     // Initialize all values in the dialog
0510     resetToDefaults();
0511     slotApply();
0512     chk_connect_a(button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &OptionDialog::slotApply);
0513     chk_connect_a(button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &OptionDialog::slotOk);
0514     chk_connect_a(button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, this, &OptionDialog::slotDefault);
0515     chk_connect_a(button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &QDialog::reject);
0516     chk_connect_a(button(QDialogButtonBox::Help), &QPushButton::clicked, this, &OptionDialog::helpRequested);
0517 }
0518 
0519 void OptionDialog::helpRequested()
0520 {
0521     KHelpClient::invokeHelp();
0522 }
0523 
0524 OptionDialog::~OptionDialog() = default;
0525 
0526 void OptionDialog::setupFontPage()
0527 {
0528     QFrame* page = new QFrame();
0529     KPageWidgetItem* pageItem = new KPageWidgetItem(page, i18n("Font"));
0530 
0531     pageItem->setHeader(i18n("Editor & Diff Output Font"));
0532     //not all themes have this icon
0533     if(QIcon::hasThemeIcon(QStringLiteral("font-select-symbolic")))
0534         pageItem->setIcon(QIcon::fromTheme(QStringLiteral("font-select-symbolic")));
0535     else
0536         pageItem->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-font")));
0537     addPage(pageItem);
0538 
0539     QVBoxLayout* topLayout = new QVBoxLayout(page);
0540     topLayout->setContentsMargins(5, 5, 5, 5);
0541 
0542     //requires QT 5.2 or later.
0543     static const QFont defaultFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
0544     static QFont defaultAppFont = QApplication::font();
0545 
0546     OptionFontChooser* pAppFontChooser = new OptionFontChooser(defaultAppFont, "ApplicationFont", &gOptions->mAppFont, page);
0547 
0548     topLayout->addWidget(pAppFontChooser);
0549     pAppFontChooser->setTitle(i18n("Application font"));
0550 
0551     OptionFontChooser* pFontChooser = new OptionFontChooser(defaultFont, "Font", &gOptions->mFont, page);
0552 
0553     topLayout->addWidget(pFontChooser);
0554     pFontChooser->setTitle(i18n("File view font"));
0555 
0556     //QGridLayout* gbox = new QGridLayout();
0557     //topLayout->addLayout(gbox);
0558     //qint32 line=0;
0559 
0560     // This currently does not work (see rendering in class DiffTextWindow)
0561     //OptionCheckBox* pItalicDeltas = new OptionCheckBox( i18n("Italic font for deltas"), false, "ItalicForDeltas", &m_options->m_bItalicForDeltas, page, this );
0562 
0563     //gbox->addWidget( pItalicDeltas, line, 0, 1, 2 );
0564     //pItalicDeltas->setToolTip( i18n(
0565     //   "Selects the italic version of the font for differences.\n"
0566     //   "If the font doesn't support italic characters, then this does nothing.")
0567     //   );
0568 }
0569 
0570 void OptionDialog::setupColorPage()
0571 {
0572     QScrollArea* pageFrame = new QScrollArea();
0573     KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18nc("Title for color settings page", "Color"));
0574     pageItem->setHeader(i18n("Colors Settings"));
0575     pageItem->setIcon(QIcon::fromTheme(QStringLiteral("colormanagement")));
0576     addPage(pageItem);
0577 
0578     QVBoxLayout* scrollLayout = new QVBoxLayout();
0579     scrollLayout->setContentsMargins(2, 2, 2, 2);
0580     scrollLayout->addWidget(pageFrame);
0581 
0582     std::unique_ptr<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
0583     scrollArea->setupUi(pageFrame);
0584 
0585     QWidget* page = pageFrame->findChild<QWidget*>("contents");
0586     QVBoxLayout* topLayout = new QVBoxLayout(page);
0587     topLayout->setContentsMargins(5, 5, 5, 5);
0588 
0589     QGridLayout* gbox = new QGridLayout();
0590     gbox->setColumnStretch(1, 5);
0591     topLayout->addLayout(gbox);
0592 
0593     QLabel* label;
0594     qint32 line = 0;
0595 
0596     qint32 depth = QPixmap::defaultDepth();
0597     bool bLowColor = depth <= 8;
0598 
0599     label = new QLabel(i18n("Editor and Diff Views:"), page);
0600     gbox->addWidget(label, line, 0);
0601     QFont f(label->font());
0602     f.setBold(true);
0603     label->setFont(f);
0604     ++line;
0605 
0606     OptionColorButton* pFgColor = new OptionColorButton(Qt::black, "FgColor", &gOptions->m_fgColor, page);
0607     label = new QLabel(i18n("Foreground color:"), page);
0608     label->setBuddy(pFgColor);
0609 
0610     gbox->addWidget(label, line, 0);
0611     gbox->addWidget(pFgColor, line, 1);
0612     ++line;
0613 
0614     OptionColorButton* pBgColor = new OptionColorButton(Qt::white, "BgColor", &gOptions->m_bgColor, page);
0615     label = new QLabel(i18n("Background color:"), page);
0616     label->setBuddy(pBgColor);
0617 
0618     gbox->addWidget(label, line, 0);
0619     gbox->addWidget(pBgColor, line, 1);
0620 
0621     ++line;
0622 
0623     OptionColorButton* pDiffBgColor = new OptionColorButton(
0624         bLowColor ? QColor(Qt::lightGray) : qRgb(224, 224, 224), "DiffBgColor", &gOptions->m_diffBgColor, page);
0625     label = new QLabel(i18n("Diff background color:"), page);
0626     label->setBuddy(pDiffBgColor);
0627 
0628     gbox->addWidget(label, line, 0);
0629     gbox->addWidget(pDiffBgColor, line, 1);
0630     ++line;
0631 
0632     OptionColorButton* pColorA = new OptionColorButton(
0633         bLowColor ? qRgb(0, 0, 255) : qRgb(0, 0, 200) /*blue*/, "ColorA", &gOptions->m_colorA, page);
0634     label = new QLabel(i18n("Color A:"), page);
0635     label->setBuddy(pColorA);
0636 
0637     gbox->addWidget(label, line, 0);
0638     gbox->addWidget(pColorA, line, 1);
0639     ++line;
0640 
0641     OptionColorButton* pColorB = new OptionColorButton(
0642         bLowColor ? qRgb(0, 128, 0) : qRgb(0, 150, 0) /*green*/, "ColorB", &gOptions->m_colorB, page);
0643     label = new QLabel(i18n("Color B:"), page);
0644     label->setBuddy(pColorB);
0645 
0646     gbox->addWidget(label, line, 0);
0647     gbox->addWidget(pColorB, line, 1);
0648     ++line;
0649 
0650     OptionColorButton* pColorC = new OptionColorButton(
0651         bLowColor ? qRgb(128, 0, 128) : qRgb(150, 0, 150) /*magenta*/, "ColorC", &gOptions->m_colorC, page);
0652     label = new QLabel(i18n("Color C:"), page);
0653     label->setBuddy(pColorC);
0654 
0655     gbox->addWidget(label, line, 0);
0656     gbox->addWidget(pColorC, line, 1);
0657     ++line;
0658 
0659     OptionColorButton* pColorForConflict = new OptionColorButton(Qt::red, "ColorForConflict", &gOptions->m_colorForConflict, page);
0660     label = new QLabel(i18n("Conflict color:"), page);
0661     label->setBuddy(pColorForConflict);
0662 
0663     gbox->addWidget(label, line, 0);
0664     gbox->addWidget(pColorForConflict, line, 1);
0665     ++line;
0666 
0667     OptionColorButton* pColor = new OptionColorButton(
0668         bLowColor ? qRgb(192, 192, 192) : qRgb(220, 220, 100), "CurrentRangeBgColor", &gOptions->m_currentRangeBgColor, page);
0669     label = new QLabel(i18n("Current range background color:"), page);
0670     label->setBuddy(pColor);
0671 
0672     gbox->addWidget(label, line, 0);
0673     gbox->addWidget(pColor, line, 1);
0674     ++line;
0675 
0676     pColor = new OptionColorButton(
0677         bLowColor ? qRgb(255, 255, 0) : qRgb(255, 255, 150), "CurrentRangeDiffBgColor", &gOptions->m_currentRangeDiffBgColor, page);
0678     label = new QLabel(i18n("Current range diff background color:"), page);
0679     label->setBuddy(pColor);
0680 
0681     gbox->addWidget(label, line, 0);
0682     gbox->addWidget(pColor, line, 1);
0683     ++line;
0684 
0685     pColor = new OptionColorButton(qRgb(0xff, 0xd0, 0x80), "ManualAlignmentRangeColor", &gOptions->m_manualHelpRangeColor, page);
0686     label = new QLabel(i18n("Color for manually aligned difference ranges:"), page);
0687     label->setBuddy(pColor);
0688 
0689     gbox->addWidget(label, line, 0);
0690     gbox->addWidget(pColor, line, 1);
0691     ++line;
0692 
0693     label = new QLabel(i18n("Folder Comparison View:"), page);
0694     gbox->addWidget(label, line, 0);
0695     label->setFont(f);
0696     ++line;
0697 
0698     pColor = new OptionColorButton(qRgb(0, 0xd0, 0), "NewestFileColor", &gOptions->m_newestFileColor, page);
0699     label = new QLabel(i18n("Newest file color:"), page);
0700     label->setBuddy(pColor);
0701 
0702     gbox->addWidget(label, line, 0);
0703     gbox->addWidget(pColor, line, 1);
0704     QString dirColorTip = i18n("Changing this color will only be effective when starting the next folder comparison.");
0705     label->setToolTip(dirColorTip);
0706     ++line;
0707 
0708     pColor = new OptionColorButton(qRgb(0xf0, 0, 0), "OldestFileColor", &gOptions->m_oldestFileColor, page);
0709     label = new QLabel(i18n("Oldest file color:"), page);
0710     label->setBuddy(pColor);
0711 
0712     gbox->addWidget(label, line, 0);
0713     gbox->addWidget(pColor, line, 1);
0714     label->setToolTip(dirColorTip);
0715     ++line;
0716 
0717     pColor = new OptionColorButton(qRgb(0xc0, 0xc0, 0), "MidAgeFileColor", &gOptions->m_midAgeFileColor, page);
0718     label = new QLabel(i18n("Middle age file color:"), page);
0719     label->setBuddy(pColor);
0720 
0721     gbox->addWidget(label, line, 0);
0722     gbox->addWidget(pColor, line, 1);
0723     label->setToolTip(dirColorTip);
0724     ++line;
0725 
0726     pColor = new OptionColorButton(qRgb(0, 0, 0), "MissingFileColor", &gOptions->m_missingFileColor, page);
0727     label = new QLabel(i18n("Color for missing files:"), page);
0728     label->setBuddy(pColor);
0729 
0730     gbox->addWidget(label, line, 0);
0731     gbox->addWidget(pColor, line, 1);
0732     label->setToolTip(dirColorTip);
0733     ++line;
0734 
0735     topLayout->addStretch(10);
0736 }
0737 
0738 void OptionDialog::setupEditPage()
0739 {
0740     QScrollArea* pageFrame = new QScrollArea();
0741     KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18n("Editor"));
0742     pageItem->setHeader(i18n("Editor Behavior"));
0743     pageItem->setIcon(QIcon::fromTheme(QStringLiteral("accessories-text-editor")));
0744     addPage(pageItem);
0745 
0746     QVBoxLayout* scrollLayout = new QVBoxLayout();
0747     scrollLayout->setContentsMargins(2, 2, 2, 2);
0748     scrollLayout->addWidget(pageFrame);
0749 
0750     std::unique_ptr<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
0751     scrollArea->setupUi(pageFrame);
0752 
0753     QWidget* page = pageFrame->findChild<QWidget*>("contents");
0754 
0755     QVBoxLayout* topLayout = new QVBoxLayout(page);
0756     topLayout->setContentsMargins(5, 5, 5, 5);
0757 
0758     QGridLayout* gbox = new QGridLayout();
0759     gbox->setColumnStretch(1, 5);
0760     topLayout->addLayout(gbox);
0761     QLabel* label;
0762     qint32 line = 0;
0763 
0764     OptionCheckBox* pReplaceTabs = new OptionCheckBox(i18n("Tab inserts spaces"), false, "ReplaceTabs", &gOptions->m_bReplaceTabs, page);
0765 
0766     gbox->addWidget(pReplaceTabs, line, 0, 1, 2);
0767     pReplaceTabs->setToolTip(i18nc("Tool Tip",
0768         "On: Pressing tab generates the appropriate number of spaces.\n"
0769         "Off: A tab character will be inserted."));
0770     ++line;
0771 
0772     OptionIntEdit* pTabSize = new OptionIntEdit(8, "TabSize", &gOptions->m_tabSize, 1, 100, page);
0773     label = new QLabel(i18n("Tab size:"), page);
0774     label->setBuddy(pTabSize);
0775 
0776     gbox->addWidget(label, line, 0);
0777     gbox->addWidget(pTabSize, line, 1);
0778     ++line;
0779 
0780     OptionCheckBox* pAutoIndentation = new OptionCheckBox(i18n("Auto indentation"), true, "AutoIndentation", &gOptions->m_bAutoIndentation, page);
0781     gbox->addWidget(pAutoIndentation, line, 0, 1, 2);
0782 
0783     pAutoIndentation->setToolTip(i18nc("Tool Tip",
0784         "On: The indentation of the previous line is used for a new line.\n"));
0785     ++line;
0786 
0787     OptionCheckBox* pAutoCopySelection = new OptionCheckBox(i18n("Auto copy selection"), false, "AutoCopySelection", &gOptions->m_bAutoCopySelection, page);
0788     gbox->addWidget(pAutoCopySelection, line, 0, 1, 2);
0789 
0790     pAutoCopySelection->setToolTip(i18nc("Tool Tip",
0791         "On: Any selection is immediately written to the clipboard.\n"
0792         "Off: You must explicitly copy e.g. via Ctrl-C."));
0793     ++line;
0794 
0795     label = new QLabel(i18n("Line end style:"), page);
0796     gbox->addWidget(label, line, 0);
0797 
0798     OptionComboBox* pLineEndStyle = new OptionComboBox(eLineEndStyleAutoDetect, "LineEndStyle", (qint32*)&gOptions->m_lineEndStyle, page);
0799     gbox->addWidget(pLineEndStyle, line, 1);
0800 
0801     pLineEndStyle->insertItem(eLineEndStyleUnix, i18nc("Unix line ending", "Unix"));
0802     pLineEndStyle->insertItem(eLineEndStyleDos, i18nc("Dos/Windows line ending", "Dos/Windows"));
0803     pLineEndStyle->insertItem(eLineEndStyleAutoDetect, i18nc("Automatically detected line ending", "Autodetect"));
0804 
0805     label->setToolTip(i18nc("Tool Tip",
0806         "Sets the line endings for when an edited file is saved.\n"
0807         "DOS/Windows: CR+LF; UNIX: LF; with CR=0D, LF=0A"));
0808     ++line;
0809 
0810     topLayout->addStretch(10);
0811 }
0812 
0813 void OptionDialog::setupDiffPage()
0814 {
0815     QScrollArea* pageFrame = new QScrollArea();
0816     KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18n("Diff"));
0817     pageItem->setHeader(i18n("Diff Settings"));
0818     pageItem->setIcon(QIcon::fromTheme(QStringLiteral("text-x-patch")));
0819     addPage(pageItem);
0820 
0821     QVBoxLayout* scrollLayout = new QVBoxLayout();
0822     scrollLayout->setContentsMargins(2, 2, 2, 2);
0823     scrollLayout->addWidget(pageFrame);
0824 
0825     std::unique_ptr<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
0826     scrollArea->setupUi(pageFrame);
0827 
0828     QWidget* page = pageFrame->findChild<QWidget*>("contents");
0829 
0830     QVBoxLayout* topLayout = new QVBoxLayout(page);
0831     topLayout->setContentsMargins(5, 5, 5, 5);
0832 
0833     QGridLayout* gbox = new QGridLayout();
0834     gbox->setColumnStretch(1, 5);
0835     topLayout->addLayout(gbox);
0836     qint32 line = 0;
0837 
0838     QLabel* label = nullptr;
0839 
0840     OptionCheckBox* pIgnoreNumbers = new OptionCheckBox(i18n("Ignore numbers (treat as white space)"), false, "IgnoreNumbers", &gOptions->m_bIgnoreNumbers, page);
0841     gbox->addWidget(pIgnoreNumbers, line, 0, 1, 2);
0842 
0843     pIgnoreNumbers->setToolTip(i18nc("Tool Tip",
0844         "Ignore number characters during line matching phase. (Similar to Ignore white space.)\n"
0845         "Might help to compare files with numeric data."));
0846     ++line;
0847 
0848     OptionCheckBox* pIgnoreComments = new OptionCheckBox(i18n("Ignore C/C++ comments (treat as white space)"), false, "IgnoreComments", &gOptions->m_bIgnoreComments, page);
0849     gbox->addWidget(pIgnoreComments, line, 0, 1, 2);
0850 
0851     pIgnoreComments->setToolTip(i18nc("Tool Tip", "Treat C/C++ comments like white space."));
0852     ++line;
0853 
0854     OptionCheckBox* pIgnoreCase = new OptionCheckBox(i18n("Ignore case (treat as white space)"), false, "IgnoreCase", &gOptions->m_bIgnoreCase, page);
0855     gbox->addWidget(pIgnoreCase, line, 0, 1, 2);
0856 
0857     pIgnoreCase->setToolTip(i18nc("Tool Tip",
0858         "Treat case differences like white space changes. ('a'<=>'A')"));
0859     ++line;
0860 
0861     label = new QLabel(i18n("Preprocessor command:"), page);
0862     gbox->addWidget(label, line, 0);
0863     OptionLineEdit* pLE = new OptionLineEdit("", "PreProcessorCmd", &gOptions->m_PreProcessorCmd, page);
0864     gbox->addWidget(pLE, line, 1);
0865 
0866     label->setToolTip(i18nc("Tool Tip", "User defined pre-processing. (See the docs for details.)"));
0867     ++line;
0868 
0869     label = new QLabel(i18n("Line-matching preprocessor command:"), page);
0870     gbox->addWidget(label, line, 0);
0871     pLE = new OptionLineEdit("", "LineMatchingPreProcessorCmd", &gOptions->m_LineMatchingPreProcessorCmd, page);
0872     gbox->addWidget(pLE, line, 1);
0873 
0874     label->setToolTip(i18nc("Tool Tip", "This pre-processor is only used during line matching.\n(See the docs for details.)"));
0875     ++line;
0876 
0877     OptionCheckBox* pTryHard = new OptionCheckBox(i18n("Try hard (slower)"), true, "TryHard", &gOptions->m_bTryHard, page);
0878     gbox->addWidget(pTryHard, line, 0, 1, 2);
0879 
0880     pTryHard->setToolTip(i18nc("Tool Tip",
0881         "Enables the --minimal option for the external diff.\n"
0882         "The analysis of big files will be much slower."));
0883     ++line;
0884 
0885     OptionCheckBox* pDiff3AlignBC = new OptionCheckBox(i18n("Align B and C for 3 input files"), false, "Diff3AlignBC", &gOptions->m_bDiff3AlignBC, page);
0886     gbox->addWidget(pDiff3AlignBC, line, 0, 1, 2);
0887 
0888     pDiff3AlignBC->setToolTip(i18nc("Tool Tip",
0889         "Try to align B and C when comparing or merging three input files.\n"
0890         "Not recommended for merging because merge might get more complicated.\n"
0891         "(Default is off.)"));
0892     ++line;
0893 
0894     topLayout->addStretch(10);
0895 }
0896 
0897 void OptionDialog::setupMergePage()
0898 {
0899     QScrollArea* pageFrame = new QScrollArea();
0900     KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18nc("Settings page", "Merge"));
0901     pageItem->setHeader(i18n("Merge Settings"));
0902     pageItem->setIcon(QIcon::fromTheme(QStringLiteral("merge")));
0903     addPage(pageItem);
0904 
0905     QVBoxLayout* scrollLayout = new QVBoxLayout();
0906     scrollLayout->setContentsMargins(2, 2, 2, 2);
0907     scrollLayout->addWidget(pageFrame);
0908 
0909     std::unique_ptr<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
0910     scrollArea->setupUi(pageFrame);
0911 
0912     QWidget* page = pageFrame->findChild<QWidget*>("contents");
0913 
0914     QVBoxLayout* topLayout = new QVBoxLayout(page);
0915     topLayout->setContentsMargins(5, 5, 5, 5);
0916 
0917     QGridLayout* gbox = new QGridLayout();
0918     gbox->setColumnStretch(1, 5);
0919     topLayout->addLayout(gbox);
0920     qint32 line = 0;
0921 
0922     QLabel* label = nullptr;
0923 
0924     label = new QLabel(i18n("Auto advance delay (ms):"), page);
0925     gbox->addWidget(label, line, 0);
0926     OptionIntEdit* pAutoAdvanceDelay = new OptionIntEdit(500, "AutoAdvanceDelay", &gOptions->m_autoAdvanceDelay, 0, 2000, page);
0927     gbox->addWidget(pAutoAdvanceDelay, line, 1);
0928 
0929     label->setToolTip(i18nc("Tool Tip",
0930         "When in Auto-Advance mode the result of the current selection is shown \n"
0931         "for the specified time, before jumping to the next conflict. Range: 0-2000 ms"));
0932     ++line;
0933 
0934     OptionCheckBox* pShowInfoDialogs = new OptionCheckBox(i18n("Show info dialogs"), true, "ShowInfoDialogs", &gOptions->m_bShowInfoDialogs, page);
0935     gbox->addWidget(pShowInfoDialogs, line, 0, 1, 2);
0936 
0937     pShowInfoDialogs->setToolTip(i18nc("Tool Tip", "Show a dialog with information about the number of conflicts."));
0938     ++line;
0939 
0940     label = new QLabel(i18n("White space 2-file merge default:"), page);
0941     gbox->addWidget(label, line, 0);
0942     OptionComboBox* pWhiteSpace2FileMergeDefault = new OptionComboBox(0, "WhiteSpace2FileMergeDefault", &gOptions->m_whiteSpace2FileMergeDefault, page);
0943     gbox->addWidget(pWhiteSpace2FileMergeDefault, line, 1);
0944 
0945     pWhiteSpace2FileMergeDefault->insertItem(0, i18n("Manual Choice"));
0946     pWhiteSpace2FileMergeDefault->insertItem(1, QStringLiteral("A"));
0947     pWhiteSpace2FileMergeDefault->insertItem(2, QStringLiteral("B"));
0948     label->setToolTip(i18nc("Tool Tip",
0949         "Allow the merge algorithm to automatically select an input for "
0950         "white-space-only changes."));
0951     ++line;
0952 
0953     label = new QLabel(i18n("White space 3-file merge default:"), page);
0954     gbox->addWidget(label, line, 0);
0955     OptionComboBox* pWhiteSpace3FileMergeDefault = new OptionComboBox(0, "WhiteSpace3FileMergeDefault", &gOptions->m_whiteSpace3FileMergeDefault, page);
0956     gbox->addWidget(pWhiteSpace3FileMergeDefault, line, 1);
0957 
0958     pWhiteSpace3FileMergeDefault->insertItem(0, i18n("Manual Choice"));
0959     pWhiteSpace3FileMergeDefault->insertItem(1, QStringLiteral("A"));
0960     pWhiteSpace3FileMergeDefault->insertItem(2, QStringLiteral("B"));
0961     pWhiteSpace3FileMergeDefault->insertItem(3, QStringLiteral("C"));
0962     label->setToolTip(i18nc("Tool Tip",
0963         "Allow the merge algorithm to automatically select an input for "
0964         "white-space-only changes."));
0965     ++line;
0966 
0967     QGroupBox* pGroupBox = new QGroupBox(i18n("Automatic Merge Regular Expression"));
0968     gbox->addWidget(pGroupBox, line, 0, 1, 2);
0969     ++line;
0970     {
0971         gbox = new QGridLayout(pGroupBox);
0972         gbox->setColumnStretch(1, 10);
0973         line = 0;
0974 
0975         label = new QLabel(i18n("Auto merge regular expression:"), page);
0976         gbox->addWidget(label, line, 0);
0977         m_pAutoMergeRegExpLineEdit = new OptionLineEdit(".*\\$(Version|Header|Date|Author).*\\$.*", "AutoMergeRegExp", &gOptions->m_autoMergeRegExp, page);
0978         gbox->addWidget(m_pAutoMergeRegExpLineEdit, line, 1);
0979 
0980         label->setToolTip(s_autoMergeRegExpToolTip);
0981         ++line;
0982 
0983         OptionCheckBox* pAutoMergeRegExp = new OptionCheckBox(i18n("Run regular expression auto merge on merge start"), false, "RunRegExpAutoMergeOnMergeStart", &gOptions->m_bRunRegExpAutoMergeOnMergeStart, page);
0984 
0985         gbox->addWidget(pAutoMergeRegExp, line, 0, 1, 2);
0986         pAutoMergeRegExp->setToolTip(i18nc("Tool Tip", "Run the merge for auto merge regular expressions\n"
0987                                           "immediately when a merge starts.\n"));
0988         ++line;
0989     }
0990 
0991     pGroupBox = new QGroupBox(i18n("Version Control History Merging"));
0992     gbox->addWidget(pGroupBox, line, 0, 1, 2);
0993     ++line;
0994     {
0995         gbox = new QGridLayout(pGroupBox);
0996         gbox->setColumnStretch(1, 10);
0997         line = 0;
0998 
0999         label = new QLabel(i18n("History start regular expression:"), page);
1000         gbox->addWidget(label, line, 0);
1001         m_pHistoryStartRegExpLineEdit = new OptionLineEdit(".*\\$Log.*\\$.*", "HistoryStartRegExp", &gOptions->m_historyStartRegExp, page);
1002         gbox->addWidget(m_pHistoryStartRegExpLineEdit, line, 1);
1003 
1004         label->setToolTip(s_historyStartRegExpToolTip);
1005         ++line;
1006 
1007         label = new QLabel(i18n("History entry start regular expression:"), page);
1008         gbox->addWidget(label, line, 0);
1009         // Example line:  "** \main\rolle_fsp_dev_008\1   17 Aug 2001 10:45:44   rolle"
1010         QString historyEntryStartDefault =
1011             "\\s*\\\\main\\\\(\\S+)\\s+"                         // Start with  "\main\"
1012             "([0-9]+) "                                          // day
1013             "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) " //month
1014             "([0-9][0-9][0-9][0-9]) "                            // year
1015             "([0-9][0-9]:[0-9][0-9]:[0-9][0-9])\\s+(.*)";        // time, name
1016 
1017         m_pHistoryEntryStartRegExpLineEdit = new OptionLineEdit(historyEntryStartDefault, "HistoryEntryStartRegExp", &gOptions->m_historyEntryStartRegExp, page);
1018         gbox->addWidget(m_pHistoryEntryStartRegExpLineEdit, line, 1);
1019 
1020         label->setToolTip(s_historyEntryStartRegExpToolTip);
1021         ++line;
1022 
1023         m_pHistoryMergeSorting = new OptionCheckBox(i18n("History merge sorting"), false, "HistoryMergeSorting", &gOptions->m_bHistoryMergeSorting, page);
1024         gbox->addWidget(m_pHistoryMergeSorting, line, 0, 1, 2);
1025 
1026         m_pHistoryMergeSorting->setToolTip(i18nc("Tool Tip", "Sort version control history by a key."));
1027         ++line;
1028         //QString branch = newHistoryEntry.cap(1);
1029         //qint32 day    = newHistoryEntry.cap(2).toInt();
1030         //qint32 month  = QString("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec").find(newHistoryEntry.cap(3))/4 + 1;
1031         //qint32 year   = newHistoryEntry.cap(4).toInt();
1032         //QString time = newHistoryEntry.cap(5);
1033         //QString name = newHistoryEntry.cap(6);
1034         QString defaultSortKeyOrder = "4,3,2,5,1,6"; //QDate(year,month,day).toString(Qt::ISODate) +" "+ time + " " + branch + " " + name;
1035 
1036         label = new QLabel(i18n("History entry start sort key order:"), page);
1037         gbox->addWidget(label, line, 0);
1038         m_pHistorySortKeyOrderLineEdit = new OptionLineEdit(defaultSortKeyOrder, "HistoryEntryStartSortKeyOrder", &gOptions->m_historyEntryStartSortKeyOrder, page);
1039         gbox->addWidget(m_pHistorySortKeyOrderLineEdit, line, 1);
1040 
1041         label->setToolTip(s_historyEntryStartSortKeyOrderToolTip);
1042         m_pHistorySortKeyOrderLineEdit->setEnabled(false);
1043         chk_connect_a(m_pHistoryMergeSorting, &OptionCheckBox::toggled, m_pHistorySortKeyOrderLineEdit, &OptionLineEdit::setEnabled);
1044         ++line;
1045 
1046         m_pHistoryAutoMerge = new OptionCheckBox(i18n("Merge version control history on merge start"), false, "RunHistoryAutoMergeOnMergeStart", &gOptions->m_bRunHistoryAutoMergeOnMergeStart, page);
1047 
1048         gbox->addWidget(m_pHistoryAutoMerge, line, 0, 1, 2);
1049         m_pHistoryAutoMerge->setToolTip(i18nc("Tool Tip", "Run version control history auto-merge on merge start."));
1050         ++line;
1051 
1052         OptionIntEdit* pMaxNofHistoryEntries = new OptionIntEdit(-1, "MaxNofHistoryEntries", &gOptions->m_maxNofHistoryEntries, -1, 1000, page);
1053         label = new QLabel(i18n("Max number of history entries:"), page);
1054         gbox->addWidget(label, line, 0);
1055         gbox->addWidget(pMaxNofHistoryEntries, line, 1);
1056 
1057         pMaxNofHistoryEntries->setToolTip(i18nc("Tool Tip", "Cut off after specified number. Use -1 for infinite number of entries."));
1058         ++line;
1059     }
1060 
1061     QPushButton* pButton = new QPushButton(i18n("Test your regular expressions"), page);
1062     gbox->addWidget(pButton, line, 0);
1063     chk_connect_a(pButton, &QPushButton::clicked, this, &OptionDialog::slotHistoryMergeRegExpTester);
1064     ++line;
1065 
1066     label = new QLabel(i18n("Irrelevant merge command:"), page);
1067     gbox->addWidget(label, line, 0);
1068     OptionLineEdit* pLE = new OptionLineEdit("", "IrrelevantMergeCmd", &gOptions->m_IrrelevantMergeCmd, page);
1069     gbox->addWidget(pLE, line, 1);
1070 
1071     label->setToolTip(i18nc("Tool Tip", "If specified this script is run after auto-merge\n"
1072                                         "when no other relevant changes were detected.\n"
1073                                         "Called with the parameters: filename1 filename2 filename3"));
1074     ++line;
1075 
1076     OptionCheckBox* pAutoSaveAndQuit = new OptionCheckBox(i18n("Auto save and quit on merge without conflicts"), false,
1077                                                           "AutoSaveAndQuitOnMergeWithoutConflicts", &gOptions->m_bAutoSaveAndQuitOnMergeWithoutConflicts, page);
1078     gbox->addWidget(pAutoSaveAndQuit, line, 0, 1, 2);
1079 
1080     pAutoSaveAndQuit->setToolTip(i18nc("Tool Tip", "If KDiff3 was started for a file-merge from the command line and all\n"
1081                                       "conflicts are solvable without user interaction then automatically save and quit.\n"
1082                                       "(Similar to command line option \"--auto\".)"));
1083     ++line;
1084 
1085     topLayout->addStretch(10);
1086 }
1087 
1088 void OptionDialog::setupDirectoryMergePage()
1089 {
1090     QScrollArea* pageFrame = new QScrollArea();
1091     KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18nc("Tab title label", "Folder"));
1092     pageItem->setHeader(i18nc("Tab title label", "Folder"));
1093     pageItem->setIcon(QIcon::fromTheme(QStringLiteral("inode-directory")));
1094     addPage(pageItem);
1095 
1096     QVBoxLayout* scrollLayout = new QVBoxLayout();
1097     scrollLayout->setContentsMargins(2, 2, 2, 2);
1098     scrollLayout->addWidget(pageFrame);
1099 
1100     std::unique_ptr<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
1101     scrollArea->setupUi(pageFrame);
1102 
1103     QWidget* page = pageFrame->findChild<QWidget*>("contents");
1104     QVBoxLayout* topLayout = new QVBoxLayout(page);
1105     topLayout->setContentsMargins(5, 5, 5, 5);
1106 
1107     QGridLayout* gbox = new QGridLayout();
1108     gbox->setColumnStretch(1, 5);
1109     topLayout->addLayout(gbox);
1110     qint32 line = 0;
1111 
1112     OptionCheckBox* pRecursiveDirs = new OptionCheckBox(i18n("Recursive folders"), true, "RecursiveDirs", &gOptions->m_bDmRecursiveDirs, page);
1113     gbox->addWidget(pRecursiveDirs, line, 0, 1, 2);
1114 
1115     pRecursiveDirs->setToolTip(i18nc("Tool Tip", "Whether to analyze subfolders or not."));
1116     ++line;
1117     QLabel* label = new QLabel(i18n("File pattern(s):"), page);
1118     gbox->addWidget(label, line, 0);
1119     OptionLineEdit* pFilePattern = new OptionLineEdit("*", "FilePattern", &gOptions->m_DmFilePattern, page);
1120     gbox->addWidget(pFilePattern, line, 1);
1121 
1122     label->setToolTip(i18nc("Tool Tip",
1123         "Pattern(s) of files to be analyzed. \n"
1124         "Wildcards: '*' and '?'\n"
1125         "Several Patterns can be specified by using the separator: ';'"));
1126     ++line;
1127 
1128     label = new QLabel(i18n("File-anti-pattern(s):"), page);
1129     gbox->addWidget(label, line, 0);
1130     OptionLineEdit* pFileAntiPattern = new OptionLineEdit("*.orig;*.o;*.obj;*.rej;*.bak", "FileAntiPattern", &gOptions->m_DmFileAntiPattern, page);
1131     gbox->addWidget(pFileAntiPattern, line, 1);
1132 
1133     label->setToolTip(i18nc("Tool Tip",
1134         "Pattern(s) of files to be excluded from analysis. \n"
1135         "Wildcards: '*' and '?'\n"
1136         "Several Patterns can be specified by using the separator: ';'"));
1137     ++line;
1138 
1139     label = new QLabel(i18n("Folder-anti-pattern(s):"), page);
1140     gbox->addWidget(label, line, 0);
1141     OptionLineEdit* pDirAntiPattern = new OptionLineEdit("CVS;.deps;.svn;.hg;.git", "DirAntiPattern", &gOptions->m_DmDirAntiPattern, page);
1142     gbox->addWidget(pDirAntiPattern, line, 1);
1143 
1144     label->setToolTip(i18nc("Tool Tip",
1145         "Pattern(s) of folders to be excluded from analysis. \n"
1146         "Wildcards: '*' and '?'\n"
1147         "Several Patterns can be specified by using the separator: ';'"));
1148     ++line;
1149 
1150     OptionCheckBox* pUseCvsIgnore = new OptionCheckBox(i18n("Use Ignore File"), false, "UseCvsIgnore", &gOptions->m_bDmUseCvsIgnore, page);
1151     gbox->addWidget(pUseCvsIgnore, line, 0, 1, 2);
1152 
1153     pUseCvsIgnore->setToolTip(i18nc("Tool Tip",
1154                                     "Extends the anti-pattern to anything that would be ignored by source control.\n"
1155                                     "Via local ignore files this can be folder-specific."));
1156     ++line;
1157 
1158     OptionCheckBox* pFindHidden = new OptionCheckBox(i18n("Find hidden files and folders"), true, "FindHidden", &gOptions->m_bDmFindHidden, page);
1159     gbox->addWidget(pFindHidden, line, 0, 1, 2);
1160 
1161     pFindHidden->setToolTip(i18nc("Tool Tip", "Finds hidden files and folders."));
1162     ++line;
1163 
1164     OptionCheckBox* pFollowFileLinks = new OptionCheckBox(i18n("Follow file links"), true, "FollowFileLinks", &gOptions->m_bDmFollowFileLinks, page);
1165     gbox->addWidget(pFollowFileLinks, line, 0, 1, 2);
1166 
1167     pFollowFileLinks->setToolTip(i18nc("Tool Tip",
1168         "On: Compare the file the link points to.\n"
1169         "Off: Compare the links."));
1170     ++line;
1171 
1172     OptionCheckBox* pFollowDirLinks = new OptionCheckBox(i18n("Follow folder links"), true, "FollowDirLinks", &gOptions->m_bDmFollowDirLinks, page);
1173     gbox->addWidget(pFollowDirLinks, line, 0, 1, 2);
1174 
1175     pFollowDirLinks->setToolTip(i18nc("Tool Tip",
1176         "On: Compare the folder the link points to.\n"
1177         "Off: Compare the links."));
1178     ++line;
1179 
1180 #if defined(Q_OS_WIN)
1181     bool bCaseSensitiveFilenameComparison = false;
1182 #else
1183     bool bCaseSensitiveFilenameComparison = true;
1184 #endif
1185     OptionCheckBox* pCaseSensitiveFileNames = new OptionCheckBox(i18n("Case sensitive filename comparison"), bCaseSensitiveFilenameComparison, "CaseSensitiveFilenameComparison", &gOptions->m_bDmCaseSensitiveFilenameComparison, page);
1186     gbox->addWidget(pCaseSensitiveFileNames, line, 0, 1, 2);
1187 
1188     pCaseSensitiveFileNames->setToolTip(i18nc("Tool Tip",
1189         "The folder comparison will compare files or folders when their names match.\n"
1190         "Set this option if the case of the names must match. (Default for Windows is off, otherwise on.)"));
1191     ++line;
1192 
1193     OptionCheckBox* pUnfoldSubdirs = new OptionCheckBox(i18n("Unfold all subfolders on load"), false, "UnfoldSubdirs", &gOptions->m_bDmUnfoldSubdirs, page);
1194     gbox->addWidget(pUnfoldSubdirs, line, 0, 1, 2);
1195 
1196     pUnfoldSubdirs->setToolTip(i18nc("Tool Tip",
1197         "On: Unfold all subfolders when starting a folder diff.\n"
1198         "Off: Leave subfolders folded."));
1199     ++line;
1200 
1201     OptionCheckBox* pSkipDirStatus = new OptionCheckBox(i18n("Skip folder status report"), false, "SkipDirStatus", &gOptions->m_bDmSkipDirStatus, page);
1202     gbox->addWidget(pSkipDirStatus, line, 0, 1, 2);
1203 
1204     pSkipDirStatus->setToolTip(i18nc("Tool Tip",
1205         "On: Do not show the Folder Comparison Status.\n"
1206         "Off: Show the status dialog on start."));
1207     ++line;
1208 
1209     QGroupBox* pBG = new QGroupBox(i18n("File Comparison Mode"));
1210     gbox->addWidget(pBG, line, 0, 1, 2);
1211 
1212     QVBoxLayout* pBGLayout = new QVBoxLayout(pBG);
1213 
1214     OptionRadioButton* pBinaryComparison = new OptionRadioButton(i18n("Binary comparison"), true, "BinaryComparison", &gOptions->m_bDmBinaryComparison, pBG);
1215 
1216     pBinaryComparison->setToolTip(i18nc("Tool Tip", "Binary comparison of each file. (Default)"));
1217     pBGLayout->addWidget(pBinaryComparison);
1218 
1219     OptionRadioButton* pFullAnalysis = new OptionRadioButton(i18n("Full analysis"), false, "FullAnalysis", &gOptions->m_bDmFullAnalysis, pBG);
1220 
1221     pFullAnalysis->setToolTip(i18nc("Tool Tip", "Do a full analysis and show statistics information in extra columns.\n"
1222                                    "(Slower than a binary comparison, much slower for binary files.)"));
1223     pBGLayout->addWidget(pFullAnalysis);
1224 
1225     OptionRadioButton* pTrustDate = new OptionRadioButton(i18n("Trust the size and modification date (unsafe)"), false, "TrustDate", &gOptions->m_bDmTrustDate, pBG);
1226 
1227     pTrustDate->setToolTip(i18nc("Tool Tip", "Assume that files are equal if the modification date and file length are equal.\n"
1228                                 "Files with equal contents but different modification dates will appear as different.\n"
1229                                 "Useful for big folders or slow networks."));
1230     pBGLayout->addWidget(pTrustDate);
1231 
1232     OptionRadioButton* pTrustDateFallbackToBinary = new OptionRadioButton(i18n("Trust the size and date, but use binary comparison if date does not match (unsafe)"), false, "TrustDateFallbackToBinary", &gOptions->m_bDmTrustDateFallbackToBinary, pBG);
1233 
1234     pTrustDateFallbackToBinary->setToolTip(i18nc("Tool Tip", "Assume that files are equal if the modification date and file length are equal.\n"
1235                                                 "If the dates are not equal but the sizes are, use binary comparison.\n"
1236                                                 "Useful for big folders or slow networks."));
1237     pBGLayout->addWidget(pTrustDateFallbackToBinary);
1238 
1239     OptionRadioButton* pTrustSize = new OptionRadioButton(i18n("Trust the size (unsafe)"), false, "TrustSize", &gOptions->m_bDmTrustSize, pBG);
1240 
1241     pTrustSize->setToolTip(i18nc("Tool Tip", "Assume that files are equal if their file lengths are equal.\n"
1242                                 "Useful for big folders or slow networks when the date is modified during download."));
1243     pBGLayout->addWidget(pTrustSize);
1244 
1245     ++line;
1246 
1247     // Some two Dir-options: Affects only the default actions.
1248     OptionCheckBox* pSyncMode = new OptionCheckBox(i18n("Synchronize folders"), false, "SyncMode", &gOptions->m_bDmSyncMode, page);
1249 
1250     gbox->addWidget(pSyncMode, line, 0, 1, 2);
1251     pSyncMode->setToolTip(i18nc("Tool Tip",
1252         "Offers to store files in both folders so that\n"
1253         "both folders are the same afterwards.\n"
1254         "Works only when comparing two folders without specifying a destination."));
1255     ++line;
1256 
1257     // Allow white-space only differences to be considered equal
1258     OptionCheckBox* pWhiteSpaceDiffsEqual = new OptionCheckBox(i18n("White space differences considered equal"), true, "WhiteSpaceEqual", &gOptions->m_bDmWhiteSpaceEqual, page);
1259 
1260     gbox->addWidget(pWhiteSpaceDiffsEqual, line, 0, 1, 2);
1261     pWhiteSpaceDiffsEqual->setToolTip(i18nc("Tool Tip",
1262         "If files differ only by white space consider them equal.\n"
1263         "This is only active when full analysis is chosen."));
1264     chk_connect_a(pFullAnalysis, &OptionRadioButton::toggled, pWhiteSpaceDiffsEqual, &OptionCheckBox::setEnabled);
1265     pWhiteSpaceDiffsEqual->setEnabled(false);
1266     ++line;
1267 
1268     OptionCheckBox* pCopyNewer = new OptionCheckBox(i18n("Copy newer instead of merging (unsafe)"), false, "CopyNewer", &gOptions->m_bDmCopyNewer, page);
1269 
1270     gbox->addWidget(pCopyNewer, line, 0, 1, 2);
1271     pCopyNewer->setToolTip(i18nc("Tool Tip",
1272         "Do not look inside, just take the newer file.\n"
1273         "(Use this only if you know what you are doing!)\n"
1274         "Only effective when comparing two folders."));
1275     ++line;
1276 
1277     OptionCheckBox* pCreateBakFiles = new OptionCheckBox(i18n("Backup files (.orig)"), true, "CreateBakFiles", &gOptions->m_bDmCreateBakFiles, page);
1278     gbox->addWidget(pCreateBakFiles, line, 0, 1, 2);
1279 
1280     pCreateBakFiles->setToolTip(i18nc("Tool Tip",
1281         "If a file would be saved over an old file, then the old file\n"
1282         "will be renamed with a '.orig' extension instead of being deleted."));
1283     ++line;
1284 
1285     topLayout->addStretch(10);
1286 }
1287 void OptionDialog::setupRegionalPage()
1288 {
1289     QScrollArea* pageFrame = new QScrollArea();
1290     KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18n("Regional Settings"));
1291     pageItem->setHeader(i18n("Regional Settings"));
1292     pageItem->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-locale")));
1293     addPage(pageItem);
1294 
1295     QVBoxLayout* scrollLayout = new QVBoxLayout();
1296     scrollLayout->setContentsMargins(2, 2, 2, 2);
1297     scrollLayout->addWidget(pageFrame);
1298 
1299     std::unique_ptr<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
1300     scrollArea->setupUi(pageFrame);
1301 
1302     QWidget* page = pageFrame->findChild<QWidget*>("contents");
1303 
1304     QVBoxLayout* topLayout = new QVBoxLayout(page);
1305     topLayout->setContentsMargins(5, 5, 5, 5);
1306 
1307     QGridLayout* gbox = new QGridLayout();
1308     gbox->setColumnStretch(1, 5);
1309     topLayout->addLayout(gbox);
1310     qint32 line = 0;
1311 
1312     QLabel* label;
1313 
1314     m_pSameEncoding = new OptionCheckBox(i18n("Use the same encoding for everything:"), true, "SameEncoding", &gOptions->m_bSameEncoding, page);
1315 
1316     gbox->addWidget(m_pSameEncoding, line, 0, 1, 2);
1317     m_pSameEncoding->setToolTip(i18nc("Tool Tip",
1318         "Enable this allows to change all encodings by changing the first only.\n"
1319         "Disable this if different individual settings are needed."));
1320     ++line;
1321 
1322     label = new QLabel(i18n("Note: Local Encoding is \"%1\"", QLatin1String(QTextCodec::codecForLocale()->name())), page);
1323     gbox->addWidget(label, line, 0);
1324     ++line;
1325 
1326     label = new QLabel(i18n("File Encoding for A:"), page);
1327     gbox->addWidget(label, line, 0);
1328     m_pEncodingAComboBox = new OptionEncodingComboBox("EncodingForA", &gOptions->mEncodingA, page);
1329 
1330     gbox->addWidget(m_pEncodingAComboBox, line, 1);
1331 
1332     QString autoDetectToolTip = i18n(
1333         "If enabled then encoding will be automaticly detected.\n"
1334         "If the file's encoding can not be found automaticly then the selected encoding will be used as fallback.\n"
1335         "(Unicode detection depends on the first bytes of a file.)");
1336     mAutoDetectA = new OptionCheckBox(i18n("Auto Detect"), true, "AutoDetectUnicodeA", &gOptions->mAutoDetectA, page);
1337     gbox->addWidget(mAutoDetectA, line, 2);
1338 
1339     mAutoDetectA->setToolTip(autoDetectToolTip);
1340     ++line;
1341 
1342     label = new QLabel(i18n("File Encoding for B:"), page);
1343     gbox->addWidget(label, line, 0);
1344     m_pEncodingBComboBox = new OptionEncodingComboBox("EncodingForB", &gOptions->mEncodingB, page);
1345 
1346     gbox->addWidget(m_pEncodingBComboBox, line, 1);
1347     mAutoDetectB = new OptionCheckBox(i18n("Auto Detect"), true, "AutoDetectUnicodeB", &gOptions->mAutoDetectB, page);
1348 
1349     gbox->addWidget(mAutoDetectB, line, 2);
1350     mAutoDetectB->setToolTip(autoDetectToolTip);
1351     ++line;
1352 
1353     label = new QLabel(i18n("File Encoding for C:"), page);
1354     gbox->addWidget(label, line, 0);
1355     m_pEncodingCComboBox = new OptionEncodingComboBox("EncodingForC", &gOptions->mEncodingC, page);
1356 
1357     gbox->addWidget(m_pEncodingCComboBox, line, 1);
1358     mAutoDetectC = new OptionCheckBox(i18n("Auto Detect"), true, "AutoDetectUnicodeC", &gOptions->mAutoDetectC, page);
1359 
1360     gbox->addWidget(mAutoDetectC, line, 2);
1361     mAutoDetectC->setToolTip(autoDetectToolTip);
1362     ++line;
1363 
1364     label = new QLabel(i18n("File Encoding for Merge Output and Saving:"), page);
1365     gbox->addWidget(label, line, 0);
1366     m_pEncodingOutComboBox = new OptionEncodingComboBox("EncodingForOutput", &gOptions->mEncodingOut, page);
1367 
1368     gbox->addWidget(m_pEncodingOutComboBox, line, 1);
1369     m_pAutoSelectOutEncoding = new OptionCheckBox(i18n("Auto Select"), true, "AutoSelectOutEncoding", &gOptions->m_bAutoSelectOutEncoding, page);
1370 
1371     gbox->addWidget(m_pAutoSelectOutEncoding, line, 2);
1372     m_pAutoSelectOutEncoding->setToolTip(i18nc("Tool Tip",
1373         "If enabled then the encoding from the input files is used.\n"
1374         "In ambiguous cases a dialog will ask the user to choose the encoding for saving."));
1375     ++line;
1376     label = new QLabel(i18n("File Encoding for Preprocessor Files:"), page);
1377     gbox->addWidget(label, line, 0);
1378     m_pEncodingPPComboBox = new OptionEncodingComboBox("EncodingForPP", &gOptions->mEncodingPP, page);
1379 
1380     gbox->addWidget(m_pEncodingPPComboBox, line, 1);
1381     ++line;
1382 
1383     chk_connect_a(m_pSameEncoding, &OptionCheckBox::toggled, this, &OptionDialog::slotEncodingChanged);
1384     chk_connect_a(m_pEncodingAComboBox, static_cast<void (OptionEncodingComboBox::*)(qint32)>(&OptionEncodingComboBox::activated), this, &OptionDialog::slotEncodingChanged);
1385     chk_connect_a(mAutoDetectA, &OptionCheckBox::toggled, this, &OptionDialog::slotEncodingChanged);
1386     chk_connect_a(m_pAutoSelectOutEncoding, &OptionCheckBox::toggled, this, &OptionDialog::slotEncodingChanged);
1387 
1388     OptionCheckBox* pRightToLeftLanguage = new OptionCheckBox(i18n("Right To Left Language"), false, "RightToLeftLanguage", &gOptions->m_bRightToLeftLanguage, page);
1389 
1390     gbox->addWidget(pRightToLeftLanguage, line, 0, 1, 2);
1391     pRightToLeftLanguage->setToolTip(i18nc("Tool Tip",
1392         "Some languages are read from right to left.\n"
1393         "This setting will change the viewer and editor accordingly."));
1394     ++line;
1395 
1396     topLayout->addStretch(10);
1397 }
1398 
1399 void OptionDialog::setupIntegrationPage()
1400 {
1401     QScrollArea* pageFrame = new QScrollArea();
1402     KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18n("Integration"));
1403     pageItem->setHeader(i18n("Integration Settings"));
1404     pageItem->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal")));
1405     addPage(pageItem);
1406 
1407     QVBoxLayout* scrollLayout = new QVBoxLayout();
1408     scrollLayout->setContentsMargins(2, 2, 2, 2);
1409     scrollLayout->addWidget(pageFrame);
1410 
1411     std::unique_ptr<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
1412     scrollArea->setupUi(pageFrame);
1413 
1414     QWidget* page = pageFrame->findChild<QWidget*>("contents");
1415     QVBoxLayout* topLayout = new QVBoxLayout(page);
1416     topLayout->setContentsMargins(5, 5, 5, 5);
1417 
1418     QGridLayout* gbox = new QGridLayout();
1419     gbox->setColumnStretch(2, 5);
1420     topLayout->addLayout(gbox);
1421     qint32 line = 0;
1422 
1423     QLabel* label;
1424     label = new QLabel(i18n("Command line options to ignore:"), page);
1425     gbox->addWidget(label, line, 0);
1426     OptionLineEdit* pIgnorableCmdLineOptions = new OptionLineEdit("-u;-query;-html;-abort", "IgnorableCmdLineOptions", &gOptions->m_ignorableCmdLineOptions, page);
1427     gbox->addWidget(pIgnorableCmdLineOptions, line, 1, 1, 2);
1428 
1429     label->setToolTip(i18nc("Tool Tip",
1430         "List of command line options that should be ignored when KDiff3 is used by other tools.\n"
1431         "Several values can be specified if separated via ';'\n"
1432         "This will suppress the \"Unknown option\" error."));
1433     ++line;
1434 
1435     OptionCheckBox* pEscapeKeyQuits = new OptionCheckBox(i18n("Quit also via Escape key"), false, "EscapeKeyQuits", &gOptions->m_bEscapeKeyQuits, page);
1436     gbox->addWidget(pEscapeKeyQuits, line, 0, 1, 2);
1437 
1438     pEscapeKeyQuits->setToolTip(i18nc("Tool Tip",
1439         "Fast method to exit.\n"
1440         "For those who are used to using the Escape key."));
1441     ++line;
1442 
1443     topLayout->addStretch(10);
1444 }
1445 
1446 void OptionDialog::slotEncodingChanged()
1447 {
1448     if(m_pSameEncoding->isChecked())
1449     {
1450         m_pEncodingBComboBox->setEnabled(false);
1451         m_pEncodingBComboBox->setCurrentIndex(m_pEncodingAComboBox->currentIndex());
1452         m_pEncodingCComboBox->setEnabled(false);
1453         m_pEncodingCComboBox->setCurrentIndex(m_pEncodingAComboBox->currentIndex());
1454         m_pEncodingOutComboBox->setEnabled(false);
1455         m_pEncodingOutComboBox->setCurrentIndex(m_pEncodingAComboBox->currentIndex());
1456         m_pEncodingPPComboBox->setEnabled(false);
1457         m_pEncodingPPComboBox->setCurrentIndex(m_pEncodingAComboBox->currentIndex());
1458         mAutoDetectB->setEnabled(false);
1459         mAutoDetectB->setCheckState(mAutoDetectA->checkState());
1460         mAutoDetectC->setEnabled(false);
1461         mAutoDetectC->setCheckState(mAutoDetectA->checkState());
1462         m_pAutoSelectOutEncoding->setEnabled(false);
1463         m_pAutoSelectOutEncoding->setCheckState(mAutoDetectA->checkState());
1464     }
1465     else
1466     {
1467         m_pEncodingBComboBox->setEnabled(true);
1468         m_pEncodingCComboBox->setEnabled(true);
1469         m_pEncodingOutComboBox->setEnabled(true);
1470         m_pEncodingPPComboBox->setEnabled(true);
1471         mAutoDetectB->setEnabled(true);
1472         mAutoDetectC->setEnabled(true);
1473         m_pAutoSelectOutEncoding->setEnabled(true);
1474         m_pEncodingOutComboBox->setEnabled(m_pAutoSelectOutEncoding->checkState() == Qt::Unchecked);
1475     }
1476 }
1477 
1478 void OptionDialog::slotOk()
1479 {
1480     slotApply();
1481 
1482     accept();
1483 }
1484 
1485 /** Copy the values from the widgets to the public variables.*/
1486 void OptionDialog::slotApply()
1487 {
1488     Options::apply();
1489 
1490     Q_EMIT applyDone();
1491 }
1492 
1493 /** Set the default values in the widgets only, while the
1494     public variables remain unchanged. */
1495 void OptionDialog::slotDefault()
1496 {
1497     qint32 result = KMessageBox::warningContinueCancel(this, i18n("This resets all options. Not only those of the current topic."));
1498     if(result == KMessageBox::Cancel)
1499         return;
1500     else
1501         resetToDefaults();
1502 }
1503 
1504 void OptionDialog::resetToDefaults()
1505 {
1506     Options::resetToDefaults();
1507 
1508     slotEncodingChanged();
1509 }
1510 
1511 /** Initialise the widgets using the values in the public variables. */
1512 void OptionDialog::setState()
1513 {
1514     Options::setToCurrent();
1515 
1516     slotEncodingChanged();
1517 }
1518 
1519 void OptionDialog::saveOptions(KSharedConfigPtr config)
1520 {
1521     // No i18n()-Translations here!
1522     gOptions->saveOptions(config);
1523 }
1524 
1525 void OptionDialog::readOptions(KSharedConfigPtr config)
1526 {
1527     // No i18n()-Translations here!
1528     gOptions->readOptions(config);
1529 
1530     setState();
1531 }
1532 
1533 const QString OptionDialog::parseOptions(const QStringList& optionList)
1534 {
1535 
1536     return gOptions->parseOptions(optionList);
1537 }
1538 
1539 QString OptionDialog::calcOptionHelp()
1540 {
1541     return gOptions->calcOptionHelp();
1542 }
1543 
1544 void OptionDialog::slotHistoryMergeRegExpTester()
1545 {
1546     QPointer<RegExpTester> dlg = QPointer<RegExpTester>(new RegExpTester(this, s_autoMergeRegExpToolTip, s_historyStartRegExpToolTip,
1547                                                                          s_historyEntryStartRegExpToolTip, s_historyEntryStartSortKeyOrderToolTip));
1548     dlg->init(m_pAutoMergeRegExpLineEdit->currentText(), m_pHistoryStartRegExpLineEdit->currentText(),
1549               m_pHistoryEntryStartRegExpLineEdit->currentText(), m_pHistorySortKeyOrderLineEdit->currentText());
1550     if(dlg->exec())
1551     {
1552         m_pAutoMergeRegExpLineEdit->setEditText(dlg->autoMergeRegExp());
1553         m_pHistoryStartRegExpLineEdit->setEditText(dlg->historyStartRegExp());
1554         m_pHistoryEntryStartRegExpLineEdit->setEditText(dlg->historyEntryStartRegExp());
1555         m_pHistorySortKeyOrderLineEdit->setEditText(dlg->historySortKeyOrder());
1556     }
1557 }
1558 
1559 #include "optiondialog.moc"