katedialogs.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2002, 2003 Anders Lund <anders.lund@lund.tdcadsl.dk>
00003    Copyright (C) 2003 Christoph Cullmann <cullmann@kde.org>
00004    Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
00005 
00006    Based on work of:
00007      Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
00008 
00009    This library is free software; you can redistribute it and/or
00010    modify it under the terms of the GNU Library General Public
00011    License version 2 as published by the Free Software Foundation.
00012 
00013    This library is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016    Library General Public License for more details.
00017 
00018    You should have received a copy of the GNU Library General Public License
00019    along with this library; see the file COPYING.LIB.  If not, write to
00020    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021    Boston, MA 02110-1301, USA.
00022 */
00023 
00024 //BEGIN Includes
00025 #include "katedialogs.h"
00026 #include "katedialogs.moc"
00027 
00028 #include "kateautoindent.h"
00029 #include "katebuffer.h"
00030 #include "kateconfig.h"
00031 #include "katedocument.h"
00032 #include "katefactory.h"
00033 #include "kateschema.h"
00034 #include "katesyntaxdocument.h"
00035 #include "kateview.h"
00036 
00037 
00038 #include <ktexteditor/configinterfaceextension.h>
00039 #include <ktexteditor/plugin.h>
00040 
00041 #include <kio/job.h>
00042 #include <kio/jobclasses.h>
00043 #include <kio/netaccess.h>
00044 
00045 #include <kaccel.h>
00046 #include <kapplication.h>
00047 #include <kbuttonbox.h>
00048 #include <kcharsets.h>
00049 #include <kcolorbutton.h>
00050 #include <kcolorcombo.h>
00051 #include <kcolordialog.h>
00052 #include <kcombobox.h>
00053 #include <kconfig.h>
00054 #include <kdebug.h>
00055 #include <kfontdialog.h>
00056 #include <kglobal.h>
00057 #include <kglobalsettings.h>
00058 #include <kiconloader.h>
00059 #include <kkeybutton.h>
00060 #include <kkeydialog.h>
00061 #include <klineedit.h>
00062 #include <klistview.h>
00063 #include <klocale.h>
00064 #include <kmessagebox.h>
00065 #include <kmimetypechooser.h>
00066 #include <knuminput.h>
00067 #include <kparts/componentfactory.h>
00068 #include <kpopupmenu.h>
00069 #include <kprocess.h>
00070 #include <kprocio.h>
00071 #include <kregexpeditorinterface.h>
00072 #include <krun.h>
00073 #include <kseparator.h>
00074 #include <kstandarddirs.h>
00075 #include <ktempfile.h>
00076 
00077 #include <qbuttongroup.h>
00078 #include <qcheckbox.h>
00079 #include <qcombobox.h>
00080 #include <qdialog.h>
00081 #include <qdom.h>
00082 #include <qfile.h>
00083 #include <qgrid.h>
00084 #include <qgroupbox.h>
00085 #include <qhbox.h>
00086 #include <qheader.h>
00087 #include <qhgroupbox.h>
00088 #include <qlabel.h>
00089 #include <qlayout.h>
00090 #include <qlineedit.h>
00091 #include <qlistbox.h>
00092 #include <qlistview.h>
00093 #include <qmap.h>
00094 #include <qobjectlist.h>
00095 #include <qpainter.h>
00096 #include <qpointarray.h>
00097 #include <qptrcollection.h>
00098 #include <qpushbutton.h>
00099 #include <qradiobutton.h>
00100 #include <qslider.h>
00101 #include <qspinbox.h>
00102 #include <qstringlist.h>
00103 #include <qtabwidget.h>
00104 #include <qtextcodec.h>
00105 #include <qtoolbutton.h>
00106 #include <qvbox.h>
00107 #include <qvgroupbox.h>
00108 #include <qwhatsthis.h>
00109 #include <qwidgetstack.h>
00110 
00111 // trailing slash is important
00112 #define HLDOWNLOADPATH "http://kate.kde.org/syntax/"
00113 
00114 //END
00115 
00116 //BEGIN KateConfigPage
00117 KateConfigPage::KateConfigPage ( QWidget *parent, const char *name )
00118   : Kate::ConfigPage (parent, name)
00119   , m_changed (false)
00120 {
00121   connect (this, SIGNAL(changed()), this, SLOT(somethingHasChanged ()));
00122 }
00123 
00124 KateConfigPage::~KateConfigPage ()
00125 {
00126 }
00127 
00128 void KateConfigPage::somethingHasChanged ()
00129 {
00130   m_changed = true;
00131   kdDebug (13000) << "TEST: something changed on the config page: " << this << endl;
00132 }
00133 //END KateConfigPage
00134 
00135 //BEGIN KateIndentConfigTab
00136 const int KateIndentConfigTab::flags[] = {
00137     KateDocument::cfSpaceIndent,
00138     KateDocument::cfKeepIndentProfile,
00139     KateDocument::cfKeepExtraSpaces,
00140     KateDocument::cfTabIndents,
00141     KateDocument::cfBackspaceIndents,
00142     KateDocumentConfig::cfDoxygenAutoTyping,
00143     KateDocumentConfig::cfMixedIndent,
00144     KateDocumentConfig::cfIndentPastedText
00145 };
00146 
00147 KateIndentConfigTab::KateIndentConfigTab(QWidget *parent)
00148   : KateConfigPage(parent)
00149 {
00150   QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() );
00151   int configFlags = KateDocumentConfig::global()->configFlags();
00152 
00153   QVGroupBox *gbAuto = new QVGroupBox(i18n("Automatic Indentation"), this);
00154 
00155   QHBox *indentLayout = new QHBox(gbAuto);
00156   indentLayout->setSpacing(KDialog::spacingHint());
00157   QLabel *indentLabel = new QLabel(i18n("&Indentation mode:"), indentLayout);
00158   m_indentMode = new KComboBox (indentLayout);
00159   m_indentMode->insertStringList (KateAutoIndent::listModes());
00160   indentLabel->setBuddy(m_indentMode);
00161   m_configPage = new QPushButton(SmallIconSet("configure"), i18n("Configure..."), indentLayout);
00162 
00163   opt[5] = new QCheckBox(i18n("Insert leading Doxygen \"*\" when typing"), gbAuto);
00164   opt[7] = new QCheckBox(i18n("Adjust indentation of code pasted from the clipboard"), gbAuto);
00165 
00166   QVGroupBox *gbSpaces = new QVGroupBox(i18n("Indentation with Spaces"), this);
00167   QVBox *spaceLayout = new QVBox(gbSpaces);
00168   opt[0] = new QCheckBox(i18n("Use &spaces instead of tabs to indent"), spaceLayout );
00169   opt[6] = new QCheckBox(i18n("Emacs style mixed mode"), spaceLayout);
00170 
00171   indentationWidth = new KIntNumInput(KateDocumentConfig::global()->indentationWidth(), spaceLayout);
00172   indentationWidth->setRange(1, 16, 1, false);
00173   indentationWidth->setLabel(i18n("Number of spaces:"), AlignVCenter);
00174 
00175   opt[1] = new QCheckBox(i18n("Keep indent &profile"), this);
00176   opt[2] = new QCheckBox(i18n("&Keep extra spaces"), this);
00177 
00178   QVGroupBox *keys = new QVGroupBox(i18n("Keys to Use"), this);
00179   opt[3] = new QCheckBox(i18n("&Tab key indents"), keys);
00180   opt[4] = new QCheckBox(i18n("&Backspace key indents"), keys);
00181 
00182   QRadioButton *rb1, *rb2, *rb3;
00183   m_tabs = new QButtonGroup( 1, Qt::Horizontal, i18n("Tab Key Mode if Nothing Selected"), this );
00184   m_tabs->setRadioButtonExclusive( true );
00185   m_tabs->insert( rb1=new QRadioButton( i18n("Insert indent &characters"), m_tabs ), 0 );
00186   m_tabs->insert( rb2=new QRadioButton( i18n("I&nsert tab character"), m_tabs ), 1 );
00187   m_tabs->insert( rb3=new QRadioButton( i18n("Indent current &line"), m_tabs ), 2 );
00188 
00189   opt[0]->setChecked(configFlags & flags[0]);
00190   opt[1]->setChecked(configFlags & flags[1]);
00191   opt[2]->setChecked(configFlags & flags[2]);
00192   opt[3]->setChecked(configFlags & flags[3]);
00193   opt[4]->setChecked(configFlags & flags[4]);
00194   opt[5]->setChecked(configFlags & flags[5]);
00195   opt[6]->setChecked(configFlags & flags[6]);
00196   opt[7]->setChecked(configFlags & flags[7]);
00197 
00198   layout->addWidget(gbAuto);
00199   layout->addWidget(gbSpaces);
00200   layout->addWidget(opt[1]);
00201   layout->addWidget(opt[2]);
00202   layout->addWidget(keys);
00203   layout->addWidget(m_tabs, 0);
00204 
00205   layout->addStretch();
00206 
00207   // What is this? help
00208   QWhatsThis::add(opt[0], i18n(
00209         "Check this if you want to indent with spaces rather than tabs."));
00210   QWhatsThis::add(opt[2], i18n(
00211         "Indentations of more than the selected number of spaces will not be "
00212         "shortened."));
00213   QWhatsThis::add(opt[3], i18n(
00214         "This allows the <b>Tab</b> key to be used to increase the indentation "
00215         "level."));
00216   QWhatsThis::add(opt[4], i18n(
00217         "This allows the <b>Backspace</b> key to be used to decrease the "
00218         "indentation level."));
00219   QWhatsThis::add(opt[5], i18n(
00220         "Automatically inserts a leading \"*\" while typing within a Doxygen "
00221         "style comment."));
00222   QWhatsThis::add( opt[6], i18n(
00223       "Use a mix of tab and space characters for indentation.") );
00224   QWhatsThis::add( opt[7], i18n(
00225       "If this option is selected, pasted code from the clipboard is indented. "
00226       "Triggering the <b>undo</b>-action removes the indentation.") );
00227   QWhatsThis::add(indentationWidth, i18n("The number of spaces to indent with."));
00228 
00229   QWhatsThis::add(m_configPage, i18n(
00230         "If this button is enabled, additional indenter specific options are "
00231         "available and can be configured in an extra dialog.") );
00232 
00233   reload ();
00234 
00235   //
00236   // after initial reload, connect the stuff for the changed () signal
00237   //
00238 
00239   connect(m_indentMode, SIGNAL(activated(int)), this, SLOT(slotChanged()));
00240   connect(m_indentMode, SIGNAL(activated(int)), this, SLOT(indenterSelected(int)));
00241 
00242   connect( opt[0], SIGNAL(toggled(bool)), this, SLOT(somethingToggled()));
00243 
00244   connect( opt[0], SIGNAL( toggled(bool) ), this, SLOT( slotChanged() ) );
00245   connect( opt[1], SIGNAL( toggled(bool) ), this, SLOT( slotChanged() ) );
00246   connect( opt[2], SIGNAL( toggled(bool) ), this, SLOT( slotChanged() ) );
00247   connect( opt[3], SIGNAL( toggled(bool) ), this, SLOT( slotChanged() ) );
00248   connect( opt[4], SIGNAL( toggled(bool) ), this, SLOT( slotChanged() ) );
00249   connect( opt[5], SIGNAL( toggled(bool) ), this, SLOT( slotChanged() ) );
00250   connect( opt[6], SIGNAL( toggled(bool) ), this, SLOT( slotChanged() ) );
00251   connect( opt[7], SIGNAL( toggled(bool) ), this, SLOT( slotChanged() ) );
00252 
00253   connect(indentationWidth, SIGNAL(valueChanged(int)), this, SLOT(slotChanged()));
00254 
00255   connect(rb1, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00256   connect(rb2, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00257   connect(rb3, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00258 
00259   connect(m_configPage, SIGNAL(clicked()), this, SLOT(configPage()));
00260 }
00261 
00262 void KateIndentConfigTab::somethingToggled() {
00263   indentationWidth->setEnabled(opt[0]->isChecked());
00264   opt[6]->setEnabled(opt[0]->isChecked());
00265 }
00266 
00267 void KateIndentConfigTab::indenterSelected (int index)
00268 {
00269   if (index == KateDocumentConfig::imCStyle || index == KateDocumentConfig::imCSAndS)
00270     opt[5]->setEnabled(true);
00271   else
00272     opt[5]->setEnabled(false);
00273 
00274   m_configPage->setEnabled( KateAutoIndent::hasConfigPage(index) );
00275 }
00276 
00277 void KateIndentConfigTab::configPage()
00278 {
00279   uint index = m_indentMode->currentItem();
00280   if ( KateAutoIndent::hasConfigPage(index) )
00281   {
00282     KDialogBase dlg(this, "indenter_config_dialog", true, i18n("Configure Indenter"),
00283       KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Cancel, true);
00284 
00285     QVBox *box = new QVBox(&dlg);
00286     box->setSpacing( KDialog::spacingHint() );
00287     dlg.setMainWidget(box);
00288     new QLabel("<qt><b>" + KateAutoIndent::modeDescription(index) + "</b></qt>", box);
00289     new KSeparator(KSeparator::HLine, box);
00290 
00291     IndenterConfigPage* page = KateAutoIndent::configPage(box, index);
00292 
00293     if (!page) return;
00294     box->setStretchFactor(page, 1);
00295 
00296     connect( &dlg, SIGNAL(okClicked()), page, SLOT(apply()) );
00297 
00298     dlg.resize(400, 300);
00299     dlg.exec();
00300   }
00301 }
00302 
00303 void KateIndentConfigTab::apply ()
00304 {
00305   // nothing changed, no need to apply stuff
00306   if (!changed())
00307     return;
00308   m_changed = false;
00309 
00310   KateDocumentConfig::global()->configStart ();
00311 
00312   int configFlags, z;
00313 
00314   configFlags = KateDocumentConfig::global()->configFlags();
00315   for (z = 0; z < numFlags; z++) {
00316     configFlags &= ~flags[z];
00317     if (opt[z]->isChecked()) configFlags |= flags[z];
00318   }
00319 
00320   KateDocumentConfig::global()->setConfigFlags(configFlags);
00321   KateDocumentConfig::global()->setIndentationWidth(indentationWidth->value());
00322 
00323   KateDocumentConfig::global()->setIndentationMode(m_indentMode->currentItem());
00324 
00325   KateDocumentConfig::global()->setConfigFlags (KateDocumentConfig::cfTabIndentsMode, 2 == m_tabs->id (m_tabs->selected()));
00326   KateDocumentConfig::global()->setConfigFlags (KateDocumentConfig::cfTabInsertsTab, 1 == m_tabs->id (m_tabs->selected()));
00327 
00328   KateDocumentConfig::global()->configEnd ();
00329 }
00330 
00331 void KateIndentConfigTab::reload ()
00332 {
00333   if (KateDocumentConfig::global()->configFlags() & KateDocumentConfig::cfTabIndentsMode)
00334     m_tabs->setButton (2);
00335   else if (KateDocumentConfig::global()->configFlags() & KateDocumentConfig::cfTabInsertsTab)
00336     m_tabs->setButton (1);
00337   else
00338     m_tabs->setButton (0);
00339 
00340   m_indentMode->setCurrentItem (KateDocumentConfig::global()->indentationMode());
00341 
00342   somethingToggled ();
00343   indenterSelected (m_indentMode->currentItem());
00344 }
00345 //END KateIndentConfigTab
00346 
00347 //BEGIN KateSelectConfigTab
00348 const int KateSelectConfigTab::flags[] = {};
00349 
00350 KateSelectConfigTab::KateSelectConfigTab(QWidget *parent)
00351   : KateConfigPage(parent)
00352 {
00353   int configFlags = KateDocumentConfig::global()->configFlags();
00354 
00355   QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() );
00356 
00357   QVGroupBox *gbCursor = new QVGroupBox(i18n("Text Cursor Movement"), this);
00358 
00359   opt[0] = new QCheckBox(i18n("Smart ho&me and smart end"), gbCursor);
00360   opt[0]->setChecked(configFlags & KateDocumentConfig::cfSmartHome);
00361   connect(opt[0], SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00362 
00363   opt[1] = new QCheckBox(i18n("Wrap c&ursor"), gbCursor);
00364   opt[1]->setChecked(configFlags & KateDocumentConfig::cfWrapCursor);
00365   connect(opt[1], SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00366 
00367   e6 = new QCheckBox(i18n("&PageUp/PageDown moves cursor"), gbCursor);
00368   e6->setChecked(KateDocumentConfig::global()->pageUpDownMovesCursor());
00369   connect(e6, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00370 
00371   e4 = new KIntNumInput(KateViewConfig::global()->autoCenterLines(), gbCursor);
00372   e4->setRange(0, 1000000, 1, false);
00373   e4->setLabel(i18n("Autocenter cursor (lines):"), AlignVCenter);
00374   connect(e4, SIGNAL(valueChanged(int)), this, SLOT(slotChanged()));
00375 
00376   layout->addWidget(gbCursor);
00377 
00378   QRadioButton *rb1, *rb2;
00379 
00380   m_tabs = new QButtonGroup( 1, Qt::Horizontal, i18n("Selection Mode"), this );
00381   layout->add (m_tabs);
00382 
00383   m_tabs->setRadioButtonExclusive( true );
00384   m_tabs->insert( rb1=new QRadioButton( i18n("&Normal"), m_tabs ), 0 );
00385   m_tabs->insert( rb2=new QRadioButton( i18n("&Persistent"), m_tabs ), 1 );
00386 
00387   layout->addStretch();
00388 
00389   QWhatsThis::add(rb1, i18n(
00390         "Selections will be overwritten by typed text and will be lost on "
00391         "cursor movement."));
00392   QWhatsThis::add(rb2, i18n(
00393         "Selections will stay even after cursor movement and typing."));
00394 
00395   QWhatsThis::add(e4, i18n(
00396         "Sets the number of lines to maintain visible above and below the "
00397         "cursor when possible."));
00398 
00399   QWhatsThis::add(opt[0], i18n(
00400         "When selected, pressing the home key will cause the cursor to skip "
00401         "whitespace and go to the start of a line's text. "
00402         "The same applies for the end key."));
00403 
00404     QWhatsThis::add(opt[1], i18n(
00405         "When on, moving the insertion cursor using the <b>Left</b> and "
00406         "<b>Right</b> keys will go on to previous/next line at beginning/end of "
00407         "the line, similar to most editors.<p>When off, the insertion cursor "
00408         "cannot be moved left of the line start, but it can be moved off the "
00409         "line end, which can be very handy for programmers."));
00410 
00411   QWhatsThis::add(e6, i18n("Selects whether the PageUp and PageDown keys should alter the vertical position of the cursor relative to the top of the view."));
00412 
00413 
00414   reload ();
00415 
00416   //
00417   // after initial reload, connect the stuff for the changed () signal
00418   //
00419 
00420   connect(rb1, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00421   connect(rb2, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00422 }
00423 
00424 void KateSelectConfigTab::apply ()
00425 {
00426   // nothing changed, no need to apply stuff
00427   if (!changed())
00428     return;
00429   m_changed = false;
00430 
00431   KateViewConfig::global()->configStart ();
00432   KateDocumentConfig::global()->configStart ();
00433 
00434   int configFlags = KateDocumentConfig::global()->configFlags();
00435 
00436   configFlags &= ~KateDocumentConfig::cfSmartHome;
00437   configFlags &= ~KateDocumentConfig::cfWrapCursor;
00438 
00439   if (opt[0]->isChecked()) configFlags |= KateDocumentConfig::cfSmartHome;
00440   if (opt[1]->isChecked()) configFlags |= KateDocumentConfig::cfWrapCursor;
00441 
00442   KateDocumentConfig::global()->setConfigFlags(configFlags);
00443 
00444   KateViewConfig::global()->setAutoCenterLines(kMax(0, e4->value()));
00445   KateDocumentConfig::global()->setPageUpDownMovesCursor(e6->isChecked());
00446 
00447   KateViewConfig::global()->setPersistentSelection (m_tabs->id (m_tabs->selected()) == 1);
00448 
00449   KateDocumentConfig::global()->configEnd ();
00450   KateViewConfig::global()->configEnd ();
00451 }
00452 
00453 void KateSelectConfigTab::reload ()
00454 {
00455   if (KateViewConfig::global()->persistentSelection())
00456     m_tabs->setButton (1);
00457   else
00458     m_tabs->setButton (0);
00459 }
00460 //END KateSelectConfigTab
00461 
00462 //BEGIN KateEditConfigTab
00463 const int KateEditConfigTab::flags[] = {KateDocument::cfWordWrap,
00464   KateDocument::cfAutoBrackets, KateDocument::cfShowTabs,
00465   KateDocumentConfig::cfReplaceTabsDyn, KateDocumentConfig::cfRemoveTrailingDyn};
00466 
00467 KateEditConfigTab::KateEditConfigTab(QWidget *parent)
00468   : KateConfigPage(parent)
00469 {
00470   QVBoxLayout *mainLayout = new QVBoxLayout(this, 0, KDialog::spacingHint() );
00471   int configFlags = KateDocumentConfig::global()->configFlags();
00472 
00473   QVGroupBox *gbWhiteSpace = new QVGroupBox(i18n("Tabulators"), this);
00474 
00475   opt[3] = new QCheckBox( i18n("&Insert spaces instead of tabulators"), gbWhiteSpace );
00476   opt[3]->setChecked( configFlags & KateDocumentConfig::cfReplaceTabsDyn );
00477   connect( opt[3], SIGNAL(toggled(bool)), this, SLOT(slotChanged()) );
00478 
00479   opt[2] = new QCheckBox(i18n("&Show tabulators"), gbWhiteSpace);
00480   opt[2]->setChecked(configFlags & flags[2]);
00481   connect(opt[2], SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00482 
00483   e2 = new KIntNumInput(KateDocumentConfig::global()->tabWidth(), gbWhiteSpace);
00484   e2->setRange(1, 16, 1, false);
00485   e2->setLabel(i18n("Tab width:"), AlignVCenter);
00486   connect(e2, SIGNAL(valueChanged(int)), this, SLOT(slotChanged()));
00487 
00488   mainLayout->addWidget(gbWhiteSpace);
00489 
00490   QVGroupBox *gbWordWrap = new QVGroupBox(i18n("Static Word Wrap"), this);
00491 
00492   opt[0] = new QCheckBox(i18n("Enable static &word wrap"), gbWordWrap);
00493   opt[0]->setChecked(KateDocumentConfig::global()->wordWrap());
00494   connect(opt[0], SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00495 
00496   m_wwmarker = new QCheckBox( i18n("&Show static word wrap marker (if applicable)"), gbWordWrap );
00497   m_wwmarker->setChecked( KateRendererConfig::global()->wordWrapMarker() );
00498   connect(m_wwmarker, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00499 
00500   e1 = new KIntNumInput(KateDocumentConfig::global()->wordWrapAt(), gbWordWrap);
00501   e1->setRange(20, 200, 1, false);
00502   e1->setLabel(i18n("Wrap words at:"), AlignVCenter);
00503   connect(e1, SIGNAL(valueChanged(int)), this, SLOT(slotChanged()));
00504 
00505   mainLayout->addWidget(gbWordWrap);
00506 
00507   opt[4] = new QCheckBox( i18n("Remove &trailing spaces"), this );
00508   mainLayout->addWidget( opt[4] );
00509   opt[4]->setChecked( configFlags & KateDocumentConfig::cfRemoveTrailingDyn );
00510   connect( opt[4], SIGNAL(toggled(bool)), this, SLOT(slotChanged()) );
00511 
00512   opt[1] = new QCheckBox(i18n("Auto &brackets"), this);
00513   mainLayout->addWidget(opt[1]);
00514   opt[1]->setChecked(configFlags & flags[1]);
00515   connect(opt[1], SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00516 
00517   e3 = new KIntNumInput(e2, KateDocumentConfig::global()->undoSteps(), this);
00518   e3->setRange(0, 1000000, 1, false);
00519   e3->setSpecialValueText( i18n("Unlimited") );
00520   e3->setLabel(i18n("Maximum undo steps:"), AlignVCenter);
00521   mainLayout->addWidget(e3);
00522   connect(e3, SIGNAL(valueChanged(int)), this, SLOT(slotChanged()));
00523 
00524   QHBoxLayout *e5Layout = new QHBoxLayout(mainLayout);
00525   QLabel *e5Label = new QLabel(i18n("Smart search t&ext from:"), this);
00526   e5Layout->addWidget(e5Label);
00527   e5 = new KComboBox (this);
00528   e5->insertItem( i18n("Nowhere") );
00529   e5->insertItem( i18n("Selection Only") );
00530   e5->insertItem( i18n("Selection, then Current Word") );
00531   e5->insertItem( i18n("Current Word Only") );
00532   e5->insertItem( i18n("Current Word, then Selection") );
00533   e5->setCurrentItem(KateViewConfig::global()->textToSearchMode());
00534   e5Layout->addWidget(e5);
00535   e5Label->setBuddy(e5);
00536   connect(e5, SIGNAL(activated(int)), this, SLOT(slotChanged()));
00537 
00538   mainLayout->addStretch();
00539 
00540   // What is this? help
00541   QWhatsThis::add(opt[0], i18n(
00542         "Automatically start a new line of text when the current line exceeds "
00543         "the length specified by the <b>Wrap words at:</b> option."
00544         "<p>This option does not wrap existing lines of text - use the <b>Apply "
00545         "Static Word Wrap</b> option in the <b>Tools</b> menu for that purpose."
00546         "<p>If you want lines to be <i>visually wrapped</i> instead, according "
00547         "to the width of the view, enable <b>Dynamic Word Wrap</b> in the "
00548         "<b>View Defaults</b> config page."));
00549   QWhatsThis::add(e1, i18n(
00550         "If the Word Wrap option is selected this entry determines the length "
00551         "(in characters) at which the editor will automatically start a new line."));
00552   QWhatsThis::add(opt[1], i18n(
00553         "When the user types a left bracket ([,(, or {) KateView automatically "
00554         "enters the right bracket (}, ), or ]) to the right of the cursor."));
00555   QWhatsThis::add(opt[2], i18n(
00556         "The editor will display a symbol to indicate the presence of a tab in "
00557         "the text."));
00558 
00559   QWhatsThis::add(e3, i18n(
00560         "Sets the number of undo/redo steps to record. More steps uses more memory."));
00561 
00562   QString gstfwt = i18n(
00563         "This determines where KateView will get the search text from "
00564         "(this will be automatically entered into the Find Text dialog): "
00565         "<br>"
00566         "<ul>"
00567         "<li><b>Nowhere:</b> Don't guess the search text."
00568         "</li>"
00569         "<li><b>Selection Only:</b> Use the current text selection, "
00570         "if available."
00571         "</li>"
00572         "<li><b>Selection, then Current Word:</b> Use the current "
00573         "selection if available, otherwise use the current word."
00574         "</li>"
00575         "<li><b>Current Word Only:</b> Use the word that the cursor "
00576         "is currently resting on, if available."
00577         "</li>"
00578         "<li><b>Current Word, then Selection:</b> Use the current "
00579         "word if available, otherwise use the current selection."
00580         "</li>"
00581         "</ul>"
00582         "Note that, in all the above modes, if a search string has "
00583         "not been or cannot be determined, then the Find Text Dialog "
00584         "will fall back to the last search text.");
00585   QWhatsThis::add(e5Label, gstfwt);
00586   QWhatsThis::add(e5, gstfwt);
00587   QWhatsThis::add( opt[3], i18n(
00588       "If this is enabled, the editor will calculate the number of spaces up to "
00589       "the next tab position as defined by the tab width, and insert that number "
00590       "of spaces instead of a TAB character." ) );
00591   QWhatsThis::add( opt[4], i18n(
00592       "If this is enabled, the editor will remove any trailing whitespace on "
00593       "lines when they are left by the insertion cursor.") );
00594   QWhatsThis::add( m_wwmarker, i18n(
00595         "<p>If this option is checked, a vertical line will be drawn at the word "
00596         "wrap column as defined in the <strong>Editing</strong> properties."
00597         "<p>Note that the word wrap marker is only drawn if you use a fixed "
00598         "pitch font." ));
00599 }
00600 
00601 void KateEditConfigTab::apply ()
00602 {
00603   // nothing changed, no need to apply stuff
00604   if (!changed())
00605     return;
00606   m_changed = false;
00607 
00608   KateViewConfig::global()->configStart ();
00609   KateDocumentConfig::global()->configStart ();
00610 
00611   int configFlags, z;
00612 
00613   configFlags = KateDocumentConfig::global()->configFlags();
00614   for (z = 1; z < numFlags; z++) {
00615     configFlags &= ~flags[z];
00616     if (opt[z]->isChecked()) configFlags |= flags[z];
00617   }
00618   KateDocumentConfig::global()->setConfigFlags(configFlags);
00619 
00620   KateDocumentConfig::global()->setWordWrapAt(e1->value());
00621   KateDocumentConfig::global()->setWordWrap (opt[0]->isChecked());
00622   KateDocumentConfig::global()->setTabWidth(e2->value());
00623 
00624   if (e3->value() <= 0)
00625     KateDocumentConfig::global()->setUndoSteps(0);
00626   else
00627     KateDocumentConfig::global()->setUndoSteps(e3->value());
00628 
00629   KateViewConfig::global()->setTextToSearchMode(e5->currentItem());
00630 
00631   KateRendererConfig::global()->setWordWrapMarker (m_wwmarker->isChecked());
00632 
00633   KateDocumentConfig::global()->configEnd ();
00634   KateViewConfig::global()->configEnd ();
00635 }
00636 
00637 void KateEditConfigTab::reload ()
00638 {
00639 }
00640 //END KateEditConfigTab
00641 
00642 //BEGIN KateViewDefaultsConfig
00643 KateViewDefaultsConfig::KateViewDefaultsConfig(QWidget *parent)
00644   :KateConfigPage(parent)
00645 {
00646   QRadioButton *rb1;
00647   QRadioButton *rb2;
00648 
00649   QVBoxLayout *blay=new QVBoxLayout(this,0,KDialog::spacingHint());
00650 
00651   QVGroupBox *gbWordWrap = new QVGroupBox(i18n("Word Wrap"), this);
00652 
00653   m_dynwrap=new QCheckBox(i18n("&Dynamic word wrap"),gbWordWrap);
00654 
00655   QHBox *m_dynwrapIndicatorsLay = new QHBox (gbWordWrap);
00656   m_dynwrapIndicatorsLabel = new QLabel( i18n("Dynamic word wrap indicators (if applicable):"), m_dynwrapIndicatorsLay );
00657   m_dynwrapIndicatorsCombo = new KComboBox( m_dynwrapIndicatorsLay );
00658   m_dynwrapIndicatorsCombo->insertItem( i18n("Off") );
00659   m_dynwrapIndicatorsCombo->insertItem( i18n("Follow Line Numbers") );
00660   m_dynwrapIndicatorsCombo->insertItem( i18n("Always On") );
00661   m_dynwrapIndicatorsLabel->setBuddy(m_dynwrapIndicatorsCombo);
00662 
00663   m_dynwrapAlignLevel = new KIntNumInput(gbWordWrap);
00664   m_dynwrapAlignLevel->setLabel(i18n("Vertically align dynamically wrapped lines to indentation depth:"));
00665   m_dynwrapAlignLevel->setRange(0, 80, 10);
00666   // xgettext:no-c-format
00667   m_dynwrapAlignLevel->setSuffix(i18n("% of View Width"));
00668   m_dynwrapAlignLevel->setSpecialValueText(i18n("Disabled"));
00669 
00670   blay->addWidget(gbWordWrap);
00671 
00672   QVGroupBox *gbFold = new QVGroupBox(i18n("Code Folding"), this);
00673 
00674   m_folding=new QCheckBox(i18n("Show &folding markers (if available)"), gbFold );
00675   m_collapseTopLevel = new QCheckBox( i18n("Collapse toplevel folding nodes"), gbFold );
00676   m_collapseTopLevel->hide ();
00677 
00678   blay->addWidget(gbFold);
00679 
00680   QVGroupBox *gbBar = new QVGroupBox(i18n("Borders"), this);
00681 
00682   m_icons=new QCheckBox(i18n("Show &icon border"),gbBar);
00683   m_line=new QCheckBox(i18n("Show &line numbers"),gbBar);
00684   m_scrollBarMarks=new QCheckBox(i18n("Show &scrollbar marks"),gbBar);
00685 
00686   blay->addWidget(gbBar);
00687 
00688   m_bmSort = new QButtonGroup( 1, Qt::Horizontal, i18n("Sort Bookmarks Menu"), this );
00689   m_bmSort->setRadioButtonExclusive( true );
00690   m_bmSort->insert( rb1=new QRadioButton( i18n("By &position"), m_bmSort ), 0 );
00691   m_bmSort->insert( rb2=new QRadioButton( i18n("By c&reation"), m_bmSort ), 1 );
00692 
00693   blay->addWidget(m_bmSort, 0 );
00694 
00695   m_showIndentLines = new QCheckBox(i18n("Show indentation lines"), this);
00696   m_showIndentLines->setChecked(KateRendererConfig::global()->showIndentationLines());
00697   blay->addWidget(m_showIndentLines);
00698 
00699   blay->addStretch(1000);
00700 
00701   QWhatsThis::add(m_dynwrap,i18n(
00702         "If this option is checked, the text lines will be wrapped at the view "
00703         "border on the screen."));
00704   QString wtstr = i18n("Choose when the Dynamic Word Wrap Indicators should be displayed");
00705   QWhatsThis::add(m_dynwrapIndicatorsLabel, wtstr);
00706   QWhatsThis::add(m_dynwrapIndicatorsCombo, wtstr);
00707   // xgettext:no-c-format
00708   QWhatsThis::add(m_dynwrapAlignLevel, i18n(
00709         "<p>Enables the start of dynamically wrapped lines to be aligned "
00710         "vertically to the indentation level of the first line.  This can help "
00711         "to make code and markup more readable.</p><p>Additionally, this allows "
00712         "you to set a maximum width of the screen, as a percentage, after which "
00713         "dynamically wrapped lines will no longer be vertically aligned.  For "
00714         "example, at 50%, lines whose indentation levels are deeper than 50% of "
00715         "the width of the screen will not have vertical alignment applied to "
00716         "subsequent wrapped lines.</p>"));
00717   QWhatsThis::add(m_line,i18n(
00718         "If this option is checked, every new view will display line numbers "
00719         "on the left hand side."));
00720   QWhatsThis::add(m_icons,i18n(
00721         "If this option is checked, every new view will display an icon border "
00722         "on the left hand side.<br><br>The icon border shows bookmark signs, "
00723         "for instance."));
00724   QWhatsThis::add(m_scrollBarMarks,i18n(
00725         "If this option is checked, every new view will show marks on the "
00726         "vertical scrollbar.<br><br>These marks will, for instance, show "
00727         "bookmarks."));
00728   QWhatsThis::add(m_folding,i18n(
00729         "If this option is checked, every new view will display marks for code "
00730         "folding, if code folding is available."));
00731   QWhatsThis::add(m_bmSort,i18n(
00732         "Choose how the bookmarks should be ordered in the <b>Bookmarks</b> menu."));
00733   QWhatsThis::add(rb1,i18n(
00734         "The bookmarks will be ordered by the line numbers they are placed at."));
00735   QWhatsThis::add(rb2,i18n(
00736         "Each new bookmark will be added to the bottom, independently from "
00737         "where it is placed in the document."));
00738   QWhatsThis::add(m_showIndentLines, i18n(
00739         "If this is enabled, the editor will display vertical lines to help "
00740         "identify indent lines.") );
00741 
00742   reload();
00743 
00744   //
00745   // after initial reload, connect the stuff for the changed () signal
00746   //
00747 
00748   connect(m_dynwrap, SIGNAL(toggled(bool)), this, SLOT(slotChanged()));
00749   connect(m_dynwrapIndicatorsCombo, SIGNAL(activated(int)), this, SLOT(slotChanged()));
00750   connect(m_dynwrapAlignLevel, SIGNAL(valueChanged(int)), this, SLOT(slotChanged()));
00751   connect(m_icons, SIGNAL(toggled(bool)), this, SLOT(