diff --git a/plugins/grepview/grepdialog.h b/plugins/grepview/grepdialog.h --- a/plugins/grepview/grepdialog.h +++ b/plugins/grepview/grepdialog.h @@ -17,6 +17,7 @@ #include #include +#include "grepjob.h" #include "ui_grepwidget.h" class KConfig; @@ -32,20 +33,8 @@ explicit GrepDialog( GrepViewPlugin * plugin, QWidget *parent=nullptr ); ~GrepDialog() override; - void setPattern(const QString &pattern); - void setEnableProjectBox(bool enable); - - QString patternString() const; - QString templateString() const; - QString replacementTemplateString() const; - QString filesString() const; - QString excludeString() const; - - bool useProjectFilesFlag() const; - bool regexpFlag() const; - bool caseSensitiveFlag() const; - - int depthValue() const; + void setSettings(const GrepJobSettings &settings); + GrepJobSettings settings() const; public Q_SLOTS: void startSearch(); @@ -71,8 +60,11 @@ // Returns whether the given url is a subfile/subdirectory of one of the chosen directories/files // This is slow, so don't call it too often bool isPartOfChoice(QUrl url) const; + // Checks what a user has entered into the dialog and saves the data in m_settings + void updateSettings(); GrepViewPlugin * m_plugin; + GrepJobSettings m_settings; }; diff --git a/plugins/grepview/grepdialog.cpp b/plugins/grepview/grepdialog.cpp --- a/plugins/grepview/grepdialog.cpp +++ b/plugins/grepview/grepdialog.cpp @@ -38,7 +38,6 @@ #include #include "grepviewplugin.h" -#include "grepjob.h" #include "grepoutputview.h" #include "grepfindthread.h" #include "greputil.h" @@ -66,7 +65,7 @@ << QStringLiteral("\\b%s\\b\\s*=[^=]") << QStringLiteral("\\->\\s*\\b%s\\b\\s*\\(") << QStringLiteral("([a-z0-9_$]+)\\s*::\\s*\\b%s\\b\\s*\\(") - << QStringLiteral("\\b%s\\b\\s*\\->\\s*([a-z0-9_$]+)\\s*\\("); + << QStringLiteral("\\b%s\\b\\s*\\->\\s*([a-z0-9_$]+)\\s*\\("); } inline QStringList repl_template() { return QStringList() @@ -257,7 +256,7 @@ { QUrl currentUrl = QUrl::fromLocalFile(dir); if( !currentUrl.isValid() ) { - setEnableProjectBox(false); + m_settings.projectFilesOnly = false; return; } @@ -270,7 +269,7 @@ projectAvailable = false; } - setEnableProjectBox(projectAvailable); + m_settings.projectFilesOnly = projectAvailable; } GrepDialog::~GrepDialog() @@ -297,16 +296,22 @@ replacementTemplateEdit->setCurrentItem( repl_template().at(index), true ); } -void GrepDialog::setEnableProjectBox(bool enable) +void GrepDialog::setSettings(const GrepJobSettings& settings) { - limitToProjectCheck->setEnabled(enable); - limitToProjectLabel->setEnabled(enable); + patternCombo->setEditText(settings.pattern); + patternComboEditTextChanged(settings.pattern); + m_settings.pattern = settings.pattern; + + limitToProjectCheck->setEnabled(settings.projectFilesOnly); + limitToProjectLabel->setEnabled(settings.projectFilesOnly); + m_settings.projectFilesOnly = settings.projectFilesOnly; + + // Note: everything else is set by a user } -void GrepDialog::setPattern(const QString &pattern) +GrepJobSettings GrepDialog::settings() const { - patternCombo->setEditText(pattern); - patternComboEditTextChanged(pattern); + return m_settings; } void GrepDialog::setSearchLocations(const QString &dir) @@ -331,52 +336,6 @@ directoryChanged(dir); } -QString GrepDialog::patternString() const -{ - return patternCombo->currentText(); -} - -QString GrepDialog::templateString() const -{ - return templateEdit->currentText().isEmpty() ? QStringLiteral("%s") : templateEdit->currentText(); -} - -QString GrepDialog::replacementTemplateString() const -{ - return replacementTemplateEdit->currentText(); -} - -QString GrepDialog::filesString() const -{ - return filesCombo->currentText(); -} - -QString GrepDialog::excludeString() const -{ - return excludeCombo->currentText(); -} - -bool GrepDialog::useProjectFilesFlag() const -{ - if (!limitToProjectCheck->isEnabled()) return false; - return limitToProjectCheck->isChecked(); -} - -bool GrepDialog::regexpFlag() const -{ - return regexCheck->isChecked(); -} - -int GrepDialog::depthValue() const -{ - return depthSpin->value(); -} - -bool GrepDialog::caseSensitiveFlag() const -{ - return caseSensitiveCheck->isChecked(); -} - void GrepDialog::patternComboEditTextChanged( const QString& text) { buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty()); @@ -419,10 +378,12 @@ void GrepDialog::startSearch() { + updateSettings(); + // search for unsaved documents QList unsavedFiles; - QStringList include = GrepFindFilesThread::parseInclude(filesString()); - QStringList exclude = GrepFindFilesThread::parseExclude(excludeString()); + QStringList include = GrepFindFilesThread::parseInclude(m_settings.files); + QStringList exclude = GrepFindFilesThread::parseExclude(m_settings.exclude); foreach(IDocument* doc, ICore::self()->documentController()->openDocuments()) { @@ -461,7 +422,7 @@ GrepOutputView *toolView = (GrepOutputView*)ICore::self()->uiController()-> findToolView(i18n("Find/Replace in Files"), m_plugin->toolViewFactory(), IUiController::CreateAndRaise); - GrepOutputModel* outputModel = toolView->renewModel(patternString(), description); + GrepOutputModel* outputModel = toolView->renewModel(m_settings.pattern, description); connect(job, &GrepJob::showErrorMessage, toolView, &GrepOutputView::showErrorMessage); @@ -475,23 +436,31 @@ connect(toolView, &GrepOutputView::outputViewIsClosed, job, [=]() {job->kill();}); job->setOutputModel(outputModel); - job->setPatternString(patternString()); - job->setReplacementTemplateString(replacementTemplateString()); - job->setTemplateString(templateString()); - job->setFilesString(filesString()); - job->setExcludeString(excludeString()); job->setDirectoryChoice(choice); - job->setProjectFilesFlag( useProjectFilesFlag() ); - job->setRegexpFlag( regexpFlag() ); - job->setDepth( depthValue() ); - job->setCaseSensitive( caseSensitiveFlag() ); + job->setSettings(m_settings); ICore::self()->runController()->registerJob(job); m_plugin->rememberSearchDirectory(descriptionOrUrl); close(); } +void GrepDialog::updateSettings() +{ + if (limitToProjectCheck->isEnabled()) + m_settings.projectFilesOnly = limitToProjectCheck->isChecked(); + + m_settings.caseSensitive = caseSensitiveCheck->isChecked(); + m_settings.regexp = regexCheck->isChecked(); + + m_settings.depth = depthSpin->value(); + + m_settings.pattern = patternCombo->currentText(); + m_settings.searchTemplate = templateEdit->currentText().isEmpty() ? QStringLiteral("%s") : templateEdit->currentText(); + m_settings.replacementTemplate = replacementTemplateEdit->currentText(); + m_settings.files = filesCombo->currentText(); + m_settings.exclude = excludeCombo->currentText(); +} diff --git a/plugins/grepview/grepjob.h b/plugins/grepview/grepjob.h --- a/plugins/grepview/grepjob.h +++ b/plugins/grepview/grepjob.h @@ -36,6 +36,21 @@ class GrepViewPlugin; class FindReplaceTest; //FIXME: this is useful only for tests +struct GrepJobSettings +{ + bool projectFilesOnly = false; + bool caseSensitive = true; + bool regexp = true; + + int depth = -1; + + QString pattern; + QString searchTemplate; + QString replacementTemplate; + QString files; + QString exclude; +}; + class GrepJob : public KJob, public KDevelop::IStatus { Q_OBJECT @@ -49,18 +64,11 @@ explicit GrepJob( QObject *parent = nullptr ); public: + void setSettings(const GrepJobSettings& settings); + GrepJobSettings settings() const; void setOutputModel(GrepOutputModel * model); - void setPatternString(const QString& patternString); - void setTemplateString(const QString &templateString); - void setReplacementTemplateString(const QString &replTmplString); - void setFilesString(const QString &filesString); - void setExcludeString(const QString &excludeString); void setDirectoryChoice(const QList &choice); - void setDepth(int depth); - void setRegexpFlag(bool regexpFlag); - void setCaseSensitive(bool caseSensitive); - void setProjectFilesFlag(bool projectFilesFlag); void start() override; @@ -85,7 +93,9 @@ private: Q_INVOKABLE void slotWork(); - QString m_patternString; + QList m_directoryChoice; + QString m_errorMessage; + QRegExp m_regExp; QString m_regExpSimple; GrepOutputModel *m_outputModel; @@ -101,17 +111,7 @@ int m_fileIndex; QPointer m_findThread; - QString m_errorMessage; - QString m_templateString; - QString m_replacementTemplateString; - QString m_filesString; - QString m_excludeString; - QList m_directoryChoice; - - bool m_useProjectFilesFlag; - bool m_regexpFlag; - bool m_caseSensitiveFlag; - int m_depthValue; + GrepJobSettings m_settings; bool m_findSomething; }; diff --git a/plugins/grepview/grepjob.cpp b/plugins/grepview/grepjob.cpp --- a/plugins/grepview/grepjob.cpp +++ b/plugins/grepview/grepjob.cpp @@ -90,10 +90,6 @@ : KJob( parent ) , m_workState(WorkIdle) , m_fileIndex(0) - , m_useProjectFilesFlag(false) - , m_regexpFlag(true) - , m_caseSensitiveFlag(true) - , m_depthValue(-1) , m_findSomething(false) { setCapabilities(Killable); @@ -134,12 +130,12 @@ return; } - if(!m_regexpFlag) + if(!m_settings.regexp) { - m_patternString = QRegExp::escape(m_patternString); + m_settings.pattern = QRegExp::escape(m_settings.pattern); } - if(m_regexpFlag && QRegExp(m_patternString).captureCount() > 0) + if(m_settings.regexp && QRegExp(m_settings.pattern).captureCount() > 0) { m_workState = WorkIdle; emit hideProgress(this); @@ -151,19 +147,19 @@ return; } - QString pattern = substitudePattern(m_templateString, m_patternString); + QString pattern = substitudePattern(m_settings.searchTemplate, m_settings.pattern); m_regExp.setPattern(pattern); m_regExp.setPatternSyntax(QRegExp::RegExp2); - m_regExp.setCaseSensitivity( m_caseSensitiveFlag ? Qt::CaseSensitive : Qt::CaseInsensitive ); + m_regExp.setCaseSensitivity( m_settings.caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive ); if(pattern == QRegExp::escape(pattern)) { // enable wildcard mode when possible // if pattern has already been escaped (raw text serch) a second escape will result in a different string anyway m_regExp.setPatternSyntax(QRegExp::Wildcard); } m_outputModel->setRegExp(m_regExp); - m_outputModel->setReplacementTemplate(m_replacementTemplateString); + m_outputModel->setReplacementTemplate(m_settings.replacementTemplate); emit showMessage(this, i18np("Searching for %2 in one file", @@ -186,7 +182,7 @@ QMetaObject::invokeMethod(this, "slotWork", Qt::QueuedConnection); break; case WorkCollectFiles: - m_findThread = new GrepFindFilesThread(this, m_directoryChoice, m_depthValue, m_filesString, m_excludeString, m_useProjectFilesFlag); + m_findThread = new GrepFindFilesThread(this, m_directoryChoice, m_settings.depth, m_settings.files, m_settings.exclude, m_settings.projectFilesOnly); emit showMessage(this, i18n("Collecting files...")); connect(m_findThread.data(), &GrepFindFilesThread::finished, this, &GrepJob::slotFindFinished); m_findThread->start(); @@ -279,55 +275,19 @@ m_outputModel = model; } -void GrepJob::setTemplateString(const QString& templateString) -{ - m_templateString = templateString; -} - -void GrepJob::setReplacementTemplateString(const QString &replTmplString) -{ - m_replacementTemplateString = replTmplString; -} - -void GrepJob::setFilesString(const QString& filesString) -{ - m_filesString = filesString; -} - -void GrepJob::setExcludeString(const QString& excludeString) -{ - m_excludeString = excludeString; -} - void GrepJob::setDirectoryChoice(const QList& choice) { m_directoryChoice = choice; } -void GrepJob::setCaseSensitive(bool caseSensitive) -{ - m_caseSensitiveFlag = caseSensitive; -} - -void GrepJob::setDepth(int depth) +void GrepJob::setSettings(const GrepJobSettings& settings) { - m_depthValue = depth; -} + m_settings = settings; -void GrepJob::setRegexpFlag(bool regexpFlag) -{ - m_regexpFlag = regexpFlag; + setObjectName(i18n("Grep: %1", m_settings.pattern)); } -void GrepJob::setProjectFilesFlag(bool projectFilesFlag) +GrepJobSettings GrepJob::settings() const { - m_useProjectFilesFlag = projectFilesFlag; + return m_settings; } - -void GrepJob::setPatternString(const QString& patternString) -{ - m_patternString = patternString; - - setObjectName(i18n("Grep: %1", m_patternString)); -} - diff --git a/plugins/grepview/grepoutputview.h b/plugins/grepview/grepoutputview.h --- a/plugins/grepview/grepoutputview.h +++ b/plugins/grepview/grepoutputview.h @@ -90,6 +90,7 @@ void expandAllItems(); void onApply(); void showDialog(); + void refresh(); void expandElements( const QModelIndex & parent ); void rowsRemoved(); void clearSearchHistory(); diff --git a/plugins/grepview/grepoutputview.cpp b/plugins/grepview/grepoutputview.cpp --- a/plugins/grepview/grepoutputview.cpp +++ b/plugins/grepview/grepoutputview.cpp @@ -84,13 +84,15 @@ separator->setSeparator(true); QAction *newSearchAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-find")), i18n("New &Search"), this); m_clearSearchHistory = new QAction(QIcon::fromTheme(QStringLiteral("edit-clear-list")), i18n("Clear Search History"), this); + QAction *refreshAction = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), i18n("Refresh"), this); addAction(m_prev); addAction(m_next); addAction(m_collapseAll); addAction(m_expandAll); addAction(separator); addAction(newSearchAction); + addAction(refreshAction); addAction(m_clearSearchHistory); separator = new QAction(this); @@ -129,6 +131,8 @@ connect(newSearchAction, &QAction::triggered, this, &GrepOutputView::showDialog); + connect(refreshAction, &QAction::triggered, this, &GrepOutputView::refresh); + resultsTreeView->header()->setStretchLastSection(true); resultsTreeView->header()->setStretchLastSection(true); @@ -274,6 +278,11 @@ m_plugin->showDialog(true); } +void GrepOutputView::refresh() +{ + m_plugin->showDialog(true, QString(), false); +} + void GrepOutputView::expandElements(const QModelIndex& index) { m_prev->setEnabled(true); diff --git a/plugins/grepview/grepviewplugin.cpp b/plugins/grepview/grepviewplugin.cpp --- a/plugins/grepview/grepviewplugin.cpp +++ b/plugins/grepview/grepviewplugin.cpp @@ -163,17 +163,20 @@ void GrepViewPlugin::showDialog(bool setLastUsed, QString pattern, bool show) { GrepDialog* dlg = new GrepDialog( this, core()->uiController()->activeMainWindow() ); + GrepJobSettings dlgSettings = dlg->settings(); KDevelop::IDocument* doc = core()->documentController()->activeDocument(); if(!pattern.isEmpty()) { - dlg->setPattern(pattern); + dlgSettings.pattern = pattern; + dlg->setSettings(dlgSettings); } else if(!setLastUsed) { QString pattern = patternFromSelection(doc); if (!pattern.isEmpty()) { - dlg->setPattern( pattern ); + dlgSettings.pattern = pattern; + dlg->setSettings(dlgSettings); } } diff --git a/plugins/grepview/tests/test_findreplace.cpp b/plugins/grepview/tests/test_findreplace.cpp --- a/plugins/grepview/tests/test_findreplace.cpp +++ b/plugins/grepview/tests/test_findreplace.cpp @@ -162,18 +162,23 @@ GrepJob *job = new GrepJob(this); GrepOutputModel *model = new GrepOutputModel(job); + GrepJobSettings settings; job->setOutputModel(model); - job->setPatternString(searchPattern); - job->setTemplateString(searchTemplate); - job->setReplacementTemplateString(replaceTemplate); - job->setFilesString(QStringLiteral("*")); - job->setExcludeString(QString()); job->setDirectoryChoice(QList() << QUrl::fromLocalFile(dir.path())); - job->setDepth(-1); // fully recursive - job->setRegexpFlag(true); - job->setCaseSensitive(true); - job->setProjectFilesFlag(false); + + settings.projectFilesOnly = false; + settings.caseSensitive = true; + settings.regexp = true; + settings.depth = -1; // fully recursive + settings.pattern = searchPattern; + settings.searchTemplate = searchTemplate; + settings.replacementTemplate = replaceTemplate; + settings.files = QStringLiteral("*"); + settings.exclude = QString(); + + job->setSettings(settings); + QVERIFY(job->exec()); QVERIFY(model->hasResults());