Results tree now uses only QStandardItemModel for data storage.

Items are now hidden from the tree and the tree is not recreated everytime it is refreshed.
Also added test.cpp as a sample data for GUI testing.
Added Check all and uncheck all buttons to menu to show/hide all errors more easily.
This commit is contained in:
Vesa Pikki 2009-05-23 11:17:27 +03:00
parent 63000e57d1
commit f0a26b3ffe
11 changed files with 243 additions and 59 deletions

View File

@ -23,7 +23,7 @@
typedef enum typedef enum
{ {
SHOW_ALL, SHOW_ALL = 0,
SHOW_STYLE, SHOW_STYLE,
SHOW_SECURITY, SHOW_SECURITY,
SHOW_UNUSED, SHOW_UNUSED,

View File

@ -39,6 +39,8 @@ MainWindow::MainWindow() :
mActionShowStyle(tr("Show s&tyle errors"), this), mActionShowStyle(tr("Show s&tyle errors"), this),
mActionShowUnused(tr("Show errors on &unused functions"), this), mActionShowUnused(tr("Show errors on &unused functions"), this),
mActionShowErrors(tr("Show &common errors"), this), mActionShowErrors(tr("Show &common errors"), this),
mActionShowCheckAll(tr("Check all"), this),
mActionShowUncheckAll(tr("Uncheck all"), this),
mResults(mSettings) mResults(mSettings)
{ {
QMenu *menu = menuBar()->addMenu(tr("&File")); QMenu *menu = menuBar()->addMenu(tr("&File"));
@ -61,6 +63,8 @@ MainWindow::MainWindow() :
menuview->addAction(&mActionShowStyle); menuview->addAction(&mActionShowStyle);
menuview->addAction(&mActionShowUnused); menuview->addAction(&mActionShowUnused);
menuview->addAction(&mActionShowErrors); menuview->addAction(&mActionShowErrors);
menuview->addAction(&mActionShowCheckAll);
menuview->addAction(&mActionShowUncheckAll);
QMenu *menuprogram = menuBar()->addMenu(tr("&Program")); QMenu *menuprogram = menuBar()->addMenu(tr("&Program"));
menuprogram->addAction(&mActionSettings); menuprogram->addAction(&mActionSettings);
@ -79,6 +83,8 @@ MainWindow::MainWindow() :
connect(&mActionShowStyle, SIGNAL(toggled(bool)), this, SLOT(ShowStyle(bool))); connect(&mActionShowStyle, SIGNAL(toggled(bool)), this, SLOT(ShowStyle(bool)));
connect(&mActionShowUnused, SIGNAL(toggled(bool)), this, SLOT(ShowUnused(bool))); connect(&mActionShowUnused, SIGNAL(toggled(bool)), this, SLOT(ShowUnused(bool)));
connect(&mActionShowErrors, SIGNAL(toggled(bool)), this, SLOT(ShowErrors(bool))); connect(&mActionShowErrors, SIGNAL(toggled(bool)), this, SLOT(ShowErrors(bool)));
connect(&mActionShowCheckAll, SIGNAL(triggered()), this, SLOT(CheckAll()));
connect(&mActionShowUncheckAll, SIGNAL(triggered()), this, SLOT(UncheckAll()));
connect(&mActionReCheck, SIGNAL(triggered()), this, SLOT(ReCheck())); connect(&mActionReCheck, SIGNAL(triggered()), this, SLOT(ReCheck()));
connect(&mThread, SIGNAL(Done()), this, SLOT(CheckDone())); connect(&mThread, SIGNAL(Done()), this, SLOT(CheckDone()));
@ -293,3 +299,31 @@ void MainWindow::ShowErrors(bool checked)
{ {
mResults.ShowResults(SHOW_ERRORS, checked); mResults.ShowResults(SHOW_ERRORS, checked);
} }
void MainWindow::CheckAll()
{
ToggleAllChecked(true);
}
void MainWindow::UncheckAll()
{
ToggleAllChecked(false);
}
void MainWindow::ToggleAllChecked(bool checked)
{
mActionShowAll.setChecked(checked);
ShowAll(checked);
mActionShowSecurity.setChecked(checked);
ShowSecurity(checked);
mActionShowStyle.setChecked(checked);
ShowStyle(checked);
mActionShowUnused.setChecked(checked);
ShowUnused(checked);
mActionShowErrors.setChecked(checked);
ShowErrors(checked);
}

View File

@ -57,6 +57,8 @@ public slots:
void ShowStyle(bool checked); void ShowStyle(bool checked);
void ShowUnused(bool checked); void ShowUnused(bool checked);
void ShowErrors(bool checked); void ShowErrors(bool checked);
void CheckAll();
void UncheckAll();
/** /**
* @brief Slot for check directory menu item * @brief Slot for check directory menu item
@ -74,6 +76,7 @@ protected slots:
*/ */
void CheckDone(); void CheckDone();
protected: protected:
void ToggleAllChecked(bool checked);
void EnableCheckButtons(bool enable); void EnableCheckButtons(bool enable);
void DoCheckFiles(QFileDialog::FileMode mode); void DoCheckFiles(QFileDialog::FileMode mode);
QStringList GetFilesRecursively(const QString &path); QStringList GetFilesRecursively(const QString &path);
@ -141,6 +144,8 @@ protected:
QAction mActionShowStyle; QAction mActionShowStyle;
QAction mActionShowUnused; QAction mActionShowUnused;
QAction mActionShowErrors; QAction mActionShowErrors;
QAction mActionShowCheckAll;
QAction mActionShowUncheckAll;

View File

@ -26,7 +26,7 @@ ResultsTree::ResultsTree(QSettings &settings) :
{ {
setModel(&mModel); setModel(&mModel);
QStringList labels; QStringList labels;
labels << tr("severity") << tr("Line") << tr("Message"); labels <<tr("File")<< tr("Severity") << tr("Line") << tr("Message");
mModel.setHorizontalHeaderLabels(labels); mModel.setHorizontalHeaderLabels(labels);
LoadSettings(); LoadSettings();
@ -51,30 +51,91 @@ void ResultsTree::AddErrorItem(const QString &file,
const QString &severity, const QString &severity,
const QString &message, const QString &message,
const QStringList &files, const QStringList &files,
const QList<int> &lines) const QVariantList &lines)
{ {
Q_UNUSED(file); Q_UNUSED(file);
if (files.isEmpty()) if (files.isEmpty())
{
return; return;
}
QString realfile = files[0]; QString realfile = files[0];
if (realfile.isEmpty()) if (realfile.isEmpty())
realfile = "Undefined file";
ErrorItem item;
item.file = realfile;
item.type = SeverityToShowType(severity);
item.message = message;
item.files = files;
item.lines = lines;
mItems << item;
if (mShowTypes[item.type])
{ {
AddItem(mItems.size() - 1); realfile = "Undefined file";
} }
//Create the base item for the error and ensure it has a proper
//file item as a parent
QStandardItem *item = AddBacktraceFiles(EnsureFileItem(realfile),
realfile,
lines[0].toInt(),
severity,
message);
//Add user data to that item
QMap<QString, QVariant> data;
data["severity"] = SeverityToShowType(severity);
data["message"] = message;
data["files"] = files;
data["lines"] = lines;
item->setData(QVariant(data));
//Add backtrace files as children
for (int i=1;i<files.size() && i < lines.size();i++)
{
AddBacktraceFiles(item,files[i],lines[i].toInt(),severity,message);
}
//TODO just hide/show current error and it's file
//since this does a lot of unnecessary work
RefreshTree();
}
QStandardItem *ResultsTree::AddBacktraceFiles(QStandardItem *parent,
const QString &file,
const int line,
const QString &severity,
const QString &message)
{
QList<QStandardItem*> list;
list << CreateItem(file);
list << CreateItem(severity);
list << CreateItem(QString("%1").arg(line));
list << CreateItem(message);
if (parent)
{
parent->appendRow(list);
}
else
{
mModel.appendRow(list);
}
//TODO Does this leak memory? Should items from list be deleted?
return list[0];
}
ShowTypes ResultsTree::VariantToShowType(const QVariant &data)
{
int value = data.toInt();
if (value < SHOW_ALL && value > SHOW_ERRORS)
{
return SHOW_NONE;
}
return (ShowTypes)value;
} }
ShowTypes ResultsTree::SeverityToShowType(const QString & severity) ShowTypes ResultsTree::SeverityToShowType(const QString & severity)
@ -95,14 +156,15 @@ QStandardItem *ResultsTree::FindFileItem(const QString &name)
{ {
QList<QStandardItem *> list = mModel.findItems(name); QList<QStandardItem *> list = mModel.findItems(name);
if (list.size() > 0) if (list.size() > 0)
{
return list[0]; return list[0];
}
return 0; return 0;
} }
void ResultsTree::Clear() void ResultsTree::Clear()
{ {
mModel.removeRows(0, mModel.rowCount()); mModel.removeRows(0, mModel.rowCount());
mItems.clear();
} }
void ResultsTree::LoadSettings() void ResultsTree::LoadSettings()
@ -126,26 +188,64 @@ void ResultsTree::SaveSettings()
void ResultsTree::ShowResults(ShowTypes type, bool show) void ResultsTree::ShowResults(ShowTypes type, bool show)
{ {
if (type != SHOW_NONE) if (type != SHOW_NONE && mShowTypes[type] != show)
{
if (mShowTypes[type] != show)
{ {
mShowTypes[type] = show; mShowTypes[type] = show;
RefreshTree(); RefreshTree();
}
} }
} }
void ResultsTree::RefreshTree() void ResultsTree::RefreshTree()
{ {
mModel.removeRows(0, mModel.rowCount()); //Get the amount of files in the tree
for (int i = 0;i < mItems.size();i++) int filecount = mModel.rowCount();
for (int i=0;i<filecount;i++)
{ {
if (mShowTypes[mItems[i].type]) //Get file i
QStandardItem *file = mModel.item(i,0);
if (!file)
{ {
AddItem(i); continue;
} }
//Get the amount of errors this file contains
int errorcount = file->rowCount();
//By default it shouldn't be visible
bool show = false;
for (int j=0;j<errorcount;j++)
{
//Get the error itself
QStandardItem *child = file->child(j,0);
if (!child)
{
continue;
}
//Get error's user data
QVariant userdata = child->data();
//Convert it to QVariantMap
QVariantMap data = userdata.toMap();
//Check if this error should be hidden
bool hide = !mShowTypes[VariantToShowType(data["severity"])];
//Hide/show accordingly
setRowHidden(j,file->index(),hide);
//If it was shown then the file itself has to be shown aswell
if (!hide)
{
show = true;
}
}
//Show the file if any of it's errors are visible
setRowHidden(i,QModelIndex(),!show);
} }
} }
@ -170,24 +270,27 @@ QString ResultsTree::ShowTypeToString(ShowTypes type)
return ""; return "";
} }
QStandardItem *ResultsTree::EnsureFileItem(const QString &name)
{
QStandardItem *item = FindFileItem(name);
void ResultsTree::AddItem(int index) if (item)
{ {
if (index >= 0 && index < mItems.size()) return item;
{
QStandardItem *fileitem = FindFileItem(mItems[index].file);
if (!fileitem)
{
//qDebug()<<"No previous error for file"<<realfile;
fileitem = CreateItem(mItems[index].file);
mModel.appendRow(fileitem);
} }
QList<QStandardItem*> list; item = CreateItem(name);
list << CreateItem(ShowTypeToString(mItems[index].type));
list << CreateItem(QString("%1").arg(mItems[index].lines[0])); mModel.appendRow(item);
list << CreateItem(mItems[index].message);
fileitem->appendRow(list); return item;
}
} }
void ResultsTree::ShowFileItem(const QString &name)
{
QStandardItem *item = FindFileItem(name);
if (item)
{
setRowHidden(0,mModel.indexFromItem(item),false);
}
}

View File

@ -27,6 +27,7 @@
#include <QSettings> #include <QSettings>
#include "common.h" #include "common.h"
/** /**
* @brief Cppcheck's results are shown in this tree * @brief Cppcheck's results are shown in this tree
* *
@ -48,7 +49,7 @@ public:
const QString &severity, const QString &severity,
const QString &message, const QString &message,
const QStringList &files, const QStringList &files,
const QList<int> &lines); const QVariantList &lines);
/** /**
* @brief Clear all errors from the tree * @brief Clear all errors from the tree
@ -58,21 +59,18 @@ public:
void ShowResults(ShowTypes type, bool show); void ShowResults(ShowTypes type, bool show);
protected: protected:
QStandardItem *AddBacktraceFiles(QStandardItem *parent,
const QString &file,
const int line,
const QString &severity,
const QString &message);
void AddItem(int index); void AddItem(int index);
void RefreshTree(); void RefreshTree();
ShowTypes VariantToShowType(const QVariant &data);
ShowTypes SeverityToShowType(const QString &severity); ShowTypes SeverityToShowType(const QString &severity);
QString ShowTypeToString(ShowTypes type); QString ShowTypeToString(ShowTypes type);
typedef struct
{
QString file;
ShowTypes type;
QString message;
QStringList files;
QList<int> lines;
}ErrorItem;
QList<ErrorItem> mItems;
/** /**
* @brief Load all settings * @brief Load all settings
* Colum widths * Colum widths
@ -101,6 +99,22 @@ protected:
*/ */
QStandardItem *FindFileItem(const QString &name); QStandardItem *FindFileItem(const QString &name);
/**
* @brief Ensures there's a item in the model for the specified file
*
* @param name Filename
* @return QStandardItem to be used as a parent for all errors for specified file
*/
QStandardItem *EnsureFileItem(const QString &name);
/**
* @brief Show a file item
*
* @param name Filename of the fileitem
*/
void ShowFileItem(const QString &name);
/** /**
* @brief Item model for tree * @brief Item model for tree
* *

View File

@ -59,7 +59,7 @@ void ResultsView::Error(const QString &file,
const QString &severity, const QString &severity,
const QString &message, const QString &message,
const QStringList &files, const QStringList &files,
const QList<int> &lines) const QVariantList &lines)
{ {
mTree->AddErrorItem(file, severity, message, files, lines); mTree->AddErrorItem(file, severity, message, files, lines);
} }

View File

@ -57,7 +57,7 @@ public slots:
const QString &severity, const QString &severity,
const QString &message, const QString &message,
const QStringList &files, const QStringList &files,
const QList<int> &lines); const QVariantList &lines);
protected: protected:
/** /**
* @brief Tree to show cppcheck's results * @brief Tree to show cppcheck's results

27
gui/test.cpp Normal file
View File

@ -0,0 +1,27 @@
/*
This is testing data for the GUI.
Used for testing GUI with various error styles reported by cppcheck.
Not meant to be compiled.
*/
void unused()
{
int a = 15;
}
void f(char k)
{
delete k;
}
int main()
{
char *b = new char[1];
char *a = new char[8];
if (a);
b = gets();
f(a);
}

View File

@ -139,12 +139,12 @@ void ThreadHandler::Initialize(ResultsView *view)
const QString &, const QString &,
const QString &, const QString &,
const QStringList &, const QStringList &,
const QList<int> &)), const QVariantList &)),
view, SLOT(Error(const QString &, view, SLOT(Error(const QString &,
const QString &, const QString &,
const QString &, const QString &,
const QStringList &, const QStringList &,
const QList<int> &))); const QVariantList &)));
} }

View File

@ -47,7 +47,7 @@ void ThreadResult::reportErr(const ErrorLogger::ErrorMessage &msg)
{ {
QMutexLocker locker(&mutex); QMutexLocker locker(&mutex);
QList<int> lines; QVariantList lines;
QStringList files; QStringList files;
for (std::list<ErrorLogger::ErrorMessage::FileLocation>::const_iterator tok = msg._callStack.begin(); for (std::list<ErrorLogger::ErrorMessage::FileLocation>::const_iterator tok = msg._callStack.begin();

View File

@ -24,6 +24,7 @@
#include <QMutex> #include <QMutex>
#include <QObject> #include <QObject>
#include <QStringList> #include <QStringList>
#include <QVariant>
#include "../src/errorlogger.h" #include "../src/errorlogger.h"
/** /**
@ -55,7 +56,7 @@ signals:
const QString &severity, const QString &severity,
const QString &message, const QString &message,
const QStringList &files, const QStringList &files,
const QList<int> &lines); const QVariantList &lines);
protected: protected:
mutable QMutex mutex; mutable QMutex mutex;