2009-03-01 08:38:21 +01:00
/*
* Cppcheck - A tool for static C / C + + code analysis
2023-01-28 10:16:34 +01:00
* Copyright ( C ) 2007 - 2023 Cppcheck team .
2009-03-01 08:38:21 +01:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2009-09-27 17:08:31 +02:00
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
2009-03-01 08:38:21 +01:00
*/
2021-04-03 21:30:50 +02:00
# include "mainwindow.h"
2023-10-09 10:07:20 +02:00
# include "addoninfo.h"
2012-10-07 12:25:34 +02:00
# include "applicationlist.h"
2009-06-04 14:35:41 +02:00
# include "aboutdialog.h"
2022-04-13 12:24:00 +02:00
# include "analyzerinfo.h"
2012-10-07 12:25:34 +02:00
# include "common.h"
2022-02-02 16:17:28 +01:00
# include "cppcheck.h"
2022-04-13 12:24:00 +02:00
# include "errortypes.h"
2020-07-20 11:59:28 +02:00
# include "filelist.h"
2023-11-02 17:42:41 +01:00
# include "filesettings.h"
2023-01-30 14:59:45 +01:00
# include "compliancereportdialog.h"
2009-06-14 11:57:43 +02:00
# include "fileviewdialog.h"
2020-08-25 19:58:52 +02:00
# include "helpdialog.h"
2022-04-13 12:24:00 +02:00
# include "importproject.h"
2020-07-20 11:59:28 +02:00
# include "librarydialog.h"
2022-04-13 12:24:00 +02:00
# include "platform.h"
2009-06-22 10:57:17 +02:00
# include "projectfile.h"
2017-07-31 12:02:51 +02:00
# include "projectfiledialog.h"
2009-07-06 11:30:49 +02:00
# include "report.h"
2022-04-13 12:24:00 +02:00
# include "resultsview.h"
2012-10-20 20:14:52 +02:00
# include "scratchpad.h"
2020-07-20 11:59:28 +02:00
# include "showtypes.h"
2010-09-01 08:12:24 +02:00
# include "statsdialog.h"
2012-10-07 12:25:34 +02:00
# include "settingsdialog.h"
2022-04-13 12:24:00 +02:00
# include "standards.h"
# include "suppressions.h"
2020-07-20 11:59:28 +02:00
# include "threadhandler.h"
2012-10-20 20:14:52 +02:00
# include "threadresult.h"
2012-10-07 12:25:34 +02:00
# include "translationhandler.h"
2011-03-26 15:06:11 +01:00
2022-03-19 19:54:20 +01:00
# include "ui_mainwindow.h"
2022-04-13 12:24:00 +02:00
# include <algorithm>
2023-04-08 16:08:47 +02:00
# include <iterator>
2022-04-13 12:24:00 +02:00
# include <list>
# include <set>
# include <string>
2023-04-08 16:08:47 +02:00
# include <unordered_set>
2023-10-09 10:07:20 +02:00
# include <utility>
2022-04-13 12:24:00 +02:00
# include <vector>
2022-02-02 16:17:28 +01:00
# include <QApplication>
# include <QAction>
# include <QActionGroup>
2023-04-08 16:08:47 +02:00
# include <QByteArray>
# include <QChar>
2022-03-19 19:54:20 +01:00
# include <QCloseEvent>
2023-04-08 16:08:47 +02:00
# include <QCoreApplication>
# include <QDateTime>
2022-02-02 16:17:28 +01:00
# include <QDebug>
2023-04-08 16:08:47 +02:00
# include <QDialog>
2022-02-02 16:17:28 +01:00
# include <QDir>
# include <QFile>
# include <QFileInfo>
2023-04-08 16:08:47 +02:00
# include <QHBoxLayout>
2022-02-02 16:17:28 +01:00
# include <QInputDialog>
2023-04-08 16:08:47 +02:00
# include <QKeySequence>
# include <QLabel>
# include <QLineEdit>
# include <QList>
# include <QMap>
# include <QMenu>
2022-02-02 16:17:28 +01:00
# include <QMessageBox>
2023-04-08 16:08:47 +02:00
# include <QtNetwork/QNetworkAccessManager>
# include <QtNetwork/QNetworkReply>
# include <QtNetwork/QNetworkRequest>
# include <QPushButton>
2022-03-23 18:16:22 +01:00
# include <QRegularExpression>
2022-02-02 16:17:28 +01:00
# include <QSettings>
2023-04-08 16:08:47 +02:00
# include <QSize>
2022-02-02 16:17:28 +01:00
# include <QTimer>
2023-01-30 14:59:45 +01:00
# include <QTemporaryFile>
2023-04-08 16:08:47 +02:00
# include <QToolBar>
# include <QUrl>
# include <QVariant>
# include <Qt>
2022-02-02 16:17:28 +01:00
2016-10-01 11:25:58 +02:00
static const QString compile_commands_json ( " compile_commands.json " ) ;
2009-03-01 08:38:21 +01:00
2022-10-30 10:59:43 +01:00
static QString fromNativePath ( const QString & p ) {
# ifdef Q_OS_WIN
QString ret ( p ) ;
ret . replace ( ' \\ ' , ' / ' ) ;
return ret ;
# else
return p ;
# endif
}
2013-03-01 19:11:27 +01:00
MainWindow : : MainWindow ( TranslationHandler * th , QSettings * settings ) :
mSettings ( settings ) ,
2010-04-15 20:08:51 +02:00
mApplications ( new ApplicationList ( this ) ) ,
2013-03-01 19:11:27 +01:00
mTranslation ( th ) ,
2022-03-19 19:54:20 +01:00
mUI ( new Ui : : MainWindow ) ,
2011-12-27 11:46:21 +01:00
mPlatformActions ( new QActionGroup ( this ) ) ,
2013-03-02 13:01:21 +01:00
mCStandardActions ( new QActionGroup ( this ) ) ,
mCppStandardActions ( new QActionGroup ( this ) ) ,
2023-08-08 11:05:02 +02:00
mSelectLanguageActions ( new QActionGroup ( this ) )
2009-07-02 10:32:29 +02:00
{
2022-03-24 22:44:47 +01:00
{
Settings tempSettings ;
2022-10-08 17:05:18 +02:00
tempSettings . exename = QCoreApplication : : applicationFilePath ( ) . toStdString ( ) ;
2022-03-24 22:44:47 +01:00
tempSettings . loadCppcheckCfg ( ) ;
mCppcheckCfgProductName = QString : : fromStdString ( tempSettings . cppcheckCfgProductName ) ;
mCppcheckCfgAbout = QString : : fromStdString ( tempSettings . cppcheckCfgAbout ) ;
}
2022-03-19 19:54:20 +01:00
mUI - > setupUi ( this ) ;
2009-06-20 18:55:23 +02:00
mThread = new ThreadHandler ( this ) ;
2022-03-19 19:54:20 +01:00
mUI - > mResults - > initialize ( mSettings , mApplications , mThread ) ;
2009-05-24 10:53:29 +02:00
2011-05-04 07:30:54 +02:00
// Filter timer to delay filtering results slightly while typing
mFilterTimer = new QTimer ( this ) ;
mFilterTimer - > setInterval ( 500 ) ;
mFilterTimer - > setSingleShot ( true ) ;
2017-07-31 07:36:42 +02:00
connect ( mFilterTimer , & QTimer : : timeout , this , & MainWindow : : filterResults ) ;
2011-05-04 07:30:54 +02:00
// "Filter" toolbar
2022-03-19 19:54:20 +01:00
mLineEditFilter = new QLineEdit ( mUI - > mToolBarFilter ) ;
2011-05-04 07:30:54 +02:00
mLineEditFilter - > setPlaceholderText ( tr ( " Quick Filter: " ) ) ;
2019-01-15 10:35:23 +01:00
mLineEditFilter - > setClearButtonEnabled ( true ) ;
2022-03-19 19:54:20 +01:00
mUI - > mToolBarFilter - > addWidget ( mLineEditFilter ) ;
2023-08-22 12:01:30 +02:00
connect ( mLineEditFilter , SIGNAL ( textChanged ( QString ) ) , mFilterTimer , SLOT ( start ( ) ) ) ;
2017-07-31 07:36:42 +02:00
connect ( mLineEditFilter , & QLineEdit : : returnPressed , this , & MainWindow : : filterResults ) ;
2011-05-04 07:30:54 +02:00
2022-03-19 19:54:20 +01:00
connect ( mUI - > mActionPrint , SIGNAL ( triggered ( ) ) , mUI - > mResults , SLOT ( print ( ) ) ) ;
connect ( mUI - > mActionPrintPreview , SIGNAL ( triggered ( ) ) , mUI - > mResults , SLOT ( printPreview ( ) ) ) ;
connect ( mUI - > mActionQuit , & QAction : : triggered , this , & MainWindow : : close ) ;
connect ( mUI - > mActionAnalyzeFiles , & QAction : : triggered , this , & MainWindow : : analyzeFiles ) ;
connect ( mUI - > mActionAnalyzeDirectory , & QAction : : triggered , this , & MainWindow : : analyzeDirectory ) ;
connect ( mUI - > mActionSettings , & QAction : : triggered , this , & MainWindow : : programSettings ) ;
connect ( mUI - > mActionClearResults , & QAction : : triggered , this , & MainWindow : : clearResults ) ;
connect ( mUI - > mActionOpenXML , & QAction : : triggered , this , & MainWindow : : openResults ) ;
connect ( mUI - > mActionShowStyle , & QAction : : toggled , this , & MainWindow : : showStyle ) ;
connect ( mUI - > mActionShowErrors , & QAction : : toggled , this , & MainWindow : : showErrors ) ;
connect ( mUI - > mActionShowWarnings , & QAction : : toggled , this , & MainWindow : : showWarnings ) ;
connect ( mUI - > mActionShowPortability , & QAction : : toggled , this , & MainWindow : : showPortability ) ;
connect ( mUI - > mActionShowPerformance , & QAction : : toggled , this , & MainWindow : : showPerformance ) ;
connect ( mUI - > mActionShowInformation , & QAction : : toggled , this , & MainWindow : : showInformation ) ;
connect ( mUI - > mActionShowCppcheck , & QAction : : toggled , mUI - > mResults , & ResultsView : : showCppcheckResults ) ;
connect ( mUI - > mActionShowClang , & QAction : : toggled , mUI - > mResults , & ResultsView : : showClangResults ) ;
connect ( mUI - > mActionCheckAll , & QAction : : triggered , this , & MainWindow : : checkAll ) ;
connect ( mUI - > mActionUncheckAll , & QAction : : triggered , this , & MainWindow : : uncheckAll ) ;
connect ( mUI - > mActionCollapseAll , & QAction : : triggered , mUI - > mResults , & ResultsView : : collapseAllResults ) ;
connect ( mUI - > mActionExpandAll , & QAction : : triggered , mUI - > mResults , & ResultsView : : expandAllResults ) ;
connect ( mUI - > mActionShowHidden , & QAction : : triggered , mUI - > mResults , & ResultsView : : showHiddenResults ) ;
connect ( mUI - > mActionViewStats , & QAction : : triggered , this , & MainWindow : : showStatistics ) ;
connect ( mUI - > mActionLibraryEditor , & QAction : : triggered , this , & MainWindow : : showLibraryEditor ) ;
connect ( mUI - > mActionReanalyzeModified , & QAction : : triggered , this , & MainWindow : : reAnalyzeModified ) ;
connect ( mUI - > mActionReanalyzeAll , & QAction : : triggered , this , & MainWindow : : reAnalyzeAll ) ;
connect ( mUI - > mActionCheckLibrary , & QAction : : triggered , this , & MainWindow : : checkLibrary ) ;
connect ( mUI - > mActionCheckConfiguration , & QAction : : triggered , this , & MainWindow : : checkConfiguration ) ;
connect ( mUI - > mActionStop , & QAction : : triggered , this , & MainWindow : : stopAnalysis ) ;
connect ( mUI - > mActionSave , & QAction : : triggered , this , & MainWindow : : save ) ;
2023-01-30 14:59:45 +01:00
connect ( mUI - > mActionComplianceReport , & QAction : : triggered , this , & MainWindow : : complianceReport ) ;
2009-05-24 10:53:29 +02:00
2011-05-04 07:30:54 +02:00
// About menu
2022-03-19 19:54:20 +01:00
connect ( mUI - > mActionAbout , & QAction : : triggered , this , & MainWindow : : about ) ;
connect ( mUI - > mActionLicense , & QAction : : triggered , this , & MainWindow : : showLicense ) ;
2011-05-04 07:30:54 +02:00
// View > Toolbar menu
2022-03-19 19:54:20 +01:00
connect ( mUI - > mActionToolBarMain , SIGNAL ( toggled ( bool ) ) , this , SLOT ( toggleMainToolBar ( ) ) ) ;
connect ( mUI - > mActionToolBarView , SIGNAL ( toggled ( bool ) ) , this , SLOT ( toggleViewToolBar ( ) ) ) ;
connect ( mUI - > mActionToolBarFilter , SIGNAL ( toggled ( bool ) ) , this , SLOT ( toggleFilterToolBar ( ) ) ) ;
2009-06-14 23:48:16 +02:00
2022-03-19 19:54:20 +01:00
connect ( mUI - > mActionAuthors , & QAction : : triggered , this , & MainWindow : : showAuthors ) ;
2017-07-31 07:36:42 +02:00
connect ( mThread , & ThreadHandler : : done , this , & MainWindow : : analysisDone ) ;
2022-03-19 19:54:20 +01:00
connect ( mThread , & ThreadHandler : : log , mUI - > mResults , & ResultsView : : log ) ;
connect ( mThread , & ThreadHandler : : debugError , mUI - > mResults , & ResultsView : : debugError ) ;
connect ( mUI - > mResults , & ResultsView : : gotResults , this , & MainWindow : : resultsAdded ) ;
connect ( mUI - > mResults , & ResultsView : : resultsHidden , mUI - > mActionShowHidden , & QAction : : setEnabled ) ;
connect ( mUI - > mResults , & ResultsView : : checkSelected , this , & MainWindow : : performSelectedFilesCheck ) ;
connect ( mUI - > mResults , & ResultsView : : suppressIds , this , & MainWindow : : suppressIds ) ;
connect ( mUI - > mMenuView , & QMenu : : aboutToShow , this , & MainWindow : : aboutToShowViewMenu ) ;
2009-05-26 17:21:39 +02:00
2011-05-04 07:30:54 +02:00
// File menu
2022-03-19 19:54:20 +01:00
connect ( mUI - > mActionNewProjectFile , & QAction : : triggered , this , & MainWindow : : newProjectFile ) ;
connect ( mUI - > mActionOpenProjectFile , & QAction : : triggered , this , & MainWindow : : openProjectFile ) ;
connect ( mUI - > mActionShowScratchpad , & QAction : : triggered , this , & MainWindow : : showScratchpad ) ;
connect ( mUI - > mActionCloseProjectFile , & QAction : : triggered , this , & MainWindow : : closeProjectFile ) ;
connect ( mUI - > mActionEditProjectFile , & QAction : : triggered , this , & MainWindow : : editProjectFile ) ;
2010-07-07 20:18:42 +02:00
2022-03-19 19:54:20 +01:00
connect ( mUI - > mActionHelpContents , & QAction : : triggered , this , & MainWindow : : openHelpContents ) ;
2010-02-23 16:29:49 +01:00
2017-07-28 05:44:15 +02:00
loadSettings ( ) ;
2009-07-02 10:32:29 +02:00
2022-03-19 19:54:20 +01:00
mThread - > initialize ( mUI - > mResults ) ;
2017-07-31 12:02:51 +02:00
if ( mProjectFile )
formatAndSetTitle ( tr ( " Project: " ) + ' ' + mProjectFile - > getFilename ( ) ) ;
2017-07-30 00:13:00 +02:00
else
formatAndSetTitle ( ) ;
2009-05-26 17:21:39 +02:00
2023-01-30 14:59:45 +01:00
mUI - > mActionComplianceReport - > setVisible ( isCppcheckPremium ( ) ) ;
2017-07-28 05:44:15 +02:00
enableCheckButtons ( true ) ;
2009-06-03 20:18:22 +02:00
2022-03-19 19:54:20 +01:00
mUI - > mActionPrint - > setShortcut ( QKeySequence : : Print ) ;
2018-04-12 08:15:04 +02:00
enableResultsButtons ( ) ;
2017-07-28 05:44:15 +02:00
enableProjectOpenActions ( true ) ;
enableProjectActions ( false ) ;
2009-07-02 10:32:29 +02:00
2012-01-10 20:16:47 +01:00
// Must setup MRU menu before CLI param handling as it can load a
// project file and update MRU menu.
2011-10-13 20:53:06 +02:00
for ( int i = 0 ; i < MaxRecentProjects ; + + i ) {
2011-05-12 11:34:23 +02:00
mRecentProjectActs [ i ] = new QAction ( this ) ;
mRecentProjectActs [ i ] - > setVisible ( false ) ;
connect ( mRecentProjectActs [ i ] , SIGNAL ( triggered ( ) ) ,
2017-07-28 12:22:15 +02:00
this , SLOT ( openRecentProject ( ) ) ) ;
2011-05-12 11:34:23 +02:00
}
2017-07-31 15:19:51 +02:00
mRecentProjectActs [ MaxRecentProjects ] = nullptr ; // The separator
2022-03-19 19:54:20 +01:00
mUI - > mActionProjectMRU - > setVisible ( false ) ;
2017-07-28 05:44:15 +02:00
updateMRUMenuItems ( ) ;
2011-10-02 21:08:12 +02:00
2012-01-10 20:16:47 +01:00
QStringList args = QCoreApplication : : arguments ( ) ;
//Remove the application itself
args . removeFirst ( ) ;
if ( ! args . isEmpty ( ) ) {
2017-07-28 05:44:15 +02:00
handleCLIParams ( args ) ;
2012-01-10 20:16:47 +01:00
}
2022-03-19 19:54:20 +01:00
mUI - > mActionCloseProjectFile - > setEnabled ( mProjectFile ! = nullptr ) ;
mUI - > mActionEditProjectFile - > setEnabled ( mProjectFile ! = nullptr ) ;
2017-07-30 00:13:00 +02:00
2011-10-13 20:53:06 +02:00
for ( int i = 0 ; i < mPlatforms . getCount ( ) ; i + + ) {
2023-10-13 16:02:04 +02:00
PlatformData platform = mPlatforms . mPlatforms [ i ] ;
2018-02-16 22:22:13 +01:00
QAction * action = new QAction ( this ) ;
platform . mActMainWindow = action ;
mPlatforms . mPlatforms [ i ] = platform ;
action - > setText ( platform . mTitle ) ;
action - > setData ( platform . mType ) ;
action - > setCheckable ( true ) ;
action - > setActionGroup ( mPlatformActions ) ;
2022-03-19 19:54:20 +01:00
mUI - > mMenuAnalyze - > insertAction ( mUI - > mActionPlatforms , action ) ;
2018-02-16 22:22:13 +01:00
connect ( action , SIGNAL ( triggered ( ) ) , this , SLOT ( selectPlatform ( ) ) ) ;
2011-10-02 21:08:12 +02:00
}
2022-03-19 19:54:20 +01:00
mUI - > mActionC89 - > setActionGroup ( mCStandardActions ) ;
mUI - > mActionC99 - > setActionGroup ( mCStandardActions ) ;
mUI - > mActionC11 - > setActionGroup ( mCStandardActions ) ;
2013-03-02 13:01:21 +01:00
2022-03-19 19:54:20 +01:00
mUI - > mActionCpp03 - > setActionGroup ( mCppStandardActions ) ;
mUI - > mActionCpp11 - > setActionGroup ( mCppStandardActions ) ;
mUI - > mActionCpp14 - > setActionGroup ( mCppStandardActions ) ;
mUI - > mActionCpp17 - > setActionGroup ( mCppStandardActions ) ;
mUI - > mActionCpp20 - > setActionGroup ( mCppStandardActions ) ;
2022-04-15 16:17:36 +02:00
//mUI->mActionCpp23->setActionGroup(mCppStandardActions);
2013-03-02 13:01:21 +01:00
2022-03-19 19:54:20 +01:00
mUI - > mActionEnforceC - > setActionGroup ( mSelectLanguageActions ) ;
mUI - > mActionEnforceCpp - > setActionGroup ( mSelectLanguageActions ) ;
mUI - > mActionAutoDetectLanguage - > setActionGroup ( mSelectLanguageActions ) ;
2015-10-14 14:31:52 +02:00
2023-11-03 09:55:44 +01:00
// TODO: we no longer default to a Windows platform in CLI - so we should probably also get rid of this in the GUI
2011-10-02 22:45:11 +02:00
// For Windows platforms default to Win32 checked platform.
// For other platforms default to unspecified/default which means the
// platform Cppcheck GUI was compiled on.
# if defined(_WIN32)
2023-11-03 09:55:44 +01:00
constexpr Platform : : Type defaultPlatform = Platform : : Type : : Win32W ;
2011-10-02 22:45:11 +02:00
# else
2023-11-03 09:55:44 +01:00
constexpr Platform : : Type defaultPlatform = Platform : : Type : : Unspecified ;
2011-10-02 22:45:11 +02:00
# endif
2023-10-13 16:02:04 +02:00
PlatformData & platform = mPlatforms . get ( ( Platform : : Type ) mSettings - > value ( SETTINGS_CHECKED_PLATFORM , defaultPlatform ) . toInt ( ) ) ;
2018-02-16 22:22:13 +01:00
platform . mActMainWindow - > setChecked ( true ) ;
2022-10-09 18:51:01 +02:00
mNetworkAccessManager = new QNetworkAccessManager ( this ) ;
connect ( mNetworkAccessManager , & QNetworkAccessManager : : finished ,
this , & MainWindow : : replyFinished ) ;
mUI - > mLabelInformation - > setVisible ( false ) ;
mUI - > mButtonHideInformation - > setVisible ( false ) ;
connect ( mUI - > mButtonHideInformation , & QPushButton : : clicked ,
this , & MainWindow : : hideInformation ) ;
2022-10-22 20:27:24 +02:00
if ( mSettings - > value ( SETTINGS_CHECK_FOR_UPDATES , false ) . toBool ( ) ) {
// Is there a new version?
if ( isCppcheckPremium ( ) ) {
const QUrl url ( " https://files.cppchecksolutions.com/version.txt " ) ;
mNetworkAccessManager - > get ( QNetworkRequest ( url ) ) ;
} else {
const QUrl url ( " https://cppcheck.sourceforge.io/version.txt " ) ;
mNetworkAccessManager - > get ( QNetworkRequest ( url ) ) ;
}
2022-10-09 18:51:01 +02:00
} else {
2022-10-22 20:27:24 +02:00
delete mUI - > mLayoutInformation ;
2022-10-09 18:51:01 +02:00
}
2009-03-01 08:38:21 +01:00
}
MainWindow : : ~ MainWindow ( )
{
2017-07-31 12:02:51 +02:00
delete mProjectFile ;
2012-10-20 20:14:52 +02:00
delete mScratchPad ;
2022-03-19 19:54:20 +01:00
delete mUI ;
2009-03-01 08:38:21 +01:00
}
2017-07-28 05:44:15 +02:00
void MainWindow : : handleCLIParams ( const QStringList & params )
2011-04-07 14:34:15 +02:00
{
2015-12-26 11:47:07 +01:00
int index ;
2011-10-13 20:53:06 +02:00
if ( params . contains ( " -p " ) ) {
2015-12-26 11:47:07 +01:00
index = params . indexOf ( " -p " ) ;
if ( ( index + 1 ) < params . length ( ) )
2017-07-28 05:44:15 +02:00
loadProjectFile ( params [ index + 1 ] ) ;
2013-02-10 07:48:09 +01:00
} else if ( params . contains ( " -l " ) ) {
QString logFile ;
2015-12-26 11:47:07 +01:00
index = params . indexOf ( " -l " ) ;
if ( ( index + 1 ) < params . length ( ) )
logFile = params [ index + 1 ] ;
2013-02-10 07:48:09 +01:00
if ( params . contains ( " -d " ) ) {
QString checkedDir ;
2015-12-26 11:47:07 +01:00
index = params . indexOf ( " -d " ) ;
if ( ( index + 1 ) < params . length ( ) )
checkedDir = params [ index + 1 ] ;
2013-02-10 07:48:09 +01:00
2017-07-28 05:44:15 +02:00
loadResults ( logFile , checkedDir ) ;
2013-02-10 23:53:01 +01:00
} else {
2017-07-28 05:44:15 +02:00
loadResults ( logFile ) ;
2013-02-10 07:48:09 +01:00
}
2022-04-11 19:15:42 +02:00
} else if ( ( index = params . indexOf ( QRegularExpression ( " .* \\ .cppcheck$ " , QRegularExpression : : CaseInsensitiveOption ) ) ) > = 0 & & index < params . length ( ) & & QFile ( params [ index ] ) . exists ( ) ) {
2017-07-28 05:44:15 +02:00
loadProjectFile ( params [ index ] ) ;
2022-04-11 19:15:42 +02:00
} else if ( ( index = params . indexOf ( QRegularExpression ( " .* \\ .xml$ " , QRegularExpression : : CaseInsensitiveOption ) ) ) > = 0 & & index < params . length ( ) & & QFile ( params [ index ] ) . exists ( ) ) {
2017-07-28 05:44:15 +02:00
loadResults ( params [ index ] , QDir : : currentPath ( ) ) ;
2011-10-13 20:53:06 +02:00
} else
2017-07-30 11:50:08 +02:00
doAnalyzeFiles ( params ) ;
2011-04-07 14:34:15 +02:00
}
2017-07-28 05:44:15 +02:00
void MainWindow : : loadSettings ( )
2009-03-01 08:38:21 +01:00
{
2011-05-04 07:30:54 +02:00
// Window/dialog sizes
2011-10-13 20:53:06 +02:00
if ( mSettings - > value ( SETTINGS_WINDOW_MAXIMIZED , false ) . toBool ( ) ) {
2009-03-01 08:38:21 +01:00
showMaximized ( ) ;
2011-10-13 20:53:06 +02:00
} else {
2009-07-02 10:32:29 +02:00
resize ( mSettings - > value ( SETTINGS_WINDOW_WIDTH , 800 ) . toInt ( ) ,
mSettings - > value ( SETTINGS_WINDOW_HEIGHT , 600 ) . toInt ( ) ) ;
2009-03-01 08:38:21 +01:00
}
2009-03-22 18:39:44 +01:00
2023-02-24 21:22:08 +01:00
const ShowTypes & types = mUI - > mResults - > getShowTypes ( ) ;
mUI - > mActionShowStyle - > setChecked ( types . isShown ( ShowTypes : : ShowStyle ) ) ;
mUI - > mActionShowErrors - > setChecked ( types . isShown ( ShowTypes : : ShowErrors ) ) ;
mUI - > mActionShowWarnings - > setChecked ( types . isShown ( ShowTypes : : ShowWarnings ) ) ;
mUI - > mActionShowPortability - > setChecked ( types . isShown ( ShowTypes : : ShowPortability ) ) ;
mUI - > mActionShowPerformance - > setChecked ( types . isShown ( ShowTypes : : ShowPerformance ) ) ;
mUI - > mActionShowInformation - > setChecked ( types . isShown ( ShowTypes : : ShowInformation ) ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionShowCppcheck - > setChecked ( true ) ;
mUI - > mActionShowClang - > setChecked ( true ) ;
2009-07-01 23:05:09 +02:00
2019-04-12 12:12:12 +02:00
Standards standards ;
standards . setC ( mSettings - > value ( SETTINGS_STD_C , QString ( ) ) . toString ( ) . toStdString ( ) ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionC89 - > setChecked ( standards . c = = Standards : : C89 ) ;
mUI - > mActionC99 - > setChecked ( standards . c = = Standards : : C99 ) ;
mUI - > mActionC11 - > setChecked ( standards . c = = Standards : : C11 ) ;
2019-04-12 12:12:12 +02:00
standards . setCPP ( mSettings - > value ( SETTINGS_STD_CPP , QString ( ) ) . toString ( ) . toStdString ( ) ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionCpp03 - > setChecked ( standards . cpp = = Standards : : CPP03 ) ;
mUI - > mActionCpp11 - > setChecked ( standards . cpp = = Standards : : CPP11 ) ;
mUI - > mActionCpp14 - > setChecked ( standards . cpp = = Standards : : CPP14 ) ;
mUI - > mActionCpp17 - > setChecked ( standards . cpp = = Standards : : CPP17 ) ;
mUI - > mActionCpp20 - > setChecked ( standards . cpp = = Standards : : CPP20 ) ;
2022-04-15 16:17:36 +02:00
//mUI->mActionCpp23->setChecked(standards.cpp == Standards::CPP23);
2011-12-27 21:12:52 +01:00
2011-05-04 07:30:54 +02:00
// Main window settings
const bool showMainToolbar = mSettings - > value ( SETTINGS_TOOLBARS_MAIN_SHOW , true ) . toBool ( ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionToolBarMain - > setChecked ( showMainToolbar ) ;
mUI - > mToolBarMain - > setVisible ( showMainToolbar ) ;
2011-05-04 07:30:54 +02:00
const bool showViewToolbar = mSettings - > value ( SETTINGS_TOOLBARS_VIEW_SHOW , true ) . toBool ( ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionToolBarView - > setChecked ( showViewToolbar ) ;
mUI - > mToolBarView - > setVisible ( showViewToolbar ) ;
2011-05-04 07:30:54 +02:00
const bool showFilterToolbar = mSettings - > value ( SETTINGS_TOOLBARS_FILTER_SHOW , true ) . toBool ( ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionToolBarFilter - > setChecked ( showFilterToolbar ) ;
mUI - > mToolBarFilter - > setVisible ( showFilterToolbar ) ;
2009-07-02 10:32:29 +02:00
2022-10-02 07:12:40 +02:00
const Settings : : Language enforcedLanguage = ( Settings : : Language ) mSettings - > value ( SETTINGS_ENFORCED_LANGUAGE , 0 ) . toInt ( ) ;
2015-10-14 14:31:52 +02:00
if ( enforcedLanguage = = Settings : : CPP )
2022-03-19 19:54:20 +01:00
mUI - > mActionEnforceCpp - > setChecked ( true ) ;
2015-10-14 14:31:52 +02:00
else if ( enforcedLanguage = = Settings : : C )
2022-03-19 19:54:20 +01:00
mUI - > mActionEnforceC - > setChecked ( true ) ;
2015-10-14 14:31:52 +02:00
else
2022-03-19 19:54:20 +01:00
mUI - > mActionAutoDetectLanguage - > setChecked ( true ) ;
2015-10-14 14:31:52 +02:00
2022-10-02 07:12:40 +02:00
const bool succeeded = mApplications - > loadSettings ( ) ;
2011-10-13 20:53:06 +02:00
if ( ! succeeded ) {
2011-08-22 21:37:38 +02:00
const QString msg = tr ( " There was a problem with loading the editor application settings. \n \n "
2011-08-23 02:32:35 +02:00
" This is probably because the settings were changed between the Cppcheck versions. "
" Please check (and fix) the editor application settings, otherwise the editor "
" program might not start correctly. " ) ;
2011-04-01 23:53:26 +02:00
QMessageBox msgBox ( QMessageBox : : Warning ,
tr ( " Cppcheck " ) ,
msg ,
QMessageBox : : Ok ,
this ) ;
msgBox . exec ( ) ;
}
2017-07-30 13:42:34 +02:00
const QString projectFile = mSettings - > value ( SETTINGS_OPEN_PROJECT , QString ( ) ) . toString ( ) ;
if ( ! projectFile . isEmpty ( ) & & QCoreApplication : : arguments ( ) . size ( ) = = 1 ) {
QFileInfo inf ( projectFile ) ;
2017-07-30 00:13:00 +02:00
if ( inf . exists ( ) & & inf . isReadable ( ) ) {
2017-07-30 23:02:30 +02:00
setPath ( SETTINGS_LAST_PROJECT_PATH , projectFile ) ;
2017-07-31 12:02:51 +02:00
mProjectFile = new ProjectFile ( this ) ;
2020-07-15 13:03:07 +02:00
mProjectFile - > setActiveProject ( ) ;
2017-07-31 12:02:51 +02:00
mProjectFile - > read ( projectFile ) ;
2017-07-30 13:42:34 +02:00
loadLastResults ( ) ;
2019-08-14 10:23:36 +02:00
QDir : : setCurrent ( inf . absolutePath ( ) ) ;
2017-07-30 00:13:00 +02:00
}
}
2009-03-01 08:38:21 +01:00
}
2017-07-28 05:44:15 +02:00
void MainWindow : : saveSettings ( ) const
2009-03-01 08:38:21 +01:00
{
2011-05-04 07:30:54 +02:00
// Window/dialog sizes
2009-07-02 10:32:29 +02:00
mSettings - > setValue ( SETTINGS_WINDOW_WIDTH , size ( ) . width ( ) ) ;
mSettings - > setValue ( SETTINGS_WINDOW_HEIGHT , size ( ) . height ( ) ) ;
mSettings - > setValue ( SETTINGS_WINDOW_MAXIMIZED , isMaximized ( ) ) ;
2009-03-22 18:39:44 +01:00
2011-05-04 07:30:54 +02:00
// Show * states
2022-03-19 19:54:20 +01:00
mSettings - > setValue ( SETTINGS_SHOW_STYLE , mUI - > mActionShowStyle - > isChecked ( ) ) ;
mSettings - > setValue ( SETTINGS_SHOW_ERRORS , mUI - > mActionShowErrors - > isChecked ( ) ) ;
mSettings - > setValue ( SETTINGS_SHOW_WARNINGS , mUI - > mActionShowWarnings - > isChecked ( ) ) ;
mSettings - > setValue ( SETTINGS_SHOW_PORTABILITY , mUI - > mActionShowPortability - > isChecked ( ) ) ;
mSettings - > setValue ( SETTINGS_SHOW_PERFORMANCE , mUI - > mActionShowPerformance - > isChecked ( ) ) ;
mSettings - > setValue ( SETTINGS_SHOW_INFORMATION , mUI - > mActionShowInformation - > isChecked ( ) ) ;
if ( mUI - > mActionC89 - > isChecked ( ) )
2019-04-12 12:12:12 +02:00
mSettings - > setValue ( SETTINGS_STD_C , " C89 " ) ;
2022-03-19 19:54:20 +01:00
if ( mUI - > mActionC99 - > isChecked ( ) )
2019-04-12 12:12:12 +02:00
mSettings - > setValue ( SETTINGS_STD_C , " C99 " ) ;
2022-03-19 19:54:20 +01:00
if ( mUI - > mActionC11 - > isChecked ( ) )
2019-04-12 12:12:12 +02:00
mSettings - > setValue ( SETTINGS_STD_C , " C11 " ) ;
2022-03-19 19:54:20 +01:00
if ( mUI - > mActionCpp03 - > isChecked ( ) )
2019-04-12 12:12:12 +02:00
mSettings - > setValue ( SETTINGS_STD_CPP , " C++03 " ) ;
2022-03-19 19:54:20 +01:00
if ( mUI - > mActionCpp11 - > isChecked ( ) )
2019-04-12 12:12:12 +02:00
mSettings - > setValue ( SETTINGS_STD_CPP , " C++11 " ) ;
2022-03-19 19:54:20 +01:00
if ( mUI - > mActionCpp14 - > isChecked ( ) )
2019-04-12 12:12:12 +02:00
mSettings - > setValue ( SETTINGS_STD_CPP , " C++14 " ) ;
2022-03-19 19:54:20 +01:00
if ( mUI - > mActionCpp17 - > isChecked ( ) )
2019-04-12 12:12:12 +02:00
mSettings - > setValue ( SETTINGS_STD_CPP , " C++17 " ) ;
2022-03-19 19:54:20 +01:00
if ( mUI - > mActionCpp20 - > isChecked ( ) )
2019-05-05 10:44:09 +02:00
mSettings - > setValue ( SETTINGS_STD_CPP , " C++20 " ) ;
2022-04-15 16:17:36 +02:00
//if (mUI.mActionCpp23->isChecked())
// mSettings->setValue(SETTINGS_STD_CPP, "C++23");
2011-12-27 21:12:52 +01:00
2011-05-04 07:30:54 +02:00
// Main window settings
2022-03-19 19:54:20 +01:00
mSettings - > setValue ( SETTINGS_TOOLBARS_MAIN_SHOW , mUI - > mToolBarMain - > isVisible ( ) ) ;
mSettings - > setValue ( SETTINGS_TOOLBARS_VIEW_SHOW , mUI - > mToolBarView - > isVisible ( ) ) ;
mSettings - > setValue ( SETTINGS_TOOLBARS_FILTER_SHOW , mUI - > mToolBarFilter - > isVisible ( ) ) ;
2009-07-01 23:05:09 +02:00
2022-03-19 19:54:20 +01:00
if ( mUI - > mActionEnforceCpp - > isChecked ( ) )
2015-10-14 14:31:52 +02:00
mSettings - > setValue ( SETTINGS_ENFORCED_LANGUAGE , Settings : : CPP ) ;
2022-03-19 19:54:20 +01:00
else if ( mUI - > mActionEnforceC - > isChecked ( ) )
2015-10-14 14:31:52 +02:00
mSettings - > setValue ( SETTINGS_ENFORCED_LANGUAGE , Settings : : C ) ;
else
mSettings - > setValue ( SETTINGS_ENFORCED_LANGUAGE , Settings : : None ) ;
2017-07-28 05:18:43 +02:00
mApplications - > saveSettings ( ) ;
2009-07-02 10:32:29 +02:00
2017-07-28 13:43:49 +02:00
mSettings - > setValue ( SETTINGS_LANGUAGE , mTranslation - > getCurrentLanguage ( ) ) ;
2017-07-30 00:13:00 +02:00
2017-07-31 12:02:51 +02:00
mSettings - > setValue ( SETTINGS_OPEN_PROJECT , mProjectFile ? mProjectFile - > getFilename ( ) : QString ( ) ) ;
2017-07-30 00:13:00 +02:00
2022-03-19 19:54:20 +01:00
mUI - > mResults - > saveSettings ( mSettings ) ;
2009-03-01 08:38:21 +01:00
}
2018-04-13 15:28:05 +02:00
void MainWindow : : doAnalyzeProject ( ImportProject p , const bool checkLibrary , const bool checkConfiguration )
2016-08-18 21:58:50 +02:00
{
2017-07-28 10:41:03 +02:00
clearResults ( ) ;
2016-08-18 21:58:50 +02:00
mIsLogfileLoaded = false ;
2017-07-31 12:02:51 +02:00
if ( mProjectFile ) {
2016-08-18 21:58:50 +02:00
std : : vector < std : : string > v ;
2022-10-16 13:46:26 +02:00
const QStringList excluded = mProjectFile - > getExcludedPaths ( ) ;
2022-12-30 15:13:47 +01:00
std : : transform ( excluded . cbegin ( ) , excluded . cend ( ) , std : : back_inserter ( v ) , [ ] ( const QString & e ) {
2022-10-16 13:46:26 +02:00
return e . toStdString ( ) ;
} ) ;
2016-08-18 21:58:50 +02:00
p . ignorePaths ( v ) ;
2017-08-10 00:18:04 +02:00
if ( ! mProjectFile - > getAnalyzeAllVsConfigs ( ) ) {
2023-10-13 16:02:04 +02:00
const Platform : : Type platform = ( Platform : : Type ) mSettings - > value ( SETTINGS_CHECKED_PLATFORM , 0 ) . toInt ( ) ;
2023-05-23 12:44:03 +02:00
std : : vector < std : : string > configurations ;
const QStringList configs = mProjectFile - > getVsConfigurations ( ) ;
std : : transform ( configs . cbegin ( ) , configs . cend ( ) , std : : back_inserter ( configurations ) , [ ] ( const QString & e ) {
return e . toStdString ( ) ;
} ) ;
p . selectVsConfigurations ( platform , configurations ) ;
2017-08-10 00:18:04 +02:00
}
2016-08-18 21:58:50 +02:00
} else {
2017-07-28 05:44:15 +02:00
enableProjectActions ( false ) ;
2016-08-18 21:58:50 +02:00
}
2022-03-19 19:54:20 +01:00
mUI - > mResults - > clear ( true ) ;
2017-07-28 12:39:28 +02:00
mThread - > clearFiles ( ) ;
2016-08-18 21:58:50 +02:00
2022-03-19 19:54:20 +01:00
mUI - > mResults - > checkingStarted ( p . fileSettings . size ( ) ) ;
2016-08-18 21:58:50 +02:00
QDir inf ( mCurrentDirectory ) ;
const QString checkPath = inf . canonicalPath ( ) ;
2017-07-28 11:20:35 +02:00
setPath ( SETTINGS_LAST_CHECK_PATH , checkPath ) ;
2016-08-18 21:58:50 +02:00
2017-07-28 10:41:03 +02:00
checkLockDownUI ( ) ; // lock UI while checking
2016-08-18 21:58:50 +02:00
2022-03-19 19:54:20 +01:00
mUI - > mResults - > setCheckDirectory ( checkPath ) ;
2017-07-28 05:44:15 +02:00
Settings checkSettings = getCppcheckSettings ( ) ;
2016-08-20 13:32:48 +02:00
checkSettings . force = false ;
2018-04-13 15:28:05 +02:00
checkSettings . checkLibrary = checkLibrary ;
checkSettings . checkConfiguration = checkConfiguration ;
2016-08-18 21:58:50 +02:00
2017-07-31 12:02:51 +02:00
if ( mProjectFile )
qDebug ( ) < < " Checking project file " < < mProjectFile - > getFilename ( ) ;
2016-08-18 21:58:50 +02:00
2016-12-09 20:48:32 +01:00
if ( ! checkSettings . buildDir . empty ( ) ) {
2020-12-19 20:45:51 +01:00
checkSettings . loadSummaries ( ) ;
2016-12-09 20:48:32 +01:00
std : : list < std : : string > sourcefiles ;
2020-12-19 20:45:51 +01:00
AnalyzerInformation : : writeFilesTxt ( checkSettings . buildDir , sourcefiles , checkSettings . userDefines , p . fileSettings ) ;
2016-12-09 20:48:32 +01:00
}
2017-07-30 11:50:08 +02:00
//mThread->SetanalyzeProject(true);
2017-08-04 20:08:01 +02:00
if ( mProjectFile ) {
2020-05-17 16:50:02 +02:00
mThread - > setAddonsAndTools ( mProjectFile - > getAddonsAndTools ( ) ) ;
2017-08-13 17:13:24 +02:00
QString clangHeaders = mSettings - > value ( SETTINGS_VS_INCLUDE_PATHS ) . toString ( ) ;
mThread - > setClangIncludePaths ( clangHeaders . split ( " ; " ) ) ;
2019-08-11 15:53:03 +02:00
mThread - > setSuppressions ( mProjectFile - > getSuppressions ( ) ) ;
2017-08-04 20:08:01 +02:00
}
2017-07-28 12:39:28 +02:00
mThread - > setProject ( p ) ;
2017-08-03 22:12:12 +02:00
mThread - > check ( checkSettings ) ;
2023-08-31 18:28:47 +02:00
mUI - > mResults - > setCheckSettings ( checkSettings ) ;
2016-08-18 21:58:50 +02:00
}
2018-04-13 15:28:05 +02:00
void MainWindow : : doAnalyzeFiles ( const QStringList & files , const bool checkLibrary , const bool checkConfiguration )
2009-07-16 07:20:29 +02:00
{
2011-10-13 20:53:06 +02:00
if ( files . isEmpty ( ) ) {
2009-07-16 07:20:29 +02:00
return ;
}
2017-07-28 10:41:03 +02:00
clearResults ( ) ;
2009-07-16 07:20:29 +02:00
2016-01-16 09:59:02 +01:00
mIsLogfileLoaded = false ;
2010-08-09 21:15:05 +02:00
FileList pathList ;
2017-07-28 10:55:51 +02:00
pathList . addPathList ( files ) ;
2017-07-31 12:02:51 +02:00
if ( mProjectFile ) {
pathList . addExcludeList ( mProjectFile - > getExcludedPaths ( ) ) ;
2016-01-16 09:59:02 +01:00
} else {
2017-07-28 05:44:15 +02:00
enableProjectActions ( false ) ;
2016-01-16 09:59:02 +01:00
}
2017-07-28 10:55:51 +02:00
QStringList fileNames = pathList . getFileList ( ) ;
2009-07-16 07:20:29 +02:00
2022-03-19 19:54:20 +01:00
mUI - > mResults - > clear ( true ) ;
2017-07-28 12:39:28 +02:00
mThread - > clearFiles ( ) ;
2009-07-16 07:20:29 +02:00
2011-10-13 20:53:06 +02:00
if ( fileNames . isEmpty ( ) ) {
2009-07-16 07:20:29 +02:00
QMessageBox msg ( QMessageBox : : Warning ,
tr ( " Cppcheck " ) ,
2017-07-30 13:31:02 +02:00
tr ( " No suitable files found to analyze! " ) ,
2009-07-16 07:20:29 +02:00
QMessageBox : : Ok ,
this ) ;
msg . exec ( ) ;
return ;
}
2022-03-19 19:54:20 +01:00
mUI - > mResults - > checkingStarted ( fileNames . count ( ) ) ;
2009-07-16 07:20:29 +02:00
2017-07-28 12:39:28 +02:00
mThread - > setFiles ( fileNames ) ;
2018-04-13 15:28:05 +02:00
if ( mProjectFile & & ! checkConfiguration )
2020-05-17 16:50:02 +02:00
mThread - > setAddonsAndTools ( mProjectFile - > getAddonsAndTools ( ) ) ;
2019-08-19 12:59:44 +02:00
mThread - > setSuppressions ( mProjectFile ? mProjectFile - > getSuppressions ( ) : QList < Suppressions : : Suppression > ( ) ) ;
2013-02-10 08:15:32 +01:00
QDir inf ( mCurrentDirectory ) ;
const QString checkPath = inf . canonicalPath ( ) ;
2017-07-28 11:20:35 +02:00
setPath ( SETTINGS_LAST_CHECK_PATH , checkPath ) ;
2009-07-16 07:20:29 +02:00
2017-07-28 10:41:03 +02:00
checkLockDownUI ( ) ; // lock UI while checking
2011-02-11 20:08:37 +01:00
2022-03-19 19:54:20 +01:00
mUI - > mResults - > setCheckDirectory ( checkPath ) ;
2017-07-28 05:44:15 +02:00
Settings checkSettings = getCppcheckSettings ( ) ;
2018-04-13 15:28:05 +02:00
checkSettings . checkLibrary = checkLibrary ;
checkSettings . checkConfiguration = checkConfiguration ;
2011-06-04 14:38:51 +02:00
2017-07-31 12:02:51 +02:00
if ( mProjectFile )
qDebug ( ) < < " Checking project file " < < mProjectFile - > getFilename ( ) ;
2011-06-04 14:38:51 +02:00
2016-11-19 20:38:50 +01:00
if ( ! checkSettings . buildDir . empty ( ) ) {
2020-12-19 20:45:51 +01:00
checkSettings . loadSummaries ( ) ;
2016-12-09 20:48:32 +01:00
std : : list < std : : string > sourcefiles ;
2022-12-30 15:13:47 +01:00
std : : transform ( fileNames . cbegin ( ) , fileNames . cend ( ) , std : : back_inserter ( sourcefiles ) , [ ] ( const QString & s ) {
2022-10-16 13:46:26 +02:00
return s . toStdString ( ) ;
} ) ;
2023-11-03 23:24:04 +01:00
AnalyzerInformation : : writeFilesTxt ( checkSettings . buildDir , sourcefiles , checkSettings . userDefines , { } ) ;
2016-11-19 20:38:50 +01:00
}
2017-07-28 12:39:28 +02:00
mThread - > setCheckFiles ( true ) ;
2017-08-03 22:12:12 +02:00
mThread - > check ( checkSettings ) ;
2023-08-31 18:28:47 +02:00
mUI - > mResults - > setCheckSettings ( checkSettings ) ;
2009-07-16 07:20:29 +02:00
}
2017-07-30 11:19:47 +02:00
void MainWindow : : analyzeCode ( const QString & code , const QString & filename )
2012-10-20 20:14:52 +02:00
{
// Initialize dummy ThreadResult as ErrorLogger
ThreadResult result ;
2017-07-28 12:39:28 +02:00
result . setFiles ( QStringList ( filename ) ) ;
2023-08-22 12:01:30 +02:00
connect ( & result , SIGNAL ( progress ( int , QString ) ) ,
mUI - > mResults , SLOT ( progress ( int , QString ) ) ) ;
connect ( & result , SIGNAL ( error ( ErrorItem ) ) ,
mUI - > mResults , SLOT ( error ( ErrorItem ) ) ) ;
connect ( & result , SIGNAL ( log ( QString ) ) ,
mUI - > mResults , SLOT ( log ( QString ) ) ) ;
connect ( & result , SIGNAL ( debugError ( ErrorItem ) ) ,
mUI - > mResults , SLOT ( debugError ( ErrorItem ) ) ) ;
2012-10-20 20:14:52 +02:00
// Create CppCheck instance
2020-05-19 16:04:25 +02:00
CppCheck cppcheck ( result , true , nullptr ) ;
2017-07-28 05:44:15 +02:00
cppcheck . settings ( ) = getCppcheckSettings ( ) ;
2012-10-20 20:14:52 +02:00
// Check
2017-07-28 10:41:03 +02:00
checkLockDownUI ( ) ;
clearResults ( ) ;
2022-03-19 19:54:20 +01:00
mUI - > mResults - > checkingStarted ( 1 ) ;
2012-10-20 20:14:52 +02:00
cppcheck . check ( filename . toStdString ( ) , code . toStdString ( ) ) ;
2017-07-30 11:19:47 +02:00
analysisDone ( ) ;
2018-03-07 00:18:47 +01:00
// Expand results
2022-03-19 19:54:20 +01:00
if ( mUI - > mResults - > hasVisibleResults ( ) )
mUI - > mResults - > expandAllResults ( ) ;
2012-10-20 20:14:52 +02:00
}
2017-07-30 11:19:47 +02:00
QStringList MainWindow : : selectFilesToAnalyze ( QFileDialog : : FileMode mode )
2009-03-01 08:38:21 +01:00
{
2017-07-31 12:02:51 +02:00
if ( mProjectFile ) {
2010-08-19 21:28:56 +02:00
QMessageBox msgBox ( this ) ;
msgBox . setWindowTitle ( tr ( " Cppcheck " ) ) ;
const QString msg ( tr ( " You must close the project file before selecting new files or directories! " ) ) ;
msgBox . setText ( msg ) ;
msgBox . setIcon ( QMessageBox : : Critical ) ;
msgBox . exec ( ) ;
return QStringList ( ) ;
}
2009-06-17 21:35:24 +02:00
QStringList selected ;
2009-03-22 13:32:07 +01:00
2009-06-17 21:35:24 +02:00
// NOTE: we use QFileDialog::getOpenFileNames() and
// QFileDialog::getExistingDirectory() because they show native Windows
2012-09-09 13:51:34 +02:00
// selection dialog which is a lot more usable than Qt:s own dialog.
2011-10-13 20:53:06 +02:00
if ( mode = = QFileDialog : : ExistingFiles ) {
2018-05-25 07:09:49 +02:00
QMap < QString , QString > filters ;
filters [ tr ( " C/C++ Source " ) ] = FileList : : getDefaultFilters ( ) . join ( " " ) ;
filters [ tr ( " Compile database " ) ] = compile_commands_json ;
filters [ tr ( " Visual Studio " ) ] = " *.sln *.vcxproj " ;
filters [ tr ( " Borland C++ Builder 6 " ) ] = " *.bpr " ;
QString lastFilter = mSettings - > value ( SETTINGS_LAST_ANALYZE_FILES_FILTER ) . toString ( ) ;
2013-01-04 10:23:16 +01:00
selected = QFileDialog : : getOpenFileNames ( this ,
2021-08-07 20:51:18 +02:00
tr ( " Select files to analyze " ) ,
getPath ( SETTINGS_LAST_CHECK_PATH ) ,
toFilterString ( filters ) ,
& lastFilter ) ;
2018-05-25 07:09:49 +02:00
mSettings - > setValue ( SETTINGS_LAST_ANALYZE_FILES_FILTER , lastFilter ) ;
2010-04-02 07:30:58 +02:00
if ( selected . isEmpty ( ) )
2009-06-22 10:57:17 +02:00
mCurrentDirectory . clear ( ) ;
2011-10-13 20:53:06 +02:00
else {
2010-01-06 10:34:02 +01:00
QFileInfo inf ( selected [ 0 ] ) ;
mCurrentDirectory = inf . absolutePath ( ) ;
}
2017-07-28 05:44:15 +02:00
formatAndSetTitle ( ) ;
2022-03-22 21:44:41 +01:00
} else if ( mode = = QFileDialog : : Directory ) {
2013-09-07 19:38:40 +02:00
QString dir = QFileDialog : : getExistingDirectory ( this ,
2021-08-07 20:51:18 +02:00
tr ( " Select directory to analyze " ) ,
getPath ( SETTINGS_LAST_CHECK_PATH ) ) ;
2013-09-07 19:38:40 +02:00
if ( ! dir . isEmpty ( ) ) {
qDebug ( ) < < " Setting current directory to: " < < dir ;
2009-06-22 10:57:17 +02:00
mCurrentDirectory = dir ;
2009-06-17 21:35:24 +02:00
selected . append ( dir ) ;
2009-08-02 13:08:04 +02:00
dir = QDir : : toNativeSeparators ( dir ) ;
2017-07-28 05:44:15 +02:00
formatAndSetTitle ( dir ) ;
2009-06-22 10:57:17 +02:00
}
2009-06-17 21:35:24 +02:00
}
2023-05-07 08:33:47 +02:00
if ( ! mCurrentDirectory . isEmpty ( ) )
setPath ( SETTINGS_LAST_CHECK_PATH , mCurrentDirectory ) ;
2013-02-19 21:39:50 +01:00
2009-07-16 07:20:29 +02:00
return selected ;
2009-03-01 08:38:21 +01:00
}
2017-07-30 11:19:47 +02:00
void MainWindow : : analyzeFiles ( )
2009-03-22 13:32:07 +01:00
{
2017-08-06 21:28:49 +02:00
Settings : : terminate ( false ) ;
2017-07-30 11:19:47 +02:00
QStringList selected = selectFilesToAnalyze ( QFileDialog : : ExistingFiles ) ;
2016-08-20 13:32:48 +02:00
2023-08-17 17:01:08 +02:00
const QString file0 = ( ! selected . empty ( ) ? selected [ 0 ] . toLower ( ) : QString ( ) ) ;
2018-05-25 07:09:49 +02:00
if ( file0 . endsWith ( " .sln " )
| | file0 . endsWith ( " .vcxproj " )
| | file0 . endsWith ( compile_commands_json )
| | file0 . endsWith ( " .bpr " ) ) {
2016-08-20 13:32:48 +02:00
ImportProject p ;
p . import ( selected [ 0 ] . toStdString ( ) ) ;
2016-08-21 15:57:38 +02:00
if ( file0 . endsWith ( " .sln " ) ) {
QStringList configs ;
2023-11-02 17:42:41 +01:00
for ( std : : list < FileSettings > : : const_iterator it = p . fileSettings . cbegin ( ) ; it ! = p . fileSettings . cend ( ) ; + + it ) {
2016-08-21 15:57:38 +02:00
const QString cfg ( QString : : fromStdString ( it - > cfg ) ) ;
if ( ! configs . contains ( cfg ) )
configs . push_back ( cfg ) ;
}
configs . sort ( ) ;
bool ok = false ;
2017-07-30 13:31:02 +02:00
const QString cfg = QInputDialog : : getItem ( this , tr ( " Select configuration " ) , tr ( " Select the configuration that will be analyzed " ) , configs , 0 , false , & ok ) ;
2016-08-21 15:57:38 +02:00
if ( ! ok )
return ;
p . ignoreOtherConfigs ( cfg . toStdString ( ) ) ;
}
2017-07-30 11:50:08 +02:00
doAnalyzeProject ( p ) ;
2016-08-20 13:32:48 +02:00
return ;
}
2017-07-30 11:50:08 +02:00
doAnalyzeFiles ( selected ) ;
2009-03-22 13:32:07 +01:00
}
2017-07-30 11:19:47 +02:00
void MainWindow : : analyzeDirectory ( )
2009-03-22 13:32:07 +01:00
{
2022-03-22 21:44:41 +01:00
QStringList dir = selectFilesToAnalyze ( QFileDialog : : Directory ) ;
2011-06-07 15:12:21 +02:00
if ( dir . isEmpty ( ) )
return ;
QDir checkDir ( dir [ 0 ] ) ;
QStringList filters ;
filters < < " *.cppcheck " ;
2011-06-07 22:56:48 +02:00
checkDir . setFilter ( QDir : : Files | QDir : : Readable ) ;
2011-06-07 15:12:21 +02:00
checkDir . setNameFilters ( filters ) ;
QStringList projFiles = checkDir . entryList ( ) ;
2011-10-13 20:53:06 +02:00
if ( ! projFiles . empty ( ) ) {
if ( projFiles . size ( ) = = 1 ) {
2011-06-07 15:12:21 +02:00
// If one project file found, suggest loading it
QMessageBox msgBox ( this ) ;
msgBox . setWindowTitle ( tr ( " Cppcheck " ) ) ;
const QString msg ( tr ( " Found project file: %1 \n \n Do you want to "
" load this project file instead? " ) . arg ( projFiles [ 0 ] ) ) ;
msgBox . setText ( msg ) ;
msgBox . setIcon ( QMessageBox : : Warning ) ;
msgBox . addButton ( QMessageBox : : Yes ) ;
msgBox . addButton ( QMessageBox : : No ) ;
msgBox . setDefaultButton ( QMessageBox : : Yes ) ;
2022-10-02 07:12:40 +02:00
const int dlgResult = msgBox . exec ( ) ;
2011-10-13 20:53:06 +02:00
if ( dlgResult = = QMessageBox : : Yes ) {
2011-06-08 09:40:17 +02:00
QString path = checkDir . canonicalPath ( ) ;
if ( ! path . endsWith ( " / " ) )
path + = " / " ;
path + = projFiles [ 0 ] ;
2017-07-28 05:44:15 +02:00
loadProjectFile ( path ) ;
2011-10-13 20:53:06 +02:00
} else {
2017-07-30 11:50:08 +02:00
doAnalyzeFiles ( dir ) ;
2011-06-07 15:12:21 +02:00
}
2011-10-13 20:53:06 +02:00
} else {
2011-06-07 15:12:21 +02:00
// If multiple project files found inform that there are project
// files also available.
QMessageBox msgBox ( this ) ;
msgBox . setWindowTitle ( tr ( " Cppcheck " ) ) ;
const QString msg ( tr ( " Found project files from the directory. \n \n "
2017-07-30 13:31:02 +02:00
" Do you want to proceed analysis without "
2011-06-07 15:12:21 +02:00
" using any of these project files? " ) ) ;
msgBox . setText ( msg ) ;
msgBox . setIcon ( QMessageBox : : Warning ) ;
msgBox . addButton ( QMessageBox : : Yes ) ;
msgBox . addButton ( QMessageBox : : No ) ;
msgBox . setDefaultButton ( QMessageBox : : Yes ) ;
2022-10-02 07:12:40 +02:00
const int dlgResult = msgBox . exec ( ) ;
2011-10-13 20:53:06 +02:00
if ( dlgResult = = QMessageBox : : Yes ) {
2017-07-30 11:50:08 +02:00
doAnalyzeFiles ( dir ) ;
2011-06-07 15:12:21 +02:00
}
}
2011-10-13 20:53:06 +02:00
} else {
2017-07-30 11:50:08 +02:00
doAnalyzeFiles ( dir ) ;
2011-06-07 15:12:21 +02:00
}
2009-03-22 13:32:07 +01:00
}
2017-07-28 05:44:15 +02:00
void MainWindow : : addIncludeDirs ( const QStringList & includeDirs , Settings & result )
2010-11-26 21:51:38 +01:00
{
2022-03-21 17:14:26 +01:00
for ( const QString & dir : includeDirs ) {
2010-11-26 21:51:38 +01:00
QString incdir ;
if ( ! QDir : : isAbsolutePath ( dir ) )
incdir = mCurrentDirectory + " / " ;
incdir + = dir ;
incdir = QDir : : cleanPath ( incdir ) ;
// include paths must end with '/'
if ( ! incdir . endsWith ( " / " ) )
incdir + = " / " ;
2016-01-03 16:18:17 +01:00
result . includePaths . push_back ( incdir . toStdString ( ) ) ;
2010-11-26 21:51:38 +01:00
}
}
2018-06-23 23:04:54 +02:00
Library : : Error MainWindow : : loadLibrary ( Library * library , const QString & filename )
2013-12-31 10:46:44 +01:00
{
2014-05-26 20:16:19 +02:00
Library : : Error ret ;
2013-12-31 10:46:44 +01:00
// Try to load the library from the project folder..
2017-07-31 12:02:51 +02:00
if ( mProjectFile ) {
QString path = QFileInfo ( mProjectFile - > getFilename ( ) ) . canonicalPath ( ) ;
2017-07-31 15:19:51 +02:00
ret = library - > load ( nullptr , ( path + " / " + filename ) . toLatin1 ( ) ) ;
2014-05-26 20:16:19 +02:00
if ( ret . errorcode ! = Library : : ErrorCode : : FILE_NOT_FOUND )
return ret ;
2013-12-31 10:46:44 +01:00
}
// Try to load the library from the application folder..
2014-03-19 19:34:20 +01:00
const QString appPath = QFileInfo ( QCoreApplication : : applicationFilePath ( ) ) . canonicalPath ( ) ;
2017-07-31 15:19:51 +02:00
ret = library - > load ( nullptr , ( appPath + " / " + filename ) . toLatin1 ( ) ) ;
2014-05-26 20:16:19 +02:00
if ( ret . errorcode ! = Library : : ErrorCode : : FILE_NOT_FOUND )
return ret ;
2017-07-31 15:19:51 +02:00
ret = library - > load ( nullptr , ( appPath + " /cfg/ " + filename ) . toLatin1 ( ) ) ;
2014-05-26 20:16:19 +02:00
if ( ret . errorcode ! = Library : : ErrorCode : : FILE_NOT_FOUND )
return ret ;
2013-12-31 10:46:44 +01:00
2019-08-17 10:53:07 +02:00
# ifdef FILESDIR
// Try to load the library from FILESDIR/cfg..
const QString filesdir = FILESDIR ;
if ( ! filesdir . isEmpty ( ) ) {
ret = library - > load ( nullptr , ( filesdir + " /cfg/ " + filename ) . toLatin1 ( ) ) ;
2016-10-16 01:08:04 +02:00
if ( ret . errorcode ! = Library : : ErrorCode : : FILE_NOT_FOUND )
return ret ;
2019-08-17 10:53:07 +02:00
ret = library - > load ( nullptr , ( filesdir + filename ) . toLatin1 ( ) ) ;
2016-10-16 01:08:04 +02:00
if ( ret . errorcode ! = Library : : ErrorCode : : FILE_NOT_FOUND )
return ret ;
}
# endif
2014-03-19 19:34:20 +01:00
// Try to load the library from the cfg subfolder..
2020-08-29 21:26:49 +02:00
const QString datadir = getDataDir ( ) ;
2014-03-19 19:34:20 +01:00
if ( ! datadir . isEmpty ( ) ) {
2017-07-31 15:19:51 +02:00
ret = library - > load ( nullptr , ( datadir + " / " + filename ) . toLatin1 ( ) ) ;
2014-05-26 20:16:19 +02:00
if ( ret . errorcode ! = Library : : ErrorCode : : FILE_NOT_FOUND )
return ret ;
2017-07-31 15:19:51 +02:00
ret = library - > load ( nullptr , ( datadir + " /cfg/ " + filename ) . toLatin1 ( ) ) ;
2014-05-26 20:16:19 +02:00
if ( ret . errorcode ! = Library : : ErrorCode : : FILE_NOT_FOUND )
return ret ;
2014-01-11 08:38:26 +01:00
}
2014-05-26 20:16:19 +02:00
return ret ;
2013-12-31 10:46:44 +01:00
}
2020-03-07 11:33:08 +01:00
bool MainWindow : : tryLoadLibrary ( Library * library , const QString & filename )
2015-01-10 22:51:45 +01:00
{
2017-07-28 05:44:15 +02:00
const Library : : Error error = loadLibrary ( library , filename ) ;
2015-01-10 22:51:45 +01:00
if ( error . errorcode ! = Library : : ErrorCode : : OK ) {
2021-01-08 10:29:01 +01:00
if ( error . errorcode = = Library : : ErrorCode : : UNKNOWN_ELEMENT ) {
2015-01-10 22:51:45 +01:00
QMessageBox : : information ( this , tr ( " Information " ) , tr ( " The library '%1' contains unknown elements: \n %2 " ) . arg ( filename ) . arg ( error . reason . c_str ( ) ) ) ;
return true ;
}
QString errmsg ;
switch ( error . errorcode ) {
case Library : : ErrorCode : : OK :
break ;
case Library : : ErrorCode : : FILE_NOT_FOUND :
errmsg = tr ( " File not found " ) ;
break ;
case Library : : ErrorCode : : BAD_XML :
errmsg = tr ( " Bad XML " ) ;
break ;
case Library : : ErrorCode : : MISSING_ATTRIBUTE :
errmsg = tr ( " Missing attribute " ) ;
break ;
case Library : : ErrorCode : : BAD_ATTRIBUTE_VALUE :
errmsg = tr ( " Bad attribute value " ) ;
break ;
case Library : : ErrorCode : : UNSUPPORTED_FORMAT :
errmsg = tr ( " Unsupported format " ) ;
break ;
case Library : : ErrorCode : : DUPLICATE_PLATFORM_TYPE :
errmsg = tr ( " Duplicate platform type " ) ;
break ;
case Library : : ErrorCode : : PLATFORM_TYPE_REDEFINED :
errmsg = tr ( " Platform type redefined " ) ;
break ;
2015-12-07 11:24:54 +01:00
case Library : : ErrorCode : : UNKNOWN_ELEMENT :
errmsg = tr ( " Unknown element " ) ;
break ;
default :
errmsg = tr ( " Unknown issue " ) ;
break ;
2015-01-10 22:51:45 +01:00
}
if ( ! error . reason . empty ( ) )
errmsg + = " ' " + QString : : fromStdString ( error . reason ) + " ' " ;
QMessageBox : : information ( this , tr ( " Information " ) , tr ( " Failed to load the selected library '%1'. \n %2 " ) . arg ( filename ) . arg ( errmsg ) ) ;
return false ;
}
return true ;
}
2017-07-28 05:44:15 +02:00
Settings MainWindow : : getCppcheckSettings ( )
2010-08-24 23:47:05 +02:00
{
2017-07-28 05:44:15 +02:00
saveSettings ( ) ; // Save settings
2015-10-14 14:31:52 +02:00
2010-08-24 23:47:05 +02:00
Settings result ;
2010-11-26 21:35:45 +01:00
2021-12-15 20:43:25 +01:00
result . exename = QCoreApplication : : applicationFilePath ( ) . toStdString ( ) ;
2021-12-15 19:22:29 +01:00
2019-03-15 06:59:37 +01:00
const bool std = tryLoadLibrary ( & result . library , " std.cfg " ) ;
2022-03-21 18:35:53 +01:00
if ( ! std )
QMessageBox : : critical ( this , tr ( " Error " ) , tr ( " Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. " ) . arg ( " std.cfg " ) ) ;
result . loadCppcheckCfg ( ) ;
2019-03-15 06:59:37 +01:00
2011-05-12 12:53:59 +02:00
// If project file loaded, read settings from it
2017-07-31 12:02:51 +02:00
if ( mProjectFile ) {
QStringList dirs = mProjectFile - > getIncludeDirs ( ) ;
2017-07-28 05:44:15 +02:00
addIncludeDirs ( dirs , result ) ;
2010-11-26 21:51:38 +01:00
2017-07-31 12:02:51 +02:00
const QStringList defines = mProjectFile - > getDefines ( ) ;
2022-03-21 17:14:26 +01:00
for ( const QString & define : defines ) {
2010-08-21 21:59:55 +02:00
if ( ! result . userDefines . empty ( ) )
result . userDefines + = " ; " ;
result . userDefines + = define . toStdString ( ) ;
2009-06-22 10:57:17 +02:00
}
2013-06-18 14:14:33 +02:00
2021-04-30 16:47:02 +02:00
result . clang = mProjectFile - > clangParser ;
2020-08-22 11:37:44 +02:00
2018-10-09 15:05:05 +02:00
const QStringList undefines = mProjectFile - > getUndefines ( ) ;
2022-03-21 17:14:26 +01:00
for ( const QString & undefine : undefines )
result . userUndefs . insert ( undefine . toStdString ( ) ) ;
2018-10-09 15:05:05 +02:00
2017-07-31 12:02:51 +02:00
const QStringList libraries = mProjectFile - > getLibraries ( ) ;
2022-03-21 17:14:26 +01:00
for ( const QString & library : libraries ) {
2021-06-13 19:48:45 +02:00
result . libraries . emplace_back ( library . toStdString ( ) ) ;
2013-12-30 00:23:42 +01:00
const QString filename = library + " .cfg " ;
2017-07-28 05:44:15 +02:00
tryLoadLibrary ( & result . library , filename ) ;
2013-12-29 18:06:31 +01:00
}
2022-03-21 17:14:26 +01:00
for ( const Suppressions : : Suppression & suppression : mProjectFile - > getSuppressions ( ) ) {
2018-04-09 06:43:48 +02:00
result . nomsg . addSuppression ( suppression ) ;
2013-12-30 22:32:50 +01:00
}
2013-06-18 14:14:33 +02:00
// Only check the given -D configuration
if ( ! defines . isEmpty ( ) )
2016-01-03 16:18:17 +01:00
result . maxConfigs = 1 ;
2016-11-19 20:38:50 +01:00
2019-11-09 17:51:16 +01:00
// If importing a project, only check the given configuration
if ( ! mProjectFile - > getImportProject ( ) . isEmpty ( ) )
result . checkAllConfigurations = false ;
2022-10-30 10:59:43 +01:00
const QString & buildDir = fromNativePath ( mProjectFile - > getBuildDir ( ) ) ;
2016-11-19 20:38:50 +01:00
if ( ! buildDir . isEmpty ( ) ) {
2017-10-08 15:01:03 +02:00
if ( QDir ( buildDir ) . isAbsolute ( ) ) {
result . buildDir = buildDir . toStdString ( ) ;
} else {
QString prjpath = QFileInfo ( mProjectFile - > getFilename ( ) ) . absolutePath ( ) ;
result . buildDir = ( prjpath + ' / ' + buildDir ) . toStdString ( ) ;
}
2016-11-19 20:38:50 +01:00
}
2018-03-13 13:07:10 +01:00
const QString platform = mProjectFile - > getPlatform ( ) ;
if ( platform . endsWith ( " .xml " ) ) {
const QString applicationFilePath = QCoreApplication : : applicationFilePath ( ) ;
2023-03-03 18:36:27 +01:00
result . platform . loadFromFile ( applicationFilePath . toStdString ( ) . c_str ( ) , platform . toStdString ( ) ) ;
2018-03-13 13:07:10 +01:00
} else {
2023-10-13 16:02:04 +02:00
for ( int i = Platform : : Type : : Native ; i < = Platform : : Type : : Unix64 ; i + + ) {
const Platform : : Type p = ( Platform : : Type ) i ;
if ( platform = = Platform : : toString ( p ) ) {
2023-03-03 18:36:27 +01:00
result . platform . set ( p ) ;
2018-03-13 13:07:10 +01:00
break ;
}
}
}
2019-04-10 16:49:24 +02:00
result . maxCtuDepth = mProjectFile - > getMaxCtuDepth ( ) ;
2020-06-26 17:12:02 +02:00
result . maxTemplateRecursion = mProjectFile - > getMaxTemplateRecursion ( ) ;
2023-06-28 19:55:57 +02:00
if ( mProjectFile - > isCheckLevelExhaustive ( ) )
result . setCheckLevelExhaustive ( ) ;
else
result . setCheckLevelNormal ( ) ;
2019-04-10 16:49:24 +02:00
result . checkHeaders = mProjectFile - > getCheckHeaders ( ) ;
result . checkUnusedTemplates = mProjectFile - > getCheckUnusedTemplates ( ) ;
2020-02-09 21:02:28 +01:00
result . safeChecks . classes = mProjectFile - > safeChecks . classes ;
result . safeChecks . externalFunctions = mProjectFile - > safeChecks . externalFunctions ;
result . safeChecks . internalFunctions = mProjectFile - > safeChecks . internalFunctions ;
result . safeChecks . externalVariables = mProjectFile - > safeChecks . externalVariables ;
2022-03-21 17:14:26 +01:00
for ( const QString & s : mProjectFile - > getCheckUnknownFunctionReturn ( ) )
result . checkUnknownFunctionReturn . insert ( s . toStdString ( ) ) ;
2020-05-17 16:50:02 +02:00
2020-08-29 21:26:49 +02:00
QString filesDir ( getDataDir ( ) ) ;
2022-10-30 10:59:43 +01:00
const QString pythonCmd = fromNativePath ( mSettings - > value ( SETTINGS_PYTHON_PATH ) . toString ( ) ) ;
2022-03-21 17:14:26 +01:00
for ( const QString & addon : mProjectFile - > getAddons ( ) ) {
2020-05-17 16:50:02 +02:00
QString addonFilePath = ProjectFile : : getAddonFilePath ( filesDir , addon ) ;
if ( addonFilePath . isEmpty ( ) )
continue ;
2020-05-17 21:45:37 +02:00
addonFilePath . replace ( QChar ( ' \\ ' ) , QChar ( ' / ' ) ) ;
2023-10-08 21:28:57 +02:00
// TODO: use picojson to generate the JSON
2020-05-17 16:50:02 +02:00
QString json ;
json + = " { \" script \" : \" " + addonFilePath + " \" " ;
if ( ! pythonCmd . isEmpty ( ) )
json + = " , \" python \" : \" " + pythonCmd + " \" " ;
2022-12-31 16:08:23 +01:00
const QString misraFile = fromNativePath ( mSettings - > value ( SETTINGS_MISRA_FILE ) . toString ( ) ) ;
2023-06-09 17:15:48 +02:00
if ( ! isCppcheckPremium ( ) & & addon = = " misra " & & ! misraFile . isEmpty ( ) ) {
2022-12-31 16:08:23 +01:00
QString arg ;
if ( misraFile . endsWith ( " .pdf " , Qt : : CaseInsensitive ) )
arg = " --misra-pdf= " + misraFile ;
else
arg = " --rule-texts= " + misraFile ;
json + = " , \" args \" :[ \" " + arg + " \" ] " ;
}
2020-05-17 16:50:02 +02:00
json + = " } " ;
2022-10-31 15:04:16 +01:00
result . addons . emplace ( json . toStdString ( ) ) ;
2023-10-08 21:28:57 +02:00
AddonInfo addonInfo ;
addonInfo . getAddonInfo ( json . toStdString ( ) , result . exename ) ;
result . addonInfos . emplace_back ( std : : move ( addonInfo ) ) ;
2020-05-17 16:50:02 +02:00
}
2022-08-22 21:11:28 +02:00
if ( isCppcheckPremium ( ) ) {
QString premiumArgs ;
if ( mProjectFile - > getBughunting ( ) )
premiumArgs + = " --bughunting " ;
if ( mProjectFile - > getCertIntPrecision ( ) > 0 )
premiumArgs + = " --cert-c-int-precision= " + QString : : number ( mProjectFile - > getCertIntPrecision ( ) ) ;
2023-08-25 13:38:27 +02:00
for ( const QString & c : mProjectFile - > getCodingStandards ( ) )
2022-08-22 21:11:28 +02:00
premiumArgs + = " -- " + c ;
2023-08-25 13:38:27 +02:00
if ( ! premiumArgs . contains ( " misra " ) & & mProjectFile - > getAddons ( ) . contains ( " misra " ) )
premiumArgs + = " --misra-c-2012 " ;
2022-08-22 21:11:28 +02:00
result . premiumArgs = premiumArgs . mid ( 1 ) . toStdString ( ) ;
}
2009-06-22 10:57:17 +02:00
}
2011-08-26 09:34:01 +02:00
// Include directories (and files) are searched in listed order.
// Global include directories must be added AFTER the per project include
// directories so per project include directories can override global ones.
const QString globalIncludes = mSettings - > value ( SETTINGS_GLOBAL_INCLUDE_PATHS ) . toString ( ) ;
2011-10-13 20:53:06 +02:00
if ( ! globalIncludes . isEmpty ( ) ) {
2011-08-26 09:34:01 +02:00
QStringList includes = globalIncludes . split ( " ; " ) ;
2017-07-28 05:44:15 +02:00
addIncludeDirs ( includes , result ) ;
2011-08-26 09:34:01 +02:00
}
2021-02-24 22:00:06 +01:00
result . severity . enable ( Severity : : warning ) ;
result . severity . enable ( Severity : : style ) ;
result . severity . enable ( Severity : : performance ) ;
result . severity . enable ( Severity : : portability ) ;
result . severity . enable ( Severity : : information ) ;
result . checks . enable ( Checks : : missingInclude ) ;
2016-11-19 20:38:50 +01:00
if ( ! result . buildDir . empty ( ) )
2021-02-24 22:00:06 +01:00
result . checks . enable ( Checks : : unusedFunction ) ;
2010-12-26 17:37:11 +01:00
result . debugwarnings = mSettings - > value ( SETTINGS_SHOW_DEBUG_WARNINGS , false ) . toBool ( ) ;
2015-07-25 19:17:24 +02:00
result . quiet = false ;
2016-01-03 16:18:17 +01:00
result . verbose = true ;
result . force = mSettings - > value ( SETTINGS_CHECK_FORCE , 1 ) . toBool ( ) ;
result . xml = false ;
result . jobs = mSettings - > value ( SETTINGS_CHECK_THREADS , 1 ) . toInt ( ) ;
result . inlineSuppressions = mSettings - > value ( SETTINGS_INLINE_SUPPRESSIONS , false ) . toBool ( ) ;
2021-02-24 22:00:06 +01:00
result . certainty . setEnabled ( Certainty : : inconclusive , mSettings - > value ( SETTINGS_INCONCLUSIVE_ERRORS , false ) . toBool ( ) ) ;
2023-10-13 16:02:04 +02:00
if ( ! mProjectFile | | result . platform . type = = Platform : : Type : : Unspecified )
result . platform . set ( ( Platform : : Type ) mSettings - > value ( SETTINGS_CHECKED_PLATFORM , 0 ) . toInt ( ) ) ;
2019-04-12 12:12:12 +02:00
result . standards . setCPP ( mSettings - > value ( SETTINGS_STD_CPP , QString ( ) ) . toString ( ) . toStdString ( ) ) ;
result . standards . setC ( mSettings - > value ( SETTINGS_STD_C , QString ( ) ) . toString ( ) . toStdString ( ) ) ;
2015-10-14 14:31:52 +02:00
result . enforcedLang = ( Settings : : Language ) mSettings - > value ( SETTINGS_ENFORCED_LANGUAGE , 0 ) . toInt ( ) ;
2009-05-24 10:53:29 +02:00
2016-01-03 16:18:17 +01:00
if ( result . jobs < = 1 ) {
result . jobs = 1 ;
2009-05-24 10:53:29 +02:00
}
2021-01-02 19:10:25 +01:00
Settings : : terminate ( false ) ;
2016-10-01 13:08:58 +02:00
2009-03-22 13:32:07 +01:00
return result ;
}
2017-07-30 11:19:47 +02:00
void MainWindow : : analysisDone ( )
2009-03-01 08:38:21 +01:00
{
2011-10-13 20:53:06 +02:00
if ( mExiting ) {
2010-07-17 22:52:50 +02:00
close ( ) ;
return ;
}
2022-03-19 19:54:20 +01:00
mUI - > mResults - > checkingFinished ( ) ;
2017-07-28 05:44:15 +02:00
enableCheckButtons ( true ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionSettings - > setEnabled ( true ) ;
mUI - > mActionOpenXML - > setEnabled ( true ) ;
2017-07-31 12:02:51 +02:00
if ( mProjectFile ) {
2017-07-28 05:44:15 +02:00
enableProjectActions ( true ) ;
2016-01-16 09:59:02 +01:00
} else if ( mIsLogfileLoaded ) {
2022-03-19 19:54:20 +01:00
mUI - > mActionReanalyzeModified - > setEnabled ( false ) ;
mUI - > mActionReanalyzeAll - > setEnabled ( false ) ;
2016-01-16 09:59:02 +01:00
}
2017-07-28 05:44:15 +02:00
enableProjectOpenActions ( true ) ;
2011-12-27 11:46:21 +01:00
mPlatformActions - > setEnabled ( true ) ;
2013-03-02 13:01:21 +01:00
mCStandardActions - > setEnabled ( true ) ;
mCppStandardActions - > setEnabled ( true ) ;
2015-10-14 14:31:52 +02:00
mSelectLanguageActions - > setEnabled ( true ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionPosix - > setEnabled ( true ) ;
2012-10-20 20:14:52 +02:00
if ( mScratchPad )
mScratchPad - > setEnabled ( true ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionViewStats - > setEnabled ( true ) ;
2010-07-13 11:46:28 +02:00
2017-07-31 12:02:51 +02:00
if ( mProjectFile & & ! mProjectFile - > getBuildDir ( ) . isEmpty ( ) ) {
const QString prjpath = QFileInfo ( mProjectFile - > getFilename ( ) ) . absolutePath ( ) ;
const QString buildDir = prjpath + ' / ' + mProjectFile - > getBuildDir ( ) ;
2017-07-30 00:13:00 +02:00
if ( QDir ( buildDir ) . exists ( ) ) {
2022-03-19 19:54:20 +01:00
mUI - > mResults - > saveStatistics ( buildDir + " /statistics.txt " ) ;
mUI - > mResults - > updateFromOldReport ( buildDir + " /lastResults.xml " ) ;
mUI - > mResults - > save ( buildDir + " /lastResults.xml " , Report : : XMLV2 ) ;
2017-07-30 00:13:00 +02:00
}
}
2018-04-12 08:15:04 +02:00
enableResultsButtons ( ) ;
2009-06-20 22:23:54 +02:00
2020-09-21 19:30:47 +02:00
for ( QAction * recentProjectAct : mRecentProjectActs ) {
if ( recentProjectAct ! = nullptr )
2020-09-21 19:48:04 +02:00
recentProjectAct - > setEnabled ( true ) ;
2011-12-28 10:50:26 +01:00
}
2009-06-20 22:23:54 +02:00
// Notify user - if the window is not active - that check is ready
QApplication : : alert ( this , 3000 ) ;
2016-01-16 17:43:57 +01:00
if ( mSettings - > value ( SETTINGS_SHOW_STATISTICS , false ) . toBool ( ) )
2017-07-28 10:41:03 +02:00
showStatistics ( ) ;
2009-03-22 13:32:07 +01:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : checkLockDownUI ( )
2011-02-11 20:08:37 +01:00
{
2017-07-28 05:44:15 +02:00
enableCheckButtons ( false ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionSettings - > setEnabled ( false ) ;
mUI - > mActionOpenXML - > setEnabled ( false ) ;
2017-07-28 05:44:15 +02:00
enableProjectActions ( false ) ;
enableProjectOpenActions ( false ) ;
2011-12-27 11:46:21 +01:00
mPlatformActions - > setEnabled ( false ) ;
2013-03-02 13:01:21 +01:00
mCStandardActions - > setEnabled ( false ) ;
mCppStandardActions - > setEnabled ( false ) ;
2015-10-14 14:31:52 +02:00
mSelectLanguageActions - > setEnabled ( false ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionPosix - > setEnabled ( false ) ;
2012-10-20 20:14:52 +02:00
if ( mScratchPad )
mScratchPad - > setEnabled ( false ) ;
2011-12-28 10:50:26 +01:00
2020-09-21 19:30:47 +02:00
for ( QAction * recentProjectAct : mRecentProjectActs ) {
if ( recentProjectAct ! = nullptr )
2020-09-21 19:48:04 +02:00
recentProjectAct - > setEnabled ( false ) ;
2011-12-28 10:50:26 +01:00
}
2011-02-11 20:08:37 +01:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : programSettings ( )
2009-03-22 13:32:07 +01:00
{
2022-10-30 10:59:43 +01:00
SettingsDialog dialog ( mApplications , mTranslation , isCppcheckPremium ( ) , this ) ;
2011-10-13 20:53:06 +02:00
if ( dialog . exec ( ) = = QDialog : : Accepted ) {
2017-07-28 13:43:49 +02:00
dialog . saveSettingValues ( ) ;
2019-06-23 19:04:53 +02:00
mSettings - > sync ( ) ;
2022-03-19 19:54:20 +01:00
mUI - > mResults - > updateSettings ( dialog . showFullPath ( ) ,
dialog . saveFullPath ( ) ,
dialog . saveAllErrors ( ) ,
dialog . showNoErrorsMessage ( ) ,
dialog . showErrorId ( ) ,
dialog . showInconclusive ( ) ) ;
mUI - > mResults - > updateStyleSetting ( mSettings ) ;
2011-02-07 11:30:13 +01:00
const QString newLang = mSettings - > value ( SETTINGS_LANGUAGE , " en " ) . toString ( ) ;
2017-07-28 05:44:15 +02:00
setLanguage ( newLang ) ;
2009-03-22 13:32:07 +01:00
}
2009-03-01 08:38:21 +01:00
}
2009-03-22 13:32:07 +01:00
2017-07-30 11:19:47 +02:00
void MainWindow : : reAnalyzeModified ( )
2009-03-22 16:42:00 +01:00
{
2017-07-30 11:19:47 +02:00
reAnalyze ( false ) ;
2015-10-14 19:07:20 +02:00
}
2017-07-30 11:19:47 +02:00
void MainWindow : : reAnalyzeAll ( )
2015-10-14 19:07:20 +02:00
{
2017-07-31 12:02:51 +02:00
if ( mProjectFile )
analyzeProject ( mProjectFile ) ;
2017-07-30 23:02:30 +02:00
else
reAnalyze ( true ) ;
2015-10-14 19:07:20 +02:00
}
2018-04-13 15:28:05 +02:00
void MainWindow : : checkLibrary ( )
{
if ( mProjectFile )
analyzeProject ( mProjectFile , true ) ;
}
void MainWindow : : checkConfiguration ( )
{
if ( mProjectFile )
analyzeProject ( mProjectFile , false , true ) ;
}
2023-03-30 07:24:23 +02:00
void MainWindow : : reAnalyzeSelected ( const QStringList & files )
2015-12-23 10:28:07 +01:00
{
if ( files . empty ( ) )
return ;
2017-07-28 12:39:28 +02:00
if ( mThread - > isChecking ( ) )
2015-12-23 10:28:07 +01:00
return ;
// Clear details, statistics and progress
2022-03-19 19:54:20 +01:00
mUI - > mResults - > clear ( false ) ;
2015-12-23 10:28:07 +01:00
for ( int i = 0 ; i < files . size ( ) ; + + i )
2022-03-19 19:54:20 +01:00
mUI - > mResults - > clearRecheckFile ( files [ i ] ) ;
2015-12-29 01:38:36 +01:00
2022-03-19 19:54:20 +01:00
mCurrentDirectory = mUI - > mResults - > getCheckDirectory ( ) ;
2015-12-29 01:38:36 +01:00
FileList pathList ;
2017-07-28 10:55:51 +02:00
pathList . addPathList ( files ) ;
2017-07-31 12:02:51 +02:00
if ( mProjectFile )
pathList . addExcludeList ( mProjectFile - > getExcludedPaths ( ) ) ;
2017-07-28 10:55:51 +02:00
QStringList fileNames = pathList . getFileList ( ) ;
2017-07-28 10:41:03 +02:00
checkLockDownUI ( ) ; // lock UI while checking
2022-03-19 19:54:20 +01:00
mUI - > mResults - > checkingStarted ( fileNames . size ( ) ) ;
2017-07-28 12:39:28 +02:00
mThread - > setCheckFiles ( fileNames ) ;
2015-12-23 10:28:07 +01:00
// Saving last check start time, otherwise unchecked modified files will not be
// considered in "Modified Files Check" performed after "Selected Files Check"
// TODO: Should we store per file CheckStartTime?
2017-07-28 12:39:28 +02:00
QDateTime saveCheckStartTime = mThread - > getCheckStartTime ( ) ;
2023-08-31 18:28:47 +02:00
const Settings & checkSettings = getCppcheckSettings ( ) ;
mThread - > check ( checkSettings ) ;
mUI - > mResults - > setCheckSettings ( checkSettings ) ;
2017-07-28 12:39:28 +02:00
mThread - > setCheckStartTime ( saveCheckStartTime ) ;
2015-12-23 10:28:07 +01:00
}
2017-07-30 11:19:47 +02:00
void MainWindow : : reAnalyze ( bool all )
2015-10-14 19:07:20 +02:00
{
2017-07-28 12:39:28 +02:00
const QStringList files = mThread - > getReCheckFiles ( all ) ;
2012-02-14 21:16:11 +01:00
if ( files . empty ( ) )
return ;
2010-07-07 11:25:47 +02:00
2012-09-05 21:01:50 +02:00
// Clear details, statistics and progress
2022-03-19 19:54:20 +01:00
mUI - > mResults - > clear ( all ) ;
2012-09-05 21:01:50 +02:00
2012-02-14 21:16:11 +01:00
// Clear results for changed files
for ( int i = 0 ; i < files . size ( ) ; + + i )
2022-03-19 19:54:20 +01:00
mUI - > mResults - > clear ( files [ i ] ) ;
2012-02-14 21:16:11 +01:00
2017-07-28 10:41:03 +02:00
checkLockDownUI ( ) ; // lock UI while checking
2022-03-19 19:54:20 +01:00
mUI - > mResults - > checkingStarted ( files . size ( ) ) ;
2010-07-07 11:25:47 +02:00
2017-07-31 12:02:51 +02:00
if ( mProjectFile )
qDebug ( ) < < " Rechecking project file " < < mProjectFile - > getFilename ( ) ;
2011-06-04 14:38:51 +02:00
2017-07-28 12:39:28 +02:00
mThread - > setCheckFiles ( all ) ;
2023-08-31 18:28:47 +02:00
const Settings & checkSettings = getCppcheckSettings ( ) ;
mThread - > check ( checkSettings ) ;
mUI - > mResults - > setCheckSettings ( checkSettings ) ;
2009-03-22 16:42:00 +01:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : clearResults ( )
2009-03-22 16:42:00 +01:00
{
2020-04-29 18:10:01 +02:00
if ( mProjectFile & & ! mProjectFile - > getBuildDir ( ) . isEmpty ( ) ) {
QDir dir ( QFileInfo ( mProjectFile - > getFilename ( ) ) . absolutePath ( ) + ' / ' + mProjectFile - > getBuildDir ( ) ) ;
for ( const QString & f : dir . entryList ( QDir : : Files ) ) {
2022-04-11 19:15:42 +02:00
if ( ! f . endsWith ( " files.txt " ) ) {
static const QRegularExpression rx ( " ^.*.s[0-9]+$ " ) ;
if ( ! rx . match ( f ) . hasMatch ( ) )
dir . remove ( f ) ;
}
2020-04-29 18:10:01 +02:00
}
}
2022-03-19 19:54:20 +01:00
mUI - > mResults - > clear ( true ) ;
Q_ASSERT ( false = = mUI - > mResults - > hasResults ( ) ) ;
2018-04-12 08:15:04 +02:00
enableResultsButtons ( ) ;
2009-03-22 16:42:00 +01:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : openResults ( )
2010-07-10 15:37:36 +02:00
{
2022-03-19 19:54:20 +01:00
if ( mUI - > mResults - > hasResults ( ) ) {
2012-08-02 14:09:08 +02:00
QMessageBox msgBox ( this ) ;
msgBox . setWindowTitle ( tr ( " Cppcheck " ) ) ;
const QString msg ( tr ( " Current results will be cleared. \n \n "
2019-07-12 17:55:44 +02:00
" Opening a new XML file will clear current results. \n "
2012-08-02 14:09:08 +02:00
" Do you want to proceed? " ) ) ;
msgBox . setText ( msg ) ;
msgBox . setIcon ( QMessageBox : : Warning ) ;
msgBox . addButton ( QMessageBox : : Yes ) ;
msgBox . addButton ( QMessageBox : : No ) ;
msgBox . setDefaultButton ( QMessageBox : : Yes ) ;
2022-10-02 07:12:40 +02:00
const int dlgResult = msgBox . exec ( ) ;
2012-08-02 14:09:08 +02:00
if ( dlgResult = = QMessageBox : : No ) {
return ;
}
}
2010-07-10 15:37:36 +02:00
QString selectedFilter ;
2011-08-22 21:37:38 +02:00
const QString filter ( tr ( " XML files (*.xml) " )) ;
2010-07-10 15:37:36 +02:00
QString selectedFile = QFileDialog : : getOpenFileName ( this ,
2021-08-07 20:51:18 +02:00
tr ( " Open the report file " ) ,
getPath ( SETTINGS_LAST_RESULT_PATH ) ,
filter ,
& selectedFilter ) ;
2010-07-10 15:37:36 +02:00
2013-02-10 07:48:09 +01:00
if ( ! selectedFile . isEmpty ( ) ) {
2017-07-28 05:44:15 +02:00
loadResults ( selectedFile ) ;
2013-02-10 07:48:09 +01:00
}
}
2018-06-23 23:04:54 +02:00
void MainWindow : : loadResults ( const QString & selectedFile )
2013-02-10 07:48:09 +01:00
{
2018-02-20 13:10:36 +01:00
if ( selectedFile . isEmpty ( ) )
return ;
if ( mProjectFile )
closeProjectFile ( ) ;
mIsLogfileLoaded = true ;
2022-03-19 19:54:20 +01:00
mUI - > mResults - > clear ( true ) ;
mUI - > mActionReanalyzeModified - > setEnabled ( false ) ;
mUI - > mActionReanalyzeAll - > setEnabled ( false ) ;
mUI - > mResults - > readErrorsXml ( selectedFile ) ;
2018-02-20 13:10:36 +01:00
setPath ( SETTINGS_LAST_RESULT_PATH , selectedFile ) ;
2018-04-12 08:15:04 +02:00
formatAndSetTitle ( selectedFile ) ;
2010-07-10 15:37:36 +02:00
}
2018-06-23 23:04:54 +02:00
void MainWindow : : loadResults ( const QString & selectedFile , const QString & sourceDirectory )
2013-02-10 07:48:09 +01:00
{
2017-07-28 05:44:15 +02:00
loadResults ( selectedFile ) ;
2022-03-19 19:54:20 +01:00
mUI - > mResults - > setCheckDirectory ( sourceDirectory ) ;
2013-02-10 07:48:09 +01:00
}
2017-07-28 05:44:15 +02:00
void MainWindow : : enableCheckButtons ( bool enable )
2009-03-22 16:42:00 +01:00
{
2022-03-19 19:54:20 +01:00
mUI - > mActionStop - > setEnabled ( ! enable ) ;
mUI - > mActionAnalyzeFiles - > setEnabled ( enable ) ;
2009-10-13 10:19:00 +02:00
2017-07-31 12:02:51 +02:00
if ( mProjectFile ) {
2022-03-19 19:54:20 +01:00
mUI - > mActionReanalyzeModified - > setEnabled ( false ) ;
mUI - > mActionReanalyzeAll - > setEnabled ( enable ) ;
2017-07-30 23:02:30 +02:00
} else if ( ! enable | | mThread - > hasPreviousFiles ( ) ) {
2022-03-19 19:54:20 +01:00
mUI - > mActionReanalyzeModified - > setEnabled ( enable ) ;
mUI - > mActionReanalyzeAll - > setEnabled ( enable ) ;
2015-10-14 19:07:20 +02:00
}
2009-10-13 10:19:00 +02:00
2022-03-19 19:54:20 +01:00
mUI - > mActionAnalyzeDirectory - > setEnabled ( enable ) ;
2023-01-30 14:59:45 +01:00
if ( isCppcheckPremium ( ) ) {
mUI - > mActionComplianceReport - > setEnabled ( enable & & mProjectFile & & mProjectFile - > getAddons ( ) . contains ( " misra " ) ) ;
}
2009-03-22 16:42:00 +01:00
}
2018-04-12 08:15:04 +02:00
void MainWindow : : enableResultsButtons ( )
{
2022-10-02 07:12:40 +02:00
const bool enabled = mUI - > mResults - > hasResults ( ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionClearResults - > setEnabled ( enabled ) ;
mUI - > mActionSave - > setEnabled ( enabled ) ;
mUI - > mActionPrint - > setEnabled ( enabled ) ;
mUI - > mActionPrintPreview - > setEnabled ( enabled ) ;
2018-04-12 08:15:04 +02:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : showStyle ( bool checked )
2009-03-22 18:39:44 +01:00
{
2022-03-19 19:54:20 +01:00
mUI - > mResults - > showResults ( ShowTypes : : ShowStyle , checked ) ;
2009-03-22 18:39:44 +01:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : showErrors ( bool checked )
2009-03-22 18:39:44 +01:00
{
2022-03-19 19:54:20 +01:00
mUI - > mResults - > showResults ( ShowTypes : : ShowErrors , checked ) ;
2009-03-22 18:39:44 +01:00
}
2009-05-23 10:17:27 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : showWarnings ( bool checked )
2010-10-18 19:50:34 +02:00
{
2022-03-19 19:54:20 +01:00
mUI - > mResults - > showResults ( ShowTypes : : ShowWarnings , checked ) ;
2010-10-18 19:50:34 +02:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : showPortability ( bool checked )
2010-12-27 10:06:31 +01:00
{
2022-03-19 19:54:20 +01:00
mUI - > mResults - > showResults ( ShowTypes : : ShowPortability , checked ) ;
2010-12-27 10:06:31 +01:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : showPerformance ( bool checked )
2010-10-18 19:50:34 +02:00
{
2022-03-19 19:54:20 +01:00
mUI - > mResults - > showResults ( ShowTypes : : ShowPerformance , checked ) ;
2010-10-18 19:50:34 +02:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : showInformation ( bool checked )
2010-12-26 13:36:24 +01:00
{
2022-03-19 19:54:20 +01:00
mUI - > mResults - > showResults ( ShowTypes : : ShowInformation , checked ) ;
2010-12-26 13:36:24 +01:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : checkAll ( )
2009-05-23 10:17:27 +02:00
{
2017-07-28 05:44:15 +02:00
toggleAllChecked ( true ) ;
2009-05-23 10:17:27 +02:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : uncheckAll ( )
2009-05-23 10:17:27 +02:00
{
2017-07-28 05:44:15 +02:00
toggleAllChecked ( false ) ;
2009-05-23 10:17:27 +02:00
}
2009-06-04 16:02:35 +02:00
void MainWindow : : closeEvent ( QCloseEvent * event )
{
// Check that we aren't checking files
2017-07-28 12:39:28 +02:00
if ( ! mThread - > isChecking ( ) ) {
2017-07-28 05:44:15 +02:00
saveSettings ( ) ;
2009-06-04 16:02:35 +02:00
event - > accept ( ) ;
2011-10-13 20:53:06 +02:00
} else {
2017-07-30 13:31:02 +02:00
const QString text ( tr ( " Analyzer is running. \n \n " \
" Do you want to stop the analysis and exit Cppcheck? " ) ) ;
2009-06-09 09:51:27 +02:00
QMessageBox msg ( QMessageBox : : Warning ,
tr ( " Cppcheck " ) ,
text ,
2010-07-16 11:44:11 +02:00
QMessageBox : : Yes | QMessageBox : : No ,
2009-06-09 09:51:27 +02:00
this ) ;
2010-07-16 11:44:11 +02:00
msg . setDefaultButton ( QMessageBox : : No ) ;
2022-10-02 07:12:40 +02:00
const int rv = msg . exec ( ) ;
2011-10-13 20:53:06 +02:00
if ( rv = = QMessageBox : : Yes ) {
2010-07-16 11:44:11 +02:00
// This isn't really very clean way to close threads but since the app is
// exiting it doesn't matter.
2017-07-28 12:39:28 +02:00
mThread - > stop ( ) ;
2017-07-28 05:44:15 +02:00
saveSettings ( ) ;
2010-07-17 22:52:50 +02:00
mExiting = true ;
2010-07-16 11:44:11 +02:00
}
2010-07-17 22:52:50 +02:00
event - > ignore ( ) ;
2009-06-04 16:02:35 +02:00
}
}
2017-07-28 05:44:15 +02:00
void MainWindow : : toggleAllChecked ( bool checked )
2009-05-23 10:17:27 +02:00
{
2022-03-19 19:54:20 +01:00
mUI - > mActionShowStyle - > setChecked ( checked ) ;
2017-07-28 10:41:03 +02:00
showStyle ( checked ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionShowErrors - > setChecked ( checked ) ;
2017-07-28 10:41:03 +02:00
showErrors ( checked ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionShowWarnings - > setChecked ( checked ) ;
2017-07-28 10:41:03 +02:00
showWarnings ( checked ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionShowPortability - > setChecked ( checked ) ;
2017-07-28 10:41:03 +02:00
showPortability ( checked ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionShowPerformance - > setChecked ( checked ) ;
2017-07-28 10:41:03 +02:00
showPerformance ( checked ) ;
2022-03-19 19:54:20 +01:00
mUI - > mActionShowInformation - > setChecked ( checked ) ;
2017-07-28 10:41:03 +02:00
showInformation ( checked ) ;
2009-05-23 10:17:27 +02:00
}
2009-05-24 10:53:29 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : about ( )
2009-05-24 10:53:29 +02:00
{
2022-03-24 22:44:47 +01:00
if ( ! mCppcheckCfgAbout . isEmpty ( ) ) {
QMessageBox msg ( QMessageBox : : Information ,
tr ( " About " ) ,
mCppcheckCfgAbout ,
QMessageBox : : Ok ,
this ) ;
msg . exec ( ) ;
}
else {
AboutDialog * dlg = new AboutDialog ( CppCheck : : version ( ) , CppCheck : : extraVersion ( ) , this ) ;
dlg - > exec ( ) ;
}
2009-05-24 10:53:29 +02:00
}
2009-05-26 17:21:39 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : showLicense ( )
2009-06-14 11:57:43 +02:00
{
2009-07-02 19:23:44 +02:00
FileViewDialog * dlg = new FileViewDialog ( " :COPYING " , tr ( " License " ) , this ) ;
2009-07-02 18:46:26 +02:00
dlg - > resize ( 570 , 400 ) ;
2009-06-14 11:57:43 +02:00
dlg - > exec ( ) ;
}
2017-07-28 10:41:03 +02:00
void MainWindow : : showAuthors ( )
2009-06-14 11:57:43 +02:00
{
2009-07-02 19:23:44 +02:00
FileViewDialog * dlg = new FileViewDialog ( " :AUTHORS " , tr ( " Authors " ) , this ) ;
2009-06-14 22:22:19 +02:00
dlg - > resize ( 350 , 400 ) ;
2009-06-14 11:57:43 +02:00
dlg - > exec ( ) ;
}
2009-05-26 17:21:39 +02:00
2018-06-23 23:04:54 +02:00
void MainWindow : : performSelectedFilesCheck ( const QStringList & selectedFilesList )
2015-12-23 10:28:07 +01:00
{
2017-08-14 05:14:18 +02:00
reAnalyzeSelected ( selectedFilesList ) ;
2015-12-23 10:28:07 +01:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : save ( )
2009-05-26 17:21:39 +02:00
{
2009-06-17 23:34:22 +02:00
QString selectedFilter ;
2017-07-29 19:36:01 +02:00
const QString filter ( tr ( " XML files (*.xml) ; ; Text files ( * . txt ) ; ; CSV files ( * . csv ) " )) ;
2009-06-17 23:34:22 +02:00
QString selectedFile = QFileDialog : : getSaveFileName ( this ,
2021-08-07 20:51:18 +02:00
tr ( " Save the report file " ) ,
getPath ( SETTINGS_LAST_RESULT_PATH ) ,
filter ,
& selectedFilter ) ;
2009-06-17 23:34:22 +02:00
2011-10-13 20:53:06 +02:00
if ( ! selectedFile . isEmpty ( ) ) {
2009-11-19 23:19:44 +01:00
Report : : Type type = Report : : TXT ;
2017-07-29 19:36:01 +02:00
if ( selectedFilter = = tr ( " XML files (*.xml) " ) ) {
2011-02-03 20:40:35 +01:00
type = Report : : XMLV2 ;
if ( ! selectedFile . endsWith ( " .xml " , Qt : : CaseInsensitive ) )
selectedFile + = " .xml " ;
2011-10-13 20:53:06 +02:00
} else if ( selectedFilter = = tr ( " Text files (*.txt) " )) {
2009-07-06 11:30:49 +02:00
type = Report : : TXT ;
2010-04-02 07:30:58 +02:00
if ( ! selectedFile . endsWith ( " .txt " , Qt : : CaseInsensitive ) )
2009-07-06 11:30:49 +02:00
selectedFile + = " .txt " ;
2011-10-13 20:53:06 +02:00
} else if ( selectedFilter = = tr ( " CSV files (*.csv) " )) {
2009-07-06 11:30:49 +02:00
type = Report : : CSV ;
2010-04-02 07:30:58 +02:00
if ( ! selectedFile . endsWith ( " .csv " , Qt : : CaseInsensitive ) )
2009-07-06 11:30:49 +02:00
selectedFile + = " .csv " ;
2011-10-13 20:53:06 +02:00
} else {
2010-04-02 07:30:58 +02:00
if ( selectedFile . endsWith ( " .xml " , Qt : : CaseInsensitive ) )
2017-07-29 19:36:01 +02:00
type = Report : : XMLV2 ;
2010-04-02 07:30:58 +02:00
else if ( selectedFile . endsWith ( " .txt " , Qt : : CaseInsensitive ) )
2009-11-19 23:19:44 +01:00
type = Report : : TXT ;
2010-04-02 07:30:58 +02:00
else if ( selectedFile . endsWith ( " .csv " , Qt : : CaseInsensitive ) )
2009-11-19 23:19:44 +01:00
type = Report : : CSV ;
}
2009-06-17 23:34:22 +02:00
2022-03-19 19:54:20 +01:00
mUI - > mResults - > save ( selectedFile , type ) ;
2017-07-28 11:20:35 +02:00
setPath ( SETTINGS_LAST_RESULT_PATH , selectedFile ) ;
2009-06-03 20:18:22 +02:00
}
2009-05-26 17:21:39 +02:00
}
2023-01-30 14:59:45 +01:00
void MainWindow : : complianceReport ( )
{
2023-08-25 13:38:27 +02:00
if ( ! mUI - > mResults - > isSuccess ( ) ) {
QMessageBox m ( QMessageBox : : Critical ,
" Cppcheck " ,
tr ( " Cannot generate a compliance report right now, an analysis must finish successfully. Try to reanalyze the code and ensure there are no critical errors. " ) ,
QMessageBox : : Ok ,
this ) ;
m . exec ( ) ;
return ;
}
2023-01-30 14:59:45 +01:00
2023-08-25 13:38:27 +02:00
QTemporaryFile tempResults ;
tempResults . open ( ) ;
tempResults . close ( ) ;
2023-01-30 14:59:45 +01:00
2023-08-25 13:38:27 +02:00
mUI - > mResults - > save ( tempResults . fileName ( ) , Report : : XMLV2 ) ;
ComplianceReportDialog dlg ( mProjectFile , tempResults . fileName ( ) ) ;
dlg . exec ( ) ;
2023-01-30 14:59:45 +01:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : resultsAdded ( )
2021-08-07 20:51:18 +02:00
{ }
2009-06-22 17:45:48 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : toggleMainToolBar ( )
2009-07-01 22:46:42 +02:00
{
2022-03-19 19:54:20 +01:00
mUI - > mToolBarMain - > setVisible ( mUI - > mActionToolBarMain - > isChecked ( ) ) ;
2009-07-01 22:46:42 +02:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : toggleViewToolBar ( )
2010-07-03 18:37:09 +02:00
{
2022-03-19 19:54:20 +01:00
mUI - > mToolBarView - > setVisible ( mUI - > mActionToolBarView - > isChecked ( ) ) ;
2010-07-03 18:37:09 +02:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : toggleFilterToolBar ( )
2011-05-04 07:30:54 +02:00
{
2022-03-19 19:54:20 +01:00
mUI - > mToolBarFilter - > setVisible ( mUI - > mActionToolBarFilter - > isChecked ( ) ) ;
2011-05-04 07:30:54 +02:00
mLineEditFilter - > clear ( ) ; // Clearing the filter also disables filtering
}
2017-07-28 05:44:15 +02:00
void MainWindow : : formatAndSetTitle ( const QString & text )
2009-06-22 17:45:48 +02:00
{
2020-04-22 09:26:21 +02:00
QString nameWithVersion = QString ( " Cppcheck %1 " ) . arg ( CppCheck : : version ( ) ) ;
QString extraVersion = CppCheck : : extraVersion ( ) ;
if ( ! extraVersion . isEmpty ( ) ) {
nameWithVersion + = " ( " + extraVersion + " ) " ;
}
2022-03-24 22:44:47 +01:00
if ( ! mCppcheckCfgProductName . isEmpty ( ) )
nameWithVersion = mCppcheckCfgProductName ;
2009-06-22 17:45:48 +02:00
QString title ;
2010-04-02 07:30:58 +02:00
if ( text . isEmpty ( ) )
2020-04-22 09:26:21 +02:00
title = nameWithVersion ;
2009-06-22 17:45:48 +02:00
else
2020-04-22 09:26:21 +02:00
title = QString ( " %1 - %2 " ) . arg ( nameWithVersion , text ) ;
2009-06-22 17:45:48 +02:00
setWindowTitle ( title ) ;
}
2009-07-01 22:46:42 +02:00
2017-07-28 05:44:15 +02:00
void MainWindow : : setLanguage ( const QString & code )
2009-07-01 22:46:42 +02:00
{
2017-07-28 13:43:49 +02:00
const QString currentLang = mTranslation - > getCurrentLanguage ( ) ;
2011-02-08 17:22:44 +01:00
if ( currentLang = = code )
2009-07-02 10:32:29 +02:00
return ;
2017-07-28 13:43:49 +02:00
if ( mTranslation - > setLanguage ( code ) ) {
2009-07-02 12:48:32 +02:00
//Translate everything that is visible here
2022-03-19 19:54:20 +01:00
mUI - > retranslateUi ( this ) ;
mUI - > mResults - > translate ( ) ;
2021-01-15 18:19:51 +01:00
mLineEditFilter - > setPlaceholderText ( QCoreApplication : : translate ( " MainWindow " , " Quick Filter: " ) ) ;
if ( mProjectFile )
formatAndSetTitle ( tr ( " Project: " ) + ' ' + mProjectFile - > getFilename ( ) ) ;
2021-01-23 17:56:16 +01:00
if ( mScratchPad )
mScratchPad - > translate ( ) ;
2009-07-02 10:32:29 +02:00
}
2009-07-01 22:46:42 +02:00
}
2009-07-02 10:32:29 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : aboutToShowViewMenu ( )
2009-07-02 19:11:47 +02:00
{
2022-03-19 19:54:20 +01:00
mUI - > mActionToolBarMain - > setChecked ( mUI - > mToolBarMain - > isVisible ( ) ) ;
mUI - > mActionToolBarView - > setChecked ( mUI - > mToolBarView - > isVisible ( ) ) ;
mUI - > mActionToolBarFilter - > setChecked ( mUI - > mToolBarFilter - > isVisible ( ) ) ;
2009-07-02 19:11:47 +02:00
}
2009-07-02 19:23:44 +02:00
2017-07-30 11:19:47 +02:00
void MainWindow : : stopAnalysis ( )
2009-07-02 19:23:44 +02:00
{
2017-07-28 12:39:28 +02:00
mThread - > stop ( ) ;
2023-08-25 13:38:27 +02:00
mUI - > mResults - > stopAnalysis ( ) ;
2022-03-19 19:54:20 +01:00
mUI - > mResults - > disableProgressbar ( ) ;
2017-08-02 22:28:45 +02:00
const QString & lastResults = getLastResults ( ) ;
if ( ! lastResults . isEmpty ( ) ) {
2022-03-19 19:54:20 +01:00
mUI - > mResults - > updateFromOldReport ( lastResults ) ;
2017-08-02 20:24:23 +02:00
}
2009-07-02 19:23:44 +02:00
}
2010-02-23 16:29:49 +01:00
2017-07-28 10:41:03 +02:00
void MainWindow : : openHelpContents ( )
2010-02-23 16:29:49 +01:00
{
2017-07-28 05:44:15 +02:00
openOnlineHelp ( ) ;
2010-02-23 16:29:49 +01:00
}
2017-07-28 05:44:15 +02:00
void MainWindow : : openOnlineHelp ( )
2010-02-23 16:29:49 +01:00
{
2020-08-25 19:58:52 +02:00
HelpDialog * helpDialog = new HelpDialog ;
helpDialog - > showMaximized ( ) ;
2010-02-23 16:29:49 +01:00
}
2010-07-07 20:18:42 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : openProjectFile ( )
2010-07-07 20:18:42 +02:00
{
const QString filter = tr ( " Project files (*.cppcheck);;All files(*.*) " ) ;
2012-01-10 20:40:11 +01:00
const QString filepath = QFileDialog : : getOpenFileName ( this ,
2021-08-07 20:51:18 +02:00
tr ( " Select Project File " ) ,
getPath ( SETTINGS_LAST_PROJECT_PATH ) ,
filter ) ;
2010-07-07 20:18:42 +02:00
2011-10-13 20:53:06 +02:00
if ( ! filepath . isEmpty ( ) ) {
2012-01-10 20:40:11 +01:00
const QFileInfo fi ( filepath ) ;
if ( fi . exists ( ) & & fi . isFile ( ) & & fi . isReadable ( ) ) {
2017-07-28 11:20:35 +02:00
setPath ( SETTINGS_LAST_PROJECT_PATH , filepath ) ;
2017-07-28 05:44:15 +02:00
loadProjectFile ( filepath ) ;
2012-01-10 20:40:11 +01:00
}
2011-04-07 14:34:15 +02:00
}
}
2010-08-21 18:38:51 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : showScratchpad ( )
2012-10-20 20:14:52 +02:00
{
if ( ! mScratchPad )
mScratchPad = new ScratchPad ( * this ) ;
mScratchPad - > show ( ) ;
if ( ! mScratchPad - > isActiveWindow ( ) )
mScratchPad - > activateWindow ( ) ;
}
2017-07-28 05:44:15 +02:00
void MainWindow : : loadProjectFile ( const QString & filePath )
2011-04-07 14:34:15 +02:00
{
QFileInfo inf ( filePath ) ;
const QString filename = inf . fileName ( ) ;
2017-07-30 00:13:00 +02:00
formatAndSetTitle ( tr ( " Project: " ) + ' ' + filename ) ;
2017-07-28 05:44:15 +02:00
addProjectMRU ( filePath ) ;
2011-04-07 14:34:15 +02:00
2016-01-16 09:59:02 +01:00
mIsLogfileLoaded = false ;
2022-03-19 19:54:20 +01:00
mUI - > mActionCloseProjectFile - > setEnabled ( true ) ;
mUI - > mActionEditProjectFile - > setEnabled ( true ) ;
2017-07-31 12:02:51 +02:00
delete mProjectFile ;
mProjectFile = new ProjectFile ( filePath , this ) ;
2020-07-15 13:03:07 +02:00
mProjectFile - > setActiveProject ( ) ;
2017-07-30 13:42:34 +02:00
if ( ! loadLastResults ( ) )
2017-07-31 12:02:51 +02:00
analyzeProject ( mProjectFile ) ;
2017-07-30 13:42:34 +02:00
}
2017-08-02 22:28:45 +02:00
QString MainWindow : : getLastResults ( ) const
{
if ( ! mProjectFile | | mProjectFile - > getBuildDir ( ) . isEmpty ( ) )
return QString ( ) ;
return QFileInfo ( mProjectFile - > getFilename ( ) ) . absolutePath ( ) + ' / ' + mProjectFile - > getBuildDir ( ) + " /lastResults.xml " ;
}
2017-07-30 13:42:34 +02:00
bool MainWindow : : loadLastResults ( )
{
2017-08-02 22:28:45 +02:00
const QString & lastResults = getLastResults ( ) ;
if ( lastResults . isEmpty ( ) )
2017-07-30 13:42:34 +02:00
return false ;
2023-08-22 12:01:30 +02:00
if ( ! QFileInfo : : exists ( lastResults ) )
2017-07-30 13:42:34 +02:00
return false ;
2022-03-19 19:54:20 +01:00
mUI - > mResults - > readErrorsXml ( lastResults ) ;
mUI - > mResults - > setCheckDirectory ( mSettings - > value ( SETTINGS_LAST_CHECK_PATH , QString ( ) ) . toString ( ) ) ;
mUI - > mActionViewStats - > setEnabled ( true ) ;
2018-04-12 08:15:04 +02:00
enableResultsButtons ( ) ;
2017-07-30 13:42:34 +02:00
return true ;
2011-08-24 21:41:48 +02:00
}
2018-04-13 15:28:05 +02:00
void MainWindow : : analyzeProject ( const ProjectFile * projectFile , const bool checkLibrary , const bool checkConfiguration )
2011-08-24 21:41:48 +02:00
{
2017-08-06 21:28:49 +02:00
Settings : : terminate ( false ) ;
2017-07-31 12:02:51 +02:00
QFileInfo inf ( projectFile - > getFilename ( ) ) ;
const QString rootpath = projectFile - > getRootPath ( ) ;
2011-04-07 14:34:15 +02:00
2018-07-01 08:00:05 +02:00
QDir : : setCurrent ( inf . absolutePath ( ) ) ;
2020-05-17 16:50:02 +02:00
mThread - > setAddonsAndTools ( projectFile - > getAddonsAndTools ( ) ) ;
2017-08-03 12:30:28 +02:00
2011-06-07 13:29:59 +02:00
// If the root path is not given or is not "current dir", use project
// file's location directory as root path
2011-04-07 14:34:15 +02:00
if ( rootpath . isEmpty ( ) | | rootpath = = " . " )
mCurrentDirectory = inf . canonicalPath ( ) ;
2019-07-17 16:01:54 +02:00
else if ( rootpath . startsWith ( " ./ " ) )
2015-08-10 20:48:08 +02:00
mCurrentDirectory = inf . canonicalPath ( ) + rootpath . mid ( 1 ) ;
2011-04-07 14:34:15 +02:00
else
mCurrentDirectory = rootpath ;
2017-07-31 12:02:51 +02:00
if ( ! projectFile - > getBuildDir ( ) . isEmpty ( ) ) {
QString buildDir = projectFile - > getBuildDir ( ) ;
2017-07-28 19:39:11 +02:00
if ( ! QDir : : isAbsolutePath ( buildDir ) )
2019-07-17 16:01:54 +02:00
buildDir = inf . canonicalPath ( ) + ' / ' + buildDir ;
2017-07-28 19:39:11 +02:00
if ( ! QDir ( buildDir ) . exists ( ) ) {
2021-06-09 11:21:23 +02:00
QMessageBox msg ( QMessageBox : : Question ,
2017-07-28 19:39:11 +02:00
tr ( " Cppcheck " ) ,
tr ( " Build dir '%1' does not exist, create it? " ) . arg ( buildDir ) ,
QMessageBox : : Yes | QMessageBox : : No ,
this ) ;
if ( msg . exec ( ) = = QMessageBox : : Yes ) {
2017-12-05 20:44:09 +01:00
QDir ( ) . mkpath ( buildDir ) ;
2021-06-09 11:21:23 +02:00
} else if ( ! projectFile - > getAddons ( ) . isEmpty ( ) ) {
QMessageBox m ( QMessageBox : : Critical ,
tr ( " Cppcheck " ) ,
tr ( " To check the project using addons, you need a build directory. " ) ,
QMessageBox : : Ok ,
this ) ;
m . exec ( ) ;
return ;
2017-07-28 19:39:11 +02:00
}
}
}
2017-07-31 12:02:51 +02:00
if ( ! projectFile - > getImportProject ( ) . isEmpty ( ) ) {
2016-08-18 21:58:50 +02:00
ImportProject p ;
2018-03-06 22:50:16 +01:00
QString prjfile ;
2018-03-06 22:51:06 +01:00
if ( QFileInfo ( projectFile - > getImportProject ( ) ) . isAbsolute ( ) ) {
2018-03-06 22:50:16 +01:00
prjfile = projectFile - > getImportProject ( ) ;
2018-03-06 22:51:06 +01:00
} else {
2018-03-06 22:50:16 +01:00
prjfile = inf . canonicalPath ( ) + ' / ' + projectFile - > getImportProject ( ) ;
}
2017-09-02 11:11:35 +02:00
try {
2023-04-06 21:38:12 +02:00
const ImportProject : : Type result = p . import ( prjfile . toStdString ( ) ) ;
QString errorMessage ;
switch ( result ) {
case ImportProject : : Type : : COMPILE_DB :
case ImportProject : : Type : : VS_SLN :
case ImportProject : : Type : : VS_VCXPROJ :
case ImportProject : : Type : : BORLAND :
case ImportProject : : Type : : CPPCHECK_GUI :
// Loading was successful
break ;
case ImportProject : : Type : : MISSING :
errorMessage = tr ( " Failed to open file " ) ;
break ;
case ImportProject : : Type : : UNKNOWN :
errorMessage = tr ( " Unknown project file format " ) ;
break ;
case ImportProject : : Type : : FAILURE :
errorMessage = tr ( " Failed to import project file " ) ;
break ;
2023-10-05 21:36:44 +02:00
case ImportProject : : Type : : NONE :
// can never happen
break ;
2023-04-06 21:38:12 +02:00
}
if ( ! errorMessage . isEmpty ( ) ) {
QMessageBox msg ( QMessageBox : : Critical ,
tr ( " Cppcheck " ) ,
tr ( " Failed to import '%1': %2 \n \n Analysis is stopped. " ) . arg ( prjfile ) . arg ( errorMessage ) ,
QMessageBox : : Ok ,
this ) ;
msg . exec ( ) ;
return ;
}
2017-09-02 11:11:35 +02:00
} catch ( InternalError & e ) {
QMessageBox msg ( QMessageBox : : Critical ,
tr ( " Cppcheck " ) ,
2023-10-09 18:06:35 +02:00
tr ( " Failed to import '%1' (%2), analysis is stopped " ) . arg ( prjfile ) . arg ( QString : : fromStdString ( e . errorMessage ) ) ,
2017-09-02 11:11:35 +02:00
QMessageBox : : Ok ,
this ) ;
msg . exec ( ) ;
return ;
}
2018-04-13 15:28:05 +02:00
doAnalyzeProject ( p , checkLibrary , checkConfiguration ) ;
2016-08-18 21:58:50 +02:00
return ;
}
2017-07-31 12:02:51 +02:00
QStringList paths = projectFile - > getCheckPaths ( ) ;
2011-06-07 13:29:59 +02:00
// If paths not given then check the root path (which may be the project
// file's location, see above). This is to keep the compatibility with
// old "silent" project file loading when we checked the director where the
// project file was located.
2011-10-13 20:53:06 +02:00
if ( paths . isEmpty ( ) ) {
2011-06-07 13:29:59 +02:00
paths < < mCurrentDirectory ;
}
2018-04-13 15:28:05 +02:00
doAnalyzeFiles ( paths , checkLibrary , checkConfiguration ) ;
2010-07-07 20:18:42 +02:00
}
2010-07-08 17:59:06 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : newProjectFile ( )
2010-07-08 17:59:06 +02:00
{
2017-07-31 16:14:01 +02:00
const QString filter = tr ( " Project files (*.cppcheck) " ) ;
2010-07-12 19:21:45 +02:00
QString filepath = QFileDialog : : getSaveFileName ( this ,
2021-08-07 20:51:18 +02:00
tr ( " Select Project Filename " ) ,
getPath ( SETTINGS_LAST_PROJECT_PATH ) ,
filter ) ;
2010-07-12 19:21:45 +02:00
2011-11-25 07:42:16 +01:00
if ( filepath . isEmpty ( ) )
return ;
2017-07-31 16:14:01 +02:00
if ( ! filepath . endsWith ( " .cppcheck " , Qt : : CaseInsensitive ) )
filepath + = " .cppcheck " ;
2013-02-09 19:36:48 +01:00
2017-07-28 11:20:35 +02:00
setPath ( SETTINGS_LAST_PROJECT_PATH , filepath ) ;
2013-02-19 21:39:50 +01:00
2011-11-25 07:42:16 +01:00
QFileInfo inf ( filepath ) ;
const QString filename = inf . fileName ( ) ;
2017-07-28 05:44:15 +02:00
formatAndSetTitle ( tr ( " Project: " ) + QString ( " " ) + filename ) ;
2011-11-25 07:42:16 +01:00
2017-07-31 12:02:51 +02:00
delete mProjectFile ;
mProjectFile = new ProjectFile ( this ) ;
2020-07-15 13:03:07 +02:00
mProjectFile - > setActiveProject ( ) ;
2017-07-31 16:14:01 +02:00
mProjectFile - > setFilename ( filepath ) ;
2023-09-04 10:58:48 +02:00
mProjectFile - > setProjectName ( filename . left ( filename . indexOf ( " . " ) ) ) ;
2017-09-25 09:19:22 +02:00
mProjectFile - > setBuildDir ( filename . left ( filename . indexOf ( " . " ) ) + " -cppcheck-build-dir " ) ;
2017-07-31 12:02:51 +02:00
2022-08-22 21:11:28 +02:00
ProjectFileDialog dlg ( mProjectFile , isCppcheckPremium ( ) , this ) ;
2017-07-31 12:02:51 +02:00
if ( dlg . exec ( ) = = QDialog : : Accepted ) {
2017-07-28 05:44:15 +02:00
addProjectMRU ( filepath ) ;
2017-07-31 12:02:51 +02:00
analyzeProject ( mProjectFile ) ;
} else {
closeProjectFile ( ) ;
2012-10-14 14:13:54 +02:00
}
2010-07-08 17:59:06 +02:00
}
2010-07-16 16:48:13 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : closeProjectFile ( )
2010-08-15 11:12:28 +02:00
{
2017-07-31 12:02:51 +02:00
delete mProjectFile ;
2017-07-31 15:19:51 +02:00
mProjectFile = nullptr ;
2022-03-19 19:54:20 +01:00
mUI - > mResults - > clear ( true ) ;
2017-07-28 05:44:15 +02:00
enableProjectActions ( false ) ;
enableProjectOpenActions ( true ) ;
formatAndSetTitle ( ) ;
2010-08-15 15:12:32 +02:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : editProjectFile ( )
2010-08-15 15:12:32 +02:00
{
2017-07-31 12:02:51 +02:00
if ( ! mProjectFile ) {
2010-08-15 15:12:32 +02:00
QMessageBox msg ( QMessageBox : : Critical ,
tr ( " Cppcheck " ) ,
QString ( tr ( " No project file loaded " ) ) ,
QMessageBox : : Ok ,
this ) ;
msg . exec ( ) ;
return ;
2010-07-12 19:21:45 +02:00
}
2017-07-31 12:02:51 +02:00
2022-08-22 21:11:28 +02:00
ProjectFileDialog dlg ( mProjectFile , isCppcheckPremium ( ) , this ) ;
2017-07-31 12:02:51 +02:00
if ( dlg . exec ( ) = = QDialog : : Accepted ) {
mProjectFile - > write ( ) ;
analyzeProject ( mProjectFile ) ;
}
2010-07-08 17:59:06 +02:00
}
2010-07-16 16:48:13 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : showStatistics ( )
2010-09-01 08:12:24 +02:00
{
StatsDialog statsDialog ( this ) ;
// Show a dialog with the previous scan statistics and project information
2017-07-31 12:02:51 +02:00
statsDialog . setProject ( mProjectFile ) ;
2010-09-01 08:12:24 +02:00
statsDialog . setPathSelected ( mCurrentDirectory ) ;
2017-07-28 12:39:28 +02:00
statsDialog . setNumberOfFilesScanned ( mThread - > getPreviousFilesCount ( ) ) ;
statsDialog . setScanDuration ( mThread - > getPreviousScanDuration ( ) / 1000.0 ) ;
2022-03-19 19:54:20 +01:00
statsDialog . setStatistics ( mUI - > mResults - > getStatistics ( ) ) ;
2010-09-01 08:12:24 +02:00
statsDialog . exec ( ) ;
}
2017-07-28 10:41:03 +02:00
void MainWindow : : showLibraryEditor ( )
2015-08-16 17:36:10 +02:00
{
2015-09-04 20:46:26 +02:00
LibraryDialog libraryDialog ( this ) ;
libraryDialog . exec ( ) ;
2015-08-16 17:36:10 +02:00
}
2017-07-28 10:41:03 +02:00
void MainWindow : : filterResults ( )
2011-05-04 07:30:54 +02:00
{
2022-03-19 19:54:20 +01:00
mUI - > mResults - > filterResults ( mLineEditFilter - > text ( ) ) ;
2011-05-04 07:30:54 +02:00
}
2017-07-28 05:44:15 +02:00
void MainWindow : : enableProjectActions ( bool enable )
2010-08-25 17:54:45 +02:00
{
2022-03-19 19:54:20 +01:00
mUI - > mActionCloseProjectFile - > setEnabled ( enable ) ;
mUI - > mActionEditProjectFile - > setEnabled ( enable ) ;
mUI - > mActionCheckLibrary - > setEnabled ( enable ) ;
mUI - > mActionCheckConfiguration - > setEnabled ( enable ) ;
2010-08-25 17:54:45 +02:00
}
2010-08-25 19:59:30 +02:00
2017-07-28 05:44:15 +02:00
void MainWindow : : enableProjectOpenActions ( bool enable )
2010-08-25 19:59:30 +02:00
{
2022-03-19 19:54:20 +01:00
mUI - > mActionNewProjectFile - > setEnabled ( enable ) ;
mUI - > mActionOpenProjectFile - > setEnabled ( enable ) ;
2010-08-25 19:59:30 +02:00
}
2011-05-12 11:34:23 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : openRecentProject ( )
2011-05-12 11:34:23 +02:00
{
QAction * action = qobject_cast < QAction * > ( sender ( ) ) ;
2018-08-08 09:00:04 +02:00
if ( ! action )
return ;
const QString project = action - > data ( ) . toString ( ) ;
QFileInfo inf ( project ) ;
if ( inf . exists ( ) ) {
2019-08-23 21:27:17 +02:00
if ( inf . suffix ( ) = = " xml " )
loadResults ( project ) ;
else {
loadProjectFile ( project ) ;
loadLastResults ( ) ;
}
2018-08-08 09:00:04 +02:00
} else {
const QString text ( tr ( " The project file \n \n %1 \n \n could not be found! \n \n "
" Do you want to remove the file from the recently "
" used projects -list? " ) . arg ( project ) ) ;
2011-05-12 12:30:22 +02:00
2018-08-08 09:00:04 +02:00
QMessageBox msg ( QMessageBox : : Warning ,
tr ( " Cppcheck " ) ,
text ,
QMessageBox : : Yes | QMessageBox : : No ,
this ) ;
2011-05-12 12:30:22 +02:00
2018-08-08 09:00:04 +02:00
msg . setDefaultButton ( QMessageBox : : No ) ;
2022-10-02 07:12:40 +02:00
const int rv = msg . exec ( ) ;
2018-08-08 09:00:04 +02:00
if ( rv = = QMessageBox : : Yes ) {
removeProjectMRU ( project ) ;
2011-05-12 12:30:22 +02:00
}
}
2011-05-12 11:34:23 +02:00
}
2017-07-28 05:44:15 +02:00
void MainWindow : : updateMRUMenuItems ( )
2011-05-12 11:34:23 +02:00
{
2020-09-21 19:30:47 +02:00
for ( QAction * recentProjectAct : mRecentProjectActs ) {
if ( recentProjectAct ! = nullptr )
2022-03-19 19:54:20 +01:00
mUI - > mMenuFile - > removeAction ( recentProjectAct ) ;
2011-05-12 11:34:23 +02:00
}
QStringList projects = mSettings - > value ( SETTINGS_MRU_PROJECTS ) . toStringList ( ) ;
2011-12-27 10:46:43 +01:00
2018-08-08 11:03:51 +02:00
// Do a sanity check - remove duplicates and non-existing projects
2011-12-27 10:46:43 +01:00
int removed = projects . removeDuplicates ( ) ;
for ( int i = projects . size ( ) - 1 ; i > = 0 ; i - - ) {
2023-08-22 12:01:30 +02:00
if ( ! QFileInfo : : exists ( projects [ i ] ) ) {
2011-12-27 10:46:43 +01:00
projects . removeAt ( i ) ;
removed + + ;
}
}
if ( removed )
mSettings - > setValue ( SETTINGS_MRU_PROJECTS , projects ) ;
2011-05-12 11:34:23 +02:00
const int numRecentProjects = qMin ( projects . size ( ) , ( int ) MaxRecentProjects ) ;
2011-10-13 20:53:06 +02:00
for ( int i = 0 ; i < numRecentProjects ; i + + ) {
2011-05-12 11:34:23 +02:00
const QString filename = QFileInfo ( projects [ i ] ) . fileName ( ) ;
const QString text = QString ( " &%1 %2 " ) . arg ( i + 1 ) . arg ( filename ) ;
mRecentProjectActs [ i ] - > setText ( text ) ;
mRecentProjectActs [ i ] - > setData ( projects [ i ] ) ;
mRecentProjectActs [ i ] - > setVisible ( true ) ;
2022-03-19 19:54:20 +01:00
mUI - > mMenuFile - > insertAction ( mUI - > mActionProjectMRU , mRecentProjectActs [ i ] ) ;
2011-05-12 11:34:23 +02:00
}
if ( numRecentProjects > 1 )
2022-03-19 19:54:20 +01:00
mRecentProjectActs [ numRecentProjects ] = mUI - > mMenuFile - > insertSeparator ( mUI - > mActionProjectMRU ) ;
2011-05-12 11:34:23 +02:00
}
2017-07-28 05:44:15 +02:00
void MainWindow : : addProjectMRU ( const QString & project )
2011-05-12 11:34:23 +02:00
{
QStringList files = mSettings - > value ( SETTINGS_MRU_PROJECTS ) . toStringList ( ) ;
files . removeAll ( project ) ;
files . prepend ( project ) ;
while ( files . size ( ) > MaxRecentProjects )
files . removeLast ( ) ;
mSettings - > setValue ( SETTINGS_MRU_PROJECTS , files ) ;
2017-07-28 05:44:15 +02:00
updateMRUMenuItems ( ) ;
2011-05-12 11:34:23 +02:00
}
2011-05-12 12:30:22 +02:00
2017-07-28 05:44:15 +02:00
void MainWindow : : removeProjectMRU ( const QString & project )
2011-05-12 12:30:22 +02:00
{
QStringList files = mSettings - > value ( SETTINGS_MRU_PROJECTS ) . toStringList ( ) ;
files . removeAll ( project ) ;
mSettings - > setValue ( SETTINGS_MRU_PROJECTS , files ) ;
2017-07-28 05:44:15 +02:00
updateMRUMenuItems ( ) ;
2011-05-12 12:30:22 +02:00
}
2011-09-29 21:46:19 +02:00
2017-07-28 10:41:03 +02:00
void MainWindow : : selectPlatform ( )
2011-09-29 21:46:19 +02:00
{
2011-10-02 21:08:12 +02:00
QAction * action = qobject_cast < QAction * > ( sender ( ) ) ;
2011-10-13 20:53:06 +02:00
if ( action ) {
2023-10-13 16:02:04 +02:00
const Platform : : Type platform = ( Platform : : Type ) action - > data ( ) . toInt ( ) ;
2011-10-02 21:08:12 +02:00
mSettings - > setValue ( SETTINGS_CHECKED_PLATFORM , platform ) ;
}
2011-09-29 21:46:19 +02:00
}
2017-08-02 22:28:45 +02:00
2017-08-11 07:45:29 +02:00
void MainWindow : : suppressIds ( QStringList ids )
{
2018-04-09 06:43:48 +02:00
if ( ! mProjectFile )
return ;
ids . removeDuplicates ( ) ;
QList < Suppressions : : Suppression > suppressions = mProjectFile - > getSuppressions ( ) ;
2022-03-21 17:14:26 +01:00
for ( const QString & id : ids ) {
2018-04-09 06:43:48 +02:00
// Remove all matching suppressions
std : : string id2 = id . toStdString ( ) ;
for ( int i = 0 ; i < suppressions . size ( ) ; ) {
if ( suppressions [ i ] . errorId = = id2 )
suppressions . removeAt ( i ) ;
else
+ + i ;
2017-08-11 07:45:29 +02:00
}
2018-04-09 06:43:48 +02:00
Suppressions : : Suppression newSuppression ;
newSuppression . errorId = id2 ;
suppressions < < newSuppression ;
2017-08-11 07:45:29 +02:00
}
2018-04-09 06:43:48 +02:00
mProjectFile - > setSuppressions ( suppressions ) ;
mProjectFile - > write ( ) ;
2017-08-11 07:45:29 +02:00
}
2022-08-22 21:11:28 +02:00
2022-10-09 18:51:01 +02:00
static int getVersion ( const QString & nameWithVersion ) {
int ret = 0 ;
int v = 0 ;
int dot = 0 ;
for ( const auto c : nameWithVersion ) {
if ( c = = ' \n ' | | c = = ' \r ' )
break ;
2023-06-20 18:43:21 +02:00
if ( c = = ' ' ) {
2022-11-03 18:20:13 +01:00
if ( ret > 0 & & dot = = 1 & & nameWithVersion . endsWith ( " dev " ) )
return ret * 1000000 + v * 1000 + 500 ;
2022-10-09 18:51:01 +02:00
dot = ret = v = 0 ;
2022-11-03 18:20:13 +01:00
}
2022-10-09 18:51:01 +02:00
else if ( c = = ' . ' ) {
+ + dot ;
ret = ret * 1000 + v ;
v = 0 ;
} else if ( c > = ' 0 ' & & c < = ' 9 ' )
v = v * 10 + ( c . toLatin1 ( ) - ' 0 ' ) ;
}
ret = ret * 1000 + v ;
while ( dot < 2 ) {
+ + dot ;
ret * = 1000 ;
}
return ret ;
}
void MainWindow : : replyFinished ( QNetworkReply * reply ) {
reply - > deleteLater ( ) ;
if ( reply - > error ( ) ) {
2022-10-24 15:17:36 +02:00
mUI - > mLayoutInformation - > deleteLater ( ) ;
2022-10-09 18:51:01 +02:00
qDebug ( ) < < " Response: ERROR " ;
return ;
}
const QString str = reply - > readAll ( ) ;
qDebug ( ) < < " Response: " < < str ;
if ( reply - > url ( ) . fileName ( ) = = " version.txt " ) {
QString nameWithVersion = QString ( " Cppcheck %1 " ) . arg ( CppCheck : : version ( ) ) ;
if ( ! mCppcheckCfgProductName . isEmpty ( ) )
nameWithVersion = mCppcheckCfgProductName ;
const int appVersion = getVersion ( nameWithVersion ) ;
const int latestVersion = getVersion ( str . trimmed ( ) ) ;
if ( appVersion < latestVersion ) {
if ( mSettings - > value ( SETTINGS_CHECK_VERSION , 0 ) . toInt ( ) ! = latestVersion ) {
2022-11-08 13:33:57 +01:00
QString install ;
if ( isCppcheckPremium ( ) ) {
# ifdef Q_OS_WIN
const QString url ( " https://cppchecksolutions.com/cppcheck-premium-installation " ) ;
# else
const QString url ( " https://cppchecksolutions.com/cppcheck-premium-linux-installation " ) ;
# endif
install = " <a href= \" " + url + " \" > " + tr ( " Install " ) + " </a> " ;
}
2022-10-09 18:51:01 +02:00
mUI - > mButtonHideInformation - > setVisible ( true ) ;
mUI - > mLabelInformation - > setVisible ( true ) ;
2022-11-08 13:33:57 +01:00
mUI - > mLabelInformation - > setText ( tr ( " New version available: %1. %2 " ) . arg ( str . trimmed ( ) ) . arg ( install ) ) ;
2022-10-09 18:51:01 +02:00
}
}
}
2022-10-24 15:17:36 +02:00
if ( ! mUI - > mLabelInformation - > isVisible ( ) ) {
mUI - > mLayoutInformation - > deleteLater ( ) ;
}
2022-10-09 18:51:01 +02:00
}
void MainWindow : : hideInformation ( ) {
int version = getVersion ( mUI - > mLabelInformation - > text ( ) ) ;
mSettings - > setValue ( SETTINGS_CHECK_VERSION , version ) ;
mUI - > mLabelInformation - > setVisible ( false ) ;
mUI - > mButtonHideInformation - > setVisible ( false ) ;
2022-10-22 20:27:24 +02:00
mUI - > mLayoutInformation - > deleteLater ( ) ;
2022-10-09 18:51:01 +02:00
}
2022-08-22 21:11:28 +02:00
bool MainWindow : : isCppcheckPremium ( ) const {
return mCppcheckCfgProductName . startsWith ( " Cppcheck Premium " ) ;
}
2022-10-09 18:51:01 +02:00