00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 QDialog* m_regexpDialog;
00045 bool m_regexpDialogQueryDone;
00046 bool m_hasCursor;
00047 bool m_hasSelection;
00048 QStringList findStrings;
00049 QString pattern;
00050 };
00051
00052 KFindDialog::KFindDialog(QWidget *parent, const char *name, long options, const QStringList &findStrings, bool hasSelection) :
00053 KDialogBase(parent, name, true, i18n("Find Text"), Ok | Cancel, Ok),
00054 m_findExtension (0),
00055 m_replaceExtension (0)
00056 {
00057 d = new KFindDialogPrivate;
00058 init(false, findStrings, hasSelection);
00059 setOptions(options);
00060 }
00061
00062 KFindDialog::KFindDialog(QWidget *parent, const char *name, bool ) :
00063 KDialogBase(parent, name, true, i18n("Replace Text"), Ok | Cancel, Ok),
00064 m_findExtension (0),
00065 m_replaceExtension (0)
00066 {
00067 d = new KFindDialogPrivate;
00068 }
00069
00070 KFindDialog::~KFindDialog()
00071 {
00072 delete d;
00073 }
00074
00075 QWidget *KFindDialog::findExtension()
00076 {
00077 if (!m_findExtension)
00078 {
00079 m_findExtension = new QWidget(m_findGrp);
00080 m_findLayout->addMultiCellWidget(m_findExtension, 3, 3, 0, 1);
00081 }
00082
00083 return m_findExtension;
00084 }
00085
00086 QStringList KFindDialog::findHistory() const
00087 {
00088 return m_find->historyItems();
00089 }
00090
00091 void KFindDialog::init(bool forReplace, const QStringList &findStrings, bool hasSelection)
00092 {
00093 QVBoxLayout *topLayout;
00094 QGridLayout *optionsLayout;
00095
00096
00097 QWidget *page = new QWidget(this);
00098 setMainWidget(page);
00099
00100 topLayout = new QVBoxLayout(page);
00101 topLayout->setSpacing( KDialog::spacingHint() );
00102 topLayout->setMargin( KDialog::marginHint() );
00103
00104 m_findGrp = new QGroupBox(0, Qt::Vertical, i18n("Find"), page);
00105 m_findGrp->layout()->setSpacing( KDialog::spacingHint() );
00106
00107 m_findLayout = new QGridLayout(m_findGrp->layout());
00108 m_findLayout->setSpacing( KDialog::spacingHint() );
00109
00110
00111 m_findLabel = new QLabel(i18n("&Text to find:"), m_findGrp);
00112 m_find = new KHistoryCombo(true, m_findGrp);
00113 m_find->setMaxCount(10);
00114 m_find->setDuplicatesEnabled(false);
00115 m_regExp = new QCheckBox(i18n("&Regular expression"), m_findGrp);
00116 m_regExpItem = new QPushButton(i18n("&Edit..."), m_findGrp);
00117 m_regExpItem->setEnabled(false);
00118
00119 m_findLayout->addWidget(m_findLabel, 0, 0);
00120 m_findLayout->addMultiCellWidget(m_find, 1, 1, 0, 1);
00121 m_findLayout->addWidget(m_regExp, 2, 0);
00122 m_findLayout->addWidget(m_regExpItem, 2, 1);
00123 topLayout->addWidget(m_findGrp);
00124
00125 m_replaceGrp = new QGroupBox(0, Qt::Vertical, i18n("Replace With"), page);
00126 m_replaceGrp->layout()->setSpacing( KDialog::spacingHint() );
00127
00128 m_replaceLayout = new QGridLayout(m_replaceGrp->layout());
00129 m_replaceLayout->setSpacing( KDialog::spacingHint() );
00130
00131
00132 m_replaceLabel = new QLabel(i18n("&Replacement text:"), m_replaceGrp);
00133 m_replace = new KHistoryCombo(true, m_replaceGrp);
00134 m_replace->setMaxCount(10);
00135 m_replace->setDuplicatesEnabled(false);
00136 m_backRef = new QCheckBox(i18n("Us&e placeholders"), m_replaceGrp);
00137 m_backRefItem = new QPushButton(i18n("Insert Place&holder"), m_replaceGrp);
00138 m_backRefItem->setEnabled(false);
00139
00140 m_replaceLayout->addWidget(m_replaceLabel, 0, 0);
00141 m_replaceLayout->addMultiCellWidget(m_replace, 1, 1, 0, 1);
00142 m_replaceLayout->addWidget(m_backRef, 2, 0);
00143 m_replaceLayout->addWidget(m_backRefItem, 2, 1);
00144 topLayout->addWidget(m_replaceGrp);
00145
00146 m_optionGrp = new QGroupBox(0, Qt::Vertical, i18n("Options"), page);
00147 m_optionGrp->layout()->setSpacing(KDialog::spacingHint());
00148
00149 optionsLayout = new QGridLayout(m_optionGrp->layout());
00150 optionsLayout->setSpacing( KDialog::spacingHint() );
00151
00152
00153 m_caseSensitive = new QCheckBox(i18n("C&ase sensitive"), m_optionGrp);
00154 m_wholeWordsOnly = new QCheckBox(i18n("&Whole words only"), m_optionGrp);
00155 m_fromCursor = new QCheckBox(i18n("&From cursor"), m_optionGrp);
00156 m_findBackwards = new QCheckBox(i18n("Find &backwards"), m_optionGrp);
00157 m_selectedText = new QCheckBox(i18n("&Selected text"), m_optionGrp);
00158 setHasSelection( hasSelection );
00159 m_promptOnReplace = new QCheckBox(i18n("&Prompt on replace"), m_optionGrp);
00160 m_promptOnReplace->setChecked( true );
00161
00162 optionsLayout->addWidget(m_caseSensitive, 0, 0);
00163 optionsLayout->addWidget(m_wholeWordsOnly, 1, 0);
00164 optionsLayout->addWidget(m_fromCursor, 2, 0);
00165 optionsLayout->addWidget(m_findBackwards, 0, 1);
00166 optionsLayout->addWidget(m_selectedText, 1, 1);
00167 optionsLayout->addWidget(m_promptOnReplace, 2, 1);
00168 topLayout->addWidget(m_optionGrp);
00169
00170
00171 m_patterns = 0L;
00172 m_placeholders = 0L;
00173
00174
00175 connect(m_selectedText, SIGNAL(toggled(bool)), this, SLOT(slotSelectedTextToggled(bool)));
00176 connect(m_regExp, SIGNAL(toggled(bool)), m_regExpItem, SLOT(setEnabled(bool)));
00177 connect(m_backRef, SIGNAL(toggled(bool)), m_backRefItem, SLOT(setEnabled(bool)));
00178 connect(m_regExpItem, SIGNAL(pressed()), this, SLOT(showPatterns()));
00179 connect(m_backRefItem, SIGNAL(pressed()), this, SLOT(showPlaceholders()));
00180
00181 connect(m_find, SIGNAL(textChanged ( const QString & )),this, SLOT(textSearchChanged( const QString & )));
00182
00183
00184 setTabOrder(m_find, m_regExp);
00185 setTabOrder(m_regExp, m_regExpItem);
00186 setTabOrder(m_regExpItem, m_replace);
00187 setTabOrder(m_replace, m_backRef);
00188 setTabOrder(m_backRef, m_backRefItem);
00189 setTabOrder(m_backRefItem, m_caseSensitive);
00190 setTabOrder(m_caseSensitive, m_wholeWordsOnly);
00191 setTabOrder(m_wholeWordsOnly, m_fromCursor);
00192 setTabOrder(m_fromCursor, m_findBackwards);
00193 setTabOrder(m_findBackwards, m_selectedText);
00194 setTabOrder(m_selectedText, m_promptOnReplace);
00195
00196
00197 m_findLabel->setBuddy(m_find);
00198 m_replaceLabel->setBuddy(m_replace);
00199
00200 if (!forReplace)
00201 {
00202 m_promptOnReplace->hide();
00203 m_replaceGrp->hide();
00204 }
00205
00206 d->findStrings = findStrings;
00207 m_find->setFocus();
00208 enableButtonOK( !pattern().isEmpty() );
00209 }
00210
00211 void KFindDialog::textSearchChanged( const QString & text)
00212 {
00213 enableButtonOK( !text.isEmpty() );
00214 }
00215
00216 void KFindDialog::showEvent( QShowEvent *e )
00217 {
00218 kdDebug() << "showEvent\n";
00219 if (!d->findStrings.isEmpty())
00220 setFindHistory(d->findStrings);
00221 d->findStrings = QStringList();
00222 if (!d->pattern.isEmpty()) {
00223 m_find->lineEdit()->setText( d->pattern );
00224 m_find->lineEdit()->selectAll();
00225 d->pattern = QString::null;
00226 }
00227 KDialogBase::showEvent(e);
00228 }
00229
00230 long KFindDialog::options() const
00231 {
00232 long options = 0;
00233
00234 if (m_caseSensitive->isChecked())
00235 options |= CaseSensitive;
00236 if (m_wholeWordsOnly->isChecked())
00237 options |= WholeWordsOnly;
00238 if (m_fromCursor->isChecked())
00239 options |= FromCursor;
00240 if (m_findBackwards->isChecked())
00241 options |= FindBackwards;
00242 if (m_selectedText->isChecked())
00243 options |= SelectedText;
00244 if (m_regExp->isChecked())
00245 options |= RegularExpression;
00246 return options;
00247 }
00248
00249 QString KFindDialog::pattern() const
00250 {
00251 return m_find->currentText();
00252 }
00253
00254 void KFindDialog::setPattern (const QString &pattern)
00255 {
00256 m_find->lineEdit()->setText( pattern );
00257 m_find->lineEdit()->selectAll();
00258 d->pattern = pattern;
00259 kdDebug() << "setPattern " << pattern<<endl;
00260 }
00261
00262 void KFindDialog::setFindHistory(const QStringList &strings)
00263 {
00264 if (strings.count() > 0)
00265 {
00266 m_find->setHistoryItems(strings, true);
00267 m_find->lineEdit()->setText( strings.first() );
00268 m_find->lineEdit()->selectAll();
00269 }
00270 else
00271 m_find->clearHistory();
00272 }
00273
00274 void KFindDialog::setHasSelection(bool hasSelection)
00275 {
00276 d->m_hasSelection = hasSelection;
00277 m_selectedText->setEnabled( hasSelection );
00278
00279
00280 m_selectedText->setChecked( hasSelection );
00281 slotSelectedTextToggled( hasSelection );
00282 }
00283
00284 void KFindDialog::slotSelectedTextToggled(bool selec)
00285 {
00286
00287 m_fromCursor->setEnabled( !selec && d->m_hasCursor );
00288 if ( selec )
00289 m_fromCursor->setChecked( false );
00290 }
00291
00292 void KFindDialog::setHasCursor(bool hasCursor)
00293 {
00294 d->m_hasCursor = hasCursor;
00295 m_fromCursor->setEnabled( hasCursor );
00296 m_fromCursor->setChecked( hasCursor && (options() & FromCursor) );
00297 }
00298
00299 void KFindDialog::setOptions(long options)
00300 {
00301 m_caseSensitive->setChecked(options & CaseSensitive);
00302 m_wholeWordsOnly->setChecked(options & WholeWordsOnly);
00303 m_fromCursor->setChecked(d->m_hasCursor && (options & FromCursor));
00304 m_findBackwards->setChecked(options & FindBackwards);
00305 m_selectedText->setChecked(d->m_hasSelection && (options & SelectedText));
00306 m_regExp->setChecked(options & RegularExpression);
00307 }
00308
00309
00310
00311 void KFindDialog::showPatterns()
00312 {
00313 if ( !d->m_regexpDialogQueryDone )
00314 {
00315 d->m_regexpDialog = KParts::ComponentFactory::createInstanceFromQuery<QDialog>( "KRegExpEditor/KRegExpEditor", QString::null, this );
00316 d->m_regexpDialogQueryDone = true;
00317 }
00318
00319 if ( d->m_regexpDialog )
00320 {
00321 KRegExpEditorInterface *iface = static_cast<KRegExpEditorInterface *>( d->m_regexpDialog->qt_cast( "KRegExpEditorInterface" ) );
00322 assert( iface );
00323
00324 iface->setRegExp( pattern() );
00325 if ( d->m_regexpDialog->exec() == QDialog::Accepted )
00326 setPattern( iface->regExp() );
00327 }
00328 else
00329 {
00330 typedef struct
00331 {
00332 const char *description;
00333 const char *regExp;
00334 int cursorAdjustment;
00335 } term;
00336 static const term items[] =
00337 {
00338 { I18N_NOOP("Any Character"), ".", 0 },
00339 { I18N_NOOP("Start of Line"), "^", 0 },
00340 { I18N_NOOP("End of Line"), "$", 0 },
00341 { I18N_NOOP("Set of Characters"), "[]", -1 },
00342 { I18N_NOOP("Repeats, Zero or More Times"), "*", 0 },
00343 { I18N_NOOP("Repeats, One or More Times"), "+", 0 },
00344 { I18N_NOOP("Optional"), "?", 0 },
00345 { I18N_NOOP("Escape"), "\\", 0 },
00346 { I18N_NOOP("TAB"), "\\t", 0 },
00347 { I18N_NOOP("Newline"), "\\n", 0 },
00348 { I18N_NOOP("Carriage Return"), "\\r", 0 },
00349 { I18N_NOOP("White Space"), "\\s", 0 },
00350 { I18N_NOOP("Digit"), "\\d", 0 },
00351 };
00352 int i;
00353
00354
00355 if (!m_patterns)
00356 {
00357 m_patterns = new QPopupMenu(this);
00358 for (i = 0; (unsigned)i < sizeof(items) / sizeof(items[0]); i++)
00359 {
00360 m_patterns->insertItem(i18n(items[i].description), i, i);
00361 }
00362 }
00363
00364
00365 i = m_patterns->exec(QCursor::pos());
00366 if (i != -1)
00367 {
00368 QLineEdit *editor = m_find->lineEdit();
00369
00370 editor->insert(items[i].regExp);
00371 editor->setCursorPosition(editor->cursorPosition() + items[i].cursorAdjustment);
00372 }
00373 }
00374 }
00375
00376
00377
00378 void KFindDialog::showPlaceholders()
00379 {
00380 typedef struct
00381 {
00382 const char *description;
00383 const char *backRef;
00384 } term;
00385 static const term items[] =
00386 {
00387 { I18N_NOOP("Complete text found"), "\\0" },
00388 };
00389 int i;
00390
00391
00392 if (!m_placeholders)
00393 {
00394 m_placeholders = new QPopupMenu(this);
00395 for (i = 0; (unsigned)i < sizeof(items) / sizeof(items[0]); i++)
00396 {
00397 m_placeholders->insertItem(i18n(items[i].description), i, i);
00398 }
00399 }
00400
00401
00402 i = m_placeholders->exec(QCursor::pos());
00403 if (i != -1)
00404 {
00405 QLineEdit *editor = m_replace->lineEdit();
00406
00407 editor->insert(items[i].backRef);
00408 }
00409 }
00410
00411 void KFindDialog::slotOk()
00412 {
00413
00414 if (pattern().isEmpty())
00415 {
00416 KMessageBox::error(this, i18n("You must enter some text to search for."));
00417 return;
00418 }
00419
00420 if (m_regExp->isChecked())
00421 {
00422
00423 QRegExp regExp(pattern());
00424
00425 if (!regExp.isValid())
00426 {
00427 KMessageBox::error(this, i18n("Invalid regular expression."));
00428 return;
00429 }
00430 }
00431 m_find->addToHistory(pattern());
00432 emit okClicked();
00433 accept();
00434 }
00435
00436 #include "kfinddialog.moc"