diff --git a/src/FindReplaceDialog.cpp b/src/FindReplaceDialog.cpp index 4a7ba171..0d4ddbb5 100644 --- a/src/FindReplaceDialog.cpp +++ b/src/FindReplaceDialog.cpp @@ -6,7 +6,8 @@ FindReplaceDialog::FindReplaceDialog(QWidget* parent) : QDialog(parent), - ui(new Ui::FindReplaceDialog) + ui(new Ui::FindReplaceDialog), + findInProgress(false) { // Create UI ui->setupUi(this); @@ -34,29 +35,67 @@ void FindReplaceDialog::setExtendedScintilla(ExtendedScintilla* scintilla) connect(m_scintilla, SIGNAL(destroyed()), this, SLOT(hide())); connect(ui->findText, SIGNAL(editingFinished()), this, SLOT(cancelFind())); + connect(ui->regexpCheckBox, &QCheckBox::toggled, this, &FindReplaceDialog::cancelFind); + connect(ui->caseCheckBox, &QCheckBox::toggled, this, &FindReplaceDialog::cancelFind); + connect(ui->wholeWordsCheckBox, &QCheckBox::toggled, this, &FindReplaceDialog::cancelFind); + connect(ui->wrapCheckBox, &QCheckBox::toggled, this, &FindReplaceDialog::cancelFind); + connect(ui->backwardsCheckBox, &QCheckBox::toggled, this, &FindReplaceDialog::cancelFind); + connect(ui->selectionCheckBox, &QCheckBox::toggled, this, &FindReplaceDialog::cancelFind); + connect(ui->selectionCheckBox, &QCheckBox::toggled, ui->wrapCheckBox, &QCheckBox::setDisabled); +} + +bool FindReplaceDialog::findFirst(bool wrap, bool forward) +{ + if (ui->selectionCheckBox->isChecked()) + return m_scintilla->findFirstInSelection + (ui->findText->text(), + ui->regexpCheckBox->isChecked(), + ui->caseCheckBox->isChecked(), + ui->wholeWordsCheckBox->isChecked(), + forward); + else + return m_scintilla->findFirst + (ui->findText->text(), + ui->regexpCheckBox->isChecked(), + ui->caseCheckBox->isChecked(), + ui->wholeWordsCheckBox->isChecked(), + wrap, + forward); } bool FindReplaceDialog::findNext() { clearIndicators(); - bool found = m_scintilla->findText - (ui->findText->text(), - ui->regexpCheckBox->isChecked(), - ui->caseCheckBox->isChecked(), - ui->wholeWordsCheckBox->isChecked(), - ui->wrapCheckBox->isChecked(), - !ui->backwardsCheckBox->isChecked()); - if (!found) + if (findInProgress) + findInProgress = m_scintilla->findNext(); + else + findInProgress = findFirst(ui->wrapCheckBox->isChecked(), + !ui->backwardsCheckBox->isChecked()); + + if (!findInProgress) ui->messageLabel->setText(tr("The searched text was not found")); - return found; + return findInProgress; } void FindReplaceDialog::show() { ui->findText->setFocus(); + + // If there is multi-line selected text set automatically the selection + // check box. If it's only part of a line, use it as text to find. + if (m_scintilla->hasSelectedText()) + if (m_scintilla->selectedText().contains("\n")) + ui->selectionCheckBox->setChecked(true); + else { + ui->findText->setText(m_scintilla->selectedText()); + ui->selectionCheckBox->setChecked(false); + } + else + ui->selectionCheckBox->setChecked(false); + ui->findText->selectAll(); QDialog::show(); } @@ -73,24 +112,27 @@ void FindReplaceDialog::indicateSelection() int fromRow, fromIndex, toRow, toIndex; m_scintilla->getSelection(&fromRow, &fromIndex, &toRow, &toIndex); m_scintilla->fillIndicatorRange(fromRow, fromIndex, toRow, toIndex, foundIndicatorNumber); - } -void FindReplaceDialog::findAll() + +void FindReplaceDialog::searchAll(bool replace) { clearIndicators(); + if (!ui->selectionCheckBox->isChecked()) + m_scintilla->setCursorPosition(0, 0); + + bool found = findFirst(/* wrap */ false, /* fordward */ true); + int occurrences = 0; - m_scintilla->setCursorPosition(0, 0); - while (m_scintilla->findText - (ui->findText->text(), - ui->regexpCheckBox->isChecked(), - ui->caseCheckBox->isChecked(), - ui->wholeWordsCheckBox->isChecked(), - false, - true)) { + while (found) { + if (replace) + m_scintilla->replace(ui->replaceWithText->text()); indicateSelection(); ++occurrences; + found = m_scintilla->findNext(); } - m_scintilla->clearSelection(); + + if (!ui->selectionCheckBox->isChecked()) + m_scintilla->clearSelection(); QString message; switch (occurrences) { @@ -98,55 +140,39 @@ void FindReplaceDialog::findAll() message = tr("The searched text was not found."); break; case 1: - message = tr("The searched text was found one time."); + if (replace) + message = tr("The searched text was replaced one time."); + else + message = tr("The searched text was found one time."); break; default: - message = tr("The searched text was found %1 times.").arg(occurrences); + if (replace) + message = tr("The searched text was replaced %1 times.").arg(occurrences); + else + message = tr("The searched text was found %1 times.").arg(occurrences); + break; } ui->messageLabel->setText(message); } +void FindReplaceDialog::findAll() +{ + searchAll(/* replace */ false); +} + void FindReplaceDialog::replaceAll() { - clearIndicators(); - int occurrences = 0; - m_scintilla->setCursorPosition(0, 0); - while (m_scintilla->findText - (ui->findText->text(), - ui->regexpCheckBox->isChecked(), - ui->caseCheckBox->isChecked(), - ui->wholeWordsCheckBox->isChecked(), - false, - true)) { - m_scintilla->replace(ui->replaceWithText->text()); - indicateSelection(); - ++occurrences; - } - m_scintilla->clearSelection(); - - QString message; - switch (occurrences) { - case 0: - message = tr("The searched text was not found."); - break; - case 1: - message = tr("The searched text was replaced one time."); - break; - default: - message = tr("The searched text was replaced %1 times.").arg(occurrences); - break; - } - - ui->messageLabel->setText(message); - + searchAll(/* replace */ true); } void FindReplaceDialog::cancelFind() { m_scintilla->findFirst(QString(), false, false, false, false); clearIndicators(); + findInProgress = false; + ui->messageLabel->setText(""); } void FindReplaceDialog::help() { diff --git a/src/FindReplaceDialog.h b/src/FindReplaceDialog.h index aea18ae4..6bc05a9a 100644 --- a/src/FindReplaceDialog.h +++ b/src/FindReplaceDialog.h @@ -33,11 +33,14 @@ private slots: void buttonBox_clicked(QAbstractButton* button); private: + bool findFirst(bool wrap, bool forward); + void searchAll(bool replace); void indicateSelection(); void clearIndicators(); Ui::FindReplaceDialog* ui; ExtendedScintilla* m_scintilla; int foundIndicatorNumber; + bool findInProgress; }; #endif diff --git a/src/FindReplaceDialog.ui b/src/FindReplaceDialog.ui index 689e6e6a..6d947f9f 100644 --- a/src/FindReplaceDialog.ui +++ b/src/FindReplaceDialog.ui @@ -101,6 +101,16 @@ + + + <html><head/><body><p>When checked, the pattern to find is searched only in the current selection.</p></body></html> + + + &Selection only + + + + <html><head/><body><p>When checked, the pattern to find is interpreted as a UNIX regular expression. See <a href="https://en.wikibooks.org/wiki/Regular_Expressions">Regular Expression in Wikibooks</a>.</p></body></html> @@ -210,6 +220,7 @@ wholeWordsCheckBox wrapCheckBox backwardsCheckBox + selectionCheckBox regexpCheckBox findNextButton replaceButton