Cppcheck
resultsview.cpp
Go to the documentation of this file.
1 /*
2  * Cppcheck - A tool for static C/C++ code analysis
3  * Copyright (C) 2007-2024 Cppcheck team.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "resultsview.h"
20 
21 #include "checkstatistics.h"
22 #include "checkersreport.h"
23 #include "codeeditor.h"
24 #include "codeeditorstyle.h"
25 #include "common.h"
26 #include "csvreport.h"
27 #include "erroritem.h"
28 #include "errorlogger.h"
29 #include "errortypes.h"
30 #include "path.h"
31 #include "printablereport.h"
32 #include "resultstree.h"
33 #include "settings.h"
34 #include "txtreport.h"
35 #include "xmlreport.h"
36 #include "xmlreportv2.h"
37 
38 #include "ui_resultsview.h"
39 
40 #include <set>
41 #include <string>
42 
43 #include <QAbstractItemModel>
44 #include <QApplication>
45 #include <QByteArray>
46 #include <QClipboard>
47 #include <QDate>
48 #include <QDateTime>
49 #include <QDialog>
50 #include <QDir>
51 #include <QFile>
52 #include <QFileInfo>
53 #include <QIODevice>
54 #include <QLabel>
55 #include <QList>
56 #include <QListWidget>
57 #include <QListWidgetItem>
58 #include <QMenu>
59 #include <QMessageBox>
60 #include <QPoint>
61 #include <QPrintDialog>
62 #include <QPrintPreviewDialog>
63 #include <QPrinter>
64 #include <QProgressBar>
65 #include <QSettings>
66 #include <QSplitter>
67 #include <QStandardItem>
68 #include <QStandardItemModel>
69 #include <QTextDocument>
70 #include <QTextEdit>
71 #include <QTextStream>
72 #include <QVariant>
73 #include <QVariantMap>
74 #include <Qt>
75 
76 ResultsView::ResultsView(QWidget * parent) :
77  QWidget(parent),
78  mUI(new Ui::ResultsView),
79  mStatistics(new CheckStatistics(this))
80 {
81  mUI->setupUi(this);
82 
86  connect(mUI->mTree, &ResultsTree::suppressIds, this, &ResultsView::suppressIds);
87  connect(this, &ResultsView::showResults, mUI->mTree, &ResultsTree::showResults);
90  connect(this, &ResultsView::collapseAllResults, mUI->mTree, &ResultsTree::collapseAll);
91  connect(this, &ResultsView::expandAllResults, mUI->mTree, &ResultsTree::expandAll);
93 
94  mUI->mListLog->setContextMenuPolicy(Qt::CustomContextMenu);
95 }
96 
97 void ResultsView::initialize(QSettings *settings, ApplicationList *list, ThreadHandler *checkThreadHandler)
98 {
99  mUI->mProgress->setMinimum(0);
100  mUI->mProgress->setVisible(false);
101  mUI->mLabelCriticalErrors->setVisible(false);
102 
104  mUI->mCode->setStyle(theStyle);
105 
106  QByteArray state = settings->value(SETTINGS_MAINWND_SPLITTER_STATE).toByteArray();
107  mUI->mVerticalSplitter->restoreState(state);
108  mShowNoErrorsMessage = settings->value(SETTINGS_SHOW_NO_ERRORS, true).toBool();
109 
110  mUI->mTree->initialize(settings, list, checkThreadHandler);
111 }
112 
114 {
115  delete mUI;
116  delete mCheckSettings;
117 }
118 
119 void ResultsView::clear(bool results)
120 {
121  if (results) {
122  mUI->mTree->clear();
123  }
124 
125  mUI->mDetails->setText(QString());
126 
127  mStatistics->clear();
128  delete mCheckSettings;
129  mCheckSettings = nullptr;
130 
131  //Clear the progressbar
132  mUI->mProgress->setMaximum(PROGRESS_MAX);
133  mUI->mProgress->setValue(0);
134  mUI->mProgress->setFormat("%p%");
135 
136  mUI->mLabelCriticalErrors->setVisible(false);
137 
138  mSuccess = false;
139 }
140 
141 void ResultsView::clear(const QString &filename)
142 {
143  mUI->mTree->clear(filename);
144 }
145 
146 void ResultsView::clearRecheckFile(const QString &filename)
147 {
148  mUI->mTree->clearRecheckFile(filename);
149 }
150 
152 {
153  return mUI->mTree->mShowSeverities;
154 }
155 
156 void ResultsView::progress(int value, const QString& description)
157 {
158  mUI->mProgress->setValue(value);
159  mUI->mProgress->setFormat(QString("%p% (%1)").arg(description));
160 }
161 
162 void ResultsView::error(const ErrorItem &item)
163 {
164  if (item.severity == Severity::internal && (item.errorId == "logChecker" || item.errorId.endsWith("-logChecker"))) {
166  return;
167  }
168 
169  handleCriticalError(item);
170 
171  if (item.severity == Severity::internal)
172  return;
173 
174  if (mUI->mTree->addErrorItem(item)) {
175  emit gotResults();
177  }
178 }
179 
180 void ResultsView::filterResults(const QString& filter)
181 {
182  mUI->mTree->filterResults(filter);
183 }
184 
185 void ResultsView::saveStatistics(const QString &filename) const
186 {
187  QFile f(filename);
188  if (!f.open(QIODevice::Text | QIODevice::Append))
189  return;
190  QTextStream ts(&f);
191  ts << '[' << QDate::currentDate().toString("dd.MM.yyyy") << "]\n";
192  ts << QDateTime::currentMSecsSinceEpoch() << '\n';
193  for (const QString& tool : mStatistics->getTools()) {
194  ts << tool << "-error:" << mStatistics->getCount(tool, ShowTypes::ShowErrors) << '\n';
195  ts << tool << "-warning:" << mStatistics->getCount(tool, ShowTypes::ShowWarnings) << '\n';
196  ts << tool << "-style:" << mStatistics->getCount(tool, ShowTypes::ShowStyle) << '\n';
197  ts << tool << "-performance:" << mStatistics->getCount(tool, ShowTypes::ShowPerformance) << '\n';
198  ts << tool << "-portability:" << mStatistics->getCount(tool, ShowTypes::ShowPortability) << '\n';
199  }
200 }
201 
202 void ResultsView::updateFromOldReport(const QString &filename) const
203 {
204  mUI->mTree->updateFromOldReport(filename);
205 }
206 
207 void ResultsView::save(const QString &filename, Report::Type type, const QString& productName) const
208 {
209  Report *report = nullptr;
210 
211  switch (type) {
212  case Report::CSV:
213  report = new CsvReport(filename);
214  break;
215  case Report::TXT:
216  report = new TxtReport(filename);
217  break;
218  case Report::XMLV2:
219  report = new XmlReportV2(filename, productName);
220  break;
221  }
222 
223  if (report) {
224  if (report->create())
225  mUI->mTree->saveResults(report);
226  else {
227  QMessageBox msgBox;
228  msgBox.setText(tr("Failed to save the report."));
229  msgBox.setIcon(QMessageBox::Critical);
230  msgBox.exec();
231  }
232  delete report;
233  report = nullptr;
234  } else {
235  QMessageBox msgBox;
236  msgBox.setText(tr("Failed to save the report."));
237  msgBox.setIcon(QMessageBox::Critical);
238  msgBox.exec();
239  }
240 }
241 
243 {
244  QPrinter printer;
245  QPrintDialog dialog(&printer, this);
246  dialog.setWindowTitle(tr("Print Report"));
247  if (dialog.exec() != QDialog::Accepted)
248  return;
249 
250  print(&printer);
251 }
252 
254 {
255  QPrinter printer;
256  QPrintPreviewDialog dialog(&printer, this);
257  connect(&dialog, SIGNAL(paintRequested(QPrinter*)), SLOT(print(QPrinter*)));
258  dialog.exec();
259 }
260 
261 void ResultsView::print(QPrinter* printer)
262 {
263  if (!hasResults()) {
264  QMessageBox msgBox;
265  msgBox.setText(tr("No errors found, nothing to print."));
266  msgBox.setIcon(QMessageBox::Critical);
267  msgBox.exec();
268  return;
269  }
270 
271  PrintableReport report;
272  mUI->mTree->saveResults(&report);
273  QTextDocument doc(report.getFormattedReportText());
274  doc.print(printer);
275 }
276 
277 void ResultsView::updateSettings(bool showFullPath,
278  bool saveFullPath,
279  bool saveAllErrors,
280  bool showNoErrorsMessage,
281  bool showErrorId,
282  bool showInconclusive)
283 {
284  mUI->mTree->updateSettings(showFullPath, saveFullPath, saveAllErrors, showErrorId, showInconclusive);
285  mShowNoErrorsMessage = showNoErrorsMessage;
286 }
287 
288 void ResultsView::updateStyleSetting(QSettings *settings)
289 {
291  mUI->mCode->setStyle(theStyle);
292 }
293 
294 void ResultsView::setCheckDirectory(const QString &dir)
295 {
296  mUI->mTree->setCheckDirectory(dir);
297 }
298 
300 {
301  return mUI->mTree->getCheckDirectory();
302 }
303 
305 {
306  delete mCheckSettings;
307  mCheckSettings = new Settings;
308  *mCheckSettings = settings;
309 }
310 
312 {
313  mSuccess = true;
314  mUI->mProgress->setVisible(true);
315  mUI->mProgress->setMaximum(PROGRESS_MAX);
316  mUI->mProgress->setValue(0);
317  mUI->mProgress->setFormat(tr("%p% (%1 of %2 files checked)").arg(0).arg(count));
318 }
319 
321 {
322  mUI->mProgress->setVisible(false);
323  mUI->mProgress->setFormat("%p%");
324 
325  {
326  Settings checkSettings;
327  const std::set<std::string> activeCheckers = mStatistics->getActiveCheckers();
328  CheckersReport checkersReport(mCheckSettings ? *mCheckSettings : checkSettings, activeCheckers);
329  mStatistics->setCheckersReport(QString::fromStdString(checkersReport.getReport(mCriticalErrors.toStdString())));
330  }
331 
332  // TODO: Items can be mysteriously hidden when checking is finished, this function
333  // call should be redundant but it "unhides" the wrongly hidden items.
334  mUI->mTree->refreshTree();
335 
336  //Should we inform user of non visible/not found errors?
337  if (mShowNoErrorsMessage) {
338  //Tell user that we found no errors
339  if (!hasResults()) {
340  QMessageBox msg(QMessageBox::Information,
341  tr("Cppcheck"),
342  tr("No errors found."),
343  QMessageBox::Ok,
344  this);
345 
346  msg.exec();
347  } //If we have errors but they aren't visible, tell user about it
348  else if (!mUI->mTree->hasVisibleResults()) {
349  QString text = tr("Errors were found, but they are configured to be hidden.\n" \
350  "To toggle what kind of errors are shown, open view menu.");
351  QMessageBox msg(QMessageBox::Information,
352  tr("Cppcheck"),
353  text,
354  QMessageBox::Ok,
355  this);
356 
357  msg.exec();
358  }
359  }
360 }
361 
363 {
364  return mUI->mTree->hasVisibleResults();
365 }
366 
368 {
369  return mUI->mTree->hasResults();
370 }
371 
372 void ResultsView::saveSettings(QSettings *settings)
373 {
374  mUI->mTree->saveSettings();
375  QByteArray state = mUI->mVerticalSplitter->saveState();
376  settings->setValue(SETTINGS_MAINWND_SPLITTER_STATE, state);
377  mUI->mVerticalSplitter->restoreState(state);
378 }
379 
381 {
382  mUI->retranslateUi(this);
383  mUI->mTree->translate();
384 }
385 
387 {
388  mUI->mProgress->setEnabled(false);
389 }
390 
391 void ResultsView::readErrorsXml(const QString &filename)
392 {
393  mSuccess = false; // Don't know if results come from an aborted analysis
394 
395  const int version = XmlReport::determineVersion(filename);
396  if (version == 0) {
397  QMessageBox msgBox;
398  msgBox.setText(tr("Failed to read the report."));
399  msgBox.setIcon(QMessageBox::Critical);
400  msgBox.exec();
401  return;
402  }
403  if (version == 1) {
404  QMessageBox msgBox;
405  msgBox.setText(tr("XML format version 1 is no longer supported."));
406  msgBox.setIcon(QMessageBox::Critical);
407  msgBox.exec();
408  return;
409  }
410 
411  XmlReportV2 report(filename, QString());
412  QList<ErrorItem> errors;
413  if (report.open()) {
414  errors = report.read();
415  } else {
416  QMessageBox msgBox;
417  msgBox.setText(tr("Failed to read the report."));
418  msgBox.setIcon(QMessageBox::Critical);
419  msgBox.exec();
420  }
421 
422  for (const ErrorItem& item : errors) {
423  handleCriticalError(item);
424  mUI->mTree->addErrorItem(item);
425  }
426 
427  QString dir;
428  if (!errors.isEmpty() && !errors[0].errorPath.isEmpty()) {
429  QString relativePath = QFileInfo(filename).canonicalPath();
430  if (QFileInfo::exists(relativePath + '/' + errors[0].errorPath[0].file))
431  dir = relativePath;
432  }
433 
434  mUI->mTree->setCheckDirectory(dir);
435 }
436 
437 void ResultsView::updateDetails(const QModelIndex &index)
438 {
439  const auto *model = qobject_cast<const QStandardItemModel*>(mUI->mTree->model());
440  QStandardItem *item = model->itemFromIndex(index);
441 
442  if (!item) {
443  mUI->mCode->clear();
444  mUI->mDetails->setText(QString());
445  return;
446  }
447 
448  // Make sure we are working with the first column
449  if (item->parent() && item->column() != 0)
450  item = item->parent()->child(item->row(), 0);
451 
452  QVariantMap data = item->data().toMap();
453 
454  // If there is no severity data then it is a parent item without summary and message
455  if (!data.contains("severity")) {
456  mUI->mCode->clear();
457  mUI->mDetails->setText(QString());
458  return;
459  }
460 
461  const QString message = data["message"].toString();
462  QString formattedMsg = message;
463 
464  const QString file0 = data["file0"].toString();
465  if (!file0.isEmpty() && Path::isHeader2(data["file"].toString().toStdString()))
466  formattedMsg += QString("\n\n%1: %2").arg(tr("First included by")).arg(QDir::toNativeSeparators(file0));
467 
468  if (data["cwe"].toInt() > 0)
469  formattedMsg.prepend("CWE: " + QString::number(data["cwe"].toInt()) + "\n");
470  if (mUI->mTree->showIdColumn())
471  formattedMsg.prepend(tr("Id") + ": " + data["id"].toString() + "\n");
472  if (data["incomplete"].toBool())
473  formattedMsg += "\n" + tr("Bug hunting analysis is incomplete");
474  mUI->mDetails->setText(formattedMsg);
475 
476  const int lineNumber = data["line"].toInt();
477 
478  QString filepath = data["file"].toString();
479  if (!QFileInfo::exists(filepath) && QFileInfo::exists(mUI->mTree->getCheckDirectory() + '/' + filepath))
480  filepath = mUI->mTree->getCheckDirectory() + '/' + filepath;
481 
482  QStringList symbols;
483  if (data.contains("symbolNames"))
484  symbols = data["symbolNames"].toString().split("\n");
485 
486  if (filepath == mUI->mCode->getFileName()) {
487  mUI->mCode->setError(lineNumber, symbols);
488  return;
489  }
490 
491  QFile file(filepath);
492  if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
493  mUI->mCode->clear();
494  return;
495  }
496 
497  QTextStream in(&file);
498  mUI->mCode->setError(in.readAll(), lineNumber, symbols);
499  mUI->mCode->setFileName(filepath);
500 }
501 
502 void ResultsView::log(const QString &str)
503 {
504  mUI->mListLog->addItem(str);
505 }
506 
508 {
509  mUI->mListLog->addItem(item.toString());
510 }
511 
513 {
514  mUI->mListLog->clear();
515 }
516 
518 {
519  const QListWidgetItem * item = mUI->mListLog->currentItem();
520  if (nullptr != item) {
521  QClipboard *clipboard = QApplication::clipboard();
522  clipboard->setText(item->text());
523  }
524 }
525 
527 {
528  QString logText;
529  for (int i=0; i < mUI->mListLog->count(); ++i) {
530  const QListWidgetItem * item = mUI->mListLog->item(i);
531  if (nullptr != item) {
532  logText += item->text();
533  }
534  }
535  QClipboard *clipboard = QApplication::clipboard();
536  clipboard->setText(logText);
537 }
538 
540 {
541  if (mUI->mListLog->count() <= 0)
542  return;
543 
544  const QPoint globalPos = mUI->mListLog->mapToGlobal(pos);
545 
546  QMenu contextMenu;
547  contextMenu.addAction(tr("Clear Log"), this, SLOT(logClear()));
548  contextMenu.addAction(tr("Copy this Log entry"), this, SLOT(logCopyEntry()));
549  contextMenu.addAction(tr("Copy complete Log"), this, SLOT(logCopyComplete()));
550 
551  contextMenu.exec(globalPos);
552 }
553 
555 {
556  mSuccess = false;
557  mUI->mLabelCriticalErrors->setText(tr("Analysis was stopped"));
558  mUI->mLabelCriticalErrors->setVisible(true);
559 }
560 
562 {
563  if (ErrorLogger::isCriticalErrorId(item.errorId.toStdString())) {
564  if (!mCriticalErrors.contains(item.errorId)) {
565  if (!mCriticalErrors.isEmpty())
566  mCriticalErrors += ",";
567  mCriticalErrors += item.errorId;
568  if (item.severity == Severity::internal)
569  mCriticalErrors += " (suppressed)";
570  }
571  QString msg = tr("There was a critical error with id '%1'").arg(item.errorId);
572  if (!item.file0.isEmpty())
573  msg += ", " + tr("when checking %1").arg(item.file0);
574  else
575  msg += ", " + tr("when checking a file");
576  msg += ". " + tr("Analysis was aborted.");
577  mUI->mLabelCriticalErrors->setText(msg);
578  mUI->mLabelCriticalErrors->setVisible(true);
579  mSuccess = false;
580  }
581 }
582 
584  return mSuccess;
585 }
List of applications user has specified to open errors with.
A class for check statistics.
QStringList getTools() const
Get tools with results.
void clear()
Clear the statistics.
unsigned getCount(const QString &tool, ShowTypes::ShowType type) const
Return statistics for given type.
const std::set< std::string > & getActiveCheckers() const
void addItem(const QString &tool, ShowTypes::ShowType type)
Add new checked item to statistics.
void setCheckersReport(QString report)
void addChecker(const QString &checker)
Add checker to statistics.
std::string getReport(const std::string &criticalErrors) const
static CodeEditorStyle loadSettings(QSettings *settings)
CSV text file report.
Definition: csvreport.h:39
A class containing error data for one error.
Definition: erroritem.h:72
QString toString() const
Convert error item to string.
Definition: erroritem.cpp:73
QString file0
Definition: erroritem.h:84
QString tool() const
Definition: erroritem.cpp:62
Severity severity
Definition: erroritem.h:86
QString message
Definition: erroritem.h:89
QString errorId
Definition: erroritem.h:85
static bool isCriticalErrorId(const std::string &id)
Definition: errorlogger.h:264
static bool isHeader2(const std::string &path)
Is filename a header based on file extension.
Definition: path.cpp:277
Printable (in-memory) report.
const QString & getFormattedReportText() const
Returns the formatted report.
A base class for reports.
Definition: report.h:34
Type
Definition: report.h:36
@ CSV
Definition: report.h:39
@ XMLV2
Definition: report.h:38
@ TXT
Definition: report.h:37
virtual bool create()
Create the report (file).
Definition: report.cpp:34
void treeSelectionChanged(const QModelIndex &current)
Signal for selection change in result tree.
void showHiddenResults()
Function to show results that were previous hidden with HideResult()
void resultsHidden(bool hidden)
Signal that results have been hidden or shown.
void showClangResults(bool show)
Show/hide clang-tidy/clang-analyzer errors.
void checkSelected(QStringList selectedItems)
Signal to perform selected files recheck.
void suppressIds(QStringList ids)
Suppress Ids.
void showResults(ShowTypes::ShowType type, bool show)
Function to show/hide certain type of errors Refreshes the tree.
void showCppcheckResults(bool show)
Show/hide cppcheck errors.
Widget to show cppcheck progressbar and result.
Definition: resultsview.h:51
void progress(int value, const QString &description)
Slot for updating the checking progress.
void logClear()
Clear log messages.
bool isSuccess() const
Are there successful results?
bool hasResults() const
Do we have results from check?
void updateSettings(bool showFullPath, bool saveFullPath, bool saveAllErrors, bool showNoErrorsMessage, bool showErrorId, bool showInconclusive)
Update tree settings.
bool hasVisibleResults() const
Do we have visible results to show?
void showResults(ShowTypes::ShowType type, bool show)
Show/hide certain type of errors Refreshes the tree.
void checkSelected(QStringList selectedFilesList)
Signal to perform recheck of selected files.
void setCheckSettings(const Settings &settings)
Set settings used in checking.
void suppressIds(QStringList ids)
Suppress Ids.
bool mShowNoErrorsMessage
Should we show a "No errors found dialog" every time no errors were found?
Definition: resultsview.h:372
void save(const QString &filename, Report::Type type, const QString &productName) const
Save results to a file.
void updateStyleSetting(QSettings *settings)
Update Code Editor Style.
void setCheckDirectory(const QString &dir)
Set the directory we are checking.
Ui::ResultsView * mUI
Definition: resultsview.h:374
void showCppcheckResults(bool show)
Show/hide cppcheck errors.
QString mCriticalErrors
Critical error ids.
Definition: resultsview.h:386
void collapseAllResults()
Collapse all results in the result list.
void readErrorsXml(const QString &filename)
Read errors from report XML file.
ResultsView(QWidget *parent=nullptr)
Definition: resultsview.cpp:76
void updateDetails(const QModelIndex &index)
Update detailed message when selected item is changed.
void printPreview()
Slot opening a print preview dialog.
CheckStatistics * mStatistics
Definition: resultsview.h:376
void checkingFinished()
Inform the view that checking finished.
void print()
Slot opening a print dialog to print the current report.
void clear(bool results)
Clear results and statistics and reset progressinfo.
void disableProgressbar()
void showHiddenResults()
Show hidden results in the result list.
void showClangResults(bool show)
Show/hide clang-tidy/clang-analyzer errors.
void resultsHidden(bool hidden)
Signal that results have been hidden or shown.
void error(const ErrorItem &item)
Slot for new error to be displayed.
Settings * mCheckSettings
Definition: resultsview.h:378
void gotResults()
Signal to be emitted when we have results.
~ResultsView() override
void on_mListLog_customContextMenuRequested(const QPoint &pos)
Custom context menu for Analysis Log.
void expandAllResults()
Expand all results in the result list.
bool mSuccess
Set to true when checking finish successfully.
Definition: resultsview.h:383
void translate()
Translate this view.
void logCopyComplete()
Copy all log messages.
void log(const QString &str)
Log message.
void clearRecheckFile(const QString &filename)
Remove a recheck file from the results.
void checkingStarted(int count)
Inform the view that checking has started.
void saveSettings(QSettings *settings)
Save View's settings.
void debugError(const ErrorItem &item)
debug message
void updateFromOldReport(const QString &filename) const
Update results from old report (tag, sinceDate)
const ShowTypes & getShowTypes() const
Return Showtypes.
void saveStatistics(const QString &filename) const
Write statistics in file.
void logCopyEntry()
Copy selected log message entry.
void stopAnalysis()
This function should be called when analysis is stopped.
void filterResults(const QString &filter)
Filters the results in the result list.
QString getCheckDirectory()
Get the directory we are checking.
void handleCriticalError(const ErrorItem &item)
If provided ErrorItem is a critical error then display warning message in the resultsview.
void initialize(QSettings *settings, ApplicationList *list, ThreadHandler *checkThreadHandler)
Definition: resultsview.cpp:97
This is just a container for general settings so that we don't need to pass individual values to func...
Definition: settings.h:95
A class for different show types we have.
Definition: showtypes.h:38
static ShowTypes::ShowType SeverityToShowType(Severity severity)
Convert severity string to ShowTypes value.
Definition: showtypes.cpp:36
@ ShowPerformance
Definition: showtypes.h:47
@ ShowPortability
Definition: showtypes.h:48
@ ShowErrors
Definition: showtypes.h:50
@ ShowWarnings
Definition: showtypes.h:46
@ ShowStyle
Definition: showtypes.h:45
This class handles creating threadresult and starting threads.
Definition: threadhandler.h:50
Text file report.
Definition: txtreport.h:38
XML file report version 2.
Definition: xmlreportv2.h:40
QList< ErrorItem > read() override
Read contents of the report file.
bool open() override
Open existing report file.
Definition: xmlreportv2.cpp:84
static int determineVersion(const QString &filename)
Get the XML report format version from the file.
Definition: xmlreport.cpp:61
std::string toString(Color c)
Definition: color.cpp:54
@ internal
Internal message.
#define SETTINGS_SHOW_NO_ERRORS
Definition: common.h:70
#define PROGRESS_MAX
Definition: common.h:94
#define SETTINGS_MAINWND_SPLITTER_STATE
Definition: common.h:39
Definition: aboutdialog.h:27