Fixed #2758 ([GUI] Provide a means to filter results based on a search string)

This commit is contained in:
Zachary Blair 2011-05-03 22:30:54 -07:00
parent fb290a7197
commit 79370258df
8 changed files with 149 additions and 4 deletions

View File

@ -57,6 +57,7 @@ ShowTypes;
#define SETTINGS_RESULT_COLUMN_WIDTH "Result column %1 width" #define SETTINGS_RESULT_COLUMN_WIDTH "Result column %1 width"
#define SETTINGS_TOOLBARS_MAIN_SHOW "Toolbars/ShowStandard" #define SETTINGS_TOOLBARS_MAIN_SHOW "Toolbars/ShowStandard"
#define SETTINGS_TOOLBARS_VIEW_SHOW "Toolbars/ShowView" #define SETTINGS_TOOLBARS_VIEW_SHOW "Toolbars/ShowView"
#define SETTINGS_TOOLBARS_FILTER_SHOW "Toolbars/ShowFilter"
// Show * states // Show * states
#define SETTINGS_SHOW_STYLE "Show style" #define SETTINGS_SHOW_STYLE "Show style"

View File

@ -66,7 +66,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>640</width> <width>640</width>
<height>21</height> <height>28</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="mMenuFile"> <widget class="QMenu" name="mMenuFile">
@ -93,6 +93,7 @@
</property> </property>
<addaction name="mActionToolBarMain"/> <addaction name="mActionToolBarMain"/>
<addaction name="mActionToolBarView"/> <addaction name="mActionToolBarView"/>
<addaction name="mActionToolBarFilter"/>
</widget> </widget>
<addaction name="mMenuToolbars"/> <addaction name="mMenuToolbars"/>
<addaction name="separator"/> <addaction name="separator"/>
@ -181,6 +182,17 @@
<addaction name="mActionShowPerformance"/> <addaction name="mActionShowPerformance"/>
<addaction name="mActionShowInformation"/> <addaction name="mActionShowInformation"/>
</widget> </widget>
<widget class="QToolBar" name="mToolBarFilter">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<action name="mActionLicense"> <action name="mActionLicense">
<property name="text"> <property name="text">
<string>&amp;License...</string> <string>&amp;License...</string>
@ -517,6 +529,17 @@
<string>Show portability warnings</string> <string>Show portability warnings</string>
</property> </property>
</action> </action>
<action name="mActionToolBarFilter">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Filter</string>
</property>
<property name="toolTip">
<string>Filter results</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -55,6 +55,19 @@ MainWindow::MainWindow() :
mThread = new ThreadHandler(this); mThread = new ThreadHandler(this);
mLogView = new LogView(mSettings); 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.mActionQuit, SIGNAL(triggered()), this, SLOT(close()));
connect(mUI.mActionCheckFiles, SIGNAL(triggered()), this, SLOT(CheckFiles())); connect(mUI.mActionCheckFiles, SIGNAL(triggered()), this, SLOT(CheckFiles()));
connect(mUI.mActionCheckDirectory, SIGNAL(triggered()), this, SLOT(CheckDirectory())); connect(mUI.mActionCheckDirectory, SIGNAL(triggered()), this, SLOT(CheckDirectory()));
@ -81,10 +94,14 @@ MainWindow::MainWindow() :
connect(mUI.mActionStop, SIGNAL(triggered()), this, SLOT(StopChecking())); connect(mUI.mActionStop, SIGNAL(triggered()), this, SLOT(StopChecking()));
connect(mUI.mActionSave, SIGNAL(triggered()), this, SLOT(Save())); connect(mUI.mActionSave, SIGNAL(triggered()), this, SLOT(Save()));
// About menu
connect(mUI.mActionAbout, SIGNAL(triggered()), this, SLOT(About())); connect(mUI.mActionAbout, SIGNAL(triggered()), this, SLOT(About()));
connect(mUI.mActionLicense, SIGNAL(triggered()), this, SLOT(ShowLicense())); connect(mUI.mActionLicense, SIGNAL(triggered()), this, SLOT(ShowLicense()));
// View > Toolbar menu
connect(mUI.mActionToolBarMain, SIGNAL(toggled(bool)), this, SLOT(ToggleMainToolBar())); connect(mUI.mActionToolBarMain, SIGNAL(toggled(bool)), this, SLOT(ToggleMainToolBar()));
connect(mUI.mActionToolBarView, SIGNAL(toggled(bool)), this, SLOT(ToggleViewToolBar())); 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(mUI.mActionAuthors, SIGNAL(triggered()), this, SLOT(ShowAuthors()));
connect(mThread, SIGNAL(Done()), this, SLOT(CheckDone())); 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.mResults, SIGNAL(ResultsHidden(bool)), mUI.mActionShowHidden, SLOT(setEnabled(bool)));
connect(mUI.mMenuView, SIGNAL(aboutToShow()), this, SLOT(AboutToShowViewMenu())); connect(mUI.mMenuView, SIGNAL(aboutToShow()), this, SLOT(AboutToShowViewMenu()));
// File menu
connect(mUI.mActionNewProjectFile, SIGNAL(triggered()), this, SLOT(NewProjectFile())); connect(mUI.mActionNewProjectFile, SIGNAL(triggered()), this, SLOT(NewProjectFile()));
connect(mUI.mActionOpenProjectFile, SIGNAL(triggered()), this, SLOT(OpenProjectFile())); connect(mUI.mActionOpenProjectFile, SIGNAL(triggered()), this, SLOT(OpenProjectFile()));
connect(mUI.mActionCloseProjectFile, SIGNAL(triggered()), this, SLOT(CloseProjectFile())); connect(mUI.mActionCloseProjectFile, SIGNAL(triggered()), this, SLOT(CloseProjectFile()));
@ -144,6 +162,7 @@ void MainWindow::HandleCLIParams(const QStringList &params)
void MainWindow::LoadSettings() void MainWindow::LoadSettings()
{ {
// Window/dialog sizes
if (mSettings->value(SETTINGS_WINDOW_MAXIMIZED, false).toBool()) if (mSettings->value(SETTINGS_WINDOW_MAXIMIZED, false).toBool())
{ {
showMaximized(); showMaximized();
@ -154,6 +173,7 @@ void MainWindow::LoadSettings()
mSettings->value(SETTINGS_WINDOW_HEIGHT, 600).toInt()); mSettings->value(SETTINGS_WINDOW_HEIGHT, 600).toInt());
} }
// Show * states
mUI.mActionShowStyle->setChecked(mSettings->value(SETTINGS_SHOW_STYLE, true).toBool()); mUI.mActionShowStyle->setChecked(mSettings->value(SETTINGS_SHOW_STYLE, true).toBool());
mUI.mActionShowErrors->setChecked(mSettings->value(SETTINGS_SHOW_ERRORS, true).toBool()); mUI.mActionShowErrors->setChecked(mSettings->value(SETTINGS_SHOW_ERRORS, true).toBool());
mUI.mActionShowWarnings->setChecked(mSettings->value(SETTINGS_SHOW_WARNINGS, 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_ERRORS, mUI.mActionShowErrors->isChecked());
mUI.mResults->ShowResults(SHOW_STYLE, mUI.mActionShowStyle->isChecked()); mUI.mResults->ShowResults(SHOW_STYLE, mUI.mActionShowStyle->isChecked());
mUI.mActionToolBarMain->setChecked(mSettings->value(SETTINGS_TOOLBARS_MAIN_SHOW, true).toBool()); // Main window settings
mUI.mToolBarMain->setVisible(mSettings->value(SETTINGS_TOOLBARS_MAIN_SHOW, true).toBool()); const bool showMainToolbar = mSettings->value(SETTINGS_TOOLBARS_MAIN_SHOW, true).toBool();
mUI.mToolBarView->setVisible(mSettings->value(SETTINGS_TOOLBARS_VIEW_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()); SetLanguage(mSettings->value(SETTINGS_LANGUAGE, mTranslation->SuggestLanguage()).toString());
@ -193,18 +222,23 @@ void MainWindow::SaveSettings()
//Force toolbar checkbox value to be updated //Force toolbar checkbox value to be updated
AboutToShowViewMenu(); AboutToShowViewMenu();
// Window/dialog sizes
mSettings->setValue(SETTINGS_WINDOW_WIDTH, size().width()); mSettings->setValue(SETTINGS_WINDOW_WIDTH, size().width());
mSettings->setValue(SETTINGS_WINDOW_HEIGHT, size().height()); mSettings->setValue(SETTINGS_WINDOW_HEIGHT, size().height());
mSettings->setValue(SETTINGS_WINDOW_MAXIMIZED, isMaximized()); mSettings->setValue(SETTINGS_WINDOW_MAXIMIZED, isMaximized());
// Show * states
mSettings->setValue(SETTINGS_SHOW_STYLE, mUI.mActionShowStyle->isChecked()); mSettings->setValue(SETTINGS_SHOW_STYLE, mUI.mActionShowStyle->isChecked());
mSettings->setValue(SETTINGS_SHOW_ERRORS, mUI.mActionShowErrors->isChecked()); mSettings->setValue(SETTINGS_SHOW_ERRORS, mUI.mActionShowErrors->isChecked());
mSettings->setValue(SETTINGS_SHOW_WARNINGS, mUI.mActionShowWarnings->isChecked()); mSettings->setValue(SETTINGS_SHOW_WARNINGS, mUI.mActionShowWarnings->isChecked());
mSettings->setValue(SETTINGS_SHOW_PORTABILITY, mUI.mActionShowPortability->isChecked()); mSettings->setValue(SETTINGS_SHOW_PORTABILITY, mUI.mActionShowPortability->isChecked());
mSettings->setValue(SETTINGS_SHOW_PERFORMANCE, mUI.mActionShowPerformance->isChecked()); mSettings->setValue(SETTINGS_SHOW_PERFORMANCE, mUI.mActionShowPerformance->isChecked());
mSettings->setValue(SETTINGS_SHOW_INFORMATION, mUI.mActionShowInformation->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_MAIN_SHOW, mUI.mToolBarMain->isVisible());
mSettings->setValue(SETTINGS_TOOLBARS_VIEW_SHOW, mUI.mToolBarView->isVisible()); mSettings->setValue(SETTINGS_TOOLBARS_VIEW_SHOW, mUI.mToolBarView->isVisible());
mSettings->setValue(SETTINGS_TOOLBARS_FILTER_SHOW, mUI.mToolBarFilter->isVisible());
mApplications->SaveSettings(mSettings); mApplications->SaveSettings(mSettings);
@ -675,6 +709,12 @@ void MainWindow::ToggleViewToolBar()
mUI.mToolBarView->setVisible(mUI.mActionToolBarView->isChecked()); 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) void MainWindow::FormatAndSetTitle(const QString &text)
{ {
QString title; 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) void MainWindow::EnableProjectActions(bool enable)
{ {
mUI.mActionCloseProjectFile->setEnabled(enable); mUI.mActionCloseProjectFile->setEnabled(enable);

View File

@ -24,6 +24,7 @@
#include <QFileDialog> #include <QFileDialog>
#include <QSignalMapper> #include <QSignalMapper>
#include <QActionGroup> #include <QActionGroup>
#include <QTimer>
#include <QToolBar> #include <QToolBar>
#include <QStringList> #include <QStringList>
@ -228,6 +229,11 @@ protected slots:
*/ */
void ToggleViewToolBar(); void ToggleViewToolBar();
/**
* @brief Slot for showing/hiding Filter toolbar
*/
void ToggleFilterToolBar();
/** /**
* @brief Slot for updating View-menu before it is shown. * @brief Slot for updating View-menu before it is shown.
*/ */
@ -257,6 +263,12 @@ protected slots:
*/ */
void DebugError(const ErrorItem &item); void DebugError(const ErrorItem &item);
/**
* @brief Filters the results in the result list.
*/
void FilterResults();
protected: protected:
/** /**
@ -417,6 +429,16 @@ protected:
*/ */
Project *mProject; Project *mProject;
/**
* @brief Filter field in the Filter toolbar.
*/
QLineEdit* mLineEditFilter;
/**
* @brief Timer to delay filtering while typing.
*/
QTimer* mFilterTimer;
private: private:
/** /**

View File

@ -112,6 +112,18 @@ void ResultsTree::AddErrorItem(const ErrorItem &item)
bool hide = !mShowTypes[SeverityToShowType(item.severity)]; 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 there is at least one error that is not hidden, we have a visible error
if (!hide) 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() void ResultsTree::ShowHiddenResults()
{ {
//Clear the "hide" flag for each item //Clear the "hide" flag for each item
@ -480,6 +498,18 @@ void ResultsTree::RefreshTree()
//Check if this error should be hidden //Check if this error should be hidden
bool hide = (data["hide"].toBool() || !mShowTypes[VariantToShowType(data["severity"])]); 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) if (!hide)
{ {
mVisibleErrors = true; mVisibleErrors = true;

View File

@ -75,6 +75,14 @@ public:
*/ */
void ShowResults(ShowTypes type, bool show); 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() * @brief Function to show results that were previous hidden with HideResult()
*/ */
@ -378,6 +386,12 @@ protected:
*/ */
bool mShowTypes[SHOW_NONE]; bool mShowTypes[SHOW_NONE];
/**
* @brief A string used to filter the results for display.
*
*/
QString mFilter;
/** /**
* @brief List of applications to open errors with * @brief List of applications to open errors with
* *

View File

@ -111,6 +111,11 @@ void ResultsView::ShowHiddenResults()
mUI.mTree->ShowHiddenResults(); mUI.mTree->ShowHiddenResults();
} }
void ResultsView::FilterResults(const QString& filter)
{
mUI.mTree->FilterResults(filter);
}
void ResultsView::Save(const QString &filename, Report::Type type) void ResultsView::Save(const QString &filename, Report::Type type)
{ {
if (!mErrorsFound) if (!mErrorsFound)

View File

@ -193,6 +193,11 @@ public slots:
*/ */
void ExpandAllResults(); void ExpandAllResults();
/**
* @brief Filters the results in the result list.
*/
void FilterResults(const QString& filter);
/** /**
* @brief Show hidden results in the result list. * @brief Show hidden results in the result list.
*/ */