1 /*
2 * KDiff3 - Text Diff And Merge Tool
3 *
4 * SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachim.eibl at gmx.de
5 * SPDX-FileCopyrightText: 2018-2020 Michael Reeves reeves.87@gmail.com
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8 #include "optiondialog.h"
9 #include "OptionItems.h"
10 #include "ui_scroller.h"
11
12 #include "common.h"
13 #include "defmac.h"
14 #include "smalldialogs.h"
15
16 #include <map>
17
18 #include <KColorButton>
19 #include <KHelpClient>
20 #include <KLocalizedString>
21 #include <KMessageBox>
22 #include <KToolBar>
23
24 #include <QApplication>
25 #include <QCheckBox>
26 #include <QComboBox>
27 #include <QDialogButtonBox>
28 #include <QFontDatabase>
29 #include <QFontDialog>
30 #include <QFrame>
31 #include <QGridLayout>
32 #include <QGroupBox>
33 #include <QLabel>
34 #include <QLayout>
35 #include <QLineEdit>
36 #include <QPixmap>
37 #include <QPlainTextEdit>
38 #include <QPointer>
39 #include <QPushButton>
40 #include <QRadioButton>
41 #include <QTextCodec>
42 #include <QScrollArea>
43
44 const QString OptionDialog::s_historyEntryStartRegExpToolTip = i18n("A version control history entry consists of several lines.\n"
45 "Specify the regular expression to detect the first line (without the leading comment).\n"
46 "Use parentheses to group the keys you want to use for sorting.\n"
47 "If left empty, then KDiff3 assumes that empty lines separate history entries.\n"
48 "See the documentation for details.");
49 const QString OptionDialog::s_historyEntryStartSortKeyOrderToolTip = i18n("Each pair of parentheses used in the regular expression for the history start entry\n"
50 "groups a key that can be used for sorting.\n"
51 "Specify the list of keys (that are numbered in order of occurrence\n"
52 "starting with 1) using ',' as separator (e.g. \"4,5,6,1,2,3,7\").\n"
53 "If left empty, then no sorting will be done.\n"
54 "See the documentation for details.");
55 const QString OptionDialog::s_autoMergeRegExpToolTip = i18n("Regular expression for lines where KDiff3 should automatically choose one source.\n"
56 "When a line with a conflict matches the regular expression then\n"
57 "- if available - C, otherwise B will be chosen.");
58 const QString OptionDialog::s_historyStartRegExpToolTip = i18n("Regular expression for the start of the version control history entry.\n"
59 "Usually this line contains the \"$Log$\" keyword.\n"
60 "Default value: \".*\\$Log.*\\$.*\"");
61
62 class OptionCheckBox : public QCheckBox, public OptionBool
63 {
64 public:
OptionCheckBox(const QString & text,bool bDefaultVal,const QString & saveName,bool * pbVar,QWidget * pParent)65 OptionCheckBox(const QString& text, bool bDefaultVal, const QString& saveName, bool* pbVar,
66 QWidget* pParent)
67 : QCheckBox(text, pParent), OptionBool(pbVar, bDefaultVal, saveName)
68 {}
setToDefault()69 void setToDefault() override { setChecked(getDefault()); }
setToCurrent()70 void setToCurrent() override { setChecked(getCurrent()); }
71
72 using OptionBool::apply;
apply()73 void apply() override { apply(isChecked()); }
74
75 private:
76 Q_DISABLE_COPY(OptionCheckBox)
77 };
78
79 class OptionRadioButton : public QRadioButton, public OptionBool
80 {
81 public:
OptionRadioButton(const QString & text,bool bDefaultVal,const QString & saveName,bool * pbVar,QWidget * pParent)82 OptionRadioButton(const QString& text, bool bDefaultVal, const QString& saveName, bool* pbVar,
83 QWidget* pParent)
84 : QRadioButton(text, pParent), OptionBool(pbVar, bDefaultVal, saveName)
85 {}
setToDefault()86 void setToDefault() override { setChecked(getDefault()); }
setToCurrent()87 void setToCurrent() override { setChecked(getCurrent()); }
88
89 using OptionBool::apply;
apply()90 void apply() override { apply(isChecked()); }
91
92 private:
93 Q_DISABLE_COPY(OptionRadioButton)
94 };
95
FontChooser(QWidget * pParent)96 FontChooser::FontChooser(QWidget* pParent)
97 : QGroupBox(pParent)
98 {
99 QVBoxLayout* pLayout = new QVBoxLayout(this);
100 m_pLabel = new QLabel(QString());
101 pLayout->addWidget(m_pLabel);
102
103 QChar visualTab(0x2192);
104 QChar visualSpace((ushort)0xb7);
105 m_pExampleTextEdit = new QPlainTextEdit(i18n("The quick brown fox jumps over the river\n"
106 "but the little red hen escapes with a shiver.\n"
107 ":-)") +
108 visualTab + visualSpace,
109 this);
110 m_pExampleTextEdit->setFont(m_font);
111 m_pExampleTextEdit->setReadOnly(true);
112 pLayout->addWidget(m_pExampleTextEdit);
113
114 m_pSelectFont = new QPushButton(i18n("Change Font"));
115 m_pSelectFont->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
116 chk_connect(m_pSelectFont, &QPushButton::clicked, this, &FontChooser::slotSelectFont);
117 pLayout->addWidget(m_pSelectFont);
118 pLayout->setAlignment(m_pSelectFont, Qt::AlignRight);
119 }
120
font()121 QFont FontChooser::font()
122 {
123 return m_font; //QFont("courier",10);
124 }
125
setFont(const QFont & font,bool)126 void FontChooser::setFont(const QFont& font, bool)
127 {
128 m_font = font;
129 m_pExampleTextEdit->setFont(m_font);
130 m_pLabel->setText(i18n("Font: %1, %2, %3\n\nExample:", m_font.family(), m_font.styleName(), m_font.pointSize()));
131
132 //update();
133 }
134
slotSelectFont()135 void FontChooser::slotSelectFont()
136 {
137 bool bOk;
138 m_font = QFontDialog::getFont(&bOk, m_font);
139 m_pExampleTextEdit->setFont(m_font);
140 m_pLabel->setText(i18n("Font: %1, %2, %3\n\nExample:", m_font.family(), m_font.styleName(), m_font.pointSize()));
141 }
142
143 class OptionFontChooser : public FontChooser, public OptionFont
144 {
145 public:
OptionFontChooser(const QFont & defaultVal,const QString & saveName,QFont * pVar,QWidget * pParent)146 OptionFontChooser(const QFont& defaultVal, const QString& saveName, QFont* pVar, QWidget* pParent) : FontChooser(pParent),
147 OptionFont(pVar, defaultVal, saveName)
148 {}
149
setToDefault()150 void setToDefault() override { setFont(getDefault(), false); }
setToCurrent()151 void setToCurrent() override { setFont(getCurrent(), false); }
152 using OptionFont::apply;
apply()153 void apply() override { apply(font()); }
154 private:
155 Q_DISABLE_COPY(OptionFontChooser)
156 };
157
158 class OptionColorButton : public KColorButton, public OptionColor
159 {
160 public:
OptionColorButton(const QColor & defaultVal,const QString & saveName,QColor * pVar,QWidget * pParent)161 OptionColorButton(const QColor &defaultVal, const QString& saveName, QColor* pVar, QWidget* pParent)
162 : KColorButton(pParent), OptionColor(pVar, defaultVal, saveName)
163 {}
164
setToDefault()165 void setToDefault() override { setColor(getDefault()); }
setToCurrent()166 void setToCurrent() override { setColor(getCurrent()); }
167 using OptionColor::apply;
apply()168 void apply() override { apply(color()); }
169
170 private:
171 Q_DISABLE_COPY(OptionColorButton)
172 };
173
174 class OptionLineEdit : public QComboBox, public OptionString
175 {
176 public:
OptionLineEdit(const QString & defaultVal,const QString & saveName,QString * pVar,QWidget * pParent)177 OptionLineEdit(const QString& defaultVal, const QString& saveName, QString* pVar,
178 QWidget* pParent)
179 : QComboBox(pParent), OptionString(pVar, defaultVal, saveName)
180 {
181 setMinimumWidth(50);
182 setEditable(true);
183 m_list.push_back(defaultVal);
184 insertText();
185 }
setToDefault()186 void setToDefault() override
187 {
188 setEditText(getDefault());
189 }
setToCurrent()190 void setToCurrent() override
191 {
192 setEditText(getCurrent());
193 }
194
195 using OptionString::apply;
apply()196 void apply() override
197 {
198 apply(currentText());
199 insertText();
200 }
write(ValueMap * config) const201 void write(ValueMap* config) const override
202 {
203 config->writeEntry(m_saveName, m_list);
204 }
read(ValueMap * config)205 void read(ValueMap* config) override
206 {
207 m_list = config->readEntry(m_saveName, QStringList(m_defaultVal));
208 if(!m_list.empty()) setCurrent(m_list.front());
209 clear();
210 insertItems(0, m_list);
211 }
212
213 private:
insertText()214 void insertText()
215 { // Check if the text exists. If yes remove it and push it in as first element
216 QString current = currentText();
217 m_list.removeAll(current);
218 m_list.push_front(current);
219 clear();
220 if(m_list.size() > 10)
221 m_list.erase(m_list.begin() + 10, m_list.end());
222 insertItems(0, m_list);
223 }
224
225 Q_DISABLE_COPY(OptionLineEdit)
226 QStringList m_list;
227 };
228
229 class OptionIntEdit : public QLineEdit, public OptionNum<int>
230 {
231 public:
OptionIntEdit(int defaultVal,const QString & saveName,int * pVar,int rangeMin,int rangeMax,QWidget * pParent)232 OptionIntEdit(int defaultVal, const QString& saveName, int* pVar, int rangeMin, int rangeMax,
233 QWidget* pParent)
234 : QLineEdit(pParent), OptionNum<int>(pVar, defaultVal, saveName)
235 {
236 QIntValidator* v = new QIntValidator(this);
237 v->setRange(rangeMin, rangeMax);
238 setValidator(v);
239 }
setToDefault()240 void setToDefault() override
241 {
242 //QString::setNum does not account for locale settings
243 setText(OptionNum::toString(getDefault()));
244 }
245
setToCurrent()246 void setToCurrent() override
247 {
248 setText(getString());
249 }
250
251 using OptionNum<int>::apply;
apply()252 void apply() override
253 {
254 const QIntValidator* v = static_cast<const QIntValidator*>(validator());
255 setCurrent( qBound(v->bottom(), text().toInt(), v->top()) );
256
257 setText(getString());
258 }
259
260 private:
261 Q_DISABLE_COPY(OptionIntEdit)
262 };
263
264 class OptionComboBox : public QComboBox, public OptionItemBase
265 {
266 public:
OptionComboBox(int defaultVal,const QString & saveName,int * pVarNum,QWidget * pParent)267 OptionComboBox(int defaultVal, const QString& saveName, int* pVarNum,
268 QWidget* pParent)
269 : QComboBox(pParent), OptionItemBase(saveName)
270 {
271 setMinimumWidth(50);
272 m_pVarNum = pVarNum;
273 m_pVarStr = nullptr;
274 m_defaultVal = defaultVal;
275 setEditable(false);
276 }
OptionComboBox(int defaultVal,const QString & saveName,QString * pVarStr,QWidget * pParent)277 OptionComboBox(int defaultVal, const QString& saveName, QString* pVarStr,
278 QWidget* pParent)
279 : QComboBox(pParent), OptionItemBase(saveName)
280 {
281 m_pVarNum = nullptr;
282 m_pVarStr = pVarStr;
283 m_defaultVal = defaultVal;
284 setEditable(false);
285 }
setToDefault()286 void setToDefault() override
287 {
288 setCurrentIndex(m_defaultVal);
289 if(m_pVarStr != nullptr) {
290 *m_pVarStr = currentText();
291 }
292 }
setToCurrent()293 void setToCurrent() override
294 {
295 if(m_pVarNum != nullptr)
296 setCurrentIndex(*m_pVarNum);
297 else
298 setText(*m_pVarStr);
299 }
300 using OptionItemBase::apply;
apply()301 void apply() override
302 {
303 if(m_pVarNum != nullptr) {
304 *m_pVarNum = currentIndex();
305 }
306 else
307 {
308 *m_pVarStr = currentText();
309 }
310 }
write(ValueMap * config) const311 void write(ValueMap* config) const override
312 {
313 if(m_pVarStr != nullptr)
314 config->writeEntry(m_saveName, *m_pVarStr);
315 else
316 config->writeEntry(m_saveName, *m_pVarNum);
317 }
read(ValueMap * config)318 void read(ValueMap* config) override
319 {
320 if(m_pVarStr != nullptr)
321 setText(config->readEntry(m_saveName, currentText()));
322 else
323 *m_pVarNum = config->readEntry(m_saveName, *m_pVarNum);
324 }
preserve()325 void preserve() override
326 {
327 if(m_pVarStr != nullptr) {
328 m_preservedStrVal = *m_pVarStr;
329 }
330 else
331 {
332 m_preservedNumVal = *m_pVarNum;
333 }
334 }
unpreserve()335 void unpreserve() override
336 {
337 if(m_pVarStr != nullptr) {
338 *m_pVarStr = m_preservedStrVal;
339 }
340 else
341 {
342 *m_pVarNum = m_preservedNumVal;
343 }
344 }
345
346 private:
347 Q_DISABLE_COPY(OptionComboBox)
348 int* m_pVarNum;
349 int m_preservedNumVal = 0;
350 QString* m_pVarStr;
351 QString m_preservedStrVal;
352 int m_defaultVal;
353
setText(const QString & s)354 void setText(const QString& s)
355 {
356 // Find the string in the combobox-list, don't change the value if nothing fits.
357 for(int i = 0; i < count(); ++i)
358 {
359 if(itemText(i) == s)
360 {
361 if(m_pVarNum != nullptr) *m_pVarNum = i;
362 if(m_pVarStr != nullptr) *m_pVarStr = s;
363 setCurrentIndex(i);
364 return;
365 }
366 }
367 }
368 };
369
370 class OptionEncodingComboBox : public QComboBox, public OptionCodec
371 {
372 Q_OBJECT
373 QVector<QTextCodec*> m_codecVec;
374 QTextCodec** m_ppVarCodec;
375
376 public:
OptionEncodingComboBox(const QString & saveName,QTextCodec ** ppVarCodec,QWidget * pParent)377 OptionEncodingComboBox(const QString& saveName, QTextCodec** ppVarCodec,
378 QWidget* pParent)
379 : QComboBox(pParent), OptionCodec(saveName)
380 {
381 m_ppVarCodec = ppVarCodec;
382 insertCodec(i18n("Unicode, 8 bit"), QTextCodec::codecForName("UTF-8"));
383 insertCodec(i18n("Unicode"), QTextCodec::codecForName("iso-10646-UCS-2"));
384 insertCodec(i18n("Latin1"), QTextCodec::codecForName("iso 8859-1"));
385
386 // First sort codec names:
387 std::map<QString, QTextCodec*> names;
388 const QList<int> mibs = QTextCodec::availableMibs();
389 for(int i: mibs)
390 {
391 QTextCodec* c = QTextCodec::codecForMib(i);
392 if(c != nullptr)
393 names[QString(QLatin1String(c->name())).toUpper()] = c;
394 }
395
396 std::map<QString, QTextCodec*>::const_iterator it;
397 for(const auto& pair: names)
398 {
399 insertCodec("", pair.second);
400 }
401
402 setToolTip(i18n(
403 "Change this if non-ASCII characters are not displayed correctly."));
404 }
insertCodec(const QString & visibleCodecName,QTextCodec * c)405 void insertCodec(const QString& visibleCodecName, QTextCodec* c)
406 {
407 if(c != nullptr)
408 {
409 const QByteArray nameArray = c->name();
410 const QLatin1String codecName = QLatin1String(nameArray);
411
412 for(int i = 0; i < m_codecVec.size(); ++i)
413 {
414 if(c == m_codecVec[i])
415 return; // don't insert any codec twice
416 }
417
418 // The m_codecVec.size will at this point return the value we need for the index.
419 if(codecName == defaultName())
420 saveDefaultIndex(m_codecVec.size());
421 QString itemText = visibleCodecName.isEmpty() ? codecName : visibleCodecName + QLatin1String(" (") + codecName + QLatin1String(")");
422 addItem(itemText, m_codecVec.size());
423 m_codecVec.push_back(c);
424 }
425 }
setToDefault()426 void setToDefault() override
427 {
428 int index = getDefaultIndex();
429
430 setCurrentIndex(index);
431 if(m_ppVarCodec != nullptr)
432 {
433 *m_ppVarCodec = m_codecVec[index];
434 }
435 }
setToCurrent()436 void setToCurrent() override
437 {
438 if(m_ppVarCodec != nullptr)
439 {
440 for(int i = 0; i < m_codecVec.size(); ++i)
441 {
442 if(*m_ppVarCodec == m_codecVec[i])
443 {
444 setCurrentIndex(i);
445 break;
446 }
447 }
448 }
449 }
450 using OptionCodec::apply;
apply()451 void apply() override
452 {
453 if(m_ppVarCodec != nullptr)
454 {
455 *m_ppVarCodec = m_codecVec[currentIndex()];
456 }
457 }
write(ValueMap * config) const458 void write(ValueMap* config) const override
459 {
460 if(m_ppVarCodec != nullptr) config->writeEntry(m_saveName, (const char*)(*m_ppVarCodec)->name());
461 }
read(ValueMap * config)462 void read(ValueMap* config) override
463 {
464 QString codecName = config->readEntry(m_saveName, (const char*)m_codecVec[currentIndex()]->name());
465 for(int i = 0; i < m_codecVec.size(); ++i)
466 {
467 if(codecName == QLatin1String(m_codecVec[i]->name()))
468 {
469 setCurrentIndex(i);
470 if(m_ppVarCodec != nullptr) *m_ppVarCodec = m_codecVec[i];
471 break;
472 }
473 }
474 }
475
476 protected:
preserve()477 void preserve() override { m_preservedVal = currentIndex(); }
unpreserve()478 void unpreserve() override { setCurrentIndex(m_preservedVal); }
479 int m_preservedVal;
480 };
481
addOptionItem(OptionItemBase * p)482 void OptionDialog::addOptionItem(OptionItemBase* p)
483 {
484 m_options->addOptionItem(p);
485 }
486
OptionDialog(bool bShowDirMergeSettings,QWidget * parent)487 OptionDialog::OptionDialog(bool bShowDirMergeSettings, QWidget* parent) : KPageDialog(parent)
488 {
489 setFaceType(List);
490 setWindowTitle(i18n("Configure"));
491 setStandardButtons(QDialogButtonBox::Help | QDialogButtonBox::RestoreDefaults | QDialogButtonBox::Apply | QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
492
493 setModal(true);
494 setMinimumSize(600, 500);
495
496 //showButtonSeparator( true );
497 //setHelp( "kdiff3/index.html", QString::null );
498
499 m_options->init();
500 setupFontPage();
501 setupColorPage();
502 setupEditPage();
503 setupDiffPage();
504 setupMergePage();
505 setupOtherOptions();
506 if(bShowDirMergeSettings)
507 setupDirectoryMergePage();
508
509 setupRegionalPage();
510 setupIntegrationPage();
511
512 // Initialize all values in the dialog
513 resetToDefaults();
514 slotApply();
515 chk_connect(button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &OptionDialog::slotApply);
516 chk_connect(button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &OptionDialog::slotOk);
517 chk_connect(button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, this, &OptionDialog::slotDefault);
518 chk_connect(button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &QDialog::reject);
519 chk_connect(button(QDialogButtonBox::Help), &QPushButton::clicked, this, &OptionDialog::helpRequested);
520 }
521
helpRequested()522 void OptionDialog::helpRequested()
523 {
524 KHelpClient::invokeHelp(QStringLiteral("kdiff3/index.html"));
525 }
526
527 OptionDialog::~OptionDialog() = default;
528
setupOtherOptions()529 void OptionDialog::setupOtherOptions()
530 {
531 //TODO move to Options class
532 addOptionItem(new OptionToggleAction(false, "AutoAdvance", &m_options->m_bAutoAdvance));
533 addOptionItem(new OptionToggleAction(true, "ShowWhiteSpaceCharacters", &m_options->m_bShowWhiteSpaceCharacters));
534 addOptionItem(new OptionToggleAction(true, "ShowWhiteSpace", &m_options->m_bShowWhiteSpace));
535 addOptionItem(new OptionToggleAction(false, "ShowLineNumbers", &m_options->m_bShowLineNumbers));
536 addOptionItem(new OptionToggleAction(true, "HorizDiffWindowSplitting", &m_options->m_bHorizDiffWindowSplitting));
537 addOptionItem(new OptionToggleAction(false, "WordWrap", &m_options->m_bWordWrap));
538
539 addOptionItem(new OptionToggleAction(true, "ShowIdenticalFiles", &m_options->m_bDmShowIdenticalFiles));
540
541 addOptionItem(new OptionStringList(&m_options->m_recentAFiles, "RecentAFiles"));
542 addOptionItem(new OptionStringList(&m_options->m_recentBFiles, "RecentBFiles"));
543 addOptionItem(new OptionStringList(&m_options->m_recentCFiles, "RecentCFiles"));
544 addOptionItem(new OptionStringList(&m_options->m_recentOutputFiles, "RecentOutputFiles"));
545 addOptionItem(new OptionStringList(&m_options->m_recentEncodings, "RecentEncodings"));
546 }
547
setupFontPage()548 void OptionDialog::setupFontPage()
549 {
550 QFrame* page = new QFrame();
551 KPageWidgetItem* pageItem = new KPageWidgetItem(page, i18n("Font"));
552
553 pageItem->setHeader(i18n("Editor & Diff Output Font"));
554 //not all themes have this icon
555 if(QIcon::hasThemeIcon(QStringLiteral("font-select-symbolic")))
556 pageItem->setIcon(QIcon::fromTheme(QStringLiteral("font-select-symbolic")));
557 else
558 pageItem->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-font")));
559 addPage(pageItem);
560
561 QVBoxLayout* topLayout = new QVBoxLayout(page);
562 topLayout->setContentsMargins(5, 5, 5, 5);
563
564 //requires QT 5.2 or later.
565 static const QFont defaultFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
566 static QFont defaultAppFont = QApplication::font();
567
568 OptionFontChooser* pAppFontChooser = new OptionFontChooser(defaultAppFont, "ApplicationFont", &m_options->m_appFont, page);
569 addOptionItem(pAppFontChooser);
570 topLayout->addWidget(pAppFontChooser);
571 pAppFontChooser->setTitle(i18n("Application font"));
572
573 OptionFontChooser* pFontChooser = new OptionFontChooser(defaultFont, "Font", &m_options->m_font, page);
574 addOptionItem(pFontChooser);
575 topLayout->addWidget(pFontChooser);
576 pFontChooser->setTitle(i18n("File view font"));
577
578 QGridLayout* gbox = new QGridLayout();
579 topLayout->addLayout(gbox);
580 //int line=0;
581
582 // This currently does not work (see rendering in class DiffTextWindow)
583 //OptionCheckBox* pItalicDeltas = new OptionCheckBox( i18n("Italic font for deltas"), false, "ItalicForDeltas", &m_options->m_bItalicForDeltas, page, this );
584 //addOptionItem(pItalicDeltas);
585 //gbox->addWidget( pItalicDeltas, line, 0, 1, 2 );
586 //pItalicDeltas->setToolTip( i18n(
587 // "Selects the italic version of the font for differences.\n"
588 // "If the font doesn't support italic characters, then this does nothing.")
589 // );
590 }
591
setupColorPage()592 void OptionDialog::setupColorPage()
593 {
594 QScrollArea* pageFrame = new QScrollArea();
595 KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18nc("Title for color settings page","Color"));
596 pageItem->setHeader(i18n("Colors Settings"));
597 pageItem->setIcon(QIcon::fromTheme(QStringLiteral("colormanagement")));
598 addPage(pageItem);
599
600 QVBoxLayout* scrollLayout = new QVBoxLayout();
601 scrollLayout->setContentsMargins(2, 2, 2, 2);
602 scrollLayout->addWidget(pageFrame);
603
604 QScopedPointer<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
605 scrollArea->setupUi(pageFrame);
606
607 QWidget* page = pageFrame->findChild<QWidget*>("contents");
608 QVBoxLayout* topLayout = new QVBoxLayout(page);
609 topLayout->setContentsMargins(5, 5, 5, 5);
610
611 QGridLayout* gbox = new QGridLayout();
612 gbox->setColumnStretch(1, 5);
613 topLayout->addLayout(gbox);
614
615 QLabel* label;
616 int line = 0;
617
618 int depth = QPixmap::defaultDepth();
619 bool bLowColor = depth <= 8;
620
621 label = new QLabel(i18n("Editor and Diff Views:"), page);
622 gbox->addWidget(label, line, 0);
623 QFont f(label->font());
624 f.setBold(true);
625 label->setFont(f);
626 ++line;
627
628 OptionColorButton* pFgColor = new OptionColorButton(Qt::black, "FgColor", &m_options->m_fgColor, page);
629 label = new QLabel(i18n("Foreground color:"), page);
630 label->setBuddy(pFgColor);
631 addOptionItem(pFgColor);
632 gbox->addWidget(label, line, 0);
633 gbox->addWidget(pFgColor, line, 1);
634 ++line;
635
636 OptionColorButton* pBgColor = new OptionColorButton(Qt::white, "BgColor", &m_options->m_bgColor, page);
637 label = new QLabel(i18n("Background color:"), page);
638 label->setBuddy(pBgColor);
639 addOptionItem(pBgColor);
640 gbox->addWidget(label, line, 0);
641 gbox->addWidget(pBgColor, line, 1);
642
643 ++line;
644
645 OptionColorButton* pDiffBgColor = new OptionColorButton(
646 bLowColor ? QColor(Qt::lightGray) : qRgb(224, 224, 224), "DiffBgColor", &m_options->m_diffBgColor, page);
647 label = new QLabel(i18n("Diff background color:"), page);
648 label->setBuddy(pDiffBgColor);
649 addOptionItem(pDiffBgColor);
650 gbox->addWidget(label, line, 0);
651 gbox->addWidget(pDiffBgColor, line, 1);
652 ++line;
653
654 OptionColorButton* pColorA = new OptionColorButton(
655 bLowColor ? qRgb(0, 0, 255) : qRgb(0, 0, 200) /*blue*/, "ColorA", &m_options->m_colorA, page);
656 label = new QLabel(i18n("Color A:"), page);
657 label->setBuddy(pColorA);
658 addOptionItem(pColorA);
659 gbox->addWidget(label, line, 0);
660 gbox->addWidget(pColorA, line, 1);
661 ++line;
662
663 OptionColorButton* pColorB = new OptionColorButton(
664 bLowColor ? qRgb(0, 128, 0) : qRgb(0, 150, 0) /*green*/, "ColorB", &m_options->m_colorB, page);
665 label = new QLabel(i18n("Color B:"), page);
666 label->setBuddy(pColorB);
667 addOptionItem(pColorB);
668 gbox->addWidget(label, line, 0);
669 gbox->addWidget(pColorB, line, 1);
670 ++line;
671
672 OptionColorButton* pColorC = new OptionColorButton(
673 bLowColor ? qRgb(128, 0, 128) : qRgb(150, 0, 150) /*magenta*/, "ColorC", &m_options->m_colorC, page);
674 label = new QLabel(i18n("Color C:"), page);
675 label->setBuddy(pColorC);
676 addOptionItem(pColorC);
677 gbox->addWidget(label, line, 0);
678 gbox->addWidget(pColorC, line, 1);
679 ++line;
680
681 OptionColorButton* pColorForConflict = new OptionColorButton(Qt::red, "ColorForConflict", &m_options->m_colorForConflict, page);
682 label = new QLabel(i18n("Conflict color:"), page);
683 label->setBuddy(pColorForConflict);
684 addOptionItem(pColorForConflict);
685 gbox->addWidget(label, line, 0);
686 gbox->addWidget(pColorForConflict, line, 1);
687 ++line;
688
689 OptionColorButton* pColor = new OptionColorButton(
690 bLowColor ? qRgb(192, 192, 192) : qRgb(220, 220, 100), "CurrentRangeBgColor", &m_options->m_currentRangeBgColor, page);
691 label = new QLabel(i18n("Current range background color:"), page);
692 label->setBuddy(pColor);
693 addOptionItem(pColor);
694 gbox->addWidget(label, line, 0);
695 gbox->addWidget(pColor, line, 1);
696 ++line;
697
698 pColor = new OptionColorButton(
699 bLowColor ? qRgb(255, 255, 0) : qRgb(255, 255, 150), "CurrentRangeDiffBgColor", &m_options->m_currentRangeDiffBgColor, page);
700 label = new QLabel(i18n("Current range diff background color:"), page);
701 label->setBuddy(pColor);
702 addOptionItem(pColor);
703 gbox->addWidget(label, line, 0);
704 gbox->addWidget(pColor, line, 1);
705 ++line;
706
707 pColor = new OptionColorButton(qRgb(0xff, 0xd0, 0x80), "ManualAlignmentRangeColor", &m_options->m_manualHelpRangeColor, page);
708 label = new QLabel(i18n("Color for manually aligned difference ranges:"), page);
709 label->setBuddy(pColor);
710 addOptionItem(pColor);
711 gbox->addWidget(label, line, 0);
712 gbox->addWidget(pColor, line, 1);
713 ++line;
714
715 label = new QLabel(i18n("Folder Comparison View:"), page);
716 gbox->addWidget(label, line, 0);
717 label->setFont(f);
718 ++line;
719
720 pColor = new OptionColorButton(qRgb(0, 0xd0, 0), "NewestFileColor", &m_options->m_newestFileColor, page);
721 label = new QLabel(i18n("Newest file color:"), page);
722 label->setBuddy(pColor);
723 addOptionItem(pColor);
724 gbox->addWidget(label, line, 0);
725 gbox->addWidget(pColor, line, 1);
726 QString dirColorTip = i18n("Changing this color will only be effective when starting the next folder comparison.");
727 label->setToolTip(dirColorTip);
728 ++line;
729
730 pColor = new OptionColorButton(qRgb(0xf0, 0, 0), "OldestFileColor", &m_options->m_oldestFileColor, page);
731 label = new QLabel(i18n("Oldest file color:"), page);
732 label->setBuddy(pColor);
733 addOptionItem(pColor);
734 gbox->addWidget(label, line, 0);
735 gbox->addWidget(pColor, line, 1);
736 label->setToolTip(dirColorTip);
737 ++line;
738
739 pColor = new OptionColorButton(qRgb(0xc0, 0xc0, 0), "MidAgeFileColor", &m_options->m_midAgeFileColor, page);
740 label = new QLabel(i18n("Middle age file color:"), page);
741 label->setBuddy(pColor);
742 addOptionItem(pColor);
743 gbox->addWidget(label, line, 0);
744 gbox->addWidget(pColor, line, 1);
745 label->setToolTip(dirColorTip);
746 ++line;
747
748 pColor = new OptionColorButton(qRgb(0, 0, 0), "MissingFileColor", &m_options->m_missingFileColor, page);
749 label = new QLabel(i18n("Color for missing files:"), page);
750 label->setBuddy(pColor);
751 addOptionItem(pColor);
752 gbox->addWidget(label, line, 0);
753 gbox->addWidget(pColor, line, 1);
754 label->setToolTip(dirColorTip);
755 ++line;
756
757 topLayout->addStretch(10);
758 }
759
setupEditPage()760 void OptionDialog::setupEditPage()
761 {
762 QScrollArea* pageFrame = new QScrollArea();
763 KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18n("Editor"));
764 pageItem->setHeader(i18n("Editor Behavior"));
765 pageItem->setIcon(QIcon::fromTheme(QStringLiteral("accessories-text-editor")));
766 addPage(pageItem);
767
768 QVBoxLayout* scrollLayout = new QVBoxLayout();
769 scrollLayout->setContentsMargins(2, 2, 2, 2);
770 scrollLayout->addWidget(pageFrame);
771
772 QScopedPointer<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
773 scrollArea->setupUi(pageFrame);
774
775 QWidget* page = pageFrame->findChild<QWidget*>("contents");
776
777 QVBoxLayout* topLayout = new QVBoxLayout(page);
778 topLayout->setContentsMargins(5, 5, 5, 5);
779
780 QGridLayout* gbox = new QGridLayout();
781 gbox->setColumnStretch(1, 5);
782 topLayout->addLayout(gbox);
783 QLabel* label;
784 int line = 0;
785
786 OptionCheckBox* pReplaceTabs = new OptionCheckBox(i18n("Tab inserts spaces"), false, "ReplaceTabs", &m_options->m_bReplaceTabs, page);
787 addOptionItem(pReplaceTabs);
788 gbox->addWidget(pReplaceTabs, line, 0, 1, 2);
789 pReplaceTabs->setToolTip(i18n(
790 "On: Pressing tab generates the appropriate number of spaces.\n"
791 "Off: A tab character will be inserted."));
792 ++line;
793
794 OptionIntEdit* pTabSize = new OptionIntEdit(8, "TabSize", &m_options->m_tabSize, 1, 100, page);
795 label = new QLabel(i18n("Tab size:"), page);
796 label->setBuddy(pTabSize);
797 addOptionItem(pTabSize);
798 gbox->addWidget(label, line, 0);
799 gbox->addWidget(pTabSize, line, 1);
800 ++line;
801
802 OptionCheckBox* pAutoIndentation = new OptionCheckBox(i18n("Auto indentation"), true, "AutoIndentation", &m_options->m_bAutoIndentation, page);
803 gbox->addWidget(pAutoIndentation, line, 0, 1, 2);
804 addOptionItem(pAutoIndentation);
805 pAutoIndentation->setToolTip(i18n(
806 "On: The indentation of the previous line is used for a new line.\n"));
807 ++line;
808
809 OptionCheckBox* pAutoCopySelection = new OptionCheckBox(i18n("Auto copy selection"), false, "AutoCopySelection", &m_options->m_bAutoCopySelection, page);
810 gbox->addWidget(pAutoCopySelection, line, 0, 1, 2);
811 addOptionItem(pAutoCopySelection);
812 pAutoCopySelection->setToolTip(i18n(
813 "On: Any selection is immediately written to the clipboard.\n"
814 "Off: You must explicitly copy e.g. via Ctrl-C."));
815 ++line;
816
817 label = new QLabel(i18n("Line end style:"), page);
818 gbox->addWidget(label, line, 0);
819
820 OptionComboBox* pLineEndStyle = new OptionComboBox(eLineEndStyleAutoDetect, "LineEndStyle", (int*)&m_options->m_lineEndStyle, page);
821 gbox->addWidget(pLineEndStyle, line, 1);
822 addOptionItem(pLineEndStyle);
823 pLineEndStyle->insertItem(eLineEndStyleUnix, i18nc("Unix line ending", "Unix"));
824 pLineEndStyle->insertItem(eLineEndStyleDos, i18nc("Dos/Windows line ending", "Dos/Windows"));
825 pLineEndStyle->insertItem(eLineEndStyleAutoDetect, i18nc("Automatically detected line ending", "Autodetect"));
826
827 label->setToolTip(i18n(
828 "Sets the line endings for when an edited file is saved.\n"
829 "DOS/Windows: CR+LF; UNIX: LF; with CR=0D, LF=0A"));
830 ++line;
831
832 topLayout->addStretch(10);
833 }
834
setupDiffPage()835 void OptionDialog::setupDiffPage()
836 {
837 QScrollArea* pageFrame = new QScrollArea();
838 KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18n("Diff"));
839 pageItem->setHeader(i18n("Diff Settings"));
840 pageItem->setIcon(QIcon::fromTheme(QStringLiteral("text-x-patch")));
841 addPage(pageItem);
842
843 QVBoxLayout* scrollLayout = new QVBoxLayout();
844 scrollLayout->setContentsMargins(2, 2, 2, 2);
845 scrollLayout->addWidget(pageFrame);
846
847 QScopedPointer<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
848 scrollArea->setupUi(pageFrame);
849
850 QWidget* page = pageFrame->findChild<QWidget*>("contents");
851
852 QVBoxLayout* topLayout = new QVBoxLayout(page);
853 topLayout->setContentsMargins(5, 5, 5, 5);
854
855 QGridLayout* gbox = new QGridLayout();
856 gbox->setColumnStretch(1, 5);
857 topLayout->addLayout(gbox);
858 int line = 0;
859
860 QLabel* label = nullptr;
861
862 m_options->m_bPreserveCarriageReturn = false;
863 /*
864 OptionCheckBox* pPreserveCarriageReturn = new OptionCheckBox( i18n("Preserve carriage return"), false, "PreserveCarriageReturn", &m_options->m_bPreserveCarriageReturn, page, this );
865 addOptionItem(pPreserveCarriageReturn);
866 gbox->addWidget( pPreserveCarriageReturn, line, 0, 1, 2 );
867 pPreserveCarriageReturn->setToolTip( i18n(
868 "Show carriage return characters '\\r' if they exist.\n"
869 "Helps to compare files that were modified under different operating systems.")
870 );
871 ++line;
872 */
873 OptionCheckBox* pIgnoreNumbers = new OptionCheckBox(i18n("Ignore numbers (treat as white space)"), false, "IgnoreNumbers", &m_options->m_bIgnoreNumbers, page);
874 gbox->addWidget(pIgnoreNumbers, line, 0, 1, 2);
875 addOptionItem(pIgnoreNumbers);
876 pIgnoreNumbers->setToolTip(i18n(
877 "Ignore number characters during line matching phase. (Similar to Ignore white space.)\n"
878 "Might help to compare files with numeric data."));
879 ++line;
880
881 OptionCheckBox* pIgnoreComments = new OptionCheckBox(i18n("Ignore C/C++ comments (treat as white space)"), false, "IgnoreComments", &m_options->m_bIgnoreComments, page);
882 gbox->addWidget(pIgnoreComments, line, 0, 1, 2);
883 addOptionItem(pIgnoreComments);
884 pIgnoreComments->setToolTip(i18n("Treat C/C++ comments like white space."));
885 ++line;
886
887 OptionCheckBox* pIgnoreCase = new OptionCheckBox(i18n("Ignore case (treat as white space)"), false, "IgnoreCase", &m_options->m_bIgnoreCase, page);
888 gbox->addWidget(pIgnoreCase, line, 0, 1, 2);
889 addOptionItem(pIgnoreCase);
890 pIgnoreCase->setToolTip(i18n(
891 "Treat case differences like white space changes. ('a'<=>'A')"));
892 ++line;
893
894 label = new QLabel(i18n("Preprocessor command:"), page);
895 gbox->addWidget(label, line, 0);
896 OptionLineEdit* pLE = new OptionLineEdit("", "PreProcessorCmd", &m_options->m_PreProcessorCmd, page);
897 gbox->addWidget(pLE, line, 1);
898 addOptionItem(pLE);
899 label->setToolTip(i18n("User defined pre-processing. (See the docs for details.)"));
900 ++line;
901
902 label = new QLabel(i18n("Line-matching preprocessor command:"), page);
903 gbox->addWidget(label, line, 0);
904 pLE = new OptionLineEdit("", "LineMatchingPreProcessorCmd", &m_options->m_LineMatchingPreProcessorCmd, page);
905 gbox->addWidget(pLE, line, 1);
906 addOptionItem(pLE);
907 label->setToolTip(i18n("This pre-processor is only used during line matching.\n(See the docs for details.)"));
908 ++line;
909
910 OptionCheckBox* pTryHard = new OptionCheckBox(i18n("Try hard (slower)"), true, "TryHard", &m_options->m_bTryHard, page);
911 gbox->addWidget(pTryHard, line, 0, 1, 2);
912 addOptionItem(pTryHard);
913 pTryHard->setToolTip(i18n(
914 "Enables the --minimal option for the external diff.\n"
915 "The analysis of big files will be much slower."));
916 ++line;
917
918 OptionCheckBox* pDiff3AlignBC = new OptionCheckBox(i18n("Align B and C for 3 input files"), false, "Diff3AlignBC", &m_options->m_bDiff3AlignBC, page);
919 gbox->addWidget(pDiff3AlignBC, line, 0, 1, 2);
920 addOptionItem(pDiff3AlignBC);
921 pDiff3AlignBC->setToolTip(i18n(
922 "Try to align B and C when comparing or merging three input files.\n"
923 "Not recommended for merging because merge might get more complicated.\n"
924 "(Default is off.)"));
925 ++line;
926
927 topLayout->addStretch(10);
928 }
929
setupMergePage()930 void OptionDialog::setupMergePage()
931 {
932 QScrollArea* pageFrame = new QScrollArea();
933 KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18nc("Settings page", "Merge"));
934 pageItem->setHeader(i18n("Merge Settings"));
935 pageItem->setIcon(QIcon::fromTheme(QStringLiteral("merge")));
936 addPage(pageItem);
937
938 QVBoxLayout* scrollLayout = new QVBoxLayout();
939 scrollLayout->setContentsMargins(2, 2, 2, 2);
940 scrollLayout->addWidget(pageFrame);
941
942 QScopedPointer<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
943 scrollArea->setupUi(pageFrame);
944
945 QWidget* page = pageFrame->findChild<QWidget*>("contents");
946
947 QVBoxLayout* topLayout = new QVBoxLayout(page);
948 topLayout->setContentsMargins(5, 5, 5, 5);
949
950 QGridLayout* gbox = new QGridLayout();
951 gbox->setColumnStretch(1, 5);
952 topLayout->addLayout(gbox);
953 int line = 0;
954
955 QLabel* label = nullptr;
956
957 label = new QLabel(i18n("Auto advance delay (ms):"), page);
958 gbox->addWidget(label, line, 0);
959 OptionIntEdit* pAutoAdvanceDelay = new OptionIntEdit(500, "AutoAdvanceDelay", &m_options->m_autoAdvanceDelay, 0, 2000, page);
960 gbox->addWidget(pAutoAdvanceDelay, line, 1);
961 addOptionItem(pAutoAdvanceDelay);
962 label->setToolTip(i18n(
963 "When in Auto-Advance mode the result of the current selection is shown \n"
964 "for the specified time, before jumping to the next conflict. Range: 0-2000 ms"));
965 ++line;
966
967 OptionCheckBox* pShowInfoDialogs = new OptionCheckBox(i18n("Show info dialogs"), true, "ShowInfoDialogs", &m_options->m_bShowInfoDialogs, page);
968 gbox->addWidget(pShowInfoDialogs, line, 0, 1, 2);
969 addOptionItem(pShowInfoDialogs);
970 pShowInfoDialogs->setToolTip(i18n("Show a dialog with information about the number of conflicts."));
971 ++line;
972
973 label = new QLabel(i18n("White space 2-file merge default:"), page);
974 gbox->addWidget(label, line, 0);
975 OptionComboBox* pWhiteSpace2FileMergeDefault = new OptionComboBox(0, "WhiteSpace2FileMergeDefault", &m_options->m_whiteSpace2FileMergeDefault, page);
976 gbox->addWidget(pWhiteSpace2FileMergeDefault, line, 1);
977 addOptionItem(pWhiteSpace2FileMergeDefault);
978 pWhiteSpace2FileMergeDefault->insertItem(0, i18n("Manual Choice"));
979 pWhiteSpace2FileMergeDefault->insertItem(1, i18n("A"));
980 pWhiteSpace2FileMergeDefault->insertItem(2, i18n("B"));
981 label->setToolTip(i18n(
982 "Allow the merge algorithm to automatically select an input for "
983 "white-space-only changes."));
984 ++line;
985
986 label = new QLabel(i18n("White space 3-file merge default:"), page);
987 gbox->addWidget(label, line, 0);
988 OptionComboBox* pWhiteSpace3FileMergeDefault = new OptionComboBox(0, "WhiteSpace3FileMergeDefault", &m_options->m_whiteSpace3FileMergeDefault, page);
989 gbox->addWidget(pWhiteSpace3FileMergeDefault, line, 1);
990 addOptionItem(pWhiteSpace3FileMergeDefault);
991 pWhiteSpace3FileMergeDefault->insertItem(0, i18n("Manual Choice"));
992 pWhiteSpace3FileMergeDefault->insertItem(1, i18n("A"));
993 pWhiteSpace3FileMergeDefault->insertItem(2, i18n("B"));
994 pWhiteSpace3FileMergeDefault->insertItem(3, i18n("C"));
995 label->setToolTip(i18n(
996 "Allow the merge algorithm to automatically select an input for "
997 "white-space-only changes."));
998 ++line;
999
1000 QGroupBox* pGroupBox = new QGroupBox(i18n("Automatic Merge Regular Expression"));
1001 gbox->addWidget(pGroupBox, line, 0, 1, 2);
1002 ++line;
1003 {
1004 gbox = new QGridLayout(pGroupBox);
1005 gbox->setColumnStretch(1, 10);
1006 line = 0;
1007
1008 label = new QLabel(i18n("Auto merge regular expression:"), page);
1009 gbox->addWidget(label, line, 0);
1010 m_pAutoMergeRegExpLineEdit = new OptionLineEdit(".*\\$(Version|Header|Date|Author).*\\$.*", "AutoMergeRegExp", &m_options->m_autoMergeRegExp, page);
1011 gbox->addWidget(m_pAutoMergeRegExpLineEdit, line, 1);
1012 addOptionItem(m_pAutoMergeRegExpLineEdit);
1013 label->setToolTip(s_autoMergeRegExpToolTip);
1014 ++line;
1015
1016 OptionCheckBox* pAutoMergeRegExp = new OptionCheckBox(i18n("Run regular expression auto merge on merge start"), false, "RunRegExpAutoMergeOnMergeStart", &m_options->m_bRunRegExpAutoMergeOnMergeStart, page);
1017 addOptionItem(pAutoMergeRegExp);
1018 gbox->addWidget(pAutoMergeRegExp, line, 0, 1, 2);
1019 pAutoMergeRegExp->setToolTip(i18n("Run the merge for auto merge regular expressions\n"
1020 "immediately when a merge starts.\n"));
1021 ++line;
1022 }
1023
1024 pGroupBox = new QGroupBox(i18n("Version Control History Merging"));
1025 gbox->addWidget(pGroupBox, line, 0, 1, 2);
1026 ++line;
1027 {
1028 gbox = new QGridLayout(pGroupBox);
1029 gbox->setColumnStretch(1, 10);
1030 line = 0;
1031
1032 label = new QLabel(i18n("History start regular expression:"), page);
1033 gbox->addWidget(label, line, 0);
1034 m_pHistoryStartRegExpLineEdit = new OptionLineEdit(".*\\$Log.*\\$.*", "HistoryStartRegExp", &m_options->m_historyStartRegExp, page);
1035 gbox->addWidget(m_pHistoryStartRegExpLineEdit, line, 1);
1036 addOptionItem(m_pHistoryStartRegExpLineEdit);
1037 label->setToolTip(s_historyStartRegExpToolTip);
1038 ++line;
1039
1040 label = new QLabel(i18n("History entry start regular expression:"), page);
1041 gbox->addWidget(label, line, 0);
1042 // Example line: "** \main\rolle_fsp_dev_008\1 17 Aug 2001 10:45:44 rolle"
1043 QString historyEntryStartDefault =
1044 "\\s*\\\\main\\\\(\\S+)\\s+" // Start with "\main\"
1045 "([0-9]+) " // day
1046 "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) " //month
1047 "([0-9][0-9][0-9][0-9]) " // year
1048 "([0-9][0-9]:[0-9][0-9]:[0-9][0-9])\\s+(.*)"; // time, name
1049
1050 m_pHistoryEntryStartRegExpLineEdit = new OptionLineEdit(historyEntryStartDefault, "HistoryEntryStartRegExp", &m_options->m_historyEntryStartRegExp, page);
1051 gbox->addWidget(m_pHistoryEntryStartRegExpLineEdit, line, 1);
1052 addOptionItem(m_pHistoryEntryStartRegExpLineEdit);
1053 label->setToolTip(s_historyEntryStartRegExpToolTip);
1054 ++line;
1055
1056 m_pHistoryMergeSorting = new OptionCheckBox(i18n("History merge sorting"), false, "HistoryMergeSorting", &m_options->m_bHistoryMergeSorting, page);
1057 gbox->addWidget(m_pHistoryMergeSorting, line, 0, 1, 2);
1058 addOptionItem(m_pHistoryMergeSorting);
1059 m_pHistoryMergeSorting->setToolTip(i18n("Sort version control history by a key."));
1060 ++line;
1061 //QString branch = newHistoryEntry.cap(1);
1062 //int day = newHistoryEntry.cap(2).toInt();
1063 //int month = QString("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec").find(newHistoryEntry.cap(3))/4 + 1;
1064 //int year = newHistoryEntry.cap(4).toInt();
1065 //QString time = newHistoryEntry.cap(5);
1066 //QString name = newHistoryEntry.cap(6);
1067 QString defaultSortKeyOrder = "4,3,2,5,1,6"; //QDate(year,month,day).toString(Qt::ISODate) +" "+ time + " " + branch + " " + name;
1068
1069 label = new QLabel(i18n("History entry start sort key order:"), page);
1070 gbox->addWidget(label, line, 0);
1071 m_pHistorySortKeyOrderLineEdit = new OptionLineEdit(defaultSortKeyOrder, "HistoryEntryStartSortKeyOrder", &m_options->m_historyEntryStartSortKeyOrder, page);
1072 gbox->addWidget(m_pHistorySortKeyOrderLineEdit, line, 1);
1073 addOptionItem(m_pHistorySortKeyOrderLineEdit);
1074 label->setToolTip(s_historyEntryStartSortKeyOrderToolTip);
1075 m_pHistorySortKeyOrderLineEdit->setEnabled(false);
1076 chk_connect(m_pHistoryMergeSorting, &OptionCheckBox::toggled, m_pHistorySortKeyOrderLineEdit, &OptionLineEdit::setEnabled);
1077 ++line;
1078
1079 m_pHistoryAutoMerge = new OptionCheckBox(i18n("Merge version control history on merge start"), false, "RunHistoryAutoMergeOnMergeStart", &m_options->m_bRunHistoryAutoMergeOnMergeStart, page);
1080 addOptionItem(m_pHistoryAutoMerge);
1081 gbox->addWidget(m_pHistoryAutoMerge, line, 0, 1, 2);
1082 m_pHistoryAutoMerge->setToolTip(i18n("Run version control history automerge on merge start."));
1083 ++line;
1084
1085 OptionIntEdit* pMaxNofHistoryEntries = new OptionIntEdit(-1, "MaxNofHistoryEntries", &m_options->m_maxNofHistoryEntries, -1, 1000, page);
1086 label = new QLabel(i18n("Max number of history entries:"), page);
1087 gbox->addWidget(label, line, 0);
1088 gbox->addWidget(pMaxNofHistoryEntries, line, 1);
1089 addOptionItem(pMaxNofHistoryEntries);
1090 pMaxNofHistoryEntries->setToolTip(i18n("Cut off after specified number. Use -1 for infinite number of entries."));
1091 ++line;
1092 }
1093
1094 QPushButton* pButton = new QPushButton(i18n("Test your regular expressions"), page);
1095 gbox->addWidget(pButton, line, 0);
1096 chk_connect(pButton, &QPushButton::clicked, this, &OptionDialog::slotHistoryMergeRegExpTester);
1097 ++line;
1098
1099 label = new QLabel(i18n("Irrelevant merge command:"), page);
1100 gbox->addWidget(label, line, 0);
1101 OptionLineEdit* pLE = new OptionLineEdit("", "IrrelevantMergeCmd", &m_options->m_IrrelevantMergeCmd, page);
1102 gbox->addWidget(pLE, line, 1);
1103 addOptionItem(pLE);
1104 label->setToolTip(i18n("If specified this script is run after automerge\n"
1105 "when no other relevant changes were detected.\n"
1106 "Called with the parameters: filename1 filename2 filename3"));
1107 ++line;
1108
1109 OptionCheckBox* pAutoSaveAndQuit = new OptionCheckBox(i18n("Auto save and quit on merge without conflicts"), false,
1110 "AutoSaveAndQuitOnMergeWithoutConflicts", &m_options->m_bAutoSaveAndQuitOnMergeWithoutConflicts, page);
1111 gbox->addWidget(pAutoSaveAndQuit, line, 0, 1, 2);
1112 addOptionItem(pAutoSaveAndQuit);
1113 pAutoSaveAndQuit->setToolTip(i18n("If KDiff3 was started for a file-merge from the command line and all\n"
1114 "conflicts are solvable without user interaction then automatically save and quit.\n"
1115 "(Similar to command line option \"--auto\".)"));
1116 ++line;
1117
1118 topLayout->addStretch(10);
1119 }
1120
setupDirectoryMergePage()1121 void OptionDialog::setupDirectoryMergePage()
1122 {
1123 QScrollArea* pageFrame = new QScrollArea();
1124 KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18n("Folder"));
1125 pageItem->setHeader(i18n("Folder"));
1126 pageItem->setIcon(QIcon::fromTheme(QStringLiteral("inode-directory")));
1127 addPage(pageItem);
1128
1129 QVBoxLayout* scrollLayout = new QVBoxLayout();
1130 scrollLayout->setContentsMargins(2, 2, 2, 2);
1131 scrollLayout->addWidget(pageFrame);
1132
1133 QScopedPointer<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
1134 scrollArea->setupUi(pageFrame);
1135
1136 QWidget* page = pageFrame->findChild<QWidget*>("contents");
1137 QVBoxLayout* topLayout = new QVBoxLayout(page);
1138 topLayout->setContentsMargins(5, 5, 5, 5);
1139
1140 QGridLayout* gbox = new QGridLayout();
1141 gbox->setColumnStretch(1, 5);
1142 topLayout->addLayout(gbox);
1143 int line = 0;
1144
1145 OptionCheckBox* pRecursiveDirs = new OptionCheckBox(i18n("Recursive folders"), true, "RecursiveDirs", &m_options->m_bDmRecursiveDirs, page);
1146 gbox->addWidget(pRecursiveDirs, line, 0, 1, 2);
1147 addOptionItem(pRecursiveDirs);
1148 pRecursiveDirs->setToolTip(i18n("Whether to analyze subfolders or not."));
1149 ++line;
1150 QLabel* label = new QLabel(i18n("File pattern(s):"), page);
1151 gbox->addWidget(label, line, 0);
1152 OptionLineEdit* pFilePattern = new OptionLineEdit("*", "FilePattern", &m_options->m_DmFilePattern, page);
1153 gbox->addWidget(pFilePattern, line, 1);
1154 addOptionItem(pFilePattern);
1155 label->setToolTip(i18n(
1156 "Pattern(s) of files to be analyzed. \n"
1157 "Wildcards: '*' and '?'\n"
1158 "Several Patterns can be specified by using the separator: ';'"));
1159 ++line;
1160
1161 label = new QLabel(i18n("File-anti-pattern(s):"), page);
1162 gbox->addWidget(label, line, 0);
1163 OptionLineEdit* pFileAntiPattern = new OptionLineEdit("*.orig;*.o;*.obj;*.rej;*.bak", "FileAntiPattern", &m_options->m_DmFileAntiPattern, page);
1164 gbox->addWidget(pFileAntiPattern, line, 1);
1165 addOptionItem(pFileAntiPattern);
1166 label->setToolTip(i18n(
1167 "Pattern(s) of files to be excluded from analysis. \n"
1168 "Wildcards: '*' and '?'\n"
1169 "Several Patterns can be specified by using the separator: ';'"));
1170 ++line;
1171
1172 label = new QLabel(i18n("Folder-anti-pattern(s):"), page);
1173 gbox->addWidget(label, line, 0);
1174 OptionLineEdit* pDirAntiPattern = new OptionLineEdit("CVS;.deps;.svn;.hg;.git", "DirAntiPattern", &m_options->m_DmDirAntiPattern, page);
1175 gbox->addWidget(pDirAntiPattern, line, 1);
1176 addOptionItem(pDirAntiPattern);
1177 label->setToolTip(i18n(
1178 "Pattern(s) of folders to be excluded from analysis. \n"
1179 "Wildcards: '*' and '?'\n"
1180 "Several Patterns can be specified by using the separator: ';'"));
1181 ++line;
1182
1183 OptionCheckBox* pUseCvsIgnore = new OptionCheckBox(i18n("Use Ignore File"), false, "UseCvsIgnore", &m_options->m_bDmUseCvsIgnore, page);
1184 gbox->addWidget(pUseCvsIgnore, line, 0, 1, 2);
1185 addOptionItem(pUseCvsIgnore);
1186 pUseCvsIgnore->setToolTip(i18n(
1187 "Extends the antipattern to anything that would be ignored by source control.\n"
1188 "Via local ignore files this can be folder-specific."));
1189 ++line;
1190
1191 OptionCheckBox* pFindHidden = new OptionCheckBox(i18n("Find hidden files and folders"), true, "FindHidden", &m_options->m_bDmFindHidden, page);
1192 gbox->addWidget(pFindHidden, line, 0, 1, 2);
1193 addOptionItem(pFindHidden);
1194 pFindHidden->setToolTip(i18n("Finds hidden files and folders."));
1195 ++line;
1196
1197 OptionCheckBox* pFollowFileLinks = new OptionCheckBox(i18n("Follow file links"), true, "FollowFileLinks", &m_options->m_bDmFollowFileLinks, page);
1198 gbox->addWidget(pFollowFileLinks, line, 0, 1, 2);
1199 addOptionItem(pFollowFileLinks);
1200 pFollowFileLinks->setToolTip(i18n(
1201 "On: Compare the file the link points to.\n"
1202 "Off: Compare the links."));
1203 ++line;
1204
1205 OptionCheckBox* pFollowDirLinks = new OptionCheckBox(i18n("Follow folder links"), true, "FollowDirLinks", &m_options->m_bDmFollowDirLinks, page);
1206 gbox->addWidget(pFollowDirLinks, line, 0, 1, 2);
1207 addOptionItem(pFollowDirLinks);
1208 pFollowDirLinks->setToolTip(i18n(
1209 "On: Compare the folder the link points to.\n"
1210 "Off: Compare the links."));
1211 ++line;
1212
1213 #if defined(Q_OS_WIN)
1214 bool bCaseSensitiveFilenameComparison = false;
1215 #else
1216 bool bCaseSensitiveFilenameComparison = true;
1217 #endif
1218 OptionCheckBox* pCaseSensitiveFileNames = new OptionCheckBox(i18n("Case sensitive filename comparison"), bCaseSensitiveFilenameComparison, "CaseSensitiveFilenameComparison", &m_options->m_bDmCaseSensitiveFilenameComparison, page);
1219 gbox->addWidget(pCaseSensitiveFileNames, line, 0, 1, 2);
1220 addOptionItem(pCaseSensitiveFileNames);
1221 pCaseSensitiveFileNames->setToolTip(i18n(
1222 "The folder comparison will compare files or folders when their names match.\n"
1223 "Set this option if the case of the names must match. (Default for Windows is off, otherwise on.)"));
1224 ++line;
1225
1226 OptionCheckBox* pUnfoldSubdirs = new OptionCheckBox(i18n("Unfold all subfolders on load"), false, "UnfoldSubdirs", &m_options->m_bDmUnfoldSubdirs, page);
1227 gbox->addWidget(pUnfoldSubdirs, line, 0, 1, 2);
1228 addOptionItem(pUnfoldSubdirs);
1229 pUnfoldSubdirs->setToolTip(i18n(
1230 "On: Unfold all subfolders when starting a folder diff.\n"
1231 "Off: Leave subfolders folded."));
1232 ++line;
1233
1234 OptionCheckBox* pSkipDirStatus = new OptionCheckBox(i18n("Skip folder status report"), false, "SkipDirStatus", &m_options->m_bDmSkipDirStatus, page);
1235 gbox->addWidget(pSkipDirStatus, line, 0, 1, 2);
1236 addOptionItem(pSkipDirStatus);
1237 pSkipDirStatus->setToolTip(i18n(
1238 "On: Do not show the Folder Comparison Status.\n"
1239 "Off: Show the status dialog on start."));
1240 ++line;
1241
1242 QGroupBox* pBG = new QGroupBox(i18n("File Comparison Mode"));
1243 gbox->addWidget(pBG, line, 0, 1, 2);
1244
1245 QVBoxLayout* pBGLayout = new QVBoxLayout(pBG);
1246
1247 OptionRadioButton* pBinaryComparison = new OptionRadioButton(i18n("Binary comparison"), true, "BinaryComparison", &m_options->m_bDmBinaryComparison, pBG);
1248 addOptionItem(pBinaryComparison);
1249 pBinaryComparison->setToolTip(i18n("Binary comparison of each file. (Default)"));
1250 pBGLayout->addWidget(pBinaryComparison);
1251
1252 OptionRadioButton* pFullAnalysis = new OptionRadioButton(i18n("Full analysis"), false, "FullAnalysis", &m_options->m_bDmFullAnalysis, pBG);
1253 addOptionItem(pFullAnalysis);
1254 pFullAnalysis->setToolTip(i18n("Do a full analysis and show statistics information in extra columns.\n"
1255 "(Slower than a binary comparison, much slower for binary files.)"));
1256 pBGLayout->addWidget(pFullAnalysis);
1257
1258 OptionRadioButton* pTrustDate = new OptionRadioButton(i18n("Trust the size and modification date (unsafe)"), false, "TrustDate", &m_options->m_bDmTrustDate, pBG);
1259 addOptionItem(pTrustDate);
1260 pTrustDate->setToolTip(i18n("Assume that files are equal if the modification date and file length are equal.\n"
1261 "Files with equal contents but different modification dates will appear as different.\n"
1262 "Useful for big folders or slow networks."));
1263 pBGLayout->addWidget(pTrustDate);
1264
1265 OptionRadioButton* pTrustDateFallbackToBinary = new OptionRadioButton(i18n("Trust the size and date, but use binary comparison if date does not match (unsafe)"), false, "TrustDateFallbackToBinary", &m_options->m_bDmTrustDateFallbackToBinary, pBG);
1266 addOptionItem(pTrustDateFallbackToBinary);
1267 pTrustDateFallbackToBinary->setToolTip(i18n("Assume that files are equal if the modification date and file length are equal.\n"
1268 "If the dates are not equal but the sizes are, use binary comparison.\n"
1269 "Useful for big folders or slow networks."));
1270 pBGLayout->addWidget(pTrustDateFallbackToBinary);
1271
1272 OptionRadioButton* pTrustSize = new OptionRadioButton(i18n("Trust the size (unsafe)"), false, "TrustSize", &m_options->m_bDmTrustSize, pBG);
1273 addOptionItem(pTrustSize);
1274 pTrustSize->setToolTip(i18n("Assume that files are equal if their file lengths are equal.\n"
1275 "Useful for big folders or slow networks when the date is modified during download."));
1276 pBGLayout->addWidget(pTrustSize);
1277
1278 ++line;
1279
1280 // Some two Dir-options: Affects only the default actions.
1281 OptionCheckBox* pSyncMode = new OptionCheckBox(i18n("Synchronize folders"), false, "SyncMode", &m_options->m_bDmSyncMode, page);
1282 addOptionItem(pSyncMode);
1283 gbox->addWidget(pSyncMode, line, 0, 1, 2);
1284 pSyncMode->setToolTip(i18n(
1285 "Offers to store files in both folders so that\n"
1286 "both folders are the same afterwards.\n"
1287 "Works only when comparing two folders without specifying a destination."));
1288 ++line;
1289
1290 // Allow white-space only differences to be considered equal
1291 OptionCheckBox* pWhiteSpaceDiffsEqual = new OptionCheckBox(i18n("White space differences considered equal"), true, "WhiteSpaceEqual", &m_options->m_bDmWhiteSpaceEqual, page);
1292 addOptionItem(pWhiteSpaceDiffsEqual);
1293 gbox->addWidget(pWhiteSpaceDiffsEqual, line, 0, 1, 2);
1294 pWhiteSpaceDiffsEqual->setToolTip(i18n(
1295 "If files differ only by white space consider them equal.\n"
1296 "This is only active when full analysis is chosen."));
1297 chk_connect(pFullAnalysis, &OptionRadioButton::toggled, pWhiteSpaceDiffsEqual, &OptionCheckBox::setEnabled);
1298 pWhiteSpaceDiffsEqual->setEnabled(false);
1299 ++line;
1300
1301 OptionCheckBox* pCopyNewer = new OptionCheckBox(i18n("Copy newer instead of merging (unsafe)"), false, "CopyNewer", &m_options->m_bDmCopyNewer, page);
1302 addOptionItem(pCopyNewer);
1303 gbox->addWidget(pCopyNewer, line, 0, 1, 2);
1304 pCopyNewer->setToolTip(i18n(
1305 "Do not look inside, just take the newer file.\n"
1306 "(Use this only if you know what you are doing!)\n"
1307 "Only effective when comparing two folders."));
1308 ++line;
1309
1310 OptionCheckBox* pCreateBakFiles = new OptionCheckBox(i18n("Backup files (.orig)"), true, "CreateBakFiles", &m_options->m_bDmCreateBakFiles, page);
1311 gbox->addWidget(pCreateBakFiles, line, 0, 1, 2);
1312 addOptionItem(pCreateBakFiles);
1313 pCreateBakFiles->setToolTip(i18n(
1314 "If a file would be saved over an old file, then the old file\n"
1315 "will be renamed with a '.orig' extension instead of being deleted."));
1316 ++line;
1317
1318 topLayout->addStretch(10);
1319 }
setupRegionalPage()1320 void OptionDialog::setupRegionalPage()
1321 {
1322 QScrollArea* pageFrame = new QScrollArea();
1323 KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18n("Regional Settings"));
1324 pageItem->setHeader(i18n("Regional Settings"));
1325 pageItem->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-locale")));
1326 addPage(pageItem);
1327
1328 QVBoxLayout* scrollLayout = new QVBoxLayout();
1329 scrollLayout->setContentsMargins(2, 2, 2, 2);
1330 scrollLayout->addWidget(pageFrame);
1331
1332 QScopedPointer<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
1333 scrollArea->setupUi(pageFrame);
1334
1335 QWidget* page = pageFrame->findChild<QWidget*>("contents");
1336
1337 QVBoxLayout* topLayout = new QVBoxLayout(page);
1338 topLayout->setContentsMargins(5, 5, 5, 5);
1339
1340 QGridLayout* gbox = new QGridLayout();
1341 gbox->setColumnStretch(1, 5);
1342 topLayout->addLayout(gbox);
1343 int line = 0;
1344
1345 QLabel* label;
1346
1347 m_pSameEncoding = new OptionCheckBox(i18n("Use the same encoding for everything:"), true, "SameEncoding", &m_options->m_bSameEncoding, page);
1348 addOptionItem(m_pSameEncoding);
1349 gbox->addWidget(m_pSameEncoding, line, 0, 1, 2);
1350 m_pSameEncoding->setToolTip(i18n(
1351 "Enable this allows to change all encodings by changing the first only.\n"
1352 "Disable this if different individual settings are needed."));
1353 ++line;
1354
1355 label = new QLabel(i18n("Note: Local Encoding is \"%1\"", QLatin1String(QTextCodec::codecForLocale()->name())), page);
1356 gbox->addWidget(label, line, 0);
1357 ++line;
1358
1359 label = new QLabel(i18n("File Encoding for A:"), page);
1360 gbox->addWidget(label, line, 0);
1361 m_pEncodingAComboBox = new OptionEncodingComboBox("EncodingForA", &m_options->m_pEncodingA, page);
1362 addOptionItem(m_pEncodingAComboBox);
1363 gbox->addWidget(m_pEncodingAComboBox, line, 1);
1364
1365 QString autoDetectToolTip = i18n(
1366 "If enabled then Unicode (UTF-16 or UTF-8) encoding will be detected.\n"
1367 "If the file is not Unicode then the selected encoding will be used as fallback.\n"
1368 "(Unicode detection depends on the first bytes of a file.)");
1369 m_pAutoDetectUnicodeA = new OptionCheckBox(i18n("Auto Detect Unicode"), true, "AutoDetectUnicodeA", &m_options->m_bAutoDetectUnicodeA, page);
1370 gbox->addWidget(m_pAutoDetectUnicodeA, line, 2);
1371 addOptionItem(m_pAutoDetectUnicodeA);
1372 m_pAutoDetectUnicodeA->setToolTip(autoDetectToolTip);
1373 ++line;
1374
1375 label = new QLabel(i18n("File Encoding for B:"), page);
1376 gbox->addWidget(label, line, 0);
1377 m_pEncodingBComboBox = new OptionEncodingComboBox("EncodingForB", &m_options->m_pEncodingB, page);
1378 addOptionItem(m_pEncodingBComboBox);
1379 gbox->addWidget(m_pEncodingBComboBox, line, 1);
1380 m_pAutoDetectUnicodeB = new OptionCheckBox(i18n("Auto Detect Unicode"), true, "AutoDetectUnicodeB", &m_options->m_bAutoDetectUnicodeB, page);
1381 addOptionItem(m_pAutoDetectUnicodeB);
1382 gbox->addWidget(m_pAutoDetectUnicodeB, line, 2);
1383 m_pAutoDetectUnicodeB->setToolTip(autoDetectToolTip);
1384 ++line;
1385
1386 label = new QLabel(i18n("File Encoding for C:"), page);
1387 gbox->addWidget(label, line, 0);
1388 m_pEncodingCComboBox = new OptionEncodingComboBox("EncodingForC", &m_options->m_pEncodingC, page);
1389 addOptionItem(m_pEncodingCComboBox);
1390 gbox->addWidget(m_pEncodingCComboBox, line, 1);
1391 m_pAutoDetectUnicodeC = new OptionCheckBox(i18n("Auto Detect Unicode"), true, "AutoDetectUnicodeC", &m_options->m_bAutoDetectUnicodeC, page);
1392 addOptionItem(m_pAutoDetectUnicodeC);
1393 gbox->addWidget(m_pAutoDetectUnicodeC, line, 2);
1394 m_pAutoDetectUnicodeC->setToolTip(autoDetectToolTip);
1395 ++line;
1396
1397 label = new QLabel(i18n("File Encoding for Merge Output and Saving:"), page);
1398 gbox->addWidget(label, line, 0);
1399 m_pEncodingOutComboBox = new OptionEncodingComboBox("EncodingForOutput", &m_options->m_pEncodingOut, page);
1400 addOptionItem(m_pEncodingOutComboBox);
1401 gbox->addWidget(m_pEncodingOutComboBox, line, 1);
1402 m_pAutoSelectOutEncoding = new OptionCheckBox(i18n("Auto Select"), true, "AutoSelectOutEncoding", &m_options->m_bAutoSelectOutEncoding, page);
1403 addOptionItem(m_pAutoSelectOutEncoding);
1404 gbox->addWidget(m_pAutoSelectOutEncoding, line, 2);
1405 m_pAutoSelectOutEncoding->setToolTip(i18n(
1406 "If enabled then the encoding from the input files is used.\n"
1407 "In ambiguous cases a dialog will ask the user to choose the encoding for saving."));
1408 ++line;
1409 label = new QLabel(i18n("File Encoding for Preprocessor Files:"), page);
1410 gbox->addWidget(label, line, 0);
1411 m_pEncodingPPComboBox = new OptionEncodingComboBox("EncodingForPP", &m_options->m_pEncodingPP, page);
1412 addOptionItem(m_pEncodingPPComboBox);
1413 gbox->addWidget(m_pEncodingPPComboBox, line, 1);
1414 ++line;
1415
1416 chk_connect(m_pSameEncoding, &OptionCheckBox::toggled, this, &OptionDialog::slotEncodingChanged);
1417 chk_connect(m_pEncodingAComboBox, static_cast<void (OptionEncodingComboBox::*)(int)>(&OptionEncodingComboBox::activated), this, &OptionDialog::slotEncodingChanged);
1418 chk_connect(m_pAutoDetectUnicodeA, &OptionCheckBox::toggled, this, &OptionDialog::slotEncodingChanged);
1419 chk_connect(m_pAutoSelectOutEncoding, &OptionCheckBox::toggled, this, &OptionDialog::slotEncodingChanged);
1420
1421 OptionCheckBox* pRightToLeftLanguage = new OptionCheckBox(i18n("Right To Left Language"), false, "RightToLeftLanguage", &m_options->m_bRightToLeftLanguage, page);
1422 addOptionItem(pRightToLeftLanguage);
1423 gbox->addWidget(pRightToLeftLanguage, line, 0, 1, 2);
1424 pRightToLeftLanguage->setToolTip(i18n(
1425 "Some languages are read from right to left.\n"
1426 "This setting will change the viewer and editor accordingly."));
1427 ++line;
1428
1429 topLayout->addStretch(10);
1430 }
1431
setupIntegrationPage()1432 void OptionDialog::setupIntegrationPage()
1433 {
1434 QScrollArea* pageFrame = new QScrollArea();
1435 KPageWidgetItem* pageItem = new KPageWidgetItem(pageFrame, i18n("Integration"));
1436 pageItem->setHeader(i18n("Integration Settings"));
1437 pageItem->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal")));
1438 addPage(pageItem);
1439
1440 QVBoxLayout* scrollLayout = new QVBoxLayout();
1441 scrollLayout->setContentsMargins(2, 2, 2, 2);
1442 scrollLayout->addWidget(pageFrame);
1443
1444 QScopedPointer<Ui::ScrollArea> scrollArea(new Ui::ScrollArea());
1445 scrollArea->setupUi(pageFrame);
1446
1447 QWidget* page = pageFrame->findChild<QWidget*>("contents");
1448 QVBoxLayout* topLayout = new QVBoxLayout(page);
1449 topLayout->setContentsMargins(5, 5, 5, 5);
1450
1451 QGridLayout* gbox = new QGridLayout();
1452 gbox->setColumnStretch(2, 5);
1453 topLayout->addLayout(gbox);
1454 int line = 0;
1455
1456 QLabel* label;
1457 label = new QLabel(i18n("Command line options to ignore:"), page);
1458 gbox->addWidget(label, line, 0);
1459 OptionLineEdit* pIgnorableCmdLineOptions = new OptionLineEdit("-u;-query;-html;-abort", "IgnorableCmdLineOptions", &m_options->m_ignorableCmdLineOptions, page);
1460 gbox->addWidget(pIgnorableCmdLineOptions, line, 1, 1, 2);
1461 addOptionItem(pIgnorableCmdLineOptions);
1462 label->setToolTip(i18n(
1463 "List of command line options that should be ignored when KDiff3 is used by other tools.\n"
1464 "Several values can be specified if separated via ';'\n"
1465 "This will suppress the \"Unknown option\" error."));
1466 ++line;
1467
1468 OptionCheckBox* pEscapeKeyQuits = new OptionCheckBox(i18n("Quit also via Escape key"), false, "EscapeKeyQuits", &m_options->m_bEscapeKeyQuits, page);
1469 gbox->addWidget(pEscapeKeyQuits, line, 0, 1, 2);
1470 addOptionItem(pEscapeKeyQuits);
1471 pEscapeKeyQuits->setToolTip(i18n(
1472 "Fast method to exit.\n"
1473 "For those who are used to using the Escape key."));
1474 ++line;
1475
1476 topLayout->addStretch(10);
1477 }
1478
1479
slotEncodingChanged()1480 void OptionDialog::slotEncodingChanged()
1481 {
1482 if(m_pSameEncoding->isChecked())
1483 {
1484 m_pEncodingBComboBox->setEnabled(false);
1485 m_pEncodingBComboBox->setCurrentIndex(m_pEncodingAComboBox->currentIndex());
1486 m_pEncodingCComboBox->setEnabled(false);
1487 m_pEncodingCComboBox->setCurrentIndex(m_pEncodingAComboBox->currentIndex());
1488 m_pEncodingOutComboBox->setEnabled(false);
1489 m_pEncodingOutComboBox->setCurrentIndex(m_pEncodingAComboBox->currentIndex());
1490 m_pEncodingPPComboBox->setEnabled(false);
1491 m_pEncodingPPComboBox->setCurrentIndex(m_pEncodingAComboBox->currentIndex());
1492 m_pAutoDetectUnicodeB->setEnabled(false);
1493 m_pAutoDetectUnicodeB->setCheckState(m_pAutoDetectUnicodeA->checkState());
1494 m_pAutoDetectUnicodeC->setEnabled(false);
1495 m_pAutoDetectUnicodeC->setCheckState(m_pAutoDetectUnicodeA->checkState());
1496 m_pAutoSelectOutEncoding->setEnabled(false);
1497 m_pAutoSelectOutEncoding->setCheckState(m_pAutoDetectUnicodeA->checkState());
1498 }
1499 else
1500 {
1501 m_pEncodingBComboBox->setEnabled(true);
1502 m_pEncodingCComboBox->setEnabled(true);
1503 m_pEncodingOutComboBox->setEnabled(true);
1504 m_pEncodingPPComboBox->setEnabled(true);
1505 m_pAutoDetectUnicodeB->setEnabled(true);
1506 m_pAutoDetectUnicodeC->setEnabled(true);
1507 m_pAutoSelectOutEncoding->setEnabled(true);
1508 m_pEncodingOutComboBox->setEnabled(m_pAutoSelectOutEncoding->checkState() == Qt::Unchecked);
1509 }
1510 }
1511
slotOk()1512 void OptionDialog::slotOk()
1513 {
1514 slotApply();
1515
1516 accept();
1517 }
1518
1519 /** Copy the values from the widgets to the public variables.*/
slotApply()1520 void OptionDialog::slotApply()
1521 {
1522 m_options->apply();
1523
1524 Q_EMIT applyDone();
1525 }
1526
1527 /** Set the default values in the widgets only, while the
1528 public variables remain unchanged. */
slotDefault()1529 void OptionDialog::slotDefault()
1530 {
1531 int result = KMessageBox::warningContinueCancel(this, i18n("This resets all options. Not only those of the current topic."));
1532 if(result == KMessageBox::Cancel)
1533 return;
1534 else
1535 resetToDefaults();
1536 }
1537
resetToDefaults()1538 void OptionDialog::resetToDefaults()
1539 {
1540 m_options->resetToDefaults();
1541 slotEncodingChanged();
1542 }
1543
1544 /** Initialise the widgets using the values in the public varibles. */
setState()1545 void OptionDialog::setState()
1546 {
1547 m_options->setToCurrent();
1548
1549 slotEncodingChanged();
1550 }
1551
saveOptions(KSharedConfigPtr config)1552 void OptionDialog::saveOptions(KSharedConfigPtr config)
1553 {
1554 // No i18n()-Translations here!
1555 m_options->saveOptions(config);
1556 }
1557
readOptions(KSharedConfigPtr config)1558 void OptionDialog::readOptions(KSharedConfigPtr config)
1559 {
1560 // No i18n()-Translations here!
1561 m_options->readOptions(config);
1562
1563 setState();
1564 }
1565
parseOptions(const QStringList & optionList)1566 const QString OptionDialog::parseOptions(const QStringList& optionList)
1567 {
1568
1569 return m_options->parseOptions(optionList);
1570 }
1571
calcOptionHelp()1572 QString OptionDialog::calcOptionHelp()
1573 {
1574 return m_options->calcOptionHelp();
1575 }
1576
slotHistoryMergeRegExpTester()1577 void OptionDialog::slotHistoryMergeRegExpTester()
1578 {
1579 QPointer<RegExpTester> dlg=QPointer<RegExpTester>(new RegExpTester(this, s_autoMergeRegExpToolTip, s_historyStartRegExpToolTip,
1580 s_historyEntryStartRegExpToolTip, s_historyEntryStartSortKeyOrderToolTip));
1581 dlg->init(m_pAutoMergeRegExpLineEdit->currentText(), m_pHistoryStartRegExpLineEdit->currentText(),
1582 m_pHistoryEntryStartRegExpLineEdit->currentText(), m_pHistorySortKeyOrderLineEdit->currentText());
1583 if(dlg->exec())
1584 {
1585 m_pAutoMergeRegExpLineEdit->setEditText(dlg->autoMergeRegExp());
1586 m_pHistoryStartRegExpLineEdit->setEditText(dlg->historyStartRegExp());
1587 m_pHistoryEntryStartRegExpLineEdit->setEditText(dlg->historyEntryStartRegExp());
1588 m_pHistorySortKeyOrderLineEdit->setEditText(dlg->historySortKeyOrder());
1589 }
1590 }
1591
1592 #include "optiondialog.moc"
1593