optiondialog.cpp 75.7 KB
Newer Older
Joachim Eibl's avatar
Joachim Eibl committed
1 2
/*
 *   kdiff3 - Text Diff And Merge Tool
Joachim Eibl's avatar
Joachim Eibl committed
3
 *   Copyright (C) 2002-2009  Joachim Eibl, joachim.eibl at gmx.de
Joachim Eibl's avatar
Joachim Eibl committed
4 5 6 7 8 9 10 11 12 13 14 15 16
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
Joachim Eibl's avatar
Joachim Eibl committed
17
 *   Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.
Joachim Eibl's avatar
Joachim Eibl committed
18 19 20
 *
 */

Joachim Eibl's avatar
Joachim Eibl committed
21 22 23 24 25 26 27 28 29
#include <QCheckBox>
#include <QComboBox>
#include <QLabel>
#include <QLayout>
#include <QLineEdit> 
#include <QToolTip>
#include <QRadioButton>
#include <QGroupBox>
#include <QTextCodec>
Joachim Eibl's avatar
Joachim Eibl committed
30
#include <QDir>
Joachim Eibl's avatar
Joachim Eibl committed
31 32
#include <QSettings>
#include <QLocale>
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
33 34 35 36
#include <QGridLayout>
#include <QPixmap>
#include <QFrame>
#include <QVBoxLayout>
Joachim Eibl's avatar
Joachim Eibl committed
37 38

#include <kapplication.h>
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
39
#include <kcolorbutton.h>
Joachim Eibl's avatar
Joachim Eibl committed
40 41 42 43 44
#include <kfontdialog.h> // For KFontChooser
#include <kiconloader.h>
#include <klocale.h>
#include <kconfig.h>
#include <kmessagebox.h>
Joachim Eibl's avatar
Joachim Eibl committed
45
#include <kmainwindow.h> //For ktoolbar.h
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
46
#include <ktoolbar.h>
Joachim Eibl's avatar
Joachim Eibl committed
47

Joachim Eibl's avatar
Joachim Eibl committed
48
//#include <kkeydialog.h>
Joachim Eibl's avatar
Joachim Eibl committed
49
#include <map>
Joachim Eibl's avatar
Joachim Eibl committed
50 51 52

#include "optiondialog.h"
#include "diff.h"
Joachim Eibl's avatar
Joachim Eibl committed
53 54
#include "smalldialogs.h"

Joachim Eibl's avatar
0.9.86  
Joachim Eibl committed
55 56
#ifndef KREPLACEMENTS_H
#include <kglobalsettings.h>
Michael Reeves's avatar
Michael Reeves committed
57 58 59
#include <KConfigGroup>
#include <QDialogButtonBox>
#include <QPushButton>
Joachim Eibl's avatar
0.9.86  
Joachim Eibl committed
60 61
#endif

Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
62 63
#define KDIFF3_CONFIG_GROUP "KDiff3 Options"

Joachim Eibl's avatar
Joachim Eibl committed
64 65 66 67 68
static QString s_historyEntryStartRegExpToolTip;
static QString s_historyEntryStartSortKeyOrderToolTip;
static QString s_autoMergeRegExpToolTip;
static QString s_historyStartRegExpToolTip;

Joachim Eibl's avatar
Joachim Eibl committed
69 70 71 72 73 74 75 76
void OptionDialog::addOptionItem(OptionItem* p)
{
   m_optionItemList.push_back(p);
}

class OptionItem
{
public:
Joachim Eibl's avatar
Joachim Eibl committed
77
   OptionItem( OptionDialog* pOptionDialog, const QString& saveName )
Joachim Eibl's avatar
Joachim Eibl committed
78 79 80 81
   {
      assert(pOptionDialog!=0);
      pOptionDialog->addOptionItem( this );
      m_saveName = saveName;
82
      m_bPreserved = false;
Joachim Eibl's avatar
Joachim Eibl committed
83 84 85 86 87
   }
   virtual ~OptionItem(){}
   virtual void setToDefault()=0;
   virtual void setToCurrent()=0;
   virtual void apply()=0;
Joachim Eibl's avatar
Joachim Eibl committed
88 89
   virtual void write(ValueMap*)=0;
   virtual void read(ValueMap*)=0;
90 91
   void doPreserve(){ if (!m_bPreserved){ m_bPreserved=true; preserve(); } }
   void doUnpreserve(){ if( m_bPreserved ){ unpreserve(); } }
Joachim Eibl's avatar
Joachim Eibl committed
92
   QString getSaveName(){return m_saveName;}
Joachim Eibl's avatar
Joachim Eibl committed
93
protected:
94 95 96
   virtual void preserve()=0;
   virtual void unpreserve()=0;
   bool m_bPreserved;
Joachim Eibl's avatar
Joachim Eibl committed
97 98 99
   QString m_saveName;
};

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
template <class T>
class OptionItemT : public OptionItem
{
public:
  OptionItemT( OptionDialog* pOptionDialog, const QString& saveName ) 
  : OptionItem(pOptionDialog,saveName ) 
  {}
  
protected:
   virtual void preserve(){ m_preservedVal = *m_pVar; }
   virtual void unpreserve(){ *m_pVar = m_preservedVal; }
   T* m_pVar;
   T m_preservedVal;
   T m_defaultVal;
};

class OptionCheckBox : public QCheckBox, public OptionItemT<bool>
Joachim Eibl's avatar
Joachim Eibl committed
117 118 119 120
{
public:
   OptionCheckBox( QString text, bool bDefaultVal, const QString& saveName, bool* pbVar,
                   QWidget* pParent, OptionDialog* pOD )
121
   : QCheckBox( text, pParent ), OptionItemT<bool>( pOD, saveName )
Joachim Eibl's avatar
Joachim Eibl committed
122
   {
123 124
      m_pVar = pbVar;
      m_defaultVal = bDefaultVal;
Joachim Eibl's avatar
Joachim Eibl committed
125
   }
126 127 128 129 130
   void setToDefault(){ setChecked( m_defaultVal );      }
   void setToCurrent(){ setChecked( *m_pVar );           }
   void apply()       { *m_pVar = isChecked();                              }
   void write(ValueMap* config){ config->writeEntry(m_saveName, *m_pVar );   }
   void read (ValueMap* config){ *m_pVar = config->readBoolEntry( m_saveName, *m_pVar ); }
Joachim Eibl's avatar
Joachim Eibl committed
131 132 133 134
private:
   OptionCheckBox( const OptionCheckBox& ); // private copy constructor without implementation
};

