Cppcheck
projectfiledialog.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 "projectfiledialog.h"
20 
21 #include "checkthread.h"
22 #include "common.h"
23 #include "importproject.h"
24 #include "library.h"
25 #include "newsuppressiondialog.h"
26 #include "platform.h"
27 #include "platforms.h"
28 #include "projectfile.h"
29 #include "settings.h"
30 
31 #include "ui_projectfile.h"
32 
33 #include <list>
34 #include <string>
35 #include <utility>
36 
37 #include <QByteArray>
38 #include <QCheckBox>
39 #include <QComboBox>
40 #include <QCoreApplication>
41 #include <QDialogButtonBox>
42 #include <QDir>
43 #include <QFileDialog>
44 #include <QFileInfo>
45 #include <QFlags>
46 #include <QLabel>
47 #include <QLineEdit>
48 #include <QListWidget>
49 #include <QListWidgetItem>
50 #include <QMap>
51 #include <QPushButton>
52 #include <QRadioButton>
53 #include <QRegularExpression>
54 #include <QRegularExpressionValidator>
55 #include <QSettings>
56 #include <QSize>
57 #include <QSpinBox>
58 #include <QVariant>
59 
60 static constexpr char ADDON_MISRA[] = "misra";
61 static constexpr char CODING_STANDARD_MISRA_C_2023[] = "misra-c-2023";
62 static constexpr char CODING_STANDARD_MISRA_CPP_2008[] = "misra-cpp-2008";
63 static constexpr char CODING_STANDARD_CERT_C[] = "cert-c-2016";
64 static constexpr char CODING_STANDARD_CERT_CPP[] = "cert-cpp-2016";
65 static constexpr char CODING_STANDARD_AUTOSAR[] = "autosar";
66 
67 /** Return paths from QListWidget */
68 static QStringList getPaths(const QListWidget *list)
69 {
70  const int count = list->count();
71  QStringList paths;
72  for (int i = 0; i < count; i++) {
73  QListWidgetItem *item = list->item(i);
74  paths << QDir::fromNativeSeparators(item->text());
75  }
76  return paths;
77 }
78 
79 /** Platforms shown in the platform combobox */
80 static constexpr Platform::Type builtinPlatforms[] = {
81  Platform::Type::Native,
82  Platform::Type::Win32A,
83  Platform::Type::Win32W,
84  Platform::Type::Win64,
85  Platform::Type::Unix32,
86  Platform::Type::Unix64
87 };
88 
89 static constexpr int numberOfBuiltinPlatforms = sizeof(builtinPlatforms) / sizeof(builtinPlatforms[0]);
90 
91 QStringList ProjectFileDialog::getProjectConfigs(const QString &fileName)
92 {
93  if (!fileName.endsWith(".sln") && !fileName.endsWith(".vcxproj"))
94  return QStringList();
95  QStringList ret;
96  ImportProject importer;
97  Settings projSettings;
98  importer.import(fileName.toStdString(), &projSettings);
99  for (const std::string &cfg : importer.getVSConfigs())
100  ret << QString::fromStdString(cfg);
101  return ret;
102 }
103 
104 ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, bool premium, QWidget *parent)
105  : QDialog(parent)
106  , mUI(new Ui::ProjectFile)
107  , mProjectFile(projectFile)
108  , mPremium(premium)
109 {
110  mUI->setupUi(this);
111 
112  mUI->mToolClangAnalyzer->hide();
113 
114  const QFileInfo inf(projectFile->getFilename());
115  QString filename = inf.fileName();
116  QString title = tr("Project file: %1").arg(filename);
117  setWindowTitle(title);
118  loadSettings();
119 
120  // Checkboxes for the libraries..
121  const QString applicationFilePath = QCoreApplication::applicationFilePath();
122  const QString appPath = QFileInfo(applicationFilePath).canonicalPath();
123  const QString datadir = getDataDir();
124  QStringList searchPaths;
125  searchPaths << appPath << appPath + "/cfg" << inf.canonicalPath();
126 #ifdef FILESDIR
127  if (FILESDIR[0])
128  searchPaths << FILESDIR << FILESDIR "/cfg";
129 #endif
130  if (!datadir.isEmpty())
131  searchPaths << datadir << datadir + "/cfg";
132  QStringList libs;
133  // Search the std.cfg first since other libraries could depend on it
134  QString stdLibraryFilename;
135  for (const QString &sp : searchPaths) {
136  QDir dir(sp);
137  dir.setSorting(QDir::Name);
138  dir.setNameFilters(QStringList("*.cfg"));
139  dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
140  for (const QFileInfo& item : dir.entryInfoList()) {
141  QString library = item.fileName();
142  if (library.compare("std.cfg", Qt::CaseInsensitive) != 0)
143  continue;
144  Library lib;
145  const QString fullfilename = sp + "/" + library;
146  const Library::Error err = lib.load(nullptr, fullfilename.toLatin1());
148  continue;
149  // Working std.cfg found
150  stdLibraryFilename = fullfilename;
151  break;
152  }
153  if (!stdLibraryFilename.isEmpty())
154  break;
155  }
156  // Search other libraries
157  for (const QString &sp : searchPaths) {
158  QDir dir(sp);
159  dir.setSorting(QDir::Name);
160  dir.setNameFilters(QStringList("*.cfg"));
161  dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
162  for (const QFileInfo& item : dir.entryInfoList()) {
163  QString library = item.fileName();
164  {
165  Library lib;
166  const QString fullfilename = sp + "/" + library;
167  Library::Error err = lib.load(nullptr, fullfilename.toLatin1());
168  if (err.errorcode != Library::ErrorCode::OK) {
169  // Some libraries depend on std.cfg so load it first and test again
170  lib.load(nullptr, stdLibraryFilename.toLatin1());
171  err = lib.load(nullptr, fullfilename.toLatin1());
172  }
174  continue;
175  }
176  library.chop(4);
177  if (library.compare("std", Qt::CaseInsensitive) == 0)
178  continue;
179  if (libs.indexOf(library) == -1)
180  libs << library;
181  }
182  }
183  libs.sort();
184  mUI->mLibraries->clear();
185  for (const QString &lib : libs) {
186  auto* item = new QListWidgetItem(lib, mUI->mLibraries);
187  item->setFlags(item->flags() | Qt::ItemIsUserCheckable); // set checkable flag
188  item->setCheckState(Qt::Unchecked); // AND initialize check state
189  }
190 
191  // Platforms..
192  Platforms platforms;
193  for (const Platform::Type builtinPlatform : builtinPlatforms)
194  mUI->mComboBoxPlatform->addItem(platforms.get(builtinPlatform).mTitle);
195  QStringList platformFiles;
196  for (QString sp : searchPaths) {
197  if (sp.endsWith("/cfg"))
198  sp = sp.mid(0,sp.length()-3) + "platforms";
199  QDir dir(sp);
200  dir.setSorting(QDir::Name);
201  dir.setNameFilters(QStringList("*.xml"));
202  dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
203  for (const QFileInfo& item : dir.entryInfoList()) {
204  const QString platformFile = item.fileName();
205 
206  Platform plat2;
207  if (!plat2.loadFromFile(applicationFilePath.toStdString().c_str(), platformFile.toStdString()))
208  continue;
209 
210  if (platformFiles.indexOf(platformFile) == -1)
211  platformFiles << platformFile;
212  }
213  }
214  platformFiles.sort();
215  mUI->mComboBoxPlatform->addItems(platformFiles);
216 
217  // integer. allow empty.
218  mUI->mEditCertIntPrecision->setValidator(new QRegularExpressionValidator(QRegularExpression("[0-9]*"),this));
219 
220  mUI->mEditTags->setValidator(new QRegularExpressionValidator(QRegularExpression("[a-zA-Z0-9 ;]*"),this));
221 
222  const QRegularExpression undefRegExp("\\s*([a-zA-Z_][a-zA-Z0-9_]*[; ]*)*");
223  mUI->mEditUndefines->setValidator(new QRegularExpressionValidator(undefRegExp, this));
224 
225  connect(mUI->mButtons, &QDialogButtonBox::accepted, this, &ProjectFileDialog::ok);
226  connect(mUI->mBtnBrowseBuildDir, &QPushButton::clicked, this, &ProjectFileDialog::browseBuildDir);
227  connect(mUI->mBtnClearImportProject, &QPushButton::clicked, this, &ProjectFileDialog::clearImportProject);
228  connect(mUI->mBtnBrowseImportProject, &QPushButton::clicked, this, &ProjectFileDialog::browseImportProject);
229  connect(mUI->mBtnAddCheckPath, SIGNAL(clicked()), this, SLOT(addCheckPath()));
230  connect(mUI->mBtnEditCheckPath, &QPushButton::clicked, this, &ProjectFileDialog::editCheckPath);
231  connect(mUI->mBtnRemoveCheckPath, &QPushButton::clicked, this, &ProjectFileDialog::removeCheckPath);
232  connect(mUI->mBtnAddInclude, SIGNAL(clicked()), this, SLOT(addIncludeDir()));
233  connect(mUI->mBtnEditInclude, &QPushButton::clicked, this, &ProjectFileDialog::editIncludeDir);
234  connect(mUI->mBtnRemoveInclude, &QPushButton::clicked, this, &ProjectFileDialog::removeIncludeDir);
235  connect(mUI->mBtnAddIgnorePath, SIGNAL(clicked()), this, SLOT(addExcludePath()));
236  connect(mUI->mBtnAddIgnoreFile, SIGNAL(clicked()), this, SLOT(addExcludeFile()));
237  connect(mUI->mBtnEditIgnorePath, &QPushButton::clicked, this, &ProjectFileDialog::editExcludePath);
238  connect(mUI->mBtnRemoveIgnorePath, &QPushButton::clicked, this, &ProjectFileDialog::removeExcludePath);
239  connect(mUI->mBtnIncludeUp, &QPushButton::clicked, this, &ProjectFileDialog::moveIncludePathUp);
240  connect(mUI->mBtnIncludeDown, &QPushButton::clicked, this, &ProjectFileDialog::moveIncludePathDown);
241  connect(mUI->mBtnAddSuppression, &QPushButton::clicked, this, &ProjectFileDialog::addSuppression);
242  connect(mUI->mBtnRemoveSuppression, &QPushButton::clicked, this, &ProjectFileDialog::removeSuppression);
243  connect(mUI->mListSuppressions, &QListWidget::doubleClicked, this, &ProjectFileDialog::editSuppression);
244  connect(mUI->mBtnBrowseMisraFile, &QPushButton::clicked, this, &ProjectFileDialog::browseMisraFile);
245  connect(mUI->mChkAllVsConfigs, &QCheckBox::clicked, this, &ProjectFileDialog::checkAllVSConfigs);
246  loadFromProjectFile(projectFile);
247 }
248 
250 {
251  saveSettings();
252  delete mUI;
253 }
254 
256 {
257  QSettings settings;
258  resize(settings.value(SETTINGS_PROJECT_DIALOG_WIDTH, 470).toInt(),
259  settings.value(SETTINGS_PROJECT_DIALOG_HEIGHT, 330).toInt());
260 }
261 
263 {
264  QSettings settings;
265  settings.setValue(SETTINGS_PROJECT_DIALOG_WIDTH, size().width());
266  settings.setValue(SETTINGS_PROJECT_DIALOG_HEIGHT, size().height());
267 }
268 
269 static void updateAddonCheckBox(QCheckBox *cb, const ProjectFile *projectFile, const QString &dataDir, const QString &addon)
270 {
271  if (projectFile)
272  cb->setChecked(projectFile->getAddons().contains(addon));
273  if (ProjectFile::getAddonFilePath(dataDir, addon).isEmpty()) {
274  cb->setEnabled(false);
275  cb->setText(cb->text() + QObject::tr(" (Not found)"));
276  }
277 }
278 
280 {
281  if (mUI->mChkAllVsConfigs->isChecked()) {
282  for (int row = 0; row < mUI->mListVsConfigs->count(); ++row) {
283  QListWidgetItem *item = mUI->mListVsConfigs->item(row);
284  item->setCheckState(Qt::Checked);
285  }
286  }
287  mUI->mListVsConfigs->setEnabled(!mUI->mChkAllVsConfigs->isChecked());
288 }
289 
291 {
292  setRootPath(projectFile->getRootPath());
293  setBuildDir(projectFile->getBuildDir());
294  setIncludepaths(projectFile->getIncludeDirs());
295  setDefines(projectFile->getDefines());
296  setUndefines(projectFile->getUndefines());
297  setCheckPaths(projectFile->getCheckPaths());
298  setImportProject(projectFile->getImportProject());
299  mUI->mChkAllVsConfigs->setChecked(projectFile->getAnalyzeAllVsConfigs());
300  setProjectConfigurations(getProjectConfigs(mUI->mEditImportProject->text()));
301  for (int row = 0; row < mUI->mListVsConfigs->count(); ++row) {
302  QListWidgetItem *item = mUI->mListVsConfigs->item(row);
303  if (projectFile->getAnalyzeAllVsConfigs() || projectFile->getVsConfigurations().contains(item->text()))
304  item->setCheckState(Qt::Checked);
305  else
306  item->setCheckState(Qt::Unchecked);
307  }
308  if (projectFile->isCheckLevelExhaustive())
309  mUI->mCheckLevelExhaustive->setChecked(true);
310  else
311  mUI->mCheckLevelNormal->setChecked(true);
312  mUI->mCheckHeaders->setChecked(projectFile->getCheckHeaders());
313  mUI->mCheckUnusedTemplates->setChecked(projectFile->getCheckUnusedTemplates());
314  mUI->mMaxCtuDepth->setValue(projectFile->getMaxCtuDepth());
315  mUI->mMaxTemplateRecursion->setValue(projectFile->getMaxTemplateRecursion());
316  if (projectFile->clangParser)
317  mUI->mBtnClangParser->setChecked(true);
318  else
319  mUI->mBtnCppcheckParser->setChecked(true);
320  mUI->mBtnSafeClasses->setChecked(projectFile->safeChecks.classes);
321  setExcludedPaths(projectFile->getExcludedPaths());
322  setLibraries(projectFile->getLibraries());
323  const QString platform = projectFile->getPlatform();
324  if (platform.endsWith(".xml")) {
325  int i;
326  for (i = numberOfBuiltinPlatforms; i < mUI->mComboBoxPlatform->count(); ++i) {
327  if (mUI->mComboBoxPlatform->itemText(i) == platform)
328  break;
329  }
330  if (i < mUI->mComboBoxPlatform->count())
331  mUI->mComboBoxPlatform->setCurrentIndex(i);
332  else {
333  mUI->mComboBoxPlatform->addItem(platform);
334  mUI->mComboBoxPlatform->setCurrentIndex(i);
335  }
336  } else {
337  int i;
338  for (i = 0; i < numberOfBuiltinPlatforms; ++i) {
339  const Platform::Type p = builtinPlatforms[i];
340  if (platform == Platform::toString(p))
341  break;
342  }
343  if (i < numberOfBuiltinPlatforms)
344  mUI->mComboBoxPlatform->setCurrentIndex(i);
345  else
346  mUI->mComboBoxPlatform->setCurrentIndex(-1);
347  }
348 
349  mUI->mComboBoxPlatform->setCurrentText(projectFile->getPlatform());
350  setSuppressions(projectFile->getSuppressions());
351 
352  // TODO
353  // Human knowledge..
354  /*
355  mUI->mListUnknownFunctionReturn->clear();
356  mUI->mListUnknownFunctionReturn->addItem("rand()");
357  for (int row = 0; row < mUI->mListUnknownFunctionReturn->count(); ++row) {
358  QListWidgetItem *item = mUI->mListUnknownFunctionReturn->item(row);
359  item->setFlags(item->flags() | Qt::ItemIsUserCheckable); // set checkable flag
360  const bool unknownValues = projectFile->getCheckUnknownFunctionReturn().contains(item->text());
361  item->setCheckState(unknownValues ? Qt::Checked : Qt::Unchecked); // AND initialize check state
362  }
363  mUI->mCheckSafeClasses->setChecked(projectFile->getSafeChecks().classes);
364  mUI->mCheckSafeExternalFunctions->setChecked(projectFile->getSafeChecks().externalFunctions);
365  mUI->mCheckSafeInternalFunctions->setChecked(projectFile->getSafeChecks().internalFunctions);
366  mUI->mCheckSafeExternalVariables->setChecked(projectFile->getSafeChecks().externalVariables);
367  */
368 
369  // Addons..
370  QSettings settings;
371  const QString dataDir = getDataDir();
372  updateAddonCheckBox(mUI->mAddonThreadSafety, projectFile, dataDir, "threadsafety");
373  updateAddonCheckBox(mUI->mAddonY2038, projectFile, dataDir, "y2038");
374 
375  // Misra checkbox..
376  mUI->mMisraC->setText(mPremium ? "Misra C" : "Misra C 2012");
377  updateAddonCheckBox(mUI->mMisraC, projectFile, dataDir, ADDON_MISRA);
378  mUI->mMisraVersion->setEnabled(mUI->mMisraC->isChecked());
379  connect(mUI->mMisraC, &QCheckBox::toggled, mUI->mMisraVersion, &QComboBox::setEnabled);
380 
381  const QString &misraFile = settings.value(SETTINGS_MISRA_FILE, QString()).toString();
382  mUI->mEditMisraFile->setText(misraFile);
383  mUI->mMisraVersion->setVisible(mPremium);
384  mUI->mMisraVersion->setCurrentIndex(projectFile->getCodingStandards().contains(CODING_STANDARD_MISRA_C_2023));
385  if (mPremium) {
386  mUI->mLabelMisraFile->setVisible(false);
387  mUI->mEditMisraFile->setVisible(false);
388  mUI->mBtnBrowseMisraFile->setVisible(false);
389  } else if (!mUI->mMisraC->isEnabled()) {
390  mUI->mEditMisraFile->setEnabled(false);
391  mUI->mBtnBrowseMisraFile->setEnabled(false);
392  }
393 
394  mUI->mCertC2016->setChecked(mPremium && projectFile->getCodingStandards().contains(CODING_STANDARD_CERT_C));
395  mUI->mCertCpp2016->setChecked(mPremium && projectFile->getCodingStandards().contains(CODING_STANDARD_CERT_CPP));
396  mUI->mMisraCpp2008->setChecked(mPremium && projectFile->getCodingStandards().contains(CODING_STANDARD_MISRA_CPP_2008));
397  mUI->mAutosar->setChecked(mPremium && projectFile->getCodingStandards().contains(CODING_STANDARD_AUTOSAR));
398 
399  if (projectFile->getCertIntPrecision() <= 0)
400  mUI->mEditCertIntPrecision->setText(QString());
401  else
402  mUI->mEditCertIntPrecision->setText(QString::number(projectFile->getCertIntPrecision()));
403 
404  mUI->mMisraCpp2008->setEnabled(mPremium);
405  mUI->mCertC2016->setEnabled(mPremium);
406  mUI->mCertCpp2016->setEnabled(mPremium);
407  mUI->mAutosar->setEnabled(mPremium);
408  mUI->mLabelCertIntPrecision->setVisible(mPremium);
409  mUI->mEditCertIntPrecision->setVisible(mPremium);
410  mUI->mBughunting->setChecked(mPremium && projectFile->getBughunting());
411  mUI->mBughunting->setEnabled(mPremium);
412 
413  mUI->mToolClangAnalyzer->setChecked(projectFile->getClangAnalyzer());
414  mUI->mToolClangTidy->setChecked(projectFile->getClangTidy());
415  if (CheckThread::clangTidyCmd().isEmpty()) {
416  mUI->mToolClangTidy->setText(tr("Clang-tidy (not found)"));
417  mUI->mToolClangTidy->setEnabled(false);
418  }
419  mUI->mEditTags->setText(projectFile->getTags().join(';'));
421 }
422 
424 {
425  projectFile->setRootPath(getRootPath());
426  projectFile->setBuildDir(getBuildDir());
427  projectFile->setImportProject(getImportProject());
428  projectFile->setAnalyzeAllVsConfigs(mUI->mChkAllVsConfigs->isChecked());
430  projectFile->setCheckHeaders(mUI->mCheckHeaders->isChecked());
431  projectFile->setCheckUnusedTemplates(mUI->mCheckUnusedTemplates->isChecked());
432  projectFile->setMaxCtuDepth(mUI->mMaxCtuDepth->value());
433  projectFile->setMaxTemplateRecursion(mUI->mMaxTemplateRecursion->value());
434  projectFile->setIncludes(getIncludePaths());
435  projectFile->setDefines(getDefines());
436  projectFile->setUndefines(getUndefines());
437  projectFile->setCheckPaths(getCheckPaths());
438  projectFile->setExcludedPaths(getExcludedPaths());
439  projectFile->setLibraries(getLibraries());
440  projectFile->setCheckLevel(mUI->mCheckLevelExhaustive->isChecked() ? ProjectFile::CheckLevel::exhaustive : ProjectFile::CheckLevel::normal);
441  projectFile->clangParser = mUI->mBtnClangParser->isChecked();
442  projectFile->safeChecks.classes = mUI->mBtnSafeClasses->isChecked();
443  if (mUI->mComboBoxPlatform->currentText().endsWith(".xml"))
444  projectFile->setPlatform(mUI->mComboBoxPlatform->currentText());
445  else {
446  const int i = mUI->mComboBoxPlatform->currentIndex();
447  if (i>=0 && i < numberOfBuiltinPlatforms)
449  else
450  projectFile->setPlatform(QString());
451  }
452  projectFile->setSuppressions(getSuppressions());
453  // Human knowledge
454  /*
455  QStringList unknownReturnValues;
456  for (int row = 0; row < mUI->mListUnknownFunctionReturn->count(); ++row) {
457  QListWidgetItem *item = mUI->mListUnknownFunctionReturn->item(row);
458  if (item->checkState() == Qt::Checked)
459  unknownReturnValues << item->text();
460  }
461  projectFile->setCheckUnknownFunctionReturn(unknownReturnValues);
462  ProjectFile::SafeChecks safeChecks;
463  safeChecks.classes = mUI->mCheckSafeClasses->isChecked();
464  safeChecks.externalFunctions = mUI->mCheckSafeExternalFunctions->isChecked();
465  safeChecks.internalFunctions = mUI->mCheckSafeInternalFunctions->isChecked();
466  safeChecks.externalVariables = mUI->mCheckSafeExternalVariables->isChecked();
467  projectFile->setSafeChecks(safeChecks);
468  */
469  // Addons
470  QStringList addons;
471  if (mUI->mAddonThreadSafety->isChecked())
472  addons << "threadsafety";
473  if (mUI->mAddonY2038->isChecked())
474  addons << "y2038";
475  if (mUI->mMisraC->isChecked())
476  addons << ADDON_MISRA;
477  projectFile->setAddons(addons);
478  QStringList codingStandards;
479  if (mUI->mCertC2016->isChecked())
480  codingStandards << CODING_STANDARD_CERT_C;
481  if (mUI->mCertCpp2016->isChecked())
482  codingStandards << CODING_STANDARD_CERT_CPP;
483  if (mPremium && mUI->mMisraVersion->currentIndex() == 1)
484  codingStandards << CODING_STANDARD_MISRA_C_2023;
485  if (mUI->mMisraCpp2008->isChecked())
486  codingStandards << CODING_STANDARD_MISRA_CPP_2008;
487  if (mUI->mAutosar->isChecked())
488  codingStandards << CODING_STANDARD_AUTOSAR;
489  projectFile->setCodingStandards(std::move(codingStandards));
490  projectFile->setCertIntPrecision(mUI->mEditCertIntPrecision->text().toInt());
491  projectFile->setBughunting(mUI->mBughunting->isChecked());
492  projectFile->setClangAnalyzer(mUI->mToolClangAnalyzer->isChecked());
493  projectFile->setClangTidy(mUI->mToolClangTidy->isChecked());
494 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
495  projectFile->setTags(mUI->mEditTags->text().split(";", Qt::SkipEmptyParts));
496 #else
497  projectFile->setTags(mUI->mEditTags->text().split(";", QString::SkipEmptyParts));
498 #endif
499 }
500 
502 {
504  mProjectFile->write();
505  accept();
506 }
507 
508 QString ProjectFileDialog::getExistingDirectory(const QString &caption, bool trailingSlash)
509 {
510  const QFileInfo inf(mProjectFile->getFilename());
511  const QString rootpath = inf.absolutePath();
512  QString selectedDir = QFileDialog::getExistingDirectory(this,
513  caption,
514  rootpath);
515 
516  if (selectedDir.isEmpty())
517  return QString();
518 
519  // Check if the path is relative to project file's path and if so
520  // make it a relative path instead of absolute path.
521  const QDir dir(rootpath);
522  const QString relpath(dir.relativeFilePath(selectedDir));
523  if (!relpath.startsWith("../.."))
524  selectedDir = relpath;
525 
526  // Trailing slash..
527  if (trailingSlash && !selectedDir.endsWith('/'))
528  selectedDir += '/';
529 
530  return selectedDir;
531 }
532 
534 {
535  const QString dir(getExistingDirectory(tr("Select Cppcheck build dir"), false));
536  if (!dir.isEmpty())
537  mUI->mEditBuildDir->setText(dir);
538 }
539 
541 {
542  const QString &fileName = mUI->mEditImportProject->text();
543  const bool importProject = !fileName.isEmpty();
544  const bool hasConfigs = fileName.endsWith(".sln") || fileName.endsWith(".vcxproj");
545  mUI->mBtnClearImportProject->setEnabled(importProject);
546  mUI->mListCheckPaths->setEnabled(!importProject);
547  mUI->mListIncludeDirs->setEnabled(!importProject);
548  mUI->mBtnAddCheckPath->setEnabled(!importProject);
549  mUI->mBtnEditCheckPath->setEnabled(!importProject);
550  mUI->mBtnRemoveCheckPath->setEnabled(!importProject);
551  mUI->mEditDefines->setEnabled(!importProject);
552  mUI->mEditUndefines->setEnabled(!importProject);
553  mUI->mBtnAddInclude->setEnabled(!importProject);
554  mUI->mBtnEditInclude->setEnabled(!importProject);
555  mUI->mBtnRemoveInclude->setEnabled(!importProject);
556  mUI->mBtnIncludeUp->setEnabled(!importProject);
557  mUI->mBtnIncludeDown->setEnabled(!importProject);
558  mUI->mChkAllVsConfigs->setEnabled(hasConfigs);
559  mUI->mListVsConfigs->setEnabled(hasConfigs && !mUI->mChkAllVsConfigs->isChecked());
560  if (!hasConfigs)
561  mUI->mListVsConfigs->clear();
562 }
563 
565 {
566  mUI->mEditImportProject->clear();
568 }
569 
571 {
572  const QFileInfo inf(mProjectFile->getFilename());
573  const QDir &dir = inf.absoluteDir();
574  QMap<QString,QString> filters;
575  filters[tr("Visual Studio")] = "*.sln *.vcxproj";
576  filters[tr("Compile database")] = "compile_commands.json";
577  filters[tr("Borland C++ Builder 6")] = "*.bpr";
578  QString fileName = QFileDialog::getOpenFileName(this, tr("Import Project"),
579  dir.canonicalPath(),
580  toFilterString(filters));
581  if (!fileName.isEmpty()) {
582  mUI->mEditImportProject->setText(dir.relativeFilePath(fileName));
585  for (int row = 0; row < mUI->mListVsConfigs->count(); ++row) {
586  QListWidgetItem *item = mUI->mListVsConfigs->item(row);
587  item->setCheckState(Qt::Checked);
588  }
589  }
590 }
591 
593 {
594  QStringList configs;
595  for (int row = 0; row < mUI->mListVsConfigs->count(); ++row) {
596  QListWidgetItem *item = mUI->mListVsConfigs->item(row);
597  if (item->checkState() == Qt::Checked)
598  configs << item->text();
599  }
600  return configs;
601 }
602 
603 void ProjectFileDialog::setProjectConfigurations(const QStringList &configs)
604 {
605  mUI->mListVsConfigs->clear();
606  mUI->mListVsConfigs->setEnabled(!configs.isEmpty() && !mUI->mChkAllVsConfigs->isChecked());
607  for (const QString &cfg : configs) {
608  auto* item = new QListWidgetItem(cfg, mUI->mListVsConfigs);
609  item->setFlags(item->flags() | Qt::ItemIsUserCheckable); // set checkable flag
610  item->setCheckState(Qt::Unchecked);
611  }
612 }
613 
615 {
616  return mUI->mEditImportProject->text();
617 }
618 
619 void ProjectFileDialog::addIncludeDir(const QString &dir)
620 {
621  if (dir.isEmpty())
622  return;
623 
624  const QString newdir = QDir::toNativeSeparators(dir);
625  auto *item = new QListWidgetItem(newdir);
626  item->setFlags(item->flags() | Qt::ItemIsEditable);
627  mUI->mListIncludeDirs->addItem(item);
628 }
629 
630 void ProjectFileDialog::addCheckPath(const QString &path)
631 {
632  if (path.isEmpty())
633  return;
634 
635  const QString newpath = QDir::toNativeSeparators(path);
636  auto *item = new QListWidgetItem(newpath);
637  item->setFlags(item->flags() | Qt::ItemIsEditable);
638  mUI->mListCheckPaths->addItem(item);
639 }
640 
641 void ProjectFileDialog::addExcludePath(const QString &path)
642 {
643  if (path.isEmpty())
644  return;
645 
646  const QString newpath = QDir::toNativeSeparators(path);
647  auto *item = new QListWidgetItem(newpath);
648  item->setFlags(item->flags() | Qt::ItemIsEditable);
649  mUI->mListExcludedPaths->addItem(item);
650 }
651 
653 {
654  QString root = mUI->mEditProjectRoot->text();
655  root = root.trimmed();
656  root = QDir::fromNativeSeparators(root);
657  return root;
658 }
659 
661 {
662  return mUI->mEditBuildDir->text();
663 }
664 
666 {
667  return getPaths(mUI->mListIncludeDirs);
668 }
669 
670 QStringList ProjectFileDialog::getDefines() const
671 {
672 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
673  return mUI->mEditDefines->text().trimmed().split(QRegularExpression("\\s*;\\s*"), Qt::SkipEmptyParts);
674 #else
675  return mUI->mEditDefines->text().trimmed().split(QRegularExpression("\\s*;\\s*"), QString::SkipEmptyParts);
676 #endif
677 }
678 
680 {
681  const QString undefine = mUI->mEditUndefines->text().trimmed();
682 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
683  QStringList undefines = undefine.split(QRegularExpression("\\s*;\\s*"), Qt::SkipEmptyParts);
684 #else
685  QStringList undefines = undefine.split(QRegularExpression("\\s*;\\s*"), QString::SkipEmptyParts);
686 #endif
687  undefines.removeDuplicates();
688  return undefines;
689 }
690 
692 {
693  return getPaths(mUI->mListCheckPaths);
694 }
695 
697 {
698  return getPaths(mUI->mListExcludedPaths);
699 }
700 
702 {
703  QStringList libraries;
704  for (int row = 0; row < mUI->mLibraries->count(); ++row) {
705  QListWidgetItem *item = mUI->mLibraries->item(row);
706  if (item->checkState() == Qt::Checked)
707  libraries << item->text();
708  }
709  return libraries;
710 }
711 
712 void ProjectFileDialog::setRootPath(const QString &root)
713 {
714  mUI->mEditProjectRoot->setText(QDir::toNativeSeparators(root));
715 }
716 
717 void ProjectFileDialog::setBuildDir(const QString &buildDir)
718 {
719  mUI->mEditBuildDir->setText(buildDir);
720 }
721 
722 void ProjectFileDialog::setImportProject(const QString &importProject)
723 {
724  mUI->mEditImportProject->setText(importProject);
725 }
726 
727 void ProjectFileDialog::setIncludepaths(const QStringList &includes)
728 {
729  for (const QString& dir : includes) {
730  addIncludeDir(dir);
731  }
732 }
733 
734 void ProjectFileDialog::setDefines(const QStringList &defines)
735 {
736  mUI->mEditDefines->setText(defines.join(";"));
737 }
738 
739 void ProjectFileDialog::setUndefines(const QStringList &undefines)
740 {
741  mUI->mEditUndefines->setText(undefines.join(";"));
742 }
743 
744 void ProjectFileDialog::setCheckPaths(const QStringList &paths)
745 {
746  for (const QString& path : paths) {
747  addCheckPath(path);
748  }
749 }
750 
751 void ProjectFileDialog::setExcludedPaths(const QStringList &paths)
752 {
753  for (const QString& path : paths) {
754  addExcludePath(path);
755  }
756 }
757 
758 void ProjectFileDialog::setLibraries(const QStringList &libraries)
759 {
760  for (int row = 0; row < mUI->mLibraries->count(); ++row) {
761  QListWidgetItem *item = mUI->mLibraries->item(row);
762  item->setCheckState(libraries.contains(item->text()) ? Qt::Checked : Qt::Unchecked);
763  }
764 }
765 
767 {
768  mSuppressions += suppression;
769  mUI->mListSuppressions->addItem(QString::fromStdString(suppression.getText()));
770 }
771 
772 void ProjectFileDialog::setSuppressions(const QList<SuppressionList::Suppression> &suppressions)
773 {
774  mUI->mListSuppressions->clear();
775  QList<SuppressionList::Suppression> new_suppressions = suppressions;
776  mSuppressions.clear();
777  for (const SuppressionList::Suppression &suppression : new_suppressions) {
778  addSingleSuppression(suppression);
779  }
780  mUI->mListSuppressions->sortItems();
781 }
782 
784 {
785  QString dir = getExistingDirectory(tr("Select a directory to check"), false);
786  if (!dir.isEmpty())
787  addCheckPath(dir);
788 }
789 
791 {
792  QListWidgetItem *item = mUI->mListCheckPaths->currentItem();
793  mUI->mListCheckPaths->editItem(item);
794 }
795 
797 {
798  const int row = mUI->mListCheckPaths->currentRow();
799  QListWidgetItem *item = mUI->mListCheckPaths->takeItem(row);
800  delete item;
801 }
802 
804 {
805  const QString dir = getExistingDirectory(tr("Select include directory"), true);
806  if (!dir.isEmpty())
807  addIncludeDir(dir);
808 }
809 
811 {
812  const int row = mUI->mListIncludeDirs->currentRow();
813  QListWidgetItem *item = mUI->mListIncludeDirs->takeItem(row);
814  delete item;
815 }
816 
818 {
819  QListWidgetItem *item = mUI->mListIncludeDirs->currentItem();
820  mUI->mListIncludeDirs->editItem(item);
821 }
822 
824 {
825  addExcludePath(getExistingDirectory(tr("Select directory to ignore"), true));
826 }
827 
829 {
830  const QFileInfo inf(mProjectFile->getFilename());
831  const QDir &dir = inf.absoluteDir();
832  QMap<QString,QString> filters;
833  filters[tr("Source files")] = "*.c *.cpp";
834  filters[tr("All files")] = "*.*";
835  addExcludePath(QFileDialog::getOpenFileName(this, tr("Exclude file"), dir.canonicalPath(), toFilterString(filters)));
836 }
837 
839 {
840  QListWidgetItem *item = mUI->mListExcludedPaths->currentItem();
841  mUI->mListExcludedPaths->editItem(item);
842 }
843 
845 {
846  const int row = mUI->mListExcludedPaths->currentRow();
847  QListWidgetItem *item = mUI->mListExcludedPaths->takeItem(row);
848  delete item;
849 }
850 
852 {
853  int row = mUI->mListIncludeDirs->currentRow();
854  QListWidgetItem *item = mUI->mListIncludeDirs->takeItem(row);
855  row = row > 0 ? row - 1 : 0;
856  mUI->mListIncludeDirs->insertItem(row, item);
857  mUI->mListIncludeDirs->setCurrentItem(item);
858 }
859 
861 {
862  int row = mUI->mListIncludeDirs->currentRow();
863  QListWidgetItem *item = mUI->mListIncludeDirs->takeItem(row);
864  const int count = mUI->mListIncludeDirs->count();
865  row = row < count ? row + 1 : count;
866  mUI->mListIncludeDirs->insertItem(row, item);
867  mUI->mListIncludeDirs->setCurrentItem(item);
868 }
869 
871 {
873  if (dlg.exec() == QDialog::Accepted) {
875  }
876 }
877 
879 {
880  const int row = mUI->mListSuppressions->currentRow();
881  QListWidgetItem *item = mUI->mListSuppressions->takeItem(row);
882  if (!item)
883  return;
884 
885  const int suppressionIndex = getSuppressionIndex(item->text());
886  if (suppressionIndex >= 0)
887  mSuppressions.removeAt(suppressionIndex);
888  delete item;
889 }
890 
891 void ProjectFileDialog::editSuppression(const QModelIndex & /*index*/)
892 {
893  const int row = mUI->mListSuppressions->currentRow();
894  QListWidgetItem *item = mUI->mListSuppressions->item(row);
895  const int suppressionIndex = getSuppressionIndex(item->text());
896  if (suppressionIndex >= 0) { // TODO what if suppression is not found?
898  dlg.setSuppression(mSuppressions[suppressionIndex]);
899  if (dlg.exec() == QDialog::Accepted) {
900  mSuppressions[suppressionIndex] = dlg.getSuppression();
902  }
903  }
904 }
905 
906 int ProjectFileDialog::getSuppressionIndex(const QString &shortText) const
907 {
908  const std::string s = shortText.toStdString();
909  for (int i = 0; i < mSuppressions.size(); ++i) {
910  if (mSuppressions[i].getText() == s)
911  return i;
912  }
913  return -1;
914 }
915 
917 {
918  const QString fileName = QFileDialog::getOpenFileName(this,
919  tr("Select MISRA rule texts file"),
920  QDir::homePath(),
921  tr("MISRA rule texts file (%1)").arg("*.txt"));
922  if (!fileName.isEmpty()) {
923  QSettings settings;
924  mUI->mEditMisraFile->setText(fileName);
925  settings.setValue(SETTINGS_MISRA_FILE, fileName);
926 
927  mUI->mMisraC->setText("MISRA C 2012");
928  mUI->mMisraC->setEnabled(true);
929  updateAddonCheckBox(mUI->mMisraC, nullptr, getDataDir(), ADDON_MISRA);
930  }
931 }
static QString clangTidyCmd()
Determine command to run clang-tidy.
Importing project settings.
Definition: importproject.h:52
std::list< std::string > getVSConfigs()
Type import(const std::string &filename, Settings *settings=nullptr)
ErrorCode errorcode
Definition: library.h:74
Library definitions handling.
Definition: library.h:52
Error load(const char exename[], const char path[])
Definition: library.cpp:68
SuppressionList::Suppression getSuppression() const
Translate the user input in the GUI into a suppression.
void setSuppression(const SuppressionList::Suppression &suppression)
Update the GUI so it corresponds with the given Cppcheck suppression.
Platform settings.
Definition: platform.h:43
bool loadFromFile(const char exename[], const std::string &filename, bool verbose=false)
load platform file
Definition: platform.cpp:192
const char * toString() const
Definition: platform.h:148
List of checked platforms.
Definition: platforms.h:45
PlatformData & get(Platform::Type platform)
Definition: platforms.cpp:51
int getSuppressionIndex(const QString &shortText) const
Get mSuppressions index that match the given short text.
void updatePathsAndDefines()
Enable and disable widgets in the 'Paths and Defines' tab.
ProjectFileDialog(ProjectFile *projectFile, bool premium, QWidget *parent=nullptr)
bool mPremium
Is this Cppcheck Premium?
void ok()
ok button pressed, save changes and accept
void browseBuildDir()
Browse for build dir.
void setExcludedPaths(const QStringList &paths)
Set excluded paths to dialog control.
QStringList getLibraries() const
Return selected libraries from the dialog control.
QString getExistingDirectory(const QString &caption, bool trailingSlash)
QString getBuildDir() const
Get Cppcheck build dir.
void setCheckPaths(const QStringList &paths)
Set check paths to dialog control.
void moveIncludePathUp()
Move include path up in the list.
void addExcludePath()
Add new path to exclude list.
void editSuppression(const QModelIndex &index)
Edit suppression (double clicking on suppression)
void saveSettings() const
Load dialog settings.
void removeExcludePath()
Remove excluded path from the list.
QString getImportProject() const
void setBuildDir(const QString &buildDir)
Set build dir.
QStringList getExcludedPaths() const
Return excluded paths from the dialog control.
void addExcludeFile()
Add new file to exclude list.
static QStringList getProjectConfigs(const QString &fileName)
void clearImportProject()
Clear 'import project'.
void moveIncludePathDown()
Move include path down in the list.
void loadFromProjectFile(const ProjectFile *projectFile)
void addCheckPath()
Add new path to check.
void addSuppression()
Add suppression to the list.
void setImportProject(const QString &importProject)
void editExcludePath()
Edit excluded path in the list.
void loadSettings()
Save dialog settings.
void setProjectConfigurations(const QStringList &configs)
void browseImportProject()
Browse for solution / project / compile database.
QStringList getCheckPaths() const
Return check paths from the dialog control.
void removeIncludeDir()
Remove include directory from the list.
void setIncludepaths(const QStringList &includes)
Set include paths to dialog control.
const QList< SuppressionList::Suppression > & getSuppressions() const
Return suppressions from the dialog control.
void setRootPath(const QString &root)
Set project root path to dialog control.
QStringList getProjectConfigurations() const
void addIncludeDir()
Browse for include directory.
void addSingleSuppression(const SuppressionList::Suppression &suppression)
Add a single suppression to dialog control.
QStringList getDefines() const
Return define names from the dialog control.
void browseMisraFile()
Browse for misra file.
void checkAllVSConfigs()
Check for all VS configurations.
void saveToProjectFile(ProjectFile *projectFile) const
QString getRootPath() const
Return project root path from the dialog control.
QStringList getIncludePaths() const
Return include paths from the dialog control.
void removeSuppression()
Remove selected suppression from the list.
void editIncludeDir()
Edit include directory in the list.
void setUndefines(const QStringList &undefines)
Set undefine names to dialog control.
void removeCheckPath()
Remove path from the list.
void setLibraries(const QStringList &libraries)
Set libraries to dialog control.
void setSuppressions(const QList< SuppressionList::Suppression > &suppressions)
Set suppressions to dialog control.
QStringList getUndefines() const
Return undefine names from the dialog control.
QList< SuppressionList::Suppression > mSuppressions
void setDefines(const QStringList &defines)
Set define names to dialog control.
void editCheckPath()
Edit path in the list.
ProjectFile * mProjectFile
Projectfile path.
Ui::ProjectFile * mUI
A class that reads and writes project files.
Definition: projectfile.h:46
void setMaxCtuDepth(int maxCtuDepth)
Definition: projectfile.h:241
SafeChecks safeChecks
Definition: projectfile.h:414
const QStringList & getCodingStandards() const
Get list of coding standards (checked by Cppcheck Premium).
Definition: projectfile.h:370
bool clangParser
Use Clang parser.
Definition: projectfile.h:427
void setAnalyzeAllVsConfigs(bool b)
Definition: projectfile.h:277
int getMaxCtuDepth() const
Definition: projectfile.h:237
const QStringList & getAddons() const
Get list addons.
Definition: projectfile.h:200
const QString & getPlatform() const
Get platform.
Definition: projectfile.h:170
void setCheckPaths(const QStringList &paths)
Set list of paths to check.
void setCheckLevel(CheckLevel checkLevel)
CheckLevel: normal/exhaustive.
bool isCheckLevelExhaustive() const
const QString & getFilename() const
Get filename for the project file.
Definition: projectfile.h:257
const QString & getRootPath() const
Get project root path.
Definition: projectfile.h:78
void setCodingStandards(QStringList codingStandards)
Set list of coding standards (checked by Cppcheck Premium).
Definition: projectfile.h:378
bool getBughunting() const
Definition: projectfile.h:365
bool getClangAnalyzer() const
Definition: projectfile.h:217
void setBuildDir(const QString &buildDir)
Definition: projectfile.h:269
void setCheckHeaders(bool b)
Definition: projectfile.h:98
const QList< SuppressionList::Suppression > & getSuppressions() const
Get "raw" suppressions.
Definition: projectfile.h:186
void setTags(const QStringList &tags)
Set tags.
Definition: projectfile.h:351
void setExcludedPaths(const QStringList &paths)
Set list of paths to exclude from the check.
const QStringList & getDefines() const
Get list of defines.
Definition: projectfile.h:122
void setClangTidy(bool c)
Definition: projectfile.h:229
void setVSConfigurations(const QStringList &vsConfigs)
Set list of Visual Studio configurations to be checked.
QStringList getCheckPaths() const
Get list of paths to check.
Definition: projectfile.h:138
void setDefines(const QStringList &defines)
Set list of defines.
void setCertIntPrecision(int p)
Cert C: int precision.
Definition: projectfile.h:383
void setUndefines(const QStringList &undefines)
Set list of undefines.
void setIncludes(const QStringList &includes)
Set list of includes.
bool getClangTidy() const
Definition: projectfile.h:225
bool getAnalyzeAllVsConfigs() const
Definition: projectfile.h:90
int getCertIntPrecision() const
Definition: projectfile.h:386
int getMaxTemplateRecursion() const
Definition: projectfile.h:245
const QStringList & getUndefines() const
Get list of undefines.
Definition: projectfile.h:130
void setImportProject(const QString &importProject)
Definition: projectfile.h:273
void setLibraries(const QStringList &libraries)
Set list of libraries.
const QStringList & getVsConfigurations() const
Get list of paths to exclude from the check.
Definition: projectfile.h:154
static QString getAddonFilePath(QString filesDir, const QString &addon)
Get path to addon python script.
const QStringList & getTags() const
Definition: projectfile.h:233
void setMaxTemplateRecursion(int maxTemplateRecursion)
Definition: projectfile.h:249
void setAddons(const QStringList &addons)
Set list of addons.
bool getCheckUnusedTemplates() const
Definition: projectfile.h:102
void setPlatform(const QString &platform)
Set platform.
QStringList getExcludedPaths() const
Get list of paths to exclude from the check.
Definition: projectfile.h:146
void setBughunting(bool bughunting)
Bughunting (Cppcheck Premium)
Definition: projectfile.h:362
void setRootPath(const QString &rootpath)
Set project root path.
Definition: projectfile.h:265
QStringList getIncludeDirs() const
Get list of include directories.
Definition: projectfile.h:114
bool getCheckHeaders() const
Definition: projectfile.h:94
void setCheckUnusedTemplates(bool b)
Definition: projectfile.h:106
const QStringList & getLibraries() const
Get list libraries.
Definition: projectfile.h:162
const QString & getBuildDir() const
Definition: projectfile.h:82
void setClangAnalyzer(bool c)
Definition: projectfile.h:221
bool write(const QString &filename=QString())
Write project file (to disk).
void setSuppressions(const QList< SuppressionList::Suppression > &suppressions)
Set list of suppressions.
const QString & getImportProject() const
Definition: projectfile.h:86
This is just a container for general settings so that we don't need to pass individual values to func...
Definition: settings.h:95
#define SETTINGS_PROJECT_DIALOG_HEIGHT
Definition: common.h:43
QString getDataDir()
Get configured data dir.
Definition: common.cpp:75
QString toFilterString(const QMap< QString, QString > &filters, bool addAllSupported, bool addAll)
Creates a string suitable for passing as the filter argument to methods like QFileDialog::getOpenFile...
Definition: common.cpp:52
#define SETTINGS_PROJECT_DIALOG_WIDTH
Definition: common.h:42
#define SETTINGS_MISRA_FILE
Definition: common.h:81
static constexpr char Name[]
Definition: aboutdialog.h:27
static std::string cfg(const std::vector< std::string > &configs, const std::string &userDefines)
static constexpr int numberOfBuiltinPlatforms
static constexpr Platform::Type builtinPlatforms[]
Platforms shown in the platform combobox.
static constexpr char ADDON_MISRA[]
static constexpr char CODING_STANDARD_CERT_CPP[]
static QStringList getPaths(const QListWidget *list)
Return paths from QListWidget.
static constexpr char CODING_STANDARD_CERT_C[]
static constexpr char CODING_STANDARD_MISRA_C_2023[]
static void updateAddonCheckBox(QCheckBox *cb, const ProjectFile *projectFile, const QString &dataDir, const QString &addon)
static constexpr char CODING_STANDARD_MISRA_CPP_2008[]
static constexpr char CODING_STANDARD_AUTOSAR[]
QString mTitle
Text visible in the GUI.
Definition: platforms.h:37
bool classes
Public interface of classes.
Definition: settings.h:334
std::string getText() const