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
@@ -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.
*/