diff --git a/gui/common.h b/gui/common.h index 903eefe1d..116be8687 100644 --- a/gui/common.h +++ b/gui/common.h @@ -57,6 +57,7 @@ ShowTypes; #define SETTINGS_RESULT_COLUMN_WIDTH "Result column %1 width" #define SETTINGS_TOOLBARS_MAIN_SHOW "Toolbars/ShowStandard" #define SETTINGS_TOOLBARS_VIEW_SHOW "Toolbars/ShowView" +#define SETTINGS_TOOLBARS_FILTER_SHOW "Toolbars/ShowFilter" // Show * states #define SETTINGS_SHOW_STYLE "Show style" diff --git a/gui/main.ui b/gui/main.ui index 8ed52ff5c..c1456f70b 100644 --- a/gui/main.ui +++ b/gui/main.ui @@ -66,7 +66,7 @@ 0 0 640 - 21 + 28 @@ -93,6 +93,7 @@ + @@ -181,6 +182,17 @@ + + + toolBar + + + TopToolBarArea + + + false + + &License... @@ -517,6 +529,17 @@ Show portability warnings + + + true + + + &Filter + + + Filter results + + diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 76b4cc281..4ece1ffb5 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -55,6 +55,19 @@ MainWindow::MainWindow() : mThread = new ThreadHandler(this); mLogView = new LogView(mSettings); + // Filter timer to delay filtering results slightly while typing + mFilterTimer = new QTimer(this); + mFilterTimer->setInterval(500); + mFilterTimer->setSingleShot(true); + connect(mFilterTimer, SIGNAL(timeout()), this, SLOT(FilterResults())); + + // "Filter" toolbar + mLineEditFilter = new QLineEdit(mUI.mToolBarFilter); + mLineEditFilter->setPlaceholderText(tr("Quick Filter:")); + mUI.mToolBarFilter->addWidget(mLineEditFilter); + connect(mLineEditFilter, SIGNAL(textChanged(const QString&)), mFilterTimer, SLOT(start())); + connect(mLineEditFilter, SIGNAL(returnPressed()), this, SLOT(FilterResults())); + connect(mUI.mActionQuit, SIGNAL(triggered()), this, SLOT(close())); connect(mUI.mActionCheckFiles, SIGNAL(triggered()), this, SLOT(CheckFiles())); connect(mUI.mActionCheckDirectory, SIGNAL(triggered()), this, SLOT(CheckDirectory())); @@ -81,10 +94,14 @@ MainWindow::MainWindow() : connect(mUI.mActionStop, SIGNAL(triggered()), this, SLOT(StopChecking())); connect(mUI.mActionSave, SIGNAL(triggered()), this, SLOT(Save())); + // About menu connect(mUI.mActionAbout, SIGNAL(triggered()), this, SLOT(About())); connect(mUI.mActionLicense, SIGNAL(triggered()), this, SLOT(ShowLicense())); + + // View > Toolbar menu connect(mUI.mActionToolBarMain, SIGNAL(toggled(bool)), this, SLOT(ToggleMainToolBar())); connect(mUI.mActionToolBarView, SIGNAL(toggled(bool)), this, SLOT(ToggleViewToolBar())); + connect(mUI.mActionToolBarFilter, SIGNAL(toggled(bool)), this, SLOT(ToggleFilterToolBar())); connect(mUI.mActionAuthors, SIGNAL(triggered()), this, SLOT(ShowAuthors())); connect(mThread, SIGNAL(Done()), this, SLOT(CheckDone())); @@ -92,6 +109,7 @@ MainWindow::MainWindow() : connect(mUI.mResults, SIGNAL(ResultsHidden(bool)), mUI.mActionShowHidden, SLOT(setEnabled(bool))); connect(mUI.mMenuView, SIGNAL(aboutToShow()), this, SLOT(AboutToShowViewMenu())); + // File menu connect(mUI.mActionNewProjectFile, SIGNAL(triggered()), this, SLOT(NewProjectFile())); connect(mUI.mActionOpenProjectFile, SIGNAL(triggered()), this, SLOT(OpenProjectFile())); connect(mUI.mActionCloseProjectFile, SIGNAL(triggered()), this, SLOT(CloseProjectFile())); @@ -144,6 +162,7 @@ void MainWindow::HandleCLIParams(const QStringList ¶ms) void MainWindow::LoadSettings() { + // Window/dialog sizes if (mSettings->value(SETTINGS_WINDOW_MAXIMIZED, false).toBool()) { showMaximized(); @@ -154,6 +173,7 @@ void MainWindow::LoadSettings() mSettings->value(SETTINGS_WINDOW_HEIGHT, 600).toInt()); } + // Show * states mUI.mActionShowStyle->setChecked(mSettings->value(SETTINGS_SHOW_STYLE, true).toBool()); mUI.mActionShowErrors->setChecked(mSettings->value(SETTINGS_SHOW_ERRORS, true).toBool()); mUI.mActionShowWarnings->setChecked(mSettings->value(SETTINGS_SHOW_WARNINGS, true).toBool()); @@ -164,9 +184,18 @@ void MainWindow::LoadSettings() mUI.mResults->ShowResults(SHOW_ERRORS, mUI.mActionShowErrors->isChecked()); mUI.mResults->ShowResults(SHOW_STYLE, mUI.mActionShowStyle->isChecked()); - mUI.mActionToolBarMain->setChecked(mSettings->value(SETTINGS_TOOLBARS_MAIN_SHOW, true).toBool()); - mUI.mToolBarMain->setVisible(mSettings->value(SETTINGS_TOOLBARS_MAIN_SHOW, true).toBool()); - mUI.mToolBarView->setVisible(mSettings->value(SETTINGS_TOOLBARS_VIEW_SHOW, true).toBool()); + // Main window settings + const bool showMainToolbar = mSettings->value(SETTINGS_TOOLBARS_MAIN_SHOW, true).toBool(); + mUI.mActionToolBarMain->setChecked(showMainToolbar); + mUI.mToolBarMain->setVisible(showMainToolbar); + + const bool showViewToolbar = mSettings->value(SETTINGS_TOOLBARS_VIEW_SHOW, true).toBool(); + mUI.mActionToolBarView->setChecked(showViewToolbar); + mUI.mToolBarView->setVisible(showViewToolbar); + + const bool showFilterToolbar = mSettings->value(SETTINGS_TOOLBARS_FILTER_SHOW, true).toBool(); + mUI.mActionToolBarFilter->setChecked(showFilterToolbar); + mUI.mToolBarFilter->setVisible(showFilterToolbar); SetLanguage(mSettings->value(SETTINGS_LANGUAGE, mTranslation->SuggestLanguage()).toString()); @@ -193,18 +222,23 @@ void MainWindow::SaveSettings() //Force toolbar checkbox value to be updated AboutToShowViewMenu(); + // Window/dialog sizes mSettings->setValue(SETTINGS_WINDOW_WIDTH, size().width()); mSettings->setValue(SETTINGS_WINDOW_HEIGHT, size().height()); mSettings->setValue(SETTINGS_WINDOW_MAXIMIZED, isMaximized()); + // Show * states mSettings->setValue(SETTINGS_SHOW_STYLE, mUI.mActionShowStyle->isChecked()); mSettings->setValue(SETTINGS_SHOW_ERRORS, mUI.mActionShowErrors->isChecked()); mSettings->setValue(SETTINGS_SHOW_WARNINGS, mUI.mActionShowWarnings->isChecked()); mSettings->setValue(SETTINGS_SHOW_PORTABILITY, mUI.mActionShowPortability->isChecked()); mSettings->setValue(SETTINGS_SHOW_PERFORMANCE, mUI.mActionShowPerformance->isChecked()); mSettings->setValue(SETTINGS_SHOW_INFORMATION, mUI.mActionShowInformation->isChecked()); + + // Main window settings mSettings->setValue(SETTINGS_TOOLBARS_MAIN_SHOW, mUI.mToolBarMain->isVisible()); mSettings->setValue(SETTINGS_TOOLBARS_VIEW_SHOW, mUI.mToolBarView->isVisible()); + mSettings->setValue(SETTINGS_TOOLBARS_FILTER_SHOW, mUI.mToolBarFilter->isVisible()); mApplications->SaveSettings(mSettings); @@ -675,6 +709,12 @@ void MainWindow::ToggleViewToolBar() mUI.mToolBarView->setVisible(mUI.mActionToolBarView->isChecked()); } +void MainWindow::ToggleFilterToolBar() +{ + mUI.mToolBarFilter->setVisible(mUI.mActionToolBarFilter->isChecked()); + mLineEditFilter->clear(); // Clearing the filter also disables filtering +} + void MainWindow::FormatAndSetTitle(const QString &text) { QString title; @@ -875,6 +915,11 @@ void MainWindow::DebugError(const ErrorItem &item) } } +void MainWindow::FilterResults() +{ + mUI.mResults->FilterResults(mLineEditFilter->text()); +} + void MainWindow::EnableProjectActions(bool enable) { mUI.mActionCloseProjectFile->setEnabled(enable); diff --git a/gui/mainwindow.h b/gui/mainwindow.h index c316f5970..a4d88ec38 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -228,6 +229,11 @@ protected slots: */ void ToggleViewToolBar(); + /** + * @brief Slot for showing/hiding Filter toolbar + */ + void ToggleFilterToolBar(); + /** * @brief Slot for updating View-menu before it is shown. */ @@ -257,6 +263,12 @@ protected slots: */ void DebugError(const ErrorItem &item); + /** + * @brief Filters the results in the result list. + */ + void FilterResults(); + + protected: /** @@ -417,6 +429,16 @@ protected: */ Project *mProject; + /** + * @brief Filter field in the Filter toolbar. + */ + QLineEdit* mLineEditFilter; + + /** + * @brief Timer to delay filtering while typing. + */ + QTimer* mFilterTimer; + private: /** diff --git a/gui/resultstree.cpp b/gui/resultstree.cpp index f201792e2..7f0c4d263 100644 --- a/gui/resultstree.cpp +++ b/gui/resultstree.cpp @@ -112,6 +112,18 @@ void ResultsTree::AddErrorItem(const ErrorItem &item) bool hide = !mShowTypes[SeverityToShowType(item.severity)]; + //If specified, filter on summary, message, filename, and id + if (!hide && !mFilter.isEmpty()) + { + if (!item.summary.contains(mFilter, Qt::CaseInsensitive) && + !item.message.contains(mFilter, Qt::CaseInsensitive) && + !item.file.contains(mFilter, Qt::CaseInsensitive) && + !item.id.contains(mFilter, Qt::CaseInsensitive)) + { + hide = true; + } + } + //if there is at least one error that is not hidden, we have a visible error if (!hide) { @@ -411,6 +423,12 @@ void ResultsTree::ShowResults(ShowTypes type, bool show) } } +void ResultsTree::FilterResults(const QString& filter) +{ + mFilter = filter; + RefreshTree(); +} + void ResultsTree::ShowHiddenResults() { //Clear the "hide" flag for each item @@ -480,6 +498,18 @@ void ResultsTree::RefreshTree() //Check if this error should be hidden bool hide = (data["hide"].toBool() || !mShowTypes[VariantToShowType(data["severity"])]); + //If specified, filter on summary, message, filename, and id + if (!hide && !mFilter.isEmpty()) + { + if (!data["summary"].toString().contains(mFilter, Qt::CaseInsensitive) && + !data["message"].toString().contains(mFilter, Qt::CaseInsensitive) && + !data["file"].toString().contains(mFilter, Qt::CaseInsensitive) && + !data["id"].toString().contains(mFilter, Qt::CaseInsensitive)) + { + hide = true; + } + } + if (!hide) { mVisibleErrors = true; diff --git a/gui/resultstree.h b/gui/resultstree.h index cc5f1b03d..7cee9917c 100644 --- a/gui/resultstree.h +++ b/gui/resultstree.h @@ -75,6 +75,14 @@ public: */ void ShowResults(ShowTypes type, bool show); + /** + * @brief Function to filter the displayed list of errors. + * Refreshes the tree. + * + * @param filter String that must be found in the summary, description, file or id + */ + void FilterResults(const QString& filter); + /** * @brief Function to show results that were previous hidden with HideResult() */ @@ -378,6 +386,12 @@ protected: */ bool mShowTypes[SHOW_NONE]; + /** + * @brief A string used to filter the results for display. + * + */ + QString mFilter; + /** * @brief List of applications to open errors with * diff --git a/gui/resultsview.cpp b/gui/resultsview.cpp index 1d4f90568..3641a646e 100644 --- a/gui/resultsview.cpp +++ b/gui/resultsview.cpp @@ -111,6 +111,11 @@ void ResultsView::ShowHiddenResults() mUI.mTree->ShowHiddenResults(); } +void ResultsView::FilterResults(const QString& filter) +{ + mUI.mTree->FilterResults(filter); +} + void ResultsView::Save(const QString &filename, Report::Type type) { if (!mErrorsFound) diff --git a/gui/resultsview.h b/gui/resultsview.h index 69973a07d..fd5425872 100644 --- a/gui/resultsview.h +++ b/gui/resultsview.h @@ -193,6 +193,11 @@ public slots: */ void ExpandAllResults(); + /** + * @brief Filters the results in the result list. + */ + void FilterResults(const QString& filter); + /** * @brief Show hidden results in the result list. */