135
class OptionRadioButton : public QRadioButton, public OptionItemT<bool>
Joachim Eibl's avatar
0.9.86  
Joachim Eibl committed
136 137 138 139
{
public:
   OptionRadioButton( QString text, bool bDefaultVal, const QString& saveName, bool* pbVar,
                   QWidget* pParent, OptionDialog* pOD )
140
   : QRadioButton( text, pParent ), OptionItemT<bool>( pOD, saveName )
Joachim Eibl's avatar
0.9.86  
Joachim Eibl committed
141
   {
142 143
      m_pVar = pbVar;
      m_defaultVal = bDefaultVal;
Joachim Eibl's avatar
0.9.86  
Joachim Eibl committed
144
   }
145 146 147 148 149
   void setToDefault(){ setChecked( m_defaultVal );      }
   void setToCurrent(){ setChecked( *m_pVar );           }
   void apply()       { *m_pVar = isChecked();                              }
   void write(ValueMap* config){ config->writeEntry(m_saveName, *m_pVar );   }
   void read (ValueMap* config){ *m_pVar = config->readBoolEntry( m_saveName, *m_pVar ); }
Joachim Eibl's avatar
0.9.86  
Joachim Eibl committed
150 151 152 153
private:
   OptionRadioButton( const OptionRadioButton& ); // private copy constructor without implementation
};

Joachim Eibl's avatar
Joachim Eibl committed
154 155

template<class T>
156
class OptionT : public OptionItemT<T>
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
157 158
{
public:
Joachim Eibl's avatar
Joachim Eibl committed
159
   OptionT( const T& defaultVal, const QString& saveName, T* pVar, OptionDialog* pOD )
160
   : OptionItemT<T>( pOD, saveName )
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
161
   {
162 163
      this->m_pVar = pVar;
      *this->m_pVar = defaultVal;
Joachim Eibl's avatar
Joachim Eibl committed
164 165
   }
   OptionT( const QString& saveName, T* pVar, OptionDialog* pOD )
166
   : OptionItemT<T>( pOD, saveName )
Joachim Eibl's avatar
Joachim Eibl committed
167
   {
168
      this->m_pVar = pVar;
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
169 170 171 172
   }
   void setToDefault(){}
   void setToCurrent(){}
   void apply()       {}
173 174
   void write(ValueMap* vm){ writeEntry( vm, this->m_saveName, *this->m_pVar ); }
   void read (ValueMap* vm){ *this->m_pVar = vm->readEntry ( this->m_saveName, *this->m_pVar ); }
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
175
private:
Joachim Eibl's avatar
Joachim Eibl committed
176
   OptionT( const OptionT& ); // private copy constructor without implementation
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
177 178
};

Joachim Eibl's avatar
Joachim Eibl committed
179 180 181
template <class T> void writeEntry(ValueMap* vm, const QString& saveName, const T& v ) {   vm->writeEntry( saveName, v ); }
static void writeEntry(ValueMap* vm, const QString& saveName, const QStringList& v )   {   vm->writeEntry( saveName, v, '|' ); }

Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
182 183 184 185 186
//static void readEntry(ValueMap* vm, const QString& saveName, bool& v )       {   v = vm->readBoolEntry( saveName, v ); }
//static void readEntry(ValueMap* vm, const QString& saveName, int&  v )       {   v = vm->readNumEntry( saveName, v ); }
//static void readEntry(ValueMap* vm, const QString& saveName, QSize& v )      {   v = vm->readSizeEntry( saveName, &v ); }
//static void readEntry(ValueMap* vm, const QString& saveName, QPoint& v )     {   v = vm->readPointEntry( saveName, &v ); }
//static void readEntry(ValueMap* vm, const QString& saveName, QStringList& v ){   v = vm->readListEntry( saveName, QStringList(), '|' ); }
Joachim Eibl's avatar
Joachim Eibl committed
187 188 189 190 191 192 193

typedef OptionT<bool> OptionToggleAction;
typedef OptionT<int>  OptionNum;
typedef OptionT<QPoint> OptionPoint;
typedef OptionT<QSize> OptionSize;
typedef OptionT<QStringList> OptionStringList;

194
class OptionFontChooser : public KFontChooser, public OptionItemT<QFont>
Joachim Eibl's avatar
Joachim Eibl committed
195 196
{
public:
197
   OptionFontChooser( const QFont& defaultVal, const QString& saveName, QFont* pVar, QWidget* pParent, OptionDialog* pOD ) :
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
198
       KFontChooser( pParent ),
199
       OptionItemT<QFont>( pOD, saveName )
Joachim Eibl's avatar
Joachim Eibl committed
200
   {
201 202 203
      m_pVar = pVar;
      *m_pVar = defaultVal;
      m_defaultVal = defaultVal;
Joachim Eibl's avatar
Joachim Eibl committed
204
   }
205 206
   void setToDefault(){ setFont( m_defaultVal, false ); }
   void setToCurrent(){ setFont( *m_pVar, false ); }
207 208 209
   void apply()       { *m_pVar = font();}
   void write(ValueMap* config){ config->writeEntry(m_saveName, *m_pVar );   }
   void read (ValueMap* config){ *m_pVar = config->readFontEntry( m_saveName, m_pVar ); }
Joachim Eibl's avatar
Joachim Eibl committed
210 211 212
private:
   OptionFontChooser( const OptionToggleAction& ); // private copy constructor without implementation
};
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
213

214
class OptionColorButton : public KColorButton, public OptionItemT<QColor>
Joachim Eibl's avatar
Joachim Eibl committed
215 216 217
{
public:
   OptionColorButton( QColor defaultVal, const QString& saveName, QColor* pVar, QWidget* pParent, OptionDialog* pOD )
218
   : KColorButton( pParent ), OptionItemT<QColor>( pOD, saveName )
Joachim Eibl's avatar
Joachim Eibl committed
219 220 221 222 223 224 225
   {
      m_pVar = pVar;
      m_defaultVal = defaultVal;
   }
   void setToDefault(){ setColor( m_defaultVal );      }
   void setToCurrent(){ setColor( *m_pVar );           }
   void apply()       { *m_pVar = color();                              }
Joachim Eibl's avatar
Joachim Eibl committed
226 227
   void write(ValueMap* config){ config->writeEntry(m_saveName, *m_pVar );   }
   void read (ValueMap* config){ *m_pVar = config->readColorEntry( m_saveName, m_pVar ); }
Joachim Eibl's avatar
Joachim Eibl committed
228 229 230 231
private:
   OptionColorButton( const OptionColorButton& ); // private copy constructor without implementation
};

