kutils Library API Documentation

kfinddialog.cpp

00001 /* 00002 Copyright (C) 2001, S.R.Haque <srhaque@iee.org>. 00003 Copyright (C) 2002, David Faure <david@mandrakesoft.com> 00004 This file is part of the KDE project 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License version 2, as published by the Free Software Foundation. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #include "kfinddialog.h" 00022 #include <qcheckbox.h> 00023 #include <qcursor.h> 00024 #include <qgroupbox.h> 00025 #include <qlabel.h> 00026 #include <qlayout.h> 00027 #include <qpopupmenu.h> 00028 #include <qpushbutton.h> 00029 #include <qregexp.h> 00030 #include <kcombobox.h> 00031 #include <kdebug.h> 00032 #include <klocale.h> 00033 #include <kmessagebox.h> 00034 #include <assert.h> 00035 00036 #include <kregexpeditorinterface.h> 00037 #include <kparts/componentfactory.h> 00038 00039 class KFindDialog::KFindDialogPrivate 00040 { 00041 public: 00042 KFindDialogPrivate() : m_regexpDialog(0), 00043 m_regexpDialogQueryDone(false), m_hasCursor(true), m_hasSelection(false), 00044 m_initialShowDone(false) {} 00045 QDialog* m_regexpDialog; 00046 bool m_regexpDialogQueryDone; 00047 bool m_hasCursor; 00048 bool m_hasSelection; 00049 bool m_initialShowDone; 00050 QStringList findStrings; 00051 QString pattern; 00052 }; 00053 00054 KFindDialog::KFindDialog(QWidget *parent, const char *name, long options, const QStringList &findStrings, bool hasSelection) : 00055 KDialogBase(parent, name, true, i18n("Find Text"), Ok | Cancel, Ok), 00056 m_findExtension (0), 00057 m_replaceExtension (0) 00058 { 00059 d = new KFindDialogPrivate; 00060 init(false, findStrings, hasSelection); 00061 setOptions(options); 00062 setButtonCancel( KStdGuiItem::close() ); 00063 } 00064 00065 KFindDialog::KFindDialog(bool modal, QWidget *parent, const char *name, long options, const QStringList &findStrings, bool hasSelection) : 00066 KDialogBase(parent, name, modal, i18n("Find Text"), Ok | Cancel, Ok), 00067 m_findExtension (0), 00068 m_replaceExtension (0) 00069 { 00070 d = new KFindDialogPrivate; 00071 init(false, findStrings, hasSelection); 00072 setOptions(options); 00073 setButtonCancel( KStdGuiItem::close() ); 00074 } 00075 00076 KFindDialog::KFindDialog(QWidget *parent, const char *name, bool /*forReplace*/) : 00077 KDialogBase(parent, name, true, i18n("Replace Text"), Ok | Cancel, Ok), 00078 m_findExtension (0), 00079 m_replaceExtension (0) 00080 { 00081 d = new KFindDialogPrivate; 00082 setButtonCancel( KStdGuiItem::close() ); 00083 } 00084 00085 KFindDialog::~KFindDialog() 00086 { 00087 delete d; 00088 } 00089 00090 QWidget *KFindDialog::findExtension() 00091 { 00092 if (!m_findExtension) 00093 { 00094 m_findExtension = new QWidget(m_findGrp); 00095 m_findLayout->addMultiCellWidget(m_findExtension, 3, 3, 0, 1); 00096 } 00097 00098 return m_findExtension; 00099 } 00100 00101 QStringList KFindDialog::findHistory() const 00102 { 00103 return m_find->historyItems(); 00104 } 00105 00106 void KFindDialog::init(bool forReplace, const QStringList &findStrings, bool hasSelection) 00107 { 00108 QVBoxLayout *topLayout; 00109 QGridLayout *optionsLayout; 00110 00111 // Create common parts of dialog. 00112 QWidget *page = new QWidget(this); 00113 setMainWidget(page); 00114 00115 topLayout = new QVBoxLayout(page); 00116 topLayout->setSpacing( KDialog::spacingHint() ); 00117 topLayout->setMargin( 0 ); 00118 00119 m_findGrp = new QGroupBox(0, Qt::Vertical, i18n("Find"), page); 00120 m_findGrp->layout()->setSpacing( KDialog::spacingHint() ); 00121 // m_findGrp->layout()->setMargin( KDialog::marginHint() ); 00122 m_findLayout = new QGridLayout(m_findGrp->layout()); 00123 m_findLayout->setSpacing( KDialog::spacingHint() ); 00124 // m_findLayout->setMargin( KDialog::marginHint() ); 00125 00126 m_findLabel = new QLabel(i18n("&Text to find:"), m_findGrp); 00127 m_find = new KHistoryCombo(true, m_findGrp); 00128 m_find->setMaxCount(10); 00129 m_find->setDuplicatesEnabled(false); 00130 m_regExp = new QCheckBox(i18n("Regular e&xpression"), m_findGrp); 00131 m_regExpItem = new QPushButton(i18n("&Edit..."), m_findGrp); 00132 m_regExpItem->setEnabled(false); 00133 00134 m_findLayout->addWidget(m_findLabel, 0, 0); 00135 m_findLayout->addMultiCellWidget(m_find, 1, 1, 0, 1); 00136 m_findLayout->addWidget(m_regExp, 2, 0); 00137 m_findLayout->addWidget(m_regExpItem, 2, 1); 00138 topLayout->addWidget(m_findGrp); 00139 00140 m_replaceGrp = new QGroupBox(0, Qt::Vertical, i18n("Replace With"), page); 00141 m_replaceGrp->layout()->setSpacing( KDialog::spacingHint() ); 00142 // m_replaceGrp->layout()->setMargin( KDialog::marginHint() ); 00143 m_replaceLayout = new QGridLayout(m_replaceGrp->layout()); 00144 m_replaceLayout->setSpacing( KDialog::spacingHint() ); 00145 // m_replaceLayout->setMargin( KDialog::marginHint() ); 00146 00147 m_replaceLabel = new QLabel(i18n("Replace&ment text:"), m_replaceGrp); 00148 m_replace = new KHistoryCombo(true, m_replaceGrp); 00149 m_replace->setMaxCount(10); 00150 m_replace->setDuplicatesEnabled(false); 00151 m_backRef = new QCheckBox(i18n("Use p&laceholders"), m_replaceGrp); 00152 m_backRefItem = new QPushButton(i18n("Insert Place&holder"), m_replaceGrp); 00153 m_backRefItem->setEnabled(false); 00154 00155 m_replaceLayout->addWidget(m_replaceLabel, 0, 0); 00156 m_replaceLayout->addMultiCellWidget(m_replace, 1, 1, 0, 1); 00157 m_replaceLayout->addWidget(m_backRef, 2, 0); 00158 m_replaceLayout->addWidget(m_backRefItem, 2, 1); 00159 topLayout->addWidget(m_replaceGrp); 00160 00161 m_optionGrp = new QGroupBox(0, Qt::Vertical, i18n("Options"), page); 00162 m_optionGrp->layout()->setSpacing(KDialog::spacingHint()); 00163 // m_optionGrp->layout()->setMargin(KDialog::marginHint()); 00164 optionsLayout = new QGridLayout(m_optionGrp->layout()); 00165 optionsLayout->setSpacing( KDialog::spacingHint() ); 00166 // optionsLayout->setMargin( KDialog::marginHint() ); 00167 00168 m_caseSensitive = new QCheckBox(i18n("C&ase sensitive"), m_optionGrp); 00169 m_wholeWordsOnly = new QCheckBox(i18n("&Whole words only"), m_optionGrp); 00170 m_fromCursor = new QCheckBox(i18n("From c&ursor"), m_optionGrp); 00171 m_findBackwards = new QCheckBox(i18n("Find &backwards"), m_optionGrp); 00172 m_selectedText = new QCheckBox(i18n("&Selected text"), m_optionGrp); 00173 setHasSelection( hasSelection ); 00174 // If we have a selection, we make 'find in selection' default 00175 // and if we don't, then the option has to be unchecked, obviously. 00176 m_selectedText->setChecked( hasSelection ); 00177 slotSelectedTextToggled( hasSelection ); 00178 00179 m_promptOnReplace = new QCheckBox(i18n("&Prompt on replace"), m_optionGrp); 00180 m_promptOnReplace->setChecked( true ); 00181 00182 optionsLayout->addWidget(m_caseSensitive, 0, 0); 00183 optionsLayout->addWidget(m_wholeWordsOnly, 1, 0); 00184 optionsLayout->addWidget(m_fromCursor, 2, 0); 00185 optionsLayout->addWidget(m_findBackwards, 0, 1); 00186 optionsLayout->addWidget(m_selectedText, 1, 1); 00187 optionsLayout->addWidget(m_promptOnReplace, 2, 1); 00188 topLayout->addWidget(m_optionGrp); 00189 00190 // We delay creation of these until needed. 00191 m_patterns = 0L; 00192 m_placeholders = 0L; 00193 00194 // signals and slots connections 00195 connect(m_selectedText, SIGNAL(toggled(bool)), this, SLOT(slotSelectedTextToggled(bool))); 00196 connect(m_regExp, SIGNAL(toggled(bool)), m_regExpItem, SLOT(setEnabled(bool))); 00197 connect(m_backRef, SIGNAL(toggled(bool)), m_backRefItem, SLOT(setEnabled(bool))); 00198 connect(m_regExpItem, SIGNAL(clicked()), this, SLOT(showPatterns())); 00199 connect(m_backRefItem, SIGNAL(clicked()), this, SLOT(showPlaceholders())); 00200 00201 connect(m_find, SIGNAL(textChanged ( const QString & )),this, SLOT(textSearchChanged( const QString & ))); 00202 00203 // tab order 00204 setTabOrder(m_find, m_regExp); 00205 setTabOrder(m_regExp, m_regExpItem); 00206 setTabOrder(m_regExpItem, m_replace); 00207 setTabOrder(m_replace, m_backRef); 00208 setTabOrder(m_backRef, m_backRefItem); 00209 setTabOrder(m_backRefItem, m_caseSensitive); 00210 setTabOrder(m_caseSensitive, m_wholeWordsOnly); 00211 setTabOrder(m_wholeWordsOnly, m_fromCursor); 00212 setTabOrder(m_fromCursor, m_findBackwards); 00213 setTabOrder(m_findBackwards, m_selectedText); 00214 setTabOrder(m_selectedText, m_promptOnReplace); 00215 00216 // buddies 00217 m_findLabel->setBuddy(m_find); 00218 m_replaceLabel->setBuddy(m_replace); 00219 00220 if (!forReplace) 00221 { 00222 m_promptOnReplace->hide(); 00223 m_replaceGrp->hide(); 00224 } 00225 00226 d->findStrings = findStrings; 00227 m_find->setFocus(); 00228 enableButtonOK( !pattern().isEmpty() ); 00229 if (forReplace) 00230 { 00231 setButtonOKText(i18n("&Replace"), 00232 i18n("Start replace"), 00233 i18n("<qt>If you press the <b>Replace</b> button, the text you entered " 00234 "above is searched for within the document and any occurrence is " 00235 "replaced with the replacement text.</qt>")); 00236 } 00237 else 00238 { 00239 setButtonOK( KGuiItem(i18n("&Find"),"find", 00240 i18n("Start searching"), 00241 i18n("<qt>If you press the <b>Find</b> button, the text you entered " 00242 "above is searched for within the document.</qt>")) ); 00243 } 00244 } 00245 00246 void KFindDialog::textSearchChanged( const QString & text) 00247 { 00248 enableButtonOK( !text.isEmpty() ); 00249 } 00250 00251 void KFindDialog::showEvent( QShowEvent *e ) 00252 { 00253 if ( !d->m_initialShowDone ) 00254 { 00255 d->m_initialShowDone = true; // only once 00256 kdDebug() << "showEvent\n"; 00257 if (!d->findStrings.isEmpty()) 00258 setFindHistory(d->findStrings); 00259 d->findStrings = QStringList(); 00260 if (!d->pattern.isEmpty()) { 00261 m_find->lineEdit()->setText( d->pattern ); 00262 m_find->lineEdit()->selectAll(); 00263 d->pattern = QString::null; 00264 } 00265 } 00266 KDialogBase::showEvent(e); 00267 } 00268 00269 long KFindDialog::options() const 00270 { 00271 long options = 0; 00272 00273 if (m_caseSensitive->isChecked()) 00274 options |= CaseSensitive; 00275 if (m_wholeWordsOnly->isChecked()) 00276 options |= WholeWordsOnly; 00277 if (m_fromCursor->isChecked()) 00278 options |= FromCursor; 00279 if (m_findBackwards->isChecked()) 00280 options |= FindBackwards; 00281 if (m_selectedText->isChecked()) 00282 options |= SelectedText; 00283 if (m_regExp->isChecked()) 00284 options |= RegularExpression; 00285 return options; 00286 } 00287 00288 QString KFindDialog::pattern() const 00289 { 00290 return m_find->currentText(); 00291 } 00292 00293 void KFindDialog::setPattern (const QString &pattern) 00294 { 00295 m_find->lineEdit()->setText( pattern ); 00296 m_find->lineEdit()->selectAll(); 00297 d->pattern = pattern; 00298 kdDebug() << "setPattern " << pattern<<endl; 00299 } 00300 00301 void KFindDialog::setFindHistory(const QStringList &strings) 00302 { 00303 if (strings.count() > 0) 00304 { 00305 m_find->setHistoryItems(strings, true); 00306 m_find->lineEdit()->setText( strings.first() ); 00307 m_find->lineEdit()->selectAll(); 00308 } 00309 else 00310 m_find->clearHistory(); 00311 } 00312 00313 void KFindDialog::setHasSelection(bool hasSelection) 00314 { 00315 d->m_hasSelection = hasSelection; 00316 m_selectedText->setEnabled( hasSelection ); 00317 if ( !hasSelection ) 00318 { 00319 m_selectedText->setChecked( false ); 00320 slotSelectedTextToggled( hasSelection ); 00321 } 00322 } 00323 00324 void KFindDialog::slotSelectedTextToggled(bool selec) 00325 { 00326 // From cursor doesn't make sense if we have a selection 00327 m_fromCursor->setEnabled( !selec && d->m_hasCursor ); 00328 if ( selec ) // uncheck if disabled 00329 m_fromCursor->setChecked( false ); 00330 } 00331 00332 void KFindDialog::setHasCursor(bool hasCursor) 00333 { 00334 d->m_hasCursor = hasCursor; 00335 m_fromCursor->setEnabled( hasCursor ); 00336 m_fromCursor->setChecked( hasCursor && (options() & FromCursor) ); 00337 } 00338 00339 void KFindDialog::setOptions(long options) 00340 { 00341 m_caseSensitive->setChecked(options & CaseSensitive); 00342 m_wholeWordsOnly->setChecked(options & WholeWordsOnly); 00343 m_fromCursor->setChecked(d->m_hasCursor && (options & FromCursor)); 00344 m_findBackwards->setChecked(options & FindBackwards); 00345 m_selectedText->setChecked(d->m_hasSelection && (options & SelectedText)); 00346 m_regExp->setChecked(options & RegularExpression); 00347 } 00348 00349 // Create a popup menu with a list of regular expression terms, to help the user 00350 // compose a regular expression search pattern. 00351 void KFindDialog::showPatterns() 00352 { 00353 if ( !d->m_regexpDialogQueryDone ) 00354 { 00355 d->m_regexpDialog = KParts::ComponentFactory::createInstanceFromQuery<QDialog>( "KRegExpEditor/KRegExpEditor", QString::null, this ); 00356 d->m_regexpDialogQueryDone = true; 00357 } 00358 00359 if ( d->m_regexpDialog ) 00360 { 00361 KRegExpEditorInterface *iface = static_cast<KRegExpEditorInterface *>( d->m_regexpDialog->qt_cast( "KRegExpEditorInterface" ) ); 00362 assert( iface ); 00363 00364 iface->setRegExp( pattern() ); 00365 if ( d->m_regexpDialog->exec() == QDialog::Accepted ) 00366 setPattern( iface->regExp() ); 00367 } 00368 else // No complete regexp-editor available, bring up the old popupmenu 00369 { 00370 typedef struct 00371 { 00372 const char *description; 00373 const char *regExp; 00374 int cursorAdjustment; 00375 } term; 00376 static const term items[] = 00377 { 00378 { I18N_NOOP("Any Character"), ".", 0 }, 00379 { I18N_NOOP("Start of Line"), "^", 0 }, 00380 { I18N_NOOP("End of Line"), "$", 0 }, 00381 { I18N_NOOP("Set of Characters"), "[]", -1 }, 00382 { I18N_NOOP("Repeats, Zero or More Times"), "*", 0 }, 00383 { I18N_NOOP("Repeats, One or More Times"), "+", 0 }, 00384 { I18N_NOOP("Optional"), "?", 0 }, 00385 { I18N_NOOP("Escape"), "\\", 0 }, 00386 { I18N_NOOP("TAB"), "\\t", 0 }, 00387 { I18N_NOOP("Newline"), "\\n", 0 }, 00388 { I18N_NOOP("Carriage Return"), "\\r", 0 }, 00389 { I18N_NOOP("White Space"), "\\s", 0 }, 00390 { I18N_NOOP("Digit"), "\\d", 0 }, 00391 }; 00392 int i; 00393 00394 // Populate the popup menu. 00395 if (!m_patterns) 00396 { 00397 m_patterns = new QPopupMenu(this); 00398 for (i = 0; (unsigned)i < sizeof(items) / sizeof(items[0]); i++) 00399 { 00400 m_patterns->insertItem(i18n(items[i].description), i, i); 00401 } 00402 } 00403 00404 // Insert the selection into the edit control. 00405 i = m_patterns->exec(m_regExpItem->mapToGlobal(m_regExpItem->rect().bottomLeft())); 00406 if (i != -1) 00407 { 00408 QLineEdit *editor = m_find->lineEdit(); 00409 00410 editor->insert(items[i].regExp); 00411 editor->setCursorPosition(editor->cursorPosition() + items[i].cursorAdjustment); 00412 } 00413 } 00414 } 00415 00416 // Create a popup menu with a list of backreference terms, to help the user 00417 // compose a regular expression replacement pattern. 00418 void KFindDialog::showPlaceholders() 00419 { 00420 typedef struct 00421 { 00422 const char *description; 00423 const char *backRef; 00424 } term; 00425 static const term items[] = 00426 { 00427 { I18N_NOOP("Complete text found"), "\\0" }, 00428 }; 00429 int i; 00430 00431 // Populate the popup menu. 00432 if (!m_placeholders) 00433 { 00434 m_placeholders = new QPopupMenu(this); 00435 for (i = 0; (unsigned)i < sizeof(items) / sizeof(items[0]); i++) 00436 { 00437 m_placeholders->insertItem(i18n(items[i].description), i, i); 00438 } 00439 } 00440 00441 // Insert the selection into the edit control. 00442 i = m_placeholders->exec(m_backRefItem->mapToGlobal(m_backRefItem->rect().bottomLeft())); 00443 if (i != -1) 00444 { 00445 QLineEdit *editor = m_replace->lineEdit(); 00446 00447 editor->insert(items[i].backRef); 00448 } 00449 } 00450 00451 void KFindDialog::slotOk() 00452 { 00453 // Nothing to find? 00454 if (pattern().isEmpty()) 00455 { 00456 KMessageBox::error(this, i18n("You must enter some text to search for.")); 00457 return; 00458 } 00459 00460 if (m_regExp->isChecked()) 00461 { 00462 // Check for a valid regular expression. 00463 QRegExp regExp(pattern()); 00464 00465 if (!regExp.isValid()) 00466 { 00467 KMessageBox::error(this, i18n("Invalid regular expression.")); 00468 return; 00469 } 00470 } 00471 m_find->addToHistory(pattern()); 00472 emit okClicked(); 00473 if ( testWFlags( WShowModal ) ) 00474 accept(); 00475 } 00476 00477 #include "kfinddialog.moc"
KDE Logo
This file is part of the documentation for kutils Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 8 11:15:23 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003