diff --git a/src/linguist/linguist/finddialog.cpp b/src/linguist/linguist/finddialog.cpp index 53bb348011e973b76d2a214bae0411374af03b78..9dd801a712f11955876418bf2442aaed82b2db07 100644 --- a/src/linguist/linguist/finddialog.cpp +++ b/src/linguist/linguist/finddialog.cpp @@ -44,14 +44,25 @@ FindDialog::FindDialog(QWidget *parent) findNxt->setEnabled(false); connect(findNxt, SIGNAL(clicked()), this, SLOT(emitFindNext())); - connect(led, SIGNAL(textChanged(QString)), this, SLOT(verifyText(QString))); + connect(useRegExp, SIGNAL(stateChanged(int)), this, SLOT(verify())); + connect(led, SIGNAL(textChanged(QString)), this, SLOT(verify())); led->setFocus(); } -void FindDialog::verifyText(const QString &text) +void FindDialog::verify() { - findNxt->setEnabled(!text.isEmpty()); + bool validRegExp = true; + if (useRegExp->isChecked() && !led->text().isEmpty()) { + m_regExp.setPattern(led->text()); + validRegExp = m_regExp.isValid(); + } + if (validRegExp && m_redText) + led->setStyleSheet(QStringLiteral("color: auto;")); + else if (!validRegExp && !m_redText) + led->setStyleSheet(QStringLiteral("color: red;")); + m_redText = !validRegExp; + findNxt->setEnabled(!led->text().isEmpty() && validRegExp); } void FindDialog::emitFindNext() @@ -65,7 +76,8 @@ void FindDialog::emitFindNext() (comments->isChecked() ? DataModel::Comments : 0)); else where = DataModel::Translations; - emit findNext(led->text(), where, matchCase->isChecked(), ignoreAccelerators->isChecked(), skipObsolete->isChecked()); + emit findNext(led->text(), where, matchCase->isChecked(), ignoreAccelerators->isChecked(), + skipObsolete->isChecked(), useRegExp->isChecked()); led->selectAll(); } diff --git a/src/linguist/linguist/finddialog.h b/src/linguist/linguist/finddialog.h index 5b655587421f5d06f4c5adcf855db71516f178e9..039f0b9e72dc0ed52087fd631fc0123ce1cf3d46 100644 --- a/src/linguist/linguist/finddialog.h +++ b/src/linguist/linguist/finddialog.h @@ -33,6 +33,7 @@ #include "messagemodel.h" #include <QDialog> +#include <QRegularExpression> QT_BEGIN_NAMESPACE @@ -41,15 +42,20 @@ class FindDialog : public QDialog, public Ui::FindDialog Q_OBJECT public: FindDialog(QWidget *parent = 0); + QRegularExpression &getRegExp() { return m_regExp; } signals: void findNext(const QString& text, DataModel::FindLocation where, - bool matchCase, bool ignoreAccelerators, bool skipObsolete); + bool matchCase, bool ignoreAccelerators, bool skipObsolete, bool useRegExp); private slots: void emitFindNext(); - void verifyText(const QString &); + void verify(); void find(); + +private: + QRegularExpression m_regExp; + bool m_redText = false; }; QT_END_NAMESPACE diff --git a/src/linguist/linguist/finddialog.ui b/src/linguist/linguist/finddialog.ui index f405a45be61009960298afdb129198ee350c0461..20dceb7e1d7179923fe6637f78e18119f63d6370 100644 --- a/src/linguist/linguist/finddialog.ui +++ b/src/linguist/linguist/finddialog.ui @@ -50,28 +50,22 @@ <string>This window allows you to search for some text in the translation source file.</string> </property> <layout class="QHBoxLayout"> - <property name="spacing"> - <number>6</number> + <property name="leftMargin"> + <number>11</number> + </property> + <property name="topMargin"> + <number>11</number> </property> - <property name="margin"> + <property name="rightMargin"> + <number>11</number> + </property> + <property name="bottomMargin"> <number>11</number> </property> <item> <layout class="QVBoxLayout"> - <property name="spacing"> - <number>6</number> - </property> - <property name="margin"> - <number>0</number> - </property> <item> <layout class="QHBoxLayout"> - <property name="spacing"> - <number>6</number> - </property> - <property name="margin"> - <number>0</number> - </property> <item> <widget class="QLabel" name="findWhat"> <property name="text"> @@ -97,45 +91,46 @@ <string>Options</string> </property> <layout class="QGridLayout"> - <property name="margin"> - <number>9</number> - </property> - <property name="spacing"> - <number>6</number> - </property> - <item row="1" column="0"> - <widget class="QCheckBox" name="sourceText"> + <item row="1" column="1"> + <widget class="QCheckBox" name="useRegExp"> <property name="whatsThis"> - <string>Source texts are searched when checked.</string> + <string>Lets you use a Perl-compatible regular expression</string> </property> <property name="text"> - <string>&Source texts</string> + <string>Regular &expression</string> </property> - <property name="checked"> - <bool>true</bool> + </widget> + </item> + <item row="0" column="1"> + <widget class="QCheckBox" name="matchCase"> + <property name="whatsThis"> + <string>Texts such as 'TeX' and 'tex' are considered as different when checked.</string> + </property> + <property name="text"> + <string>&Match case</string> </property> </widget> </item> - <item row="2" column="0"> - <widget class="QCheckBox" name="translations"> + <item row="1" column="0"> + <widget class="QCheckBox" name="sourceText"> <property name="whatsThis"> - <string>Translations are searched when checked.</string> + <string>Source texts are searched when checked.</string> </property> <property name="text"> - <string>&Translations</string> + <string>&Source texts</string> </property> <property name="checked"> <bool>true</bool> </property> </widget> </item> - <item row="0" column="1"> - <widget class="QCheckBox" name="matchCase"> + <item row="3" column="1"> + <widget class="QCheckBox" name="skipObsolete"> <property name="whatsThis"> - <string>Texts such as 'TeX' and 'tex' are considered as different when checked.</string> + <string>Obsoleted messages are skipped when checked.</string> </property> <property name="text"> - <string>&Match case</string> + <string>Skip &obsolete</string> </property> </widget> </item> @@ -152,7 +147,7 @@ </property> </widget> </item> - <item row="1" column="1"> + <item row="2" column="1"> <widget class="QCheckBox" name="ignoreAccelerators"> <property name="text"> <string>Ignore &accelerators</string> @@ -162,13 +157,16 @@ </property> </widget> </item> - <item row="2" column="1"> - <widget class="QCheckBox" name="skipObsolete"> + <item row="2" column="0"> + <widget class="QCheckBox" name="translations"> <property name="whatsThis"> - <string>Obsoleted messages are skipped when checked.</string> + <string>Translations are searched when checked.</string> </property> <property name="text"> - <string>Skip &obsolete</string> + <string>&Translations</string> + </property> + <property name="checked"> + <bool>true</bool> </property> </widget> </item> @@ -179,12 +177,6 @@ </item> <item> <layout class="QVBoxLayout"> - <property name="spacing"> - <number>6</number> - </property> - <property name="margin"> - <number>0</number> - </property> <item> <widget class="QPushButton" name="findNxt"> <property name="whatsThis"> diff --git a/src/linguist/linguist/mainwindow.cpp b/src/linguist/linguist/mainwindow.cpp index 8cc55d44b0838d426856cb65dda17fb962736147..9f7109c8545f9e62c7f85c31c44580221f4bb625 100644 --- a/src/linguist/linguist/mainwindow.cpp +++ b/src/linguist/linguist/mainwindow.cpp @@ -277,6 +277,7 @@ MainWindow::MainWindow() m_findMatchCase(Qt::CaseInsensitive), m_findIgnoreAccelerators(true), m_findSkipObsolete(false), + m_findUseRegExp(false), m_findWhere(DataModel::NoLocation), m_translationSettingsDialog(0), m_settingCurrentMessage(false), @@ -483,8 +484,8 @@ MainWindow::MainWindow() this, SLOT(updateTranslation(QStringList))); connect(m_messageEditor, SIGNAL(translatorCommentChanged(QString)), this, SLOT(updateTranslatorComment(QString))); - connect(m_findDialog, SIGNAL(findNext(QString,DataModel::FindLocation,bool,bool,bool)), - this, SLOT(findNext(QString,DataModel::FindLocation,bool,bool,bool))); + connect(m_findDialog, SIGNAL(findNext(QString,DataModel::FindLocation,bool,bool,bool,bool)), + this, SLOT(findNext(QString,DataModel::FindLocation,bool,bool,bool,bool))); connect(m_translateDialog, SIGNAL(requestMatchUpdate(bool&)), SLOT(updateTranslateHit(bool&))); connect(m_translateDialog, SIGNAL(activated(int)), SLOT(translate(int))); @@ -986,8 +987,10 @@ bool MainWindow::searchItem(DataModel::FindLocation where, const QString &search // FIXME: This removes too much. The proper solution might be too slow, though. text.remove(QLatin1Char('&')); - int foundOffset = text.indexOf(m_findText, 0, m_findMatchCase); - return foundOffset >= 0; + if (m_findUseRegExp) + return m_findDialog->getRegExp().match(text).hasMatch(); + else + return text.indexOf(m_findText, 0, m_findMatchCase) >= 0; } void MainWindow::findAgain() @@ -1763,7 +1766,7 @@ bool MainWindow::next(bool checkUnfinished) } void MainWindow::findNext(const QString &text, DataModel::FindLocation where, - bool matchCase, bool ignoreAccelerators, bool skipObsolete) + bool matchCase, bool ignoreAccelerators, bool skipObsolete, bool useRegExp) { if (text.isEmpty()) return; @@ -1772,6 +1775,12 @@ void MainWindow::findNext(const QString &text, DataModel::FindLocation where, m_findMatchCase = matchCase ? Qt::CaseSensitive : Qt::CaseInsensitive; m_findIgnoreAccelerators = ignoreAccelerators; m_findSkipObsolete = skipObsolete; + m_findUseRegExp = useRegExp; + if (m_findUseRegExp) { + m_findDialog->getRegExp().setPatternOptions(matchCase + ? QRegularExpression::NoPatternOption + : QRegularExpression::CaseInsensitiveOption); + } m_ui.actionFindNext->setEnabled(true); findAgain(); } diff --git a/src/linguist/linguist/mainwindow.h b/src/linguist/linguist/mainwindow.h index 63deaa3293a6183bf9c76014836de3b342e44f98..b871b635ec55febe6a36494bb5a70c1c92651671 100644 --- a/src/linguist/linguist/mainwindow.h +++ b/src/linguist/linguist/mainwindow.h @@ -150,7 +150,7 @@ private slots: void prevUnfinished(); void nextUnfinished(); void findNext(const QString &text, DataModel::FindLocation where, - bool matchCase, bool ignoreAccelerators, bool skipObsolete); + bool matchCase, bool ignoreAccelerators, bool skipObsolete, bool regularExp); void revalidate(); void toggleStatistics(); void toggleVisualizeWhitespace(); @@ -225,6 +225,7 @@ private: Qt::CaseSensitivity m_findMatchCase; bool m_findIgnoreAccelerators; bool m_findSkipObsolete; + bool m_findUseRegExp; DataModel::FindLocation m_findWhere; TranslateDialog *m_translateDialog;