2009-03-01 08:38:21 +01:00
/*
* Cppcheck - A tool for static C / C + + code analysis
2022-02-05 11:45:17 +01:00
* Copyright ( C ) 2007 - 2022 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"
2012-10-07 12:25:34 +02:00
# include "applicationlist.h"
2009-06-04 14:35:41 +02:00
# include "aboutdialog.h"
2012-10-07 12:25:34 +02:00
# include "common.h"
2022-02-02 16:17:28 +01:00
# include "cppcheck.h"
2020-07-20 11:59:28 +02:00
# include "filelist.h"
2009-06-14 11:57:43 +02:00
# include "fileviewdialog.h"
2020-04-27 17:36:17 +02:00
# include "functioncontractdialog.h"
2020-08-25 19:58:52 +02:00
# include "helpdialog.h"
2020-07-20 11:59:28 +02:00
# include "librarydialog.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"
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"
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"
2020-08-22 11:37:44 +02:00
# include "variablecontractsdialog.h"
2011-03-26 15:06:11 +01:00
2022-02-02 16:17:28 +01:00
# include <QApplication>
# include <QAction>
# include <QActionGroup>
# include <QDebug>
# include <QDir>
# include <QFile>
# include <QFileInfo>
# include <QInputDialog>
# include <QMessageBox>
# include <QSettings>
# include <QTimer>
2021-08-28 12:46:54 +02:00
static const QString OnlineHelpURL ( " https://cppcheck.sourceforge.io/manual.html " ) ;
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
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 ) ,
2017-07-31 15:19:51 +02:00
mScratchPad ( nullptr ) ,
mProjectFile ( nullptr ) ,
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 ) ) ,
2015-10-14 14:31:52 +02:00
mSelectLanguageActions ( new QActionGroup ( this ) ) ,
2016-01-16 09:59:02 +01:00
mExiting ( false ) ,
mIsLogfileLoaded ( false )
2009-07-02 10:32:29 +02:00
{
mUI . setupUi ( this ) ;
2009-06-20 18:55:23 +02:00
mThread = new ThreadHandler ( this ) ;
2017-07-28 12:10:10 +02: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
mLineEditFilter = new QLineEdit ( mUI . mToolBarFilter ) ;
mLineEditFilter - > setPlaceholderText ( tr ( " Quick Filter: " ) ) ;
2019-01-15 10:35:23 +01:00
mLineEditFilter - > setClearButtonEnabled ( true ) ;
2011-05-04 07:30:54 +02:00
mUI . mToolBarFilter - > addWidget ( mLineEditFilter ) ;
connect ( mLineEditFilter , SIGNAL ( textChanged ( const 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
2017-07-28 12:22:15 +02:00
connect ( mUI . mActionPrint , SIGNAL ( triggered ( ) ) , mUI . mResults , SLOT ( print ( ) ) ) ;
connect ( mUI . mActionPrintPreview , SIGNAL ( triggered ( ) ) , mUI . mResults , SLOT ( printPreview ( ) ) ) ;
2017-07-31 07:36:42 +02:00
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 ) ;
2017-08-20 12:21:46 +02:00
connect ( mUI . mActionShowCppcheck , & QAction : : toggled , mUI . mResults , & ResultsView : : showCppcheckResults ) ;
connect ( mUI . mActionShowClang , & QAction : : toggled , mUI . mResults , & ResultsView : : showClangResults ) ;
2017-07-31 07:36:42 +02:00
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 ) ;
2018-04-13 15:28:05 +02:00
connect ( mUI . mActionCheckLibrary , & QAction : : triggered , this , & MainWindow : : checkLibrary ) ;
connect ( mUI . mActionCheckConfiguration , & QAction : : triggered , this , & MainWindow : : checkConfiguration ) ;
2017-07-31 07:36:42 +02:00
connect ( mUI . mActionStop , & QAction : : triggered , this , & MainWindow : : stopAnalysis ) ;
connect ( mUI . mActionSave , & QAction : : triggered , this , & MainWindow : : save ) ;
2009-05-24 10:53:29 +02:00
2011-05-04 07:30:54 +02:00
// About menu
2017-07-31 07:36:42 +02: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
2017-07-28 12:22:15 +02: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
2017-07-31 07:36:42 +02:00
connect ( mUI . mActionAuthors , & QAction : : triggered , this , & MainWindow : : showAuthors ) ;
connect ( mThread , & ThreadHandler : : done , this , & MainWindow : : analysisDone ) ;
2017-08-19 22:55:13 +02:00
connect ( mThread , & ThreadHandler : : log , mUI . mResults , & ResultsView : : log ) ;
connect ( mThread , & ThreadHandler : : debugError , mUI . mResults , & ResultsView : : debugError ) ;
2020-02-10 20:24:36 +01:00
connect ( mThread , & ThreadHandler : : bughuntingReportLine , mUI . mResults , & ResultsView : : bughuntingReportLine ) ;
2017-07-31 07:36:42 +02:00
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 ) ;
2017-08-11 07:45:29 +02:00
connect ( mUI . mResults , & ResultsView : : suppressIds , this , & MainWindow : : suppressIds ) ;
2020-04-27 17:36:17 +02:00
connect ( mUI . mResults , & ResultsView : : editFunctionContract , this , & MainWindow : : editFunctionContract ) ;
2020-08-22 11:37:44 +02:00
connect ( mUI . mResults , & ResultsView : : editVariableContract , this , & MainWindow : : editVariableContract ) ;
connect ( mUI . mResults , & ResultsView : : deleteFunctionContract , this , & MainWindow : : deleteFunctionContract ) ;
connect ( mUI . mResults , & ResultsView : : deleteVariableContract , this , & MainWindow : : deleteVariableContract ) ;
2017-07-31 07:36:42 +02:00
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
2017-07-31 07:36:42 +02: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
2017-07-31 07:36:42 +02: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
2017-07-28 12:39:28 +02: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
2017-07-28 05:44:15 +02:00
enableCheckButtons ( true ) ;
2009-06-03 20:18:22 +02:00
2015-04-17 16:33:52 +02: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
2011-05-12 11:34:23 +02: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
}
2017-07-31 12:02:51 +02: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 + + ) {
2018-02-16 22:22:13 +01:00
Platform platform = mPlatforms . mPlatforms [ i ] ;
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 ) ;
mUI . mMenuAnalyze - > insertAction ( mUI . mActionPlatforms , action ) ;
connect ( action , SIGNAL ( triggered ( ) ) , this , SLOT ( selectPlatform ( ) ) ) ;
2011-10-02 21:08:12 +02:00
}
2013-03-02 13:01:21 +01:00
mUI . mActionC89 - > setActionGroup ( mCStandardActions ) ;
mUI . mActionC99 - > setActionGroup ( mCStandardActions ) ;
mUI . mActionC11 - > setActionGroup ( mCStandardActions ) ;
mUI . mActionCpp03 - > setActionGroup ( mCppStandardActions ) ;
mUI . mActionCpp11 - > setActionGroup ( mCppStandardActions ) ;
2017-09-22 22:00:00 +02:00
mUI . mActionCpp14 - > setActionGroup ( mCppStandardActions ) ;
2019-04-12 11:52:28 +02:00
mUI . mActionCpp17 - > setActionGroup ( mCppStandardActions ) ;
2019-05-05 10:44:09 +02:00
mUI . mActionCpp20 - > setActionGroup ( mCppStandardActions ) ;
2013-03-02 13:01:21 +01:00
2015-10-14 14:31:52 +02:00
mUI . mActionEnforceC - > setActionGroup ( mSelectLanguageActions ) ;
mUI . mActionEnforceCpp - > setActionGroup ( mSelectLanguageActions ) ;
mUI . mActionAutoDetectLanguage - > setActionGroup ( mSelectLanguageActions ) ;
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)
2018-02-16 22:22:13 +01:00
const Settings : : PlatformType defaultPlatform = Settings : : Win32W ;
2011-10-02 22:45:11 +02:00
# else
2018-02-16 22:22:13 +01:00
const Settings : : PlatformType defaultPlatform = Settings : : Unspecified ;
2011-10-02 22:45:11 +02:00
# endif
2018-02-16 22:22:13 +01:00
Platform & platform = mPlatforms . get ( ( Settings : : PlatformType ) mSettings - > value ( SETTINGS_CHECKED_PLATFORM , defaultPlatform ) . toInt ( ) ) ;
platform . mActMainWindow - > setChecked ( true ) ;
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 ;
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
}
2017-06-25 22:18:51 +02:00
} else if ( ( index = params . indexOf ( QRegExp ( " .* \\ .cppcheck$ " , Qt : : CaseInsensitive ) , 0 ) ) > = 0 & & index < params . length ( ) & & QFile ( params [ index ] ) . exists ( ) ) {
2017-07-28 05:44:15 +02:00
loadProjectFile ( params [ index ] ) ;
2016-01-15 16:52:22 +01:00
} else if ( ( index = params . indexOf ( QRegExp ( " .* \\ .xml$ " , Qt : : CaseInsensitive ) , 0 ) ) > = 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
2017-07-28 12:10:10 +02:00
ShowTypes * types = mUI . mResults - > getShowTypes ( ) ;
2011-10-11 21:14:15 +02:00
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 ) ) ;
2017-08-20 12:21:46 +02: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 ( ) ) ;
mUI . mActionC89 - > setChecked ( standards . c = = Standards : : C89 ) ;
mUI . mActionC99 - > setChecked ( standards . c = = Standards : : C99 ) ;
mUI . mActionC11 - > setChecked ( standards . c = = Standards : : C11 ) ;
standards . setCPP ( mSettings - > value ( SETTINGS_STD_CPP , QString ( ) ) . toString ( ) . toStdString ( ) ) ;
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 ) ;
2019-05-05 10:44:09 +02:00
mUI . mActionCpp20 - > setChecked ( standards . cpp = = Standards : : CPP20 ) ;
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 ( ) ;
mUI . mActionToolBarMain - > setChecked ( showMainToolbar ) ;
mUI . mToolBarMain - > setVisible ( showMainToolbar ) ;
const bool showViewToolbar = mSettings - > value ( SETTINGS_TOOLBARS_VIEW_SHOW , true ) . toBool ( ) ;
mUI . mActionToolBarView - > setChecked ( showViewToolbar ) ;
mUI . mToolBarView - > setVisible ( showViewToolbar ) ;
const bool showFilterToolbar = mSettings - > value ( SETTINGS_TOOLBARS_FILTER_SHOW , true ) . toBool ( ) ;
mUI . mActionToolBarFilter - > setChecked ( showFilterToolbar ) ;
mUI . mToolBarFilter - > setVisible ( showFilterToolbar ) ;
2009-07-02 10:32:29 +02:00
2015-10-14 14:31:52 +02:00
Settings : : Language enforcedLanguage = ( Settings : : Language ) mSettings - > value ( SETTINGS_ENFORCED_LANGUAGE , 0 ) . toInt ( ) ;
if ( enforcedLanguage = = Settings : : CPP )
mUI . mActionEnforceCpp - > setChecked ( true ) ;
else if ( enforcedLanguage = = Settings : : C )
mUI . mActionEnforceC - > setChecked ( true ) ;
else
mUI . mActionAutoDetectLanguage - > setChecked ( true ) ;
2017-07-28 05:18:43 +02:00
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
}
}
2020-04-28 22:09:01 +02:00
2020-08-22 11:37:44 +02:00
updateFunctionContractsTab ( ) ;
updateVariableContractsTab ( ) ;
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
2009-07-02 10:32:29 +02:00
mSettings - > setValue ( SETTINGS_SHOW_STYLE , mUI . mActionShowStyle - > isChecked ( ) ) ;
mSettings - > setValue ( SETTINGS_SHOW_ERRORS , mUI . mActionShowErrors - > isChecked ( ) ) ;
2010-10-18 19:50:34 +02:00
mSettings - > setValue ( SETTINGS_SHOW_WARNINGS , mUI . mActionShowWarnings - > isChecked ( ) ) ;
2010-12-27 10:06:31 +01:00
mSettings - > setValue ( SETTINGS_SHOW_PORTABILITY , mUI . mActionShowPortability - > isChecked ( ) ) ;
2010-10-18 19:50:34 +02:00
mSettings - > setValue ( SETTINGS_SHOW_PERFORMANCE , mUI . mActionShowPerformance - > isChecked ( ) ) ;
2010-12-26 13:36:24 +01:00
mSettings - > setValue ( SETTINGS_SHOW_INFORMATION , mUI . mActionShowInformation - > isChecked ( ) ) ;
2011-05-04 07:30:54 +02:00
2019-04-12 12:12:12 +02:00
if ( mUI . mActionC89 - > isChecked ( ) )
mSettings - > setValue ( SETTINGS_STD_C , " C89 " ) ;
if ( mUI . mActionC99 - > isChecked ( ) )
mSettings - > setValue ( SETTINGS_STD_C , " C99 " ) ;
if ( mUI . mActionC11 - > isChecked ( ) )
mSettings - > setValue ( SETTINGS_STD_C , " C11 " ) ;
if ( mUI . mActionCpp03 - > isChecked ( ) )
mSettings - > setValue ( SETTINGS_STD_CPP , " C++03 " ) ;
if ( mUI . mActionCpp11 - > isChecked ( ) )
mSettings - > setValue ( SETTINGS_STD_CPP , " C++11 " ) ;
if ( mUI . mActionCpp14 - > isChecked ( ) )
mSettings - > setValue ( SETTINGS_STD_CPP , " C++14 " ) ;
if ( mUI . mActionCpp17 - > isChecked ( ) )
mSettings - > setValue ( SETTINGS_STD_CPP , " C++17 " ) ;
2019-05-05 10:44:09 +02:00
if ( mUI . mActionCpp20 - > isChecked ( ) )
mSettings - > setValue ( SETTINGS_STD_CPP , " C++20 " ) ;
2011-12-27 21:12:52 +01:00
2011-05-04 07:30:54 +02:00
// Main window settings
2010-07-03 19:03:53 +02:00
mSettings - > setValue ( SETTINGS_TOOLBARS_MAIN_SHOW , mUI . mToolBarMain - > isVisible ( ) ) ;
2010-07-03 18:37:09 +02:00
mSettings - > setValue ( SETTINGS_TOOLBARS_VIEW_SHOW , mUI . mToolBarView - > isVisible ( ) ) ;
2011-05-04 07:30:54 +02:00
mSettings - > setValue ( SETTINGS_TOOLBARS_FILTER_SHOW , mUI . mToolBarFilter - > isVisible ( ) ) ;
2009-07-01 23:05:09 +02:00
2015-10-14 14:31:52 +02:00
if ( mUI . mActionEnforceCpp - > isChecked ( ) )
mSettings - > setValue ( SETTINGS_ENFORCED_LANGUAGE , Settings : : CPP ) ;
else if ( mUI . mActionEnforceC - > isChecked ( ) )
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
2017-07-28 12:10:10 +02: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 ;
2017-07-31 12:02:51 +02:00
foreach ( const QString & i , mProjectFile - > getExcludedPaths ( ) ) {
v . push_back ( i . toStdString ( ) ) ;
2016-08-18 21:58:50 +02:00
}
p . ignorePaths ( v ) ;
2017-08-10 00:18:04 +02:00
if ( ! mProjectFile - > getAnalyzeAllVsConfigs ( ) ) {
Settings : : PlatformType platform = ( Settings : : PlatformType ) mSettings - > value ( SETTINGS_CHECKED_PLATFORM , 0 ) . toInt ( ) ;
2019-04-13 20:01:40 +02:00
p . selectOneVsConfig ( platform ) ;
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
}
2017-07-28 12:10:10 +02:00
mUI . mResults - > clear ( true ) ;
2017-07-28 12:39:28 +02:00
mThread - > clearFiles ( ) ;
2016-08-18 21:58:50 +02:00
2017-07-28 12:10:10 +02: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
2017-07-28 12:10:10 +02: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 ) ;
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
2017-07-28 12:10:10 +02: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 ;
}
2017-07-28 12:10:10 +02: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
2017-07-28 12:10:10 +02: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
2021-11-05 20:37:48 +01:00
checkSettings . loadCppcheckCfg ( QCoreApplication : : applicationFilePath ( ) . toStdString ( ) ) ;
2021-10-13 20:02:48 +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-02-05 11:33:28 +01:00
for ( const QString & s : fileNames )
sourcefiles . push_back ( s . toStdString ( ) ) ;
2020-12-19 20:45:51 +01:00
AnalyzerInformation : : writeFilesTxt ( checkSettings . buildDir , sourcefiles , checkSettings . userDefines , checkSettings . project . fileSettings ) ;
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 ) ;
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 ) ) ;
2021-08-07 20:51:18 +02:00
connect ( & result , SIGNAL ( progress ( int , const QString & ) ) ,
mUI . mResults , SLOT ( progress ( int , const QString & ) ) ) ;
connect ( & result , SIGNAL ( error ( const ErrorItem & ) ) ,
mUI . mResults , SLOT ( error ( const ErrorItem & ) ) ) ;
connect ( & result , SIGNAL ( log ( const QString & ) ) ,
mUI . mResults , SLOT ( log ( const QString & ) ) ) ;
connect ( & result , SIGNAL ( debugError ( const ErrorItem & ) ) ,
mUI . mResults , SLOT ( debugError ( const 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 ( ) ;
2017-07-28 12:10:10 +02: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
2018-03-07 12:38:50 +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 ( ) ;
2011-10-13 20:53:06 +02:00
} else if ( mode = = QFileDialog : : DirectoryOnly ) {
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
}
2013-02-19 21:39:50 +01:00
2017-07-28 11:20:35 +02:00
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
}
2020-08-22 11:37:44 +02:00
void MainWindow : : updateFunctionContractsTab ( )
2020-04-28 22:09:01 +02:00
{
QStringList addedContracts ;
if ( mProjectFile ) {
2020-09-21 19:41:28 +02:00
for ( const auto & it : mProjectFile - > getFunctionContracts ( ) ) {
2020-04-28 22:09:01 +02:00
addedContracts < < QString : : fromStdString ( it . first ) ;
}
}
2020-08-22 11:37:44 +02:00
mUI . mResults - > setAddedFunctionContracts ( addedContracts ) ;
}
void MainWindow : : updateVariableContractsTab ( )
{
QStringList added ;
if ( mProjectFile ) {
2022-02-12 08:20:45 +01:00
for ( const auto & vc : mProjectFile - > getVariableContracts ( ) ) {
2020-08-22 11:37:44 +02:00
QString line = vc . first ;
if ( ! vc . second . minValue . empty ( ) )
line + = " min: " + QString : : fromStdString ( vc . second . minValue ) ;
if ( ! vc . second . maxValue . empty ( ) )
line + = " max: " + QString : : fromStdString ( vc . second . maxValue ) ;
added < < line ;
}
}
mUI . mResults - > setAddedVariableContracts ( added ) ;
2020-04-28 22:09:01 +02: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
2017-08-03 12:39:31 +02:00
const QString file0 = ( selected . size ( ) ? 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 ;
for ( std : : list < ImportProject : : FileSettings > : : const_iterator it = p . fileSettings . begin ( ) ; it ! = p . fileSettings . end ( ) ; + + it ) {
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
{
2017-07-30 11:19:47 +02:00
QStringList dir = selectFilesToAnalyze ( QFileDialog : : DirectoryOnly ) ;
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 ) ;
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 ) ;
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
{
QString dir ;
2015-12-17 15:40:54 +01:00
foreach ( 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 " ) ;
bool posix = true ;
2019-04-12 11:52:28 +02:00
if ( result . posix ( ) )
2019-03-15 06:59:37 +01:00
posix = tryLoadLibrary ( & result . library , " posix.cfg " ) ;
bool windows = true ;
if ( result . isWindowsPlatform ( ) )
windows = tryLoadLibrary ( & result . library , " windows.cfg " ) ;
if ( ! std | | ! posix | | ! windows )
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 ? " std.cfg " : ! posix ? " posix.cfg " : " windows.cfg " ) ) ;
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 ( ) ;
2017-07-28 05:08:59 +02:00
foreach ( 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-02-04 21:20:43 +01:00
result . bugHunting = mProjectFile - > bugHunting ;
2020-02-10 20:24:36 +01:00
result . bugHuntingReport = " " ;
2020-02-02 10:45:42 +01:00
2020-04-27 09:08:50 +02:00
result . functionContracts = mProjectFile - > getFunctionContracts ( ) ;
2020-09-21 19:41:28 +02:00
for ( const auto & vc : mProjectFile - > getVariableContracts ( ) )
2020-08-22 11:37:44 +02:00
result . variableContracts [ vc . first . toStdString ( ) ] = vc . second ;
2018-10-09 15:05:05 +02:00
const QStringList undefines = mProjectFile - > getUndefines ( ) ;
foreach ( QString undefine , undefines )
2021-08-07 20:51:18 +02:00
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 ( ) ;
2015-12-17 15:40:54 +01:00
foreach ( 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
}
2019-08-11 15:53:03 +02:00
foreach ( 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 ;
2017-07-31 12:02:51 +02:00
const QString & buildDir = 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 ( ) ;
2018-10-17 12:44:41 +02:00
result . loadPlatformFile ( applicationFilePath . toStdString ( ) . c_str ( ) , platform . toStdString ( ) ) ;
2018-03-13 13:07:10 +01:00
} else {
for ( int i = cppcheck : : Platform : : Native ; i < = cppcheck : : Platform : : Unix64 ; i + + ) {
const cppcheck : : Platform : : PlatformType p = ( cppcheck : : Platform : : PlatformType ) i ;
if ( platform = = cppcheck : : Platform : : platformString ( p ) ) {
result . platform ( p ) ;
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 ( ) ;
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 ;
2019-07-11 21:05:52 +02:00
foreach ( QString s , mProjectFile - > getCheckUnknownFunctionReturn ( ) )
2021-08-07 20:51:18 +02:00
result . checkUnknownFunctionReturn . insert ( s . toStdString ( ) ) ;
2020-05-17 16:50:02 +02:00
2020-08-29 21:26:49 +02:00
QString filesDir ( getDataDir ( ) ) ;
2020-05-17 16:50:02 +02:00
const QString pythonCmd = mSettings - > value ( SETTINGS_PYTHON_PATH ) . toString ( ) ;
foreach ( QString addon , mProjectFile - > getAddons ( ) ) {
QString addonFilePath = ProjectFile : : getAddonFilePath ( filesDir , addon ) ;
if ( addonFilePath . isEmpty ( ) )
continue ;
2020-05-17 21:45:37 +02:00
addonFilePath . replace ( QChar ( ' \\ ' ) , QChar ( ' / ' ) ) ;
2020-05-17 16:50:02 +02:00
QString json ;
json + = " { \" script \" : \" " + addonFilePath + " \" " ;
if ( ! pythonCmd . isEmpty ( ) )
json + = " , \" python \" : \" " + pythonCmd + " \" " ;
QString misraFile = mSettings - > value ( SETTINGS_MISRA_FILE ) . toString ( ) ;
if ( addon = = " misra " & & ! misraFile . isEmpty ( ) ) {
QString arg ;
if ( misraFile . endsWith ( " .pdf " , Qt : : CaseInsensitive ) )
arg = " --misra-pdf= " + misraFile ;
else
arg = " --rule-texts= " + misraFile ;
json + = " , \" args \" :[ \" " + arg + " \" ] " ;
}
json + = " } " ;
result . addons . push_back ( json . 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 ( ) ) ;
2019-07-29 11:22:57 +02:00
if ( ! mProjectFile | | result . platformType = = cppcheck : : Platform : : Unspecified )
2018-03-13 13:07:10 +01:00
result . platform ( ( cppcheck : : Platform : : PlatformType ) 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 ;
}
2017-07-28 12:10:10 +02:00
mUI . mResults - > checkingFinished ( ) ;
2017-07-28 05:44:15 +02:00
enableCheckButtons ( true ) ;
2009-07-02 10:32:29 +02:00
mUI . mActionSettings - > setEnabled ( true ) ;
2010-07-12 01:18:26 +02:00
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 ) {
2017-07-30 09:46:01 +02: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 ) ;
2011-12-27 21:12:52 +01:00
mUI . mActionPosix - > setEnabled ( true ) ;
2012-10-20 20:14:52 +02:00
if ( mScratchPad )
mScratchPad - > setEnabled ( true ) ;
2018-02-16 22:15:15 +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 ( ) ) {
mUI . mResults - > saveStatistics ( buildDir + " /statistics.txt " ) ;
2017-08-02 20:24:23 +02:00
mUI . mResults - > updateFromOldReport ( buildDir + " /lastResults.xml " ) ;
2017-07-30 00:13:00 +02:00
mUI . mResults - > save ( buildDir + " /lastResults.xml " , Report : : XMLV2 ) ;
}
}
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 ) ;
2011-02-11 20:08:37 +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 ) ;
2011-12-27 21:12:52 +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
{
2011-05-13 09:25:52 +02:00
SettingsDialog dialog ( mApplications , mTranslation , 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 ( ) ;
2017-07-28 13:43:49 +02:00
mUI . mResults - > updateSettings ( dialog . showFullPath ( ) ,
dialog . saveFullPath ( ) ,
dialog . saveAllErrors ( ) ,
dialog . showNoErrorsMessage ( ) ,
dialog . showErrorId ( ) ,
dialog . showInconclusive ( ) ) ;
2019-08-18 21:11:46 +02:00
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 ) ;
}
2017-08-14 05:14:18 +02:00
void MainWindow : : reAnalyzeSelected ( 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
2017-07-28 12:10:10 +02:00
mUI . mResults - > clear ( false ) ;
2015-12-23 10:28:07 +01:00
for ( int i = 0 ; i < files . size ( ) ; + + i )
2017-07-28 12:10:10 +02:00
mUI . mResults - > clearRecheckFile ( files [ i ] ) ;
2015-12-29 01:38:36 +01:00
2017-07-28 12:10:10 +02: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
2017-07-28 12:10:10 +02: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 ( ) ;
2017-08-03 22:12:12 +02:00
mThread - > check ( getCppcheckSettings ( ) ) ;
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
2017-07-28 12:10:10 +02: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 )
2017-07-28 12:10:10 +02: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
2017-07-28 12:10:10 +02: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 ) ;
2017-08-03 22:12:12 +02:00
mThread - > check ( getCppcheckSettings ( ) ) ;
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 ) ) {
2020-12-19 20:45:51 +01:00
if ( ! f . endsWith ( " files.txt " ) & & ! QRegExp ( " .*.s[0-9]+$ " ) . exactMatch ( f ) )
dir . remove ( f ) ;
2020-04-29 18:10:01 +02:00
}
}
2017-07-28 12:10:10 +02:00
mUI . mResults - > clear ( true ) ;
2018-04-13 15:28:05 +02:00
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
{
2017-07-28 12:10:10 +02: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 ) ;
int dlgResult = msgBox . exec ( ) ;
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 ;
mUI . mResults - > clear ( true ) ;
mUI . mActionReanalyzeModified - > setEnabled ( false ) ;
mUI . mActionReanalyzeAll - > setEnabled ( false ) ;
mUI . mResults - > readErrorsXml ( selectedFile ) ;
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 ) ;
2017-07-28 12:10:10 +02: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
{
2009-07-02 10:32:29 +02:00
mUI . mActionStop - > setEnabled ( ! enable ) ;
2017-07-30 09:46:01 +02:00
mUI . mActionAnalyzeFiles - > setEnabled ( enable ) ;
2009-10-13 10:19:00 +02:00
2017-07-31 12:02:51 +02:00
if ( mProjectFile ) {
2017-07-30 23:02:30 +02:00
mUI . mActionReanalyzeModified - > setEnabled ( false ) ;
mUI . mActionReanalyzeAll - > setEnabled ( enable ) ;
} else if ( ! enable | | mThread - > hasPreviousFiles ( ) ) {
mUI . mActionReanalyzeModified - > setEnabled ( enable ) ;
2017-07-30 09:46:01 +02:00
mUI . mActionReanalyzeAll - > setEnabled ( enable ) ;
2015-10-14 19:07:20 +02:00
}
2009-10-13 10:19:00 +02:00
2017-07-30 09:46:01 +02:00
mUI . mActionAnalyzeDirectory - > setEnabled ( enable ) ;
2009-03-22 16:42:00 +01:00
}
2018-04-12 08:15:04 +02:00
void MainWindow : : enableResultsButtons ( )
{
bool enabled = mUI . mResults - > hasResults ( ) ;
mUI . mActionClearResults - > setEnabled ( enabled ) ;
mUI . mActionSave - > setEnabled ( enabled ) ;
mUI . mActionPrint - > setEnabled ( enabled ) ;
mUI . mActionPrintPreview - > setEnabled ( enabled ) ;
}
2017-07-28 10:41:03 +02:00
void MainWindow : : showStyle ( bool checked )
2009-03-22 18:39:44 +01:00
{
2017-07-28 12:10:10 +02: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
{
2017-07-28 12:10:10 +02: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
{
2017-07-28 12:10:10 +02: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
{
2017-07-28 12:10:10 +02: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
{
2017-07-28 12:10:10 +02: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
{
2017-07-28 12:10:10 +02: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 ) ;
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
{
2009-07-02 10:32:29 +02:00
mUI . mActionShowStyle - > setChecked ( checked ) ;
2017-07-28 10:41:03 +02:00
showStyle ( checked ) ;
2009-07-02 10:32:29 +02:00
mUI . mActionShowErrors - > setChecked ( checked ) ;
2017-07-28 10:41:03 +02:00
showErrors ( checked ) ;
2010-10-18 19:50:34 +02:00
mUI . mActionShowWarnings - > setChecked ( checked ) ;
2017-07-28 10:41:03 +02:00
showWarnings ( checked ) ;
2010-12-27 10:06:31 +01:00
mUI . mActionShowPortability - > setChecked ( checked ) ;
2017-07-28 10:41:03 +02:00
showPortability ( checked ) ;
2010-10-18 19:50:34 +02:00
mUI . mActionShowPerformance - > setChecked ( checked ) ;
2017-07-28 10:41:03 +02:00
showPerformance ( checked ) ;
2010-12-26 13:36:24 +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
{
2011-08-11 17:13:54 +02:00
AboutDialog * dlg = new AboutDialog ( CppCheck : : version ( ) , CppCheck : : extraVersion ( ) , this ) ;
2009-06-14 11:57:43 +02:00
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
2017-07-28 12:10:10 +02: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
}
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
{
2010-07-03 19:03:53 +02: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
{
mUI . mToolBarView - > setVisible ( mUI . mActionToolBarView - > isChecked ( ) ) ;
}
2017-07-28 10:41:03 +02:00
void MainWindow : : toggleFilterToolBar ( )
2011-05-04 07:30:54 +02:00
{
mUI . mToolBarFilter - > setVisible ( mUI . mActionToolBarFilter - > isChecked ( ) ) ;
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 + " ) " ;
}
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
2009-07-02 10:32:29 +02:00
mUI . retranslateUi ( this ) ;
2017-07-28 12:10:10 +02:00
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
{
2010-07-03 19:03:53 +02:00
mUI . mActionToolBarMain - > setChecked ( mUI . mToolBarMain - > isVisible ( ) ) ;
2010-07-03 18:37:09 +02:00
mUI . mActionToolBarView - > setChecked ( mUI . mToolBarView - > isVisible ( ) ) ;
2011-07-20 12:35:56 +02:00
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 ( ) ;
2017-07-28 12:10:10 +02:00
mUI . mResults - > disableProgressbar ( ) ;
2017-08-02 22:28:45 +02:00
const QString & lastResults = getLastResults ( ) ;
if ( ! lastResults . isEmpty ( ) ) {
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 ;
2011-04-07 14:34:15 +02: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 ( ) ;
2020-08-22 11:37:44 +02:00
mUI . mResults - > showContracts ( mProjectFile - > bugHunting ) ;
updateFunctionContractsTab ( ) ;
updateVariableContractsTab ( ) ;
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 ;
if ( ! QFileInfo ( lastResults ) . exists ( ) )
return false ;
mUI . mResults - > readErrorsXml ( lastResults ) ;
2017-09-23 15:11:42 +02:00
mUI . mResults - > setCheckDirectory ( mSettings - > value ( SETTINGS_LAST_CHECK_PATH , QString ( ) ) . toString ( ) ) ;
2018-02-16 22:22:13 +01:00
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 {
p . import ( prjfile . toStdString ( ) ) ;
} catch ( InternalError & e ) {
QMessageBox msg ( QMessageBox : : Critical ,
tr ( " Cppcheck " ) ,
tr ( " Failed to import '%1', analysis is stopped " ) . arg ( prjfile ) ,
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 ) ;
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
2017-07-31 16:14:01 +02:00
ProjectFileDialog dlg ( mProjectFile , this ) ;
2017-07-31 12:02:51 +02:00
if ( dlg . exec ( ) = = QDialog : : Accepted ) {
2017-07-28 05:44:15 +02:00
addProjectMRU ( filepath ) ;
2020-08-22 11:37:44 +02:00
mUI . mResults - > showContracts ( mProjectFile - > bugHunting ) ;
2017-07-31 12:02:51 +02:00
analyzeProject ( mProjectFile ) ;
} else {
closeProjectFile ( ) ;
2012-10-14 14:13:54 +02:00
}
2020-04-29 17:51:25 +02:00
2020-08-22 11:37:44 +02:00
updateFunctionContractsTab ( ) ;
updateVariableContractsTab ( ) ;
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 ;
2017-08-09 11:23:47 +02:00
mUI . mResults - > clear ( true ) ;
2020-08-22 11:37:44 +02:00
mUI . mResults - > clearContracts ( ) ;
mUI . mResults - > showContracts ( false ) ;
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
2017-07-31 16:14:01 +02:00
ProjectFileDialog dlg ( mProjectFile , this ) ;
2017-07-31 12:02:51 +02:00
if ( dlg . exec ( ) = = QDialog : : Accepted ) {
mProjectFile - > write ( ) ;
2020-08-22 11:37:44 +02:00
mUI . mResults - > showContracts ( mProjectFile - > bugHunting ) ;
2017-07-31 12:02:51 +02:00
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 ) ;
2017-07-28 12:10:10 +02: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
{
2017-07-28 12:10:10 +02: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
{
mUI . mActionCloseProjectFile - > setEnabled ( enable ) ;
mUI . mActionEditProjectFile - > setEnabled ( enable ) ;
2018-04-13 15:28:05 +02:00
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
{
mUI . mActionNewProjectFile - > setEnabled ( enable ) ;
mUI . mActionOpenProjectFile - > setEnabled ( enable ) ;
}
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 ) ;
int rv = msg . exec ( ) ;
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 )
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 - - ) {
2018-08-08 11:03:51 +02:00
if ( ! QFileInfo ( projects [ i ] ) . exists ( ) ) {
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 ) ;
mUI . mMenuFile - > insertAction ( mUI . mActionProjectMRU , mRecentProjectActs [ i ] ) ;
}
if ( numRecentProjects > 1 )
2011-08-24 22:14:28 +02: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 ) {
2011-10-02 21:08:12 +02:00
const Settings : : PlatformType platform = ( Settings : : PlatformType ) action - > data ( ) . toInt ( ) ;
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 ( ) ;
foreach ( QString id , ids ) {
// 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
}
2020-04-27 09:08:50 +02:00
2020-04-27 17:36:17 +02:00
void MainWindow : : editFunctionContract ( QString function )
2020-04-27 09:08:50 +02:00
{
if ( ! mProjectFile )
return ;
2020-04-27 17:36:17 +02:00
QString expects ;
const auto it = mProjectFile - > getFunctionContracts ( ) . find ( function . toStdString ( ) ) ;
if ( it ! = mProjectFile - > getFunctionContracts ( ) . end ( ) )
expects = QString : : fromStdString ( it - > second ) ;
FunctionContractDialog dlg ( nullptr ,
function ,
expects ) ;
if ( dlg . exec ( ) = = QDialog : : Accepted ) {
mProjectFile - > setFunctionContract ( function , dlg . getExpects ( ) ) ;
2020-04-27 09:08:50 +02:00
mProjectFile - > write ( ) ;
}
2020-04-28 22:09:01 +02:00
2020-08-22 11:37:44 +02:00
updateFunctionContractsTab ( ) ;
}
void MainWindow : : editVariableContract ( QString var )
{
if ( ! mProjectFile )
return ;
VariableContractsDialog dlg ( nullptr , var ) ;
if ( dlg . exec ( ) = = QDialog : : Accepted ) {
mProjectFile - > setVariableContracts ( dlg . getVarname ( ) , dlg . getMin ( ) , dlg . getMax ( ) ) ;
mProjectFile - > write ( ) ;
}
updateVariableContractsTab ( ) ;
}
2022-01-18 20:17:05 +01:00
void MainWindow : : deleteFunctionContract ( const QString & function )
2020-08-22 11:37:44 +02:00
{
if ( mProjectFile ) {
mProjectFile - > deleteFunctionContract ( function ) ;
mProjectFile - > write ( ) ;
}
}
2022-01-18 20:17:05 +01:00
void MainWindow : : deleteVariableContract ( const QString & var )
2020-08-22 11:37:44 +02:00
{
if ( mProjectFile ) {
mProjectFile - > deleteVariableContract ( var ) ;
mProjectFile - > write ( ) ;
}
2020-04-27 09:08:50 +02:00
}