232
class OptionLineEdit : public QComboBox, public OptionItemT<QString>
Joachim Eibl's avatar
Joachim Eibl committed
233 234 235 236
{
public:
   OptionLineEdit( const QString& defaultVal, const QString& saveName, QString* pVar,
                   QWidget* pParent, OptionDialog* pOD )
237
   : QComboBox( pParent ), OptionItemT<QString>( pOD, saveName )
Joachim Eibl's avatar
Joachim Eibl committed
238
   {
Joachim Eibl's avatar
Joachim Eibl committed
239 240
      setMinimumWidth(50);
      setEditable(true);
Joachim Eibl's avatar
Joachim Eibl committed
241 242
      m_pVar = pVar;
      m_defaultVal = defaultVal;
Joachim Eibl's avatar
Joachim Eibl committed
243
      m_list.push_back(defaultVal);
Joachim Eibl's avatar
Joachim Eibl committed
244
      insertText();
Joachim Eibl's avatar
Joachim Eibl committed
245
   }
Joachim Eibl's avatar
Joachim Eibl committed
246 247
   void setToDefault(){ setEditText( m_defaultVal );   }
   void setToCurrent(){ setEditText( *m_pVar );        }
Joachim Eibl's avatar
Joachim Eibl committed
248
   void apply()       { *m_pVar = currentText(); insertText();            }
Joachim Eibl's avatar
Joachim Eibl committed
249 250
   void write(ValueMap* config){ config->writeEntry( m_saveName, m_list, '|' );      }
   void read (ValueMap* config){ 
Joachim Eibl's avatar
Joachim Eibl committed
251
      m_list = config->readListEntry( m_saveName, QStringList(m_defaultVal), '|' ); 
Joachim Eibl's avatar
Joachim Eibl committed
252
      if ( !m_list.empty() ) *m_pVar = m_list.front();
Joachim Eibl's avatar
Joachim Eibl committed
253
      clear();
Joachim Eibl's avatar
Joachim Eibl committed
254
      insertItems(0,m_list);
Joachim Eibl's avatar
Joachim Eibl committed
255 256
   }
private:
Joachim Eibl's avatar
Joachim Eibl committed
257
   void insertText()
Joachim Eibl's avatar
Joachim Eibl committed
258
   {  // Check if the text exists. If yes remove it and push it in as first element
Joachim Eibl's avatar
Joachim Eibl committed
259
      QString current = currentText();
Joachim Eibl's avatar
Joachim Eibl committed
260
      m_list.removeAll( current );
Joachim Eibl's avatar
Joachim Eibl committed
261 262
      m_list.push_front( current );
      clear();
Joachim Eibl's avatar
Joachim Eibl committed
263
      if ( m_list.size()>10 ) 
Joachim Eibl's avatar
Joachim Eibl committed
264
         m_list.erase( m_list.begin()+10, m_list.end() );
Joachim Eibl's avatar
Joachim Eibl committed
265
      insertItems(0,m_list);
Joachim Eibl's avatar
Joachim Eibl committed
266
   }
Joachim Eibl's avatar
Joachim Eibl committed
267
   OptionLineEdit( const OptionLineEdit& ); // private copy constructor without implementation
Joachim Eibl's avatar
Joachim Eibl committed
268
   QStringList m_list;
Joachim Eibl's avatar
Joachim Eibl committed
269 270 271 272 273
};

#if defined QT_NO_VALIDATOR
#error No validator
#endif
274
class OptionIntEdit : public QLineEdit, public OptionItemT<int>
Joachim Eibl's avatar
Joachim Eibl committed
275 276 277 278
{
public:
   OptionIntEdit( int defaultVal, const QString& saveName, int* pVar, int rangeMin, int rangeMax,
                   QWidget* pParent, OptionDialog* pOD )
279
   : QLineEdit( pParent ), OptionItemT<int>( pOD, saveName )
Joachim Eibl's avatar
Joachim Eibl committed
280 281 282
   {
      m_pVar = pVar;
      m_defaultVal = defaultVal;
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
283
      QIntValidator* v = new QIntValidator(this);
Joachim Eibl's avatar
Joachim Eibl committed
284 285 286 287 288 289 290 291
      v->setRange( rangeMin, rangeMax );
      setValidator( v );
   }
   void setToDefault(){ QString s;  s.setNum(m_defaultVal); setText( s );  }
   void setToCurrent(){ QString s;  s.setNum(*m_pVar);      setText( s );  }
   void apply()       { const QIntValidator* v=static_cast<const QIntValidator*>(validator());
                        *m_pVar = minMaxLimiter( text().toInt(), v->bottom(), v->top());
                        setText( QString::number(*m_pVar) );  }
Joachim Eibl's avatar
Joachim Eibl committed
292 293
   void write(ValueMap* config){ config->writeEntry(m_saveName, *m_pVar );   }
   void read (ValueMap* config){ *m_pVar = config->readNumEntry( m_saveName, *m_pVar ); }
Joachim Eibl's avatar
Joachim Eibl committed
294 295 296 297
private:
   OptionIntEdit( const OptionIntEdit& ); // private copy constructor without implementation
};

Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
298 299 300
class OptionComboBox : public QComboBox, public OptionItem
{
public:
Joachim Eibl's avatar
Joachim Eibl committed
301
   OptionComboBox( int defaultVal, const QString& saveName, int* pVarNum,
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
302 303 304
                   QWidget* pParent, OptionDialog* pOD )
   : QComboBox( pParent ), OptionItem( pOD, saveName )
   {
Joachim Eibl's avatar
Joachim Eibl committed
305
      setMinimumWidth(50);
Joachim Eibl's avatar
Joachim Eibl committed
306 307
      m_pVarNum = pVarNum;
      m_pVarStr = 0;
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
308 309 310
      m_defaultVal = defaultVal;
      setEditable(false);
   }
Joachim Eibl's avatar
Joachim Eibl committed
311 312 313 314 315 316 317 318 319 320 321
   OptionComboBox( int defaultVal, const QString& saveName, QString* pVarStr,
                   QWidget* pParent, OptionDialog* pOD )
   : QComboBox( pParent ), OptionItem( pOD, saveName )
   {
      m_pVarNum = 0;
      m_pVarStr = pVarStr;
      m_defaultVal = defaultVal;
      setEditable(false);
   }
   void setToDefault()
   { 
Joachim Eibl's avatar
Joachim Eibl committed
322
      setCurrentIndex( m_defaultVal ); 
Joachim Eibl's avatar
Joachim Eibl committed
323 324 325 326
      if (m_pVarStr!=0){ *m_pVarStr=currentText(); } 
   }
   void setToCurrent()
   { 
Joachim Eibl's avatar
Joachim Eibl committed
327
      if (m_pVarNum!=0) setCurrentIndex( *m_pVarNum );
Joachim Eibl's avatar
Joachim Eibl committed
328 329
      else              setText( *m_pVarStr );
   }
Joachim Eibl's avatar
Joachim Eibl committed
330
   void apply()
Joachim Eibl's avatar
Joachim Eibl committed
331
   { 
Joachim Eibl's avatar
Joachim Eibl committed
332
      if (m_pVarNum!=0){ *m_pVarNum = currentIndex(); }
Joachim Eibl's avatar
Joachim Eibl committed
333 334
      else             { *m_pVarStr = currentText(); }
   }
Joachim Eibl's avatar
Joachim Eibl committed
335
   void write(ValueMap* config)
Joachim Eibl's avatar
Joachim Eibl committed
336 337 338 339
   { 
      if (m_pVarStr!=0) config->writeEntry(m_saveName, *m_pVarStr );
      else              config->writeEntry(m_saveName, *m_pVarNum );   
   }
Joachim Eibl's avatar
Joachim Eibl committed
340
   void read (ValueMap* config)
Joachim Eibl's avatar
Joachim Eibl committed
341 342 343 344
   {
      if (m_pVarStr!=0)  setText( config->readEntry( m_saveName, currentText() ) );
      else               *m_pVarNum = config->readNumEntry( m_saveName, *m_pVarNum ); 
   }
345 346 347 348 349 350 351 352 353 354
   void preserve()
   {
      if (m_pVarStr!=0)  { m_preservedStrVal = *m_pVarStr; }
      else               { m_preservedNumVal = *m_pVarNum; }
   }
   void unpreserve()
   {
      if (m_pVarStr!=0)  { *m_pVarStr = m_preservedStrVal; }
      else               { *m_pVarNum = m_preservedNumVal; }
   }
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
355 356
private:
   OptionComboBox( const OptionIntEdit& ); // private copy constructor without implementation
Joachim Eibl's avatar
Joachim Eibl committed
357
   int* m_pVarNum;
358
   int m_preservedNumVal;
Joachim Eibl's avatar
Joachim Eibl committed
359
   QString* m_pVarStr;
360
   QString m_preservedStrVal;
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
361
   int m_defaultVal;
Joachim Eibl's avatar
Joachim Eibl committed
362 363 364 365 366 367
   
