File indexing completed on 2024-12-08 03:43:01

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2001 S.R. Haque <srhaque@iee.org>.
0004     SPDX-FileCopyrightText: 2002 David Faure <david@mandrakesoft.com>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #include "kfinddialog.h"
0010 #include "kfinddialog_p.h"
0011 
0012 #include "kfind.h"
0013 
0014 #include <QCheckBox>
0015 #include <QDialogButtonBox>
0016 #include <QGridLayout>
0017 #include <QGroupBox>
0018 #include <QLabel>
0019 #include <QLineEdit>
0020 #include <QMenu>
0021 #include <QPushButton>
0022 #include <QRegularExpression>
0023 
0024 #include <KGuiItem>
0025 #include <KHistoryComboBox>
0026 #include <KLazyLocalizedString>
0027 #include <KLocalizedString>
0028 #include <KMessageBox>
0029 
0030 #include <assert.h>
0031 
0032 KFindDialog::KFindDialog(QWidget *parent, long options, const QStringList &findStrings, bool hasSelection, bool replaceDialog)
0033     : KFindDialog(*new KFindDialogPrivate(this), parent, options, findStrings, hasSelection, replaceDialog)
0034 {
0035     setWindowTitle(i18n("Find Text"));
0036 }
0037 
0038 KFindDialog::KFindDialog(KFindDialogPrivate &dd, QWidget *parent, long options, const QStringList &findStrings, bool hasSelection, bool replaceDialog)
0039     : QDialog(parent)
0040     , d_ptr(&dd)
0041 {
0042     Q_D(KFindDialog);
0043 
0044     d->init(replaceDialog, findStrings, hasSelection);
0045     setOptions(options);
0046 }
0047 
0048 KFindDialog::~KFindDialog() = default;
0049 
0050 QWidget *KFindDialog::findExtension() const
0051 {
0052     Q_D(const KFindDialog);
0053 
0054     if (!d->findExtension) {
0055         d->findExtension = new QWidget(d->findGrp);
0056         d->findLayout->addWidget(d->findExtension, 3, 0, 1, 2);
0057     }
0058 
0059     return d->findExtension;
0060 }
0061 
0062 QStringList KFindDialog::findHistory() const
0063 {
0064     Q_D(const KFindDialog);
0065 
0066     return d->find->historyItems();
0067 }
0068 
0069 void KFindDialogPrivate::init(bool forReplace, const QStringList &_findStrings, bool hasSelection)
0070 {
0071     Q_Q(KFindDialog);
0072 
0073     // Create common parts of dialog.
0074     QVBoxLayout *topLayout = new QVBoxLayout(q);
0075 
0076     findGrp = new QGroupBox(i18nc("@title:group", "Find"), q);
0077     findLayout = new QGridLayout(findGrp);
0078 
0079     QLabel *findLabel = new QLabel(i18n("&Text to find:"), findGrp);
0080     find = new KHistoryComboBox(findGrp);
0081     find->setMaxCount(10);
0082     find->setDuplicatesEnabled(false);
0083     regExp = new QCheckBox(i18n("Regular e&xpression"), findGrp);
0084     regExpItem = new QPushButton(i18n("&Edit..."), findGrp);
0085     regExpItem->setEnabled(false);
0086 
0087     findLayout->addWidget(findLabel, 0, 0);
0088     findLayout->addWidget(find, 1, 0, 1, 2);
0089     findLayout->addWidget(regExp, 2, 0);
0090     findLayout->addWidget(regExpItem, 2, 1);
0091     topLayout->addWidget(findGrp);
0092 
0093     replaceGrp = new QGroupBox(i18n("Replace With"), q);
0094     replaceLayout = new QGridLayout(replaceGrp);
0095 
0096     QLabel *replaceLabel = new QLabel(i18n("Replace&ment text:"), replaceGrp);
0097     replace = new KHistoryComboBox(replaceGrp);
0098     replace->setMaxCount(10);
0099     replace->setDuplicatesEnabled(false);
0100     backRef = new QCheckBox(i18n("Use p&laceholders"), replaceGrp);
0101     backRefItem = new QPushButton(i18n("Insert Place&holder"), replaceGrp);
0102     backRefItem->setEnabled(false);
0103 
0104     replaceLayout->addWidget(replaceLabel, 0, 0);
0105     replaceLayout->addWidget(replace, 1, 0, 1, 2);
0106     replaceLayout->addWidget(backRef, 2, 0);
0107     replaceLayout->addWidget(backRefItem, 2, 1);
0108     topLayout->addWidget(replaceGrp);
0109 
0110     QGroupBox *optionGrp = new QGroupBox(i18n("Options"), q);
0111     QGridLayout *optionsLayout = new QGridLayout(optionGrp);
0112 
0113     caseSensitive = new QCheckBox(i18n("C&ase sensitive"), optionGrp);
0114     wholeWordsOnly = new QCheckBox(i18n("&Whole words only"), optionGrp);
0115     fromCursor = new QCheckBox(i18n("From c&ursor"), optionGrp);
0116     findBackwards = new QCheckBox(i18n("Find &backwards"), optionGrp);
0117     selectedText = new QCheckBox(i18n("&Selected text"), optionGrp);
0118     q->setHasSelection(hasSelection);
0119     // If we have a selection, we make 'find in selection' default
0120     // and if we don't, then the option has to be unchecked, obviously.
0121     selectedText->setChecked(hasSelection);
0122     slotSelectedTextToggled(hasSelection);
0123 
0124     promptOnReplace = new QCheckBox(i18n("&Prompt on replace"), optionGrp);
0125     promptOnReplace->setChecked(true);
0126 
0127     optionsLayout->addWidget(caseSensitive, 0, 0);
0128     optionsLayout->addWidget(wholeWordsOnly, 1, 0);
0129     optionsLayout->addWidget(fromCursor, 2, 0);
0130     optionsLayout->addWidget(findBackwards, 0, 1);
0131     optionsLayout->addWidget(selectedText, 1, 1);
0132     optionsLayout->addWidget(promptOnReplace, 2, 1);
0133     topLayout->addWidget(optionGrp);
0134 
0135     buttonBox = new QDialogButtonBox(q);
0136     buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Close);
0137     q->connect(buttonBox, &QDialogButtonBox::accepted, q, [this]() {
0138         slotOk();
0139     });
0140     q->connect(buttonBox, &QDialogButtonBox::rejected, q, [this]() {
0141         slotReject();
0142     });
0143     topLayout->addWidget(buttonBox);
0144 
0145     // We delay creation of these until needed.
0146     patterns = nullptr;
0147     placeholders = nullptr;
0148 
0149     // signals and slots connections
0150     q->connect(selectedText, &QCheckBox::toggled, q, [this](bool checked) {
0151         slotSelectedTextToggled(checked);
0152     });
0153     q->connect(regExp, &QCheckBox::toggled, regExpItem, &QWidget::setEnabled);
0154     q->connect(backRef, &QCheckBox::toggled, backRefItem, &QWidget::setEnabled);
0155     q->connect(regExpItem, &QPushButton::clicked, q, [this]() {
0156         showPatterns();
0157     });
0158     q->connect(backRefItem, &QPushButton::clicked, q, [this]() {
0159         showPlaceholders();
0160     });
0161 
0162     q->connect(find, &KHistoryComboBox::editTextChanged, q, [this](const QString &text) {
0163         textSearchChanged(text);
0164     });
0165 
0166     q->connect(regExp, &QCheckBox::toggled, q, &KFindDialog::optionsChanged);
0167     q->connect(backRef, &QCheckBox::toggled, q, &KFindDialog::optionsChanged);
0168     q->connect(caseSensitive, &QCheckBox::toggled, q, &KFindDialog::optionsChanged);
0169     q->connect(wholeWordsOnly, &QCheckBox::toggled, q, &KFindDialog::optionsChanged);
0170     q->connect(fromCursor, &QCheckBox::toggled, q, &KFindDialog::optionsChanged);
0171     q->connect(findBackwards, &QCheckBox::toggled, q, &KFindDialog::optionsChanged);
0172     q->connect(selectedText, &QCheckBox::toggled, q, &KFindDialog::optionsChanged);
0173     q->connect(promptOnReplace, &QCheckBox::toggled, q, &KFindDialog::optionsChanged);
0174 
0175     // tab order
0176     q->setTabOrder(find, regExp);
0177     q->setTabOrder(regExp, regExpItem);
0178     q->setTabOrder(regExpItem, replace); // findExtension widgets are inserted in showEvent()
0179     q->setTabOrder(replace, backRef);
0180     q->setTabOrder(backRef, backRefItem);
0181     q->setTabOrder(backRefItem, caseSensitive);
0182     q->setTabOrder(caseSensitive, wholeWordsOnly);
0183     q->setTabOrder(wholeWordsOnly, fromCursor);
0184     q->setTabOrder(fromCursor, findBackwards);
0185     q->setTabOrder(findBackwards, selectedText);
0186     q->setTabOrder(selectedText, promptOnReplace);
0187 
0188     // buddies
0189     findLabel->setBuddy(find);
0190     replaceLabel->setBuddy(replace);
0191 
0192     if (!forReplace) {
0193         promptOnReplace->hide();
0194         replaceGrp->hide();
0195     }
0196 
0197     findStrings = _findStrings;
0198     find->setFocus();
0199     QPushButton *buttonOk = buttonBox->button(QDialogButtonBox::Ok);
0200     buttonOk->setEnabled(!q->pattern().isEmpty());
0201 
0202     if (forReplace) {
0203         KGuiItem::assign(buttonOk,
0204                          KGuiItem(i18n("&Replace"),
0205                                   QString(),
0206                                   i18n("Start replace"),
0207                                   i18n("<qt>If you press the <b>Replace</b> button, the text you entered "
0208                                        "above is searched for within the document and any occurrence is "
0209                                        "replaced with the replacement text.</qt>")));
0210     } else {
0211         KGuiItem::assign(buttonOk,
0212                          KGuiItem(i18n("&Find"),
0213                                   QStringLiteral("edit-find"),
0214                                   i18n("Start searching"),
0215                                   i18n("<qt>If you press the <b>Find</b> button, the text you entered "
0216                                        "above is searched for within the document.</qt>")));
0217     }
0218 
0219     // QWhatsthis texts
0220     find->setWhatsThis(i18n("Enter a pattern to search for, or select a previous pattern from the list."));
0221     regExp->setWhatsThis(i18n("If enabled, search for a regular expression."));
0222     regExpItem->setWhatsThis(i18n("Click here to edit your regular expression using a graphical editor."));
0223     replace->setWhatsThis(i18n("Enter a replacement string, or select a previous one from the list."));
0224     backRef->setWhatsThis(
0225         i18n("<qt>If enabled, any occurrence of <code><b>\\N</b></code>, where "
0226              "<code><b>N</b></code> is an integer number, will be replaced with "
0227              "the corresponding capture (\"parenthesized substring\") from the "
0228              "pattern.<p>To include (a literal <code><b>\\N</b></code> in your "
0229              "replacement, put an extra backslash in front of it, like "
0230              "<code><b>\\\\N</b></code>.</p></qt>"));
0231     backRefItem->setWhatsThis(i18n("Click for a menu of available captures."));
0232     wholeWordsOnly->setWhatsThis(i18n("Require word boundaries in both ends of a match to succeed."));
0233     fromCursor->setWhatsThis(i18n("Start searching at the current cursor location rather than at the top."));
0234     selectedText->setWhatsThis(i18n("Only search within the current selection."));
0235     caseSensitive->setWhatsThis(i18n("Perform a case sensitive search: entering the pattern 'Joe' will not match 'joe' or 'JOE', only 'Joe'."));
0236     findBackwards->setWhatsThis(i18n("Search backwards."));
0237     promptOnReplace->setWhatsThis(i18n("Ask before replacing each match found."));
0238 
0239     textSearchChanged(find->lineEdit()->text());
0240 }
0241 
0242 void KFindDialogPrivate::textSearchChanged(const QString &text)
0243 {
0244     buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty());
0245 }
0246 
0247 void KFindDialog::showEvent(QShowEvent *e)
0248 {
0249     Q_D(KFindDialog);
0250 
0251     if (!d->initialShowDone) {
0252         d->initialShowDone = true; // only once
0253         // qDebug() << "showEvent\n";
0254         if (!d->findStrings.isEmpty()) {
0255             setFindHistory(d->findStrings);
0256         }
0257         d->findStrings = QStringList();
0258         if (!d->pattern.isEmpty()) {
0259             d->find->lineEdit()->setText(d->pattern);
0260             d->find->lineEdit()->selectAll();
0261             d->pattern.clear();
0262         }
0263         // maintain a user-friendly tab order
0264         if (d->findExtension) {
0265             QWidget *prev = d->regExpItem;
0266             const auto children = d->findExtension->findChildren<QWidget *>();
0267             for (QWidget *child : children) {
0268                 setTabOrder(prev, child);
0269                 prev = child;
0270             }
0271             setTabOrder(prev, d->replace);
0272         }
0273     }
0274     d->find->setFocus();
0275     QDialog::showEvent(e);
0276 }
0277 
0278 long KFindDialog::options() const
0279 {
0280     Q_D(const KFindDialog);
0281 
0282     long options = 0;
0283 
0284     if (d->caseSensitive->isChecked()) {
0285         options |= KFind::CaseSensitive;
0286     }
0287     if (d->wholeWordsOnly->isChecked()) {
0288         options |= KFind::WholeWordsOnly;
0289     }
0290     if (d->fromCursor->isChecked()) {
0291         options |= KFind::FromCursor;
0292     }
0293     if (d->findBackwards->isChecked()) {
0294         options |= KFind::FindBackwards;
0295     }
0296     if (d->selectedText->isChecked()) {
0297         options |= KFind::SelectedText;
0298     }
0299     if (d->regExp->isChecked()) {
0300         options |= KFind::RegularExpression;
0301     }
0302     return options;
0303 }
0304 
0305 QString KFindDialog::pattern() const
0306 {
0307     Q_D(const KFindDialog);
0308 
0309     return d->find->currentText();
0310 }
0311 
0312 void KFindDialog::setPattern(const QString &pattern)
0313 {
0314     Q_D(KFindDialog);
0315 
0316     d->find->lineEdit()->setText(pattern);
0317     d->find->lineEdit()->selectAll();
0318     d->pattern = pattern;
0319     // qDebug() << "setPattern " << pattern;
0320 }
0321 
0322 void KFindDialog::setFindHistory(const QStringList &strings)
0323 {
0324     Q_D(KFindDialog);
0325 
0326     if (!strings.isEmpty()) {
0327         d->find->setHistoryItems(strings, true);
0328         d->find->lineEdit()->setText(strings.first());
0329         d->find->lineEdit()->selectAll();
0330     } else {
0331         d->find->clearHistory();
0332     }
0333 }
0334 
0335 void KFindDialog::setHasSelection(bool hasSelection)
0336 {
0337     Q_D(KFindDialog);
0338 
0339     if (hasSelection) {
0340         d->enabled |= KFind::SelectedText;
0341     } else {
0342         d->enabled &= ~KFind::SelectedText;
0343     }
0344     d->selectedText->setEnabled(hasSelection);
0345     if (!hasSelection) {
0346         d->selectedText->setChecked(false);
0347         d->slotSelectedTextToggled(hasSelection);
0348     }
0349 }
0350 
0351 void KFindDialogPrivate::slotSelectedTextToggled(bool selec)
0352 {
0353     // From cursor doesn't make sense if we have a selection
0354     fromCursor->setEnabled(!selec && (enabled & KFind::FromCursor));
0355     if (selec) { // uncheck if disabled
0356         fromCursor->setChecked(false);
0357     }
0358 }
0359 
0360 void KFindDialog::setHasCursor(bool hasCursor)
0361 {
0362     Q_D(KFindDialog);
0363 
0364     if (hasCursor) {
0365         d->enabled |= KFind::FromCursor;
0366     } else {
0367         d->enabled &= ~KFind::FromCursor;
0368     }
0369     d->fromCursor->setEnabled(hasCursor);
0370     d->fromCursor->setChecked(hasCursor && (options() & KFind::FromCursor));
0371 }
0372 
0373 void KFindDialog::setSupportsBackwardsFind(bool supports)
0374 {
0375     Q_D(KFindDialog);
0376 
0377     // ########## Shouldn't this hide the checkbox instead?
0378     if (supports) {
0379         d->enabled |= KFind::FindBackwards;
0380     } else {
0381         d->enabled &= ~KFind::FindBackwards;
0382     }
0383     d->findBackwards->setEnabled(supports);
0384     d->findBackwards->setChecked(supports && (options() & KFind::FindBackwards));
0385 }
0386 
0387 void KFindDialog::setSupportsCaseSensitiveFind(bool supports)
0388 {
0389     Q_D(KFindDialog);
0390 
0391     // ########## This should hide the checkbox instead
0392     if (supports) {
0393         d->enabled |= KFind::CaseSensitive;
0394     } else {
0395         d->enabled &= ~KFind::CaseSensitive;
0396     }
0397     d->caseSensitive->setEnabled(supports);
0398     d->caseSensitive->setChecked(supports && (options() & KFind::CaseSensitive));
0399 }
0400 
0401 void KFindDialog::setSupportsWholeWordsFind(bool supports)
0402 {
0403     Q_D(KFindDialog);
0404 
0405     // ########## This should hide the checkbox instead
0406     if (supports) {
0407         d->enabled |= KFind::WholeWordsOnly;
0408     } else {
0409         d->enabled &= ~KFind::WholeWordsOnly;
0410     }
0411     d->wholeWordsOnly->setEnabled(supports);
0412     d->wholeWordsOnly->setChecked(supports && (options() & KFind::WholeWordsOnly));
0413 }
0414 
0415 void KFindDialog::setSupportsRegularExpressionFind(bool supports)
0416 {
0417     Q_D(KFindDialog);
0418 
0419     if (supports) {
0420         d->enabled |= KFind::RegularExpression;
0421     } else {
0422         d->enabled &= ~KFind::RegularExpression;
0423     }
0424     d->regExp->setEnabled(supports);
0425     d->regExp->setChecked(supports && (options() & KFind::RegularExpression));
0426     if (!supports) {
0427         d->regExpItem->hide();
0428         d->regExp->hide();
0429     } else {
0430         d->regExpItem->show();
0431         d->regExp->show();
0432     }
0433 }
0434 
0435 void KFindDialog::setOptions(long options)
0436 {
0437     Q_D(KFindDialog);
0438 
0439     d->caseSensitive->setChecked((d->enabled & KFind::CaseSensitive) && (options & KFind::CaseSensitive));
0440     d->wholeWordsOnly->setChecked((d->enabled & KFind::WholeWordsOnly) && (options & KFind::WholeWordsOnly));
0441     d->fromCursor->setChecked((d->enabled & KFind::FromCursor) && (options & KFind::FromCursor));
0442     d->findBackwards->setChecked((d->enabled & KFind::FindBackwards) && (options & KFind::FindBackwards));
0443     d->selectedText->setChecked((d->enabled & KFind::SelectedText) && (options & KFind::SelectedText));
0444     d->regExp->setChecked((d->enabled & KFind::RegularExpression) && (options & KFind::RegularExpression));
0445 }
0446 
0447 // Create a popup menu with a list of regular expression terms, to help the user
0448 // compose a regular expression search pattern.
0449 void KFindDialogPrivate::showPatterns()
0450 {
0451     Q_Q(KFindDialog);
0452 
0453     typedef struct {
0454         const KLazyLocalizedString description;
0455         const char *regExp;
0456         int cursorAdjustment;
0457     } Term;
0458     static const Term items[] = {
0459         {kli18n("Any Character"), ".", 0},
0460         {kli18n("Start of Line"), "^", 0},
0461         {kli18n("End of Line"), "$", 0},
0462         {kli18n("Set of Characters"), "[]", -1},
0463         {kli18n("Repeats, Zero or More Times"), "*", 0},
0464         {kli18n("Repeats, One or More Times"), "+", 0},
0465         {kli18n("Optional"), "?", 0},
0466         {kli18n("Escape"), "\\", 0},
0467         {kli18n("TAB"), "\\t", 0},
0468         {kli18n("Newline"), "\\n", 0},
0469         {kli18n("Carriage Return"), "\\r", 0},
0470         {kli18n("White Space"), "\\s", 0},
0471         {kli18n("Digit"), "\\d", 0},
0472     };
0473 
0474     class RegExpAction : public QAction
0475     {
0476     public:
0477         RegExpAction(QObject *parent, const QString &text, const QString &regExp, int cursor)
0478             : QAction(text, parent)
0479             , mText(text)
0480             , mRegExp(regExp)
0481             , mCursor(cursor)
0482         {
0483         }
0484 
0485         QString text() const
0486         {
0487             return mText;
0488         }
0489         QString regExp() const
0490         {
0491             return mRegExp;
0492         }
0493         int cursor() const
0494         {
0495             return mCursor;
0496         }
0497 
0498     private:
0499         QString mText;
0500         QString mRegExp;
0501         int mCursor;
0502     };
0503 
0504     // Populate the popup menu.
0505     if (!patterns) {
0506         patterns = new QMenu(q);
0507         for (const Term &item : items) {
0508             patterns->addAction(new RegExpAction(patterns, item.description.toString(), QLatin1String(item.regExp), item.cursorAdjustment));
0509         }
0510     }
0511 
0512     // Insert the selection into the edit control.
0513     QAction *action = patterns->exec(regExpItem->mapToGlobal(regExpItem->rect().bottomLeft()));
0514     if (action) {
0515         RegExpAction *regExpAction = static_cast<RegExpAction *>(action);
0516         if (regExpAction) {
0517             QLineEdit *editor = find->lineEdit();
0518 
0519             editor->insert(regExpAction->regExp());
0520             editor->setCursorPosition(editor->cursorPosition() + regExpAction->cursor());
0521         }
0522     }
0523 }
0524 
0525 class PlaceHolderAction : public QAction
0526 {
0527 public:
0528     PlaceHolderAction(QObject *parent, const QString &text, int id)
0529         : QAction(text, parent)
0530         , mText(text)
0531         , mId(id)
0532     {
0533     }
0534 
0535     QString text() const
0536     {
0537         return mText;
0538     }
0539     int id() const
0540     {
0541         return mId;
0542     }
0543 
0544 private:
0545     QString mText;
0546     int mId;
0547 };
0548 
0549 // Create a popup menu with a list of backreference terms, to help the user
0550 // compose a regular expression replacement pattern.
0551 void KFindDialogPrivate::showPlaceholders()
0552 {
0553     Q_Q(KFindDialog);
0554 
0555     // Populate the popup menu.
0556     if (!placeholders) {
0557         placeholders = new QMenu(q);
0558         q->connect(placeholders, &QMenu::aboutToShow, q, [this]() {
0559             slotPlaceholdersAboutToShow();
0560         });
0561     }
0562 
0563     // Insert the selection into the edit control.
0564     QAction *action = placeholders->exec(backRefItem->mapToGlobal(backRefItem->rect().bottomLeft()));
0565     if (action) {
0566         PlaceHolderAction *placeHolderAction = static_cast<PlaceHolderAction *>(action);
0567         if (placeHolderAction) {
0568             QLineEdit *editor = replace->lineEdit();
0569             editor->insert(QStringLiteral("\\%1").arg(placeHolderAction->id()));
0570         }
0571     }
0572 }
0573 
0574 void KFindDialogPrivate::slotPlaceholdersAboutToShow()
0575 {
0576     Q_Q(KFindDialog);
0577 
0578     placeholders->clear();
0579     placeholders->addAction(new PlaceHolderAction(placeholders, i18n("Complete Match"), 0));
0580 
0581     const int n = QRegularExpression(q->pattern(), QRegularExpression::UseUnicodePropertiesOption).captureCount();
0582     for (int i = 1; i <= n; ++i) {
0583         placeholders->addAction(new PlaceHolderAction(placeholders, i18n("Captured Text (%1)", i), i));
0584     }
0585 }
0586 
0587 void KFindDialogPrivate::slotOk()
0588 {
0589     Q_Q(KFindDialog);
0590 
0591     // Nothing to find?
0592     if (q->pattern().isEmpty()) {
0593         KMessageBox::error(q, i18n("You must enter some text to search for."));
0594         return;
0595     }
0596 
0597     if (regExp->isChecked()) {
0598         // Check for a valid regular expression.
0599         if (!QRegularExpression(q->pattern(), QRegularExpression::UseUnicodePropertiesOption).isValid()) {
0600             KMessageBox::error(q, i18n("Invalid PCRE pattern syntax."));
0601             return;
0602         }
0603     }
0604 
0605     find->addToHistory(q->pattern());
0606 
0607     if (q->windowModality() != Qt::NonModal) {
0608         q->accept();
0609     }
0610     Q_EMIT q->okClicked();
0611 }
0612 
0613 void KFindDialogPrivate::slotReject()
0614 {
0615     Q_Q(KFindDialog);
0616 
0617     Q_EMIT q->cancelClicked();
0618     q->reject();
0619 }
0620 
0621 #include "moc_kfinddialog.cpp"