Skip to content

Commit 78e30e7

Browse files
committed
GUI: Better history. Prepare for tagging messages.
1 parent 3e2236a commit 78e30e7

8 files changed

Lines changed: 178 additions & 6 deletions

File tree

gui/erroritem.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,16 @@ QErrorPathItem::QErrorPathItem(const ErrorLogger::ErrorMessage::FileLocation &lo
2626
{
2727
}
2828

29+
bool operator==(const QErrorPathItem &i1, const QErrorPathItem &i2)
30+
{
31+
return i1.file == i2.file && i1.col == i2.col && i1.line == i2.line && i1.info == i2.info;
32+
}
33+
2934
ErrorItem::ErrorItem()
3035
: severity(Severity::none)
3136
, inconclusive(false)
3237
, cwe(-1)
38+
, tag(NONE)
3339
{
3440
}
3541

@@ -40,6 +46,7 @@ ErrorItem::ErrorItem(const ErrorLogger::ErrorMessage &errmsg)
4046
, summary(QString::fromStdString(errmsg.shortMessage()))
4147
, message(QString::fromStdString(errmsg.verboseMessage()))
4248
, cwe(errmsg._cwe.id)
49+
, tag(NONE)
4350
{
4451
for (std::list<ErrorLogger::ErrorMessage::FileLocation>::const_iterator loc = errmsg._callStack.begin();
4552
loc != errmsg._callStack.end();

gui/erroritem.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class QErrorPathItem {
5959
QString info;
6060
};
6161

62+
bool operator==(const QErrorPathItem &i1, const QErrorPathItem &i2);
63+
6264
/**
6365
* @brief A class containing error data for one error.
6466
*
@@ -86,6 +88,10 @@ class ErrorItem {
8688
QString message;
8789
int cwe;
8890
QList<QErrorPathItem> errorPath;
91+
92+
// Special GUI properties
93+
QString sinceDate;
94+
enum Tag { NONE, FP, IGNORE, BUG } tag;
8995
};
9096

9197
Q_DECLARE_METATYPE(ErrorItem);
@@ -103,6 +109,8 @@ class ErrorLine {
103109
Severity::SeverityType severity;
104110
QString summary;
105111
QString message;
112+
QString sinceDate;
113+
ErrorItem::Tag tag;
106114
};
107115

108116
/// @}

gui/mainwindow.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,7 @@ void MainWindow::analysisDone()
872872
const QString buildDir = prjpath + '/' + mProjectFile->getBuildDir();
873873
if (QDir(buildDir).exists()) {
874874
mUI.mResults->saveStatistics(buildDir + "/statistics.txt");
875+
mUI.mResults->updateFromOldReport(buildDir + "/lastResults.xml");
875876
mUI.mResults->save(buildDir + "/lastResults.xml", Report::XMLV2);
876877
}
877878
}
@@ -1278,6 +1279,13 @@ void MainWindow::stopAnalysis()
12781279
{
12791280
mThread->stop();
12801281
mUI.mResults->disableProgressbar();
1282+
if (mProjectFile && !mProjectFile->getBuildDir().isEmpty()) {
1283+
const QString prjpath = QFileInfo(mProjectFile->getFilename()).absolutePath();
1284+
const QString buildDir = prjpath + '/' + mProjectFile->getBuildDir();
1285+
if (QDir(buildDir).exists()) {
1286+
mUI.mResults->updateFromOldReport(buildDir + "/lastResults.xml");
1287+
}
1288+
}
12811289
}
12821290

12831291
void MainWindow::openHelpContents()

gui/resultstree.cpp

Lines changed: 110 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@
4747
#include "showtypes.h"
4848
#include "threadhandler.h"
4949
#include "path.h"
50+
#include "xmlreportv2.h"
51+
52+
// These must match column headers given in ResultsTree::translate()
53+
static const unsigned int COLUMN_SINCE_DATE = 6;
54+
static const unsigned int COLUMN_TAG = 7;
5055

5156
ResultsTree::ResultsTree(QWidget * parent) :
5257
QTreeView(parent),
@@ -154,6 +159,8 @@ bool ResultsTree::addErrorItem(const ErrorItem &item)
154159
line.summary = item.summary;
155160
line.message = item.message;
156161
line.severity = item.severity;
162+
line.sinceDate = item.sinceDate;
163+
line.tag = item.tag;
157164
//Create the base item for the error and ensure it has a proper
158165
//file item as a parent
159166
QStandardItem* fileItem = ensureFileItem(item.errorPath.back().file, item.file0, hide);
@@ -232,7 +239,22 @@ QStandardItem *ResultsTree::addBacktraceFiles(QStandardItem *parent,
232239
<< createLineNumberItem(QString::number(item.line))
233240
<< createNormalItem(childOfMessage ? QString() : item.errorId)
234241
<< (childOfMessage ? createNormalItem(QString()) : createCheckboxItem(item.inconclusive))
235-
<< createNormalItem(item.summary);
242+
<< createNormalItem(item.summary)
243+
<< createNormalItem(item.sinceDate);
244+
switch (item.tag) {
245+
case ErrorItem::NONE:
246+
list << createNormalItem("");
247+
break;
248+
case ErrorItem::FP:
249+
list << createNormalItem("fp");
250+
break;
251+
case ErrorItem::IGNORE:
252+
list << createNormalItem("ignore");
253+
break;
254+
case ErrorItem::BUG:
255+
list << createNormalItem("bug");
256+
break;
257+
};
236258
//TODO message has parameter names so we'll need changes to the core
237259
//cppcheck so we can get proper translations
238260

@@ -1003,19 +1025,101 @@ void ResultsTree::saveErrors(Report *report, QStandardItem *fileItem) const
10031025
}
10041026
}
10051027

1028+
1029+
QList<ErrorItem> ResultsTree::getAllErrorItems() const
1030+
{
1031+
QList<ErrorItem> ret;
1032+
for (int i = 0; i < mModel.rowCount(); i++) {
1033+
const QStandardItem *item = mModel.item(i,0);
1034+
for (int j = 0; j < item->rowCount(); j++) {
1035+
const QStandardItem *error = item->child(j,0);
1036+
ErrorItem errorItem;
1037+
readErrorItem(error, &errorItem);
1038+
ret << errorItem;
1039+
}
1040+
}
1041+
return ret;
1042+
}
1043+
1044+
static int indexOf(const QList<ErrorItem> &list, const ErrorItem &item)
1045+
{
1046+
for (int i = 0; i < list.size(); i++) {
1047+
if (list[i].errorId == item.errorId &&
1048+
list[i].errorPath == item.errorPath &&
1049+
list[i].file0 == item.file0 &&
1050+
list[i].message == item.message &&
1051+
list[i].inconclusive == item.inconclusive &&
1052+
list[i].severity == item.severity) {
1053+
return i;
1054+
}
1055+
}
1056+
return -1;
1057+
}
1058+
1059+
void ResultsTree::updateFromOldReport(const QString &filename)
1060+
{
1061+
QList<ErrorItem> oldErrors;
1062+
XmlReportV2 oldReport(filename);
1063+
if (oldReport.open()) {
1064+
oldErrors = oldReport.read();
1065+
oldReport.close();
1066+
}
1067+
1068+
// Read current results..
1069+
for (int i = 0; i < mModel.rowCount(); i++) {
1070+
QStandardItem *fileItem = mModel.item(i,0);
1071+
for (int j = 0; j < fileItem->rowCount(); j++) {
1072+
QStandardItem *error = fileItem->child(j,0);
1073+
ErrorItem errorItem;
1074+
readErrorItem(error, &errorItem);
1075+
int oldErrorIndex = indexOf(oldErrors, errorItem);
1076+
QVariantMap data = error->data().toMap();
1077+
1078+
// New error .. set the "sinceDate" property
1079+
if (oldErrorIndex < 0 || data["sinceDate"].toString().isEmpty()) {
1080+
const QString sinceDate = QDate::currentDate().toString(Qt::SystemLocaleShortDate);
1081+
data["sinceDate"] = sinceDate;
1082+
error->setData(data);
1083+
fileItem->child(j, COLUMN_SINCE_DATE)->setText(sinceDate);
1084+
if (oldErrorIndex < 0)
1085+
continue;
1086+
}
1087+
1088+
if (errorItem.tag != ErrorItem::NONE)
1089+
continue;
1090+
1091+
const ErrorItem &oldErrorItem = oldErrors[oldErrorIndex];
1092+
1093+
if (oldErrorItem.tag == ErrorItem::FP)
1094+
data["tag"] = "fp";
1095+
else if (oldErrorItem.tag == ErrorItem::IGNORE)
1096+
data["tag"] = "ignore";
1097+
else if (oldErrorItem.tag == ErrorItem::BUG)
1098+
data["tag"] = "bug";
1099+
error->setData(data);
1100+
}
1101+
}
1102+
}
1103+
10061104
void ResultsTree::readErrorItem(const QStandardItem *error, ErrorItem *item) const
10071105
{
1008-
//Get error's user data
1009-
QVariant userdata = error->data();
1010-
//Convert it to QVariantMap
1011-
QVariantMap data = userdata.toMap();
1106+
// Get error's user data
1107+
QVariantMap data = error->data().toMap();
10121108

10131109
item->severity = ShowTypes::ShowTypeToSeverity(ShowTypes::VariantToShowType(data["severity"]));
10141110
item->summary = data["summary"].toString();
10151111
item->message = data["message"].toString();
10161112
item->errorId = data["id"].toString();
10171113
item->inconclusive = data["inconclusive"].toBool();
10181114
item->file0 = data["file0"].toString();
1115+
item->sinceDate = data["sinceDate"].toString();
1116+
QString tag = data["tag"].toString();
1117+
if (tag == "fp")
1118+
item->tag = ErrorItem::FP;
1119+
else if (tag == "ignore")
1120+
item->tag = ErrorItem::IGNORE;
1121+
else if (tag == "bug")
1122+
item->tag = ErrorItem::BUG;
10191123

10201124
if (error->rowCount() == 0) {
10211125
QErrorPathItem e;
@@ -1161,7 +1265,7 @@ bool ResultsTree::hasResults() const
11611265
void ResultsTree::translate()
11621266
{
11631267
QStringList labels;
1164-
labels << tr("File") << tr("Severity") << tr("Line") << tr("Id") << tr("Inconclusive") << tr("Summary");
1268+
labels << tr("File") << tr("Severity") << tr("Line") << tr("Id") << tr("Inconclusive") << tr("Summary") << tr("Since date") << tr("Tag");
11651269
mModel.setHorizontalHeaderLabels(labels);
11661270
//TODO go through all the errors in the tree and translate severity and message
11671271
}

gui/resultstree.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,16 @@ class ResultsTree : public QTreeView {
103103
*/
104104
void saveResults(Report *report) const;
105105

106+
/**
107+
* @brief Get all error items
108+
*/
109+
QList<ErrorItem> getAllErrorItems() const;
110+
111+
/**
112+
* @brief Update items from old report (tag, sinceDate)
113+
*/
114+
void updateFromOldReport(const QString &filename);
115+
106116
/**
107117
* @brief Update tree settings
108118
*

gui/resultsview.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ void ResultsView::saveStatistics(const QString &filename) const
149149
ts << "portability:" << mStatistics->getCount(ShowTypes::ShowPortability) << '\n';
150150
}
151151

152+
void ResultsView::updateFromOldReport(const QString &filename) const
153+
{
154+
mUI.mTree->updateFromOldReport(filename);
155+
}
156+
152157
void ResultsView::save(const QString &filename, Report::Type type) const
153158
{
154159
if (!hasResults()) {

gui/resultsview.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ class ResultsView : public QWidget {
8888
*/
8989
void save(const QString &filename, Report::Type type) const;
9090

91+
/**
92+
* @brief Update results from old report (tag, sinceDate)
93+
*/
94+
void updateFromOldReport(const QString &filename) const;
95+
9196
/**
9297
* @brief Update tree settings
9398
*

gui/xmlreportv2.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ static const char ErrorsElementName[] = "errors";
3535
static const char LocationElementName[] = "location";
3636
static const char ColAttribute[] = "col";
3737
static const char CWEAttribute[] = "cwe";
38+
static const char SinceDateAttribute[] = "sinceDate";
39+
static const char TagAttribute[] = "tag";
3840
static const char FilenameAttribute[] = "file";
3941
static const char IncludedFromFilenameAttribute[] = "file0";
4042
static const char InconclusiveAttribute[] = "inconclusive";
@@ -120,6 +122,14 @@ void XmlReportV2::writeError(const ErrorItem &error)
120122
mXmlWriter->writeAttribute(InconclusiveAttribute, "true");
121123
if (error.cwe > 0)
122124
mXmlWriter->writeAttribute(CWEAttribute, QString::number(error.cwe));
125+
if (!error.sinceDate.isEmpty())
126+
mXmlWriter->writeAttribute(SinceDateAttribute, error.sinceDate);
127+
if (error.tag == ErrorItem::FP)
128+
mXmlWriter->writeAttribute(TagAttribute, "fp");
129+
else if (error.tag == ErrorItem::IGNORE)
130+
mXmlWriter->writeAttribute(TagAttribute, "ignore");
131+
else if (error.tag == ErrorItem::BUG)
132+
mXmlWriter->writeAttribute(TagAttribute, "bug");
123133

124134
for (int i = error.errorPath.count() - 1; i >= 0; i--) {
125135
mXmlWriter->writeStartElement(LocationElementName);
@@ -209,6 +219,17 @@ ErrorItem XmlReportV2::readError(QXmlStreamReader *reader)
209219
item.inconclusive = true;
210220
if (attribs.hasAttribute("", CWEAttribute))
211221
item.cwe = attribs.value("", CWEAttribute).toString().toInt();
222+
if (attribs.hasAttribute("", SinceDateAttribute))
223+
item.sinceDate = attribs.value("", SinceDateAttribute).toString();
224+
if (attribs.hasAttribute("", TagAttribute)) {
225+
const QString tag = attribs.value("", TagAttribute).toString();
226+
if (tag == "fp")
227+
item.tag = ErrorItem::FP;
228+
else if (tag == "ignore")
229+
item.tag = ErrorItem::IGNORE;
230+
else if (tag == "bug")
231+
item.tag = ErrorItem::BUG;
232+
}
212233
}
213234

214235
bool errorRead = false;
@@ -251,5 +272,9 @@ ErrorItem XmlReportV2::readError(QXmlStreamReader *reader)
251272
break;
252273
}
253274
}
275+
276+
if (item.errorPath.size() == 1 && item.errorPath[0].info.isEmpty())
277+
item.errorPath[0].info = item.message;
278+
254279
return item;
255280
}

0 commit comments

Comments
 (0)