   void setText(const QString& s)
   {
      // Find the string in the combobox-list, don't change the value if nothing fits.
      for( int i=0; i<count(); ++i )
      {
Joachim Eibl's avatar
Joachim Eibl committed
368
         if ( itemText(i)==s )
Joachim Eibl's avatar
Joachim Eibl committed
369 370 371
         {
            if (m_pVarNum!=0) *m_pVarNum = i;
            if (m_pVarStr!=0) *m_pVarStr = s;
Joachim Eibl's avatar
Joachim Eibl committed
372
            setCurrentIndex(i);
Joachim Eibl's avatar
Joachim Eibl committed
373 374 375 376
            return;
         }
      }
   }
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
377
};
Joachim Eibl's avatar
Joachim Eibl committed
378

Joachim Eibl's avatar
Joachim Eibl committed
379 380
class OptionEncodingComboBox : public QComboBox, public OptionItem
{
381
   QVector<QTextCodec*> m_codecVec;
Joachim Eibl's avatar
Joachim Eibl committed
382 383 384 385 386 387 388 389 390 391 392 393 394
   QTextCodec** m_ppVarCodec;
public:
   OptionEncodingComboBox( const QString& saveName, QTextCodec** ppVarCodec,
                   QWidget* pParent, OptionDialog* pOD )
   : QComboBox( pParent ), OptionItem( pOD, saveName )
   {
      m_ppVarCodec = ppVarCodec;
      insertCodec( i18n("Unicode, 8 bit"),  QTextCodec::codecForName("UTF-8") );
      insertCodec( i18n("Unicode"), QTextCodec::codecForName("iso-10646-UCS-2") );
      insertCodec( i18n("Latin1"), QTextCodec::codecForName("iso 8859-1") );

      // First sort codec names:
      std::map<QString, QTextCodec*> names;
Joachim Eibl's avatar
Joachim Eibl committed
395 396
      QList<int> mibs = QTextCodec::availableMibs();
      foreach(int i, mibs)
Joachim Eibl's avatar
Joachim Eibl committed
397
      {
Joachim Eibl's avatar
Joachim Eibl committed
398
         QTextCodec* c = QTextCodec::codecForMib(i);
Joachim Eibl's avatar
Joachim Eibl committed
399 400
         if ( c!=0 )
            names[QString(c->name()).toUpper()]=c;
Joachim Eibl's avatar
Joachim Eibl committed
401 402 403 404 405 406 407 408
      }

      std::map<QString, QTextCodec*>::iterator it;
      for(it=names.begin();it!=names.end();++it)
      {
         insertCodec( "", it->second );
      }

Joachim Eibl's avatar
Joachim Eibl committed
409
      this->setToolTip( i18n(
Joachim Eibl's avatar
Joachim Eibl committed
410 411 412 413 414 415 416
         "Change this if non-ASCII characters are not displayed correctly."
         ));
   }
   void insertCodec( const QString& visibleCodecName, QTextCodec* c )
   {
      if (c!=0)
      {
417
         for( int i=0; i<m_codecVec.size(); ++i )
Joachim Eibl's avatar
Joachim Eibl committed
418 419 420 421
         {
            if ( c==m_codecVec[i] )
               return;  // don't insert any codec twice
         }
Joachim Eibl's avatar
Joachim Eibl committed
422
         addItem( visibleCodecName.isEmpty() ? QString(c->name()) : visibleCodecName+" ("+c->name()+")", (int)m_codecVec.size() );
Joachim Eibl's avatar
Joachim Eibl committed
423 424 425 426
         m_codecVec.push_back( c );
      }
   }
   void setToDefault()
Joachim Eibl's avatar
Joachim Eibl committed
427 428 429 430
   {
      QString defaultName = QTextCodec::codecForLocale()->name();
      for(int i=0;i<count();++i)
      {
Joachim Eibl's avatar
Joachim Eibl committed
431
         if (defaultName==itemText(i) &&
Joachim Eibl's avatar
Joachim Eibl committed
432 433
             m_codecVec[i]==QTextCodec::codecForLocale())
         {
Joachim Eibl's avatar
Joachim Eibl committed
434
            setCurrentIndex(i);
Joachim Eibl's avatar
Joachim Eibl committed
435 436 437 438 439
            if (m_ppVarCodec!=0){ *m_ppVarCodec=m_codecVec[i]; }
            return;
         }
      }

Joachim Eibl's avatar
Joachim Eibl committed
440
      setCurrentIndex( 0 );
Joachim Eibl's avatar
Joachim Eibl committed
441
      if (m_ppVarCodec!=0){ *m_ppVarCodec=m_codecVec[0]; }
Joachim Eibl's avatar
Joachim Eibl committed
442 443 444 445 446
   }
   void setToCurrent()
   {
      if (m_ppVarCodec!=0)
      {
447
         for( int i=0; i<m_codecVec.size(); ++i)
Joachim Eibl's avatar
Joachim Eibl committed
448 449 450
         {
            if ( *m_ppVarCodec==m_codecVec[i] )
            {
Joachim Eibl's avatar
Joachim Eibl committed
451
               setCurrentIndex( i );
Joachim Eibl's avatar
Joachim Eibl committed
452 453 454 455 456 457 458
               break;
            }
         }
      }
   }
   void apply()
   {
Joachim Eibl's avatar
Joachim Eibl committed
459
      if (m_ppVarCodec!=0){ *m_ppVarCodec = m_codecVec[ currentIndex() ]; }
Joachim Eibl's avatar
Joachim Eibl committed
460
   }
Joachim Eibl's avatar
Joachim Eibl committed
461
   void write(ValueMap* config)
Joachim Eibl's avatar
Joachim Eibl committed
462
   {
Joachim Eibl's avatar
Joachim Eibl committed
463
      if (m_ppVarCodec!=0) config->writeEntry(m_saveName, QString((*m_ppVarCodec)->name()) );
Joachim Eibl's avatar
Joachim Eibl committed
464
   }
Joachim Eibl's avatar
Joachim Eibl committed
465
   void read (ValueMap* config)
Joachim Eibl's avatar
Joachim Eibl committed
466
   {
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
467
      QString codecName = config->readEntry( m_saveName, QString(m_codecVec[ currentIndex() ]->name()) );
468
      for( int i=0; i<m_codecVec.size(); ++i)
Joachim Eibl's avatar
Joachim Eibl committed
469 470 471
      {
         if ( codecName == m_codecVec[i]->name() )
         {
Joachim Eibl's avatar
Joachim Eibl committed
472
            setCurrentIndex( i );
Joachim Eibl's avatar
Joachim Eibl committed
473 474 475 476 477
            if (m_ppVarCodec!=0) *m_ppVarCodec = m_codecVec[i];
            break;
         }
      }
   }
478 479 480 481
protected:
   void preserve()   { m_preservedVal = currentIndex(); }
   void unpreserve() { setCurrentIndex( m_preservedVal ); }
   int m_preservedVal;
Joachim Eibl's avatar
Joachim Eibl committed
482 483 484
};


Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
485 486 487 488
OptionDialog::OptionDialog( bool bShowDirMergeSettings, QWidget *parent, char *name ) : 
//    KPageDialog( IconList, i18n("Configure"), Help|Default|Apply|Ok|Cancel,
//                 Ok, parent, name, true /*modal*/, true )
    KPageDialog( parent )
