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(slotChanged())); 00752 connect(m_scrollBarMarks, SIGNAL(toggled(bool)), this, SLOT(slotChanged())); 00753 connect(m_line, SIGNAL(toggled(bool)), this, SLOT(slotChanged())); 00754 connect(m_folding, SIGNAL(toggled(bool)), this, SLOT(slotChanged())); 00755 connect(m_collapseTopLevel, SIGNAL(toggled(bool)), this, SLOT(slotChanged()) ); 00756 connect(rb1, SIGNAL(toggled(bool)), this, SLOT(slotChanged())); 00757 connect(rb2, SIGNAL(toggled(bool)), this, SLOT(slotChanged())); 00758 connect(m_showIndentLines, SIGNAL(toggled(bool)), this, SLOT(slotChanged())); 00759 } 00760 00761 KateViewDefaultsConfig::~KateViewDefaultsConfig() 00762 { 00763 } 00764 00765 void KateViewDefaultsConfig::apply () 00766 { 00767 // nothing changed, no need to apply stuff 00768 if (!changed()) 00769 return; 00770 m_changed = false; 00771 00772 KateViewConfig::global()->configStart (); 00773 KateRendererConfig::global()->configStart (); 00774 00775 KateViewConfig::global()->setDynWordWrap (m_dynwrap->isChecked()); 00776 KateViewConfig::global()->setDynWordWrapIndicators (m_dynwrapIndicatorsCombo->currentItem ()); 00777 KateViewConfig::global()->setDynWordWrapAlignIndent(m_dynwrapAlignLevel->value()); 00778 KateViewConfig::global()->setLineNumbers (m_line->isChecked()); 00779 KateViewConfig::global()->setIconBar (m_icons->isChecked()); 00780 KateViewConfig::global()->setScrollBarMarks (m_scrollBarMarks->isChecked()); 00781 KateViewConfig::global()->setFoldingBar (m_folding->isChecked()); 00782 KateViewConfig::global()->setBookmarkSort (m_bmSort->id (m_bmSort->selected())); 00783 00784 KateRendererConfig::global()->setShowIndentationLines(m_showIndentLines->isChecked()); 00785 00786 KateRendererConfig::global()->configEnd (); 00787 KateViewConfig::global()->configEnd (); 00788 } 00789 00790 void KateViewDefaultsConfig::reload () 00791 { 00792 m_dynwrap->setChecked(KateViewConfig::global()->dynWordWrap()); 00793 m_dynwrapIndicatorsCombo->setCurrentItem( KateViewConfig::global()->dynWordWrapIndicators() ); 00794 m_dynwrapAlignLevel->setValue(KateViewConfig::global()->dynWordWrapAlignIndent()); 00795 m_line->setChecked(KateViewConfig::global()->lineNumbers()); 00796 m_icons->setChecked(KateViewConfig::global()->iconBar()); 00797 m_scrollBarMarks->setChecked(KateViewConfig::global()->scrollBarMarks()); 00798 m_folding->setChecked(KateViewConfig::global()->foldingBar()); 00799 m_bmSort->setButton( KateViewConfig::global()->bookmarkSort() ); 00800 m_showIndentLines->setChecked(KateRendererConfig::global()->showIndentationLines()); 00801 } 00802 00803 void KateViewDefaultsConfig::reset () {;} 00804 00805 void KateViewDefaultsConfig::defaults (){;} 00806 //END KateViewDefaultsConfig 00807 00808 //BEGIN KateEditKeyConfiguration 00809 00810 KateEditKeyConfiguration::KateEditKeyConfiguration( QWidget* parent, KateDocument* doc ) 00811 : KateConfigPage( parent ) 00812 { 00813 m_doc = doc; 00814 m_ready = false; 00815 } 00816 00817 void KateEditKeyConfiguration::showEvent ( QShowEvent * ) 00818 { 00819 if (!m_ready) 00820 { 00821 (new QVBoxLayout(this))->setAutoAdd(true); 00822 KateView* view = (KateView*)m_doc->views().at(0); 00823 m_ac = view->editActionCollection(); 00824 m_keyChooser = new KKeyChooser( m_ac, this, false ); 00825 connect( m_keyChooser, SIGNAL( keyChange() ), this, SLOT( slotChanged() ) ); 00826 m_keyChooser->show (); 00827 00828 m_ready = true; 00829 } 00830 00831 QWidget::show (); 00832 } 00833 00834 void KateEditKeyConfiguration::apply() 00835 { 00836 if ( ! changed() ) 00837 return; 00838 m_changed = false; 00839 00840 if (m_ready) 00841 { 00842 m_keyChooser->commitChanges(); 00843 m_ac->writeShortcutSettings( "Katepart Shortcuts" ); 00844 } 00845 } 00846 //END KateEditKeyConfiguration 00847 00848 //BEGIN KateSaveConfigTab 00849 KateSaveConfigTab::KateSaveConfigTab( QWidget *parent ) 00850 : KateConfigPage( parent ) 00851 { 00852 int configFlags = KateDocumentConfig::global()->configFlags(); 00853 QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() ); 00854 00855 QVGroupBox *gbEnc = new QVGroupBox(i18n("File Format"), this); 00856 layout->addWidget( gbEnc ); 00857 00858 QHBox *e5Layout = new QHBox(gbEnc); 00859 QLabel *e5Label = new QLabel(i18n("&Encoding:"), e5Layout); 00860 m_encoding = new KComboBox (e5Layout); 00861 e5Label->setBuddy(m_encoding); 00862 00863 e5Layout = new QHBox(gbEnc); 00864 e5Label = new QLabel(i18n("End &of line:"), e5Layout); 00865 m_eol = new KComboBox (e5Layout); 00866 e5Label->setBuddy(m_eol); 00867 00868 allowEolDetection = new QCheckBox(i18n("&Automatic end of line detection"), gbEnc); 00869 00870 m_eol->insertItem (i18n("UNIX")); 00871 m_eol->insertItem (i18n("DOS/Windows")); 00872 m_eol->insertItem (i18n("Macintosh")); 00873 00874 QVGroupBox *gbMem = new QVGroupBox(i18n("Memory Usage"), this); 00875 layout->addWidget( gbMem ); 00876 00877 e5Layout = new QHBox(gbMem); 00878 e5Layout->setSpacing (32); 00879 blockCountLabel = new QLabel(i18n("Maximum loaded &blocks per file:"), e5Layout); 00880 blockCount = new QSpinBox (4, 512, 4, e5Layout); 00881 00882 blockCount->setValue (KateBuffer::maxLoadedBlocks()); 00883 blockCountLabel->setBuddy(blockCount); 00884 00885 QVGroupBox *gbWhiteSpace = new QVGroupBox(i18n("Automatic Cleanups on Load/Save"), this); 00886 layout->addWidget( gbWhiteSpace ); 00887 00888 removeSpaces = new QCheckBox(i18n("Re&move trailing spaces"), gbWhiteSpace); 00889 removeSpaces->setChecked(configFlags & KateDocument::cfRemoveSpaces); 00890 00891 QVGroupBox *dirConfigBox = new QVGroupBox(i18n("Folder Config File"), this); 00892 layout->addWidget( dirConfigBox ); 00893 00894 dirSearchDepth = new KIntNumInput(KateDocumentConfig::global()->searchDirConfigDepth(), dirConfigBox); 00895 dirSearchDepth->setRange(-1, 64, 1, false); 00896 dirSearchDepth->setSpecialValueText( i18n("Do not use config file") ); 00897 dirSearchDepth->setLabel(i18n("Se&arch depth for config file:"), AlignVCenter); 00898 00899 QGroupBox *gb = new QGroupBox( 1, Qt::Horizontal, i18n("Backup on Save"), this ); 00900 layout->addWidget( gb ); 00901 cbLocalFiles = new QCheckBox( i18n("&Local files"), gb ); 00902 cbRemoteFiles = new QCheckBox( i18n("&Remote files"), gb ); 00903 00904 QHBox *hbBuPrefix = new QHBox( gb ); 00905 QLabel *lBuPrefix = new QLabel( i18n("&Prefix:"), hbBuPrefix ); 00906 leBuPrefix = new QLineEdit( hbBuPrefix ); 00907 lBuPrefix->setBuddy( leBuPrefix ); 00908 00909 QHBox *hbBuSuffix = new QHBox( gb ); 00910 QLabel *lBuSuffix = new QLabel( i18n("&Suffix:"), hbBuSuffix ); 00911 leBuSuffix = new QLineEdit( hbBuSuffix ); 00912 lBuSuffix->setBuddy( leBuSuffix ); 00913 00914 layout->addStretch(); 00915 00916 QWhatsThis::add(removeSpaces, i18n( 00917 "The editor will automatically eliminate extra spaces at the ends of " 00918 "lines of text while loading/saving the file.")); 00919 QWhatsThis::add( gb, i18n( 00920 "<p>Backing up on save will cause Kate to copy the disk file to " 00921 "'<prefix><filename><suffix>' before saving changes." 00922 "<p>The suffix defaults to <strong>~</strong> and prefix is empty by default" ) ); 00923 QWhatsThis::add( allowEolDetection, i18n( 00924 "Check this if you want the editor to autodetect the end of line type." 00925 "The first found end of line type will be used for the whole file.") ); 00926 QWhatsThis::add( cbLocalFiles, i18n( 00927 "Check this if you want backups of local files when saving") ); 00928 QWhatsThis::add( cbRemoteFiles, i18n( 00929 "Check this if you want backups of remote files when saving") ); 00930 QWhatsThis::add( leBuPrefix, i18n( 00931 "Enter the prefix to prepend to the backup file names" ) ); 00932 QWhatsThis::add( leBuSuffix, i18n( 00933 "Enter the suffix to add to the backup file names" ) ); 00934 QWhatsThis::add(dirSearchDepth, i18n( 00935 "The editor will search the given number of folder levels upwards for .kateconfig file" 00936 " and load the settings line from it." )); 00937 QWhatsThis::add(blockCount, i18n( 00938 "The editor will load given number of blocks (of around 2048 lines) of text into memory;" 00939 " if the filesize is bigger than this the other blocks are swapped " 00940 " to disk and loaded transparently as-needed.<br>" 00941 " This can cause little delays while navigating in the document; a larger block count" 00942 " increases the editing speed at the cost of memory. <br>For normal usage, just choose the highest possible" 00943 " block count: limit it only if you have problems with the memory usage.")); 00944 00945 reload(); 00946 00947 // 00948 // after initial reload, connect the stuff for the changed () signal 00949 // 00950 00951 connect(m_encoding, SIGNAL(activated(int)), this, SLOT(slotChanged())); 00952 connect(m_eol, SIGNAL(activated(int)), this, SLOT(slotChanged())); 00953 connect( allowEolDetection, SIGNAL( toggled(bool) ), this, SLOT( slotChanged() ) ); 00954 connect(blockCount, SIGNAL(valueChanged(int)), this, SLOT(slotChanged())); 00955 connect(removeSpaces, SIGNAL(toggled(bool)), this, SLOT(slotChanged())); 00956 connect( cbLocalFiles, SIGNAL( toggled(bool) ), this, SLOT( slotChanged() ) ); 00957 connect( cbRemoteFiles, SIGNAL( toggled(bool) ), this, SLOT( slotChanged() ) ); 00958 connect(dirSearchDepth, SIGNAL(valueChanged(int)), this, SLOT(slotChanged())); 00959 connect( leBuPrefix, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) ); 00960 connect( leBuSuffix, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) ); 00961 } 00962 00963 void KateSaveConfigTab::apply() 00964 { 00965 // nothing changed, no need to apply stuff 00966 if (!changed()) 00967 return; 00968 m_changed = false; 00969 00970 KateBuffer::setMaxLoadedBlocks (blockCount->value()); 00971 00972 KateDocumentConfig::global()->configStart (); 00973 00974 if ( leBuSuffix->text().isEmpty() && leBuPrefix->text().isEmpty() ) { 00975 KMessageBox::information( 00976 this, 00977 i18n("You did not provide a backup suffix or prefix. Using default suffix: '~'"), 00978 i18n("No Backup Suffix or Prefix") 00979 ); 00980 leBuSuffix->setText( "~" ); 00981 } 00982 00983 uint f( 0 ); 00984 if ( cbLocalFiles->isChecked() ) 00985 f |= KateDocumentConfig::LocalFiles; 00986 if ( cbRemoteFiles->isChecked() ) 00987 f |= KateDocumentConfig::RemoteFiles; 00988 00989 KateDocumentConfig::global()->setBackupFlags(f); 00990 KateDocumentConfig::global()->setBackupPrefix(leBuPrefix->text()); 00991 KateDocumentConfig::global()->setBackupSuffix(leBuSuffix->text()); 00992 00993 KateDocumentConfig::global()->setSearchDirConfigDepth(dirSearchDepth->value()); 00994 00995 int configFlags = KateDocumentConfig::global()->configFlags(); 00996 00997 configFlags &= ~KateDocument::cfRemoveSpaces; // clear flag 00998 if (removeSpaces->isChecked()) configFlags |= KateDocument::cfRemoveSpaces; // set flag if checked 00999 01000 KateDocumentConfig::global()->setConfigFlags(configFlags); 01001 01002 KateDocumentConfig::global()->setEncoding((m_encoding->currentItem() == 0) ? "" : KGlobal::charsets()->encodingForName(m_encoding->currentText())); 01003 01004 KateDocumentConfig::global()->setEol(m_eol->currentItem()); 01005 KateDocumentConfig::global()->setAllowEolDetection(allowEolDetection->isChecked()); 01006 01007 KateDocumentConfig::global()->configEnd (); 01008 } 01009 01010 void KateSaveConfigTab::reload() 01011 { 01012 // encoding 01013 m_encoding->clear (); 01014 m_encoding->insertItem (i18n("KDE Default")); 01015 m_encoding->setCurrentItem(0); 01016 QStringList encodings (KGlobal::charsets()->descriptiveEncodingNames()); 01017 int insert = 1; 01018 for (uint i=0; i < encodings.count(); i++) 01019 { 01020 bool found = false; 01021 QTextCodec *codecForEnc = KGlobal::charsets()->codecForName(KGlobal::charsets()->encodingForName(encodings[i]), found); 01022 01023 if (found) 01024 { 01025 m_encoding->insertItem (encodings[i]); 01026 01027 if ( codecForEnc->name() == KateDocumentConfig::global()->encoding() ) 01028 { 01029 m_encoding->setCurrentItem(insert); 01030 } 01031 01032 insert++; 01033 } 01034 } 01035 01036 // eol 01037 m_eol->setCurrentItem(KateDocumentConfig::global()->eol()); 01038 allowEolDetection->setChecked(KateDocumentConfig::global()->allowEolDetection()); 01039 01040 dirSearchDepth->setValue(KateDocumentConfig::global()->searchDirConfigDepth()); 01041 01042 // other stuff 01043 uint f ( KateDocumentConfig::global()->backupFlags() ); 01044 cbLocalFiles->setChecked( f & KateDocumentConfig::LocalFiles ); 01045 cbRemoteFiles->setChecked( f & KateDocumentConfig::RemoteFiles ); 01046 leBuPrefix->setText( KateDocumentConfig::global()->backupPrefix() ); 01047 leBuSuffix->setText( KateDocumentConfig::global()->backupSuffix() ); 01048 } 01049 01050 void KateSaveConfigTab::reset() 01051 { 01052 } 01053 01054 void KateSaveConfigTab::defaults() 01055 { 01056 cbLocalFiles->setChecked( true ); 01057 cbRemoteFiles->setChecked( false ); 01058 leBuPrefix->setText( "" ); 01059 leBuSuffix->setText( "~" ); 01060 } 01061 01062 //END KateSaveConfigTab 01063 01064 //BEGIN PluginListItem 01065 class KatePartPluginListItem : public QCheckListItem 01066 { 01067 public: 01068 KatePartPluginListItem(bool checked, uint i, const QString &name, QListView *parent); 01069 uint pluginIndex () const { return index; } 01070 01071 protected: 01072 void stateChange(bool); 01073 01074 private: 01075 uint index; 01076 bool silentStateChange; 01077 }; 01078 01079 KatePartPluginListItem::KatePartPluginListItem(bool checked, uint i, const QString &name, QListView *parent) 01080 : QCheckListItem(parent, name, CheckBox) 01081 , index(i) 01082 , silentStateChange(false) 01083 { 01084 silentStateChange = true; 01085 setOn(checked); 01086 silentStateChange = false; 01087 } 01088 01089 void KatePartPluginListItem::stateChange(bool b) 01090 { 01091 if(!silentStateChange) 01092 static_cast<KatePartPluginListView *>(listView())->stateChanged(this, b); 01093 } 01094 //END 01095 01096 //BEGIN PluginListView 01097 KatePartPluginListView::KatePartPluginListView(QWidget *parent, const char *name) 01098 : KListView(parent, name) 01099 { 01100 } 01101 01102 void KatePartPluginListView::stateChanged(KatePartPluginListItem *item, bool b) 01103 { 01104 emit stateChange(item, b); 01105 } 01106 //END 01107 01108 //BEGIN KatePartPluginConfigPage 01109 KatePartPluginConfigPage::KatePartPluginConfigPage (QWidget *parent) : KateConfigPage (parent, "") 01110 { 01111 // sizemanagment 01112 QGridLayout *grid = new QGridLayout( this, 1, 1 ); 01113 grid->setSpacing( KDialogBase::spacingHint() ); 01114 01115 listView = new KatePartPluginListView(this); 01116 listView->addColumn(i18n("Name")); 01117 listView->addColumn(i18n("Comment")); 01118 01119 grid->addWidget( listView, 0, 0); 01120 01121 for (uint i=0; i<KateFactory::self()->plugins().count(); i++) 01122 { 01123 KatePartPluginListItem *item = new KatePartPluginListItem(KateDocumentConfig::global()->plugin(i), i, (KateFactory::self()->plugins())[i]->name(), listView); 01124 item->setText(0, (KateFactory::self()->plugins())[i]->name()); 01125 item->setText(1, (KateFactory::self()->plugins())[i]->comment()); 01126 01127 m_items.append (item); 01128 } 01129 01130 // configure button 01131 01132 btnConfigure = new QPushButton( i18n("Configure..."), this ); 01133 btnConfigure->setEnabled( false ); 01134 grid->addWidget( btnConfigure, 1, 0, Qt::AlignRight ); 01135 connect( btnConfigure, SIGNAL(clicked()), this, SLOT(slotConfigure()) ); 01136 01137 connect( listView, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(slotCurrentChanged(QListViewItem*)) ); 01138 connect( listView, SIGNAL(stateChange(KatePartPluginListItem *, bool)), 01139 this, SLOT(slotStateChanged(KatePartPluginListItem *, bool))); 01140 connect(listView, SIGNAL(stateChange(KatePartPluginListItem *, bool)), this, SLOT(slotChanged())); 01141 } 01142 01143 KatePartPluginConfigPage::~KatePartPluginConfigPage () 01144 { 01145 } 01146 01147 void KatePartPluginConfigPage::apply () 01148 { 01149 // nothing changed, no need to apply stuff 01150 if (!changed()) 01151 return; 01152 m_changed = false; 01153 01154 KateDocumentConfig::global()->configStart (); 01155 01156 for (uint i=0; i < m_items.count(); i++) 01157 KateDocumentConfig::global()->setPlugin (m_items.at(i)->pluginIndex(), m_items.at(i)->isOn()); 01158 01159 KateDocumentConfig::global()->configEnd (); 01160 } 01161 01162 void KatePartPluginConfigPage::slotStateChanged( KatePartPluginListItem *item, bool b ) 01163 { 01164 if ( b ) 01165 slotCurrentChanged( (QListViewItem*)item ); 01166 } 01167 01168 void KatePartPluginConfigPage::slotCurrentChanged( QListViewItem* i ) 01169 { 01170 KatePartPluginListItem *item = static_cast<KatePartPluginListItem *>(i); 01171 if ( ! item ) return; 01172 01173 bool b = false; 01174 if ( item->isOn() ) 01175 { 01176 01177 // load this plugin, and see if it has config pages 01178 KTextEditor::Plugin *plugin = KTextEditor::createPlugin(QFile::encodeName((KateFactory::self()->plugins())[item->pluginIndex()]->library())); 01179 if ( plugin ) { 01180 KTextEditor::ConfigInterfaceExtension *cie = KTextEditor::configInterfaceExtension( plugin ); 01181 b = ( cie && cie->configPages() ); 01182 } 01183 01184 } 01185 btnConfigure->setEnabled( b ); 01186 } 01187 01188 void KatePartPluginConfigPage::slotConfigure() 01189 { 01190 KatePartPluginListItem *item = static_cast<KatePartPluginListItem*>(listView->currentItem()); 01191 KTextEditor::Plugin *plugin = 01192 KTextEditor::createPlugin(QFile::encodeName((KateFactory::self()->plugins())[item->pluginIndex()]->library())); 01193 01194 if ( ! plugin ) return; 01195 01196 KTextEditor::ConfigInterfaceExtension *cife = 01197 KTextEditor::configInterfaceExtension( plugin ); 01198 01199 if ( ! cife ) 01200 return; 01201 01202 if ( ! cife->configPages() ) 01203 return; 01204 01205 // If we have only one page, we use a simple dialog, else an icon list type 01206 KDialogBase::DialogType dt = 01207 cife->configPages() > 1 ? 01208 KDialogBase::IconList : // still untested 01209 KDialogBase::Plain; 01210 01211 QString name = (KateFactory::self()->plugins())[item->pluginIndex()]->name(); 01212 KDialogBase *kd = new KDialogBase ( dt, 01213 i18n("Configure %1").arg( name ), 01214 KDialogBase::Ok | KDialogBase::Cancel | KDialogBase::Help, 01215 KDialogBase::Ok, 01216 this ); 01217 01218 QPtrList<KTextEditor::ConfigPage> editorPages; 01219 01220 for (uint i = 0; i < cife->configPages (); i++) 01221 { 01222 QWidget *page; 01223 if ( dt == KDialogBase::IconList ) 01224 { 01225 QStringList path; 01226 path.clear(); 01227 path << cife->configPageName( i ); 01228 page = kd->addVBoxPage( path, cife->configPageFullName (i), 01229 cife->configPagePixmap(i, KIcon::SizeMedium) ); 01230 } 01231 else 01232 { 01233 page = kd->plainPage(); 01234 QVBoxLayout *_l = new QVBoxLayout( page ); 01235 _l->setAutoAdd( true ); 01236 } 01237 01238 editorPages.append( cife->configPage( i, page ) ); 01239 } 01240 01241 if (kd->exec()) 01242 { 01243 01244 for( uint i=0; i<editorPages.count(); i++ ) 01245 { 01246 editorPages.at( i )->apply(); 01247 } 01248 } 01249 01250 delete kd; 01251 } 01252 //END KatePartPluginConfigPage 01253 01254 //BEGIN KateHlConfigPage 01255 KateHlConfigPage::KateHlConfigPage (QWidget *parent, KateDocument *doc) 01256 : KateConfigPage (parent, "") 01257 , hlData (0) 01258 , m_doc (doc) 01259 { 01260 QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() ); 01261 01262 // hl chooser 01263 QHBox *hbHl = new QHBox( this ); 01264 layout->add (hbHl); 01265 01266 hbHl->setSpacing( KDialog::spacingHint() ); 01267 QLabel *lHl = new QLabel( i18n("H&ighlight:"), hbHl ); 01268 hlCombo = new QComboBox( false, hbHl ); 01269 lHl->setBuddy( hlCombo ); 01270 connect( hlCombo, SIGNAL(activated(int)), 01271 this, SLOT(hlChanged(int)) ); 01272 01273 for( int i = 0; i < KateHlManager::self()->highlights(); i++) { 01274 if (KateHlManager::self()->hlSection(i).length() > 0) 01275 hlCombo->insertItem(KateHlManager::self()->hlSection(i) + QString ("/") + KateHlManager::self()->hlNameTranslated(i)); 01276 else 01277 hlCombo->insertItem(KateHlManager::self()->hlNameTranslated(i)); 01278 } 01279 01280 QGroupBox *gbInfo = new QGroupBox( 1, Qt::Horizontal, i18n("Information"), this ); 01281 layout->add (gbInfo); 01282 01283 // author 01284 QHBox *hb1 = new QHBox( gbInfo); 01285 new QLabel( i18n("Author:"), hb1 ); 01286 author = new QLabel (hb1); 01287 author->setTextFormat (Qt::RichText); 01288 01289 // license 01290 QHBox *hb2 = new QHBox( gbInfo); 01291 new QLabel( i18n("License:"), hb2 ); 01292 license = new QLabel (hb2); 01293 01294 QGroupBox *gbProps = new QGroupBox( 1, Qt::Horizontal, i18n("Properties"), this ); 01295 layout->add (gbProps); 01296 01297 // file & mime types 01298 QHBox *hbFE = new QHBox( gbProps); 01299 QLabel *lFileExts = new QLabel( i18n("File e&xtensions:"), hbFE ); 01300 wildcards = new QLineEdit( hbFE ); 01301 lFileExts->setBuddy( wildcards ); 01302 01303 QHBox *hbMT = new QHBox( gbProps ); 01304 QLabel *lMimeTypes = new QLabel( i18n("MIME &types:"), hbMT); 01305 mimetypes = new QLineEdit( hbMT ); 01306 lMimeTypes->setBuddy( mimetypes ); 01307 01308 QHBox *hbMT2 = new QHBox( gbProps ); 01309 QLabel *lprio = new QLabel( i18n("Prio&rity:"), hbMT2); 01310 priority = new KIntNumInput( hbMT2 ); 01311 01312 lprio->setBuddy( priority ); 01313 01314 QToolButton *btnMTW = new QToolButton(hbMT); 01315 btnMTW->setIconSet(QIconSet(SmallIcon("wizard"))); 01316 connect(btnMTW, SIGNAL(clicked()), this, SLOT(showMTDlg())); 01317 01318 // download/new buttons 01319 QHBox *hbBtns = new QHBox( this ); 01320 layout->add (hbBtns); 01321 01322 ((QBoxLayout*)hbBtns->layout())->addStretch(1); // hmm. 01323 hbBtns->setSpacing( KDialog::spacingHint() ); 01324 QPushButton *btnDl = new QPushButton(i18n("Do&wnload..."), hbBtns); 01325 connect( btnDl, SIGNAL(clicked()), this, SLOT(hlDownload()) ); 01326 01327 int currentHl = m_doc ? m_doc->hlMode() : 0; 01328 hlCombo->setCurrentItem( currentHl ); 01329 hlChanged( currentHl ); 01330 01331 QWhatsThis::add( hlCombo, i18n( 01332 "Choose a <em>Syntax Highlight mode</em> from this list to view its " 01333 "properties below.") ); 01334 QWhatsThis::add( wildcards, i18n( 01335 "The list of file extensions used to determine which files to highlight " 01336 "using the current syntax highlight mode.") ); 01337 QWhatsThis::add( mimetypes, i18n( 01338 "The list of Mime Types used to determine which files to highlight " 01339 "using the current highlight mode.<p>Click the wizard button on the " 01340 "left of the entry field to display the MimeType selection dialog.") ); 01341 QWhatsThis::add( btnMTW, i18n( 01342 "Display a dialog with a list of all available mime types to choose from." 01343 "<p>The <strong>File Extensions</strong> entry will automatically be " 01344 "edited as well.") ); 01345 QWhatsThis::add( btnDl, i18n( 01346 "Click this button to download new or updated syntax highlight " 01347 "descriptions from the Kate website.") ); 01348 01349 layout->addStretch (); 01350 01351 connect( wildcards, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) ); 01352 connect( mimetypes, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotChanged() ) ); 01353 connect( priority, SIGNAL( valueChanged ( int ) ), this, SLOT( slotChanged() ) ); 01354 } 01355 01356 KateHlConfigPage::~KateHlConfigPage () 01357 { 01358 } 01359 01360 void KateHlConfigPage::apply () 01361 { 01362 // nothing changed, no need to apply stuff 01363 if (!changed()) 01364 return; 01365 m_changed = false; 01366 01367 writeback(); 01368 01369 for ( QIntDictIterator<KateHlData> it( hlDataDict ); it.current(); ++it ) 01370 KateHlManager::self()->getHl( it.currentKey() )->setData( it.current() ); 01371 01372 KateHlManager::self()->getKConfig()->sync (); 01373 } 01374 01375 void KateHlConfigPage::reload () 01376 { 01377 } 01378 01379 void KateHlConfigPage::hlChanged(int z) 01380 { 01381 writeback(); 01382 01383 KateHighlighting *hl = KateHlManager::self()->getHl( z ); 01384 01385 if (!hl) 01386 { 01387 hlData = 0; 01388 return; 01389 } 01390 01391 if ( !hlDataDict.find( z ) ) 01392 hlDataDict.insert( z, hl->getData() ); 01393 01394 hlData = hlDataDict.find( z ); 01395 wildcards->setText(hlData->wildcards); 01396 mimetypes->setText(hlData->mimetypes); 01397 priority->setValue(hlData->priority); 01398 01399 // split author string if needed into multiple lines ! 01400 QStringList l= QStringList::split (QRegExp("[,;]"), hl->author()); 01401 author->setText (l.join ("<br>")); 01402 01403 license->setText (hl->license()); 01404 } 01405 01406 void KateHlConfigPage::writeback() 01407 { 01408 if (hlData) 01409 { 01410 hlData->wildcards = wildcards->text(); 01411 hlData->mimetypes = mimetypes->text(); 01412 hlData->priority = priority->value(); 01413 } 01414 } 01415 01416 void KateHlConfigPage::hlDownload() 01417 { 01418 KateHlDownloadDialog diag(this,"hlDownload",true); 01419 diag.exec(); 01420 } 01421 01422 void KateHlConfigPage::showMTDlg() 01423 { 01424 QString text = i18n("Select the MimeTypes you want highlighted using the '%1' syntax highlight rules.\nPlease note that this will automatically edit the associated file extensions as well.").arg( hlCombo->currentText() ); 01425 QStringList list = QStringList::split( QRegExp("\\s*;\\s*"), mimetypes->text() ); 01426 KMimeTypeChooserDialog d( i18n("Select Mime Types"), text, list, "text", this ); 01427 01428 if ( d.exec() == KDialogBase::Accepted ) { 01429 // do some checking, warn user if mime types or patterns are removed. 01430 // if the lists are empty, and the fields not, warn. 01431 wildcards->setText(d.chooser()->patterns().join(";")); 01432 mimetypes->setText(d.chooser()->mimeTypes().join(";")); 01433 } 01434 } 01435 //END KateHlConfigPage 01436 01437 //BEGIN KateHlDownloadDialog 01438 KateHlDownloadDialog::KateHlDownloadDialog(QWidget *parent, const char *name, bool modal) 01439 :KDialogBase(KDialogBase::Swallow, i18n("Highlight Download"), User1|Close, User1, parent, name, modal, true, i18n("&Install")) 01440 { 01441 QVBox* vbox = new QVBox(this); 01442 setMainWidget(vbox); 01443 vbox->setSpacing(spacingHint()); 01444 new QLabel(i18n("Select the syntax highlighting files you want to update:"), vbox); 01445 list = new QListView(vbox); 01446 list->addColumn(""); 01447 list->addColumn(i18n("Name")); 01448 list->addColumn(i18n("Installed")); 01449 list->addColumn(i18n("Latest")); 01450 list->setSelectionMode(QListView::Multi); 01451 list->setAllColumnsShowFocus(true); 01452 01453 new QLabel(i18n("<b>Note:</b> New versions are selected automatically."), vbox); 01454 actionButton (User1)->setIconSet(SmallIconSet("ok")); 01455 01456 transferJob = KIO::get( 01457 KURL(QString(HLDOWNLOADPATH) 01458 + QString("update-") 01459 + QString(KATEPART_VERSION) 01460 + QString(".xml")), true, true ); 01461 connect(transferJob, SIGNAL(data(KIO::Job *, const QByteArray &)), 01462 this, SLOT(listDataReceived(KIO::Job *, const QByteArray &))); 01463 // void data( KIO::Job *, const QByteArray &data); 01464 resize(450, 400); 01465 } 01466 01467 KateHlDownloadDialog::~KateHlDownloadDialog(){} 01468 01469 void KateHlDownloadDialog::listDataReceived(KIO::Job *, const QByteArray &data) 01470 { 01471 if (!transferJob || transferJob->isErrorPage()) 01472 { 01473 actionButton(User1)->setEnabled(false); 01474 return; 01475 } 01476 01477 listData+=QString(data); 01478 kdDebug(13000)<<QString("CurrentListData: ")<<listData<<endl<<endl; 01479 kdDebug(13000)<<QString("Data length: %1").arg(data.size())<<endl; 01480 kdDebug(13000)<<QString("listData length: %1").arg(listData.length())<<endl; 01481 if (data.size()==0) 01482 { 01483 if (listData.length()>0) 01484 { 01485 QString installedVersion; 01486 KateHlManager *hlm=KateHlManager::self(); 01487 QDomDocument doc; 01488 doc.setContent(listData); 01489 QDomElement DocElem=doc.documentElement(); 01490 QDomNode n=DocElem.firstChild(); 01491 KateHighlighting *hl = 0; 01492 01493 if (n.isNull()) kdDebug(13000)<<"There is no usable childnode"<<endl; 01494 while (!n.isNull()) 01495 { 01496 installedVersion=" --"; 01497 01498 QDomElement e=n.toElement(); 01499 if (!e.isNull()) 01500 kdDebug(13000)<<QString("NAME: ")<<e.tagName()<<QString(" - ")<<e.attribute("name")<<endl; 01501 n=n.nextSibling(); 01502 01503 QString Name=e.attribute("name"); 01504 01505 for (int i=0;i<hlm->highlights();i++) 01506 { 01507 hl=hlm->getHl(i); 01508 if (hl && hl->name()==Name) 01509 { 01510 installedVersion=" "+hl->version(); 01511 break; 01512 } 01513 else hl = 0; 01514 } 01515 01516 // autoselect entry if new or updated. 01517 QListViewItem* entry = new QListViewItem( 01518 list, "", e.attribute("name"), installedVersion, 01519 e.attribute("version"),e.attribute("url")); 01520 if (!hl || hl->version() < e.attribute("version")) 01521 { 01522 entry->setSelected(true); 01523 entry->setPixmap(0, SmallIcon(("knewstuff"))); 01524 } 01525 } 01526 } 01527 } 01528 } 01529 01530 void KateHlDownloadDialog::slotUser1() 01531 { 01532 QString destdir=KGlobal::dirs()->saveLocation("data","katepart/syntax/"); 01533 for (QListViewItem *it=list->firstChild();it;it=it->nextSibling()) 01534 { 01535 if (list->isSelected(it)) 01536 { 01537 KURL src(it->text(4)); 01538 QString filename=src.fileName(false); 01539 QString dest = destdir+filename; 01540 01541 KIO::NetAccess::download(src,dest, this); 01542 } 01543 } 01544 01545 // update Config !! 01546 KateSyntaxDocument doc (true); 01547 } 01548 //END KateHlDownloadDialog 01549 01550 //BEGIN KateGotoLineDialog 01551 KateGotoLineDialog::KateGotoLineDialog(QWidget *parent, int line, int max) 01552 : KDialogBase(parent, 0L, true, i18n("Go to Line"), Ok | Cancel, Ok) { 01553 01554 QWidget *page = new QWidget(this); 01555 setMainWidget(page); 01556 01557 QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() ); 01558 e1 = new KIntNumInput(line, page); 01559 e1->setRange(1, max); 01560 e1->setEditFocus(true); 01561 01562 QLabel *label = new QLabel( e1,i18n("&Go to line:"), page ); 01563 topLayout->addWidget(label); 01564 topLayout->addWidget(e1); 01565 topLayout->addSpacing(spacingHint()); // A little bit extra space 01566 topLayout->addStretch(10); 01567 e1->setFocus(); 01568 } 01569 01570 int KateGotoLineDialog::getLine() { 01571 return e1->value(); 01572 } 01573 //END KateGotoLineDialog 01574 01575 //BEGIN KateModOnHdPrompt 01576 KateModOnHdPrompt::KateModOnHdPrompt( KateDocument *doc, 01577 int modtype, 01578 const QString &reason, 01579 QWidget *parent ) 01580 : KDialogBase( parent, "", true, "", Ok|Apply|Cancel|User1 ), 01581 m_doc( doc ), 01582 m_modtype ( modtype ), 01583 m_tmpfile( 0 ) 01584 { 01585 QString title, btnOK, whatisok; 01586 if ( modtype == 3 ) // deleted 01587 { 01588 title = i18n("File Was Deleted on Disk"); 01589 btnOK = i18n("&Save File As..."); 01590 whatisok = i18n("Lets you select a location and save the file again."); 01591 } else { 01592 title = i18n("File Changed on Disk"); 01593 btnOK = i18n("&Reload File"); 01594 whatisok = i18n("Reload the file from disk. If you have unsaved changes, " 01595 "they will be lost."); 01596 } 01597 01598 setButtonText( Ok, btnOK); 01599 setButtonText( Apply, i18n("&Ignore") ); 01600 01601 setButtonWhatsThis( Ok, whatisok ); 01602 setButtonWhatsThis( Apply, i18n("Ignore the changes. You will not be prompted again.") ); 01603 setButtonWhatsThis( Cancel, i18n("Do nothing. Next time you focus the file, " 01604 "or try to save it or close it, you will be prompted again.") ); 01605 01606 enableButtonSeparator( true ); 01607 setCaption( title ); 01608 01609 QFrame *w = makeMainWidget(); 01610 QVBoxLayout *lo = new QVBoxLayout( w ); 01611 QHBoxLayout *lo1 = new QHBoxLayout( lo ); 01612 QLabel *icon = new QLabel( w ); 01613 icon->setPixmap( DesktopIcon("messagebox_warning" ) ); 01614 lo1->addWidget( icon ); 01615 lo1->addWidget( new QLabel( reason + "\n\n" + i18n("What do you want to do?"), w ) ); 01616 01617 // If the file isn't deleted, present a diff button, and a overwrite action. 01618 if ( modtype != 3 ) 01619 { 01620 QHBoxLayout *lo2 = new QHBoxLayout( lo ); 01621 QPushButton *btnDiff = new QPushButton( i18n("&View Difference"), w ); 01622 lo2->addStretch( 1 ); 01623 lo2->addWidget( btnDiff ); 01624 connect( btnDiff, SIGNAL(clicked()), this, SLOT(slotDiff()) ); 01625 QWhatsThis::add( btnDiff, i18n( 01626 "Calculates the difference between the editor contents and the disk " 01627 "file using diff(1) and opens the diff file with the default application " 01628 "for that.") ); 01629 01630 setButtonText( User1, i18n("Overwrite") ); 01631 setButtonWhatsThis( User1, i18n("Overwrite the disk file with the editor content.") ); 01632 } 01633 else 01634 showButton( User1, false ); 01635 } 01636 01637 KateModOnHdPrompt::~KateModOnHdPrompt() 01638 { 01639 } 01640 01641 void KateModOnHdPrompt::slotDiff() 01642 { 01643 // Start a KProcess that creates a diff 01644 KProcIO *p = new KProcIO(); 01645 p->setComm( KProcess::All ); 01646 *p << "diff" << "-u" << "-" << m_doc->url().path(); 01647 connect( p, SIGNAL(processExited(KProcess*)), this, SLOT(slotPDone(KProcess*)) ); 01648 connect( p, SIGNAL(readReady(KProcIO*)), this, SLOT(slotPRead(KProcIO*)) ); 01649 01650 setCursor( WaitCursor ); 01651 01652 p->start( KProcess::NotifyOnExit, true ); 01653 01654 uint lastln = m_doc->numLines(); 01655 for ( uint l = 0; l < lastln; l++ ) 01656 p->writeStdin( m_doc->textLine( l ) ); 01657 01658 p->closeWhenDone(); 01659 } 01660 01661 void KateModOnHdPrompt::slotPRead( KProcIO *p) 01662 { 01663 // create a file for the diff if we haven't one allready 01664 if ( ! m_tmpfile ) 01665 m_tmpfile = new KTempFile(); 01666 // put all the data we have in it 01667 QString stmp; 01668 bool dataRead = false; 01669 while ( p->readln( stmp, false ) > -1 ) 01670 { 01671 *m_tmpfile->textStream() << stmp << endl; 01672 dataRead = true; 01673 } 01674 01675 // dominik: only ackRead(), when we *really* read data, otherwise, this slot 01676 // is called initity times, which leads to a crash 01677 if( dataRead ) 01678 p->ackRead(); 01679 } 01680 01681 void KateModOnHdPrompt::slotPDone( KProcess *p ) 01682 { 01683 setCursor( ArrowCursor ); 01684 if( ! m_tmpfile ) 01685 { 01686 // dominik: there were only whitespace changes, so that the diff returned by 01687 // diff(1) has 0 bytes. So slotPRead() is never called, as there is 01688 // no data, so that m_tmpfile was never created and thus is NULL. 01689 // NOTE: would be nice, if we could produce a fake-diff, so that kompare 01690 // tells us "The files are identical". Right now, we get an ugly 01691 // "Could not parse diff output". 01692 m_tmpfile = new KTempFile(); 01693 } 01694 m_tmpfile->close(); 01695 01696 if ( ! p->normalExit() /*|| p->exitStatus()*/ ) 01697 { 01698 KMessageBox::sorry( this, 01699 i18n("The diff command failed. Please make sure that " 01700 "diff(1) is installed and in your PATH."), 01701 i18n("Error Creating Diff") ); 01702 delete m_tmpfile; 01703 m_tmpfile = 0; 01704 return; 01705 } 01706 01707 KRun::runURL( m_tmpfile->name(), "text/x-diff", true ); 01708 delete m_tmpfile; 01709 m_tmpfile = 0; 01710 } 01711 01712 void KateModOnHdPrompt::slotApply() 01713 { 01714 if ( KMessageBox::warningContinueCancel( 01715 this, 01716 i18n("Ignoring means that you will not be warned again (unless " 01717 "the disk file changes once more): if you save the document, you " 01718 "will overwrite the file on disk; if you do not save then the disk file " 01719 "(if present) is what you have."), 01720 i18n("You Are on Your Own"), 01721 KStdGuiItem::cont(), 01722 "kate_ignore_modonhd" ) != KMessageBox::Continue ) 01723 return; 01724 01725 done(Ignore); 01726 } 01727 01728 void KateModOnHdPrompt::slotOk() 01729 { 01730 done( m_modtype == 3 ? Save : Reload ); 01731 } 01732 01733 void KateModOnHdPrompt::slotUser1() 01734 { 01735 done( Overwrite ); 01736 } 01737 01738 //END KateModOnHdPrompt 01739 01740 // kate: space-indent on; indent-width 2; replace-tabs on;