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
   Q_OBJECT
382
   QVector<QTextCodec*> m_codecVec;
Joachim Eibl's avatar
Joachim Eibl committed
383 384 385 386 387 388 389 390 391 392 393 394 395
   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
396 397
      QList<int> mibs = QTextCodec::availableMibs();
      foreach(int i, mibs)
Joachim Eibl's avatar
Joachim Eibl committed
398
      {
Joachim Eibl's avatar
Joachim Eibl committed
399
         QTextCodec* c = QTextCodec::codecForMib(i);
Joachim Eibl's avatar
Joachim Eibl committed
400 401
         if ( c!=0 )
            names[QString(c->name()).toUpper()]=c;
Joachim Eibl's avatar
Joachim Eibl committed
402 403 404 405 406 407 408 409
      }

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

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

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


Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
486 487 488 489
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
490
{
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
491 492
   setFaceType( List );
   setWindowTitle( i18n("Configure") );
Michael Reeves's avatar
Michael Reeves committed
493 494 495 496 497 498 499 500 501 502 503 504 505
   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
506 507
   setObjectName( name );
   setModal( true  );
Joachim Eibl's avatar
Joachim Eibl committed
508
   setHelp( "kdiff3/index.html", QString::null );
Joachim Eibl's avatar
Joachim Eibl committed
509

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

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

   //setupKeysPage();

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

OptionDialog::~OptionDialog( void )
{
}

Joachim Eibl's avatar
0.9.80  
Joachim Eibl committed
537 538
void OptionDialog::setupOtherOptions()
{
539 540 541 542 543 544
   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
545

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

548 549
   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
550

Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
551 552
/*
   TODO manage toolbar positioning
Joachim Eibl's avatar
Joachim Eibl committed
553
   new OptionNum( (int)KToolBar::Top, "ToolBarPos", &m_toolBarPos, this );
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
554
*/
555 556 557
   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
558

559 560 561 562 563
   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 );
564

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

void OptionDialog::setupFontPage( void )
{
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
569 570 571
   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
572
   pageItem->setIcon( QIcon::fromTheme(QStringLiteral("preferences-desktop-font")) );
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
573
   addPage( pageItem );
Joachim Eibl's avatar
Joachim Eibl committed
574

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

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

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

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

595
   OptionCheckBox* pItalicDeltas = new OptionCheckBox( i18n("Italic font for deltas"), false, "ItalicForDeltas", &m_options.m_bItalicForDeltas, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
596 597
   gbox->addWidget( pItalicDeltas, line, 0, 1, 2 );
   pItalicDeltas->setToolTip( i18n(
Joachim Eibl's avatar
Joachim Eibl committed
598 599 600 601 602 603 604 605
      "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
606 607 608
   QFrame* page = new QFrame();
   KPageWidgetItem* pageItem = new KPageWidgetItem( page, i18n("Color") );
   pageItem->setHeader( i18n("Colors Settings") );
Michael Reeves's avatar
Michael Reeves committed
609
   pageItem->setIcon( QIcon::fromTheme(QStringLiteral("preferences-desktop-color")) );
Joachim Eibl's avatar
0.9.93  
Joachim Eibl committed
610 611
   addPage( pageItem );

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

Joachim Eibl's avatar
Joachim Eibl committed
616 617 618

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

  QLabel* label;
  int line = 0;

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

Joachim Eibl's avatar
Joachim Eibl committed
627 628 629 630 631 632 633
  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;

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

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

  ++line;

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

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

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

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

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

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

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

704
  pColor = new OptionColorButton( qRgb(0xff,0xd0,0x80), "ManualAlignmentRangeColor", &m_options.m_manualHelpRangeColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
705 706
  label = new QLabel( i18n("Color for manually aligned difference ranges:"), page );
  label->setBuddy(pColor);
Joachim Eibl's avatar
Joachim Eibl committed
707 708 709 710 711 712 713 714 715
  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;

716
  pColor = new OptionColorButton( qRgb(0,0xd0,0), "NewestFileColor", &m_options.m_newestFileColor, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
717 718
  label = new QLabel( i18n("Newest file color:"), page );
  label->setBuddy(pColor);
Joachim Eibl's avatar
Joachim Eibl committed
719 720 721
  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
722
  label->setToolTip( dirColorTip );
Joachim Eibl's avatar
Joachim Eibl committed
723 724
  ++line;

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

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

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

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


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

Joachim Eibl's avatar
Joachim Eibl committed
761 762 763 764 765 766
   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
767 768 769 770
   topLayout->addLayout( gbox );
   QLabel* label;
   int line=0;

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

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

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

793
   OptionCheckBox* pAutoCopySelection = new OptionCheckBox( i18n("Auto copy selection"), false, "AutoCopySelection", &m_options.m_bAutoCopySelection, page, this );
Joachim Eibl's avatar
Joachim Eibl committed
794 795
   gbox->addWidget( pAutoCopySelection, line, 0, 1, 2 );
   pAutoCopySelection->setToolTip( i18n(
Joachim Eibl's avatar
Joachim Eibl committed
796 797 798 799
      "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
800
   
Joachim Eibl's avatar
Joachim Eibl committed
801
   label = new QLabel( i18n("Line end style:"), page );
Joachim Eibl's avatar
Joachim Eibl committed
802
   gbox->addWidget( label, line, 0 );
Joachim Eibl's avatar
Joachim Eibl committed
803

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

Joachim Eibl's avatar
Joachim Eibl committed
810
   label->setToolTip( i18n(
Joachim Eibl's avatar
Joachim Eibl committed
811 812
      "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
813 814 815
      );
   ++line;
      
Joachim Eibl's avatar
Joachim Eibl committed
816 817 818 819 820 821
   topLayout->addStretch(10);
}


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


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

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

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

840
   m_options.m_bPreserveCarriageReturn = false;
Joachim Eibl's avatar
Joachim Eibl committed
841 842 843 844 845 846 847 848
   //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
849

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

858
   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
859 860
   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
861 862 863
      );
   ++line;

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

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

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