Joachim Eibl's avatar
Joachim Eibl committed
489
{
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
490 491
   setFaceType( List );
   setWindowTitle( i18n("Configure") );
Michael Reeves's avatar
Michael Reeves committed
492 493 494 495 496 497 498 499 500 501 502 503 504
   QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::RestoreDefaults|QDialogButtonBox::Apply);
   QWidget *mainWidget = new QWidget(this);
   QVBoxLayout *mainLayout = new QVBoxLayout;
   setLayout(mainLayout);
   mainLayout->addWidget(mainWidget);
   QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
   okButton->setDefault(true);
   okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
   connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
   connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
   //PORTING SCRIPT: WARNING mainLayout->addWidget(buttonBox) must be last item in layout. Please move it.
   mainLayout->addWidget(buttonBox);
   okButton->setDefault(true);
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
505 506
   setObjectName( name );
   setModal( true  );
Joachim Eibl's avatar
Joachim Eibl committed
507
   setHelp( "kdiff3/index.html", QString::null );
Joachim Eibl's avatar
Joachim Eibl committed
508

Joachim Eibl's avatar
Joachim Eibl committed
509 510 511 512
   setupFontPage();
   setupColorPage();
   setupEditPage();
   setupDiffPage();
Joachim Eibl's avatar
Joachim Eibl committed
513
   setupMergePage();
Joachim Eibl's avatar
Joachim Eibl committed
514 515 516
   setupOtherOptions();
   if (bShowDirMergeSettings)
      setupDirectoryMergePage();
Joachim Eibl's avatar
Joachim Eibl committed
517

Joachim Eibl's avatar
Joachim Eibl committed
518
   setupRegionalPage();
Joachim Eibl's avatar
Joachim Eibl committed
519
   setupIntegrationPage();
Joachim Eibl's avatar
Joachim Eibl committed
520 521 522 523 524 525

   //setupKeysPage();

   // Initialize all values in the dialog
   resetToDefaults();
   slotApply();
526 527
   connect(this, &OptionDialog::applyClicked, this, &OptionDialog::slotApply);
   connect(this, &OptionDialog::okClicked, this, &OptionDialog::slotOk);
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
528
   //helpClicked() is connected in KDiff3App::KDiff3App
529
   connect(this, &OptionDialog::defaultClicked, this, &OptionDialog::slotDefault);
Joachim Eibl's avatar
Joachim Eibl committed
530 531 532 533 534 535
}

OptionDialog::~OptionDialog( void )
{
}

Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
536 537
void OptionDialog::setupOtherOptions()
{
538 539 540 541 542 543
   new OptionToggleAction( false, "AutoAdvance", &m_options.m_bAutoAdvance, this );
   new OptionToggleAction( true,  "ShowWhiteSpaceCharacters", &m_options.m_bShowWhiteSpaceCharacters, this );
   new OptionToggleAction( true,  "ShowWhiteSpace", &m_options.m_bShowWhiteSpace, this );
   new OptionToggleAction( false, "ShowLineNumbers", &m_options.m_bShowLineNumbers, this );
   new OptionToggleAction( true,  "HorizDiffWindowSplitting", &m_options.m_bHorizDiffWindowSplitting, this );
   new OptionToggleAction( false, "WordWrap", &m_options.m_bWordWrap, this );
Joachim Eibl's avatar
Joachim Eibl committed
544

545
   new OptionToggleAction( true,  "ShowIdenticalFiles", &m_options.m_bDmShowIdenticalFiles, this );
Joachim Eibl's avatar
Joachim Eibl committed
546

547 548
   new OptionToggleAction( true,  "Show Toolbar", &m_options.m_bShowToolBar, this );
   new OptionToggleAction( true,  "Show Statusbar", &m_options.m_bShowStatusBar, this );
Joachim Eibl's avatar
Joachim Eibl committed
549

Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
550 551
/*
   TODO manage toolbar positioning
Joachim Eibl's avatar
Joachim Eibl committed
552
   new OptionNum( (int)KToolBar::Top, "ToolBarPos", &m_toolBarPos, this );
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
553
*/
554 555 556
   new OptionSize( QSize(600,400),"Geometry", &m_options.m_geometry, this );
   new OptionPoint( QPoint(0,22), "Position", &m_options.m_position, this );
   new OptionToggleAction( false, "WindowStateMaximised", &m_options.m_bMaximised, this );
Joachim Eibl's avatar
Joachim Eibl committed
557

558 559 560 561 562
   new OptionStringList( "RecentAFiles", &m_options.m_recentAFiles, this );
   new OptionStringList( "RecentBFiles", &m_options.m_recentBFiles, this );
   new OptionStringList( "RecentCFiles", &m_options.m_recentCFiles, this );
   new OptionStringList( "RecentOutputFiles", &m_options.m_recentOutputFiles, this );
   new OptionStringList( "RecentEncodings", &m_options.m_recentEncodings, this );
563

Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
564
}
Joachim Eibl's avatar
Joachim Eibl committed
565 566 567

void OptionDialog::setupFontPage( void )
{
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
568 569 570
   QFrame* page = new QFrame();
   KPageWidgetItem *pageItem = new KPageWidgetItem( page, i18n("Font") );
   pageItem->setHeader( i18n("Editor & Diff Output Font" ) );
Michael Reeves's avatar
Michael Reeves committed
571
   pageItem->setIcon( QIcon::fromTheme(QStringLiteral("preferences-desktop-font")) );
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
572
   addPage( pageItem );
Joachim Eibl's avatar
Joachim Eibl committed
573

Joachim Eibl's avatar
Joachim Eibl committed
574 575 576
   QVBoxLayout *topLayout = new QVBoxLayout( page );
   topLayout->setMargin( 5 );
   topLayout->setSpacing( spacingHint() );
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
577

Joachim Eibl's avatar
Joachim Eibl committed
578 579 580 581 582 583 584 585 586
   QFont defaultFont =
#ifdef _WIN32
      QFont("Courier New", 10 );
#elif defined( KREPLACEMENTS_H )
      QFont("Courier", 10 );
#else
      KGlobalSettings::fixedFont();
#endif

587
   OptionFontChooser* pFontChooser = new OptionFontChooser( defaultFont, "Font", &m_options.m_font, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
588
   topLayout->addWidget( pFontChooser );
Joachim Eibl's avatar
Joachim Eibl committed
589

Joachim Eibl's avatar
Joachim Eibl committed
590
   QGridLayout *gbox = new QGridLayout();
Joachim Eibl's avatar
Joachim Eibl committed
591 592 593
   topLayout->addLayout( gbox );
   int line=0;

594
   OptionCheckBox* pItalicDeltas = new OptionCheckBox( i18n("Italic font for deltas"), false, "ItalicForDeltas", &m_options.m_bItalicForDeltas, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
595 596
   gbox->addWidget( pItalicDeltas, line, 0, 1, 2 );
   pItalicDeltas->setToolTip( i18n(
Joachim Eibl's avatar
Joachim Eibl committed
597 598 599 600 601 602 603 604
      "Selects the italic version of the font for differences.\n"
      "If the font doesn't support italic characters, then this does nothing.")
      );
}


void OptionDialog::setupColorPage( void )
{
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
605 606 607
   QFrame* page = new QFrame();
   KPageWidgetItem* pageItem = new KPageWidgetItem( page, i18n("Color") );
   pageItem->setHeader( i18n("Colors Settings") );
Michael Reeves's avatar
Michael Reeves committed
608
   pageItem->setIcon( QIcon::fromTheme(QStringLiteral("preferences-desktop-color")) );
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
609 610
   addPage( pageItem );

Joachim Eibl's avatar
Joachim Eibl committed
611 612 613
   QVBoxLayout *topLayout = new QVBoxLayout( page );
   topLayout->setMargin( 5 );
   topLayout->setSpacing( spacingHint() );
Joachim Eibl's avatar
Joachim Eibl committed
614

Joachim Eibl's avatar
Joachim Eibl committed
615 616 617

  QGridLayout *gbox = new QGridLayout();
  gbox->setColumnStretch(1,5);
Joachim Eibl's avatar
Joachim Eibl committed
618 619 620 621 622
  topLayout->addLayout(gbox);

  QLabel* label;
  int line = 0;

Joachim Eibl's avatar
Joachim Eibl committed
623
  int depth = QPixmap::defaultDepth();
Joachim Eibl's avatar
Joachim Eibl committed
624 625
  bool bLowColor = depth<=8;

Joachim Eibl's avatar
Joachim Eibl committed
626 627 628 629 630 631 632
  label = new QLabel( i18n("Editor and Diff Views:"), page );
  gbox->addWidget( label, line, 0 );
  QFont f( label->font() );
  f.setBold(true);
  label->setFont(f);
  ++line;

633
  OptionColorButton* pFgColor = new OptionColorButton( Qt::black,"FgColor", &m_options.m_fgColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
634 635
  label = new QLabel( i18n("Foreground color:"), page );
  label->setBuddy(pFgColor);
Joachim Eibl's avatar
Joachim Eibl committed
636 637 638 639
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pFgColor, line, 1 );
  ++line;

640
  OptionColorButton* pBgColor = new OptionColorButton( Qt::white, "BgColor", &m_options.m_bgColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
641 642
  label = new QLabel( i18n("Background color:"), page );
  label->setBuddy(pBgColor);
Joachim Eibl's avatar
Joachim Eibl committed
643 644 645 646 647
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pBgColor, line, 1 );

  ++line;

Joachim Eibl's avatar
Joachim Eibl committed
648
  OptionColorButton* pDiffBgColor = new OptionColorButton( 
649
     bLowColor ? QColor(Qt::lightGray) : qRgb(224,224,224), "DiffBgColor", &m_options.m_diffBgColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
650 651
  label = new QLabel( i18n("Diff background color:"), page );
  label->setBuddy(pDiffBgColor);
Joachim Eibl's avatar
Joachim Eibl committed
652 653 654 655 656
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pDiffBgColor, line, 1 );
  ++line;

  OptionColorButton* pColorA = new OptionColorButton(
657
     bLowColor ? qRgb(0,0,255) : qRgb(0,0,200)/*blue*/, "ColorA", &m_options.m_colorA, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
658 659
  label = new QLabel( i18n("Color A:"), page );
  label->setBuddy(pColorA);
Joachim Eibl's avatar
Joachim Eibl committed
660 661 662 663 664
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pColorA, line, 1 );
  ++line;

  OptionColorButton* pColorB = new OptionColorButton(
665
     bLowColor ? qRgb(0,128,0) : qRgb(0,150,0)/*green*/, "ColorB", &m_options.m_colorB, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
666 667
  label = new QLabel( i18n("Color B:"), page );
  label->setBuddy(pColorB);
Joachim Eibl's avatar
Joachim Eibl committed
668 669 670 671 672
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pColorB, line, 1 );
  ++line;

  OptionColorButton* pColorC = new OptionColorButton(
673
     bLowColor ? qRgb(128,0,128) : qRgb(150,0,150)/*magenta*/, "ColorC", &m_options.m_colorC, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
674 675
  label = new QLabel( i18n("Color C:"), page );
  label->setBuddy(pColorC);
Joachim Eibl's avatar
Joachim Eibl committed
676 677 678 679
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pColorC, line, 1 );
  ++line;

680
  OptionColorButton* pColorForConflict = new OptionColorButton( Qt::red, "ColorForConflict", &m_options.m_colorForConflict, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
681 682
  label = new QLabel( i18n("Conflict color:"), page );
  label->setBuddy(pColorForConflict);
Joachim Eibl's avatar
Joachim Eibl committed
683 684 685 686 687
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pColorForConflict, line, 1 );
  ++line;

  OptionColorButton* pColor = new OptionColorButton( 
688
     bLowColor ? qRgb(192,192,192) : qRgb(220,220,100), "CurrentRangeBgColor", &m_options.m_currentRangeBgColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
689 690
  label = new QLabel( i18n("Current range background color:"), page );
  label->setBuddy(pColor);
Joachim Eibl's avatar
Joachim Eibl committed
691 692 693 694 695
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pColor, line, 1 );
  ++line;

  pColor = new OptionColorButton( 
696
     bLowColor ? qRgb(255,255,0) : qRgb(255,255,150), "CurrentRangeDiffBgColor", &m_options.m_currentRangeDiffBgColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
697 698
  label = new QLabel( i18n("Current range diff background color:"), page );
  label->setBuddy(pColor);
Joachim Eibl's avatar
Joachim Eibl committed
699 700 701 702
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pColor, line, 1 );
  ++line;

703
  pColor = new OptionColorButton( qRgb(0xff,0xd0,0x80), "ManualAlignmentRangeColor", &m_options.m_manualHelpRangeColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
704 705
  label = new QLabel( i18n("Color for manually aligned difference ranges:"), page );
  label->setBuddy(pColor);
Joachim Eibl's avatar
Joachim Eibl committed
706 707 708 709 710 711 712 713 714
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pColor, line, 1 );
  ++line;

  label = new QLabel( i18n("Directory Comparison View:"), page );
  gbox->addWidget( label, line, 0 );
  label->setFont(f);
  ++line;

715
  pColor = new OptionColorButton( qRgb(0,0xd0,0), "NewestFileColor", &m_options.m_newestFileColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
716 717
  label = new QLabel( i18n("Newest file color:"), page );
  label->setBuddy(pColor);
Joachim Eibl's avatar
Joachim Eibl committed
718 719 720
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pColor, line, 1 );
  QString dirColorTip = i18n( "Changing this color will only be effective when starting the next directory comparison.");
Joachim Eibl's avatar
Joachim Eibl committed
721
  label->setToolTip( dirColorTip );
Joachim Eibl's avatar
Joachim Eibl committed
722 723
  ++line;

724
  pColor = new OptionColorButton( qRgb(0xf0,0,0), "OldestFileColor", &m_options.m_oldestFileColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
725 726
  label = new QLabel( i18n("Oldest file color:"), page );
  label->setBuddy(pColor);
Joachim Eibl's avatar
Joachim Eibl committed
727 728
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pColor, line, 1 );
Joachim Eibl's avatar
Joachim Eibl committed
729
  label->setToolTip( dirColorTip );
Joachim Eibl's avatar
Joachim Eibl committed
730 731
  ++line;

732
  pColor = new OptionColorButton( qRgb(0xc0,0xc0,0), "MidAgeFileColor", &m_options.m_midAgeFileColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
733 734
  label = new QLabel( i18n("Middle age file color:"), page );
  label->setBuddy(pColor);
Joachim Eibl's avatar
Joachim Eibl committed
735 736
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pColor, line, 1 );
Joachim Eibl's avatar
Joachim Eibl committed
737
  label->setToolTip( dirColorTip );
Joachim Eibl's avatar
Joachim Eibl committed
738 739
  ++line;

740
  pColor = new OptionColorButton( qRgb(0,0,0), "MissingFileColor", &m_options.m_missingFileColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
741 742
  label = new QLabel( i18n("Color for missing files:"), page );
  label->setBuddy(pColor);
Joachim Eibl's avatar
Joachim Eibl committed
743 744
  gbox->addWidget( label, line, 0 );
  gbox->addWidget( pColor, line, 1 );
Joachim Eibl's avatar
Joachim Eibl committed
745
  label->setToolTip( dirColorTip );
Joachim Eibl's avatar
Joachim Eibl committed
746 747
  ++line;

Joachim Eibl's avatar
Joachim Eibl committed
748 749 750 751 752 753
  topLayout->addStretch(10);
}


void OptionDialog::setupEditPage( void )
{
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
754 755 756
   QFrame* page = new QFrame();
   KPageWidgetItem* pageItem = new KPageWidgetItem( page, i18n("Editor") );
   pageItem->setHeader( i18n("Editor Behavior") );
Michael Reeves's avatar
Michael Reeves committed
757
   pageItem->setIcon( QIcon::fromTheme(QStringLiteral("accessories-text-editor")) );
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
758 759
   addPage( pageItem );

Joachim Eibl's avatar
Joachim Eibl committed
760 761 762 763 764 765
   QVBoxLayout *topLayout = new QVBoxLayout( page );
   topLayout->setMargin( 5 );
   topLayout->setSpacing( spacingHint() );

   QGridLayout *gbox = new QGridLayout();
   gbox->setColumnStretch(1,5);
Joachim Eibl's avatar
Joachim Eibl committed
766 767 768 769
   topLayout->addLayout( gbox );
   QLabel* label;
   int line=0;

770
   OptionCheckBox* pReplaceTabs = new OptionCheckBox( i18n("Tab inserts spaces"), false, "ReplaceTabs", &m_options.m_bReplaceTabs, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
771 772
   gbox->addWidget( pReplaceTabs, line, 0, 1, 2 );
   pReplaceTabs->setToolTip( i18n(
Joachim Eibl's avatar
Joachim Eibl committed
773
      "On: Pressing tab generates the appropriate number of spaces.\n"
Joachim Eibl's avatar
Joachim Eibl committed
774
      "Off: A tab character will be inserted.")
Joachim Eibl's avatar
Joachim Eibl committed
775 776 777
      );
   ++line;

778
   OptionIntEdit* pTabSize = new OptionIntEdit( 8, "TabSize", &m_options.m_tabSize, 1, 100, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
779 780
   label = new QLabel( i18n("Tab size:"), page );
   label->setBuddy( pTabSize );
Joachim Eibl's avatar
Joachim Eibl committed
781 782 783 784
   gbox->addWidget( label, line, 0 );
   gbox->addWidget( pTabSize, line, 1 );
   ++line;

785
   OptionCheckBox* pAutoIndentation = new OptionCheckBox( i18n("Auto indentation"), true, "AutoIndentation", &m_options.m_bAutoIndentation, page, this  );
Joachim Eibl's avatar
Joachim Eibl committed
786 787
   gbox->addWidget( pAutoIndentation, line, 0, 1, 2 );
   pAutoIndentation->setToolTip( i18n(
Joachim Eibl's avatar
Joachim Eibl committed
788 789 790 791
      "On: The indentation of the previous line is used for a new line.\n"
      ));
   ++line;

792
   OptionCheckBox* pAutoCopySelection = new OptionCheckBox( i18n("Auto copy selection"), false, "AutoCopySelection", &m_options.m_bAutoCopySelection, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
793 794
   gbox->addWidget( pAutoCopySelection, line, 0, 1, 2 );
   pAutoCopySelection->setToolTip( i18n(
Joachim Eibl's avatar
Joachim Eibl committed
795 796 797 798
      "On: Any selection is immediately written to the clipboard.\n"
      "Off: You must explicitely copy e.g. via Ctrl-C."
      ));
   ++line;
Joachim Eibl's avatar
Joachim Eibl committed
799
   
Joachim Eibl's avatar
Joachim Eibl committed
800
   label = new QLabel( i18n("Line end style:"), page );
Joachim Eibl's avatar
Joachim Eibl committed
801
   gbox->addWidget( label, line, 0 );
Joachim Eibl's avatar
Joachim Eibl committed
802

803
   OptionComboBox* pLineEndStyle = new OptionComboBox( eLineEndStyleAutoDetect, "LineEndStyle", &m_options.m_lineEndStyle, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
804
   gbox->addWidget( pLineEndStyle, line, 1 );
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
805 806 807 808
   pLineEndStyle->insertItem( eLineEndStyleUnix, "Unix" );
   pLineEndStyle->insertItem( eLineEndStyleDos, "Dos/Windows" );
   pLineEndStyle->insertItem( eLineEndStyleAutoDetect, "Autodetect" );

Joachim Eibl's avatar
Joachim Eibl committed
809
   label->setToolTip( i18n(
Joachim Eibl's avatar
Joachim Eibl committed
810 811
      "Sets the line endings for when an edited file is saved.\n"
      "DOS/Windows: CR+LF; UNIX: LF; with CR=0D, LF=0A")
Joachim Eibl's avatar
Joachim Eibl committed
812 813 814
      );
   ++line;
      
Joachim Eibl's avatar
Joachim Eibl committed
815 816 817 818 819 820
   topLayout->addStretch(10);
}


void OptionDialog::setupDiffPage( void )
{
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
821 822 823
   QFrame* page = new QFrame();
   KPageWidgetItem* pageItem = new KPageWidgetItem( page, i18n("Diff") );
   pageItem->setHeader( i18n("Diff Settings") );
Michael Reeves's avatar
Michael Reeves committed
824
   pageItem->setIcon( QIcon::fromTheme(QStringLiteral("preferences-other")) );
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
825 826 827
   addPage( pageItem );


Joachim Eibl's avatar
Joachim Eibl committed
828 829 830
   QVBoxLayout *topLayout = new QVBoxLayout( page );
   topLayout->setMargin( 5 );
   topLayout->setSpacing( spacingHint() );
Joachim Eibl's avatar
Joachim Eibl committed
831

Joachim Eibl's avatar
Joachim Eibl committed
832 833
   QGridLayout *gbox = new QGridLayout();
   gbox->setColumnStretch(1,5);
Joachim Eibl's avatar
Joachim Eibl committed
834 835 836
   topLayout->addLayout( gbox );
   int line=0;

Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
837
   QLabel* label=0;
Joachim Eibl's avatar
Joachim Eibl committed
838

839
   m_options.m_bPreserveCarriageReturn = false;
Joachim Eibl's avatar
Joachim Eibl committed
840 841 842 843 844 845 846 847
   //OptionCheckBox* pPreserveCarriageReturn = new OptionCheckBox( i18n("Preserve carriage return"), false, "PreserveCarriageReturn", &m_bPreserveCarriageReturn, page, this );
   //gbox->addWidget( pPreserveCarriageReturn, line, 0, 1, 2 );
   //pPreserveCarriageReturn->setToolTip( i18n(
   //   "Show carriage return characters '\\r' if they exist.\n"
   //   "Helps to compare files that were modified under different operating systems.")
   //   );
   //++line;
   QString treatAsWhiteSpace = " ("+i18n("Treat as white space.")+")";
Joachim Eibl's avatar
Joachim Eibl committed
848

849
   OptionCheckBox* pIgnoreNumbers = new OptionCheckBox( i18n("Ignore numbers")+treatAsWhiteSpace, false, "IgnoreNumbers", &m_options.m_bIgnoreNumbers, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
850 851
   gbox->addWidget( pIgnoreNumbers, line, 0, 1, 2 );
   pIgnoreNumbers->setToolTip( i18n(
Joachim Eibl's avatar
Joachim Eibl committed
852
      "Ignore number characters during line matching phase. (Similar to Ignore white space.)\n"
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
853
      "Might help to compare files with numeric data.")
Joachim Eibl's avatar
Joachim Eibl committed
854 855 856
      );
   ++line;

857
   OptionCheckBox* pIgnoreComments = new OptionCheckBox( i18n("Ignore C/C++ comments")+treatAsWhiteSpace, false, "IgnoreComments", &m_options.m_bIgnoreComments, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
858 859
   gbox->addWidget( pIgnoreComments, line, 0, 1, 2 );
   pIgnoreComments->setToolTip( i18n( "Treat C/C++ comments like white space.")
Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
860 861 862
      );
   ++line;

863
   OptionCheckBox* pIgnoreCase = new OptionCheckBox( i18n("Ignore case")+treatAsWhiteSpace, false, "IgnoreCase", &m_options.m_bIgnoreCase, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
864 865
   gbox->addWidget( pIgnoreCase, line, 0, 1, 2 );
   pIgnoreCase->setToolTip( i18n(
Joachim Eibl's avatar
0.9.86  
Joachim Eibl committed
866
      "Treat case differences like white space changes. ('a'<=>'A')")
Joachim Eibl's avatar
Joachim Eibl committed
867 868 869
      );
   ++line;

Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
870
   label = new QLabel( i18n("Preprocessor command:"), page );
Joachim Eibl's avatar
Joachim Eibl committed
871
   gbox->addWidget( label, line, 0 );
872
   OptionLineEdit* pLE = new OptionLineEdit( "", "PreProcessorCmd", &m_options.m_PreProcessorCmd, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
873
   gbox->addWidget( pLE, line, 1 );
Joachim Eibl's avatar
Joachim Eibl committed
874
   label->setToolTip( i18n("User defined pre-processing. (See the docs for details.)") );
Joachim Eibl's avatar
Joachim Eibl committed
875 876
   ++line;

Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
877
   label = new QLabel( i18n("Line-matching preprocessor command:"), page );
Joachim Eibl's avatar
Joachim Eibl committed
878