aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app/app.pro5
-rw-r--r--src/app/app_version.h.in4
-rw-r--r--src/app/main.cpp36
-rw-r--r--src/libs/3rdparty/cplusplus/Symbols.cpp16
-rw-r--r--src/libs/clangbackendipc/clangbackendipc_dependencies.pri3
-rw-r--r--src/libs/clangbackendipc/stringcache.h179
-rw-r--r--src/libs/clangsupport/cancelmessage.cpp (renamed from src/libs/clangbackendipc/cancelmessage.cpp)0
-rw-r--r--src/libs/clangsupport/cancelmessage.h (renamed from src/libs/clangbackendipc/cancelmessage.h)2
-rw-r--r--src/libs/clangsupport/clangcodemodelclientinterface.cpp (renamed from src/libs/clangbackendipc/clangcodemodelclientinterface.cpp)3
-rw-r--r--src/libs/clangsupport/clangcodemodelclientinterface.h (renamed from src/libs/clangbackendipc/clangcodemodelclientinterface.h)3
-rw-r--r--src/libs/clangsupport/clangcodemodelclientmessages.h (renamed from src/libs/clangbackendipc/clangcodemodelclientmessages.h)1
-rw-r--r--src/libs/clangsupport/clangcodemodelclientproxy.cpp (renamed from src/libs/clangbackendipc/clangcodemodelclientproxy.cpp)5
-rw-r--r--src/libs/clangsupport/clangcodemodelclientproxy.h (renamed from src/libs/clangbackendipc/clangcodemodelclientproxy.h)3
-rw-r--r--src/libs/clangsupport/clangcodemodelconnectionclient.cpp (renamed from src/libs/clangbackendipc/clangcodemodelconnectionclient.cpp)0
-rw-r--r--src/libs/clangsupport/clangcodemodelconnectionclient.h (renamed from src/libs/clangbackendipc/clangcodemodelconnectionclient.h)0
-rw-r--r--src/libs/clangsupport/clangcodemodelserverinterface.cpp (renamed from src/libs/clangbackendipc/clangcodemodelserverinterface.cpp)3
-rw-r--r--src/libs/clangsupport/clangcodemodelserverinterface.h (renamed from src/libs/clangbackendipc/clangcodemodelserverinterface.h)3
-rw-r--r--src/libs/clangsupport/clangcodemodelservermessages.h (renamed from src/libs/clangbackendipc/clangcodemodelservermessages.h)1
-rw-r--r--src/libs/clangsupport/clangcodemodelserverproxy.cpp (renamed from src/libs/clangbackendipc/clangcodemodelserverproxy.cpp)5
-rw-r--r--src/libs/clangsupport/clangcodemodelserverproxy.h (renamed from src/libs/clangbackendipc/clangcodemodelserverproxy.h)1
-rw-r--r--src/libs/clangsupport/clangrefactoringclientmessages.h (renamed from src/libs/clangbackendipc/clangrefactoringclientmessages.h)0
-rw-r--r--src/libs/clangsupport/clangrefactoringmessages.h (renamed from src/libs/clangbackendipc/clangrefactoringmessages.h)0
-rw-r--r--src/libs/clangsupport/clangrefactoringservermessages.h (renamed from src/libs/clangbackendipc/clangrefactoringservermessages.h)2
-rw-r--r--src/libs/clangsupport/clangsupport-lib.pri (renamed from src/libs/clangbackendipc/clangbackendipc-lib.pri)22
-rw-r--r--src/libs/clangsupport/clangsupport.pro (renamed from src/libs/clangbackendipc/clangbackendipc.pro)2
-rw-r--r--src/libs/clangsupport/clangsupport.qbs (renamed from src/libs/clangbackendipc/clangbackendipc.qbs)4
-rw-r--r--src/libs/clangsupport/clangsupport_dependencies.pri3
-rw-r--r--src/libs/clangsupport/clangsupport_global.h (renamed from src/libs/clangbackendipc/clangbackendipc_global.h)7
-rw-r--r--src/libs/clangsupport/clangsupportdebugutils.cpp (renamed from src/libs/clangbackendipc/clangbackendipcdebugutils.cpp)4
-rw-r--r--src/libs/clangsupport/clangsupportdebugutils.h (renamed from src/libs/clangbackendipc/clangbackendipcdebugutils.h)2
-rw-r--r--src/libs/clangsupport/cmbalivemessage.cpp (renamed from src/libs/clangbackendipc/cmbalivemessage.cpp)0
-rw-r--r--src/libs/clangsupport/cmbalivemessage.h (renamed from src/libs/clangbackendipc/cmbalivemessage.h)2
-rw-r--r--src/libs/clangsupport/cmbcodecompletedmessage.cpp (renamed from src/libs/clangbackendipc/cmbcodecompletedmessage.cpp)0
-rw-r--r--src/libs/clangsupport/cmbcodecompletedmessage.h (renamed from src/libs/clangbackendipc/cmbcodecompletedmessage.h)0
-rw-r--r--src/libs/clangsupport/cmbcompletecodemessage.cpp (renamed from src/libs/clangbackendipc/cmbcompletecodemessage.cpp)6
-rw-r--r--src/libs/clangsupport/cmbcompletecodemessage.h (renamed from src/libs/clangbackendipc/cmbcompletecodemessage.h)30
-rw-r--r--src/libs/clangsupport/cmbechomessage.cpp (renamed from src/libs/clangbackendipc/cmbechomessage.cpp)0
-rw-r--r--src/libs/clangsupport/cmbechomessage.h (renamed from src/libs/clangbackendipc/cmbechomessage.h)2
-rw-r--r--src/libs/clangsupport/cmbendmessage.cpp (renamed from src/libs/clangbackendipc/cmbendmessage.cpp)0
-rw-r--r--src/libs/clangsupport/cmbendmessage.h (renamed from src/libs/clangbackendipc/cmbendmessage.h)2
-rw-r--r--src/libs/clangsupport/cmbregisterprojectsforeditormessage.cpp (renamed from src/libs/clangbackendipc/cmbregisterprojectsforeditormessage.cpp)0
-rw-r--r--src/libs/clangsupport/cmbregisterprojectsforeditormessage.h (renamed from src/libs/clangbackendipc/cmbregisterprojectsforeditormessage.h)0
-rw-r--r--src/libs/clangsupport/cmbregistertranslationunitsforeditormessage.cpp (renamed from src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.cpp)0
-rw-r--r--src/libs/clangsupport/cmbregistertranslationunitsforeditormessage.h (renamed from src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.h)0
-rw-r--r--src/libs/clangsupport/cmbunregisterprojectsforeditormessage.cpp (renamed from src/libs/clangbackendipc/cmbunregisterprojectsforeditormessage.cpp)0
-rw-r--r--src/libs/clangsupport/cmbunregisterprojectsforeditormessage.h (renamed from src/libs/clangbackendipc/cmbunregisterprojectsforeditormessage.h)2
-rw-r--r--src/libs/clangsupport/cmbunregistertranslationunitsforeditormessage.cpp (renamed from src/libs/clangbackendipc/cmbunregistertranslationunitsforeditormessage.cpp)0
-rw-r--r--src/libs/clangsupport/cmbunregistertranslationunitsforeditormessage.h (renamed from src/libs/clangbackendipc/cmbunregistertranslationunitsforeditormessage.h)2
-rw-r--r--src/libs/clangsupport/codecompletion.cpp (renamed from src/libs/clangbackendipc/codecompletion.cpp)0
-rw-r--r--src/libs/clangsupport/codecompletion.h (renamed from src/libs/clangbackendipc/codecompletion.h)2
-rw-r--r--src/libs/clangsupport/codecompletionchunk.cpp (renamed from src/libs/clangbackendipc/codecompletionchunk.cpp)0
-rw-r--r--src/libs/clangsupport/codecompletionchunk.h (renamed from src/libs/clangbackendipc/codecompletionchunk.h)2
-rw-r--r--src/libs/clangsupport/connectionclient.cpp (renamed from src/libs/clangbackendipc/connectionclient.cpp)2
-rw-r--r--src/libs/clangsupport/connectionclient.h (renamed from src/libs/clangbackendipc/connectionclient.h)0
-rw-r--r--src/libs/clangsupport/connectionserver.cpp (renamed from src/libs/clangbackendipc/connectionserver.cpp)0
-rw-r--r--src/libs/clangsupport/connectionserver.h (renamed from src/libs/clangbackendipc/connectionserver.h)2
-rw-r--r--src/libs/clangsupport/diagnosticcontainer.cpp (renamed from src/libs/clangbackendipc/diagnosticcontainer.cpp)0
-rw-r--r--src/libs/clangsupport/diagnosticcontainer.h (renamed from src/libs/clangbackendipc/diagnosticcontainer.h)0
-rw-r--r--src/libs/clangsupport/documentannotationschangedmessage.cpp (renamed from src/libs/clangbackendipc/documentannotationschangedmessage.cpp)0
-rw-r--r--src/libs/clangsupport/documentannotationschangedmessage.h (renamed from src/libs/clangbackendipc/documentannotationschangedmessage.h)2
-rw-r--r--src/libs/clangsupport/dynamicastmatcherdiagnosticcontainer.cpp (renamed from src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontainer.cpp)0
-rw-r--r--src/libs/clangsupport/dynamicastmatcherdiagnosticcontainer.h (renamed from src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontainer.h)0
-rw-r--r--src/libs/clangsupport/dynamicastmatcherdiagnosticcontextcontainer.cpp (renamed from src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontextcontainer.cpp)0
-rw-r--r--src/libs/clangsupport/dynamicastmatcherdiagnosticcontextcontainer.h (renamed from src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontextcontainer.h)0
-rw-r--r--src/libs/clangsupport/dynamicastmatcherdiagnosticmessagecontainer.cpp (renamed from src/libs/clangbackendipc/dynamicastmatcherdiagnosticmessagecontainer.cpp)0
-rw-r--r--src/libs/clangsupport/dynamicastmatcherdiagnosticmessagecontainer.h (renamed from src/libs/clangbackendipc/dynamicastmatcherdiagnosticmessagecontainer.h)0
-rw-r--r--src/libs/clangsupport/dynamicmatcherdiagnostics.h (renamed from src/libs/clangbackendipc/dynamicmatcherdiagnostics.h)0
-rw-r--r--src/libs/clangsupport/filecontainer.cpp (renamed from src/libs/clangbackendipc/filecontainer.cpp)2
-rw-r--r--src/libs/clangsupport/filecontainer.h (renamed from src/libs/clangbackendipc/filecontainer.h)2
-rw-r--r--src/libs/clangsupport/filecontainerv2.cpp (renamed from src/libs/clangbackendipc/filecontainerv2.cpp)0
-rw-r--r--src/libs/clangsupport/filecontainerv2.h (renamed from src/libs/clangbackendipc/filecontainerv2.h)2
-rw-r--r--src/libs/clangsupport/filepath.cpp (renamed from src/libs/clangbackendipc/filepath.cpp)0
-rw-r--r--src/libs/clangsupport/filepath.h (renamed from src/libs/clangbackendipc/filepath.h)2
-rw-r--r--src/libs/clangsupport/fixitcontainer.cpp (renamed from src/libs/clangbackendipc/fixitcontainer.cpp)0
-rw-r--r--src/libs/clangsupport/fixitcontainer.h (renamed from src/libs/clangbackendipc/fixitcontainer.h)0
-rw-r--r--src/libs/clangsupport/followsymbolmessage.cpp57
-rw-r--r--src/libs/clangsupport/followsymbolmessage.h96
-rw-r--r--src/libs/clangsupport/highlightingmarkcontainer.cpp (renamed from src/libs/clangbackendipc/highlightingmarkcontainer.cpp)6
-rw-r--r--src/libs/clangsupport/highlightingmarkcontainer.h (renamed from src/libs/clangbackendipc/highlightingmarkcontainer.h)34
-rw-r--r--src/libs/clangsupport/ipcclientinterface.cpp (renamed from src/libs/clangbackendipc/ipcclientinterface.cpp)0
-rw-r--r--src/libs/clangsupport/ipcclientinterface.h (renamed from src/libs/clangbackendipc/ipcclientinterface.h)0
-rw-r--r--src/libs/clangsupport/ipcclientprovider.h (renamed from src/libs/clangbackendipc/ipcserverinterface.h)14
-rw-r--r--src/libs/clangsupport/ipcinterface.cpp (renamed from src/libs/clangbackendipc/ipcinterface.cpp)0
-rw-r--r--src/libs/clangsupport/ipcinterface.h (renamed from src/libs/clangbackendipc/ipcinterface.h)2
-rw-r--r--src/libs/clangsupport/ipcserverinterface.cpp (renamed from src/libs/clangbackendipc/ipcserverinterface.cpp)0
-rw-r--r--src/libs/clangsupport/ipcserverinterface.h36
-rw-r--r--src/libs/clangsupport/lineprefixer.cpp (renamed from src/libs/clangbackendipc/lineprefixer.cpp)0
-rw-r--r--src/libs/clangsupport/lineprefixer.h (renamed from src/libs/clangbackendipc/lineprefixer.h)2
-rw-r--r--src/libs/clangsupport/messageenvelop.cpp (renamed from src/libs/clangbackendipc/messageenvelop.cpp)0
-rw-r--r--src/libs/clangsupport/messageenvelop.h (renamed from src/libs/clangbackendipc/messageenvelop.h)2
-rw-r--r--src/libs/clangsupport/pchmanagerclientinterface.cpp (renamed from src/libs/clangbackendipc/pchmanagerclientinterface.cpp)0
-rw-r--r--src/libs/clangsupport/pchmanagerclientinterface.h (renamed from src/libs/clangbackendipc/pchmanagerclientinterface.h)0
-rw-r--r--src/libs/clangsupport/pchmanagerclientproxy.cpp (renamed from src/libs/clangbackendipc/pchmanagerclientproxy.cpp)0
-rw-r--r--src/libs/clangsupport/pchmanagerclientproxy.h (renamed from src/libs/clangbackendipc/pchmanagerclientproxy.h)2
-rw-r--r--src/libs/clangsupport/pchmanagerserverinterface.cpp (renamed from src/libs/clangbackendipc/pchmanagerserverinterface.cpp)0
-rw-r--r--src/libs/clangsupport/pchmanagerserverinterface.h46
-rw-r--r--src/libs/clangsupport/pchmanagerserverproxy.cpp (renamed from src/libs/clangbackendipc/pchmanagerserverproxy.cpp)0
-rw-r--r--src/libs/clangsupport/pchmanagerserverproxy.h (renamed from src/libs/clangbackendipc/pchmanagerserverproxy.h)2
-rw-r--r--src/libs/clangsupport/precompiledheadersupdatedmessage.cpp (renamed from src/libs/clangbackendipc/precompiledheadersupdatedmessage.cpp)0
-rw-r--r--src/libs/clangsupport/precompiledheadersupdatedmessage.h (renamed from src/libs/clangbackendipc/precompiledheadersupdatedmessage.h)0
-rw-r--r--src/libs/clangsupport/projectmanagementserverinterface.h (renamed from src/libs/clangbackendipc/pchmanagerserverinterface.h)11
-rw-r--r--src/libs/clangsupport/projectpartcontainer.cpp (renamed from src/libs/clangbackendipc/projectpartcontainer.cpp)2
-rw-r--r--src/libs/clangsupport/projectpartcontainer.h (renamed from src/libs/clangbackendipc/projectpartcontainer.h)2
-rw-r--r--src/libs/clangsupport/projectpartcontainerv2.cpp (renamed from src/libs/clangbackendipc/projectpartcontainerv2.cpp)0
-rw-r--r--src/libs/clangsupport/projectpartcontainerv2.h (renamed from src/libs/clangbackendipc/projectpartcontainerv2.h)2
-rw-r--r--src/libs/clangsupport/projectpartpch.cpp (renamed from src/libs/clangbackendipc/projectpartpch.cpp)0
-rw-r--r--src/libs/clangsupport/projectpartpch.h (renamed from src/libs/clangbackendipc/projectpartpch.h)2
-rw-r--r--src/libs/clangsupport/projectpartsdonotexistmessage.cpp (renamed from src/libs/clangbackendipc/projectpartsdonotexistmessage.cpp)0
-rw-r--r--src/libs/clangsupport/projectpartsdonotexistmessage.h (renamed from src/libs/clangbackendipc/projectpartsdonotexistmessage.h)2
-rw-r--r--src/libs/clangsupport/readmessageblock.cpp (renamed from src/libs/clangbackendipc/readmessageblock.cpp)0
-rw-r--r--src/libs/clangsupport/readmessageblock.h (renamed from src/libs/clangbackendipc/readmessageblock.h)0
-rw-r--r--src/libs/clangsupport/refactoringclientinterface.cpp (renamed from src/libs/clangbackendipc/refactoringclientinterface.cpp)0
-rw-r--r--src/libs/clangsupport/refactoringclientinterface.h (renamed from src/libs/clangbackendipc/refactoringclientinterface.h)0
-rw-r--r--src/libs/clangsupport/refactoringclientproxy.cpp (renamed from src/libs/clangbackendipc/refactoringclientproxy.cpp)0
-rw-r--r--src/libs/clangsupport/refactoringclientproxy.h (renamed from src/libs/clangbackendipc/refactoringclientproxy.h)2
-rw-r--r--src/libs/clangsupport/refactoringdatabaseinitializer.h93
-rw-r--r--src/libs/clangsupport/refactoringserverinterface.cpp (renamed from src/libs/clangbackendipc/refactoringserverinterface.cpp)6
-rw-r--r--src/libs/clangsupport/refactoringserverinterface.h (renamed from src/libs/clangbackendipc/refactoringserverinterface.h)7
-rw-r--r--src/libs/clangsupport/refactoringserverproxy.cpp (renamed from src/libs/clangbackendipc/refactoringserverproxy.cpp)10
-rw-r--r--src/libs/clangsupport/refactoringserverproxy.h (renamed from src/libs/clangbackendipc/refactoringserverproxy.h)4
-rw-r--r--src/libs/clangsupport/referencesmessage.cpp (renamed from src/libs/clangbackendipc/referencesmessage.cpp)0
-rw-r--r--src/libs/clangsupport/referencesmessage.h (renamed from src/libs/clangbackendipc/referencesmessage.h)0
-rw-r--r--src/libs/clangsupport/registerunsavedfilesforeditormessage.cpp (renamed from src/libs/clangbackendipc/registerunsavedfilesforeditormessage.cpp)0
-rw-r--r--src/libs/clangsupport/registerunsavedfilesforeditormessage.h (renamed from src/libs/clangbackendipc/registerunsavedfilesforeditormessage.h)0
-rw-r--r--src/libs/clangsupport/removepchprojectpartsmessage.cpp (renamed from src/libs/clangbackendipc/removepchprojectpartsmessage.cpp)0
-rw-r--r--src/libs/clangsupport/removepchprojectpartsmessage.h (renamed from src/libs/clangbackendipc/removepchprojectpartsmessage.h)0
-rw-r--r--src/libs/clangsupport/requestdocumentannotations.cpp (renamed from src/libs/clangbackendipc/requestdocumentannotations.cpp)0
-rw-r--r--src/libs/clangsupport/requestdocumentannotations.h (renamed from src/libs/clangbackendipc/requestdocumentannotations.h)0
-rw-r--r--src/libs/clangsupport/requestfollowsymbolmessage.cpp64
-rw-r--r--src/libs/clangsupport/requestfollowsymbolmessage.h121
-rw-r--r--src/libs/clangsupport/requestreferencesmessage.cpp (renamed from src/libs/clangbackendipc/requestreferencesmessage.cpp)0
-rw-r--r--src/libs/clangsupport/requestreferencesmessage.h (renamed from src/libs/clangbackendipc/requestreferencesmessage.h)2
-rw-r--r--src/libs/clangsupport/requestsourcelocationforrenamingmessage.cpp (renamed from src/libs/clangbackendipc/requestsourcelocationforrenamingmessage.cpp)0
-rw-r--r--src/libs/clangsupport/requestsourcelocationforrenamingmessage.h (renamed from src/libs/clangbackendipc/requestsourcelocationforrenamingmessage.h)2
-rw-r--r--src/libs/clangsupport/requestsourcerangesanddiagnosticsforquerymessage.cpp (renamed from src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.cpp)0
-rw-r--r--src/libs/clangsupport/requestsourcerangesanddiagnosticsforquerymessage.h (renamed from src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h)0
-rw-r--r--src/libs/clangsupport/requestsourcerangesforquerymessage.cpp (renamed from src/libs/clangbackendipc/requestsourcerangesforquerymessage.cpp)0
-rw-r--r--src/libs/clangsupport/requestsourcerangesforquerymessage.h (renamed from src/libs/clangbackendipc/requestsourcerangesforquerymessage.h)0
-rw-r--r--src/libs/clangsupport/sourcefilepathcontainerbase.cpp (renamed from src/libs/clangbackendipc/sourcefilepathcontainerbase.cpp)0
-rw-r--r--src/libs/clangsupport/sourcefilepathcontainerbase.h (renamed from src/libs/clangbackendipc/sourcefilepathcontainerbase.h)0
-rw-r--r--src/libs/clangsupport/sourcelocationcontainer.cpp (renamed from src/libs/clangbackendipc/sourcelocationcontainer.cpp)0
-rw-r--r--src/libs/clangsupport/sourcelocationcontainer.h (renamed from src/libs/clangbackendipc/sourcelocationcontainer.h)2
-rw-r--r--src/libs/clangsupport/sourcelocationcontainerv2.cpp (renamed from src/libs/clangbackendipc/sourcelocationcontainerv2.cpp)0
-rw-r--r--src/libs/clangsupport/sourcelocationcontainerv2.h (renamed from src/libs/clangbackendipc/sourcelocationcontainerv2.h)2
-rw-r--r--src/libs/clangsupport/sourcelocationscontainer.cpp (renamed from src/libs/clangbackendipc/sourcelocationscontainer.cpp)0
-rw-r--r--src/libs/clangsupport/sourcelocationscontainer.h (renamed from src/libs/clangbackendipc/sourcelocationscontainer.h)0
-rw-r--r--src/libs/clangsupport/sourcelocationsforrenamingmessage.cpp (renamed from src/libs/clangbackendipc/sourcelocationsforrenamingmessage.cpp)0
-rw-r--r--src/libs/clangsupport/sourcelocationsforrenamingmessage.h (renamed from src/libs/clangbackendipc/sourcelocationsforrenamingmessage.h)0
-rw-r--r--src/libs/clangsupport/sourcerangecontainer.cpp (renamed from src/libs/clangbackendipc/sourcerangecontainer.cpp)0
-rw-r--r--src/libs/clangsupport/sourcerangecontainer.h (renamed from src/libs/clangbackendipc/sourcerangecontainer.h)0
-rw-r--r--src/libs/clangsupport/sourcerangecontainerv2.cpp (renamed from src/libs/clangbackendipc/sourcerangecontainerv2.cpp)0
-rw-r--r--src/libs/clangsupport/sourcerangecontainerv2.h (renamed from src/libs/clangbackendipc/sourcerangecontainerv2.h)0
-rw-r--r--src/libs/clangsupport/sourcerangesanddiagnosticsforquerymessage.cpp (renamed from src/libs/clangbackendipc/sourcerangesanddiagnosticsforquerymessage.cpp)0
-rw-r--r--src/libs/clangsupport/sourcerangesanddiagnosticsforquerymessage.h (renamed from src/libs/clangbackendipc/sourcerangesanddiagnosticsforquerymessage.h)0
-rw-r--r--src/libs/clangsupport/sourcerangescontainer.cpp (renamed from src/libs/clangbackendipc/sourcerangescontainer.cpp)0
-rw-r--r--src/libs/clangsupport/sourcerangescontainer.h (renamed from src/libs/clangbackendipc/sourcerangescontainer.h)0
-rw-r--r--src/libs/clangsupport/sourcerangesforquerymessage.cpp (renamed from src/libs/clangbackendipc/sourcerangesforquerymessage.cpp)0
-rw-r--r--src/libs/clangsupport/sourcerangesforquerymessage.h (renamed from src/libs/clangbackendipc/sourcerangesforquerymessage.h)0
-rw-r--r--src/libs/clangsupport/sourcerangewithtextcontainer.cpp (renamed from src/libs/clangbackendipc/sourcerangewithtextcontainer.cpp)0
-rw-r--r--src/libs/clangsupport/sourcerangewithtextcontainer.h (renamed from src/libs/clangbackendipc/sourcerangewithtextcontainer.h)0
-rw-r--r--src/libs/clangsupport/stringcache.h237
-rw-r--r--src/libs/clangsupport/stringcachealgorithms.h72
-rw-r--r--src/libs/clangsupport/stringcachefwd.h51
-rw-r--r--src/libs/clangsupport/translationunitdoesnotexistmessage.cpp (renamed from src/libs/clangbackendipc/translationunitdoesnotexistmessage.cpp)0
-rw-r--r--src/libs/clangsupport/translationunitdoesnotexistmessage.h (renamed from src/libs/clangbackendipc/translationunitdoesnotexistmessage.h)0
-rw-r--r--src/libs/clangsupport/unregisterunsavedfilesforeditormessage.cpp (renamed from src/libs/clangbackendipc/unregisterunsavedfilesforeditormessage.cpp)0
-rw-r--r--src/libs/clangsupport/unregisterunsavedfilesforeditormessage.h (renamed from src/libs/clangbackendipc/unregisterunsavedfilesforeditormessage.h)0
-rw-r--r--src/libs/clangsupport/updatepchprojectpartsmessage.cpp (renamed from src/libs/clangbackendipc/updatepchprojectpartsmessage.cpp)0
-rw-r--r--src/libs/clangsupport/updatepchprojectpartsmessage.h (renamed from src/libs/clangbackendipc/updatepchprojectpartsmessage.h)0
-rw-r--r--src/libs/clangsupport/updatetranslationunitsforeditormessage.cpp (renamed from src/libs/clangbackendipc/updatetranslationunitsforeditormessage.cpp)0
-rw-r--r--src/libs/clangsupport/updatetranslationunitsforeditormessage.h (renamed from src/libs/clangbackendipc/updatetranslationunitsforeditormessage.h)0
-rw-r--r--src/libs/clangsupport/updatevisibletranslationunitsmessage.cpp (renamed from src/libs/clangbackendipc/updatevisibletranslationunitsmessage.cpp)0
-rw-r--r--src/libs/clangsupport/updatevisibletranslationunitsmessage.h (renamed from src/libs/clangbackendipc/updatevisibletranslationunitsmessage.h)2
-rw-r--r--src/libs/clangsupport/writemessageblock.cpp (renamed from src/libs/clangbackendipc/writemessageblock.cpp)0
-rw-r--r--src/libs/clangsupport/writemessageblock.h (renamed from src/libs/clangbackendipc/writemessageblock.h)0
-rw-r--r--src/libs/extensionsystem/pluginerroroverview.ui2
-rw-r--r--src/libs/extensionsystem/pluginmanager.cpp6
-rw-r--r--src/libs/extensionsystem/pluginview.cpp3
-rw-r--r--src/libs/extensionsystem/pluginview.h7
-rw-r--r--src/libs/flamegraph/flamegraph.h3
-rw-r--r--src/libs/libs.pro2
-rw-r--r--src/libs/libs.qbs2
-rw-r--r--src/libs/modelinglib/modelinglib.qbs12
-rw-r--r--src/libs/modelinglib/qmt/config/configcontroller.cpp9
-rw-r--r--src/libs/modelinglib/qmt/config/configcontroller.h4
-rw-r--r--src/libs/modelinglib/qmt/config/sourcepos.cpp3
-rw-r--r--src/libs/modelinglib/qmt/config/sourcepos.h6
-rw-r--r--src/libs/modelinglib/qmt/config/stereotypedefinitionparser.cpp707
-rw-r--r--src/libs/modelinglib/qmt/config/stereotypedefinitionparser.h36
-rw-r--r--src/libs/modelinglib/qmt/config/stringtextsource.cpp12
-rw-r--r--src/libs/modelinglib/qmt/config/stringtextsource.h8
-rw-r--r--src/libs/modelinglib/qmt/config/textscanner.cpp8
-rw-r--r--src/libs/modelinglib/qmt/config/textscanner.h2
-rw-r--r--src/libs/modelinglib/qmt/config/token.cpp4
-rw-r--r--src/libs/modelinglib/qmt/config/token.h1
-rw-r--r--src/libs/modelinglib/qmt/controller/namecontroller.cpp10
-rw-r--r--src/libs/modelinglib/qmt/controller/namecontroller.h2
-rw-r--r--src/libs/modelinglib/qmt/controller/undocommand.cpp4
-rw-r--r--src/libs/modelinglib/qmt/controller/undocommand.h4
-rw-r--r--src/libs/modelinglib/qmt/controller/undocontroller.cpp3
-rw-r--r--src/libs/modelinglib/qmt/controller/undocontroller.h6
-rw-r--r--src/libs/modelinglib/qmt/diagram/dannotation.cpp4
-rw-r--r--src/libs/modelinglib/qmt/diagram/dannotation.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram/dassociation.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram/dassociation.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram/dclass.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram/dclass.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram/dcomponent.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram/dcomponent.h2
-rw-r--r--src/libs/modelinglib/qmt/diagram/dconnection.cpp103
-rw-r--r--src/libs/modelinglib/qmt/diagram/dconnection.h78
-rw-r--r--src/libs/modelinglib/qmt/diagram/dconstvisitor.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram/ddependency.cpp1
-rw-r--r--src/libs/modelinglib/qmt/diagram/ddependency.h2
-rw-r--r--src/libs/modelinglib/qmt/diagram/ditem.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram/ditem.h2
-rw-r--r--src/libs/modelinglib/qmt/diagram/dobject.cpp8
-rw-r--r--src/libs/modelinglib/qmt/diagram/dobject.h14
-rw-r--r--src/libs/modelinglib/qmt/diagram/dswimlane.cpp (renamed from src/libs/sqlite/columndefinition.cpp)61
-rw-r--r--src/libs/modelinglib/qmt/diagram/dswimlane.h58
-rw-r--r--src/libs/modelinglib/qmt/diagram/dvisitor.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp33
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.h8
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp14
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dfactory.h3
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.cpp39
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.cpp76
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.h6
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp42
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.h9
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp22
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/capabilities/intersectionable.h2
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/capabilities/selectable.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/diagramgraphicsscene.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/diagramsceneconstants.h1
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp134
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.h26
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.cpp83
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.h16
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.cpp19
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.h14
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/associationitem.cpp6
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/associationitem.h12
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.cpp21
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.h16
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp271
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/classitem.h31
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/componentitem.cpp54
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/componentitem.h21
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.cpp170
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.h64
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/diagramitem.cpp8
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/diagramitem.h8
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/itemitem.cpp50
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/itemitem.h17
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/objectitem.cpp331
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/objectitem.h40
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/packageitem.cpp47
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/packageitem.h17
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/relationitem.cpp83
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/relationitem.h16
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/stereotypedisplayvisitor.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/stereotypedisplayvisitor.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.cpp250
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.h87
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/latchcontroller.cpp9
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/latchcontroller.h16
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.cpp16
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/alignlineitem.h8
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.cpp156
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.h22
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/contextlabelitem.cpp6
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/contextlabelitem.h2
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/customiconitem.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.cpp10
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.h6
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.cpp22
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.h6
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.cpp13
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.h15
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/stereotypesitem.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/stereotypesitem.h2
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/templateparameterbox.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/templateparameterbox.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram_ui/diagram_mime_types.h1
-rw-r--r--src/libs/modelinglib/qmt/diagram_ui/diagramsmanager.cpp15
-rw-r--r--src/libs/modelinglib/qmt/diagram_ui/diagramsmanager.h12
-rw-r--r--src/libs/modelinglib/qmt/diagram_ui/sceneinspector.cpp7
-rw-r--r--src/libs/modelinglib/qmt/diagram_ui/sceneinspector.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram_widgets_ui/diagramsview.cpp7
-rw-r--r--src/libs/modelinglib/qmt/diagram_widgets_ui/diagramsview.h4
-rw-r--r--src/libs/modelinglib/qmt/diagram_widgets_ui/diagramview.cpp24
-rw-r--r--src/libs/modelinglib/qmt/diagram_widgets_ui/diagramview.h2
-rw-r--r--src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.cpp7
-rw-r--r--src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.h4
-rw-r--r--src/libs/modelinglib/qmt/document_controller/documentcontroller.cpp9
-rw-r--r--src/libs/modelinglib/qmt/document_controller/documentcontroller.h26
-rw-r--r--src/libs/modelinglib/qmt/infrastructure/contextmenuaction.h4
-rw-r--r--src/libs/modelinglib/qmt/infrastructure/geometryutilities.cpp2
-rw-r--r--src/libs/modelinglib/qmt/infrastructure/geometryutilities.h2
-rw-r--r--src/libs/modelinglib/qmt/infrastructure/handle.h10
-rw-r--r--src/libs/modelinglib/qmt/infrastructure/handles.h28
-rw-r--r--src/libs/modelinglib/qmt/infrastructure/qcompressedfile.cpp16
-rw-r--r--src/libs/modelinglib/qmt/infrastructure/qcompressedfile.h6
-rw-r--r--src/libs/modelinglib/qmt/infrastructure/qmtassert.h4
-rw-r--r--src/libs/modelinglib/qmt/model/massociation.cpp2
-rw-r--r--src/libs/modelinglib/qmt/model/massociation.h4
-rw-r--r--src/libs/modelinglib/qmt/model/mclassmember.cpp32
-rw-r--r--src/libs/modelinglib/qmt/model/mclassmember.h8
-rw-r--r--src/libs/modelinglib/qmt/model/mconnection.cpp114
-rw-r--r--src/libs/modelinglib/qmt/model/mconnection.h85
-rw-r--r--src/libs/modelinglib/qmt/model/mconstvisitor.h2
-rw-r--r--src/libs/modelinglib/qmt/model/mdependency.cpp2
-rw-r--r--src/libs/modelinglib/qmt/model/mdependency.h2
-rw-r--r--src/libs/modelinglib/qmt/model/mdiagram.cpp10
-rw-r--r--src/libs/modelinglib/qmt/model/melement.h6
-rw-r--r--src/libs/modelinglib/qmt/model/mitem.cpp3
-rw-r--r--src/libs/modelinglib/qmt/model/mitem.h4
-rw-r--r--src/libs/modelinglib/qmt/model/mobject.cpp44
-rw-r--r--src/libs/modelinglib/qmt/model/msourceexpansion.cpp4
-rw-r--r--src/libs/modelinglib/qmt/model/msourceexpansion.h2
-rw-r--r--src/libs/modelinglib/qmt/model/mvisitor.h2
-rw-r--r--src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.cpp6
-rw-r--r--src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.h1
-rw-r--r--src/libs/modelinglib/qmt/model_controller/mclonevisitor.cpp29
-rw-r--r--src/libs/modelinglib/qmt/model_controller/mclonevisitor.h6
-rw-r--r--src/libs/modelinglib/qmt/model_controller/mflatassignmentvisitor.cpp26
-rw-r--r--src/libs/modelinglib/qmt/model_controller/mflatassignmentvisitor.h3
-rw-r--r--src/libs/modelinglib/qmt/model_controller/modelcontroller.cpp165
-rw-r--r--src/libs/modelinglib/qmt/model_controller/modelcontroller.h8
-rw-r--r--src/libs/modelinglib/qmt/model_controller/mvoidvisitor.cpp11
-rw-r--r--src/libs/modelinglib/qmt/model_controller/mvoidvisitor.h2
-rw-r--r--src/libs/modelinglib/qmt/model_ui/sortedtreemodel.h4
-rw-r--r--src/libs/modelinglib/qmt/model_ui/stereotypescontroller.cpp2
-rw-r--r--src/libs/modelinglib/qmt/model_ui/stereotypescontroller.h2
-rw-r--r--src/libs/modelinglib/qmt/model_ui/treemodel.cpp117
-rw-r--r--src/libs/modelinglib/qmt/model_ui/treemodel.h2
-rw-r--r--src/libs/modelinglib/qmt/model_ui/treemodelmanager.cpp8
-rw-r--r--src/libs/modelinglib/qmt/model_ui/treemodelmanager.h6
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.cpp130
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.h2
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp36
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.h6
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/palettebox.cpp13
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/palettebox.h4
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.cpp38
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.h16
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp383
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.h102
-rw-r--r--src/libs/modelinglib/qmt/project/project.h2
-rw-r--r--src/libs/modelinglib/qmt/project_controller/projectcontroller.cpp3
-rw-r--r--src/libs/modelinglib/qmt/project_controller/projectcontroller.h4
-rw-r--r--src/libs/modelinglib/qmt/qmt.pri16
-rw-r--r--src/libs/modelinglib/qmt/resources/48x48/swimlane.pngbin0 -> 191 bytes
-rw-r--r--src/libs/modelinglib/qmt/resources/resources.qrc1
-rw-r--r--src/libs/modelinglib/qmt/serializer/diagramserializer.cpp142
-rw-r--r--src/libs/modelinglib/qmt/serializer/infrastructureserializer.h10
-rw-r--r--src/libs/modelinglib/qmt/serializer/modelserializer.cpp106
-rw-r--r--src/libs/modelinglib/qmt/serializer/projectserializer.cpp18
-rw-r--r--src/libs/modelinglib/qmt/stereotype/customrelation.cpp139
-rw-r--r--src/libs/modelinglib/qmt/stereotype/customrelation.h166
-rw-r--r--src/libs/modelinglib/qmt/stereotype/iconshape.cpp22
-rw-r--r--src/libs/modelinglib/qmt/stereotype/iconshape.h2
-rw-r--r--src/libs/modelinglib/qmt/stereotype/shape.h2
-rw-r--r--src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.cpp56
-rw-r--r--src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.h4
-rw-r--r--src/libs/modelinglib/qmt/stereotype/shapes.cpp44
-rw-r--r--src/libs/modelinglib/qmt/stereotype/shapes.h70
-rw-r--r--src/libs/modelinglib/qmt/stereotype/shapevalue.h6
-rw-r--r--src/libs/modelinglib/qmt/stereotype/shapevisitor.h6
-rw-r--r--src/libs/modelinglib/qmt/stereotype/stereotypecontroller.cpp28
-rw-r--r--src/libs/modelinglib/qmt/stereotype/stereotypecontroller.h8
-rw-r--r--src/libs/modelinglib/qmt/stereotype/stereotypeicon.cpp15
-rw-r--r--src/libs/modelinglib/qmt/stereotype/stereotypeicon.h17
-rw-r--r--src/libs/modelinglib/qmt/stereotype/toolbar.cpp11
-rw-r--r--src/libs/modelinglib/qmt/stereotype/toolbar.h13
-rw-r--r--src/libs/modelinglib/qmt/style/defaultstyleengine.cpp55
-rw-r--r--src/libs/modelinglib/qmt/style/defaultstyleengine.h5
-rw-r--r--src/libs/modelinglib/qmt/style/objectvisuals.cpp4
-rw-r--r--src/libs/modelinglib/qmt/style/objectvisuals.h8
-rw-r--r--src/libs/modelinglib/qmt/style/stylecontroller.cpp11
-rw-r--r--src/libs/modelinglib/qmt/style/stylecontroller.h5
-rw-r--r--src/libs/modelinglib/qmt/style/styledobject.h2
-rw-r--r--src/libs/modelinglib/qmt/style/styledrelation.h6
-rw-r--r--src/libs/modelinglib/qmt/style/styleengine.h6
-rw-r--r--src/libs/modelinglib/qmt/tasks/alignonrastervisitor.cpp17
-rw-r--r--src/libs/modelinglib/qmt/tasks/alignonrastervisitor.h8
-rw-r--r--src/libs/modelinglib/qmt/tasks/diagramscenecontroller.cpp198
-rw-r--r--src/libs/modelinglib/qmt/tasks/diagramscenecontroller.h39
-rw-r--r--src/libs/modelinglib/qmt/tasks/finddiagramvisitor.cpp2
-rw-r--r--src/libs/modelinglib/qmt/tasks/finddiagramvisitor.h2
-rw-r--r--src/libs/modelinglib/qmt/tasks/findrootdiagramvisitor.cpp2
-rw-r--r--src/libs/modelinglib/qmt/tasks/findrootdiagramvisitor.h2
-rw-r--r--src/libs/modelinglib/qstringparser/qstringparser.h4
-rw-r--r--src/libs/modelinglib/qtserialization/inc/qark/attribute.h18
-rw-r--r--src/libs/modelinglib/qtserialization/inc/qark/baseclass.h4
-rw-r--r--src/libs/modelinglib/qtserialization/inc/qark/qxmlinarchive.h48
-rw-r--r--src/libs/modelinglib/qtserialization/inc/qark/qxmloutarchive.h5
-rw-r--r--src/libs/modelinglib/qtserialization/inc/qark/reference.h18
-rw-r--r--src/libs/modelinglib/qtserialization/inc/qark/serialize_basic.h8
-rw-r--r--src/libs/modelinglib/qtserialization/inc/qark/serialize_container.h50
-rw-r--r--src/libs/modelinglib/qtserialization/inc/qark/serialize_pointer.h6
-rw-r--r--src/libs/modelinglib/qtserialization/inc/qark/tag.h2
-rw-r--r--src/libs/modelinglib/qtserialization/inc/qark/typeregistry.h12
-rw-r--r--src/libs/qmldebug/baseenginedebugclient.cpp28
-rw-r--r--src/libs/qmldebug/baseenginedebugclient.h6
-rw-r--r--src/libs/qmldebug/basetoolsclient.h2
-rw-r--r--src/libs/qmldebug/declarativeenginedebugclient.cpp8
-rw-r--r--src/libs/qmldebug/declarativeenginedebugclient.h9
-rw-r--r--src/libs/qmldebug/declarativetoolsclient.h15
-rw-r--r--src/libs/qmldebug/qdebugmessageclient.h5
-rw-r--r--src/libs/qmldebug/qmldebugclient.cpp20
-rw-r--r--src/libs/qmldebug/qmldebugclient.h4
-rw-r--r--src/libs/qmldebug/qmldebugcommandlinearguments.h18
-rw-r--r--src/libs/qmldebug/qmlenginecontrolclient.h3
-rw-r--r--src/libs/qmldebug/qmltoolsclient.cpp8
-rw-r--r--src/libs/qmldebug/qmltoolsclient.h15
-rw-r--r--src/libs/qmldebug/qpacketprotocol.h3
-rw-r--r--src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp9
-rw-r--r--src/libs/qmleditorwidgets/easingpane/easingpane.qrc2
-rw-r--r--src/libs/qmleditorwidgets/easingpane/playicon.pngbin100 -> 0 bytes
-rw-r--r--src/libs/qmleditorwidgets/easingpane/stopicon.pngbin78 -> 0 bytes
-rw-r--r--src/libs/qmleditorwidgets/images/hole.pngbin116 -> 0 bytes
-rw-r--r--src/libs/qmleditorwidgets/images/lock.pngbin525 -> 0 bytes
-rw-r--r--src/libs/qmleditorwidgets/resources.qrc2
-rw-r--r--src/libs/qmljs/parser/qmljslexer.cpp1
-rw-r--r--src/libs/qmljs/parser/qmljsparser.cpp1
-rw-r--r--src/libs/qmljs/qmljscheck.cpp24
-rw-r--r--src/libs/qmljs/qmljscodeformatter.cpp3
-rw-r--r--src/libs/qmljs/qmljsdescribevalue.h2
-rw-r--r--src/libs/qmljs/qmljsfindexportedcpptypes.cpp4
-rw-r--r--src/libs/qmljs/qmljsreformatter.cpp24
-rw-r--r--src/libs/qmljs/qmljsreformatter.h1
-rw-r--r--src/libs/qmljs/qmljsscopeastpath.h2
-rw-r--r--src/libs/qmljs/qmljsstaticanalysismessage.cpp2
-rw-r--r--src/libs/qmljs/qmljsstaticanalysismessage.h2
-rw-r--r--src/libs/qmljs/qmljstypedescriptionreader.h4
-rw-r--r--src/libs/qt-breakpad/poster/__init__.py32
-rw-r--r--src/libs/qt-breakpad/poster/encode.py433
-rw-r--r--src/libs/qt-breakpad/poster/streaminghttp.py216
-rw-r--r--src/libs/qt-breakpad/qtbreakpad.pri64
-rw-r--r--src/libs/qt-breakpad/qtbreakpad/qtsystemexceptionhandler.cpp222
-rw-r--r--src/libs/qt-breakpad/qtbreakpad/qtsystemexceptionhandler.h56
-rwxr-xr-xsrc/libs/qt-breakpad/qtbreakpadsymbols271
-rw-r--r--src/libs/qt-breakpad/qtbreakpadsymbols.bat1
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler.pri21
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler/detaildialog.cpp55
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler/detaildialog.h48
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler/dumpsender.cpp178
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler/dumpsender.h (renamed from src/libs/sqlite/sqlitedatabaseconnection.h)36
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler/main.cpp73
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler/mainwidget.cpp155
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler/mainwidget.h (renamed from src/libs/sqlite/sqlitedatabaseconnectionproxy.h)53
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler/mainwidget.ui143
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler/qtcrashhandler.pro6
-rw-r--r--src/libs/qt-breakpad/testapp/main.cpp43
-rw-r--r--src/libs/qt-breakpad/testapp/testapp.pro14
-rw-r--r--src/libs/sqlite/columndefinition.h52
-rw-r--r--src/libs/sqlite/createtablecommand.cpp36
-rw-r--r--src/libs/sqlite/createtablesqlstatementbuilder.cpp113
-rw-r--r--src/libs/sqlite/createtablesqlstatementbuilder.h33
-rw-r--r--src/libs/sqlite/sqlite-lib.pri17
-rw-r--r--src/libs/sqlite/sqlitecolumn.cpp54
-rw-r--r--src/libs/sqlite/sqlitecolumn.h94
-rw-r--r--src/libs/sqlite/sqlitedatabase.cpp108
-rw-r--r--src/libs/sqlite/sqlitedatabase.h84
-rw-r--r--src/libs/sqlite/sqlitedatabasebackend.cpp274
-rw-r--r--src/libs/sqlite/sqlitedatabasebackend.h100
-rw-r--r--src/libs/sqlite/sqlitedatabaseconnection.cpp97
-rw-r--r--src/libs/sqlite/sqlitedatabaseconnectionproxy.cpp92
-rw-r--r--src/libs/sqlite/sqliteexception.cpp17
-rw-r--r--src/libs/sqlite/sqliteexception.h226
-rw-r--r--src/libs/sqlite/sqliteglobal.cpp8
-rw-r--r--src/libs/sqlite/sqliteglobal.h44
-rw-r--r--src/libs/sqlite/sqliteindex.h82
-rw-r--r--src/libs/sqlite/sqlitereadstatement.cpp13
-rw-r--r--src/libs/sqlite/sqlitereadstatement.h25
-rw-r--r--src/libs/sqlite/sqlitereadwritestatement.cpp8
-rw-r--r--src/libs/sqlite/sqlitereadwritestatement.h32
-rw-r--r--src/libs/sqlite/sqlitestatement.cpp606
-rw-r--r--src/libs/sqlite/sqlitestatement.h368
-rw-r--r--src/libs/sqlite/sqlitetable.cpp86
-rw-r--r--src/libs/sqlite/sqlitetable.h143
-rw-r--r--src/libs/sqlite/sqlitetransaction.cpp29
-rw-r--r--src/libs/sqlite/sqlitetransaction.h66
-rw-r--r--src/libs/sqlite/sqliteworkerthread.cpp59
-rw-r--r--src/libs/sqlite/sqliteworkerthread.h49
-rw-r--r--src/libs/sqlite/sqlitewritestatement.cpp13
-rw-r--r--src/libs/sqlite/sqlitewritestatement.h22
-rw-r--r--src/libs/sqlite/sqlstatementbuilder.cpp168
-rw-r--r--src/libs/sqlite/sqlstatementbuilder.h59
-rw-r--r--src/libs/sqlite/sqlstatementbuilderexception.cpp11
-rw-r--r--src/libs/sqlite/sqlstatementbuilderexception.h8
-rw-r--r--src/libs/sqlite/tablewriteworker.cpp65
-rw-r--r--src/libs/sqlite/tablewriteworkerproxy.cpp62
-rw-r--r--src/libs/ssh/images/dir.png (renamed from src/libs/utils/images/dir.png)bin862 -> 862 bytes
-rw-r--r--src/libs/ssh/images/help.png (renamed from src/libs/utils/images/help.png)bin430 -> 430 bytes
-rw-r--r--src/libs/ssh/images/unknownfile.png (renamed from src/libs/utils/images/unknownfile.png)bin345 -> 345 bytes
-rw-r--r--src/libs/ssh/sftpfilesystemmodel.cpp6
-rw-r--r--src/libs/ssh/ssh.pro2
-rw-r--r--src/libs/ssh/ssh.qbs1
-rw-r--r--src/libs/ssh/ssh.qrc7
-rw-r--r--src/libs/ssh/sshagent.cpp2
-rw-r--r--src/libs/ssh/sshagent_p.h2
-rw-r--r--src/libs/ssh/sshexception_p.h11
-rw-r--r--src/libs/timeline/qml/MainView.qml3
-rw-r--r--src/libs/timeline/qml/lock_closed@2x.pngbin190 -> 0 bytes
-rw-r--r--src/libs/timeline/qml/lock_open@2x.pngbin177 -> 0 bytes
-rw-r--r--src/libs/timeline/timelinemodelaggregator.h1
-rw-r--r--src/libs/utils/basetreeview.cpp2
-rw-r--r--src/libs/utils/camelhumpmatcher.cpp143
-rw-r--r--src/libs/utils/camelhumpmatcher.h (renamed from src/libs/sqlite/tablewriteworkerproxy.h)55
-rw-r--r--src/libs/utils/environment.cpp79
-rw-r--r--src/libs/utils/fancylineedit.cpp25
-rw-r--r--src/libs/utils/fancylineedit.h9
-rw-r--r--src/libs/utils/fileutils.cpp3
-rw-r--r--src/libs/utils/highlightingitemdelegate.cpp43
-rw-r--r--src/libs/utils/images/empty16.pngbin0 -> 75 bytes
-rw-r--r--src/libs/utils/images/magnifier.pngbin178 -> 201 bytes
-rw-r--r--src/libs/utils/images/magnifier@2x.pngbin338 -> 360 bytes
-rw-r--r--src/libs/utils/optional.h2
-rw-r--r--src/libs/utils/pathchooser.cpp38
-rw-r--r--src/libs/utils/pathchooser.h4
-rw-r--r--src/libs/utils/persistentsettings.h1
-rw-r--r--src/libs/utils/progressindicator.cpp134
-rw-r--r--src/libs/utils/progressindicator.h70
-rw-r--r--src/libs/utils/reloadpromptutils.cpp10
-rw-r--r--src/libs/utils/shellcommand.cpp15
-rw-r--r--src/libs/utils/shellcommand.h2
-rw-r--r--src/libs/utils/smallstring.h381
-rw-r--r--src/libs/utils/smallstringfwd.h6
-rw-r--r--src/libs/utils/smallstringio.h58
-rw-r--r--src/libs/utils/smallstringiterator.h2
-rw-r--r--src/libs/utils/smallstringlayout.h6
-rw-r--r--src/libs/utils/smallstringliteral.h11
-rw-r--r--src/libs/utils/smallstringvector.h28
-rw-r--r--src/libs/utils/smallstringview.h123
-rw-r--r--src/libs/utils/stylehelper.cpp11
-rw-r--r--src/libs/utils/textutils.cpp (renamed from src/plugins/texteditor/convenience.cpp)19
-rw-r--r--src/libs/utils/textutils.h (renamed from src/plugins/texteditor/convenience.h)30
-rw-r--r--src/libs/utils/theme/theme.cpp2
-rw-r--r--src/libs/utils/tooltip/tooltip.cpp7
-rw-r--r--src/libs/utils/treemodel.cpp22
-rw-r--r--src/libs/utils/treemodel.h3
-rw-r--r--src/libs/utils/utils-lib.pri8
-rw-r--r--src/libs/utils/utils.qbs4
-rw-r--r--src/libs/utils/utils.qrc4
-rw-r--r--src/libs/utils/utilsicons.cpp1
-rw-r--r--src/libs/utils/utilsicons.h1
-rw-r--r--src/plugins/android/android.qbs1
-rw-r--r--src/plugins/android/androidanalyzesupport.cpp2
-rw-r--r--src/plugins/android/androidbuildapkstep.cpp59
-rw-r--r--src/plugins/android/androidbuildapkstep.h8
-rw-r--r--src/plugins/android/androidbuildapkwidget.cpp48
-rw-r--r--src/plugins/android/androidbuildapkwidget.h3
-rw-r--r--src/plugins/android/androidbuildapkwidget.ui97
-rw-r--r--src/plugins/android/androidconfigurations.cpp71
-rw-r--r--src/plugins/android/androidconfigurations.h15
-rw-r--r--src/plugins/android/androiddebugsupport.cpp52
-rw-r--r--src/plugins/android/androiddeployqtstep.cpp12
-rw-r--r--src/plugins/android/androiddevicedialog.cpp15
-rw-r--r--src/plugins/android/androiddevicedialog.h2
-rw-r--r--src/plugins/android/androidmanager.cpp27
-rw-r--r--src/plugins/android/androidmanager.h1
-rw-r--r--src/plugins/android/androidpotentialkit.cpp7
-rw-r--r--src/plugins/android/androidqtsupport.cpp6
-rw-r--r--src/plugins/android/androidrunconfiguration.cpp9
-rw-r--r--src/plugins/android/androidrunconfiguration.h11
-rw-r--r--src/plugins/android/androidrunconfigurationwidget.cpp4
-rw-r--r--src/plugins/android/androidrunner.cpp31
-rw-r--r--src/plugins/android/androidrunner.h9
-rw-r--r--src/plugins/android/androidsdkmanager.cpp9
-rw-r--r--src/plugins/android/androidsettingswidget.cpp232
-rw-r--r--src/plugins/android/androidsettingswidget.h13
-rw-r--r--src/plugins/android/androidsettingswidget.ui462
-rw-r--r--src/plugins/android/androidtoolchain.cpp2
-rw-r--r--src/plugins/android/images/androiddevice.pngbin211 -> 216 bytes
-rw-r--r--src/plugins/android/images/androiddevice@2x.pngbin255 -> 259 bytes
-rw-r--r--src/plugins/autotest/autotest.qrc1
-rw-r--r--src/plugins/autotest/autotestconstants.h12
-rw-r--r--src/plugins/autotest/autotesticons.h4
-rw-r--r--src/plugins/autotest/autotestplugin.cpp6
-rw-r--r--src/plugins/autotest/gtest/gtestconfiguration.cpp42
-rw-r--r--src/plugins/autotest/gtest/gtestconfiguration.h2
-rw-r--r--src/plugins/autotest/gtest/gtestoutputreader.cpp2
-rw-r--r--src/plugins/autotest/gtest/gtesttreeitem.cpp4
-rw-r--r--src/plugins/autotest/images/benchmark.pngbin374 -> 202 bytes
-rw-r--r--src/plugins/autotest/images/benchmark@2x.pngbin0 -> 366 bytes
-rw-r--r--src/plugins/autotest/images/text.pngbin148 -> 152 bytes
-rw-r--r--src/plugins/autotest/images/text@2x.pngbin274 -> 212 bytes
-rw-r--r--src/plugins/autotest/images/visual.pngbin213 -> 123 bytes
-rw-r--r--src/plugins/autotest/images/visual@2x.pngbin297 -> 134 bytes
-rw-r--r--src/plugins/autotest/qtest/qttest_utils.cpp58
-rw-r--r--src/plugins/autotest/qtest/qttest_utils.h1
-rw-r--r--src/plugins/autotest/qtest/qttestconfiguration.cpp12
-rw-r--r--src/plugins/autotest/qtest/qttestconfiguration.h2
-rw-r--r--src/plugins/autotest/qtest/qttestparser.cpp7
-rw-r--r--src/plugins/autotest/qtest/qttesttreeitem.cpp2
-rw-r--r--src/plugins/autotest/quick/quicktestconfiguration.cpp11
-rw-r--r--src/plugins/autotest/quick/quicktestconfiguration.h2
-rw-r--r--src/plugins/autotest/quick/quicktestframework.cpp2
-rw-r--r--src/plugins/autotest/quick/quicktestparser.cpp25
-rw-r--r--src/plugins/autotest/quick/quicktesttreeitem.cpp2
-rw-r--r--src/plugins/autotest/testcodeparser.cpp2
-rw-r--r--src/plugins/autotest/testconfiguration.cpp45
-rw-r--r--src/plugins/autotest/testconfiguration.h31
-rw-r--r--src/plugins/autotest/testnavigationwidget.cpp20
-rw-r--r--src/plugins/autotest/testnavigationwidget.h2
-rw-r--r--src/plugins/autotest/testresultspane.cpp4
-rw-r--r--src/plugins/autotest/testrunconfiguration.h3
-rw-r--r--src/plugins/autotest/testrunner.cpp58
-rw-r--r--src/plugins/autotest/testrunner.h12
-rw-r--r--src/plugins/autotest/testsettings.cpp3
-rw-r--r--src/plugins/autotest/testsettings.h1
-rw-r--r--src/plugins/autotest/testsettingspage.cpp2
-rw-r--r--src/plugins/autotest/testsettingspage.ui11
-rw-r--r--src/plugins/autotest/testtreeitem.cpp5
-rw-r--r--src/plugins/autotoolsprojectmanager/autogenstep.cpp14
-rw-r--r--src/plugins/autotoolsprojectmanager/autoreconfstep.cpp10
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp2
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsproject.cpp5
-rw-r--r--src/plugins/autotoolsprojectmanager/configurestep.cpp18
-rw-r--r--src/plugins/autotoolsprojectmanager/makefileparser.cpp10
-rw-r--r--src/plugins/autotoolsprojectmanager/makefileparser.h9
-rw-r--r--src/plugins/autotoolsprojectmanager/makefileparserthread.cpp6
-rw-r--r--src/plugins/autotoolsprojectmanager/makefileparserthread.h11
-rw-r--r--src/plugins/autotoolsprojectmanager/makestep.cpp27
-rw-r--r--src/plugins/baremetal/baremetalcustomrunconfiguration.cpp14
-rw-r--r--src/plugins/baremetal/baremetalcustomrunconfiguration.h8
-rw-r--r--src/plugins/baremetal/baremetaldebugsupport.cpp36
-rw-r--r--src/plugins/baremetal/baremetalrunconfiguration.cpp51
-rw-r--r--src/plugins/baremetal/baremetalrunconfiguration.h13
-rw-r--r--src/plugins/baremetal/baremetalrunconfigurationfactory.cpp9
-rw-r--r--src/plugins/baremetal/baremetalrunconfigurationwidget.cpp35
-rw-r--r--src/plugins/baremetal/baremetalrunconfigurationwidget.h3
-rw-r--r--src/plugins/baremetal/images/baremetaldevice.pngbin184 -> 185 bytes
-rw-r--r--src/plugins/baremetal/images/baremetaldevice@2x.pngbin277 -> 280 bytes
-rw-r--r--src/plugins/bazaar/bazaarplugin.cpp6
-rw-r--r--src/plugins/beautifier/beautifierplugin.cpp16
-rw-r--r--src/plugins/beautifier/beautifierplugin.h2
-rw-r--r--src/plugins/beautifier/clangformat/clangformat.cpp63
-rw-r--r--src/plugins/beautifier/clangformat/clangformat.h4
-rw-r--r--src/plugins/beautifier/clangformat/clangformatconstants.h3
-rw-r--r--src/plugins/beautifier/clangformat/clangformatoptionspage.cpp2
-rw-r--r--src/plugins/beautifier/clangformat/clangformatoptionspage.ui36
-rw-r--r--src/plugins/beautifier/clangformat/clangformatsettings.cpp12
-rw-r--r--src/plugins/beautifier/clangformat/clangformatsettings.h3
-rw-r--r--src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp23
-rw-r--r--src/plugins/clangcodemodel/clangassistproposalmodel.h2
-rw-r--r--src/plugins/clangcodemodel/clangbackendipcintegration.cpp85
-rw-r--r--src/plugins/clangcodemodel/clangbackendipcintegration.h22
-rw-r--r--src/plugins/clangcodemodel/clangcodemodel.pro2
-rw-r--r--src/plugins/clangcodemodel/clangcodemodel.qbs4
-rw-r--r--src/plugins/clangcodemodel/clangcodemodel_dependencies.pri2
-rw-r--r--src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp30
-rw-r--r--src/plugins/clangcodemodel/clangcompletionassistprocessor.h9
-rw-r--r--src/plugins/clangcodemodel/clangcompletionchunkstotextconverter.h2
-rw-r--r--src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp32
-rw-r--r--src/plugins/clangcodemodel/clangcompletioncontextanalyzer.h8
-rw-r--r--src/plugins/clangcodemodel/clangdiagnosticfilter.h2
-rw-r--r--src/plugins/clangcodemodel/clangdiagnosticmanager.cpp4
-rw-r--r--src/plugins/clangcodemodel/clangdiagnosticmanager.h2
-rw-r--r--src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h2
-rw-r--r--src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp71
-rw-r--r--src/plugins/clangcodemodel/clangeditordocumentprocessor.h4
-rw-r--r--src/plugins/clangcodemodel/clangfixitoperation.h2
-rw-r--r--src/plugins/clangcodemodel/clangfixitoperationsextractor.h2
-rw-r--r--src/plugins/clangcodemodel/clangfollowsymbol.cpp144
-rw-r--r--src/plugins/clangcodemodel/clangfollowsymbol.h (renamed from src/libs/sqlite/createtablecommand.h)26
-rw-r--r--src/plugins/clangcodemodel/clangfunctionhintmodel.cpp9
-rw-r--r--src/plugins/clangcodemodel/clangfunctionhintmodel.h1
-rw-r--r--src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp9
-rw-r--r--src/plugins/clangcodemodel/clanghighlightingmarksreporter.h2
-rw-r--r--src/plugins/clangcodemodel/clangisdiagnosticrelatedtolocation.h2
-rw-r--r--src/plugins/clangcodemodel/clangmodelmanagersupport.cpp24
-rw-r--r--src/plugins/clangcodemodel/clangmodelmanagersupport.h5
-rw-r--r--src/plugins/clangcodemodel/clangtextmark.h4
-rw-r--r--src/plugins/clangcodemodel/clangutils.cpp43
-rw-r--r--src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp40
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager-source.pri6
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager_dependencies.pri2
-rw-r--r--src/plugins/clangpchmanager/clangpchmanagerplugin.cpp2
-rw-r--r--src/plugins/clangpchmanager/pchmanagerclient.cpp2
-rw-r--r--src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp47
-rw-r--r--src/plugins/clangpchmanager/pchmanagerprojectupdater.h44
-rw-r--r--src/plugins/clangpchmanager/projectupdater.cpp41
-rw-r--r--src/plugins/clangpchmanager/projectupdater.h12
-rw-r--r--src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp39
-rw-r--r--src/plugins/clangpchmanager/qtcreatorprojectupdater.h56
-rw-r--r--src/plugins/clangrefactoring/clangqueryhoverhandler.cpp4
-rw-r--r--src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp27
-rw-r--r--src/plugins/clangrefactoring/clangrefactoring-source.pri6
-rw-r--r--src/plugins/clangrefactoring/clangrefactoring.pro8
-rw-r--r--src/plugins/clangrefactoring/clangrefactoring_dependencies.pri5
-rw-r--r--src/plugins/clangrefactoring/clangrefactoringplugin.cpp7
-rw-r--r--src/plugins/clangrefactoring/querysqlitestatementfactory.h54
-rw-r--r--src/plugins/clangrefactoring/refactoringclient.cpp2
-rw-r--r--src/plugins/clangrefactoring/refactoringengine.cpp29
-rw-r--r--src/plugins/clangrefactoring/refactoringengine.h5
-rw-r--r--src/plugins/clangrefactoring/refactoringprojectupdater.cpp37
-rw-r--r--src/plugins/clangrefactoring/refactoringprojectupdater.h41
-rw-r--r--src/plugins/clangrefactoring/sourcelocations.h65
-rw-r--r--src/plugins/clangrefactoring/symbolquery.cpp30
-rw-r--r--src/plugins/clangrefactoring/symbolquery.h110
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerpreconfiguredsessiontests.cpp2
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp170
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp4
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp2
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp14
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h2
-rw-r--r--src/plugins/clearcase/clearcaseplugin.cpp20
-rw-r--r--src/plugins/clearcase/clearcaseplugin.h1
-rw-r--r--src/plugins/cmakeprojectmanager/builddirmanager.cpp17
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp15
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h3
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp132
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h5
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildstep.cpp79
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildstep.h4
-rw-r--r--src/plugins/cmakeprojectmanager/cmakecbpparser.cpp18
-rw-r--r--src/plugins/cmakeprojectmanager/cmakekitconfigwidget.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/cmakekitinformation.cpp6
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeproject.cpp22
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeproject.h12
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs1
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp10
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp4
-rw-r--r--src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp105
-rw-r--r--src/plugins/cmakeprojectmanager/cmakerunconfiguration.h22
-rw-r--r--src/plugins/cmakeprojectmanager/cmakesettingspage.cpp36
-rw-r--r--src/plugins/cmakeprojectmanager/cmaketool.cpp17
-rw-r--r--src/plugins/cmakeprojectmanager/cmaketool.h3
-rw-r--r--src/plugins/cmakeprojectmanager/configmodel.cpp550
-rw-r--r--src/plugins/cmakeprojectmanager/configmodel.h51
-rw-r--r--src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp128
-rw-r--r--src/plugins/cmakeprojectmanager/configmodelitemdelegate.h20
-rw-r--r--src/plugins/cmakeprojectmanager/servermodereader.cpp135
-rw-r--r--src/plugins/cmakeprojectmanager/servermodereader.h28
-rw-r--r--src/plugins/cmakeprojectmanager/tealeafreader.cpp7
-rw-r--r--src/plugins/coreplugin/actionmanager/commandsfile.cpp7
-rw-r--r--src/plugins/coreplugin/coreconstants.h3
-rw-r--r--src/plugins/coreplugin/corejsextensions.cpp2
-rw-r--r--src/plugins/coreplugin/coreplugin.cpp22
-rw-r--r--src/plugins/coreplugin/documentmanager.cpp206
-rw-r--r--src/plugins/coreplugin/documentmanager.h9
-rw-r--r--src/plugins/coreplugin/editormanager/documentmodel.cpp8
-rw-r--r--src/plugins/coreplugin/editormanager/editormanager.cpp13
-rw-r--r--src/plugins/coreplugin/externaltool.cpp5
-rw-r--r--src/plugins/coreplugin/externaltoolmanager.cpp2
-rw-r--r--src/plugins/coreplugin/fancyactionbar.cpp8
-rw-r--r--src/plugins/coreplugin/fancytabwidget.cpp17
-rw-r--r--src/plugins/coreplugin/fancytabwidget.h3
-rw-r--r--src/plugins/coreplugin/fileiconprovider.cpp13
-rw-r--r--src/plugins/coreplugin/fileiconprovider.h2
-rw-r--r--src/plugins/coreplugin/find/findplugin.cpp5
-rw-r--r--src/plugins/coreplugin/find/findtoolbar.cpp8
-rw-r--r--src/plugins/coreplugin/generalsettings.cpp2
-rw-r--r--src/plugins/coreplugin/icore.cpp5
-rw-r--r--src/plugins/coreplugin/images/mode_Design.pngbin1779 -> 1565 bytes
-rw-r--r--src/plugins/coreplugin/images/mode_Design@2x.pngbin6227 -> 5116 bytes
-rw-r--r--src/plugins/coreplugin/images/mode_Edit.pngbin426 -> 389 bytes
-rw-r--r--src/plugins/coreplugin/images/mode_Edit@2x.pngbin3157 -> 1081 bytes
-rw-r--r--src/plugins/coreplugin/images/mode_design_mask.pngbin223 -> 218 bytes
-rw-r--r--src/plugins/coreplugin/images/mode_design_mask@2x.pngbin369 -> 362 bytes
-rw-r--r--src/plugins/coreplugin/images/mode_edit_mask.pngbin109 -> 110 bytes
-rw-r--r--src/plugins/coreplugin/images/mode_edit_mask@2x.pngbin118 -> 117 bytes
-rw-r--r--src/plugins/coreplugin/iversioncontrol.cpp6
-rw-r--r--src/plugins/coreplugin/iwizardfactory.cpp9
-rw-r--r--src/plugins/coreplugin/jsexpander.cpp2
-rw-r--r--src/plugins/coreplugin/locator/basefilefilter.cpp30
-rw-r--r--src/plugins/coreplugin/locator/ilocatorfilter.cpp20
-rw-r--r--src/plugins/coreplugin/locator/ilocatorfilter.h15
-rw-r--r--src/plugins/coreplugin/locator/locatorwidget.cpp9
-rw-r--r--src/plugins/coreplugin/locator/opendocumentsfilter.cpp19
-rw-r--r--src/plugins/coreplugin/mainwindow.cpp12
-rw-r--r--src/plugins/coreplugin/messagemanager.cpp28
-rw-r--r--src/plugins/coreplugin/messagemanager.h4
-rw-r--r--src/plugins/coreplugin/mimetypemagicdialog.ui2
-rw-r--r--src/plugins/coreplugin/mimetypesettings.cpp3
-rw-r--r--src/plugins/coreplugin/outputwindow.cpp2
-rw-r--r--src/plugins/coreplugin/patchtool.cpp6
-rw-r--r--src/plugins/coreplugin/shellcommand.cpp21
-rw-r--r--src/plugins/coreplugin/systemsettings.cpp6
-rw-r--r--src/plugins/coreplugin/systemsettings.ui13
-rw-r--r--src/plugins/coreplugin/themechooser.cpp2
-rw-r--r--src/plugins/coreplugin/variablechooser.cpp8
-rw-r--r--src/plugins/coreplugin/vcsmanager.cpp103
-rw-r--r--src/plugins/coreplugin/vcsmanager.h17
-rw-r--r--src/plugins/coreplugin/versiondialog.cpp2
-rw-r--r--src/plugins/coreplugin/windowsupport.cpp3
-rw-r--r--src/plugins/cppeditor/cppautocompleter.cpp1
-rw-r--r--src/plugins/cppeditor/cppcodemodelinspectordialog.cpp39
-rw-r--r--src/plugins/cppeditor/cppdoxygen_test.cpp2
-rw-r--r--src/plugins/cppeditor/cppeditor.cpp992
-rw-r--r--src/plugins/cppeditor/cppeditor.h114
-rw-r--r--src/plugins/cppeditor/cppeditor.pro8
-rw-r--r--src/plugins/cppeditor/cppeditor.qbs8
-rw-r--r--src/plugins/cppeditor/cppeditorplugin.cpp2
-rw-r--r--src/plugins/cppeditor/cppeditorplugin.h3
-rw-r--r--src/plugins/cppeditor/cppeditortestcase.cpp1
-rw-r--r--src/plugins/cppeditor/cppeditortestcase.h2
-rw-r--r--src/plugins/cppeditor/cppeditorwidget.cpp1085
-rw-r--r--src/plugins/cppeditor/cppeditorwidget.h151
-rw-r--r--src/plugins/cppeditor/cppfunctiondecldeflink.cpp2
-rw-r--r--src/plugins/cppeditor/cpphoverhandler.cpp6
-rw-r--r--src/plugins/cppeditor/cppincludehierarchy.cpp3
-rw-r--r--src/plugins/cppeditor/cppincludehierarchy_test.cpp2
-rw-r--r--src/plugins/cppeditor/cppoutline.h1
-rw-r--r--src/plugins/cppeditor/cppparsecontext.cpp2
-rw-r--r--src/plugins/cppeditor/cpppreprocessordialog.cpp1
-rw-r--r--src/plugins/cppeditor/cppquickfix_test.cpp2
-rw-r--r--src/plugins/cppeditor/cppquickfixassistant.cpp3
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp50
-rw-r--r--src/plugins/cppeditor/cpptypehierarchy.cpp1
-rw-r--r--src/plugins/cppeditor/cppuseselections_test.cpp1
-rw-r--r--src/plugins/cppeditor/cppuseselectionsupdater.cpp42
-rw-r--r--src/plugins/cppeditor/cppuseselectionsupdater.h7
-rw-r--r--src/plugins/cppeditor/fileandtokenactions_test.cpp1
-rw-r--r--src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp145
-rw-r--r--src/plugins/cpptools/baseeditordocumentprocessor.h2
-rw-r--r--src/plugins/cpptools/builtincursorinfo.cpp6
-rw-r--r--src/plugins/cpptools/builtineditordocumentparser.cpp5
-rw-r--r--src/plugins/cpptools/builtineditordocumentprocessor.cpp4
-rw-r--r--src/plugins/cpptools/builtineditordocumentprocessor.h2
-rw-r--r--src/plugins/cpptools/clangcompileroptionsbuilder.cpp117
-rw-r--r--src/plugins/cpptools/clangcompileroptionsbuilder.h27
-rw-r--r--src/plugins/cpptools/clangdiagnosticconfigswidget.cpp87
-rw-r--r--src/plugins/cpptools/clangdiagnosticconfigswidget.h3
-rw-r--r--src/plugins/cpptools/clangdiagnosticconfigswidget.ui54
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.cpp115
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.h14
-rw-r--r--src/plugins/cpptools/cppcanonicalsymbol.cpp5
-rw-r--r--src/plugins/cpptools/cppcodemodelinspectordumper.cpp24
-rw-r--r--src/plugins/cpptools/cppcodemodelinspectordumper.h1
-rw-r--r--src/plugins/cpptools/cppcodemodelsettingspage.ui4
-rw-r--r--src/plugins/cpptools/cppcompletion_test.cpp5
-rw-r--r--src/plugins/cpptools/cppcompletionassist.cpp12
-rw-r--r--src/plugins/cpptools/cppcurrentdocumentfilter.cpp33
-rw-r--r--src/plugins/cpptools/cppeditorwidgetinterface.h54
-rw-r--r--src/plugins/cpptools/cppfindreferences.cpp17
-rw-r--r--src/plugins/cpptools/cppfollowsymbolundercursor.cpp (renamed from src/plugins/cppeditor/cppfollowsymbolundercursor.cpp)83
-rw-r--r--src/plugins/cpptools/cppfollowsymbolundercursor.h (renamed from src/plugins/cppeditor/cppfollowsymbolundercursor.h)37
-rw-r--r--src/plugins/cpptools/cpplocatorfilter.cpp52
-rw-r--r--src/plugins/cpptools/cpplocatorfilter_test.cpp13
-rw-r--r--src/plugins/cpptools/cppmodelmanager.cpp67
-rw-r--r--src/plugins/cpptools/cppmodelmanager.h8
-rw-r--r--src/plugins/cpptools/cppmodelmanager_test.cpp18
-rw-r--r--src/plugins/cpptools/cppmodelmanagersupport.h2
-rw-r--r--src/plugins/cpptools/cppmodelmanagersupportinternal.cpp13
-rw-r--r--src/plugins/cpptools/cppmodelmanagersupportinternal.h8
-rw-r--r--src/plugins/cpptools/cppprojectinfogenerator.cpp5
-rw-r--r--src/plugins/cpptools/cpprawprojectpart.cpp9
-rw-r--r--src/plugins/cpptools/cpprawprojectpart.h6
-rw-r--r--src/plugins/cpptools/cpprefactoringengine.cpp55
-rw-r--r--src/plugins/cpptools/cpprefactoringengine.h43
-rw-r--r--src/plugins/cpptools/cppselectionchanger.cpp4
-rw-r--r--src/plugins/cpptools/cppsourceprocessor.cpp21
-rw-r--r--src/plugins/cpptools/cppsymbolinfo.h44
-rw-r--r--src/plugins/cpptools/cpptools.pro16
-rw-r--r--src/plugins/cpptools/cpptools.qbs13
-rw-r--r--src/plugins/cpptools/cpptoolsplugin.cpp4
-rw-r--r--src/plugins/cpptools/cpptoolsreuse.cpp4
-rw-r--r--src/plugins/cpptools/cpptoolsunittestfiles.pri4
-rw-r--r--src/plugins/cpptools/cppvirtualfunctionassistprovider.cpp (renamed from src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp)24
-rw-r--r--src/plugins/cpptools/cppvirtualfunctionassistprovider.h (renamed from src/plugins/cppeditor/cppvirtualfunctionassistprovider.h)10
-rw-r--r--src/plugins/cpptools/cppvirtualfunctionproposalitem.cpp (renamed from src/plugins/cppeditor/cppvirtualfunctionproposalitem.cpp)6
-rw-r--r--src/plugins/cpptools/cppvirtualfunctionproposalitem.h (renamed from src/plugins/cppeditor/cppvirtualfunctionproposalitem.h)8
-rw-r--r--src/plugins/cpptools/cursorineditor.h54
-rw-r--r--src/plugins/cpptools/doxygengenerator.cpp9
-rw-r--r--src/plugins/cpptools/followsymbolinterface.h53
-rw-r--r--src/plugins/cpptools/projectinfo.cpp11
-rw-r--r--src/plugins/cpptools/projectinfo.h2
-rw-r--r--src/plugins/cpptools/projectpart.cpp15
-rw-r--r--src/plugins/cpptools/projectpart.h12
-rw-r--r--src/plugins/cpptools/refactoringengineinterface.h23
-rw-r--r--src/plugins/cpptools/wrappablelineedit.cpp59
-rw-r--r--src/plugins/cpptools/wrappablelineedit.h (renamed from src/libs/sqlite/tablewriteworker.h)24
-rw-r--r--src/plugins/cvs/cvsplugin.cpp5
-rw-r--r--src/plugins/cvs/cvssettings.cpp2
-rw-r--r--src/plugins/debugger/breakhandler.cpp2
-rw-r--r--src/plugins/debugger/cdb/cdbengine.cpp21
-rw-r--r--src/plugins/debugger/cdb/cdbengine.h2
-rw-r--r--src/plugins/debugger/cdb/cdboptionspagewidget.ui2
-rw-r--r--src/plugins/debugger/commonoptionspage.cpp17
-rw-r--r--src/plugins/debugger/debugger.pro1
-rw-r--r--src/plugins/debugger/debugger.qbs7
-rw-r--r--src/plugins/debugger/debuggerconstants.h1
-rw-r--r--src/plugins/debugger/debuggerdialogs.cpp81
-rw-r--r--src/plugins/debugger/debuggerdialogs.h4
-rw-r--r--src/plugins/debugger/debuggerengine.cpp106
-rw-r--r--src/plugins/debugger/debuggerengine.h129
-rw-r--r--src/plugins/debugger/debuggerkitinformation.cpp8
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp349
-rw-r--r--src/plugins/debugger/debuggerruncontrol.cpp879
-rw-r--r--src/plugins/debugger/debuggerruncontrol.h85
-rw-r--r--src/plugins/debugger/debuggersourcepathmappingwidget.cpp2
-rw-r--r--src/plugins/debugger/debuggerstartparameters.h112
-rw-r--r--src/plugins/debugger/disassembleragent.cpp1
-rw-r--r--src/plugins/debugger/gdb/attachgdbadapter.cpp125
-rw-r--r--src/plugins/debugger/gdb/coregdbadapter.cpp321
-rw-r--r--src/plugins/debugger/gdb/coregdbadapter.h78
-rw-r--r--src/plugins/debugger/gdb/gdb.pri10
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp1043
-rw-r--r--src/plugins/debugger/gdb/gdbengine.h253
-rw-r--r--src/plugins/debugger/gdb/gdboptionspage.cpp10
-rw-r--r--src/plugins/debugger/gdb/gdbplainengine.cpp148
-rw-r--r--src/plugins/debugger/gdb/gdbplainengine.h57
-rw-r--r--src/plugins/debugger/gdb/remotegdbserveradapter.cpp459
-rw-r--r--src/plugins/debugger/gdb/remotegdbserveradapter.h68
-rw-r--r--src/plugins/debugger/gdb/startgdbserverdialog.cpp20
-rw-r--r--src/plugins/debugger/gdb/termgdbadapter.cpp208
-rw-r--r--src/plugins/debugger/gdb/termgdbadapter.h67
-rw-r--r--src/plugins/debugger/images/debugger_continue.pngbin2812 -> 2601 bytes
-rw-r--r--src/plugins/debugger/images/debugger_continue@2x.pngbin2271 -> 2222 bytes
-rw-r--r--src/plugins/debugger/images/debugger_continue_1_mask.pngbin97 -> 97 bytes
-rw-r--r--src/plugins/debugger/images/debugger_continue_1_mask@2x.pngbin99 -> 101 bytes
-rw-r--r--src/plugins/debugger/images/debugger_continue_2_mask.pngbin147 -> 157 bytes
-rw-r--r--src/plugins/debugger/images/debugger_continue_2_mask@2x.pngbin192 -> 202 bytes
-rw-r--r--src/plugins/debugger/images/debugger_interrupt.pngbin1231 -> 1193 bytes
-rw-r--r--src/plugins/debugger/images/debugger_interrupt@2x.pngbin1442 -> 1402 bytes
-rw-r--r--src/plugins/debugger/images/debugger_interrupt_mask.pngbin98 -> 100 bytes
-rw-r--r--src/plugins/debugger/images/debugger_interrupt_mask@2x.pngbin101 -> 105 bytes
-rw-r--r--src/plugins/debugger/images/mode_debug.pngbin2061 -> 1756 bytes
-rw-r--r--src/plugins/debugger/images/mode_debug@2x.pngbin6535 -> 5524 bytes
-rw-r--r--src/plugins/debugger/images/mode_debug_mask.pngbin285 -> 282 bytes
-rw-r--r--src/plugins/debugger/images/mode_debug_mask@2x.pngbin547 -> 531 bytes
-rw-r--r--src/plugins/debugger/lldb/lldbengine.cpp31
-rw-r--r--src/plugins/debugger/lldb/lldbengine.h2
-rw-r--r--src/plugins/debugger/loadcoredialog.cpp6
-rw-r--r--src/plugins/debugger/logwindow.cpp10
-rw-r--r--src/plugins/debugger/memoryagent.cpp1
-rw-r--r--src/plugins/debugger/moduleshandler.cpp2
-rw-r--r--src/plugins/debugger/pdb/pdbengine.cpp1
-rw-r--r--src/plugins/debugger/qml/qmlcppengine.cpp35
-rw-r--r--src/plugins/debugger/qml/qmlcppengine.h8
-rw-r--r--src/plugins/debugger/qml/qmlengine.cpp150
-rw-r--r--src/plugins/debugger/qml/qmlengine.h6
-rw-r--r--src/plugins/debugger/registerhandler.cpp6
-rw-r--r--src/plugins/debugger/stackhandler.cpp2
-rw-r--r--src/plugins/debugger/watchhandler.cpp19
-rw-r--r--src/plugins/designer/formeditorplugin.cpp2
-rw-r--r--src/plugins/diffeditor/diffeditorwidgetcontroller.cpp2
-rw-r--r--src/plugins/diffeditor/differ.cpp2
-rw-r--r--src/plugins/fakevim/fakevimoptions.ui4
-rw-r--r--src/plugins/genericprojectmanager/genericmakestep.cpp27
-rw-r--r--src/plugins/genericprojectmanager/genericmakestep.h2
-rw-r--r--src/plugins/genericprojectmanager/genericproject.cpp7
-rw-r--r--src/plugins/genericprojectmanager/genericprojectmanager.qbs1
-rw-r--r--src/plugins/genericprojectmanager/genericprojectwizard.cpp4
-rw-r--r--src/plugins/git/gerrit/gerritdialog.cpp2
-rw-r--r--src/plugins/git/gerrit/gerritplugin.cpp2
-rw-r--r--src/plugins/git/gitclient.cpp14
-rw-r--r--src/plugins/git/gitplugin.cpp7
-rw-r--r--src/plugins/git/remotemodel.cpp3
-rw-r--r--src/plugins/help/images/mode_help.pngbin1445 -> 1328 bytes
-rw-r--r--src/plugins/help/images/mode_help@2x.pngbin5215 -> 4348 bytes
-rw-r--r--src/plugins/help/images/mode_help_mask.pngbin316 -> 312 bytes
-rw-r--r--src/plugins/help/images/mode_help_mask@2x.pngbin629 -> 614 bytes
-rw-r--r--src/plugins/imageviewer/imageviewerplugin.cpp16
-rw-r--r--src/plugins/ios/images/iosdevice.pngbin196 -> 196 bytes
-rw-r--r--src/plugins/ios/images/iosdevice@2x.pngbin349 -> 351 bytes
-rw-r--r--src/plugins/ios/iosbuildstep.cpp18
-rw-r--r--src/plugins/ios/iosbuildstep.h5
-rw-r--r--src/plugins/ios/iosdsymbuildstep.cpp10
-rw-r--r--src/plugins/ios/iosrunconfiguration.cpp95
-rw-r--r--src/plugins/ios/iosrunconfiguration.h19
-rw-r--r--src/plugins/ios/iosrunfactories.cpp7
-rw-r--r--src/plugins/ios/iosrunner.cpp34
-rw-r--r--src/plugins/ios/iossettingswidget.cpp2
-rw-r--r--src/plugins/mercurial/mercurialplugin.cpp12
-rw-r--r--src/plugins/modeleditor/actionhandler.cpp40
-rw-r--r--src/plugins/modeleditor/actionhandler.h2
-rw-r--r--src/plugins/modeleditor/classviewcontroller.cpp2
-rw-r--r--src/plugins/modeleditor/classviewcontroller.h2
-rw-r--r--src/plugins/modeleditor/componentviewcontroller.cpp22
-rw-r--r--src/plugins/modeleditor/componentviewcontroller.h2
-rw-r--r--src/plugins/modeleditor/diagramsviewmanager.h2
-rw-r--r--src/plugins/modeleditor/dragtool.h2
-rw-r--r--src/plugins/modeleditor/editordiagramview.cpp4
-rw-r--r--src/plugins/modeleditor/editordiagramview.h2
-rw-r--r--src/plugins/modeleditor/elementtasks.cpp16
-rw-r--r--src/plugins/modeleditor/elementtasks.h2
-rw-r--r--src/plugins/modeleditor/extdocumentcontroller.cpp4
-rw-r--r--src/plugins/modeleditor/extdocumentcontroller.h2
-rw-r--r--src/plugins/modeleditor/extpropertiesmview.cpp4
-rw-r--r--src/plugins/modeleditor/extpropertiesmview.h6
-rw-r--r--src/plugins/modeleditor/jsextension.h2
-rw-r--r--src/plugins/modeleditor/modeldocument.cpp2
-rw-r--r--src/plugins/modeleditor/modeldocument.h2
-rw-r--r--src/plugins/modeleditor/modeleditor.cpp131
-rw-r--r--src/plugins/modeleditor/modeleditor.h2
-rw-r--r--src/plugins/modeleditor/modeleditor_plugin.cpp10
-rw-r--r--src/plugins/modeleditor/modeleditorfactory.cpp4
-rw-r--r--src/plugins/modeleditor/modeleditorfactory.h2
-rw-r--r--src/plugins/modeleditor/modelindexer.cpp40
-rw-r--r--src/plugins/modeleditor/modelindexer.h2
-rw-r--r--src/plugins/modeleditor/modelsmanager.cpp22
-rw-r--r--src/plugins/modeleditor/modelsmanager.h2
-rw-r--r--src/plugins/modeleditor/openelementvisitor.cpp16
-rw-r--r--src/plugins/modeleditor/openelementvisitor.h35
-rw-r--r--src/plugins/modeleditor/pxnodecontroller.cpp36
-rw-r--r--src/plugins/modeleditor/pxnodecontroller.h2
-rw-r--r--src/plugins/modeleditor/pxnodeutilities.cpp18
-rw-r--r--src/plugins/modeleditor/pxnodeutilities.h2
-rw-r--r--src/plugins/modeleditor/settingscontroller.h2
-rw-r--r--src/plugins/modeleditor/uicontroller.h2
-rw-r--r--src/plugins/nim/project/nimcompilerbuildstep.cpp4
-rw-r--r--src/plugins/nim/project/nimproject.cpp3
-rw-r--r--src/plugins/nim/project/nimprojectnode.cpp2
-rw-r--r--src/plugins/nim/project/nimprojectnode.h2
-rw-r--r--src/plugins/nim/project/nimrunconfiguration.cpp8
-rw-r--r--src/plugins/nim/project/nimrunconfiguration.h4
-rw-r--r--src/plugins/nim/project/nimrunconfigurationfactory.cpp8
-rw-r--r--src/plugins/nim/project/nimrunconfigurationwidget.cpp10
-rw-r--r--src/plugins/nim/project/nimrunconfigurationwidget.h4
-rw-r--r--src/plugins/nim/project/nimtoolchain.cpp4
-rw-r--r--src/plugins/nim/project/nimtoolchain.h2
-rw-r--r--src/plugins/perforce/perforceplugin.cpp9
-rw-r--r--src/plugins/perforce/perforceplugin.h1
-rw-r--r--src/plugins/projectexplorer/abi.cpp354
-rw-r--r--src/plugins/projectexplorer/abi.h6
-rw-r--r--src/plugins/projectexplorer/abstractmsvctoolchain.cpp9
-rw-r--r--src/plugins/projectexplorer/abstractmsvctoolchain.h9
-rw-r--r--src/plugins/projectexplorer/appoutputpane.cpp8
-rw-r--r--src/plugins/projectexplorer/baseprojectwizarddialog.cpp3
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.cpp16
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.h3
-rw-r--r--src/plugins/projectexplorer/buildconfigurationmodel.cpp184
-rw-r--r--src/plugins/projectexplorer/buildconfigurationmodel.h58
-rw-r--r--src/plugins/projectexplorer/buildenvironmentwidget.cpp2
-rw-r--r--src/plugins/projectexplorer/buildsettingspropertiespage.cpp4
-rw-r--r--src/plugins/projectexplorer/buildstep.cpp15
-rw-r--r--src/plugins/projectexplorer/buildstep.h6
-rw-r--r--src/plugins/projectexplorer/buildsteplist.cpp16
-rw-r--r--src/plugins/projectexplorer/buildsteplist.h3
-rw-r--r--src/plugins/projectexplorer/compileoutputwindow.cpp13
-rw-r--r--src/plugins/projectexplorer/compileoutputwindow.h2
-rw-r--r--src/plugins/projectexplorer/customexecutablerunconfiguration.cpp38
-rw-r--r--src/plugins/projectexplorer/customexecutablerunconfiguration.h10
-rw-r--r--src/plugins/projectexplorer/customtoolchain.cpp63
-rw-r--r--src/plugins/projectexplorer/customtoolchain.h8
-rw-r--r--src/plugins/projectexplorer/deployconfiguration.cpp16
-rw-r--r--src/plugins/projectexplorer/deployconfiguration.h3
-rw-r--r--src/plugins/projectexplorer/deployconfigurationmodel.cpp184
-rw-r--r--src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp2
-rw-r--r--src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp11
-rw-r--r--src/plugins/projectexplorer/extracompiler.cpp4
-rw-r--r--src/plugins/projectexplorer/foldernavigationwidget.cpp353
-rw-r--r--src/plugins/projectexplorer/foldernavigationwidget.h55
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.cpp194
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.h28
-rw-r--r--src/plugins/projectexplorer/gcctoolchainfactories.h2
-rw-r--r--src/plugins/projectexplorer/images/build.pngbin1239 -> 925 bytes
-rw-r--r--src/plugins/projectexplorer/images/build@2x.pngbin2803 -> 2305 bytes
-rw-r--r--src/plugins/projectexplorer/images/build_hammerhandle_mask.pngbin165 -> 173 bytes
-rw-r--r--src/plugins/projectexplorer/images/build_hammerhandle_mask@2x.pngbin240 -> 258 bytes
-rw-r--r--src/plugins/projectexplorer/images/build_hammerhead_mask.pngbin183 -> 183 bytes
-rw-r--r--src/plugins/projectexplorer/images/build_hammerhead_mask@2x.pngbin228 -> 246 bytes
-rw-r--r--src/plugins/projectexplorer/images/build_small.pngbin475 -> 0 bytes
-rw-r--r--src/plugins/projectexplorer/images/buildhammerhandle.pngbin0 -> 153 bytes
-rw-r--r--src/plugins/projectexplorer/images/buildhammerhandle@2x.pngbin0 -> 184 bytes
-rw-r--r--src/plugins/projectexplorer/images/buildhammerhead.pngbin0 -> 143 bytes
-rw-r--r--src/plugins/projectexplorer/images/buildhammerhead@2x.pngbin0 -> 186 bytes
-rw-r--r--src/plugins/projectexplorer/images/debugger_beetle_mask.pngbin198 -> 207 bytes
-rw-r--r--src/plugins/projectexplorer/images/debugger_beetle_mask@2x.pngbin357 -> 375 bytes
-rw-r--r--src/plugins/projectexplorer/images/debugger_start.pngbin2094 -> 1677 bytes
-rw-r--r--src/plugins/projectexplorer/images/debugger_start@2x.pngbin5121 -> 5095 bytes
-rw-r--r--src/plugins/projectexplorer/images/desktopdevice.pngbin181 -> 187 bytes
-rw-r--r--src/plugins/projectexplorer/images/desktopdevice@2x.pngbin227 -> 233 bytes
-rw-r--r--src/plugins/projectexplorer/images/devicestatusindicator.pngbin158 -> 157 bytes
-rw-r--r--src/plugins/projectexplorer/images/devicestatusindicator@2x.pngbin265 -> 269 bytes
-rw-r--r--src/plugins/projectexplorer/images/mode_project.pngbin1658 -> 870 bytes
-rw-r--r--src/plugins/projectexplorer/images/mode_project@2x.pngbin4227 -> 3256 bytes
-rw-r--r--src/plugins/projectexplorer/images/mode_project_mask.pngbin239 -> 235 bytes
-rw-r--r--src/plugins/projectexplorer/images/mode_project_mask@2x.pngbin410 -> 399 bytes
-rw-r--r--src/plugins/projectexplorer/images/rebuildhammerhandles.pngbin189 -> 168 bytes
-rw-r--r--src/plugins/projectexplorer/images/rebuildhammerhandles@2x.pngbin267 -> 240 bytes
-rw-r--r--src/plugins/projectexplorer/images/rebuildhammerheads.pngbin180 -> 143 bytes
-rw-r--r--src/plugins/projectexplorer/images/rebuildhammerheads@2x.pngbin169 -> 178 bytes
-rw-r--r--src/plugins/projectexplorer/images/run.pngbin1719 -> 1152 bytes
-rw-r--r--src/plugins/projectexplorer/images/run@2x.pngbin3058 -> 2832 bytes
-rw-r--r--src/plugins/projectexplorer/images/run_mask.pngbin177 -> 179 bytes
-rw-r--r--src/plugins/projectexplorer/images/run_mask@2x.pngbin273 -> 291 bytes
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp52
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonprojectpage.cpp3
-rw-r--r--src/plugins/projectexplorer/kit.cpp2
-rw-r--r--src/plugins/projectexplorer/kitinformation.cpp25
-rw-r--r--src/plugins/projectexplorer/localenvironmentaspect.cpp4
-rw-r--r--src/plugins/projectexplorer/miniprojecttargetselector.cpp240
-rw-r--r--src/plugins/projectexplorer/miniprojecttargetselector.h15
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.cpp41
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.h4
-rw-r--r--src/plugins/projectexplorer/project.cpp101
-rw-r--r--src/plugins/projectexplorer/project.h53
-rw-r--r--src/plugins/projectexplorer/projectconfiguration.cpp42
-rw-r--r--src/plugins/projectexplorer/projectconfiguration.h33
-rw-r--r--src/plugins/projectexplorer/projectconfigurationmodel.cpp218
-rw-r--r--src/plugins/projectexplorer/projectconfigurationmodel.h (renamed from src/plugins/projectexplorer/runconfigurationmodel.h)44
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp240
-rw-r--r--src/plugins/projectexplorer/projectexplorer.pro16
-rw-r--r--src/plugins/projectexplorer/projectexplorer.qbs7
-rw-r--r--src/plugins/projectexplorer/projectexplorer.qrc5
-rw-r--r--src/plugins/projectexplorer/projectexplorerconstants.h1
-rw-r--r--src/plugins/projectexplorer/projectexplorericons.cpp8
-rw-r--r--src/plugins/projectexplorer/projectexplorersettings.h6
-rw-r--r--src/plugins/projectexplorer/projectexplorersettingspage.cpp9
-rw-r--r--src/plugins/projectexplorer/projectexplorersettingspage.ui56
-rw-r--r--src/plugins/projectexplorer/projectexplorerunittestfiles.pri12
-rw-r--r--src/plugins/projectexplorer/projectmacro.cpp226
-rw-r--r--src/plugins/projectexplorer/projectmacro.h102
-rw-r--r--src/plugins/projectexplorer/projectmodels.cpp48
-rw-r--r--src/plugins/projectexplorer/projectmodels.h6
-rw-r--r--src/plugins/projectexplorer/projectnodes.cpp22
-rw-r--r--src/plugins/projectexplorer/projectnodes.h27
-rw-r--r--src/plugins/projectexplorer/projecttree.cpp58
-rw-r--r--src/plugins/projectexplorer/projecttree.h13
-rw-r--r--src/plugins/projectexplorer/projecttreewidget.cpp95
-rw-r--r--src/plugins/projectexplorer/runconfiguration.cpp178
-rw-r--r--src/plugins/projectexplorer/runconfiguration.h36
-rw-r--r--src/plugins/projectexplorer/runconfigurationmodel.cpp186
-rw-r--r--src/plugins/projectexplorer/runnables.cpp6
-rw-r--r--src/plugins/projectexplorer/runnables.h1
-rw-r--r--src/plugins/projectexplorer/runsettingspropertiespage.cpp40
-rw-r--r--src/plugins/projectexplorer/runsettingspropertiespage.h4
-rw-r--r--src/plugins/projectexplorer/session.cpp10
-rw-r--r--src/plugins/projectexplorer/sessiondialog.ui3
-rw-r--r--src/plugins/projectexplorer/settingsaccessor.cpp18
-rw-r--r--src/plugins/projectexplorer/subscription.cpp97
-rw-r--r--src/plugins/projectexplorer/subscription.h (renamed from src/plugins/projectexplorer/deployconfigurationmodel.h)52
-rw-r--r--src/plugins/projectexplorer/target.cpp101
-rw-r--r--src/plugins/projectexplorer/target.h61
-rw-r--r--src/plugins/projectexplorer/targetsettingspanel.cpp16
-rw-r--r--src/plugins/projectexplorer/targetsetuppage.cpp2
-rw-r--r--src/plugins/projectexplorer/task.cpp11
-rw-r--r--src/plugins/projectexplorer/toolchain.h5
-rw-r--r--src/plugins/projectexplorer/toolchainmanager.cpp2
-rw-r--r--src/plugins/pythoneditor/pythoneditorplugin.cpp78
-rw-r--r--src/plugins/pythoneditor/pythonhighlighter.cpp36
-rw-r--r--src/plugins/pythoneditor/pythonhighlighter.h3
-rw-r--r--src/plugins/pythoneditor/pythonindenter.cpp29
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp6
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildconfiguration.h4
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildstep.cpp13
-rw-r--r--src/plugins/qbsprojectmanager/qbsinstallstep.cpp2
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodes.cpp54
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodes.h6
-rw-r--r--src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp3
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.cpp36
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.h5
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectimporter.cpp2
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectmanager.qbs1
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp20
-rw-r--r--src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp116
-rw-r--r--src/plugins/qbsprojectmanager/qbsrunconfiguration.h32
-rw-r--r--src/plugins/qmakeandroidsupport/androidpackageinstallationstep.cpp12
-rw-r--r--src/plugins/qmakeandroidsupport/qmakeandroidbuildapkstep.cpp62
-rw-r--r--src/plugins/qmakeandroidsupport/qmakeandroidrunconfiguration.cpp80
-rw-r--r--src/plugins/qmakeandroidsupport/qmakeandroidrunconfiguration.h19
-rw-r--r--src/plugins/qmakeandroidsupport/qmakeandroidrunfactories.cpp19
-rw-r--r--src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp99
-rw-r--r--src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h16
-rw-r--r--src/plugins/qmakeprojectmanager/makestep.cpp54
-rw-r--r--src/plugins/qmakeprojectmanager/profileeditor.cpp60
-rw-r--r--src/plugins/qmakeprojectmanager/qmakekitinformation.cpp5
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodes.cpp8
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodes.h2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp17
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp8
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.cpp38
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.h5
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp11
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs1
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp14
-rw-r--r--src/plugins/qmakeprojectmanager/qmakestep.cpp53
-rw-r--r--src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp10
-rw-r--r--src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp2
-rw-r--r--src/plugins/qmldesigner/components/componentcore/componentcore_constants.h4
-rw-r--r--src/plugins/qmldesigner/components/componentcore/findimplementation.cpp2
-rw-r--r--src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp9
-rw-r--r--src/plugins/qmldesigner/components/componentcore/selectioncontext.h4
-rw-r--r--src/plugins/qmldesigner/components/formeditor/anchorindicatorgraphicsitem.h4
-rw-r--r--src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp36
-rw-r--r--src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.h8
-rw-r--r--src/plugins/qmldesigner/components/navigator/navigator.qrc1
-rw-r--r--src/plugins/qmldesigner/components/navigator/navigatorview.cpp14
-rw-r--r--src/plugins/qmldesigner/components/navigator/warning.pngbin287 -> 0 bytes
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp2
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/images/button2_hovered.pngbin898 -> 0 bytes
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/images/button2_normal.pngbin898 -> 0 bytes
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/images/button2_pressed.pngbin898 -> 0 bytes
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/images/button_hovered.pngbin390 -> 0 bytes
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/images/button_normal.pngbin379 -> 0 bytes
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/images/button_pressed.pngbin1328 -> 0 bytes
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/images/frame.pngbin4826 -> 0 bytes
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/images/gradient.pngbin533 -> 0 bytes
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri2
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditor.qrc12
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp2
-rw-r--r--src/plugins/qmldesigner/components/resources/resources.qrc1
-rw-r--r--src/plugins/qmldesigner/components/resources/templates/Standard/Form.xml10
-rw-r--r--src/plugins/qmldesigner/components/texteditor/texteditorview.cpp4
-rw-r--r--src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp6
-rw-r--r--src/plugins/qmldesigner/components/texteditor/texteditorwidget.h4
-rw-r--r--src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.h2
-rw-r--r--src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.h2
-rw-r--r--src/plugins/qmldesigner/designercore/filemanager/moveobjectbeforeobjectvisitor.h4
-rw-r--r--src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.h4
-rw-r--r--src/plugins/qmldesigner/designercore/include/nodeinstanceview.h1
-rw-r--r--src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp10
-rw-r--r--src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h16
-rw-r--r--src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp7
-rw-r--r--src/plugins/qmldesigner/designercore/model/internalnode_p.h2
-rw-r--r--src/plugins/qmldesigner/designercore/model/modelnode.cpp4
-rw-r--r--src/plugins/qmldesigner/designercore/model/textmodifier.cpp5
-rw-r--r--src/plugins/qmldesigner/designercore/rewritertransaction.h2
-rw-r--r--src/plugins/qmldesigner/openuiqmlfiledialog.cpp2
-rw-r--r--src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionviewwidget.cpp16
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.qbs2
-rw-r--r--src/plugins/qmldesigner/settingspage.cpp5
-rw-r--r--src/plugins/qmldesigner/settingspage.ui4
-rw-r--r--src/plugins/qmldesigner/shortcutmanager.cpp2
-rw-r--r--src/plugins/qmljseditor/qmljseditorplugin.cpp7
-rw-r--r--src/plugins/qmljstools/qmljsfunctionfilter.cpp35
-rw-r--r--src/plugins/qmljstools/qmljsmodelmanager.cpp3
-rw-r--r--src/plugins/qmlprofiler/flamegraphmodel.h5
-rw-r--r--src/plugins/qmlprofiler/flamegraphview.cpp7
-rw-r--r--src/plugins/qmlprofiler/flamegraphview.h1
-rw-r--r--src/plugins/qmlprofiler/inputeventsmodel.cpp2
-rw-r--r--src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml8
-rw-r--r--src/plugins/qmlprofiler/qmlprofiler.qbs4
-rw-r--r--src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp1
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp13
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerclientmanager.h7
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerconfigwidget.h3
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerconfigwidget.ui2
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp58
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.h16
-rw-r--r--src/plugins/qmlprofiler/qmlprofilereventsview.h7
-rw-r--r--src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp29
-rw-r--r--src/plugins/qmlprofiler/qmlprofilermodelmanager.h23
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerplugin.cpp4
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp27
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerstatemanager.h13
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerstatewidget.h3
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h2
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerstatisticsview.h21
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertextmark.cpp22
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertextmark.h10
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertimelinemodel.h7
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertool.cpp23
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertool.h8
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertraceclient.cpp15
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertraceclient.h7
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertracefile.cpp11
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertraceview.cpp4
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertraceview.h1
-rw-r--r--src/plugins/qmlprofiler/qmltypedevent.cpp8
-rw-r--r--src/plugins/qmlprofiler/tests/Test.qml7
-rw-r--r--src/plugins/qmlprofiler/tests/inputeventsmodel_test.cpp18
-rw-r--r--src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp1
-rw-r--r--src/plugins/qmlprofiler/tests/pixmapcachemodel_test.cpp3
-rw-r--r--src/plugins/qmlprofiler/tests/qmlprofileranimationsmodel_test.cpp8
-rw-r--r--src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp83
-rw-r--r--src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.cpp215
-rw-r--r--src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.h (renamed from src/plugins/debugger/gdb/attachgdbadapter.h)34
-rw-r--r--src/plugins/qmlprofiler/tests/tests.pri5
-rw-r--r--src/plugins/qmlprofiler/tests/tests.qrc6
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.cpp5
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectnodes.cpp18
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectnodes.h2
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp95
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h24
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfigurationfactory.cpp6
-rw-r--r--src/plugins/qnx/qnx.pro4
-rw-r--r--src/plugins/qnx/qnx.qbs4
-rw-r--r--src/plugins/qnx/qnxattachdebugdialog.cpp66
-rw-r--r--src/plugins/qnx/qnxattachdebugdialog.h51
-rw-r--r--src/plugins/qnx/qnxattachdebugsupport.cpp171
-rw-r--r--src/plugins/qnx/qnxattachdebugsupport.h81
-rw-r--r--src/plugins/qnx/qnxconstants.h1
-rw-r--r--src/plugins/qnx/qnxdebugsupport.cpp207
-rw-r--r--src/plugins/qnx/qnxdebugsupport.h16
-rw-r--r--src/plugins/qnx/qnxplugin.cpp11
-rw-r--r--src/plugins/qnx/qnxrunconfiguration.cpp13
-rw-r--r--src/plugins/qnx/qnxrunconfiguration.h9
-rw-r--r--src/plugins/qnx/qnxrunconfigurationfactory.cpp7
-rw-r--r--src/plugins/qnx/qnxutils.cpp21
-rw-r--r--src/plugins/qnx/qnxutils.h1
-rw-r--r--src/plugins/qtsupport/gettingstartedwelcomepage.cpp2
-rw-r--r--src/plugins/qtsupport/qtkitinformation.cpp6
-rw-r--r--src/plugins/qtsupport/qtoptionspage.cpp4
-rw-r--r--src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp99
-rw-r--r--src/plugins/remotelinux/abstractremotelinuxrunsupport.h54
-rw-r--r--src/plugins/remotelinux/remotelinux.pro2
-rw-r--r--src/plugins/remotelinux/remotelinux.qbs2
-rw-r--r--src/plugins/remotelinux/remotelinuxanalyzesupport.cpp74
-rw-r--r--src/plugins/remotelinux/remotelinuxanalyzesupport.h31
-rw-r--r--src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp36
-rw-r--r--src/plugins/remotelinux/remotelinuxcustomrunconfiguration.h10
-rw-r--r--src/plugins/remotelinux/remotelinuxdebugsupport.cpp64
-rw-r--r--src/plugins/remotelinux/remotelinuxdebugsupport.h10
-rw-r--r--src/plugins/remotelinux/remotelinuxplugin.cpp1
-rw-r--r--src/plugins/remotelinux/remotelinuxrunconfiguration.cpp69
-rw-r--r--src/plugins/remotelinux/remotelinuxrunconfiguration.h18
-rw-r--r--src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp16
-rw-r--r--src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp34
-rw-r--r--src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h3
-rw-r--r--src/plugins/resourceeditor/qrceditor/resourcefile.cpp4
-rw-r--r--src/plugins/resourceeditor/resourceeditorplugin.cpp26
-rw-r--r--src/plugins/resourceeditor/resourcenode.cpp10
-rw-r--r--src/plugins/resourceeditor/resourcenode.h6
-rw-r--r--src/plugins/scxmleditor/common/stateproperties.cpp2
-rw-r--r--src/plugins/scxmleditor/outputpane/warningmodel.cpp11
-rw-r--r--src/plugins/scxmleditor/plugin_interface/connectableitem.cpp4
-rw-r--r--src/plugins/scxmleditor/plugin_interface/graphicsscene.cpp2
-rw-r--r--src/plugins/scxmleditor/plugin_interface/scattributeitemmodel.cpp3
-rw-r--r--src/plugins/scxmleditor/plugin_interface/transitionitem.cpp2
-rw-r--r--src/plugins/subversion/subversionplugin.cpp5
-rw-r--r--src/plugins/subversion/subversionsettings.cpp4
-rw-r--r--src/plugins/texteditor/behaviorsettingspage.cpp10
-rw-r--r--src/plugins/texteditor/behaviorsettingswidget.ui4
-rw-r--r--src/plugins/texteditor/codeassist/assistinterface.cpp4
-rw-r--r--src/plugins/texteditor/codeassist/codeassistant.cpp29
-rw-r--r--src/plugins/texteditor/codeassist/codeassistant.h3
-rw-r--r--src/plugins/texteditor/codeassist/functionhintproposal.cpp9
-rw-r--r--src/plugins/texteditor/codeassist/functionhintproposal.h1
-rw-r--r--src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp85
-rw-r--r--src/plugins/texteditor/codeassist/functionhintproposalwidget.h3
-rw-r--r--src/plugins/texteditor/codeassist/genericproposal.cpp5
-rw-r--r--src/plugins/texteditor/codeassist/genericproposal.h1
-rw-r--r--src/plugins/texteditor/codeassist/genericproposalmodel.cpp72
-rw-r--r--src/plugins/texteditor/codeassist/genericproposalmodel.h5
-rw-r--r--src/plugins/texteditor/codeassist/iassistproposal.cpp10
-rw-r--r--src/plugins/texteditor/codeassist/iassistproposal.h4
-rw-r--r--src/plugins/texteditor/codeassist/iassistproposalwidget.cpp10
-rw-r--r--src/plugins/texteditor/codeassist/iassistproposalwidget.h6
-rw-r--r--src/plugins/texteditor/codeassist/ifunctionhintproposalmodel.cpp7
-rw-r--r--src/plugins/texteditor/codeassist/ifunctionhintproposalmodel.h3
-rw-r--r--src/plugins/texteditor/codeassist/runner.cpp4
-rw-r--r--src/plugins/texteditor/codeassist/runner.h10
-rw-r--r--src/plugins/texteditor/fontsettingspage.cpp2
-rw-r--r--src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.cpp3
-rw-r--r--src/plugins/texteditor/generichighlighter/highlighter.cpp5
-rw-r--r--src/plugins/texteditor/generichighlighter/specificrules.h13
-rw-r--r--src/plugins/texteditor/helpitem.h2
-rw-r--r--src/plugins/texteditor/linenumberfilter.h2
-rw-r--r--src/plugins/texteditor/outlinefactory.cpp6
-rw-r--r--src/plugins/texteditor/textdocument.cpp4
-rw-r--r--src/plugins/texteditor/texteditor.cpp81
-rw-r--r--src/plugins/texteditor/texteditor.h2
-rw-r--r--src/plugins/texteditor/texteditor.pro2
-rw-r--r--src/plugins/texteditor/texteditor.qbs2
-rw-r--r--src/plugins/texteditor/texteditor_test.cpp8
-rw-r--r--src/plugins/texteditor/texteditoractionhandler.cpp166
-rw-r--r--src/plugins/texteditor/texteditorconstants.h1
-rw-r--r--src/plugins/texteditor/textmark.cpp2
-rw-r--r--src/plugins/texteditor/textmark.h4
-rw-r--r--src/plugins/todo/todoitemsprovider.cpp2
-rw-r--r--src/plugins/todo/todoplugin.cpp2
-rw-r--r--src/plugins/updateinfo/settingspage.cpp2
-rw-r--r--src/plugins/updateinfo/settingspage.ui2
-rw-r--r--src/plugins/valgrind/memcheckengine.cpp186
-rw-r--r--src/plugins/valgrind/memcheckengine.h69
-rw-r--r--src/plugins/valgrind/memchecktool.cpp252
-rw-r--r--src/plugins/valgrind/valgrind.pro2
-rw-r--r--src/plugins/valgrind/valgrind.qbs2
-rw-r--r--src/plugins/valgrind/valgrindengine.cpp2
-rw-r--r--src/plugins/vcsbase/basevcseditorfactory.cpp4
-rw-r--r--src/plugins/vcsbase/commonsettingspage.cpp2
-rw-r--r--src/plugins/vcsbase/vcsbaseclientsettings.cpp6
-rw-r--r--src/plugins/vcsbase/vcsbaseeditor.cpp2
-rw-r--r--src/plugins/vcsbase/vcsbaseplugin.cpp15
-rw-r--r--src/plugins/vcsbase/vcsbaseplugin.h18
-rw-r--r--src/plugins/vcsbase/vcsprojectcache.cpp4
-rw-r--r--src/plugins/welcome/images/mode_edit_mask.pngbin189 -> 0 bytes
-rw-r--r--src/plugins/welcome/images/mode_welcome.pngbin1243 -> 1100 bytes
-rw-r--r--src/plugins/welcome/images/mode_welcome@2x.pngbin2282 -> 2271 bytes
-rw-r--r--src/plugins/welcome/images/mode_welcome_mask.pngbin100 -> 101 bytes
-rw-r--r--src/plugins/welcome/images/mode_welcome_mask@2x.pngbin106 -> 107 bytes
-rw-r--r--src/plugins/welcome/welcome.qbs1
-rw-r--r--src/plugins/welcome/welcome.qrc1
-rw-r--r--src/plugins/welcome/welcomeplugin.cpp7
-rw-r--r--src/plugins/winrt/images/winrtdevice.pngbin163 -> 164 bytes
-rw-r--r--src/plugins/winrt/images/winrtdevice@2x.pngbin235 -> 239 bytes
-rw-r--r--src/plugins/winrt/winrt.qbs1
-rw-r--r--src/plugins/winrt/winrtdebugsupport.cpp39
-rw-r--r--src/plugins/winrt/winrtdebugsupport.h2
-rw-r--r--src/plugins/winrt/winrtrunconfiguration.cpp14
-rw-r--r--src/plugins/winrt/winrtrunconfiguration.h8
-rw-r--r--src/plugins/winrt/winrtrunfactories.cpp6
-rw-r--r--src/shared/clang/clang_installation.pri8
-rw-r--r--src/shared/help/bookmarkmanager.cpp6
-rw-r--r--src/tools/clangbackend/clangbackend.pro2
-rw-r--r--src/tools/clangbackend/clangbackend.qbs2
-rw-r--r--src/tools/clangbackend/ipcsource/clangasyncjob.h4
-rw-r--r--src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri9
-rw-r--r--src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp45
-rw-r--r--src/tools/clangbackend/ipcsource/clangcodemodelserver.h8
-rw-r--r--src/tools/clangbackend/ipcsource/clangcompletecodejob.cpp60
-rw-r--r--src/tools/clangbackend/ipcsource/clangcompletecodejob.h10
-rw-r--r--src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.cpp34
-rw-r--r--src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.h9
-rw-r--r--src/tools/clangbackend/ipcsource/clangdocumentjob.h64
-rw-r--r--src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.cpp2
-rw-r--r--src/tools/clangbackend/ipcsource/clangfollowsymbol.cpp337
-rw-r--r--src/tools/clangbackend/ipcsource/clangfollowsymbol.h52
-rw-r--r--src/tools/clangbackend/ipcsource/clangfollowsymboljob.cpp73
-rw-r--r--src/tools/clangbackend/ipcsource/clangfollowsymboljob.h42
-rw-r--r--src/tools/clangbackend/ipcsource/clangiasyncjob.cpp36
-rw-r--r--src/tools/clangbackend/ipcsource/clangiasyncjob.h2
-rw-r--r--src/tools/clangbackend/ipcsource/clangjobqueue.cpp20
-rw-r--r--src/tools/clangbackend/ipcsource/clangjobrequest.cpp159
-rw-r--r--src/tools/clangbackend/ipcsource/clangjobrequest.h27
-rw-r--r--src/tools/clangbackend/ipcsource/clangjobs.cpp37
-rw-r--r--src/tools/clangbackend/ipcsource/clangjobs.h3
-rw-r--r--src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.cpp43
-rw-r--r--src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.h17
-rw-r--r--src/tools/clangbackend/ipcsource/clangreferencescollector.cpp2
-rw-r--r--src/tools/clangbackend/ipcsource/clangreferencescollector.h2
-rw-r--r--src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.cpp46
-rw-r--r--src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.h9
-rw-r--r--src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.cpp65
-rw-r--r--src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.h18
-rw-r--r--src/tools/clangbackend/ipcsource/clangrequestreferencesjob.cpp40
-rw-r--r--src/tools/clangbackend/ipcsource/clangrequestreferencesjob.h11
-rw-r--r--src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.cpp30
-rw-r--r--src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.h9
-rw-r--r--src/tools/clangbackend/ipcsource/clangtranslationunit.cpp20
-rw-r--r--src/tools/clangbackend/ipcsource/clangtranslationunit.h14
-rw-r--r--src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp85
-rw-r--r--src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h22
-rw-r--r--src/tools/clangbackend/ipcsource/codecompleter.cpp71
-rw-r--r--src/tools/clangbackend/ipcsource/codecompleter.h8
-rw-r--r--src/tools/clangbackend/ipcsource/codecompletionsextractor.cpp6
-rw-r--r--src/tools/clangbackend/ipcsource/codecompletionsextractor.h2
-rw-r--r--src/tools/clangbackend/ipcsource/cursor.cpp5
-rw-r--r--src/tools/clangbackend/ipcsource/cursor.h1
-rw-r--r--src/tools/clangbackend/ipcsource/diagnostic.h2
-rw-r--r--src/tools/clangbackend/ipcsource/highlightingmark.cpp8
-rw-r--r--src/tools/clangbackend/ipcsource/highlightingmark.h4
-rw-r--r--src/tools/clangbackend/ipcsource/highlightingmarks.cpp9
-rw-r--r--src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro2
-rw-r--r--src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp4
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpathwatcher.h46
-rw-r--r--src/tools/clangpchmanagerbackend/source/collectincludesaction.h16
-rw-r--r--src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h20
-rw-r--r--src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h16
-rw-r--r--src/tools/clangpchmanagerbackend/source/idpaths.h4
-rw-r--r--src/tools/clangpchmanagerbackend/source/includecollector.cpp4
-rw-r--r--src/tools/clangpchmanagerbackend/source/includecollector.h8
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.cpp32
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.h12
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchgenerator.h4
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp2
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.h10
-rw-r--r--src/tools/clangrefactoringbackend/clangrefactoringbackend.pro2
-rw-r--r--src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp13
-rw-r--r--src/tools/clangrefactoringbackend/source/clangquery.cpp2
-rw-r--r--src/tools/clangrefactoringbackend/source/clangquery.h4
-rw-r--r--src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp12
-rw-r--r--src/tools/clangrefactoringbackend/source/clangquerygatherer.h6
-rw-r--r--src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri28
-rw-r--r--src/tools/clangrefactoringbackend/source/clangtool.cpp26
-rw-r--r--src/tools/clangrefactoringbackend/source/clangtool.h15
-rw-r--r--src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp35
-rw-r--r--src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h38
-rw-r--r--src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp39
-rw-r--r--src/tools/clangrefactoringbackend/source/collectsymbolsaction.h73
-rw-r--r--src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h158
-rw-r--r--src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h74
-rw-r--r--src/tools/clangrefactoringbackend/source/findcursorusr.h38
-rw-r--r--src/tools/clangrefactoringbackend/source/findusrforcursoraction.cpp63
-rw-r--r--src/tools/clangrefactoringbackend/source/findusrforcursoraction.h32
-rw-r--r--src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h14
-rw-r--r--src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.h4
-rw-r--r--src/tools/clangrefactoringbackend/source/refactoringserver.cpp34
-rw-r--r--src/tools/clangrefactoringbackend/source/refactoringserver.h13
-rw-r--r--src/tools/clangrefactoringbackend/source/sourcelocationentry.cpp42
-rw-r--r--src/tools/clangrefactoringbackend/source/sourcelocationentry.h92
-rw-r--r--src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp4
-rw-r--r--src/tools/clangrefactoringbackend/source/sourcerangeextractor.h6
-rw-r--r--src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h142
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolentry.cpp41
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolentry.h62
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolfinder.h16
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexer.cpp50
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexer.h50
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexing.cpp30
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexing.h87
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexinginterface.h40
-rw-r--r--src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp16
-rw-r--r--src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h24
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollector.cpp63
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollector.h57
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h54
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolstorage.cpp30
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolstorage.h158
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolstorageinterface.h40
-rw-r--r--src/tools/icons/qtcreatoricons.svg1100
-rw-r--r--src/tools/qml2puppet/qml2puppet/qml2puppet.pro3
-rw-r--r--src/tools/qtcrashhandler/qtcrashhandler.pro7
-rw-r--r--src/tools/sdktool/addcmakeoperation.cpp2
-rw-r--r--src/tools/sdktool/adddebuggeroperation.cpp2
-rw-r--r--src/tools/sdktool/adddeviceoperation.cpp2
-rw-r--r--src/tools/sdktool/addkeysoperation.cpp2
-rw-r--r--src/tools/sdktool/addkitoperation.cpp2
-rw-r--r--src/tools/sdktool/addqtoperation.cpp2
-rw-r--r--src/tools/sdktool/addtoolchainoperation.cpp2
-rw-r--r--src/tools/sdktool/findkeyoperation.cpp2
-rw-r--r--src/tools/sdktool/findvalueoperation.cpp2
-rw-r--r--src/tools/sdktool/getoperation.cpp2
-rw-r--r--src/tools/sdktool/main.cpp6
-rw-r--r--src/tools/sdktool/rmcmakeoperation.cpp2
-rw-r--r--src/tools/sdktool/rmdebuggeroperation.cpp2
-rw-r--r--src/tools/sdktool/rmdeviceoperation.cpp2
-rw-r--r--src/tools/sdktool/rmkeysoperation.cpp2
-rw-r--r--src/tools/sdktool/rmkitoperation.cpp2
-rw-r--r--src/tools/sdktool/rmqtoperation.cpp2
-rw-r--r--src/tools/sdktool/rmtoolchainoperation.cpp2
-rw-r--r--src/tools/tools.pro3
1524 files changed, 27175 insertions, 17583 deletions
diff --git a/src/app/app.pro b/src/app/app.pro
index da162cce810..37a999fd8da 100644
--- a/src/app/app.pro
+++ b/src/app/app.pro
@@ -12,13 +12,10 @@ HEADERS += ../tools/qtcreatorcrashhandler/crashhandlersetup.h
SOURCES += main.cpp ../tools/qtcreatorcrashhandler/crashhandlersetup.cpp
include(../rpath.pri)
+include(../libs/qt-breakpad/qtbreakpad.pri)
LIBS *= -l$$qtLibraryName(ExtensionSystem) -l$$qtLibraryName(Aggregation) -l$$qtLibraryName(Utils)
-QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
-!isEmpty(QT_BREAKPAD_ROOT_PATH) {
- include($$QT_BREAKPAD_ROOT_PATH/qtbreakpad.pri)
-}
win32 {
# We need the version in two separate formats for the .rc file
# RC_VERSION=4,3,82,0 (quadruple)
diff --git a/src/app/app_version.h.in b/src/app/app_version.h.in
index 97fd0735a4c..2c31ce0e16f 100644
--- a/src/app/app_version.h.in
+++ b/src/app/app_version.h.in
@@ -31,6 +31,10 @@ namespace Constants {
#define STRINGIFY_INTERNAL(x) #x
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
+const char IDE_DISPLAY_NAME[] = \"Qt Creator\";
+const char IDE_ID[] = \"qtcreator\";
+const char IDE_CASED_ID[] = \"QtCreator\";
+
#define IDE_VERSION $${QTCREATOR_VERSION}
#define IDE_VERSION_STR STRINGIFY(IDE_VERSION)
#define IDE_VERSION_DISPLAY_DEF $${QTCREATOR_DISPLAY_VERSION}
diff --git a/src/app/main.cpp b/src/app/main.cpp
index c1ae3245fb0..7235796e3fd 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -66,7 +66,6 @@ using namespace ExtensionSystem;
enum { OptionIndent = 4, DescriptionIndent = 34 };
-const char appNameC[] = "Qt Creator";
const char corePluginNameC[] = "Core";
const char fixedOptionsC[] =
" [OPTION]... [FILE]...\n"
@@ -110,7 +109,7 @@ static inline QString toHtml(const QString &t)
static void displayHelpText(const QString &t)
{
if (Utils::HostOsInfo::isWindowsHost())
- QMessageBox::information(0, QLatin1String(appNameC), toHtml(t));
+ QMessageBox::information(0, QLatin1String(Core::Constants::IDE_DISPLAY_NAME), toHtml(t));
else
qWarning("%s", qPrintable(t));
}
@@ -118,7 +117,7 @@ static void displayHelpText(const QString &t)
static void displayError(const QString &t)
{
if (Utils::HostOsInfo::isWindowsHost())
- QMessageBox::critical(0, QLatin1String(appNameC), t);
+ QMessageBox::critical(0, QLatin1String(Core::Constants::IDE_DISPLAY_NAME), t);
else
qCritical("%s", qPrintable(t));
}
@@ -127,7 +126,7 @@ static void printVersion(const PluginSpec *coreplugin)
{
QString version;
QTextStream str(&version);
- str << '\n' << appNameC << ' ' << coreplugin->version()<< " based on Qt " << qVersion() << "\n\n";
+ str << '\n' << Core::Constants::IDE_DISPLAY_NAME << ' ' << coreplugin->version()<< " based on Qt " << qVersion() << "\n\n";
PluginManager::formatPluginVersions(str);
str << '\n' << coreplugin->copyright() << '\n';
displayHelpText(version);
@@ -211,7 +210,9 @@ static inline QStringList getPluginPaths()
pluginPath += QLatin1Char('/')
+ QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR)
+ QLatin1Char('/');
- pluginPath += QLatin1String(Utils::HostOsInfo::isMacHost() ? "Qt Creator" : "qtcreator");
+ pluginPath += QLatin1String(Utils::HostOsInfo::isMacHost() ?
+ Core::Constants::IDE_DISPLAY_NAME :
+ Core::Constants::IDE_ID);
pluginPath += QLatin1String("/plugins/");
pluginPath += QLatin1String(Core::Constants::IDE_VERSION_LONG);
rc.push_back(pluginPath);
@@ -228,7 +229,7 @@ static void setupInstallSettings()
QCoreApplication::applicationDirPath() + '/' + RELATIVE_DATA_PATH);
QSettings installSettings(QSettings::IniFormat, QSettings::UserScope,
QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR),
- QLatin1String("QtCreator"));
+ QLatin1String(Core::Constants::IDE_CASED_ID));
if (installSettings.contains(kInstallSettingsKey)) {
QString installSettingsPath = installSettings.value(kInstallSettingsKey).toString();
if (QDir::isRelativePath(installSettingsPath))
@@ -241,7 +242,7 @@ static QSettings *createUserSettings()
{
return new QSettings(QSettings::IniFormat, QSettings::UserScope,
QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR),
- QLatin1String("QtCreator"));
+ QLatin1String(Core::Constants::IDE_CASED_ID));
}
static inline QSettings *userSettings()
@@ -276,9 +277,9 @@ static inline QSettings *userSettings()
|| lowerFile.startsWith(QLatin1String("qtversion.xml"))
|| lowerFile.startsWith(QLatin1String("devices.xml"))
|| lowerFile.startsWith(QLatin1String("debuggers.xml"))
- || lowerFile.startsWith(QLatin1String("qtcreator.")))
+ || lowerFile.startsWith(QLatin1String(Core::Constants::IDE_ID) + "."))
QFile::copy(srcDir.absoluteFilePath(file), destDir.absoluteFilePath(file));
- if (file == QLatin1String("qtcreator"))
+ if (file == QLatin1String(Core::Constants::IDE_ID))
copyRecursively(srcDir.absoluteFilePath(file), destDir.absoluteFilePath(file));
}
@@ -300,7 +301,7 @@ int main(int argc, char **argv)
if (Utils::HostOsInfo::isLinuxHost())
QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar);
- Utils::TemporaryDirectory::setMasterTemporaryDirectory(QDir::tempPath() + "/QtCreator-XXXXXX");
+ Utils::TemporaryDirectory::setMasterTemporaryDirectory(QDir::tempPath() + "/" + Core::Constants::IDE_CASED_ID + "-XXXXXX");
setHighDpiEnvironmentVariable();
@@ -316,7 +317,7 @@ int main(int argc, char **argv)
#endif
SharedTools::QtSingleApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
- SharedTools::QtSingleApplication app((QLatin1String(appNameC)), argc, argv);
+ SharedTools::QtSingleApplication app((QLatin1String(Core::Constants::IDE_DISPLAY_NAME)), argc, argv);
loadFonts();
@@ -329,13 +330,14 @@ int main(int argc, char **argv)
const int threadCount = QThreadPool::globalInstance()->maxThreadCount();
QThreadPool::globalInstance()->setMaxThreadCount(qMax(4, 2 * threadCount));
- // Display a backtrace once a serious signal is delivered (Linux only).
const QString libexecPath = QCoreApplication::applicationDirPath()
+ '/' + RELATIVE_LIBEXEC_PATH;
- CrashHandlerSetup setupCrashHandler(appNameC, CrashHandlerSetup::EnableRestart, libexecPath);
-
#ifdef ENABLE_QT_BREAKPAD
- QtSystemExceptionHandler systemExceptionHandler;
+ QtSystemExceptionHandler systemExceptionHandler(libexecPath);
+#else
+ // Display a backtrace once a serious signal is delivered (Linux only).
+ CrashHandlerSetup setupCrashHandler(Core::Constants::IDE_DISPLAY_NAME,
+ CrashHandlerSetup::EnableRestart, libexecPath);
#endif
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
@@ -384,7 +386,7 @@ int main(int argc, char **argv)
QSettings *globalSettings = new QSettings(QSettings::IniFormat, QSettings::SystemScope,
QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR),
- QLatin1String("QtCreator"));
+ QLatin1String(Core::Constants::IDE_CASED_ID));
PluginManager pluginManager;
PluginManager::setPluginIID(QLatin1String("org.qt-project.Qt.QtCreatorPlugin"));
PluginManager::setGlobalSettings(globalSettings);
@@ -401,7 +403,7 @@ int main(int argc, char **argv)
+ '/' + RELATIVE_DATA_PATH + "/translations";
foreach (QString locale, uiLanguages) {
locale = QLocale(locale).name();
- if (translator.load(QLatin1String("qtcreator_") + locale, creatorTrPath)) {
+ if (translator.load(QString::fromLatin1(Core::Constants::IDE_ID) + "_" + locale, creatorTrPath)) {
const QString &qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
const QString &qtTrFile = QLatin1String("qt_") + locale;
// Binary installer puts Qt tr files into creatorTrPath
diff --git a/src/libs/3rdparty/cplusplus/Symbols.cpp b/src/libs/3rdparty/cplusplus/Symbols.cpp
index fe0148b23b4..4952469fba4 100644
--- a/src/libs/3rdparty/cplusplus/Symbols.cpp
+++ b/src/libs/3rdparty/cplusplus/Symbols.cpp
@@ -341,8 +341,22 @@ bool Function::isSignatureEqualTo(const Function *other, Matcher *matcher) const
for (unsigned i = 0; i < argc; ++i) {
Symbol *l = argumentAt(i);
Symbol *r = other->argumentAt(i);
- if (! l->type().match(r->type(), matcher))
+ if (! l->type().match(r->type(), matcher)) {
+ if (!l->type()->isReferenceType() && !l->type()->isPointerType()
+ && !l->type()->isPointerToMemberType()
+ && !r->type()->isReferenceType() && !r->type()->isPointerType()
+ && !r->type()->isPointerToMemberType()) {
+ FullySpecifiedType lType = l->type();
+ FullySpecifiedType rType = r->type();
+ lType.setConst(false);
+ lType.setVolatile(false);
+ rType.setConst(false);
+ rType.setVolatile(false);
+ if (lType.match(rType))
+ continue;
+ }
return false;
+ }
}
return true;
}
diff --git a/src/libs/clangbackendipc/clangbackendipc_dependencies.pri b/src/libs/clangbackendipc/clangbackendipc_dependencies.pri
deleted file mode 100644
index 3b52d130c3f..00000000000
--- a/src/libs/clangbackendipc/clangbackendipc_dependencies.pri
+++ /dev/null
@@ -1,3 +0,0 @@
-QTC_LIB_NAME = Clangbackendipc
-QTC_LIB_DEPENDS += sqlite utils
-INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/clangbackendipc
diff --git a/src/libs/clangbackendipc/stringcache.h b/src/libs/clangbackendipc/stringcache.h
deleted file mode 100644
index 7b4230b5770..00000000000
--- a/src/libs/clangbackendipc/stringcache.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <utils/smallstringview.h>
-
-#include <algorithm>
-#include <mutex>
-#include <vector>
-
-namespace ClangBackEnd {
-
-class NonLockingMutex
-{
-public:
- constexpr NonLockingMutex() noexcept {}
- NonLockingMutex(const NonLockingMutex&) = delete;
- NonLockingMutex& operator=(const NonLockingMutex&) = delete;
- void lock() {}
- void unlock() {}
-};
-
-template <typename StringType,
- typename Mutex = NonLockingMutex>
-class StringCache
-{
- class StringCacheEntry
- {
- public:
- StringCacheEntry(StringType &&string, uint id)
- : string(std::move(string)),
- id(id)
- {}
-
- friend bool operator<(const StringCacheEntry &entry, Utils::SmallStringView stringView)
- {
- return entry.string < stringView;
- }
-
- friend bool operator<(Utils::SmallStringView stringView, const StringCacheEntry &entry)
- {
- return stringView < entry.string;
- }
-
- StringType string;
- uint id;
- };
-
- using StringCacheEntries = std::vector<StringCacheEntry>;
- using const_iterator = typename StringCacheEntries::const_iterator;
-
- class Found
- {
- public:
- typename StringCacheEntries::const_iterator iterator;
- bool wasFound;
- };
-
-
-public:
- StringCache()
- {
- m_strings.reserve(1024);
- m_indices.reserve(1024);
- }
-
- uint stringId(Utils::SmallStringView stringView)
- {
- std::lock_guard<Mutex> lock(m_mutex);
-
- Found found = find(stringView);
-
- if (!found.wasFound)
- return insertString(found.iterator, stringView);
-
- return found.iterator->id;
- }
-
- std::vector<uint> stringIds(const std::vector<StringType> &strings)
- {
- std::lock_guard<Mutex> lock(m_mutex);
-
- std::vector<uint> ids;
- ids.reserve(strings.size());
-
- std::transform(strings.begin(),
- strings.end(),
- std::back_inserter(ids),
- [&] (const StringType &string) { return stringId(string); });
-
- return ids;
- }
-
- const StringType &string(uint id) const
- {
- std::lock_guard<Mutex> lock(m_mutex);
-
- return m_strings.at(m_indices.at(id)).string;
- }
-
- std::vector<StringType> strings(const std::vector<uint> &ids) const
- {
- std::lock_guard<Mutex> lock(m_mutex);
-
- std::vector<StringType> strings;
- strings.reserve(ids.size());
-
- std::transform(ids.begin(),
- ids.end(),
- std::back_inserter(strings),
- [&] (uint id) { return m_strings.at(m_indices.at(id)).string; });
-
- return strings;
- }
-
-private:
- Found find(Utils::SmallStringView stringView)
- {
- auto range = std::equal_range(m_strings.cbegin(), m_strings.cend(), stringView);
-
- return {range.first, range.first != range.second};
- }
-
- void incrementLargerOrEqualIndicesByOne(uint newIndex)
- {
- std::transform(m_indices.begin(),
- m_indices.end(),
- m_indices.begin(),
- [&] (uint index) {
- return index >= newIndex ? ++index : index;
- });
- }
-
- uint insertString(const_iterator beforeIterator,
- Utils::SmallStringView stringView)
- {
- auto id = uint(m_strings.size());
-
- auto inserted = m_strings.emplace(beforeIterator, StringType(stringView), id);
-
- auto newIndex = uint(std::distance(m_strings.begin(), inserted));
-
- incrementLargerOrEqualIndicesByOne(newIndex);
-
- m_indices.push_back(newIndex);
-
- return id;
- }
-
-private:
- StringCacheEntries m_strings;
- std::vector<uint> m_indices;
- mutable Mutex m_mutex;
-};
-
-} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/cancelmessage.cpp b/src/libs/clangsupport/cancelmessage.cpp
index ca5adf0ab40..ca5adf0ab40 100644
--- a/src/libs/clangbackendipc/cancelmessage.cpp
+++ b/src/libs/clangsupport/cancelmessage.cpp
diff --git a/src/libs/clangbackendipc/cancelmessage.h b/src/libs/clangsupport/cancelmessage.h
index c8924faec6b..151799c3ab4 100644
--- a/src/libs/clangbackendipc/cancelmessage.h
+++ b/src/libs/clangsupport/cancelmessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
namespace ClangBackEnd {
diff --git a/src/libs/clangbackendipc/clangcodemodelclientinterface.cpp b/src/libs/clangsupport/clangcodemodelclientinterface.cpp
index 6fa2b25d476..77bd1a589ea 100644
--- a/src/libs/clangbackendipc/clangcodemodelclientinterface.cpp
+++ b/src/libs/clangsupport/clangcodemodelclientinterface.cpp
@@ -56,6 +56,9 @@ void ClangCodeModelClientInterface::dispatch(const MessageEnvelop &messageEnvelo
case MessageType::ReferencesMessage:
references(messageEnvelop.message<ReferencesMessage>());
break;
+ case MessageType::FollowSymbolMessage:
+ followSymbol(messageEnvelop.message<FollowSymbolMessage>());
+ break;
default:
qWarning() << "Unknown ClangCodeModelClientMessage";
}
diff --git a/src/libs/clangbackendipc/clangcodemodelclientinterface.h b/src/libs/clangsupport/clangcodemodelclientinterface.h
index d526b98228f..04682ff4830 100644
--- a/src/libs/clangbackendipc/clangcodemodelclientinterface.h
+++ b/src/libs/clangsupport/clangcodemodelclientinterface.h
@@ -37,11 +37,13 @@ class DocumentAnnotationsChangedMessage;
class EchoMessage;
class ProjectPartsDoNotExistMessage;
class ReferencesMessage;
+class FollowSymbolMessage;
class RegisterProjectPartsForEditorMessage;
class RegisterTranslationUnitForEditorMessage;
class RegisterUnsavedFilesForEditorMessage;
class RequestDocumentAnnotationsMessage;
class RequestReferencesMessage;
+class RequestFollowSymbolMessage;
class TranslationUnitDoesNotExistMessage;
class UnregisterProjectPartsForEditorMessage;
class UnregisterTranslationUnitsForEditorMessage;
@@ -61,6 +63,7 @@ public:
virtual void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) = 0;
virtual void documentAnnotationsChanged(const DocumentAnnotationsChangedMessage &message) = 0;
virtual void references(const ReferencesMessage &message) = 0;
+ virtual void followSymbol(const FollowSymbolMessage &message) = 0;
};
} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/clangcodemodelclientmessages.h b/src/libs/clangsupport/clangcodemodelclientmessages.h
index 9f75d6a9ff2..99f9a41c054 100644
--- a/src/libs/clangbackendipc/clangcodemodelclientmessages.h
+++ b/src/libs/clangsupport/clangcodemodelclientmessages.h
@@ -31,4 +31,5 @@
#include "documentannotationschangedmessage.h"
#include "projectpartsdonotexistmessage.h"
#include "referencesmessage.h"
+#include "followsymbolmessage.h"
#include "translationunitdoesnotexistmessage.h"
diff --git a/src/libs/clangbackendipc/clangcodemodelclientproxy.cpp b/src/libs/clangsupport/clangcodemodelclientproxy.cpp
index f9786092bb9..b9ec51cac96 100644
--- a/src/libs/clangbackendipc/clangcodemodelclientproxy.cpp
+++ b/src/libs/clangsupport/clangcodemodelclientproxy.cpp
@@ -100,6 +100,11 @@ void ClangCodeModelClientProxy::references(const ReferencesMessage &message)
m_writeMessageBlock.write(message);
}
+void ClangCodeModelClientProxy::followSymbol(const FollowSymbolMessage &message)
+{
+ m_writeMessageBlock.write(message);
+}
+
void ClangCodeModelClientProxy::readMessages()
{
for (const MessageEnvelop &message : m_readMessageBlock.readAll())
diff --git a/src/libs/clangbackendipc/clangcodemodelclientproxy.h b/src/libs/clangsupport/clangcodemodelclientproxy.h
index 689f9684768..a86321888de 100644
--- a/src/libs/clangbackendipc/clangcodemodelclientproxy.h
+++ b/src/libs/clangsupport/clangcodemodelclientproxy.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "clangcodemodelclientinterface.h"
#include "readmessageblock.h"
#include "writemessageblock.h"
@@ -58,6 +58,7 @@ public:
void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) override;
void documentAnnotationsChanged(const DocumentAnnotationsChangedMessage &message) override;
void references(const ReferencesMessage &message) override;
+ void followSymbol(const FollowSymbolMessage &message) override;
void readMessages();
diff --git a/src/libs/clangbackendipc/clangcodemodelconnectionclient.cpp b/src/libs/clangsupport/clangcodemodelconnectionclient.cpp
index 254f650f227..254f650f227 100644
--- a/src/libs/clangbackendipc/clangcodemodelconnectionclient.cpp
+++ b/src/libs/clangsupport/clangcodemodelconnectionclient.cpp
diff --git a/src/libs/clangbackendipc/clangcodemodelconnectionclient.h b/src/libs/clangsupport/clangcodemodelconnectionclient.h
index 4069d654bdf..4069d654bdf 100644
--- a/src/libs/clangbackendipc/clangcodemodelconnectionclient.h
+++ b/src/libs/clangsupport/clangcodemodelconnectionclient.h
diff --git a/src/libs/clangbackendipc/clangcodemodelserverinterface.cpp b/src/libs/clangsupport/clangcodemodelserverinterface.cpp
index 67090e2c54b..bdaa802a47e 100644
--- a/src/libs/clangbackendipc/clangcodemodelserverinterface.cpp
+++ b/src/libs/clangsupport/clangcodemodelserverinterface.cpp
@@ -68,6 +68,9 @@ void ClangCodeModelServerInterface::dispatch(const MessageEnvelop &messageEnvelo
case MessageType::RequestReferencesMessage:
requestReferences(messageEnvelop.message<RequestReferencesMessage>());
break;
+ case MessageType::RequestFollowSymbolMessage:
+ requestFollowSymbol(messageEnvelop.message<RequestFollowSymbolMessage>());
+ break;
case MessageType::UpdateVisibleTranslationUnitsMessage:
updateVisibleTranslationUnits(messageEnvelop.message<UpdateVisibleTranslationUnitsMessage>());
break;
diff --git a/src/libs/clangbackendipc/clangcodemodelserverinterface.h b/src/libs/clangsupport/clangcodemodelserverinterface.h
index e25b9ef66b5..e5b2956eddf 100644
--- a/src/libs/clangbackendipc/clangcodemodelserverinterface.h
+++ b/src/libs/clangsupport/clangcodemodelserverinterface.h
@@ -33,7 +33,7 @@ namespace ClangBackEnd {
class ClangCodeModelClientInterface;
-class CMBIPC_EXPORT ClangCodeModelServerInterface : public IpcServerInterface<ClangCodeModelClientInterface>
+class CMBIPC_EXPORT ClangCodeModelServerInterface : public IpcServerInterface
{
public:
void dispatch(const MessageEnvelop &messageEnvelop) override;
@@ -49,6 +49,7 @@ public:
virtual void completeCode(const CompleteCodeMessage &message) = 0;
virtual void requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &message) = 0;
virtual void requestReferences(const RequestReferencesMessage &message) = 0;
+ virtual void requestFollowSymbol(const RequestFollowSymbolMessage &message) = 0;
virtual void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) = 0;
};
diff --git a/src/libs/clangbackendipc/clangcodemodelservermessages.h b/src/libs/clangsupport/clangcodemodelservermessages.h
index 8d8cb037b7a..b1ba7a07016 100644
--- a/src/libs/clangbackendipc/clangcodemodelservermessages.h
+++ b/src/libs/clangsupport/clangcodemodelservermessages.h
@@ -35,6 +35,7 @@
#include "registerunsavedfilesforeditormessage.h"
#include "requestdocumentannotations.h"
#include "requestreferencesmessage.h"
+#include "requestfollowsymbolmessage.h"
#include "unregisterunsavedfilesforeditormessage.h"
#include "updatetranslationunitsforeditormessage.h"
#include "updatevisibletranslationunitsmessage.h"
diff --git a/src/libs/clangbackendipc/clangcodemodelserverproxy.cpp b/src/libs/clangsupport/clangcodemodelserverproxy.cpp
index 9b6a2141608..a5b6411e752 100644
--- a/src/libs/clangbackendipc/clangcodemodelserverproxy.cpp
+++ b/src/libs/clangsupport/clangcodemodelserverproxy.cpp
@@ -110,6 +110,11 @@ void ClangCodeModelServerProxy::requestReferences(const RequestReferencesMessage
m_writeMessageBlock.write(message);
}
+void ClangCodeModelServerProxy::requestFollowSymbol(const RequestFollowSymbolMessage &message)
+{
+ m_writeMessageBlock.write(message);
+}
+
void ClangCodeModelServerProxy::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
{
m_writeMessageBlock.write(message);
diff --git a/src/libs/clangbackendipc/clangcodemodelserverproxy.h b/src/libs/clangsupport/clangcodemodelserverproxy.h
index a854225ffc0..c43c9cd01d6 100644
--- a/src/libs/clangbackendipc/clangcodemodelserverproxy.h
+++ b/src/libs/clangsupport/clangcodemodelserverproxy.h
@@ -60,6 +60,7 @@ public:
void completeCode(const CompleteCodeMessage &message) override;
void requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &message) override;
void requestReferences(const RequestReferencesMessage &message) override;
+ void requestFollowSymbol(const RequestFollowSymbolMessage &message) override;
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
void readMessages();
diff --git a/src/libs/clangbackendipc/clangrefactoringclientmessages.h b/src/libs/clangsupport/clangrefactoringclientmessages.h
index 7b90453540a..7b90453540a 100644
--- a/src/libs/clangbackendipc/clangrefactoringclientmessages.h
+++ b/src/libs/clangsupport/clangrefactoringclientmessages.h
diff --git a/src/libs/clangbackendipc/clangrefactoringmessages.h b/src/libs/clangsupport/clangrefactoringmessages.h
index 7f6f0de69ea..7f6f0de69ea 100644
--- a/src/libs/clangbackendipc/clangrefactoringmessages.h
+++ b/src/libs/clangsupport/clangrefactoringmessages.h
diff --git a/src/libs/clangbackendipc/clangrefactoringservermessages.h b/src/libs/clangsupport/clangrefactoringservermessages.h
index 797b3d58ef7..2be6f0d54d0 100644
--- a/src/libs/clangbackendipc/clangrefactoringservermessages.h
+++ b/src/libs/clangsupport/clangrefactoringservermessages.h
@@ -30,3 +30,5 @@
#include "requestsourcelocationforrenamingmessage.h"
#include "requestsourcerangesanddiagnosticsforquerymessage.h"
#include "requestsourcerangesforquerymessage.h"
+#include "updatepchprojectpartsmessage.h"
+#include "removepchprojectpartsmessage.h"
diff --git a/src/libs/clangbackendipc/clangbackendipc-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri
index 3f3758772de..6c7d00b7d87 100644
--- a/src/libs/clangbackendipc/clangbackendipc-lib.pri
+++ b/src/libs/clangsupport/clangsupport-lib.pri
@@ -1,7 +1,7 @@
shared {
- DEFINES += CLANGBACKENDIPC_BUILD_LIB
+ DEFINES += CLANGSUPPORT_BUILD_LIB
} else {
- DEFINES += CLANGBACKENDIPC_BUILD_STATIC_LIB
+ DEFINES += CLANGSUPPORT_BUILD_STATIC_LIB
}
QT += network
@@ -10,7 +10,7 @@ INCLUDEPATH += $$PWD
SOURCES += \
$$PWD/cancelmessage.cpp \
- $$PWD/clangbackendipcdebugutils.cpp \
+ $$PWD/clangsupportdebugutils.cpp \
$$PWD/clangcodemodelclientinterface.cpp \
$$PWD/clangcodemodelclientproxy.cpp \
$$PWD/clangcodemodelconnectionclient.cpp \
@@ -38,6 +38,7 @@ SOURCES += \
$$PWD/filecontainerv2.cpp \
$$PWD/filepath.cpp \
$$PWD/fixitcontainer.cpp \
+ $$PWD/followsymbolmessage.cpp \
$$PWD/highlightingmarkcontainer.cpp \
$$PWD/ipcclientinterface.cpp \
$$PWD/ipcinterface.cpp \
@@ -62,6 +63,7 @@ SOURCES += \
$$PWD/registerunsavedfilesforeditormessage.cpp \
$$PWD/removepchprojectpartsmessage.cpp \
$$PWD/requestdocumentannotations.cpp \
+ $$PWD/requestfollowsymbolmessage.cpp \
$$PWD/requestreferencesmessage.cpp \
$$PWD/requestsourcelocationforrenamingmessage.cpp \
$$PWD/requestsourcerangesanddiagnosticsforquerymessage.cpp \
@@ -82,12 +84,12 @@ SOURCES += \
$$PWD/updatepchprojectpartsmessage.cpp \
$$PWD/updatetranslationunitsforeditormessage.cpp \
$$PWD/updatevisibletranslationunitsmessage.cpp \
- $$PWD/writemessageblock.cpp \
+ $$PWD/writemessageblock.cpp
HEADERS += \
$$PWD/cancelmessage.h \
- $$PWD/clangbackendipcdebugutils.h \
- $$PWD/clangbackendipc_global.h \
+ $$PWD/clangsupportdebugutils.h \
+ $$PWD/clangsupport_global.h \
$$PWD/clangcodemodelclientinterface.h \
$$PWD/clangcodemodelclientmessages.h \
$$PWD/clangcodemodelclientproxy.h \
@@ -121,6 +123,7 @@ HEADERS += \
$$PWD/filecontainerv2.h \
$$PWD/filepath.h \
$$PWD/fixitcontainer.h \
+ $$PWD/followsymbolmessage.h \
$$PWD/highlightingmarkcontainer.h \
$$PWD/ipcclientinterface.h \
$$PWD/ipcinterface.h \
@@ -145,6 +148,7 @@ HEADERS += \
$$PWD/registerunsavedfilesforeditormessage.h \
$$PWD/removepchprojectpartsmessage.h \
$$PWD/requestdocumentannotations.h \
+ $$PWD/requestfollowsymbolmessage.h \
$$PWD/requestreferencesmessage.h \
$$PWD/requestsourcelocationforrenamingmessage.h \
$$PWD/requestsourcerangesanddiagnosticsforquerymessage.h \
@@ -167,5 +171,11 @@ HEADERS += \
$$PWD/updatetranslationunitsforeditormessage.h \
$$PWD/updatevisibletranslationunitsmessage.h \
$$PWD/writemessageblock.h \
+ $$PWD/ipcclientprovider.h \
+ $$PWD/requestsourcerangesforquerymessage.h \
+ $$PWD/stringcachefwd.h \
+ $$PWD/stringcachealgorithms.h \
+ $$PWD/projectmanagementserverinterface.h \
+ $$PWD/refactoringdatabaseinitializer.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
diff --git a/src/libs/clangbackendipc/clangbackendipc.pro b/src/libs/clangsupport/clangsupport.pro
index e5997d06881..fa614e74ff6 100644
--- a/src/libs/clangbackendipc/clangbackendipc.pro
+++ b/src/libs/clangsupport/clangsupport.pro
@@ -1,2 +1,2 @@
include(../../qtcreatorlibrary.pri)
-include(clangbackendipc-lib.pri)
+include(clangsupport-lib.pri)
diff --git a/src/libs/clangbackendipc/clangbackendipc.qbs b/src/libs/clangsupport/clangsupport.qbs
index afa80a5e2b4..6b76f784aff 100644
--- a/src/libs/clangbackendipc/clangbackendipc.qbs
+++ b/src/libs/clangsupport/clangsupport.qbs
@@ -1,14 +1,14 @@
import qbs 1.0
QtcLibrary {
- name: "ClangBackEndIpc"
+ name: "ClangSupport"
targetName: "Clangbackendipc"
Depends { name: "Qt.network" }
Depends { name: "Sqlite" }
Depends { name: "Utils" }
- cpp.defines: base.concat("CLANGBACKENDIPC_BUILD_LIB")
+ cpp.defines: base.concat("CLANGSUPPORT_BUILD_LIB")
cpp.includePaths: base.concat(".")
Group {
diff --git a/src/libs/clangsupport/clangsupport_dependencies.pri b/src/libs/clangsupport/clangsupport_dependencies.pri
new file mode 100644
index 00000000000..74afbf09a8a
--- /dev/null
+++ b/src/libs/clangsupport/clangsupport_dependencies.pri
@@ -0,0 +1,3 @@
+QTC_LIB_NAME = Clangsupport
+QTC_LIB_DEPENDS += sqlite utils
+INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/clangsupport
diff --git a/src/libs/clangbackendipc/clangbackendipc_global.h b/src/libs/clangsupport/clangsupport_global.h
index e48a05e7d99..18e15f52ea6 100644
--- a/src/libs/clangbackendipc/clangbackendipc_global.h
+++ b/src/libs/clangsupport/clangsupport_global.h
@@ -35,9 +35,9 @@
#include <gtest/gtest.h>
#endif
-#if defined(CLANGBACKENDIPC_BUILD_LIB)
+#if defined(CLANGSUPPORT_BUILD_LIB)
# define CMBIPC_EXPORT Q_DECL_EXPORT
-#elif defined(CLANGBACKENDIPC_BUILD_STATIC_LIB)
+#elif defined(CLANGSUPPORT_BUILD_STATIC_LIB)
# define CMBIPC_EXPORT
#else
# define CMBIPC_EXPORT Q_DECL_IMPORT
@@ -116,6 +116,9 @@ enum class MessageType : quint8 {
RequestReferencesMessage,
ReferencesMessage,
+ RequestFollowSymbolMessage,
+ FollowSymbolMessage,
+
UpdateVisibleTranslationUnitsMessage,
CompleteCodeMessage,
diff --git a/src/libs/clangbackendipc/clangbackendipcdebugutils.cpp b/src/libs/clangsupport/clangsupportdebugutils.cpp
index 8c0f83e10be..c62ad0bbc1f 100644
--- a/src/libs/clangbackendipc/clangbackendipcdebugutils.cpp
+++ b/src/libs/clangsupport/clangsupportdebugutils.cpp
@@ -23,7 +23,7 @@
**
****************************************************************************/
-#include "clangbackendipcdebugutils.h"
+#include "clangsupportdebugutils.h"
#include "filecontainer.h"
@@ -43,7 +43,7 @@ class DebugInspectionDir : public QTemporaryDir
{
public:
DebugInspectionDir()
- : QTemporaryDir(QDir::tempPath() + QLatin1String("/qtc-clangbackendipc-XXXXXX"))
+ : QTemporaryDir(QDir::tempPath() + QLatin1String("/qtc-clangsupport-XXXXXX"))
{
setAutoRemove(false); // Keep around for later inspection.
}
diff --git a/src/libs/clangbackendipc/clangbackendipcdebugutils.h b/src/libs/clangsupport/clangsupportdebugutils.h
index 7f766c45d51..52352bb315d 100644
--- a/src/libs/clangbackendipc/clangbackendipcdebugutils.h
+++ b/src/libs/clangsupport/clangsupportdebugutils.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <QElapsedTimer>
diff --git a/src/libs/clangbackendipc/cmbalivemessage.cpp b/src/libs/clangsupport/cmbalivemessage.cpp
index d0ec78d6326..d0ec78d6326 100644
--- a/src/libs/clangbackendipc/cmbalivemessage.cpp
+++ b/src/libs/clangsupport/cmbalivemessage.cpp
diff --git a/src/libs/clangbackendipc/cmbalivemessage.h b/src/libs/clangsupport/cmbalivemessage.h
index 435423a2f09..6093b4b86bf 100644
--- a/src/libs/clangbackendipc/cmbalivemessage.h
+++ b/src/libs/clangsupport/cmbalivemessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <QDataStream>
diff --git a/src/libs/clangbackendipc/cmbcodecompletedmessage.cpp b/src/libs/clangsupport/cmbcodecompletedmessage.cpp
index e5667fd04eb..e5667fd04eb 100644
--- a/src/libs/clangbackendipc/cmbcodecompletedmessage.cpp
+++ b/src/libs/clangsupport/cmbcodecompletedmessage.cpp
diff --git a/src/libs/clangbackendipc/cmbcodecompletedmessage.h b/src/libs/clangsupport/cmbcodecompletedmessage.h
index 1bcac526ca5..1bcac526ca5 100644
--- a/src/libs/clangbackendipc/cmbcodecompletedmessage.h
+++ b/src/libs/clangsupport/cmbcodecompletedmessage.h
diff --git a/src/libs/clangbackendipc/cmbcompletecodemessage.cpp b/src/libs/clangsupport/cmbcompletecodemessage.cpp
index 3bc968e76d4..561391b3d5a 100644
--- a/src/libs/clangbackendipc/cmbcompletecodemessage.cpp
+++ b/src/libs/clangsupport/cmbcompletecodemessage.cpp
@@ -42,6 +42,8 @@ QDebug operator<<(QDebug debug, const CompleteCodeMessage &message)
debug.nospace() << message.m_column << ", ";
debug.nospace() << message.m_projectPartId << ", ";
debug.nospace() << message.m_ticketNumber;
+ debug.nospace() << message.m_funcNameStartLine << ", ";
+ debug.nospace() << message.m_funcNameStartColumn << ", ";
debug.nospace() << ")";
@@ -55,7 +57,9 @@ std::ostream &operator<<(std::ostream &os, const CompleteCodeMessage &message)
<< message.m_line << ", "
<< message.m_column << ", "
<< message.m_projectPartId.constData() << ", "
- << message.m_ticketNumber
+ << message.m_ticketNumber << ", "
+ << message.m_funcNameStartLine << ", "
+ << message.m_funcNameStartColumn
<< ")";
diff --git a/src/libs/clangbackendipc/cmbcompletecodemessage.h b/src/libs/clangsupport/cmbcompletecodemessage.h
index 1c37a6538b1..423d711d456 100644
--- a/src/libs/clangbackendipc/cmbcompletecodemessage.h
+++ b/src/libs/clangsupport/cmbcompletecodemessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <utf8string.h>
@@ -41,12 +41,16 @@ public:
CompleteCodeMessage(const Utf8String &filePath,
quint32 line,
quint32 column,
- const Utf8String &projectPartId)
+ const Utf8String &projectPartId,
+ qint32 funcNameStartLine = -1,
+ qint32 funcNameStartColumn = -1)
: m_filePath(filePath),
m_projectPartId(projectPartId),
m_ticketNumber(++ticketCounter),
m_line(line),
- m_column(column)
+ m_column(column),
+ m_funcNameStartLine(funcNameStartLine),
+ m_funcNameStartColumn(funcNameStartColumn)
{
}
@@ -75,6 +79,16 @@ public:
return m_ticketNumber;
}
+ qint32 funcNameStartLine() const
+ {
+ return m_funcNameStartLine;
+ }
+
+ qint32 funcNameStartColumn() const
+ {
+ return m_funcNameStartColumn;
+ }
+
friend QDataStream &operator<<(QDataStream &out, const CompleteCodeMessage &message)
{
out << message.m_filePath;
@@ -82,6 +96,8 @@ public:
out << message.m_ticketNumber;
out << message.m_line;
out << message.m_column;
+ out << message.m_funcNameStartLine;
+ out << message.m_funcNameStartColumn;
return out;
}
@@ -93,6 +109,8 @@ public:
in >> message.m_ticketNumber;
in >> message.m_line;
in >> message.m_column;
+ in >> message.m_funcNameStartLine;
+ in >> message.m_funcNameStartColumn;
return in;
}
@@ -103,7 +121,9 @@ public:
&& first.m_filePath == second.m_filePath
&& first.m_projectPartId == second.m_projectPartId
&& first.m_line == second.m_line
- && first.m_column == second.m_column;
+ && first.m_column == second.m_column
+ && first.m_funcNameStartLine == second.m_funcNameStartLine
+ && first.m_funcNameStartColumn == second.m_funcNameStartColumn;
}
friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const CompleteCodeMessage &message);
@@ -116,6 +136,8 @@ private:
quint64 m_ticketNumber = 0;
quint32 m_line = 0;
quint32 m_column = 0;
+ qint32 m_funcNameStartLine = -1;
+ qint32 m_funcNameStartColumn = -1;
};
DECLARE_MESSAGE(CompleteCodeMessage);
diff --git a/src/libs/clangbackendipc/cmbechomessage.cpp b/src/libs/clangsupport/cmbechomessage.cpp
index 734eb0d1033..734eb0d1033 100644
--- a/src/libs/clangbackendipc/cmbechomessage.cpp
+++ b/src/libs/clangsupport/cmbechomessage.cpp
diff --git a/src/libs/clangbackendipc/cmbechomessage.h b/src/libs/clangsupport/cmbechomessage.h
index 098d75f2403..7e75a35e3a6 100644
--- a/src/libs/clangbackendipc/cmbechomessage.h
+++ b/src/libs/clangsupport/cmbechomessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "messageenvelop.h"
diff --git a/src/libs/clangbackendipc/cmbendmessage.cpp b/src/libs/clangsupport/cmbendmessage.cpp
index d4535f45fac..d4535f45fac 100644
--- a/src/libs/clangbackendipc/cmbendmessage.cpp
+++ b/src/libs/clangsupport/cmbendmessage.cpp
diff --git a/src/libs/clangbackendipc/cmbendmessage.h b/src/libs/clangsupport/cmbendmessage.h
index 684e5b7a7d2..40db9ef51fc 100644
--- a/src/libs/clangbackendipc/cmbendmessage.h
+++ b/src/libs/clangsupport/cmbendmessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <QDataStream>
diff --git a/src/libs/clangbackendipc/cmbregisterprojectsforeditormessage.cpp b/src/libs/clangsupport/cmbregisterprojectsforeditormessage.cpp
index c18cf089802..c18cf089802 100644
--- a/src/libs/clangbackendipc/cmbregisterprojectsforeditormessage.cpp
+++ b/src/libs/clangsupport/cmbregisterprojectsforeditormessage.cpp
diff --git a/src/libs/clangbackendipc/cmbregisterprojectsforeditormessage.h b/src/libs/clangsupport/cmbregisterprojectsforeditormessage.h
index 10880735f7a..10880735f7a 100644
--- a/src/libs/clangbackendipc/cmbregisterprojectsforeditormessage.h
+++ b/src/libs/clangsupport/cmbregisterprojectsforeditormessage.h
diff --git a/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.cpp b/src/libs/clangsupport/cmbregistertranslationunitsforeditormessage.cpp
index 3b3d3e5e288..3b3d3e5e288 100644
--- a/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.cpp
+++ b/src/libs/clangsupport/cmbregistertranslationunitsforeditormessage.cpp
diff --git a/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.h b/src/libs/clangsupport/cmbregistertranslationunitsforeditormessage.h
index 85afdf63f9f..85afdf63f9f 100644
--- a/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.h
+++ b/src/libs/clangsupport/cmbregistertranslationunitsforeditormessage.h
diff --git a/src/libs/clangbackendipc/cmbunregisterprojectsforeditormessage.cpp b/src/libs/clangsupport/cmbunregisterprojectsforeditormessage.cpp
index e5099269700..e5099269700 100644
--- a/src/libs/clangbackendipc/cmbunregisterprojectsforeditormessage.cpp
+++ b/src/libs/clangsupport/cmbunregisterprojectsforeditormessage.cpp
diff --git a/src/libs/clangbackendipc/cmbunregisterprojectsforeditormessage.h b/src/libs/clangsupport/cmbunregisterprojectsforeditormessage.h
index 355e85217db..8f1e02f2fe5 100644
--- a/src/libs/clangbackendipc/cmbunregisterprojectsforeditormessage.h
+++ b/src/libs/clangsupport/cmbunregisterprojectsforeditormessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <utf8stringvector.h>
diff --git a/src/libs/clangbackendipc/cmbunregistertranslationunitsforeditormessage.cpp b/src/libs/clangsupport/cmbunregistertranslationunitsforeditormessage.cpp
index c547b94b2fc..c547b94b2fc 100644
--- a/src/libs/clangbackendipc/cmbunregistertranslationunitsforeditormessage.cpp
+++ b/src/libs/clangsupport/cmbunregistertranslationunitsforeditormessage.cpp
diff --git a/src/libs/clangbackendipc/cmbunregistertranslationunitsforeditormessage.h b/src/libs/clangsupport/cmbunregistertranslationunitsforeditormessage.h
index ea9df17d286..aa6bf47edd3 100644
--- a/src/libs/clangbackendipc/cmbunregistertranslationunitsforeditormessage.h
+++ b/src/libs/clangsupport/cmbunregistertranslationunitsforeditormessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "filecontainer.h"
diff --git a/src/libs/clangbackendipc/codecompletion.cpp b/src/libs/clangsupport/codecompletion.cpp
index 07b2daac0ff..07b2daac0ff 100644
--- a/src/libs/clangbackendipc/codecompletion.cpp
+++ b/src/libs/clangsupport/codecompletion.cpp
diff --git a/src/libs/clangbackendipc/codecompletion.h b/src/libs/clangsupport/codecompletion.h
index bd63115da09..78303c1c33f 100644
--- a/src/libs/clangbackendipc/codecompletion.h
+++ b/src/libs/clangsupport/codecompletion.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "codecompletionchunk.h"
#include <utf8string.h>
diff --git a/src/libs/clangbackendipc/codecompletionchunk.cpp b/src/libs/clangsupport/codecompletionchunk.cpp
index 60a0fee2c4b..60a0fee2c4b 100644
--- a/src/libs/clangbackendipc/codecompletionchunk.cpp
+++ b/src/libs/clangsupport/codecompletionchunk.cpp
diff --git a/src/libs/clangbackendipc/codecompletionchunk.h b/src/libs/clangsupport/codecompletionchunk.h
index 8ba1032c8e9..57d351afde5 100644
--- a/src/libs/clangbackendipc/codecompletionchunk.h
+++ b/src/libs/clangsupport/codecompletionchunk.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <utf8string.h>
diff --git a/src/libs/clangbackendipc/connectionclient.cpp b/src/libs/clangsupport/connectionclient.cpp
index c0a0fa5de54..e53fac18102 100644
--- a/src/libs/clangbackendipc/connectionclient.cpp
+++ b/src/libs/clangsupport/connectionclient.cpp
@@ -25,7 +25,7 @@
#include "connectionclient.h"
-#include "clangbackendipcdebugutils.h"
+#include "clangsupportdebugutils.h"
#include <QCoreApplication>
#include <QMetaMethod>
diff --git a/src/libs/clangbackendipc/connectionclient.h b/src/libs/clangsupport/connectionclient.h
index d8c6692b569..d8c6692b569 100644
--- a/src/libs/clangbackendipc/connectionclient.h
+++ b/src/libs/clangsupport/connectionclient.h
diff --git a/src/libs/clangbackendipc/connectionserver.cpp b/src/libs/clangsupport/connectionserver.cpp
index 6828041de81..6828041de81 100644
--- a/src/libs/clangbackendipc/connectionserver.cpp
+++ b/src/libs/clangsupport/connectionserver.cpp
diff --git a/src/libs/clangbackendipc/connectionserver.h b/src/libs/clangsupport/connectionserver.h
index 021ffac0f95..268c3776a43 100644
--- a/src/libs/clangbackendipc/connectionserver.h
+++ b/src/libs/clangsupport/connectionserver.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <QCoreApplication>
#include <QLocalServer>
diff --git a/src/libs/clangbackendipc/diagnosticcontainer.cpp b/src/libs/clangsupport/diagnosticcontainer.cpp
index b73114d6d0b..b73114d6d0b 100644
--- a/src/libs/clangbackendipc/diagnosticcontainer.cpp
+++ b/src/libs/clangsupport/diagnosticcontainer.cpp
diff --git a/src/libs/clangbackendipc/diagnosticcontainer.h b/src/libs/clangsupport/diagnosticcontainer.h
index 56f45abee3a..56f45abee3a 100644
--- a/src/libs/clangbackendipc/diagnosticcontainer.h
+++ b/src/libs/clangsupport/diagnosticcontainer.h
diff --git a/src/libs/clangbackendipc/documentannotationschangedmessage.cpp b/src/libs/clangsupport/documentannotationschangedmessage.cpp
index a9fef59e4ac..a9fef59e4ac 100644
--- a/src/libs/clangbackendipc/documentannotationschangedmessage.cpp
+++ b/src/libs/clangsupport/documentannotationschangedmessage.cpp
diff --git a/src/libs/clangbackendipc/documentannotationschangedmessage.h b/src/libs/clangsupport/documentannotationschangedmessage.h
index 75b9350cd3a..63fbdcd902e 100644
--- a/src/libs/clangbackendipc/documentannotationschangedmessage.h
+++ b/src/libs/clangsupport/documentannotationschangedmessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "diagnosticcontainer.h"
#include "filecontainer.h"
#include "highlightingmarkcontainer.h"
diff --git a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontainer.cpp b/src/libs/clangsupport/dynamicastmatcherdiagnosticcontainer.cpp
index a7e367609a4..a7e367609a4 100644
--- a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontainer.cpp
+++ b/src/libs/clangsupport/dynamicastmatcherdiagnosticcontainer.cpp
diff --git a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontainer.h b/src/libs/clangsupport/dynamicastmatcherdiagnosticcontainer.h
index 09149ea35dd..09149ea35dd 100644
--- a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontainer.h
+++ b/src/libs/clangsupport/dynamicastmatcherdiagnosticcontainer.h
diff --git a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontextcontainer.cpp b/src/libs/clangsupport/dynamicastmatcherdiagnosticcontextcontainer.cpp
index 37ce0667063..37ce0667063 100644
--- a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontextcontainer.cpp
+++ b/src/libs/clangsupport/dynamicastmatcherdiagnosticcontextcontainer.cpp
diff --git a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontextcontainer.h b/src/libs/clangsupport/dynamicastmatcherdiagnosticcontextcontainer.h
index c220aa23777..c220aa23777 100644
--- a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontextcontainer.h
+++ b/src/libs/clangsupport/dynamicastmatcherdiagnosticcontextcontainer.h
diff --git a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticmessagecontainer.cpp b/src/libs/clangsupport/dynamicastmatcherdiagnosticmessagecontainer.cpp
index e17ecd4da90..e17ecd4da90 100644
--- a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticmessagecontainer.cpp
+++ b/src/libs/clangsupport/dynamicastmatcherdiagnosticmessagecontainer.cpp
diff --git a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticmessagecontainer.h b/src/libs/clangsupport/dynamicastmatcherdiagnosticmessagecontainer.h
index 07a21af605f..07a21af605f 100644
--- a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticmessagecontainer.h
+++ b/src/libs/clangsupport/dynamicastmatcherdiagnosticmessagecontainer.h
diff --git a/src/libs/clangbackendipc/dynamicmatcherdiagnostics.h b/src/libs/clangsupport/dynamicmatcherdiagnostics.h
index 52bcbcb8e5e..52bcbcb8e5e 100644
--- a/src/libs/clangbackendipc/dynamicmatcherdiagnostics.h
+++ b/src/libs/clangsupport/dynamicmatcherdiagnostics.h
diff --git a/src/libs/clangbackendipc/filecontainer.cpp b/src/libs/clangsupport/filecontainer.cpp
index 9de0b550a36..c3f484dbdf0 100644
--- a/src/libs/clangbackendipc/filecontainer.cpp
+++ b/src/libs/clangsupport/filecontainer.cpp
@@ -25,7 +25,7 @@
#include "filecontainer.h"
-#include "clangbackendipcdebugutils.h"
+#include "clangsupportdebugutils.h"
#include <QDebug>
diff --git a/src/libs/clangbackendipc/filecontainer.h b/src/libs/clangsupport/filecontainer.h
index 56779396949..0a45c491d2f 100644
--- a/src/libs/clangbackendipc/filecontainer.h
+++ b/src/libs/clangsupport/filecontainer.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <utf8string.h>
#include <utf8stringvector.h>
diff --git a/src/libs/clangbackendipc/filecontainerv2.cpp b/src/libs/clangsupport/filecontainerv2.cpp
index 57b460d8429..57b460d8429 100644
--- a/src/libs/clangbackendipc/filecontainerv2.cpp
+++ b/src/libs/clangsupport/filecontainerv2.cpp
diff --git a/src/libs/clangbackendipc/filecontainerv2.h b/src/libs/clangsupport/filecontainerv2.h
index 365bb5283dd..7832a43c392 100644
--- a/src/libs/clangbackendipc/filecontainerv2.h
+++ b/src/libs/clangsupport/filecontainerv2.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "filepath.h"
#include <vector>
diff --git a/src/libs/clangbackendipc/filepath.cpp b/src/libs/clangsupport/filepath.cpp
index 0dbb1b4e266..0dbb1b4e266 100644
--- a/src/libs/clangbackendipc/filepath.cpp
+++ b/src/libs/clangsupport/filepath.cpp
diff --git a/src/libs/clangbackendipc/filepath.h b/src/libs/clangsupport/filepath.h
index a29ecf941fe..c57da408bc0 100644
--- a/src/libs/clangbackendipc/filepath.h
+++ b/src/libs/clangsupport/filepath.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <utils/smallstringio.h>
diff --git a/src/libs/clangbackendipc/fixitcontainer.cpp b/src/libs/clangsupport/fixitcontainer.cpp
index 05cea43ffc7..05cea43ffc7 100644
--- a/src/libs/clangbackendipc/fixitcontainer.cpp
+++ b/src/libs/clangsupport/fixitcontainer.cpp
diff --git a/src/libs/clangbackendipc/fixitcontainer.h b/src/libs/clangsupport/fixitcontainer.h
index eac27da02f0..eac27da02f0 100644
--- a/src/libs/clangbackendipc/fixitcontainer.h
+++ b/src/libs/clangsupport/fixitcontainer.h
diff --git a/src/libs/clangsupport/followsymbolmessage.cpp b/src/libs/clangsupport/followsymbolmessage.cpp
new file mode 100644
index 00000000000..cafd22aa4bc
--- /dev/null
+++ b/src/libs/clangsupport/followsymbolmessage.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "followsymbolmessage.h"
+
+#include <QDebug>
+
+#include <ostream>
+
+namespace ClangBackEnd {
+
+QDebug operator<<(QDebug debug, const FollowSymbolMessage &message)
+{
+ debug.nospace() << "FollowSymbolMessage("
+ << message.m_fileContainer
+ << ", " << message.m_ticketNumber
+ << ", " << message.m_sourceRange;
+
+ debug.nospace() << ")";
+
+ return debug;
+}
+
+std::ostream &operator<<(std::ostream &os, const FollowSymbolMessage &message)
+{
+ os << "("
+ << message.m_fileContainer << ", "
+ << message.m_ticketNumber << ", "
+ << message.m_sourceRange << ", "
+ << ")";
+
+ return os;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/followsymbolmessage.h b/src/libs/clangsupport/followsymbolmessage.h
new file mode 100644
index 00000000000..3893a6e49c3
--- /dev/null
+++ b/src/libs/clangsupport/followsymbolmessage.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "filecontainer.h"
+#include "sourcerangecontainer.h"
+
+#include <QDataStream>
+#include <QVector>
+
+namespace ClangBackEnd {
+
+class FollowSymbolMessage
+{
+public:
+ FollowSymbolMessage() = default;
+ FollowSymbolMessage(const FileContainer &fileContainer,
+ const SourceRangeContainer &range,
+ quint64 ticketNumber)
+ : m_fileContainer(fileContainer)
+ , m_sourceRange(range)
+ , m_ticketNumber(ticketNumber)
+ {
+ }
+ const FileContainer &fileContainer() const
+ {
+ return m_fileContainer;
+ }
+
+ const SourceRangeContainer &sourceRange() const
+ {
+ return m_sourceRange;
+ }
+
+ quint64 ticketNumber() const
+ {
+ return m_ticketNumber;
+ }
+
+ friend QDataStream &operator<<(QDataStream &out, const FollowSymbolMessage &message)
+ {
+ out << message.m_fileContainer;
+ out << message.m_sourceRange;
+ out << message.m_ticketNumber;
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, FollowSymbolMessage &message)
+ {
+ in >> message.m_fileContainer;
+ in >> message.m_sourceRange;
+ in >> message.m_ticketNumber;
+ return in;
+ }
+
+ friend bool operator==(const FollowSymbolMessage &first, const FollowSymbolMessage &second)
+ {
+ return first.m_ticketNumber == second.m_ticketNumber
+ && first.m_fileContainer == second.m_fileContainer
+ && first.m_sourceRange == second.m_sourceRange;
+ }
+
+ friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const FollowSymbolMessage &message);
+ friend std::ostream &operator<<(std::ostream &os, const FollowSymbolMessage &message);
+private:
+ FileContainer m_fileContainer;
+ SourceRangeContainer m_sourceRange;
+ quint64 m_ticketNumber = 0;
+};
+
+DECLARE_MESSAGE(FollowSymbolMessage);
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/highlightingmarkcontainer.cpp b/src/libs/clangsupport/highlightingmarkcontainer.cpp
index ab679c8d890..ec460a14a6f 100644
--- a/src/libs/clangbackendipc/highlightingmarkcontainer.cpp
+++ b/src/libs/clangsupport/highlightingmarkcontainer.cpp
@@ -65,6 +65,8 @@ QDebug operator<<(QDebug debug, const HighlightingMarkContainer &container)
<< container.column() << ", "
<< container.length() << ", "
<< highlightingTypeToCStringLiteral(container.types().mainHighlightingType) << ", "
+ << container.isIdentifier() << ", "
+ << container.isIncludeDirectivePath()
<< ")";
return debug;
@@ -94,7 +96,9 @@ std::ostream &operator<<(std::ostream &os, const HighlightingMarkContainer &cont
<< container.line() << ", "
<< container.column() << ", "
<< container.length() << ", "
- << container.types()
+ << container.types() << ", "
+ << container.isIdentifier() << ", "
+ << container.isIncludeDirectivePath()
<< ")";
return os;
diff --git a/src/libs/clangbackendipc/highlightingmarkcontainer.h b/src/libs/clangsupport/highlightingmarkcontainer.h
index 56e998f26c0..8b6e585e501 100644
--- a/src/libs/clangbackendipc/highlightingmarkcontainer.h
+++ b/src/libs/clangsupport/highlightingmarkcontainer.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <QDataStream>
@@ -44,11 +44,14 @@ class HighlightingMarkContainer
{
public:
HighlightingMarkContainer() = default;
- HighlightingMarkContainer(uint line, uint column, uint length, HighlightingTypes types)
+ HighlightingMarkContainer(uint line, uint column, uint length, HighlightingTypes types,
+ bool isIdentifier = false, bool isIncludeDirectivePath = false)
: line_(line),
column_(column),
length_(length),
- types_(types)
+ types_(types),
+ isIdentifier_(isIdentifier),
+ isIncludeDirectivePath_(isIncludeDirectivePath)
{
}
@@ -80,12 +83,29 @@ public:
return types_;
}
+ bool isInvalid() const
+ {
+ return line_ == 0 && column_ == 0 && length_ == 0;
+ }
+
+ bool isIdentifier() const
+ {
+ return isIdentifier_;
+ }
+
+ bool isIncludeDirectivePath() const
+ {
+ return isIncludeDirectivePath_;
+ }
+
friend QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container)
{
out << container.line_;
out << container.column_;
out << container.length_;
out << container.types_;
+ out << container.isIdentifier_;
+ out << container.isIncludeDirectivePath_;
return out;
}
@@ -96,6 +116,8 @@ public:
in >> container.column_;
in >> container.length_;
in >> container.types_;
+ in >> container.isIdentifier_;
+ in >> container.isIncludeDirectivePath_;
return in;
}
@@ -105,7 +127,9 @@ public:
return first.line_ == second.line_
&& first.column_ == second.column_
&& first.length_ == second.length_
- && first.types_ == second.types_;
+ && first.types_ == second.types_
+ && first.isIdentifier_ == second.isIdentifier_
+ && first.isIncludeDirectivePath_ == second.isIncludeDirectivePath_;
}
private:
@@ -113,6 +137,8 @@ private:
uint column_ = 0;
uint length_ = 0;
HighlightingTypes types_;
+ bool isIdentifier_ = false;
+ bool isIncludeDirectivePath_ = false;
};
inline QDataStream &operator<<(QDataStream &out, HighlightingType highlightingType)
diff --git a/src/libs/clangbackendipc/ipcclientinterface.cpp b/src/libs/clangsupport/ipcclientinterface.cpp
index 76f5d81eea0..76f5d81eea0 100644
--- a/src/libs/clangbackendipc/ipcclientinterface.cpp
+++ b/src/libs/clangsupport/ipcclientinterface.cpp
diff --git a/src/libs/clangbackendipc/ipcclientinterface.h b/src/libs/clangsupport/ipcclientinterface.h
index 080de8a2075..080de8a2075 100644
--- a/src/libs/clangbackendipc/ipcclientinterface.h
+++ b/src/libs/clangsupport/ipcclientinterface.h
diff --git a/src/libs/clangbackendipc/ipcserverinterface.h b/src/libs/clangsupport/ipcclientprovider.h
index 87caf34c888..a4bcb7705cc 100644
--- a/src/libs/clangbackendipc/ipcserverinterface.h
+++ b/src/libs/clangsupport/ipcclientprovider.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,15 +25,13 @@
#pragma once
-#include "ipcinterface.h"
-
namespace ClangBackEnd {
-template <typename ClientInterface>
-class IpcServerInterface : public IpcInterface
+template <typename ClientType>
+class IpcClientProvider
{
public:
- void setClient(ClientInterface *client)
+ void setClient(ClientType *client)
{
client_ = client;
}
@@ -43,13 +41,13 @@ public:
client_ = nullptr;
}
- ClientInterface *client()
+ ClientType *client()
{
return client_;
}
private:
- ClientInterface *client_;
+ ClientType *client_;
};
} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/ipcinterface.cpp b/src/libs/clangsupport/ipcinterface.cpp
index dc579a49f9d..dc579a49f9d 100644
--- a/src/libs/clangbackendipc/ipcinterface.cpp
+++ b/src/libs/clangsupport/ipcinterface.cpp
diff --git a/src/libs/clangbackendipc/ipcinterface.h b/src/libs/clangsupport/ipcinterface.h
index f58a7e2a5c6..25ebeb650fe 100644
--- a/src/libs/clangbackendipc/ipcinterface.h
+++ b/src/libs/clangsupport/ipcinterface.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <QtGlobal>
diff --git a/src/libs/clangbackendipc/ipcserverinterface.cpp b/src/libs/clangsupport/ipcserverinterface.cpp
index fbc92de52ec..fbc92de52ec 100644
--- a/src/libs/clangbackendipc/ipcserverinterface.cpp
+++ b/src/libs/clangsupport/ipcserverinterface.cpp
diff --git a/src/libs/clangsupport/ipcserverinterface.h b/src/libs/clangsupport/ipcserverinterface.h
new file mode 100644
index 00000000000..d78176ece0e
--- /dev/null
+++ b/src/libs/clangsupport/ipcserverinterface.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "ipcinterface.h"
+
+namespace ClangBackEnd {
+
+class IpcServerInterface : public IpcInterface
+{
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/lineprefixer.cpp b/src/libs/clangsupport/lineprefixer.cpp
index b11f98e7a76..b11f98e7a76 100644
--- a/src/libs/clangbackendipc/lineprefixer.cpp
+++ b/src/libs/clangsupport/lineprefixer.cpp
diff --git a/src/libs/clangbackendipc/lineprefixer.h b/src/libs/clangsupport/lineprefixer.h
index 4e2972319c7..de87e4b10d0 100644
--- a/src/libs/clangbackendipc/lineprefixer.h
+++ b/src/libs/clangsupport/lineprefixer.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <QString>
#include <QTextStream>
diff --git a/src/libs/clangbackendipc/messageenvelop.cpp b/src/libs/clangsupport/messageenvelop.cpp
index 489806a986b..489806a986b 100644
--- a/src/libs/clangbackendipc/messageenvelop.cpp
+++ b/src/libs/clangsupport/messageenvelop.cpp
diff --git a/src/libs/clangbackendipc/messageenvelop.h b/src/libs/clangsupport/messageenvelop.h
index 592fdcd7f97..b2dd6576200 100644
--- a/src/libs/clangbackendipc/messageenvelop.h
+++ b/src/libs/clangsupport/messageenvelop.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <QByteArray>
#include <QDataStream>
diff --git a/src/libs/clangbackendipc/pchmanagerclientinterface.cpp b/src/libs/clangsupport/pchmanagerclientinterface.cpp
index b7e40f3f5db..b7e40f3f5db 100644
--- a/src/libs/clangbackendipc/pchmanagerclientinterface.cpp
+++ b/src/libs/clangsupport/pchmanagerclientinterface.cpp
diff --git a/src/libs/clangbackendipc/pchmanagerclientinterface.h b/src/libs/clangsupport/pchmanagerclientinterface.h
index 771951641a0..771951641a0 100644
--- a/src/libs/clangbackendipc/pchmanagerclientinterface.h
+++ b/src/libs/clangsupport/pchmanagerclientinterface.h
diff --git a/src/libs/clangbackendipc/pchmanagerclientproxy.cpp b/src/libs/clangsupport/pchmanagerclientproxy.cpp
index ad583113bba..ad583113bba 100644
--- a/src/libs/clangbackendipc/pchmanagerclientproxy.cpp
+++ b/src/libs/clangsupport/pchmanagerclientproxy.cpp
diff --git a/src/libs/clangbackendipc/pchmanagerclientproxy.h b/src/libs/clangsupport/pchmanagerclientproxy.h
index 210e5b01250..71361881e9a 100644
--- a/src/libs/clangbackendipc/pchmanagerclientproxy.h
+++ b/src/libs/clangsupport/pchmanagerclientproxy.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "pchmanagerclientinterface.h"
#include "readmessageblock.h"
#include "writemessageblock.h"
diff --git a/src/libs/clangbackendipc/pchmanagerserverinterface.cpp b/src/libs/clangsupport/pchmanagerserverinterface.cpp
index 1a6d9d4a25d..1a6d9d4a25d 100644
--- a/src/libs/clangbackendipc/pchmanagerserverinterface.cpp
+++ b/src/libs/clangsupport/pchmanagerserverinterface.cpp
diff --git a/src/libs/clangsupport/pchmanagerserverinterface.h b/src/libs/clangsupport/pchmanagerserverinterface.h
new file mode 100644
index 00000000000..6af04c91fed
--- /dev/null
+++ b/src/libs/clangsupport/pchmanagerserverinterface.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "projectmanagementserverinterface.h"
+
+#include <memory>
+
+namespace ClangBackEnd {
+
+class PchManagerClientInterface;
+class RemovePchProjectPartsMessage;
+class UpdatePchProjectPartsMessage;
+
+class CMBIPC_EXPORT PchManagerServerInterface : public ProjectManagementServerInterface
+{
+public:
+ void dispatch(const MessageEnvelop &messageEnvelop) override;
+
+ virtual void end() = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/pchmanagerserverproxy.cpp b/src/libs/clangsupport/pchmanagerserverproxy.cpp
index d513fddc87d..d513fddc87d 100644
--- a/src/libs/clangbackendipc/pchmanagerserverproxy.cpp
+++ b/src/libs/clangsupport/pchmanagerserverproxy.cpp
diff --git a/src/libs/clangbackendipc/pchmanagerserverproxy.h b/src/libs/clangsupport/pchmanagerserverproxy.h
index 0b4e593bc1a..6b7c212934c 100644
--- a/src/libs/clangbackendipc/pchmanagerserverproxy.h
+++ b/src/libs/clangsupport/pchmanagerserverproxy.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "pchmanagerserverinterface.h"
#include "readmessageblock.h"
#include "writemessageblock.h"
diff --git a/src/libs/clangbackendipc/precompiledheadersupdatedmessage.cpp b/src/libs/clangsupport/precompiledheadersupdatedmessage.cpp
index 38c56be38b5..38c56be38b5 100644
--- a/src/libs/clangbackendipc/precompiledheadersupdatedmessage.cpp
+++ b/src/libs/clangsupport/precompiledheadersupdatedmessage.cpp
diff --git a/src/libs/clangbackendipc/precompiledheadersupdatedmessage.h b/src/libs/clangsupport/precompiledheadersupdatedmessage.h
index e4fdcda0112..e4fdcda0112 100644
--- a/src/libs/clangbackendipc/precompiledheadersupdatedmessage.h
+++ b/src/libs/clangsupport/precompiledheadersupdatedmessage.h
diff --git a/src/libs/clangbackendipc/pchmanagerserverinterface.h b/src/libs/clangsupport/projectmanagementserverinterface.h
index a4a8ed683db..5704db417c0 100644
--- a/src/libs/clangbackendipc/pchmanagerserverinterface.h
+++ b/src/libs/clangsupport/projectmanagementserverinterface.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -27,21 +27,14 @@
#include "ipcserverinterface.h"
-#include <memory>
-
namespace ClangBackEnd {
-class PchManagerClientInterface;
class RemovePchProjectPartsMessage;
class UpdatePchProjectPartsMessage;
-
-class CMBIPC_EXPORT PchManagerServerInterface : public IpcServerInterface<PchManagerClientInterface>
+class CMBIPC_EXPORT ProjectManagementServerInterface : public IpcInterface
{
public:
- void dispatch(const MessageEnvelop &messageEnvelop) override;
-
- virtual void end() = 0;
virtual void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) = 0;
virtual void removePchProjectParts(RemovePchProjectPartsMessage &&message) = 0;
};
diff --git a/src/libs/clangbackendipc/projectpartcontainer.cpp b/src/libs/clangsupport/projectpartcontainer.cpp
index f39ba741c3e..9fc1e8d905a 100644
--- a/src/libs/clangbackendipc/projectpartcontainer.cpp
+++ b/src/libs/clangsupport/projectpartcontainer.cpp
@@ -25,7 +25,7 @@
#include "projectpartcontainer.h"
-#include "clangbackendipcdebugutils.h"
+#include "clangsupportdebugutils.h"
#include <QDebug>
diff --git a/src/libs/clangbackendipc/projectpartcontainer.h b/src/libs/clangsupport/projectpartcontainer.h
index 6d5fb147f15..9c735632a51 100644
--- a/src/libs/clangbackendipc/projectpartcontainer.h
+++ b/src/libs/clangsupport/projectpartcontainer.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <utf8stringvector.h>
diff --git a/src/libs/clangbackendipc/projectpartcontainerv2.cpp b/src/libs/clangsupport/projectpartcontainerv2.cpp
index 89b489ee5be..89b489ee5be 100644
--- a/src/libs/clangbackendipc/projectpartcontainerv2.cpp
+++ b/src/libs/clangsupport/projectpartcontainerv2.cpp
diff --git a/src/libs/clangbackendipc/projectpartcontainerv2.h b/src/libs/clangsupport/projectpartcontainerv2.h
index a0ad06f3ca4..be2102fad37 100644
--- a/src/libs/clangbackendipc/projectpartcontainerv2.h
+++ b/src/libs/clangsupport/projectpartcontainerv2.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <utils/smallstringio.h>
diff --git a/src/libs/clangbackendipc/projectpartpch.cpp b/src/libs/clangsupport/projectpartpch.cpp
index 0df291b3dfa..0df291b3dfa 100644
--- a/src/libs/clangbackendipc/projectpartpch.cpp
+++ b/src/libs/clangsupport/projectpartpch.cpp
diff --git a/src/libs/clangbackendipc/projectpartpch.h b/src/libs/clangsupport/projectpartpch.h
index 6798f0eafbc..5ddbca57a0a 100644
--- a/src/libs/clangbackendipc/projectpartpch.h
+++ b/src/libs/clangsupport/projectpartpch.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <utils/smallstringio.h>
diff --git a/src/libs/clangbackendipc/projectpartsdonotexistmessage.cpp b/src/libs/clangsupport/projectpartsdonotexistmessage.cpp
index 18fc44e0ab7..18fc44e0ab7 100644
--- a/src/libs/clangbackendipc/projectpartsdonotexistmessage.cpp
+++ b/src/libs/clangsupport/projectpartsdonotexistmessage.cpp
diff --git a/src/libs/clangbackendipc/projectpartsdonotexistmessage.h b/src/libs/clangsupport/projectpartsdonotexistmessage.h
index 65a8132dc5f..1c579929062 100644
--- a/src/libs/clangbackendipc/projectpartsdonotexistmessage.h
+++ b/src/libs/clangsupport/projectpartsdonotexistmessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <utf8stringvector.h>
diff --git a/src/libs/clangbackendipc/readmessageblock.cpp b/src/libs/clangsupport/readmessageblock.cpp
index e566093074c..e566093074c 100644
--- a/src/libs/clangbackendipc/readmessageblock.cpp
+++ b/src/libs/clangsupport/readmessageblock.cpp
diff --git a/src/libs/clangbackendipc/readmessageblock.h b/src/libs/clangsupport/readmessageblock.h
index 54c06b9fe6f..54c06b9fe6f 100644
--- a/src/libs/clangbackendipc/readmessageblock.h
+++ b/src/libs/clangsupport/readmessageblock.h
diff --git a/src/libs/clangbackendipc/refactoringclientinterface.cpp b/src/libs/clangsupport/refactoringclientinterface.cpp
index fc69cd0cd54..fc69cd0cd54 100644
--- a/src/libs/clangbackendipc/refactoringclientinterface.cpp
+++ b/src/libs/clangsupport/refactoringclientinterface.cpp
diff --git a/src/libs/clangbackendipc/refactoringclientinterface.h b/src/libs/clangsupport/refactoringclientinterface.h
index 8f109869296..8f109869296 100644
--- a/src/libs/clangbackendipc/refactoringclientinterface.h
+++ b/src/libs/clangsupport/refactoringclientinterface.h
diff --git a/src/libs/clangbackendipc/refactoringclientproxy.cpp b/src/libs/clangsupport/refactoringclientproxy.cpp
index 576489aa250..576489aa250 100644
--- a/src/libs/clangbackendipc/refactoringclientproxy.cpp
+++ b/src/libs/clangsupport/refactoringclientproxy.cpp
diff --git a/src/libs/clangbackendipc/refactoringclientproxy.h b/src/libs/clangsupport/refactoringclientproxy.h
index 2f7c3af980c..482fde8b1fd 100644
--- a/src/libs/clangbackendipc/refactoringclientproxy.h
+++ b/src/libs/clangsupport/refactoringclientproxy.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "refactoringclientinterface.h"
#include "readmessageblock.h"
#include "writemessageblock.h"
diff --git a/src/libs/clangsupport/refactoringdatabaseinitializer.h b/src/libs/clangsupport/refactoringdatabaseinitializer.h
new file mode 100644
index 00000000000..29f41d621e9
--- /dev/null
+++ b/src/libs/clangsupport/refactoringdatabaseinitializer.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <createtablesqlstatementbuilder.h>
+
+#include <sqlitetransaction.h>
+#include <sqlitetable.h>
+
+namespace ClangBackEnd {
+
+template<typename DatabaseType>
+class RefactoringDatabaseInitializer
+{
+public:
+ RefactoringDatabaseInitializer(DatabaseType &database)
+ : database(database)
+ {
+ Sqlite::ImmediateTransaction<DatabaseType> transaction{database};
+
+ createSymbolsTable();
+ createLocationsTable();
+ createSourcesTable();
+
+ transaction.commit();
+ }
+
+ void createSymbolsTable()
+ {
+ Sqlite::Table table;
+ table.setUseIfNotExists(true);
+ table.setName("symbols");
+ table.addColumn("symbolId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
+ const Sqlite::Column &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
+ table.addColumn("symbolName", Sqlite::ColumnType::Text);
+ table.addIndex({usrColumn});
+
+ table.initialize(database);
+ }
+
+ void createLocationsTable()
+ {
+ Sqlite::Table table;
+ table.setUseIfNotExists(true);
+ table.setName("locations");
+ table.addColumn("symbolId", Sqlite::ColumnType::Integer);
+ table.addColumn("line", Sqlite::ColumnType::Integer);
+ table.addColumn("column", Sqlite::ColumnType::Integer);
+ const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
+ table.addIndex({sourceIdColumn});
+
+ table.initialize(database);
+ }
+
+ void createSourcesTable()
+ {
+ Sqlite::Table table;
+ table.setUseIfNotExists(true);
+ table.setName("sources");
+ table.addColumn("sourceId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
+ table.addColumn("sourcePath", Sqlite::ColumnType::Text);
+
+ table.initialize(database);
+ }
+
+public:
+ DatabaseType &database;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/refactoringserverinterface.cpp b/src/libs/clangsupport/refactoringserverinterface.cpp
index d6b0f6815b7..52ab7834b06 100644
--- a/src/libs/clangbackendipc/refactoringserverinterface.cpp
+++ b/src/libs/clangsupport/refactoringserverinterface.cpp
@@ -47,6 +47,12 @@ void RefactoringServerInterface::dispatch(const MessageEnvelop &messageEnvelop)
case MessageType::RequestSourceRangesForQueryMessage:
requestSourceRangesForQueryMessage(messageEnvelop.message<RequestSourceRangesForQueryMessage>());
break;
+ case MessageType::UpdatePchProjectPartsMessage:
+ updatePchProjectParts(messageEnvelop.message<UpdatePchProjectPartsMessage>());
+ break;
+ case MessageType::RemovePchProjectPartsMessage:
+ removePchProjectParts(messageEnvelop.message<RemovePchProjectPartsMessage>());
+ break;
case MessageType::CancelMessage:
cancel();
break;
diff --git a/src/libs/clangbackendipc/refactoringserverinterface.h b/src/libs/clangsupport/refactoringserverinterface.h
index c4a8ec6195c..a4a3b1e6f4a 100644
--- a/src/libs/clangbackendipc/refactoringserverinterface.h
+++ b/src/libs/clangsupport/refactoringserverinterface.h
@@ -25,7 +25,7 @@
#pragma once
-#include "ipcserverinterface.h"
+#include "projectmanagementserverinterface.h"
#include <memory>
@@ -36,8 +36,11 @@ class RequestSourceLocationsForRenamingMessage;
class RequestSourceRangesAndDiagnosticsForQueryMessage;
class RequestSourceRangesForQueryMessage;
class CancelMessage;
+class UpdatePchProjectPartsMessage;
+class RemovePchProjectPartsMessage;
+
+class CMBIPC_EXPORT RefactoringServerInterface : public ProjectManagementServerInterface
-class CMBIPC_EXPORT RefactoringServerInterface : public IpcServerInterface<RefactoringClientInterface>
{
public:
void dispatch(const MessageEnvelop &messageEnvelop) override;
diff --git a/src/libs/clangbackendipc/refactoringserverproxy.cpp b/src/libs/clangsupport/refactoringserverproxy.cpp
index 0cf4473f075..cc6741b118c 100644
--- a/src/libs/clangbackendipc/refactoringserverproxy.cpp
+++ b/src/libs/clangsupport/refactoringserverproxy.cpp
@@ -62,6 +62,16 @@ void RefactoringServerProxy::requestSourceRangesForQueryMessage(RequestSourceRan
writeMessageBlock.write(message);
}
+void RefactoringServerProxy::updatePchProjectParts(UpdatePchProjectPartsMessage &&message)
+{
+ writeMessageBlock.write(message);
+}
+
+void RefactoringServerProxy::removePchProjectParts(RemovePchProjectPartsMessage &&message)
+{
+ writeMessageBlock.write(message);
+}
+
void RefactoringServerProxy::cancel()
{
writeMessageBlock.write(CancelMessage());
diff --git a/src/libs/clangbackendipc/refactoringserverproxy.h b/src/libs/clangsupport/refactoringserverproxy.h
index 73d165a9a05..611155b5110 100644
--- a/src/libs/clangbackendipc/refactoringserverproxy.h
+++ b/src/libs/clangsupport/refactoringserverproxy.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "refactoringserverinterface.h"
#include "readmessageblock.h"
#include "writemessageblock.h"
@@ -53,6 +53,8 @@ public:
void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override;
void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override;
void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override;
+ void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) override;
+ void removePchProjectParts(RemovePchProjectPartsMessage &&message) override;
void cancel() override;
void readMessages();
diff --git a/src/libs/clangbackendipc/referencesmessage.cpp b/src/libs/clangsupport/referencesmessage.cpp
index 8b994a7d7cf..8b994a7d7cf 100644
--- a/src/libs/clangbackendipc/referencesmessage.cpp
+++ b/src/libs/clangsupport/referencesmessage.cpp
diff --git a/src/libs/clangbackendipc/referencesmessage.h b/src/libs/clangsupport/referencesmessage.h
index 5d0b4d292a1..5d0b4d292a1 100644
--- a/src/libs/clangbackendipc/referencesmessage.h
+++ b/src/libs/clangsupport/referencesmessage.h
diff --git a/src/libs/clangbackendipc/registerunsavedfilesforeditormessage.cpp b/src/libs/clangsupport/registerunsavedfilesforeditormessage.cpp
index 2881382ce8e..2881382ce8e 100644
--- a/src/libs/clangbackendipc/registerunsavedfilesforeditormessage.cpp
+++ b/src/libs/clangsupport/registerunsavedfilesforeditormessage.cpp
diff --git a/src/libs/clangbackendipc/registerunsavedfilesforeditormessage.h b/src/libs/clangsupport/registerunsavedfilesforeditormessage.h
index 973fe9294fd..973fe9294fd 100644
--- a/src/libs/clangbackendipc/registerunsavedfilesforeditormessage.h
+++ b/src/libs/clangsupport/registerunsavedfilesforeditormessage.h
diff --git a/src/libs/clangbackendipc/removepchprojectpartsmessage.cpp b/src/libs/clangsupport/removepchprojectpartsmessage.cpp
index 24c657336ac..24c657336ac 100644
--- a/src/libs/clangbackendipc/removepchprojectpartsmessage.cpp
+++ b/src/libs/clangsupport/removepchprojectpartsmessage.cpp
diff --git a/src/libs/clangbackendipc/removepchprojectpartsmessage.h b/src/libs/clangsupport/removepchprojectpartsmessage.h
index c6ae105dd0b..c6ae105dd0b 100644
--- a/src/libs/clangbackendipc/removepchprojectpartsmessage.h
+++ b/src/libs/clangsupport/removepchprojectpartsmessage.h
diff --git a/src/libs/clangbackendipc/requestdocumentannotations.cpp b/src/libs/clangsupport/requestdocumentannotations.cpp
index 6d3400ccc3a..6d3400ccc3a 100644
--- a/src/libs/clangbackendipc/requestdocumentannotations.cpp
+++ b/src/libs/clangsupport/requestdocumentannotations.cpp
diff --git a/src/libs/clangbackendipc/requestdocumentannotations.h b/src/libs/clangsupport/requestdocumentannotations.h
index e8facfef332..e8facfef332 100644
--- a/src/libs/clangbackendipc/requestdocumentannotations.h
+++ b/src/libs/clangsupport/requestdocumentannotations.h
diff --git a/src/libs/clangsupport/requestfollowsymbolmessage.cpp b/src/libs/clangsupport/requestfollowsymbolmessage.cpp
new file mode 100644
index 00000000000..dcb0b5cd2ef
--- /dev/null
+++ b/src/libs/clangsupport/requestfollowsymbolmessage.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "requestfollowsymbolmessage.h"
+
+#include <QDebug>
+
+#include <ostream>
+
+namespace ClangBackEnd {
+
+quint64 RequestFollowSymbolMessage::ticketCounter = 0;
+
+QDebug operator<<(QDebug debug, const RequestFollowSymbolMessage &message)
+{
+ debug.nospace() << "RequestFollowSymbolMessage(";
+
+ debug.nospace() << message.m_fileContainer << ", ";
+ debug.nospace() << message.m_dependentFiles << ", ";
+ debug.nospace() << message.m_ticketNumber << ", ";
+ debug.nospace() << message.m_line << ", ";
+ debug.nospace() << message.m_column << ", ";
+
+ debug.nospace() << ")";
+
+ return debug;
+}
+
+std::ostream &operator<<(std::ostream &os, const RequestFollowSymbolMessage &message)
+{
+ os << "("
+ << message.m_fileContainer << ", "
+ << message.m_dependentFiles << ", "
+ << message.m_ticketNumber << ", "
+ << message.m_line << ", "
+ << message.m_column << ", "
+ << ")";
+
+ return os;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/requestfollowsymbolmessage.h b/src/libs/clangsupport/requestfollowsymbolmessage.h
new file mode 100644
index 00000000000..1305abfba81
--- /dev/null
+++ b/src/libs/clangsupport/requestfollowsymbolmessage.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "clangsupport_global.h"
+
+#include "filecontainer.h"
+
+#include <QDataStream>
+
+namespace ClangBackEnd {
+
+class RequestFollowSymbolMessage
+{
+public:
+ RequestFollowSymbolMessage() = default;
+ RequestFollowSymbolMessage(const FileContainer &fileContainer,
+ const QVector<Utf8String> &dependentFiles,
+ quint32 line,
+ quint32 column)
+ : m_fileContainer(fileContainer)
+ , m_ticketNumber(++ticketCounter)
+ , m_line(line)
+ , m_column(column)
+ , m_dependentFiles(dependentFiles)
+ {
+ }
+
+ const FileContainer &fileContainer() const
+ {
+ return m_fileContainer;
+ }
+
+ const QVector<Utf8String> &dependentFiles() const
+ {
+ return m_dependentFiles;
+ }
+
+ quint32 line() const
+ {
+ return m_line;
+ }
+
+ quint32 column() const
+ {
+ return m_column;
+ }
+
+ quint64 ticketNumber() const
+ {
+ return m_ticketNumber;
+ }
+
+ friend QDataStream &operator<<(QDataStream &out, const RequestFollowSymbolMessage &message)
+ {
+ out << message.m_fileContainer;
+ out << message.m_dependentFiles;
+ out << message.m_ticketNumber;
+ out << message.m_line;
+ out << message.m_column;
+
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, RequestFollowSymbolMessage &message)
+ {
+ in >> message.m_fileContainer;
+ in >> message.m_dependentFiles;
+ in >> message.m_ticketNumber;
+ in >> message.m_line;
+ in >> message.m_column;
+
+ return in;
+ }
+
+ friend bool operator==(const RequestFollowSymbolMessage &first,
+ const RequestFollowSymbolMessage &second)
+ {
+ return first.m_ticketNumber == second.m_ticketNumber
+ && first.m_line == second.m_line
+ && first.m_column == second.m_column
+ && first.m_fileContainer == second.m_fileContainer
+ && first.m_dependentFiles == second.m_dependentFiles;
+ }
+
+ friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestFollowSymbolMessage &message);
+ friend std::ostream &operator<<(std::ostream &os, const RequestFollowSymbolMessage &message);
+private:
+ FileContainer m_fileContainer;
+ quint64 m_ticketNumber = 0;
+ quint32 m_line = 0;
+ quint32 m_column = 0;
+ QVector<Utf8String> m_dependentFiles;
+ static CMBIPC_EXPORT quint64 ticketCounter;
+};
+
+DECLARE_MESSAGE(RequestFollowSymbolMessage);
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/requestreferencesmessage.cpp b/src/libs/clangsupport/requestreferencesmessage.cpp
index 0527db59d6e..0527db59d6e 100644
--- a/src/libs/clangbackendipc/requestreferencesmessage.cpp
+++ b/src/libs/clangsupport/requestreferencesmessage.cpp
diff --git a/src/libs/clangbackendipc/requestreferencesmessage.h b/src/libs/clangsupport/requestreferencesmessage.h
index 8d76c1c5afd..8757799d206 100644
--- a/src/libs/clangbackendipc/requestreferencesmessage.h
+++ b/src/libs/clangsupport/requestreferencesmessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "filecontainer.h"
diff --git a/src/libs/clangbackendipc/requestsourcelocationforrenamingmessage.cpp b/src/libs/clangsupport/requestsourcelocationforrenamingmessage.cpp
index 6d5d8a24a1e..6d5d8a24a1e 100644
--- a/src/libs/clangbackendipc/requestsourcelocationforrenamingmessage.cpp
+++ b/src/libs/clangsupport/requestsourcelocationforrenamingmessage.cpp
diff --git a/src/libs/clangbackendipc/requestsourcelocationforrenamingmessage.h b/src/libs/clangsupport/requestsourcelocationforrenamingmessage.h
index 8b1f46798c1..271202cda3c 100644
--- a/src/libs/clangbackendipc/requestsourcelocationforrenamingmessage.h
+++ b/src/libs/clangsupport/requestsourcelocationforrenamingmessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "filepath.h"
#include <utils/smallstringvector.h>
diff --git a/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.cpp b/src/libs/clangsupport/requestsourcerangesanddiagnosticsforquerymessage.cpp
index 878f11f0de4..878f11f0de4 100644
--- a/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.cpp
+++ b/src/libs/clangsupport/requestsourcerangesanddiagnosticsforquerymessage.cpp
diff --git a/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h b/src/libs/clangsupport/requestsourcerangesanddiagnosticsforquerymessage.h
index afac9e9b6b3..afac9e9b6b3 100644
--- a/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h
+++ b/src/libs/clangsupport/requestsourcerangesanddiagnosticsforquerymessage.h
diff --git a/src/libs/clangbackendipc/requestsourcerangesforquerymessage.cpp b/src/libs/clangsupport/requestsourcerangesforquerymessage.cpp
index ab5b8d8468f..ab5b8d8468f 100644
--- a/src/libs/clangbackendipc/requestsourcerangesforquerymessage.cpp
+++ b/src/libs/clangsupport/requestsourcerangesforquerymessage.cpp
diff --git a/src/libs/clangbackendipc/requestsourcerangesforquerymessage.h b/src/libs/clangsupport/requestsourcerangesforquerymessage.h
index 1dc3ca6ac52..1dc3ca6ac52 100644
--- a/src/libs/clangbackendipc/requestsourcerangesforquerymessage.h
+++ b/src/libs/clangsupport/requestsourcerangesforquerymessage.h
diff --git a/src/libs/clangbackendipc/sourcefilepathcontainerbase.cpp b/src/libs/clangsupport/sourcefilepathcontainerbase.cpp
index 66d44d88274..66d44d88274 100644
--- a/src/libs/clangbackendipc/sourcefilepathcontainerbase.cpp
+++ b/src/libs/clangsupport/sourcefilepathcontainerbase.cpp
diff --git a/src/libs/clangbackendipc/sourcefilepathcontainerbase.h b/src/libs/clangsupport/sourcefilepathcontainerbase.h
index ebf717f15e6..ebf717f15e6 100644
--- a/src/libs/clangbackendipc/sourcefilepathcontainerbase.h
+++ b/src/libs/clangsupport/sourcefilepathcontainerbase.h
diff --git a/src/libs/clangbackendipc/sourcelocationcontainer.cpp b/src/libs/clangsupport/sourcelocationcontainer.cpp
index f4c9648f563..f4c9648f563 100644
--- a/src/libs/clangbackendipc/sourcelocationcontainer.cpp
+++ b/src/libs/clangsupport/sourcelocationcontainer.cpp
diff --git a/src/libs/clangbackendipc/sourcelocationcontainer.h b/src/libs/clangsupport/sourcelocationcontainer.h
index 6514b484697..80971e8ee8f 100644
--- a/src/libs/clangbackendipc/sourcelocationcontainer.h
+++ b/src/libs/clangsupport/sourcelocationcontainer.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <utf8string.h>
diff --git a/src/libs/clangbackendipc/sourcelocationcontainerv2.cpp b/src/libs/clangsupport/sourcelocationcontainerv2.cpp
index 3206daf2b58..3206daf2b58 100644
--- a/src/libs/clangbackendipc/sourcelocationcontainerv2.cpp
+++ b/src/libs/clangsupport/sourcelocationcontainerv2.cpp
diff --git a/src/libs/clangbackendipc/sourcelocationcontainerv2.h b/src/libs/clangsupport/sourcelocationcontainerv2.h
index db54c7c0282..def1c389fa2 100644
--- a/src/libs/clangbackendipc/sourcelocationcontainerv2.h
+++ b/src/libs/clangsupport/sourcelocationcontainerv2.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <QDataStream>
diff --git a/src/libs/clangbackendipc/sourcelocationscontainer.cpp b/src/libs/clangsupport/sourcelocationscontainer.cpp
index c5775e6a761..c5775e6a761 100644
--- a/src/libs/clangbackendipc/sourcelocationscontainer.cpp
+++ b/src/libs/clangsupport/sourcelocationscontainer.cpp
diff --git a/src/libs/clangbackendipc/sourcelocationscontainer.h b/src/libs/clangsupport/sourcelocationscontainer.h
index 731ad16906b..731ad16906b 100644
--- a/src/libs/clangbackendipc/sourcelocationscontainer.h
+++ b/src/libs/clangsupport/sourcelocationscontainer.h
diff --git a/src/libs/clangbackendipc/sourcelocationsforrenamingmessage.cpp b/src/libs/clangsupport/sourcelocationsforrenamingmessage.cpp
index 0ce0b8f7a87..0ce0b8f7a87 100644
--- a/src/libs/clangbackendipc/sourcelocationsforrenamingmessage.cpp
+++ b/src/libs/clangsupport/sourcelocationsforrenamingmessage.cpp
diff --git a/src/libs/clangbackendipc/sourcelocationsforrenamingmessage.h b/src/libs/clangsupport/sourcelocationsforrenamingmessage.h
index 5362ed2e46b..5362ed2e46b 100644
--- a/src/libs/clangbackendipc/sourcelocationsforrenamingmessage.h
+++ b/src/libs/clangsupport/sourcelocationsforrenamingmessage.h
diff --git a/src/libs/clangbackendipc/sourcerangecontainer.cpp b/src/libs/clangsupport/sourcerangecontainer.cpp
index a2db7545eb5..a2db7545eb5 100644
--- a/src/libs/clangbackendipc/sourcerangecontainer.cpp
+++ b/src/libs/clangsupport/sourcerangecontainer.cpp
diff --git a/src/libs/clangbackendipc/sourcerangecontainer.h b/src/libs/clangsupport/sourcerangecontainer.h
index ff871cf8edb..ff871cf8edb 100644
--- a/src/libs/clangbackendipc/sourcerangecontainer.h
+++ b/src/libs/clangsupport/sourcerangecontainer.h
diff --git a/src/libs/clangbackendipc/sourcerangecontainerv2.cpp b/src/libs/clangsupport/sourcerangecontainerv2.cpp
index 47907beb8da..47907beb8da 100644
--- a/src/libs/clangbackendipc/sourcerangecontainerv2.cpp
+++ b/src/libs/clangsupport/sourcerangecontainerv2.cpp
diff --git a/src/libs/clangbackendipc/sourcerangecontainerv2.h b/src/libs/clangsupport/sourcerangecontainerv2.h
index a5dba3ddf15..a5dba3ddf15 100644
--- a/src/libs/clangbackendipc/sourcerangecontainerv2.h
+++ b/src/libs/clangsupport/sourcerangecontainerv2.h
diff --git a/src/libs/clangbackendipc/sourcerangesanddiagnosticsforquerymessage.cpp b/src/libs/clangsupport/sourcerangesanddiagnosticsforquerymessage.cpp
index f4ac78ea438..f4ac78ea438 100644
--- a/src/libs/clangbackendipc/sourcerangesanddiagnosticsforquerymessage.cpp
+++ b/src/libs/clangsupport/sourcerangesanddiagnosticsforquerymessage.cpp
diff --git a/src/libs/clangbackendipc/sourcerangesanddiagnosticsforquerymessage.h b/src/libs/clangsupport/sourcerangesanddiagnosticsforquerymessage.h
index f91db432f60..f91db432f60 100644
--- a/src/libs/clangbackendipc/sourcerangesanddiagnosticsforquerymessage.h
+++ b/src/libs/clangsupport/sourcerangesanddiagnosticsforquerymessage.h
diff --git a/src/libs/clangbackendipc/sourcerangescontainer.cpp b/src/libs/clangsupport/sourcerangescontainer.cpp
index ff833be8749..ff833be8749 100644
--- a/src/libs/clangbackendipc/sourcerangescontainer.cpp
+++ b/src/libs/clangsupport/sourcerangescontainer.cpp
diff --git a/src/libs/clangbackendipc/sourcerangescontainer.h b/src/libs/clangsupport/sourcerangescontainer.h
index 6968830a6d8..6968830a6d8 100644
--- a/src/libs/clangbackendipc/sourcerangescontainer.h
+++ b/src/libs/clangsupport/sourcerangescontainer.h
diff --git a/src/libs/clangbackendipc/sourcerangesforquerymessage.cpp b/src/libs/clangsupport/sourcerangesforquerymessage.cpp
index e9227b3a66e..e9227b3a66e 100644
--- a/src/libs/clangbackendipc/sourcerangesforquerymessage.cpp
+++ b/src/libs/clangsupport/sourcerangesforquerymessage.cpp
diff --git a/src/libs/clangbackendipc/sourcerangesforquerymessage.h b/src/libs/clangsupport/sourcerangesforquerymessage.h
index 7aa410e1aef..7aa410e1aef 100644
--- a/src/libs/clangbackendipc/sourcerangesforquerymessage.h
+++ b/src/libs/clangsupport/sourcerangesforquerymessage.h
diff --git a/src/libs/clangbackendipc/sourcerangewithtextcontainer.cpp b/src/libs/clangsupport/sourcerangewithtextcontainer.cpp
index 82f410c8968..82f410c8968 100644
--- a/src/libs/clangbackendipc/sourcerangewithtextcontainer.cpp
+++ b/src/libs/clangsupport/sourcerangewithtextcontainer.cpp
diff --git a/src/libs/clangbackendipc/sourcerangewithtextcontainer.h b/src/libs/clangsupport/sourcerangewithtextcontainer.h
index 4edb2315509..4edb2315509 100644
--- a/src/libs/clangbackendipc/sourcerangewithtextcontainer.h
+++ b/src/libs/clangsupport/sourcerangewithtextcontainer.h
diff --git a/src/libs/clangsupport/stringcache.h b/src/libs/clangsupport/stringcache.h
new file mode 100644
index 00000000000..6d5f4e986b2
--- /dev/null
+++ b/src/libs/clangsupport/stringcache.h
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "stringcachealgorithms.h"
+#include "stringcachefwd.h"
+
+#include <utils/smallstringview.h>
+#include <utils/smallstringfwd.h>
+
+#include <algorithm>
+#include <mutex>
+#include <vector>
+
+namespace ClangBackEnd {
+
+class StringCacheException : public std::exception
+{
+ const char *what() const noexcept override
+ {
+ return "StringCache entries are in invalid state.";
+ }
+};
+
+class NonLockingMutex
+{
+public:
+ constexpr NonLockingMutex() noexcept {}
+ NonLockingMutex(const NonLockingMutex&) = delete;
+ NonLockingMutex& operator=(const NonLockingMutex&) = delete;
+ void lock() {}
+ void unlock() {}
+};
+
+template <typename StringType, typename IndexType>
+class StringCacheEntry
+{
+public:
+ StringCacheEntry(StringType &&string, IndexType id)
+ : string(std::move(string)),
+ id(id)
+ {}
+
+ operator Utils::SmallStringView() const
+ {
+ return {string.data(), string.size()};
+ }
+
+ StringType string;
+ uint id;
+};
+
+template <typename StringType, typename IndexType>
+using StringCacheEntries = std::vector<StringCacheEntry<StringType, IndexType>>;
+
+using FileCacheCacheEntry = StringCacheEntry<Utils::PathString, FilePathIndex>;
+using FileCacheCacheEntries = std::vector<FileCacheCacheEntry>;
+
+template <typename StringType,
+ typename IndexType,
+ typename Mutex,
+ typename Compare,
+ Compare compare = Utils::compare>
+class StringCache
+{
+ using CacheEntry = StringCacheEntry<StringType, IndexType>;
+ using CacheEnties = StringCacheEntries<StringType, IndexType>;
+ using const_iterator = typename CacheEnties::const_iterator;
+ using Found = ClangBackEnd::Found<const_iterator>;
+public:
+ StringCache()
+ {
+ m_strings.reserve(1024);
+ m_indices.reserve(1024);
+ }
+
+ void populate(CacheEnties &&entries)
+ {
+ uncheckedPopulate(std::move(entries));
+
+ checkEntries();
+ }
+
+ void uncheckedPopulate(CacheEnties &&entries)
+ {
+ std::sort(entries.begin(),
+ entries.end(),
+ [] (Utils::SmallStringView first, Utils::SmallStringView second) {
+ return compare(first, second) < 0;
+ });
+
+ m_strings = std::move(entries);
+ m_indices.resize(m_strings.size());
+
+ auto begin = m_strings.cbegin();
+ for (auto current = begin; current != m_strings.end(); ++current)
+ m_indices.at(current->id) = std::distance(begin, current);
+ }
+
+
+ IndexType stringId(Utils::SmallStringView stringView)
+ {
+ std::lock_guard<Mutex> lock(m_mutex);
+
+ return ungardedStringId(stringView);
+ }
+
+ template <typename Container>
+ std::vector<IndexType> stringIds(const Container &strings)
+ {
+ std::lock_guard<Mutex> lock(m_mutex);
+
+ std::vector<IndexType> ids;
+ ids.reserve(strings.size());
+
+ std::transform(strings.begin(),
+ strings.end(),
+ std::back_inserter(ids),
+ [&] (const auto &string) { return this->ungardedStringId(string); });
+
+ return ids;
+ }
+
+ std::vector<IndexType> stringIds(std::initializer_list<StringType> strings)
+ {
+ return stringIds<std::initializer_list<StringType>>(strings);
+ }
+
+ Utils::SmallStringView string(IndexType id) const
+ {
+ std::lock_guard<Mutex> lock(m_mutex);
+
+ return m_strings.at(m_indices.at(id)).string;
+ }
+
+ std::vector<StringType> strings(const std::vector<IndexType> &ids) const
+ {
+ std::lock_guard<Mutex> lock(m_mutex);
+
+ std::vector<StringType> strings;
+ strings.reserve(ids.size());
+
+ std::transform(ids.begin(),
+ ids.end(),
+ std::back_inserter(strings),
+ [&] (IndexType id) { return m_strings.at(m_indices.at(id)).string; });
+
+ return strings;
+ }
+
+ bool isEmpty() const
+ {
+ return m_strings.empty() && m_indices.empty();
+ }
+
+private:
+ IndexType ungardedStringId(Utils::SmallStringView stringView)
+ {
+ Found found = find(stringView);
+
+ if (!found.wasFound)
+ return insertString(found.iterator, stringView);
+
+ return found.iterator->id;
+ }
+
+ Found find(Utils::SmallStringView stringView)
+ {
+ return findInSorted(m_strings.cbegin(), m_strings.cend(), stringView, compare);
+ }
+
+ void incrementLargerOrEqualIndicesByOne(IndexType newIndex)
+ {
+ std::transform(m_indices.begin(),
+ m_indices.end(),
+ m_indices.begin(),
+ [&] (IndexType index) {
+ return index >= newIndex ? ++index : index;
+ });
+ }
+
+ IndexType insertString(const_iterator beforeIterator,
+ Utils::SmallStringView stringView)
+ {
+ auto id = IndexType(m_indices.size());
+
+ auto inserted = m_strings.emplace(beforeIterator, StringType(stringView), id);
+
+ auto newIndex = IndexType(std::distance(m_strings.begin(), inserted));
+
+ incrementLargerOrEqualIndicesByOne(newIndex);
+
+ m_indices.push_back(newIndex);
+
+ return id;
+ }
+
+ void checkEntries()
+ {
+ for (const auto &entry : m_strings) {
+ if (entry.string != string(entry.id) || entry.id != stringId(entry.string))
+ throw StringCacheException();
+ }
+ }
+
+private:
+ CacheEnties m_strings;
+ std::vector<IndexType> m_indices;
+ mutable Mutex m_mutex;
+};
+
+using FilePathIndices = std::vector<FilePathIndex>;
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/stringcachealgorithms.h b/src/libs/clangsupport/stringcachealgorithms.h
new file mode 100644
index 00000000000..573a692b727
--- /dev/null
+++ b/src/libs/clangsupport/stringcachealgorithms.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <utils/smallstringio.h>
+
+#include <iterator>
+
+#include <QDebug>
+
+namespace ClangBackEnd {
+
+template <typename Iterator>
+class Found
+{
+public:
+ Iterator iterator;
+ bool wasFound;
+};
+
+template<typename ForwardIterator,
+ typename Type,
+ typename Compare>
+Found<ForwardIterator> findInSorted(ForwardIterator first, ForwardIterator last, const Type& value, Compare compare)
+{
+ ForwardIterator current;
+ using DifferenceType = typename std::iterator_traits<ForwardIterator>::difference_type;
+ DifferenceType count{std::distance(first, last)};
+ DifferenceType step;
+
+ while (count > 0) {
+ current = first;
+ step = count / 2;
+ std::advance(current, step);
+ auto comparison = compare(*current, value);
+ if (comparison < 0) {
+ first = ++current;
+ count -= step + 1;
+ } else if (comparison > 0) {
+ count = step;
+ } else {
+ return {current, true};
+ }
+ }
+
+ return {first, false};
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/stringcachefwd.h b/src/libs/clangsupport/stringcachefwd.h
new file mode 100644
index 00000000000..66448411e12
--- /dev/null
+++ b/src/libs/clangsupport/stringcachefwd.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <utils/smallstringfwd.h>
+
+namespace ClangBackEnd {
+
+using FilePathIndex = long long int;
+
+class NonLockingMutex;
+
+template <typename StringType,
+ typename IndexType,
+ typename Mutex,
+ typename Compare,
+ Compare compare>
+class StringCache;
+
+template <typename Mutex = NonLockingMutex>
+using FilePathCache = StringCache<Utils::PathString,
+ FilePathIndex,
+ Mutex,
+ decltype(&Utils::reverseCompare),
+ Utils::reverseCompare>;
+
+} // namespace ClangBackEnd
+
diff --git a/src/libs/clangbackendipc/translationunitdoesnotexistmessage.cpp b/src/libs/clangsupport/translationunitdoesnotexistmessage.cpp
index 28f54325bb3..28f54325bb3 100644
--- a/src/libs/clangbackendipc/translationunitdoesnotexistmessage.cpp
+++ b/src/libs/clangsupport/translationunitdoesnotexistmessage.cpp
diff --git a/src/libs/clangbackendipc/translationunitdoesnotexistmessage.h b/src/libs/clangsupport/translationunitdoesnotexistmessage.h
index 67c6601fae9..67c6601fae9 100644
--- a/src/libs/clangbackendipc/translationunitdoesnotexistmessage.h
+++ b/src/libs/clangsupport/translationunitdoesnotexistmessage.h
diff --git a/src/libs/clangbackendipc/unregisterunsavedfilesforeditormessage.cpp b/src/libs/clangsupport/unregisterunsavedfilesforeditormessage.cpp
index 7cd14039091..7cd14039091 100644
--- a/src/libs/clangbackendipc/unregisterunsavedfilesforeditormessage.cpp
+++ b/src/libs/clangsupport/unregisterunsavedfilesforeditormessage.cpp
diff --git a/src/libs/clangbackendipc/unregisterunsavedfilesforeditormessage.h b/src/libs/clangsupport/unregisterunsavedfilesforeditormessage.h
index cc43e188726..cc43e188726 100644
--- a/src/libs/clangbackendipc/unregisterunsavedfilesforeditormessage.h
+++ b/src/libs/clangsupport/unregisterunsavedfilesforeditormessage.h
diff --git a/src/libs/clangbackendipc/updatepchprojectpartsmessage.cpp b/src/libs/clangsupport/updatepchprojectpartsmessage.cpp
index f86ef12aac1..f86ef12aac1 100644
--- a/src/libs/clangbackendipc/updatepchprojectpartsmessage.cpp
+++ b/src/libs/clangsupport/updatepchprojectpartsmessage.cpp
diff --git a/src/libs/clangbackendipc/updatepchprojectpartsmessage.h b/src/libs/clangsupport/updatepchprojectpartsmessage.h
index 67301faf447..67301faf447 100644
--- a/src/libs/clangbackendipc/updatepchprojectpartsmessage.h
+++ b/src/libs/clangsupport/updatepchprojectpartsmessage.h
diff --git a/src/libs/clangbackendipc/updatetranslationunitsforeditormessage.cpp b/src/libs/clangsupport/updatetranslationunitsforeditormessage.cpp
index 0dc0d861a7b..0dc0d861a7b 100644
--- a/src/libs/clangbackendipc/updatetranslationunitsforeditormessage.cpp
+++ b/src/libs/clangsupport/updatetranslationunitsforeditormessage.cpp
diff --git a/src/libs/clangbackendipc/updatetranslationunitsforeditormessage.h b/src/libs/clangsupport/updatetranslationunitsforeditormessage.h
index 3838ea89aec..3838ea89aec 100644
--- a/src/libs/clangbackendipc/updatetranslationunitsforeditormessage.h
+++ b/src/libs/clangsupport/updatetranslationunitsforeditormessage.h
diff --git a/src/libs/clangbackendipc/updatevisibletranslationunitsmessage.cpp b/src/libs/clangsupport/updatevisibletranslationunitsmessage.cpp
index 00f154f4c83..00f154f4c83 100644
--- a/src/libs/clangbackendipc/updatevisibletranslationunitsmessage.cpp
+++ b/src/libs/clangsupport/updatevisibletranslationunitsmessage.cpp
diff --git a/src/libs/clangbackendipc/updatevisibletranslationunitsmessage.h b/src/libs/clangsupport/updatevisibletranslationunitsmessage.h
index 033d3a98a16..cdd57fe2f10 100644
--- a/src/libs/clangbackendipc/updatevisibletranslationunitsmessage.h
+++ b/src/libs/clangsupport/updatevisibletranslationunitsmessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include <utf8stringvector.h>
diff --git a/src/libs/clangbackendipc/writemessageblock.cpp b/src/libs/clangsupport/writemessageblock.cpp
index f891f83c293..f891f83c293 100644
--- a/src/libs/clangbackendipc/writemessageblock.cpp
+++ b/src/libs/clangsupport/writemessageblock.cpp
diff --git a/src/libs/clangbackendipc/writemessageblock.h b/src/libs/clangsupport/writemessageblock.h
index edf1d74a1c7..edf1d74a1c7 100644
--- a/src/libs/clangbackendipc/writemessageblock.h
+++ b/src/libs/clangsupport/writemessageblock.h
diff --git a/src/libs/extensionsystem/pluginerroroverview.ui b/src/libs/extensionsystem/pluginerroroverview.ui
index 768b2f65732..e87cb34c639 100644
--- a/src/libs/extensionsystem/pluginerroroverview.ui
+++ b/src/libs/extensionsystem/pluginerroroverview.ui
@@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
- <string>Qt Creator - Plugin loader messages</string>
+ <string>Plugin loader messages</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp
index 5bd975ceace..1266e944334 100644
--- a/src/libs/extensionsystem/pluginmanager.cpp
+++ b/src/libs/extensionsystem/pluginmanager.cpp
@@ -1322,11 +1322,11 @@ bool PluginManagerPrivate::loadQueue(PluginSpec *spec, QList<PluginSpec *> &queu
spec->d->errorString += QLatin1Char('\n');
int index = circularityCheckQueue.indexOf(spec);
for (int i = index; i < circularityCheckQueue.size(); ++i) {
- spec->d->errorString.append(PluginManager::tr("%1(%2) depends on")
+ spec->d->errorString.append(PluginManager::tr("%1 (%2) depends on")
.arg(circularityCheckQueue.at(i)->name()).arg(circularityCheckQueue.at(i)->version()));
spec->d->errorString += QLatin1Char('\n');
}
- spec->d->errorString.append(PluginManager::tr("%1(%2)").arg(spec->name()).arg(spec->version()));
+ spec->d->errorString.append(PluginManager::tr("%1 (%2)").arg(spec->name()).arg(spec->version()));
return false;
}
circularityCheckQueue.append(spec);
@@ -1348,7 +1348,7 @@ bool PluginManagerPrivate::loadQueue(PluginSpec *spec, QList<PluginSpec *> &queu
if (!loadQueue(depSpec, queue, circularityCheckQueue)) {
spec->d->hasError = true;
spec->d->errorString =
- PluginManager::tr("Cannot load plugin because dependency failed to load: %1(%2)\nReason: %3")
+ PluginManager::tr("Cannot load plugin because dependency failed to load: %1 (%2)\nReason: %3")
.arg(depSpec->name()).arg(depSpec->version()).arg(depSpec->errorString());
return false;
}
diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp
index 042e666c6aa..96052579eee 100644
--- a/src/libs/extensionsystem/pluginview.cpp
+++ b/src/libs/extensionsystem/pluginview.cpp
@@ -33,7 +33,6 @@
#include <utils/utilsicons.h>
#include <utils/itemviews.h>
#include <utils/qtcassert.h>
-#include <utils/treemodel.h>
#include <QDebug>
#include <QDir>
@@ -42,7 +41,6 @@
#include <QItemSelectionModel>
#include <QMessageBox>
#include <QSet>
-#include <QSortFilterProxyModel>
/*!
\class ExtensionSystem::PluginView
@@ -86,7 +84,6 @@ static const int HiddenByDefaultRole = Qt::UserRole + 2;
static const QIcon &icon(IconIndex icon)
{
- using namespace Utils;
switch (icon) {
case OkIcon: {
static const QIcon ok = Utils::Icons::OK.icon();
diff --git a/src/libs/extensionsystem/pluginview.h b/src/libs/extensionsystem/pluginview.h
index 44ca2e2b129..33c48ba0b91 100644
--- a/src/libs/extensionsystem/pluginview.h
+++ b/src/libs/extensionsystem/pluginview.h
@@ -30,18 +30,11 @@
#include <utils/treemodel.h>
#include <QWidget>
-#include <QSet>
-#include <QHash>
-
-QT_BEGIN_NAMESPACE
-class QSortFilterProxyModel;
-QT_END_NAMESPACE
namespace Utils { class TreeView; }
namespace ExtensionSystem {
-class PluginManager;
class PluginSpec;
namespace Internal {
diff --git a/src/libs/flamegraph/flamegraph.h b/src/libs/flamegraph/flamegraph.h
index 5fe7f88ca09..9a25a6bb109 100644
--- a/src/libs/flamegraph/flamegraph.h
+++ b/src/libs/flamegraph/flamegraph.h
@@ -85,10 +85,9 @@ signals:
void depthChanged(int depth);
void maximumDepthChanged();
-private slots:
+private:
void rebuild();
-private:
QQmlComponent *m_delegate = nullptr;
QAbstractItemModel *m_model = nullptr;
int m_sizeRole = 0;
diff --git a/src/libs/libs.pro b/src/libs/libs.pro
index 178a7a4cb8c..669dc0183ab 100644
--- a/src/libs/libs.pro
+++ b/src/libs/libs.pro
@@ -15,7 +15,7 @@ SUBDIRS = \
glsl \
ssh \
sqlite \
- clangbackendipc
+ clangsupport
qtHaveModule(quick) {
SUBDIRS += \
diff --git a/src/libs/libs.qbs b/src/libs/libs.qbs
index 29eb744c1a7..4eedda662ce 100644
--- a/src/libs/libs.qbs
+++ b/src/libs/libs.qbs
@@ -4,7 +4,7 @@ Project {
name: "Libs"
references: [
"aggregation/aggregation.qbs",
- "clangbackendipc/clangbackendipc.qbs",
+ "clangsupport/clangsupport.qbs",
"cplusplus/cplusplus.qbs",
"extensionsystem/extensionsystem.qbs",
"flamegraph/flamegraph.qbs",
diff --git a/src/libs/modelinglib/modelinglib.qbs b/src/libs/modelinglib/modelinglib.qbs
index ab79fcc1123..b9ee382bbdf 100644
--- a/src/libs/modelinglib/modelinglib.qbs
+++ b/src/libs/modelinglib/modelinglib.qbs
@@ -55,6 +55,8 @@ QtcLibrary {
"diagram/dclass.h",
"diagram/dcomponent.cpp",
"diagram/dcomponent.h",
+ "diagram/dconnection.cpp",
+ "diagram/dconnection.h",
"diagram/dconstvisitor.h",
"diagram/ddependency.cpp",
"diagram/ddependency.h",
@@ -72,6 +74,8 @@ QtcLibrary {
"diagram/dpackage.h",
"diagram/drelation.cpp",
"diagram/drelation.h",
+ "diagram/dswimlane.cpp",
+ "diagram/dswimlane.h",
"diagram/dvisitor.h",
"diagram_controller/dclonevisitor.cpp",
"diagram_controller/dclonevisitor.h",
@@ -114,6 +118,8 @@ QtcLibrary {
"diagram_scene/items/classitem.h",
"diagram_scene/items/componentitem.cpp",
"diagram_scene/items/componentitem.h",
+ "diagram_scene/items/connectionitem.cpp",
+ "diagram_scene/items/connectionitem.h",
"diagram_scene/items/diagramitem.cpp",
"diagram_scene/items/diagramitem.h",
"diagram_scene/items/itemitem.cpp",
@@ -126,6 +132,8 @@ QtcLibrary {
"diagram_scene/items/relationitem.h",
"diagram_scene/items/stereotypedisplayvisitor.cpp",
"diagram_scene/items/stereotypedisplayvisitor.h",
+ "diagram_scene/items/swimlaneitem.cpp",
+ "diagram_scene/items/swimlaneitem.h",
"diagram_scene/latchcontroller.cpp",
"diagram_scene/latchcontroller.h",
"diagram_scene/parts/alignbuttonsitem.cpp",
@@ -188,6 +196,8 @@ QtcLibrary {
"model/mclassmember.h",
"model/mcomponent.cpp",
"model/mcomponent.h",
+ "model/mconnection.cpp",
+ "model/mconnection.h",
"model/mconstvisitor.h",
"model/mdependency.cpp",
"model/mdependency.h",
@@ -252,6 +262,8 @@ QtcLibrary {
"serializer/modelserializer.h",
"serializer/projectserializer.cpp",
"serializer/projectserializer.h",
+ "stereotype/customrelation.cpp",
+ "stereotype/customrelation.h",
"stereotype/iconshape.cpp",
"stereotype/iconshape.h",
"stereotype/shape.h",
diff --git a/src/libs/modelinglib/qmt/config/configcontroller.cpp b/src/libs/modelinglib/qmt/config/configcontroller.cpp
index cb31845e2ce..c7b9a783557 100644
--- a/src/libs/modelinglib/qmt/config/configcontroller.cpp
+++ b/src/libs/modelinglib/qmt/config/configcontroller.cpp
@@ -42,7 +42,7 @@ namespace qmt {
class ConfigController::ConfigControllerPrivate
{
public:
- StereotypeController *m_stereotypeController = 0;
+ StereotypeController *m_stereotypeController = nullptr;
};
ConfigController::ConfigController(QObject *parent)
@@ -71,6 +71,8 @@ void ConfigController::readStereotypeDefinitions(const QString &path)
StereotypeDefinitionParser parser;
connect(&parser, &StereotypeDefinitionParser::iconParsed,
this, &ConfigController::onStereotypeIconParsed);
+ connect(&parser, &StereotypeDefinitionParser::relationParsed,
+ this, &ConfigController::onRelationParsed);
connect(&parser, &StereotypeDefinitionParser::toolbarParsed,
this, &ConfigController::onToolbarParsed);
@@ -116,6 +118,11 @@ void ConfigController::onStereotypeIconParsed(const StereotypeIcon &stereotypeIc
d->m_stereotypeController->addStereotypeIcon(stereotypeIcon);
}
+void ConfigController::onRelationParsed(const CustomRelation &customRelation)
+{
+ d->m_stereotypeController->addCustomRelation(customRelation);
+}
+
void ConfigController::onToolbarParsed(const Toolbar &toolbar)
{
d->m_stereotypeController->addToolbar(toolbar);
diff --git a/src/libs/modelinglib/qmt/config/configcontroller.h b/src/libs/modelinglib/qmt/config/configcontroller.h
index 34135bb4af3..c14202b8c1c 100644
--- a/src/libs/modelinglib/qmt/config/configcontroller.h
+++ b/src/libs/modelinglib/qmt/config/configcontroller.h
@@ -30,6 +30,7 @@
namespace qmt {
+class CustomRelation;
class StereotypeController;
class StereotypeIcon;
class Toolbar;
@@ -40,7 +41,7 @@ class QMT_EXPORT ConfigController : public QObject
class ConfigControllerPrivate;
public:
- explicit ConfigController(QObject *parent = 0);
+ explicit ConfigController(QObject *parent = nullptr);
~ConfigController() override;
void setStereotypeController(StereotypeController *stereotypeController);
@@ -49,6 +50,7 @@ public:
private:
void onStereotypeIconParsed(const StereotypeIcon &stereotypeIcon);
+ void onRelationParsed(const CustomRelation &customRelation);
void onToolbarParsed(const Toolbar &toolbar);
ConfigControllerPrivate *d;
diff --git a/src/libs/modelinglib/qmt/config/sourcepos.cpp b/src/libs/modelinglib/qmt/config/sourcepos.cpp
index eeab8c890d5..e58b2b32d7e 100644
--- a/src/libs/modelinglib/qmt/config/sourcepos.cpp
+++ b/src/libs/modelinglib/qmt/config/sourcepos.cpp
@@ -28,9 +28,6 @@
namespace qmt {
SourcePos::SourcePos()
- : m_sourceId(-1),
- m_lineNumber(-1),
- m_columnNumber(-1)
{
}
diff --git a/src/libs/modelinglib/qmt/config/sourcepos.h b/src/libs/modelinglib/qmt/config/sourcepos.h
index 2d86eca92d0..cb9b3423c58 100644
--- a/src/libs/modelinglib/qmt/config/sourcepos.h
+++ b/src/libs/modelinglib/qmt/config/sourcepos.h
@@ -42,9 +42,9 @@ public:
int columnNumber() const { return m_columnNumber; }
private:
- int m_sourceId;
- int m_lineNumber;
- int m_columnNumber;
+ int m_sourceId = -1;
+ int m_lineNumber = -1;
+ int m_columnNumber = -1;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/config/stereotypedefinitionparser.cpp b/src/libs/modelinglib/qmt/config/stereotypedefinitionparser.cpp
index e9ea4e90c5a..8c28e638382 100644
--- a/src/libs/modelinglib/qmt/config/stereotypedefinitionparser.cpp
+++ b/src/libs/modelinglib/qmt/config/stereotypedefinitionparser.cpp
@@ -30,12 +30,13 @@
#include "qmt/infrastructure/qmtassert.h"
#include "qmt/stereotype/stereotypeicon.h"
#include "qmt/stereotype/shapevalue.h"
+#include "qmt/stereotype/customrelation.h"
#include "qmt/stereotype/toolbar.h"
#include <QHash>
#include <QSet>
#include <QPair>
-#include <QDebug>
+#include <QVariant>
namespace qmt {
@@ -89,6 +90,40 @@ static const int KEYWORD_TOOL = 73;
static const int KEYWORD_ELEMENT = 74;
static const int KEYWORD_SEPARATOR = 75;
+// Relation Definition
+static const int KEYWORD_RELATION = 100;
+static const int KEYWORD_DEPENDENCY = 101;
+static const int KEYWORD_INHERITANCE = 102;
+static const int KEYWORD_ASSOCIATION = 103;
+static const int KEYWORD_NAME = 104;
+static const int KEYWORD_DIRECTION = 105;
+static const int KEYWORD_ATOB = 106;
+static const int KEYWORD_BTOA = 107;
+static const int KEYWORD_BI = 108;
+static const int KEYWORD_END = 109;
+static const int KEYWORD_A = 110;
+static const int KEYWORD_B = 111;
+static const int KEYWORD_ROLE = 112;
+static const int KEYWORD_CARDINALITY = 113;
+static const int KEYWORD_NAVIGABLE = 114;
+static const int KEYWORD_RELATIONSHIP = 115;
+static const int KEYWORD_AGGREGATION = 116;
+static const int KEYWORD_COMPOSITION = 117;
+static const int KEYWORD_SHAFT = 118;
+static const int KEYWORD_HEAD = 119;
+
+// Relation Shapes
+static const int KEYWORD_DIAMOND = 130;
+static const int KEYWORD_TRIANGLE = 131;
+static const int KEYWORD_FILLED = 132;
+static const int KEYWORD_PATTERN = 133;
+static const int KEYWORD_SOLID = 134;
+static const int KEYWORD_DOT = 135;
+static const int KEYWORD_DASH = 136;
+static const int KEYWORD_DASHDOT = 137;
+static const int KEYWORD_DASHDOTDOT = 138;
+static const int KEYWORD_COLOR = 139;
+
// Operatoren
static const int OPERATOR_SEMICOLON = 1;
static const int OPERATOR_BRACE_OPEN = 2;
@@ -117,25 +152,68 @@ StereotypeDefinitionParserError::~StereotypeDefinitionParserError()
class StereotypeDefinitionParser::StereotypeDefinitionParserPrivate
{
public:
- TextScanner *m_scanner = 0;
+ TextScanner *m_scanner = nullptr;
};
class StereotypeDefinitionParser::IconCommandParameter
{
public:
+ enum Type {
+ ShapeValue,
+ Boolean
+ };
+
IconCommandParameter() = default;
IconCommandParameter(int keyword, ShapeValueF::Unit unit, ShapeValueF::Origin origin = ShapeValueF::OriginSmart)
: m_keyword(keyword),
+ m_type(ShapeValue),
m_unit(unit),
m_origin(origin)
{
}
+ IconCommandParameter(int keyword, Type type)
+ : m_keyword(keyword),
+ m_type(type)
+ {
+ }
+
+ operator ShapeValueF() const { return m_shapeValue; }
+
+ Type type() const { return m_type; }
+ ShapeValueF::Unit unit() const { return m_unit; }
+ ShapeValueF::Origin origin() const { return m_origin; }
+ ShapeValueF shapeValue() const { return m_shapeValue; }
+ void setShapeValue(const ShapeValueF &shapeValue) { m_shapeValue = shapeValue; }
+ bool boolean() const { return m_boolean; }
+ void setBoolean(bool boolean) { m_boolean = boolean; }
+
+private:
int m_keyword = -1;
- ShapeValueF::Unit m_unit;
- ShapeValueF::Origin m_origin;
+ Type m_type = ShapeValue;
+ ShapeValueF::Unit m_unit = ShapeValueF::UnitAbsolute;
+ ShapeValueF::Origin m_origin = ShapeValueF::OriginSmart;
+ ShapeValueF m_shapeValue;
+ bool m_boolean = false;
+};
+
+class StereotypeDefinitionParser::Value
+{
+public:
+ Value(StereotypeDefinitionParser::Type type, QVariant value)
+ : m_type(type),
+ m_value(value)
+ {
+ }
+
+ StereotypeDefinitionParser::Type type() const { return m_type; }
+ QVariant value() const { return m_value; }
+
+private:
+ StereotypeDefinitionParser::Type m_type = StereotypeDefinitionParser::Void;
+ QVariant m_value;
};
StereotypeDefinitionParser::StereotypeDefinitionParser(QObject *parent)
@@ -154,58 +232,88 @@ void StereotypeDefinitionParser::parse(ITextSource *source)
TextScanner textScanner;
textScanner.setKeywords(
QList<QPair<QString, int> >()
- << qMakePair(QString(QStringLiteral("icon")), KEYWORD_ICON)
- << qMakePair(QString(QStringLiteral("id")), KEYWORD_ID)
- << qMakePair(QString(QStringLiteral("title")), KEYWORD_TITLE)
- << qMakePair(QString(QStringLiteral("elements")), KEYWORD_ELEMENTS)
- << qMakePair(QString(QStringLiteral("stereotype")), KEYWORD_STEREOTYPE)
- << qMakePair(QString(QStringLiteral("width")), KEYWORD_WIDTH)
- << qMakePair(QString(QStringLiteral("height")), KEYWORD_HEIGHT)
- << qMakePair(QString(QStringLiteral("minwidth")), KEYWORD_MINWIDTH)
- << qMakePair(QString(QStringLiteral("minheight")), KEYWORD_MINHEIGHT)
- << qMakePair(QString(QStringLiteral("locksize")), KEYWORD_LOCK_SIZE)
- << qMakePair(QString(QStringLiteral("display")), KEYWORD_DISPLAY)
- << qMakePair(QString(QStringLiteral("textalignment")), KEYWORD_TEXTALIGN)
- << qMakePair(QString(QStringLiteral("basecolor")), KEYWORD_BASECOLOR)
- << qMakePair(QString(QStringLiteral("shape")), KEYWORD_SHAPE)
- << qMakePair(QString(QStringLiteral("circle")), KEYWORD_CIRCLE)
- << qMakePair(QString(QStringLiteral("ellipse")), KEYWORD_ELLIPSE)
- << qMakePair(QString(QStringLiteral("line")), KEYWORD_LINE)
- << qMakePair(QString(QStringLiteral("rect")), KEYWORD_RECT)
- << qMakePair(QString(QStringLiteral("roundedrect")), KEYWORD_ROUNDEDRECT)
- << qMakePair(QString(QStringLiteral("arc")), KEYWORD_ARC)
- << qMakePair(QString(QStringLiteral("moveto")), KEYWORD_MOVETO)
- << qMakePair(QString(QStringLiteral("lineto")), KEYWORD_LINETO)
- << qMakePair(QString(QStringLiteral("arcmoveto")), KEYWORD_ARCMOVETO)
- << qMakePair(QString(QStringLiteral("arcto")), KEYWORD_ARCTO)
- << qMakePair(QString(QStringLiteral("close")), KEYWORD_CLOSE)
- << qMakePair(QString(QStringLiteral("x")), KEYWORD_X)
- << qMakePair(QString(QStringLiteral("y")), KEYWORD_Y)
- << qMakePair(QString(QStringLiteral("x0")), KEYWORD_X0)
- << qMakePair(QString(QStringLiteral("y0")), KEYWORD_Y0)
- << qMakePair(QString(QStringLiteral("x1")), KEYWORD_X1)
- << qMakePair(QString(QStringLiteral("y1")), KEYWORD_Y1)
- << qMakePair(QString(QStringLiteral("radius")), KEYWORD_RADIUS)
- << qMakePair(QString(QStringLiteral("radiusx")), KEYWORD_RADIUS_X)
- << qMakePair(QString(QStringLiteral("radiusy")), KEYWORD_RADIUS_Y)
- << qMakePair(QString(QStringLiteral("start")), KEYWORD_START)
- << qMakePair(QString(QStringLiteral("span")), KEYWORD_SPAN)
- << qMakePair(QString(QStringLiteral("toolbar")), KEYWORD_TOOLBAR)
- << qMakePair(QString(QStringLiteral("priority")), KEYWORD_PRIORITY)
- << qMakePair(QString(QStringLiteral("tools")), KEYWORD_TOOLS)
- << qMakePair(QString(QStringLiteral("tool")), KEYWORD_TOOL)
- << qMakePair(QString(QStringLiteral("element")), KEYWORD_ELEMENT)
- << qMakePair(QString(QStringLiteral("separator")), KEYWORD_SEPARATOR)
+ << qMakePair(QString("icon"), KEYWORD_ICON)
+ << qMakePair(QString("id"), KEYWORD_ID)
+ << qMakePair(QString("title"), KEYWORD_TITLE)
+ << qMakePair(QString("elements"), KEYWORD_ELEMENTS)
+ << qMakePair(QString("stereotype"), KEYWORD_STEREOTYPE)
+ << qMakePair(QString("width"), KEYWORD_WIDTH)
+ << qMakePair(QString("height"), KEYWORD_HEIGHT)
+ << qMakePair(QString("minwidth"), KEYWORD_MINWIDTH)
+ << qMakePair(QString("minheight"), KEYWORD_MINHEIGHT)
+ << qMakePair(QString("locksize"), KEYWORD_LOCK_SIZE)
+ << qMakePair(QString("display"), KEYWORD_DISPLAY)
+ << qMakePair(QString("textalignment"), KEYWORD_TEXTALIGN)
+ << qMakePair(QString("basecolor"), KEYWORD_BASECOLOR)
+ << qMakePair(QString("shape"), KEYWORD_SHAPE)
+ << qMakePair(QString("circle"), KEYWORD_CIRCLE)
+ << qMakePair(QString("ellipse"), KEYWORD_ELLIPSE)
+ << qMakePair(QString("line"), KEYWORD_LINE)
+ << qMakePair(QString("rect"), KEYWORD_RECT)
+ << qMakePair(QString("roundedrect"), KEYWORD_ROUNDEDRECT)
+ << qMakePair(QString("arc"), KEYWORD_ARC)
+ << qMakePair(QString("moveto"), KEYWORD_MOVETO)
+ << qMakePair(QString("lineto"), KEYWORD_LINETO)
+ << qMakePair(QString("arcmoveto"), KEYWORD_ARCMOVETO)
+ << qMakePair(QString("arcto"), KEYWORD_ARCTO)
+ << qMakePair(QString("close"), KEYWORD_CLOSE)
+ << qMakePair(QString("x"), KEYWORD_X)
+ << qMakePair(QString("y"), KEYWORD_Y)
+ << qMakePair(QString("x0"), KEYWORD_X0)
+ << qMakePair(QString("y0"), KEYWORD_Y0)
+ << qMakePair(QString("x1"), KEYWORD_X1)
+ << qMakePair(QString("y1"), KEYWORD_Y1)
+ << qMakePair(QString("radius"), KEYWORD_RADIUS)
+ << qMakePair(QString("radiusx"), KEYWORD_RADIUS_X)
+ << qMakePair(QString("radiusy"), KEYWORD_RADIUS_Y)
+ << qMakePair(QString("start"), KEYWORD_START)
+ << qMakePair(QString("span"), KEYWORD_SPAN)
+ << qMakePair(QString("toolbar"), KEYWORD_TOOLBAR)
+ << qMakePair(QString("priority"), KEYWORD_PRIORITY)
+ << qMakePair(QString("tools"), KEYWORD_TOOLS)
+ << qMakePair(QString("tool"), KEYWORD_TOOL)
+ << qMakePair(QString("element"), KEYWORD_ELEMENT)
+ << qMakePair(QString("separator"), KEYWORD_SEPARATOR)
+ << qMakePair(QString("relation"), KEYWORD_RELATION)
+ << qMakePair(QString("dependency"), KEYWORD_DEPENDENCY)
+ << qMakePair(QString("inheritance"), KEYWORD_INHERITANCE)
+ << qMakePair(QString("association"), KEYWORD_ASSOCIATION)
+ << qMakePair(QString("name"), KEYWORD_NAME)
+ << qMakePair(QString("direction"), KEYWORD_DIRECTION)
+ << qMakePair(QString("atob"), KEYWORD_ATOB)
+ << qMakePair(QString("btoa"), KEYWORD_BTOA)
+ << qMakePair(QString("bi"), KEYWORD_BI)
+ << qMakePair(QString("end"), KEYWORD_END)
+ << qMakePair(QString("a"), KEYWORD_A)
+ << qMakePair(QString("b"), KEYWORD_B)
+ << qMakePair(QString("role"), KEYWORD_ROLE)
+ << qMakePair(QString("cardinality"), KEYWORD_CARDINALITY)
+ << qMakePair(QString("navigable"), KEYWORD_NAVIGABLE)
+ << qMakePair(QString("relationship"), KEYWORD_RELATIONSHIP)
+ << qMakePair(QString("aggregation"), KEYWORD_AGGREGATION)
+ << qMakePair(QString("composition"), KEYWORD_COMPOSITION)
+ << qMakePair(QString("shaft"), KEYWORD_SHAFT)
+ << qMakePair(QString("head"), KEYWORD_HEAD)
+ << qMakePair(QString("diamond"), KEYWORD_DIAMOND)
+ << qMakePair(QString("triangle"), KEYWORD_TRIANGLE)
+ << qMakePair(QString("filled"), KEYWORD_FILLED)
+ << qMakePair(QString("pattern"), KEYWORD_PATTERN)
+ << qMakePair(QString("solid"), KEYWORD_SOLID)
+ << qMakePair(QString("dot"), KEYWORD_DOT)
+ << qMakePair(QString("dash"), KEYWORD_DASH)
+ << qMakePair(QString("dashdot"), KEYWORD_DASHDOT)
+ << qMakePair(QString("dashdotdot"), KEYWORD_DASHDOTDOT)
+ << qMakePair(QString("color"), KEYWORD_COLOR)
);
textScanner.setOperators(
QList<QPair<QString, int> >()
- << qMakePair(QString(QStringLiteral(";")), OPERATOR_SEMICOLON)
- << qMakePair(QString(QStringLiteral("{")), OPERATOR_BRACE_OPEN)
- << qMakePair(QString(QStringLiteral("}")), OPERATOR_BRACE_CLOSE)
- << qMakePair(QString(QStringLiteral(":")), OPERATOR_COLON)
- << qMakePair(QString(QStringLiteral(",")), OPERATOR_COMMA)
- << qMakePair(QString(QStringLiteral(".")), OPERATOR_PERIOD)
- << qMakePair(QString(QStringLiteral("-")), OPERATOR_MINUS)
+ << qMakePair(QString(";"), OPERATOR_SEMICOLON)
+ << qMakePair(QString("{"), OPERATOR_BRACE_OPEN)
+ << qMakePair(QString("}"), OPERATOR_BRACE_CLOSE)
+ << qMakePair(QString(":"), OPERATOR_COLON)
+ << qMakePair(QString(","), OPERATOR_COMMA)
+ << qMakePair(QString("."), OPERATOR_PERIOD)
+ << qMakePair(QString("-"), OPERATOR_MINUS)
);
textScanner.setSource(source);
@@ -213,10 +321,10 @@ void StereotypeDefinitionParser::parse(ITextSource *source)
try {
parseFile();
} catch (...) {
- d->m_scanner = 0;
+ d->m_scanner = nullptr;
throw;
}
- d->m_scanner = 0;
+ d->m_scanner = nullptr;
}
void StereotypeDefinitionParser::parseFile()
@@ -229,8 +337,16 @@ void StereotypeDefinitionParser::parseFile()
parseIcon();
else if (token.type() == Token::TokenKeyword && token.subtype() == KEYWORD_TOOLBAR)
parseToolbar();
+ else if (token.type() == Token::TokenKeyword && token.subtype() == KEYWORD_RELATION)
+ parseRelation(CustomRelation::Element::Relation);
+ else if (token.type() == Token::TokenKeyword && token.subtype() == KEYWORD_DEPENDENCY)
+ parseRelation(CustomRelation::Element::Dependency);
+ else if (token.type() == Token::TokenKeyword && token.subtype() == KEYWORD_INHERITANCE)
+ parseRelation(CustomRelation::Element::Inheritance);
+ else if (token.type() == Token::TokenKeyword && token.subtype() == KEYWORD_ASSOCIATION)
+ parseRelation(CustomRelation::Element::Association);
else
- throw StereotypeDefinitionParserError(QStringLiteral("Expected 'Icon' or 'Toolbar'."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Expected 'Icon', 'Toolbar', 'Relation', 'Dependency', 'Inheritance' or 'Association'.", token.sourcePos());
}
}
@@ -251,19 +367,15 @@ void StereotypeDefinitionParser::parseIcon()
break;
case KEYWORD_ELEMENTS:
{
- QList<QString> identifiers = parseIdentifierListProperty();
- foreach (const QString &identifier, identifiers) {
- static QHash<QString, StereotypeIcon::Element> elementNames = QHash<QString, StereotypeIcon::Element>()
- << qMakePair(QString(QStringLiteral("package")), StereotypeIcon::ElementPackage)
- << qMakePair(QString(QStringLiteral("component")), StereotypeIcon::ElementComponent)
- << qMakePair(QString(QStringLiteral("class")), StereotypeIcon::ElementClass)
- << qMakePair(QString(QStringLiteral("diagram")), StereotypeIcon::ElementDiagram)
- << qMakePair(QString(QStringLiteral("item")), StereotypeIcon::ElementItem);
- QString elementName = identifier.toLower();
- if (!elementNames.contains(elementName))
- throw StereotypeDefinitionParserError(QString(QStringLiteral("Unexpected value \"%1\" for element.")).arg(identifier), token.sourcePos());
- elements.insert(elementNames.value(elementName));
- }
+ const static QHash<QString, StereotypeIcon::Element> elementNames = QHash<QString, StereotypeIcon::Element>()
+ << qMakePair(QString("package"), StereotypeIcon::ElementPackage)
+ << qMakePair(QString("component"), StereotypeIcon::ElementComponent)
+ << qMakePair(QString("class"), StereotypeIcon::ElementClass)
+ << qMakePair(QString("diagram"), StereotypeIcon::ElementDiagram)
+ << qMakePair(QString("item"), StereotypeIcon::ElementItem);
+ parseEnums<StereotypeIcon::Element>(
+ parseIdentifierListProperty(), elementNames, token.sourcePos(),
+ [&](StereotypeIcon::Element element) { elements.insert(element); });
break;
}
case KEYWORD_STEREOTYPE:
@@ -283,61 +395,46 @@ void StereotypeDefinitionParser::parseIcon()
break;
case KEYWORD_LOCK_SIZE:
{
- QString lockValue = parseIdentifierProperty();
- QString lockName = lockValue.toLower();
- static QHash<QString, StereotypeIcon::SizeLock> lockNames = QHash<QString, StereotypeIcon::SizeLock>()
- << qMakePair(QString(QStringLiteral("none")), StereotypeIcon::LockNone)
- << qMakePair(QString(QStringLiteral("width")), StereotypeIcon::LockWidth)
- << qMakePair(QString(QStringLiteral("height")), StereotypeIcon::LockHeight)
- << qMakePair(QString(QStringLiteral("size")), StereotypeIcon::LockSize)
- << qMakePair(QString(QStringLiteral("ratio")), StereotypeIcon::LockRatio);
- if (lockNames.contains(lockName)) {
- StereotypeIcon::SizeLock sizeLock = lockNames.value(lockName);
- stereotypeIcon.setSizeLock(sizeLock);
- } else {
- throw StereotypeDefinitionParserError(QString(QStringLiteral("Unexpected value \"%1\" for size lock.")).arg(lockValue), token.sourcePos());
- }
+ const static QHash<QString, StereotypeIcon::SizeLock> lockNames = QHash<QString, StereotypeIcon::SizeLock>()
+ << qMakePair(QString("none"), StereotypeIcon::LockNone)
+ << qMakePair(QString("width"), StereotypeIcon::LockWidth)
+ << qMakePair(QString("height"), StereotypeIcon::LockHeight)
+ << qMakePair(QString("size"), StereotypeIcon::LockSize)
+ << qMakePair(QString("ratio"), StereotypeIcon::LockRatio);
+ parseEnum<StereotypeIcon::SizeLock>(
+ parseIdentifierProperty(), lockNames, token.sourcePos(),
+ [&](StereotypeIcon::SizeLock lock) { stereotypeIcon.setSizeLock(lock); });
break;
}
case KEYWORD_DISPLAY:
{
- QString displayValue = parseIdentifierProperty();
- QString displayName = displayValue.toLower();
- static QHash<QString, StereotypeIcon::Display> displayNames = QHash<QString, StereotypeIcon::Display>()
- << qMakePair(QString(QStringLiteral("none")), StereotypeIcon::DisplayNone)
- << qMakePair(QString(QStringLiteral("label")), StereotypeIcon::DisplayLabel)
- << qMakePair(QString(QStringLiteral("decoration")), StereotypeIcon::DisplayDecoration)
- << qMakePair(QString(QStringLiteral("icon")), StereotypeIcon::DisplayIcon)
- << qMakePair(QString(QStringLiteral("smart")), StereotypeIcon::DisplaySmart);
- if (displayNames.contains(displayName)) {
- StereotypeIcon::Display display = displayNames.value(displayName);
- stereotypeIcon.setDisplay(display);
- } else {
- throw StereotypeDefinitionParserError(QString(QStringLiteral("Unexpected value \"%1\" for stereotype display.")).arg(displayValue), token.sourcePos());
- }
+ const static QHash<QString, StereotypeIcon::Display> displayNames = QHash<QString, StereotypeIcon::Display>()
+ << qMakePair(QString("none"), StereotypeIcon::DisplayNone)
+ << qMakePair(QString("label"), StereotypeIcon::DisplayLabel)
+ << qMakePair(QString("decoration"), StereotypeIcon::DisplayDecoration)
+ << qMakePair(QString("icon"), StereotypeIcon::DisplayIcon)
+ << qMakePair(QString("smart"), StereotypeIcon::DisplaySmart);
+ parseEnum<StereotypeIcon::Display>(
+ parseIdentifierProperty(), displayNames, token.sourcePos(),
+ [&](StereotypeIcon::Display display) { stereotypeIcon.setDisplay(display); });
break;
}
case KEYWORD_TEXTALIGN:
{
- QString alignValue = parseIdentifierProperty();
- QString alignName = alignValue.toLower();
- static QHash<QString, StereotypeIcon::TextAlignment> alignNames = QHash<QString, StereotypeIcon::TextAlignment>()
- << qMakePair(QString(QStringLiteral("below")), StereotypeIcon::TextalignBelow)
- << qMakePair(QString(QStringLiteral("center")), StereotypeIcon::TextalignCenter)
- << qMakePair(QString(QStringLiteral("none")), StereotypeIcon::TextalignNone);
- if (alignNames.contains(alignName)) {
- StereotypeIcon::TextAlignment textAlignment = alignNames.value(alignName);
- stereotypeIcon.setTextAlignment(textAlignment);
- } else {
- throw StereotypeDefinitionParserError(QString(QStringLiteral("Unexpected value \"%1\" for text alignment.")).arg(alignValue), token.sourcePos());
- }
+ const static QHash<QString, StereotypeIcon::TextAlignment> alignNames = QHash<QString, StereotypeIcon::TextAlignment>()
+ << qMakePair(QString("below"), StereotypeIcon::TextalignBelow)
+ << qMakePair(QString("center"), StereotypeIcon::TextalignCenter)
+ << qMakePair(QString("none"), StereotypeIcon::TextalignNone);
+ parseEnum<StereotypeIcon::TextAlignment>(
+ parseIdentifierProperty(), alignNames, token.sourcePos(),
+ [&](StereotypeIcon::TextAlignment align) { stereotypeIcon.setTextAlignment(align); });
break;
}
case KEYWORD_BASECOLOR:
stereotypeIcon.setBaseColor(parseColorProperty());
break;
case KEYWORD_SHAPE:
- parseIconShape(&stereotypeIcon);
+ stereotypeIcon.setIconShape(parseIconShape());
break;
default:
throwUnknownPropertyError(token);
@@ -348,7 +445,7 @@ void StereotypeDefinitionParser::parseIcon()
stereotypeIcon.setElements(elements);
stereotypeIcon.setStereotypes(stereotypes);
if (stereotypeIcon.id().isEmpty())
- throw StereotypeDefinitionParserError(QStringLiteral("Missing id in Icon definition."), d->m_scanner->sourcePos());
+ throw StereotypeDefinitionParserError("Missing id in Icon definition.", d->m_scanner->sourcePos());
emit iconParsed(stereotypeIcon);
}
@@ -367,10 +464,15 @@ QPair<int, StereotypeDefinitionParser::IconCommandParameter> StereotypeDefinitio
return qMakePair(keyword, IconCommandParameter(keyword, ShapeValueF::UnitAbsolute));
}
-void StereotypeDefinitionParser::parseIconShape(StereotypeIcon *stereotypeIcon)
+QPair<int, StereotypeDefinitionParser::IconCommandParameter> StereotypeDefinitionParser::BOOLEAN(int keyword)
+{
+ return qMakePair(keyword, IconCommandParameter(keyword, IconCommandParameter::Boolean));
+}
+
+IconShape StereotypeDefinitionParser::parseIconShape()
{
IconShape iconShape;
- QHash<int, ShapeValueF> values;
+ QHash<int, IconCommandParameter> values;
typedef QHash<int, IconCommandParameter> Parameters;
expectBlockBegin();
Token token;
@@ -458,26 +560,50 @@ void StereotypeDefinitionParser::parseIconShape(StereotypeIcon *stereotypeIcon)
iconShape.closePath();
skipOptionalEmptyBlock();
break;
+ case KEYWORD_DIAMOND:
+ values = parseIconShapeProperties(
+ Parameters() << SCALED(KEYWORD_X) << SCALED(KEYWORD_Y)
+ << SCALED(KEYWORD_WIDTH) << SCALED(KEYWORD_HEIGHT)
+ << BOOLEAN(KEYWORD_FILLED));
+ iconShape.addDiamond(ShapePointF(values.value(KEYWORD_X), values.value(KEYWORD_Y)),
+ ShapeSizeF(values.value(KEYWORD_WIDTH), values.value(KEYWORD_HEIGHT)),
+ values.value(KEYWORD_FILLED).boolean());
+ break;
+ case KEYWORD_TRIANGLE:
+ values = parseIconShapeProperties(
+ Parameters() << SCALED(KEYWORD_X) << SCALED(KEYWORD_Y)
+ << SCALED(KEYWORD_WIDTH) << SCALED(KEYWORD_HEIGHT)
+ << BOOLEAN(KEYWORD_FILLED));
+ iconShape.addTriangle(ShapePointF(values.value(KEYWORD_X), values.value(KEYWORD_Y)),
+ ShapeSizeF(values.value(KEYWORD_WIDTH), values.value(KEYWORD_HEIGHT)),
+ values.value(KEYWORD_FILLED).boolean());
+ break;
default:
throwUnknownPropertyError(token);
}
if (!expectPropertySeparatorOrBlockEnd())
break;
}
- stereotypeIcon->setIconShape(iconShape);
+ return iconShape;
}
-QHash<int, ShapeValueF> StereotypeDefinitionParser::parseIconShapeProperties(const QHash<int, IconCommandParameter> &parameters)
+QHash<int, StereotypeDefinitionParser::IconCommandParameter> StereotypeDefinitionParser::parseIconShapeProperties(const QHash<int, IconCommandParameter> &parameters)
{
expectBlockBegin();
- QHash<int, ShapeValueF> values;
+ QHash<int, IconCommandParameter> values;
Token token;
while (readProperty(&token)) {
if (parameters.contains(token.subtype())) {
- IconCommandParameter parameter = parameters.value(token.subtype());
if (values.contains(token.subtype()))
- throw StereotypeDefinitionParserError(QStringLiteral("Property givent twice."), token.sourcePos());
- values.insert(token.subtype(), ShapeValueF(parseFloatProperty(), parameter.m_unit, parameter.m_origin));
+ throw StereotypeDefinitionParserError("Property given twice.", token.sourcePos());
+ IconCommandParameter parameter = parameters.value(token.subtype());
+ if (parameter.type() == IconCommandParameter::ShapeValue)
+ parameter.setShapeValue(ShapeValueF(parseFloatProperty(), parameter.unit(), parameter.origin()));
+ else if (parameter.type() == IconCommandParameter::Boolean)
+ parameter.setBoolean(parseBoolProperty());
+ else
+ throw StereotypeDefinitionParserError("Unexpected type of property.", token.sourcePos());
+ values.insert(token.subtype(), parameter);
} else {
throwUnknownPropertyError(token);
}
@@ -485,12 +611,198 @@ QHash<int, ShapeValueF> StereotypeDefinitionParser::parseIconShapeProperties(con
break;
}
if (values.count() < parameters.count())
- throw StereotypeDefinitionParserError(QStringLiteral("Missing some properties."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Missing some properties.", token.sourcePos());
else if (values.count() > parameters.count())
- throw StereotypeDefinitionParserError(QStringLiteral("Too many properties given."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Too many properties given.", token.sourcePos());
return values;
}
+void StereotypeDefinitionParser::parseRelation(CustomRelation::Element element)
+{
+ CustomRelation relation;
+ relation.setElement(element);
+ QSet<QString> stereotypes;
+ expectBlockBegin();
+ Token token;
+ while (readProperty(&token)) {
+ switch (token.subtype()) {
+ case KEYWORD_ID:
+ relation.setId(parseIdentifierProperty());
+ break;
+ case KEYWORD_TITLE:
+ relation.setTitle(parseStringProperty());
+ break;
+ case KEYWORD_ELEMENTS:
+ relation.setEndItems(parseIdentifierListProperty());
+ break;
+ case KEYWORD_STEREOTYPE:
+ stereotypes.insert(parseStringProperty());
+ break;
+ case KEYWORD_NAME:
+ relation.setName(parseStringProperty());
+ break;
+ case KEYWORD_DIRECTION:
+ {
+ const static QHash<QString, CustomRelation::Direction> directionNames = QHash<QString, CustomRelation::Direction>()
+ << qMakePair(QString("atob"), CustomRelation::Direction::AtoB)
+ << qMakePair(QString("btoa"), CustomRelation::Direction::BToA)
+ << qMakePair(QString("bi"), CustomRelation::Direction::Bi);
+ if (element != CustomRelation::Element::Dependency)
+ throwUnknownPropertyError(token);
+ parseEnum<CustomRelation::Direction>(
+ parseIdentifierProperty(), directionNames, token.sourcePos(),
+ [&](CustomRelation::Direction direction) { relation.setDirection(direction); });
+ break;
+ }
+ case KEYWORD_PATTERN:
+ {
+ const static QHash<QString, CustomRelation::ShaftPattern> patternNames = QHash<QString, CustomRelation::ShaftPattern>()
+ << qMakePair(QString("solid"), CustomRelation::ShaftPattern::Solid)
+ << qMakePair(QString("dash"), CustomRelation::ShaftPattern::Dash)
+ << qMakePair(QString("dot"), CustomRelation::ShaftPattern::Dot)
+ << qMakePair(QString("dashdot"), CustomRelation::ShaftPattern::DashDot)
+ << qMakePair(QString("dashdotdot"), CustomRelation::ShaftPattern::DashDotDot);
+ if (element != CustomRelation::Element::Relation)
+ throwUnknownPropertyError(token);
+ parseEnum<CustomRelation::ShaftPattern>(
+ parseIdentifierProperty(), patternNames, token.sourcePos(),
+ [&](CustomRelation::ShaftPattern pattern) { relation.setShaftPattern(pattern); });
+ break;
+ }
+ case KEYWORD_COLOR:
+ {
+ if (element != CustomRelation::Element::Relation)
+ throwUnknownPropertyError(token);
+ Value expression = parseProperty();
+ if (expression.type() == Color) {
+ relation.setColorType(CustomRelation::ColorType::Custom);
+ relation.setColor(expression.value().value<QColor>());
+ } else if (expression.type() == Identifier) {
+ QString colorValue = expression.value().toString();
+ QString colorName = colorValue.toLower();
+ if (colorName == "a") {
+ relation.setColorType(CustomRelation::ColorType::EndA);
+ } else if (colorName == "b") {
+ relation.setColorType(CustomRelation::ColorType::EndB);
+ } else if (QColor::isValidColor(colorName)) {
+ relation.setColorType(CustomRelation::ColorType::Custom);
+ relation.setColor(QColor(colorName));
+ } else {
+ throw StereotypeDefinitionParserError(QString("Unexpected value \"%1\" for color.").arg(colorValue), token.sourcePos());
+ }
+ } else {
+ throw StereotypeDefinitionParserError("Unexpected value for color.", token.sourcePos());
+ }
+ break;
+ }
+ case KEYWORD_END:
+ parseRelationEnd(&relation);
+ break;
+ default:
+ throwUnknownPropertyError(token);
+ }
+ if (!expectPropertySeparatorOrBlockEnd())
+ break;
+ }
+ relation.setStereotypes(stereotypes);
+ if (relation.id().isEmpty())
+ throw StereotypeDefinitionParserError("Missing id in Relation definition.", d->m_scanner->sourcePos());
+ emit relationParsed(relation);
+}
+
+void StereotypeDefinitionParser::parseRelationEnd(CustomRelation *relation)
+{
+ CustomRelation::End relationEnd;
+ bool isEndB = false;
+ expectBlockBegin();
+ Token token;
+ while (readProperty(&token)) {
+ switch (token.subtype()) {
+ case KEYWORD_END:
+ {
+ QString endValue = parseIdentifierProperty();
+ QString endName = endValue.toLower();
+ if (endName == "a")
+ isEndB = false;
+ else if (endName == "b")
+ isEndB = true;
+ else
+ throw StereotypeDefinitionParserError(QString("Unexpected value \"%1\" for end.").arg(endValue), token.sourcePos());
+ break;
+ }
+ case KEYWORD_ELEMENTS:
+ if (relation->element() != CustomRelation::Element::Relation)
+ throwUnknownPropertyError(token);
+ relationEnd.setEndItems(parseIdentifierListProperty());
+ break;
+ case KEYWORD_ROLE:
+ if (relation->element() != CustomRelation::Element::Relation && relation->element() != CustomRelation::Element::Association)
+ throwUnknownPropertyError(token);
+ relationEnd.setRole(parseStringProperty());
+ break;
+ case KEYWORD_CARDINALITY:
+ {
+ if (relation->element() != CustomRelation::Element::Relation && relation->element() != CustomRelation::Element::Association)
+ throwUnknownPropertyError(token);
+ Value expression = parseProperty();
+ if (expression.type() == Int || expression.type() == String)
+ relationEnd.setCardinality(expression.value().toString());
+ else
+ throw StereotypeDefinitionParserError("Wrong type for cardinality.", token.sourcePos());
+ break;
+ }
+ case KEYWORD_NAVIGABLE:
+ if (relation->element() != CustomRelation::Element::Relation && relation->element() != CustomRelation::Element::Association)
+ throwUnknownPropertyError(token);
+ relationEnd.setNavigable(parseBoolProperty());
+ break;
+ case KEYWORD_RELATIONSHIP:
+ {
+ if (relation->element() != CustomRelation::Element::Association)
+ throwUnknownPropertyError(token);
+ const static QHash<QString, CustomRelation::Relationship> relationshipNames = QHash<QString, CustomRelation::Relationship>()
+ << qMakePair(QString("association"), CustomRelation::Relationship::Association)
+ << qMakePair(QString("aggregation"), CustomRelation::Relationship::Aggregation)
+ << qMakePair(QString("composition"), CustomRelation::Relationship::Composition);
+ parseEnum<CustomRelation::Relationship>(
+ parseIdentifierProperty(), relationshipNames, token.sourcePos(),
+ [&](CustomRelation::Relationship relationship) { relationEnd.setRelationship(relationship); });
+ break;
+ }
+ case KEYWORD_HEAD:
+ {
+ if (relation->element() != CustomRelation::Element::Relation)
+ throwUnknownPropertyError(token);
+ const static QHash<QString, CustomRelation::Head> headNames = QHash<QString, CustomRelation::Head>()
+ << qMakePair(QString("none"), CustomRelation::Head::None)
+ << qMakePair(QString("arrow"), CustomRelation::Head::Arrow)
+ << qMakePair(QString("triangle"), CustomRelation::Head::Triangle)
+ << qMakePair(QString("filledtriangle"), CustomRelation::Head::FilledTriangle)
+ << qMakePair(QString("diamond"), CustomRelation::Head::Diamond)
+ << qMakePair(QString("filleddiamond"), CustomRelation::Head::FilledDiamond);
+ parseEnum<CustomRelation::Head>(
+ parseIdentifierProperty(), headNames, token.sourcePos(),
+ [&](CustomRelation::Head head) { relationEnd.setHead(head); });
+ break;
+ }
+ case KEYWORD_SHAPE:
+ if (relation->element() != CustomRelation::Element::Relation)
+ throwUnknownPropertyError(token);
+ relationEnd.setHead(CustomRelation::Head::Shape);
+ relationEnd.setShape(parseIconShape());
+ break;
+ default:
+ throwUnknownPropertyError(token);
+ }
+ if (!expectPropertySeparatorOrBlockEnd())
+ break;
+ }
+ if (isEndB)
+ relation->setEndB(relationEnd);
+ else
+ relation->setEndA(relationEnd);
+}
+
void StereotypeDefinitionParser::parseToolbar()
{
Toolbar toolbar;
@@ -507,6 +819,10 @@ void StereotypeDefinitionParser::parseToolbar()
case KEYWORD_PRIORITY:
toolbar.setPriority(parseIntProperty());
break;
+ case KEYWORD_ELEMENT:
+ toolbar.setElementTypes(parseIdentifierListProperty());
+ toolbar.setToolbarType(toolbar.elementTypes().isEmpty() ? Toolbar::ObjectToolbar : Toolbar::RelationToolbar);
+ break;
case KEYWORD_TOOLS:
parseToolbarTools(&toolbar);
break;
@@ -517,7 +833,7 @@ void StereotypeDefinitionParser::parseToolbar()
break;
}
if (toolbar.id().isEmpty())
- throw StereotypeDefinitionParserError(QStringLiteral("Missing id in Toolbar definition."), d->m_scanner->sourcePos());
+ throw StereotypeDefinitionParserError("Missing id in Toolbar definition.", d->m_scanner->sourcePos());
emit toolbarParsed(toolbar);
}
@@ -532,7 +848,7 @@ void StereotypeDefinitionParser::parseToolbarTools(Toolbar *toolbar)
{
Toolbar::Tool tool;
tool.m_toolType = Toolbar::TooltypeTool;
- parseToolbarTool(&tool);
+ parseToolbarTool(toolbar, &tool);
tools.append(tool);
break;
}
@@ -549,7 +865,7 @@ void StereotypeDefinitionParser::parseToolbarTools(Toolbar *toolbar)
toolbar->setTools(tools);
}
-void StereotypeDefinitionParser::parseToolbarTool(Toolbar::Tool *tool)
+void StereotypeDefinitionParser::parseToolbarTool(const Toolbar *toolbar, Toolbar::Tool *tool)
{
expectBlockBegin();
Token token;
@@ -561,17 +877,30 @@ void StereotypeDefinitionParser::parseToolbarTool(Toolbar::Tool *tool)
case KEYWORD_ELEMENT:
{
QString element = parseIdentifierProperty();
- static QSet<QString> elementNames = QSet<QString>()
- << QStringLiteral("package")
- << QStringLiteral("component")
- << QStringLiteral("class")
- << QStringLiteral("item")
- << QStringLiteral("annotation")
- << QStringLiteral("boundary");
- QString elementName = element.toLower();
- if (!elementNames.contains(elementName))
- throw StereotypeDefinitionParserError(QString(QStringLiteral("Unexpected value \"%1\" for element.")).arg(element), token.sourcePos());
- tool->m_elementType = elementName;
+ if (toolbar->toolbarType() == Toolbar::ObjectToolbar) {
+ static QSet<QString> elementNames = QSet<QString>()
+ << "package"
+ << "component"
+ << "class"
+ << "item"
+ << "annotation"
+ << "boundary"
+ << "swimlane";
+ QString elementName = element.toLower();
+ if (!elementNames.contains(elementName))
+ throw StereotypeDefinitionParserError(QString("Unexpected value \"%1\" for element.").arg(element), token.sourcePos());
+ tool->m_elementType = elementName;
+ } else {
+ static QSet<QString> relationNames = QSet<QString>()
+ << "dependency"
+ << "inheritance"
+ << "association";
+ QString relationName = element.toLower();
+ if (relationNames.contains(relationName))
+ tool->m_elementType = relationName;
+ else
+ tool->m_elementType = element;
+ }
break;
}
case KEYWORD_STEREOTYPE:
@@ -585,6 +914,28 @@ void StereotypeDefinitionParser::parseToolbarTool(Toolbar::Tool *tool)
}
}
+template<typename T>
+void StereotypeDefinitionParser::parseEnums(const QList<QString> &identifiers,
+ const QHash<QString, T> &identifierNames,
+ const SourcePos &sourcePos,
+ std::function<void (T)> setter)
+{
+ for (const QString &identifier : identifiers)
+ parseEnum(identifier, identifierNames, sourcePos, setter);
+}
+
+template<typename T>
+void StereotypeDefinitionParser::parseEnum(const QString &identifier,
+ const QHash<QString, T> &identifierNames,
+ const SourcePos &sourcePos,
+ std::function<void (T)> setter)
+{
+ const QString name = identifier.toLower();
+ if (!identifierNames.contains(name))
+ throw StereotypeDefinitionParserError(QString("Unexpected value \"%1\".").arg(identifier), sourcePos);
+ setter(identifierNames.value(name));
+}
+
QString StereotypeDefinitionParser::parseStringProperty()
{
expectColon();
@@ -616,7 +967,7 @@ QList<QString> StereotypeDefinitionParser::parseIdentifierListProperty()
for (;;) {
Token token = d->m_scanner->read();
if (token.type() != Token::TokenIdentifier && token.type() != Token::TokenKeyword) {
- throw StereotypeDefinitionParserError(QStringLiteral("Expected identifier."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Expected identifier.", token.sourcePos());
}
identifiers.append(token.text());
token = d->m_scanner->read();
@@ -640,11 +991,17 @@ QColor StereotypeDefinitionParser::parseColorProperty()
return parseColorExpression();
}
+StereotypeDefinitionParser::Value StereotypeDefinitionParser::parseProperty()
+{
+ expectColon();
+ return parseExpression();
+}
+
QString StereotypeDefinitionParser::parseStringExpression()
{
Token token = d->m_scanner->read();
if (token.type() != Token::TokenString)
- throw StereotypeDefinitionParserError(QStringLiteral("Expected string constant."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Expected string constant.", token.sourcePos());
return token.text();
}
@@ -665,7 +1022,7 @@ qreal StereotypeDefinitionParser::parseFloatExpression()
QMT_CHECK(ok);
return value;
} else {
- throw StereotypeDefinitionParserError(QStringLiteral("Expected number constant."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Expected number constant.", token.sourcePos());
}
}
}
@@ -683,7 +1040,7 @@ int StereotypeDefinitionParser::parseIntExpression()
QMT_CHECK(ok);
return value;
} else {
- throw StereotypeDefinitionParserError(QStringLiteral("Expected integer constant."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Expected integer constant.", token.sourcePos());
}
}
}
@@ -692,7 +1049,7 @@ QString StereotypeDefinitionParser::parseIdentifierExpression()
{
Token token = d->m_scanner->read();
if (token.type() != Token::TokenIdentifier && token.type() != Token::TokenKeyword)
- throw StereotypeDefinitionParserError(QStringLiteral("Expected identifier."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Expected identifier.", token.sourcePos());
return token.text();
}
@@ -701,12 +1058,12 @@ bool StereotypeDefinitionParser::parseBoolExpression()
Token token = d->m_scanner->read();
if (token.type() == Token::TokenIdentifier) {
QString value = token.text().toLower();
- if (value == QStringLiteral("yes") || value == QStringLiteral("true"))
+ if (value == "yes" || value == "true")
return true;
- else if (value == QStringLiteral("no") || value == QStringLiteral("false"))
+ else if (value == "no" || value == "false")
return false;
}
- throw StereotypeDefinitionParserError(QStringLiteral("Expected 'yes', 'no', 'true' or 'false'."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Expected 'yes', 'no', 'true' or 'false'.", token.sourcePos());
}
QColor StereotypeDefinitionParser::parseColorExpression()
@@ -720,13 +1077,57 @@ QColor StereotypeDefinitionParser::parseColorExpression()
return color;
}
}
- throw StereotypeDefinitionParserError(QStringLiteral("Expected color name."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Expected color name.", token.sourcePos());
+}
+
+StereotypeDefinitionParser::Value StereotypeDefinitionParser::parseExpression()
+{
+ Token token = d->m_scanner->read();
+ if (token.type() == Token::TokenString) {
+ return Value(String, QVariant(token.text()));
+ } else if (token.type() == Token::TokenOperator && token.subtype() == OPERATOR_MINUS) {
+ Value v = parseExpression();
+ if (v.type() == Int)
+ return Value(Int, QVariant(-v.value().toInt()));
+ else if (v.type() == Float)
+ return Value(Float, QVariant(-v.value().toDouble()));
+ else
+ throw StereotypeDefinitionParserError("Illegal number expression.", token.sourcePos());
+ } else if (token.type() == Token::TokenInteger) {
+ bool ok = false;
+ int value = token.text().toInt(&ok);
+ QMT_CHECK(ok);
+ return Value(Int, QVariant(value));
+ } else if (token.type() == Token::TokenFloat) {
+ bool ok = false;
+ qreal value = token.text().toDouble(&ok);
+ QMT_CHECK(ok);
+ return Value(Float, QVariant(value));
+ } else if (token.type() == Token::TokenColor) {
+ QString value = token.text().toLower();
+ QColor color;
+ if (QColor::isValidColor(value)) {
+ color.setNamedColor(value);
+ return Value(Color, QVariant(color));
+ } else {
+ throw StereotypeDefinitionParserError("Invalid color.", token.sourcePos());
+ }
+ } else if (token.type() == Token::TokenIdentifier || token.type() == Token::TokenKeyword) {
+ QString value = token.text().toLower();
+ if (value == "yes" || value == "true")
+ return Value(Boolean, QVariant(true));
+ else if (value == "no" || value == "false")
+ return Value(Boolean, QVariant(false));
+ else
+ return Value(Identifier, QVariant(token.text()));
+ }
+ throw StereotypeDefinitionParserError("Syntax error in expression.", token.sourcePos());
}
void StereotypeDefinitionParser::expectBlockBegin()
{
skipEOLTokens();
- expectOperator(OPERATOR_BRACE_OPEN, QStringLiteral("{"));
+ expectOperator(OPERATOR_BRACE_OPEN, "{");
}
bool StereotypeDefinitionParser::readProperty(Token *token)
@@ -739,13 +1140,13 @@ bool StereotypeDefinitionParser::readProperty(Token *token)
else if (token->type() == Token::TokenIdentifier)
throwUnknownPropertyError(*token);
else
- throw StereotypeDefinitionParserError(QStringLiteral("Syntax error."), token->sourcePos());
+ throw StereotypeDefinitionParserError("Syntax error.", token->sourcePos());
return false; // will never be reached but avoids compiler warning
}
void StereotypeDefinitionParser::throwUnknownPropertyError(const Token &token)
{
- throw StereotypeDefinitionParserError(QString(QStringLiteral("Unknown property '%1'.")).arg(token.text()), token.sourcePos());
+ throw StereotypeDefinitionParserError(QString("Unknown property '%1'.").arg(token.text()), token.sourcePos());
}
bool StereotypeDefinitionParser::expectPropertySeparatorOrBlockEnd()
@@ -764,7 +1165,7 @@ bool StereotypeDefinitionParser::expectPropertySeparatorOrBlockEnd()
else
d->m_scanner->unread(token);
if (!ok)
- throw StereotypeDefinitionParserError(QStringLiteral("Expected ';', '}' or end-of-line."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Expected ';', '}' or end-of-line.", token.sourcePos());
return true;
}
@@ -782,7 +1183,7 @@ void StereotypeDefinitionParser::skipOptionalEmptyBlock()
if (isOperator(token, OPERATOR_BRACE_OPEN)) {
token = readNextToken();
if (!isOperator(token, OPERATOR_BRACE_CLOSE))
- throw StereotypeDefinitionParserError(QStringLiteral("Expected '}' in empty block."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Expected '}' in empty block.", token.sourcePos());
} else {
d->m_scanner->unread(token);
d->m_scanner->unread(eolToken);
@@ -790,7 +1191,7 @@ void StereotypeDefinitionParser::skipOptionalEmptyBlock()
} else if (isOperator(token, OPERATOR_BRACE_OPEN)) {
token = readNextToken();
if (!isOperator(token, OPERATOR_BRACE_CLOSE))
- throw StereotypeDefinitionParserError(QStringLiteral("Expected '}' in empty block."), token.sourcePos());
+ throw StereotypeDefinitionParserError("Expected '}' in empty block.", token.sourcePos());
} else {
d->m_scanner->unread(token);
}
@@ -799,7 +1200,7 @@ void StereotypeDefinitionParser::skipOptionalEmptyBlock()
qreal StereotypeDefinitionParser::expectAbsoluteValue(const ShapeValueF &value, const SourcePos &sourcePos)
{
if (value.unit() != ShapeValueF::UnitAbsolute || value.origin() != ShapeValueF::OriginSmart)
- throw StereotypeDefinitionParserError(QStringLiteral("Expected absolute value"), sourcePos);
+ throw StereotypeDefinitionParserError("Expected absolute value", sourcePos);
return value.value();
}
@@ -812,12 +1213,12 @@ void StereotypeDefinitionParser::expectOperator(int op, const QString &opName)
{
Token token = d->m_scanner->read();
if (!isOperator(token, op))
- throw StereotypeDefinitionParserError(QString(QStringLiteral("Expected '%1'.")).arg(opName), token.sourcePos());
+ throw StereotypeDefinitionParserError(QString("Expected '%1'.").arg(opName), token.sourcePos());
}
void StereotypeDefinitionParser::expectColon()
{
- expectOperator(OPERATOR_COLON, QStringLiteral(":"));
+ expectOperator(OPERATOR_COLON, ":");
}
void StereotypeDefinitionParser::skipEOLTokens()
diff --git a/src/libs/modelinglib/qmt/config/stereotypedefinitionparser.h b/src/libs/modelinglib/qmt/config/stereotypedefinitionparser.h
index 390ab4424e9..2a25e70b095 100644
--- a/src/libs/modelinglib/qmt/config/stereotypedefinitionparser.h
+++ b/src/libs/modelinglib/qmt/config/stereotypedefinitionparser.h
@@ -27,12 +27,14 @@
#include <QObject>
#include "qmt/infrastructure/exceptions.h"
+#include "qmt/stereotype/customrelation.h"
#include "qmt/stereotype/toolbar.h"
#include "sourcepos.h"
#include <QPair>
#include <QHash>
+#include <functional>
namespace qmt {
@@ -59,13 +61,25 @@ class QMT_EXPORT StereotypeDefinitionParser : public QObject
Q_OBJECT
class StereotypeDefinitionParserPrivate;
class IconCommandParameter;
+ class Value;
+
+ enum Type {
+ Void,
+ Identifier,
+ String,
+ Int,
+ Float,
+ Boolean,
+ Color
+ };
public:
- explicit StereotypeDefinitionParser(QObject *parent = 0);
+ explicit StereotypeDefinitionParser(QObject *parent = nullptr);
~StereotypeDefinitionParser() override;
signals:
void iconParsed(const StereotypeIcon &stereotypeIcon);
+ void relationParsed(const CustomRelation &relation);
void toolbarParsed(const Toolbar &toolbar);
public:
@@ -78,12 +92,24 @@ private:
static QPair<int, IconCommandParameter> SCALED(int keyword);
static QPair<int, IconCommandParameter> FIX(int keyword);
static QPair<int, IconCommandParameter> ABSOLUTE(int keyword);
- void parseIconShape(StereotypeIcon *stereotypeIcon);
- QHash<int, ShapeValueF> parseIconShapeProperties(const QHash<int, IconCommandParameter> &parameters);
+ static QPair<int, IconCommandParameter> BOOLEAN(int keyword);
+ IconShape parseIconShape();
+ QHash<int, IconCommandParameter> parseIconShapeProperties(const QHash<int, IconCommandParameter> &parameters);
+
+ void parseRelation(CustomRelation::Element element);
+ void parseRelationEnd(CustomRelation *relation);
void parseToolbar();
void parseToolbarTools(Toolbar *toolbar);
- void parseToolbarTool(Toolbar::Tool *tool);
+ void parseToolbarTool(const Toolbar *toolbar, Toolbar::Tool *tool);
+
+ template<typename T>
+ void parseEnums(const QList<QString> &identifiers, const QHash<QString, T> &identifierNames,
+ const SourcePos &sourcePos, std::function<void(T)> setter);
+
+ template<typename T>
+ void parseEnum(const QString &identifier, const QHash<QString, T> &identifierNames,
+ const SourcePos &sourcePos, std::function<void(T)> setter);
QString parseStringProperty();
int parseIntProperty();
@@ -92,6 +118,7 @@ private:
QList<QString> parseIdentifierListProperty();
bool parseBoolProperty();
QColor parseColorProperty();
+ Value parseProperty();
QString parseStringExpression();
qreal parseFloatExpression();
@@ -99,6 +126,7 @@ private:
QString parseIdentifierExpression();
bool parseBoolExpression();
QColor parseColorExpression();
+ Value parseExpression();
void expectBlockBegin();
bool readProperty(Token *token);
diff --git a/src/libs/modelinglib/qmt/config/stringtextsource.cpp b/src/libs/modelinglib/qmt/config/stringtextsource.cpp
index d62575ffa64..bf7a6b92190 100644
--- a/src/libs/modelinglib/qmt/config/stringtextsource.cpp
+++ b/src/libs/modelinglib/qmt/config/stringtextsource.cpp
@@ -31,10 +31,6 @@
namespace qmt {
StringTextSource::StringTextSource()
- : m_sourceId(-1),
- m_index(-1),
- m_lineNumber(-1),
- m_columnNumber(-1)
{
}
@@ -57,10 +53,10 @@ void StringTextSource::setSourceId(int sourceId)
SourceChar StringTextSource::readNextChar()
{
- QMT_CHECK(m_sourceId >= 0);
- QMT_CHECK(m_index >= 0);
- QMT_CHECK(m_lineNumber >= 0);
- QMT_CHECK(m_columnNumber >= 0);
+ QMT_ASSERT(m_sourceId >= 0, return SourceChar());
+ QMT_ASSERT(m_index >= 0, return SourceChar());
+ QMT_ASSERT(m_lineNumber >= 0, return SourceChar());
+ QMT_ASSERT(m_columnNumber >= 0, return SourceChar());
if (m_index >= m_text.length())
return SourceChar(QChar(), SourcePos(m_sourceId, m_lineNumber, m_columnNumber));
diff --git a/src/libs/modelinglib/qmt/config/stringtextsource.h b/src/libs/modelinglib/qmt/config/stringtextsource.h
index 01301ca6cde..5cfcc32a5d7 100644
--- a/src/libs/modelinglib/qmt/config/stringtextsource.h
+++ b/src/libs/modelinglib/qmt/config/stringtextsource.h
@@ -46,10 +46,10 @@ public:
private:
QString m_text;
- int m_sourceId;
- int m_index;
- int m_lineNumber;
- int m_columnNumber;
+ int m_sourceId = -1;
+ int m_index = -1;
+ int m_lineNumber = -1;
+ int m_columnNumber = -1;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/config/textscanner.cpp b/src/libs/modelinglib/qmt/config/textscanner.cpp
index 80c13c80d0a..32e3d937c10 100644
--- a/src/libs/modelinglib/qmt/config/textscanner.cpp
+++ b/src/libs/modelinglib/qmt/config/textscanner.cpp
@@ -57,7 +57,7 @@ public:
int m_maxOperatorLength = 0;
QSet<QChar> m_operatorFirstCharsSet;
QSet<QChar> m_operatorCharsSet;
- ITextSource *m_source = 0;
+ ITextSource *m_source = nullptr;
QStack<SourceChar> m_unreadSourceChars;
SourcePos m_lastSourcePos;
QStack<Token> m_unreadTokens;
@@ -129,7 +129,7 @@ Token TextScanner::read()
else if (d->m_operatorFirstCharsSet.contains(sourceChar.ch))
return scanOperator(sourceChar);
else
- throw TextScannerError(QStringLiteral("Unexpected character."), sourceChar.pos);
+ throw TextScannerError("Unexpected character.", sourceChar.pos);
}
void TextScanner::unread(const Token &token)
@@ -201,9 +201,9 @@ Token TextScanner::scanString(const SourceChar &delimiterChar)
else if (sourceChar.ch == QLatin1Char('\''))
text += QLatin1Char('\'');
else
- throw TextScannerError(QStringLiteral("Unexpected character after '\\' in string constant."), sourceChar.pos);
+ throw TextScannerError("Unexpected character after '\\' in string constant.", sourceChar.pos);
} else if (sourceChar.ch == QChar::LineFeed || sourceChar.ch == QChar::CarriageReturn) {
- throw TextScannerError(QStringLiteral("Unexpected end of line in string constant."), sourceChar.pos);
+ throw TextScannerError("Unexpected end of line in string constant.", sourceChar.pos);
} else {
text += sourceChar.ch;
}
diff --git a/src/libs/modelinglib/qmt/config/textscanner.h b/src/libs/modelinglib/qmt/config/textscanner.h
index de682a65c46..941a3a5b3e3 100644
--- a/src/libs/modelinglib/qmt/config/textscanner.h
+++ b/src/libs/modelinglib/qmt/config/textscanner.h
@@ -55,7 +55,7 @@ class QMT_EXPORT TextScanner : public QObject
class TextScannerPrivate;
public:
- explicit TextScanner(QObject *parent = 0);
+ explicit TextScanner(QObject *parent = nullptr);
~TextScanner() override;
void setKeywords(const QList<QPair<QString, int> > &keywords);
diff --git a/src/libs/modelinglib/qmt/config/token.cpp b/src/libs/modelinglib/qmt/config/token.cpp
index 9ef1ee2bd81..8c740f95be8 100644
--- a/src/libs/modelinglib/qmt/config/token.cpp
+++ b/src/libs/modelinglib/qmt/config/token.cpp
@@ -46,10 +46,6 @@ Token::Token(Token::Type type, int subtype, const QString &text, const SourcePos
{
}
-Token::~Token()
-{
-}
-
void Token::setType(Token::Type type)
{
m_type = type;
diff --git a/src/libs/modelinglib/qmt/config/token.h b/src/libs/modelinglib/qmt/config/token.h
index 8672c0ea1d8..dd9888795ce 100644
--- a/src/libs/modelinglib/qmt/config/token.h
+++ b/src/libs/modelinglib/qmt/config/token.h
@@ -50,7 +50,6 @@ public:
Token();
Token(Type type, const QString &text, const SourcePos &sourcePos);
Token(Type type, int subtype, const QString &text, const SourcePos &sourcePos);
- ~Token();
Type type() const { return m_type; }
void setType(Type type);
diff --git a/src/libs/modelinglib/qmt/controller/namecontroller.cpp b/src/libs/modelinglib/qmt/controller/namecontroller.cpp
index 2285fb39716..c2c23c772ab 100644
--- a/src/libs/modelinglib/qmt/controller/namecontroller.cpp
+++ b/src/libs/modelinglib/qmt/controller/namecontroller.cpp
@@ -135,11 +135,11 @@ QStringList NameController::buildElementsPath(const QString &filePath, bool igno
{
QList<QString> relativeElements;
- QStringList splitted = filePath.split(QStringLiteral("/"));
- QStringList::const_iterator splittedEnd = splitted.end();
- if (ignoreLastFilePathPart || splitted.last().isEmpty())
- splittedEnd = --splittedEnd;
- for (auto it = splitted.cbegin(); it != splittedEnd; ++it) {
+ QStringList split = filePath.split("/");
+ QStringList::const_iterator splitEnd = split.end();
+ if (ignoreLastFilePathPart || split.last().isEmpty())
+ splitEnd = --splitEnd;
+ for (auto it = split.cbegin(); it != splitEnd; ++it) {
QString packageName = qmt::NameController::convertFileNameToElementName(*it);
relativeElements.append(packageName);
}
diff --git a/src/libs/modelinglib/qmt/controller/namecontroller.h b/src/libs/modelinglib/qmt/controller/namecontroller.h
index ec77165695c..50ed023d201 100644
--- a/src/libs/modelinglib/qmt/controller/namecontroller.h
+++ b/src/libs/modelinglib/qmt/controller/namecontroller.h
@@ -38,7 +38,7 @@ class QMT_EXPORT NameController : public QObject
Q_OBJECT
private:
- explicit NameController(QObject *parent = 0);
+ explicit NameController(QObject *parent = nullptr);
~NameController() override;
public:
diff --git a/src/libs/modelinglib/qmt/controller/undocommand.cpp b/src/libs/modelinglib/qmt/controller/undocommand.cpp
index eea123a9424..40348d3f86c 100644
--- a/src/libs/modelinglib/qmt/controller/undocommand.cpp
+++ b/src/libs/modelinglib/qmt/controller/undocommand.cpp
@@ -30,9 +30,7 @@
namespace qmt {
UndoCommand::UndoCommand(const QString &text)
- : QUndoCommand(text),
- m_canRedo(false),
- m_doNotMerge(false)
+ : QUndoCommand(text)
{
}
diff --git a/src/libs/modelinglib/qmt/controller/undocommand.h b/src/libs/modelinglib/qmt/controller/undocommand.h
index 52cd00b7078..aa96cd7430c 100644
--- a/src/libs/modelinglib/qmt/controller/undocommand.h
+++ b/src/libs/modelinglib/qmt/controller/undocommand.h
@@ -47,8 +47,8 @@ public:
void redo() override;
private:
- bool m_canRedo;
- bool m_doNotMerge;
+ bool m_canRedo = false;
+ bool m_doNotMerge = false;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/controller/undocontroller.cpp b/src/libs/modelinglib/qmt/controller/undocontroller.cpp
index 85475d55cc8..a9940291417 100644
--- a/src/libs/modelinglib/qmt/controller/undocontroller.cpp
+++ b/src/libs/modelinglib/qmt/controller/undocontroller.cpp
@@ -33,8 +33,7 @@ namespace qmt {
UndoController::UndoController(QObject *parent) :
QObject(parent),
- m_undoStack(new QUndoStack(this)),
- m_doNotMerge(false)
+ m_undoStack(new QUndoStack(this))
{
}
diff --git a/src/libs/modelinglib/qmt/controller/undocontroller.h b/src/libs/modelinglib/qmt/controller/undocontroller.h
index 7a3e162d1b4..8179493a55e 100644
--- a/src/libs/modelinglib/qmt/controller/undocontroller.h
+++ b/src/libs/modelinglib/qmt/controller/undocontroller.h
@@ -41,7 +41,7 @@ class QMT_EXPORT UndoController : public QObject
Q_OBJECT
public:
- explicit UndoController(QObject *parent = 0);
+ explicit UndoController(QObject *parent = nullptr);
~UndoController() override;
QUndoStack *undoStack() const { return m_undoStack; }
@@ -54,8 +54,8 @@ public:
void doNotMerge();
private:
- QUndoStack *m_undoStack;
- bool m_doNotMerge;
+ QUndoStack *m_undoStack = nullptr;
+ bool m_doNotMerge = false;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram/dannotation.cpp b/src/libs/modelinglib/qmt/diagram/dannotation.cpp
index cae6d96eb22..2a7787c7b58 100644
--- a/src/libs/modelinglib/qmt/diagram/dannotation.cpp
+++ b/src/libs/modelinglib/qmt/diagram/dannotation.cpp
@@ -31,9 +31,7 @@
namespace qmt {
DAnnotation::DAnnotation()
- : DElement(),
- m_visualRole(RoleNormal),
- m_isAutoSized(true)
+ : DElement()
{
}
diff --git a/src/libs/modelinglib/qmt/diagram/dannotation.h b/src/libs/modelinglib/qmt/diagram/dannotation.h
index fe1e57d37d2..f0080820e5d 100644
--- a/src/libs/modelinglib/qmt/diagram/dannotation.h
+++ b/src/libs/modelinglib/qmt/diagram/dannotation.h
@@ -69,8 +69,8 @@ private:
QString m_text;
QPointF m_pos;
QRectF m_rect;
- VisualRole m_visualRole;
- bool m_isAutoSized;
+ VisualRole m_visualRole = RoleNormal;
+ bool m_isAutoSized = true;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram/dassociation.cpp b/src/libs/modelinglib/qmt/diagram/dassociation.cpp
index 1c62bd388f9..f1c2ea9b521 100644
--- a/src/libs/modelinglib/qmt/diagram/dassociation.cpp
+++ b/src/libs/modelinglib/qmt/diagram/dassociation.cpp
@@ -31,8 +31,6 @@
namespace qmt {
DAssociationEnd::DAssociationEnd()
- : m_kind(MAssociationEnd::Association),
- m_isNavigable(false)
{
}
diff --git a/src/libs/modelinglib/qmt/diagram/dassociation.h b/src/libs/modelinglib/qmt/diagram/dassociation.h
index 1da72c36b5b..7c914272e58 100644
--- a/src/libs/modelinglib/qmt/diagram/dassociation.h
+++ b/src/libs/modelinglib/qmt/diagram/dassociation.h
@@ -49,8 +49,8 @@ public:
private:
QString m_name;
QString m_cardinality;
- MAssociationEnd::Kind m_kind;
- bool m_isNavigable;
+ MAssociationEnd::Kind m_kind = MAssociationEnd::Association;
+ bool m_isNavigable = false;
};
diff --git a/src/libs/modelinglib/qmt/diagram/dclass.cpp b/src/libs/modelinglib/qmt/diagram/dclass.cpp
index 56337a998ef..92103439c5f 100644
--- a/src/libs/modelinglib/qmt/diagram/dclass.cpp
+++ b/src/libs/modelinglib/qmt/diagram/dclass.cpp
@@ -31,8 +31,6 @@
namespace qmt {
DClass::DClass()
- : m_templateDisplay(TemplateSmart),
- m_showAllMembers(false)
{
}
diff --git a/src/libs/modelinglib/qmt/diagram/dclass.h b/src/libs/modelinglib/qmt/diagram/dclass.h
index c86d8b335cc..159c79a940e 100644
--- a/src/libs/modelinglib/qmt/diagram/dclass.h
+++ b/src/libs/modelinglib/qmt/diagram/dclass.h
@@ -65,8 +65,8 @@ private:
QList<QString> m_templateParameters;
QList<MClassMember> m_members;
QSet<Uid> m_visibleMembers;
- TemplateDisplay m_templateDisplay;
- bool m_showAllMembers;
+ TemplateDisplay m_templateDisplay = TemplateSmart;
+ bool m_showAllMembers = false;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram/dcomponent.cpp b/src/libs/modelinglib/qmt/diagram/dcomponent.cpp
index 4bee3ad9b95..4fe05aa8a64 100644
--- a/src/libs/modelinglib/qmt/diagram/dcomponent.cpp
+++ b/src/libs/modelinglib/qmt/diagram/dcomponent.cpp
@@ -31,8 +31,6 @@
namespace qmt {
DComponent::DComponent()
- : DObject(),
- m_isPlainShape(false)
{
}
diff --git a/src/libs/modelinglib/qmt/diagram/dcomponent.h b/src/libs/modelinglib/qmt/diagram/dcomponent.h
index 03ef43ecdbe..c3602a10154 100644
--- a/src/libs/modelinglib/qmt/diagram/dcomponent.h
+++ b/src/libs/modelinglib/qmt/diagram/dcomponent.h
@@ -42,7 +42,7 @@ public:
void accept(DConstVisitor *visitor) const override;
private:
- bool m_isPlainShape;
+ bool m_isPlainShape = false;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram/dconnection.cpp b/src/libs/modelinglib/qmt/diagram/dconnection.cpp
new file mode 100644
index 00000000000..a5611795fc0
--- /dev/null
+++ b/src/libs/modelinglib/qmt/diagram/dconnection.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Jochen Becher
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "dconnection.h"
+
+#include "dvisitor.h"
+#include "dconstvisitor.h"
+
+namespace qmt {
+
+DConnectionEnd::DConnectionEnd()
+{
+}
+
+DConnectionEnd::~DConnectionEnd()
+{
+}
+
+void DConnectionEnd::setName(const QString &name)
+{
+ m_name = name;
+}
+
+void DConnectionEnd::setCardinatlity(const QString &cardinality)
+{
+ m_cardinality = cardinality;
+}
+
+void DConnectionEnd::setNavigable(bool navigable)
+{
+ m_isNavigable = navigable;
+}
+
+bool operator==(const DConnectionEnd &lhs, const DConnectionEnd &rhs)
+{
+ if (&lhs == &rhs)
+ return true;
+ return lhs.name() == rhs.name()
+ && lhs.cardinality() == rhs.cardinality()
+ && lhs.isNavigable() == rhs.isNavigable();
+}
+
+bool operator!=(const DConnectionEnd &lhs, const DConnectionEnd &rhs)
+{
+ return !operator==(lhs, rhs);
+}
+
+DConnection::DConnection()
+{
+}
+
+DConnection::~DConnection()
+{
+}
+
+void DConnection::setCustomRelationId(const QString &customRelationId)
+{
+ m_customRelationId = customRelationId;
+}
+
+void DConnection::setEndA(const DConnectionEnd &endA)
+{
+ m_endA = endA;
+}
+
+void DConnection::setEndB(const DConnectionEnd &endB)
+{
+ m_endB = endB;
+}
+
+void DConnection::accept(DVisitor *visitor)
+{
+ visitor->visitDConnection(this);
+}
+
+void DConnection::accept(DConstVisitor *visitor) const
+{
+ visitor->visitDConnection(this);
+}
+
+} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram/dconnection.h b/src/libs/modelinglib/qmt/diagram/dconnection.h
new file mode 100644
index 00000000000..4100142eeff
--- /dev/null
+++ b/src/libs/modelinglib/qmt/diagram/dconnection.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Jochen Becher
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "drelation.h"
+
+#include "qmt/model/mconnection.h"
+
+namespace qmt {
+
+class QMT_EXPORT DConnectionEnd
+{
+public:
+ DConnectionEnd();
+ ~DConnectionEnd();
+
+ QString name() const { return m_name; }
+ void setName(const QString &name);
+ QString cardinality() const { return m_cardinality; }
+ void setCardinatlity(const QString &cardinality);
+ bool isNavigable() const { return m_isNavigable; }
+ void setNavigable(bool navigable);
+
+private:
+ QString m_name;
+ QString m_cardinality;
+ bool m_isNavigable = false;
+};
+
+bool operator==(const DConnectionEnd &lhs, const DConnectionEnd &rhs);
+bool operator!=(const DConnectionEnd &lhs, const DConnectionEnd &rhs);
+
+class QMT_EXPORT DConnection : public DRelation
+{
+public:
+ DConnection();
+ ~DConnection() override;
+
+ QString customRelationId() const { return m_customRelationId; }
+ void setCustomRelationId(const QString &customRelationId);
+ DConnectionEnd endA() const { return m_endA; }
+ void setEndA(const DConnectionEnd &endA);
+ DConnectionEnd endB() const { return m_endB; }
+ void setEndB(const DConnectionEnd &endB);
+
+ void accept(DVisitor *visitor) override;
+ void accept(DConstVisitor *visitor) const override;
+
+private:
+ QString m_customRelationId;
+ DConnectionEnd m_endA;
+ DConnectionEnd m_endB;
+};
+
+} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram/dconstvisitor.h b/src/libs/modelinglib/qmt/diagram/dconstvisitor.h
index 23bdb91d58d..a8f6032aa57 100644
--- a/src/libs/modelinglib/qmt/diagram/dconstvisitor.h
+++ b/src/libs/modelinglib/qmt/diagram/dconstvisitor.h
@@ -38,8 +38,10 @@ class DRelation;
class DInheritance;
class DDependency;
class DAssociation;
+class DConnection;
class DAnnotation;
class DBoundary;
+class DSwimlane;
class DConstVisitor
{
@@ -57,8 +59,10 @@ public:
virtual void visitDInheritance(const DInheritance *inheritance) = 0;
virtual void visitDDependency(const DDependency *dependency) = 0;
virtual void visitDAssociation(const DAssociation *association) = 0;
+ virtual void visitDConnection(const DConnection *connection) = 0;
virtual void visitDAnnotation(const DAnnotation *annotation) = 0;
virtual void visitDBoundary(const DBoundary *boundary) = 0;
+ virtual void visitDSwimlane(const DSwimlane *swimlane) = 0;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram/ddependency.cpp b/src/libs/modelinglib/qmt/diagram/ddependency.cpp
index 8706ebc4ff3..1a0e5136c9c 100644
--- a/src/libs/modelinglib/qmt/diagram/ddependency.cpp
+++ b/src/libs/modelinglib/qmt/diagram/ddependency.cpp
@@ -31,7 +31,6 @@
namespace qmt {
DDependency::DDependency()
- : m_direction(MDependency::AToB)
{
}
diff --git a/src/libs/modelinglib/qmt/diagram/ddependency.h b/src/libs/modelinglib/qmt/diagram/ddependency.h
index 7c3c712452b..6542379a0bb 100644
--- a/src/libs/modelinglib/qmt/diagram/ddependency.h
+++ b/src/libs/modelinglib/qmt/diagram/ddependency.h
@@ -50,7 +50,7 @@ public:
void accept(DConstVisitor *visitor) const override;
private:
- MDependency::Direction m_direction;
+ MDependency::Direction m_direction = MDependency::AToB;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram/ditem.cpp b/src/libs/modelinglib/qmt/diagram/ditem.cpp
index d9a33dc6026..3c7241575f2 100644
--- a/src/libs/modelinglib/qmt/diagram/ditem.cpp
+++ b/src/libs/modelinglib/qmt/diagram/ditem.cpp
@@ -31,8 +31,6 @@
namespace qmt {
DItem::DItem()
- : DObject(),
- m_isShapeEditable(true)
{
}
diff --git a/src/libs/modelinglib/qmt/diagram/ditem.h b/src/libs/modelinglib/qmt/diagram/ditem.h
index 7782e9497d6..e6c184bf338 100644
--- a/src/libs/modelinglib/qmt/diagram/ditem.h
+++ b/src/libs/modelinglib/qmt/diagram/ditem.h
@@ -48,7 +48,7 @@ public:
private:
QString m_variety;
QString m_shape;
- bool m_isShapeEditable;
+ bool m_isShapeEditable = true;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram/dobject.cpp b/src/libs/modelinglib/qmt/diagram/dobject.cpp
index 4405b165549..4111ba929e5 100644
--- a/src/libs/modelinglib/qmt/diagram/dobject.cpp
+++ b/src/libs/modelinglib/qmt/diagram/dobject.cpp
@@ -31,14 +31,6 @@
namespace qmt {
DObject::DObject()
- : DElement(),
- m_modelUid(Uid::invalidUid()),
- m_depth(0),
- m_visualPrimaryRole(PrimaryRoleNormal),
- m_visualSecondaryRole(SecondaryRoleNone),
- m_stereotypeDisplay(StereotypeSmart),
- m_isAutoSized(true),
- m_isVisualEmphasized(false)
{
}
diff --git a/src/libs/modelinglib/qmt/diagram/dobject.h b/src/libs/modelinglib/qmt/diagram/dobject.h
index 6e5f85358a8..17d22488ab5 100644
--- a/src/libs/modelinglib/qmt/diagram/dobject.h
+++ b/src/libs/modelinglib/qmt/diagram/dobject.h
@@ -104,18 +104,18 @@ public:
void accept(DConstVisitor *visitor) const override;
private:
- Uid m_modelUid;
+ Uid m_modelUid = Uid::invalidUid();
QList<QString> m_stereotypes;
QString m_context;
QString m_name;
QPointF m_pos;
QRectF m_rect;
- int m_depth;
- VisualPrimaryRole m_visualPrimaryRole;
- VisualSecondaryRole m_visualSecondaryRole;
- StereotypeDisplay m_stereotypeDisplay;
- bool m_isAutoSized;
- bool m_isVisualEmphasized;
+ int m_depth = 0;
+ VisualPrimaryRole m_visualPrimaryRole = PrimaryRoleNormal;
+ VisualSecondaryRole m_visualSecondaryRole = SecondaryRoleNone;
+ StereotypeDisplay m_stereotypeDisplay = StereotypeSmart;
+ bool m_isAutoSized = true;
+ bool m_isVisualEmphasized = false;
};
} // namespace qmt
diff --git a/src/libs/sqlite/columndefinition.cpp b/src/libs/modelinglib/qmt/diagram/dswimlane.cpp
index 2d2d83844cb..41d29a32b88 100644
--- a/src/libs/sqlite/columndefinition.cpp
+++ b/src/libs/modelinglib/qmt/diagram/dswimlane.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 Jochen Becher
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -23,51 +23,64 @@
**
****************************************************************************/
-#include "columndefinition.h"
+#include "dswimlane.h"
-namespace Internal {
+#include "dvisitor.h"
+#include "dconstvisitor.h"
-void ColumnDefinition::setName(const Utf8String &name)
+namespace qmt {
+
+DSwimlane::DSwimlane()
+ : DElement()
{
- name_ = name;
}
-const Utf8String &ColumnDefinition::name() const
+DSwimlane::DSwimlane(const DSwimlane &rhs)
+ : DElement(rhs),
+ m_text(rhs.m_text),
+ m_horizontal(rhs.m_horizontal),
+ m_pos(rhs.m_pos)
{
- return name_;
}
-void ColumnDefinition::setType(ColumnType type)
+DSwimlane::~DSwimlane()
{
- type_ = type;
}
-ColumnType ColumnDefinition::type() const
+DSwimlane &DSwimlane::operator=(const DSwimlane &rhs)
{
- return type_;
+ if (this != &rhs) {
+ DElement::operator=(rhs);
+ m_text = rhs.m_text;
+ m_horizontal = rhs.m_horizontal;
+ m_pos = rhs.m_pos;
+ }
+ return *this;
}
-Utf8String ColumnDefinition::typeString() const
+void DSwimlane::setText(const QString &text)
{
- switch (type_) {
- case ColumnType::None: return Utf8String();
- case ColumnType::Numeric: return Utf8StringLiteral("NUMERIC");
- case ColumnType::Integer: return Utf8StringLiteral("INTEGER");
- case ColumnType::Real: return Utf8StringLiteral("REAL");
- case ColumnType::Text: return Utf8StringLiteral("TEXT");
- }
+ m_text = text;
+}
- Q_UNREACHABLE();
+void DSwimlane::setHorizontal(bool horizontal)
+{
+ m_horizontal = horizontal;
}
-void ColumnDefinition::setIsPrimaryKey(bool isPrimaryKey)
+void DSwimlane::setPos(qreal pos)
{
- isPrimaryKey_ = isPrimaryKey;
+ m_pos = pos;
}
-bool ColumnDefinition::isPrimaryKey() const
+void DSwimlane::accept(DVisitor *visitor)
{
- return isPrimaryKey_;
+ visitor->visitDSwimlane(this);
}
+void DSwimlane::accept(DConstVisitor *visitor) const
+{
+ visitor->visitDSwimlane(this);
}
+
+} // namespoace qmt
diff --git a/src/libs/modelinglib/qmt/diagram/dswimlane.h b/src/libs/modelinglib/qmt/diagram/dswimlane.h
new file mode 100644
index 00000000000..c1b87960638
--- /dev/null
+++ b/src/libs/modelinglib/qmt/diagram/dswimlane.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Jochen Becher
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "delement.h"
+
+namespace qmt {
+
+class QMT_EXPORT DSwimlane : public DElement
+{
+public:
+ DSwimlane();
+ DSwimlane(const DSwimlane &rhs);
+ ~DSwimlane();
+
+ DSwimlane &operator=(const DSwimlane &rhs);
+
+ Uid modelUid() const override { return Uid::invalidUid(); }
+ QString text() const { return m_text; }
+ void setText(const QString &text);
+ bool isHorizontal() const { return m_horizontal; }
+ void setHorizontal(bool horizontal);
+ qreal pos() const { return m_pos; }
+ void setPos(qreal pos);
+
+ void accept(DVisitor *visitor) override;
+ void accept(DConstVisitor *visitor) const override;
+
+private:
+ QString m_text;
+ bool m_horizontal = false; // false: vertical, true: horizontal
+ qreal m_pos = 0.0;
+};
+
+} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram/dvisitor.h b/src/libs/modelinglib/qmt/diagram/dvisitor.h
index bb9e7873ee5..01adf15b704 100644
--- a/src/libs/modelinglib/qmt/diagram/dvisitor.h
+++ b/src/libs/modelinglib/qmt/diagram/dvisitor.h
@@ -38,8 +38,10 @@ class DRelation;
class DInheritance;
class DDependency;
class DAssociation;
+class DConnection;
class DAnnotation;
class DBoundary;
+class DSwimlane;
class DVisitor
{
@@ -57,8 +59,10 @@ public:
virtual void visitDInheritance(DInheritance *inheritance) = 0;
virtual void visitDDependency(DDependency *dependency) = 0;
virtual void visitDAssociation(DAssociation *association) = 0;
+ virtual void visitDConnection(DConnection *connection) = 0;
virtual void visitDAnnotation(DAnnotation *annotation) = 0;
virtual void visitDBoundary(DBoundary *boundary) = 0;
+ virtual void visitDSwimlane(DSwimlane *swimlane) = 0;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp b/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp
index c9e2067c8b6..d882c81eef8 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp
@@ -36,14 +36,15 @@
#include "qmt/diagram/dinheritance.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dassociation.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/diagram/dannotation.h"
#include "qmt/diagram/dboundary.h"
+#include "qmt/diagram/dswimlane.h"
#include "qmt/infrastructure/qmtassert.h"
namespace qmt {
DCloneVisitor::DCloneVisitor()
- : m_cloned(0)
{
}
@@ -122,6 +123,13 @@ void DCloneVisitor::visitDAssociation(const DAssociation *association)
visitDRelation(association);
}
+void DCloneVisitor::visitDConnection(const DConnection *connection)
+{
+ if (!m_cloned)
+ m_cloned = new DConnection(*connection);
+ visitDRelation(connection);
+}
+
void DCloneVisitor::visitDAnnotation(const DAnnotation *annotation)
{
if (!m_cloned)
@@ -136,8 +144,15 @@ void DCloneVisitor::visitDBoundary(const DBoundary *boundary)
visitDElement(boundary);
}
+void DCloneVisitor::visitDSwimlane(const DSwimlane *swimlane)
+{
+ if (!m_cloned)
+ m_cloned = new DSwimlane(*swimlane);
+ visitDElement(swimlane);
+}
+
+
DCloneDeepVisitor::DCloneDeepVisitor()
- : m_cloned(0)
{
}
@@ -215,6 +230,13 @@ void DCloneDeepVisitor::visitDAssociation(const DAssociation *association)
visitDRelation(association);
}
+void DCloneDeepVisitor::visitDConnection(const DConnection *connection)
+{
+ if (!m_cloned)
+ m_cloned = new DConnection(*connection);
+ visitDRelation(connection);
+}
+
void DCloneDeepVisitor::visitDAnnotation(const DAnnotation *annotation)
{
if (!m_cloned)
@@ -229,4 +251,11 @@ void DCloneDeepVisitor::visitDBoundary(const DBoundary *boundary)
visitDElement(boundary);
}
+void DCloneDeepVisitor::visitDSwimlane(const DSwimlane *swimlane)
+{
+ if (!m_cloned)
+ m_cloned = new DSwimlane(*swimlane);
+ visitDElement(swimlane);
+}
+
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.h b/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.h
index c69534b5429..82877bef583 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.h
+++ b/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.h
@@ -48,11 +48,13 @@ public:
void visitDInheritance(const DInheritance *inheritance) override;
void visitDDependency(const DDependency *dependency) override;
void visitDAssociation(const DAssociation *association) override;
+ void visitDConnection(const DConnection *connection) override;
void visitDAnnotation(const DAnnotation *annotation) override;
void visitDBoundary(const DBoundary *boundary) override;
+ void visitDSwimlane(const DSwimlane *swimlane) override;
private:
- DElement *m_cloned;
+ DElement *m_cloned = nullptr;
};
class QMT_EXPORT DCloneDeepVisitor : public DConstVisitor
@@ -73,11 +75,13 @@ public:
void visitDInheritance(const DInheritance *inheritance) override;
void visitDDependency(const DDependency *dependency) override;
void visitDAssociation(const DAssociation *association) override;
+ void visitDConnection(const DConnection *connection) override;
void visitDAnnotation(const DAnnotation *annotation) override;
void visitDBoundary(const DBoundary *boundary) override;
+ void visitDSwimlane(const DSwimlane *swimlane) override;
private:
- DElement *m_cloned;
+ DElement *m_cloned = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp b/src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp
index 02745bf71a0..e87fb8ce5ef 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp
@@ -36,6 +36,7 @@
#include "qmt/diagram/dinheritance.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dassociation.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/model/melement.h"
#include "qmt/model/mobject.h"
@@ -53,7 +54,6 @@
namespace qmt {
DFactory::DFactory()
- : m_product(0)
{
}
@@ -66,7 +66,7 @@ void DFactory::visitMElement(const MElement *element)
void DFactory::visitMObject(const MObject *object)
{
auto diagramObject = dynamic_cast<DObject *>(m_product);
- QMT_CHECK(diagramObject);
+ QMT_ASSERT(diagramObject, return);
diagramObject->setModelUid(object->uid());
visitMElement(object);
}
@@ -120,7 +120,7 @@ void DFactory::visitMItem(const MItem *item)
void DFactory::visitMRelation(const MRelation *relation)
{
auto diagramRelation = dynamic_cast<DRelation *>(m_product);
- QMT_CHECK(diagramRelation);
+ QMT_ASSERT(diagramRelation, return);
diagramRelation->setModelUid(relation->uid());
visitMElement(relation);
}
@@ -149,4 +149,12 @@ void DFactory::visitMAssociation(const MAssociation *association)
visitMRelation(association);
}
+void DFactory::visitMConnection(const MConnection *connection)
+{
+ QMT_CHECK(!m_product);
+ auto diagramConnection = new DConnection();
+ m_product = diagramConnection;
+ visitMRelation(connection);
+}
+
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dfactory.h b/src/libs/modelinglib/qmt/diagram_controller/dfactory.h
index 5d5e48ded8d..c55879c73e6 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dfactory.h
+++ b/src/libs/modelinglib/qmt/diagram_controller/dfactory.h
@@ -51,9 +51,10 @@ public:
void visitMDependency(const MDependency *dependency) override;
void visitMInheritance(const MInheritance *inheritance) override;
void visitMAssociation(const MAssociation *association) override;
+ void visitMConnection(const MConnection *connection) override;
private:
- DElement *m_product;
+ DElement *m_product = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.cpp b/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.cpp
index 16902bc0d4f..20531bb85c4 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.cpp
@@ -36,8 +36,10 @@
#include "qmt/diagram/dinheritance.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dassociation.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/diagram/dannotation.h"
#include "qmt/diagram/dboundary.h"
+#include "qmt/diagram/dswimlane.h"
#include "qmt/infrastructure/qmtassert.h"
namespace qmt {
@@ -59,7 +61,7 @@ void DFlatAssignmentVisitor::visitDObject(const DObject *object)
{
visitDElement(object);
auto target = dynamic_cast<DObject *>(m_target);
- QMT_CHECK(target);
+ QMT_ASSERT(target, return);
target->setStereotypes(object->stereotypes());
target->setName(object->name());
target->setPos(object->pos());
@@ -81,7 +83,7 @@ void DFlatAssignmentVisitor::visitDClass(const DClass *klass)
{
visitDObject(klass);
auto target = dynamic_cast<DClass *>(m_target);
- QMT_CHECK(target);
+ QMT_ASSERT(target, return);
target->setUmlNamespace(klass->umlNamespace());
target->setTemplateParameters(klass->templateParameters());
target->setTemplateDisplay(klass->templateDisplay());
@@ -94,7 +96,7 @@ void DFlatAssignmentVisitor::visitDComponent(const DComponent *component)
{
visitDObject(component);
auto target = dynamic_cast<DComponent *>(m_target);
- QMT_CHECK(target);
+ QMT_ASSERT(target, return);
target->setPlainShape(component->isPlainShape());
}
@@ -107,7 +109,7 @@ void DFlatAssignmentVisitor::visitDItem(const DItem *item)
{
visitDObject(item);
auto target = dynamic_cast<DItem *>(m_target);
- QMT_CHECK(target);
+ QMT_ASSERT(target, return);
target->setVariety(target->variety());
target->setShapeEditable(target->isShapeEditable());
target->setShape(target->shape());
@@ -117,7 +119,7 @@ void DFlatAssignmentVisitor::visitDRelation(const DRelation *relation)
{
visitDElement(relation);
auto target = dynamic_cast<DRelation *>(m_target);
- QMT_CHECK(target);
+ QMT_ASSERT(target, return);
target->setStereotypes(relation->stereotypes());
target->setIntermediatePoints(relation->intermediatePoints());
}
@@ -131,7 +133,7 @@ void DFlatAssignmentVisitor::visitDDependency(const DDependency *dependency)
{
visitDRelation(dependency);
auto target = dynamic_cast<DDependency *>(m_target);
- QMT_CHECK(target);
+ QMT_ASSERT(target, return);
target->setDirection(dependency->direction());
}
@@ -139,15 +141,27 @@ void DFlatAssignmentVisitor::visitDAssociation(const DAssociation *association)
{
visitDRelation(association);
auto target = dynamic_cast<DAssociation *>(m_target);
- QMT_CHECK(target);
+ QMT_ASSERT(target, return);
target->setEndA(association->endA());
target->setEndB(association->endB());
+ // TODO assign assoziation class?
+}
+
+void DFlatAssignmentVisitor::visitDConnection(const DConnection *connection)
+{
+ visitDRelation(connection);
+ auto target = dynamic_cast<DConnection *>(m_target);
+ QMT_ASSERT(target, return);
+ target->setCustomRelationId(connection->customRelationId());
+ target->setEndA(connection->endA());
+ target->setEndB(connection->endB());
}
void DFlatAssignmentVisitor::visitDAnnotation(const DAnnotation *annotation)
{
visitDElement(annotation);
auto target = dynamic_cast<DAnnotation *>(m_target);
+ QMT_ASSERT(target, return);
target->setText(annotation->text());
target->setPos(annotation->pos());
target->setRect(annotation->rect());
@@ -159,9 +173,20 @@ void DFlatAssignmentVisitor::visitDBoundary(const DBoundary *boundary)
{
visitDElement(boundary);
auto target = dynamic_cast<DBoundary *>(m_target);
+ QMT_ASSERT(target, return);
target->setText(boundary->text());
target->setPos(boundary->pos());
target->setRect(boundary->rect());
}
+void DFlatAssignmentVisitor::visitDSwimlane(const DSwimlane *swimlane)
+{
+ visitDElement(swimlane);
+ auto target = dynamic_cast<DSwimlane *>(m_target);
+ QMT_ASSERT(target, return);
+ target->setText(swimlane->text());
+ target->setHorizontal(swimlane->isHorizontal());
+ target->setPos(swimlane->pos());
+}
+
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.h b/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.h
index 8c2537ab05e..0109c3b753d 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.h
+++ b/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.h
@@ -46,11 +46,13 @@ public:
void visitDInheritance(const DInheritance *inheritance) override;
void visitDDependency(const DDependency *dependency) override;
void visitDAssociation(const DAssociation *association) override;
+ void visitDConnection(const DConnection *connection) override;
void visitDAnnotation(const DAnnotation *annotation) override;
void visitDBoundary(const DBoundary *boundary) override;
+ void visitDSwimlane(const DSwimlane *swimlane) override;
private:
- DElement *m_target;
+ DElement *m_target = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.cpp b/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.cpp
index d2111cbac51..a794de55a76 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.cpp
@@ -55,7 +55,7 @@ class DiagramController::Clone
public:
Uid m_elementKey;
int m_indexOfElement = -1;
- DElement *m_clonedElement = 0;
+ DElement *m_clonedElement = nullptr;
};
class DiagramController::DiagramUndoCommand : public UndoCommand
@@ -84,7 +84,7 @@ protected:
}
private:
- DiagramController *m_diagramController = 0;
+ DiagramController *m_diagramController = nullptr;
Uid m_diagramKey;
};
@@ -151,7 +151,7 @@ private:
MDiagram *diagram = this->diagram();
foreach (DElement *clonedElement, m_clonedElements) {
DElement *activeElement = diagramController->findElement(clonedElement->uid(), diagram);
- QMT_CHECK(activeElement);
+ QMT_ASSERT(activeElement, return);
int row = diagram->diagramElements().indexOf(activeElement);
emit diagramController->beginUpdateElement(row, diagram);
// clone active element
@@ -198,9 +198,9 @@ protected:
Clone &clone = m_clonedElements[i];
QMT_CHECK(!clone.m_clonedElement);
DElement *activeElement = diagramController->findElement(clone.m_elementKey, diagram);
- QMT_CHECK(activeElement);
+ QMT_ASSERT(activeElement, return);
clone.m_indexOfElement = diagram->diagramElements().indexOf(activeElement);
- QMT_CHECK(clone.m_indexOfElement >= 0);
+ QMT_ASSERT(clone.m_indexOfElement >= 0, return);
emit diagramController->beginRemoveElement(clone.m_indexOfElement, diagram);
DCloneDeepVisitor cloneVisitor;
activeElement->accept(&cloneVisitor);
@@ -221,11 +221,11 @@ protected:
bool inserted = false;
for (int i = m_clonedElements.count() - 1; i >= 0; --i) {
Clone &clone = m_clonedElements[i];
- QMT_CHECK(clone.m_clonedElement);
+ QMT_ASSERT(clone.m_clonedElement, return);
QMT_CHECK(clone.m_clonedElement->uid() == clone.m_elementKey);
emit diagramController->beginInsertElement(clone.m_indexOfElement, diagram);
diagram->insertDiagramElement(clone.m_indexOfElement, clone.m_clonedElement);
- clone.m_clonedElement = 0;
+ clone.m_clonedElement = nullptr;
emit diagramController->endInsertElement(clone.m_indexOfElement, diagram);
inserted = true;
}
@@ -287,7 +287,7 @@ public:
DCloneDeepVisitor visitor;
element->accept(&visitor);
clone.m_clonedElement = visitor.cloned();
- QMT_CHECK(clone.m_clonedElement);
+ QMT_ASSERT(clone.m_clonedElement, return);
m_clonedElements.append(clone);
}
@@ -321,13 +321,11 @@ public:
}
private:
- QList<MDiagram *> *m_allDiagrams = 0;
+ QList<MDiagram *> *m_allDiagrams = nullptr;
};
DiagramController::DiagramController(QObject *parent)
- : QObject(parent),
- m_modelController(nullptr),
- m_undoController(nullptr)
+ : QObject(parent)
{
}
@@ -338,8 +336,8 @@ DiagramController::~DiagramController()
void DiagramController::setModelController(ModelController *modelController)
{
if (m_modelController) {
- disconnect(m_modelController, 0, this, 0);
- m_modelController = 0;
+ disconnect(m_modelController, nullptr, this, nullptr);
+ m_modelController = nullptr;
}
if (modelController) {
m_modelController = modelController;
@@ -424,7 +422,7 @@ void DiagramController::removeElement(DElement *element, MDiagram *diagram)
DElement *DiagramController::findElement(const Uid &key, const MDiagram *diagram) const
{
- QMT_CHECK(diagram);
+ QMT_ASSERT(diagram, return nullptr);
return diagram->findDiagramElement(key);
}
@@ -432,7 +430,7 @@ DElement *DiagramController::findElement(const Uid &key, const MDiagram *diagram
bool DiagramController::hasDelegate(const MElement *modelElement, const MDiagram *diagram) const
{
// PERFORM smarter implementation after map is introduced
- return findDelegate(modelElement, diagram) != 0;
+ return findDelegate(modelElement, diagram) != nullptr;
}
DElement *DiagramController::findDelegate(const MElement *modelElement, const MDiagram *diagram) const
@@ -442,7 +440,7 @@ DElement *DiagramController::findDelegate(const MElement *modelElement, const MD
if (diagramElement->modelUid().isValid() && diagramElement->modelUid() == modelElement->uid())
return diagramElement;
}
- return 0;
+ return nullptr;
}
void DiagramController::startUpdateElement(DElement *element, MDiagram *diagram, UpdateAction updateAction)
@@ -476,7 +474,7 @@ DContainer DiagramController::cutElements(const DSelection &diagramSelection, MD
DContainer DiagramController::copyElements(const DSelection &diagramSelection, const MDiagram *diagram)
{
- QMT_CHECK(diagram);
+ QMT_ASSERT(diagram, return DContainer());
DReferences simplifiedSelection = simplify(diagramSelection, diagram);
DContainer copiedElements;
@@ -491,7 +489,7 @@ DContainer DiagramController::copyElements(const DSelection &diagramSelection, c
void DiagramController::pasteElements(const DContainer &diagramContainer, MDiagram *diagram)
{
- QMT_CHECK(diagram);
+ QMT_ASSERT(diagram, return);
// clone all elements and renew their keys
QHash<Uid, Uid> renewedKeys;
@@ -593,7 +591,7 @@ void DiagramController::onBeginUpdateObject(int row, const MObject *parent)
void DiagramController::onEndUpdateObject(int row, const MObject *parent)
{
MObject *modelObject = m_modelController->object(row, parent);
- QMT_CHECK(modelObject);
+ QMT_ASSERT(modelObject, return);
auto modelPackage = dynamic_cast<MPackage *>(modelObject);
foreach (MDiagram *diagram, m_allDiagrams) {
DObject *object = findDelegate<DObject>(modelObject, diagram);
@@ -622,7 +620,7 @@ void DiagramController::onBeginInsertObject(int row, const MObject *owner)
void DiagramController::onEndInsertObject(int row, const MObject *owner)
{
- QMT_CHECK(owner);
+ QMT_ASSERT(owner, return);
MObject *modelObject = m_modelController->object(row, owner);
if (auto modelDiagram = dynamic_cast<MDiagram *>(modelObject)) {
@@ -634,7 +632,7 @@ void DiagramController::onEndInsertObject(int row, const MObject *owner)
void DiagramController::onBeginRemoveObject(int row, const MObject *parent)
{
- QMT_CHECK(parent);
+ QMT_ASSERT(parent, return);
MObject *modelObject = m_modelController->object(row, parent);
removeObjects(modelObject);
@@ -658,7 +656,7 @@ void DiagramController::onEndMoveObject(int row, const MObject *owner)
// if diagram was moved update all elements because of changed context
MObject *modelObject = m_modelController->object(row, owner);
- QMT_CHECK(modelObject);
+ QMT_ASSERT(modelObject, return);
auto modelDiagram = dynamic_cast<MDiagram *>(modelObject);
if (modelDiagram) {
emit beginResetDiagram(modelDiagram);
@@ -691,7 +689,7 @@ void DiagramController::onEndUpdateRelation(int row, const MObject *owner)
void DiagramController::onBeginRemoveRelation(int row, const MObject *owner)
{
- QMT_CHECK(owner);
+ QMT_ASSERT(owner, return);
MRelation *modelRelation = owner->relations().at(row);
removeRelations(modelRelation);
@@ -719,7 +717,7 @@ void DiagramController::onEndMoveRelation(int row, const MObject *owner)
void DiagramController::deleteElements(const DSelection &diagramSelection, MDiagram *diagram,
const QString &commandLabel)
{
- QMT_CHECK(diagram);
+ QMT_ASSERT(diagram, return);
DReferences simplifiedSelection = simplify(diagramSelection, diagram);
if (simplifiedSelection.elements().isEmpty())
@@ -757,7 +755,7 @@ DElement *DiagramController::findElementOnAnyDiagram(const Uid &uid)
if (element)
return element;
}
- return 0;
+ return nullptr;
}
void DiagramController::removeObjects(MObject *modelObject)
@@ -818,7 +816,7 @@ void DiagramController::removeRelations(DElement *element, MDiagram *diagram)
void DiagramController::renewElementKey(DElement *element, QHash<Uid, Uid> *renewedKeys)
{
- QMT_CHECK(renewedKeys);
+ QMT_ASSERT(renewedKeys, return);
if (element) {
DElement *existingElementOnDiagram = findElementOnAnyDiagram(element->uid());
@@ -850,7 +848,7 @@ void DiagramController::updateElementFromModel(DElement *element, const MDiagram
DUpdateVisitor visitor(element, diagram);
MElement *melement = m_modelController->findElement(element->modelUid());
- QMT_CHECK(melement);
+ QMT_ASSERT(melement, return);
if (emitUpdateSignal) {
visitor.setCheckNeedsUpdate(true);
@@ -890,7 +888,7 @@ DReferences DiagramController::simplify(const DSelection &diagramSelection, cons
MElement *DiagramController::delegatedElement(const DElement *element) const
{
if (!element->modelUid().isValid())
- return 0;
+ return nullptr;
return m_modelController->findElement(element->modelUid());
}
@@ -925,7 +923,7 @@ void DiagramController::verifyDiagramsIntegrity()
FindDiagramsVisitor visitor(&allDiagrams);
m_modelController->rootPackage()->accept(&visitor);
}
- QMT_CHECK(allDiagrams == m_allDiagrams);
+ QMT_ASSERT(allDiagrams == m_allDiagrams, return);
foreach (const MDiagram *diagram, allDiagrams)
verifyDiagramIntegrity(diagram);
}
@@ -936,27 +934,27 @@ void DiagramController::verifyDiagramIntegrity(const MDiagram *diagram)
QHash<Uid, const DElement *> delementsMap;
foreach (const DElement *delement, diagram->diagramElements()) {
delementsMap.insert(delement->uid(), delement);
- if (dynamic_cast<const DObject *>(delement) != 0 || dynamic_cast<const DRelation *>(delement) != 0) {
- QMT_CHECK(delement->modelUid().isValid());
- QMT_CHECK(m_modelController->findElement(delement->modelUid()) != 0);
- if (!delement->modelUid().isValid() || m_modelController->findElement(delement->modelUid()) == 0) {
+ if (dynamic_cast<const DObject *>(delement) || dynamic_cast<const DRelation *>(delement)) {
+ QMT_ASSERT(delement->modelUid().isValid(), return);
+ QMT_ASSERT(m_modelController->findElement(delement->modelUid()), return);
+ if (!delement->modelUid().isValid() || !m_modelController->findElement(delement->modelUid())) {
if (const DObject *dobject = dynamic_cast<const DObject *>(delement))
qWarning() << "Diagram" << diagram->name() << diagram->uid().toString() << ": object" << dobject->name() << dobject->uid().toString() << "has invalid reference to model element.";
else if (const DRelation *drelation = dynamic_cast<const DRelation *>(delement))
qWarning() << "Diagram" << diagram->name() << diagram->uid().toString() << ": relation" << drelation->uid().toString() << "has invalid refeference to model element.";
}
} else {
- QMT_CHECK(!delement->modelUid().isValid());
+ QMT_ASSERT(!delement->modelUid().isValid(), return);
}
}
foreach (const DElement *delement, diagram->diagramElements()) {
if (const DRelation *drelation = dynamic_cast<const DRelation *>(delement)) {
- QMT_CHECK(drelation->endAUid().isValid());
- QMT_CHECK(delementsMap.contains(drelation->endAUid()));
+ QMT_ASSERT(drelation->endAUid().isValid(), return);
+ QMT_ASSERT(delementsMap.contains(drelation->endAUid()), return);
if (!drelation->endAUid().isValid() || !delementsMap.contains(drelation->endAUid()))
qWarning() << "Diagram" << diagram->name() << diagram->uid().toString() << ": relation" << drelation->uid().toString() << "has invalid end A.";
- QMT_CHECK(drelation->endBUid().isValid());
- QMT_CHECK(delementsMap.contains(drelation->endBUid()));
+ QMT_ASSERT(drelation->endBUid().isValid(), return);
+ QMT_ASSERT(delementsMap.contains(drelation->endBUid()), return);
if (!drelation->endBUid().isValid() || !delementsMap.contains(drelation->endBUid()))
qWarning() << "Diagram" << diagram->name() << diagram->uid().toString() << ": relation" << drelation->uid().toString() << "has invalid end B.";
}
diff --git a/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.h b/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.h
index 1f688198a43..aa09636e5e3 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.h
+++ b/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.h
@@ -65,7 +65,7 @@ private:
class FindDiagramsVisitor;
public:
- explicit DiagramController(QObject *parent = 0);
+ explicit DiagramController(QObject *parent = nullptr);
~DiagramController() override;
signals:
@@ -167,8 +167,8 @@ private:
void verifyDiagramsIntegrity();
void verifyDiagramIntegrity(const MDiagram *diagram);
- ModelController *m_modelController;
- UndoController *m_undoController;
+ ModelController *m_modelController = nullptr;
+ UndoController *m_undoController = nullptr;
QList<MDiagram *> m_allDiagrams;
};
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp b/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp
index 3454de26029..4b99d5e69a2 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp
@@ -32,6 +32,7 @@
#include "qmt/diagram/drelation.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dassociation.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/model/melement.h"
#include "qmt/model/mobject.h"
@@ -72,7 +73,7 @@ void DUpdateVisitor::visitMElement(const MElement *element)
void DUpdateVisitor::visitMObject(const MObject *object)
{
auto dobject = dynamic_cast<DObject *>(m_target);
- QMT_CHECK(dobject);
+ QMT_ASSERT(dobject, return);
if (isUpdating(object->stereotypes() != dobject->stereotypes()))
dobject->setStereotypes(object->stereotypes());
const MObject *objectOwner = object->owner();
@@ -107,7 +108,7 @@ void DUpdateVisitor::visitMPackage(const MPackage *package)
void DUpdateVisitor::visitMClass(const MClass *klass)
{
auto dclass = dynamic_cast<DClass *>(m_target);
- QMT_CHECK(dclass);
+ QMT_ASSERT(dclass, return);
if (isUpdating(klass->umlNamespace() != dclass->umlNamespace()))
dclass->setUmlNamespace(klass->umlNamespace());
if (isUpdating(klass->templateParameters() != dclass->templateParameters()))
@@ -135,7 +136,7 @@ void DUpdateVisitor::visitMCanvasDiagram(const MCanvasDiagram *diagram)
void DUpdateVisitor::visitMItem(const MItem *item)
{
auto ditem = dynamic_cast<DItem *>(m_target);
- QMT_CHECK(ditem);
+ QMT_ASSERT(ditem, return);
if (isUpdating(item->isShapeEditable() != ditem->isShapeEditable()))
ditem->setShapeEditable(item->isShapeEditable());
if (isUpdating(item->variety() != ditem->variety()))
@@ -146,7 +147,7 @@ void DUpdateVisitor::visitMItem(const MItem *item)
void DUpdateVisitor::visitMRelation(const MRelation *relation)
{
auto drelation = dynamic_cast<DRelation *>(m_target);
- QMT_CHECK(drelation);
+ QMT_ASSERT(drelation, return);
if (isUpdating(relation->stereotypes() != drelation->stereotypes()))
drelation->setStereotypes(relation->stereotypes());
if (isUpdating(relation->name() != drelation->name()))
@@ -154,8 +155,8 @@ void DUpdateVisitor::visitMRelation(const MRelation *relation)
// TODO improve performance of MDiagram::findDiagramElement
DObject *endAObject = dynamic_cast<DObject *>(m_diagram->findDiagramElement(drelation->endAUid()));
if (!endAObject || relation->endAUid() != endAObject->modelUid()) {
- isUpdating(true);
- endAObject = 0;
+ (void) isUpdating(true);
+ endAObject = nullptr;
// TODO use DiagramController::findDelegate (and improve performance of that method)
foreach (DElement *diagramElement, m_diagram->diagramElements()) {
if (diagramElement->modelUid().isValid() && diagramElement->modelUid() == relation->endAUid()) {
@@ -170,8 +171,8 @@ void DUpdateVisitor::visitMRelation(const MRelation *relation)
}
DObject *endBObject = dynamic_cast<DObject *>(m_diagram->findDiagramElement(drelation->endBUid()));
if (!endBObject || relation->endBUid() != endBObject->modelUid()) {
- isUpdating(true);
- endBObject = 0;
+ (void) isUpdating(true);
+ endBObject = nullptr;
// TODO use DiagramController::findDelegate
foreach (DElement *diagramElement, m_diagram->diagramElements()) {
if (diagramElement->modelUid().isValid() && diagramElement->modelUid() == relation->endBUid()) {
@@ -190,7 +191,7 @@ void DUpdateVisitor::visitMRelation(const MRelation *relation)
void DUpdateVisitor::visitMDependency(const MDependency *dependency)
{
auto ddependency = dynamic_cast<DDependency *>(m_target);
- QMT_CHECK(ddependency);
+ QMT_ASSERT(ddependency, return);
if (isUpdating(dependency->direction() != ddependency->direction()))
ddependency->setDirection(dependency->direction());
visitMRelation(dependency);
@@ -204,7 +205,7 @@ void DUpdateVisitor::visitMInheritance(const MInheritance *inheritance)
void DUpdateVisitor::visitMAssociation(const MAssociation *association)
{
auto dassociation = dynamic_cast<DAssociation *>(m_target);
- QMT_CHECK(dassociation);
+ QMT_ASSERT(dassociation, return);
DAssociationEnd endA;
endA.setName(association->endA().name());
endA.setCardinatlity(association->endA().cardinality());
@@ -222,6 +223,27 @@ void DUpdateVisitor::visitMAssociation(const MAssociation *association)
visitMRelation(association);
}
+void DUpdateVisitor::visitMConnection(const MConnection *connection)
+{
+ auto dconnection = dynamic_cast<DConnection *>(m_target);
+ QMT_ASSERT(dconnection, return);
+ if (isUpdating(connection->customRelationId() != dconnection->customRelationId()))
+ dconnection->setCustomRelationId(connection->customRelationId());
+ DConnectionEnd endA;
+ endA.setName(connection->endA().name());
+ endA.setCardinatlity(connection->endA().cardinality());
+ endA.setNavigable(connection->endA().isNavigable());
+ if (isUpdating(endA != dconnection->endA()))
+ dconnection->setEndA(endA);
+ DConnectionEnd endB;
+ endB.setName(connection->endB().name());
+ endB.setCardinatlity(connection->endB().cardinality());
+ endB.setNavigable(connection->endB().isNavigable());
+ if (isUpdating(endB != dconnection->endB()))
+ dconnection->setEndB(endB);
+ visitMRelation(connection);
+}
+
bool DUpdateVisitor::isUpdating(bool valueChanged)
{
if (m_checkNeedsUpdate) {
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.h b/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.h
index e88e9eed4b7..f435a397053 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.h
+++ b/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.h
@@ -52,14 +52,15 @@ public:
void visitMDependency(const MDependency *dependency) override;
void visitMInheritance(const MInheritance *inheritance) override;
void visitMAssociation(const MAssociation *association) override;
+ void visitMConnection(const MConnection *connection) override;
private:
bool isUpdating(bool valueChanged);
- DElement *m_target;
- const MDiagram *m_diagram;
- bool m_checkNeedsUpdate;
- bool m_isUpdateNeeded;
+ DElement *m_target = nullptr;
+ const MDiagram *m_diagram = nullptr;
+ bool m_checkNeedsUpdate = false;
+ bool m_isUpdateNeeded = false;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp b/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp
index 09b7c92d508..56fdfe2cb47 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp
@@ -36,8 +36,10 @@
#include "qmt/diagram/dinheritance.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dassociation.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/diagram/dannotation.h"
#include "qmt/diagram/dboundary.h"
+#include "qmt/diagram/dswimlane.h"
namespace qmt {
@@ -100,6 +102,11 @@ void DVoidVisitor::visitDAssociation(DAssociation *association)
visitDRelation(association);
}
+void DVoidVisitor::visitDConnection(DConnection *connection)
+{
+ visitDRelation(connection);
+}
+
void DVoidVisitor::visitDAnnotation(DAnnotation *annotation)
{
visitDElement(annotation);
@@ -110,6 +117,11 @@ void DVoidVisitor::visitDBoundary(DBoundary *boundary)
visitDElement(boundary);
}
+void DVoidVisitor::visitDSwimlane(DSwimlane *swimlane)
+{
+ visitDElement(swimlane);
+}
+
DConstVoidVisitor::DConstVoidVisitor()
{
}
@@ -169,6 +181,11 @@ void DConstVoidVisitor::visitDAssociation(const DAssociation *association)
visitDRelation(association);
}
+void DConstVoidVisitor::visitDConnection(const DConnection *connection)
+{
+ visitDRelation(connection);
+}
+
void DConstVoidVisitor::visitDAnnotation(const DAnnotation *annotation)
{
visitDElement(annotation);
@@ -179,4 +196,9 @@ void DConstVoidVisitor::visitDBoundary(const DBoundary *boundary)
visitDElement(boundary);
}
+void DConstVoidVisitor::visitDSwimlane(const DSwimlane *swimlane)
+{
+ visitDElement(swimlane);
+}
+
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.h b/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.h
index 4519c1a943e..7050b7adbf7 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.h
+++ b/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.h
@@ -47,8 +47,10 @@ public:
void visitDInheritance(DInheritance *inheritance) override;
void visitDDependency(DDependency *dependency) override;
void visitDAssociation(DAssociation *association) override;
+ void visitDConnection(DConnection *connection) override;
void visitDAnnotation(DAnnotation *annotation) override;
void visitDBoundary(DBoundary *boundary) override;
+ void visitDSwimlane(DSwimlane *swimlane) override;
};
class QMT_EXPORT DConstVoidVisitor : public DConstVisitor
@@ -67,8 +69,10 @@ public:
void visitDInheritance(const DInheritance *inheritance) override;
void visitDDependency(const DDependency *dependency) override;
void visitDAssociation(const DAssociation *association) override;
+ void visitDConnection(const DConnection *connection) override;
void visitDAnnotation(const DAnnotation *annotation) override;
void visitDBoundary(const DBoundary *boundary) override;
+ void visitDSwimlane(const DSwimlane *swimlane) override;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/capabilities/intersectionable.h b/src/libs/modelinglib/qmt/diagram_scene/capabilities/intersectionable.h
index bb7b0ec81c6..eb1371ea98a 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/capabilities/intersectionable.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/capabilities/intersectionable.h
@@ -40,7 +40,7 @@ public:
virtual ~IIntersectionable() { }
virtual bool intersectShapeWithLine(const QLineF &line, QPointF *intersectionPoint,
- QLineF *intersectionLine = 0) const = 0;
+ QLineF *intersectionLine = nullptr) const = 0;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/capabilities/selectable.h b/src/libs/modelinglib/qmt/diagram_scene/capabilities/selectable.h
index 5afcf64efdb..8da587bc56f 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/capabilities/selectable.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/capabilities/selectable.h
@@ -25,6 +25,8 @@
#pragma once
+#include <QRectF>
+
namespace qmt {
class ISelectable
@@ -36,6 +38,8 @@ public:
virtual void setSecondarySelected(bool secondarySelected) = 0;
virtual bool isFocusSelected() const = 0;
virtual void setFocusSelected(bool focusSelected) = 0;
+ virtual QRectF getSecondarySelectionBoundary() = 0;
+ virtual void setBoundarySelected(const QRectF &boundary, bool secondary) = 0;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/diagramgraphicsscene.h b/src/libs/modelinglib/qmt/diagram_scene/diagramgraphicsscene.h
index 3be43fa3970..d9fc21f4410 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/diagramgraphicsscene.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/diagramgraphicsscene.h
@@ -37,7 +37,7 @@ class QMT_EXPORT DiagramGraphicsScene : public QGraphicsScene
Q_OBJECT
public:
- explicit DiagramGraphicsScene(DiagramSceneModel *diagramSceneModel, QObject *parent = 0);
+ explicit DiagramGraphicsScene(DiagramSceneModel *diagramSceneModel, QObject *parent = nullptr);
~DiagramGraphicsScene() override;
signals:
@@ -64,7 +64,7 @@ protected:
void inputMethodEvent(QInputMethodEvent *event) override;
private:
- DiagramSceneModel *m_diagramSceneModel;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/diagramsceneconstants.h b/src/libs/modelinglib/qmt/diagram_scene/diagramsceneconstants.h
index 6f7d0a89e27..c91e62725b3 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/diagramsceneconstants.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/diagramsceneconstants.h
@@ -27,6 +27,7 @@
namespace qmt {
+const int SWIMLANE_ITEMS_ZVALUE = -1100;
const int BOUNDARY_ITEMS_ZVALUE = -1000;
// all model objects have z-values from -500 to 500 depending on their depth in the model tree
const int RELATION_ITEMS_ZVALUE = 1000;
diff --git a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp
index 9d40cf3a8e9..b1ca87b008e 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp
@@ -38,6 +38,8 @@
#include "qmt/diagram/drelation.h"
#include "qmt/diagram_controller/diagramcontroller.h"
#include "qmt/diagram_controller/dselection.h"
+#include "qmt/diagram_scene/items/objectitem.h"
+#include "qmt/diagram_scene/items/swimlaneitem.h"
#include "qmt/model/mdiagram.h"
#include "qmt/model/mobject.h"
#include "qmt/model/mpackage.h"
@@ -47,6 +49,8 @@
#include "qmt/tasks/diagramscenecontroller.h"
#include "qmt/tasks/ielementtasks.h"
+#include "utils/asconst.h"
+
#include <QSet>
#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
@@ -68,7 +72,7 @@ namespace qmt {
class DiagramSceneModel::OriginItem : public QGraphicsItem
{
public:
- explicit OriginItem(QGraphicsItem *parent = 0)
+ explicit OriginItem(QGraphicsItem *parent = nullptr)
: QGraphicsItem(parent)
{
}
@@ -92,16 +96,9 @@ public:
DiagramSceneModel::DiagramSceneModel(QObject *parent)
: QObject(parent),
- m_diagramController(0),
- m_diagramSceneController(0),
- m_styleController(0),
- m_stereotypeController(0),
- m_diagram(0),
m_graphicsScene(new DiagramGraphicsScene(this)),
m_latchController(new LatchController(this)),
- m_busyState(NotBusy),
- m_originItem(new OriginItem()),
- m_focusItem(0)
+ m_originItem(new OriginItem())
{
m_latchController->setDiagramSceneModel(this);
connect(m_graphicsScene, &QGraphicsScene::selectionChanged,
@@ -111,7 +108,6 @@ DiagramSceneModel::DiagramSceneModel(QObject *parent)
m_graphicsScene->addItem(m_originItem);
m_latchController->addToGraphicsScene(m_graphicsScene);
-
}
DiagramSceneModel::~DiagramSceneModel()
@@ -120,7 +116,7 @@ DiagramSceneModel::~DiagramSceneModel()
m_latchController->removeFromGraphicsScene(m_graphicsScene);
disconnect();
if (m_diagramController)
- disconnect(m_diagramController, 0, this, 0);
+ disconnect(m_diagramController, nullptr, this, nullptr);
m_graphicsScene->deleteLater();
}
@@ -129,8 +125,8 @@ void DiagramSceneModel::setDiagramController(DiagramController *diagramControlle
if (m_diagramController == diagramController)
return;
if (m_diagramController) {
- disconnect(m_diagramController, 0, this, 0);
- m_diagramController = 0;
+ disconnect(m_diagramController, nullptr, this, nullptr);
+ m_diagramController = nullptr;
}
m_diagramController = diagramController;
if (diagramController) {
@@ -197,7 +193,7 @@ bool DiagramSceneModel::hasMultiObjectsSelection() const
foreach (QGraphicsItem *item, m_graphicsScene->selectedItems()) {
DElement *element = m_itemToElementMap.value(item);
QMT_CHECK(element);
- if (dynamic_cast<DObject *>(element) != 0) {
+ if (dynamic_cast<DObject *>(element)) {
++count;
if (count > 1)
return true;
@@ -211,7 +207,7 @@ DSelection DiagramSceneModel::selectedElements() const
DSelection selection;
foreach (QGraphicsItem *item, m_graphicsScene->selectedItems()) {
DElement *element = m_itemToElementMap.value(item);
- QMT_CHECK(element);
+ QMT_ASSERT(element, return selection);
selection.append(element->uid(), m_diagram->uid());
}
return selection;
@@ -225,21 +221,29 @@ DElement *DiagramSceneModel::findTopmostElement(const QPointF &scenePos) const
if (m_graphicsItems.contains(item))
return m_itemToElementMap.value(item);
}
- return 0;
+ return nullptr;
}
DObject *DiagramSceneModel::findTopmostObject(const QPointF &scenePos) const
{
+ ObjectItem *item = findTopmostObjectItem(scenePos);
+ if (!item)
+ return nullptr;
+ return item->object();
+}
+
+ObjectItem *DiagramSceneModel::findTopmostObjectItem(const QPointF &scenePos) const
+{
// fetch affected items from scene in correct drawing order to find topmost element
- QList<QGraphicsItem *> items = m_graphicsScene->items(scenePos);
- foreach (QGraphicsItem *item, items) {
+ const QList<QGraphicsItem *> items = m_graphicsScene->items(scenePos);
+ for (QGraphicsItem *item : Utils::asConst(items)) {
if (m_graphicsItems.contains(item)) {
DObject *object = dynamic_cast<DObject *>(m_itemToElementMap.value(item));
if (object)
- return object;
+ return dynamic_cast<ObjectItem *>(item);
}
}
- return 0;
+ return nullptr;
}
QGraphicsItem *DiagramSceneModel::graphicsItem(DElement *element) const
@@ -264,8 +268,8 @@ DElement *DiagramSceneModel::element(QGraphicsItem *item) const
bool DiagramSceneModel::isElementEditable(const DElement *element) const
{
- auto editable = dynamic_cast<IEditable *>(m_elementToItemMap.value(element));
- return editable != 0 && editable->isEditable();
+ auto editable = dynamic_cast<IEditable *>(m_elementToItemMap.value(element));
+ return editable && editable->isEditable();
}
void DiagramSceneModel::selectAllElements()
@@ -288,7 +292,7 @@ void DiagramSceneModel::selectElement(DElement *element)
void DiagramSceneModel::editElement(DElement *element)
{
auto editable = dynamic_cast<IEditable *>(m_elementToItemMap.value(element));
- if (editable != 0 && editable->isEditable())
+ if (editable && editable->isEditable())
editable->edit();
}
@@ -569,8 +573,6 @@ QList<QGraphicsItem *> DiagramSceneModel::collectCollidingObjectItems(const QGra
}
}
break;
- default:
- QMT_CHECK(false);
}
return collidingItems;
}
@@ -633,7 +635,7 @@ void DiagramSceneModel::mouseReleaseEventReparenting(QGraphicsSceneMouseEvent *e
{
if (event->modifiers() & Qt::AltModifier) {
ModelController *modelController = diagramController()->modelController();
- MPackage *newOwner = 0;
+ MPackage *newOwner = nullptr;
QSet<QGraphicsItem *> selectedItemSet = m_graphicsScene->selectedItems().toSet();
QList<QGraphicsItem *> itemsUnderMouse = m_graphicsScene->items(event->scenePos());
foreach (QGraphicsItem *item, itemsUnderMouse) {
@@ -649,7 +651,7 @@ void DiagramSceneModel::mouseReleaseEventReparenting(QGraphicsSceneMouseEvent *e
if (newOwner) {
foreach (QGraphicsItem *item, m_graphicsScene->selectedItems()) {
DElement *element = m_itemToElementMap.value(item);
- QMT_CHECK(element);
+ QMT_ASSERT(element, return);
if (element->modelUid().isValid()) {
MObject *modelObject = modelController->findObject(element->modelUid());
if (modelObject) {
@@ -698,6 +700,7 @@ void DiagramSceneModel::onEndResetDiagram(const MDiagram *diagram)
// update graphics items again so every item gets a correct list of colliding items
foreach (DElement *element, diagram->diagramElements())
updateGraphicsItem(m_elementToItemMap.value(element), element);
+ recalcSceneRectSize();
}
m_busyState = NotBusy;
}
@@ -717,6 +720,7 @@ void DiagramSceneModel::onEndUpdateElement(int row, const MDiagram *diagram)
if (diagram == m_diagram) {
QGraphicsItem *item = m_graphicsItems.at(row);
updateGraphicsItem(item, diagram->diagramElements().at(row));
+ recalcSceneRectSize();
}
m_busyState = NotBusy;
}
@@ -732,7 +736,7 @@ void DiagramSceneModel::onBeginInsertElement(int row, const MDiagram *diagram)
void DiagramSceneModel::onEndInsertElement(int row, const MDiagram *diagram)
{
QMT_CHECK(m_busyState == InsertElement);
- QGraphicsItem *item = 0;
+ QGraphicsItem *item = nullptr;
if (diagram == m_diagram) {
DElement *element = diagram->diagramElements().at(row);
item = createGraphicsItem(element);
@@ -740,6 +744,7 @@ void DiagramSceneModel::onEndInsertElement(int row, const MDiagram *diagram)
updateGraphicsItem(item, element);
m_graphicsScene->invalidate();
updateGraphicsItem(item, element);
+ recalcSceneRectSize();
}
m_busyState = NotBusy;
}
@@ -750,6 +755,7 @@ void DiagramSceneModel::onBeginRemoveElement(int row, const MDiagram *diagram)
if (diagram == m_diagram) {
QGraphicsItem *item = m_graphicsItems.takeAt(row);
deleteGraphicsItem(item, diagram->diagramElements().at(row));
+ recalcSceneRectSize();
}
m_busyState = RemoveElement;
}
@@ -791,7 +797,7 @@ void DiagramSceneModel::onSelectionChanged()
// select all contained objects secondarily
foreach (QGraphicsItem *selectedItem, m_selectedItems) {
foreach (QGraphicsItem *item, collectCollidingObjectItems(selectedItem, CollidingInnerItems)) {
- if (!item->isSelected() && dynamic_cast<ISelectable *>(item) != 0
+ if (!item->isSelected() && dynamic_cast<ISelectable *>(item)
&& item->collidesWithItem(selectedItem, Qt::ContainsItemBoundingRect)
&& isInFrontOf(item, selectedItem)) {
QMT_CHECK(!m_selectedItems.contains(item));
@@ -800,20 +806,41 @@ void DiagramSceneModel::onSelectionChanged()
}
}
+ // select more items secondarily
+ for (QGraphicsItem *selectedItem : Utils::asConst(m_selectedItems)) {
+ if (auto selectable = dynamic_cast<ISelectable *>(selectedItem)) {
+ QRectF boundary = selectable->getSecondarySelectionBoundary();
+ if (!boundary.isEmpty()) {
+ for (QGraphicsItem *item : Utils::asConst(m_graphicsItems)) {
+ if (auto secondarySelectable = dynamic_cast<ISelectable *>(item)) {
+ if (!item->isSelected() && !secondarySelectable->isSecondarySelected()) {
+ secondarySelectable->setBoundarySelected(boundary, true);
+ QMT_CHECK(!m_selectedItems.contains(item));
+ QMT_CHECK(!m_secondarySelectedItems.contains(item));
+ if (secondarySelectable->isSecondarySelected())
+ newSecondarySelectedItems.insert(item);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
// select all relations where both ends are primary or secondary selected
foreach (DElement *element, m_diagram->diagramElements()) {
auto relation = dynamic_cast<DRelation *>(element);
if (relation) {
QGraphicsItem *relationItem = m_elementToItemMap.value(relation);
- QMT_CHECK(relationItem);
+ QMT_ASSERT(relationItem, return);
DObject *endAObject = m_diagramController->findElement<DObject>(relation->endAUid(), m_diagram);
- QMT_CHECK(endAObject);
+ QMT_ASSERT(endAObject, return);
QGraphicsItem *endAItem = m_elementToItemMap.value(endAObject);
- QMT_CHECK(endAItem);
+ QMT_ASSERT(endAItem, return);
DObject *endBObject = m_diagramController->findElement<DObject>(relation->endBUid(), m_diagram);
- QMT_CHECK(endBObject);
+ QMT_ASSERT(endBObject, return);
QGraphicsItem *endBItem = m_elementToItemMap.value(endBObject);
- QMT_CHECK(endBItem);
+ QMT_ASSERT(endBItem, return);
if (relationItem && !relationItem->isSelected()
&& (m_selectedItems.contains(endAItem) || newSecondarySelectedItems.contains(endAItem))
&& (m_selectedItems.contains(endBItem) || newSecondarySelectedItems.contains(endBItem))) {
@@ -826,7 +853,7 @@ void DiagramSceneModel::onSelectionChanged()
foreach (QGraphicsItem *item, m_secondarySelectedItems) {
if (!newSecondarySelectedItems.contains(item)) {
auto selectable = dynamic_cast<ISelectable *>(item);
- QMT_CHECK(selectable);
+ QMT_ASSERT(selectable, return);
selectable->setSecondarySelected(false);
selectionChanged = true;
}
@@ -834,7 +861,7 @@ void DiagramSceneModel::onSelectionChanged()
foreach (QGraphicsItem *item, newSecondarySelectedItems) {
if (!m_secondarySelectedItems.contains(item)) {
auto selectable = dynamic_cast<ISelectable *>(item);
- QMT_CHECK(selectable);
+ QMT_ASSERT(selectable, return);
selectable->setSecondarySelected(true);
selectionChanged = true;
}
@@ -856,7 +883,7 @@ void DiagramSceneModel::clearGraphicsScene()
m_elementToItemMap.clear();
m_selectedItems.clear();
m_secondarySelectedItems.clear();
- m_focusItem = 0;
+ m_focusItem = nullptr;
// save extra items from being deleted
removeExtraSceneItems();
m_graphicsScene->clear();
@@ -875,9 +902,20 @@ void DiagramSceneModel::addExtraSceneItems()
m_latchController->addToGraphicsScene(m_graphicsScene);
}
+void DiagramSceneModel::recalcSceneRectSize()
+{
+ QRectF sceneRect = m_originItem->mapRectToScene(m_originItem->boundingRect());
+ for (QGraphicsItem *item : Utils::asConst(m_graphicsItems)) {
+ // TODO use an interface to update sceneRect by item
+ if (!dynamic_cast<SwimlaneItem *>(item))
+ sceneRect |= item->mapRectToScene(item->boundingRect());
+ }
+ emit sceneRectChanged(sceneRect);
+}
+
QGraphicsItem *DiagramSceneModel::createGraphicsItem(DElement *element)
{
- QMT_CHECK(element);
+ QMT_ASSERT(element, return nullptr);
QMT_CHECK(!m_elementToItemMap.contains(element));
CreationVisitor visitor(this);
@@ -891,8 +929,8 @@ QGraphicsItem *DiagramSceneModel::createGraphicsItem(DElement *element)
void DiagramSceneModel::updateGraphicsItem(QGraphicsItem *item, DElement *element)
{
- QMT_CHECK(item);
- QMT_CHECK(element);
+ QMT_ASSERT(item, return);
+ QMT_ASSERT(element, return);
UpdateVisitor visitor(item, this);
element->accept(&visitor);
@@ -915,8 +953,8 @@ void DiagramSceneModel::deleteGraphicsItem(QGraphicsItem *item, DElement *elemen
void DiagramSceneModel::updateFocusItem(const QSet<QGraphicsItem *> &selectedItems)
{
QGraphicsItem *mouseGrabberItem = m_graphicsScene->mouseGrabberItem();
- QGraphicsItem *focusItem = 0;
- ISelectable *selectable = 0;
+ QGraphicsItem *focusItem = nullptr;
+ ISelectable *selectable = nullptr;
if (mouseGrabberItem && selectedItems.contains(mouseGrabberItem)) {
selectable = dynamic_cast<ISelectable *>(mouseGrabberItem);
@@ -939,17 +977,17 @@ void DiagramSceneModel::unsetFocusItem()
oldSelectable->setFocusSelected(false);
else
QMT_CHECK(false);
- m_focusItem = 0;
+ m_focusItem = nullptr;
}
}
bool DiagramSceneModel::isInFrontOf(const QGraphicsItem *frontItem, const QGraphicsItem *backItem)
{
- QMT_CHECK(frontItem);
- QMT_CHECK(backItem);
+ QMT_ASSERT(frontItem, return false);
+ QMT_ASSERT(backItem, return false);
// shortcut for usual case of root items
- if (frontItem->parentItem() == 0 && backItem->parentItem() == 0) {
+ if (!frontItem->parentItem() && !backItem->parentItem()) {
foreach (const QGraphicsItem *item, m_graphicsScene->items()) {
if (item == frontItem)
return true;
@@ -963,7 +1001,7 @@ bool DiagramSceneModel::isInFrontOf(const QGraphicsItem *frontItem, const QGraph
// collect all anchestors of front item
QList<const QGraphicsItem *> frontStack;
const QGraphicsItem *iterator = frontItem;
- while (iterator != 0) {
+ while (iterator) {
frontStack.append(iterator);
iterator = iterator->parentItem();
}
@@ -971,7 +1009,7 @@ bool DiagramSceneModel::isInFrontOf(const QGraphicsItem *frontItem, const QGraph
// collect all anchestors of back item
QList<const QGraphicsItem *> backStack;
iterator = backItem;
- while (iterator != 0) {
+ while (iterator) {
backStack.append(iterator);
iterator = iterator->parentItem();
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.h b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.h
index 1b616710cfa..04cbf6b418d 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.h
@@ -54,6 +54,7 @@ class DSelection;
class MDiagram;
class DElement;
class DObject;
+class ObjectItem;
class QMT_EXPORT DiagramSceneModel : public QObject
{
@@ -73,12 +74,13 @@ public:
CollidingOuterItems
};
- explicit DiagramSceneModel(QObject *parent = 0);
+ explicit DiagramSceneModel(QObject *parent = nullptr);
~DiagramSceneModel() override;
signals:
void diagramSceneActivated(const MDiagram *diagram);
void selectionHasChanged(const MDiagram *diagram);
+ void sceneRectChanged(const QRectF &sceneRect);
public:
DiagramController *diagramController() const { return m_diagramController; }
@@ -98,6 +100,7 @@ public:
DSelection selectedElements() const;
DElement *findTopmostElement(const QPointF &scenePos) const;
DObject *findTopmostObject(const QPointF &scenePos) const;
+ ObjectItem *findTopmostObjectItem(const QPointF &scenePos) const;
QList<QGraphicsItem *> graphicsItems() const { return m_graphicsItems; }
QGraphicsItem *graphicsItem(DElement *element) const;
@@ -150,6 +153,7 @@ private:
void clearGraphicsScene();
void removeExtraSceneItems();
void addExtraSceneItems();
+ void recalcSceneRectSize();
QGraphicsItem *createGraphicsItem(DElement *element);
void updateGraphicsItem(QGraphicsItem *item, DElement *element);
void deleteGraphicsItem(QGraphicsItem *item, DElement *element);
@@ -165,21 +169,21 @@ private:
RemoveElement
};
- DiagramController *m_diagramController;
- DiagramSceneController *m_diagramSceneController;
- StyleController *m_styleController;
- StereotypeController *m_stereotypeController;
- MDiagram *m_diagram;
- DiagramGraphicsScene *m_graphicsScene;
- LatchController *m_latchController;
+ DiagramController *m_diagramController = nullptr;
+ DiagramSceneController *m_diagramSceneController = nullptr;
+ StyleController *m_styleController = nullptr;
+ StereotypeController *m_stereotypeController = nullptr;
+ MDiagram *m_diagram = nullptr;
+ DiagramGraphicsScene *m_graphicsScene = nullptr;
+ LatchController *m_latchController = nullptr;
QList<QGraphicsItem *> m_graphicsItems;
QHash<const QGraphicsItem *, DElement *> m_itemToElementMap;
QHash<const DElement *, QGraphicsItem *> m_elementToItemMap;
QSet<QGraphicsItem *> m_selectedItems;
QSet<QGraphicsItem *> m_secondarySelectedItems;
- Busy m_busyState;
- OriginItem *m_originItem;
- QGraphicsItem *m_focusItem;
+ Busy m_busyState = NotBusy;
+ OriginItem *m_originItem = nullptr;
+ QGraphicsItem *m_focusItem = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.cpp b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.cpp
index 370b901d6b2..2a0a557190b 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.cpp
@@ -32,8 +32,10 @@
#include "items/itemitem.h"
#include "items/relationitem.h"
#include "items/associationitem.h"
+#include "items/connectionitem.h"
#include "items/annotationitem.h"
#include "items/boundaryitem.h"
+#include "items/swimlaneitem.h"
#include "qmt/diagram/delement.h"
#include "qmt/diagram/dobject.h"
@@ -46,15 +48,16 @@
#include "qmt/diagram/dinheritance.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dassociation.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/diagram/dannotation.h"
#include "qmt/diagram/dboundary.h"
+#include "qmt/diagram/dswimlane.h"
#include "qmt/infrastructure/qmtassert.h"
namespace qmt {
DiagramSceneModel::CreationVisitor::CreationVisitor(DiagramSceneModel *diagramSceneModel)
- : m_diagramSceneModel(diagramSceneModel),
- m_graphicsItem(nullptr)
+ : m_diagramSceneModel(diagramSceneModel)
{
}
@@ -122,6 +125,12 @@ void DiagramSceneModel::CreationVisitor::visitDAssociation(DAssociation *associa
m_graphicsItem = new AssociationItem(association, m_diagramSceneModel);
}
+void DiagramSceneModel::CreationVisitor::visitDConnection(DConnection *connection)
+{
+ QMT_CHECK(!m_graphicsItem);
+ m_graphicsItem = new ConnectionItem(connection, m_diagramSceneModel);
+}
+
void DiagramSceneModel::CreationVisitor::visitDAnnotation(DAnnotation *annotation)
{
QMT_CHECK(!m_graphicsItem);
@@ -134,6 +143,12 @@ void DiagramSceneModel::CreationVisitor::visitDBoundary(DBoundary *boundary)
m_graphicsItem = new BoundaryItem(boundary, m_diagramSceneModel);
}
+void DiagramSceneModel::CreationVisitor::visitDSwimlane(DSwimlane *swimlane)
+{
+ QMT_CHECK(!m_graphicsItem);
+ m_graphicsItem = new SwimlaneItem(swimlane, m_diagramSceneModel);
+}
+
DiagramSceneModel::UpdateVisitor::UpdateVisitor(QGraphicsItem *item, DiagramSceneModel *diagramSceneModel,
DElement *relatedElement)
: m_graphicsItem(item),
@@ -150,12 +165,12 @@ void DiagramSceneModel::UpdateVisitor::visitDElement(DElement *element)
void DiagramSceneModel::UpdateVisitor::visitDObject(DObject *object)
{
- if (m_relatedElement == 0) {
+ if (!m_relatedElement) {
// update all related relations
foreach (QGraphicsItem *item, m_diagramSceneModel->m_graphicsItems) {
DElement *element = m_diagramSceneModel->m_itemToElementMap.value(item);
QMT_CHECK(element);
- if (dynamic_cast<DRelation *>(element) != 0) {
+ if (dynamic_cast<DRelation *>(element)) {
UpdateVisitor visitor(item, m_diagramSceneModel, object);
element->accept(&visitor);
}
@@ -165,11 +180,11 @@ void DiagramSceneModel::UpdateVisitor::visitDObject(DObject *object)
void DiagramSceneModel::UpdateVisitor::visitDPackage(DPackage *package)
{
- QMT_CHECK(m_graphicsItem);
+ QMT_ASSERT(m_graphicsItem, return);
- if (m_relatedElement == 0) {
+ if (!m_relatedElement) {
PackageItem *packageItem = qgraphicsitem_cast<PackageItem *>(m_graphicsItem);
- QMT_CHECK(packageItem);
+ QMT_ASSERT(packageItem, return);
QMT_CHECK(packageItem->object() == package);
packageItem->update();
}
@@ -179,11 +194,11 @@ void DiagramSceneModel::UpdateVisitor::visitDPackage(DPackage *package)
void DiagramSceneModel::UpdateVisitor::visitDClass(DClass *klass)
{
- QMT_CHECK(m_graphicsItem);
+ QMT_ASSERT(m_graphicsItem, return);
- if (m_relatedElement == 0) {
+ if (!m_relatedElement) {
ClassItem *classItem = qgraphicsitem_cast<ClassItem *>(m_graphicsItem);
- QMT_CHECK(classItem);
+ QMT_ASSERT(classItem, return);
QMT_CHECK(classItem->object() == klass);
classItem->update();
}
@@ -193,11 +208,11 @@ void DiagramSceneModel::UpdateVisitor::visitDClass(DClass *klass)
void DiagramSceneModel::UpdateVisitor::visitDComponent(DComponent *component)
{
- QMT_CHECK(m_graphicsItem);
+ QMT_ASSERT(m_graphicsItem, return);
- if (m_relatedElement == 0) {
+ if (!m_relatedElement) {
ComponentItem *componentItem = qgraphicsitem_cast<ComponentItem *>(m_graphicsItem);
- QMT_CHECK(componentItem);
+ QMT_ASSERT(componentItem, return);
QMT_CHECK(componentItem->object() == component);
componentItem->update();
}
@@ -207,11 +222,11 @@ void DiagramSceneModel::UpdateVisitor::visitDComponent(DComponent *component)
void DiagramSceneModel::UpdateVisitor::visitDDiagram(DDiagram *diagram)
{
- QMT_CHECK(m_graphicsItem);
+ QMT_ASSERT(m_graphicsItem, return);
- if (m_relatedElement == 0) {
+ if (!m_relatedElement) {
DiagramItem *documentItem = qgraphicsitem_cast<DiagramItem *>(m_graphicsItem);
- QMT_CHECK(documentItem);
+ QMT_ASSERT(documentItem, return);
QMT_CHECK(documentItem->object() == diagram);
documentItem->update();
}
@@ -221,11 +236,11 @@ void DiagramSceneModel::UpdateVisitor::visitDDiagram(DDiagram *diagram)
void DiagramSceneModel::UpdateVisitor::visitDItem(DItem *item)
{
- QMT_CHECK(m_graphicsItem);
+ QMT_ASSERT(m_graphicsItem, return);
- if (m_relatedElement == 0) {
+ if (!m_relatedElement) {
ItemItem *itemItem = qgraphicsitem_cast<ItemItem *>(m_graphicsItem);
- QMT_CHECK(itemItem);
+ QMT_ASSERT(itemItem, return);
QMT_CHECK(itemItem->object() == item);
itemItem->update();
}
@@ -235,13 +250,13 @@ void DiagramSceneModel::UpdateVisitor::visitDItem(DItem *item)
void DiagramSceneModel::UpdateVisitor::visitDRelation(DRelation *relation)
{
- QMT_CHECK(m_graphicsItem);
+ QMT_ASSERT(m_graphicsItem, return);
- if (m_relatedElement == 0
+ if (!m_relatedElement
|| m_relatedElement->uid() == relation->endAUid()
|| m_relatedElement->uid() == relation->endBUid()) {
RelationItem *relationItem = qgraphicsitem_cast<RelationItem *>(m_graphicsItem);
- QMT_CHECK(relationItem);
+ QMT_ASSERT(relationItem, return);
QMT_CHECK(relationItem->relation() == relation);
relationItem->update();
}
@@ -262,13 +277,18 @@ void DiagramSceneModel::UpdateVisitor::visitDAssociation(DAssociation *associati
visitDRelation(association);
}
+void DiagramSceneModel::UpdateVisitor::visitDConnection(DConnection *connection)
+{
+ visitDRelation(connection);
+}
+
void DiagramSceneModel::UpdateVisitor::visitDAnnotation(DAnnotation *annotation)
{
Q_UNUSED(annotation); // avoid warning in release mode
- QMT_CHECK(m_graphicsItem);
+ QMT_ASSERT(m_graphicsItem, return);
AnnotationItem *annotationItem = qgraphicsitem_cast<AnnotationItem *>(m_graphicsItem);
- QMT_CHECK(annotationItem);
+ QMT_ASSERT(annotationItem, return);
QMT_CHECK(annotationItem->annotation() == annotation);
annotationItem->update();
}
@@ -276,12 +296,23 @@ void DiagramSceneModel::UpdateVisitor::visitDAnnotation(DAnnotation *annotation)
void DiagramSceneModel::UpdateVisitor::visitDBoundary(DBoundary *boundary)
{
Q_UNUSED(boundary); // avoid warning in release mode
- QMT_CHECK(m_graphicsItem);
+ QMT_ASSERT(m_graphicsItem, return);
BoundaryItem *boundaryItem = qgraphicsitem_cast<BoundaryItem *>(m_graphicsItem);
- QMT_CHECK(boundaryItem);
+ QMT_ASSERT(boundaryItem, return);
QMT_CHECK(boundaryItem->boundary() == boundary);
boundaryItem->update();
}
+void DiagramSceneModel::UpdateVisitor::visitDSwimlane(DSwimlane *swimlane)
+{
+ Q_UNUSED(swimlane); // avoid warning in release mode
+ QMT_ASSERT(m_graphicsItem, return);
+
+ SwimlaneItem *swimlaneItem = qgraphicsitem_cast<SwimlaneItem *>(m_graphicsItem);
+ QMT_ASSERT(swimlaneItem, return);
+ QMT_CHECK(swimlaneItem->swimlane() == swimlane);
+ swimlaneItem->update();
+}
+
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.h b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.h
index 138f0874816..a2bbefc9f0e 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.h
@@ -49,19 +49,21 @@ public:
void visitDInheritance(DInheritance *inheritance) override;
void visitDDependency(DDependency *dependency) override;
void visitDAssociation(DAssociation *association) override;
+ void visitDConnection(DConnection *connection) override;
void visitDAnnotation(DAnnotation *annotation) override;
void visitDBoundary(DBoundary *boundary) override;
+ void visitDSwimlane(DSwimlane *swimlane) override;
private:
- DiagramSceneModel *m_diagramSceneModel;
- QGraphicsItem *m_graphicsItem;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
+ QGraphicsItem *m_graphicsItem = nullptr;
};
class QMT_EXPORT DiagramSceneModel::UpdateVisitor : public DVisitor
{
public:
UpdateVisitor(QGraphicsItem *item, DiagramSceneModel *diagramSceneModel,
- DElement *relatedElement = 0);
+ DElement *relatedElement = nullptr);
void visitDElement(DElement *element) override;
void visitDObject(DObject *object) override;
@@ -74,13 +76,15 @@ public:
void visitDInheritance(DInheritance *inheritance) override;
void visitDDependency(DDependency *dependency) override;
void visitDAssociation(DAssociation *association) override;
+ void visitDConnection(DConnection *connection) override;
void visitDAnnotation(DAnnotation *annotation) override;
void visitDBoundary(DBoundary *boundary) override;
+ void visitDSwimlane(DSwimlane *swimlane) override;
private:
- QGraphicsItem *m_graphicsItem;
- DiagramSceneModel *m_diagramSceneModel;
- DElement *m_relatedElement;
+ QGraphicsItem *m_graphicsItem = nullptr;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
+ DElement *m_relatedElement = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.cpp
index 2f21e00042c..d9da017d58c 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.cpp
@@ -60,7 +60,7 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- QMT_CHECK(option);
+ QMT_ASSERT(option, return);
QStyleOptionGraphicsItem option2(*option);
option2.state &= ~(QStyle::State_Selected | QStyle::State_HasFocus);
@@ -213,6 +213,21 @@ void AnnotationItem::setFocusSelected(bool focusSelected)
}
}
+QRectF AnnotationItem::getSecondarySelectionBoundary()
+{
+ return QRectF();
+}
+
+void AnnotationItem::setBoundarySelected(const QRectF &boundary, bool secondary)
+{
+ if (boundary.contains(mapRectToScene(boundingRect()))) {
+ if (secondary)
+ setSecondarySelected(true);
+ else
+ setSelected(true);
+ }
+}
+
bool AnnotationItem::isEditable() const
{
return true;
@@ -260,7 +275,7 @@ void AnnotationItem::updateSelectionMarker()
if (m_selectionMarker->scene())
m_selectionMarker->scene()->removeItem(m_selectionMarker);
delete m_selectionMarker;
- m_selectionMarker = 0;
+ m_selectionMarker = nullptr;
}
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.h
index 29e16224ecd..d7bce8d8dc7 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.h
@@ -50,7 +50,7 @@ class AnnotationItem :
public:
AnnotationItem(DAnnotation *annotation, DiagramSceneModel *diagramSceneModel,
- QGraphicsItem *parent = 0);
+ QGraphicsItem *parent = nullptr);
~AnnotationItem() override;
DAnnotation *annotation() const { return m_annotation; }
@@ -77,6 +77,8 @@ public:
void setSecondarySelected(bool secondarySelected) override;
bool isFocusSelected() const override;
void setFocusSelected(bool focusSelected) override;
+ QRectF getSecondarySelectionBoundary() override;
+ void setBoundarySelected(const QRectF &boundary, bool secondary) override;
bool isEditable() const override;
void edit() override;
@@ -98,13 +100,13 @@ private:
QSizeF calcMinimumGeometry() const;
void updateGeometry();
- DAnnotation *m_annotation = 0;
- DiagramSceneModel *m_diagramSceneModel = 0;
+ DAnnotation *m_annotation = nullptr;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
bool m_isSecondarySelected = false;
bool m_isFocusSelected = false;
- RectangularSelectionItem *m_selectionMarker = 0;
- QGraphicsRectItem *m_noTextItem = 0;
- AnnotationTextItem *m_textItem = 0;
+ RectangularSelectionItem *m_selectionMarker = nullptr;
+ QGraphicsRectItem *m_noTextItem = nullptr;
+ AnnotationTextItem *m_textItem = nullptr;
bool m_isUpdating = false;
bool m_isChanged = false;
};
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.cpp
index 0211700ab27..1aee12d4652 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.cpp
@@ -60,7 +60,7 @@ void AssociationItem::update(const Style *style)
updateEndLabels(m_association->endA(), m_association->endB(), &m_endAName, &m_endACardinality, style);
updateEndLabels(m_association->endB(), m_association->endA(), &m_endBName, &m_endBCardinality, style);
- QMT_CHECK(m_arrow);
+ QMT_ASSERT(m_arrow, return);
QGraphicsItem *endAItem = m_diagramSceneModel->graphicsItem(m_association->endAUid());
if (!endAItem)
return;
@@ -86,7 +86,7 @@ void AssociationItem::updateEndLabels(const DAssociationEnd &end, const DAssocia
} else if (*endName) {
(*endName)->scene()->removeItem(*endName);
delete *endName;
- *endName = 0;
+ *endName = nullptr;
}
if (!otherEnd.cardinality().isEmpty()) {
@@ -98,7 +98,7 @@ void AssociationItem::updateEndLabels(const DAssociationEnd &end, const DAssocia
} else if (*endCardinality) {
(*endCardinality)->scene()->removeItem(*endCardinality);
delete *endCardinality;
- *endCardinality = 0;
+ *endCardinality = nullptr;
}
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.h
index ad076eee591..ea11df42e34 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.h
@@ -40,7 +40,7 @@ class AssociationItem : public RelationItem
{
public:
AssociationItem(DAssociation *association, DiagramSceneModel *diagramSceneModel,
- QGraphicsItem *parent = 0);
+ QGraphicsItem *parent = nullptr);
~AssociationItem() override;
protected:
@@ -54,11 +54,11 @@ private:
QGraphicsItem *endCardinality,
QGraphicsItem *endItem, double headLength);
- DAssociation *m_association = 0;
- QGraphicsSimpleTextItem *m_endAName = 0;
- QGraphicsSimpleTextItem *m_endACardinality = 0;
- QGraphicsSimpleTextItem *m_endBName = 0;
- QGraphicsSimpleTextItem *m_endBCardinality = 0;
+ DAssociation *m_association = nullptr;
+ QGraphicsSimpleTextItem *m_endAName = nullptr;
+ QGraphicsSimpleTextItem *m_endACardinality = nullptr;
+ QGraphicsSimpleTextItem *m_endBName = nullptr;
+ QGraphicsSimpleTextItem *m_endBCardinality = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.cpp
index 6cd673969de..cedfc5816c0 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.cpp
@@ -62,7 +62,7 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- QMT_CHECK(option);
+ QMT_ASSERT(option, return);
QStyleOptionGraphicsItem option2(*option);
option2.state &= ~(QStyle::State_Selected | QStyle::State_HasFocus);
@@ -126,7 +126,7 @@ void BoundaryItem::update()
} else if (m_noTextItem) {
m_noTextItem->scene()->removeItem(m_noTextItem);
delete m_noTextItem;
- m_noTextItem = 0;
+ m_noTextItem = nullptr;
}
// item shown if annotation has no text and is not selected
@@ -264,6 +264,21 @@ void BoundaryItem::setFocusSelected(bool focusSelected)
}
}
+QRectF BoundaryItem::getSecondarySelectionBoundary()
+{
+ return QRectF();
+}
+
+void BoundaryItem::setBoundarySelected(const QRectF &boundary, bool secondary)
+{
+ if (boundary.contains(mapRectToScene(boundingRect()))) {
+ if (secondary)
+ setSecondarySelected(true);
+ else
+ setSelected(true);
+ }
+}
+
bool BoundaryItem::isEditable() const
{
return true;
@@ -308,7 +323,7 @@ void BoundaryItem::updateSelectionMarker()
if (m_selectionMarker->scene())
m_selectionMarker->scene()->removeItem(m_selectionMarker);
delete m_selectionMarker;
- m_selectionMarker = 0;
+ m_selectionMarker = nullptr;
}
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.h
index b6b3380bebc..d2105c08bf9 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.h
@@ -50,7 +50,7 @@ class BoundaryItem :
public:
BoundaryItem(DBoundary *boundary, DiagramSceneModel *diagramSceneModel,
- QGraphicsItem *parent = 0);
+ QGraphicsItem *parent = nullptr);
~BoundaryItem() override;
DBoundary *boundary() const { return m_boundary; }
@@ -76,6 +76,8 @@ public:
void setSecondarySelected(bool secondarySelected) override;
bool isFocusSelected() const override;
void setFocusSelected(bool focusSelected) override;
+ QRectF getSecondarySelectionBoundary() override;
+ void setBoundarySelected(const QRectF &boundary, bool secondary) override;
bool isEditable() const override;
void edit() override;
@@ -96,14 +98,14 @@ private:
QSizeF calcMinimumGeometry() const;
void updateGeometry();
- DBoundary *m_boundary = 0;
- DiagramSceneModel *m_diagramSceneModel = 0;
+ DBoundary *m_boundary = nullptr;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
bool m_isSecondarySelected = false;
bool m_isFocusSelected = false;
- RectangularSelectionItem *m_selectionMarker = 0;
- QGraphicsRectItem *m_borderItem = 0;
- QGraphicsRectItem *m_noTextItem = 0;
- BoundaryTextItem *m_textItem = 0;
+ RectangularSelectionItem *m_selectionMarker = nullptr;
+ QGraphicsRectItem *m_borderItem = nullptr;
+ QGraphicsRectItem *m_noTextItem = nullptr;
+ BoundaryTextItem *m_textItem = nullptr;
bool m_isUpdating = false;
bool m_isChanged = false;
};
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp
index a1c76b26179..fe459338a17 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp
@@ -40,6 +40,7 @@
#include "qmt/infrastructure/qmtassert.h"
#include "qmt/model/mclass.h"
#include "qmt/model/mclassmember.h"
+#include "qmt/model/massociation.h"
#include "qmt/model_controller/modelcontroller.h"
#include "qmt/stereotype/stereotypecontroller.h"
#include "qmt/stereotype/stereotypeicon.h"
@@ -59,15 +60,20 @@
#include <algorithm>
+#include <qmt/stereotype/customrelation.h>
+
namespace qmt {
+static const char ASSOCIATION[] = "association";
+static const char INHERITANCE[] = "inheritance";
+
static const qreal MINIMUM_AUTO_WIDTH = 80.0;
static const qreal MINIMUM_AUTO_HEIGHT = 60.0;
static const qreal BODY_VERT_BORDER = 4.0;
static const qreal BODY_HORIZ_BORDER = 4.0;
ClassItem::ClassItem(DClass *klass, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent)
- : ObjectItem(klass, diagramSceneModel, parent)
+ : ObjectItem("class", klass, diagramSceneModel, parent)
{
}
@@ -82,7 +88,7 @@ void ClassItem::update()
updateStereotypeIconDisplay();
auto diagramClass = dynamic_cast<DClass *>(object());
- QMT_CHECK(diagramClass);
+ QMT_ASSERT(diagramClass, return);
const Style *style = adaptedStyle(stereotypeIconId());
@@ -105,7 +111,7 @@ void ClassItem::update()
} else if (m_customIcon) {
m_customIcon->scene()->removeItem(m_customIcon);
delete m_customIcon;
- m_customIcon = 0;
+ m_customIcon = nullptr;
}
// shape
@@ -118,7 +124,7 @@ void ClassItem::update()
} else if (m_shape){
m_shape->scene()->removeItem(m_shape);
delete m_shape;
- m_shape = 0;
+ m_shape = nullptr;
}
// stereotypes
@@ -134,7 +140,7 @@ void ClassItem::update()
} else if (m_namespace) {
m_namespace->scene()->removeItem(m_namespace);
delete m_namespace;
- m_namespace = 0;
+ m_namespace = nullptr;
}
// class name
@@ -150,7 +156,7 @@ void ClassItem::update()
} else if (m_contextLabel) {
m_contextLabel->scene()->removeItem(m_contextLabel);
delete m_contextLabel;
- m_contextLabel = 0;
+ m_contextLabel = nullptr;
}
// attributes separator
@@ -162,7 +168,7 @@ void ClassItem::update()
} else if (m_attributesSeparator) {
m_attributesSeparator->scene()->removeItem(m_attributesSeparator);
delete m_attributesSeparator;
- m_attributesSeparator = 0;
+ m_attributesSeparator = nullptr;
}
// attributes
@@ -176,7 +182,7 @@ void ClassItem::update()
} else if (m_attributes) {
m_attributes->scene()->removeItem(m_attributes);
delete m_attributes;
- m_attributes = 0;
+ m_attributes = nullptr;
}
// methods separator
@@ -188,7 +194,7 @@ void ClassItem::update()
} else if (m_methodsSeparator) {
m_methodsSeparator->scene()->removeItem(m_methodsSeparator);
delete m_methodsSeparator;
- m_methodsSeparator = 0;
+ m_methodsSeparator = nullptr;
}
// methods
@@ -202,7 +208,7 @@ void ClassItem::update()
} else if (m_methods) {
m_methods->scene()->removeItem(m_methods);
delete m_methods;
- m_methods = 0;
+ m_methods = nullptr;
}
// template parameters
@@ -223,27 +229,11 @@ void ClassItem::update()
} else if (m_templateParameterBox) {
m_templateParameterBox->scene()->removeItem(m_templateParameterBox);
delete m_templateParameterBox;
- m_templateParameterBox = 0;
+ m_templateParameterBox = nullptr;
}
updateSelectionMarker(m_customIcon);
-
- // relation starters
- if (isFocusSelected()) {
- if (!m_relationStarter) {
- m_relationStarter = new RelationStarter(this, diagramSceneModel(), 0);
- scene()->addItem(m_relationStarter);
- m_relationStarter->setZValue(RELATION_STARTER_ZVALUE);
- m_relationStarter->addArrow(QLatin1String("inheritance"), ArrowItem::ShaftSolid, ArrowItem::HeadTriangle);
- m_relationStarter->addArrow(QLatin1String("dependency"), ArrowItem::ShaftDashed, ArrowItem::HeadOpen);
- m_relationStarter->addArrow(QLatin1String("association"), ArrowItem::ShaftSolid, ArrowItem::HeadFilledTriangle);
- }
- } else if (m_relationStarter) {
- scene()->removeItem(m_relationStarter);
- delete m_relationStarter;
- m_relationStarter = 0;
- }
-
+ updateRelationStarter();
updateAlignmentButtons();
updateGeometry();
}
@@ -263,42 +253,90 @@ QSizeF ClassItem::minimumSize() const
return calcMinimumGeometry();
}
-QPointF ClassItem::relationStartPos() const
+void ClassItem::relationDrawn(const QString &id, ObjectItem *targetItem, const QList<QPointF> &intermediatePoints)
{
- return pos();
-}
-
-void ClassItem::relationDrawn(const QString &id, const QPointF &toScenePos, const QList<QPointF> &intermediatePoints)
-{
- DElement *targetElement = diagramSceneModel()->findTopmostElement(toScenePos);
- if (targetElement) {
- if (id == QLatin1String("inheritance")) {
- auto baseClass = dynamic_cast<DClass *>(targetElement);
- if (baseClass) {
- auto derivedClass = dynamic_cast<DClass *>(object());
- QMT_CHECK(derivedClass);
- diagramSceneModel()->diagramSceneController()->createInheritance(derivedClass, baseClass, intermediatePoints, diagramSceneModel()->diagram());
+ DiagramSceneController *diagramSceneController = diagramSceneModel()->diagramSceneController();
+ if (id == INHERITANCE) {
+ auto baseClass = dynamic_cast<DClass *>(targetItem->object());
+ if (baseClass) {
+ auto derivedClass = dynamic_cast<DClass *>(object());
+ QMT_ASSERT(derivedClass, return);
+ diagramSceneController->createInheritance(derivedClass, baseClass, intermediatePoints, diagramSceneModel()->diagram());
+ }
+ return;
+ } else if (id == ASSOCIATION) {
+ auto associatedClass = dynamic_cast<DClass *>(targetItem->object());
+ if (associatedClass) {
+ auto derivedClass = dynamic_cast<DClass *>(object());
+ QMT_ASSERT(derivedClass, return);
+ diagramSceneController->createAssociation(derivedClass, associatedClass, intermediatePoints, diagramSceneModel()->diagram());
+ }
+ return;
+ } else {
+ StereotypeController *stereotypeController = diagramSceneModel()->stereotypeController();
+ CustomRelation customRelation = stereotypeController->findCustomRelation(id);
+ if (!customRelation.isNull()) {
+ switch (customRelation.element()) {
+ case CustomRelation::Element::Inheritance:
+ {
+ auto baseClass = dynamic_cast<DClass *>(targetItem->object());
+ if (baseClass) {
+ auto derivedClass = dynamic_cast<DClass *>(object());
+ QMT_ASSERT(derivedClass, return);
+ diagramSceneController->createInheritance(derivedClass, baseClass, intermediatePoints, diagramSceneModel()->diagram());
+ }
+ return;
}
- } else if (id == QLatin1String("dependency")) {
- auto dependantObject = dynamic_cast<DObject *>(targetElement);
- if (dependantObject)
- diagramSceneModel()->diagramSceneController()->createDependency(object(), dependantObject, intermediatePoints, diagramSceneModel()->diagram());
- } else if (id == QLatin1String("association")) {
- auto assoziatedClass = dynamic_cast<DClass *>(targetElement);
- if (assoziatedClass) {
- auto derivedClass = dynamic_cast<DClass *>(object());
- QMT_CHECK(derivedClass);
- diagramSceneModel()->diagramSceneController()->createAssociation(derivedClass, assoziatedClass, intermediatePoints, diagramSceneModel()->diagram());
+ case CustomRelation::Element::Association:
+ {
+ auto assoziatedClass = dynamic_cast<DClass *>(targetItem->object());
+ if (assoziatedClass) {
+ auto derivedClass = dynamic_cast<DClass *>(object());
+ QMT_ASSERT(derivedClass, return);
+ diagramSceneController->createAssociation(
+ derivedClass, assoziatedClass, intermediatePoints, diagramSceneModel()->diagram(),
+ [=] (MAssociation *mAssociation, DAssociation *dAssociation) {
+ if (mAssociation && dAssociation) {
+ static const QHash<CustomRelation::Relationship, MAssociationEnd::Kind> relationship2KindMap = {
+ { CustomRelation::Relationship::Association, MAssociationEnd::Association },
+ { CustomRelation::Relationship::Aggregation, MAssociationEnd::Aggregation },
+ { CustomRelation::Relationship::Composition, MAssociationEnd::Composition } };
+ diagramSceneController->modelController()->startUpdateRelation(mAssociation);
+ mAssociation->setStereotypes(customRelation.stereotypes().toList());
+ mAssociation->setName(customRelation.name());
+ MAssociationEnd endA;
+ endA.setCardinality(customRelation.endA().cardinality());
+ endA.setKind(relationship2KindMap.value(customRelation.endA().relationship()));
+ endA.setName(customRelation.endA().role());
+ endA.setNavigable(customRelation.endA().navigable());
+ mAssociation->setEndA(endA);
+ MAssociationEnd endB;
+ endB.setCardinality(customRelation.endB().cardinality());
+ endB.setKind(relationship2KindMap.value(customRelation.endB().relationship()));
+ endB.setName(customRelation.endB().role());
+ endB.setNavigable(customRelation.endB().navigable());
+ mAssociation->setEndB(endB);
+ diagramSceneController->modelController()->finishUpdateRelation(mAssociation, false);
+ }
+ });
+ }
+ return;
+ }
+ case CustomRelation::Element::Dependency:
+ case CustomRelation::Element::Relation:
+ // fall thru
+ break;
}
}
}
+ ObjectItem::relationDrawn(id, targetItem, intermediatePoints);
}
bool ClassItem::extendContextMenu(QMenu *menu)
{
bool extended = false;
if (diagramSceneModel()->diagramSceneController()->elementTasks()->hasClassDefinition(object(), diagramSceneModel()->diagram())) {
- menu->addAction(new ContextMenuAction(tr("Show Definition"), QStringLiteral("showDefinition"), menu));
+ menu->addAction(new ContextMenuAction(tr("Show Definition"), "showDefinition", menu));
extended = true;
}
return extended;
@@ -306,7 +344,7 @@ bool ClassItem::extendContextMenu(QMenu *menu)
bool ClassItem::handleSelectedContextMenuAction(const QString &id)
{
- if (id == QStringLiteral("showDefinition")) {
+ if (id == "showDefinition") {
diagramSceneModel()->diagramSceneController()->elementTasks()->openClassDefinition(object(), diagramSceneModel()->diagram());
return true;
}
@@ -316,7 +354,7 @@ bool ClassItem::handleSelectedContextMenuAction(const QString &id)
QString ClassItem::buildDisplayName() const
{
auto diagramClass = dynamic_cast<DClass *>(object());
- QMT_CHECK(diagramClass);
+ QMT_ASSERT(diagramClass, return QString());
QString name;
if (templateDisplay() == DClass::TemplateName && !diagramClass->templateParameters().isEmpty()) {
@@ -342,9 +380,9 @@ void ClassItem::setFromDisplayName(const QString &displayName)
QString name;
QStringList templateParameters;
// NOTE namespace is ignored because it has its own edit field
- if (NameController::parseClassName(displayName, 0, &name, &templateParameters)) {
+ if (NameController::parseClassName(displayName, nullptr, &name, &templateParameters)) {
auto diagramClass = dynamic_cast<DClass *>(object());
- QMT_CHECK(diagramClass);
+ QMT_ASSERT(diagramClass, return);
ModelController *modelController = diagramSceneModel()->diagramSceneController()->modelController();
MClass *mklass = modelController->findObject<MClass>(diagramClass->modelUid());
if (mklass && (name != mklass->name() || templateParameters != mklass->templateParameters())) {
@@ -359,10 +397,70 @@ void ClassItem::setFromDisplayName(const QString &displayName)
}
}
+void ClassItem::addRelationStarterTool(const QString &id)
+{
+ if (id == INHERITANCE)
+ relationStarter()->addArrow(INHERITANCE, ArrowItem::ShaftSolid,
+ ArrowItem::HeadNone, ArrowItem::HeadTriangle,
+ tr("Inheritance"));
+ else if (id == ASSOCIATION)
+ relationStarter()->addArrow(ASSOCIATION, ArrowItem::ShaftSolid,
+ ArrowItem::HeadNone, ArrowItem::HeadFilledTriangle,
+ tr("Association"));
+ else
+ ObjectItem::addRelationStarterTool(id);
+}
+
+void ClassItem::addRelationStarterTool(const CustomRelation &customRelation)
+{
+ ArrowItem::Shaft shaft = ArrowItem::ShaftSolid;
+ ArrowItem::Head headStart = ArrowItem::HeadNone;
+ ArrowItem::Head headEnd = ArrowItem::HeadNone;
+ switch (customRelation.element()) {
+ case CustomRelation::Element::Inheritance:
+ shaft = ArrowItem::ShaftSolid;
+ headEnd = ArrowItem::HeadTriangle;
+ break;
+ case CustomRelation::Element::Association:
+ switch (customRelation.endA().relationship()) {
+ case CustomRelation::Relationship::Association:
+ if (customRelation.endA().navigable() && customRelation.endB().navigable()) {
+ headStart = ArrowItem::HeadNone;
+ headEnd = ArrowItem::HeadNone;
+ } else if (customRelation.endA().navigable()) {
+ headStart = ArrowItem::HeadFilledTriangle;
+ } else {
+ headEnd = ArrowItem::HeadFilledTriangle;
+ }
+ break;
+ case CustomRelation::Relationship::Aggregation:
+ headStart = ArrowItem::HeadDiamond;
+ break;
+ case CustomRelation::Relationship::Composition:
+ headStart = ArrowItem::HeadFilledDiamond;
+ break;
+ }
+ break;
+ case CustomRelation::Element::Dependency:
+ case CustomRelation::Element::Relation:
+ ObjectItem::addRelationStarterTool(customRelation);
+ return;
+ }
+ relationStarter()->addArrow(customRelation.id(), shaft, headStart, headEnd,
+ customRelation.title());
+}
+
+void ClassItem::addStandardRelationStarterTools()
+{
+ ObjectItem::addStandardRelationStarterTools();
+ addRelationStarterTool(INHERITANCE);
+ addRelationStarterTool(ASSOCIATION);
+}
+
DClass::TemplateDisplay ClassItem::templateDisplay() const
{
auto diagramClass = dynamic_cast<DClass *>(object());
- QMT_CHECK(diagramClass);
+ QMT_ASSERT(diagramClass, return DClass::TemplateSmart);
DClass::TemplateDisplay templateDisplay = diagramClass->templateDisplay();
if (templateDisplay == DClass::TemplateSmart) {
@@ -535,10 +633,7 @@ void ClassItem::updateGeometry()
}
updateSelectionMarkerGeometry(rect);
-
- if (m_relationStarter)
- m_relationStarter->setPos(mapToScene(QPointF(right + 8.0, top)));
-
+ updateRelationStarterGeometry(rect);
updateAlignmentButtonsGeometry(rect);
updateDepth();
}
@@ -555,17 +650,17 @@ void ClassItem::updateMembers(const Style *style)
QString attributesGroup;
QString methodsGroup;
- MClassMember::Visibility *currentVisibility = 0;
- QString *currentGroup = 0;
- QString *text = 0;
+ MClassMember::Visibility *currentVisibility = nullptr;
+ QString *currentGroup = nullptr;
+ QString *text = nullptr;
auto dclass = dynamic_cast<DClass *>(object());
- QMT_CHECK(dclass);
+ QMT_ASSERT(dclass, return);
foreach (const MClassMember &member, dclass->members()) {
switch (member.memberType()) {
case MClassMember::MemberUndefined:
- QMT_CHECK(false);
+ QMT_ASSERT(false, return);
break;
case MClassMember::MemberAttribute:
currentVisibility = &attributesVisibility;
@@ -580,19 +675,19 @@ void ClassItem::updateMembers(const Style *style)
}
if (text && !text->isEmpty())
- *text += QStringLiteral("<br/>");
+ *text += "<br/>";
bool addNewline = false;
bool addSpace = false;
if (currentVisibility)
*currentVisibility = member.visibility();
if (currentGroup && member.group() != *currentGroup) {
- *text += QString(QStringLiteral("[%1]")).arg(member.group());
+ *text += QString("[%1]").arg(member.group());
addNewline = true;
*currentGroup = member.group();
}
if (addNewline)
- *text += QStringLiteral("<br/>");
+ *text += "<br/>";
bool haveSignal = false;
bool haveSlot = false;
@@ -602,34 +697,34 @@ void ClassItem::updateMembers(const Style *style)
case MClassMember::VisibilityUndefined:
break;
case MClassMember::VisibilityPublic:
- vis = QStringLiteral("+");
+ vis = "+";
addSpace = true;
break;
case MClassMember::VisibilityProtected:
- vis = QStringLiteral("#");
+ vis = "#";
addSpace = true;
break;
case MClassMember::VisibilityPrivate:
- vis = QStringLiteral("-");
+ vis = "-";
addSpace = true;
break;
case MClassMember::VisibilitySignals:
- vis = QStringLiteral("&gt;");
+ vis = "&gt;";
haveSignal = true;
addSpace = true;
break;
case MClassMember::VisibilityPrivateSlots:
- vis = QStringLiteral("-$");
+ vis = "-$";
haveSlot = true;
addSpace = true;
break;
case MClassMember::VisibilityProtectedSlots:
- vis = QStringLiteral("#$");
+ vis = "#$";
haveSlot = true;
addSpace = true;
break;
case MClassMember::VisibilityPublicSlots:
- vis = QStringLiteral("+$");
+ vis = "+$";
haveSlot = true;
addSpace = true;
break;
@@ -638,34 +733,34 @@ void ClassItem::updateMembers(const Style *style)
}
if (member.properties() & MClassMember::PropertyQsignal && !haveSignal) {
- *text += QStringLiteral("&gt;");
+ *text += "&gt;";
addSpace = true;
}
if (member.properties() & MClassMember::PropertyQslot && !haveSlot) {
- *text += QStringLiteral("$");
+ *text += "$";
addSpace = true;
}
if (addSpace)
- *text += QStringLiteral(" ");
+ *text += " ";
if (member.properties() & MClassMember::PropertyQinvokable)
- *text += QStringLiteral("invokable ");
+ *text += "invokable ";
if (!member.stereotypes().isEmpty()) {
*text += StereotypesItem::format(member.stereotypes());
- *text += QStringLiteral(" ");
+ *text += " ";
}
if (member.properties() & MClassMember::PropertyStatic)
- *text += QStringLiteral("static ");
+ *text += "static ";
if (member.properties() & MClassMember::PropertyVirtual)
- *text += QStringLiteral("virtual ");
+ *text += "virtual ";
*text += member.declaration().toHtmlEscaped();
if (member.properties() & MClassMember::PropertyConst)
- *text += QStringLiteral(" const");
+ *text += " const";
if (member.properties() & MClassMember::PropertyOverride)
- *text += QStringLiteral(" override");
+ *text += " override";
if (member.properties() & MClassMember::PropertyFinal)
- *text += QStringLiteral(" final");
+ *text += " final";
if (member.properties() & MClassMember::PropertyAbstract)
- *text += QStringLiteral(" = 0");
+ *text += " = 0";
}
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/classitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/classitem.h
index eb80e3e865c..9fa9dc40bdc 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/classitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/classitem.h
@@ -27,7 +27,6 @@
#include "objectitem.h"
-#include "qmt/diagram_scene/capabilities/relationable.h"
#include "qmt/diagram/dclass.h"
QT_BEGIN_NAMESPACE
@@ -43,15 +42,14 @@ class DiagramSceneModel;
class CustomIconItem;
class ContextLabelItem;
class TemplateParameterBox;
-class RelationStarter;
class Style;
-class ClassItem : public ObjectItem, public IRelationable
+class ClassItem : public ObjectItem
{
Q_DECLARE_TR_FUNCTIONS(qmt::ClassItem)
public:
- ClassItem(DClass *klass, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent = 0);
+ ClassItem(DClass *klass, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent = nullptr);
~ClassItem() override;
void update() override;
@@ -61,8 +59,7 @@ public:
QSizeF minimumSize() const override;
- QPointF relationStartPos() const override;
- void relationDrawn(const QString &id, const QPointF &toScenePos,
+ void relationDrawn(const QString &id, ObjectItem *targetElement,
const QList<QPointF> &intermediatePoints) override;
protected:
@@ -70,6 +67,9 @@ protected:
bool handleSelectedContextMenuAction(const QString &id) override;
QString buildDisplayName() const override;
void setFromDisplayName(const QString &displayName) override;
+ void addRelationStarterTool(const QString &id) override;
+ void addRelationStarterTool(const CustomRelation &customRelation) override;
+ void addStandardRelationStarterTools() override;
private:
DClass::TemplateDisplay templateDisplay() const;
@@ -77,18 +77,17 @@ private:
void updateGeometry();
void updateMembers(const Style *style);
- CustomIconItem *m_customIcon = 0;
- QGraphicsRectItem *m_shape = 0;
- QGraphicsSimpleTextItem *m_namespace = 0;
- ContextLabelItem *m_contextLabel = 0;
- QGraphicsLineItem *m_attributesSeparator = 0;
+ CustomIconItem *m_customIcon = nullptr;
+ QGraphicsRectItem *m_shape = nullptr;
+ QGraphicsSimpleTextItem *m_namespace = nullptr;
+ ContextLabelItem *m_contextLabel = nullptr;
+ QGraphicsLineItem *m_attributesSeparator = nullptr;
QString m_attributesText;
- QGraphicsTextItem *m_attributes = 0;
- QGraphicsLineItem *m_methodsSeparator = 0;
+ QGraphicsTextItem *m_attributes = nullptr;
+ QGraphicsLineItem *m_methodsSeparator = nullptr;
QString m_methodsText;
- QGraphicsTextItem *m_methods = 0;
- TemplateParameterBox *m_templateParameterBox = 0;
- RelationStarter *m_relationStarter = 0;
+ QGraphicsTextItem *m_methods = nullptr;
+ TemplateParameterBox *m_templateParameterBox = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/componentitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/componentitem.cpp
index af4818f2831..98aa69c5c3f 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/componentitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/componentitem.cpp
@@ -32,7 +32,6 @@
#include "qmt/diagram_scene/parts/contextlabelitem.h"
#include "qmt/diagram_scene/parts/customiconitem.h"
#include "qmt/diagram_scene/parts/editabletextitem.h"
-#include "qmt/diagram_scene/parts/relationstarter.h"
#include "qmt/diagram_scene/parts/stereotypesitem.h"
#include "qmt/infrastructure/geometryutilities.h"
#include "qmt/infrastructure/qmtassert.h"
@@ -61,7 +60,7 @@ static const qreal BODY_VERT_BORDER = 4.0;
static const qreal BODY_HORIZ_BORDER = 4.0;
ComponentItem::ComponentItem(DComponent *component, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent)
- : ObjectItem(component, diagramSceneModel, parent)
+ : ObjectItem("component", component, diagramSceneModel, parent)
{
}
@@ -88,7 +87,7 @@ void ComponentItem::update()
} else if (m_customIcon) {
m_customIcon->scene()->removeItem(m_customIcon);
delete m_customIcon;
- m_customIcon = 0;
+ m_customIcon = nullptr;
}
// shape
@@ -118,19 +117,19 @@ void ComponentItem::update()
if (m_shape) {
m_shape->scene()->removeItem(m_shape);
delete m_shape;
- m_shape = 0;
+ m_shape = nullptr;
}
}
if (deleteRects) {
if (m_lowerRect) {
m_lowerRect->scene()->removeItem(m_lowerRect);
delete m_lowerRect;
- m_lowerRect = 0;
+ m_lowerRect = nullptr;
}
if (m_upperRect) {
m_upperRect->scene()->removeItem(m_upperRect);
delete m_upperRect;
- m_upperRect = 0;
+ m_upperRect = nullptr;
}
}
@@ -150,26 +149,11 @@ void ComponentItem::update()
} else if (m_contextLabel) {
m_contextLabel->scene()->removeItem(m_contextLabel);
delete m_contextLabel;
- m_contextLabel = 0;
+ m_contextLabel = nullptr;
}
updateSelectionMarker(m_customIcon);
-
- // relation starters
- if (isFocusSelected()) {
- if (!m_relationStarter && scene()) {
- m_relationStarter = new RelationStarter(this, diagramSceneModel(), 0);
- scene()->addItem(m_relationStarter);
- m_relationStarter->setZValue(RELATION_STARTER_ZVALUE);
- m_relationStarter->addArrow(QStringLiteral("dependency"), ArrowItem::ShaftDashed, ArrowItem::HeadOpen);
- }
- } else if (m_relationStarter) {
- if (m_relationStarter->scene())
- m_relationStarter->scene()->removeItem(m_relationStarter);
- delete m_relationStarter;
- m_relationStarter = 0;
- }
-
+ updateRelationStarter();
updateAlignmentButtons();
updateGeometry();
}
@@ -217,27 +201,10 @@ QList<ILatchable::Latch> ComponentItem::verticalLatches(ILatchable::Action actio
return ObjectItem::verticalLatches(action, grabbedItem);
}
-QPointF ComponentItem::relationStartPos() const
-{
- return pos();
-}
-
-void ComponentItem::relationDrawn(const QString &id, const QPointF &toScenePos, const QList<QPointF> &intermediatePoints)
-{
- DElement *targetElement = diagramSceneModel()->findTopmostElement(toScenePos);
- if (targetElement) {
- if (id == QStringLiteral("dependency")) {
- auto dependantObject = dynamic_cast<DObject *>(targetElement);
- if (dependantObject)
- diagramSceneModel()->diagramSceneController()->createDependency(object(), dependantObject, intermediatePoints, diagramSceneModel()->diagram());
- }
- }
-}
-
bool ComponentItem::hasPlainShape() const
{
auto diagramComponent = dynamic_cast<DComponent *>(object());
- QMT_CHECK(diagramComponent);
+ QMT_ASSERT(diagramComponent, return false);
return diagramComponent->isPlainShape();
}
@@ -361,10 +328,7 @@ void ComponentItem::updateGeometry()
}
updateSelectionMarkerGeometry(rect);
-
- if (m_relationStarter)
- m_relationStarter->setPos(mapToScene(QPointF(right + 8.0, top)));
-
+ updateRelationStarterGeometry(rect);
updateAlignmentButtonsGeometry(rect);
updateDepth();
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/componentitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/componentitem.h
index 1b524247f3b..83e01062ea6 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/componentitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/componentitem.h
@@ -27,8 +27,6 @@
#include "objectitem.h"
-#include "qmt/diagram_scene/capabilities/relationable.h"
-
QT_BEGIN_NAMESPACE
class QGraphicsRectItem;
class QGraphicsSimpleTextItem;
@@ -43,11 +41,11 @@ class CustomIconItem;
class ContextLabelItem;
class RelationStarter;
-class ComponentItem : public ObjectItem, public IRelationable
+class ComponentItem : public ObjectItem
{
public:
ComponentItem(DComponent *component, DiagramSceneModel *diagramSceneModel,
- QGraphicsItem *parent = 0);
+ QGraphicsItem *parent = nullptr);
~ComponentItem() override;
void update() override;
@@ -60,21 +58,16 @@ public:
QList<Latch> horizontalLatches(Action action, bool grabbedItem) const override;
QList<Latch> verticalLatches(Action action, bool grabbedItem) const override;
- QPointF relationStartPos() const override;
- void relationDrawn(const QString &id, const QPointF &toScenePos, const
- QList<QPointF> &intermediatePoints) override;
-
private:
bool hasPlainShape() const;
QSizeF calcMinimumGeometry() const;
void updateGeometry();
- CustomIconItem *m_customIcon = 0;
- QGraphicsRectItem *m_shape = 0;
- QGraphicsRectItem *m_upperRect = 0;
- QGraphicsRectItem *m_lowerRect = 0;
- ContextLabelItem *m_contextLabel = 0;
- RelationStarter *m_relationStarter = 0;
+ CustomIconItem *m_customIcon = nullptr;
+ QGraphicsRectItem *m_shape = nullptr;
+ QGraphicsRectItem *m_upperRect = nullptr;
+ QGraphicsRectItem *m_lowerRect = nullptr;
+ ContextLabelItem *m_contextLabel = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.cpp
new file mode 100644
index 00000000000..d8e3a37df56
--- /dev/null
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Jochen Becher
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "connectionitem.h"
+
+#include "qmt/diagram_controller/diagramcontroller.h"
+#include "qmt/diagram/dconnection.h"
+#include "qmt/diagram_scene/capabilities/intersectionable.h"
+#include "qmt/diagram_scene/diagramscenemodel.h"
+#include "qmt/diagram_scene/parts/arrowitem.h"
+#include "qmt/infrastructure/geometryutilities.h"
+#include "qmt/infrastructure/qmtassert.h"
+#include "qmt/style/style.h"
+
+#include <QGraphicsScene>
+#include <QFont>
+#include <QPen>
+#include <QBrush>
+#include <QVector2D>
+#include <QPair>
+
+namespace qmt {
+
+ConnectionItem::ConnectionItem(DConnection *connection, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent)
+ : RelationItem(connection, diagramSceneModel, parent),
+ m_connection(connection)
+{
+}
+
+ConnectionItem::~ConnectionItem()
+{
+}
+
+void ConnectionItem::update(const Style *style)
+{
+ RelationItem::update(style);
+
+ updateEndLabels(m_connection->endA(), m_connection->endB(), &m_endAName, &m_endACardinality, style);
+ updateEndLabels(m_connection->endB(), m_connection->endA(), &m_endBName, &m_endBCardinality, style);
+
+ QMT_CHECK(m_arrow);
+ QGraphicsItem *endAItem = m_diagramSceneModel->graphicsItem(m_connection->endAUid());
+ if (!endAItem)
+ return;
+ placeEndLabels(m_arrow->firstLineSegment(), m_endAName, m_endACardinality, endAItem, m_arrow->startHeadLength());
+ QGraphicsItem *endBItem = m_diagramSceneModel->graphicsItem(m_connection->endBUid());
+ if (!endBItem)
+ return;
+ placeEndLabels(m_arrow->lastLineSegment(), m_endBName, m_endBCardinality, endBItem, m_arrow->endHeadLength());
+}
+
+void ConnectionItem::updateEndLabels(const DConnectionEnd &end, const DConnectionEnd &otherEnd,
+ QGraphicsSimpleTextItem **endName, QGraphicsSimpleTextItem **endCardinality,
+ const Style *style)
+{
+ Q_UNUSED(end);
+
+ if (!otherEnd.name().isEmpty()) {
+ if (!*endName)
+ *endName = new QGraphicsSimpleTextItem(this);
+ (*endName)->setFont(style->smallFont());
+ (*endName)->setBrush(style->textBrush());
+ (*endName)->setText(otherEnd.name());
+ } else if (*endName) {
+ (*endName)->scene()->removeItem(*endName);
+ delete *endName;
+ *endName = nullptr;
+ }
+
+ if (!otherEnd.cardinality().isEmpty()) {
+ if (!*endCardinality)
+ *endCardinality = new QGraphicsSimpleTextItem(this);
+ (*endCardinality)->setFont(style->smallFont());
+ (*endCardinality)->setBrush(style->textBrush());
+ (*endCardinality)->setText(otherEnd.cardinality());
+ } else if (*endCardinality) {
+ (*endCardinality)->scene()->removeItem(*endCardinality);
+ delete *endCardinality;
+ *endCardinality = nullptr;
+ }
+}
+
+void ConnectionItem::placeEndLabels(const QLineF &lineSegment, QGraphicsItem *endName, QGraphicsItem *endCardinality,
+ QGraphicsItem *endItem, double headLength)
+{
+ const double HEAD_OFFSET = headLength + 6.0;
+ const double SIDE_OFFSET = 4.0;
+ QPointF headOffset = QPointF(HEAD_OFFSET, 0);
+ QPointF sideOffset = QPointF(0.0, SIDE_OFFSET);
+
+ double angle = GeometryUtilities::calcAngle(lineSegment);
+ if (angle >= -5 && angle <= 5) {
+ if (endName)
+ endName->setPos(lineSegment.p1() + headOffset + sideOffset);
+ if (endCardinality)
+ endCardinality->setPos(lineSegment.p1() + headOffset - sideOffset
+ - endCardinality->boundingRect().bottomLeft());
+ } else if (angle <= -175 || angle >= 175) {
+ if (endName)
+ endName->setPos(lineSegment.p1() - headOffset + sideOffset - endName->boundingRect().topRight());
+ if (endCardinality)
+ endCardinality->setPos(lineSegment.p1() - headOffset
+ - sideOffset - endCardinality->boundingRect().bottomRight());
+ } else {
+ QRectF rect;
+ if (endCardinality)
+ rect = endCardinality->boundingRect();
+ if (endName)
+ rect = rect.united(endName->boundingRect().translated(rect.bottomLeft()));
+
+ QPointF rectPlacement;
+ GeometryUtilities::Side alignedSide = GeometryUtilities::SideUnspecified;
+
+ if (auto objectItem = dynamic_cast<IIntersectionable *>(endItem)) {
+ QPointF intersectionPoint;
+ QLineF intersectionLine;
+
+ if (objectItem->intersectShapeWithLine(GeometryUtilities::stretch(lineSegment.translated(pos()), 2.0, 0.0),
+ &intersectionPoint, &intersectionLine)) {
+ if (!GeometryUtilities::placeRectAtLine(rect, lineSegment, HEAD_OFFSET, SIDE_OFFSET,
+ intersectionLine, &rectPlacement, &alignedSide)) {
+ rectPlacement = intersectionPoint;
+ }
+ } else {
+ rectPlacement = lineSegment.p1();
+ }
+ } else {
+ rectPlacement = endItem->pos();
+ }
+
+ if (endCardinality) {
+ if (alignedSide == GeometryUtilities::SideRight)
+ endCardinality->setPos(rectPlacement
+ + QPointF(rect.width() - endCardinality->boundingRect().width(), 0.0));
+ else
+ endCardinality->setPos(rectPlacement);
+ rectPlacement += endCardinality->boundingRect().bottomLeft();
+ }
+ if (endName) {
+ if (alignedSide == GeometryUtilities::SideRight)
+ endName->setPos(rectPlacement + QPointF(rect.width() - endName->boundingRect().width(), 0.0));
+ else
+ endName->setPos(rectPlacement);
+ }
+ }
+}
+
+} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.h
new file mode 100644
index 00000000000..6f473067417
--- /dev/null
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Jochen Becher
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "relationitem.h"
+
+QT_BEGIN_NAMESPACE
+class QGraphicsSimpleTextItem;
+QT_END_NAMESPACE
+
+namespace qmt {
+
+class DConnection;
+class DConnectionEnd;
+
+class ConnectionItem : public RelationItem
+{
+public:
+ ConnectionItem(DConnection *connection, DiagramSceneModel *diagramSceneModel,
+ QGraphicsItem *parent = nullptr);
+ ~ConnectionItem() override;
+
+protected:
+ void update(const Style *style) override;
+
+private:
+ void updateEndLabels(const DConnectionEnd &end, const DConnectionEnd &otherEnd,
+ QGraphicsSimpleTextItem **endName,
+ QGraphicsSimpleTextItem **endCardinality, const Style *style);
+ void placeEndLabels(const QLineF &lineSegment, QGraphicsItem *endName,
+ QGraphicsItem *endCardinality,
+ QGraphicsItem *endItem, double headLength);
+
+ DConnection *m_connection = nullptr;
+ QGraphicsSimpleTextItem *m_endAName = nullptr;
+ QGraphicsSimpleTextItem *m_endACardinality = nullptr;
+ QGraphicsSimpleTextItem *m_endBName = nullptr;
+ QGraphicsSimpleTextItem *m_endBCardinality = nullptr;
+};
+
+} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/diagramitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/diagramitem.cpp
index 01feb195a1e..c466328407d 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/diagramitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/diagramitem.cpp
@@ -54,7 +54,7 @@ static const qreal BODY_HORIZ_BORDER = 4.0;
static const qreal BODY_VERT_BORDER = 4.0;
DiagramItem::DiagramItem(DDiagram *diagram, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent)
- : ObjectItem(diagram, diagramSceneModel, parent)
+ : ObjectItem("diagram", diagram, diagramSceneModel, parent)
{
}
@@ -81,7 +81,7 @@ void DiagramItem::update()
} else if (m_customIcon) {
m_customIcon->scene()->removeItem(m_customIcon);
delete m_customIcon;
- m_customIcon = 0;
+ m_customIcon = nullptr;
}
// shape
@@ -100,12 +100,12 @@ void DiagramItem::update()
if (m_fold) {
m_fold->scene()->removeItem(m_fold);
delete m_fold;
- m_fold = 0;
+ m_fold = nullptr;
}
if (m_body) {
m_body->scene()->removeItem(m_body);
delete m_body;
- m_body = 0;
+ m_body = nullptr;
}
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/diagramitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/diagramitem.h
index 33919920a6b..d20ba34bee1 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/diagramitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/diagramitem.h
@@ -37,7 +37,7 @@ class DiagramItem : public ObjectItem
{
public:
explicit DiagramItem(DDiagram *diagram, DiagramSceneModel *diagramSceneModel,
- QGraphicsItem *parent = 0);
+ QGraphicsItem *parent = nullptr);
~DiagramItem() override;
void update() override;
@@ -51,9 +51,9 @@ private:
QSizeF calcMinimumGeometry() const;
void updateGeometry();
- CustomIconItem *m_customIcon = 0;
- QGraphicsPolygonItem *m_body = 0;
- QGraphicsPolygonItem *m_fold = 0;
+ CustomIconItem *m_customIcon = nullptr;
+ QGraphicsPolygonItem *m_body = nullptr;
+ QGraphicsPolygonItem *m_fold = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.cpp
index 5eea90c443c..dba8f7822fd 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.cpp
@@ -32,7 +32,6 @@
#include "qmt/diagram_scene/parts/contextlabelitem.h"
#include "qmt/diagram_scene/parts/customiconitem.h"
#include "qmt/diagram_scene/parts/editabletextitem.h"
-#include "qmt/diagram_scene/parts/relationstarter.h"
#include "qmt/diagram_scene/parts/stereotypesitem.h"
#include "qmt/infrastructure/geometryutilities.h"
#include "qmt/infrastructure/qmtassert.h"
@@ -56,7 +55,7 @@ static const qreal BODY_VERT_BORDER = 4.0;
static const qreal BODY_HORIZ_BORDER = 4.0;
ItemItem::ItemItem(DItem *item, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent)
- : ObjectItem(item, diagramSceneModel, parent)
+ : ObjectItem("item", item, diagramSceneModel, parent)
{
}
@@ -71,7 +70,7 @@ void ItemItem::update()
auto diagramItem = dynamic_cast<DItem *>(object());
Q_UNUSED(diagramItem); // avoid warning about unsed variable
- QMT_CHECK(diagramItem);
+ QMT_ASSERT(diagramItem, return);
const Style *style = adaptedStyle(shapeIconId());
@@ -86,7 +85,7 @@ void ItemItem::update()
} else if (m_customIcon) {
m_customIcon->scene()->removeItem(m_customIcon);
delete m_customIcon;
- m_customIcon = 0;
+ m_customIcon = nullptr;
}
// shape
@@ -100,7 +99,7 @@ void ItemItem::update()
if (m_shape) {
m_shape->scene()->removeItem(m_shape);
delete m_shape;
- m_shape = 0;
+ m_shape = nullptr;
}
}
@@ -120,26 +119,11 @@ void ItemItem::update()
} else if (m_contextLabel) {
m_contextLabel->scene()->removeItem(m_contextLabel);
delete m_contextLabel;
- m_contextLabel = 0;
+ m_contextLabel = nullptr;
}
updateSelectionMarker(m_customIcon);
-
- // relation starters
- if (isFocusSelected()) {
- if (!m_relationStarter && scene()) {
- m_relationStarter = new RelationStarter(this, diagramSceneModel(), 0);
- scene()->addItem(m_relationStarter);
- m_relationStarter->setZValue(RELATION_STARTER_ZVALUE);
- m_relationStarter->addArrow(QStringLiteral("dependency"), ArrowItem::ShaftDashed, ArrowItem::HeadOpen);
- }
- } else if (m_relationStarter) {
- if (m_relationStarter->scene())
- m_relationStarter->scene()->removeItem(m_relationStarter);
- delete m_relationStarter;
- m_relationStarter = 0;
- }
-
+ updateRelationStarter();
updateAlignmentButtons();
updateGeometry();
}
@@ -175,23 +159,6 @@ QList<ILatchable::Latch> ItemItem::verticalLatches(ILatchable::Action action, bo
return ObjectItem::verticalLatches(action, grabbedItem);
}
-QPointF ItemItem::relationStartPos() const
-{
- return pos();
-}
-
-void ItemItem::relationDrawn(const QString &id, const QPointF &toScenePos, const QList<QPointF> &intermediatePoints)
-{
- DElement *targetElement = diagramSceneModel()->findTopmostElement(toScenePos);
- if (targetElement) {
- if (id == QStringLiteral("dependency")) {
- auto dependantObject = dynamic_cast<DObject *>(targetElement);
- if (dependantObject)
- diagramSceneModel()->diagramSceneController()->createDependency(object(), dependantObject, intermediatePoints, diagramSceneModel()->diagram());
- }
- }
-}
-
QSizeF ItemItem::calcMinimumGeometry() const
{
double width = 0.0;
@@ -294,10 +261,7 @@ void ItemItem::updateGeometry()
}
updateSelectionMarkerGeometry(rect);
-
- if (m_relationStarter)
- m_relationStarter->setPos(mapToScene(QPointF(right + 8.0, top)));
-
+ updateRelationStarterGeometry(rect);
updateAlignmentButtonsGeometry(rect);
updateDepth();
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.h
index 49a3c2fc588..3030071a0dd 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.h
@@ -27,8 +27,6 @@
#include "objectitem.h"
-#include "qmt/diagram_scene/capabilities/relationable.h"
-
QT_BEGIN_NAMESPACE
class QGraphicsRectItem;
class QGraphicsSimpleTextItem;
@@ -43,10 +41,10 @@ class CustomIconItem;
class ContextLabelItem;
class RelationStarter;
-class ItemItem : public ObjectItem, public IRelationable
+class ItemItem : public ObjectItem
{
public:
- ItemItem(DItem *item, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent = 0);
+ ItemItem(DItem *item, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent = nullptr);
~ItemItem() override;
void update() override;
@@ -59,18 +57,13 @@ public:
QList<Latch> horizontalLatches(Action action, bool grabbedItem) const override;
QList<Latch> verticalLatches(Action action, bool grabbedItem) const override;
- QPointF relationStartPos() const override;
- void relationDrawn(const QString &id, const QPointF &toScenePos,
- const QList<QPointF> &intermediatePoints) override;
-
private:
QSizeF calcMinimumGeometry() const;
void updateGeometry();
- CustomIconItem *m_customIcon = 0;
- QGraphicsRectItem *m_shape = 0;
- ContextLabelItem *m_contextLabel = 0;
- RelationStarter *m_relationStarter = 0;
+ CustomIconItem *m_customIcon = nullptr;
+ QGraphicsRectItem *m_shape = nullptr;
+ ContextLabelItem *m_contextLabel = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.cpp
index 8c73b3c91f1..104d374ee8b 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.cpp
@@ -34,6 +34,7 @@
#include "qmt/diagram_scene/parts/alignbuttonsitem.h"
#include "qmt/diagram_scene/parts/editabletextitem.h"
#include "qmt/diagram_scene/parts/rectangularselectionitem.h"
+#include "qmt/diagram_scene/parts/relationstarter.h"
#include "qmt/diagram_scene/parts/customiconitem.h"
#include "qmt/diagram_scene/parts/stereotypesitem.h"
#include "qmt/infrastructure/contextmenuaction.h"
@@ -41,7 +42,9 @@
#include "qmt/model/mdiagram.h"
#include "qmt/model/mobject.h"
#include "qmt/model_controller/modelcontroller.h"
+#include "qmt/stereotype/customrelation.h"
#include "qmt/stereotype/stereotypecontroller.h"
+#include "qmt/stereotype/toolbar.h"
#include "qmt/style/style.h"
#include "qmt/style/stylecontroller.h"
#include "qmt/style/styledobject.h"
@@ -57,8 +60,12 @@
namespace qmt {
-ObjectItem::ObjectItem(DObject *object, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent)
+static const char DEPENDENCY[] = "dependency";
+
+
+ObjectItem::ObjectItem(const QString &elementType, DObject *object, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent)
: QGraphicsItem(parent),
+ m_elementType(elementType),
m_object(object),
m_diagramSceneModel(diagramSceneModel)
{
@@ -201,8 +208,25 @@ void ObjectItem::setFocusSelected(bool focusSelected)
}
}
+QRectF ObjectItem::getSecondarySelectionBoundary()
+{
+ return QRectF();
+}
+
+void ObjectItem::setBoundarySelected(const QRectF &boundary, bool secondary)
+{
+ if (boundary.contains(mapRectToScene(boundingRect()))) {
+ if (secondary)
+ setSecondarySelected(true);
+ else
+ setSelected(true);
+ }
+}
+
ILatchable::Action ObjectItem::horizontalLatchAction() const
{
+ if (!m_selectionMarker)
+ return Move;
switch (m_selectionMarker->activeHandle()) {
case RectangularSelectionItem::HandleTopLeft:
case RectangularSelectionItem::HandleLeft:
@@ -225,6 +249,8 @@ ILatchable::Action ObjectItem::horizontalLatchAction() const
ILatchable::Action ObjectItem::verticalLatchAction() const
{
+ if (!m_selectionMarker)
+ return Move;
switch (m_selectionMarker->activeHandle()) {
case RectangularSelectionItem::HandleTopLeft:
case RectangularSelectionItem::HandleTop:
@@ -253,18 +279,18 @@ QList<ILatchable::Latch> ObjectItem::horizontalLatches(ILatchable::Action action
QList<ILatchable::Latch> result;
switch (action) {
case ILatchable::Move:
- result << ILatchable::Latch(ILatchable::Left, rect.left(), rect.top(), rect.bottom(), QStringLiteral("left"))
- << ILatchable::Latch(ILatchable::Hcenter, rect.center().x(), rect.top(), rect.bottom(), QStringLiteral("center"))
- << ILatchable::Latch(ILatchable::Right, rect.right(), rect.top(), rect.bottom(), QStringLiteral("right"));
+ result << ILatchable::Latch(ILatchable::Left, rect.left(), rect.top(), rect.bottom(), "left")
+ << ILatchable::Latch(ILatchable::Hcenter, rect.center().x(), rect.top(), rect.bottom(), "center")
+ << ILatchable::Latch(ILatchable::Right, rect.right(), rect.top(), rect.bottom(), "right");
break;
case ILatchable::ResizeLeft:
- result << ILatchable::Latch(ILatchable::Left, rect.left(), rect.top(), rect.bottom(), QStringLiteral("left"));
+ result << ILatchable::Latch(ILatchable::Left, rect.left(), rect.top(), rect.bottom(), "left");
break;
case ILatchable::ResizeTop:
QMT_CHECK(false);
break;
case ILatchable::ResizeRight:
- result << ILatchable::Latch(ILatchable::Right, rect.right(), rect.top(), rect.bottom(), QStringLiteral("right"));
+ result << ILatchable::Latch(ILatchable::Right, rect.right(), rect.top(), rect.bottom(), "right");
break;
case ILatchable::ResizeBottom:
QMT_CHECK(false);
@@ -281,26 +307,91 @@ QList<ILatchable::Latch> ObjectItem::verticalLatches(ILatchable::Action action,
QList<ILatchable::Latch> result;
switch (action) {
case ILatchable::Move:
- result << ILatchable::Latch(ILatchable::Top, rect.top(), rect.left(), rect.right(), QStringLiteral("top"))
- << ILatchable::Latch(ILatchable::Vcenter, rect.center().y(), rect.left(), rect.right(), QStringLiteral("center"))
- << ILatchable::Latch(ILatchable::Bottom, rect.bottom(), rect.left(), rect.right(), QStringLiteral("bottom"));
+ result << ILatchable::Latch(ILatchable::Top, rect.top(), rect.left(), rect.right(), "top")
+ << ILatchable::Latch(ILatchable::Vcenter, rect.center().y(), rect.left(), rect.right(), "center")
+ << ILatchable::Latch(ILatchable::Bottom, rect.bottom(), rect.left(), rect.right(), "bottom");
break;
case ILatchable::ResizeLeft:
QMT_CHECK(false);
break;
case ILatchable::ResizeTop:
- result << ILatchable::Latch(ILatchable::Top, rect.top(), rect.left(), rect.right(), QStringLiteral("top"));
+ result << ILatchable::Latch(ILatchable::Top, rect.top(), rect.left(), rect.right(), "top");
break;
case ILatchable::ResizeRight:
QMT_CHECK(false);
break;
case ILatchable::ResizeBottom:
- result << ILatchable::Latch(ILatchable::Bottom, rect.bottom(), rect.left(), rect.right(), QStringLiteral("bottom"));
+ result << ILatchable::Latch(ILatchable::Bottom, rect.bottom(), rect.left(), rect.right(), "bottom");
break;
}
return result;
}
+QPointF ObjectItem::relationStartPos() const
+{
+ return pos();
+}
+
+void ObjectItem::relationDrawn(const QString &id, const QPointF &toScenePos, const QList<QPointF> &intermediatePoints)
+{
+ ObjectItem *targetItem = diagramSceneModel()->findTopmostObjectItem(toScenePos);
+ if (targetItem)
+ relationDrawn(id, targetItem, intermediatePoints);
+}
+
+void ObjectItem::relationDrawn(const QString &id, ObjectItem *targetItem, const QList<QPointF> &intermediatePoints)
+{
+ DiagramSceneController *diagramSceneController = diagramSceneModel()->diagramSceneController();
+ if (id == DEPENDENCY) {
+ DObject *dependantObject = targetItem->object();
+ if (dependantObject)
+ diagramSceneController->createDependency(object(), dependantObject, intermediatePoints,
+ diagramSceneModel()->diagram());
+ } else {
+ StereotypeController *stereotypeController = diagramSceneModel()->stereotypeController();
+ CustomRelation customRelation = stereotypeController->findCustomRelation(id);
+ if (!customRelation.isNull()) {
+ switch (customRelation.element()) {
+ case CustomRelation::Element::Dependency:
+ {
+ DObject *dependantObject = targetItem->object();
+ if (dependantObject)
+ diagramSceneController->createDependency(object(), dependantObject, intermediatePoints,
+ diagramSceneModel()->diagram());
+ break;
+ }
+ case CustomRelation::Element::Relation:
+ {
+ DObject *relatedObject = targetItem->object();
+ if (relatedObject) {
+ // check if element is allowed as target
+ QList<QString> endItems = customRelation.endB().endItems();
+ if (endItems.isEmpty())
+ endItems = customRelation.endItems();
+ QString elementType;
+ if (!targetItem->stereotypeIconId().isEmpty())
+ elementType = targetItem->stereotypeIconId();
+ else if (!targetItem->shapeIconId().isEmpty())
+ elementType = targetItem->shapeIconId();
+ else
+ elementType = targetItem->elementType();
+ if (!endItems.contains(elementType)) {
+ return;
+ }
+ // create relation
+ diagramSceneController->createConnection(id, object(), relatedObject, intermediatePoints,
+ diagramSceneModel()->diagram());
+ }
+ break;
+ }
+ default:
+ // ignore other elements
+ break;
+ }
+ }
+ }
+}
+
void ObjectItem::align(IAlignable::AlignType alignType, const QString &identifier)
{
Q_UNUSED(identifier); // avoid warning in release mode
@@ -309,49 +400,49 @@ void ObjectItem::align(IAlignable::AlignType alignType, const QString &identifie
// but this implementation does not. So assert the names.
switch (alignType) {
case IAlignable::AlignLeft:
- QMT_CHECK(identifier == QStringLiteral("left"));
+ QMT_CHECK(identifier == "left");
m_diagramSceneModel->diagramSceneController()->alignLeft(m_object, m_diagramSceneModel->selectedElements(),
m_diagramSceneModel->diagram());
break;
case IAlignable::AlignRight:
- QMT_CHECK(identifier == QStringLiteral("right"));
+ QMT_CHECK(identifier == "right");
m_diagramSceneModel->diagramSceneController()->alignRight(m_object, m_diagramSceneModel->selectedElements(),
m_diagramSceneModel->diagram());
break;
case IAlignable::AlignTop:
- QMT_CHECK(identifier == QStringLiteral("top"));
+ QMT_CHECK(identifier == "top");
m_diagramSceneModel->diagramSceneController()->alignTop(m_object, m_diagramSceneModel->selectedElements(),
m_diagramSceneModel->diagram());
break;
case IAlignable::AlignBottom:
- QMT_CHECK(identifier == QStringLiteral("bottom"));
+ QMT_CHECK(identifier == "bottom");
m_diagramSceneModel->diagramSceneController()->alignBottom(m_object, m_diagramSceneModel->selectedElements(),
m_diagramSceneModel->diagram());
break;
case IAlignable::AlignHcenter:
- QMT_CHECK(identifier == QStringLiteral("center"));
+ QMT_CHECK(identifier == "center");
m_diagramSceneModel->diagramSceneController()->alignHCenter(m_object, m_diagramSceneModel->selectedElements(),
m_diagramSceneModel->diagram());
break;
case IAlignable::AlignVcenter:
- QMT_CHECK(identifier == QStringLiteral("center"));
+ QMT_CHECK(identifier == "center");
m_diagramSceneModel->diagramSceneController()->alignVCenter(m_object, m_diagramSceneModel->selectedElements(),
m_diagramSceneModel->diagram());
break;
case IAlignable::AlignWidth:
- QMT_CHECK(identifier == QStringLiteral("width"));
+ QMT_CHECK(identifier == "width");
m_diagramSceneModel->diagramSceneController()->alignWidth(m_object, m_diagramSceneModel->selectedElements(),
minimumSize(m_diagramSceneModel->selectedItems()),
m_diagramSceneModel->diagram());
break;
case IAlignable::AlignHeight:
- QMT_CHECK(identifier == QStringLiteral("height"));
+ QMT_CHECK(identifier == "height");
m_diagramSceneModel->diagramSceneController()->alignHeight(m_object, m_diagramSceneModel->selectedElements(),
minimumSize(m_diagramSceneModel->selectedItems()),
m_diagramSceneModel->diagram());
break;
case IAlignable::AlignSize:
- QMT_CHECK(identifier == QStringLiteral("size"));
+ QMT_CHECK(identifier == "size");
m_diagramSceneModel->diagramSceneController()->alignSize(m_object, m_diagramSceneModel->selectedElements(),
minimumSize(m_diagramSceneModel->selectedItems()),
m_diagramSceneModel->diagram());
@@ -400,7 +491,7 @@ void ObjectItem::updateStereotypes(const QString &stereotypeIconId, StereotypeIc
} else if (m_stereotypeIcon) {
m_stereotypeIcon->scene()->removeItem(m_stereotypeIcon);
delete m_stereotypeIcon;
- m_stereotypeIcon = 0;
+ m_stereotypeIcon = nullptr;
}
if (stereotypeDisplay != StereotypeIcon::DisplayNone && !stereotypes.isEmpty()) {
if (!m_stereotypes)
@@ -411,7 +502,7 @@ void ObjectItem::updateStereotypes(const QString &stereotypeIconId, StereotypeIc
} else if (m_stereotypes) {
m_stereotypes->scene()->removeItem(m_stereotypes);
delete m_stereotypes;
- m_stereotypes = 0;
+ m_stereotypes = nullptr;
}
}
@@ -559,7 +650,7 @@ void ObjectItem::updateSelectionMarker(ResizeFlags resizeFlags)
if (m_selectionMarker->scene())
m_selectionMarker->scene()->removeItem(m_selectionMarker);
delete m_selectionMarker;
- m_selectionMarker = 0;
+ m_selectionMarker = nullptr;
}
}
@@ -569,6 +660,118 @@ void ObjectItem::updateSelectionMarkerGeometry(const QRectF &objectRect)
m_selectionMarker->setRect(objectRect);
}
+void ObjectItem::updateRelationStarter()
+{
+ if (isFocusSelected()) {
+ if (!m_relationStarter) {
+ m_relationStarter = new RelationStarter(this, diagramSceneModel(), 0);
+ scene()->addItem(m_relationStarter);
+ m_relationStarter->setZValue(RELATION_STARTER_ZVALUE);
+ QString elementType;
+ if (!m_stereotypeIconId.isEmpty())
+ elementType = m_stereotypeIconId;
+ else if (!m_shapeIconId.isEmpty())
+ elementType = m_shapeIconId;
+ else
+ elementType = m_elementType;
+ StereotypeController *stereotypeController = diagramSceneModel()->stereotypeController();
+ QList<Toolbar> toolbars = stereotypeController->findToolbars(elementType);
+ if (!toolbars.isEmpty()) {
+ foreach (const Toolbar &toolbar, toolbars) {
+ foreach (const Toolbar::Tool &tool, toolbar.tools()) {
+ CustomRelation customRelation =
+ stereotypeController->findCustomRelation(tool.m_elementType);
+ if (!customRelation.isNull())
+ addRelationStarterTool(customRelation);
+ else
+ addRelationStarterTool(tool.m_elementType);
+ }
+ }
+ } else {
+ addStandardRelationStarterTools();
+ }
+ }
+ } else if (m_relationStarter) {
+ scene()->removeItem(m_relationStarter);
+ delete m_relationStarter;
+ m_relationStarter = nullptr;
+ }
+
+}
+
+void ObjectItem::addRelationStarterTool(const QString &id)
+{
+ if (id == DEPENDENCY)
+ m_relationStarter->addArrow(DEPENDENCY, ArrowItem::ShaftDashed,
+ ArrowItem::HeadNone, ArrowItem::HeadOpen,
+ tr("Dependency"));
+}
+
+void ObjectItem::addRelationStarterTool(const CustomRelation &customRelation)
+{
+ ArrowItem::Shaft shaft = ArrowItem::ShaftSolid;
+ ArrowItem::Head headStart = ArrowItem::HeadNone;
+ ArrowItem::Head headEnd = ArrowItem::HeadNone;
+ switch (customRelation.element()) {
+ case CustomRelation::Element::Dependency:
+ shaft = ArrowItem::ShaftDashed;
+ switch (customRelation.direction()) {
+ case CustomRelation::Direction::AtoB:
+ headEnd = ArrowItem::HeadOpen;
+ break;
+ case CustomRelation::Direction::BToA:
+ headStart = ArrowItem::HeadOpen;
+ break;
+ case CustomRelation::Direction::Bi:
+ headStart = ArrowItem::HeadOpen;
+ headEnd = ArrowItem::HeadOpen;
+ break;
+ }
+ break;
+ case CustomRelation::Element::Relation:
+ {
+ // TODO support custom shapes
+ static const QHash<CustomRelation::ShaftPattern, ArrowItem::Shaft> shaft2shaft = {
+ { CustomRelation::ShaftPattern::Solid, ArrowItem::ShaftSolid },
+ { CustomRelation::ShaftPattern::Dash, ArrowItem::ShaftDashed },
+ { CustomRelation::ShaftPattern::Dot, ArrowItem::ShaftDot },
+ { CustomRelation::ShaftPattern::DashDot, ArrowItem::ShaftDashDot },
+ { CustomRelation::ShaftPattern::DashDotDot, ArrowItem::ShaftDashDotDot },
+ };
+ static const QHash<CustomRelation::Head, ArrowItem::Head> head2head = {
+ { CustomRelation::Head::None, ArrowItem::HeadNone },
+ { CustomRelation::Head::Shape, ArrowItem::HeadNone },
+ { CustomRelation::Head::Arrow, ArrowItem::HeadOpen },
+ { CustomRelation::Head::Triangle, ArrowItem::HeadTriangle },
+ { CustomRelation::Head::FilledTriangle, ArrowItem::HeadFilledTriangle },
+ { CustomRelation::Head::Diamond, ArrowItem::HeadDiamond },
+ { CustomRelation::Head::FilledDiamond, ArrowItem::HeadFilledDiamond },
+ };
+ shaft = shaft2shaft.value(customRelation.shaftPattern());
+ headStart = head2head.value(customRelation.endA().head());
+ headEnd = head2head.value(customRelation.endB().head());
+ // TODO use color?
+ break;
+ }
+ default:
+ return;
+ }
+ m_relationStarter->addArrow(customRelation.id(), shaft, headStart, headEnd,
+ customRelation.title());
+
+}
+
+void ObjectItem::addStandardRelationStarterTools()
+{
+ addRelationStarterTool(DEPENDENCY);
+}
+
+void ObjectItem::updateRelationStarterGeometry(const QRectF &objectRect)
+{
+ if (m_relationStarter)
+ m_relationStarter->setPos(mapToScene(QPointF(objectRect.right() + 8.0, objectRect.top())));
+}
+
void ObjectItem::updateAlignmentButtons()
{
if (isFocusSelected() && m_diagramSceneModel->hasMultiObjectsSelection()) {
@@ -588,13 +791,13 @@ void ObjectItem::updateAlignmentButtons()
if (m_horizontalAlignButtons->scene())
m_horizontalAlignButtons->scene()->removeItem(m_horizontalAlignButtons);
delete m_horizontalAlignButtons;
- m_horizontalAlignButtons = 0;
+ m_horizontalAlignButtons = nullptr;
}
if (m_verticalAlignButtons) {
if (m_verticalAlignButtons->scene())
m_verticalAlignButtons->scene()->removeItem(m_verticalAlignButtons);
delete m_verticalAlignButtons;
- m_verticalAlignButtons = 0;
+ m_verticalAlignButtons = nullptr;
}
}
}
@@ -674,7 +877,7 @@ bool ObjectItem::showContext() const
// TODO Because of this algorithm adding, moving, removing of one item need to update() all colliding items as well
QMT_CHECK(object()->modelUid().isValid());
MObject *mobject = m_diagramSceneModel->diagramController()->modelController()->findObject(object()->modelUid());
- QMT_CHECK(mobject);
+ QMT_ASSERT(mobject, return false);
MObject *owner = mobject->owner();
if (owner) {
foreach (QGraphicsItem *item, m_diagramSceneModel->collectCollidingObjectItems(this, DiagramSceneModel::CollidingOuterItems)) {
@@ -740,10 +943,10 @@ void ObjectItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
bool addSeparator = false;
if (element_tasks->hasDiagram(m_object, m_diagramSceneModel->diagram())) {
- menu.addAction(new ContextMenuAction(tr("Open Diagram"), QStringLiteral("openDiagram"), &menu));
+ menu.addAction(new ContextMenuAction(tr("Open Diagram"), "openDiagram", &menu));
addSeparator = true;
} else if (element_tasks->mayCreateDiagram(m_object, m_diagramSceneModel->diagram())) {
- menu.addAction(new ContextMenuAction(tr("Create Diagram"), QStringLiteral("createDiagram"), &menu));
+ menu.addAction(new ContextMenuAction(tr("Create Diagram"), "createDiagram", &menu));
addSeparator = true;
}
if (extendContextMenu(&menu))
@@ -752,70 +955,70 @@ void ObjectItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
addSeparator = true;
if (addSeparator)
menu.addSeparator();
- menu.addAction(new ContextMenuAction(tr("Remove"), QStringLiteral("remove"),
+ menu.addAction(new ContextMenuAction(tr("Remove"), "remove",
QKeySequence(QKeySequence::Delete), &menu));
- menu.addAction(new ContextMenuAction(tr("Delete"), QStringLiteral("delete"),
+ menu.addAction(new ContextMenuAction(tr("Delete"), "delete",
QKeySequence(Qt::CTRL + Qt::Key_D), &menu));
- //menu.addAction(new ContextMenuAction(tr("Select in Model Tree"), QStringLiteral("selectInModelTree"), &menu));
+ //menu.addAction(new ContextMenuAction(tr("Select in Model Tree"), "selectInModelTree", &menu));
QMenu alignMenu;
alignMenu.setTitle(tr("Align Objects"));
- alignMenu.addAction(new ContextMenuAction(tr("Align Left"), QStringLiteral("alignLeft"), &alignMenu));
- alignMenu.addAction(new ContextMenuAction(tr("Center Vertically"), QStringLiteral("centerVertically"),
+ alignMenu.addAction(new ContextMenuAction(tr("Align Left"), "alignLeft", &alignMenu));
+ alignMenu.addAction(new ContextMenuAction(tr("Center Vertically"), "centerVertically",
&alignMenu));
- alignMenu.addAction(new ContextMenuAction(tr("Align Right"), QStringLiteral("alignRight"), &alignMenu));
+ alignMenu.addAction(new ContextMenuAction(tr("Align Right"), "alignRight", &alignMenu));
alignMenu.addSeparator();
- alignMenu.addAction(new ContextMenuAction(tr("Align Top"), QStringLiteral("alignTop"), &alignMenu));
- alignMenu.addAction(new ContextMenuAction(tr("Center Horizontally"), QStringLiteral("centerHorizontally"),
+ alignMenu.addAction(new ContextMenuAction(tr("Align Top"), "alignTop", &alignMenu));
+ alignMenu.addAction(new ContextMenuAction(tr("Center Horizontally"), "centerHorizontally",
&alignMenu));
- alignMenu.addAction(new ContextMenuAction(tr("Align Bottom"), QStringLiteral("alignBottom"), &alignMenu));
+ alignMenu.addAction(new ContextMenuAction(tr("Align Bottom"), "alignBottom", &alignMenu));
alignMenu.addSeparator();
- alignMenu.addAction(new ContextMenuAction(tr("Same Width"), QStringLiteral("sameWidth"), &alignMenu));
- alignMenu.addAction(new ContextMenuAction(tr("Same Height"), QStringLiteral("sameHeight"), &alignMenu));
- alignMenu.addAction(new ContextMenuAction(tr("Same Size"), QStringLiteral("sameSize"), &alignMenu));
+ alignMenu.addAction(new ContextMenuAction(tr("Same Width"), "sameWidth", &alignMenu));
+ alignMenu.addAction(new ContextMenuAction(tr("Same Height"), "sameHeight", &alignMenu));
+ alignMenu.addAction(new ContextMenuAction(tr("Same Size"), "sameSize", &alignMenu));
alignMenu.setEnabled(m_diagramSceneModel->hasMultiObjectsSelection());
menu.addMenu(&alignMenu);
QAction *selectedAction = menu.exec(event->screenPos());
if (selectedAction) {
auto action = dynamic_cast<ContextMenuAction *>(selectedAction);
- QMT_CHECK(action);
+ QMT_ASSERT(action, return);
bool handled = handleSelectedContextMenuAction(action->id());
handled |= element_tasks->handleContextMenuAction(object(), diagramSceneModel()->diagram(), action->id());
if (!handled) {
- if (action->id() == QStringLiteral("openDiagram")) {
+ if (action->id() == "openDiagram") {
m_diagramSceneModel->diagramSceneController()->elementTasks()->openDiagram(m_object, m_diagramSceneModel->diagram());
- } else if (action->id() == QStringLiteral("createDiagram")) {
+ } else if (action->id() == "createDiagram") {
m_diagramSceneModel->diagramSceneController()->elementTasks()->createAndOpenDiagram(m_object, m_diagramSceneModel->diagram());
- } else if (action->id() == QStringLiteral("remove")) {
+ } else if (action->id() == "remove") {
DSelection selection = m_diagramSceneModel->selectedElements();
if (selection.isEmpty())
selection.append(m_object->uid(), m_diagramSceneModel->diagram()->uid());
m_diagramSceneModel->diagramController()->deleteElements(selection, m_diagramSceneModel->diagram());
- } else if (action->id() == QStringLiteral("delete")) {
+ } else if (action->id() == "delete") {
DSelection selection = m_diagramSceneModel->selectedElements();
if (selection.isEmpty())
selection.append(m_object->uid(), m_diagramSceneModel->diagram()->uid());
m_diagramSceneModel->diagramSceneController()->deleteFromDiagram(selection, m_diagramSceneModel->diagram());
- } else if (action->id() == QStringLiteral("selectInModelTree")) {
+ } else if (action->id() == "selectInModelTree") {
// TODO implement
- } else if (action->id() == QStringLiteral("alignLeft")) {
- align(IAlignable::AlignLeft, QStringLiteral("left"));
- } else if (action->id() == QStringLiteral("centerVertically")) {
- align(IAlignable::AlignVcenter, QStringLiteral("center"));
- } else if (action->id() == QStringLiteral("alignRight")) {
- align(IAlignable::AlignRight, QStringLiteral("right"));
- } else if (action->id() == QStringLiteral("alignTop")) {
- align(IAlignable::AlignTop, QStringLiteral("top"));
- } else if (action->id() == QStringLiteral("centerHorizontally")) {
- align(IAlignable::AlignHcenter, QStringLiteral("center"));
- } else if (action->id() == QStringLiteral("alignBottom")) {
- align(IAlignable::AlignBottom, QStringLiteral("bottom"));
- } else if (action->id() == QStringLiteral("sameWidth")) {
- align(IAlignable::AlignWidth, QStringLiteral("width"));
- } else if (action->id() == QStringLiteral("sameHeight")) {
- align(IAlignable::AlignHeight, QStringLiteral("height"));
- } else if (action->id() == QStringLiteral("sameSize")) {
- align(IAlignable::AlignSize, QStringLiteral("size"));
+ } else if (action->id() == "alignLeft") {
+ align(IAlignable::AlignLeft, "left");
+ } else if (action->id() == "centerVertically") {
+ align(IAlignable::AlignVcenter, "center");
+ } else if (action->id() == "alignRight") {
+ align(IAlignable::AlignRight, "right");
+ } else if (action->id() == "alignTop") {
+ align(IAlignable::AlignTop, "top");
+ } else if (action->id() == "centerHorizontally") {
+ align(IAlignable::AlignHcenter, "center");
+ } else if (action->id() == "alignBottom") {
+ align(IAlignable::AlignBottom, "bottom");
+ } else if (action->id() == "sameWidth") {
+ align(IAlignable::AlignWidth, "width");
+ } else if (action->id() == "sameHeight") {
+ align(IAlignable::AlignHeight, "height");
+ } else if (action->id() == "sameSize") {
+ align(IAlignable::AlignSize, "size");
}
}
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.h
index 5595c86667f..89bf89ea576 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.h
@@ -32,6 +32,7 @@
#include "qmt/diagram_scene/capabilities/moveable.h"
#include "qmt/diagram_scene/capabilities/selectable.h"
#include "qmt/diagram_scene/capabilities/latchable.h"
+#include "qmt/diagram_scene/capabilities/relationable.h"
#include "qmt/diagram_scene/capabilities/alignable.h"
#include "qmt/diagram_scene/capabilities/editable.h"
@@ -45,12 +46,15 @@ QT_END_NAMESPACE
namespace qmt {
+class DElement;
class DObject;
class DiagramSceneModel;
class StereotypesItem;
class CustomIconItem;
+class CustomRelation;
class EditableTextItem;
class RectangularSelectionItem;
+class RelationStarter;
class AlignButtonsItem;
class Style;
@@ -66,6 +70,7 @@ class ObjectItem :
public IMoveable,
public ISelectable,
public ILatchable,
+ public IRelationable,
public IAlignable,
public IEditable
{
@@ -81,9 +86,10 @@ protected:
};
public:
- ObjectItem(DObject *object, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent = 0);
+ ObjectItem(const QString &elementType, DObject *object, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent = nullptr);
~ObjectItem() override;
+ QString elementType() const { return m_elementType; }
DObject *object() const { return m_object; }
DiagramSceneModel *diagramSceneModel() const { return m_diagramSceneModel; }
@@ -107,12 +113,20 @@ public:
void setSecondarySelected(bool secondarySelected) override;
bool isFocusSelected() const override;
void setFocusSelected(bool focusSelected) override;
+ QRectF getSecondarySelectionBoundary() override;
+ void setBoundarySelected(const QRectF &boundary, bool secondary) override;
Action horizontalLatchAction() const override;
Action verticalLatchAction() const override;
QList<Latch> horizontalLatches(Action action, bool grabbedItem) const override;
QList<Latch> verticalLatches(Action action, bool grabbedItem) const override;
+ QPointF relationStartPos() const override;
+ void relationDrawn(const QString &id, const QPointF &toScenePos,
+ const QList<QPointF> &intermediatePoints) override;
+ virtual void relationDrawn(const QString &id, ObjectItem *targetElement,
+ const QList<QPointF> &intermediatePoints);
+
void align(AlignType alignType, const QString &identifier) override;
bool isEditable() const override;
@@ -139,6 +153,12 @@ protected:
void updateSelectionMarker(CustomIconItem *customIconItem);
void updateSelectionMarker(ResizeFlags resizeFlags);
void updateSelectionMarkerGeometry(const QRectF &objectRect);
+ void updateRelationStarter();
+ RelationStarter *relationStarter() const { return m_relationStarter; }
+ virtual void addRelationStarterTool(const QString &id);
+ virtual void addRelationStarterTool(const CustomRelation &customRelation);
+ virtual void addStandardRelationStarterTools();
+ void updateRelationStarterGeometry(const QRectF &objectRect);
void updateAlignmentButtons();
void updateAlignmentButtonsGeometry(const QRectF &objectRect);
@@ -158,19 +178,21 @@ protected:
private:
QSizeF minimumSize(const QSet<QGraphicsItem *> &items) const;
- DObject *m_object = 0;
- DiagramSceneModel *m_diagramSceneModel = 0;
+ QString m_elementType;
+ DObject *m_object = nullptr;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
bool m_isSecondarySelected = false;
bool m_isFocusSelected = false;
QString m_stereotypeIconId;
QString m_shapeIconId;
StereotypeIcon::Display m_stereotypeIconDisplay = StereotypeIcon::DisplayLabel;
- StereotypesItem *m_stereotypes = 0;
- CustomIconItem *m_stereotypeIcon = 0;
- EditableTextItem *m_nameItem = 0;
- RectangularSelectionItem *m_selectionMarker = 0;
- AlignButtonsItem *m_horizontalAlignButtons = 0;
- AlignButtonsItem *m_verticalAlignButtons = 0;
+ StereotypesItem *m_stereotypes = nullptr;
+ CustomIconItem *m_stereotypeIcon = nullptr;
+ EditableTextItem *m_nameItem = nullptr;
+ RectangularSelectionItem *m_selectionMarker = nullptr;
+ RelationStarter *m_relationStarter = nullptr;
+ AlignButtonsItem *m_horizontalAlignButtons = nullptr;
+ AlignButtonsItem *m_verticalAlignButtons = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/packageitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/packageitem.cpp
index 783a284fa38..97ff26f00ad 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/packageitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/packageitem.cpp
@@ -32,7 +32,6 @@
#include "qmt/diagram_scene/parts/contextlabelitem.h"
#include "qmt/diagram_scene/parts/customiconitem.h"
#include "qmt/diagram_scene/parts/editabletextitem.h"
-#include "qmt/diagram_scene/parts/relationstarter.h"
#include "qmt/diagram_scene/parts/stereotypesitem.h"
#include "qmt/infrastructure/geometryutilities.h"
#include "qmt/stereotype/stereotypecontroller.h"
@@ -72,7 +71,7 @@ public:
};
PackageItem::PackageItem(DPackage *package, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent)
- : ObjectItem(package, diagramSceneModel, parent)
+ : ObjectItem("package", package, diagramSceneModel, parent)
{
}
@@ -99,7 +98,7 @@ void PackageItem::update()
} else if (m_customIcon) {
m_customIcon->scene()->removeItem(m_customIcon);
delete m_customIcon;
- m_customIcon = 0;
+ m_customIcon = nullptr;
}
// shape
@@ -112,7 +111,7 @@ void PackageItem::update()
} else if (m_shape) {
m_shape->scene()->removeItem(m_shape);
delete m_shape;
- m_shape = 0;
+ m_shape = nullptr;
}
// stereotypes
@@ -131,25 +130,11 @@ void PackageItem::update()
} else if (m_contextLabel) {
m_contextLabel->scene()->removeItem(m_contextLabel);
delete m_contextLabel;
- m_contextLabel = 0;
+ m_contextLabel = nullptr;
}
updateSelectionMarker(m_customIcon);
-
- // relation starters
- if (isFocusSelected()) {
- if (!m_relationStarter) {
- m_relationStarter = new RelationStarter(this, diagramSceneModel(), 0);
- scene()->addItem(m_relationStarter);
- m_relationStarter->setZValue(RELATION_STARTER_ZVALUE);
- m_relationStarter->addArrow(QStringLiteral("dependency"), ArrowItem::ShaftDashed, ArrowItem::HeadOpen);
- }
- } else if (m_relationStarter) {
- scene()->removeItem(m_relationStarter);
- delete m_relationStarter;
- m_relationStarter = 0;
- }
-
+ updateRelationStarter();
updateAlignmentButtons();
updateGeometry();
}
@@ -190,23 +175,6 @@ QList<ILatchable::Latch> PackageItem::verticalLatches(ILatchable::Action action,
return ObjectItem::verticalLatches(action, grabbedItem);
}
-QPointF PackageItem::relationStartPos() const
-{
- return pos();
-}
-
-void PackageItem::relationDrawn(const QString &id, const QPointF &toScenePos, const QList<QPointF> &intermediatePoints)
-{
- DElement *targetElement = diagramSceneModel()->findTopmostElement(toScenePos);
- if (targetElement) {
- if (id == QStringLiteral("dependency")) {
- auto dependantObject = dynamic_cast<DObject *>(targetElement);
- if (dependantObject)
- diagramSceneModel()->diagramSceneController()->createDependency(object(), dependantObject, intermediatePoints, diagramSceneModel()->diagram());
- }
- }
-}
-
PackageItem::ShapeGeometry PackageItem::calcMinimumGeometry() const
{
double width = 0.0;
@@ -343,10 +311,7 @@ void PackageItem::updateGeometry()
}
updateSelectionMarkerGeometry(rect);
-
- if (m_relationStarter)
- m_relationStarter->setPos(mapToScene(QPointF(right + 8.0, top)));
-
+ updateRelationStarterGeometry(rect);
updateAlignmentButtonsGeometry(rect);
updateDepth();
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/packageitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/packageitem.h
index c08add83686..323447dda5f 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/packageitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/packageitem.h
@@ -27,8 +27,6 @@
#include "objectitem.h"
-#include "qmt/diagram_scene/capabilities/relationable.h"
-
QT_BEGIN_NAMESPACE
class QGraphicsPolygonItem;
class QGraphicsSimpleTextItem;
@@ -42,12 +40,12 @@ class CustomIconItem;
class ContextLabelItem;
class RelationStarter;
-class PackageItem : public ObjectItem, public IRelationable
+class PackageItem : public ObjectItem
{
class ShapeGeometry;
public:
- PackageItem(DPackage *package, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent = 0);
+ PackageItem(DPackage *package, DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent = nullptr);
~PackageItem() override;
void update() override;
@@ -60,18 +58,13 @@ public:
QList<Latch> horizontalLatches(Action action, bool grabbedItem) const override;
QList<Latch> verticalLatches(Action action, bool grabbedItem) const override;
- QPointF relationStartPos() const override;
- void relationDrawn(const QString &id, const QPointF &toScenePos,
- const QList<QPointF> &intermediatePoints) override;
-
private:
ShapeGeometry calcMinimumGeometry() const;
void updateGeometry();
- CustomIconItem *m_customIcon = 0;
- QGraphicsPolygonItem *m_shape = 0;
- ContextLabelItem *m_contextLabel = 0;
- RelationStarter *m_relationStarter = 0;
+ CustomIconItem *m_customIcon = nullptr;
+ QGraphicsPolygonItem *m_shape = nullptr;
+ ContextLabelItem *m_contextLabel = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.cpp
index 338c57595b6..6904bc2a041 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.cpp
@@ -28,6 +28,7 @@
#include "qmt/diagram_controller/diagramcontroller.h"
#include "qmt/diagram_controller/dvoidvisitor.h"
#include "qmt/diagram/dassociation.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dinheritance.h"
#include "qmt/diagram/dobject.h"
@@ -41,6 +42,8 @@
#include "qmt/diagram_scene/parts/stereotypesitem.h"
#include "qmt/infrastructure/geometryutilities.h"
#include "qmt/infrastructure/qmtassert.h"
+#include "qmt/stereotype/customrelation.h"
+#include "qmt/stereotype/stereotypecontroller.h"
#include "qmt/style/stylecontroller.h"
#include "qmt/style/styledrelation.h"
#include "qmt/style/style.h"
@@ -67,11 +70,11 @@ public:
void visitDInheritance(const DInheritance *inheritance)
{
DObject *baseObject = m_diagramSceneModel->diagramController()->findElement<DObject>(inheritance->base(), m_diagramSceneModel->diagram());
- QMT_CHECK(baseObject);
+ QMT_ASSERT(baseObject, return);
bool baseIsInterface = false;
bool lollipopDisplay = false;
if (baseObject) {
- baseIsInterface = baseObject->stereotypes().contains(QStringLiteral("interface"));
+ baseIsInterface = baseObject->stereotypes().contains("interface");
if (baseIsInterface) {
StereotypeDisplayVisitor stereotypeDisplayVisitor;
stereotypeDisplayVisitor.setModelController(m_diagramSceneModel->diagramSceneController()->modelController());
@@ -83,7 +86,7 @@ public:
if (lollipopDisplay) {
m_arrow->setShaft(ArrowItem::ShaftSolid);
m_arrow->setEndHead(ArrowItem::HeadNone);
- } else if (baseIsInterface || inheritance->stereotypes().contains(QStringLiteral("realize"))) {
+ } else if (baseIsInterface || inheritance->stereotypes().contains("realize")) {
m_arrow->setShaft(ArrowItem::ShaftDashed);
m_arrow->setEndHead(ArrowItem::HeadTriangle);
} else {
@@ -99,7 +102,7 @@ public:
{
ArrowItem::Head endAHead = ArrowItem::HeadNone;
ArrowItem::Head endBHead = ArrowItem::HeadNone;
- bool isRealization = dependency->stereotypes().contains(QStringLiteral("realize"));
+ bool isRealization = dependency->stereotypes().contains("realize");
switch (dependency->direction()) {
case MDependency::AToB:
endBHead = isRealization ? ArrowItem::HeadTriangle : ArrowItem::HeadOpen;
@@ -166,9 +169,49 @@ public:
m_arrow->setPoints(m_points);
}
+ void visitDConnection(const DConnection *connection)
+ {
+
+ ArrowItem::Shaft shaft = ArrowItem::ShaftSolid;
+ ArrowItem::Head endAHead = ArrowItem::HeadNone;
+ ArrowItem::Head endBHead = ArrowItem::HeadNone;
+
+ CustomRelation customRelation = m_diagramSceneModel->stereotypeController()->findCustomRelation(connection->customRelationId());
+ if (!customRelation.isNull()) {
+ // TODO support custom shapes
+ static const QHash<CustomRelation::ShaftPattern, ArrowItem::Shaft> shaft2shaft = {
+ { CustomRelation::ShaftPattern::Solid, ArrowItem::ShaftSolid },
+ { CustomRelation::ShaftPattern::Dash, ArrowItem::ShaftDashed },
+ { CustomRelation::ShaftPattern::Dot, ArrowItem::ShaftDot },
+ { CustomRelation::ShaftPattern::DashDot, ArrowItem::ShaftDashDot },
+ { CustomRelation::ShaftPattern::DashDotDot, ArrowItem::ShaftDashDotDot },
+ };
+ static const QHash<CustomRelation::Head, ArrowItem::Head> head2head = {
+ { CustomRelation::Head::None, ArrowItem::HeadNone },
+ { CustomRelation::Head::Shape, ArrowItem::HeadNone },
+ { CustomRelation::Head::Arrow, ArrowItem::HeadOpen },
+ { CustomRelation::Head::Triangle, ArrowItem::HeadTriangle },
+ { CustomRelation::Head::FilledTriangle, ArrowItem::HeadFilledTriangle },
+ { CustomRelation::Head::Diamond, ArrowItem::HeadDiamond },
+ { CustomRelation::Head::FilledDiamond, ArrowItem::HeadFilledDiamond },
+ };
+ shaft = shaft2shaft.value(customRelation.shaftPattern());
+ endAHead = head2head.value(customRelation.endA().head());
+ endBHead = head2head.value(customRelation.endB().head());
+ // TODO color
+ }
+
+ m_arrow->setShaft(shaft);
+ m_arrow->setArrowSize(12.0);
+ m_arrow->setDiamondSize(12.0);
+ m_arrow->setStartHead(endAHead);
+ m_arrow->setEndHead(endBHead);
+ m_arrow->setPoints(m_points);
+ }
+
private:
- DiagramSceneModel *m_diagramSceneModel = 0;
- ArrowItem *m_arrow = 0;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
+ ArrowItem *m_arrow = nullptr;
QList<QPointF> m_points;
};
@@ -273,6 +316,18 @@ void RelationItem::setFocusSelected(bool focusSelected)
}
}
+QRectF RelationItem::getSecondarySelectionBoundary()
+{
+ return QRectF();
+}
+
+void RelationItem::setBoundarySelected(const QRectF &boundary, bool secondary)
+{
+ // TODO make individual intermediate points selectable
+ Q_UNUSED(boundary)
+ Q_UNUSED(secondary)
+}
+
QPointF RelationItem::grabHandle(int index)
{
if (index == 0) {
@@ -289,7 +344,7 @@ QPointF RelationItem::grabHandle(int index)
} else {
QList<DRelation::IntermediatePoint> intermediatePoints = m_relation->intermediatePoints();
--index;
- QMT_CHECK(index >= 0 && index < intermediatePoints.size());
+ QMT_ASSERT(index >= 0 && index < intermediatePoints.size(), return QPointF());
return intermediatePoints.at(index).pos();
}
}
@@ -337,7 +392,7 @@ void RelationItem::setHandlePos(int index, const QPointF &pos)
} else {
QList<DRelation::IntermediatePoint> intermediatePoints = m_relation->intermediatePoints();
--index;
- QMT_CHECK(index >= 0 && index < intermediatePoints.size());
+ QMT_ASSERT(index >= 0 && index < intermediatePoints.size(), return);
intermediatePoints[index].setPos(pos);
m_diagramSceneModel->diagramController()->startUpdateElement(m_relation, m_diagramSceneModel->diagram(), DiagramController::UpdateMinor);
@@ -361,7 +416,7 @@ void RelationItem::dropHandle(int index, double rasterWidth, double rasterHeight
} else {
QList<DRelation::IntermediatePoint> intermediatePoints = m_relation->intermediatePoints();
--index;
- QMT_CHECK(index >= 0 && index < intermediatePoints.size());
+ QMT_ASSERT(index >= 0 && index < intermediatePoints.size(), return);
QPointF pos = intermediatePoints.at(index).pos();
double x = qRound(pos.x() / rasterWidth) * rasterWidth;
@@ -424,7 +479,7 @@ void RelationItem::update(const Style *style)
} else if (m_name) {
m_name->scene()->removeItem(m_name);
delete m_name;
- m_name = 0;
+ m_name = nullptr;
}
if (!m_relation->stereotypes().isEmpty()) {
@@ -437,7 +492,7 @@ void RelationItem::update(const Style *style)
} else if (m_stereotypes) {
m_stereotypes->scene()->removeItem(m_stereotypes);
delete m_stereotypes;
- m_stereotypes = 0;
+ m_stereotypes = nullptr;
}
if (isSelected() || isSecondarySelected()) {
@@ -449,7 +504,7 @@ void RelationItem::update(const Style *style)
if (m_selectionHandles->scene())
m_selectionHandles->scene()->removeItem(m_selectionHandles);
delete m_selectionHandles;
- m_selectionHandles = 0;
+ m_selectionHandles = nullptr;
}
setZValue((isSelected() || isSecondarySelected()) ? RELATION_ITEMS_ZVALUE_SELECTED : RELATION_ITEMS_ZVALUE);
@@ -486,7 +541,7 @@ QPointF RelationItem::calcEndPoint(const Uid &end, const Uid &otherEnd, int near
// otherEndPos will not be used
} else {
DObject *endOtherObject = m_diagramSceneModel->diagramController()->findElement<DObject>(otherEnd, m_diagramSceneModel->diagram());
- QMT_CHECK(endOtherObject);
+ QMT_ASSERT(endOtherObject, return QPointF());
if (endOtherObject)
otherEndPos = endOtherObject->pos();
}
@@ -502,7 +557,7 @@ QPointF RelationItem::calcEndPoint(const Uid &end, const QPointF &otherEndPos, i
QPointF endPos;
if (endObjectItem) {
DObject *endObject = m_diagramSceneModel->diagramController()->findElement<DObject>(end, m_diagramSceneModel->diagram());
- QMT_CHECK(endObject);
+ QMT_ASSERT(endObject, return QPointF());
bool preferAxis = false;
QPointF otherPos;
if (nearestIntermediatePointIndex >= 0 && nearestIntermediatePointIndex < m_relation->intermediatePoints().size()) {
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.h
index 983d480fbc3..4705b9c5e18 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.h
@@ -54,7 +54,7 @@ class RelationItem :
public:
RelationItem(DRelation *relation, DiagramSceneModel *diagramSceneModel,
- QGraphicsItem *parent = 0);
+ QGraphicsItem *parent = nullptr);
~RelationItem() override;
DRelation *relation() const { return m_relation; }
@@ -70,6 +70,8 @@ public:
void setSecondarySelected(bool secondarySelected) override;
bool isFocusSelected() const override;
void setFocusSelected(bool focusSelected) override;
+ QRectF getSecondarySelectionBoundary() override;
+ void setBoundarySelected(const QRectF &boundary, bool secondary) override;
QPointF grabHandle(int index) override;
void insertHandle(int beforeIndex, const QPointF &pos, double rasterWidth, double rasterHeight) override;
@@ -92,16 +94,16 @@ private:
QPointF calcEndPoint(const Uid &end, const QPointF &otherEndPos,
int nearestIntermediatePointIndex);
- DRelation *m_relation = 0;
+ DRelation *m_relation = nullptr;
protected:
- DiagramSceneModel *m_diagramSceneModel = 0;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
bool m_isSecondarySelected = false;
bool m_isFocusSelected = false;
- ArrowItem *m_arrow = 0;
- QGraphicsSimpleTextItem *m_name = 0;
- StereotypesItem *m_stereotypes = 0;
- PathSelectionItem *m_selectionHandles = 0;
+ ArrowItem *m_arrow = nullptr;
+ QGraphicsSimpleTextItem *m_name = nullptr;
+ StereotypesItem *m_stereotypes = nullptr;
+ PathSelectionItem *m_selectionHandles = nullptr;
static bool m_grabbedEndA;
static bool m_grabbedEndB;
static QPointF m_grabbedEndPos;
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/stereotypedisplayvisitor.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/stereotypedisplayvisitor.cpp
index b5130477ad8..dae666a3eb5 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/stereotypedisplayvisitor.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/stereotypedisplayvisitor.cpp
@@ -121,7 +121,7 @@ void StereotypeDisplayVisitor::visitDClass(const DClass *klass)
m_stereotypeIconElement = StereotypeIcon::ElementClass;
MClass *modelKlass = m_modelController->findObject<MClass>(klass->modelUid());
bool hasMembers = false;
- if (!modelKlass->members().isEmpty() && klass->showAllMembers())
+ if (modelKlass && !modelKlass->members().isEmpty() && klass->showAllMembers())
hasMembers = true;
m_stereotypeSmartDisplay = hasMembers ? DObject::StereotypeDecoration : DObject::StereotypeIcon;
visitDObject(klass);
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/stereotypedisplayvisitor.h b/src/libs/modelinglib/qmt/diagram_scene/items/stereotypedisplayvisitor.h
index cac65534d20..feb83c07520 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/stereotypedisplayvisitor.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/stereotypedisplayvisitor.h
@@ -56,8 +56,8 @@ public:
void visitDItem(const DItem *item) override;
private:
- ModelController *m_modelController = 0;
- StereotypeController *m_stereotypeController = 0;
+ ModelController *m_modelController = nullptr;
+ StereotypeController *m_stereotypeController = nullptr;
DObject::StereotypeDisplay m_stereotypeDisplay = DObject::StereotypeNone;
QString m_stereotypeIconId;
QString m_shapeIconId;
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.cpp
new file mode 100644
index 00000000000..ee8b791f6aa
--- /dev/null
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.cpp
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Jochen Becher
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "swimlaneitem.h"
+
+#include "qmt/diagram_controller/diagramcontroller.h"
+#include "qmt/diagram/dswimlane.h"
+#include "qmt/diagram_scene/diagramsceneconstants.h"
+#include "qmt/diagram_scene/diagramscenemodel.h"
+#include "qmt/infrastructure/qmtassert.h"
+#include "qmt/style/stylecontroller.h"
+#include "qmt/style/style.h"
+
+#include <QBrush>
+#include <QGraphicsLineItem>
+#include <QGraphicsScene>
+#include <QGraphicsSceneMouseEvent>
+#include <QPen>
+
+namespace qmt {
+
+static const qreal SWIMLANE_LENGTH = 100000;
+static const qreal SWIMLANE_WIDTH = 16;
+static const qreal SWIMLANE_MARKER_WIDTH = 8;
+
+SwimlaneItem::SwimlaneItem(DSwimlane *swimlane, DiagramSceneModel *diagramSceneModel,
+ QGraphicsItem *parent)
+ : QGraphicsItem (parent),
+ m_swimlane(swimlane),
+ m_diagramSceneModel(diagramSceneModel)
+{
+ setFlags(QGraphicsItem::ItemIsSelectable);
+}
+
+SwimlaneItem::~SwimlaneItem()
+{
+}
+
+QRectF SwimlaneItem::boundingRect() const
+{
+ if (m_swimlane->isHorizontal())
+ return QRectF(-SWIMLANE_LENGTH/2, -SWIMLANE_WIDTH/2, SWIMLANE_LENGTH, SWIMLANE_WIDTH);
+ else
+ return QRectF(-SWIMLANE_WIDTH/2, -SWIMLANE_LENGTH/2, SWIMLANE_WIDTH, SWIMLANE_LENGTH);
+}
+
+void SwimlaneItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(painter);
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+}
+
+void SwimlaneItem::update()
+{
+ QMT_CHECK(!m_isUpdating);
+ m_isUpdating = true;
+
+ prepareGeometryChange();
+
+ const Style *style = adaptedStyle();
+ Q_UNUSED(style);
+
+ // swimline line
+ if (!m_lineItem)
+ m_lineItem = new QGraphicsLineItem(this);
+ m_lineItem->setPen(QPen(QBrush(Qt::black), 1, Qt::DashLine));
+
+ updateSelectionMarker();
+ updateGeometry();
+ setZValue(SWIMLANE_ITEMS_ZVALUE);
+
+ m_isUpdating = false;
+}
+
+void SwimlaneItem::moveDelta(const QPointF &delta)
+{
+ m_diagramSceneModel->diagramController()->startUpdateElement(m_swimlane, m_diagramSceneModel->diagram(),
+ DiagramController::UpdateGeometry);
+ if (m_swimlane->isHorizontal())
+ m_swimlane->setPos(m_swimlane->pos() + delta.y());
+ else
+ m_swimlane->setPos(m_swimlane->pos() + delta.x());
+ m_diagramSceneModel->diagramController()->finishUpdateElement(m_swimlane, m_diagramSceneModel->diagram(), false);
+}
+
+void SwimlaneItem::alignItemPositionToRaster(double rasterWidth, double rasterHeight)
+{
+ if (m_swimlane->isHorizontal()) {
+ qreal yDelta = qRound(m_swimlane->pos() / rasterHeight) * rasterHeight - m_swimlane->pos();
+ moveDelta(QPointF(0, yDelta));
+ } else {
+ qreal xDelta = qRound(m_swimlane->pos() / rasterWidth) * rasterWidth - m_swimlane->pos();
+ moveDelta(QPointF(xDelta, 0));
+ }
+}
+
+bool SwimlaneItem::isSecondarySelected() const
+{
+ return m_secondarySelected;
+}
+
+void SwimlaneItem::setSecondarySelected(bool secondarySelected)
+{
+ if (m_secondarySelected != secondarySelected) {
+ m_secondarySelected = secondarySelected;
+ update();
+ }
+}
+
+bool SwimlaneItem::isFocusSelected() const
+{
+ return false;
+}
+
+void SwimlaneItem::setFocusSelected(bool focusSelected)
+{
+ Q_UNUSED(focusSelected);
+}
+
+QRectF SwimlaneItem::getSecondarySelectionBoundary()
+{
+ QRectF boundary;
+ if (m_swimlane->isHorizontal())
+ boundary = QRectF(-SWIMLANE_LENGTH/2, pos().y(), SWIMLANE_LENGTH, SWIMLANE_LENGTH);
+ else
+ boundary = QRectF(pos().x(), -SWIMLANE_LENGTH/2, SWIMLANE_LENGTH, SWIMLANE_LENGTH);
+ return boundary;
+}
+
+void SwimlaneItem::setBoundarySelected(const QRectF &boundary, bool secondary)
+{
+ qreal pos = m_swimlane->pos();
+ bool c;
+
+ if (m_swimlane->isHorizontal())
+ c = pos >= boundary.top() && pos <= boundary.bottom() && boundary.top() > -SWIMLANE_LENGTH/2;
+ else
+ c = pos >= boundary.left() && pos <= boundary.right() && boundary.left() > -SWIMLANE_LENGTH/2;
+ if (c) {
+ if (secondary)
+ setSecondarySelected(true);
+ else
+ setSelected(true);
+ }
+}
+
+void SwimlaneItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton || event->button() == Qt::RightButton) {
+ bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
+ m_diagramSceneModel->selectItem(this, multiSelect);
+ }
+}
+
+void SwimlaneItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (event->buttons() & Qt::LeftButton) {
+ QPointF delta = event->scenePos() - event->lastScenePos();
+ if (m_swimlane->isHorizontal())
+ delta.setX(0.0);
+ else
+ delta.setY(0.0);
+ m_diagramSceneModel->moveSelectedItems(this, delta);
+ }
+}
+
+void SwimlaneItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton) {
+ if (event->scenePos() != event->buttonDownScenePos(Qt::LeftButton))
+ m_diagramSceneModel->alignSelectedItemsPositionOnRaster();
+ }
+}
+
+void SwimlaneItem::updateSelectionMarker()
+{
+ if (isSelected() || m_secondarySelected) {
+ if (!m_selectionMarker)
+ m_selectionMarker = new QGraphicsRectItem(this);
+ m_selectionMarker->setBrush(isSelected() ? Qt::lightGray : Qt::transparent);
+ m_selectionMarker->setPen(isSelected() ? Qt::NoPen : QPen(Qt::lightGray));
+ m_selectionMarker->setZValue(-1);
+ } else if (m_selectionMarker) {
+ if (m_selectionMarker->scene())
+ m_selectionMarker->scene()->removeItem(m_selectionMarker);
+ delete m_selectionMarker;
+ m_selectionMarker = nullptr;
+ }
+}
+
+const Style *SwimlaneItem::adaptedStyle()
+{
+ return m_diagramSceneModel->styleController()->adaptSwimlaneStyle(m_swimlane);
+}
+
+QSizeF SwimlaneItem::calcMinimumGeometry() const
+{
+ if (m_swimlane->isHorizontal())
+ return QSizeF(SWIMLANE_LENGTH, SWIMLANE_WIDTH);
+ else
+ return QSizeF(SWIMLANE_WIDTH, SWIMLANE_LENGTH);
+}
+
+void SwimlaneItem::updateGeometry()
+{
+ prepareGeometryChange();
+
+ QSizeF geometry = calcMinimumGeometry();
+ qreal width = geometry.width();
+ qreal height = geometry.height();
+
+ if (m_swimlane->isHorizontal()) {
+ setPos(0, m_swimlane->pos());
+ if (m_lineItem)
+ m_lineItem->setLine(-width / 2, 0, width / 2, 0);
+ if (m_selectionMarker)
+ m_selectionMarker->setRect(-width / 2, -SWIMLANE_MARKER_WIDTH / 2, width, SWIMLANE_MARKER_WIDTH);
+ } else {
+ setPos(m_swimlane->pos(), 0);
+ if (m_lineItem)
+ m_lineItem->setLine(0, -height / 2, 0, height / 2);
+ if (m_selectionMarker)
+ m_selectionMarker->setRect(-SWIMLANE_MARKER_WIDTH / 2, -height / 2, SWIMLANE_MARKER_WIDTH, height);
+ }
+}
+
+} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.h b/src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.h
new file mode 100644
index 00000000000..bae23feaf11
--- /dev/null
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Jochen Becher
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QGraphicsItem>
+
+#include "qmt/diagram_scene/capabilities/moveable.h"
+#include "qmt/diagram_scene/capabilities/selectable.h"
+
+namespace qmt {
+
+class DSwimlane;
+class DiagramSceneModel;
+class Style;
+
+class SwimlaneItem :
+ public QGraphicsItem,
+ public IMoveable,
+ public ISelectable
+{
+public:
+ SwimlaneItem(DSwimlane *swimlane, DiagramSceneModel *diagramSceneModel,
+ QGraphicsItem *parent = nullptr);
+ ~SwimlaneItem() override;
+
+ DSwimlane *swimlane() const { return m_swimlane; }
+ DiagramSceneModel *diagramSceneModel() const { return m_diagramSceneModel; }
+
+ QRectF boundingRect() const override;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
+
+ virtual void update();
+
+ void moveDelta(const QPointF &delta) override;
+ void alignItemPositionToRaster(double rasterWidth, double rasterHeight) override;
+
+ bool isSecondarySelected() const override;
+ void setSecondarySelected(bool secondarySelected) override;
+ bool isFocusSelected() const override;
+ void setFocusSelected(bool focusSelected) override;
+ QRectF getSecondarySelectionBoundary() override;
+ void setBoundarySelected(const QRectF &boundary, bool secondary) override;
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
+
+ void updateSelectionMarker();
+ const Style *adaptedStyle();
+
+private:
+ QSizeF calcMinimumGeometry() const;
+ void updateGeometry();
+
+ DSwimlane *m_swimlane = nullptr;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
+ QGraphicsLineItem *m_lineItem = nullptr;
+ QGraphicsRectItem *m_selectionMarker = nullptr;
+ bool m_isUpdating = false;
+ bool m_secondarySelected = false;
+};
+
+} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.cpp b/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.cpp
index f9b7643e9f5..6ac9ab91203 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.cpp
@@ -41,13 +41,8 @@ namespace qmt {
LatchController::LatchController(QObject *parent)
: QObject(parent),
- m_diagramSceneModel(nullptr),
m_horizontalAlignLine(new AlignLineItem(AlignLineItem::Horizontal, 0)),
- m_verticalAlignLine(new AlignLineItem(AlignLineItem::Vertical, 0)),
- m_foundHorizontalLatch(false),
- m_horizontalDist(0.0),
- m_foundVerticalLatch(false),
- m_verticalDist(0.0)
+ m_verticalAlignLine(new AlignLineItem(AlignLineItem::Vertical, 0))
{
m_horizontalAlignLine->setZValue(LATCH_LINES_ZVALUE);
m_horizontalAlignLine->setVisible(false);
@@ -73,7 +68,7 @@ void LatchController::setDiagramSceneModel(DiagramSceneModel *diagramSceneModel)
void LatchController::addToGraphicsScene(QGraphicsScene *graphicsScene)
{
- QMT_CHECK(graphicsScene);
+ QMT_ASSERT(graphicsScene, return);
graphicsScene->addItem(m_horizontalAlignLine);
graphicsScene->addItem(m_verticalAlignLine);
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.h b/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.h
index fc91764d2ff..18c977114fe 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.h
@@ -47,7 +47,7 @@ class QMT_EXPORT LatchController : public QObject
Q_OBJECT
public:
- explicit LatchController(QObject *parent = 0);
+ explicit LatchController(QObject *parent = nullptr);
~LatchController() override;
void setDiagramSceneModel(DiagramSceneModel *diagramSceneModel);
@@ -67,15 +67,15 @@ private:
void applyLatches();
private:
- DiagramSceneModel *m_diagramSceneModel;
- AlignLineItem *m_horizontalAlignLine;
- AlignLineItem *m_verticalAlignLine;
- bool m_foundHorizontalLatch;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
+ AlignLineItem *m_horizontalAlignLine = nullptr;
+ AlignLineItem *m_verticalAlignLine = nullptr;
+ bool m_foundHorizontalLatch = false;
ILatchable::Latch m_horizontalLatch;
- qreal m_horizontalDist;
- bool m_foundVerticalLatch;
+ qreal m_horizontalDist = 0.0;
+ bool m_foundVerticalLatch = false;
ILatchable::Latch m_verticalLatch;
- qreal m_verticalDist;
+ qreal m_verticalDist = 0.0;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.cpp
index f8482e992cb..4848d91c75b 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.cpp
@@ -85,8 +85,8 @@ public:
private:
IAlignable::AlignType m_alignType = IAlignable::AlignLeft;
QString m_identifier;
- IAlignable *m_alignable = 0;
- QGraphicsPixmapItem *m_pixmapItem = 0;
+ IAlignable *m_alignable = nullptr;
+ QGraphicsPixmapItem *m_pixmapItem = nullptr;
};
AlignButtonsItem::AlignButtonsItem(IAlignable *alignable, QGraphicsItem *parent)
@@ -124,42 +124,42 @@ void AlignButtonsItem::addButton(IAlignable::AlignType alignType, const QString
switch (alignType) {
case IAlignable::AlignLeft:
{
- static const QPixmap alignLeftPixmap = QPixmap(QStringLiteral(":/modelinglib/25x25/align-left.png")).scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ static const QPixmap alignLeftPixmap = QPixmap(":/modelinglib/25x25/align-left.png").scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
item->setPixmap(alignLeftPixmap);
item->setPos(pos - InnerBorder - 3.0, 0); // subtract additional shift of image within pixmap
break;
}
case IAlignable::AlignRight:
{
- static const QPixmap alignRightPixmap = QPixmap(QStringLiteral(":/modelinglib/25x25/align-right.png")).scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ static const QPixmap alignRightPixmap = QPixmap(":/modelinglib/25x25/align-right.png").scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
item->setPixmap(alignRightPixmap);
item->setPos(pos - item->boundingRect().width() + InnerBorder + 3.0, 0);
break;
}
case IAlignable::AlignTop:
{
- static const QPixmap alignTopPixmap = QPixmap(QStringLiteral(":/modelinglib/25x25/align-top.png")).scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ static const QPixmap alignTopPixmap = QPixmap(":/modelinglib/25x25/align-top.png").scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
item->setPixmap(alignTopPixmap);
item->setPos(0, pos - InnerBorder - 3.0);
break;
}
case IAlignable::AlignBottom:
{
- static const QPixmap alignBottomPixmap = QPixmap(QStringLiteral(":/modelinglib/25x25/align-bottom.png")).scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ static const QPixmap alignBottomPixmap = QPixmap(":/modelinglib/25x25/align-bottom.png").scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
item->setPixmap(alignBottomPixmap);
item->setPos(0, pos - item->boundingRect().height() + InnerBorder + 3.0);
break;
}
case IAlignable::AlignHcenter:
{
- static const QPixmap alignHorizontalPixmap = QPixmap(QStringLiteral(":/modelinglib/25x25/align-horizontal.png")).scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ static const QPixmap alignHorizontalPixmap = QPixmap(":/modelinglib/25x25/align-horizontal.png").scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
item->setPixmap(alignHorizontalPixmap);
item->setPos(pos - item->boundingRect().center().x(), 0);
break;
}
case IAlignable::AlignVcenter:
{
- static const QPixmap alignVerticalPixmap = QPixmap(QStringLiteral(":/modelinglib/25x25/align-vertical.png")).scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ static const QPixmap alignVerticalPixmap = QPixmap(":/modelinglib/25x25/align-vertical.png").scaled(NormalPixmapWidth, NormalPixmapHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
item->setPixmap(alignVerticalPixmap);
item->setPos(0, pos - item->boundingRect().center().y());
break;
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.h b/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.h
index 96a48f3d8a4..d17906b299b 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.h
@@ -48,7 +48,7 @@ public:
VerticalDistanceToObejct = HorizontalDistanceToObject
};
- explicit AlignButtonsItem(IAlignable *alignable, QGraphicsItem *parent = 0);
+ explicit AlignButtonsItem(IAlignable *alignable, QGraphicsItem *parent = nullptr);
~AlignButtonsItem() override;
QRectF boundingRect() const override;
@@ -58,7 +58,7 @@ public:
void addButton(IAlignable::AlignType alignType, const QString &identifier, qreal pos);
private:
- IAlignable *m_alignable = 0;
+ IAlignable *m_alignable = nullptr;
QList<AlignButtonItem *> m_alignItems;
};
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/alignlineitem.h b/src/libs/modelinglib/qmt/diagram_scene/parts/alignlineitem.h
index a630efc2b7a..1244cb58944 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/alignlineitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/alignlineitem.h
@@ -37,7 +37,7 @@ public:
Vertical
};
- explicit AlignLineItem(Direction direction, QGraphicsItem *parent = 0);
+ explicit AlignLineItem(Direction direction, QGraphicsItem *parent = nullptr);
~AlignLineItem() override;
void setLine(qreal pos);
@@ -45,11 +45,11 @@ public:
QRectF boundingRect() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget = 0) override;
+ QWidget *widget = nullptr) override;
Direction m_direction = Horizontal;
- QGraphicsLineItem *m_alignLine = 0;
- QGraphicsLineItem *m_highlightLine = 0;
+ QGraphicsLineItem *m_alignLine = nullptr;
+ QGraphicsLineItem *m_highlightLine = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.cpp
index 7de0bf0d984..93a4a10f195 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.cpp
@@ -38,6 +38,8 @@
#include <QPainter>
#include <QPen>
+//#define DEBUG_PAINT_SHAPE
+
namespace qmt {
class ArrowItem::GraphicsHeadItem : public QGraphicsItem
@@ -110,6 +112,7 @@ public:
double length = 0.0;
switch (m_head) {
case ArrowItem::HeadNone:
+ case ArrowItem::HeadCustom:
break;
case ArrowItem::HeadOpen:
case ArrowItem::HeadTriangle:
@@ -146,6 +149,7 @@ public:
bool hasDiamond = false;
switch (m_head) {
case ArrowItem::HeadNone:
+ case ArrowItem::HeadCustom:
break;
case ArrowItem::HeadOpen:
case ArrowItem::HeadTriangle:
@@ -188,7 +192,7 @@ public:
} else if (m_arrowItem) {
m_arrowItem->scene()->removeItem(m_arrowItem);
delete m_arrowItem;
- m_arrowItem = 0;
+ m_arrowItem = nullptr;
}
if (hasDiamond) {
@@ -213,7 +217,7 @@ public:
} else if (m_diamondItem) {
m_diamondItem->scene()->removeItem(m_diamondItem);
delete m_diamondItem;
- m_diamondItem = 0;
+ m_diamondItem = nullptr;
}
}
@@ -221,8 +225,8 @@ private:
ArrowItem::Head m_head = ArrowItem::HeadNone;
double m_arrowSize = 10.0;
double m_diamondSize = 15.0;
- QGraphicsPathItem *m_arrowItem = 0;
- QGraphicsPathItem *m_diamondItem = 0;
+ QGraphicsPathItem *m_arrowItem = nullptr;
+ QGraphicsPathItem *m_diamondItem = nullptr;
};
class ArrowItem::GraphicsShaftItem : public QGraphicsPathItem
@@ -236,7 +240,6 @@ public:
ArrowItem::ArrowItem(QGraphicsItem *parent)
: QGraphicsItem(parent),
- m_shaft(ShaftSolid),
m_shaftItem(new GraphicsShaftItem(this))
{
}
@@ -248,9 +251,7 @@ ArrowItem::ArrowItem(const ArrowItem &rhs, QGraphicsItem *parent)
m_arrowSize(rhs.m_arrowSize),
m_diamondSize(rhs.m_diamondSize),
m_startHead(rhs.m_startHead),
- m_startHeadItem(nullptr),
- m_endHead(rhs.m_endHead),
- m_endHeadItem(nullptr)
+ m_endHead(rhs.m_endHead)
{
}
@@ -278,14 +279,36 @@ void ArrowItem::setDiamondSize(double diamondSize)
void ArrowItem::setStartHead(ArrowItem::Head head)
{
- if (m_startHead != head)
- m_startHead = head;
+ m_startHead = head;
+}
+
+void ArrowItem::setStartHead(QGraphicsItem *startHeadItem)
+{
+ deleteHead(&m_startHeadItem);
+ if (!startHeadItem) {
+ m_startHead = HeadNone;
+ } else {
+ QTC_ASSERT(startHeadItem->parentItem() == this, return);
+ m_startHead = HeadCustom;
+ m_startHeadItem = startHeadItem;
+ }
}
void ArrowItem::setEndHead(ArrowItem::Head head)
{
- if (m_endHead != head)
- m_endHead = head;
+ m_endHead = head;
+}
+
+void ArrowItem::setEndHead(QGraphicsItem *endHeadItem)
+{
+ deleteHead(&m_endHeadItem);
+ if (!endHeadItem) {
+ m_endHead = HeadNone;
+ } else {
+ QTC_ASSERT(endHeadItem->parentItem() == this, return);
+ m_endHead = HeadCustom;
+ m_endHeadItem = endHeadItem;
+ }
}
void ArrowItem::setPoints(const QList<QPointF> &points)
@@ -346,27 +369,27 @@ QPointF ArrowItem::calcPointAtPercent(double percentage) const
QLineF ArrowItem::firstLineSegment() const
{
- QTC_ASSERT(m_points.size() > 1, return QLineF());
+ QMT_ASSERT(m_points.size() > 1, return QLineF());
return QLineF(m_points.at(0), m_points.at(1));
}
QLineF ArrowItem::lastLineSegment() const
{
- QTC_ASSERT(m_points.size() > 1, return QLineF());
+ QMT_ASSERT(m_points.size() > 1, return QLineF());
return QLineF(m_points.at(m_points.size() - 1), m_points.at(m_points.size() - 2));
}
double ArrowItem::startHeadLength() const
{
if (m_startHeadItem)
- return m_startHeadItem->calcHeadLength();
+ return calcHeadLength(m_startHeadItem);
return 0.0;
}
double ArrowItem::endHeadLength() const
{
if (m_endHeadItem)
- return m_endHeadItem->calcHeadLength();
+ return calcHeadLength(m_endHeadItem);
return 0.0;
}
@@ -380,52 +403,89 @@ void ArrowItem::update(const Style *style)
void ArrowItem::updateShaft(const Style *style)
{
- QTC_ASSERT(m_shaftItem, return);
+ QMT_ASSERT(m_shaftItem, return);
QPen pen(style->linePen());
- if (m_shaft == ShaftDashed)
- pen.setDashPattern(QVector<qreal>() << (4.0 / pen.widthF()) << (4.0 / pen.widthF()));
+ switch (m_shaft) {
+ case ShaftSolid:
+ break;
+ case ShaftDashed:
+ pen.setDashPattern(QVector<qreal>()
+ << (4.0 / pen.widthF()) << (4.0 / pen.widthF()));
+ break;
+ case ShaftDot:
+ pen.setDashPattern(QVector<qreal>()
+ << (2.0 / pen.widthF()) << (2.0 / pen.widthF()));
+ break;
+ case ShaftDashDot:
+ pen.setDashPattern(QVector<qreal>()
+ << (4.0 / pen.widthF()) << (2.0 / pen.widthF())
+ << (2.0 / pen.widthF()) << (2.0 / pen.widthF()));
+ break;
+ case ShaftDashDotDot:
+ pen.setDashPattern(QVector<qreal>()
+ << (4.0 / pen.widthF()) << (2.0 / pen.widthF())
+ << (2.0 / pen.widthF()) << (2.0 / pen.widthF())
+ << (2.0 / pen.widthF()) << (2.0 / pen.widthF()));
+ break;
+ }
m_shaftItem->setPen(pen);
}
-void ArrowItem::updateHead(GraphicsHeadItem **headItem, Head head, const Style *style)
+void ArrowItem::deleteHead(QGraphicsItem **headItem)
+{
+ if (*headItem) {
+ if ((*headItem)->scene())
+ (*headItem)->scene()->removeItem(*headItem);
+ delete *headItem;
+ *headItem = nullptr;
+ }
+}
+
+void ArrowItem::updateHead(QGraphicsItem **headItem, Head head, const Style *style)
{
if (head == HeadNone) {
- if (*headItem) {
- if ((*headItem)->scene())
- (*headItem)->scene()->removeItem(*headItem);
- delete *headItem;
- *headItem = 0;
+ deleteHead(headItem);
+ } else if (head == HeadCustom) {
+ // nothing to do
+ } else {
+ QTC_ASSERT(headItem, return);
+ QTC_ASSERT(!*headItem || dynamic_cast<GraphicsHeadItem *>(*headItem), return);
+ GraphicsHeadItem *item;
+ if (!*headItem) {
+ item = new GraphicsHeadItem(this);
+ *headItem = item;
+ } else {
+ item = dynamic_cast<GraphicsHeadItem *>(*headItem);
+ if (!item)
+ return;
}
- return;
+ item->setArrowSize(m_arrowSize);
+ item->setDiamondSize(m_diamondSize);
+ item->setHead(head);
+ item->update(style);
}
- if (!*headItem)
- *headItem = new GraphicsHeadItem(this);
- (*headItem)->setArrowSize(m_arrowSize);
- (*headItem)->setDiamondSize(m_diamondSize);
- (*headItem)->setHead(head);
- (*headItem)->update(style);
}
-void ArrowItem::updateHeadGeometry(GraphicsHeadItem **headItem, const QPointF &pos, const QPointF &otherPos)
+void ArrowItem::updateHeadGeometry(QGraphicsItem *headItem, const QPointF &pos, const QPointF &otherPos)
{
- if (!*headItem)
+ if (!headItem)
return;
- (*headItem)->setPos(pos);
+ headItem->setPos(pos);
QVector2D directionVector(pos - otherPos);
directionVector.normalize();
double angle = qAcos(directionVector.x()) * 180.0 / 3.1415926535;
if (directionVector.y() > 0.0)
angle = -angle;
- (*headItem)->setRotation(-angle);
+ headItem->setRotation(-angle);
}
void ArrowItem::updateGeometry()
{
- QTC_ASSERT(m_points.size() > 1, return);
- QTC_ASSERT(m_shaftItem, return);
+ QMT_ASSERT(m_points.size() > 1, return);
+ QMT_ASSERT(m_shaftItem, return);
prepareGeometryChange();
@@ -434,8 +494,8 @@ void ArrowItem::updateGeometry()
if (m_startHeadItem) {
QVector2D startDirectionVector(m_points.at(1) - m_points.at(0));
startDirectionVector.normalize();
- startDirectionVector *= m_startHeadItem->calcHeadLength();
- path.moveTo(m_points.at(0) + startDirectionVector.toPointF());
+ startDirectionVector *= calcHeadLength(m_startHeadItem);
+ path.moveTo(m_points[0] + startDirectionVector.toPointF());
} else {
path.moveTo(m_points.at(0));
}
@@ -446,16 +506,24 @@ void ArrowItem::updateGeometry()
if (m_endHeadItem) {
QVector2D endDirectionVector(m_points.at(m_points.size() - 1) - m_points.at(m_points.size() - 2));
endDirectionVector.normalize();
- endDirectionVector *= m_endHeadItem->calcHeadLength();
- path.lineTo(m_points.at(m_points.size() - 1) - endDirectionVector.toPointF());
+ endDirectionVector *= calcHeadLength(m_endHeadItem);
+ path.lineTo(m_points[m_points.size() - 1] - endDirectionVector.toPointF());
} else {
path.lineTo(m_points.at(m_points.size() - 1));
}
m_shaftItem->setPath(path);
- updateHeadGeometry(&m_startHeadItem, m_points.at(0), m_points.at(1));
- updateHeadGeometry(&m_endHeadItem, m_points.at(m_points.size() - 1), m_points.at(m_points.size() - 2));
+ updateHeadGeometry(m_startHeadItem, m_points.at(0), m_points.at(1));
+ updateHeadGeometry(m_endHeadItem, m_points.at(m_points.size() - 1), m_points.at(m_points.size() - 2));
+}
+
+double ArrowItem::calcHeadLength(QGraphicsItem *headItem) const
+{
+ // TODO use an interface
+ if (GraphicsHeadItem *item = dynamic_cast<GraphicsHeadItem *>(headItem))
+ return item->calcHeadLength();
+ return 100.0;
}
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.h b/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.h
index 0f4af541fc2..6f93a0d710c 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.h
@@ -43,11 +43,15 @@ class ArrowItem : public QGraphicsItem
public:
enum Shaft {
ShaftSolid,
- ShaftDashed
+ ShaftDashed,
+ ShaftDot,
+ ShaftDashDot,
+ ShaftDashDotDot
};
enum Head {
HeadNone,
+ HeadCustom,
HeadOpen,
HeadTriangle,
HeadFilledTriangle,
@@ -57,15 +61,17 @@ public:
HeadFilledDiamondFilledTriangle
};
- explicit ArrowItem(QGraphicsItem *parent = 0);
- explicit ArrowItem(const ArrowItem &rhs, QGraphicsItem *parent = 0);
+ explicit ArrowItem(QGraphicsItem *parent = nullptr);
+ explicit ArrowItem(const ArrowItem &rhs, QGraphicsItem *parent = nullptr);
~ArrowItem() override;
void setShaft(Shaft shaft);
void setArrowSize(double arrowSize);
void setDiamondSize(double diamondSize);
void setStartHead(Head head);
+ void setStartHead(QGraphicsItem *startHeadItem);
void setEndHead(Head head);
+ void setEndHead(QGraphicsItem *endHeadItem);
void setPoints(const QList<QPointF> &points);
QRectF boundingRect() const override;
@@ -82,19 +88,21 @@ public:
private:
void updateShaft(const Style *style);
- void updateHead(GraphicsHeadItem **headItem, Head head, const Style *style);
- void updateHeadGeometry(GraphicsHeadItem **headItem, const QPointF &pos,
+ void deleteHead(QGraphicsItem **headItem);
+ void updateHead(QGraphicsItem **headItem, Head head, const Style *style);
+ void updateHeadGeometry(QGraphicsItem *headItem, const QPointF &pos,
const QPointF &otherPos);
void updateGeometry();
+ double calcHeadLength(QGraphicsItem *headItem) const;
Shaft m_shaft = ShaftSolid;
GraphicsShaftItem *m_shaftItem = nullptr;
double m_arrowSize = 10.0;
double m_diamondSize = 15.0;
Head m_startHead = HeadNone;
- GraphicsHeadItem *m_startHeadItem = nullptr;
+ QGraphicsItem *m_startHeadItem = nullptr;
Head m_endHead = HeadNone;
- GraphicsHeadItem *m_endHeadItem = nullptr;
+ QGraphicsItem *m_endHeadItem = nullptr;
QList<QPointF> m_points;
};
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/contextlabelitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/contextlabelitem.cpp
index 4eec6da0765..afda90db4f0 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/contextlabelitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/contextlabelitem.cpp
@@ -69,16 +69,16 @@ double ContextLabelItem::height() const
void ContextLabelItem::update()
{
- setText(QString(QStringLiteral("(from %1)")).arg(m_context));
+ setText(QString("(from %1)").arg(m_context));
if (m_maxWidth > 0.0) {
double contextWidth = boundingRect().width();
if (contextWidth > m_maxWidth) {
- setText(QString(QStringLiteral("(%1)")).arg(m_context));
+ setText(QString("(%1)").arg(m_context));
contextWidth = boundingRect().width();
}
if (contextWidth > m_maxWidth) {
QFontMetricsF metrics(font());
- setText(metrics.elidedText(QString(QStringLiteral("(%1)")).arg(m_context), Qt::ElideMiddle, m_maxWidth));
+ setText(metrics.elidedText(QString("(%1)").arg(m_context), Qt::ElideMiddle, m_maxWidth));
}
}
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/contextlabelitem.h b/src/libs/modelinglib/qmt/diagram_scene/parts/contextlabelitem.h
index 3bbce880731..62cac6619c4 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/contextlabelitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/contextlabelitem.h
@@ -32,7 +32,7 @@ namespace qmt {
class ContextLabelItem : public QGraphicsSimpleTextItem
{
public:
- explicit ContextLabelItem(QGraphicsItem *parent = 0);
+ explicit ContextLabelItem(QGraphicsItem *parent = nullptr);
~ContextLabelItem() override;
void setMaxWidth(double maxWidth);
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/customiconitem.h b/src/libs/modelinglib/qmt/diagram_scene/parts/customiconitem.h
index a1280f45e68..93e083b9625 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/customiconitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/customiconitem.h
@@ -40,7 +40,7 @@ class DiagramSceneModel;
class CustomIconItem : public QGraphicsItem
{
public:
- explicit CustomIconItem(DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent = 0);
+ explicit CustomIconItem(DiagramSceneModel *diagramSceneModel, QGraphicsItem *parent = nullptr);
~CustomIconItem() override;
void setStereotypeIconId(const QString &stereotypeIconId);
@@ -56,7 +56,7 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
private:
- DiagramSceneModel *m_diagramSceneModel = 0;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
QString m_stereotypeIconId;
StereotypeIcon m_stereotypeIcon;
QSizeF m_baseSize;
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.cpp
index 3af578ceaf3..78fa4fff807 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.cpp
@@ -130,7 +130,7 @@ private:
}
}
- PathSelectionItem *m_owner = 0;
+ PathSelectionItem *m_owner = nullptr;
int m_pointIndex = -1;
QSizeF m_pointSize;
Selection m_selection = NotSelected;
@@ -207,10 +207,10 @@ QList<QPointF> PathSelectionItem::points() const
void PathSelectionItem::setPoints(const QList<QPointF> &points)
{
- QMT_CHECK(points.size() >= 2);
+ QMT_ASSERT(points.size() >= 2, return);
prepareGeometryChange();
- GraphicsHandleItem *focusEndBItem = 0;
+ GraphicsHandleItem *focusEndBItem = nullptr;
if (!m_handles.isEmpty() && m_focusHandleItem == m_handles.last()) {
focusEndBItem = m_focusHandleItem;
m_handles.removeLast();
@@ -222,7 +222,7 @@ void PathSelectionItem::setPoints(const QList<QPointF> &points)
handle = focusEndBItem;
handle->setPointIndex(pointIndex);
m_handles.insert(pointIndex, handle);
- focusEndBItem = 0;
+ focusEndBItem = nullptr;
} else if (pointIndex >= m_handles.size()) {
handle = new GraphicsHandleItem(pointIndex, this);
handle->setPointSize(m_pointSize);
@@ -297,7 +297,7 @@ void PathSelectionItem::moveHandle(int pointIndex, const QPointF &deltaMove, Han
m_windable->setHandlePos(pointIndex, newPos);
if (handleStatus == Release) {
m_windable->dropHandle(pointIndex, RASTER_WIDTH, RASTER_HEIGHT);
- m_focusHandleItem = 0;
+ m_focusHandleItem = nullptr;
}
break;
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.h b/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.h
index b38688e2a03..3b8e1685fe9 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.h
@@ -49,7 +49,7 @@ class PathSelectionItem : public QGraphicsItem
};
public:
- explicit PathSelectionItem(IWindable *windable, QGraphicsItem *parent = 0);
+ explicit PathSelectionItem(IWindable *windable, QGraphicsItem *parent = nullptr);
~PathSelectionItem() override;
QRectF boundingRect() const override;
@@ -72,11 +72,11 @@ private:
HandleQualifier handleQualifier);
void keyPressed(int pointIndex, QKeyEvent *event, const QPointF &pos);
- IWindable *m_windable = 0;
+ IWindable *m_windable = nullptr;
QSizeF m_pointSize;
bool m_isSecondarySelected = false;
QList<GraphicsHandleItem *> m_handles;
- GraphicsHandleItem *m_focusHandleItem = 0;
+ GraphicsHandleItem *m_focusHandleItem = nullptr;
QPointF m_originalHandlePos;
};
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.cpp
index ba65d97d516..64936fb7735 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.cpp
@@ -86,7 +86,7 @@ protected:
}
private:
- RectangularSelectionItem *m_owner = 0;
+ RectangularSelectionItem *m_owner = nullptr;
RectangularSelectionItem::Handle m_handle = RectangularSelectionItem::HandleNone;
bool m_isSecondarySelected = false;
QPointF m_startPos;
@@ -157,7 +157,7 @@ void RectangularSelectionItem::setSecondarySelected(bool secondarySelected)
void RectangularSelectionItem::update()
{
- QMT_CHECK(HandleFirst == 0 && HandleLast == 7);
+ QMT_ASSERT(HandleFirst == 0 && HandleLast == 7, return);
prepareGeometryChange();
for (int i = 0; i <= 7; ++i) {
@@ -191,7 +191,7 @@ void RectangularSelectionItem::update()
visible = m_freedom == FreedomAny || m_freedom == FreedomKeepRatio;
break;
case HandleNone:
- QMT_CHECK(false);
+ Q_UNREACHABLE();
break;
}
m_points[i]->setSecondarySelected(m_isSecondarySelected);
@@ -220,7 +220,7 @@ void RectangularSelectionItem::update()
if (m_borderItem->scene())
m_borderItem->scene()->removeItem(m_borderItem);
delete m_borderItem;
- m_borderItem = 0;
+ m_borderItem = nullptr;
}
}
@@ -269,7 +269,7 @@ void RectangularSelectionItem::moveHandle(Handle handle, const QPointF &deltaMov
moveable = m_freedom == FreedomAny || m_freedom == FreedomKeepRatio;
break;
case HandleNone:
- QMT_CHECK(false);
+ Q_UNREACHABLE();
break;
}
if (!moveable)
@@ -328,7 +328,7 @@ void RectangularSelectionItem::moveHandle(Handle handle, const QPointF &deltaMov
bottomRightDelta = -(v * deltaLength);
break;
case HandleNone:
- QMT_CHECK(false);
+ Q_UNREACHABLE();
break;
}
} else {
@@ -360,7 +360,7 @@ void RectangularSelectionItem::moveHandle(Handle handle, const QPointF &deltaMov
bottomRightDelta = deltaMove;
break;
case HandleNone:
- QMT_CHECK(false);
+ Q_UNREACHABLE();
break;
}
}
@@ -386,7 +386,7 @@ void RectangularSelectionItem::moveHandle(Handle handle, const QPointF &deltaMov
bottomRightDelta.setX(bottomRightDelta.x() + sizeDelta.width());
break;
case HandleNone:
- QMT_CHECK(false);
+ Q_UNREACHABLE();
break;
}
@@ -408,7 +408,7 @@ void RectangularSelectionItem::moveHandle(Handle handle, const QPointF &deltaMov
bottomRightDelta.setY(bottomRightDelta.y() + sizeDelta.height());
break;
case HandleNone:
- QMT_CHECK(false);
+ Q_UNREACHABLE();
break;
}
@@ -433,7 +433,7 @@ void RectangularSelectionItem::moveHandle(Handle handle, const QPointF &deltaMov
// nothing
break;
case HandleNone:
- QMT_CHECK(false);
+ Q_UNREACHABLE();
break;
}
switch (handle) {
@@ -452,7 +452,7 @@ void RectangularSelectionItem::moveHandle(Handle handle, const QPointF &deltaMov
// nothing
break;
case HandleNone:
- QMT_CHECK(false);
+ Q_UNREACHABLE();
break;
}
m_itemResizer->alignItemSizeToRaster(horiz, vert, 2 * RASTER_WIDTH, 2 * RASTER_HEIGHT);
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.h b/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.h
index bb82cc44602..5c5d9fcbf02 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.h
@@ -75,7 +75,7 @@ public:
FreedomKeepRatio
};
- explicit RectangularSelectionItem(IResizable *itemResizer, QGraphicsItem *parent = 0);
+ explicit RectangularSelectionItem(IResizable *itemResizer, QGraphicsItem *parent = nullptr);
~RectangularSelectionItem() override;
QRectF boundingRect() const override;
@@ -99,14 +99,14 @@ private:
void moveHandle(Handle handle, const QPointF &deltaMove, HandleStatus handleStatus,
HandleQualifier handleQualifier);
- IResizable *m_itemResizer = 0;
+ IResizable *m_itemResizer = nullptr;
QRectF m_rect;
QSizeF m_pointSize;
QVector<GraphicsHandleItem *> m_points;
QPointF m_originalResizePos;
QRectF m_originalResizeRect;
bool m_showBorder = false;
- QGraphicsRectItem *m_borderItem = 0;
+ QGraphicsRectItem *m_borderItem = nullptr;
Freedom m_freedom = FreedomAny;
bool m_isSecondarySelected = false;
Handle m_activeHandle = HandleNone;
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.cpp
index 5c2ce279e64..705f673ac5b 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.cpp
@@ -70,16 +70,18 @@ void RelationStarter::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
}
void RelationStarter::addArrow(const QString &id, ArrowItem::Shaft shaft,
- ArrowItem::Head endHead, ArrowItem::Head startHead)
+ ArrowItem::Head startHead, ArrowItem::Head endHead,
+ const QString &toolTip)
{
QMT_CHECK(!id.isEmpty());
prepareGeometryChange();
auto arrow = new ArrowItem(this);
arrow->setArrowSize(10.0);
- arrow->setDiamondSize(15.0);
+ arrow->setDiamondSize(8.0);
arrow->setShaft(shaft);
arrow->setStartHead(startHead);
arrow->setEndHead(endHead);
+ arrow->setToolTip(toolTip.isEmpty() ? id : toolTip);
arrow->setPoints(QList<QPointF>() << QPointF(0.0, 10.0) << QPointF(15.0, 0.0));
arrow->setPos(6.0, m_arrows.size() * 20.0 + 8.0);
arrow->update(m_diagramSceneModel->styleController()->relationStarterStyle());
@@ -99,6 +101,9 @@ void RelationStarter::mousePressEvent(QGraphicsSceneMouseEvent *event)
m_currentPreviewArrowId = m_arrowIds.value(item);
QMT_CHECK(!m_currentPreviewArrowId.isEmpty());
m_currentPreviewArrow = new ArrowItem(*item);
+ // TODO use constants for sizes (in relationitem.h also)
+ m_currentPreviewArrow->setArrowSize(12.0);
+ m_currentPreviewArrow->setDiamondSize(12.0);
m_currentPreviewArrow->setPoints(QList<QPointF>() << m_owner->relationStartPos() << mapToScene(event->pos()));
m_currentPreviewArrow->update(m_diagramSceneModel->styleController()->relationStarterStyle());
m_currentPreviewArrow->setZValue(PREVIEW_RELATION_ZVALUE);
@@ -123,7 +128,7 @@ void RelationStarter::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
m_currentPreviewArrowIntermediatePoints);
m_currentPreviewArrow->scene()->removeItem(m_currentPreviewArrow);
delete m_currentPreviewArrow;
- m_currentPreviewArrow = 0;
+ m_currentPreviewArrow = nullptr;
m_currentPreviewArrowIntermediatePoints.clear();
}
}
@@ -152,7 +157,7 @@ void RelationStarter::focusOutEvent(QFocusEvent *event)
if (m_currentPreviewArrow) {
m_currentPreviewArrow->scene()->removeItem(m_currentPreviewArrow);
delete m_currentPreviewArrow;
- m_currentPreviewArrow = 0;
+ m_currentPreviewArrow = nullptr;
m_currentPreviewArrowIntermediatePoints.clear();
}
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.h b/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.h
index cbf69e9244f..a25d03c7bff 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.h
@@ -40,15 +40,16 @@ class RelationStarter : public QGraphicsRectItem
{
public:
RelationStarter(IRelationable *owner, DiagramSceneModel *diagramSceneModel,
- QGraphicsItem *parent = 0);
+ QGraphicsItem *parent = nullptr);
~RelationStarter() override;
QRectF boundingRect() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget = 0) override;
+ QWidget *widget = nullptr) override;
- void addArrow(const QString &id, ArrowItem::Shaft shaft, ArrowItem::Head endHead,
- ArrowItem::Head startHead = ArrowItem::HeadNone);
+ void addArrow(const QString &id, ArrowItem::Shaft shaft, ArrowItem::Head startHead,
+ ArrowItem::Head endHead,
+ const QString &toolTip = QString());
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
@@ -60,11 +61,11 @@ protected:
private:
void updateCurrentPreviewArrow(const QPointF &headPoint);
- IRelationable *m_owner = 0;
- DiagramSceneModel *m_diagramSceneModel = 0;
+ IRelationable *m_owner = nullptr;
+ DiagramSceneModel *m_diagramSceneModel = nullptr;
QList<ArrowItem *> m_arrows;
QHash<ArrowItem *, QString> m_arrowIds;
- ArrowItem *m_currentPreviewArrow = 0;
+ ArrowItem *m_currentPreviewArrow = nullptr;
QString m_currentPreviewArrowId;
QList<QPointF> m_currentPreviewArrowIntermediatePoints;
};
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/stereotypesitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/stereotypesitem.cpp
index 2c6075590aa..0269bb1e078 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/stereotypesitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/stereotypesitem.cpp
@@ -49,7 +49,7 @@ QString StereotypesItem::format(const QList<QString> &stereotypes)
bool first = true;
foreach (const QString &stereotype, stereotypes) {
if (!first)
- text += QStringLiteral(", ");
+ text += ", ";
text += stereotype;
first = false;
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/stereotypesitem.h b/src/libs/modelinglib/qmt/diagram_scene/parts/stereotypesitem.h
index bfb58082617..b07d59a3dd8 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/stereotypesitem.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/stereotypesitem.h
@@ -33,7 +33,7 @@ namespace qmt {
class StereotypesItem : public QGraphicsSimpleTextItem
{
public:
- explicit StereotypesItem(QGraphicsItem *parent = 0);
+ explicit StereotypesItem(QGraphicsItem *parent = nullptr);
~StereotypesItem() override;
void setStereotypes(const QList<QString> &stereotypes);
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/templateparameterbox.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/templateparameterbox.cpp
index 51c386c16be..8da88ea4012 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/templateparameterbox.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/templateparameterbox.cpp
@@ -82,7 +82,7 @@ void TemplateParameterBox::updateText()
if (m_breakLines)
templateText += QLatin1Char('\n');
else
- templateText += QStringLiteral(", ");
+ templateText += ", ";
}
templateText += parameter;
first = false;
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/templateparameterbox.h b/src/libs/modelinglib/qmt/diagram_scene/parts/templateparameterbox.h
index 63349f8ab81..b93eb3e1e75 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/templateparameterbox.h
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/templateparameterbox.h
@@ -32,7 +32,7 @@ namespace qmt {
class TemplateParameterBox : public QGraphicsRectItem
{
public:
- explicit TemplateParameterBox(QGraphicsItem *parent = 0);
+ explicit TemplateParameterBox(QGraphicsItem *parent = nullptr);
~TemplateParameterBox() override;
void setFont(const QFont &font);
@@ -46,7 +46,7 @@ private:
QList<QString> m_templateParameters;
bool m_breakLines = false;
- QGraphicsSimpleTextItem *m_parametersText = 0;
+ QGraphicsSimpleTextItem *m_parametersText = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_ui/diagram_mime_types.h b/src/libs/modelinglib/qmt/diagram_ui/diagram_mime_types.h
index 5926f07ba18..f1f56bfe74b 100644
--- a/src/libs/modelinglib/qmt/diagram_ui/diagram_mime_types.h
+++ b/src/libs/modelinglib/qmt/diagram_ui/diagram_mime_types.h
@@ -38,5 +38,6 @@ static const char ELEMENT_TYPE_CLASS[] = "class";
static const char ELEMENT_TYPE_ITEM[] = "item";
static const char ELEMENT_TYPE_ANNOTATION[] = "annotation";
static const char ELEMENT_TYPE_BOUNDARY[] = "boundary";
+static const char ELEMENT_TYPE_SWIMLANE[] = "swimlane";
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_ui/diagramsmanager.cpp b/src/libs/modelinglib/qmt/diagram_ui/diagramsmanager.cpp
index 9803a377852..0b5097fe639 100644
--- a/src/libs/modelinglib/qmt/diagram_ui/diagramsmanager.cpp
+++ b/src/libs/modelinglib/qmt/diagram_ui/diagramsmanager.cpp
@@ -64,12 +64,7 @@ DiagramsManager::ManagedDiagram::~ManagedDiagram()
}
DiagramsManager::DiagramsManager(QObject *parent)
- : QObject(parent),
- m_diagramsView(0),
- m_diagramController(0),
- m_diagramSceneController(0),
- m_styleController(0),
- m_stereotypeController(0)
+ : QObject(parent)
{
}
@@ -81,7 +76,7 @@ DiagramsManager::~DiagramsManager()
void DiagramsManager::setModel(TreeModel *model)
{
if (m_model)
- connect(m_model, 0, this, 0);
+ connect(m_model, nullptr, this, nullptr);
m_model = model;
if (model) {
connect(model, &QAbstractItemModel::dataChanged,
@@ -97,7 +92,7 @@ void DiagramsManager::setDiagramsView(DiagramsViewInterface *diagramsView)
void DiagramsManager::setDiagramController(DiagramController *diagramController)
{
if (m_diagramController)
- connect(m_diagramController, 0, this, 0);
+ connect(m_diagramController, nullptr, this, nullptr);
m_diagramController = diagramController;
if (diagramController) {
connect(diagramController, &DiagramController::diagramAboutToBeRemoved,
@@ -142,13 +137,13 @@ DiagramSceneModel *DiagramsManager::bindDiagramSceneModel(MDiagram *diagram)
DiagramSceneModel *DiagramsManager::diagramSceneModel(const MDiagram *diagram) const
{
const ManagedDiagram *managedDiagram = m_diagramUidToManagedDiagramMap.value(diagram->uid());
- QMT_CHECK(managedDiagram);
+ QMT_ASSERT(managedDiagram, return nullptr);
return managedDiagram->diagramSceneModel();
}
void DiagramsManager::unbindDiagramSceneModel(const MDiagram *diagram)
{
- QMT_CHECK(diagram);
+ QMT_ASSERT(diagram, return);
ManagedDiagram *managedDiagram = m_diagramUidToManagedDiagramMap.take(diagram->uid());
QMT_CHECK(managedDiagram);
delete managedDiagram;
diff --git a/src/libs/modelinglib/qmt/diagram_ui/diagramsmanager.h b/src/libs/modelinglib/qmt/diagram_ui/diagramsmanager.h
index f9af7636a01..226c2389a54 100644
--- a/src/libs/modelinglib/qmt/diagram_ui/diagramsmanager.h
+++ b/src/libs/modelinglib/qmt/diagram_ui/diagramsmanager.h
@@ -56,7 +56,7 @@ class QMT_EXPORT DiagramsManager : public QObject
class ManagedDiagram;
public:
- explicit DiagramsManager(QObject *parent = 0);
+ explicit DiagramsManager(QObject *parent = nullptr);
~DiagramsManager() override;
signals:
@@ -84,11 +84,11 @@ private:
void onDataChanged(const QModelIndex &topleft, const QModelIndex &bottomright);
QPointer<TreeModel> m_model;
- DiagramsViewInterface *m_diagramsView;
- DiagramController *m_diagramController;
- DiagramSceneController *m_diagramSceneController;
- StyleController *m_styleController;
- StereotypeController *m_stereotypeController;
+ DiagramsViewInterface *m_diagramsView = nullptr;
+ DiagramController *m_diagramController = nullptr;
+ DiagramSceneController *m_diagramSceneController = nullptr;
+ StyleController *m_styleController = nullptr;
+ StereotypeController *m_stereotypeController = nullptr;
QHash<Uid, ManagedDiagram *> m_diagramUidToManagedDiagramMap;
};
diff --git a/src/libs/modelinglib/qmt/diagram_ui/sceneinspector.cpp b/src/libs/modelinglib/qmt/diagram_ui/sceneinspector.cpp
index 283506cb2ae..3e3a144f1c3 100644
--- a/src/libs/modelinglib/qmt/diagram_ui/sceneinspector.cpp
+++ b/src/libs/modelinglib/qmt/diagram_ui/sceneinspector.cpp
@@ -38,8 +38,7 @@
namespace qmt {
SceneInspector::SceneInspector(QObject *parent)
- : QObject(parent),
- m_diagramsManager(nullptr)
+ : QObject(parent)
{
}
@@ -86,7 +85,7 @@ IMoveable *SceneInspector::moveable(const DElement *element, const MDiagram *dia
}
}
QMT_CHECK(false);
- return 0;
+ return nullptr;
}
IResizable *SceneInspector::resizable(const DElement *element, const MDiagram *diagram) const
@@ -102,7 +101,7 @@ IResizable *SceneInspector::resizable(const DElement *element, const MDiagram *d
}
}
QMT_CHECK(false);
- return 0;
+ return nullptr;
}
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_ui/sceneinspector.h b/src/libs/modelinglib/qmt/diagram_ui/sceneinspector.h
index 9cd964a6d9d..dcc5bed532b 100644
--- a/src/libs/modelinglib/qmt/diagram_ui/sceneinspector.h
+++ b/src/libs/modelinglib/qmt/diagram_ui/sceneinspector.h
@@ -36,7 +36,7 @@ class DiagramsManager;
class QMT_EXPORT SceneInspector : public QObject, public ISceneInspector
{
public:
- explicit SceneInspector(QObject *parent = 0);
+ explicit SceneInspector(QObject *parent = nullptr);
~SceneInspector() override;
void setDiagramsManager(DiagramsManager *diagramsManager);
@@ -47,7 +47,7 @@ public:
IResizable *resizable(const DElement *element, const MDiagram *diagram) const override;
private:
- DiagramsManager *m_diagramsManager;
+ DiagramsManager *m_diagramsManager = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramsview.cpp b/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramsview.cpp
index f878944159a..e0bce45f090 100644
--- a/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramsview.cpp
+++ b/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramsview.cpp
@@ -37,8 +37,7 @@
namespace qmt {
DiagramsView::DiagramsView(QWidget *parent)
- : QTabWidget(parent),
- m_diagramsManager(nullptr)
+ : QTabWidget(parent)
{
setTabsClosable(true);
setMovable(true);
@@ -58,7 +57,7 @@ void DiagramsView::setDiagramsManager(DiagramsManager *diagramsManager)
void DiagramsView::openDiagram(MDiagram *diagram)
{
- QMT_CHECK(diagram);
+ QMT_ASSERT(diagram, return);
DiagramView *diagramView = m_diagramViews.value(diagram->uid());
if (!diagramView) {
DiagramSceneModel *diagramSceneModel = m_diagramsManager->bindDiagramSceneModel(diagram);
@@ -128,7 +127,7 @@ MDiagram *DiagramsView::diagram(int tabIndex) const
MDiagram *DiagramsView::diagram(DiagramView *diagramView) const
{
if (!diagramView || diagramView->diagramSceneModel())
- return 0;
+ return nullptr;
return diagramView->diagramSceneModel()->diagram();
}
diff --git a/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramsview.h b/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramsview.h
index 6913957b66e..ec8cc026a4c 100644
--- a/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramsview.h
+++ b/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramsview.h
@@ -46,7 +46,7 @@ class QMT_EXPORT DiagramsView : public QTabWidget, public DiagramsViewInterface
Q_OBJECT
public:
- explicit DiagramsView(QWidget *parent = 0);
+ explicit DiagramsView(QWidget *parent = nullptr);
~DiagramsView() override;
signals:
@@ -69,7 +69,7 @@ private:
MDiagram *diagram(int tabIndex) const;
MDiagram *diagram(DiagramView * diagramView) const;
- DiagramsManager *m_diagramsManager;
+ DiagramsManager *m_diagramsManager = nullptr;
QHash<Uid, DiagramView *> m_diagramViews;
};
diff --git a/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramview.cpp b/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramview.cpp
index 16f361a1ea8..25ac120ee7b 100644
--- a/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramview.cpp
+++ b/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramview.cpp
@@ -60,10 +60,13 @@ DiagramSceneModel *DiagramView::diagramSceneModel() const
void DiagramView::setDiagramSceneModel(DiagramSceneModel *diagramSceneModel)
{
- setScene(0);
+ setScene(nullptr);
m_diagramSceneModel = diagramSceneModel;
- if (diagramSceneModel)
+ if (diagramSceneModel) {
setScene(m_diagramSceneModel->graphicsScene());
+ connect(m_diagramSceneModel, &DiagramSceneModel::sceneRectChanged,
+ this, &DiagramView::onSceneRectChanged, Qt::QueuedConnection);
+ }
}
void DiagramView::dragEnterEvent(QDragEnterEvent *event)
@@ -110,14 +113,17 @@ void DiagramView::dragMoveEvent(QDragMoveEvent *event)
void DiagramView::dropEvent(QDropEvent *event)
{
event->setDropAction(Qt::MoveAction);
+ DiagramSceneController *diagramSceneController = m_diagramSceneModel->diagramSceneController();
if (event->mimeData()->hasFormat(QLatin1String(MIME_TYPE_MODEL_ELEMENTS))) {
QDataStream dataStream(event->mimeData()->data(QLatin1String(MIME_TYPE_MODEL_ELEMENTS)));
while (dataStream.status() == QDataStream::Ok) {
QString key;
dataStream >> key;
if (!key.isEmpty()) {
- if (m_diagramSceneModel->diagramSceneController()->isAddingAllowed(Uid(key), m_diagramSceneModel->diagram()))
- m_diagramSceneModel->diagramSceneController()->addExistingModelElement(Uid(key), mapToScene(event->pos()), m_diagramSceneModel->diagram());
+ if (diagramSceneController->isAddingAllowed(Uid(key), m_diagramSceneModel->diagram())) {
+ diagramSceneController->addExistingModelElement(Uid(key), mapToScene(event->pos()),
+ m_diagramSceneModel->diagram());
+ }
}
}
event->accept();
@@ -130,7 +136,9 @@ void DiagramView::dropEvent(QDropEvent *event)
dataStream >> newElementId >> name >> stereotype;
if (!newElementId.isEmpty()) {
QPointF pos = mapToScene(event->pos());
- m_diagramSceneModel->diagramSceneController()->dropNewElement(newElementId, name, stereotype, m_diagramSceneModel->findTopmostElement(pos), pos, m_diagramSceneModel->diagram());
+ diagramSceneController->dropNewElement(
+ newElementId, name, stereotype, m_diagramSceneModel->findTopmostElement(pos),
+ pos, m_diagramSceneModel->diagram(), event->pos(), size());
}
}
event->accept();
@@ -139,4 +147,10 @@ void DiagramView::dropEvent(QDropEvent *event)
}
}
+void DiagramView::onSceneRectChanged(const QRectF &sceneRect)
+{
+ // TODO add some adjustment to all 4 sides?
+ setSceneRect(sceneRect);
+}
+
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramview.h b/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramview.h
index 3ddc1951b1a..c4a01b76d30 100644
--- a/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramview.h
+++ b/src/libs/modelinglib/qmt/diagram_widgets_ui/diagramview.h
@@ -51,6 +51,8 @@ protected:
void dropEvent(QDropEvent *event) override;
private:
+ void onSceneRectChanged(const QRectF &sceneRect);
+
QPointer<DiagramSceneModel> m_diagramSceneModel;
};
diff --git a/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.cpp b/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.cpp
index c459463bb0c..7592bc57db3 100644
--- a/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.cpp
+++ b/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.cpp
@@ -37,8 +37,7 @@
namespace qmt {
StackedDiagramsView::StackedDiagramsView(QWidget *parent)
- : QStackedWidget(parent),
- m_diagramsManager(nullptr)
+ : QStackedWidget(parent)
{
connect(this, &QStackedWidget::currentChanged, this, &StackedDiagramsView::onCurrentChanged);
}
@@ -54,7 +53,7 @@ void StackedDiagramsView::setDiagramsManager(DiagramsManager *diagramsManager)
void StackedDiagramsView::openDiagram(MDiagram *diagram)
{
- QMT_CHECK(diagram);
+ QMT_ASSERT(diagram, return);
DiagramView *diagramView = m_diagramViews.value(diagram->uid());
if (!diagramView) {
DiagramSceneModel *diagramSceneModel = m_diagramsManager->bindDiagramSceneModel(diagram);
@@ -117,7 +116,7 @@ MDiagram *StackedDiagramsView::diagram(int tabIndex) const
MDiagram *StackedDiagramsView::diagram(DiagramView *diagramView) const
{
if (!diagramView || !diagramView->diagramSceneModel())
- return 0;
+ return nullptr;
return diagramView->diagramSceneModel()->diagram();
}
diff --git a/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.h b/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.h
index d4b9eb1b3f9..36822ea245e 100644
--- a/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.h
+++ b/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.h
@@ -45,7 +45,7 @@ class QMT_EXPORT StackedDiagramsView : public QStackedWidget, public DiagramsVie
Q_OBJECT
public:
- explicit StackedDiagramsView(QWidget *parent = 0);
+ explicit StackedDiagramsView(QWidget *parent = nullptr);
~StackedDiagramsView() override;
signals:
@@ -67,7 +67,7 @@ private:
MDiagram *diagram(int tabIndex) const;
MDiagram *diagram(DiagramView * diagramView) const;
- DiagramsManager *m_diagramsManager;
+ DiagramsManager *m_diagramsManager = nullptr;
QHash<Uid, DiagramView *> m_diagramViews;
};
diff --git a/src/libs/modelinglib/qmt/document_controller/documentcontroller.cpp b/src/libs/modelinglib/qmt/document_controller/documentcontroller.cpp
index f6271ff14d3..009e16d2d15 100644
--- a/src/libs/modelinglib/qmt/document_controller/documentcontroller.cpp
+++ b/src/libs/modelinglib/qmt/document_controller/documentcontroller.cpp
@@ -91,6 +91,7 @@ DocumentController::DocumentController(QObject *parent) :
// diagram scene controller
m_diagramSceneController->setModelController(m_modelController);
m_diagramSceneController->setDiagramController(m_diagramController);
+ m_diagramSceneController->setStereotypeController(m_stereotypeController);
// config controller
m_configController->setStereotypeController(m_stereotypeController);
@@ -272,8 +273,8 @@ MDiagram *DocumentController::findOrCreateRootDiagram()
void DocumentController::createNewProject(const QString &fileName)
{
m_diagramsManager->removeAllDiagrams();
- m_treeModel->setModelController(0);
- m_modelController->setRootPackage(0);
+ m_treeModel->setModelController(nullptr);
+ m_modelController->setRootPackage(nullptr);
m_undoController->reset();
m_projectController->newProject(fileName);
@@ -285,8 +286,8 @@ void DocumentController::createNewProject(const QString &fileName)
void DocumentController::loadProject(const QString &fileName)
{
m_diagramsManager->removeAllDiagrams();
- m_treeModel->setModelController(0);
- m_modelController->setRootPackage(0);
+ m_treeModel->setModelController(nullptr);
+ m_modelController->setRootPackage(nullptr);
m_undoController->reset();
m_projectController->newProject(fileName);
diff --git a/src/libs/modelinglib/qmt/document_controller/documentcontroller.h b/src/libs/modelinglib/qmt/document_controller/documentcontroller.h
index d9a253773f9..6b4eea96760 100644
--- a/src/libs/modelinglib/qmt/document_controller/documentcontroller.h
+++ b/src/libs/modelinglib/qmt/document_controller/documentcontroller.h
@@ -56,7 +56,7 @@ class QMT_EXPORT DocumentController : public QObject
{
Q_OBJECT
public:
- explicit DocumentController(QObject *parent = 0);
+ explicit DocumentController(QObject *parent = nullptr);
~DocumentController() override;
signals:
@@ -106,18 +106,18 @@ public:
void loadProject(const QString &fileName);
private:
- ProjectController *m_projectController;
- UndoController *m_undoController;
- ModelController *m_modelController;
- DiagramController *m_diagramController;
- DiagramSceneController *m_diagramSceneController;
- StyleController *m_styleController;
- StereotypeController *m_stereotypeController;
- ConfigController *m_configController;
- TreeModel *m_treeModel;
- SortedTreeModel *m_sortedTreeModel;
- DiagramsManager *m_diagramsManager;
- SceneInspector *m_sceneInspector;
+ ProjectController *m_projectController = nullptr;
+ UndoController *m_undoController = nullptr;
+ ModelController *m_modelController = nullptr;
+ DiagramController *m_diagramController = nullptr;
+ DiagramSceneController *m_diagramSceneController = nullptr;
+ StyleController *m_styleController = nullptr;
+ StereotypeController *m_stereotypeController = nullptr;
+ ConfigController *m_configController = nullptr;
+ TreeModel *m_treeModel = nullptr;
+ SortedTreeModel *m_sortedTreeModel = nullptr;
+ DiagramsManager *m_diagramsManager = nullptr;
+ SceneInspector *m_sceneInspector = nullptr;
QScopedPointer<MContainer> m_modelClipboard;
QScopedPointer<DContainer> m_diagramClipboard;
};
diff --git a/src/libs/modelinglib/qmt/infrastructure/contextmenuaction.h b/src/libs/modelinglib/qmt/infrastructure/contextmenuaction.h
index 2f1402d4d37..eeab0d6f9cb 100644
--- a/src/libs/modelinglib/qmt/infrastructure/contextmenuaction.h
+++ b/src/libs/modelinglib/qmt/infrastructure/contextmenuaction.h
@@ -33,9 +33,9 @@ namespace qmt {
class QMT_EXPORT ContextMenuAction : public QAction
{
public:
- ContextMenuAction(const QString &label, const QString &id, QObject *parent = 0);
+ ContextMenuAction(const QString &label, const QString &id, QObject *parent = nullptr);
ContextMenuAction(const QString &label, const QString &id, const QKeySequence &shortcut,
- QObject *parent = 0);
+ QObject *parent = nullptr);
~ContextMenuAction() override;
QString id() const { return m_id; }
diff --git a/src/libs/modelinglib/qmt/infrastructure/geometryutilities.cpp b/src/libs/modelinglib/qmt/infrastructure/geometryutilities.cpp
index c3b1d47ce93..90c9d38499d 100644
--- a/src/libs/modelinglib/qmt/infrastructure/geometryutilities.cpp
+++ b/src/libs/modelinglib/qmt/infrastructure/geometryutilities.cpp
@@ -86,7 +86,7 @@ public:
bool GeometryUtilities::placeRectAtLine(const QRectF &rect, const QLineF &line, double lineOffset, double distance,
const QLineF &intersectionLine, QPointF *placement, Side *horizontalAlignedSide)
{
- QMT_CHECK(placement);
+ QMT_ASSERT(placement, return false);
QList<Candidate> candidates;
candidates << Candidate(QVector2D(rect.topRight() - rect.topLeft()), QPointF(0.0, 0.0), SideTop)
diff --git a/src/libs/modelinglib/qmt/infrastructure/geometryutilities.h b/src/libs/modelinglib/qmt/infrastructure/geometryutilities.h
index c0062aa297a..f0b4f697b0b 100644
--- a/src/libs/modelinglib/qmt/infrastructure/geometryutilities.h
+++ b/src/libs/modelinglib/qmt/infrastructure/geometryutilities.h
@@ -52,7 +52,7 @@ public:
static QLineF stretch(const QLineF &line, double p1Extension, double p2Extension);
static bool intersect(const QPolygonF &polygon, const QLineF &line,
- QPointF *intersectionPoint, QLineF *intersectionLine = 0);
+ QPointF *intersectionPoint, QLineF *intersectionLine = nullptr);
static bool placeRectAtLine(const QRectF &rect, const QLineF &line, double lineOffset,
double distance, const QLineF &intersectionLine, QPointF *placement,
Side *horizontalAlignedSide);
diff --git a/src/libs/modelinglib/qmt/infrastructure/handle.h b/src/libs/modelinglib/qmt/infrastructure/handle.h
index 261f8c7460a..0c28c3f2287 100644
--- a/src/libs/modelinglib/qmt/infrastructure/handle.h
+++ b/src/libs/modelinglib/qmt/infrastructure/handle.h
@@ -42,13 +42,13 @@ public:
Handle(const Handle<U> &rhs) : m_uid(rhs.uid()), m_target(rhs.target()) { }
bool isNull() const { return !m_uid.isValid(); }
- bool hasTarget() const { return m_target != 0; }
+ bool hasTarget() const { return m_target != nullptr; }
Uid uid() const { return m_uid; }
T *target() const { return m_target; }
void setUid(const Uid &uid)
{
- QMT_CHECK(m_target != 0 ? (m_target->uid() == uid) : true);
+ QMT_CHECK(m_target ? (m_target->uid() == uid) : true);
m_uid = uid;
}
@@ -61,14 +61,14 @@ public:
void clear()
{
m_uid = Uid();
- m_target = 0;
+ m_target = nullptr;
}
- void clearTarget() { m_target = 0; }
+ void clearTarget() { m_target = nullptr; }
private:
Uid m_uid;
- T *m_target = 0;
+ T *m_target = nullptr;
};
template<class T>
diff --git a/src/libs/modelinglib/qmt/infrastructure/handles.h b/src/libs/modelinglib/qmt/infrastructure/handles.h
index d0e4c83ea59..4b1d0e1c934 100644
--- a/src/libs/modelinglib/qmt/infrastructure/handles.h
+++ b/src/libs/modelinglib/qmt/infrastructure/handles.h
@@ -86,7 +86,7 @@ public:
bool contains(const T *t) const
{
- QMT_CHECK(t);
+ QMT_ASSERT(t, return false);
return contains(t->uid());
}
@@ -96,18 +96,18 @@ public:
if (handle.uid() == uid)
return handle.target();
}
- return 0;
+ return nullptr;
}
T *at(int index) const
{
- QMT_CHECK(index >= 0 && index < m_handleList.size());
+ QMT_ASSERT(index >= 0 && index < m_handleList.size(), return nullptr);
return m_handleList.at(index).target();
}
T *at(int index)
{
- QMT_CHECK(index >= 0 && index < m_handleList.size());
+ QMT_ASSERT(index >= 0 && index < m_handleList.size(), return nullptr);
return m_handleList.at(index);
}
@@ -124,7 +124,7 @@ public:
int indexOf(const T *t) const
{
- QMT_CHECK(t);
+ QMT_ASSERT(t, return -1);
return indexOf(t->uid());
}
@@ -164,27 +164,27 @@ public:
void add(T *t)
{
- QMT_CHECK(t);
+ QMT_ASSERT(t, return);
m_handleList.append(Handle<T>(t));
}
void insert(int beforeIndex, const Uid &uid)
{
- QMT_CHECK(beforeIndex >= 0 && beforeIndex <= m_handleList.size());
- QMT_CHECK(uid.isValid());
+ QMT_ASSERT(beforeIndex >= 0 && beforeIndex <= m_handleList.size(), return);
+ QMT_ASSERT(uid.isValid(), return);
m_handleList.insert(beforeIndex, Handle<T>(uid));
}
void insert(int beforeIndex, T *t)
{
- QMT_CHECK(beforeIndex >= 0 && beforeIndex <= m_handleList.size());
- QMT_CHECK(t);
+ QMT_ASSERT(beforeIndex >= 0 && beforeIndex <= m_handleList.size(), return);
+ QMT_ASSERT(t, return);
m_handleList.insert(beforeIndex, Handle<T>(t));
}
void remove(int index)
{
- QMT_CHECK(index >= 0 && index < size());
+ QMT_ASSERT(index >= 0 && index < size(), return);
if (m_takesOwnership) {
T *t = m_handleList.at(index).target();
m_handleList.removeAt(index);
@@ -201,13 +201,13 @@ public:
void remove(T *t)
{
- QMT_CHECK(t);
+ QMT_ASSERT(t, return);
remove(indexOf(t));
}
T * take(int index)
{
- QMT_CHECK(index >= 0 && index < size());
+ QMT_ASSERT(index >= 0 && index < size(), return nullptr);
T *t = m_handleList.at(index).target();
m_handleList.removeAt(index);
return t;
@@ -220,7 +220,7 @@ public:
T *take(T *t)
{
- QMT_CHECK(t);
+ QMT_ASSERT(t, return nullptr);
return take(indexOf(t));
}
diff --git a/src/libs/modelinglib/qmt/infrastructure/qcompressedfile.cpp b/src/libs/modelinglib/qmt/infrastructure/qcompressedfile.cpp
index 32ab6dc3eef..7853ad2341e 100644
--- a/src/libs/modelinglib/qmt/infrastructure/qcompressedfile.cpp
+++ b/src/libs/modelinglib/qmt/infrastructure/qcompressedfile.cpp
@@ -60,9 +60,9 @@ void QCompressedDevice::close()
qint64 QCompressedDevice::readData(char *data, qint64 maxlen)
{
- QMT_CHECK(m_targetDevice);
- QMT_CHECK(m_targetDevice->isOpen());
- QMT_CHECK(m_targetDevice->openMode() == QIODevice::ReadOnly);
+ QMT_ASSERT(m_targetDevice, return 0);
+ QMT_ASSERT(m_targetDevice->isOpen(), return 0);
+ QMT_ASSERT(m_targetDevice->openMode() == QIODevice::ReadOnly, return 0);
if (m_bytesInBuffer == 0) {
QByteArray compressedBuffer;
@@ -86,9 +86,9 @@ qint64 QCompressedDevice::readData(char *data, qint64 maxlen)
qint64 QCompressedDevice::writeData(const char *data, qint64 len)
{
- QMT_CHECK(m_targetDevice);
- QMT_CHECK(m_targetDevice->isOpen());
- QMT_CHECK(m_targetDevice->openMode() == QIODevice::WriteOnly);
+ QMT_ASSERT(m_targetDevice, return 0);
+ QMT_ASSERT(m_targetDevice->isOpen(), return 0);
+ QMT_ASSERT(m_targetDevice->openMode() == QIODevice::WriteOnly, return 0);
m_buffer.append(data, len);
if (m_buffer.size() > 1024*1024) {
@@ -106,8 +106,8 @@ qint64 QCompressedDevice::writeData(const char *data, qint64 len)
qint64 QCompressedDevice::flush()
{
if (openMode() == QIODevice::WriteOnly && m_buffer.size() > 0) {
- QMT_CHECK(m_targetDevice->isOpen());
- QMT_CHECK(m_targetDevice->openMode() == QIODevice::WriteOnly);
+ QMT_ASSERT(m_targetDevice->isOpen(), return 0);
+ QMT_ASSERT(m_targetDevice->openMode() == QIODevice::WriteOnly, return 0);
QByteArray compressedBuffer = qCompress(m_buffer);
int compressedLen = static_cast<int>(compressedBuffer.size());
if (m_targetDevice->write(reinterpret_cast<const char *>(&compressedLen), sizeof(int)) != sizeof(int))
diff --git a/src/libs/modelinglib/qmt/infrastructure/qcompressedfile.h b/src/libs/modelinglib/qmt/infrastructure/qcompressedfile.h
index dad4f9a5963..efe31b102dd 100644
--- a/src/libs/modelinglib/qmt/infrastructure/qcompressedfile.h
+++ b/src/libs/modelinglib/qmt/infrastructure/qcompressedfile.h
@@ -35,8 +35,8 @@ class QCompressedDevice : public QIODevice
Q_OBJECT
public:
- explicit QCompressedDevice(QObject *parent = 0);
- explicit QCompressedDevice(QIODevice *targetDevice, QObject *parent = 0);
+ explicit QCompressedDevice(QObject *parent = nullptr);
+ explicit QCompressedDevice(QIODevice *targetDevice, QObject *parent = nullptr);
~QCompressedDevice() override;
QIODevice *targetDevice() const { return m_targetDevice; }
@@ -52,7 +52,7 @@ public:
qint64 flush();
private:
- QIODevice *m_targetDevice = 0;
+ QIODevice *m_targetDevice = nullptr;
QByteArray m_buffer;
qint64 m_bytesInBuffer = 0;
qint64 m_indexInBuffer = 0;
diff --git a/src/libs/modelinglib/qmt/infrastructure/qmtassert.h b/src/libs/modelinglib/qmt/infrastructure/qmtassert.h
index c87076be257..3417671fcf5 100644
--- a/src/libs/modelinglib/qmt/infrastructure/qmtassert.h
+++ b/src/libs/modelinglib/qmt/infrastructure/qmtassert.h
@@ -27,7 +27,7 @@
#include "utils/qtcassert.h"
-// TODO extend with parameter action
#define QMT_CHECK(condition) QTC_CHECK(condition)
+#define QMT_ASSERT(condition, action) QTC_ASSERT(condition, action)
// TODO implement logging of where and what
-#define QMT_CHECK_X(condition, where, what) QTC_CHECK(condition)
+#define QMT_CHECK_X(condition, where, what) QMT_CHECK(condition)
diff --git a/src/libs/modelinglib/qmt/model/massociation.cpp b/src/libs/modelinglib/qmt/model/massociation.cpp
index 5bd833df522..79b88226d97 100644
--- a/src/libs/modelinglib/qmt/model/massociation.cpp
+++ b/src/libs/modelinglib/qmt/model/massociation.cpp
@@ -31,8 +31,6 @@
namespace qmt {
MAssociationEnd::MAssociationEnd()
- : m_kind(Association),
- m_isNavigable(false)
{
}
diff --git a/src/libs/modelinglib/qmt/model/massociation.h b/src/libs/modelinglib/qmt/model/massociation.h
index 82f6bdf0c6f..cec083f4fcd 100644
--- a/src/libs/modelinglib/qmt/model/massociation.h
+++ b/src/libs/modelinglib/qmt/model/massociation.h
@@ -61,8 +61,8 @@ public:
private:
QString m_name;
QString m_cardinality;
- Kind m_kind;
- bool m_isNavigable;
+ Kind m_kind = Association;
+ bool m_isNavigable = false;
};
bool operator==(const MAssociationEnd &lhs, const MAssociationEnd &rhs);
diff --git a/src/libs/modelinglib/qmt/model/mclassmember.cpp b/src/libs/modelinglib/qmt/model/mclassmember.cpp
index 49bea877b7d..a5a5be28bbf 100644
--- a/src/libs/modelinglib/qmt/model/mclassmember.cpp
+++ b/src/libs/modelinglib/qmt/model/mclassmember.cpp
@@ -28,40 +28,10 @@
namespace qmt {
MClassMember::MClassMember(MemberType memberType)
- : m_visibility(VisibilityUndefined),
- m_memberType(memberType)
+ : m_memberType(memberType)
{
}
-MClassMember::MClassMember(const MClassMember &rhs)
- : m_uid(rhs.m_uid),
- m_stereotypes(rhs.m_stereotypes),
- m_group(rhs.m_group),
- m_declaration(rhs.m_declaration),
- m_visibility(rhs.m_visibility),
- m_memberType(rhs.m_memberType),
- m_properties(rhs.m_properties)
-{
-}
-
-MClassMember::~MClassMember()
-{
-}
-
-MClassMember &MClassMember::operator=(const MClassMember &rhs)
-{
- if (this != &rhs) {
- m_uid = rhs.m_uid;
- m_stereotypes = rhs.m_stereotypes;
- m_group = rhs.m_group;
- m_declaration = rhs.m_declaration;
- m_visibility = rhs.m_visibility;
- m_memberType = rhs.m_memberType;
- m_properties = rhs.m_properties;
- }
- return *this;
-}
-
void MClassMember::setUid(const Uid &uid)
{
m_uid = uid;
diff --git a/src/libs/modelinglib/qmt/model/mclassmember.h b/src/libs/modelinglib/qmt/model/mclassmember.h
index 99acb8d2ae1..9b530b0e337 100644
--- a/src/libs/modelinglib/qmt/model/mclassmember.h
+++ b/src/libs/modelinglib/qmt/model/mclassmember.h
@@ -69,10 +69,6 @@ public:
Q_DECLARE_FLAGS(Properties, Property)
explicit MClassMember(MemberType memberType = MemberUndefined);
- MClassMember(const MClassMember &rhs);
- ~MClassMember();
-
- MClassMember &operator=(const MClassMember &rhs);
Uid uid() const { return m_uid; }
void setUid(const Uid &uid);
@@ -95,8 +91,8 @@ private:
QList<QString> m_stereotypes;
QString m_group;
QString m_declaration;
- Visibility m_visibility;
- MemberType m_memberType;
+ Visibility m_visibility = VisibilityUndefined;
+ MemberType m_memberType = MemberUndefined;
Properties m_properties;
};
diff --git a/src/libs/modelinglib/qmt/model/mconnection.cpp b/src/libs/modelinglib/qmt/model/mconnection.cpp
new file mode 100644
index 00000000000..2d8ab6c2c33
--- /dev/null
+++ b/src/libs/modelinglib/qmt/model/mconnection.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Jochen Becher
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "mconnection.h"
+
+#include "mvisitor.h"
+#include "mconstvisitor.h"
+
+namespace qmt {
+
+MConnectionEnd::MConnectionEnd()
+{
+}
+
+MConnectionEnd::MConnectionEnd(const MConnectionEnd &rhs)
+ : m_name(rhs.name()),
+ m_cardinality(rhs.m_cardinality),
+ m_isNavigable(rhs.m_isNavigable)
+{
+}
+
+MConnectionEnd::~MConnectionEnd()
+{
+}
+
+MConnectionEnd &MConnectionEnd::operator=(const MConnectionEnd &rhs)
+{
+ if (this != &rhs) {
+ m_name = rhs.m_name;
+ m_cardinality = rhs.m_cardinality;
+ m_isNavigable = rhs.m_isNavigable;
+ }
+ return *this;
+}
+
+void MConnectionEnd::setName(const QString &name)
+{
+ m_name = name;
+}
+
+void MConnectionEnd::setCardinality(const QString &cardinality)
+{
+ m_cardinality = cardinality;
+}
+
+void MConnectionEnd::setNavigable(bool navigable)
+{
+ m_isNavigable = navigable;
+}
+
+bool operator==(const MConnectionEnd &lhs, const MConnectionEnd &rhs)
+{
+ return lhs.name() == rhs.name()
+ && lhs.cardinality() == rhs.cardinality()
+ && lhs.isNavigable() == rhs.isNavigable();
+}
+
+MConnection::MConnection()
+ : MRelation()
+{
+}
+
+MConnection::~MConnection()
+{
+}
+
+void MConnection::setCustomRelationId(const QString &customRelationId)
+{
+ m_customRelationId = customRelationId;
+}
+
+void MConnection::setEndA(const MConnectionEnd &end)
+{
+ m_endA = end;
+}
+
+void MConnection::setEndB(const MConnectionEnd &end)
+{
+ m_endB = end;
+}
+
+void MConnection::accept(MVisitor *visitor)
+{
+ visitor->visitMConnection(this);
+}
+
+void MConnection::accept(MConstVisitor *visitor) const
+{
+ visitor->visitMConnection(this);
+}
+
+} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model/mconnection.h b/src/libs/modelinglib/qmt/model/mconnection.h
new file mode 100644
index 00000000000..2fe10fcbc51
--- /dev/null
+++ b/src/libs/modelinglib/qmt/model/mconnection.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Jochen Becher
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "mrelation.h"
+#include "qmt/infrastructure/handle.h"
+
+#include <QString>
+
+namespace qmt {
+
+class QMT_EXPORT MConnectionEnd
+{
+public:
+ MConnectionEnd();
+ MConnectionEnd(const MConnectionEnd &rhs);
+ ~MConnectionEnd();
+
+ MConnectionEnd &operator=(const MConnectionEnd &rhs);
+
+ QString name() const { return m_name; }
+ void setName(const QString &name);
+ QString cardinality() const { return m_cardinality; }
+ void setCardinality(const QString &cardinality);
+ bool isNavigable() const { return m_isNavigable; }
+ void setNavigable(bool navigable);
+
+private:
+ QString m_name;
+ QString m_cardinality;
+ bool m_isNavigable = false;
+};
+
+bool operator==(const MConnectionEnd &lhs, const MConnectionEnd &rhs);
+inline bool operator!=(const MConnectionEnd &lhs, const MConnectionEnd &rhs)
+{
+ return !(lhs == rhs);
+}
+
+class QMT_EXPORT MConnection : public MRelation
+{
+public:
+ MConnection();
+ ~MConnection() override;
+
+ QString customRelationId() const { return m_customRelationId; }
+ void setCustomRelationId(const QString &customRelationId);
+ MConnectionEnd endA() const { return m_endA; }
+ void setEndA(const MConnectionEnd &end);
+ MConnectionEnd endB() const { return m_endB; }
+ void setEndB(const MConnectionEnd &end);
+
+ void accept(MVisitor *visitor) override;
+ void accept(MConstVisitor *visitor) const override;
+
+private:
+ QString m_customRelationId;
+ MConnectionEnd m_endA;
+ MConnectionEnd m_endB;
+};
+
+} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model/mconstvisitor.h b/src/libs/modelinglib/qmt/model/mconstvisitor.h
index fcfa9665fc2..5ef7182726f 100644
--- a/src/libs/modelinglib/qmt/model/mconstvisitor.h
+++ b/src/libs/modelinglib/qmt/model/mconstvisitor.h
@@ -41,6 +41,7 @@ class MRelation;
class MDependency;
class MInheritance;
class MAssociation;
+class MConnection;
class MConstVisitor
{
@@ -59,6 +60,7 @@ public:
virtual void visitMDependency(const MDependency *dependency) = 0;
virtual void visitMInheritance(const MInheritance *inheritance) = 0;
virtual void visitMAssociation(const MAssociation *association) = 0;
+ virtual void visitMConnection(const MConnection *connection) = 0;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model/mdependency.cpp b/src/libs/modelinglib/qmt/model/mdependency.cpp
index d0b4bf0cb57..72567be748d 100644
--- a/src/libs/modelinglib/qmt/model/mdependency.cpp
+++ b/src/libs/modelinglib/qmt/model/mdependency.cpp
@@ -31,8 +31,6 @@
namespace qmt {
MDependency::MDependency()
- : MRelation(),
- m_direction(AToB)
{
}
diff --git a/src/libs/modelinglib/qmt/model/mdependency.h b/src/libs/modelinglib/qmt/model/mdependency.h
index f2754c4f9c8..1d5d31aa5bb 100644
--- a/src/libs/modelinglib/qmt/model/mdependency.h
+++ b/src/libs/modelinglib/qmt/model/mdependency.h
@@ -57,7 +57,7 @@ public:
void accept(MConstVisitor *visitor) const override;
private:
- Direction m_direction;
+ Direction m_direction = AToB;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model/mdiagram.cpp b/src/libs/modelinglib/qmt/model/mdiagram.cpp
index 22206095985..7f9d7e87896 100644
--- a/src/libs/modelinglib/qmt/model/mdiagram.cpp
+++ b/src/libs/modelinglib/qmt/model/mdiagram.cpp
@@ -71,7 +71,7 @@ DElement *MDiagram::findDiagramElement(const Uid &key) const
if (element->uid() == key)
return element;
}
- return 0;
+ return nullptr;
}
void MDiagram::setDiagramElements(const QList<DElement *> &elements)
@@ -81,21 +81,21 @@ void MDiagram::setDiagramElements(const QList<DElement *> &elements)
void MDiagram::addDiagramElement(DElement *element)
{
- QMT_CHECK(element);
+ QMT_ASSERT(element, return);
m_elements.append(element);
}
void MDiagram::insertDiagramElement(int beforeElement, DElement *element)
{
- QMT_CHECK(beforeElement >= 0 && beforeElement <= m_elements.size());
+ QMT_ASSERT(beforeElement >= 0 && beforeElement <= m_elements.size(), return);
m_elements.insert(beforeElement, element);
}
void MDiagram::removeDiagramElement(int index)
{
- QMT_CHECK(index >= 0 && index < m_elements.size());
+ QMT_ASSERT(index >= 0 && index < m_elements.size(), return);
delete m_elements.at(index);
m_elements.removeAt(index);
@@ -103,7 +103,7 @@ void MDiagram::removeDiagramElement(int index)
void MDiagram::removeDiagramElement(DElement *element)
{
- QMT_CHECK(element);
+ QMT_ASSERT(element, return);
removeDiagramElement(m_elements.indexOf(element));
}
diff --git a/src/libs/modelinglib/qmt/model/melement.h b/src/libs/modelinglib/qmt/model/melement.h
index b83b5bd9805..7707399fbb2 100644
--- a/src/libs/modelinglib/qmt/model/melement.h
+++ b/src/libs/modelinglib/qmt/model/melement.h
@@ -81,10 +81,10 @@ public:
private:
Uid m_uid;
- MObject *m_owner = 0;
- MExpansion *m_expansion = 0;
+ MObject *m_owner = nullptr;
+ MExpansion *m_expansion = nullptr;
QList<QString> m_stereotypes;
- Flags m_flags = 0;
+ Flags m_flags;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(MElement::Flags)
diff --git a/src/libs/modelinglib/qmt/model/mitem.cpp b/src/libs/modelinglib/qmt/model/mitem.cpp
index 3eb766fa3b9..ada6be5fc09 100644
--- a/src/libs/modelinglib/qmt/model/mitem.cpp
+++ b/src/libs/modelinglib/qmt/model/mitem.cpp
@@ -31,9 +31,6 @@
namespace qmt {
MItem::MItem()
- : MObject(),
- m_isVarietyEditable(true),
- m_isShapeEditable(false)
{
}
diff --git a/src/libs/modelinglib/qmt/model/mitem.h b/src/libs/modelinglib/qmt/model/mitem.h
index ebedea5efe8..e60efde215c 100644
--- a/src/libs/modelinglib/qmt/model/mitem.h
+++ b/src/libs/modelinglib/qmt/model/mitem.h
@@ -47,8 +47,8 @@ public:
private:
QString m_variety;
- bool m_isVarietyEditable;
- bool m_isShapeEditable;
+ bool m_isVarietyEditable = true;
+ bool m_isShapeEditable = false;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model/mobject.cpp b/src/libs/modelinglib/qmt/model/mobject.cpp
index 583335e96e7..1d5f7dc96cc 100644
--- a/src/libs/modelinglib/qmt/model/mobject.cpp
+++ b/src/libs/modelinglib/qmt/model/mobject.cpp
@@ -82,8 +82,8 @@ void MObject::addChild(const Uid &uid)
void MObject::addChild(MObject *child)
{
- QMT_CHECK(child);
- QMT_CHECK(child->owner() == 0);
+ QMT_ASSERT(child, return);
+ QMT_ASSERT(!child->owner(), return);
m_children.add(child);
child->setOwner(this);
}
@@ -95,43 +95,43 @@ void MObject::insertChild(int beforeIndex, const Uid &uid)
void MObject::insertChild(int beforeIndex, MObject *child)
{
- QMT_CHECK(child);
- QMT_CHECK(child->owner() == 0);
+ QMT_ASSERT(child, return);
+ QMT_ASSERT(!child->owner(), return);
m_children.insert(beforeIndex, child);
child->setOwner(this);
}
void MObject::removeChild(const Uid &uid)
{
- QMT_CHECK(m_children.contains(uid));
+ QMT_ASSERT(m_children.contains(uid), return);
MObject *child = m_children.find(uid);
if (child)
- child->setOwner(0);
+ child->setOwner(nullptr);
m_children.remove(uid);
}
void MObject::removeChild(MObject *child)
{
- QMT_CHECK(child);
- QMT_CHECK(m_children.contains(child));
- child->setOwner(0);
+ QMT_ASSERT(child, return);
+ QMT_ASSERT(m_children.contains(child), return);
+ child->setOwner(nullptr);
m_children.remove(child);
}
void MObject::decontrolChild(const Uid &uid)
{
- QMT_CHECK(m_children.contains(uid));
+ QMT_ASSERT(m_children.contains(uid), return);
MObject *child = m_children.find(uid);
if (child)
- child->setOwner(0);
+ child->setOwner(nullptr);
m_children.take(uid);
}
void MObject::decontrolChild(MObject *child)
{
- QMT_CHECK(child);
- QMT_CHECK(m_children.contains(child));
- child->setOwner(0);
+ QMT_ASSERT(child, return);
+ QMT_ASSERT(m_children.contains(child), return);
+ child->setOwner(nullptr);
m_children.take(child);
}
@@ -151,31 +151,31 @@ void MObject::addRelation(const Uid &uid)
void MObject::addRelation(MRelation *relation)
{
- QMT_CHECK(relation);
- QMT_CHECK(relation->owner() == 0);
+ QMT_ASSERT(relation, return);
+ QMT_ASSERT(!relation->owner(), return);
relation->setOwner(this);
m_relations.add(relation);
}
void MObject::insertRelation(int beforeIndex, MRelation *relation)
{
- QMT_CHECK(relation);
- QMT_CHECK(relation->owner() == 0);
+ QMT_ASSERT(relation, return);
+ QMT_ASSERT(!relation->owner(), return);
relation->setOwner(this);
m_relations.insert(beforeIndex, relation);
}
void MObject::removeRelation(MRelation *relation)
{
- QMT_CHECK(relation);
- relation->setOwner(0);
+ QMT_ASSERT(relation, return);
+ relation->setOwner(nullptr);
m_relations.remove(relation);
}
void MObject::decontrolRelation(MRelation *relation)
{
- QMT_CHECK(relation);
- relation->setOwner(0);
+ QMT_ASSERT(relation, return);
+ relation->setOwner(nullptr);
m_relations.take(relation);
}
diff --git a/src/libs/modelinglib/qmt/model/msourceexpansion.cpp b/src/libs/modelinglib/qmt/model/msourceexpansion.cpp
index 9a21d635e79..1d02c2811a4 100644
--- a/src/libs/modelinglib/qmt/model/msourceexpansion.cpp
+++ b/src/libs/modelinglib/qmt/model/msourceexpansion.cpp
@@ -30,8 +30,6 @@
namespace qmt {
MSourceExpansion::MSourceExpansion()
- : MExpansion(),
- m_isTransient(false)
{
}
@@ -58,7 +56,7 @@ MSourceExpansion &MSourceExpansion::operator=(const MSourceExpansion &rhs)
MSourceExpansion *MSourceExpansion::clone(const MElement &rhs) const
{
auto rightExpansion = dynamic_cast<MSourceExpansion *>(rhs.expansion());
- QMT_CHECK(rightExpansion);
+ QMT_ASSERT(rightExpansion, return nullptr);
auto expansion = new MSourceExpansion(*rightExpansion);
return expansion;
}
diff --git a/src/libs/modelinglib/qmt/model/msourceexpansion.h b/src/libs/modelinglib/qmt/model/msourceexpansion.h
index eb7c1bc3a50..a631f1ab5f4 100644
--- a/src/libs/modelinglib/qmt/model/msourceexpansion.h
+++ b/src/libs/modelinglib/qmt/model/msourceexpansion.h
@@ -47,7 +47,7 @@ public:
private:
QString m_sourceId;
- bool m_isTransient;
+ bool m_isTransient = false;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model/mvisitor.h b/src/libs/modelinglib/qmt/model/mvisitor.h
index bce52be8d05..23390a47e34 100644
--- a/src/libs/modelinglib/qmt/model/mvisitor.h
+++ b/src/libs/modelinglib/qmt/model/mvisitor.h
@@ -41,6 +41,7 @@ class MRelation;
class MDependency;
class MInheritance;
class MAssociation;
+class MConnection;
class MVisitor
{
@@ -59,6 +60,7 @@ public:
virtual void visitMDependency(MDependency *dependency) = 0;
virtual void visitMInheritance(MInheritance *inheritance) = 0;
virtual void visitMAssociation(MAssociation *association) = 0;
+ virtual void visitMConnection(MConnection *connection) = 0;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.cpp b/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.cpp
index b9edd7ff302..aed3f795f08 100644
--- a/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.cpp
+++ b/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.cpp
@@ -34,6 +34,7 @@
#include "qmt/model/mdependency.h"
#include "qmt/model/minheritance.h"
#include "qmt/model/massociation.h"
+#include "qmt/model/mconnection.h"
namespace qmt {
@@ -102,4 +103,9 @@ void MChildrenVisitor::visitMAssociation(MAssociation *association)
visitMRelation(association);
}
+void MChildrenVisitor::visitMConnection(MConnection *connection)
+{
+ visitMRelation(connection);
+}
+
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.h b/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.h
index 406febde8ee..b36fc2104f0 100644
--- a/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.h
+++ b/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.h
@@ -45,6 +45,7 @@ public:
void visitMDependency(MDependency *dependency) override;
void visitMInheritance(MInheritance *inheritance) override;
void visitMAssociation(MAssociation *association) override;
+ void visitMConnection(MConnection *connection) override;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_controller/mclonevisitor.cpp b/src/libs/modelinglib/qmt/model_controller/mclonevisitor.cpp
index 19dd6ab8e58..7231346b55f 100644
--- a/src/libs/modelinglib/qmt/model_controller/mclonevisitor.cpp
+++ b/src/libs/modelinglib/qmt/model_controller/mclonevisitor.cpp
@@ -35,6 +35,7 @@
#include "qmt/model/mitem.h"
#include "qmt/model/mrelation.h"
#include "qmt/model/massociation.h"
+#include "qmt/model/mconnection.h"
#include "qmt/model/mdependency.h"
#include "qmt/model/minheritance.h"
@@ -44,7 +45,6 @@
namespace qmt {
MCloneVisitor::MCloneVisitor()
- : m_cloned(0)
{
}
@@ -85,7 +85,7 @@ void MCloneVisitor::visitMDiagram(const MDiagram *diagram)
{
QMT_CHECK(m_cloned);
auto cloned = dynamic_cast<MDiagram *>(m_cloned);
- QMT_CHECK(cloned);
+ QMT_ASSERT(cloned, return);
foreach (const DElement *element, diagram->diagramElements()) {
DCloneDeepVisitor visitor;
element->accept(&visitor);
@@ -136,8 +136,14 @@ void MCloneVisitor::visitMAssociation(const MAssociation *association)
visitMRelation(association);
}
+void MCloneVisitor::visitMConnection(const MConnection *connection)
+{
+ if (!m_cloned)
+ m_cloned = new MConnection(*connection);
+ visitMRelation(connection);
+}
+
MCloneDeepVisitor::MCloneDeepVisitor()
- : m_cloned(0)
{
}
@@ -152,13 +158,13 @@ void MCloneDeepVisitor::visitMObject(const MObject *object)
QMT_CHECK(m_cloned);
visitMElement(object);
auto cloned = dynamic_cast<MObject *>(m_cloned);
- QMT_CHECK(cloned);
+ QMT_ASSERT(cloned, return);
foreach (const Handle<MObject> &handle, object->children()) {
if (handle.hasTarget()) {
MCloneDeepVisitor visitor;
handle.target()->accept(&visitor);
auto clonedChild = dynamic_cast<MObject *>(visitor.cloned());
- QMT_CHECK(clonedChild);
+ QMT_ASSERT(clonedChild, return);
cloned->addChild(clonedChild);
} else {
cloned->addChild(handle.uid());
@@ -169,7 +175,7 @@ void MCloneDeepVisitor::visitMObject(const MObject *object)
MCloneDeepVisitor visitor;
handle.target()->accept(&visitor);
auto clonedRelation = dynamic_cast<MRelation *>(visitor.cloned());
- QMT_CHECK(clonedRelation);
+ QMT_ASSERT(clonedRelation, return);
cloned->addRelation(clonedRelation);
} else {
cloned->addRelation(handle.uid());
@@ -202,7 +208,7 @@ void MCloneDeepVisitor::visitMDiagram(const MDiagram *diagram)
{
QMT_CHECK(m_cloned);
auto cloned = dynamic_cast<MDiagram *>(m_cloned);
- QMT_CHECK(cloned);
+ QMT_ASSERT(cloned, return);
foreach (const DElement *element, diagram->diagramElements()) {
DCloneDeepVisitor visitor;
element->accept(&visitor);
@@ -231,7 +237,7 @@ void MCloneDeepVisitor::visitMRelation(const MRelation *relation)
QMT_CHECK(m_cloned);
visitMElement(relation);
auto cloned = dynamic_cast<MRelation *>(m_cloned);
- QMT_CHECK(cloned);
+ QMT_ASSERT(cloned, return);
cloned->setEndAUid(relation->endAUid());
cloned->setEndBUid(relation->endBUid());
}
@@ -257,4 +263,11 @@ void MCloneDeepVisitor::visitMAssociation(const MAssociation *association)
visitMRelation(association);
}
+void MCloneDeepVisitor::visitMConnection(const MConnection *connection)
+{
+ if (!m_cloned)
+ m_cloned = new MConnection(*connection);
+ visitMRelation(connection);
+}
+
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_controller/mclonevisitor.h b/src/libs/modelinglib/qmt/model_controller/mclonevisitor.h
index 4d97acdd4fd..2f833bc53e6 100644
--- a/src/libs/modelinglib/qmt/model_controller/mclonevisitor.h
+++ b/src/libs/modelinglib/qmt/model_controller/mclonevisitor.h
@@ -51,9 +51,10 @@ public:
void visitMDependency(const MDependency *dependency) override;
void visitMInheritance(const MInheritance *inheritance) override;
void visitMAssociation(const MAssociation *association) override;
+ void visitMConnection(const MConnection *connection) override;
private:
- MElement *m_cloned;
+ MElement *m_cloned = nullptr;
};
class QMT_EXPORT MCloneDeepVisitor : public MConstVisitor
@@ -75,9 +76,10 @@ public:
void visitMDependency(const MDependency *dependency) override;
void visitMInheritance(const MInheritance *inheritance) override;
void visitMAssociation(const MAssociation *association) override;
+ void visitMConnection(const MConnection *connection) override;
private:
- MElement *m_cloned;
+ MElement *m_cloned = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_controller/mflatassignmentvisitor.cpp b/src/libs/modelinglib/qmt/model_controller/mflatassignmentvisitor.cpp
index 424dca860d9..8f47337e51b 100644
--- a/src/libs/modelinglib/qmt/model_controller/mflatassignmentvisitor.cpp
+++ b/src/libs/modelinglib/qmt/model_controller/mflatassignmentvisitor.cpp
@@ -34,6 +34,7 @@
#include "qmt/model/mdependency.h"
#include "qmt/model/minheritance.h"
#include "qmt/model/massociation.h"
+#include "qmt/model/mconnection.h"
namespace qmt {
@@ -54,7 +55,7 @@ void MFlatAssignmentVisitor::visitMObject(const MObject *object)
{
visitMElement(object);
auto targetObject = dynamic_cast<MObject *>(m_target);
- QMT_CHECK(targetObject);
+ QMT_ASSERT(targetObject, return);
targetObject->setName(object->name());
}
@@ -67,7 +68,7 @@ void MFlatAssignmentVisitor::visitMClass(const MClass *klass)
{
visitMObject(klass);
auto targetClass = dynamic_cast<MClass *>(m_target);
- QMT_CHECK(targetClass);
+ QMT_ASSERT(targetClass, return);
targetClass->setUmlNamespace(klass->umlNamespace());
targetClass->setTemplateParameters(klass->templateParameters());
targetClass->setMembers(klass->members());
@@ -82,7 +83,7 @@ void MFlatAssignmentVisitor::visitMDiagram(const MDiagram *diagram)
{
visitMObject(diagram);
auto targetDiagram = dynamic_cast<MDiagram *>(m_target);
- QMT_CHECK(targetDiagram);
+ QMT_ASSERT(targetDiagram, return);
targetDiagram->setToolbarId(diagram->toolbarId());
}
@@ -95,7 +96,7 @@ void MFlatAssignmentVisitor::visitMItem(const MItem *item)
{
visitMObject(item);
auto targetItem = dynamic_cast<MItem *>(m_target);
- QMT_CHECK(targetItem);
+ QMT_ASSERT(targetItem, return);
targetItem->setVarietyEditable(item->isVarietyEditable());
targetItem->setVariety(item->variety());
targetItem->setShapeEditable(item->isShapeEditable());
@@ -105,7 +106,7 @@ void MFlatAssignmentVisitor::visitMRelation(const MRelation *relation)
{
visitMElement(relation);
auto targetRelation = dynamic_cast<MRelation *>(m_target);
- QMT_CHECK(targetRelation);
+ QMT_ASSERT(targetRelation, return);
targetRelation->setName(relation->name());
targetRelation->setEndAUid(relation->endAUid());
targetRelation->setEndBUid(relation->endBUid());
@@ -115,7 +116,7 @@ void MFlatAssignmentVisitor::visitMDependency(const MDependency *dependency)
{
visitMRelation(dependency);
auto targetDependency = dynamic_cast<MDependency *>(m_target);
- QMT_CHECK(targetDependency);
+ QMT_ASSERT(targetDependency, return);
targetDependency->setDirection(dependency->direction());
}
@@ -128,9 +129,20 @@ void MFlatAssignmentVisitor::visitMAssociation(const MAssociation *association)
{
visitMRelation(association);
auto targetAssociation = dynamic_cast<MAssociation *>(m_target);
- QMT_CHECK(targetAssociation);
+ QMT_ASSERT(targetAssociation, return);
targetAssociation->setEndA(association->endA());
targetAssociation->setEndB(association->endB());
+ // TODO assign association class UID?
+}
+
+void MFlatAssignmentVisitor::visitMConnection(const MConnection *connection)
+{
+ visitMRelation(connection);
+ auto targetConnection = dynamic_cast<MConnection *>(m_target);
+ QMT_ASSERT(targetConnection, return);
+ targetConnection->setCustomRelationId(connection->customRelationId());
+ targetConnection->setEndA(connection->endA());
+ targetConnection->setEndB(connection->endB());
}
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_controller/mflatassignmentvisitor.h b/src/libs/modelinglib/qmt/model_controller/mflatassignmentvisitor.h
index 49d696fd925..6794ac68dc9 100644
--- a/src/libs/modelinglib/qmt/model_controller/mflatassignmentvisitor.h
+++ b/src/libs/modelinglib/qmt/model_controller/mflatassignmentvisitor.h
@@ -49,9 +49,10 @@ public:
void visitMDependency(const MDependency *dependency) override;
void visitMInheritance(const MInheritance *inheritance) override;
void visitMAssociation(const MAssociation *association) override;
+ void visitMConnection(const MConnection *connection) override;
private:
- MElement *m_target;
+ MElement *m_target = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_controller/modelcontroller.cpp b/src/libs/modelinglib/qmt/model_controller/modelcontroller.cpp
index 9257e149b30..fc3072da27f 100644
--- a/src/libs/modelinglib/qmt/model_controller/modelcontroller.cpp
+++ b/src/libs/modelinglib/qmt/model_controller/modelcontroller.cpp
@@ -49,7 +49,7 @@ public:
Uid m_elementKey;
Uid m_ownerKey;
int m_indexOfElement = -1;
- MElement *m_clonedElement = 0;
+ MElement *m_clonedElement = nullptr;
};
class ModelController::UpdateObjectCommand : public UndoCommand
@@ -99,7 +99,7 @@ private:
void assign()
{
MObject *object = m_modelController->findObject<MObject>(m_object->uid());
- QMT_CHECK(object);
+ QMT_ASSERT(object, return);
int row = 0;
MObject *parent = object->owner();
if (!parent) {
@@ -121,8 +121,8 @@ private:
m_modelController->verifyModelIntegrity();
}
- ModelController *m_modelController = 0;
- MObject *m_object = 0;
+ ModelController *m_modelController = nullptr;
+ MObject *m_object = nullptr;
};
class ModelController::UpdateRelationCommand :
@@ -173,9 +173,9 @@ private:
void assign()
{
MRelation *relation = m_modelController->findRelation<MRelation>(m_relation->uid());
- QMT_CHECK(relation);
+ QMT_ASSERT(relation, return);
MObject *owner = relation->owner();
- QMT_CHECK(owner);
+ QMT_ASSERT(owner, return);
int row = owner->relations().indexOf(relation);
emit m_modelController->beginUpdateRelation(row, owner);
MCloneVisitor cloneVisitor;
@@ -191,8 +191,8 @@ private:
m_modelController->verifyModelIntegrity();
}
- ModelController *m_modelController = 0;
- MRelation *m_relation = 0;
+ ModelController *m_modelController = nullptr;
+ MRelation *m_relation = nullptr;
};
class ModelController::AddElementsCommand : public UndoCommand
@@ -226,10 +226,10 @@ public:
bool inserted = false;
for (int i = m_clonedElements.count() - 1; i >= 0; --i) {
Clone &clone = m_clonedElements[i];
- QMT_CHECK(clone.m_clonedElement);
+ QMT_ASSERT(clone.m_clonedElement, return);
QMT_CHECK(clone.m_clonedElement->uid() == clone.m_elementKey);
MObject *owner = m_modelController->findObject<MObject>(clone.m_ownerKey);
- QMT_CHECK(owner);
+ QMT_ASSERT(owner, return);
QMT_CHECK(clone.m_indexOfElement >= 0);
switch (clone.m_elementType) {
case TypeObject:
@@ -239,7 +239,7 @@ public:
QMT_CHECK(object);
m_modelController->mapObject(object);
owner->insertChild(clone.m_indexOfElement, object);
- clone.m_clonedElement = 0;
+ clone.m_clonedElement = nullptr;
emit m_modelController->endInsertObject(clone.m_indexOfElement, owner);
inserted = true;
break;
@@ -251,7 +251,7 @@ public:
QMT_CHECK(relation);
m_modelController->mapRelation(relation);
owner->insertRelation(clone.m_indexOfElement, relation);
- clone.m_clonedElement = 0;
+ clone.m_clonedElement = nullptr;
emit m_modelController->endInsertRelation(clone.m_indexOfElement, owner);
inserted = true;
break;
@@ -275,12 +275,12 @@ public:
Clone &clone = m_clonedElements[i];
QMT_CHECK(!clone.m_clonedElement);
MObject *owner = m_modelController->findObject<MObject>(clone.m_ownerKey);
- QMT_CHECK(owner);
+ QMT_ASSERT(owner, return);
switch (clone.m_elementType) {
case TypeObject:
{
MObject *object = m_modelController->findObject<MObject>(clone.m_elementKey);
- QMT_CHECK(object);
+ QMT_ASSERT(object, return);
clone.m_indexOfElement = owner->children().indexOf(object);
QMT_CHECK(clone.m_indexOfElement >= 0);
emit m_modelController->beginRemoveObject(clone.m_indexOfElement, owner);
@@ -296,7 +296,7 @@ public:
case TypeRelation:
{
MRelation *relation = m_modelController->findRelation<MRelation>(clone.m_elementKey);
- QMT_CHECK(relation);
+ QMT_ASSERT(relation, return);
clone.m_indexOfElement = owner->relations().indexOf(relation);
QMT_CHECK(clone.m_indexOfElement >= 0);
emit m_modelController->beginRemoveRelation(clone.m_indexOfElement, owner);
@@ -321,7 +321,7 @@ public:
}
private:
- ModelController *m_modelController = 0;
+ ModelController *m_modelController = nullptr;
QList<ModelController::Clone> m_clonedElements;
};
@@ -360,7 +360,7 @@ public:
MCloneDeepVisitor visitor;
element->accept(&visitor);
clone.m_clonedElement = visitor.cloned();
- QMT_CHECK(clone.m_clonedElement);
+ QMT_ASSERT(clone.m_clonedElement, return);
m_clonedElements.append(clone);
}
@@ -372,12 +372,12 @@ public:
Clone &clone = m_clonedElements[i];
QMT_CHECK(!clone.m_clonedElement);
MObject *owner = m_modelController->findObject<MObject>(clone.m_ownerKey);
- QMT_CHECK(owner);
+ QMT_ASSERT(owner, return);
switch (clone.m_elementType) {
case TypeObject:
{
MObject *object = m_modelController->findObject<MObject>(clone.m_elementKey);
- QMT_CHECK(object);
+ QMT_ASSERT(object, return);
clone.m_indexOfElement = owner->children().indexOf(object);
QMT_CHECK(clone.m_indexOfElement >= 0);
emit m_modelController->beginRemoveObject(clone.m_indexOfElement, owner);
@@ -393,7 +393,7 @@ public:
case TypeRelation:
{
MRelation *relation = m_modelController->findRelation<MRelation>(clone.m_elementKey);
- QMT_CHECK(relation);
+ QMT_ASSERT(relation, return);
clone.m_indexOfElement = owner->relations().indexOf(relation);
QMT_CHECK(clone.m_indexOfElement >= 0);
emit m_modelController->beginRemoveRelation(clone.m_indexOfElement, owner);
@@ -423,9 +423,9 @@ public:
bool inserted = false;
for (int i = m_clonedElements.count() - 1; i >= 0; --i) {
Clone &clone = m_clonedElements[i];
- QMT_CHECK(clone.m_clonedElement);
+ QMT_ASSERT(clone.m_clonedElement, return);
MObject *owner = m_modelController->findObject<MObject>(clone.m_ownerKey);
- QMT_CHECK(owner);
+ QMT_ASSERT(owner, return);
QMT_CHECK(clone.m_indexOfElement >= 0);
switch (clone.m_elementType) {
case TypeObject:
@@ -435,7 +435,7 @@ public:
QMT_CHECK(object);
m_modelController->mapObject(object);
owner->insertChild(clone.m_indexOfElement, object);
- clone.m_clonedElement = 0;
+ clone.m_clonedElement = nullptr;
emit m_modelController->endInsertObject(clone.m_indexOfElement, owner);
inserted = true;
break;
@@ -447,7 +447,7 @@ public:
QMT_CHECK(relation);
m_modelController->mapRelation(relation);
owner->insertRelation(clone.m_indexOfElement, relation);
- clone.m_clonedElement = 0;
+ clone.m_clonedElement = nullptr;
emit m_modelController->endInsertRelation(clone.m_indexOfElement, owner);
inserted = true;
break;
@@ -464,7 +464,7 @@ public:
}
private:
- ModelController *m_modelController = 0;
+ ModelController *m_modelController = nullptr;
QList<ModelController::Clone> m_clonedElements;
};
@@ -502,12 +502,13 @@ private:
void swap()
{
MObject *object = m_modelController->findObject(m_objectKey);
- QMT_CHECK(object);
+ QMT_ASSERT(object, return);
MObject *formerOwner = object->owner();
int formerRow = formerOwner->children().indexOf(object);
+ MObject *newOwner = m_modelController->findObject(m_ownerKey);
+ QMT_ASSERT(newOwner, return);
emit m_modelController->beginMoveObject(formerRow, formerOwner);
formerOwner->decontrolChild(object);
- MObject *newOwner = m_modelController->findObject(m_ownerKey);
newOwner->insertChild(m_indexOfElement, object);
int newRow = m_indexOfElement;
m_ownerKey = formerOwner->uid();
@@ -517,7 +518,7 @@ private:
m_modelController->verifyModelIntegrity();
}
- ModelController *m_modelController = 0;
+ ModelController *m_modelController = nullptr;
Uid m_objectKey;
Uid m_ownerKey;
int m_indexOfElement = -1;
@@ -557,12 +558,13 @@ private:
void swap()
{
MRelation *relation = m_modelController->findRelation(m_relationKey);
- QMT_CHECK(relation);
+ QMT_ASSERT(relation, return);
MObject *formerOwner = relation->owner();
int formerRow = formerOwner->relations().indexOf(relation);
+ MObject *newOwner = m_modelController->findObject(m_ownerKey);
+ QMT_ASSERT(newOwner, return);
emit m_modelController->beginMoveRelation(formerRow, formerOwner);
formerOwner->decontrolRelation(relation);
- MObject *newOwner = m_modelController->findObject(m_ownerKey);
newOwner->insertRelation(m_indexOfElement, relation);
int newRow = m_indexOfElement;
m_ownerKey = formerOwner->uid();
@@ -572,17 +574,14 @@ private:
m_modelController->verifyModelIntegrity();
}
- ModelController *m_modelController = 0;
+ ModelController *m_modelController = nullptr;
Uid m_relationKey;
Uid m_ownerKey;
int m_indexOfElement = -1;
};
ModelController::ModelController(QObject *parent)
- : QObject(parent),
- m_rootPackage(0),
- m_undoController(0),
- m_isResettingModel(false)
+ : QObject(parent)
{
}
@@ -607,7 +606,7 @@ void ModelController::setUndoController(UndoController *undoController)
Uid ModelController::ownerKey(const MElement *element) const
{
- QMT_CHECK(element);
+ QMT_ASSERT(element, return Uid());
MObject *owner = element->owner();
if (!owner)
return Uid();
@@ -620,7 +619,7 @@ MElement *ModelController::findElement(const Uid &key)
return object;
else if (MRelation *relation = findRelation(key))
return relation;
- return 0;
+ return nullptr;
}
void ModelController::startResetModel()
@@ -647,7 +646,7 @@ MObject *ModelController::object(int row, const MObject *owner) const
QMT_CHECK(row == 0);
return m_rootPackage;
}
- QMT_CHECK(row >= 0 && row < owner->children().size());
+ QMT_ASSERT(row >= 0 && row < owner->children().size(), return nullptr);
return owner->children().at(row);
}
@@ -658,8 +657,8 @@ MObject *ModelController::findObject(const Uid &key) const
void ModelController::addObject(MPackage *parentPackage, MObject *object)
{
- QMT_CHECK(parentPackage);
- QMT_CHECK(object);
+ QMT_ASSERT(parentPackage, return);
+ QMT_ASSERT(object, return);
int row = parentPackage->children().size();
if (!m_isResettingModel)
emit beginInsertObject(row, parentPackage);
@@ -679,12 +678,12 @@ void ModelController::addObject(MPackage *parentPackage, MObject *object)
void ModelController::removeObject(MObject *object)
{
- QMT_CHECK(object);
+ QMT_ASSERT(object, return);
if (m_undoController)
m_undoController->beginMergeSequence(tr("Delete Object"));
removeRelatedRelations(object);
// remove object
- QMT_CHECK(object->owner());
+ QMT_ASSERT(object->owner(), return);
int row = object->owner()->children().indexOf(object);
MObject *owner = object->owner();
if (!m_isResettingModel)
@@ -707,7 +706,7 @@ void ModelController::removeObject(MObject *object)
void ModelController::startUpdateObject(MObject *object)
{
- QMT_CHECK(object);
+ QMT_ASSERT(object, return);
int row = 0;
MObject *parent = object->owner();
if (!parent) {
@@ -725,7 +724,7 @@ void ModelController::startUpdateObject(MObject *object)
void ModelController::finishUpdateObject(MObject *object, bool cancelled)
{
- QMT_CHECK(object);
+ QMT_ASSERT(object, return);
int row = 0;
MObject *parent = object->owner();
@@ -752,9 +751,9 @@ void ModelController::finishUpdateObject(MObject *object, bool cancelled)
void ModelController::moveObject(MPackage *newOwner, MObject *object)
{
- QMT_CHECK(newOwner);
- QMT_CHECK(object);
- QMT_CHECK(object != m_rootPackage);
+ QMT_ASSERT(newOwner, return);
+ QMT_ASSERT(object, return);
+ QMT_ASSERT(object != m_rootPackage, return);
// verify that newOwner is not a child of object
MObject *newOwnerObject = newOwner;
@@ -766,7 +765,7 @@ void ModelController::moveObject(MPackage *newOwner, MObject *object)
if (newOwner != object->owner()) {
int formerRow = 0;
MObject *formerOwner = object->owner();
- QMT_CHECK(formerOwner);
+ QMT_ASSERT(formerOwner, return);
formerRow = formerOwner->children().indexOf(object);
if (!m_isResettingModel)
emit beginMoveObject(formerRow, formerOwner);
@@ -792,10 +791,10 @@ MRelation *ModelController::findRelation(const Uid &key) const
void ModelController::addRelation(MObject *owner, MRelation *relation)
{
- QMT_CHECK(owner);
- QMT_CHECK(relation);
- QMT_CHECK(findObject(relation->endAUid()));
- QMT_CHECK(findObject(relation->endBUid()));
+ QMT_ASSERT(owner, return);
+ QMT_ASSERT(relation, return);
+ QMT_ASSERT(findObject(relation->endAUid()), return);
+ QMT_ASSERT(findObject(relation->endBUid()), return);
int row = owner->relations().size();
if (!m_isResettingModel)
@@ -816,9 +815,9 @@ void ModelController::addRelation(MObject *owner, MRelation *relation)
void ModelController::removeRelation(MRelation *relation)
{
- QMT_CHECK(relation);
+ QMT_ASSERT(relation, return);
MObject *owner = relation->owner();
- QMT_CHECK(owner);
+ QMT_ASSERT(owner, return);
int row = owner->relations().indexOf(relation);
if (!m_isResettingModel)
emit beginRemoveRelation(row, owner);
@@ -838,9 +837,9 @@ void ModelController::removeRelation(MRelation *relation)
void ModelController::startUpdateRelation(MRelation *relation)
{
- QMT_CHECK(relation);
+ QMT_ASSERT(relation, return);
MObject *owner = relation->owner();
- QMT_CHECK(owner);
+ QMT_ASSERT(owner, return);
if (!m_isResettingModel)
emit beginUpdateRelation(owner->relations().indexOf(relation), owner);
if (m_undoController)
@@ -849,11 +848,11 @@ void ModelController::startUpdateRelation(MRelation *relation)
void ModelController::finishUpdateRelation(MRelation *relation, bool cancelled)
{
- QMT_CHECK(relation);
- QMT_CHECK(findObject(relation->endAUid()));
- QMT_CHECK(findObject(relation->endBUid()));
+ QMT_ASSERT(relation, return);
+ QMT_ASSERT(findObject(relation->endAUid()), return);
+ QMT_ASSERT(findObject(relation->endBUid()), return);
MObject *owner = relation->owner();
- QMT_CHECK(owner);
+ QMT_ASSERT(owner, return);
if (!m_isResettingModel) {
emit endUpdateRelation(owner->relations().indexOf(relation), owner);
if (!cancelled)
@@ -864,13 +863,13 @@ void ModelController::finishUpdateRelation(MRelation *relation, bool cancelled)
void ModelController::moveRelation(MObject *newOwner, MRelation *relation)
{
- QMT_CHECK(newOwner);
- QMT_CHECK(relation);
+ QMT_ASSERT(newOwner, return);
+ QMT_ASSERT(relation, return);
if (newOwner != relation->owner()) {
int formerRow = 0;
MObject *formerOwner = relation->owner();
- QMT_CHECK(formerOwner);
+ QMT_ASSERT(formerOwner, return);
formerRow = formerOwner->relations().indexOf(relation);
if (!m_isResettingModel)
emit beginMoveRelation(formerRow, formerOwner);
@@ -891,7 +890,7 @@ void ModelController::moveRelation(MObject *newOwner, MRelation *relation)
QList<MRelation *> ModelController::findRelationsOfObject(const MObject *object) const
{
- QMT_CHECK(object);
+ QMT_ASSERT(object, return QList<MRelation *>());
return m_objectRelationsMap.values(object->uid());
}
@@ -1140,7 +1139,7 @@ MReferences ModelController::simplify(const MSelection &modelSelection)
MReferences references;
foreach (const MSelection::Index &index, modelSelection.indices()) {
MElement *element = findElement(index.elementKey());
- QMT_CHECK(element);
+ QMT_ASSERT(element, return MReferences());
// if any (grand-)parent of element is in modelSelection then ignore element
bool ignore = false;
MObject *owner = element->owner();
@@ -1166,28 +1165,28 @@ void ModelController::verifyModelIntegrity() const
{
static const bool debugModelIntegrity = false;
if (debugModelIntegrity) {
- QMT_CHECK(m_rootPackage);
+ QMT_ASSERT(m_rootPackage, return);
QHash<Uid, const MObject *> objectsMap;
QHash<Uid, const MRelation *> relationsMap;
QMultiHash<Uid, MRelation *> objectRelationsMap;
verifyModelIntegrity(m_rootPackage, &objectsMap, &relationsMap, &objectRelationsMap);
- QMT_CHECK(objectsMap.size() == m_objectsMap.size());
+ QMT_ASSERT(objectsMap.size() == m_objectsMap.size(), return);
foreach (const MObject *object, m_objectsMap) {
- QMT_CHECK(object);
- QMT_CHECK(m_objectsMap.contains(object->uid()));
- QMT_CHECK(objectsMap.contains(object->uid()));
+ QMT_ASSERT(object, return);
+ QMT_ASSERT(m_objectsMap.contains(object->uid()), return);
+ QMT_ASSERT(objectsMap.contains(object->uid()), return);
}
- QMT_CHECK(relationsMap.size() == m_relationsMap.size());
+ QMT_ASSERT(relationsMap.size() == m_relationsMap.size(), return);
foreach (const MRelation *relation, m_relationsMap) {
- QMT_CHECK(relation);
- QMT_CHECK(m_relationsMap.contains(relation->uid()));
- QMT_CHECK(relationsMap.contains(relation->uid()));
+ QMT_ASSERT(relation, return);
+ QMT_ASSERT(m_relationsMap.contains(relation->uid()), return);
+ QMT_ASSERT(relationsMap.contains(relation->uid()), return);
}
- QMT_CHECK(objectRelationsMap.size() == m_objectRelationsMap.size());
+ QMT_ASSERT(objectRelationsMap.size() == m_objectRelationsMap.size(), return);
for (auto it = m_objectRelationsMap.cbegin(); it != m_objectRelationsMap.cend(); ++it) {
- QMT_CHECK(objectRelationsMap.contains(it.key(), it.value()));
+ QMT_ASSERT(objectRelationsMap.contains(it.key(), it.value()), return);
}
}
}
@@ -1196,19 +1195,19 @@ void ModelController::verifyModelIntegrity(const MObject *object, QHash<Uid, con
QHash<Uid, const MRelation *> *relationsMap,
QMultiHash<Uid, MRelation *> *objectRelationsMap) const
{
- QMT_CHECK(object);
- QMT_CHECK(!objectsMap->contains(object->uid()));
+ QMT_ASSERT(object, return);
+ QMT_ASSERT(!objectsMap->contains(object->uid()), return);
objectsMap->insert(object->uid(), object);
foreach (const Handle<MRelation> &handle, object->relations()) {
MRelation *relation = handle.target();
if (relation) {
- QMT_CHECK(!relationsMap->contains(relation->uid()));
+ QMT_ASSERT(!relationsMap->contains(relation->uid()), return);
relationsMap->insert(relation->uid(), relation);
- QMT_CHECK(findObject(relation->endAUid()));
- QMT_CHECK(findObject(relation->endBUid()));
- QMT_CHECK(!objectRelationsMap->contains(relation->endAUid(), relation));
+ QMT_ASSERT(findObject(relation->endAUid()), return);
+ QMT_ASSERT(findObject(relation->endBUid()), return);
+ QMT_ASSERT(!objectRelationsMap->contains(relation->endAUid(), relation), return);
objectRelationsMap->insert(relation->endAUid(), relation);
- QMT_CHECK(!objectRelationsMap->contains(relation->endBUid(), relation));
+ QMT_ASSERT(!objectRelationsMap->contains(relation->endBUid(), relation), return);
objectRelationsMap->insert(relation->endBUid(), relation);
}
}
diff --git a/src/libs/modelinglib/qmt/model_controller/modelcontroller.h b/src/libs/modelinglib/qmt/model_controller/modelcontroller.h
index ccc53078a53..345d5c0ce98 100644
--- a/src/libs/modelinglib/qmt/model_controller/modelcontroller.h
+++ b/src/libs/modelinglib/qmt/model_controller/modelcontroller.h
@@ -61,7 +61,7 @@ class QMT_EXPORT ModelController : public QObject
class MoveRelationCommand;
public:
- explicit ModelController(QObject *parent = 0);
+ explicit ModelController(QObject *parent = nullptr);
~ModelController() override;
signals:
@@ -151,12 +151,12 @@ private:
QHash<Uid, const MRelation *> *relationsMap,
QMultiHash<Uid, MRelation *> *objectRelationsMap) const;
- MPackage *m_rootPackage;
- UndoController *m_undoController;
+ MPackage *m_rootPackage = nullptr;
+ UndoController *m_undoController = nullptr;
QHash<Uid, MObject *> m_objectsMap;
QHash<Uid, MRelation *> m_relationsMap;
QMultiHash<Uid, MRelation *> m_objectRelationsMap;
- bool m_isResettingModel;
+ bool m_isResettingModel = false;
QString m_oldPackageName;
};
diff --git a/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.cpp b/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.cpp
index 67e93cf6930..4e475ce3dd4 100644
--- a/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.cpp
+++ b/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.cpp
@@ -35,6 +35,7 @@
#include "qmt/model/mitem.h"
#include "qmt/model/mrelation.h"
#include "qmt/model/massociation.h"
+#include "qmt/model/mconnection.h"
#include "qmt/model/mdependency.h"
#include "qmt/model/minheritance.h"
@@ -102,6 +103,11 @@ void MVoidVisitor::visitMAssociation(MAssociation *association)
visitMRelation(association);
}
+void MVoidVisitor::visitMConnection(MConnection *connection)
+{
+ visitMRelation(connection);
+}
+
void MVoidConstVisitor::visitMElement(const MElement *element)
{
Q_UNUSED(element);
@@ -162,4 +168,9 @@ void MVoidConstVisitor::visitMAssociation(const MAssociation *association)
visitMRelation(association);
}
+void MVoidConstVisitor::visitMConnection(const MConnection *connection)
+{
+ visitMRelation(connection);
+}
+
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.h b/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.h
index 34404adbb27..ff65a861ca7 100644
--- a/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.h
+++ b/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.h
@@ -46,6 +46,7 @@ public:
void visitMDependency(MDependency *dependency) override;
void visitMInheritance(MInheritance *inheritance) override;
void visitMAssociation(MAssociation *association) override;
+ void visitMConnection(MConnection *connection) override;
};
class QMT_EXPORT MVoidConstVisitor : public MConstVisitor
@@ -63,6 +64,7 @@ public:
void visitMDependency(const MDependency *dependency) override;
void visitMInheritance(const MInheritance *inheritance) override;
void visitMAssociation(const MAssociation *association) override;
+ void visitMConnection(const MConnection *connection) override;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.h b/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.h
index fed3721768c..afc3ec0ebf4 100644
--- a/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.h
+++ b/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.h
@@ -39,7 +39,7 @@ class QMT_EXPORT SortedTreeModel : public QSortFilterProxyModel
Q_OBJECT
public:
- explicit SortedTreeModel(QObject *parent = 0);
+ explicit SortedTreeModel(QObject *parent = nullptr);
~SortedTreeModel() override;
TreeModel *treeModel() const { return m_treeModel; }
@@ -55,7 +55,7 @@ private:
void startDelayedSortTimer();
- TreeModel *m_treeModel;
+ TreeModel *m_treeModel = nullptr;
QTimer m_delayedSortTimer;
};
diff --git a/src/libs/modelinglib/qmt/model_ui/stereotypescontroller.cpp b/src/libs/modelinglib/qmt/model_ui/stereotypescontroller.cpp
index 738b0250b51..7f1493dcbcb 100644
--- a/src/libs/modelinglib/qmt/model_ui/stereotypescontroller.cpp
+++ b/src/libs/modelinglib/qmt/model_ui/stereotypescontroller.cpp
@@ -51,7 +51,7 @@ QString StereotypesController::toString(const QList<QString> &stereotypes)
bool first = true;
foreach (const QString &stereotype, stereotypes) {
if (!first)
- s += QStringLiteral(", ");
+ s += ", ";
s += stereotype;
first = false;
}
diff --git a/src/libs/modelinglib/qmt/model_ui/stereotypescontroller.h b/src/libs/modelinglib/qmt/model_ui/stereotypescontroller.h
index e7034640dfd..5395adb6cd4 100644
--- a/src/libs/modelinglib/qmt/model_ui/stereotypescontroller.h
+++ b/src/libs/modelinglib/qmt/model_ui/stereotypescontroller.h
@@ -38,7 +38,7 @@ class QMT_EXPORT StereotypesController : public QObject
Q_OBJECT
public:
- explicit StereotypesController(QObject *parent = 0);
+ explicit StereotypesController(QObject *parent = nullptr);
signals:
void parseError(const QString &stereotypes);
diff --git a/src/libs/modelinglib/qmt/model_ui/treemodel.cpp b/src/libs/modelinglib/qmt/model_ui/treemodel.cpp
index cce2ee17202..bd0bf56bc11 100644
--- a/src/libs/modelinglib/qmt/model_ui/treemodel.cpp
+++ b/src/libs/modelinglib/qmt/model_ui/treemodel.cpp
@@ -36,6 +36,7 @@
#include "qmt/model/mitem.h"
#include "qmt/model/mrelation.h"
#include "qmt/model/massociation.h"
+#include "qmt/model/mconnection.h"
#include "qmt/model/mdependency.h"
#include "qmt/model/minheritance.h"
@@ -86,7 +87,7 @@ public:
void visitMObject(const MObject *object)
{
Q_UNUSED(object);
- QMT_CHECK(m_item);
+ QMT_ASSERT(m_item, return);
m_item->setEditable(false);
}
@@ -94,7 +95,7 @@ public:
{
QMT_CHECK(!m_item);
- static QIcon icon(QStringLiteral(":/modelinglib/48x48/package.png"));
+ static QIcon icon(":/modelinglib/48x48/package.png");
m_item = new ModelItem(icon, m_treeModel->createObjectLabel(package));
m_item->setData(TreeModel::Package, TreeModel::RoleItemType);
visitMObject(package);
@@ -105,7 +106,7 @@ public:
QMT_CHECK(!m_item);
QIcon icon = m_treeModel->createIcon(StereotypeIcon::ElementClass, StyleEngine::TypeClass, klass->stereotypes(),
- QStringLiteral(":/modelinglib/48x48/class.png"));
+ ":/modelinglib/48x48/class.png");
m_item = new ModelItem(icon, m_treeModel->createObjectLabel(klass));
m_item->setData(TreeModel::Element, TreeModel::RoleItemType);
m_item->setStereotypes(klass->stereotypes());
@@ -118,7 +119,7 @@ public:
QIcon icon = m_treeModel->createIcon(StereotypeIcon::ElementComponent, StyleEngine::TypeComponent,
component->stereotypes(),
- QStringLiteral(":/modelinglib/48x48/component.png"));
+ ":/modelinglib/48x48/component.png");
m_item = new ModelItem(icon, m_treeModel->createObjectLabel(component));
m_item->setData(TreeModel::Element, TreeModel::RoleItemType);
m_item->setStereotypes(component->stereotypes());
@@ -135,7 +136,7 @@ public:
{
QMT_CHECK(!m_item);
- static QIcon icon(QStringLiteral(":/modelinglib/48x48/canvas-diagram.png"));
+ static QIcon icon(":/modelinglib/48x48/canvas-diagram.png");
m_item = new ModelItem(icon, m_treeModel->createObjectLabel(diagram));
visitMDiagram(diagram);
}
@@ -146,7 +147,7 @@ public:
QList<QString> stereotypes = item->stereotypes() << item->variety();
QIcon icon = m_treeModel->createIcon(StereotypeIcon::ElementItem, StyleEngine::TypeItem, stereotypes,
- QStringLiteral(":/modelinglib/48x48/item.png"));
+ ":/modelinglib/48x48/item.png");
m_item = new ModelItem(icon, m_treeModel->createObjectLabel(item));
m_item->setData(TreeModel::Element, TreeModel::RoleItemType);
m_item->setStereotypes(stereotypes);
@@ -156,7 +157,7 @@ public:
void visitMRelation(const MRelation *relation)
{
Q_UNUSED(relation);
- QMT_CHECK(m_item);
+ QMT_ASSERT(m_item, return);
m_item->setEditable(false);
m_item->setData(TreeModel::Relation, TreeModel::RoleItemType);
}
@@ -165,7 +166,7 @@ public:
{
QMT_CHECK(!m_item);
- static QIcon icon(QStringLiteral(":/modelinglib/48x48/dependency.png"));
+ static QIcon icon(":/modelinglib/48x48/dependency.png");
m_item = new ModelItem(icon, m_treeModel->createRelationLabel(dependency));
visitMRelation(dependency);
}
@@ -174,7 +175,7 @@ public:
{
QMT_CHECK(!m_item);
- static QIcon icon(QStringLiteral(":/modelinglib/48x48/inheritance.png"));
+ static QIcon icon(":/modelinglib/48x48/inheritance.png");
m_item = new ModelItem(icon, m_treeModel->createRelationLabel(inheritance));
visitMRelation(inheritance);
}
@@ -183,14 +184,23 @@ public:
{
QMT_CHECK(!m_item);
- static QIcon icon(QStringLiteral(":/modelinglib/48x48/association.png"));
+ static QIcon icon(":/modelinglib/48x48/association.png");
m_item = new ModelItem(icon, m_treeModel->createRelationLabel(association));
visitMRelation(association);
}
+ void visitMConnection(const MConnection *connection)
+ {
+ QMT_CHECK(!m_item);
+
+ static QIcon icon(":modelinglib/48x48/connection.ong");
+ m_item = new ModelItem(icon, m_treeModel->createRelationLabel(connection));
+ visitMRelation(connection);
+ }
+
private:
- TreeModel *m_treeModel = 0;
- TreeModel::ModelItem *m_item = 0;
+ TreeModel *m_treeModel = nullptr;
+ TreeModel::ModelItem *m_item = nullptr;
};
class TreeModel::ItemUpdater : public MConstVisitor
@@ -224,7 +234,7 @@ public:
{
if (klass->stereotypes() != m_item->stereotypes()) {
QIcon icon = m_treeModel->createIcon(StereotypeIcon::ElementClass, StyleEngine::TypeClass,
- klass->stereotypes(), QStringLiteral(":/modelinglib/48x48/class.png"));
+ klass->stereotypes(), ":/modelinglib/48x48/class.png");
m_item->setIcon(icon);
m_item->setStereotypes(klass->stereotypes());
}
@@ -236,7 +246,7 @@ public:
if (component->stereotypes() != m_item->stereotypes()) {
QIcon icon = m_treeModel->createIcon(StereotypeIcon::ElementComponent, StyleEngine::TypeComponent,
component->stereotypes(),
- QStringLiteral(":/modelinglib/48x48/component.png"));
+ ":/modelinglib/48x48/component.png");
m_item->setIcon(icon);
m_item->setStereotypes(component->stereotypes());
}
@@ -258,7 +268,7 @@ public:
QList<QString> stereotypes = item->stereotypes() << item->variety();
if (stereotypes != m_item->stereotypes()) {
QIcon icon = m_treeModel->createIcon(StereotypeIcon::ElementItem, StyleEngine::TypeItem, stereotypes,
- QStringLiteral(":/modelinglib/48x48/item.png"));
+ ":/modelinglib/48x48/item.png");
m_item->setIcon(icon);
m_item->setStereotypes(stereotypes);
}
@@ -285,12 +295,17 @@ public:
visitMRelation(association);
}
+ void visitMConnection(const MConnection *connection)
+ {
+ visitMRelation(connection);
+ }
+
private:
void updateObjectLabel(const MObject *object);
void updateRelationLabel(const MRelation *relation);
- TreeModel *m_treeModel = 0;
- TreeModel::ModelItem *m_item = 0;
+ TreeModel *m_treeModel = nullptr;
+ TreeModel::ModelItem *m_item = nullptr;
};
void TreeModel::ItemUpdater::updateObjectLabel(const MObject *object)
@@ -324,7 +339,7 @@ void TreeModel::setModelController(ModelController *modelController)
{
if (m_modelController != modelController) {
if (m_modelController)
- disconnect(m_modelController, 0, this, 0);
+ disconnect(m_modelController, nullptr, this, nullptr);
m_modelController = modelController;
if (m_modelController) {
connect(m_modelController, &ModelController::beginResetModel,
@@ -386,18 +401,18 @@ MElement *TreeModel::element(const QModelIndex &index) const
{
QMT_CHECK(index.isValid());
- MElement *element = 0;
+ MElement *element = nullptr;
QStandardItem *item = itemFromIndex(index);
if (item) {
if (item->parent()) {
auto parentModelItem = dynamic_cast<ModelItem *>(item->parent());
- QMT_CHECK(parentModelItem);
+ QMT_ASSERT(parentModelItem, return nullptr);
const MObject *parentObject = m_itemToObjectMap.value(parentModelItem);
- QMT_CHECK(parentObject);
+ QMT_ASSERT(parentObject, return nullptr);
if (parentObject) {
if (index.row() >= 0 && index.row() < parentObject->children().size()) {
element = parentObject->children().at(index.row());
- QMT_CHECK(element);
+ QMT_ASSERT(element, return nullptr);
} else if (index.row() >= parentObject->children().size()
&& index.row() < parentObject->children().size() + parentObject->relations().size()) {
element = parentObject->relations().at(index.row() - parentObject->children().size());
@@ -510,7 +525,7 @@ void TreeModel::onEndUpdateObject(int row, const MObject *parent)
auto object = dynamic_cast<MObject *>(element);
if (object) {
auto item = dynamic_cast<ModelItem *>(itemFromIndex(elementIndex));
- QMT_CHECK(item);
+ QMT_ASSERT(item, return);
ItemUpdater visitor(this, item);
element->accept(&visitor);
}
@@ -531,7 +546,7 @@ void TreeModel::onEndInsertObject(int row, const MObject *parent)
{
QMT_CHECK(m_busyState == InsertElement);
ModelItem *parentItem =m_objectToItemMap.value(parent);
- QMT_CHECK(parentItem);
+ QMT_ASSERT(parentItem, return);
MObject *object = parent->children().at(row);
ModelItem *item = createItem(object);
parentItem->insertRow(row, item);
@@ -542,13 +557,13 @@ void TreeModel::onEndInsertObject(int row, const MObject *parent)
void TreeModel::onBeginRemoveObject(int row, const MObject *parent)
{
QMT_CHECK(m_busyState == NotBusy);
+ QMT_ASSERT(parent, return);
m_busyState = RemoveElement;
- QMT_CHECK(parent);
MObject *object = parent->children().at(row);
if (object)
removeObjectFromItemMap(object);
ModelItem *parentItem = m_objectToItemMap.value(parent);
- QMT_CHECK(parentItem);
+ QMT_ASSERT(parentItem, return);
parentItem->removeRow(row);
}
@@ -563,13 +578,13 @@ void TreeModel::onEndRemoveObject(int row, const MObject *parent)
void TreeModel::onBeginMoveObject(int formerRow, const MObject *formerOwner)
{
QMT_CHECK(m_busyState == NotBusy);
+ QMT_ASSERT(formerOwner, return);
m_busyState = MoveElement;
- QMT_CHECK(formerOwner);
MObject *object = formerOwner->children().at(formerRow);
if (object)
removeObjectFromItemMap(object);
ModelItem *parentItem = m_objectToItemMap.value(formerOwner);
- QMT_CHECK(parentItem);
+ QMT_ASSERT(parentItem, return);
parentItem->removeRow(formerRow);
}
@@ -577,7 +592,7 @@ void TreeModel::onEndMoveObject(int row, const MObject *owner)
{
QMT_CHECK(m_busyState == MoveElement);
ModelItem *parentItem =m_objectToItemMap.value(owner);
- QMT_CHECK(parentItem);
+ QMT_ASSERT(parentItem, return);
MObject *object = owner->children().at(row);
ModelItem *item = createItem(object);
parentItem->insertRow(row, item);
@@ -595,12 +610,12 @@ void TreeModel::onBeginUpdateRelation(int row, const MObject *parent)
void TreeModel::onEndUpdateRelation(int row, const MObject *parent)
{
- QMT_CHECK(parent);
+ QMT_ASSERT(parent, return);
QMT_CHECK(m_busyState == UpdateRelation);
QMT_CHECK(m_objectToItemMap.contains(parent));
ModelItem *parentItem = m_objectToItemMap.value(parent);
- QMT_CHECK(parentItem);
+ QMT_ASSERT(parentItem, return);
QModelIndex parentIndex = indexFromItem(parentItem);
// reflect updated relation in standard item
@@ -611,7 +626,7 @@ void TreeModel::onEndUpdateRelation(int row, const MObject *parent)
auto relation = dynamic_cast<MRelation *>(element);
if (relation) {
auto item = dynamic_cast<ModelItem *>(itemFromIndex(elementIndex));
- QMT_CHECK(item);
+ QMT_ASSERT(item, return);
ItemUpdater visitor(this, item);
element->accept(&visitor);
}
@@ -630,10 +645,10 @@ void TreeModel::onBeginInsertRelation(int row, const MObject *parent)
void TreeModel::onEndInsertRelation(int row, const MObject *parent)
{
- QMT_CHECK(parent);
+ QMT_ASSERT(parent, return);
QMT_CHECK(m_busyState == InsertRelation);
ModelItem *parentItem =m_objectToItemMap.value(parent);
- QMT_CHECK(parentItem);
+ QMT_ASSERT(parentItem, return);
MRelation *relation = parent->relations().at(row);
ModelItem *item = createItem(relation);
parentItem->insertRow(parent->children().size() + row, item);
@@ -642,12 +657,12 @@ void TreeModel::onEndInsertRelation(int row, const MObject *parent)
void TreeModel::onBeginRemoveRelation(int row, const MObject *parent)
{
- QMT_CHECK(parent);
+ QMT_ASSERT(parent, return);
QMT_CHECK(m_busyState == NotBusy);
m_busyState = RemoveRelation;
QMT_CHECK(parent->relations().at(row));
ModelItem *parentItem = m_objectToItemMap.value(parent);
- QMT_CHECK(parentItem);
+ QMT_ASSERT(parentItem, return);
parentItem->removeRow(parent->children().size() + row);
}
@@ -662,20 +677,20 @@ void TreeModel::onEndRemoveRelation(int row, const MObject *parent)
void TreeModel::onBeginMoveRelation(int formerRow, const MObject *formerOwner)
{
QMT_CHECK(m_busyState == NotBusy);
+ QMT_ASSERT(formerOwner, return);
m_busyState = MoveElement;
- QMT_CHECK(formerOwner);
QMT_CHECK(formerOwner->relations().at(formerRow));
ModelItem *parentItem = m_objectToItemMap.value(formerOwner);
- QMT_CHECK(parentItem);
+ QMT_ASSERT(parentItem, return);
parentItem->removeRow(formerOwner->children().size() + formerRow);
}
void TreeModel::onEndMoveRelation(int row, const MObject *owner)
{
- QMT_CHECK(owner);
+ QMT_ASSERT(owner, return);
QMT_CHECK(m_busyState == MoveElement);
ModelItem *parentItem =m_objectToItemMap.value(owner);
- QMT_CHECK(parentItem);
+ QMT_ASSERT(parentItem, return);
MRelation *relation = owner->relations().at(row);
ModelItem *item = createItem(relation);
parentItem->insertRow(owner->children().size() + row, item);
@@ -688,10 +703,10 @@ void TreeModel::onRelationEndChanged(MRelation *relation, MObject *endObject)
QMT_CHECK(m_busyState == NotBusy);
MObject *parent = relation->owner();
- QMT_CHECK(parent);
+ QMT_ASSERT(parent, return);
QMT_CHECK(m_objectToItemMap.contains(parent));
ModelItem *parentItem = m_objectToItemMap.value(parent);
- QMT_CHECK(parentItem);
+ QMT_ASSERT(parentItem, return);
QModelIndex parentIndex = indexFromItem(parentItem);
int row = parent->children().size() + relation->owner()->relations().indexOf(relation);
@@ -699,7 +714,7 @@ void TreeModel::onRelationEndChanged(MRelation *relation, MObject *endObject)
QMT_CHECK(elementIndex.isValid());
auto item = dynamic_cast<ModelItem *>(itemFromIndex(elementIndex));
- QMT_CHECK(item);
+ QMT_ASSERT(item, return);
QString label = createRelationLabel(relation);
if (item->text() != label)
@@ -721,7 +736,7 @@ void TreeModel::onModelDataChanged(const QModelIndex &topleft, const QModelIndex
void TreeModel::clear()
{
QStandardItemModel::clear();
- m_rootItem = 0;
+ m_rootItem = nullptr;
m_objectToItemMap.clear();
m_itemToObjectMap.clear();
}
@@ -758,10 +773,10 @@ void TreeModel::createChildren(const MObject *parentObject, ModelItem *parentIte
void TreeModel::removeObjectFromItemMap(const MObject *object)
{
- QMT_CHECK(object);
+ QMT_ASSERT(object, return);
QMT_CHECK(m_objectToItemMap.contains(object));
ModelItem *item = m_objectToItemMap.value(object);
- QMT_CHECK(item);
+ QMT_ASSERT(item, return);
QMT_CHECK(m_itemToObjectMap.contains(item));
m_itemToObjectMap.remove(item);
m_objectToItemMap.remove(object);
@@ -773,19 +788,19 @@ void TreeModel::removeObjectFromItemMap(const MObject *object)
QString TreeModel::createObjectLabel(const MObject *object)
{
- QMT_CHECK(object);
+ QMT_ASSERT(object, return QString());
if (object->name().isEmpty()) {
if (auto item = dynamic_cast<const MItem *>(object)) {
if (!item->variety().isEmpty())
- return QString(QStringLiteral("[%1]")).arg(item->variety());
+ return QString("[%1]").arg(item->variety());
}
return tr("[unnamed]");
}
if (auto klass = dynamic_cast<const MClass *>(object)) {
if (!klass->umlNamespace().isEmpty())
- return QString(QStringLiteral("%1 [%2]")).arg(klass->name()).arg(klass->umlNamespace());
+ return QString("%1 [%2]").arg(klass->name()).arg(klass->umlNamespace());
}
return object->name();
}
@@ -795,11 +810,11 @@ QString TreeModel::createRelationLabel(const MRelation *relation)
QString name;
if (!relation->name().isEmpty()) {
name += relation->name();
- name += QStringLiteral(": ");
+ name += ": ";
}
if (MObject *endA = m_modelController->findObject(relation->endAUid()))
name += createObjectLabel(endA);
- name += QStringLiteral(" - ");
+ name += " - ";
if (MObject *endB = m_modelController->findObject(relation->endBUid()))
name += createObjectLabel(endB);
return name;
diff --git a/src/libs/modelinglib/qmt/model_ui/treemodel.h b/src/libs/modelinglib/qmt/model_ui/treemodel.h
index f3d8e167793..7e9bb0a4fc6 100644
--- a/src/libs/modelinglib/qmt/model_ui/treemodel.h
+++ b/src/libs/modelinglib/qmt/model_ui/treemodel.h
@@ -68,7 +68,7 @@ public:
RoleItemType = Qt::UserRole + 1
};
- explicit TreeModel(QObject *parent = 0);
+ explicit TreeModel(QObject *parent = nullptr);
~TreeModel() override;
ModelController *modelController() const { return m_modelController; }
diff --git a/src/libs/modelinglib/qmt/model_ui/treemodelmanager.cpp b/src/libs/modelinglib/qmt/model_ui/treemodelmanager.cpp
index a90fd546fd7..5a2711b14c6 100644
--- a/src/libs/modelinglib/qmt/model_ui/treemodelmanager.cpp
+++ b/src/libs/modelinglib/qmt/model_ui/treemodelmanager.cpp
@@ -38,9 +38,7 @@
namespace qmt {
TreeModelManager::TreeModelManager(QObject *parent) :
- QObject(parent),
- m_treeModel(nullptr),
- m_modelTreeView(nullptr)
+ QObject(parent)
{
}
@@ -70,7 +68,7 @@ bool TreeModelManager::isRootPackageSelected() const
MObject *TreeModelManager::selectedObject() const
{
- MObject *object = 0;
+ MObject *object = nullptr;
if (m_modelTreeView->currentSourceModelIndex().isValid()) {
MElement *element = m_treeModel->element(m_modelTreeView->currentSourceModelIndex());
if (element)
@@ -84,7 +82,7 @@ MPackage *TreeModelManager::selectedPackage() const
if (m_modelTreeView->currentSourceModelIndex().isValid())
{
MElement *element = m_treeModel->element(m_modelTreeView->currentSourceModelIndex());
- QMT_CHECK(element);
+ QMT_ASSERT(element, return nullptr);
if (auto package = dynamic_cast<MPackage *>(element)) {
return package;
} else if (auto object = dynamic_cast<MObject *>(element)) {
diff --git a/src/libs/modelinglib/qmt/model_ui/treemodelmanager.h b/src/libs/modelinglib/qmt/model_ui/treemodelmanager.h
index dfb604cd98d..ea5156c1171 100644
--- a/src/libs/modelinglib/qmt/model_ui/treemodelmanager.h
+++ b/src/libs/modelinglib/qmt/model_ui/treemodelmanager.h
@@ -41,7 +41,7 @@ class QMT_EXPORT TreeModelManager : public QObject
Q_OBJECT
public:
- explicit TreeModelManager(QObject *parent = 0);
+ explicit TreeModelManager(QObject *parent = nullptr);
~TreeModelManager() override;
TreeModel *treeModel() const { return m_treeModel; }
@@ -55,8 +55,8 @@ public:
MSelection selectedObjects() const;
private:
- TreeModel *m_treeModel;
- ModelTreeViewInterface *m_modelTreeView;
+ TreeModel *m_treeModel = nullptr;
+ ModelTreeViewInterface *m_modelTreeView = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.cpp
index bc9b770f569..68b63e3ac9f 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.cpp
@@ -94,10 +94,10 @@ QString ClassMembersEdit::Cursor::readWord()
} else {
if (c == QLatin1Char('<') && m_pos < m_text.length() && m_text.at(m_pos) == QLatin1Char('<')) {
++m_pos;
- word = QStringLiteral("<<");
+ word = "<<";
} else if (c == QLatin1Char('>') && m_pos < m_text.length() && m_text.at(m_pos) == QLatin1Char('>')) {
++m_pos;
- word = QStringLiteral(">>");
+ word = ">>";
} else {
word = c;
}
@@ -123,7 +123,7 @@ QString ClassMembersEdit::Cursor::readUntil(const QString &delimiter)
{
QString s;
while (m_isValid) {
- if (m_pos >= m_text.length() || m_text.at(m_pos) == QStringLiteral("\n")) {
+ if (m_pos >= m_text.length() || m_text.at(m_pos) == '\n') {
m_isValid = false;
return s;
}
@@ -154,7 +154,7 @@ void ClassMembersEdit::Cursor::skipUntilOrNewline(const QString &delimiter)
while (m_isValid) {
if (m_pos >= m_text.length())
return;
- if (m_text.at(m_pos) == QStringLiteral("\n"))
+ if (m_text.at(m_pos) == '\n')
return;
if (m_pos + delimiter.length() <= m_text.length()
&& QString::compare(m_text.mid(m_pos, delimiter.length()), delimiter, Qt::CaseInsensitive) == 0) {
@@ -183,10 +183,10 @@ QString ClassMembersEdit::Cursor::readWordFromRight()
} else {
if (c == QLatin1Char('<') && m_pos >= 0 && m_text.at(m_pos) == QLatin1Char('<')) {
--m_pos;
- word = QStringLiteral("<<");
+ word = "<<";
} else if (c == QLatin1Char('>') && m_pos >= 0 && m_text.at(m_pos) == QLatin1Char('>')) {
--m_pos;
- word = QStringLiteral(">>");
+ word = ">>";
} else {
word = c;
}
@@ -218,13 +218,13 @@ bool ClassMembersEdit::Cursor::searchOutsideOfBracketsFromRight(const QString &s
int brackets = 0;
for (;;) {
const QString word = readWordFromRight();
- if (!m_isValid || word == QStringLiteral("\n"))
+ if (!m_isValid || word == "\n")
break;
if (brackets == 0 && word == s)
return true;
- else if (word == QStringLiteral("(") || word == QStringLiteral("[") || word == QStringLiteral("{"))
+ else if (word == "(" || word == "[" || word == "{")
++brackets;
- else if (word == QStringLiteral(")") || word == QStringLiteral("]") || word == QStringLiteral("}"))
+ else if (word == ")" || word == "]" || word == "}")
--brackets;
}
m_isValid = true;
@@ -238,12 +238,12 @@ QString ClassMembersEdit::Cursor::extractSubstr(int start, int stop)
if (m_isValid && start >= 0 && start < m_text.length() && stop >= start && stop < m_text.length())
return m_text.mid(start, stop - start + 1);
m_isValid = false;
- return QStringLiteral("");
+ return QString();
}
void ClassMembersEdit::Cursor::skipWhitespaces()
{
- while (m_isValid && m_pos < m_text.length() && m_text.at(m_pos).isSpace() && m_text.at(m_pos) != QStringLiteral("\n"))
+ while (m_isValid && m_pos < m_text.length() && m_text.at(m_pos).isSpace() && m_text.at(m_pos) != '\n')
++m_pos;
if (m_pos >= m_text.length())
m_isValid = false;
@@ -251,7 +251,7 @@ void ClassMembersEdit::Cursor::skipWhitespaces()
void ClassMembersEdit::Cursor::skipWhitespacesFromRight()
{
- while (m_isValid && m_pos >= 0 && m_text.at(m_pos).isSpace() && m_text.at(m_pos) != QStringLiteral("\n"))
+ while (m_isValid && m_pos >= 0 && m_text.at(m_pos).isSpace() && m_text.at(m_pos) != '\n')
--m_pos;
if (m_pos < 0)
m_isValid = false;
@@ -378,29 +378,29 @@ QString ClassMembersEdit::build(const QList<MClassMember> &members)
case MClassMember::VisibilityUndefined:
break;
case MClassMember::VisibilityPublic:
- vis = QStringLiteral("public:");
+ vis = "public:";
break;
case MClassMember::VisibilityProtected:
- vis = QStringLiteral("protected:");
+ vis = "protected:";
break;
case MClassMember::VisibilityPrivate:
- vis = QStringLiteral("private:");
+ vis = "private:";
break;
case MClassMember::VisibilitySignals:
- vis = QStringLiteral("signals:");
+ vis = "signals:";
break;
case MClassMember::VisibilityPrivateSlots:
- vis = QStringLiteral("private slots:");
+ vis = "private slots:";
break;
case MClassMember::VisibilityProtectedSlots:
- vis = QStringLiteral("protected slots:");
+ vis = "protected slots:";
break;
case MClassMember::VisibilityPublicSlots:
- vis = QStringLiteral("public slots:");
+ vis = "public slots:";
break;
}
if (!text.isEmpty())
- text += QStringLiteral("\n");
+ text += "\n";
text += vis;
addNewline = true;
addSpace = true;
@@ -409,42 +409,42 @@ QString ClassMembersEdit::build(const QList<MClassMember> &members)
}
if (member.group() != currentGroup) {
if (addSpace)
- text += QStringLiteral(" ");
+ text += " ";
else if (!text.isEmpty())
- text += QStringLiteral("\n");
- text += QString(QStringLiteral("[%1]")).arg(member.group());
+ text += "\n";
+ text += QString("[%1]").arg(member.group());
addNewline = true;
currentGroup = member.group();
}
if (addNewline)
- text += QStringLiteral("\n");
+ text += "\n";
if (!member.stereotypes().isEmpty()) {
StereotypesController ctrl;
- text += QString(QStringLiteral("<<%1>> ")).arg(ctrl.toString(member.stereotypes()));
+ text += QString("<<%1>> ").arg(ctrl.toString(member.stereotypes()));
}
if (member.properties() & MClassMember::PropertyQsignal)
- text += QStringLiteral("signal ");
+ text += "signal ";
if (member.properties() & MClassMember::PropertyQslot)
- text += QStringLiteral("slot ");
+ text += "slot ";
if (member.properties() & MClassMember::PropertyQinvokable)
- text += QStringLiteral("invokable ");
+ text += "invokable ";
if (member.properties() & MClassMember::PropertyStatic)
- text += QStringLiteral("static ");
+ text += "static ";
if (member.properties() & MClassMember::PropertyVirtual)
- text += QStringLiteral("virtual ");
+ text += "virtual ";
if (member.properties() & MClassMember::PropertyConstexpr)
- text += QStringLiteral("constexpr ");
+ text += "constexpr ";
text += member.declaration();
if (member.properties() & MClassMember::PropertyConst)
- text += QStringLiteral(" const");
+ text += " const";
if (member.properties() & MClassMember::PropertyOverride)
- text += QStringLiteral(" override");
+ text += " override";
if (member.properties() & MClassMember::PropertyFinal)
- text += QStringLiteral(" final");
+ text += " final";
if (member.properties() & MClassMember::PropertyAbstract)
- text += QStringLiteral(" = 0");
- text += QStringLiteral(";\n");
+ text += " = 0";
+ text += ";\n";
}
return text;
@@ -452,7 +452,7 @@ QString ClassMembersEdit::build(const QList<MClassMember> &members)
QList<MClassMember> ClassMembersEdit::parse(const QString &text, bool *ok)
{
- QMT_CHECK(ok);
+ QMT_ASSERT(ok, return QList<MClassMember>());
*ok = true;
QList<MClassMember> members;
@@ -468,19 +468,19 @@ QList<MClassMember> ClassMembersEdit::parse(const QString &text, bool *ok)
member = MClassMember();
QString word = cursor.readWord().toLower();
for (;;) {
- if (word == QStringLiteral("public")) {
+ if (word == "public") {
currentVisibility = MClassMember::VisibilityPublic;
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("protected")) {
+ } else if (word == "protected") {
currentVisibility = MClassMember::VisibilityProtected;
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("private")) {
+ } else if (word == "private") {
currentVisibility = MClassMember::VisibilityPrivate;
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("signals")) {
+ } else if (word == "signals") {
currentVisibility = MClassMember::VisibilitySignals;
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("slots")) {
+ } else if (word == "slots") {
switch (currentVisibility) {
case MClassMember::VisibilityPrivate:
currentVisibility = MClassMember::VisibilityPrivateSlots;
@@ -496,34 +496,34 @@ QList<MClassMember> ClassMembersEdit::parse(const QString &text, bool *ok)
break;
}
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("[")) {
- currentGroup = cursor.readUntil(QStringLiteral("]"));
+ } else if (word == "[") {
+ currentGroup = cursor.readUntil("]");
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("<<")) {
- QString stereotypes = cursor.readUntil(QStringLiteral(">>"));
+ } else if (word == "<<") {
+ QString stereotypes = cursor.readUntil(">>");
StereotypesController ctrl;
member.setStereotypes(ctrl.fromString(stereotypes));
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("static")) {
+ } else if (word == "static") {
member.setProperties(member.properties() | MClassMember::PropertyStatic);
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("virtual")) {
+ } else if (word == "virtual") {
member.setProperties(member.properties() | MClassMember::PropertyVirtual);
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("constexpr") || word == QStringLiteral("q_decl_constexpr")
- || word == QStringLiteral("q_decl_relaxed_constexpr")) {
+ } else if (word == "constexpr" || word == "q_decl_constexpr"
+ || word == "q_decl_relaxed_constexpr") {
member.setProperties(member.properties() | MClassMember::PropertyConstexpr);
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("signal") || word == QStringLiteral("q_signal")) {
+ } else if (word == "signal" || word == "q_signal") {
member.setProperties(member.properties() | MClassMember::PropertyQsignal);
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("slot") || word == QStringLiteral("q_slot")) {
+ } else if (word == "slot" || word == "q_slot") {
member.setProperties(member.properties() | MClassMember::PropertyQslot);
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral("invokable") || word == QStringLiteral("q_invokable")) {
+ } else if (word == "invokable" || word == "q_invokable") {
member.setProperties(member.properties() | MClassMember::PropertyQinvokable);
word = cursor.readWord().toLower();
- } else if (word == QStringLiteral(":")) {
+ } else if (word == ":") {
word = cursor.readWord().toLower();
} else {
cursor.unreadWord();
@@ -532,32 +532,32 @@ QList<MClassMember> ClassMembersEdit::parse(const QString &text, bool *ok)
}
member.setVisibility(currentVisibility);
member.setGroup(currentGroup);
- if (word != QStringLiteral("\n")) {
+ if (word != "\n") {
int declarationStart = cursor.position();
- cursor.skipUntilOrNewline(QStringLiteral(";"));
+ cursor.skipUntilOrNewline(";");
int nextLinePosition = cursor.position();
cursor.setPosition(nextLinePosition - 1);
word = cursor.readWordFromRight().toLower();
- if (word != QStringLiteral(";"))
+ if (word != ";")
cursor.unreadWord();
int endPosition = cursor.position();
QString expr;
- if (cursor.searchOutsideOfBracketsFromRight(QStringLiteral("=")))
+ if (cursor.searchOutsideOfBracketsFromRight("="))
expr = cursor.extractSubstr(cursor.position() + 2, endPosition).trimmed();
word = cursor.readWordFromRight().toLower();
for (;;) {
// TODO ignore throw(), noexpect(*),
- if (word == QStringLiteral("final") || word == QStringLiteral("q_decl_final")) {
+ if (word == "final" || word == "q_decl_final") {
member.setProperties(member.properties() | MClassMember::PropertyFinal);
word = cursor.readWordFromRight().toLower();
- } else if (word == QStringLiteral("override") || word == QStringLiteral("q_decl_override")) {
+ } else if (word == "override" || word == "q_decl_override") {
member.setProperties(member.properties() | MClassMember::PropertyOverride);
word = cursor.readWordFromRight().toLower();
- } else if (word == QStringLiteral("const")) {
+ } else if (word == "const") {
member.setProperties(member.properties() | MClassMember::PropertyConst);
word = cursor.readWordFromRight().toLower();
- } else if (word == QStringLiteral("noexpect")) {
+ } else if (word == "noexpect") {
// just ignore it
word = cursor.readWordFromRight().toLower();
} else {
@@ -572,9 +572,9 @@ QList<MClassMember> ClassMembersEdit::parse(const QString &text, bool *ok)
if (!declaration.isEmpty()) {
member.setDeclaration(declaration);
// TODO recognize function pointer
- if (declaration.endsWith(QStringLiteral(")"))) {
+ if (declaration.endsWith(")")) {
member.setMemberType(MClassMember::MemberMethod);
- if (expr == QStringLiteral("0"))
+ if (expr == "0")
member.setProperties(member.properties() | MClassMember::PropertyAbstract);
} else {
member.setMemberType(MClassMember::MemberAttribute);
@@ -584,7 +584,7 @@ QList<MClassMember> ClassMembersEdit::parse(const QString &text, bool *ok)
cursor.setPosition(nextLinePosition);
if (cursor.atEnd())
return members;
- cursor.skip(QStringLiteral("\n"));
+ cursor.skip("\n");
} else {
word = cursor.readWord().toLower();
}
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.h b/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.h
index ca23702742c..f20acd96010 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.h
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/classmembersedit.h
@@ -39,7 +39,7 @@ class QMT_EXPORT ClassMembersEdit : public QPlainTextEdit
class ClassMembersEditPrivate;
public:
- explicit ClassMembersEdit(QWidget *parent = 0);
+ explicit ClassMembersEdit(QWidget *parent = nullptr);
~ClassMembersEdit() override;
signals:
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp
index f392a59e60c..37e74adeac8 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp
@@ -48,9 +48,7 @@
namespace qmt {
ModelTreeView::ModelTreeView(QWidget *parent)
- : QTreeView(parent),
- m_sortedTreeModel(nullptr),
- m_elementTasks(nullptr)
+ : QTreeView(parent)
{
setHeaderHidden(true);
setSortingEnabled(false);
@@ -113,7 +111,7 @@ void ModelTreeView::startDrag(Qt::DropActions supportedActions)
Q_UNUSED(supportedActions);
TreeModel *treeModel = m_sortedTreeModel->treeModel();
- QMT_CHECK(treeModel);
+ QMT_ASSERT(treeModel, return);
QByteArray dragData;
QDataStream dataStream(&dragData, QIODevice::WriteOnly);
@@ -140,10 +138,10 @@ void ModelTreeView::startDrag(Qt::DropActions supportedActions)
}
auto mimeData = new QMimeData;
- mimeData->setData(QStringLiteral("text/model-elements"), dragData);
+ mimeData->setData("text/model-elements", dragData);
if (dragIcon.isNull())
- dragIcon = QIcon(QStringLiteral(":/modelinglib/48x48/generic.png"));
+ dragIcon = QIcon(":/modelinglib/48x48/generic.png");
QPixmap pixmap(48, 48);
pixmap = dragIcon.pixmap(48, 48);
@@ -170,7 +168,7 @@ void ModelTreeView::dragMoveEvent(QDragMoveEvent *event)
QModelIndex dropSourceModelIndex = m_sortedTreeModel->mapToSource(dropIndex);
if (dropSourceModelIndex.isValid()) {
TreeModel *treeModel = m_sortedTreeModel->treeModel();
- QMT_CHECK(treeModel);
+ QMT_ASSERT(treeModel, return);
MElement *modelElement = treeModel->element(dropSourceModelIndex);
if (dynamic_cast<MObject*>(modelElement))
accept = true;
@@ -197,15 +195,15 @@ void ModelTreeView::dropEvent(QDropEvent *event)
{
bool accept = false;
event->setDropAction(Qt::MoveAction);
- if (event->mimeData()->hasFormat(QStringLiteral("text/model-elements"))) {
+ if (event->mimeData()->hasFormat("text/model-elements")) {
QModelIndex dropIndex = indexAt(event->pos());
QModelIndex dropSourceModelIndex = m_sortedTreeModel->mapToSource(dropIndex);
if (dropSourceModelIndex.isValid()) {
TreeModel *treeModel = m_sortedTreeModel->treeModel();
- QMT_CHECK(treeModel);
+ QMT_ASSERT(treeModel, return);
MElement *targetModelElement = treeModel->element(dropSourceModelIndex);
if (auto targetModelObject = dynamic_cast<MObject *>(targetModelElement)) {
- QDataStream dataStream(event->mimeData()->data(QStringLiteral("text/model-elements")));
+ QDataStream dataStream(event->mimeData()->data("text/model-elements"));
while (dataStream.status() == QDataStream::Ok) {
QString key;
dataStream >> key;
@@ -245,35 +243,35 @@ void ModelTreeView::contextMenuEvent(QContextMenuEvent *event)
QModelIndex sourceModelIndex = m_sortedTreeModel->mapToSource(index);
if (sourceModelIndex.isValid()) {
TreeModel *treeModel = m_sortedTreeModel->treeModel();
- QMT_CHECK(treeModel);
+ QMT_ASSERT(treeModel, return);
MElement *melement = treeModel->element(sourceModelIndex);
- QMT_CHECK(melement);
+ QMT_ASSERT(melement, return);
QMenu menu;
bool addSeparator = false;
if (m_elementTasks->hasClassDefinition(melement)) {
- menu.addAction(new ContextMenuAction(tr("Show Definition"), QStringLiteral("showDefinition"), &menu));
+ menu.addAction(new ContextMenuAction(tr("Show Definition"), "showDefinition", &menu));
addSeparator = true;
}
if (m_elementTasks->hasDiagram(melement)) {
- menu.addAction(new ContextMenuAction(tr("Open Diagram"), QStringLiteral("openDiagram"), &menu));
+ menu.addAction(new ContextMenuAction(tr("Open Diagram"), "openDiagram", &menu));
addSeparator = true;
}
if (melement->owner()) {
if (addSeparator)
menu.addSeparator();
- menu.addAction(new ContextMenuAction(tr("Delete"), QStringLiteral("delete"),
+ menu.addAction(new ContextMenuAction(tr("Delete"), "delete",
QKeySequence(Qt::CTRL + Qt::Key_D), &menu));
}
QAction *selectedAction = menu.exec(event->globalPos());
if (selectedAction) {
auto action = dynamic_cast<ContextMenuAction *>(selectedAction);
- QMT_CHECK(action);
- if (action->id() == QStringLiteral("showDefinition")) {
+ QMT_ASSERT(action, return);
+ if (action->id() == "showDefinition") {
m_elementTasks->openClassDefinition(melement);
- } else if (action->id() == QStringLiteral("openDiagram")) {
+ } else if (action->id() == "openDiagram") {
m_elementTasks->openDiagram(melement);
- } else if (action->id() == QStringLiteral("delete")) {
+ } else if (action->id() == "delete") {
MSelection selection;
selection.append(melement->uid(), melement->owner()->uid());
m_sortedTreeModel->treeModel()->modelController()->deleteElements(selection);
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.h b/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.h
index bb910bd635b..724097a3656 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.h
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.h
@@ -41,7 +41,7 @@ class QMT_EXPORT ModelTreeView : public QTreeView, public ModelTreeViewInterface
Q_OBJECT
public:
- explicit ModelTreeView(QWidget *parent = 0);
+ explicit ModelTreeView(QWidget *parent = nullptr);
~ModelTreeView() override;
signals:
@@ -67,8 +67,8 @@ protected:
void contextMenuEvent(QContextMenuEvent *event) override;
private:
- SortedTreeModel *m_sortedTreeModel;
- IElementTasks *m_elementTasks;
+ SortedTreeModel *m_sortedTreeModel = nullptr;
+ IElementTasks *m_elementTasks = nullptr;
QModelIndex m_autoDelayIndex;
QTime m_autoDelayStartTime;
};
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.cpp
index 8e48202009f..2f5f8d84874 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.cpp
@@ -35,8 +35,7 @@ namespace qmt {
PaletteBox::PaletteBox(QWidget *parent)
: QWidget(parent),
m_brushes(6),
- m_pens(6),
- m_currentIndex(-1)
+ m_pens(6)
{
setFocusPolicy(Qt::StrongFocus);
}
@@ -47,13 +46,13 @@ PaletteBox::~PaletteBox()
QBrush PaletteBox::brush(int index) const
{
- QMT_CHECK(index >= 0 && index <= m_brushes.size());
+ QMT_ASSERT(index >= 0 && index <= m_brushes.size(), return QBrush());
return m_brushes.at(index);
}
void PaletteBox::setBrush(int index, const QBrush &brush)
{
- QMT_CHECK(index >= 0 && index <= m_brushes.size());
+ QMT_ASSERT(index >= 0 && index <= m_brushes.size(), return);
if (m_brushes[index] != brush) {
m_brushes[index] = brush;
update();
@@ -62,13 +61,13 @@ void PaletteBox::setBrush(int index, const QBrush &brush)
QPen PaletteBox::linePen(int index) const
{
- QMT_CHECK(index >= 0 && index <= m_pens.size());
+ QMT_ASSERT(index >= 0 && index <= m_pens.size(), return QPen());
return m_pens.at(index);
}
void PaletteBox::setLinePen(int index, const QPen &pen)
{
- QMT_CHECK(index >= 0 && index <= m_pens.size());
+ QMT_ASSERT(index >= 0 && index <= m_pens.size(), return);
if (m_pens[index] != pen) {
m_pens[index] = pen;
update();
@@ -125,7 +124,7 @@ void PaletteBox::mousePressEvent(QMouseEvent *event)
qreal w = static_cast<qreal>(width()) / static_cast<qreal>(m_brushes.size());
int i = static_cast<int>((event->x() / w));
- QMT_CHECK(i >= 0 && i < m_brushes.size());
+ QMT_ASSERT(i >= 0 && i < m_brushes.size(), return);
setCurrentIndex(i);
if (m_currentIndex >= 0 && m_currentIndex < m_brushes.size())
emit activated(m_currentIndex);
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.h b/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.h
index 501b7ea758a..76499c90190 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.h
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.h
@@ -38,7 +38,7 @@ class QMT_EXPORT PaletteBox : public QWidget
Q_OBJECT
public:
- explicit PaletteBox(QWidget *parent = 0);
+ explicit PaletteBox(QWidget *parent = nullptr);
~PaletteBox() override;
signals:
@@ -62,7 +62,7 @@ protected:
private:
QVector<QBrush> m_brushes;
QVector<QPen> m_pens;
- int m_currentIndex;
+ int m_currentIndex = -1;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.cpp
index 0c59fe20c1f..350803d1684 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.cpp
@@ -39,13 +39,7 @@ namespace qmt {
PropertiesView::PropertiesView(QObject *parent)
: QObject(parent),
- m_modelController(0),
- m_diagramController(0),
- m_stereotypeController(0),
- m_styleController(0),
- m_viewFactory([=](PropertiesView *propertiesView) { return new MView(propertiesView); }),
- m_selectedDiagram(0),
- m_widget(0)
+ m_viewFactory([=](PropertiesView *propertiesView) { return new MView(propertiesView); })
{
}
@@ -57,7 +51,7 @@ void PropertiesView::setModelController(ModelController *modelController)
{
if (m_modelController != modelController) {
if (m_modelController)
- disconnect(m_modelController, 0, this, 0);
+ disconnect(m_modelController, nullptr, this, nullptr);
m_modelController = modelController;
if (m_modelController) {
connect(m_modelController, &ModelController::beginResetModel,
@@ -109,8 +103,8 @@ void PropertiesView::setDiagramController(DiagramController *diagramController)
{
if (m_diagramController != diagramController) {
if (m_diagramController) {
- disconnect(m_diagramController, 0, this, 0);
- m_diagramController = 0;
+ disconnect(m_diagramController, nullptr, this, nullptr);
+ m_diagramController = nullptr;
}
m_diagramController = diagramController;
if (diagramController) {
@@ -162,7 +156,7 @@ void PropertiesView::setSelectedModelElements(const QList<MElement *> &modelElem
if (m_selectedModelElements != modelElements) {
m_selectedModelElements = modelElements;
m_selectedDiagramElements.clear();
- m_selectedDiagram = 0;
+ m_selectedDiagram = nullptr;
m_mview.reset(m_viewFactory(this));
m_mview->update(m_selectedModelElements);
m_widget = m_mview->topLevelWidget();
@@ -172,7 +166,7 @@ void PropertiesView::setSelectedModelElements(const QList<MElement *> &modelElem
void PropertiesView::setSelectedDiagramElements(const QList<DElement *> &diagramElements, MDiagram *diagram)
{
QMT_CHECK(diagramElements.size() > 0);
- QMT_CHECK(diagram);
+ QMT_ASSERT(diagram, return);
if (m_selectedDiagramElements != diagramElements || m_selectedDiagram != diagram) {
m_selectedDiagramElements = diagramElements;
@@ -188,9 +182,9 @@ void PropertiesView::clearSelection()
{
m_selectedModelElements.clear();
m_selectedDiagramElements.clear();
- m_selectedDiagram = 0;
+ m_selectedDiagram = nullptr;
m_mview.reset();
- m_widget = 0;
+ m_widget = nullptr;
}
QWidget *PropertiesView::widget() const
@@ -386,7 +380,7 @@ void PropertiesView::onEndRemoveElement(int row, const MDiagram *diagram)
void PropertiesView::beginUpdate(MElement *modelElement)
{
- QMT_CHECK(modelElement);
+ QMT_ASSERT(modelElement, return);
if (auto object = dynamic_cast<MObject *>(modelElement)) {
m_modelController->startUpdateObject(object);
@@ -399,7 +393,7 @@ void PropertiesView::beginUpdate(MElement *modelElement)
void PropertiesView::endUpdate(MElement *modelElement, bool cancelled)
{
- QMT_CHECK(modelElement);
+ QMT_ASSERT(modelElement, return);
if (auto object = dynamic_cast<MObject *>(modelElement)) {
m_modelController->finishUpdateObject(object, cancelled);
@@ -412,18 +406,18 @@ void PropertiesView::endUpdate(MElement *modelElement, bool cancelled)
void PropertiesView::beginUpdate(DElement *diagramElement)
{
- QMT_CHECK(diagramElement);
- QMT_CHECK(m_selectedDiagram != 0);
- QMT_CHECK(m_diagramController->findElement(diagramElement->uid(), m_selectedDiagram) == diagramElement);
+ QMT_ASSERT(diagramElement, return);
+ QMT_ASSERT(m_selectedDiagram, return);
+ QMT_ASSERT(m_diagramController->findElement(diagramElement->uid(), m_selectedDiagram) == diagramElement, return);
m_diagramController->startUpdateElement(diagramElement, m_selectedDiagram, DiagramController::UpdateMinor);
}
void PropertiesView::endUpdate(DElement *diagramElement, bool cancelled)
{
- QMT_CHECK(diagramElement);
- QMT_CHECK(m_selectedDiagram != 0);
- QMT_CHECK(m_diagramController->findElement(diagramElement->uid(), m_selectedDiagram) == diagramElement);
+ QMT_ASSERT(diagramElement, return);
+ QMT_ASSERT(m_selectedDiagram, return);
+ QMT_ASSERT(m_diagramController->findElement(diagramElement->uid(), m_selectedDiagram) == diagramElement, return);
m_diagramController->finishUpdateElement(diagramElement, m_selectedDiagram, cancelled);
}
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.h b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.h
index 39c1f817a16..78273ed01b9 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.h
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.h
@@ -55,7 +55,7 @@ class QMT_EXPORT PropertiesView : public QObject
public:
class MView;
- explicit PropertiesView(QObject *parent = 0);
+ explicit PropertiesView(QObject *parent = nullptr);
~PropertiesView() override;
ModelController *modelController() const { return m_modelController; }
@@ -116,16 +116,16 @@ private:
void beginUpdate(DElement *diagramElement);
void endUpdate(DElement *diagramElement, bool cancelled);
- ModelController *m_modelController;
- DiagramController *m_diagramController;
- StereotypeController *m_stereotypeController;
- StyleController *m_styleController;
- std::function<MView *(PropertiesView *)> m_viewFactory;
+ ModelController *m_modelController = nullptr;
+ DiagramController *m_diagramController = nullptr;
+ StereotypeController *m_stereotypeController = nullptr;
+ StyleController *m_styleController = nullptr;
+ std::function<MView *(PropertiesView *)> m_viewFactory = nullptr;
QList<MElement *> m_selectedModelElements;
QList<DElement *> m_selectedDiagramElements;
- MDiagram *m_selectedDiagram;
+ MDiagram *m_selectedDiagram = nullptr;
QScopedPointer<MView> m_mview;
- QWidget *m_widget;
+ QWidget *m_widget = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp
index 62ceaad1a39..d0a87dfaa9d 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp
@@ -43,6 +43,7 @@
#include "qmt/model/mdependency.h"
#include "qmt/model/minheritance.h"
#include "qmt/model/massociation.h"
+#include "qmt/model/mconnection.h"
#include "qmt/diagram/delement.h"
#include "qmt/diagram/dobject.h"
@@ -55,12 +56,15 @@
#include "qmt/diagram/dinheritance.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dassociation.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/diagram/dannotation.h"
#include "qmt/diagram/dboundary.h"
+#include "qmt/diagram/dswimlane.h"
// TODO move into better place
#include "qmt/diagram_scene/items/stereotypedisplayvisitor.h"
#include "qmt/stereotype/stereotypecontroller.h"
+#include "qmt/stereotype/customrelation.h"
#include "qmt/style/stylecontroller.h"
#include "qmt/style/style.h"
#include "qmt/style/objectvisuals.h"
@@ -102,7 +106,7 @@ static MDependency::Direction translateIndexToDirection(int index)
static const MDependency::Direction map[] = {
MDependency::AToB, MDependency::BToA, MDependency::Bidirectional
};
- QMT_CHECK(isValidDirectionIndex(index));
+ QMT_ASSERT(isValidDirectionIndex(index), return MDependency::AToB);
return map[index];
}
@@ -129,7 +133,7 @@ static MAssociationEnd::Kind translateIndexToAssociationKind(int index)
static const MAssociationEnd::Kind map[] = {
MAssociationEnd::Association, MAssociationEnd::Aggregation, MAssociationEnd::Composition
};
- QMT_CHECK(isValidAssociationKindIndex(index));
+ QMT_ASSERT(isValidAssociationKindIndex(index), return MAssociationEnd::Association);
return map[index];
}
@@ -164,7 +168,7 @@ static DObject::VisualPrimaryRole translateIndexToVisualPrimaryRole(int index)
DObject::PrimaryRoleCustom1, DObject::PrimaryRoleCustom2, DObject::PrimaryRoleCustom3,
DObject::PrimaryRoleCustom4, DObject::PrimaryRoleCustom5
};
- QMT_CHECK(index >= 0 && index <= 5);
+ QMT_ASSERT(index >= 0 && index <= 5, return DObject::PrimaryRoleNormal);
return map[index];
}
@@ -192,7 +196,7 @@ static DObject::VisualSecondaryRole translateIndexToVisualSecondaryRole(int inde
DObject::SecondaryRoleLighter, DObject::SecondaryRoleDarker,
DObject::SecondaryRoleSoften, DObject::SecondaryRoleOutline
};
- QMT_CHECK(index >= 0 && index <= 4);
+ QMT_ASSERT(index >= 0 && index <= 4, return DObject::SecondaryRoleNone);
return map[index];
}
@@ -222,7 +226,7 @@ static DObject::StereotypeDisplay translateIndexToStereotypeDisplay(int index)
DObject::StereotypeDecoration,
DObject::StereotypeIcon
};
- QMT_CHECK(index >= 0 && index <= 4);
+ QMT_ASSERT(index >= 0 && index <= 4, return DObject::StereotypeSmart);
return map[index];
}
@@ -246,7 +250,7 @@ static DClass::TemplateDisplay translateIndexToTemplateDisplay(int index)
DClass::TemplateBox,
DClass::TemplateName
};
- QMT_CHECK(index >= 0 && index <= 2);
+ QMT_ASSERT(index >= 0 && index <= 2, return DClass::TemplateSmart);
return map[index];
}
@@ -275,56 +279,13 @@ static DAnnotation::VisualRole translateIndexToAnnotationVisualRole(int index)
DAnnotation::RoleNormal, DAnnotation::RoleTitle, DAnnotation::RoleSubtitle,
DAnnotation::RoleEmphasized, DAnnotation::RoleSoften, DAnnotation::RoleFootnote
};
- QMT_CHECK(index >= 0 && index <= 5);
+ QMT_ASSERT(index >= 0 && index <= 5, return DAnnotation::RoleNormal);
return map[index];
}
PropertiesView::MView::MView(PropertiesView *propertiesView)
: m_propertiesView(propertiesView),
- m_diagram(0),
- m_stereotypesController(new StereotypesController(this)),
- m_topWidget(0),
- m_topLayout(0),
- m_stereotypeElement(StereotypeIcon::ElementAny),
- m_classNameLabel(0),
- m_stereotypeComboBox(0),
- m_reverseEngineeredLabel(0),
- m_elementNameLineEdit(0),
- m_childrenLabel(0),
- m_relationsLabel(0),
- m_namespaceLineEdit(0),
- m_templateParametersLineEdit(0),
- m_classMembersStatusLabel(0),
- m_classMembersParseButton(0),
- m_classMembersEdit(0),
- m_diagramsLabel(0),
- m_itemVarietyEdit(0),
- m_endALabel(0),
- m_endBLabel(0),
- m_directionSelector(0),
- m_endAEndName(0),
- m_endACardinality(0),
- m_endANavigable(0),
- m_endAKind(0),
- m_endBEndName(0),
- m_endBCardinality(0),
- m_endBNavigable(0),
- m_endBKind(0),
- m_separatorLine(0),
- m_styleElementType(StyleEngine::TypeOther),
- m_posRectLabel(0),
- m_autoSizedCheckbox(0),
- m_visualPrimaryRoleSelector(0),
- m_visualSecondaryRoleSelector(0),
- m_visualEmphasizedCheckbox(0),
- m_stereotypeDisplaySelector(0),
- m_depthLabel(0),
- m_templateDisplaySelector(0),
- m_showAllMembersCheckbox(0),
- m_plainShapeCheckbox(0),
- m_itemShapeEdit(0),
- m_annotationAutoWidthCheckbox(0),
- m_annotationVisualRoleSelector(0)
+ m_stereotypesController(new StereotypesController(this))
{
}
@@ -334,18 +295,18 @@ PropertiesView::MView::~MView()
void PropertiesView::MView::update(QList<MElement *> &modelElements)
{
- QMT_CHECK(modelElements.size() > 0);
+ QMT_ASSERT(modelElements.size() > 0, return);
m_modelElements = modelElements;
m_diagramElements.clear();
- m_diagram = 0;
+ m_diagram = nullptr;
modelElements.at(0)->accept(this);
}
void PropertiesView::MView::update(QList<DElement *> &diagramElements, MDiagram *diagram)
{
- QMT_CHECK(diagramElements.size() > 0);
- QMT_CHECK(diagram);
+ QMT_ASSERT(diagramElements.size() > 0, return);
+ QMT_ASSERT(diagram, return);
m_diagramElements = diagramElements;
m_diagram = diagram;
@@ -361,7 +322,7 @@ void PropertiesView::MView::update(QList<DElement *> &diagramElements, MDiagram
}
if (!appendedMelement) {
// ensure that indices within m_diagramElements match indices into m_modelElements
- m_modelElements.append(0);
+ m_modelElements.append(nullptr);
}
}
diagramElements.at(0)->accept(this);
@@ -380,7 +341,7 @@ void PropertiesView::MView::visitMElement(const MElement *element)
Q_UNUSED(element);
prepare();
- if (m_stereotypeComboBox == 0) {
+ if (!m_stereotypeComboBox) {
m_stereotypeComboBox = new QComboBox(m_topWidget);
m_stereotypeComboBox->setEditable(true);
m_stereotypeComboBox->setInsertPolicy(QComboBox::NoInsert);
@@ -404,7 +365,7 @@ void PropertiesView::MView::visitMElement(const MElement *element)
}
}
#ifdef SHOW_DEBUG_PROPERTIES
- if (m_reverseEngineeredLabel == 0) {
+ if (!m_reverseEngineeredLabel) {
m_reverseEngineeredLabel = new QLabel(m_topWidget);
addRow(tr("Reverse engineered:"), m_reverseEngineeredLabel, "reverse engineered");
}
@@ -418,7 +379,7 @@ void PropertiesView::MView::visitMObject(const MObject *object)
visitMElement(object);
QList<MObject *> selection = filter<MObject>(m_modelElements);
bool isSingleSelection = selection.size() == 1;
- if (m_elementNameLineEdit == 0) {
+ if (!m_elementNameLineEdit) {
m_elementNameLineEdit = new QLineEdit(m_topWidget);
addRow(tr("Name:"), m_elementNameLineEdit, "name");
connect(m_elementNameLineEdit, &QLineEdit::textChanged,
@@ -434,12 +395,12 @@ void PropertiesView::MView::visitMObject(const MObject *object)
m_elementNameLineEdit->setEnabled(isSingleSelection);
#ifdef SHOW_DEBUG_PROPERTIES
- if (m_childrenLabel == 0) {
+ if (!m_childrenLabel) {
m_childrenLabel = new QLabel(m_topWidget);
addRow(tr("Children:"), m_childrenLabel, "children");
}
m_childrenLabel->setText(QString::number(object->children().size()));
- if (m_relationsLabel == 0) {
+ if (!m_relationsLabel) {
m_relationsLabel = new QLabel(m_topWidget);
addRow(tr("Relations:"), m_relationsLabel, "relations");
}
@@ -462,7 +423,7 @@ void PropertiesView::MView::visitMClass(const MClass *klass)
visitMObject(klass);
QList<MClass *> selection = filter<MClass>(m_modelElements);
bool isSingleSelection = selection.size() == 1;
- if (m_namespaceLineEdit == 0) {
+ if (!m_namespaceLineEdit) {
m_namespaceLineEdit = new QLineEdit(m_topWidget);
addRow(tr("Namespace:"), m_namespaceLineEdit, "namespace");
connect(m_namespaceLineEdit, &QLineEdit::textEdited,
@@ -479,7 +440,7 @@ void PropertiesView::MView::visitMClass(const MClass *klass)
m_namespaceLineEdit->setEnabled(false);
}
}
- if (m_templateParametersLineEdit == 0) {
+ if (!m_templateParametersLineEdit) {
m_templateParametersLineEdit = new QLineEdit(m_topWidget);
addRow(tr("Template:"), m_templateParametersLineEdit, "template");
connect(m_templateParametersLineEdit, &QLineEdit::textChanged,
@@ -496,7 +457,7 @@ void PropertiesView::MView::visitMClass(const MClass *klass)
}
if (m_templateParametersLineEdit->isEnabled() != isSingleSelection)
m_templateParametersLineEdit->setEnabled(isSingleSelection);
- if (m_classMembersStatusLabel == 0) {
+ if (!m_classMembersStatusLabel) {
QMT_CHECK(!m_classMembersParseButton);
m_classMembersStatusLabel = new QLabel(m_topWidget);
m_classMembersParseButton = new QPushButton(tr("Clean Up"), m_topWidget);
@@ -505,13 +466,13 @@ void PropertiesView::MView::visitMClass(const MClass *klass)
layout->addWidget(m_classMembersParseButton);
layout->setStretch(0, 1);
layout->setStretch(1, 0);
- addRow(QStringLiteral(""), layout, "members status");
+ addRow("", layout, "members status");
connect(m_classMembersParseButton, &QAbstractButton::clicked,
this, &PropertiesView::MView::onParseClassMembers);
}
if (m_classMembersParseButton->isEnabled() != isSingleSelection)
m_classMembersParseButton->setEnabled(isSingleSelection);
- if (m_classMembersEdit == 0) {
+ if (!m_classMembersEdit) {
m_classMembersEdit = new ClassMembersEdit(m_topWidget);
m_classMembersEdit->setLineWrapMode(QPlainTextEdit::NoWrap);
addRow(tr("Members:"), m_classMembersEdit, "members");
@@ -541,7 +502,7 @@ void PropertiesView::MView::visitMDiagram(const MDiagram *diagram)
setTitle<MDiagram>(m_modelElements, tr("Diagram"), tr("Diagrams"));
visitMObject(diagram);
#ifdef SHOW_DEBUG_PROPERTIES
- if (m_diagramsLabel == 0) {
+ if (!m_diagramsLabel) {
m_diagramsLabel = new QLabel(m_topWidget);
addRow(tr("Elements:"), m_diagramsLabel, "elements");
}
@@ -562,7 +523,7 @@ void PropertiesView::MView::visitMItem(const MItem *item)
QList<MItem *> selection = filter<MItem>(m_modelElements);
bool isSingleSelection = selection.size() == 1;
if (item->isVarietyEditable()) {
- if (m_itemVarietyEdit == 0) {
+ if (!m_itemVarietyEdit) {
m_itemVarietyEdit = new QLineEdit(m_topWidget);
addRow(tr("Variety:"), m_itemVarietyEdit, "variety");
connect(m_itemVarietyEdit, &QLineEdit::textChanged,
@@ -584,7 +545,7 @@ void PropertiesView::MView::visitMRelation(const MRelation *relation)
visitMElement(relation);
QList<MRelation *> selection = filter<MRelation>(m_modelElements);
bool isSingleSelection = selection.size() == 1;
- if (m_elementNameLineEdit == 0) {
+ if (!m_elementNameLineEdit) {
m_elementNameLineEdit = new QLineEdit(m_topWidget);
addRow(tr("Name:"), m_elementNameLineEdit, "name");
connect(m_elementNameLineEdit, &QLineEdit::textChanged,
@@ -599,10 +560,10 @@ void PropertiesView::MView::visitMRelation(const MRelation *relation)
if (m_elementNameLineEdit->isEnabled() != isSingleSelection)
m_elementNameLineEdit->setEnabled(isSingleSelection);
MObject *endAObject = m_propertiesView->modelController()->findObject(relation->endAUid());
- QMT_CHECK(endAObject);
+ QMT_ASSERT(endAObject, return);
setEndAName(tr("End A: %1").arg(endAObject->name()));
MObject *endBObject = m_propertiesView->modelController()->findObject(relation->endBUid());
- QMT_CHECK(endBObject);
+ QMT_ASSERT(endBObject, return);
setEndBName(tr("End B: %1").arg(endBObject->name()));
}
@@ -612,7 +573,7 @@ void PropertiesView::MView::visitMDependency(const MDependency *dependency)
visitMRelation(dependency);
QList<MDependency *> selection = filter<MDependency>(m_modelElements);
bool isSingleSelection = selection.size() == 1;
- if (m_directionSelector == 0) {
+ if (!m_directionSelector) {
m_directionSelector = new QComboBox(m_topWidget);
m_directionSelector->addItems(QStringList({ "->", "<-", "<->" }));
addRow(tr("Direction:"), m_directionSelector, "direction");
@@ -636,9 +597,10 @@ void PropertiesView::MView::visitMInheritance(const MInheritance *inheritance)
{
setTitle<MInheritance>(m_modelElements, tr("Inheritance"), tr("Inheritances"));
MObject *derivedClass = m_propertiesView->modelController()->findObject(inheritance->derived());
- QMT_CHECK(derivedClass);
+ QMT_ASSERT(derivedClass, return);
setEndAName(tr("Derived class: %1").arg(derivedClass->name()));
MObject *baseClass = m_propertiesView->modelController()->findObject(inheritance->base());
+ QMT_ASSERT(baseClass, return);
setEndBName(tr("Base class: %1").arg(baseClass->name()));
visitMRelation(inheritance);
}
@@ -649,11 +611,11 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
visitMRelation(association);
QList<MAssociation *> selection = filter<MAssociation>(m_modelElements);
bool isSingleSelection = selection.size() == 1;
- if (m_endALabel == 0) {
- m_endALabel = new QLabel(QStringLiteral("<b>") + m_endAName + QStringLiteral("</b>"));
+ if (!m_endALabel) {
+ m_endALabel = new QLabel("<b>" + m_endAName + "</b>");
addRow(m_endALabel, "end a");
}
- if (m_endAEndName == 0) {
+ if (!m_endAEndName) {
m_endAEndName = new QLineEdit(m_topWidget);
addRow(tr("Role:"), m_endAEndName, "role a");
connect(m_endAEndName, &QLineEdit::textChanged,
@@ -667,7 +629,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
}
if (m_endAEndName->isEnabled() != isSingleSelection)
m_endAEndName->setEnabled(isSingleSelection);
- if (m_endACardinality == 0) {
+ if (!m_endACardinality) {
m_endACardinality = new QLineEdit(m_topWidget);
addRow(tr("Cardinality:"), m_endACardinality, "cardinality a");
connect(m_endACardinality, &QLineEdit::textChanged,
@@ -681,7 +643,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
}
if (m_endACardinality->isEnabled() != isSingleSelection)
m_endACardinality->setEnabled(isSingleSelection);
- if (m_endANavigable == 0) {
+ if (!m_endANavigable) {
m_endANavigable = new QCheckBox(tr("Navigable"), m_topWidget);
addRow(QString(), m_endANavigable, "navigable a");
connect(m_endANavigable, &QAbstractButton::clicked,
@@ -695,7 +657,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
}
if (m_endANavigable->isEnabled() != isSingleSelection)
m_endANavigable->setEnabled(isSingleSelection);
- if (m_endAKind == 0) {
+ if (!m_endAKind) {
m_endAKind = new QComboBox(m_topWidget);
m_endAKind->addItems({ tr("Association"), tr("Aggregation"), tr("Composition") });
addRow(tr("Relationship:"), m_endAKind, "relationship a");
@@ -714,11 +676,11 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
if (m_endAKind->isEnabled() != isSingleSelection)
m_endAKind->setEnabled(isSingleSelection);
- if (m_endBLabel == 0) {
- m_endBLabel = new QLabel(QStringLiteral("<b>") + m_endBName + QStringLiteral("</b>"));
+ if (!m_endBLabel) {
+ m_endBLabel = new QLabel("<b>" + m_endBName + "</b>");
addRow(m_endBLabel, "end b");
}
- if (m_endBEndName == 0) {
+ if (!m_endBEndName) {
m_endBEndName = new QLineEdit(m_topWidget);
addRow(tr("Role:"), m_endBEndName, "role b");
connect(m_endBEndName, &QLineEdit::textChanged,
@@ -732,7 +694,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
}
if (m_endBEndName->isEnabled() != isSingleSelection)
m_endBEndName->setEnabled(isSingleSelection);
- if (m_endBCardinality == 0) {
+ if (!m_endBCardinality) {
m_endBCardinality = new QLineEdit(m_topWidget);
addRow(tr("Cardinality:"), m_endBCardinality, "cardinality b");
connect(m_endBCardinality, &QLineEdit::textChanged,
@@ -746,7 +708,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
}
if (m_endBCardinality->isEnabled() != isSingleSelection)
m_endBCardinality->setEnabled(isSingleSelection);
- if (m_endBNavigable == 0) {
+ if (!m_endBNavigable) {
m_endBNavigable = new QCheckBox(tr("Navigable"), m_topWidget);
addRow(QString(), m_endBNavigable, "navigable b");
connect(m_endBNavigable, &QAbstractButton::clicked,
@@ -760,7 +722,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
}
if (m_endBNavigable->isEnabled() != isSingleSelection)
m_endBNavigable->setEnabled(isSingleSelection);
- if (m_endBKind == 0) {
+ if (!m_endBKind) {
m_endBKind = new QComboBox(m_topWidget);
m_endBKind->addItems({ tr("Association"), tr("Aggregation"), tr("Composition") });
addRow(tr("Relationship:"), m_endBKind, "relationship b");
@@ -780,6 +742,107 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
m_endBKind->setEnabled(isSingleSelection);
}
+void PropertiesView::MView::visitMConnection(const MConnection *connection)
+{
+ setTitle<MConnection>(connection, m_modelElements, tr("Connection"), tr("Connections"));
+ visitMRelation(connection);
+ QList<MConnection *> selection = filter<MConnection>(m_modelElements);
+ const bool isSingleSelection = selection.size() == 1;
+ if (!m_endALabel) {
+ m_endALabel = new QLabel("<b>" + m_endAName + "</b>");
+ addRow(m_endALabel, "end a");
+ }
+ if (!m_endAEndName) {
+ m_endAEndName = new QLineEdit(m_topWidget);
+ addRow(tr("Role:"), m_endAEndName, "role a");
+ connect(m_endAEndName, &QLineEdit::textChanged,
+ this, &PropertiesView::MView::onConnectionEndANameChanged);
+ }
+ if (isSingleSelection) {
+ if (connection->endA().name() != m_endAEndName->text() && !m_endAEndName->hasFocus())
+ m_endAEndName->setText(connection->endA().name());
+ } else {
+ m_endAEndName->clear();
+ }
+ if (m_endAEndName->isEnabled() != isSingleSelection)
+ m_endAEndName->setEnabled(isSingleSelection);
+ if (!m_endACardinality) {
+ m_endACardinality = new QLineEdit(m_topWidget);
+ addRow(tr("Cardinality:"), m_endACardinality, "cardinality a");
+ connect(m_endACardinality, &QLineEdit::textChanged,
+ this, &PropertiesView::MView::onConnectionEndACardinalityChanged);
+ }
+ if (isSingleSelection) {
+ if (connection->endA().cardinality() != m_endACardinality->text() && !m_endACardinality->hasFocus())
+ m_endACardinality->setText(connection->endA().cardinality());
+ } else {
+ m_endACardinality->clear();
+ }
+ if (m_endACardinality->isEnabled() != isSingleSelection)
+ m_endACardinality->setEnabled(isSingleSelection);
+ if (!m_endANavigable) {
+ m_endANavigable = new QCheckBox(tr("Navigable"), m_topWidget);
+ addRow(QString(), m_endANavigable, "navigable a");
+ connect(m_endANavigable, &QAbstractButton::clicked,
+ this, &PropertiesView::MView::onConnectionEndANavigableChanged);
+ }
+ if (isSingleSelection) {
+ if (connection->endA().isNavigable() != m_endANavigable->isChecked())
+ m_endANavigable->setChecked(connection->endA().isNavigable());
+ } else {
+ m_endANavigable->setChecked(false);
+ }
+ if (m_endANavigable->isEnabled() != isSingleSelection)
+ m_endANavigable->setEnabled(isSingleSelection);
+
+ if (!m_endBLabel) {
+ m_endBLabel = new QLabel("<b>" + m_endBName + "</b>");
+ addRow(m_endBLabel, "end b");
+ }
+ if (!m_endBEndName) {
+ m_endBEndName = new QLineEdit(m_topWidget);
+ addRow(tr("Role:"), m_endBEndName, "role b");
+ connect(m_endBEndName, &QLineEdit::textChanged,
+ this, &PropertiesView::MView::onConnectionEndBNameChanged);
+ }
+ if (isSingleSelection) {
+ if (connection->endB().name() != m_endBEndName->text() && !m_endBEndName->hasFocus())
+ m_endBEndName->setText(connection->endB().name());
+ } else {
+ m_endBEndName->clear();
+ }
+ if (m_endBEndName->isEnabled() != isSingleSelection)
+ m_endBEndName->setEnabled(isSingleSelection);
+ if (!m_endBCardinality) {
+ m_endBCardinality = new QLineEdit(m_topWidget);
+ addRow(tr("Cardinality:"), m_endBCardinality, "cardinality b");
+ connect(m_endBCardinality, &QLineEdit::textChanged,
+ this, &PropertiesView::MView::onConnectionEndBCardinalityChanged);
+ }
+ if (isSingleSelection) {
+ if (connection->endB().cardinality() != m_endBCardinality->text() && !m_endBCardinality->hasFocus())
+ m_endBCardinality->setText(connection->endB().cardinality());
+ } else {
+ m_endBCardinality->clear();
+ }
+ if (m_endBCardinality->isEnabled() != isSingleSelection)
+ m_endBCardinality->setEnabled(isSingleSelection);
+ if (!m_endBNavigable) {
+ m_endBNavigable = new QCheckBox(tr("Navigable"), m_topWidget);
+ addRow(QString(), m_endBNavigable, "navigable b");
+ connect(m_endBNavigable, &QAbstractButton::clicked,
+ this, &PropertiesView::MView::onConnectionEndBNavigableChanged);
+ }
+ if (isSingleSelection) {
+ if (connection->endB().isNavigable() != m_endBNavigable->isChecked())
+ m_endBNavigable->setChecked(connection->endB().isNavigable());
+ } else {
+ m_endBNavigable->setChecked(false);
+ }
+ if (m_endBNavigable->isEnabled() != isSingleSelection)
+ m_endBNavigable->setEnabled(isSingleSelection);
+}
+
void PropertiesView::MView::visitDElement(const DElement *element)
{
Q_UNUSED(element);
@@ -788,7 +851,7 @@ void PropertiesView::MView::visitDElement(const DElement *element)
m_propertiesTitle.clear();
m_modelElements.at(0)->accept(this);
#ifdef SHOW_DEBUG_PROPERTIES
- if (m_separatorLine == 0) {
+ if (!m_separatorLine) {
m_separatorLine = new QFrame(m_topWidget);
m_separatorLine->setFrameShape(QFrame::StyledPanel);
m_separatorLine->setLineWidth(2);
@@ -805,11 +868,11 @@ void PropertiesView::MView::visitDObject(const DObject *object)
{
visitDElement(object);
#ifdef SHOW_DEBUG_PROPERTIES
- if (m_posRectLabel == 0) {
+ if (!m_posRectLabel) {
m_posRectLabel = new QLabel(m_topWidget);
addRow(tr("Position and size:"), m_posRectLabel, "position and size");
}
- m_posRectLabel->setText(QString(QStringLiteral("(%1,%2):(%3,%4)-(%5,%6)"))
+ m_posRectLabel->setText(QString("(%1,%2):(%3,%4)-(%5,%6)")
.arg(object->pos().x())
.arg(object->pos().y())
.arg(object->rect().left())
@@ -817,7 +880,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
.arg(object->rect().right())
.arg(object->rect().bottom()));
#endif
- if (m_autoSizedCheckbox == 0) {
+ if (!m_autoSizedCheckbox) {
m_autoSizedCheckbox = new QCheckBox(tr("Auto sized"), m_topWidget);
addRow(QString(), m_autoSizedCheckbox, "auto size");
connect(m_autoSizedCheckbox, &QAbstractButton::clicked,
@@ -830,7 +893,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
else
m_autoSizedCheckbox->setChecked(false);
}
- if (m_visualPrimaryRoleSelector == 0) {
+ if (!m_visualPrimaryRoleSelector) {
m_visualPrimaryRoleSelector = new PaletteBox(m_topWidget);
setPrimaryRolePalette(m_styleElementType, DObject::PrimaryRoleCustom1, QColor());
setPrimaryRolePalette(m_styleElementType, DObject::PrimaryRoleCustom2, QColor());
@@ -859,7 +922,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
else
m_visualPrimaryRoleSelector->setCurrentIndex(-1);
}
- if (m_visualSecondaryRoleSelector == 0) {
+ if (!m_visualSecondaryRoleSelector) {
m_visualSecondaryRoleSelector = new QComboBox(m_topWidget);
m_visualSecondaryRoleSelector->addItems({ tr("Normal"), tr("Lighter"), tr("Darker"),
tr("Soften"), tr("Outline") });
@@ -874,7 +937,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
else
m_visualSecondaryRoleSelector->setCurrentIndex(-1);
}
- if (m_visualEmphasizedCheckbox == 0) {
+ if (!m_visualEmphasizedCheckbox) {
m_visualEmphasizedCheckbox = new QCheckBox(tr("Emphasized"), m_topWidget);
addRow(QString(), m_visualEmphasizedCheckbox, "emphasized");
connect(m_visualEmphasizedCheckbox, &QAbstractButton::clicked,
@@ -887,7 +950,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
else
m_visualEmphasizedCheckbox->setChecked(false);
}
- if (m_stereotypeDisplaySelector == 0) {
+ if (!m_stereotypeDisplaySelector) {
m_stereotypeDisplaySelector = new QComboBox(m_topWidget);
m_stereotypeDisplaySelector->addItems({ tr("Smart"), tr("None"), tr("Label"),
tr("Decoration"), tr("Icon") });
@@ -903,7 +966,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
m_stereotypeDisplaySelector->setCurrentIndex(-1);
}
#ifdef SHOW_DEBUG_PROPERTIES
- if (m_depthLabel == 0) {
+ if (!m_depthLabel) {
m_depthLabel = new QLabel(m_topWidget);
addRow(tr("Depth:"), m_depthLabel, "depth");
}
@@ -925,7 +988,7 @@ void PropertiesView::MView::visitDClass(const DClass *klass)
setStereotypeIconElement(StereotypeIcon::ElementClass);
setStyleElementType(StyleEngine::TypeClass);
visitDObject(klass);
- if (m_templateDisplaySelector == 0) {
+ if (!m_templateDisplaySelector) {
m_templateDisplaySelector = new QComboBox(m_topWidget);
m_templateDisplaySelector->addItems({ tr("Smart"), tr("Box"), tr("Angle Brackets") });
addRow(tr("Template display:"), m_templateDisplaySelector, "template display");
@@ -939,7 +1002,7 @@ void PropertiesView::MView::visitDClass(const DClass *klass)
else
m_templateDisplaySelector->setCurrentIndex(-1);
}
- if (m_showAllMembersCheckbox == 0) {
+ if (!m_showAllMembersCheckbox) {
m_showAllMembersCheckbox = new QCheckBox(tr("Show members"), m_topWidget);
addRow(QString(), m_showAllMembersCheckbox, "show members");
connect(m_showAllMembersCheckbox, &QAbstractButton::clicked,
@@ -960,7 +1023,7 @@ void PropertiesView::MView::visitDComponent(const DComponent *component)
setStereotypeIconElement(StereotypeIcon::ElementComponent);
setStyleElementType(StyleEngine::TypeComponent);
visitDObject(component);
- if (m_plainShapeCheckbox == 0) {
+ if (!m_plainShapeCheckbox) {
m_plainShapeCheckbox = new QCheckBox(tr("Plain shape"), m_topWidget);
addRow(QString(), m_plainShapeCheckbox, "plain shape");
connect(m_plainShapeCheckbox, &QAbstractButton::clicked,
@@ -991,7 +1054,7 @@ void PropertiesView::MView::visitDItem(const DItem *item)
QList<DItem *> selection = filter<DItem>(m_diagramElements);
bool isSingleSelection = selection.size() == 1;
if (item->isShapeEditable()) {
- if (m_itemShapeEdit == 0) {
+ if (!m_itemShapeEdit) {
m_itemShapeEdit = new QLineEdit(m_topWidget);
addRow(tr("Shape:"), m_itemShapeEdit, "shape");
connect(m_itemShapeEdit, &QLineEdit::textChanged,
@@ -1031,11 +1094,17 @@ void PropertiesView::MView::visitDAssociation(const DAssociation *association)
visitDRelation(association);
}
+void PropertiesView::MView::visitDConnection(const DConnection *connection)
+{
+ setTitle<DConnection>(m_diagramElements, tr("Connection"), tr("Connections"));
+ visitDRelation(connection);
+}
+
void PropertiesView::MView::visitDAnnotation(const DAnnotation *annotation)
{
setTitle<DAnnotation>(m_diagramElements, tr("Annotation"), tr("Annotations"));
visitDElement(annotation);
- if (m_annotationAutoWidthCheckbox == 0) {
+ if (!m_annotationAutoWidthCheckbox) {
m_annotationAutoWidthCheckbox = new QCheckBox(tr("Auto width"), m_topWidget);
addRow(QString(), m_annotationAutoWidthCheckbox, "auto width");
connect(m_annotationAutoWidthCheckbox, &QAbstractButton::clicked,
@@ -1048,7 +1117,7 @@ void PropertiesView::MView::visitDAnnotation(const DAnnotation *annotation)
else
m_annotationAutoWidthCheckbox->setChecked(false);
}
- if (m_annotationVisualRoleSelector == 0) {
+ if (!m_annotationVisualRoleSelector) {
m_annotationVisualRoleSelector = new QComboBox(m_topWidget);
m_annotationVisualRoleSelector->addItems(QStringList({ tr("Normal"), tr("Title"),
tr("Subtitle"), tr("Emphasized"),
@@ -1072,6 +1141,12 @@ void PropertiesView::MView::visitDBoundary(const DBoundary *boundary)
visitDElement(boundary);
}
+void PropertiesView::MView::visitDSwimlane(const DSwimlane *swimlane)
+{
+ setTitle<DSwimlane>(m_diagramElements, tr("Swimlane"), tr("Swimlanes"));
+ visitDElement(swimlane);
+}
+
void PropertiesView::MView::onStereotypesChanged(const QString &stereotypes)
{
QList<QString> set = m_stereotypesController->fromString(stereotypes);
@@ -1206,6 +1281,48 @@ void PropertiesView::MView::onAssociationEndBKindChanged(int kindIndex)
&MAssociationEnd::kind, &MAssociationEnd::setKind);
}
+void PropertiesView::MView::onConnectionEndANameChanged(const QString &name)
+{
+ assignEmbeddedModelElement<MConnection, MConnectionEnd, QString>(
+ m_modelElements, SelectionSingle, name, &MConnection::endA, &MConnection::setEndA,
+ &MConnectionEnd::name, &MConnectionEnd::setName);
+}
+
+void PropertiesView::MView::onConnectionEndACardinalityChanged(const QString &cardinality)
+{
+ assignEmbeddedModelElement<MConnection, MConnectionEnd, QString>(
+ m_modelElements, SelectionSingle, cardinality, &MConnection::endA, &MConnection::setEndA,
+ &MConnectionEnd::cardinality, &MConnectionEnd::setCardinality);
+}
+
+void PropertiesView::MView::onConnectionEndANavigableChanged(bool navigable)
+{
+ assignEmbeddedModelElement<MConnection, MConnectionEnd, bool>(
+ m_modelElements, SelectionSingle, navigable, &MConnection::endA, &MConnection::setEndA,
+ &MConnectionEnd::isNavigable, &MConnectionEnd::setNavigable);
+}
+
+void PropertiesView::MView::onConnectionEndBNameChanged(const QString &name)
+{
+ assignEmbeddedModelElement<MConnection, MConnectionEnd, QString>(
+ m_modelElements, SelectionSingle, name, &MConnection::endB, &MConnection::setEndB,
+ &MConnectionEnd::name, &MConnectionEnd::setName);
+}
+
+void PropertiesView::MView::onConnectionEndBCardinalityChanged(const QString &cardinality)
+{
+ assignEmbeddedModelElement<MConnection, MConnectionEnd, QString>(
+ m_modelElements, SelectionSingle, cardinality, &MConnection::endB, &MConnection::setEndB,
+ &MConnectionEnd::cardinality, &MConnectionEnd::setCardinality);
+}
+
+void PropertiesView::MView::onConnectionEndBNavigableChanged(bool navigable)
+{
+ assignEmbeddedModelElement<MConnection, MConnectionEnd, bool>(
+ m_modelElements, SelectionSingle, navigable, &MConnection::endB, &MConnection::setEndB,
+ &MConnectionEnd::isNavigable, &MConnectionEnd::setNavigable);
+}
+
void PropertiesView::MView::onAutoSizedChanged(bool autoSized)
{
assignModelElement<DObject, bool>(m_diagramElements, SelectionMulti, autoSized,
@@ -1283,17 +1400,17 @@ void PropertiesView::MView::onAnnotationVisualRoleChanged(int visualRoleIndex)
void PropertiesView::MView::prepare()
{
QMT_CHECK(!m_propertiesTitle.isEmpty());
- if (m_topWidget == 0) {
+ if (!m_topWidget) {
m_topWidget = new QWidget();
m_topLayout = new QFormLayout(m_topWidget);
m_topWidget->setLayout(m_topLayout);
}
- if (m_classNameLabel == 0) {
+ if (!m_classNameLabel) {
m_classNameLabel = new QLabel();
m_topLayout->addRow(m_classNameLabel);
m_rowToId.append("title");
}
- QString title(QStringLiteral("<b>") + m_propertiesTitle + QStringLiteral("</b>"));
+ QString title("<b>" + m_propertiesTitle + "</b>");
if (m_classNameLabel->text() != title)
m_classNameLabel->setText(title);
}
@@ -1371,26 +1488,54 @@ template<typename T, typename V>
void PropertiesView::MView::setTitle(const MItem *item, const QList<V *> &elements,
const QString &singularTitle, const QString &pluralTitle)
{
- if (m_propertiesTitle.isEmpty()) {
- QList<T *> filtered = filter<T>(elements);
- if (filtered.size() == elements.size()) {
- if (elements.size() == 1) {
- if (item && !item->isVarietyEditable()) {
- QString stereotypeIconId = m_propertiesView->stereotypeController()
+ if (!m_propertiesTitle.isEmpty())
+ return;
+ QList<T *> filtered = filter<T>(elements);
+ if (filtered.size() == elements.size()) {
+ if (elements.size() == 1) {
+ if (item && !item->isVarietyEditable()) {
+ QString stereotypeIconId = m_propertiesView->stereotypeController()
->findStereotypeIconId(StereotypeIcon::ElementItem, QStringList(item->variety()));
- if (!stereotypeIconId.isEmpty()) {
- StereotypeIcon stereotypeIcon = m_propertiesView->stereotypeController()->findStereotypeIcon(stereotypeIconId);
- m_propertiesTitle = stereotypeIcon.title();
- }
+ if (!stereotypeIconId.isEmpty()) {
+ StereotypeIcon stereotypeIcon = m_propertiesView->stereotypeController()->findStereotypeIcon(stereotypeIconId);
+ m_propertiesTitle = stereotypeIcon.title();
+ }
+ }
+ if (m_propertiesTitle.isEmpty())
+ m_propertiesTitle = singularTitle;
+ } else {
+ m_propertiesTitle = pluralTitle;
+ }
+ } else {
+ m_propertiesTitle = QCoreApplication::translate("qmt::PropertiesView::MView", "Multi-Selection");
+ }
+}
+
+template<typename T, typename V>
+void PropertiesView::MView::setTitle(const MConnection *connection, const QList<V *> &elements,
+ const QString &singularTitle, const QString &pluralTitle)
+{
+ if (!m_propertiesTitle.isEmpty())
+ return;
+ QList<T *> filtered = filter<T>(elements);
+ if (filtered.size() == elements.size()) {
+ if (elements.size() == 1) {
+ if (connection) {
+ CustomRelation customRelation = m_propertiesView->stereotypeController()
+ ->findCustomRelation(connection->customRelationId());
+ if (!customRelation.isNull()) {
+ m_propertiesTitle = customRelation.title();
+ if (m_propertiesTitle.isEmpty())
+ m_propertiesTitle = connection->customRelationId();
}
- if (m_propertiesTitle.isEmpty())
- m_propertiesTitle = singularTitle;
- } else {
- m_propertiesTitle = pluralTitle;
}
+ if (m_propertiesTitle.isEmpty())
+ m_propertiesTitle = singularTitle;
} else {
- m_propertiesTitle = QCoreApplication::translate("qmt::PropertiesView::MView", "Multi-Selection");
+ m_propertiesTitle = pluralTitle;
}
+ } else {
+ m_propertiesTitle = QCoreApplication::translate("qmt::PropertiesView::MView", "Multi-Selection");
}
}
@@ -1444,7 +1589,7 @@ QString PropertiesView::MView::formatTemplateParameters(const QList<QString> &te
bool first = true;
foreach (const QString &parameter, templateParametersList) {
if (!first)
- templateParamters += QStringLiteral(", ");
+ templateParamters += ", ";
templateParamters += parameter;
first = false;
}
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.h b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.h
index 36418cbd9ce..1c3f091f354 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.h
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.h
@@ -78,6 +78,7 @@ public:
void visitMDependency(const MDependency *dependency) override;
void visitMInheritance(const MInheritance *inheritance) override;
void visitMAssociation(const MAssociation *association) override;
+ void visitMConnection(const MConnection *connection) override;
void visitDElement(const DElement *element) override;
void visitDObject(const DObject *object) override;
@@ -90,8 +91,10 @@ public:
void visitDInheritance(const DInheritance *inheritance) override;
void visitDDependency(const DDependency *dependency) override;
void visitDAssociation(const DAssociation *association) override;
+ void visitDConnection(const DConnection *connection) override;
void visitDAnnotation(const DAnnotation *annotation) override;
void visitDBoundary(const DBoundary *boundary) override;
+ void visitDSwimlane(const DSwimlane *swimlane) override;
void update(QList<MElement *> &modelElements);
void update(QList<DElement *> &diagramElements, MDiagram *diagram);
@@ -116,6 +119,12 @@ protected:
void onAssociationEndBCardinalityChanged(const QString &cardinality);
void onAssociationEndBNavigableChanged(bool navigable);
void onAssociationEndBKindChanged(int kindIndex);
+ void onConnectionEndANameChanged(const QString &name);
+ void onConnectionEndACardinalityChanged(const QString &cardinality);
+ void onConnectionEndANavigableChanged(bool navigable);
+ void onConnectionEndBNameChanged(const QString &name);
+ void onConnectionEndBCardinalityChanged(const QString &cardinality);
+ void onConnectionEndBNavigableChanged(bool navigable);
void onAutoSizedChanged(bool autoSized);
void onVisualPrimaryRoleChanged(int visualRoleIndex);
void onVisualSecondaryRoleChanged(int visualRoleIndex);
@@ -141,6 +150,9 @@ protected:
template<typename T, typename V>
void setTitle(const MItem *item, const QList<V *> &elements,
const QString &singularTitle, const QString &pluralTitle);
+ template<typename T, typename V>
+ void setTitle(const MConnection *connection, const QList<V *> &elements,
+ const QString &singularTitle, const QString &pluralTitle);
void setStereotypeIconElement(StereotypeIcon::Element stereotypeElement);
void setStyleElementType(StyleEngine::ElementType elementType);
void setPrimaryRolePalette(StyleEngine::ElementType elementType,
@@ -178,72 +190,72 @@ protected:
void (T::*setter)(const E &),
V (E::*vGetter)() const, void (E::*vSetter)(V));
- PropertiesView *m_propertiesView;
+ PropertiesView *m_propertiesView = nullptr;
QList<MElement *> m_modelElements;
QList<DElement *> m_diagramElements;
- MDiagram *m_diagram;
- StereotypesController *m_stereotypesController;
- QWidget *m_topWidget;
- QFormLayout *m_topLayout;
+ MDiagram *m_diagram = nullptr;
+ StereotypesController *m_stereotypesController = nullptr;
+ QWidget *m_topWidget = nullptr;
+ QFormLayout *m_topLayout = nullptr;
QList<const char *> m_rowToId;
QString m_propertiesTitle;
// MElement
- StereotypeIcon::Element m_stereotypeElement;
- QLabel *m_classNameLabel;
- QComboBox *m_stereotypeComboBox;
- QLabel *m_reverseEngineeredLabel;
+ StereotypeIcon::Element m_stereotypeElement = StereotypeIcon::ElementAny;
+ QLabel *m_classNameLabel = nullptr;
+ QComboBox *m_stereotypeComboBox = nullptr;
+ QLabel *m_reverseEngineeredLabel = nullptr;
// MObject
- QLineEdit *m_elementNameLineEdit;
- QLabel *m_childrenLabel;
- QLabel *m_relationsLabel;
+ QLineEdit *m_elementNameLineEdit = nullptr;
+ QLabel *m_childrenLabel = nullptr;
+ QLabel *m_relationsLabel = nullptr;
// MClass
- QLineEdit *m_namespaceLineEdit;
- QLineEdit *m_templateParametersLineEdit;
- QLabel *m_classMembersStatusLabel;
- QPushButton *m_classMembersParseButton;
- ClassMembersEdit *m_classMembersEdit;
+ QLineEdit *m_namespaceLineEdit = nullptr;
+ QLineEdit *m_templateParametersLineEdit = nullptr;
+ QLabel *m_classMembersStatusLabel = nullptr;
+ QPushButton *m_classMembersParseButton = nullptr;
+ ClassMembersEdit *m_classMembersEdit = nullptr;
// MDiagram
- QLabel *m_diagramsLabel;
+ QLabel *m_diagramsLabel = nullptr;
// MItem
- QLineEdit *m_itemVarietyEdit;
+ QLineEdit *m_itemVarietyEdit = nullptr;
// MRelation
QString m_endAName;
- QLabel *m_endALabel;
+ QLabel *m_endALabel = nullptr;
QString m_endBName;
- QLabel *m_endBLabel;
+ QLabel *m_endBLabel = nullptr;
// MDependency
- QComboBox *m_directionSelector;
+ QComboBox *m_directionSelector = nullptr;
// MAssociation
- QLineEdit *m_endAEndName;
- QLineEdit *m_endACardinality;
- QCheckBox *m_endANavigable;
- QComboBox *m_endAKind;
- QLineEdit *m_endBEndName;
- QLineEdit *m_endBCardinality;
- QCheckBox *m_endBNavigable;
- QComboBox *m_endBKind;
+ QLineEdit *m_endAEndName = nullptr;
+ QLineEdit *m_endACardinality = nullptr;
+ QCheckBox *m_endANavigable = nullptr;
+ QComboBox *m_endAKind = nullptr;
+ QLineEdit *m_endBEndName = nullptr;
+ QLineEdit *m_endBCardinality = nullptr;
+ QCheckBox *m_endBNavigable = nullptr;
+ QComboBox *m_endBKind = nullptr;
// DElement
- QFrame *m_separatorLine;
+ QFrame *m_separatorLine = nullptr;
// DObject
- StyleEngine::ElementType m_styleElementType;
- QLabel *m_posRectLabel;
- QCheckBox *m_autoSizedCheckbox;
- PaletteBox *m_visualPrimaryRoleSelector;
- QComboBox *m_visualSecondaryRoleSelector;
- QCheckBox *m_visualEmphasizedCheckbox;
- QComboBox *m_stereotypeDisplaySelector;
- QLabel *m_depthLabel;
+ StyleEngine::ElementType m_styleElementType = StyleEngine::TypeOther;
+ QLabel *m_posRectLabel = nullptr;
+ QCheckBox *m_autoSizedCheckbox = nullptr;
+ PaletteBox *m_visualPrimaryRoleSelector = nullptr;
+ QComboBox *m_visualSecondaryRoleSelector = nullptr;
+ QCheckBox *m_visualEmphasizedCheckbox = nullptr;
+ QComboBox *m_stereotypeDisplaySelector = nullptr;
+ QLabel *m_depthLabel = nullptr;
// DClass
- QComboBox *m_templateDisplaySelector;
- QCheckBox *m_showAllMembersCheckbox;
+ QComboBox *m_templateDisplaySelector = nullptr;
+ QCheckBox *m_showAllMembersCheckbox = nullptr;
// DComponent
- QCheckBox *m_plainShapeCheckbox;
+ QCheckBox *m_plainShapeCheckbox = nullptr;
// DItem
- QLineEdit *m_itemShapeEdit;
+ QLineEdit *m_itemShapeEdit = nullptr;
// DAnnotation
- QCheckBox *m_annotationAutoWidthCheckbox;
- QComboBox *m_annotationVisualRoleSelector;
+ QCheckBox *m_annotationAutoWidthCheckbox = nullptr;
+ QComboBox *m_annotationVisualRoleSelector = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/project/project.h b/src/libs/modelinglib/qmt/project/project.h
index b135769d875..d803789b87c 100644
--- a/src/libs/modelinglib/qmt/project/project.h
+++ b/src/libs/modelinglib/qmt/project/project.h
@@ -52,7 +52,7 @@ public:
private:
Uid m_uid;
QString m_fileName;
- MPackage *m_rootPackage;
+ MPackage *m_rootPackage = nullptr;
QString m_configPath;
};
diff --git a/src/libs/modelinglib/qmt/project_controller/projectcontroller.cpp b/src/libs/modelinglib/qmt/project_controller/projectcontroller.cpp
index 9698a2f601f..5feb0ebd560 100644
--- a/src/libs/modelinglib/qmt/project_controller/projectcontroller.cpp
+++ b/src/libs/modelinglib/qmt/project_controller/projectcontroller.cpp
@@ -43,8 +43,7 @@ ProjectIsModifiedException::ProjectIsModifiedException()
}
ProjectController::ProjectController(QObject *parent)
- : QObject(parent),
- m_isModified(false)
+ : QObject(parent)
{
}
diff --git a/src/libs/modelinglib/qmt/project_controller/projectcontroller.h b/src/libs/modelinglib/qmt/project_controller/projectcontroller.h
index 73daf2a2ac9..6b57522e202 100644
--- a/src/libs/modelinglib/qmt/project_controller/projectcontroller.h
+++ b/src/libs/modelinglib/qmt/project_controller/projectcontroller.h
@@ -52,7 +52,7 @@ class QMT_EXPORT ProjectController : public QObject
Q_OBJECT
public:
- explicit ProjectController(QObject *parent = 0);
+ explicit ProjectController(QObject *parent = nullptr);
~ProjectController() override;
signals:
@@ -73,7 +73,7 @@ public:
private:
QScopedPointer<Project> m_project;
- bool m_isModified;
+ bool m_isModified = false;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/qmt.pri b/src/libs/modelinglib/qmt/qmt.pri
index d6f5e76a52c..14f38f69918 100644
--- a/src/libs/modelinglib/qmt/qmt.pri
+++ b/src/libs/modelinglib/qmt/qmt.pri
@@ -27,6 +27,7 @@ HEADERS += \
$$PWD/diagram/dboundary.h \
$$PWD/diagram/dclass.h \
$$PWD/diagram/dcomponent.h \
+ $$PWD/diagram/dconnection.h \
$$PWD/diagram/dconstvisitor.h \
$$PWD/diagram/ddependency.h \
$$PWD/diagram/ddiagram.h \
@@ -55,6 +56,7 @@ HEADERS += \
$$PWD/diagram_scene/items/boundaryitem.h \
$$PWD/diagram_scene/items/classitem.h \
$$PWD/diagram_scene/items/componentitem.h \
+ $$PWD/diagram_scene/items/connectionitem.h \
$$PWD/diagram_scene/items/diagramitem.h \
$$PWD/diagram_scene/items/itemitem.h \
$$PWD/diagram_scene/items/objectitem.h \
@@ -103,6 +105,7 @@ HEADERS += \
$$PWD/model/mclass.h \
$$PWD/model/mclassmember.h \
$$PWD/model/mcomponent.h \
+ $$PWD/model/mconnection.h \
$$PWD/model/mconstvisitor.h \
$$PWD/model/mdependency.h \
$$PWD/model/mdiagram.h \
@@ -130,6 +133,7 @@ HEADERS += \
$$PWD/serializer/infrastructureserializer.h \
$$PWD/serializer/modelserializer.h \
$$PWD/serializer/projectserializer.h \
+ $$PWD/stereotype/customrelation.h \
$$PWD/stereotype/iconshape.h \
$$PWD/stereotype/shape.h \
$$PWD/stereotype/shapepaintvisitor.h \
@@ -155,7 +159,9 @@ HEADERS += \
$$PWD/tasks/ielementtasks.h \
$$PWD/tasks/isceneinspector.h \
$$PWD/tasks/voidelementtasks.h \
- $$PWD/infrastructure/qmtassert.h
+ $$PWD/infrastructure/qmtassert.h \
+ $$PWD/diagram_scene/items/swimlaneitem.h \
+ $$PWD/diagram/dswimlane.h
SOURCES += \
$$PWD/config/configcontroller.cpp \
@@ -179,6 +185,7 @@ SOURCES += \
$$PWD/diagram/dboundary.cpp \
$$PWD/diagram/dclass.cpp \
$$PWD/diagram/dcomponent.cpp \
+ $$PWD/diagram/dconnection.cpp \
$$PWD/diagram/ddependency.cpp \
$$PWD/diagram/ddiagram.cpp \
$$PWD/diagram/delement.cpp \
@@ -195,6 +202,7 @@ SOURCES += \
$$PWD/diagram_scene/items/boundaryitem.cpp \
$$PWD/diagram_scene/items/classitem.cpp \
$$PWD/diagram_scene/items/componentitem.cpp \
+ $$PWD/diagram_scene/items/connectionitem.cpp \
$$PWD/diagram_scene/items/diagramitem.cpp \
$$PWD/diagram_scene/items/itemitem.cpp \
$$PWD/diagram_scene/items/objectitem.cpp \
@@ -234,6 +242,7 @@ SOURCES += \
$$PWD/model/mclass.cpp \
$$PWD/model/mclassmember.cpp \
$$PWD/model/mcomponent.cpp \
+ $$PWD/model/mconnection.cpp \
$$PWD/model/mdependency.cpp \
$$PWD/model/mdiagram.cpp \
$$PWD/model/melement.cpp \
@@ -258,6 +267,7 @@ SOURCES += \
$$PWD/serializer/infrastructureserializer.cpp \
$$PWD/serializer/modelserializer.cpp \
$$PWD/serializer/projectserializer.cpp \
+ $$PWD/stereotype/customrelation.cpp \
$$PWD/stereotype/iconshape.cpp \
$$PWD/stereotype/shapepaintvisitor.cpp \
$$PWD/stereotype/shapes.cpp \
@@ -277,7 +287,9 @@ SOURCES += \
$$PWD/tasks/diagramscenecontroller.cpp \
$$PWD/tasks/finddiagramvisitor.cpp \
$$PWD/tasks/findrootdiagramvisitor.cpp \
- $$PWD/tasks/voidelementtasks.cpp
+ $$PWD/tasks/voidelementtasks.cpp \
+ $$PWD/diagram_scene/items/swimlaneitem.cpp \
+ $$PWD/diagram/dswimlane.cpp
RESOURCES += \
$$PWD/resources/resources.qrc
diff --git a/src/libs/modelinglib/qmt/resources/48x48/swimlane.png b/src/libs/modelinglib/qmt/resources/48x48/swimlane.png
new file mode 100644
index 00000000000..ae2b89fb240
--- /dev/null
+++ b/src/libs/modelinglib/qmt/resources/48x48/swimlane.png
Binary files differ
diff --git a/src/libs/modelinglib/qmt/resources/resources.qrc b/src/libs/modelinglib/qmt/resources/resources.qrc
index 896e41c050e..f6ff6af1198 100644
--- a/src/libs/modelinglib/qmt/resources/resources.qrc
+++ b/src/libs/modelinglib/qmt/resources/resources.qrc
@@ -21,5 +21,6 @@
<file>48x48/inheritance.png</file>
<file>48x48/item.png</file>
<file>48x48/package.png</file>
+ <file>48x48/swimlane.png</file>
</qresource>
</RCC>
diff --git a/src/libs/modelinglib/qmt/serializer/diagramserializer.cpp b/src/libs/modelinglib/qmt/serializer/diagramserializer.cpp
index c58eaca70e5..d00a5f94075 100644
--- a/src/libs/modelinglib/qmt/serializer/diagramserializer.cpp
+++ b/src/libs/modelinglib/qmt/serializer/diagramserializer.cpp
@@ -41,9 +41,11 @@
#include "qmt/diagram/dinheritance.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dassociation.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/diagram/dannotation.h"
#include "qmt/diagram/dboundary.h"
+#include "qmt/diagram/dswimlane.h"
#include "qark/qxmloutarchive.h"
#include "qark/qxmlinarchive.h"
@@ -62,7 +64,7 @@ template<class Archive>
inline void Access<Archive, DElement>::serialize(Archive &archive, DElement &element)
{
archive || tag(element)
- || attr(QStringLiteral("uid"), element, &DElement::uid, &DElement::setUid)
+ || attr("uid", element, &DElement::uid, &DElement::setUid)
|| end;
}
@@ -112,17 +114,17 @@ inline void Access<Archive, DObject>::serialize(Archive &archive, DObject &objec
{
archive || tag(object)
|| base<DElement>(object)
- || attr(QStringLiteral("object"), object, &DObject::modelUid, &DObject::setModelUid)
- || attr(QStringLiteral("stereotypes"), object, &DObject::stereotypes, &DObject::setStereotypes)
- || attr(QStringLiteral("context"), object, &DObject::context, &DObject::setContext)
- || attr(QStringLiteral("name"), object, &DObject::name, &DObject::setName)
- || attr(QStringLiteral("pos"), object, &DObject::pos, &DObject::setPos)
- || attr(QStringLiteral("rect"), object, &DObject::rect, &DObject::setRect)
- || attr(QStringLiteral("auto-sized"), object, &DObject::isAutoSized, &DObject::setAutoSized)
- || attr(QStringLiteral("visual-role"), object, &visualRole, &setVisualRole)
- || attr(QStringLiteral("visual-role2"), object, &DObject::visualSecondaryRole, &DObject::setVisualSecondaryRole)
- || attr(QStringLiteral("visual-emphasized"), object, &DObject::isVisualEmphasized, &DObject::setVisualEmphasized)
- || attr(QStringLiteral("stereotype-display"), object, &DObject::stereotypeDisplay, &DObject::setStereotypeDisplay)
+ || attr("object", object, &DObject::modelUid, &DObject::setModelUid)
+ || attr("stereotypes", object, &DObject::stereotypes, &DObject::setStereotypes)
+ || attr("context", object, &DObject::context, &DObject::setContext)
+ || attr("name", object, &DObject::name, &DObject::setName)
+ || attr("pos", object, &DObject::pos, &DObject::setPos)
+ || attr("rect", object, &DObject::rect, &DObject::setRect)
+ || attr("auto-sized", object, &DObject::isAutoSized, &DObject::setAutoSized)
+ || attr("visual-role", object, &visualRole, &setVisualRole)
+ || attr("visual-role2", object, &DObject::visualSecondaryRole, &DObject::setVisualSecondaryRole)
+ || attr("visual-emphasized", object, &DObject::isVisualEmphasized, &DObject::setVisualEmphasized)
+ || attr("stereotype-display", object, &DObject::stereotypeDisplay, &DObject::setStereotypeDisplay)
// depth is not persistent
|| end;
}
@@ -158,11 +160,11 @@ inline void Access<Archive, DClass>::serialize(Archive &archive, DClass &klass)
{
archive || tag(klass)
|| base<DObject>(klass)
- || attr(QStringLiteral("namespace"), klass, &DClass::umlNamespace, &DClass::setUmlNamespace)
- || attr(QStringLiteral("template"), klass, &DClass::templateParameters, &DClass::setTemplateParameters)
- || attr(QStringLiteral("template-display"), klass, &DClass::templateDisplay, &DClass::setTemplateDisplay)
- || attr(QStringLiteral("show-all-members"), klass, &DClass::showAllMembers, &DClass::setShowAllMembers)
- || attr(QStringLiteral("visible-members"), klass, &DClass::visibleMembers, &DClass::setVisibleMembers)
+ || attr("namespace", klass, &DClass::umlNamespace, &DClass::setUmlNamespace)
+ || attr("template", klass, &DClass::templateParameters, &DClass::setTemplateParameters)
+ || attr("template-display", klass, &DClass::templateDisplay, &DClass::setTemplateDisplay)
+ || attr("show-all-members", klass, &DClass::showAllMembers, &DClass::setShowAllMembers)
+ || attr("visible-members", klass, &DClass::visibleMembers, &DClass::setVisibleMembers)
|| end;
}
@@ -180,7 +182,7 @@ inline void Access<Archive, DComponent>::serialize(Archive &archive, DComponent
{
archive || tag(component)
|| base<DObject>(component)
- || attr(QStringLiteral("plain-shape"), component, &DComponent::isPlainShape, &DComponent::setPlainShape)
+ || attr("plain-shape", component, &DComponent::isPlainShape, &DComponent::setPlainShape)
|| end;
}
@@ -215,9 +217,9 @@ inline void Access<Archive, DItem>::serialize(Archive &archive, DItem &item)
{
archive || tag(item)
|| base<DObject>(item)
- || attr(QStringLiteral("variety"), item, &DItem::variety, &DItem::setVariety)
- || attr(QStringLiteral("shape-editable"), item, &DItem::isShapeEditable, &DItem::setShapeEditable)
- || attr(QStringLiteral("shape"), item, &DItem::shape, &DItem::setShape)
+ || attr("variety", item, &DItem::variety, &DItem::setVariety)
+ || attr("shape-editable", item, &DItem::isShapeEditable, &DItem::setShapeEditable)
+ || attr("shape", item, &DItem::shape, &DItem::setShape)
|| end;
}
@@ -234,12 +236,12 @@ inline void Access<Archive, DRelation>::serialize(Archive &archive, DRelation &r
{
archive || tag(relation)
|| base<DElement>(relation)
- || attr(QStringLiteral("object"), relation, &DRelation::modelUid, &DRelation::setModelUid)
- || attr(QStringLiteral("stereotypes"), relation, &DRelation::stereotypes, &DRelation::setStereotypes)
- || attr(QStringLiteral("a"), relation, &DRelation::endAUid, &DRelation::setEndAUid)
- || attr(QStringLiteral("b"), relation, &DRelation::endBUid, &DRelation::setEndBUid)
- || attr(QStringLiteral("name"), relation, &DRelation::name, &DRelation::setName)
- || attr(QStringLiteral("points"), relation, &DRelation::intermediatePoints, &DRelation::setIntermediatePoints)
+ || attr("object", relation, &DRelation::modelUid, &DRelation::setModelUid)
+ || attr("stereotypes", relation, &DRelation::stereotypes, &DRelation::setStereotypes)
+ || attr("a", relation, &DRelation::endAUid, &DRelation::setEndAUid)
+ || attr("b", relation, &DRelation::endBUid, &DRelation::setEndBUid)
+ || attr("name", relation, &DRelation::name, &DRelation::setName)
+ || attr("points", relation, &DRelation::intermediatePoints, &DRelation::setIntermediatePoints)
|| end;
}
@@ -254,7 +256,7 @@ template<class Archive>
inline void Access<Archive, DRelation::IntermediatePoint>::serialize(Archive &archive, DRelation::IntermediatePoint &point)
{
archive || tag(point)
- || attr(QStringLiteral("pos"), point, &DRelation::IntermediatePoint::pos, &DRelation::IntermediatePoint::setPos)
+ || attr("pos", point, &DRelation::IntermediatePoint::pos, &DRelation::IntermediatePoint::setPos)
|| end;
}
@@ -289,7 +291,7 @@ inline void Access<Archive, DDependency>::serialize(Archive &archive, DDependenc
{
archive || tag(dependency)
|| base<DRelation>(dependency)
- || attr(QStringLiteral("direction"), dependency, &DDependency::direction, &DDependency::setDirection)
+ || attr("direction", dependency, &DDependency::direction, &DDependency::setDirection)
|| end;
}
@@ -304,10 +306,10 @@ template<class Archive>
inline void Access<Archive, DAssociationEnd>::serialize(Archive &archive, DAssociationEnd &associationEnd)
{
archive || tag(associationEnd)
- || attr(QStringLiteral("name"), associationEnd, &DAssociationEnd::name, &DAssociationEnd::setName)
- || attr(QStringLiteral("cradinality"), associationEnd, &DAssociationEnd::cardinality, &DAssociationEnd::setCardinatlity)
- || attr(QStringLiteral("navigable"), associationEnd, &DAssociationEnd::isNavigable, &DAssociationEnd::setNavigable)
- || attr(QStringLiteral("kind"), associationEnd, &DAssociationEnd::kind, &DAssociationEnd::setKind)
+ || attr("name", associationEnd, &DAssociationEnd::name, &DAssociationEnd::setName)
+ || attr("cradinality", associationEnd, &DAssociationEnd::cardinality, &DAssociationEnd::setCardinatlity)
+ || attr("navigable", associationEnd, &DAssociationEnd::isNavigable, &DAssociationEnd::setNavigable)
+ || attr("kind", associationEnd, &DAssociationEnd::kind, &DAssociationEnd::setKind)
|| end;
}
@@ -321,14 +323,47 @@ inline void Access<Archive, DAssociation>::serialize(Archive &archive, DAssociat
{
archive || tag(association)
|| base<DRelation>(association)
- || attr(QStringLiteral("class"), association, &DAssociation::assoicationClassUid, &DAssociation::setAssociationClassUid)
- || attr(QStringLiteral("a"), association, &DAssociation::endA, &DAssociation::setEndA)
- || attr(QStringLiteral("b"), association, &DAssociation::endB, &DAssociation::setEndB)
+ || attr("class", association, &DAssociation::assoicationClassUid, &DAssociation::setAssociationClassUid)
+ || attr("a", association, &DAssociation::endA, &DAssociation::setEndA)
+ || attr("b", association, &DAssociation::endB, &DAssociation::setEndB)
|| end;
}
QARK_ACCESS_SPECIALIZE(QXmlInArchive, QXmlOutArchive, DAssociation)
+// DConnection
+
+QARK_REGISTER_TYPE_NAME(DConnectionEnd, "DConnectionEnd")
+QARK_ACCESS_SERIALIZE(DConnectionEnd)
+
+template<class Archive>
+inline void Access<Archive, DConnectionEnd>::serialize(Archive &archive, DConnectionEnd &connectionEnd)
+{
+ archive || tag(connectionEnd)
+ || attr("name", connectionEnd, &DConnectionEnd::name, &DConnectionEnd::setName)
+ || attr("cradinality", connectionEnd, &DConnectionEnd::cardinality, &DConnectionEnd::setCardinatlity)
+ || attr("navigable", connectionEnd, &DConnectionEnd::isNavigable, &DConnectionEnd::setNavigable)
+ || end;
+}
+
+QARK_REGISTER_TYPE_NAME(DConnection, "DConnection")
+QARK_REGISTER_DERIVED_CLASS(QXmlInArchive, QXmlOutArchive, DConnection, DElement)
+QARK_REGISTER_DERIVED_CLASS(QXmlInArchive, QXmlOutArchive, DConnection, DRelation)
+QARK_ACCESS_SERIALIZE(DConnection)
+
+template<class Archive>
+inline void Access<Archive, DConnection>::serialize(Archive &archive, DConnection &connection)
+{
+ archive || tag(connection)
+ || base<DRelation>(connection)
+ || attr("custom-relation", connection, &DConnection::customRelationId, &DConnection::setCustomRelationId)
+ || attr("a", connection, &DConnection::endA, &DConnection::setEndA)
+ || attr("b", connection, &DConnection::endB, &DConnection::setEndB)
+ || end;
+}
+
+QARK_ACCESS_SPECIALIZE(QXmlInArchive, QXmlOutArchive, DConnection)
+
// DAnnotation
QARK_REGISTER_TYPE_NAME(DAnnotation, "DAnnotation")
@@ -340,11 +375,11 @@ inline void Access<Archive, DAnnotation>::serialize(Archive &archive, DAnnotatio
{
archive || tag(annotation)
|| base<DElement>(annotation)
- || attr(QStringLiteral("text"), annotation, &DAnnotation::text, &DAnnotation::setText)
- || attr(QStringLiteral("pos"), annotation, &DAnnotation::pos, &DAnnotation::setPos)
- || attr(QStringLiteral("rect"), annotation, &DAnnotation::rect, &DAnnotation::setRect)
- || attr(QStringLiteral("auto-sized"), annotation, &DAnnotation::isAutoSized, &DAnnotation::setAutoSized)
- || attr(QStringLiteral("visual-role"), annotation, &DAnnotation::visualRole, &DAnnotation::setVisualRole)
+ || attr("text", annotation, &DAnnotation::text, &DAnnotation::setText)
+ || attr("pos", annotation, &DAnnotation::pos, &DAnnotation::setPos)
+ || attr("rect", annotation, &DAnnotation::rect, &DAnnotation::setRect)
+ || attr("auto-sized", annotation, &DAnnotation::isAutoSized, &DAnnotation::setAutoSized)
+ || attr("visual-role", annotation, &DAnnotation::visualRole, &DAnnotation::setVisualRole)
|| end;
}
@@ -361,12 +396,31 @@ inline void Access<Archive, DBoundary>::serialize(Archive &archive, DBoundary &b
{
archive || tag(boundary)
|| base<DElement>(boundary)
- || attr(QStringLiteral("text"), boundary, &DBoundary::text, &DBoundary::setText)
- || attr(QStringLiteral("pos"), boundary, &DBoundary::pos, &DBoundary::setPos)
- || attr(QStringLiteral("rect"), boundary, &DBoundary::rect, &DBoundary::setRect)
+ || attr("text", boundary, &DBoundary::text, &DBoundary::setText)
+ || attr("pos", boundary, &DBoundary::pos, &DBoundary::setPos)
+ || attr("rect", boundary, &DBoundary::rect, &DBoundary::setRect)
|| end;
}
QARK_ACCESS_SPECIALIZE(QXmlInArchive, QXmlOutArchive, DBoundary)
+// DSwimlane
+
+QARK_REGISTER_TYPE_NAME(DSwimlane, "DSwimlane")
+QARK_REGISTER_DERIVED_CLASS(QXmlInArchive, QXmlOutArchive, DSwimlane, DElement)
+QARK_ACCESS_SERIALIZE(DSwimlane)
+
+template<class Archive>
+inline void Access<Archive, DSwimlane>::serialize(Archive &archive, DSwimlane &swimlane)
+{
+ archive || tag(swimlane)
+ || base<DElement>(swimlane)
+ || attr("text", swimlane, &DSwimlane::text, &DSwimlane::setText)
+ || attr("horizontal", swimlane, &DSwimlane::isHorizontal, &DSwimlane::setHorizontal)
+ || attr("pos", swimlane, &DSwimlane::pos, &DSwimlane::setPos)
+ || end;
+}
+
+QARK_ACCESS_SPECIALIZE(QXmlInArchive, QXmlOutArchive, DSwimlane)
+
} // namespace qark
diff --git a/src/libs/modelinglib/qmt/serializer/infrastructureserializer.h b/src/libs/modelinglib/qmt/serializer/infrastructureserializer.h
index 1814fb6a9da..29a0cc69ad0 100644
--- a/src/libs/modelinglib/qmt/serializer/infrastructureserializer.h
+++ b/src/libs/modelinglib/qmt/serializer/infrastructureserializer.h
@@ -57,9 +57,9 @@ inline void load(Archive &archive, qmt::Uid &uid)
template<class Archive, class T>
inline void serialize(Archive &archive, qmt::Handle<T> &handle)
{
- archive || tag(QStringLiteral("handle"), handle)
- || attr(QStringLiteral("uid"), handle, &qmt::Handle<T>::uid, &qmt::Handle<T>::setUid)
- || attr(QStringLiteral("target"), handle, &qmt::Handle<T>::target, &qmt::Handle<T>::setTarget)
+ archive || tag("handle", handle)
+ || attr("uid", handle, &qmt::Handle<T>::uid, &qmt::Handle<T>::setUid)
+ || attr("target", handle, &qmt::Handle<T>::target, &qmt::Handle<T>::setTarget)
|| end;
}
@@ -68,8 +68,8 @@ inline void serialize(Archive &archive, qmt::Handle<T> &handle)
template<class Archive, class T>
inline void serialize(Archive &archive, qmt::Handles<T> &handles)
{
- archive || tag(QStringLiteral("handles"), handles)
- || attr(QStringLiteral("handles"), handles, &qmt::Handles<T>::get, &qmt::Handles<T>::set)
+ archive || tag("handles", handles)
+ || attr("handles", handles, &qmt::Handles<T>::get, &qmt::Handles<T>::set)
|| end;
}
diff --git a/src/libs/modelinglib/qmt/serializer/modelserializer.cpp b/src/libs/modelinglib/qmt/serializer/modelserializer.cpp
index e141c050e9a..66a96472dee 100644
--- a/src/libs/modelinglib/qmt/serializer/modelserializer.cpp
+++ b/src/libs/modelinglib/qmt/serializer/modelserializer.cpp
@@ -41,6 +41,7 @@
#include "qmt/model/mdependency.h"
#include "qmt/model/massociation.h"
#include "qmt/model/minheritance.h"
+#include "qmt/model/mconnection.h"
#include "qmt/diagram/delement.h"
@@ -79,8 +80,8 @@ inline void Access<Archive, MSourceExpansion>::serialize(Archive &archive, MSour
{
archive || tag(sourceExpansion)
|| base<MExpansion>(sourceExpansion)
- || attr(QStringLiteral("source"), sourceExpansion, &MSourceExpansion::sourceId, &MSourceExpansion::setSourceId)
- || attr(QStringLiteral("transient"), sourceExpansion, &MSourceExpansion::isTransient, &MSourceExpansion::setTransient)
+ || attr("source", sourceExpansion, &MSourceExpansion::sourceId, &MSourceExpansion::setSourceId)
+ || attr("transient", sourceExpansion, &MSourceExpansion::isTransient, &MSourceExpansion::setTransient)
|| end;
}
@@ -95,10 +96,10 @@ template<class Archive>
inline void Access<Archive, MElement>::serialize(Archive &archive, MElement &element)
{
archive || tag(element)
- || attr(QStringLiteral("uid"), element, &MElement::uid, &MElement::setUid)
- || attr(QStringLiteral("flags"), element, &MElement::flags, &MElement::setFlags)
- || attr(QStringLiteral("expansion"), element, &MElement::expansion, &MElement::setExpansion)
- || attr(QStringLiteral("stereotypes"), element, &MElement::stereotypes, &MElement::setStereotypes)
+ || attr("uid", element, &MElement::uid, &MElement::setUid)
+ || attr("flags", element, &MElement::flags, &MElement::setFlags)
+ || attr("expansion", element, &MElement::expansion, &MElement::setExpansion)
+ || attr("stereotypes", element, &MElement::stereotypes, &MElement::setStereotypes)
|| end;
}
@@ -115,9 +116,9 @@ inline void Access<Archive, MObject>::serialize(Archive &archive, MObject &objec
{
archive || tag(object)
|| base<MElement>(object)
- || attr(QStringLiteral("name"), object, &MObject::name, &MObject::setName)
- || attr(QStringLiteral("children"), object, &MObject::children, &MObject::setChildren)
- || attr(QStringLiteral("relations"), object, &MObject::relations, &MObject::setRelations)
+ || attr("name", object, &MObject::name, &MObject::setName)
+ || attr("children", object, &MObject::children, &MObject::setChildren)
+ || attr("relations", object, &MObject::relations, &MObject::setRelations)
|| end;
}
@@ -152,9 +153,9 @@ inline void Access<Archive, MClass>::serialize(Archive &archive, MClass &klass)
{
archive || tag(klass)
|| base<MObject>(klass)
- || attr(QStringLiteral("namespace"), klass, &MClass::umlNamespace, &MClass::setUmlNamespace)
- || attr(QStringLiteral("template"), klass, &MClass::templateParameters, &MClass::setTemplateParameters)
- || attr(QStringLiteral("members"), klass, &MClass::members, &MClass::setMembers)
+ || attr("namespace", klass, &MClass::umlNamespace, &MClass::setUmlNamespace)
+ || attr("template", klass, &MClass::templateParameters, &MClass::setTemplateParameters)
+ || attr("members", klass, &MClass::members, &MClass::setMembers)
|| end;
}
@@ -169,13 +170,13 @@ template<class Archive>
inline void Access<Archive, MClassMember>::serialize(Archive &archive, MClassMember &member)
{
archive || tag(member)
- || attr(QStringLiteral("uid"), member, &MClassMember::uid, &MClassMember::setUid)
- || attr(QStringLiteral("stereotypes"), member, &MClassMember::stereotypes, &MClassMember::setStereotypes)
- || attr(QStringLiteral("group"), member, &MClassMember::group, &MClassMember::setGroup)
- || attr(QStringLiteral("visibility"), member, &MClassMember::visibility, &MClassMember::setVisibility)
- || attr(QStringLiteral("type"), member, &MClassMember::memberType, &MClassMember::setMemberType)
- || attr(QStringLiteral("properties"), member, &MClassMember::properties, &MClassMember::setProperties)
- || attr(QStringLiteral("declaration"), member, &MClassMember::declaration, &MClassMember::setDeclaration)
+ || attr("uid", member, &MClassMember::uid, &MClassMember::setUid)
+ || attr("stereotypes", member, &MClassMember::stereotypes, &MClassMember::setStereotypes)
+ || attr("group", member, &MClassMember::group, &MClassMember::setGroup)
+ || attr("visibility", member, &MClassMember::visibility, &MClassMember::setVisibility)
+ || attr("type", member, &MClassMember::memberType, &MClassMember::setMemberType)
+ || attr("properties", member, &MClassMember::properties, &MClassMember::setProperties)
+ || attr("declaration", member, &MClassMember::declaration, &MClassMember::setDeclaration)
|| end;
}
@@ -210,9 +211,9 @@ inline void Access<Archive, MDiagram>::serialize(Archive &archive, MDiagram &dia
{
archive || tag(diagram)
|| base<MObject>(diagram)
- || attr(QStringLiteral("elements"), diagram, &MDiagram::diagramElements, &MDiagram::setDiagramElements)
- || attr(QStringLiteral("last-modified"), diagram, &MDiagram::lastModified, &MDiagram::setLastModified)
- || attr(QStringLiteral("toolbarid"), diagram, &MDiagram::toolbarId, &MDiagram::setToolbarId)
+ || attr("elements", diagram, &MDiagram::diagramElements, &MDiagram::setDiagramElements)
+ || attr("last-modified", diagram, &MDiagram::lastModified, &MDiagram::setLastModified)
+ || attr("toolbarid", diagram, &MDiagram::toolbarId, &MDiagram::setToolbarId)
|| end;
}
@@ -248,9 +249,9 @@ inline void Access<Archive, MItem>::serialize(Archive &archive, MItem &item)
{
archive || tag(item)
|| base<MObject>(item)
- || attr(QStringLiteral("variety-editable"), item, &MItem::isVarietyEditable, &MItem::setVarietyEditable)
- || attr(QStringLiteral("variety"), item, &MItem::variety, &MItem::setVariety)
- || attr(QStringLiteral("shape-editable"), item, &MItem::isShapeEditable, &MItem::setShapeEditable)
+ || attr("variety-editable", item, &MItem::isVarietyEditable, &MItem::setVarietyEditable)
+ || attr("variety", item, &MItem::variety, &MItem::setVariety)
+ || attr("shape-editable", item, &MItem::isShapeEditable, &MItem::setShapeEditable)
|| end;
}
@@ -267,9 +268,9 @@ inline void Access<Archive, MRelation>::serialize(Archive &archive, MRelation &r
{
archive || tag(relation)
|| base<MElement>(relation)
- || attr(QStringLiteral("name"), relation, &MRelation::name, &MRelation::setName)
- || attr(QStringLiteral("a"), relation, &MRelation::endAUid, &MRelation::setEndAUid)
- || attr(QStringLiteral("b"), relation, &MRelation::endBUid, &MRelation::setEndBUid)
+ || attr("name", relation, &MRelation::name, &MRelation::setName)
+ || attr("a", relation, &MRelation::endAUid, &MRelation::setEndAUid)
+ || attr("b", relation, &MRelation::endBUid, &MRelation::setEndBUid)
|| end;
}
@@ -304,7 +305,7 @@ inline void Access<Archive, MDependency>::serialize(Archive &archive, MDependenc
{
archive || tag(dependency)
|| base<MRelation>(dependency)
- || attr(QStringLiteral("direction"), dependency, &MDependency::direction, &MDependency::setDirection)
+ || attr("direction", dependency, &MDependency::direction, &MDependency::setDirection)
|| end;
}
@@ -319,10 +320,10 @@ template<class Archive>
inline void Access<Archive, MAssociationEnd>::serialize(Archive &archive, MAssociationEnd &associationEnd)
{
archive || tag(associationEnd)
- || attr(QStringLiteral("name"), associationEnd, &MAssociationEnd::name, &MAssociationEnd::setName)
- || attr(QStringLiteral("cardinality"), associationEnd, &MAssociationEnd::cardinality, &MAssociationEnd::setCardinality)
- || attr(QStringLiteral("navigable"), associationEnd, &MAssociationEnd::isNavigable, &MAssociationEnd::setNavigable)
- || attr(QStringLiteral("kind"), associationEnd, &MAssociationEnd::kind, &MAssociationEnd::setKind)
+ || attr("name", associationEnd, &MAssociationEnd::name, &MAssociationEnd::setName)
+ || attr("cardinality", associationEnd, &MAssociationEnd::cardinality, &MAssociationEnd::setCardinality)
+ || attr("navigable", associationEnd, &MAssociationEnd::isNavigable, &MAssociationEnd::setNavigable)
+ || attr("kind", associationEnd, &MAssociationEnd::kind, &MAssociationEnd::setKind)
|| end;
}
@@ -336,12 +337,45 @@ inline void Access<Archive, MAssociation>::serialize(Archive &archive, MAssociat
{
archive || tag(association)
|| base<MRelation>(association)
- || attr(QStringLiteral("class"), association, &MAssociation::assoicationClassUid, &MAssociation::setAssociationClassUid)
- || attr(QStringLiteral("a"), association, &MAssociation::endA, &MAssociation::setEndA)
- || attr(QStringLiteral("b"), association, &MAssociation::endB, &MAssociation::setEndB)
+ || attr("class", association, &MAssociation::assoicationClassUid, &MAssociation::setAssociationClassUid)
+ || attr("a", association, &MAssociation::endA, &MAssociation::setEndA)
+ || attr("b", association, &MAssociation::endB, &MAssociation::setEndB)
|| end;
}
QARK_ACCESS_SPECIALIZE(QXmlInArchive, QXmlOutArchive, MAssociation)
+// MConnection
+
+QARK_REGISTER_TYPE_NAME(MConnectionEnd, "MConnectionEnd")
+QARK_ACCESS_SERIALIZE(MConnectionEnd)
+
+template<class Archive>
+inline void Access<Archive, MConnectionEnd>::serialize(Archive &archive, MConnectionEnd &connectionEnd)
+{
+ archive || tag(connectionEnd)
+ || attr("name", connectionEnd, &MConnectionEnd::name, &MConnectionEnd::setName)
+ || attr("cardinality", connectionEnd, &MConnectionEnd::cardinality, &MConnectionEnd::setCardinality)
+ || attr("navigable", connectionEnd, &MConnectionEnd::isNavigable, &MConnectionEnd::setNavigable)
+ || end;
+}
+
+QARK_REGISTER_TYPE_NAME(MConnection, "MConnection")
+QARK_REGISTER_DERIVED_CLASS(QXmlInArchive, QXmlOutArchive, MConnection, MElement)
+QARK_REGISTER_DERIVED_CLASS(QXmlInArchive, QXmlOutArchive, MConnection, MRelation)
+QARK_ACCESS_SERIALIZE(MConnection)
+
+template<class Archive>
+inline void Access<Archive, MConnection>::serialize(Archive &archive, MConnection &connection)
+{
+ archive || tag(connection)
+ || base<MRelation>(connection)
+ || attr("custom-relation", connection, &MConnection::customRelationId, &MConnection::setCustomRelationId)
+ || attr("a", connection, &MConnection::endA, &MConnection::setEndA)
+ || attr("b", connection, &MConnection::endB, &MConnection::setEndB)
+ || end;
+}
+
+QARK_ACCESS_SPECIALIZE(QXmlInArchive, QXmlOutArchive, MConnection)
+
} // namespace qark
diff --git a/src/libs/modelinglib/qmt/serializer/projectserializer.cpp b/src/libs/modelinglib/qmt/serializer/projectserializer.cpp
index 13338ed175f..d1ddc8de73b 100644
--- a/src/libs/modelinglib/qmt/serializer/projectserializer.cpp
+++ b/src/libs/modelinglib/qmt/serializer/projectserializer.cpp
@@ -51,10 +51,10 @@ QARK_REGISTER_TYPE_NAME(Project, "Project")
template<class Archive>
void serialize(Archive &archive, Project &project)
{
- archive || qark::tag(QStringLiteral("project"), project)
- || qark::attr(QStringLiteral("uid"), project, &Project::uid, &Project::setUid)
- || qark::attr(QStringLiteral("root-package"), project, &Project::rootPackage, &Project::setRootPackage)
- || qark::attr(QStringLiteral("config-path"), project, &Project::configPath, &Project::setConfigPath)
+ archive || qark::tag("project", project)
+ || qark::attr("uid", project, &Project::uid, &Project::setUid)
+ || qark::attr("root-package", project, &Project::rootPackage, &Project::setRootPackage)
+ || qark::attr("config-path", project, &Project::configPath, &Project::setConfigPath)
|| qark::end;
}
@@ -72,7 +72,7 @@ ProjectSerializer::~ProjectSerializer()
void ProjectSerializer::save(const QString &fileName, const Project *project)
{
- QMT_CHECK(project);
+ QMT_ASSERT(project, return);
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
@@ -108,7 +108,7 @@ QByteArray ProjectSerializer::save(const Project *project)
void ProjectSerializer::load(const QString &fileName, Project *project)
{
- QMT_CHECK(project);
+ QMT_ASSERT(project, return);
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly))
@@ -133,9 +133,9 @@ void ProjectSerializer::load(const QString &fileName, Project *project)
archive >> qark::end;
archive.endDocument();
} catch (const qark::QXmlInArchive::FileFormatException &) {
- throw FileIOException(QStringLiteral("illegal file format"), fileName);
+ throw FileIOException("illegal file format", fileName);
} catch (...) {
- throw FileIOException(QStringLiteral("serialization error"), fileName);
+ throw FileIOException("serialization error", fileName);
}
#ifdef USE_COMPRESSED_FILES
@@ -157,7 +157,7 @@ void ProjectSerializer::write(QXmlStreamWriter *writer, const Project *project)
archive << qark::end;
archive.endDocument();
} catch (...) {
- throw IOException(QStringLiteral("serialization error"));
+ throw IOException("serialization error");
}
}
diff --git a/src/libs/modelinglib/qmt/stereotype/customrelation.cpp b/src/libs/modelinglib/qmt/stereotype/customrelation.cpp
new file mode 100644
index 00000000000..b51abbe3672
--- /dev/null
+++ b/src/libs/modelinglib/qmt/stereotype/customrelation.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Jochen Becher
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "customrelation.h"
+
+namespace qmt {
+
+void CustomRelation::End::setEndItems(const QList<QString> &endItems)
+{
+ m_endItems = endItems;
+}
+
+void CustomRelation::End::setRole(const QString &role)
+{
+ m_role = role;
+}
+
+void CustomRelation::End::setCardinality(const QString &cardinality)
+{
+ m_cardinality = cardinality;
+}
+
+void CustomRelation::End::setNavigable(bool navigable)
+{
+ m_navigable = navigable;
+}
+
+void CustomRelation::End::setRelationship(CustomRelation::Relationship relationship)
+{
+ m_relationship = relationship;
+}
+
+void CustomRelation::End::setHead(CustomRelation::Head head)
+{
+ m_head = head;
+}
+
+void CustomRelation::End::setShape(const IconShape &shape)
+{
+ m_shape = shape;
+}
+
+
+CustomRelation::CustomRelation()
+{
+}
+
+CustomRelation::~CustomRelation()
+{
+}
+
+bool CustomRelation::isNull() const
+{
+ return m_id.isEmpty();
+}
+
+void CustomRelation::setElement(CustomRelation::Element element)
+{
+ m_element = element;
+}
+
+void CustomRelation::setId(const QString &id)
+{
+ m_id = id;
+}
+
+void CustomRelation::setTitle(const QString &title)
+{
+ m_title = title;
+}
+
+void CustomRelation::setEndItems(const QList<QString> &endItems)
+{
+ m_endItems = endItems;
+}
+
+void CustomRelation::setStereotypes(const QSet<QString> &stereotypes)
+{
+ m_stereotypes = stereotypes;
+}
+
+void CustomRelation::setName(const QString &name)
+{
+ m_name = name;
+}
+
+void CustomRelation::setDirection(CustomRelation::Direction direction)
+{
+ m_direction = direction;
+}
+
+void CustomRelation::setEndA(const CustomRelation::End &end)
+{
+ m_endA = end;
+}
+
+void CustomRelation::setEndB(const CustomRelation::End &end)
+{
+ m_endB = end;
+}
+
+void CustomRelation::setShaftPattern(CustomRelation::ShaftPattern shaftPattern)
+{
+ m_shaftPattern = shaftPattern;
+}
+
+void CustomRelation::setColorType(CustomRelation::ColorType colorType)
+{
+ m_colorType = colorType;
+}
+
+void CustomRelation::setColor(const QColor &color)
+{
+ m_color = color;
+}
+
+} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/stereotype/customrelation.h b/src/libs/modelinglib/qmt/stereotype/customrelation.h
new file mode 100644
index 00000000000..0b72be20fdf
--- /dev/null
+++ b/src/libs/modelinglib/qmt/stereotype/customrelation.h
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Jochen Becher
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "iconshape.h"
+
+#include <QString>
+#include <QList>
+#include <QSet>
+#include <QColor>
+
+namespace qmt {
+
+class QMT_EXPORT CustomRelation
+{
+public:
+ enum class Element {
+ Relation,
+ Dependency,
+ Inheritance,
+ Association
+ };
+
+ enum class Direction {
+ AtoB,
+ BToA,
+ Bi
+ };
+
+ enum class Relationship {
+ Association,
+ Aggregation,
+ Composition
+ };
+
+ enum class ShaftPattern {
+ Solid,
+ Dash,
+ Dot,
+ DashDot,
+ DashDotDot
+ };
+
+ enum class Head {
+ None,
+ Shape,
+ Arrow,
+ Triangle,
+ FilledTriangle,
+ Diamond,
+ FilledDiamond
+ };
+
+ enum class ColorType {
+ EndA,
+ EndB,
+ Custom
+ };
+
+ class End {
+ public:
+ QList<QString> endItems() const { return m_endItems; }
+ void setEndItems(const QList<QString> &endItems);
+ QString role() const { return m_role; }
+ void setRole(const QString &role);
+ QString cardinality() const { return m_cardinality; }
+ void setCardinality(const QString &cardinality);
+ bool navigable() const { return m_navigable; }
+ void setNavigable(bool navigable);
+ Relationship relationship() const { return m_relationship; }
+ void setRelationship(Relationship relationship);
+ Head head() const { return m_head; }
+ void setHead(Head head);
+ IconShape shape() const { return m_shape; }
+ void setShape(const IconShape &shape);
+
+ private:
+ QList<QString> m_endItems;
+ QString m_role;
+ QString m_cardinality;
+ bool m_navigable = false;
+ Relationship m_relationship = Relationship::Association;
+ Head m_head = Head::None;
+ IconShape m_shape;
+ };
+
+ CustomRelation();
+ ~CustomRelation();
+
+ bool isNull() const;
+ Element element() const { return m_element; }
+ void setElement(Element element);
+ QString id() const { return m_id; }
+ void setId(const QString &id);
+ QString title() const { return m_title; }
+ void setTitle(const QString &title);
+ QList<QString> endItems() const { return m_endItems; }
+ void setEndItems(const QList<QString> &endItems);
+ QSet<QString> stereotypes() const { return m_stereotypes; }
+ void setStereotypes(const QSet<QString> &stereotypes);
+ QString name() const { return m_name; }
+ void setName(const QString &name);
+ Direction direction() const { return m_direction; }
+ void setDirection(Direction direction);
+ End endA() const { return m_endA; }
+ void setEndA(const End &end);
+ End endB() const { return m_endB; }
+ void setEndB(const End &end);
+ ShaftPattern shaftPattern() const { return m_shaftPattern; }
+ void setShaftPattern(ShaftPattern shaftPattern);
+ ColorType colorType() const { return m_colorType; }
+ void setColorType(ColorType colorType);
+ QColor color() const { return m_color; }
+ void setColor(const QColor &color);
+
+private:
+ Element m_element = Element::Relation;
+ QString m_id;
+ QString m_title;
+ QList<QString> m_endItems;
+ QSet<QString> m_stereotypes;
+ QString m_name;
+ Direction m_direction = Direction::AtoB;
+ End m_endA;
+ End m_endB;
+ ShaftPattern m_shaftPattern = ShaftPattern::Solid;
+ ColorType m_colorType = ColorType::EndA;
+ QColor m_color;
+};
+
+inline uint qHash(CustomRelation::Relationship relationship) {
+ return ::qHash(static_cast<int>(relationship));
+}
+
+inline uint qHash(CustomRelation::ShaftPattern pattern) {
+ return ::qHash(static_cast<int>(pattern));
+}
+
+inline uint qHash(CustomRelation::Head head) {
+ return ::qHash(static_cast<int>(head));
+}
+
+} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/stereotype/iconshape.cpp b/src/libs/modelinglib/qmt/stereotype/iconshape.cpp
index d9a4be058be..f138684b64e 100644
--- a/src/libs/modelinglib/qmt/stereotype/iconshape.cpp
+++ b/src/libs/modelinglib/qmt/stereotype/iconshape.cpp
@@ -34,11 +34,11 @@
#include <QPainter>
template<class T>
-QList<T *> CloneAll(const QList<T *> &rhs)
+QList<T *> cloneAll(const QList<T *> &rhs)
{
QList<T *> result;
foreach (T *t, rhs)
- result.append(t != 0 ? t->Clone() : 0);
+ result.append(t ? t->clone() : nullptr);
return result;
}
@@ -50,7 +50,7 @@ public:
IconShapePrivate() = default;
IconShapePrivate(const IconShapePrivate &rhs)
- : m_shapes(CloneAll(rhs.m_shapes))
+ : m_shapes(cloneAll(rhs.m_shapes))
{
}
@@ -63,7 +63,7 @@ public:
{
if (this != &rhs) {
qDeleteAll(m_shapes);
- m_shapes = CloneAll(rhs.m_shapes);
+ m_shapes = cloneAll(rhs.m_shapes);
}
return *this;
}
@@ -75,10 +75,10 @@ public:
PathShape *IconShape::IconShapePrivate::activePath()
{
- PathShape *pathShape = 0;
+ PathShape *pathShape = nullptr;
if (m_shapes.count() > 0)
pathShape = dynamic_cast<PathShape *>(m_shapes.last());
- if (pathShape == 0) {
+ if (!pathShape) {
pathShape = new PathShape();
m_shapes.append(pathShape);
}
@@ -132,6 +132,16 @@ void IconShape::addEllipse(const ShapePointF &center, const ShapeSizeF &radius)
d->m_shapes.append(new EllipseShape(center, radius));
}
+void IconShape::addDiamond(const ShapePointF &center, const ShapeSizeF &size, bool filled)
+{
+ d->m_shapes.append(new DiamondShape(center, size, filled));
+}
+
+void IconShape::addTriangle(const ShapePointF &center, const ShapeSizeF &size, bool filled)
+{
+ d->m_shapes.append(new TriangleShape(center, size, filled));
+}
+
void IconShape::addArc(const ShapePointF &center, const ShapeSizeF &radius, qreal startAngle, qreal spanAngle)
{
d->m_shapes.append(new ArcShape(center, radius, startAngle, spanAngle));
diff --git a/src/libs/modelinglib/qmt/stereotype/iconshape.h b/src/libs/modelinglib/qmt/stereotype/iconshape.h
index 0efea797ff8..215dc8adecf 100644
--- a/src/libs/modelinglib/qmt/stereotype/iconshape.h
+++ b/src/libs/modelinglib/qmt/stereotype/iconshape.h
@@ -54,6 +54,8 @@ public:
void addRoundedRect(const ShapePointF &pos, const ShapeSizeF &size, const ShapeValueF &radius);
void addCircle(const ShapePointF &center, const ShapeValueF &radius);
void addEllipse(const ShapePointF &center, const ShapeSizeF &radius);
+ void addDiamond(const ShapePointF &center, const ShapeSizeF &size, bool filled);
+ void addTriangle(const ShapePointF &center, const ShapeSizeF &size, bool filled);
void addArc(const ShapePointF &center, const ShapeSizeF &radius,
qreal startAngle, qreal spanAngle);
diff --git a/src/libs/modelinglib/qmt/stereotype/shape.h b/src/libs/modelinglib/qmt/stereotype/shape.h
index 467266b9614..9bf56bd5b28 100644
--- a/src/libs/modelinglib/qmt/stereotype/shape.h
+++ b/src/libs/modelinglib/qmt/stereotype/shape.h
@@ -35,7 +35,7 @@ class IShape
public:
virtual ~IShape() { }
- virtual IShape *Clone() const = 0;
+ virtual IShape *clone() const = 0;
virtual void accept(ShapeVisitor *visitor) = 0;
virtual void accept(ShapeConstVisitor *visitor) const = 0;
};
diff --git a/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.cpp b/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.cpp
index 552852c1e09..880835287ad 100644
--- a/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.cpp
+++ b/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.cpp
@@ -75,6 +75,37 @@ void ShapePaintVisitor::visitEllipse(const EllipseShape *shapeEllipse)
radius.width(), radius.height());
}
+void ShapePaintVisitor::visitDiamond(const DiamondShape *shapeDiamond)
+{
+ m_painter->save();
+ m_painter->setRenderHint(QPainter::Antialiasing, true);
+ QPainterPath path;
+ QPointF center = shapeDiamond->center().mapScaledTo(m_scaledOrigin, m_originalSize, m_baseSize, m_size);
+ QSizeF size = shapeDiamond->size().mapScaledTo(m_scaledOrigin, m_originalSize, m_baseSize, m_size);
+ path.moveTo(center + QPointF(0.0, size.height() / 2.0));
+ path.lineTo(center + QPointF(-size.width() / 2.0, 0.0));
+ path.lineTo(center + QPointF(0.0, -size.height() / 2.0));
+ path.lineTo(center + QPointF(size.width() / 2.0, 0.0));
+ path.closeSubpath();
+ m_painter->drawPath(path);
+ m_painter->restore();
+}
+
+void ShapePaintVisitor::visitTriangle(const TriangleShape *shapeTriangle)
+{
+ m_painter->save();
+ m_painter->setRenderHint(QPainter::Antialiasing, true);
+ QPainterPath path;
+ QPointF center = shapeTriangle->center().mapScaledTo(m_scaledOrigin, m_originalSize, m_baseSize, m_size);
+ QSizeF size = shapeTriangle->size().mapScaledTo(m_scaledOrigin, m_originalSize, m_baseSize, m_size);
+ path.moveTo(center + QPointF(size.width() / 2.0, size.height() / 2.0));
+ path.lineTo(center + QPointF(-size.width() / 2.0, size.height() / 2.0));
+ path.lineTo(center + QPointF(0.0, -size.height() / 2.0));
+ path.closeSubpath();
+ m_painter->drawPath(path);
+ m_painter->restore();
+}
+
void ShapePaintVisitor::visitArc(const ArcShape *shapeArc)
{
QSizeF radius = shapeArc->radius().mapScaledTo(m_scaledOrigin, m_originalSize, m_baseSize, m_size);
@@ -160,6 +191,31 @@ void ShapeSizeVisitor::visitEllipse(const EllipseShape *shapeEllipse)
m_boundingRect |= QRectF(shapeEllipse->center().mapScaledTo(m_scaledOrigin, m_originalSize, m_baseSize, m_size) - QPointF(radius.width(), radius.height()), radius * 2.0);
}
+void ShapeSizeVisitor::visitDiamond(const DiamondShape *shapeDiamond)
+{
+ QPainterPath path;
+ QPointF center = shapeDiamond->center().mapScaledTo(m_scaledOrigin, m_originalSize, m_baseSize, m_size);
+ QSizeF size = shapeDiamond->size().mapScaledTo(m_scaledOrigin, m_originalSize, m_baseSize, m_size);
+ path.moveTo(center + QPointF(0.0, size.height() / 2.0));
+ path.lineTo(center + QPointF(-size.width() / 2.0, 0.0));
+ path.lineTo(center + QPointF(0.0, -size.height() / 2.0));
+ path.lineTo(center + QPointF(size.width() / 2.0, 0.0));
+ path.closeSubpath();
+ m_boundingRect |= path.boundingRect();
+}
+
+void ShapeSizeVisitor::visitTriangle(const TriangleShape *shapeTriangle)
+{
+ QPainterPath path;
+ QPointF center = shapeTriangle->center().mapScaledTo(m_scaledOrigin, m_originalSize, m_baseSize, m_size);
+ QSizeF size = shapeTriangle->size().mapScaledTo(m_scaledOrigin, m_originalSize, m_baseSize, m_size);
+ path.moveTo(center + QPointF(size.width() / 2.0, size.height() / 2.0));
+ path.lineTo(center + QPointF(-size.width() / 2.0, size.height() / 2.0));
+ path.lineTo(center + QPointF(0.0, -size.height() / 2.0));
+ path.closeSubpath();
+ m_boundingRect |= path.boundingRect();
+}
+
void ShapeSizeVisitor::visitArc(const ArcShape *shapeArc)
{
// TODO this is the max bound rect; not the minimal one
diff --git a/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.h b/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.h
index 67a90ee6ac5..92e340e3e94 100644
--- a/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.h
+++ b/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.h
@@ -45,6 +45,8 @@ public:
void visitRoundedRect(const RoundedRectShape *shapeRoundedRect) override;
void visitCircle(const CircleShape *shapeCircle) override;
void visitEllipse(const EllipseShape *shapeEllipse) override;
+ void visitDiamond(const DiamondShape *shapeDiamond) override;
+ void visitTriangle(const TriangleShape *shapeTriangle) override;
void visitArc(const ArcShape *shapeArc) override;
void visitPath(const PathShape *shapePath) override;
@@ -69,6 +71,8 @@ public:
void visitRoundedRect(const RoundedRectShape *shapeRoundedRect) override;
void visitCircle(const CircleShape *shapeCircle) override;
void visitEllipse(const EllipseShape *shapeEllipse) override;
+ void visitDiamond(const DiamondShape *shapeDiamond) override;
+ void visitTriangle(const TriangleShape *shapeTriangle) override;
void visitArc(const ArcShape *shapeArc) override;
void visitPath(const PathShape *shapePath) override;
diff --git a/src/libs/modelinglib/qmt/stereotype/shapes.cpp b/src/libs/modelinglib/qmt/stereotype/shapes.cpp
index 05f6e61e5a5..0ee04f9bb08 100644
--- a/src/libs/modelinglib/qmt/stereotype/shapes.cpp
+++ b/src/libs/modelinglib/qmt/stereotype/shapes.cpp
@@ -27,7 +27,7 @@
namespace qmt {
-IShape *LineShape::Clone() const
+IShape *LineShape::clone() const
{
return new LineShape(*this);
}
@@ -42,7 +42,7 @@ void LineShape::accept(ShapeConstVisitor *visitor) const
visitor->visitLine(this);
}
-IShape *RectShape::Clone() const
+IShape *RectShape::clone() const
{
return new RectShape(*this);
}
@@ -57,7 +57,7 @@ void RectShape::accept(ShapeConstVisitor *visitor) const
visitor->visitRect(this);
}
-IShape *RoundedRectShape::Clone() const
+IShape *RoundedRectShape::clone() const
{
return new RoundedRectShape(*this);
}
@@ -72,7 +72,7 @@ void RoundedRectShape::accept(ShapeConstVisitor *visitor) const
visitor->visitRoundedRect(this);
}
-IShape *CircleShape::Clone() const
+IShape *CircleShape::clone() const
{
return new CircleShape(*this);
}
@@ -87,7 +87,7 @@ void CircleShape::accept(ShapeConstVisitor *visitor) const
visitor->visitCircle(this);
}
-IShape *EllipseShape::Clone() const
+IShape *EllipseShape::clone() const
{
return new EllipseShape(*this);
}
@@ -102,7 +102,37 @@ void EllipseShape::accept(ShapeConstVisitor *visitor) const
visitor->visitEllipse(this);
}
-IShape *ArcShape::Clone() const
+IShape *DiamondShape::clone() const
+{
+ return new DiamondShape(*this);
+}
+
+void DiamondShape::accept(ShapeVisitor *visitor)
+{
+ visitor->visitDiamond(this);
+}
+
+void DiamondShape::accept(ShapeConstVisitor *visitor) const
+{
+ visitor->visitDiamond(this);
+}
+
+IShape *TriangleShape::clone() const
+{
+ return new TriangleShape(*this);
+}
+
+void TriangleShape::accept(ShapeVisitor *visitor)
+{
+ visitor->visitTriangle(this);
+}
+
+void TriangleShape::accept(ShapeConstVisitor *visitor) const
+{
+ visitor->visitTriangle(this);
+}
+
+IShape *ArcShape::clone() const
{
return new ArcShape(*this);
}
@@ -125,7 +155,7 @@ PathShape::~PathShape()
{
}
-IShape *PathShape::Clone() const
+IShape *PathShape::clone() const
{
return new PathShape(*this);
}
diff --git a/src/libs/modelinglib/qmt/stereotype/shapes.h b/src/libs/modelinglib/qmt/stereotype/shapes.h
index 88f4c6e392f..145fcb4bb6a 100644
--- a/src/libs/modelinglib/qmt/stereotype/shapes.h
+++ b/src/libs/modelinglib/qmt/stereotype/shapes.h
@@ -49,7 +49,7 @@ public:
ShapePointF pos1() const { return m_pos1; }
ShapePointF pos2() const { return m_pos2; }
- IShape *Clone() const override;
+ IShape *clone() const override;
void accept(ShapeVisitor *visitor) override;
void accept(ShapeConstVisitor *visitor) const override;
@@ -72,7 +72,7 @@ public:
ShapePointF pos() const { return m_pos; }
ShapeSizeF size() const { return m_size; }
- IShape *Clone() const override;
+ IShape *clone() const override;
void accept(ShapeVisitor *visitor) override;
void accept(ShapeConstVisitor *visitor) const override;
@@ -97,7 +97,7 @@ public:
ShapeSizeF size() const { return m_size; }
ShapeValueF radius() const { return m_radius; }
- IShape *Clone() const override;
+ IShape *clone() const override;
void accept(ShapeVisitor *visitor) override;
void accept(ShapeConstVisitor *visitor) const override;
@@ -121,7 +121,7 @@ public:
ShapePointF center() const { return m_center; }
ShapeValueF radius() const { return m_radius; }
- IShape *Clone() const override;
+ IShape *clone() const override;
void accept(ShapeVisitor *visitor) override;
void accept(ShapeConstVisitor *visitor) const override;
@@ -144,7 +144,7 @@ public:
ShapePointF center() const { return m_center; }
ShapeSizeF radius() const { return m_radius; }
- IShape *Clone() const override;
+ IShape *clone() const override;
void accept(ShapeVisitor *visitor) override;
void accept(ShapeConstVisitor *visitor) const override;
@@ -153,6 +153,58 @@ private:
ShapeSizeF m_radius;
};
+class QMT_EXPORT DiamondShape : public IShape
+{
+public:
+ DiamondShape() = default;
+
+ DiamondShape(const ShapePointF &center, const ShapeSizeF &size, bool filled)
+ : m_center(center),
+ m_size(size),
+ m_filled(filled)
+ {
+ }
+
+ ShapePointF center() const { return m_center; }
+ ShapeSizeF size() const { return m_size; }
+ bool filled() const { return m_filled; }
+
+ IShape *clone() const override;
+ void accept(ShapeVisitor *visitor) override;
+ void accept(ShapeConstVisitor *visitor) const override;
+
+private:
+ ShapePointF m_center;
+ ShapeSizeF m_size;
+ bool m_filled = false;
+};
+
+class QMT_EXPORT TriangleShape : public IShape
+{
+public:
+ TriangleShape() = default;
+
+ TriangleShape(const ShapePointF &center, const ShapeSizeF &size, bool filled)
+ : m_center(center),
+ m_size(size),
+ m_filled(filled)
+ {
+ }
+
+ ShapePointF center() const { return m_center; }
+ ShapeSizeF size() const { return m_size; }
+ bool filled() const { return m_filled; }
+
+ IShape *clone() const override;
+ void accept(ShapeVisitor *visitor) override;
+ void accept(ShapeConstVisitor *visitor) const override;
+
+private:
+ ShapePointF m_center;
+ ShapeSizeF m_size;
+ bool m_filled = false;
+};
+
class QMT_EXPORT ArcShape : public IShape
{
public:
@@ -171,15 +223,15 @@ public:
qreal startAngle() const { return m_startAngle; }
qreal spanAngle() const { return m_spanAngle; }
- IShape *Clone() const override;
+ IShape *clone() const override;
void accept(ShapeVisitor *visitor) override;
void accept(ShapeConstVisitor *visitor) const override;
private:
ShapePointF m_center;
ShapeSizeF m_radius;
- qreal m_startAngle;
- qreal m_spanAngle;
+ qreal m_startAngle = 0.0;
+ qreal m_spanAngle = 0.0;
};
class QMT_EXPORT PathShape : public IShape
@@ -214,7 +266,7 @@ public:
QList<Element> elements() const { return m_elements; }
- IShape *Clone() const override;
+ IShape *clone() const override;
void accept(ShapeVisitor *visitor) override;
void accept(ShapeConstVisitor *visitor) const override;
diff --git a/src/libs/modelinglib/qmt/stereotype/shapevalue.h b/src/libs/modelinglib/qmt/stereotype/shapevalue.h
index 4b2f09a1dc7..8e184b147da 100644
--- a/src/libs/modelinglib/qmt/stereotype/shapevalue.h
+++ b/src/libs/modelinglib/qmt/stereotype/shapevalue.h
@@ -80,9 +80,9 @@ public:
qreal actualSize) const;
private:
- qreal m_value;
- Unit m_unit;
- Origin m_origin;
+ qreal m_value = 0.0;
+ Unit m_unit = UnitRelative;
+ Origin m_origin = OriginSmart;
};
class QMT_EXPORT ShapePointF
diff --git a/src/libs/modelinglib/qmt/stereotype/shapevisitor.h b/src/libs/modelinglib/qmt/stereotype/shapevisitor.h
index 6adbba12ba5..83f12ec5b83 100644
--- a/src/libs/modelinglib/qmt/stereotype/shapevisitor.h
+++ b/src/libs/modelinglib/qmt/stereotype/shapevisitor.h
@@ -32,6 +32,8 @@ class RectShape;
class RoundedRectShape;
class CircleShape;
class EllipseShape;
+class DiamondShape;
+class TriangleShape;
class ArcShape;
class PathShape;
@@ -45,6 +47,8 @@ public:
virtual void visitRoundedRect(RoundedRectShape *shapeRoundedRect) = 0;
virtual void visitCircle(CircleShape *shapeCircle) = 0;
virtual void visitEllipse(EllipseShape *shapeEllipse) = 0;
+ virtual void visitDiamond(DiamondShape *shapeDiamond) = 0;
+ virtual void visitTriangle(TriangleShape *shapeDiamond) = 0;
virtual void visitArc(ArcShape *shapeArc) = 0;
virtual void visitPath(PathShape *shapePath) = 0;
};
@@ -59,6 +63,8 @@ public:
virtual void visitRoundedRect(const RoundedRectShape *shapeRoundedRect) = 0;
virtual void visitCircle(const CircleShape *shapeCircle) = 0;
virtual void visitEllipse(const EllipseShape *shapeEllipse) = 0;
+ virtual void visitDiamond(const DiamondShape *shapeDiamond) = 0;
+ virtual void visitTriangle(const TriangleShape *shapeDiamond) = 0;
virtual void visitArc(const ArcShape *shapeArc) = 0;
virtual void visitPath(const PathShape *shapePath) = 0;
};
diff --git a/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.cpp b/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.cpp
index 8c7bbdbc26e..5e5e4b73fde 100644
--- a/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.cpp
+++ b/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.cpp
@@ -25,12 +25,14 @@
#include "stereotypecontroller.h"
+#include "customrelation.h"
#include "stereotypeicon.h"
#include "shapepaintvisitor.h"
#include "toolbar.h"
#include "qmt/infrastructure/qmtassert.h"
#include "qmt/style/style.h"
+#include "utils/algorithm.h"
#include <QHash>
#include <QPainter>
@@ -46,7 +48,9 @@ class StereotypeController::StereotypeControllerPrivate
public:
QHash<QPair<StereotypeIcon::Element, QString>, QString> m_stereotypeToIconIdMap;
QHash<QString, StereotypeIcon> m_iconIdToStereotypeIconsMap;
+ QHash<QString, CustomRelation> m_relationIdToCustomRelationMap;
QList<Toolbar> m_toolbars;
+ QList<Toolbar> m_elementToolbars;
};
StereotypeController::StereotypeController(QObject *parent) :
@@ -70,6 +74,13 @@ QList<Toolbar> StereotypeController::toolbars() const
return d->m_toolbars;
}
+QList<Toolbar> StereotypeController::findToolbars(const QString &elementType) const
+{
+ return Utils::filtered(d->m_elementToolbars, [&elementType](const Toolbar &tb) {
+ return tb.elementTypes().contains(elementType);
+ });
+}
+
QList<QString> StereotypeController::knownStereotypes(StereotypeIcon::Element stereotypeElement) const
{
QSet<QString> stereotypes;
@@ -105,12 +116,17 @@ QList<QString> StereotypeController::filterStereotypesByIconId(const QString &st
return filteredStereotypes;
}
-StereotypeIcon StereotypeController::findStereotypeIcon(const QString &stereotypeIconId)
+StereotypeIcon StereotypeController::findStereotypeIcon(const QString &stereotypeIconId) const
{
QMT_CHECK(d->m_iconIdToStereotypeIconsMap.contains(stereotypeIconId));
return d->m_iconIdToStereotypeIconsMap.value(stereotypeIconId);
}
+CustomRelation StereotypeController::findCustomRelation(const QString &customRelationId) const
+{
+ return d->m_relationIdToCustomRelationMap.value(customRelationId);
+}
+
QIcon StereotypeController::createIcon(StereotypeIcon::Element element, const QList<QString> &stereotypes,
const QString &defaultIconPath, const Style *style, const QSize &size,
const QMarginsF &margins)
@@ -180,9 +196,17 @@ void StereotypeController::addStereotypeIcon(const StereotypeIcon &stereotypeIco
d->m_iconIdToStereotypeIconsMap.insert(stereotypeIcon.id(), stereotypeIcon);
}
+void StereotypeController::addCustomRelation(const CustomRelation &customRelation)
+{
+ d->m_relationIdToCustomRelationMap.insert(customRelation.id(), customRelation);
+}
+
void StereotypeController::addToolbar(const Toolbar &toolbar)
{
- d->m_toolbars.append(toolbar);
+ if (toolbar.elementTypes().isEmpty())
+ d->m_toolbars.append(toolbar);
+ else
+ d->m_elementToolbars.append(toolbar);
}
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.h b/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.h
index 990c2ae8b46..a010352e361 100644
--- a/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.h
+++ b/src/libs/modelinglib/qmt/stereotype/stereotypecontroller.h
@@ -33,6 +33,7 @@
namespace qmt {
+class CustomRelation;
class Toolbar;
class Style;
@@ -42,23 +43,26 @@ class QMT_EXPORT StereotypeController : public QObject
class StereotypeControllerPrivate;
public:
- explicit StereotypeController(QObject *parent = 0);
+ explicit StereotypeController(QObject *parent = nullptr);
~StereotypeController() override;
QList<StereotypeIcon> stereotypeIcons() const;
QList<Toolbar> toolbars() const;
+ QList<Toolbar> findToolbars(const QString &elementType) const;
QList<QString> knownStereotypes(StereotypeIcon::Element stereotypeElement) const;
QString findStereotypeIconId(StereotypeIcon::Element element,
const QList<QString> &stereotypes) const;
QList<QString> filterStereotypesByIconId(const QString &stereotypeIconId,
const QList<QString> &stereotypes) const;
- StereotypeIcon findStereotypeIcon(const QString &stereotypeIconId);
+ StereotypeIcon findStereotypeIcon(const QString &stereotypeIconId) const;
+ CustomRelation findCustomRelation(const QString &customRelationId) const;
QIcon createIcon(StereotypeIcon::Element element, const QList<QString> &stereotypes,
const QString &defaultIconPath, const Style *style,
const QSize &size, const QMarginsF &margins);
void addStereotypeIcon(const StereotypeIcon &stereotypeIcon);
+ void addCustomRelation(const CustomRelation &customRelation);
void addToolbar(const Toolbar &toolbar);
private:
diff --git a/src/libs/modelinglib/qmt/stereotype/stereotypeicon.cpp b/src/libs/modelinglib/qmt/stereotype/stereotypeicon.cpp
index 885eeade532..d3cc9d606bb 100644
--- a/src/libs/modelinglib/qmt/stereotype/stereotypeicon.cpp
+++ b/src/libs/modelinglib/qmt/stereotype/stereotypeicon.cpp
@@ -27,21 +27,6 @@
namespace qmt {
-StereotypeIcon::StereotypeIcon()
- : m_width(100.0),
- m_height(100.0),
- m_minWidth(-1),
- m_minHeight(-1),
- m_sizeLock(LockNone),
- m_display(DisplaySmart),
- m_textAlignment(TextalignBelow)
-{
-}
-
-StereotypeIcon::~StereotypeIcon()
-{
-}
-
void StereotypeIcon::setId(const QString &id)
{
m_id = id;
diff --git a/src/libs/modelinglib/qmt/stereotype/stereotypeicon.h b/src/libs/modelinglib/qmt/stereotype/stereotypeicon.h
index 354bd6f9ce4..acdeb3f07e8 100644
--- a/src/libs/modelinglib/qmt/stereotype/stereotypeicon.h
+++ b/src/libs/modelinglib/qmt/stereotype/stereotypeicon.h
@@ -67,9 +67,6 @@ public:
TextalignNone
};
- StereotypeIcon();
- ~StereotypeIcon();
-
QString id() const { return m_id; }
void setId(const QString &id);
QString title() const;
@@ -104,13 +101,13 @@ private:
QString m_title;
QSet<Element> m_elements;
QSet<QString> m_stereotypes;
- qreal m_width;
- qreal m_height;
- qreal m_minWidth;
- qreal m_minHeight;
- SizeLock m_sizeLock;
- Display m_display;
- TextAlignment m_textAlignment;
+ qreal m_width = 100.0;
+ qreal m_height = 100.0;
+ qreal m_minWidth = -1;
+ qreal m_minHeight = -1;
+ SizeLock m_sizeLock = LockNone;
+ Display m_display = DisplaySmart;
+ TextAlignment m_textAlignment = TextalignBelow;
QColor m_baseColor;
IconShape m_iconShape;
};
diff --git a/src/libs/modelinglib/qmt/stereotype/toolbar.cpp b/src/libs/modelinglib/qmt/stereotype/toolbar.cpp
index 9106d743603..95ae78a5948 100644
--- a/src/libs/modelinglib/qmt/stereotype/toolbar.cpp
+++ b/src/libs/modelinglib/qmt/stereotype/toolbar.cpp
@@ -28,7 +28,6 @@
namespace qmt {
Toolbar::Toolbar()
- : m_priority(-1)
{
}
@@ -36,6 +35,11 @@ Toolbar::~Toolbar()
{
}
+void Toolbar::setToolbarType(Toolbar::ToolbarType toolbarType)
+{
+ m_toolbarType = toolbarType;
+}
+
void Toolbar::setId(const QString &id)
{
m_id = id;
@@ -46,6 +50,11 @@ void Toolbar::setPriority(int priority)
m_priority = priority;
}
+void Toolbar::setElementTypes(const QStringList &elementTypes)
+{
+ m_elementTypes = elementTypes;
+}
+
void Toolbar::setTools(const QList<Toolbar::Tool> &tools)
{
m_tools = tools;
diff --git a/src/libs/modelinglib/qmt/stereotype/toolbar.h b/src/libs/modelinglib/qmt/stereotype/toolbar.h
index b7422f408d7..ab3974ec2ec 100644
--- a/src/libs/modelinglib/qmt/stereotype/toolbar.h
+++ b/src/libs/modelinglib/qmt/stereotype/toolbar.h
@@ -35,6 +35,11 @@ namespace qmt {
class QMT_EXPORT Toolbar
{
public:
+ enum ToolbarType {
+ ObjectToolbar,
+ RelationToolbar
+ };
+
enum ToolType {
TooltypeTool,
TooltypeSeparator
@@ -65,16 +70,22 @@ public:
Toolbar();
~Toolbar();
+ ToolbarType toolbarType() const { return m_toolbarType; }
+ void setToolbarType(ToolbarType toolbarType);
QString id() const { return m_id; }
void setId(const QString &id);
int priority() const { return m_priority; }
void setPriority(int priority);
+ QStringList elementTypes() const { return m_elementTypes; }
+ void setElementTypes(const QStringList &elementTypes);
QList<Tool> tools() const { return m_tools; }
void setTools(const QList<Tool> &tools);
private:
+ ToolbarType m_toolbarType = ObjectToolbar;
QString m_id;
- int m_priority;
+ int m_priority = -1;
+ QStringList m_elementTypes;
QList<Tool> m_tools;
};
diff --git a/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp b/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp
index e6438e96c95..7f69962c677 100644
--- a/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp
+++ b/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp
@@ -40,7 +40,6 @@
#include <utils/algorithm.h>
#include <QSet>
-#include <QDebug>
namespace {
@@ -158,6 +157,26 @@ bool operator==(const BoundaryStyleKey &lhs, const BoundaryStyleKey &rhs)
return true;
}
+// TODO remove class if no attributes needed even with future extensions
+class SwimlaneStyleKey
+{
+};
+
+uint qHash(const SwimlaneStyleKey &styleKey)
+{
+ Q_UNUSED(styleKey);
+
+ return 1;
+}
+
+bool operator==(const SwimlaneStyleKey &lhs, const SwimlaneStyleKey &rhs)
+{
+ Q_UNUSED(lhs);
+ Q_UNUSED(rhs);
+
+ return true;
+}
+
DefaultStyleEngine::DefaultStyleEngine()
{
}
@@ -190,6 +209,8 @@ const Style *DefaultStyleEngine::applyStyle(const Style *baseStyle, StyleEngine:
parameters);
case TypeOther:
break;
+ case TypeSwimlane:
+ return applySwimlaneStyle(baseStyle, parameters);
}
return baseStyle;
}
@@ -371,6 +392,13 @@ const Style *DefaultStyleEngine::applyBoundaryStyle(const Style *baseStyle, cons
return applyBoundaryStyle(baseStyle, parameters);
}
+const Style *DefaultStyleEngine::applySwimlaneStyle(const Style *baseStyle, const DSwimlane *swimlane, const StyleEngine::Parameters *parameters)
+{
+ Q_UNUSED(swimlane);
+
+ return applySwimlaneStyle(baseStyle, parameters);
+}
+
const Style *DefaultStyleEngine::applyAnnotationStyle(const Style *baseStyle, DAnnotation::VisualRole visualRole,
const StyleEngine::Parameters *parameters)
{
@@ -429,6 +457,22 @@ const Style *DefaultStyleEngine::applyBoundaryStyle(const Style *baseStyle, cons
return derivedStyle;
}
+const Style *DefaultStyleEngine::applySwimlaneStyle(const Style *baseStyle, const StyleEngine::Parameters *parameters)
+{
+ Q_UNUSED(parameters);
+
+ SwimlaneStyleKey key;
+ const Style *derivedStyle = m_swimlaneStyleMap.value(key);
+ if (!derivedStyle) {
+ auto style = new Style(baseStyle->type());
+ style->setNormalFont(baseStyle->normalFont());
+ style->setTextBrush(baseStyle->textBrush());
+ m_swimlaneStyleMap.insert(key, style);
+ derivedStyle = style;
+ }
+ return derivedStyle;
+}
+
DefaultStyleEngine::ElementType DefaultStyleEngine::objectType(const DObject *object)
{
ElementType elementType;
@@ -459,7 +503,6 @@ bool DefaultStyleEngine::areStackingRoles(DObject::VisualPrimaryRole rhsPrimaryR
case DObject::SecondaryRoleLighter:
case DObject::SecondaryRoleDarker:
return lhsPrimaryRole == rhsPrimaryRole;
- break;
case DObject::SecondaryRoleSoften:
case DObject::SecondaryRoleOutline:
return false;
@@ -495,7 +538,11 @@ QColor DefaultStyleEngine::baseColor(ElementType elementType, ObjectVisuals obje
case TypeItem:
baseColor = QColor("#B995C6");
break;
- default:
+ case TypeRelation:
+ case TypeAnnotation:
+ case TypeBoundary:
+ case TypeSwimlane:
+ case TypeOther:
baseColor = QColor("#BF7D65");
break;
}
@@ -510,7 +557,7 @@ QColor DefaultStyleEngine::baseColor(ElementType elementType, ObjectVisuals obje
};
int index = static_cast<int>(objectVisuals.visualPrimaryRole()) - static_cast<int>(DObject::PrimaryRoleCustom1);
- QMT_CHECK(index >= 0 && index <= 4);
+ QMT_ASSERT(index >= 0 && index <= 4, return baseColor);
baseColor = customColors[index];
}
diff --git a/src/libs/modelinglib/qmt/style/defaultstyleengine.h b/src/libs/modelinglib/qmt/style/defaultstyleengine.h
index 792b9247a09..6f73b72b3fe 100644
--- a/src/libs/modelinglib/qmt/style/defaultstyleengine.h
+++ b/src/libs/modelinglib/qmt/style/defaultstyleengine.h
@@ -42,6 +42,7 @@ class ObjectStyleKey;
class RelationStyleKey;
class AnnotationStyleKey;
class BoundaryStyleKey;
+class SwimlaneStyleKey;
class QMT_EXPORT DefaultStyleEngine : public StyleEngine
{
@@ -64,11 +65,14 @@ public:
const Parameters *parameters) override;
const Style *applyBoundaryStyle(const Style *baseStyle, const DBoundary *boundary,
const Parameters *parameters) override;
+ const Style *applySwimlaneStyle(const Style *baseStyle, const DSwimlane *swimlane,
+ const Parameters *parameters) override;
private:
const Style *applyAnnotationStyle(const Style *baseStyle, DAnnotation::VisualRole visualRole,
const Parameters *parameters);
const Style *applyBoundaryStyle(const Style *baseStyle, const Parameters *parameters);
+ const Style *applySwimlaneStyle(const Style *baseStyle, const Parameters *parameters);
ElementType objectType(const DObject *object);
@@ -87,6 +91,7 @@ private:
QHash<RelationStyleKey, const Style *> m_relationStyleMap;
QHash<AnnotationStyleKey, const Style *> m_annotationStyleMap;
QHash<BoundaryStyleKey, const Style *> m_boundaryStyleMap;
+ QHash<SwimlaneStyleKey, const Style *> m_swimlaneStyleMap;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/style/objectvisuals.cpp b/src/libs/modelinglib/qmt/style/objectvisuals.cpp
index e9c73267f8b..a4bdadc26e6 100644
--- a/src/libs/modelinglib/qmt/style/objectvisuals.cpp
+++ b/src/libs/modelinglib/qmt/style/objectvisuals.cpp
@@ -30,10 +30,6 @@
namespace qmt {
ObjectVisuals::ObjectVisuals()
- : m_visualPrimaryRole(DObject::PrimaryRoleNormal),
- m_visualSecondaryRole(DObject::SecondaryRoleNone),
- m_isEmphasized(false),
- m_depth(0)
{
}
diff --git a/src/libs/modelinglib/qmt/style/objectvisuals.h b/src/libs/modelinglib/qmt/style/objectvisuals.h
index 715252befc1..0d708fe0a52 100644
--- a/src/libs/modelinglib/qmt/style/objectvisuals.h
+++ b/src/libs/modelinglib/qmt/style/objectvisuals.h
@@ -52,11 +52,11 @@ public:
void setDepth(int depth);
private:
- DObject::VisualPrimaryRole m_visualPrimaryRole;
- DObject::VisualSecondaryRole m_visualSecondaryRole;
- bool m_isEmphasized;
+ DObject::VisualPrimaryRole m_visualPrimaryRole = DObject::PrimaryRoleNormal;
+ DObject::VisualSecondaryRole m_visualSecondaryRole = DObject::SecondaryRoleNone;
+ bool m_isEmphasized = false;
QColor m_baseColor;
- int m_depth;
+ int m_depth = 0;
};
bool operator==(const ObjectVisuals &lhs, const ObjectVisuals &rhs);
diff --git a/src/libs/modelinglib/qmt/style/stylecontroller.cpp b/src/libs/modelinglib/qmt/style/stylecontroller.cpp
index 89a6fd243cb..947fef94459 100644
--- a/src/libs/modelinglib/qmt/style/stylecontroller.cpp
+++ b/src/libs/modelinglib/qmt/style/stylecontroller.cpp
@@ -47,15 +47,14 @@ public:
}
private:
- StyleController *m_styleController = 0;
+ StyleController *m_styleController = nullptr;
};
StyleController::StyleController(QObject *parent)
: QObject(parent),
m_defaultStyle(new DefaultStyle),
m_relationStarterStyle(new RelationStarterStyle),
- m_defaultStyleEngine(new DefaultStyleEngine),
- m_suppressGradients(false)
+ m_defaultStyleEngine(new DefaultStyleEngine)
{
}
@@ -104,6 +103,12 @@ const Style *StyleController::adaptBoundaryStyle(const DBoundary *boundary)
return m_defaultStyleEngine->applyBoundaryStyle(m_defaultStyle.data(), boundary, &parameters);
}
+const Style *StyleController::adaptSwimlaneStyle(const DSwimlane *swimlane)
+{
+ Parameters parameters(this);
+ return m_defaultStyleEngine->applySwimlaneStyle(m_defaultStyle.data(), swimlane, &parameters);
+}
+
const Style *StyleController::relationStarterStyle()
{
return m_relationStarterStyle.data();
diff --git a/src/libs/modelinglib/qmt/style/stylecontroller.h b/src/libs/modelinglib/qmt/style/stylecontroller.h
index 344409e9415..5a36da6e361 100644
--- a/src/libs/modelinglib/qmt/style/stylecontroller.h
+++ b/src/libs/modelinglib/qmt/style/stylecontroller.h
@@ -47,7 +47,7 @@ class QMT_EXPORT StyleController : public QObject
class Parameters;
public:
- explicit StyleController(QObject *parent = 0);
+ explicit StyleController(QObject *parent = nullptr);
~StyleController() override;
bool suppressGradients() const { return m_suppressGradients; }
@@ -60,13 +60,14 @@ public:
const Style *adaptRelationStyle(const StyledRelation &relation);
const Style *adaptAnnotationStyle(const DAnnotation *annotation);
const Style *adaptBoundaryStyle(const DBoundary *boundary);
+ const Style *adaptSwimlaneStyle(const DSwimlane *swimlane);
const Style *relationStarterStyle();
private:
QScopedPointer<Style> m_defaultStyle;
QScopedPointer<Style> m_relationStarterStyle;
QScopedPointer<StyleEngine> m_defaultStyleEngine;
- bool m_suppressGradients;
+ bool m_suppressGradients = false;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/style/styledobject.h b/src/libs/modelinglib/qmt/style/styledobject.h
index 26687065b76..ea6855234e6 100644
--- a/src/libs/modelinglib/qmt/style/styledobject.h
+++ b/src/libs/modelinglib/qmt/style/styledobject.h
@@ -45,7 +45,7 @@ public:
QList<const DObject *> collidingObjects() const { return m_collidingObjects; }
private:
- const DObject *m_object;
+ const DObject *m_object = nullptr;
ObjectVisuals m_objectVisuals;
QList<const DObject *> m_collidingObjects;
};
diff --git a/src/libs/modelinglib/qmt/style/styledrelation.h b/src/libs/modelinglib/qmt/style/styledrelation.h
index 6811f3e3dac..42fd5b883ab 100644
--- a/src/libs/modelinglib/qmt/style/styledrelation.h
+++ b/src/libs/modelinglib/qmt/style/styledrelation.h
@@ -43,9 +43,9 @@ public:
const DObject *endB() const { return m_endB; }
private:
- const DRelation *m_relation;
- const DObject *m_endA;
- const DObject *m_endB;
+ const DRelation *m_relation = nullptr;
+ const DObject *m_endA = nullptr;
+ const DObject *m_endB = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/style/styleengine.h b/src/libs/modelinglib/qmt/style/styleengine.h
index 2da52b429a2..1b2828ceb25 100644
--- a/src/libs/modelinglib/qmt/style/styleengine.h
+++ b/src/libs/modelinglib/qmt/style/styleengine.h
@@ -40,6 +40,7 @@ class StyledRelation;
class DAnnotation;
class DBoundary;
+class DSwimlane;
class QMT_EXPORT StyleEngine
{
@@ -52,7 +53,8 @@ public:
TypeItem,
TypeRelation,
TypeAnnotation,
- TypeBoundary
+ TypeBoundary,
+ TypeSwimlane
};
class Parameters
@@ -77,6 +79,8 @@ public:
const Parameters *) = 0;
virtual const Style *applyBoundaryStyle(const Style *baseStyle, const DBoundary *,
const Parameters *) = 0;
+ virtual const Style *applySwimlaneStyle(const Style *baseStyle, const DSwimlane *,
+ const Parameters *) = 0;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.cpp b/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.cpp
index 5a6fa6c381f..e896f084623 100644
--- a/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.cpp
+++ b/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.cpp
@@ -31,6 +31,7 @@
#include "qmt/diagram/dboundary.h"
#include "qmt/diagram/dclass.h"
#include "qmt/diagram/dcomponent.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/ddiagram.h"
#include "qmt/diagram/ditem.h"
@@ -39,6 +40,7 @@
#include "qmt/diagram/dobject.h"
#include "qmt/diagram/dpackage.h"
#include "qmt/diagram/drelation.h"
+#include "qmt/diagram/dswimlane.h"
#include "qmt/diagram_scene/capabilities/moveable.h"
#include "qmt/diagram_scene/capabilities/resizable.h"
#include "qmt/diagram_scene/diagramsceneconstants.h"
@@ -47,9 +49,6 @@
namespace qmt {
AlignOnRasterVisitor::AlignOnRasterVisitor()
- : m_diagramController(0),
- m_sceneInspector(0),
- m_diagram(0)
{
}
@@ -135,6 +134,11 @@ void AlignOnRasterVisitor::visitDAssociation(DAssociation *association)
visitDRelation(association);
}
+void AlignOnRasterVisitor::visitDConnection(DConnection *connection)
+{
+ visitDRelation(connection);
+}
+
void AlignOnRasterVisitor::visitDAnnotation(DAnnotation *annotation)
{
IMoveable *moveable = m_sceneInspector->moveable(annotation, m_diagram);
@@ -153,4 +157,11 @@ void AlignOnRasterVisitor::visitDBoundary(DBoundary *boundary)
moveable->alignItemPositionToRaster(RASTER_WIDTH, RASTER_HEIGHT);
}
+void AlignOnRasterVisitor::visitDSwimlane(DSwimlane *swimlane)
+{
+ IMoveable *moveable = m_sceneInspector->moveable(swimlane, m_diagram);
+ if (moveable)
+ moveable->alignItemPositionToRaster(RASTER_WIDTH, RASTER_HEIGHT);
+}
+
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.h b/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.h
index 994cab48c31..195f1a5c517 100644
--- a/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.h
+++ b/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.h
@@ -55,13 +55,15 @@ public:
void visitDInheritance(DInheritance *inheritance) override;
void visitDDependency(DDependency *dependency) override;
void visitDAssociation(DAssociation *association) override;
+ void visitDConnection(DConnection *connection) override;
void visitDAnnotation(DAnnotation *annotation) override;
void visitDBoundary(DBoundary *boundary) override;
+ void visitDSwimlane(DSwimlane *swimlane) override;
private:
- DiagramController *m_diagramController;
- ISceneInspector *m_sceneInspector;
- MDiagram *m_diagram;
+ DiagramController *m_diagramController = nullptr;
+ ISceneInspector *m_sceneInspector = nullptr;
+ MDiagram *m_diagram = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.cpp b/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.cpp
index d7619d7786c..3ae964bbcfb 100644
--- a/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.cpp
+++ b/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.cpp
@@ -31,11 +31,14 @@
#include "qmt/diagram_controller/diagramcontroller.h"
#include "qmt/diagram_controller/dselection.h"
#include "qmt/diagram/dannotation.h"
+#include "qmt/diagram/dassociation.h"
#include "qmt/diagram/dboundary.h"
#include "qmt/diagram/dclass.h"
-#include "qmt/diagram/dpackage.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/diagram/ditem.h"
+#include "qmt/diagram/dpackage.h"
#include "qmt/diagram/drelation.h"
+#include "qmt/diagram/dswimlane.h"
#include "qmt/diagram_ui/diagram_mime_types.h"
#include "qmt/model_controller/modelcontroller.h"
#include "qmt/model_controller/mselection.h"
@@ -44,6 +47,7 @@
#include "qmt/model/mcanvasdiagram.h"
#include "qmt/model/mclass.h"
#include "qmt/model/mcomponent.h"
+#include "qmt/model/mconnection.h"
#include "qmt/model/mdependency.h"
#include "qmt/model/mdiagram.h"
#include "qmt/model/minheritance.h"
@@ -51,6 +55,8 @@
#include "qmt/model/mobject.h"
#include "qmt/model/mpackage.h"
#include "qmt/model/msourceexpansion.h"
+#include "qmt/stereotype/customrelation.h"
+#include "qmt/stereotype/stereotypecontroller.h"
#include "qmt/tasks/alignonrastervisitor.h"
#include "qmt/tasks/isceneinspector.h"
#include "qmt/tasks/voidelementtasks.h"
@@ -70,8 +76,11 @@ static VoidElementTasks dummyElementTasks;
class DiagramSceneController::AcceptRelationVisitor : public MVoidConstVisitor
{
public:
- AcceptRelationVisitor(const MRelation *relation)
- : m_relation(relation)
+ AcceptRelationVisitor(StereotypeController *stereotypeController, const MRelation *relation,
+ RelationEnd relationEnd)
+ : m_stereotypeController(stereotypeController),
+ m_relation(relation),
+ m_relationEnd(relationEnd)
{
}
@@ -80,28 +89,49 @@ public:
void visitMObject(const MObject *object) override
{
Q_UNUSED(object);
- m_accepted = dynamic_cast<const MDependency *>(m_relation) != 0;
+ if (auto connection = dynamic_cast<const MConnection *>(m_relation)) {
+ CustomRelation customRelation = m_stereotypeController->findCustomRelation(connection->customRelationId());
+ if (!customRelation.isNull()) {
+ QMT_ASSERT(customRelation.element() == CustomRelation::Element::Relation, return);
+ CustomRelation::End customEnd = m_relationEnd == EndA ? customRelation.endA() : customRelation.endB();
+ QStringList endItems = customEnd.endItems();
+ if (endItems.isEmpty())
+ endItems = customRelation.endItems();
+ QString stereotypeIconId = m_stereotypeController->findStereotypeIconId(StereotypeIcon::ElementItem, object->stereotypes());
+ if (stereotypeIconId.isEmpty() && !m_variety.isEmpty())
+ stereotypeIconId = m_stereotypeController->findStereotypeIconId(StereotypeIcon::ElementItem, QStringList(m_variety));
+ m_accepted = endItems.contains(stereotypeIconId);
+ }
+ }
+ if (!m_accepted)
+ m_accepted = dynamic_cast<const MDependency *>(m_relation) != nullptr;
}
void visitMClass(const MClass *klass) override
{
- Q_UNUSED(klass);
- m_accepted = dynamic_cast<const MDependency *>(m_relation) != 0
- || dynamic_cast<const MInheritance *>(m_relation) != 0
- || dynamic_cast<const MAssociation *>(m_relation) != 0;
+ m_accepted = dynamic_cast<const MInheritance *>(m_relation) != nullptr
+ || dynamic_cast<const MAssociation *>(m_relation) != nullptr;
+ if (!m_accepted)
+ visitMObject(klass);
+ }
+
+ void visitMItem(const MItem *item) override
+ {
+ m_variety = item->variety();
+ visitMObject(item);
}
private:
- const MRelation *m_relation = 0;
+ StereotypeController *m_stereotypeController = nullptr;
+ const MRelation *m_relation = nullptr;
+ RelationEnd m_relationEnd = EndA;
+ QString m_variety;
bool m_accepted = false;
};
DiagramSceneController::DiagramSceneController(QObject *parent)
: QObject(parent),
- m_modelController(0),
- m_diagramController(0),
- m_elementTasks(&dummyElementTasks),
- m_sceneInspector(0)
+ m_elementTasks(&dummyElementTasks)
{
}
@@ -114,8 +144,8 @@ void DiagramSceneController::setModelController(ModelController *modelController
if (m_modelController == modelController)
return;
if (m_modelController) {
- disconnect(m_modelController, 0, this, 0);
- m_modelController = 0;
+ disconnect(m_modelController, nullptr, this, nullptr);
+ m_modelController = nullptr;
}
if (modelController)
m_modelController = modelController;
@@ -126,13 +156,18 @@ void DiagramSceneController::setDiagramController(DiagramController *diagramCont
if (m_diagramController == diagramController)
return;
if (m_diagramController) {
- disconnect(m_diagramController, 0, this, 0);
- m_diagramController = 0;
+ disconnect(m_diagramController, nullptr, this, nullptr);
+ m_diagramController = nullptr;
}
if (diagramController)
m_diagramController = diagramController;
}
+void DiagramSceneController::setStereotypeController(StereotypeController *stereotypeController)
+{
+ m_stereotypeController = stereotypeController;
+}
+
void DiagramSceneController::setElementTasks(IElementTasks *elementTasks)
{
m_elementTasks = elementTasks;
@@ -150,10 +185,10 @@ void DiagramSceneController::deleteFromDiagram(const DSelection &dselection, MDi
DSelection remainingDselection;
foreach (const DSelection::Index &index, dselection.indices()) {
DElement *delement = m_diagramController->findElement(index.elementKey(), diagram);
- QMT_CHECK(delement);
+ QMT_ASSERT(delement, return);
if (delement->modelUid().isValid()) {
MElement *melement = m_modelController->findElement(delement->modelUid());
- QMT_CHECK(melement);
+ QMT_ASSERT(melement, return);
if (melement->owner())
mselection.append(melement->uid(), melement->owner()->uid());
} else {
@@ -173,9 +208,9 @@ void DiagramSceneController::createDependency(DObject *endAObject, DObject *endB
m_diagramController->undoController()->beginMergeSequence(tr("Create Dependency"));
MObject *endAModelObject = m_modelController->findObject<MObject>(endAObject->modelUid());
- QMT_CHECK(endAModelObject);
+ QMT_ASSERT(endAModelObject, return);
MObject *endBModelObject = m_modelController->findObject<MObject>(endBObject->modelUid());
- QMT_CHECK(endBModelObject);
+ QMT_ASSERT(endBModelObject, return);
if (endAModelObject == endBModelObject)
return;
@@ -200,9 +235,9 @@ void DiagramSceneController::createInheritance(DClass *derivedClass, DClass *bas
m_diagramController->undoController()->beginMergeSequence(tr("Create Inheritance"));
MClass *derivedModelClass = m_modelController->findObject<MClass>(derivedClass->modelUid());
- QMT_CHECK(derivedModelClass);
+ QMT_ASSERT(derivedModelClass, return);
MClass *baseModelClass = m_modelController->findObject<MClass>(baseClass->modelUid());
- QMT_CHECK(baseModelClass);
+ QMT_ASSERT(baseModelClass, return);
if (derivedModelClass == baseModelClass)
return;
@@ -221,14 +256,15 @@ void DiagramSceneController::createInheritance(DClass *derivedClass, DClass *bas
}
void DiagramSceneController::createAssociation(DClass *endAClass, DClass *endBClass,
- const QList<QPointF> &intermediatePoints, MDiagram *diagram)
+ const QList<QPointF> &intermediatePoints, MDiagram *diagram,
+ std::function<void (MAssociation*, DAssociation*)> custom)
{
m_diagramController->undoController()->beginMergeSequence(tr("Create Association"));
MClass *endAModelObject = m_modelController->findObject<MClass>(endAClass->modelUid());
- QMT_CHECK(endAModelObject);
+ QMT_ASSERT(endAModelObject, return);
MClass *endBModelObject = m_modelController->findObject<MClass>(endBClass->modelUid());
- QMT_CHECK(endBModelObject);
+ QMT_ASSERT(endBModelObject, return);
// TODO allow self assignment with just one intermediate point and a nice round arrow
if (endAModelObject == endBModelObject && intermediatePoints.count() < 2)
@@ -243,6 +279,49 @@ void DiagramSceneController::createAssociation(DClass *endAClass, DClass *endBCl
m_modelController->addRelation(endAModelObject, modelAssociation);
DRelation *relation = addRelation(modelAssociation, intermediatePoints, diagram);
+ DAssociation *diagramAssociation = dynamic_cast<DAssociation *>(relation);
+ QMT_CHECK(diagramAssociation);
+
+ if (custom)
+ custom(modelAssociation, diagramAssociation);
+
+ m_diagramController->undoController()->endMergeSequence();
+
+ if (relation)
+ emit newElementCreated(relation, diagram);
+}
+
+void DiagramSceneController::createConnection(const QString &customRelationId,
+ DObject *endAObject, DObject *endBObject,
+ const QList<QPointF> &intermediatePoints, MDiagram *diagram,
+ std::function<void (MConnection *, DConnection *)> custom)
+{
+ m_diagramController->undoController()->beginMergeSequence(tr("Create Connection"));
+
+ MObject *endAModelObject = m_modelController->findObject<MObject>(endAObject->modelUid());
+ QMT_CHECK(endAModelObject);
+ MObject *endBModelObject = m_modelController->findObject<MObject>(endBObject->modelUid());
+ QMT_CHECK(endBModelObject);
+
+ // TODO allow self assignment with just one intermediate point and a nice round arrow
+ if (endAModelObject == endBModelObject && intermediatePoints.count() < 2)
+ return;
+
+ auto modelConnection = new MConnection();
+ modelConnection->setCustomRelationId(customRelationId);
+ modelConnection->setEndAUid(endAModelObject->uid());
+ MConnectionEnd endA = modelConnection->endA();
+ endA.setNavigable(true);
+ modelConnection->setEndA(endA);
+ modelConnection->setEndBUid(endBModelObject->uid());
+ m_modelController->addRelation(endAModelObject, modelConnection);
+
+ DRelation *relation = addRelation(modelConnection, intermediatePoints, diagram);
+ DConnection *diagramConnection = dynamic_cast<DConnection *>(relation);
+ QMT_CHECK(diagramConnection);
+
+ if (custom)
+ custom(modelConnection, diagramConnection);
m_diagramController->undoController()->endMergeSequence();
@@ -252,29 +331,29 @@ void DiagramSceneController::createAssociation(DClass *endAClass, DClass *endBCl
bool DiagramSceneController::relocateRelationEndA(DRelation *relation, DObject *targetObject)
{
- return relocateRelationEnd(relation, targetObject, &MRelation::endAUid, &MRelation::setEndAUid);
+ return relocateRelationEnd(relation, targetObject, EndA, &MRelation::endAUid, &MRelation::setEndAUid);
}
bool DiagramSceneController::relocateRelationEndB(DRelation *relation, DObject *targetObject)
{
- return relocateRelationEnd(relation, targetObject, &MRelation::endBUid, &MRelation::setEndBUid);
+ return relocateRelationEnd(relation, targetObject, EndB, &MRelation::endBUid, &MRelation::setEndBUid);
}
bool DiagramSceneController::isAddingAllowed(const Uid &modelElementKey, MDiagram *diagram)
{
MElement *modelElement = m_modelController->findElement(modelElementKey);
- QMT_CHECK(modelElement);
+ QMT_ASSERT(modelElement, return false);
if (m_diagramController->hasDelegate(modelElement, diagram))
return false;
if (auto modelRelation = dynamic_cast<MRelation *>(modelElement)) {
MObject *endAModelObject = m_modelController->findObject(modelRelation->endAUid());
- QMT_CHECK(endAModelObject);
+ QMT_ASSERT(endAModelObject, return false);
DObject *endADiagramObject = m_diagramController->findDelegate<DObject>(endAModelObject, diagram);
if (!endADiagramObject)
return false;
MObject *endBModelObject = m_modelController->findObject(modelRelation->endBUid());
- QMT_CHECK(endBModelObject);
+ QMT_ASSERT(endBModelObject, return false);
DObject *endBDiagramObject = m_diagramController->findDelegate<DObject>(endBModelObject, diagram);
if (!endBDiagramObject)
return false;
@@ -290,11 +369,11 @@ void DiagramSceneController::addExistingModelElement(const Uid &modelElementKey,
}
void DiagramSceneController::dropNewElement(const QString &newElementId, const QString &name, const QString &stereotype,
- DElement *topMostElementAtPos, const QPointF &pos, MDiagram *diagram)
+ DElement *topMostElementAtPos, const QPointF &pos, MDiagram *diagram,
+ const QPoint &viewPos, const QSize &viewSize)
{
if (newElementId == QLatin1String(ELEMENT_TYPE_ANNOTATION)) {
auto annotation = new DAnnotation();
- annotation->setText(QStringLiteral(""));
annotation->setPos(pos - QPointF(10.0, 10.0));
m_diagramController->addElement(annotation, diagram);
alignOnRaster(annotation, diagram);
@@ -305,9 +384,19 @@ void DiagramSceneController::dropNewElement(const QString &newElementId, const Q
m_diagramController->addElement(boundary, diagram);
alignOnRaster(boundary, diagram);
emit newElementCreated(boundary, diagram);
+ } else if (newElementId == QLatin1String(ELEMENT_TYPE_SWIMLANE)) {
+ auto swimlane = new DSwimlane();
+ qreal x = static_cast<qreal>(viewPos.x()) / viewSize.width();
+ qreal y = static_cast<qreal>(viewPos.y()) / viewSize.height();
+ bool horizontal = (y > x && (1-y) > x) || (y <= x && (1-y) <= x);
+ swimlane->setHorizontal(horizontal);
+ swimlane->setPos(horizontal ? pos.y() : pos.x());
+ m_diagramController->addElement(swimlane, diagram);
+ alignOnRaster(swimlane, diagram);
+ emit newElementCreated(swimlane, diagram);
} else {
MPackage *parentPackage = findSuitableParentPackage(topMostElementAtPos, diagram);
- MObject *newObject = 0;
+ MObject *newObject = nullptr;
QString newName;
if (newElementId == QLatin1String(ELEMENT_TYPE_PACKAGE)) {
auto package = new MPackage();
@@ -358,7 +447,7 @@ void DiagramSceneController::dropNewModelElement(MObject *modelObject, MPackage
MPackage *DiagramSceneController::findSuitableParentPackage(DElement *topmostDiagramElement, MDiagram *diagram)
{
- MPackage *parentPackage = 0;
+ MPackage *parentPackage = nullptr;
if (auto diagramPackage = dynamic_cast<DPackage *>(topmostDiagramElement)) {
parentPackage = m_modelController->findObject<MPackage>(diagramPackage->modelUid());
} else if (auto diagramObject = dynamic_cast<DObject *>(topmostDiagramElement)) {
@@ -366,9 +455,9 @@ MPackage *DiagramSceneController::findSuitableParentPackage(DElement *topmostDia
if (modelObject)
parentPackage = dynamic_cast<MPackage *>(modelObject->owner());
}
- if (parentPackage == 0 && diagram != 0)
+ if (!parentPackage && diagram)
parentPackage = dynamic_cast<MPackage *>(diagram->owner());
- if (parentPackage == 0)
+ if (!parentPackage)
parentPackage = m_modelController->rootPackage();
return parentPackage;
}
@@ -384,7 +473,7 @@ MDiagram *DiagramSceneController::findDiagramBySearchId(MPackage *package, const
}
}
}
- return 0;
+ return nullptr;
}
namespace {
@@ -582,7 +671,7 @@ void DiagramSceneController::alignOnRaster(DElement *element, MDiagram *diagram)
DElement *DiagramSceneController::addModelElement(const Uid &modelElementKey, const QPointF &pos, MDiagram *diagram)
{
- DElement *element = 0;
+ DElement *element = nullptr;
if (MObject *modelObject = m_modelController->findObject(modelElementKey)) {
element = addObject(modelObject, pos, diagram);
} else if (MRelation *modelRelation = m_modelController->findRelation(modelElementKey)) {
@@ -595,17 +684,17 @@ DElement *DiagramSceneController::addModelElement(const Uid &modelElementKey, co
DObject *DiagramSceneController::addObject(MObject *modelObject, const QPointF &pos, MDiagram *diagram)
{
- QMT_CHECK(modelObject);
+ QMT_ASSERT(modelObject, return nullptr);
if (m_diagramController->hasDelegate(modelObject, diagram))
- return 0;
+ return nullptr;
m_diagramController->undoController()->beginMergeSequence(tr("Add Element"));
DFactory factory;
modelObject->accept(&factory);
auto diagramObject = dynamic_cast<DObject *>(factory.product());
- QMT_CHECK(diagramObject);
+ QMT_ASSERT(diagramObject, return nullptr);
diagramObject->setPos(pos);
m_diagramController->addElement(diagramObject, diagram);
alignOnRaster(diagramObject, diagram);
@@ -657,26 +746,26 @@ DObject *DiagramSceneController::addObject(MObject *modelObject, const QPointF &
DRelation *DiagramSceneController::addRelation(MRelation *modelRelation, const QList<QPointF> &intermediatePoints,
MDiagram *diagram)
{
- QMT_CHECK(modelRelation);
+ QMT_ASSERT(modelRelation, return nullptr);
if (m_diagramController->hasDelegate(modelRelation, diagram))
- return 0;
+ return nullptr;
DFactory factory;
modelRelation->accept(&factory);
auto diagramRelation = dynamic_cast<DRelation *>(factory.product());
- QMT_CHECK(diagramRelation);
+ QMT_ASSERT(diagramRelation, return nullptr);
MObject *endAModelObject = m_modelController->findObject(modelRelation->endAUid());
- QMT_CHECK(endAModelObject);
+ QMT_ASSERT(endAModelObject, return nullptr);
DObject *endADiagramObject = m_diagramController->findDelegate<DObject>(endAModelObject, diagram);
- QMT_CHECK(endADiagramObject);
+ QMT_ASSERT(endADiagramObject, return nullptr);
diagramRelation->setEndAUid(endADiagramObject->uid());
MObject *endBModelObject = m_modelController->findObject(modelRelation->endBUid());
- QMT_CHECK(endBModelObject);
+ QMT_ASSERT(endBModelObject, return nullptr);
DObject *endBDiagramObject = m_diagramController->findDelegate<DObject>(endBModelObject, diagram);
- QMT_CHECK(endBDiagramObject);
+ QMT_ASSERT(endBDiagramObject, return nullptr);
diagramRelation->setEndBUid(endBDiagramObject->uid());
QList<DRelation::IntermediatePoint> relationPoints;
@@ -709,20 +798,21 @@ DRelation *DiagramSceneController::addRelation(MRelation *modelRelation, const Q
}
bool DiagramSceneController::relocateRelationEnd(DRelation *relation, DObject *targetObject,
+ RelationEnd relationEnd,
Uid (MRelation::*endUid)() const,
void (MRelation::*setEndUid)(const Uid &))
{
- QMT_CHECK(relation);
+ QMT_ASSERT(relation, return false);
if (targetObject && targetObject->uid() != relation->endAUid()) {
MRelation *modelRelation = m_modelController->findRelation(relation->modelUid());
- QMT_CHECK(modelRelation);
+ QMT_ASSERT(modelRelation, return false);
MObject *targetMObject = m_modelController->findObject(targetObject->modelUid());
- QMT_CHECK(targetMObject);
- AcceptRelationVisitor visitor(modelRelation);
+ QMT_ASSERT(targetMObject, return false);
+ AcceptRelationVisitor visitor(m_stereotypeController, modelRelation, relationEnd);
targetMObject->accept(&visitor);
if (visitor.isAccepted()) {
MObject *currentTargetMObject = m_modelController->findObject((modelRelation->*endUid)());
- QMT_CHECK(currentTargetMObject);
+ QMT_ASSERT(currentTargetMObject, return false);
m_modelController->undoController()->beginMergeSequence(tr("Relocate Relation"));
// move relation into new target if it was a child of the old target
if (currentTargetMObject == modelRelation->owner())
diff --git a/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.h b/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.h
index 967e02f51c9..d0483a03012 100644
--- a/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.h
+++ b/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.h
@@ -28,6 +28,8 @@
#include <QObject>
#include "qmt/infrastructure/qmt_global.h"
+#include <functional>
+
QT_BEGIN_NAMESPACE
class QPointF;
QT_END_NAMESPACE
@@ -37,14 +39,19 @@ namespace qmt {
class Uid;
class ModelController;
class DiagramController;
+class StereotypeController;
class MObject;
class MPackage;
class MDiagram;
class MRelation;
+class MAssociation;
+class MConnection;
class DElement;
class DObject;
class DClass;
class DRelation;
+class DAssociation;
+class DConnection;
class DSelection;
class IElementTasks;
class ISceneInspector;
@@ -55,8 +62,13 @@ class QMT_EXPORT DiagramSceneController : public QObject
class AcceptRelationVisitor;
+ enum RelationEnd {
+ EndA,
+ EndB
+ };
+
public:
- explicit DiagramSceneController(QObject *parent = 0);
+ explicit DiagramSceneController(QObject *parent = nullptr);
~DiagramSceneController() override;
signals:
@@ -68,6 +80,8 @@ public:
void setModelController(ModelController *modelController);
DiagramController *diagramController() const { return m_diagramController; }
void setDiagramController(DiagramController *diagramController);
+ StereotypeController *stereotypeController() const { return m_stereotypeController; }
+ void setStereotypeController(StereotypeController *stereotypeController);
IElementTasks *elementTasks() const { return m_elementTasks; }
void setElementTasks(IElementTasks *elementTasks);
ISceneInspector *sceneInspector() const { return m_sceneInspector; }
@@ -80,14 +94,18 @@ public:
void createInheritance(DClass *derivedClass, DClass *baseClass,
const QList<QPointF> &intermediatePoints, MDiagram *diagram);
void createAssociation(DClass *endAClass, DClass *endBClass,
- const QList<QPointF> &intermediatePoints, MDiagram *diagram);
+ const QList<QPointF> &intermediatePoints, MDiagram *diagram,
+ std::function<void (MAssociation*, DAssociation*)> custom = nullptr);
+ void createConnection(const QString &customRelationId, DObject *endAObject, DObject *endBObject,
+ const QList<QPointF> &intermediatePoints, MDiagram *diagram,
+ std::function<void (MConnection*, DConnection*)> custom = nullptr);
bool relocateRelationEndA(DRelation *relation, DObject *targetObject);
bool relocateRelationEndB(DRelation *relation, DObject *targetObject);
bool isAddingAllowed(const Uid &modelElementKey, MDiagram *diagram);
void addExistingModelElement(const Uid &modelElementKey, const QPointF &pos, MDiagram *diagram);
void dropNewElement(const QString &newElementId, const QString &name, const QString &stereotype,
- DElement *topMostElementAtPos, const QPointF &pos, MDiagram *diagram);
+ DElement *topMostElementAtPos, const QPointF &pos, MDiagram *diagram, const QPoint &viewPos, const QSize &viewSize);
void dropNewModelElement(MObject *modelObject, MPackage *parentPackage, const QPointF &pos,
MDiagram *diagram);
@@ -122,13 +140,14 @@ private:
DObject *addObject(MObject *modelObject, const QPointF &pos, MDiagram *diagram);
DRelation *addRelation(MRelation *modelRelation, const QList<QPointF> &intermediatePoints,
MDiagram *diagram);
- bool relocateRelationEnd(DRelation *relation, DObject *targetObject, Uid (MRelation::*endUid)() const,
- void (MRelation::*setEndUid)(const Uid &));
-
- ModelController *m_modelController;
- DiagramController *m_diagramController;
- IElementTasks *m_elementTasks;
- ISceneInspector *m_sceneInspector;
+ bool relocateRelationEnd(DRelation *relation, DObject *targetObject, RelationEnd relationEnd,
+ Uid (MRelation::*endUid)() const, void (MRelation::*setEndUid)(const Uid &));
+
+ ModelController *m_modelController = nullptr;
+ DiagramController *m_diagramController = nullptr;
+ StereotypeController *m_stereotypeController = nullptr;
+ IElementTasks *m_elementTasks = nullptr;
+ ISceneInspector *m_sceneInspector = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/tasks/finddiagramvisitor.cpp b/src/libs/modelinglib/qmt/tasks/finddiagramvisitor.cpp
index 8bbb88f60fa..a4bbd79528d 100644
--- a/src/libs/modelinglib/qmt/tasks/finddiagramvisitor.cpp
+++ b/src/libs/modelinglib/qmt/tasks/finddiagramvisitor.cpp
@@ -31,8 +31,6 @@
namespace qmt {
FindDiagramVisitor::FindDiagramVisitor()
- : MVoidConstVisitor(),
- m_diagram(nullptr)
{
}
diff --git a/src/libs/modelinglib/qmt/tasks/finddiagramvisitor.h b/src/libs/modelinglib/qmt/tasks/finddiagramvisitor.h
index bd664629f18..6be8e188d93 100644
--- a/src/libs/modelinglib/qmt/tasks/finddiagramvisitor.h
+++ b/src/libs/modelinglib/qmt/tasks/finddiagramvisitor.h
@@ -41,7 +41,7 @@ public:
void visitMDiagram(const MDiagram *diagram) override;
private:
- const MDiagram *m_diagram;
+ const MDiagram *m_diagram = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/tasks/findrootdiagramvisitor.cpp b/src/libs/modelinglib/qmt/tasks/findrootdiagramvisitor.cpp
index cf73774f324..6fad5d6d34d 100644
--- a/src/libs/modelinglib/qmt/tasks/findrootdiagramvisitor.cpp
+++ b/src/libs/modelinglib/qmt/tasks/findrootdiagramvisitor.cpp
@@ -30,8 +30,6 @@
namespace qmt {
FindRootDiagramVisitor::FindRootDiagramVisitor()
- : MVoidVisitor(),
- m_diagram(nullptr)
{
}
diff --git a/src/libs/modelinglib/qmt/tasks/findrootdiagramvisitor.h b/src/libs/modelinglib/qmt/tasks/findrootdiagramvisitor.h
index a520ef6e341..c06315a0cd7 100644
--- a/src/libs/modelinglib/qmt/tasks/findrootdiagramvisitor.h
+++ b/src/libs/modelinglib/qmt/tasks/findrootdiagramvisitor.h
@@ -42,7 +42,7 @@ public:
void visitMObject(MObject *object) override;
private:
- MDiagram *m_diagram;
+ MDiagram *m_diagram = nullptr;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qstringparser/qstringparser.h b/src/libs/modelinglib/qstringparser/qstringparser.h
index 8735e9b60ba..76b5a9fa7ce 100644
--- a/src/libs/modelinglib/qstringparser/qstringparser.h
+++ b/src/libs/modelinglib/qstringparser/qstringparser.h
@@ -62,7 +62,7 @@ private:
void (U::*setter() const)(V) { return m_setter; }
private:
U &m_object;
- void (U::*m_setter)(V) = 0;
+ void (U::*m_setter)(V) = nullptr;
};
public:
@@ -92,7 +92,7 @@ private:
template<typename V>
bool visit(RefNode<V> *node, int *index)
{
- V v = 0;
+ V v = nullptr;
if (!scan(&v, index))
return false;
node->ref() = v;
diff --git a/src/libs/modelinglib/qtserialization/inc/qark/attribute.h b/src/libs/modelinglib/qtserialization/inc/qark/attribute.h
index 7070964d6fb..4e90427e0dd 100644
--- a/src/libs/modelinglib/qtserialization/inc/qark/attribute.h
+++ b/src/libs/modelinglib/qtserialization/inc/qark/attribute.h
@@ -54,7 +54,7 @@ public:
private:
QString m_qualifiedName;
- T *m_value = 0;
+ T *m_value = nullptr;
Parameters m_parameters;
};
@@ -110,7 +110,7 @@ public:
private:
QString m_qualifiedName;
const U &m_u;
- T (U::*m_getter)() const = 0;
+ T (U::*m_getter)() const = nullptr;
Parameters m_parameters;
};
@@ -155,7 +155,7 @@ public:
private:
QString m_qualifiedName;
U &m_u;
- void (U::*m_setter)(T) = 0;
+ void (U::*m_setter)(T) = nullptr;
Parameters m_parameters;
};
@@ -205,8 +205,8 @@ public:
private:
QString m_qualifiedName;
U &m_u;
- T (U::*m_getter)() const = 0;
- void (U::*m_setter)(V) = 0;
+ T (U::*m_getter)() const = nullptr;
+ void (U::*m_setter)(V) = nullptr;
Parameters m_parameters;
};
@@ -253,7 +253,7 @@ public:
private:
QString m_qualifiedName;
U &m_u;
- T (*m_getFunc)(const U &) = 0;
+ T (*m_getFunc)(const U &) = nullptr;
Parameters m_parameters;
};
@@ -298,7 +298,7 @@ public:
private:
QString m_qualifiedName;
U &m_u;
- void (*m_setFunc)(U &, T) = 0;
+ void (*m_setFunc)(U &, T) = nullptr;
Parameters m_parameters;
};
@@ -347,8 +347,8 @@ public:
private:
QString m_qualifiedName;
U &m_u;
- T (*m_getFunc)(const U &) = 0;
- void (*m_setFunc)(U &, V) = 0;
+ T (*m_getFunc)(const U &) = nullptr;
+ void (*m_setFunc)(U &, V) = nullptr;
Parameters m_parameters;
};
diff --git a/src/libs/modelinglib/qtserialization/inc/qark/baseclass.h b/src/libs/modelinglib/qtserialization/inc/qark/baseclass.h
index 4fae0f2e7a0..d4252eaf48e 100644
--- a/src/libs/modelinglib/qtserialization/inc/qark/baseclass.h
+++ b/src/libs/modelinglib/qtserialization/inc/qark/baseclass.h
@@ -87,13 +87,13 @@ Base<BASE, DERIVED> base(const QString &qualifiedName, DERIVED *&obj, const Para
template<class BASE, class DERIVED>
Base<BASE, DERIVED> base(DERIVED &obj)
{
- return Base<BASE, DERIVED>(QString(QStringLiteral("base-%1")).arg(typeUid<BASE>()), obj);
+ return Base<BASE, DERIVED>(QString("base-%1").arg(typeUid<BASE>()), obj);
}
template<class BASE, class DERIVED>
Base<BASE, DERIVED> base(DERIVED &obj, const Parameters &parameters)
{
- return Base<BASE, DERIVED>(QString(QStringLiteral("base-%1")).arg(typeUid<BASE>()),
+ return Base<BASE, DERIVED>(QString("base-%1").arg(typeUid<BASE>()),
obj, parameters);
}
diff --git a/src/libs/modelinglib/qtserialization/inc/qark/qxmlinarchive.h b/src/libs/modelinglib/qtserialization/inc/qark/qxmlinarchive.h
index b11a4db04b2..a32f823919a 100644
--- a/src/libs/modelinglib/qtserialization/inc/qark/qxmlinarchive.h
+++ b/src/libs/modelinglib/qtserialization/inc/qark/qxmlinarchive.h
@@ -296,9 +296,7 @@ private:
public:
explicit QXmlInArchive(QXmlStreamReader &stream)
- : m_stream(stream),
- m_endTagWasRead(false),
- m_currentRefNode(0)
+ : m_stream(stream)
{
}
@@ -491,7 +489,7 @@ public:
{
public:
explicit ReferenceTag(ReferenceKind k = Nullpointer,
- const QString &string = QLatin1String(""))
+ const QString &string = QString())
: kind(k),
typeName(string)
{
@@ -587,7 +585,7 @@ private:
template<class T>
void visit(ObjectNode<T> *node, const XmlTag &tag)
{
- if (tag.m_id.isValid() && node->object().object() != 0)
+ if (tag.m_id.isValid() && node->object().object() != nullptr)
m_loadingRefMap.addObject(tag.m_id, node->object().object());
readChildren(node);
}
@@ -704,9 +702,9 @@ private:
m_currentRefNode = node;
T value = T();
load(*this, value, node->reference().parameters());
- if (m_currentRefNode != 0) { // ref node was not consumed by forward reference
+ if (m_currentRefNode) { // ref node was not consumed by forward reference
*node->reference().value() = value;
- m_currentRefNode = 0;
+ m_currentRefNode = nullptr;
}
XmlTag xmlTag = readTag();
if (!xmlTag.m_isEndTag || xmlTag.m_tagName != node->reference().qualifiedName())
@@ -719,9 +717,9 @@ private:
m_currentRefNode = node;
T value;
load(*this, value, node->reference().parameters());
- if (m_currentRefNode != 0) { // ref node was not consumed by forward reference
+ if (m_currentRefNode) { // ref node was not consumed by forward reference
(node->reference().object().*(node->reference().setter()))(value);
- m_currentRefNode = 0;
+ m_currentRefNode = nullptr;
}
XmlTag xmlTag = readTag();
if (!xmlTag.m_isEndTag || xmlTag.m_tagName != node->reference().qualifiedName())
@@ -734,9 +732,9 @@ private:
m_currentRefNode = node;
T value;
load(*this, value, node->reference().parameters());
- if (m_currentRefNode != 0) { // ref node was not consumed by forward reference
+ if (m_currentRefNode) { // ref node was not consumed by forward reference
(node->reference().object().*(node->reference().setter()))(value);
- m_currentRefNode = 0;
+ m_currentRefNode = nullptr;
}
XmlTag xmlTag = readTag();
if (!xmlTag.m_isEndTag || xmlTag.m_tagName != node->reference().qualifiedName())
@@ -749,9 +747,9 @@ private:
m_currentRefNode = node;
V value;
load(*this, value, node->reference().parameters());
- if (m_currentRefNode != 0) { // ref node was not consumed by forward reference
+ if (m_currentRefNode) { // ref node was not consumed by forward reference
(node->reference().object().*(node->reference().setter()))(value);
- m_currentRefNode = 0;
+ m_currentRefNode = nullptr;
}
XmlTag xmlTag = readTag();
if (!xmlTag.m_isEndTag || xmlTag.m_tagName != node->reference().qualifiedName())
@@ -764,9 +762,9 @@ private:
m_currentRefNode = node;
V value;
load(*this, value, node->reference().parameters());
- if (m_currentRefNode != 0) { // ref node was not consumed by forward reference
+ if (m_currentRefNode) { // ref node was not consumed by forward reference
(node->reference().object().*(node->reference().setter()))(value);
- m_currentRefNode = 0;
+ m_currentRefNode = nullptr;
}
XmlTag xmlTag = readTag();
if (!xmlTag.m_isEndTag || xmlTag.m_tagName != node->reference().qualifiedName())
@@ -779,9 +777,9 @@ private:
m_currentRefNode = node;
T value;
load(*this, value, node->reference().parameters());
- if (m_currentRefNode != 0) { // ref node was not consumed by forward reference
+ if (m_currentRefNode) { // ref node was not consumed by forward reference
(node->reference().setterFunc())(node->reference().object(), value);
- m_currentRefNode = 0;
+ m_currentRefNode = nullptr;
}
XmlTag xmlTag = readTag();
if (!xmlTag.m_isEndTag || xmlTag.m_tagName != node->reference().qualifiedName())
@@ -794,9 +792,9 @@ private:
m_currentRefNode = node;
T value;
load(*this, value, node->reference().parameters());
- if (m_currentRefNode != 0) { // ref node was not consumed by forward reference
+ if (m_currentRefNode) { // ref node was not consumed by forward reference
(node->reference().setterFunc())(node->reference().object(), value);
- m_currentRefNode = 0;
+ m_currentRefNode = nullptr;
}
XmlTag xmlTag = readTag();
if (!xmlTag.m_isEndTag || xmlTag.m_tagName != node->reference().qualifiedName())
@@ -809,9 +807,9 @@ private:
m_currentRefNode = node;
V value;
load(*this, value, node->reference().parameters());
- if (m_currentRefNode != 0) { // ref node was not consumed by forward reference
+ if (m_currentRefNode) { // ref node was not consumed by forward reference
(node->reference().setterFunc())(node->reference().object(), value);
- m_currentRefNode = 0;
+ m_currentRefNode = nullptr;
}
XmlTag xmlTag = readTag();
if (!xmlTag.m_isEndTag || xmlTag.m_tagName != node->reference().qualifiedName())
@@ -824,9 +822,9 @@ private:
m_currentRefNode = node;
V value;
load(*this, value, node->reference().parameters());
- if (m_currentRefNode != 0) { // ref node was not consumed by forward reference
+ if (m_currentRefNode) { // ref node was not consumed by forward reference
(node->reference().setterFunc())(node->reference().object(), value);
- m_currentRefNode = 0;
+ m_currentRefNode = nullptr;
}
XmlTag xmlTag = readTag();
if (!xmlTag.m_isEndTag || xmlTag.m_tagName != node->reference().qualifiedName())
@@ -837,10 +835,10 @@ private:
inline void skipUntilEndOfTag(const XmlTag &xmlTag);
QXmlStreamReader &m_stream;
- bool m_endTagWasRead;
+ bool m_endTagWasRead = false;
QStack<Node *> m_nodeStack;
impl::LoadingRefMap m_loadingRefMap;
- Node *m_currentRefNode;
+ Node *m_currentRefNode = nullptr;
};
QXmlInArchive::XmlTag QXmlInArchive::readTag()
diff --git a/src/libs/modelinglib/qtserialization/inc/qark/qxmloutarchive.h b/src/libs/modelinglib/qtserialization/inc/qark/qxmloutarchive.h
index 91525173cbc..8c51d0a2c49 100644
--- a/src/libs/modelinglib/qtserialization/inc/qark/qxmloutarchive.h
+++ b/src/libs/modelinglib/qtserialization/inc/qark/qxmloutarchive.h
@@ -52,8 +52,7 @@ public:
static const bool outArchive = true;
QXmlOutArchive(QXmlStreamWriter &stream)
- : m_stream(stream),
- m_isNextPointerAReference(false)
+ : m_stream(stream)
{
}
@@ -322,7 +321,7 @@ public:
private:
QXmlStreamWriter &m_stream;
impl::SavingRefMap m_savingRefMap;
- bool m_isNextPointerAReference;
+ bool m_isNextPointerAReference = false;
};
} // namespace qark
diff --git a/src/libs/modelinglib/qtserialization/inc/qark/reference.h b/src/libs/modelinglib/qtserialization/inc/qark/reference.h
index c00c6b66641..0c5c9ba3783 100644
--- a/src/libs/modelinglib/qtserialization/inc/qark/reference.h
+++ b/src/libs/modelinglib/qtserialization/inc/qark/reference.h
@@ -54,7 +54,7 @@ public:
private:
QString m_qualifiedName;
- T *m_value = 0;
+ T *m_value = nullptr;
Parameters m_parameters;
};
@@ -110,7 +110,7 @@ public:
private:
QString m_qualifiedName;
const U &m_u;
- T (U::*m_getter)() const = 0;
+ T (U::*m_getter)() const = nullptr;
Parameters m_parameters;
};
@@ -155,7 +155,7 @@ public:
private:
QString m_qualifiedName;
U &m_u;
- void (U::*m_setter)(T) = 0;
+ void (U::*m_setter)(T) = nullptr;
Parameters m_parameters;
};
@@ -217,8 +217,8 @@ public:
private:
QString m_qualifiedName;
U &m_u;
- T (U::*m_getter)() const = 0;
- void (U::*m_setter)(V) = 0;
+ T (U::*m_getter)() const = nullptr;
+ void (U::*m_setter)(V) = nullptr;
Parameters m_parameters;
};
@@ -279,7 +279,7 @@ public:
private:
QString m_qualifiedName;
const U &m_u;
- T (*m_getFunc)(const U &) = 0;
+ T (*m_getFunc)(const U &) = nullptr;
Parameters m_parameters;
};
@@ -324,7 +324,7 @@ public:
private:
QString m_qualifiedName;
U &m_u;
- void (*m_setFunc)(U &, T) = 0;
+ void (*m_setFunc)(U &, T) = nullptr;
Parameters m_parameters;
};
@@ -386,8 +386,8 @@ public:
private:
QString m_qualifiedName;
U &m_u;
- T (*m_getFunc)(const U &) = 0;
- void (*m_setFunc)(U &, V) = 0;
+ T (*m_getFunc)(const U &) = nullptr;
+ void (*m_setFunc)(U &, V) = nullptr;
Parameters m_parameters;
};
diff --git a/src/libs/modelinglib/qtserialization/inc/qark/serialize_basic.h b/src/libs/modelinglib/qtserialization/inc/qark/serialize_basic.h
index 695c53031dc..1997d6630d9 100644
--- a/src/libs/modelinglib/qtserialization/inc/qark/serialize_basic.h
+++ b/src/libs/modelinglib/qtserialization/inc/qark/serialize_basic.h
@@ -73,7 +73,7 @@ QARK_BASIC_SAVELOAD(QString)
template<class Archive>
inline void save(Archive &archive, const QPointF &point, const Parameters &)
{
- archive.write(QString(QStringLiteral("x:%1;y:%2")).arg(point.x()).arg(point.y()));
+ archive.write(QString("x:%1;y:%2").arg(point.x()).arg(point.y()));
}
template<class Archive>
@@ -81,7 +81,7 @@ inline void load(Archive &archive, QPointF &point, const Parameters &)
{
QString s;
archive.read(&s);
- if (QStringParser(s).parse(QStringLiteral("x:%1;y:%2"))
+ if (QStringParser(s).parse("x:%1;y:%2")
.arg(point, &QPointF::setX).arg(point, &QPointF::setY).failed()) {
throw typename Archive::FileFormatException();
}
@@ -92,7 +92,7 @@ inline void load(Archive &archive, QPointF &point, const Parameters &)
template<class Archive>
inline void save(Archive &archive, const QRectF &rect, const Parameters &)
{
- archive.write(QString(QStringLiteral("x:%1;y:%2;w:%3;h:%4"))
+ archive.write(QString("x:%1;y:%2;w:%3;h:%4")
.arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height()));
}
@@ -101,7 +101,7 @@ inline void load(Archive &archive, QRectF &point, const Parameters &)
{
QString s;
archive.read(&s);
- if (QStringParser(s).parse(QStringLiteral("x:%1;y:%2;w:%3;h:%4"))
+ if (QStringParser(s).parse("x:%1;y:%2;w:%3;h:%4")
.arg(point, &QRectF::setX).arg(point, &QRectF::setY)
.arg(point, &QRectF::setWidth).arg(point, &QRectF::setHeight).failed()) {
throw typename Archive::FileFormatException();
diff --git a/src/libs/modelinglib/qtserialization/inc/qark/serialize_container.h b/src/libs/modelinglib/qtserialization/inc/qark/serialize_container.h
index a9d8e2a9224..723194a64e3 100644
--- a/src/libs/modelinglib/qtserialization/inc/qark/serialize_container.h
+++ b/src/libs/modelinglib/qtserialization/inc/qark/serialize_container.h
@@ -41,7 +41,7 @@ inline void save(Archive &archive, const QList<T> &list, const Parameters &)
{
archive << tag("qlist");
foreach (const T &t, list)
- archive << attr(QStringLiteral("item"), t);
+ archive << attr("item", t);
archive << end;
}
@@ -51,10 +51,10 @@ inline void save(Archive &archive, const QList<T *> &list, const Parameters &par
archive << tag("qlist");
if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) {
foreach (const T *t, list)
- archive << ref(QStringLiteral("item"), t);
+ archive << ref("item", t);
} else {
foreach (const T *t, list)
- archive << attr(QStringLiteral("item"), t);
+ archive << attr("item", t);
}
archive << end;
}
@@ -62,21 +62,21 @@ inline void save(Archive &archive, const QList<T *> &list, const Parameters &par
template<class Archive, class T>
inline void load(Archive &archive, QList<T> &list, const Parameters &)
{
- archive >> tag(QStringLiteral("qlist"));
- archive >> attr<QList<T>, const T &>(QStringLiteral("item"), list, &QList<T>::append);
+ archive >> tag("qlist");
+ archive >> attr<QList<T>, const T &>("item", list, &QList<T>::append);
archive >> end;
}
template<class Archive, class T>
inline void load(Archive &archive, QList<T *> &list, const Parameters &parameters)
{
- archive >> tag(QStringLiteral("qlist"));
+ archive >> tag("qlist");
if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) {
// why does the following line not compile but the line below selects the correct function?
//archive >> ref<QList<T *>, T * const &>("item", list, &QList<T *>::append);
- archive >> ref(QStringLiteral("item"), list, &QList<T *>::append);
+ archive >> ref("item", list, &QList<T *>::append);
} else {
- archive >> attr<QList<T *>, T * const &>(QStringLiteral("item"), list, &QList<T *>::append);
+ archive >> attr<QList<T *>, T * const &>("item", list, &QList<T *>::append);
}
archive >> end;
}
@@ -88,7 +88,7 @@ inline void save(Archive &archive, const QSet<T> &set, const Parameters &)
{
archive << tag("qset");
foreach (const T &t, set)
- archive << attr(QStringLiteral("item"), t);
+ archive << attr("item", t);
archive << end;
}
@@ -98,10 +98,10 @@ inline void save(Archive &archive, const QSet<T *> &set, const Parameters &param
archive << tag("qset");
if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS)) {
foreach (const T *t, set)
- archive << ref(QStringLiteral("item"), t);
+ archive << ref("item", t);
} else {
foreach (const T *t, set)
- archive << attr(QStringLiteral("item"), t);
+ archive << attr("item", t);
}
archive << end;
}
@@ -118,19 +118,19 @@ void insertIntoSet(QSet<T> &set, const T &t) {
template<class Archive, class T>
inline void load(Archive &archive, QSet<T> &set, const Parameters &)
{
- archive >> tag(QStringLiteral("qset"));
- archive >> attr<QSet<T>, const T &>(QStringLiteral("item"), set, &impl::insertIntoSet<T>);
+ archive >> tag("qset");
+ archive >> attr<QSet<T>, const T &>("item", set, &impl::insertIntoSet<T>);
archive >> end;
}
template<class Archive, class T>
inline void load(Archive &archive, QSet<T *> &set, const Parameters &parameters)
{
- archive >> tag(QStringLiteral("qset"));
+ archive >> tag("qset");
if (parameters.hasFlag(ENFORCE_REFERENCED_ITEMS))
- archive >> ref(QStringLiteral("item"), set, &impl::insertIntoSet<T *>);
+ archive >> ref("item", set, &impl::insertIntoSet<T *>);
else
- archive >> attr<QSet<T *>, T * const &>(QStringLiteral("item"), set,
+ archive >> attr<QSet<T *>, T * const &>("item", set,
&impl::insertIntoSet<T *>);
archive >> end;
}
@@ -155,25 +155,25 @@ public:
template<class Archive, class KEY, class VALUE>
inline void save(Archive &archive, const impl::KeyValuePair<KEY, VALUE> &pair, const Parameters &)
{
- archive << tag(QStringLiteral("pair"))
- << attr(QStringLiteral("key"), pair.m_key)
- << attr(QStringLiteral("value"), pair.m_value)
+ archive << tag("pair")
+ << attr("key", pair.m_key)
+ << attr("value", pair.m_value)
<< end;
}
template<class Archive, class KEY, class VALUE>
inline void load(Archive &archive, impl::KeyValuePair<KEY, VALUE> &pair, const Parameters &)
{
- archive >> tag(QStringLiteral("pair"))
- >> attr(QStringLiteral("key"), pair.m_key)
- >> attr(QStringLiteral("value"), pair.m_value)
+ archive >> tag("pair")
+ >> attr("key", pair.m_key)
+ >> attr("value", pair.m_value)
>> end;
}
template<class Archive, class KEY, class VALUE>
inline void save(Archive &archive, const QHash<KEY, VALUE> &hash, const Parameters &)
{
- archive << tag(QStringLiteral("qhash"));
+ archive << tag("qhash");
for (auto it = hash.begin(); it != hash.end(); ++it) {
impl::KeyValuePair<KEY, VALUE> pair(it.key(), it.value());
archive << attr("item", pair);
@@ -194,8 +194,8 @@ inline void keyValuePairInsert(QHash<KEY, VALUE> &hash, const KeyValuePair<KEY,
template<class Archive, class KEY, class VALUE>
inline void load(Archive &archive, QHash<KEY, VALUE> &hash, const Parameters &)
{
- archive >> tag(QStringLiteral("qhash"));
- archive >> attr(QStringLiteral("item"), hash, &impl::keyValuePairInsert<KEY, VALUE>);
+ archive >> tag("qhash");
+ archive >> attr("item", hash, &impl::keyValuePairInsert<KEY, VALUE>);
archive >> end;
}
diff --git a/src/libs/modelinglib/qtserialization/inc/qark/serialize_pointer.h b/src/libs/modelinglib/qtserialization/inc/qark/serialize_pointer.h
index 876609643d3..246f1eca84e 100644
--- a/src/libs/modelinglib/qtserialization/inc/qark/serialize_pointer.h
+++ b/src/libs/modelinglib/qtserialization/inc/qark/serialize_pointer.h
@@ -45,7 +45,7 @@ inline void save(Archive &archive, T *p, const Parameters &)
} else {
archive.beginInstance(typeUid(*p));
typename registry::TypeRegistry<Archive, T>::TypeInfo typeData = typeInfo<Archive, T>(*p);
- if (typeData.m_saveFunc == 0)
+ if (!typeData.m_saveFunc)
throw UnregisteredType();
else
typeData.m_saveFunc(archive, p);
@@ -64,7 +64,7 @@ void load(Archive &archive, T *&p, const Parameters &)
typename Archive::ReferenceTag refTag = archive.readReferenceTag();
switch (refTag.kind) {
case Archive::Nullpointer:
- p = 0;
+ p = nullptr;
break;
case Archive::Pointer:
archive.read(p);
@@ -74,7 +74,7 @@ void load(Archive &archive, T *&p, const Parameters &)
registry::loadNonVirtualPointer<Archive,T>(archive, p);
} else {
typename registry::TypeRegistry<Archive, T>::TypeInfo typeData = typeInfo<Archive, T>(refTag.typeName);
- if (typeData.m_loadFunc == 0)
+ if (!typeData.m_loadFunc)
throw UnregisteredType();
else
typeData.m_loadFunc(archive, p);
diff --git a/src/libs/modelinglib/qtserialization/inc/qark/tag.h b/src/libs/modelinglib/qtserialization/inc/qark/tag.h
index 24f81e5d920..9216e0cf667 100644
--- a/src/libs/modelinglib/qtserialization/inc/qark/tag.h
+++ b/src/libs/modelinglib/qtserialization/inc/qark/tag.h
@@ -73,7 +73,7 @@ public:
T *object() const { return m_object; }
private:
- T *m_object = 0;
+ T *m_object = nullptr;
};
inline Tag tag(const QString &qualifiedName)
diff --git a/src/libs/modelinglib/qtserialization/inc/qark/typeregistry.h b/src/libs/modelinglib/qtserialization/inc/qark/typeregistry.h
index aa0750cfdbe..c92ac8f3760 100644
--- a/src/libs/modelinglib/qtserialization/inc/qark/typeregistry.h
+++ b/src/libs/modelinglib/qtserialization/inc/qark/typeregistry.h
@@ -59,8 +59,8 @@ public:
static MapType &uidToNameMap() { return *typeidUidToNameMap; }
#if !defined(QT_NO_DEBUG)
- static bool hasNameToUidMap() { return typeidNameToUidMap != 0; }
- static bool hasUidToNameMap() { return typeidUidToNameMap != 0; }
+ static bool hasNameToUidMap() { return typeidNameToUidMap != nullptr; }
+ static bool hasUidToNameMap() { return typeidUidToNameMap != nullptr; }
#endif
protected:
@@ -119,8 +119,6 @@ public:
typedef Archive &(*LoadFuncType)(Archive &, BASE * &p);
explicit TypeInfo()
- : m_saveFunc(0),
- m_loadFunc(0)
{
}
@@ -135,8 +133,8 @@ public:
return m_saveFunc == rhs.m_saveFunc && m_loadFunc == rhs.m_loadFunc;
}
- SaveFuncType m_saveFunc;
- LoadFuncType m_loadFunc;
+ SaveFuncType m_saveFunc = nullptr;
+ LoadFuncType m_loadFunc = nullptr;
};
typedef QHash<QString, TypeInfo> MapType;
@@ -144,7 +142,7 @@ public:
static MapType &map() { return *m_map; }
#if !defined(QT_NO_DEBUG)
- static bool hasMap() { return m_map != 0; }
+ static bool hasMap() { return m_map != nullptr; }
#endif
protected:
diff --git a/src/libs/qmldebug/baseenginedebugclient.cpp b/src/libs/qmldebug/baseenginedebugclient.cpp
index f3e5271e32b..df014e43a00 100644
--- a/src/libs/qmldebug/baseenginedebugclient.cpp
+++ b/src/libs/qmldebug/baseenginedebugclient.cpp
@@ -178,7 +178,7 @@ void BaseEngineDebugClient::stateChanged(State state)
void BaseEngineDebugClient::messageReceived(const QByteArray &data)
{
- QPacket ds(connection()->currentDataStreamVersion(), data);
+ QPacket ds(dataStreamVersion(), data);
int queryId;
QByteArray type;
ds >> type >> queryId;
@@ -251,7 +251,7 @@ quint32 BaseEngineDebugClient::addWatch(const PropertyReference &property)
quint32 id = 0;
if (state() == Enabled) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("WATCH_PROPERTY") << id << property.m_objectDebugId
<< property.m_name.toUtf8();
sendMessage(ds.data());
@@ -272,7 +272,7 @@ quint32 BaseEngineDebugClient::addWatch(const ObjectReference &object,
quint32 id = 0;
if (state() == Enabled) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("WATCH_EXPR_OBJECT") << id << object.m_debugId << expr;
sendMessage(ds.data());
}
@@ -284,7 +284,7 @@ quint32 BaseEngineDebugClient::addWatch(int objectDebugId)
quint32 id = 0;
if (state() == Enabled) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("WATCH_OBJECT") << id << objectDebugId;
sendMessage(ds.data());
}
@@ -300,7 +300,7 @@ quint32 BaseEngineDebugClient::addWatch(const FileReference &/*file*/)
void BaseEngineDebugClient::removeWatch(quint32 id)
{
if (state() == Enabled) {
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("NO_WATCH") << id;
sendMessage(ds.data());
}
@@ -311,7 +311,7 @@ quint32 BaseEngineDebugClient::queryAvailableEngines()
quint32 id = 0;
if (state() == Enabled) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("LIST_ENGINES") << id;
sendMessage(ds.data());
}
@@ -323,7 +323,7 @@ quint32 BaseEngineDebugClient::queryRootContexts(const EngineReference &engine)
quint32 id = 0;
if (state() == Enabled && engine.m_debugId != -1) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("LIST_OBJECTS") << id << engine.m_debugId;
sendMessage(ds.data());
}
@@ -335,7 +335,7 @@ quint32 BaseEngineDebugClient::queryObject(int objectId)
quint32 id = 0;
if (state() == Enabled && objectId != -1) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("FETCH_OBJECT") << id << objectId << false <<
true;
sendMessage(ds.data());
@@ -348,7 +348,7 @@ quint32 BaseEngineDebugClient::queryObjectRecursive(int objectId)
quint32 id = 0;
if (state() == Enabled && objectId != -1) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("FETCH_OBJECT") << id << objectId << true <<
true;
sendMessage(ds.data());
@@ -363,7 +363,7 @@ quint32 BaseEngineDebugClient::queryExpressionResult(int objectDebugId,
quint32 id = 0;
if (state() == Enabled && objectDebugId != -1) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr
<< engineId;
sendMessage(ds.data());
@@ -381,7 +381,7 @@ quint32 BaseEngineDebugClient::setBindingForObject(
quint32 id = 0;
if (state() == Enabled && objectDebugId != -1) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("SET_BINDING") << id << objectDebugId << propertyName
<< bindingExpression << isLiteralValue << source << line;
sendMessage(ds.data());
@@ -396,7 +396,7 @@ quint32 BaseEngineDebugClient::resetBindingForObject(
quint32 id = 0;
if (state() == Enabled && objectDebugId != -1) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("RESET_BINDING") << id << objectDebugId << propertyName;
sendMessage(ds.data());
}
@@ -410,7 +410,7 @@ quint32 BaseEngineDebugClient::setMethodBody(
quint32 id = 0;
if (state() == Enabled && objectDebugId != -1) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("SET_METHOD_BODY") << id << objectDebugId
<< methodName << methodBody;
sendMessage(ds.data());
@@ -424,7 +424,7 @@ quint32 BaseEngineDebugClient::queryObjectsForLocation(
quint32 id = 0;
if (state() == Enabled) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("FETCH_OBJECTS_FOR_LOCATION") << id <<
fileName << lineNumber << columnNumber << false <<
true;
diff --git a/src/libs/qmldebug/baseenginedebugclient.h b/src/libs/qmldebug/baseenginedebugclient.h
index b74397cf9db..1f3f2f3dfe9 100644
--- a/src/libs/qmldebug/baseenginedebugclient.h
+++ b/src/libs/qmldebug/baseenginedebugclient.h
@@ -72,6 +72,9 @@ public:
virtual quint32 queryObjectsForLocation(const QString &fileName, int lineNumber,
int columnNumber);
+ virtual void stateChanged(State status) override;
+ virtual void messageReceived(const QByteArray &) override;
+
signals:
void newState(QmlDebug::QmlDebugClient::State status);
void newObject(int engineId, int objectId, int parentId);
@@ -80,9 +83,6 @@ signals:
void result(quint32 queryId, const QVariant &result, const QByteArray &type);
protected:
- virtual void stateChanged(State status);
- virtual void messageReceived(const QByteArray &);
-
quint32 getId() { return m_nextId++; }
void decode(QDataStream &d, ContextReference &context);
diff --git a/src/libs/qmldebug/basetoolsclient.h b/src/libs/qmldebug/basetoolsclient.h
index d84e02066e5..cb8d86cb19d 100644
--- a/src/libs/qmldebug/basetoolsclient.h
+++ b/src/libs/qmldebug/basetoolsclient.h
@@ -59,7 +59,7 @@ signals:
void logActivity(QString client, QString message);
protected:
- void stateChanged(State status);
+ void stateChanged(State status) override;
void recurseObjectIdList(const ObjectReference &ref,
QList<int> &debugIds, QList<QString> &objectIds);
diff --git a/src/libs/qmldebug/declarativeenginedebugclient.cpp b/src/libs/qmldebug/declarativeenginedebugclient.cpp
index e014aa44fac..21a13a960d3 100644
--- a/src/libs/qmldebug/declarativeenginedebugclient.cpp
+++ b/src/libs/qmldebug/declarativeenginedebugclient.cpp
@@ -46,7 +46,7 @@ quint32 DeclarativeEngineDebugClient::setBindingForObject(
quint32 id = 0;
if (state() == Enabled && objectDebugId != -1) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("SET_BINDING") << objectDebugId << propertyName
<< bindingExpression << isLiteralValue << source << line;
sendMessage(ds.data());
@@ -61,7 +61,7 @@ quint32 DeclarativeEngineDebugClient::resetBindingForObject(
quint32 id = 0;
if (state() == Enabled && objectDebugId != -1) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("RESET_BINDING") << objectDebugId << propertyName;
sendMessage(ds.data());
}
@@ -75,7 +75,7 @@ quint32 DeclarativeEngineDebugClient::setMethodBody(
quint32 id = 0;
if (state() == Enabled && objectDebugId != -1) {
id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray("SET_METHOD_BODY") << objectDebugId
<< methodName << methodBody;
sendMessage(ds.data());
@@ -85,7 +85,7 @@ quint32 DeclarativeEngineDebugClient::setMethodBody(
void DeclarativeEngineDebugClient::messageReceived(const QByteArray &data)
{
- QPacket ds(connection()->currentDataStreamVersion(), data);
+ QPacket ds(dataStreamVersion(), data);
QByteArray type;
ds >> type;
diff --git a/src/libs/qmldebug/declarativeenginedebugclient.h b/src/libs/qmldebug/declarativeenginedebugclient.h
index 793347e9c71..ccd087726f3 100644
--- a/src/libs/qmldebug/declarativeenginedebugclient.h
+++ b/src/libs/qmldebug/declarativeenginedebugclient.h
@@ -40,13 +40,12 @@ public:
quint32 setBindingForObject(int objectDebugId, const QString &propertyName,
const QVariant &bindingExpression,
bool isLiteralValue,
- QString source, int line);
- quint32 resetBindingForObject(int objectDebugId, const QString &propertyName);
+ QString source, int line) override;
+ quint32 resetBindingForObject(int objectDebugId, const QString &propertyName) override;
quint32 setMethodBody(int objectDebugId, const QString &methodName,
- const QString &methodBody);
+ const QString &methodBody) override;
-protected:
- void messageReceived(const QByteArray &data);
+ void messageReceived(const QByteArray &data) override;
};
} // namespace QmlDebug
diff --git a/src/libs/qmldebug/declarativetoolsclient.h b/src/libs/qmldebug/declarativetoolsclient.h
index 83698b4037e..a6031e87c3b 100644
--- a/src/libs/qmldebug/declarativetoolsclient.h
+++ b/src/libs/qmldebug/declarativetoolsclient.h
@@ -35,17 +35,16 @@ class QMLDEBUG_EXPORT DeclarativeToolsClient : public BaseToolsClient
public:
DeclarativeToolsClient(QmlDebugConnection *client);
- void setDesignModeBehavior(bool inDesignMode);
- void changeToSelectTool();
- void changeToSelectMarqueeTool();
- void changeToZoomTool();
- void showAppOnTop(bool showOnTop);
+ void setDesignModeBehavior(bool inDesignMode) override;
+ void changeToSelectTool() override;
+ void changeToSelectMarqueeTool() override;
+ void changeToZoomTool() override;
+ void showAppOnTop(bool showOnTop) override;
// ### Qt 4.8: remove if we can have access to qdeclarativecontextdata or id's
- void setObjectIdList(const QList<ObjectReference> &objectRoots);
+ void setObjectIdList(const QList<ObjectReference> &objectRoots) override;
-protected:
- void messageReceived(const QByteArray &);
+ void messageReceived(const QByteArray &) override;
private:
void log(LogDirection direction,
diff --git a/src/libs/qmldebug/qdebugmessageclient.h b/src/libs/qmldebug/qdebugmessageclient.h
index 0c6d5995c1e..6862cfd69d5 100644
--- a/src/libs/qmldebug/qdebugmessageclient.h
+++ b/src/libs/qmldebug/qdebugmessageclient.h
@@ -46,9 +46,8 @@ class QMLDEBUG_EXPORT QDebugMessageClient : public QmlDebugClient
public:
explicit QDebugMessageClient(QmlDebugConnection *client);
-protected:
- virtual void stateChanged(State state);
- virtual void messageReceived(const QByteArray &);
+ virtual void stateChanged(State state) override;
+ virtual void messageReceived(const QByteArray &) override;
signals:
void newState(QmlDebug::QmlDebugClient::State);
diff --git a/src/libs/qmldebug/qmldebugclient.cpp b/src/libs/qmldebug/qmldebugclient.cpp
index 597281ab258..ffa21a458c4 100644
--- a/src/libs/qmldebug/qmldebugclient.cpp
+++ b/src/libs/qmldebug/qmldebugclient.cpp
@@ -33,9 +33,12 @@
#include <qlocalserver.h>
#include <qlocalsocket.h>
+#include <QPointer>
+
namespace QmlDebug {
const int protocolVersion = 1;
+const int minimumDataStreamVersion = QDataStream::Qt_4_7;
const QString serverId = QLatin1String("QDeclarativeDebugServer");
const QString clientId = QLatin1String("QDeclarativeDebugClient");
@@ -46,7 +49,7 @@ public:
QmlDebugClientPrivate();
QString name;
- QmlDebugConnection *connection;
+ QPointer<QmlDebugConnection> connection;
};
class QmlDebugConnectionPrivate
@@ -84,7 +87,7 @@ static QString socketErrorToString(QAbstractSocket::SocketError error)
QmlDebugConnectionPrivate::QmlDebugConnectionPrivate() :
protocol(0), server(0), device(0), gotHello(false),
- currentDataStreamVersion(QDataStream::Qt_4_7),
+ currentDataStreamVersion(minimumDataStreamVersion),
maximumDataStreamVersion(QDataStream::Qt_DefaultCompiledVersion)
{
}
@@ -263,11 +266,7 @@ QmlDebugConnection::QmlDebugConnection(QObject *parent)
QmlDebugConnection::~QmlDebugConnection()
{
- Q_D(QmlDebugConnection);
socketDisconnected();
- QHash<QString, QmlDebugClient*>::iterator iter = d->plugins.begin();
- for (; iter != d->plugins.end(); ++iter)
- iter.value()->d_func()->connection = 0;
}
bool QmlDebugConnection::isConnected() const
@@ -398,7 +397,7 @@ void QmlDebugConnection::newConnection()
connect(socket, &QLocalSocket::disconnected, this, &QmlDebugConnection::socketDisconnected);
connect(socket, static_cast<void (QLocalSocket::*)(QLocalSocket::LocalSocketError)>
- (&QLocalSocket::error), this, [this, d](QLocalSocket::LocalSocketError error) {
+ (&QLocalSocket::error), this, [this](QLocalSocket::LocalSocketError error) {
emit logError(socketErrorToString(static_cast<QAbstractSocket::SocketError>(error)));
socketDisconnected();
});
@@ -435,7 +434,6 @@ QAbstractSocket::SocketState QmlDebugConnection::socketState() const
}
QmlDebugClientPrivate::QmlDebugClientPrivate()
- : connection(0)
{
}
@@ -496,6 +494,12 @@ QmlDebugConnection *QmlDebugClient::connection() const
return d->connection;
}
+int QmlDebugClient::dataStreamVersion() const
+{
+ Q_D(const QmlDebugClient);
+ return (d->connection ? d->connection->currentDataStreamVersion() : minimumDataStreamVersion);
+}
+
void QmlDebugClient::sendMessage(const QByteArray &message)
{
Q_D(QmlDebugClient);
diff --git a/src/libs/qmldebug/qmldebugclient.h b/src/libs/qmldebug/qmldebugclient.h
index 2e485ecc1ab..b39ec5f3db4 100644
--- a/src/libs/qmldebug/qmldebugclient.h
+++ b/src/libs/qmldebug/qmldebugclient.h
@@ -95,15 +95,13 @@ public:
float serviceVersion() const;
State state() const;
QmlDebugConnection *connection() const;
+ int dataStreamVersion() const;
virtual void sendMessage(const QByteArray &);
-
-protected:
virtual void stateChanged(State);
virtual void messageReceived(const QByteArray &);
private:
- friend class QmlDebugConnection;
QScopedPointer<QmlDebugClientPrivate> d_ptr;
};
diff --git a/src/libs/qmldebug/qmldebugcommandlinearguments.h b/src/libs/qmldebug/qmldebugcommandlinearguments.h
index 407f991114e..dfcb40927b1 100644
--- a/src/libs/qmldebug/qmldebugcommandlinearguments.h
+++ b/src/libs/qmldebug/qmldebugcommandlinearguments.h
@@ -66,12 +66,9 @@ static inline QString qmlDebugCommandLineArguments(QmlDebugServicesPreset servic
}
static inline QString qmlDebugTcpArguments(QmlDebugServicesPreset services,
- Utils::Port port = Utils::Port(),
- bool block = true)
+ Utils::Port port, bool block = true)
{
- return qmlDebugCommandLineArguments(services, port.isValid() ?
- QString::fromLatin1("port:%1").arg(port.number()) :
- QStringLiteral("port:%qml_port%"), block);
+ return qmlDebugCommandLineArguments(services, QString("port:%1").arg(port.number()), block);
}
static inline QString qmlDebugNativeArguments(QmlDebugServicesPreset services, bool block = true)
@@ -85,15 +82,4 @@ static inline QString qmlDebugLocalArguments(QmlDebugServicesPreset services, co
return qmlDebugCommandLineArguments(services, QLatin1String("file:") + socket, block);
}
-static inline QString qmlDebugArguments(QmlDebugServicesPreset services, const QUrl &serverUrl,
- bool block = true)
-{
- if (serverUrl.scheme() == "socket")
- return qmlDebugCommandLineArguments(services, "file:" + serverUrl.path(), block);
- else
- return qmlDebugCommandLineArguments(services, serverUrl.port() != -1 ?
- QString("port:%1").arg(serverUrl.port()) :
- "port:%qml_port%", block);
-}
-
} // namespace QmlDebug
diff --git a/src/libs/qmldebug/qmlenginecontrolclient.h b/src/libs/qmldebug/qmlenginecontrolclient.h
index c5da7a71302..c947fd72f01 100644
--- a/src/libs/qmldebug/qmlenginecontrolclient.h
+++ b/src/libs/qmldebug/qmlenginecontrolclient.h
@@ -52,6 +52,8 @@ public:
void blockEngine(int engineId);
void releaseEngine(int engineId);
+ void messageReceived(const QByteArray &) override;
+
signals:
void engineAboutToBeAdded(int engineId, const QString &name);
void engineAdded(int engineId, const QString &name);
@@ -59,7 +61,6 @@ signals:
void engineRemoved(int engineId, const QString &name);
protected:
- void messageReceived(const QByteArray &);
void sendCommand(CommandType command, int engineId);
struct EngineState {
diff --git a/src/libs/qmldebug/qmltoolsclient.cpp b/src/libs/qmldebug/qmltoolsclient.cpp
index 7ce05ef71aa..e882f0733b3 100644
--- a/src/libs/qmldebug/qmltoolsclient.cpp
+++ b/src/libs/qmldebug/qmltoolsclient.cpp
@@ -55,7 +55,7 @@ QmlToolsClient::QmlToolsClient(QmlDebugConnection *client)
void QmlToolsClient::messageReceived(const QByteArray &message)
{
- QPacket ds(connection()->currentDataStreamVersion(), message);
+ QPacket ds(dataStreamVersion(), message);
QByteArray type;
int requestId;
@@ -98,7 +98,7 @@ void QmlToolsClient::setObjectIdList(const QList<ObjectReference> &objectRoots)
foreach (const ObjectReference &object, objectRoots)
debugIds << object.debugId();
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray(REQUEST) << m_requestId++ << QByteArray(SELECT) << debugIds;
sendMessage(ds.data());
}
@@ -108,7 +108,7 @@ void QmlToolsClient::setDesignModeBehavior(bool inDesignMode)
if (!m_connection || !m_connection->isConnected())
return;
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray(REQUEST) << m_requestId++;
if (inDesignMode)
ds << QByteArray(ENABLE);
@@ -140,7 +140,7 @@ void QmlToolsClient::showAppOnTop(bool showOnTop)
if (!m_connection || !m_connection->isConnected())
return;
- QPacket ds(connection()->currentDataStreamVersion());
+ QPacket ds(dataStreamVersion());
ds << QByteArray(REQUEST) << m_requestId++
<< QByteArray(SHOW_APP_ON_TOP) << showOnTop;
diff --git a/src/libs/qmldebug/qmltoolsclient.h b/src/libs/qmldebug/qmltoolsclient.h
index 51dc6730afb..0a3aba6bd4b 100644
--- a/src/libs/qmldebug/qmltoolsclient.h
+++ b/src/libs/qmldebug/qmltoolsclient.h
@@ -35,17 +35,16 @@ class QMLDEBUG_EXPORT QmlToolsClient : public BaseToolsClient
public:
explicit QmlToolsClient(QmlDebugConnection *client);
- void setDesignModeBehavior(bool inDesignMode);
- void changeToSelectTool();
- void changeToSelectMarqueeTool();
- void changeToZoomTool();
- void showAppOnTop(bool showOnTop);
+ void setDesignModeBehavior(bool inDesignMode) override;
+ void changeToSelectTool() override;
+ void changeToSelectMarqueeTool() override;
+ void changeToZoomTool() override;
+ void showAppOnTop(bool showOnTop) override;
// ### Qt 4.8: remove if we can have access to qdeclarativecontextdata or id's
- void setObjectIdList(const QList<ObjectReference> &objectRoots);
+ void setObjectIdList(const QList<ObjectReference> &objectRoots) override;
-protected:
- void messageReceived(const QByteArray &);
+ void messageReceived(const QByteArray &) override;
private:
void log(LogDirection direction,
diff --git a/src/libs/qmldebug/qpacketprotocol.h b/src/libs/qmldebug/qpacketprotocol.h
index 33d1ecdbf6f..308fd7ba58c 100644
--- a/src/libs/qmldebug/qpacketprotocol.h
+++ b/src/libs/qmldebug/qpacketprotocol.h
@@ -50,7 +50,7 @@ public:
QByteArray read();
bool waitForReadyRead(int msecs = 3000);
-Q_SIGNALS:
+signals:
void readyRead();
void invalidPacket();
@@ -66,7 +66,6 @@ public:
QByteArray data() const;
private:
- void init(QIODevice::OpenMode mode);
QBuffer buf;
};
diff --git a/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp b/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp
index 86b83ef85a4..3a7c929d305 100644
--- a/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp
+++ b/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp
@@ -26,6 +26,7 @@
#include "easingcontextpane.h"
#include "ui_easingcontextpane.h"
#include <qmljs/qmljspropertyreader.h>
+#include <utils/utilsicons.h>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
@@ -124,9 +125,7 @@ EasingContextPane::EasingContextPane(QWidget *parent) :
m_easingGraph->raise();
setLinear();
- ui->playButton->setIcon(QIcon(QLatin1String(":/playicon.png")));
-
-
+ ui->playButton->setIcon(Utils::Icons::RUN_SMALL.icon());
setGraphDisplayMode(GraphMode);
@@ -228,14 +227,14 @@ void EasingContextPane::startAnimation()
m_simulation->stop();
} else {
m_simulation->animate(ui->durationSpinBox->value(), m_easingGraph->easingCurve());
- ui->playButton->setIcon(QIcon(QLatin1String(":/stopicon.png")));
+ ui->playButton->setIcon(Utils::Icons::STOP_SMALL.icon());
}
}
void EasingContextPane::switchToGraph()
{
- ui->playButton->setIcon(QIcon(QLatin1String(":/playicon.png")));
+ ui->playButton->setIcon(Utils::Icons::RUN_SMALL.icon());
setGraphDisplayMode(GraphMode);
}
diff --git a/src/libs/qmleditorwidgets/easingpane/easingpane.qrc b/src/libs/qmleditorwidgets/easingpane/easingpane.qrc
index f6e69536806..f90ab25d145 100644
--- a/src/libs/qmleditorwidgets/easingpane/easingpane.qrc
+++ b/src/libs/qmleditorwidgets/easingpane/easingpane.qrc
@@ -1,7 +1,5 @@
<RCC>
<qresource prefix="/">
<file>qt_logo.png</file>
- <file>playicon.png</file>
- <file>stopicon.png</file>
</qresource>
</RCC>
diff --git a/src/libs/qmleditorwidgets/easingpane/playicon.png b/src/libs/qmleditorwidgets/easingpane/playicon.png
deleted file mode 100644
index ba4f36b5bf5..00000000000
--- a/src/libs/qmleditorwidgets/easingpane/playicon.png
+++ /dev/null
Binary files differ
diff --git a/src/libs/qmleditorwidgets/easingpane/stopicon.png b/src/libs/qmleditorwidgets/easingpane/stopicon.png
deleted file mode 100644
index 74eb2ead324..00000000000
--- a/src/libs/qmleditorwidgets/easingpane/stopicon.png
+++ /dev/null
Binary files differ
diff --git a/src/libs/qmleditorwidgets/images/hole.png b/src/libs/qmleditorwidgets/images/hole.png
deleted file mode 100644
index b75cca1ea3d..00000000000
--- a/src/libs/qmleditorwidgets/images/hole.png
+++ /dev/null
Binary files differ
diff --git a/src/libs/qmleditorwidgets/images/lock.png b/src/libs/qmleditorwidgets/images/lock.png
deleted file mode 100644
index 8f1b546c8dc..00000000000
--- a/src/libs/qmleditorwidgets/images/lock.png
+++ /dev/null
Binary files differ
diff --git a/src/libs/qmleditorwidgets/resources.qrc b/src/libs/qmleditorwidgets/resources.qrc
index 5c7164c7b8e..5ac07864815 100644
--- a/src/libs/qmleditorwidgets/resources.qrc
+++ b/src/libs/qmleditorwidgets/resources.qrc
@@ -4,8 +4,6 @@
<file>images/checkbox_indicator@2x.png</file>
<file>images/tr.png</file>
<file>images/tr@2x.png</file>
- <file>images/lock.png</file>
- <file>images/hole.png</file>
<file>images/scrollbar-borderimage-horizontal.png</file>
<file>images/scrollbar-borderimage-vertical.png</file>
<file>images/aspectlockset.png</file>
diff --git a/src/libs/qmljs/parser/qmljslexer.cpp b/src/libs/qmljs/parser/qmljslexer.cpp
index 8ab06dc7ecf..d24920e24d9 100644
--- a/src/libs/qmljs/parser/qmljslexer.cpp
+++ b/src/libs/qmljs/parser/qmljslexer.cpp
@@ -72,6 +72,7 @@ static inline QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
Lexer::Lexer(Engine *engine)
: _engine(engine)
, _codePtr(0)
+ , _endPtr(0)
, _lastLinePtr(0)
, _tokenLinePtr(0)
, _tokenStartPtr(0)
diff --git a/src/libs/qmljs/parser/qmljsparser.cpp b/src/libs/qmljs/parser/qmljsparser.cpp
index 87cc41b00c6..1bba51e4102 100644
--- a/src/libs/qmljs/parser/qmljsparser.cpp
+++ b/src/libs/qmljs/parser/qmljsparser.cpp
@@ -78,6 +78,7 @@ Parser::Parser(Engine *engine):
location_stack(0),
string_stack(0),
program(0),
+ yylval(0),
first_token(0),
last_token(0)
{
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index 69fdcef6011..6bc596eacde 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -324,7 +324,7 @@ protected:
class MarkUnreachableCode : protected ReachesEndCheck
{
QList<Message> _messages;
- bool _emittedWarning;
+ bool _emittedWarning = false;
public:
QList<Message> operator()(Node *ast)
@@ -1709,6 +1709,7 @@ bool Check::visit(TypeOfExpression *ast)
/// ### Maybe put this into the context as a helper function.
const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
{
+
if (!_importsOk)
return 0;
@@ -1716,6 +1717,17 @@ const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
if (scopeObjects.isEmpty())
return 0;
+ const auto getAttachedTypes = [this, &scopeObjects](const QString &propertyName) {
+ bool isAttachedProperty = false;
+ if (! propertyName.isEmpty() && propertyName[0].isUpper()) {
+ isAttachedProperty = true;
+ if (const ObjectValue *qmlTypes = _scopeChain.qmlTypes())
+ scopeObjects += qmlTypes;
+ }
+ return isAttachedProperty;
+ };
+
+
if (! id)
return 0; // ### error?
@@ -1728,12 +1740,7 @@ const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
return 0; // ### should probably be a special value
// attached properties
- bool isAttachedProperty = false;
- if (! propertyName.isEmpty() && propertyName[0].isUpper()) {
- isAttachedProperty = true;
- if (const ObjectValue *qmlTypes = _scopeChain.qmlTypes())
- scopeObjects += qmlTypes;
- }
+ bool isAttachedProperty = getAttachedTypes(propertyName);
if (scopeObjects.isEmpty())
return 0;
@@ -1775,6 +1782,9 @@ const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
idPart = idPart->next;
propertyName = idPart->name.toString();
+ isAttachedProperty = getAttachedTypes(propertyName);
+ if (isAttachedProperty)
+ return 0;
value = objectValue->lookupMember(propertyName, _context);
if (! value) {
diff --git a/src/libs/qmljs/qmljscodeformatter.cpp b/src/libs/qmljs/qmljscodeformatter.cpp
index d4e3bfb0843..5d974d735b0 100644
--- a/src/libs/qmljs/qmljscodeformatter.cpp
+++ b/src/libs/qmljs/qmljscodeformatter.cpp
@@ -41,7 +41,8 @@ CodeFormatter::BlockData::BlockData()
}
CodeFormatter::CodeFormatter()
- : m_indentDepth(0)
+ : m_tokenIndex(0)
+ , m_indentDepth(0)
, m_tabSize(4)
{
}
diff --git a/src/libs/qmljs/qmljsdescribevalue.h b/src/libs/qmljs/qmljsdescribevalue.h
index 3c27c320e53..3c5d23bcbdb 100644
--- a/src/libs/qmljs/qmljsdescribevalue.h
+++ b/src/libs/qmljs/qmljsdescribevalue.h
@@ -65,7 +65,7 @@ private:
int m_depth;
int m_indent;
int m_indentIncrement;
- bool m_emptyContext;
+ bool m_emptyContext = false;
ContextPtr m_context;
QSet<const Value *> m_visited;
QString m_description;
diff --git a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp
index 7c45339d905..84ada6a0d63 100644
--- a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp
+++ b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp
@@ -252,7 +252,7 @@ protected:
_doc->fileName(),
line, column,
QmlJS::FindExportedCppTypes::tr(
- "The type will only be available in Qt Creator's QML editors when the type name is a string literal"));
+ "The type will only be available in the QML editors when the type name is a string literal"));
return false;
}
@@ -314,7 +314,7 @@ protected:
QmlJS::FindExportedCppTypes::tr(
"The module URI cannot be determined by static analysis. The type will be available\n"
"globally in the QML editor. You can add a \"// @uri My.Module.Uri\" annotation to let\n"
- "Qt Creator know about a likely URI."));
+ "the QML editor know about a likely URI."));
}
// version arguments must be integer literals
diff --git a/src/libs/qmljs/qmljsreformatter.cpp b/src/libs/qmljs/qmljsreformatter.cpp
index 6c4befa0f84..c78f52f5b8f 100644
--- a/src/libs/qmljs/qmljsreformatter.cpp
+++ b/src/libs/qmljs/qmljsreformatter.cpp
@@ -90,11 +90,11 @@ class Rewriter : protected Visitor
QList<Split> _possibleSplits;
QTextDocument _resultDocument;
SimpleFormatter _formatter;
- int _indent;
- int _nextComment;
- int _lastNewlineOffset;
- bool _hadEmptyLine;
- int _binaryExpDepth;
+ int _indent = 0;
+ int _nextComment = 0;
+ int _lastNewlineOffset = -1;
+ bool _hadEmptyLine = false;
+ int _binaryExpDepth = 0;
public:
Rewriter(Document::Ptr doc)
@@ -102,6 +102,9 @@ public:
{
}
+ void setIndentSize(int size) { _formatter.setIndentSize(size); }
+ void setTabSize(int size) { _formatter.setTabSize(size); }
+
QString operator()(Node *node)
{
Q_ASSERT(node == _doc->ast()); // comment handling fails otherwise
@@ -1099,7 +1102,8 @@ protected:
out("case ", ast->caseToken);
accept(ast->expression);
out(ast->colonToken);
- lnAcceptIndented(ast->statements);
+ if (ast->statements)
+ lnAcceptIndented(ast->statements);
return false;
}
@@ -1309,3 +1313,11 @@ QString QmlJS::reformat(const Document::Ptr &doc)
Rewriter rewriter(doc);
return rewriter(doc->ast());
}
+
+QString QmlJS::reformat(const Document::Ptr &doc, int indentSize, int tabSize)
+{
+ Rewriter rewriter(doc);
+ rewriter.setIndentSize(indentSize);
+ rewriter.setTabSize(tabSize);
+ return rewriter(doc->ast());
+}
diff --git a/src/libs/qmljs/qmljsreformatter.h b/src/libs/qmljs/qmljsreformatter.h
index 18d5c6fd85c..7465a1a17f0 100644
--- a/src/libs/qmljs/qmljsreformatter.h
+++ b/src/libs/qmljs/qmljsreformatter.h
@@ -31,4 +31,5 @@
namespace QmlJS {
QMLJS_EXPORT QString reformat(const Document::Ptr &doc);
+QMLJS_EXPORT QString reformat(const Document::Ptr &doc, int indentSize, int tabSize);
}
diff --git a/src/libs/qmljs/qmljsscopeastpath.h b/src/libs/qmljs/qmljsscopeastpath.h
index f06db11c5c8..44b4eacf7c1 100644
--- a/src/libs/qmljs/qmljsscopeastpath.h
+++ b/src/libs/qmljs/qmljsscopeastpath.h
@@ -56,7 +56,7 @@ private:
QList<AST::Node *> _result;
Document::Ptr _doc;
- quint32 _offset;
+ quint32 _offset = 0;
};
} // namespace QmlJS
diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.cpp b/src/libs/qmljs/qmljsstaticanalysismessage.cpp
index 34929ab3b64..389cbdf3485 100644
--- a/src/libs/qmljs/qmljsstaticanalysismessage.cpp
+++ b/src/libs/qmljs/qmljsstaticanalysismessage.cpp
@@ -254,7 +254,7 @@ QList<Type> Message::allMessageTypes()
}
Message::Message()
- : type(UnknownType), severity(Hint)
+ : type(UnknownType)
{}
Message::Message(Type type,
diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.h b/src/libs/qmljs/qmljsstaticanalysismessage.h
index 4d07614c8d5..109a85a0276 100644
--- a/src/libs/qmljs/qmljsstaticanalysismessage.h
+++ b/src/libs/qmljs/qmljsstaticanalysismessage.h
@@ -160,7 +160,7 @@ public:
AST::SourceLocation location;
QString message;
Type type;
- Severity::Enum severity;
+ Severity::Enum severity = Severity::Enum::Hint;
static const PrototypeMessageData prototypeForMessageType(Type type);
};
diff --git a/src/libs/qmljs/qmljstypedescriptionreader.h b/src/libs/qmljs/qmljstypedescriptionreader.h
index 900ec383048..69eec45b175 100644
--- a/src/libs/qmljs/qmljstypedescriptionreader.h
+++ b/src/libs/qmljs/qmljstypedescriptionreader.h
@@ -91,8 +91,8 @@ private:
QString _errorMessage;
QString _warningMessage;
QHash<QString, LanguageUtils::FakeMetaObject::ConstPtr> *_objects;
- QList<ModuleApiInfo> *_moduleApis;
- QStringList *_dependencies;
+ QList<ModuleApiInfo> *_moduleApis = nullptr;
+ QStringList *_dependencies = nullptr;
};
} // namespace QmlJS
diff --git a/src/libs/qt-breakpad/poster/__init__.py b/src/libs/qt-breakpad/poster/__init__.py
new file mode 100644
index 00000000000..e963d70b960
--- /dev/null
+++ b/src/libs/qt-breakpad/poster/__init__.py
@@ -0,0 +1,32 @@
+# Copyright (c) 2010 Chris AtLee
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+"""poster module
+
+Support for streaming HTTP uploads, and multipart/form-data encoding
+
+```poster.version``` is a 3-tuple of integers representing the version number.
+New releases of poster will always have a version number that compares greater
+than an older version of poster.
+New in version 0.6."""
+
+import poster.streaminghttp
+import poster.encode
+
+version = (0, 8, 0) # Thanks JP!
diff --git a/src/libs/qt-breakpad/poster/encode.py b/src/libs/qt-breakpad/poster/encode.py
new file mode 100644
index 00000000000..fbc4e764527
--- /dev/null
+++ b/src/libs/qt-breakpad/poster/encode.py
@@ -0,0 +1,433 @@
+# Copyright (c) 2010 Chris AtLee
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+"""multipart/form-data encoding module
+
+This module provides functions that faciliate encoding name/value pairs
+as multipart/form-data suitable for a HTTP POST or PUT request.
+
+multipart/form-data is the standard way to upload files over HTTP"""
+
+__all__ = ['gen_boundary', 'encode_and_quote', 'MultipartParam',
+ 'encode_string', 'encode_file_header', 'get_body_size', 'get_headers',
+ 'multipart_encode']
+
+try:
+ import uuid
+ def gen_boundary():
+ """Returns a random string to use as the boundary for a message"""
+ return uuid.uuid4().hex
+except ImportError:
+ import random, sha
+ def gen_boundary():
+ """Returns a random string to use as the boundary for a message"""
+ bits = random.getrandbits(160)
+ return sha.new(str(bits)).hexdigest()
+
+import urllib, re, os, mimetypes
+try:
+ from email.header import Header
+except ImportError:
+ # Python 2.4
+ from email.Header import Header
+
+def encode_and_quote(data):
+ """If ``data`` is unicode, return urllib.quote_plus(data.encode("utf-8"))
+ otherwise return urllib.quote_plus(data)"""
+ if data is None:
+ return None
+
+ if isinstance(data, unicode):
+ data = data.encode("utf-8")
+ return urllib.quote_plus(data)
+
+def _strify(s):
+ """If s is a unicode string, encode it to UTF-8 and return the results,
+ otherwise return str(s), or None if s is None"""
+ if s is None:
+ return None
+ if isinstance(s, unicode):
+ return s.encode("utf-8")
+ return str(s)
+
+class MultipartParam(object):
+ """Represents a single parameter in a multipart/form-data request
+
+ ``name`` is the name of this parameter.
+
+ If ``value`` is set, it must be a string or unicode object to use as the
+ data for this parameter.
+
+ If ``filename`` is set, it is what to say that this parameter's filename
+ is. Note that this does not have to be the actual filename any local file.
+
+ If ``filetype`` is set, it is used as the Content-Type for this parameter.
+ If unset it defaults to "text/plain; charset=utf8"
+
+ If ``filesize`` is set, it specifies the length of the file ``fileobj``
+
+ If ``fileobj`` is set, it must be a file-like object that supports
+ .read().
+
+ Both ``value`` and ``fileobj`` must not be set, doing so will
+ raise a ValueError assertion.
+
+ If ``fileobj`` is set, and ``filesize`` is not specified, then
+ the file's size will be determined first by stat'ing ``fileobj``'s
+ file descriptor, and if that fails, by seeking to the end of the file,
+ recording the current position as the size, and then by seeking back to the
+ beginning of the file.
+
+ ``cb`` is a callable which will be called from iter_encode with (self,
+ current, total), representing the current parameter, current amount
+ transferred, and the total size.
+ """
+ def __init__(self, name, value=None, filename=None, filetype=None,
+ filesize=None, fileobj=None, cb=None):
+ self.name = Header(name).encode()
+ self.value = _strify(value)
+ if filename is None:
+ self.filename = None
+ else:
+ if isinstance(filename, unicode):
+ # Encode with XML entities
+ self.filename = filename.encode("ascii", "xmlcharrefreplace")
+ else:
+ self.filename = str(filename)
+ self.filename = self.filename.encode("string_escape").\
+ replace('"', '\\"')
+ self.filetype = _strify(filetype)
+
+ self.filesize = filesize
+ self.fileobj = fileobj
+ self.cb = cb
+
+ if self.value is not None and self.fileobj is not None:
+ raise ValueError("Only one of value or fileobj may be specified")
+
+ if fileobj is not None and filesize is None:
+ # Try and determine the file size
+ try:
+ self.filesize = os.fstat(fileobj.fileno()).st_size
+ except (OSError, AttributeError):
+ try:
+ fileobj.seek(0, 2)
+ self.filesize = fileobj.tell()
+ fileobj.seek(0)
+ except:
+ raise ValueError("Could not determine filesize")
+
+ def __cmp__(self, other):
+ attrs = ['name', 'value', 'filename', 'filetype', 'filesize', 'fileobj']
+ myattrs = [getattr(self, a) for a in attrs]
+ oattrs = [getattr(other, a) for a in attrs]
+ return cmp(myattrs, oattrs)
+
+ def reset(self):
+ if self.fileobj is not None:
+ self.fileobj.seek(0)
+ elif self.value is None:
+ raise ValueError("Don't know how to reset this parameter")
+
+ @classmethod
+ def from_file(cls, paramname, filename):
+ """Returns a new MultipartParam object constructed from the local
+ file at ``filename``.
+
+ ``filesize`` is determined by os.path.getsize(``filename``)
+
+ ``filetype`` is determined by mimetypes.guess_type(``filename``)[0]
+
+ ``filename`` is set to os.path.basename(``filename``)
+ """
+
+ return cls(paramname, filename=os.path.basename(filename),
+ filetype=mimetypes.guess_type(filename)[0],
+ filesize=os.path.getsize(filename),
+ fileobj=open(filename, "rb"))
+
+ @classmethod
+ def from_params(cls, params):
+ """Returns a list of MultipartParam objects from a sequence of
+ name, value pairs, MultipartParam instances,
+ or from a mapping of names to values
+
+ The values may be strings or file objects, or MultipartParam objects.
+ MultipartParam object names must match the given names in the
+ name,value pairs or mapping, if applicable."""
+ if hasattr(params, 'items'):
+ params = params.items()
+
+ retval = []
+ for item in params:
+ if isinstance(item, cls):
+ retval.append(item)
+ continue
+ name, value = item
+ if isinstance(value, cls):
+ assert value.name == name
+ retval.append(value)
+ continue
+ if hasattr(value, 'read'):
+ # Looks like a file object
+ filename = getattr(value, 'name', None)
+ if filename is not None:
+ filetype = mimetypes.guess_type(filename)[0]
+ else:
+ filetype = None
+
+ retval.append(cls(name=name, filename=filename,
+ filetype=filetype, fileobj=value))
+ else:
+ retval.append(cls(name, value))
+ return retval
+
+ def encode_hdr(self, boundary):
+ """Returns the header of the encoding of this parameter"""
+ boundary = encode_and_quote(boundary)
+
+ headers = ["--%s" % boundary]
+
+ if self.filename:
+ disposition = 'form-data; name="%s"; filename="%s"' % (self.name,
+ self.filename)
+ else:
+ disposition = 'form-data; name="%s"' % self.name
+
+ headers.append("Content-Disposition: %s" % disposition)
+
+ if self.filetype:
+ filetype = self.filetype
+ else:
+ filetype = "text/plain; charset=utf-8"
+
+ headers.append("Content-Type: %s" % filetype)
+
+ headers.append("")
+ headers.append("")
+
+ return "\r\n".join(headers)
+
+ def encode(self, boundary):
+ """Returns the string encoding of this parameter"""
+ if self.value is None:
+ value = self.fileobj.read()
+ else:
+ value = self.value
+
+ if re.search("^--%s$" % re.escape(boundary), value, re.M):
+ raise ValueError("boundary found in encoded string")
+
+ return "%s%s\r\n" % (self.encode_hdr(boundary), value)
+
+ def iter_encode(self, boundary, blocksize=4096):
+ """Yields the encoding of this parameter
+ If self.fileobj is set, then blocks of ``blocksize`` bytes are read and
+ yielded."""
+ total = self.get_size(boundary)
+ current = 0
+ if self.value is not None:
+ block = self.encode(boundary)
+ current += len(block)
+ yield block
+ if self.cb:
+ self.cb(self, current, total)
+ else:
+ block = self.encode_hdr(boundary)
+ current += len(block)
+ yield block
+ if self.cb:
+ self.cb(self, current, total)
+ last_block = ""
+ encoded_boundary = "--%s" % encode_and_quote(boundary)
+ boundary_exp = re.compile("^%s$" % re.escape(encoded_boundary),
+ re.M)
+ while True:
+ block = self.fileobj.read(blocksize)
+ if not block:
+ current += 2
+ yield "\r\n"
+ if self.cb:
+ self.cb(self, current, total)
+ break
+ last_block += block
+ if boundary_exp.search(last_block):
+ raise ValueError("boundary found in file data")
+ last_block = last_block[-len(encoded_boundary)-2:]
+ current += len(block)
+ yield block
+ if self.cb:
+ self.cb(self, current, total)
+
+ def get_size(self, boundary):
+ """Returns the size in bytes that this param will be when encoded
+ with the given boundary."""
+ if self.filesize is not None:
+ valuesize = self.filesize
+ else:
+ valuesize = len(self.value)
+
+ return len(self.encode_hdr(boundary)) + 2 + valuesize
+
+def encode_string(boundary, name, value):
+ """Returns ``name`` and ``value`` encoded as a multipart/form-data
+ variable. ``boundary`` is the boundary string used throughout
+ a single request to separate variables."""
+
+ return MultipartParam(name, value).encode(boundary)
+
+def encode_file_header(boundary, paramname, filesize, filename=None,
+ filetype=None):
+ """Returns the leading data for a multipart/form-data field that contains
+ file data.
+
+ ``boundary`` is the boundary string used throughout a single request to
+ separate variables.
+
+ ``paramname`` is the name of the variable in this request.
+
+ ``filesize`` is the size of the file data.
+
+ ``filename`` if specified is the filename to give to this field. This
+ field is only useful to the server for determining the original filename.
+
+ ``filetype`` if specified is the MIME type of this file.
+
+ The actual file data should be sent after this header has been sent.
+ """
+
+ return MultipartParam(paramname, filesize=filesize, filename=filename,
+ filetype=filetype).encode_hdr(boundary)
+
+def get_body_size(params, boundary):
+ """Returns the number of bytes that the multipart/form-data encoding
+ of ``params`` will be."""
+ size = sum(p.get_size(boundary) for p in MultipartParam.from_params(params))
+ return size + len(boundary) + 6
+
+def get_headers(params, boundary):
+ """Returns a dictionary with Content-Type and Content-Length headers
+ for the multipart/form-data encoding of ``params``."""
+ headers = {}
+ boundary = urllib.quote_plus(boundary)
+ headers['Content-Type'] = "multipart/form-data; boundary=%s" % boundary
+ headers['Content-Length'] = str(get_body_size(params, boundary))
+ return headers
+
+class multipart_yielder:
+ def __init__(self, params, boundary, cb):
+ self.params = params
+ self.boundary = boundary
+ self.cb = cb
+
+ self.i = 0
+ self.p = None
+ self.param_iter = None
+ self.current = 0
+ self.total = get_body_size(params, boundary)
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ """generator function to yield multipart/form-data representation
+ of parameters"""
+ if self.param_iter is not None:
+ try:
+ block = self.param_iter.next()
+ self.current += len(block)
+ if self.cb:
+ self.cb(self.p, self.current, self.total)
+ return block
+ except StopIteration:
+ self.p = None
+ self.param_iter = None
+
+ if self.i is None:
+ raise StopIteration
+ elif self.i >= len(self.params):
+ self.param_iter = None
+ self.p = None
+ self.i = None
+ block = "--%s--\r\n" % self.boundary
+ self.current += len(block)
+ if self.cb:
+ self.cb(self.p, self.current, self.total)
+ return block
+
+ self.p = self.params[self.i]
+ self.param_iter = self.p.iter_encode(self.boundary)
+ self.i += 1
+ return self.next()
+
+ def reset(self):
+ self.i = 0
+ self.current = 0
+ for param in self.params:
+ param.reset()
+
+def multipart_encode(params, boundary=None, cb=None):
+ """Encode ``params`` as multipart/form-data.
+
+ ``params`` should be a sequence of (name, value) pairs or MultipartParam
+ objects, or a mapping of names to values.
+ Values are either strings parameter values, or file-like objects to use as
+ the parameter value. The file-like objects must support .read() and either
+ .fileno() or both .seek() and .tell().
+
+ If ``boundary`` is set, then it as used as the MIME boundary. Otherwise
+ a randomly generated boundary will be used. In either case, if the
+ boundary string appears in the parameter values a ValueError will be
+ raised.
+
+ If ``cb`` is set, it should be a callback which will get called as blocks
+ of data are encoded. It will be called with (param, current, total),
+ indicating the current parameter being encoded, the current amount encoded,
+ and the total amount to encode.
+
+ Returns a tuple of `datagen`, `headers`, where `datagen` is a
+ generator that will yield blocks of data that make up the encoded
+ parameters, and `headers` is a dictionary with the assoicated
+ Content-Type and Content-Length headers.
+
+ Examples:
+
+ >>> datagen, headers = multipart_encode( [("key", "value1"), ("key", "value2")] )
+ >>> s = "".join(datagen)
+ >>> assert "value2" in s and "value1" in s
+
+ >>> p = MultipartParam("key", "value2")
+ >>> datagen, headers = multipart_encode( [("key", "value1"), p] )
+ >>> s = "".join(datagen)
+ >>> assert "value2" in s and "value1" in s
+
+ >>> datagen, headers = multipart_encode( {"key": "value1"} )
+ >>> s = "".join(datagen)
+ >>> assert "value2" not in s and "value1" in s
+
+ """
+ if boundary is None:
+ boundary = gen_boundary()
+ else:
+ boundary = urllib.quote_plus(boundary)
+
+ headers = get_headers(params, boundary)
+ params = MultipartParam.from_params(params)
+
+ return multipart_yielder(params, boundary, cb), headers
diff --git a/src/libs/qt-breakpad/poster/streaminghttp.py b/src/libs/qt-breakpad/poster/streaminghttp.py
new file mode 100644
index 00000000000..eb3b4661d36
--- /dev/null
+++ b/src/libs/qt-breakpad/poster/streaminghttp.py
@@ -0,0 +1,216 @@
+# Copyright (c) 2010 Chris AtLee
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+"""Streaming HTTP uploads module.
+
+This module extends the standard httplib and urllib2 objects so that
+iterable objects can be used in the body of HTTP requests.
+
+In most cases all one should have to do is call :func:`register_openers()`
+to register the new streaming http handlers which will take priority over
+the default handlers, and then you can use iterable objects in the body
+of HTTP requests.
+
+**N.B.** You must specify a Content-Length header if using an iterable object
+since there is no way to determine in advance the total size that will be
+yielded, and there is no way to reset an interator.
+
+Example usage:
+
+>>> from StringIO import StringIO
+>>> import urllib2, poster.streaminghttp
+
+>>> opener = poster.streaminghttp.register_openers()
+
+>>> s = "Test file data"
+>>> f = StringIO(s)
+
+>>> req = urllib2.Request("http://localhost:5000", f,
+... {'Content-Length': str(len(s))})
+"""
+
+import httplib, urllib2, socket
+from httplib import NotConnected
+
+__all__ = ['StreamingHTTPConnection', 'StreamingHTTPRedirectHandler',
+ 'StreamingHTTPHandler', 'register_openers']
+
+if hasattr(httplib, 'HTTPS'):
+ __all__.extend(['StreamingHTTPSHandler', 'StreamingHTTPSConnection'])
+
+class _StreamingHTTPMixin:
+ """Mixin class for HTTP and HTTPS connections that implements a streaming
+ send method."""
+ def send(self, value):
+ """Send ``value`` to the server.
+
+ ``value`` can be a string object, a file-like object that supports
+ a .read() method, or an iterable object that supports a .next()
+ method.
+ """
+ # Based on python 2.6's httplib.HTTPConnection.send()
+ if self.sock is None:
+ if self.auto_open:
+ self.connect()
+ else:
+ raise NotConnected()
+
+ # send the data to the server. if we get a broken pipe, then close
+ # the socket. we want to reconnect when somebody tries to send again.
+ #
+ # NOTE: we DO propagate the error, though, because we cannot simply
+ # ignore the error... the caller will know if they can retry.
+ if self.debuglevel > 0:
+ print "send:", repr(value)
+ try:
+ blocksize = 8192
+ if hasattr(value, 'read') :
+ if hasattr(value, 'seek'):
+ value.seek(0)
+ if self.debuglevel > 0:
+ print "sendIng a read()able"
+ data = value.read(blocksize)
+ while data:
+ self.sock.sendall(data)
+ data = value.read(blocksize)
+ elif hasattr(value, 'next'):
+ if hasattr(value, 'reset'):
+ value.reset()
+ if self.debuglevel > 0:
+ print "sendIng an iterable"
+ for data in value:
+ self.sock.sendall(data)
+ else:
+ self.sock.sendall(value)
+ except socket.error, v:
+ if v[0] == 32: # Broken pipe
+ self.close()
+ raise
+
+class StreamingHTTPConnection(_StreamingHTTPMixin, httplib.HTTPConnection):
+ """Subclass of `httplib.HTTPConnection` that overrides the `send()` method
+ to support iterable body objects"""
+
+class StreamingHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
+ """Subclass of `urllib2.HTTPRedirectHandler` that overrides the
+ `redirect_request` method to properly handle redirected POST requests
+
+ This class is required because python 2.5's HTTPRedirectHandler does
+ not remove the Content-Type or Content-Length headers when requesting
+ the new resource, but the body of the original request is not preserved.
+ """
+
+ handler_order = urllib2.HTTPRedirectHandler.handler_order - 1
+
+ # From python2.6 urllib2's HTTPRedirectHandler
+ def redirect_request(self, req, fp, code, msg, headers, newurl):
+ """Return a Request or None in response to a redirect.
+
+ This is called by the http_error_30x methods when a
+ redirection response is received. If a redirection should
+ take place, return a new Request to allow http_error_30x to
+ perform the redirect. Otherwise, raise HTTPError if no-one
+ else should try to handle this url. Return None if you can't
+ but another Handler might.
+ """
+ m = req.get_method()
+ if (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
+ or code in (301, 302, 303) and m == "POST"):
+ # Strictly (according to RFC 2616), 301 or 302 in response
+ # to a POST MUST NOT cause a redirection without confirmation
+ # from the user (of urllib2, in this case). In practice,
+ # essentially all clients do redirect in this case, so we
+ # do the same.
+ # be conciliant with URIs containing a space
+ newurl = newurl.replace(' ', '%20')
+ newheaders = dict((k, v) for k, v in req.headers.items()
+ if k.lower() not in (
+ "content-length", "content-type")
+ )
+ return urllib2.Request(newurl,
+ headers=newheaders,
+ origin_req_host=req.get_origin_req_host(),
+ unverifiable=True)
+ else:
+ raise urllib2.HTTPError(req.get_full_url(), code, msg, headers, fp)
+
+class StreamingHTTPHandler(urllib2.HTTPHandler):
+ """Subclass of `urllib2.HTTPHandler` that uses
+ StreamingHTTPConnection as its http connection class."""
+
+ handler_order = urllib2.HTTPHandler.handler_order - 1
+
+ def http_open(self, req):
+ """Open a StreamingHTTPConnection for the given request"""
+ return self.do_open(StreamingHTTPConnection, req)
+
+ def http_request(self, req):
+ """Handle a HTTP request. Make sure that Content-Length is specified
+ if we're using an interable value"""
+ # Make sure that if we're using an iterable object as the request
+ # body, that we've also specified Content-Length
+ if req.has_data():
+ data = req.get_data()
+ if hasattr(data, 'read') or hasattr(data, 'next'):
+ if not req.has_header('Content-length'):
+ raise ValueError(
+ "No Content-Length specified for iterable body")
+ return urllib2.HTTPHandler.do_request_(self, req)
+
+if hasattr(httplib, 'HTTPS'):
+ class StreamingHTTPSConnection(_StreamingHTTPMixin,
+ httplib.HTTPSConnection):
+ """Subclass of `httplib.HTTSConnection` that overrides the `send()`
+ method to support iterable body objects"""
+
+ class StreamingHTTPSHandler(urllib2.HTTPSHandler):
+ """Subclass of `urllib2.HTTPSHandler` that uses
+ StreamingHTTPSConnection as its http connection class."""
+
+ handler_order = urllib2.HTTPSHandler.handler_order - 1
+
+ def https_open(self, req):
+ return self.do_open(StreamingHTTPSConnection, req)
+
+ def https_request(self, req):
+ # Make sure that if we're using an iterable object as the request
+ # body, that we've also specified Content-Length
+ if req.has_data():
+ data = req.get_data()
+ if hasattr(data, 'read') or hasattr(data, 'next'):
+ if not req.has_header('Content-length'):
+ raise ValueError(
+ "No Content-Length specified for iterable body")
+ return urllib2.HTTPSHandler.do_request_(self, req)
+
+
+def register_openers():
+ """Register the streaming http handlers in the global urllib2 default
+ opener object.
+
+ Returns the created OpenerDirector object."""
+ handlers = [StreamingHTTPHandler, StreamingHTTPRedirectHandler]
+ if hasattr(httplib, "HTTPS"):
+ handlers.append(StreamingHTTPSHandler)
+
+ opener = urllib2.build_opener(*handlers)
+
+ urllib2.install_opener(opener)
+
+ return opener
diff --git a/src/libs/qt-breakpad/qtbreakpad.pri b/src/libs/qt-breakpad/qtbreakpad.pri
new file mode 100644
index 00000000000..4eada575c1c
--- /dev/null
+++ b/src/libs/qt-breakpad/qtbreakpad.pri
@@ -0,0 +1,64 @@
+isEmpty(BREAKPAD_SOURCE_DIR): return()
+
+HEADERS += $$PWD/qtbreakpad/qtsystemexceptionhandler.h
+SOURCES += $$PWD/qtbreakpad/qtsystemexceptionhandler.cpp
+
+DEFINES += ENABLE_QT_BREAKPAD
+
+win32:BREAKPAD_SOURCE_DIR ~= s,\\,/,
+
+INCLUDEPATH += \
+ $$BREAKPAD_SOURCE_DIR/src \
+ $$PWD/qtbreakpad
+
+SOURCES += \
+ $$BREAKPAD_SOURCE_DIR/src/common/string_conversion.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/convert_UTF.c \
+ $$BREAKPAD_SOURCE_DIR/src/common/md5.cc
+
+linux:SOURCES += \
+ $$BREAKPAD_SOURCE_DIR/src/client/minidump_file_writer.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/linux/log/log.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/linux/handler/exception_handler.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/linux/handler/minidump_descriptor.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/linux/guid_creator.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/linux/dump_writer_common/thread_info.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/linux/dump_writer_common/ucontext_reader.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/linux/minidump_writer/linux_dumper.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/linux/minidump_writer/minidump_writer.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/linux/minidump_writer/linux_ptrace_dumper.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/linux/microdump_writer/microdump_writer.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/linux/file_id.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/linux/elfutils.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/linux/linux_libc_support.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/linux/memory_mapped_file.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/linux/safe_readlink.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/linux/crash_generation/crash_generation_client.cc
+
+win32:SOURCES += \
+ $$BREAKPAD_SOURCE_DIR/src/common/windows/guid_string.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/windows/handler/exception_handler.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/windows/crash_generation/minidump_generator.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/windows/crash_generation/client_info.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/windows/crash_generation/crash_generation_client.cc
+
+macos {
+ SOURCES += \
+ $$BREAKPAD_SOURCE_DIR/src/client/minidump_file_writer.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/mac/crash_generation/crash_generation_client.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/mac/handler/exception_handler.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/mac/handler/minidump_generator.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/mac/handler/breakpad_nlist_64.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/mac/handler/dynamic_images.cc \
+ $$BREAKPAD_SOURCE_DIR/src/client/mac/handler/protected_memory_allocator.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/mac/bootstrap_compat.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/mac/file_id.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/mac/macho_id.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/mac/macho_reader.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/mac/macho_utilities.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/mac/macho_walker.cc \
+ $$BREAKPAD_SOURCE_DIR/src/common/mac/string_utilities.cc
+ OBJECTIVE_SOURCES += \
+ $$BREAKPAD_SOURCE_DIR/src/common/mac/MachIPC.mm
+ LIBS += -framework Foundation
+}
diff --git a/src/libs/qt-breakpad/qtbreakpad/qtsystemexceptionhandler.cpp b/src/libs/qt-breakpad/qtbreakpad/qtsystemexceptionhandler.cpp
new file mode 100644
index 00000000000..d439ba112de
--- /dev/null
+++ b/src/libs/qt-breakpad/qtbreakpad/qtsystemexceptionhandler.cpp
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qtsystemexceptionhandler.h"
+
+#include <utils/fileutils.h>
+#include <utils/hostosinfo.h>
+
+#include <QCoreApplication>
+#include <QDebug>
+#include <QDir>
+#include <QProcess>
+
+#if defined(Q_OS_LINUX)
+# include "client/linux/handler/exception_handler.h"
+#elif defined(Q_OS_WIN)
+# include "client/windows/handler/exception_handler.h"
+#elif defined(Q_OS_MACOS)
+# include "client/mac/handler/exception_handler.h"
+#endif
+
+#if defined(Q_OS_LINUX)
+static bool exceptionHandlerCallback(const google_breakpad::MinidumpDescriptor& descriptor,
+ void* /*context*/,
+ bool succeeded)
+{
+ if (!succeeded)
+ return succeeded;
+
+ const QStringList argumentList = {
+ QString::fromLocal8Bit(descriptor.path()),
+ QString::number(QtSystemExceptionHandler::startTime().toTime_t()),
+ QCoreApplication::applicationName(),
+ QCoreApplication::applicationVersion(),
+ QtSystemExceptionHandler::plugins(),
+ QtSystemExceptionHandler::buildVersion(),
+ QCoreApplication::applicationFilePath()
+ };
+
+ return !QProcess::execute(QtSystemExceptionHandler::crashHandlerPath(), argumentList);
+}
+#elif defined(Q_OS_MACOS)
+static bool exceptionHandlerCallback(const char *dump_dir,
+ const char *minidump_id,
+ void *context,
+ bool succeeded)
+{
+ Q_UNUSED(context);
+
+ if (!succeeded)
+ return succeeded;
+
+ const QString path = QString::fromLocal8Bit(dump_dir) + '/'
+ + QString::fromLocal8Bit(minidump_id) + ".dmp";
+ const QStringList argumentList = {
+ path,
+ QString::number(QtSystemExceptionHandler::startTime().toTime_t()),
+ QCoreApplication::applicationName(),
+ QCoreApplication::applicationVersion(),
+ QtSystemExceptionHandler::plugins(),
+ QtSystemExceptionHandler::buildVersion(),
+ QCoreApplication::applicationFilePath()
+ };
+
+ return !QProcess::execute(QtSystemExceptionHandler::crashHandlerPath(), argumentList);
+}
+#elif defined(Q_OS_WIN)
+static bool exceptionHandlerCallback(const wchar_t* dump_path,
+ const wchar_t* minidump_id,
+ void* context,
+ EXCEPTION_POINTERS* exinfo,
+ MDRawAssertionInfo* assertion,
+ bool succeeded)
+{
+ Q_UNUSED(assertion);
+ Q_UNUSED(exinfo);
+ Q_UNUSED(context);
+
+ if (!succeeded)
+ return succeeded;
+
+ const QString path = QString::fromWCharArray(dump_path, int(wcslen(dump_path))) + '/'
+ + QString::fromWCharArray(minidump_id, int(wcslen(minidump_id))) + ".dmp";
+ const QStringList argumentList = {
+ path,
+ QString::number(QtSystemExceptionHandler::startTime().toTime_t()),
+ QCoreApplication::applicationName(),
+ QCoreApplication::applicationVersion(),
+ QtSystemExceptionHandler::plugins(),
+ QtSystemExceptionHandler::buildVersion(),
+ QCoreApplication::applicationFilePath()
+ };
+
+ return !QProcess::execute(QtSystemExceptionHandler::crashHandlerPath(), argumentList);
+}
+#endif
+
+static QDateTime s_startTime;
+static QString s_plugins;
+static QString s_buildVersion;
+static QString s_crashHandlerPath;
+
+#if defined(Q_OS_LINUX)
+QtSystemExceptionHandler::QtSystemExceptionHandler(const QString &libexecPath)
+ : exceptionHandler(new google_breakpad::ExceptionHandler(
+ google_breakpad::MinidumpDescriptor(QDir::tempPath().toStdString()),
+ NULL,
+ exceptionHandlerCallback,
+ NULL,
+ true,
+ -1))
+{
+ init(libexecPath);
+}
+#elif defined(Q_OS_MACOS)
+QtSystemExceptionHandler::QtSystemExceptionHandler(const QString &libexecPath)
+ : exceptionHandler(new google_breakpad::ExceptionHandler(
+ QDir::tempPath().toStdString(),
+ NULL,
+ exceptionHandlerCallback,
+ NULL,
+ true,
+ NULL))
+{
+ init(libexecPath);
+}
+#elif defined(Q_OS_WIN)
+QtSystemExceptionHandler::QtSystemExceptionHandler(const QString &libexecPath)
+ : exceptionHandler(new google_breakpad::ExceptionHandler(
+ QDir::tempPath().toStdWString(),
+ NULL,
+ exceptionHandlerCallback,
+ NULL,
+ google_breakpad::ExceptionHandler::HANDLER_ALL))
+{
+ init(libexecPath);
+}
+#else
+QtSystemExceptionHandler::QtSystemExceptionHandler(const QString & /*libexecPath*/)
+ : exceptionHandler(0)
+{
+
+}
+#endif
+
+void QtSystemExceptionHandler::init(const QString &libexecPath)
+{
+ s_startTime = QDateTime::currentDateTime();
+ s_crashHandlerPath = libexecPath + Utils::HostOsInfo::withExecutableSuffix("/qtcrashhandler");
+}
+
+QtSystemExceptionHandler::~QtSystemExceptionHandler()
+{
+#ifdef ENABLE_QT_BREAKPAD
+ delete exceptionHandler;
+#endif
+}
+
+void QtSystemExceptionHandler::setPlugins(const QStringList &pluginNameList)
+{
+ s_plugins = QString("{%1}").arg(pluginNameList.join(","));
+}
+
+void QtSystemExceptionHandler::setBuildVersion(const QString &version)
+{
+ s_buildVersion = version;
+}
+
+QString QtSystemExceptionHandler::buildVersion()
+{
+ return s_buildVersion;
+}
+
+QString QtSystemExceptionHandler::plugins()
+{
+ return s_plugins;
+}
+
+void QtSystemExceptionHandler::setCrashHandlerPath(const QString &crashHandlerPath)
+{
+ s_crashHandlerPath = crashHandlerPath;
+}
+
+QString QtSystemExceptionHandler::crashHandlerPath()
+{
+ return s_crashHandlerPath;
+}
+
+void QtSystemExceptionHandler::crash()
+{
+ int *a = (int*)0x42;
+
+ fprintf(stdout, "Going to crash...\n");
+ fprintf(stdout, "A = %d", *a);
+}
+
+QDateTime QtSystemExceptionHandler::startTime()
+{
+ return s_startTime;
+}
diff --git a/src/libs/qt-breakpad/qtbreakpad/qtsystemexceptionhandler.h b/src/libs/qt-breakpad/qtbreakpad/qtsystemexceptionhandler.h
new file mode 100644
index 00000000000..2cc3067d776
--- /dev/null
+++ b/src/libs/qt-breakpad/qtbreakpad/qtsystemexceptionhandler.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QDateTime>
+
+namespace google_breakpad {
+ class ExceptionHandler;
+}
+
+class QtSystemExceptionHandler
+{
+public:
+ QtSystemExceptionHandler(const QString &libexecPath);
+ ~QtSystemExceptionHandler();
+
+ static void crash();
+ static void setPlugins(const QStringList &pluginNameList);
+ static void setBuildVersion(const QString &version);
+ static void setCrashHandlerPath(const QString &crashHandlerPath);
+
+ static QString plugins();
+ static QString buildVersion();
+ static QString crashHandlerPath();
+
+ static QDateTime startTime();
+
+protected:
+ void init(const QString &libexecPath);
+
+private:
+ google_breakpad::ExceptionHandler *exceptionHandler = nullptr;
+};
diff --git a/src/libs/qt-breakpad/qtbreakpadsymbols b/src/libs/qt-breakpad/qtbreakpadsymbols
new file mode 100755
index 00000000000..3b7c5af8ffc
--- /dev/null
+++ b/src/libs/qt-breakpad/qtbreakpadsymbols
@@ -0,0 +1,271 @@
+#!/usr/bin/python
+
+import sys
+import os
+import os.path
+import subprocess
+import shlex
+import shutil
+import base64
+
+from poster.encode import multipart_encode
+from poster.encode import MultipartParam
+from poster.streaminghttp import register_openers
+import urllib2
+
+from optparse import OptionParser
+
+register_openers()
+
+breakpadSourceDir = os.environ['BREAKPAD_SOURCE_DIR']
+breakpadUploadUrl = os.environ['BREAKPAD_UPLOAD_URL']
+breakpadUserName = os.environ['BREAKPAD_USER_NAME']
+breakpadUserPassword = os.environ['BREAKPAD_USER_PASSWORD']
+
+if sys.platform == 'win32':
+ nullfilename = 'nul:'
+else:
+ nullfilename = '/dev/null'
+nullfile = open(nullfilename, 'r+b')
+
+
+def stdoutFromProcess(process):
+ (stdout, stderr) = process.communicate()
+ if stderr:
+ print stderr
+ raise SystemError()
+ sys.exit(1)
+ return stdout
+
+def toolPath():
+ if sys.platform == 'linux2':
+ dumpsymsPath = os.path.join(breakpadSourceDir, 'src/tools/linux/dump_syms/dump_syms')
+ elif sys.platform == 'darwin':
+ dumpsymsPath = os.path.join(breakpadSourceDir, 'src/tools/mac/dump_syms/build/Release/dump_syms')
+ elif sys.platform == 'win32':
+ dumpsymsPath = os.path.join(breakpadSourceDir,'src\\tools\\windows\\binaries\\dump_syms.exe')
+ else:
+ sys.exit(1)
+ return dumpsymsPath
+
+gitRootDirectoryCache = {}
+
+def gitRootDirectory(path):
+ directory = os.path.dirname(path)
+ if directory in gitRootDirectoryCache:
+ return gitRootDirectoryCache[directory]
+ directoryList = directory.split(os.sep)
+ while len(directoryList) > 0:
+ gitDirectory = os.sep.join(directoryList + ['.git'])
+ if os.path.exists(gitDirectory):
+ gitDirectory = os.sep.join(directoryList)
+ gitRootDirectoryCache[directory] = gitDirectory
+ return gitDirectory
+ directoryList.pop()
+
+ return None
+
+
+gitCommitShaCache = {}
+
+
+def gitCommitSha(gitRootPath):
+ if gitRootPath in gitCommitShaCache:
+ return gitCommitShaCache[gitRootPath]
+ gitProcess = subprocess.Popen(shlex.split('git rev-parse HEAD'),
+ stdout=subprocess.PIPE,
+ stderr=nullfile, cwd=gitRootPath)
+ commitSha = stdoutFromProcess(gitProcess).strip('\n')
+ gitCommitShaCache[gitRootPath] = commitSha
+ return commitSha
+
+
+gitRemoteRepositoryCache = {}
+
+
+def gitRemoteRepository(gitRootPath):
+ if gitRootPath in gitRemoteRepositoryCache:
+ return gitRemoteRepositoryCache[gitRootPath]
+ gitProcess = \
+ subprocess.Popen(shlex.split('git config remote.origin.url'),
+ stdout=subprocess.PIPE, stderr=nullfile,
+ cwd=gitRootPath)
+ repository = stdoutFromProcess(gitProcess).strip('\n')
+ gitRemoteRepositoryCache[gitRootPath] = repository
+ return repository
+
+
+gitFilePathCache = {}
+
+
+def populateFilePathCache(gitRootPath):
+ if gitRootPath not in gitFilePathCache:
+ gitProcess = \
+ subprocess.Popen(shlex.split('git ls-files --full-name'),
+ stdout=subprocess.PIPE, stderr=nullfile,
+ cwd=gitRootPath)
+ fileNameList = stdoutFromProcess(gitProcess).split('\n')
+ filePathCache = {}
+ for fileName in fileNameList:
+ baseFileName = os.path.basename(fileName)
+ filePathCache[baseFileName] = fileName
+ gitFilePathCache[gitRootPath] = filePathCache
+
+
+def gitFilePath(path, gitRootPath):
+ if not gitRootPath:
+ return path
+
+ populateFilePathCache(gitRootPath)
+
+ baseFileName = os.path.basename(path)
+ filePathCache = gitFilePathCache[gitRootPath]
+ if baseFileName in filePathCache:
+ return filePathCache[baseFileName]
+ else:
+ return os.path.relpath(path, gitRootPath)
+
+
+def isInRepository(path):
+ gitRootPath = gitRootDirectory(path)
+ if not gitRootPath:
+ return False
+
+ populateFilePathCache(gitRootPath)
+ baseFileName = os.path.basename(path)
+ if baseFileName in gitFilePathCache[gitRootPath]:
+ return True
+ else:
+ return False
+
+
+def sendSymbolsToServer(
+ breakpadUploadUrl,
+ symbolText,
+ codeFile,
+ debugFile,
+ debugIdentifier,
+ operatingSystem,
+ cpu,
+ ):
+ (data, headers) = multipart_encode({
+ 'symbol_file': MultipartParam('symbol_file', value=symbolText,
+ filename='symbol_file'),
+ 'code_file': codeFile,
+ 'debug_file': debugFile,
+ 'debug_identifier': debugIdentifier,
+ 'os': operatingSystem,
+ 'cpu': cpu,
+ })
+ request = urllib2.Request(breakpadUploadUrl, data, headers)
+ auth = base64.encodestring('%s:%s' % (breakpadUserName,
+ breakpadUserPassword))[:-1] # This is just standard un/pw encoding
+ request.add_header('Authorization', 'Basic %s' % auth) # Add Auth header to request
+ result = urllib2.urlopen(request).read()
+
+
+def generateSymbolFilesAndSend(binaryPath, projectPath):
+ dumpsymsPath = toolPath()
+
+ originalBinaryPath = binaryPath
+
+ if sys.platform == 'darwin':
+ dsymutilProcess = \
+ subprocess.Popen(shlex.split('/usr/bin/dsymutil "'
+ + binaryPath + '"'), stdout=nullfile,
+ stderr=nullfile)
+ dsymutilProcess.wait()
+ binaryPath += os.path.join('.dSYM/Contents/Resources/DWARF/',
+ os.path.basename(binaryPath))
+
+ binaryPath = os.path.normpath(binaryPath)
+
+ dumpsymsProcess = subprocess.Popen(shlex.split('"' + dumpsymsPath
+ + '" "' + binaryPath + '"'), stdout=subprocess.PIPE,
+ stderr=nullfile, cwd=projectPath)
+ symbolList = stdoutFromProcess(dumpsymsProcess).split('\n')
+
+ outputTextList = []
+ codeFile = os.path.basename(binaryPath)
+ debugFile = ''
+ debugIdentifier = ''
+ operatingSystem = ''
+ cpu = ''
+ moduleNotParsed = True
+ for line in symbolList:
+ line = line.strip('\n').strip('\r')
+ if line[:4] == 'FILE':
+ (marker, idnumber, filepath) = line.split(' ', 2)
+ filepath = os.path.normpath(os.path.join(projectPath,
+ filepath))
+
+ if isInRepository(filepath):
+ gitRootPath = gitRootDirectory(filepath)
+ commitSha = gitCommitSha(gitRootPath)
+ repository = \
+ gitRemoteRepository(gitRootPath).replace(':', '/')
+ relativeFilePath = gitFilePath(filepath,
+ gitRootPath).replace('\\', '/')
+ outputTextList.append('FILE ' + idnumber + ' git:'
+ + repository + ':' + relativeFilePath + ':'
+ + commitSha)
+ else:
+ outputTextList.append(line)
+ elif moduleNotParsed and line[:6] == 'MODULE':
+ (operatingSystem, cpu, debugIdentifier, debugFile) = \
+ line[7:].split(' ', 3)
+ moduleNotParsed = False
+ elif line:
+ outputTextList.append(line)
+
+ if moduleNotParsed:
+ print 'Module not parsed'
+ sys.exit(1)
+
+ sendSymbolsToServer(
+ breakpadUploadUrl,
+ '\n'.join(outputTextList),
+ codeFile,
+ debugFile,
+ debugIdentifier,
+ operatingSystem,
+ cpu,
+ )
+
+ if sys.platform == 'darwin':
+ shutil.rmtree(originalBinaryPath + '.dSYM')
+
+
+def testForBreakpad():
+ try:
+ dumpsymsPath = toolPath()
+ if not dumpsymsPath:
+ sys.exit(1)
+ subprocess.Popen([dumpsymsPath], stdout=nullfile,
+ stderr=nullfile)
+ except (OSError, KeyError):
+ print 'No dumpsyms can be executed. Maybe BREAKPAD_SOURCE_DIR is wrong.'
+ sys.exit(1)
+ sys.exit(0)
+
+
+def main():
+ usage = 'usage: %prog [options] binary projectpath'
+ parser = OptionParser(usage=usage)
+ parser.add_option('-v', '--verbose', action='store_true',
+ dest='verbose')
+ parser.add_option('-e', '--breakpad-exists', action='store_true',
+ dest='testForBreakpad')
+
+ (options, args) = parser.parse_args()
+
+ if options.testForBreakpad == True:
+ testForBreakpad()
+ if len(args) > 1:
+ generateSymbolFilesAndSend(args[0], args[1])
+ else:
+ parser.print_help()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/libs/qt-breakpad/qtbreakpadsymbols.bat b/src/libs/qt-breakpad/qtbreakpadsymbols.bat
new file mode 100644
index 00000000000..aad26594d66
--- /dev/null
+++ b/src/libs/qt-breakpad/qtbreakpadsymbols.bat
@@ -0,0 +1 @@
+@python qtbreakpadsymbols %*
diff --git a/src/libs/qt-breakpad/qtcrashhandler.pri b/src/libs/qt-breakpad/qtcrashhandler.pri
new file mode 100644
index 00000000000..c452c09bd84
--- /dev/null
+++ b/src/libs/qt-breakpad/qtcrashhandler.pri
@@ -0,0 +1,21 @@
+isEmpty(BREAKPAD_SOURCE_DIR): return()
+
+QT += network
+
+INCLUDEPATH += \
+ $$BREAKPAD_SOURCE_DIR/src \
+ $$PWD/qtcrashhandler
+
+SOURCES += \
+ $$PWD/qtcrashhandler/main.cpp \
+ $$PWD/qtcrashhandler/mainwidget.cpp \
+ $$PWD/qtcrashhandler/detaildialog.cpp \
+ $$PWD/qtcrashhandler/dumpsender.cpp
+
+HEADERS += \
+ $$PWD/qtcrashhandler/mainwidget.h \
+ $$PWD/qtcrashhandler/detaildialog.h \
+ $$PWD/qtcrashhandler/dumpsender.h
+
+FORMS += \
+ $$PWD/qtcrashhandler/mainwidget.ui
diff --git a/src/libs/qt-breakpad/qtcrashhandler/detaildialog.cpp b/src/libs/qt-breakpad/qtcrashhandler/detaildialog.cpp
new file mode 100644
index 00000000000..21c7e87c896
--- /dev/null
+++ b/src/libs/qt-breakpad/qtcrashhandler/detaildialog.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "detaildialog.h"
+
+#include <QDialogButtonBox>
+#include <QTextBrowser>
+#include <QVBoxLayout>
+
+DetailDialog::DetailDialog(QWidget *parent) :
+ QDialog(parent)
+{
+ resize(640, 480);
+ QVBoxLayout *verticalLayout = new QVBoxLayout(this);
+ textBrowser = new QTextBrowser(this);
+ verticalLayout->addWidget(textBrowser);
+ buttonBox = new QDialogButtonBox(this);
+ buttonBox->setOrientation(Qt::Horizontal);
+ buttonBox->setStandardButtons(QDialogButtonBox::Close);
+
+ verticalLayout->addWidget(buttonBox);
+ connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
+}
+
+DetailDialog::~DetailDialog()
+{
+}
+
+void DetailDialog::setText(const QString &text)
+{
+ textBrowser->setPlainText(text);
+}
diff --git a/src/libs/qt-breakpad/qtcrashhandler/detaildialog.h b/src/libs/qt-breakpad/qtcrashhandler/detaildialog.h
new file mode 100644
index 00000000000..9db319a4e8f
--- /dev/null
+++ b/src/libs/qt-breakpad/qtcrashhandler/detaildialog.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+class QTextBrowser;
+class QDialogButtonBox;
+QT_END_NAMESPACE
+
+class DetailDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit DetailDialog(QWidget *parent = nullptr);
+ ~DetailDialog();
+
+ void setText(const QString &text);
+
+private:
+ QTextBrowser *textBrowser = nullptr;
+ QDialogButtonBox *buttonBox = nullptr;
+};
diff --git a/src/libs/qt-breakpad/qtcrashhandler/dumpsender.cpp b/src/libs/qt-breakpad/qtcrashhandler/dumpsender.cpp
new file mode 100644
index 00000000000..5b0d1ac3d52
--- /dev/null
+++ b/src/libs/qt-breakpad/qtcrashhandler/dumpsender.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "dumpsender.h"
+
+#include <QCoreApplication>
+#include <QDateTime>
+#include <QDebug>
+#include <QFile>
+#include <QFileInfo>
+#include <QHttpMultiPart>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QPair>
+#include <QProcess>
+#include <QStringList>
+#include <QTemporaryFile>
+#include <QUrl>
+
+static const QByteArray boundary = "12345cfdfzfsdfsdfassssaaadsd24324jxccxzzzzz98xzcz";
+
+DumpSender::DumpSender(QObject *parent) :
+ QObject(parent),
+ m_httpMultiPart(QHttpMultiPart::FormDataType)
+{
+ const QString dumpPath = QCoreApplication::arguments().at(1);
+ const QByteArray startupTime = QCoreApplication::arguments().at(2).toLocal8Bit();
+ const QByteArray applicationName = QCoreApplication::arguments().at(3).toLocal8Bit();
+ QByteArray applicationVersion = QCoreApplication::arguments().at(4).toLocal8Bit();
+ const QByteArray plugins = QCoreApplication::arguments().at(5).toLocal8Bit();
+ // QByteArray ideRevision = QCoreApplication::arguments().at(6).toLocal8Bit();
+ m_applicationFilePath = QCoreApplication::arguments().at(7);
+
+ if (applicationVersion.isEmpty())
+ applicationVersion = "1.0.0";
+
+ QFile dumpFile(dumpPath, this);
+ const bool isOpen = dumpFile.open(QIODevice::ReadOnly);
+ Q_ASSERT(isOpen);
+ Q_UNUSED(isOpen);
+
+ const QList<QPair<QByteArray, QByteArray> > pairList = {
+ { "StartupTime", startupTime },
+ { "Vendor", "Qt Project" },
+ { "InstallTime", "0" },
+ { "Add-ons", plugins },
+ { "BuildID", "" },
+ { "SecondsSinceLastCrash", "0" },
+ { "ProductName", applicationName },
+ { "URL", "" },
+ { "Theme", "" },
+ { "Version", applicationVersion },
+ { "CrashTime", QByteArray::number(QDateTime::currentDateTime().toTime_t()) },
+ { "Throttleable", "0" }
+ };
+
+ m_formData.append("--" + boundary + "\r\n");
+ for (const auto &pair : pairList) {
+ m_formData.append("Content-Disposition: form-data; name=\"" + pair.first + "\"\r\n\r\n");
+ m_formData.append(pair.second + "\r\n");
+ m_formData.append("--" + boundary + "\r\n");
+ }
+
+
+ QByteArray dumpArray = dumpFile.readAll();
+ m_formData.append("Content-Type: application/octet-stream\r\n");
+ m_formData.append("Content-Disposition: form-data; name=\"upload_file_minidump\"; filename=\""
+ + QFileInfo(dumpPath).baseName().toUtf8() + "\r\n");
+ m_formData.append("Content-Transfer-Encoding: binary\r\n\r\n");
+ m_formData.append(dumpArray);
+
+ m_formData.append("--" + boundary + "--\r\n");
+
+ for (const auto &pair : pairList) {
+ QHttpPart httpPart;
+ httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"" + pair.first + "\"");
+ httpPart.setBody(pair.second);
+ m_httpMultiPart.append(httpPart);
+ }
+
+ QHttpPart dumpPart;
+ dumpPart.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");
+ dumpPart.setHeader(QNetworkRequest::ContentDispositionHeader,
+ "form-data; name=\"upload_file_minidump\"; filename=\""
+ + QFileInfo(dumpPath).baseName().toUtf8() + "\"");
+ dumpPart.setRawHeader("Content-Transfer-Encoding:", "binary");
+ dumpPart.setBody(dumpArray);
+ m_httpMultiPart.append(dumpPart);
+}
+
+void DumpSender::sendDumpAndQuit()
+{
+ QNetworkAccessManager *manager = new QNetworkAccessManager(this);
+
+ QNetworkRequest request(QUrl("http://crashes.qt.io/submit"));
+
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + boundary);
+
+ QList<QPair<QByteArray, QByteArray>> pairList;
+
+ if (!m_emailAddress.isEmpty())
+ pairList.append({ "Email", m_emailAddress.toLocal8Bit() });
+
+ if (!m_commentText.isEmpty())
+ pairList.append({ "Comments", m_commentText.toLocal8Bit() });
+
+ for (const auto &pair : pairList) {
+ m_formData.append("Content-Disposition: form-data; name=\"" + pair.first + "\"\r\n\r\n");
+ m_formData.append(pair.second + "\r\n");
+ m_formData.append("--" + boundary + "\r\n");
+ }
+
+ for (const auto &pair : pairList) {
+ QHttpPart httpPart;
+ httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"" + pair.first + "\"");
+ httpPart.setBody(pair.second);
+ m_httpMultiPart.append(httpPart);
+ }
+
+ QNetworkReply *reply = manager->post(request, &m_httpMultiPart);
+
+ m_httpMultiPart.setParent(reply);
+
+ connect(reply, &QNetworkReply::uploadProgress, this, &DumpSender::uploadProgress);
+ connect(reply, &QNetworkReply::finished, QCoreApplication::instance(), &QCoreApplication::quit);
+ connect(reply,
+ static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
+ QCoreApplication::instance(), &QCoreApplication::quit);
+}
+
+void DumpSender::restartCrashedApplicationAndSendDump()
+{
+ QProcess::startDetached(m_applicationFilePath);
+ sendDumpAndQuit();
+}
+
+void DumpSender::restartCrashedApplication()
+{
+ QProcess::startDetached(m_applicationFilePath);
+ QCoreApplication::quit();
+}
+
+void DumpSender::setEmailAddress(const QString &email)
+{
+ m_emailAddress = email;
+}
+
+void DumpSender::setCommentText(const QString &comment)
+{
+ m_commentText = comment;
+}
+
+int DumpSender::dumperSize() const
+{
+ return m_formData.size();
+}
diff --git a/src/libs/sqlite/sqlitedatabaseconnection.h b/src/libs/qt-breakpad/qtcrashhandler/dumpsender.h
index bbf813ffe6c..4a57a5e99de 100644
--- a/src/libs/sqlite/sqlitedatabaseconnection.h
+++ b/src/libs/qt-breakpad/qtcrashhandler/dumpsender.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,33 +25,31 @@
#pragma once
-#include "sqlitedatabasebackend.h"
-
+#include <QHttpMultiPart>
#include <QObject>
-struct sqlite3;
-
-class SQLITE_EXPORT SqliteDatabaseConnection final : public QObject
+class DumpSender : public QObject
{
Q_OBJECT
-public:
- explicit SqliteDatabaseConnection(QObject *parent = 0);
- ~SqliteDatabaseConnection();
- static sqlite3 *currentSqliteDatabase();
+public:
+ explicit DumpSender(QObject *parent = nullptr);
-public slots:
- void setDatabaseFilePath(const QString &databaseName);
- void setJournalMode(JournalMode journalMode);
- void close();
+ int dumperSize() const;
-protected:
- void prioritizeThreadDown();
+ void sendDumpAndQuit();
+ void restartCrashedApplication();
+ void restartCrashedApplicationAndSendDump();
+ void setEmailAddress(const QString &email);
+ void setCommentText(const QString &comment);
signals:
- void databaseConnectionIsOpened();
- void databaseConnectionIsClosed();
+ void uploadProgress(qint64 bytesSent, qint64 bytesTotal);
private:
- SqliteDatabaseBackend databaseBackend;
+ QHttpMultiPart m_httpMultiPart;
+ QByteArray m_formData;
+ QString m_applicationFilePath;
+ QString m_emailAddress;
+ QString m_commentText;
};
diff --git a/src/libs/qt-breakpad/qtcrashhandler/main.cpp b/src/libs/qt-breakpad/qtcrashhandler/main.cpp
new file mode 100644
index 00000000000..7a307381cc8
--- /dev/null
+++ b/src/libs/qt-breakpad/qtcrashhandler/main.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "mainwidget.h"
+#include "dumpsender.h"
+
+#include <QApplication>
+#include <QFileInfo>
+#include <QHostInfo>
+#include <QNetworkProxyFactory>
+
+int main(int argc, char *argv[])
+{
+ QApplication application(argc, argv);
+
+ if (application.arguments().count() <= 1)
+ return 0;
+
+ const QString dumpPath = QApplication::arguments().at(1);
+ if (!QFileInfo(dumpPath).exists())
+ return 0;
+
+ QNetworkProxyFactory::setUseSystemConfiguration(true);
+
+ QHostInfo hostInfo = QHostInfo::fromName("crashes.qt.io");
+
+// if (hostInfo.error() != QHostInfo::NoError)
+// return 0;
+
+ DumpSender dumpSender;
+
+ MainWidget mainWindow;
+
+ mainWindow.setProgressbarMaximum(dumpSender.dumperSize());
+
+ QObject::connect(&mainWindow, &MainWidget::restartCrashedApplication,
+ &dumpSender, &DumpSender::restartCrashedApplication);
+ QObject::connect(&mainWindow, &MainWidget::restartCrashedApplicationAndSendDump,
+ &dumpSender, &DumpSender::restartCrashedApplicationAndSendDump);
+ QObject::connect(&mainWindow, &MainWidget::sendDump,
+ &dumpSender, &DumpSender::sendDumpAndQuit);
+ QObject::connect(&mainWindow, &MainWidget::commentChanged,
+ &dumpSender, &DumpSender::setCommentText);
+ QObject::connect(&mainWindow, &MainWidget::emailAdressChanged,
+ &dumpSender, &DumpSender::setEmailAddress);
+ QObject::connect(&dumpSender, &DumpSender::uploadProgress,
+ &mainWindow, &MainWidget::updateProgressBar);
+
+ mainWindow.show();
+ return application.exec();
+}
diff --git a/src/libs/qt-breakpad/qtcrashhandler/mainwidget.cpp b/src/libs/qt-breakpad/qtcrashhandler/mainwidget.cpp
new file mode 100644
index 00000000000..0fc4f2e1d47
--- /dev/null
+++ b/src/libs/qt-breakpad/qtcrashhandler/mainwidget.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "mainwidget.h"
+#include "ui_mainwidget.h"
+
+#include <QApplication>
+#include <QDateTime>
+#include <QFile>
+#include <QFileInfo>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QPair>
+#include <QStringList>
+#include <QTemporaryFile>
+#include <QUrl>
+
+MainWidget::MainWidget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::MainWidget)
+{
+ ui->setupUi(this);
+
+ connect(ui->restartButton, &QAbstractButton::clicked, this, &MainWidget::restartApplication);
+ connect(ui->quitButton, &QAbstractButton::clicked, this, &MainWidget::quitApplication);
+ connect(ui->detailButton, &QAbstractButton::clicked, this, &MainWidget::showDetails);
+ connect(ui->commentTextEdit, &QTextEdit::textChanged, this, &MainWidget::commentIsProvided);
+ connect(ui->emailLineEdit, &QLineEdit::textEdited, this, &MainWidget::emailAdressChanged);
+}
+
+MainWidget::~MainWidget()
+{
+ delete ui;
+}
+
+void MainWidget::setProgressbarMaximum(int maximum)
+{
+ ui->progressBar->setMaximum(maximum);
+}
+
+void MainWidget::changeEvent(QEvent *e)
+{
+ QWidget::changeEvent(e);
+ if (e->type() == QEvent::LanguageChange)
+ ui->retranslateUi(this);
+}
+
+void MainWidget::updateProgressBar(qint64 progressCount, qint64 fullCount)
+{
+ ui->progressBar->setValue(static_cast<int>(progressCount));
+ ui->progressBar->setMaximum(static_cast<int>(fullCount));
+}
+
+void MainWidget::showError(QNetworkReply::NetworkError error)
+{
+ QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
+ if (error != QNetworkReply::NoError && reply) {
+ ui->commentTextEdit->setReadOnly(true);
+ ui->commentTextEdit->setPlainText(reply->errorString());
+ }
+}
+
+void MainWidget::restartApplication()
+{
+ if (ui->sendDumpCheckBox->isChecked())
+ emit restartCrashedApplicationAndSendDump();
+ else
+ emit restartCrashedApplication();
+}
+
+void MainWidget::quitApplication()
+{
+ ui->quitButton->setEnabled(false);
+ if (ui->sendDumpCheckBox->isChecked())
+ emit sendDump();
+ else
+ QCoreApplication::quit();
+}
+
+void MainWidget::commentIsProvided()
+{
+ m_commentIsProvided = true;
+ emit commentChanged(ui->commentTextEdit->toPlainText());
+}
+
+void MainWidget::showDetails()
+{
+ if (m_detailDialog.isNull()) {
+ m_detailDialog = new DetailDialog(this);
+
+ QString detailText;
+
+ detailText.append(tr("We specifically send the following information:\n\n"));
+
+ QString dumpPath = QApplication::arguments().at(1);
+ QString startupTime = QApplication::arguments().at(2);
+ QString applicationName = QApplication::arguments().at(3);
+ QString applicationVersion = QApplication::arguments().at(4);
+ QString plugins = QApplication::arguments().at(5);
+ QString ideRevision = QApplication::arguments().at(6);
+
+ detailText.append(QString("StartupTime: %1\n").arg(startupTime));
+ detailText.append(QString("Vendor: %1\n").arg("Qt Project"));
+ detailText.append(QString("InstallTime: %1\n").arg("0"));
+ detailText.append(QString("Add-ons: %1\n").arg(plugins));
+ detailText.append(QString("BuildID: %1\n").arg("0"));
+ detailText.append(QString("SecondsSinceLastCrash: %1\n").arg("0"));
+ detailText.append(QString("ProductName: %1\n").arg(applicationName));
+ detailText.append(QString("URL: %1\n").arg(""));
+ detailText.append(QString("Theme: %1\n").arg(""));
+ detailText.append(QString("Version: %1\n").arg(applicationVersion));
+ detailText.append(QString("CrashTime: %1\n").arg(QString::number(QDateTime::currentDateTime().toTime_t())));
+
+ if (!ui->emailLineEdit->text().isEmpty())
+ detailText.append(tr("Email: %1\n").arg(ui->emailLineEdit->text()));
+
+ if (m_commentIsProvided)
+ detailText.append(tr("Comments: %1\n").arg(ui->commentTextEdit->toPlainText()));
+
+ detailText.append(
+ tr("In addition, we send a Microsoft Minidump file, which contains information "
+ "about this computer, such as the operating system and CPU, and most "
+ "importantly, it contains the stacktrace, which is an internal structure that "
+ "shows where the program crashed. This information will help us to identify "
+ "the cause of the crash and to fix it."));
+
+ m_detailDialog.data()->setText(detailText);
+ }
+ if (m_detailDialog->isVisible())
+ m_detailDialog->showNormal();
+ else
+ m_detailDialog->show();
+}
diff --git a/src/libs/sqlite/sqlitedatabaseconnectionproxy.h b/src/libs/qt-breakpad/qtcrashhandler/mainwidget.h
index ddc25f18b92..4e3b9880c15 100644
--- a/src/libs/sqlite/sqlitedatabaseconnectionproxy.h
+++ b/src/libs/qt-breakpad/qtcrashhandler/mainwidget.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,39 +25,46 @@
#pragma once
-#include <sqliteglobal.h>
+#include "detaildialog.h"
-#include <QObject>
+#include <QByteArray>
+#include <QNetworkReply>
#include <QPointer>
+#include <QWidget>
-struct sqlite3;
-class SqliteWorkerThread;
+namespace Ui { class MainWidget; }
-class SQLITE_EXPORT SqliteDatabaseConnectionProxy final : public QObject
+class MainWidget : public QWidget
{
Q_OBJECT
-public:
- explicit SqliteDatabaseConnectionProxy(const QString &threadName);
- ~SqliteDatabaseConnectionProxy();
-
- QThread *connectionThread() const;
- bool isOpen() const;
+public:
+ explicit MainWidget(QWidget *parent = nullptr);
+ ~MainWidget();
- static void registerTypes();
+ void setProgressbarMaximum(int maximum);
+ void updateProgressBar(qint64 progressCount, qint64 fullCount);
signals:
- void setDatabaseFilePath(const QString &databaseFilePath);
- void setJournalMode(JournalMode journal);
- void connectionIsOpened();
- void connectionIsClosed();
- void close();
+ void restartCrashedApplication();
+ void sendDump();
+ void restartCrashedApplicationAndSendDump();
+ void emailAdressChanged(const QString &email);
+ void commentChanged(const QString &comment);
-private slots:
- void handleDatabaseConnectionIsOpened();
- void handleDatabaseConnectionIsClosed();
+protected:
+ void changeEvent(QEvent *e);
private:
- QPointer<SqliteWorkerThread> databaseConnectionThread;
- bool databaseConnectionIsOpen;
+ void restartApplication();
+ void quitApplication();
+ void showError(QNetworkReply::NetworkError error);
+ void showDetails();
+ void commentIsProvided();
+
+private:
+ Ui::MainWidget *ui;
+
+ QPointer<DetailDialog> m_detailDialog;
+ bool m_commentIsProvided = false;
};
diff --git a/src/libs/qt-breakpad/qtcrashhandler/mainwidget.ui b/src/libs/qt-breakpad/qtcrashhandler/mainwidget.ui
new file mode 100644
index 00000000000..f509a705695
--- /dev/null
+++ b/src/libs/qt-breakpad/qtcrashhandler/mainwidget.ui
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWidget</class>
+ <widget class="QWidget" name="MainWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>422</width>
+ <height>510</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Crash Handler</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="font">
+ <font>
+ <pointsize>20</pointsize>
+ </font>
+ </property>
+ <property name="text">
+ <string>Qt Creator has crashed</string>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>You can send us a crash report in order to help us diagnose and fix the problem.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Email:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="emailLineEdit">
+ <property name="placeholderText">
+ <string>Enter here your email (optional)</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="sendDumpCheckBox">
+ <property name="text">
+ <string>Tell The Qt Company about this crash so they can fix it</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="detailButton">
+ <property name="text">
+ <string>Details</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="commentTextEdit">
+ <property name="overwriteMode">
+ <bool>true</bool>
+ </property>
+ <property name="placeholderText">
+ <string>Please describe what you did before it crashed (comments are publicly visible)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Your crash report will be submitted before you quit or restart.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="format">
+ <string>%v/%m Bytes</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="restartButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Restart</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="quitButton">
+ <property name="text">
+ <string>Quit</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/libs/qt-breakpad/qtcrashhandler/qtcrashhandler.pro b/src/libs/qt-breakpad/qtcrashhandler/qtcrashhandler.pro
new file mode 100644
index 00000000000..f4bca4e3222
--- /dev/null
+++ b/src/libs/qt-breakpad/qtcrashhandler/qtcrashhandler.pro
@@ -0,0 +1,6 @@
+TARGET = qtcrashhandler
+QT += network
+TEMPLATE = app
+
+include(../qtcrashhandler.pri)
+DESTDIR = ../bin
diff --git a/src/libs/qt-breakpad/testapp/main.cpp b/src/libs/qt-breakpad/testapp/main.cpp
new file mode 100644
index 00000000000..1f21f86e4b0
--- /dev/null
+++ b/src/libs/qt-breakpad/testapp/main.cpp
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include <qtsystemexceptionhandler.h>
+
+#include <QCoreApplication>
+#include <QTimer>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication a(argc, argv);
+
+ a.setApplicationName("testapp");
+ a.setApplicationVersion("1.0.0");
+
+ QtSystemExceptionHandler exceptionHandler;
+
+ QTimer::singleShot(100, [] { QtSystemExceptionHandler::crash(); });
+
+ return a.exec();
+}
diff --git a/src/libs/qt-breakpad/testapp/testapp.pro b/src/libs/qt-breakpad/testapp/testapp.pro
new file mode 100644
index 00000000000..407ad1e2eaa
--- /dev/null
+++ b/src/libs/qt-breakpad/testapp/testapp.pro
@@ -0,0 +1,14 @@
+QT -= gui
+
+include(../qtbreakpad.pri)
+
+unix:TARGET = testapp.bin
+win32:TARGET = testapp
+
+## install_name_tool -change libQtBreakpad.1.dylib @executable_path/../lib/qtbreakpad/libQtBreakpad.dylib
+
+DESTDIR = ../bin
+
+CONFIG += console release c++11
+
+SOURCES += main.cpp
diff --git a/src/libs/sqlite/columndefinition.h b/src/libs/sqlite/columndefinition.h
deleted file mode 100644
index 91f64cb24c1..00000000000
--- a/src/libs/sqlite/columndefinition.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "sqliteglobal.h"
-#include "utf8string.h"
-
-namespace Internal {
-
-class ColumnDefinition
-{
-public:
- void setName(const Utf8String &name);
- const Utf8String &name() const;
-
- void setType(ColumnType type);
- ColumnType type() const;
- Utf8String typeString() const;
-
- void setIsPrimaryKey(bool isPrimaryKey);
- bool isPrimaryKey() const;
-
-private:
- Utf8String name_;
- ColumnType type_;
- bool isPrimaryKey_ = false;
-};
-
-}
diff --git a/src/libs/sqlite/createtablecommand.cpp b/src/libs/sqlite/createtablecommand.cpp
deleted file mode 100644
index 590fda2e936..00000000000
--- a/src/libs/sqlite/createtablecommand.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "createtablecommand.h"
-
-namespace Internal {
-
-void CreateTableCommand::registerType()
-{
- qRegisterMetaType<CreateTableCommand>("CreateTableCommand");
-}
-
-} // namespace Internal
-
diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.cpp b/src/libs/sqlite/createtablesqlstatementbuilder.cpp
index 71ca071997a..9a64d8e488d 100644
--- a/src/libs/sqlite/createtablesqlstatementbuilder.cpp
+++ b/src/libs/sqlite/createtablesqlstatementbuilder.cpp
@@ -25,102 +25,129 @@
#include "createtablesqlstatementbuilder.h"
-#include "utf8stringvector.h"
-
-namespace Internal {
+namespace Sqlite {
CreateTableSqlStatementBuilder::CreateTableSqlStatementBuilder()
- : sqlStatementBuilder(Utf8StringLiteral("CREATE TABLE IF NOT EXISTS $table($columnDefinitions)$withoutRowId")),
- useWithoutRowId(false)
+ : m_sqlStatementBuilder("CREATE $temporaryTABLE $ifNotExits$table($columnDefinitions)$withoutRowId")
{
}
-void CreateTableSqlStatementBuilder::setTable(const Utf8String &tableName)
+void CreateTableSqlStatementBuilder::setTableName(Utils::SmallString &&tableName)
{
- sqlStatementBuilder.clear();
+ m_sqlStatementBuilder.clear();
- this->tableName = tableName;
+ this->m_tableName = std::move(tableName);
}
-void CreateTableSqlStatementBuilder::addColumnDefinition(const Utf8String &columnName,
- ColumnType columnType,
- bool isPrimaryKey)
+void CreateTableSqlStatementBuilder::addColumn(Utils::SmallString &&columnName,
+ ColumnType columnType,
+ Contraint constraint)
{
- sqlStatementBuilder.clear();
-
- ColumnDefinition columnDefinition;
- columnDefinition.setName(columnName);
- columnDefinition.setType(columnType);
- columnDefinition.setIsPrimaryKey(isPrimaryKey);
+ m_sqlStatementBuilder.clear();
- columnDefinitions.append(columnDefinition);
+ m_columns.emplace_back(std::move(columnName), columnType, constraint);
}
-void CreateTableSqlStatementBuilder::setColumnDefinitions(const QVector<ColumnDefinition> &columnDefinitions)
+void CreateTableSqlStatementBuilder::setColumns(const SqliteColumns &columns)
{
- sqlStatementBuilder.clear();
+ m_sqlStatementBuilder.clear();
- this->columnDefinitions = columnDefinitions;
+ m_columns = std::move(columns);
}
void CreateTableSqlStatementBuilder::setUseWithoutRowId(bool useWithoutRowId)
{
- this->useWithoutRowId = useWithoutRowId;
+ m_useWithoutRowId = useWithoutRowId;
+}
+
+void CreateTableSqlStatementBuilder::setUseIfNotExists(bool useIfNotExists)
+{
+ m_useIfNotExits = useIfNotExists;
+}
+
+void CreateTableSqlStatementBuilder::setUseTemporaryTable(bool useTemporaryTable)
+{
+ m_useTemporaryTable = useTemporaryTable;
}
void CreateTableSqlStatementBuilder::clear()
{
- sqlStatementBuilder.clear();
- columnDefinitions.clear();
- tableName.clear();
- useWithoutRowId = false;
+ m_sqlStatementBuilder.clear();
+ m_columns.clear();
+ m_tableName.clear();
+ m_useWithoutRowId = false;
}
void CreateTableSqlStatementBuilder::clearColumns()
{
- sqlStatementBuilder.clear();
- columnDefinitions.clear();
+ m_sqlStatementBuilder.clear();
+ m_columns.clear();
}
-Utf8String CreateTableSqlStatementBuilder::sqlStatement() const
+Utils::SmallStringView CreateTableSqlStatementBuilder::sqlStatement() const
{
- if (!sqlStatementBuilder.isBuild())
+ if (!m_sqlStatementBuilder.isBuild())
bindAll();
- return sqlStatementBuilder.sqlStatement();
+ return m_sqlStatementBuilder.sqlStatement();
}
bool CreateTableSqlStatementBuilder::isValid() const
{
- return tableName.hasContent() && !columnDefinitions.isEmpty();
+ return m_tableName.hasContent() && !m_columns.empty();
}
void CreateTableSqlStatementBuilder::bindColumnDefinitions() const
{
- Utf8StringVector columnDefinitionStrings;
+ Utils::SmallStringVector columnDefinitionStrings;
- foreach (const ColumnDefinition &columnDefinition, columnDefinitions) {
- Utf8String columnDefinitionString = columnDefinition.name() + Utf8StringLiteral(" ") + columnDefinition.typeString();
+ for (const Column &columns : m_columns) {
+ Utils::SmallString columnDefinitionString = {columns.name(), " ", columns.typeString()};
- if (columnDefinition.isPrimaryKey())
- columnDefinitionString.append(Utf8StringLiteral(" PRIMARY KEY"));
+ switch (columns.constraint()) {
+ case Contraint::PrimaryKey: columnDefinitionString.append(" PRIMARY KEY"); break;
+ case Contraint::Unique: columnDefinitionString.append(" UNIQUE"); break;
+ case Contraint::NoConstraint: break;
+ }
- columnDefinitionStrings.append(columnDefinitionString);
+ columnDefinitionStrings.push_back(columnDefinitionString);
}
- sqlStatementBuilder.bind(Utf8StringLiteral("$columnDefinitions"), columnDefinitionStrings);
+ m_sqlStatementBuilder.bind("$columnDefinitions", columnDefinitionStrings);
}
void CreateTableSqlStatementBuilder::bindAll() const
{
- sqlStatementBuilder.bind(Utf8StringLiteral("$table"), tableName);
+ m_sqlStatementBuilder.bind("$table", m_tableName.clone());
+ bindTemporary();
+ bindIfNotExists();
bindColumnDefinitions();
+ bindWithoutRowId();
+}
- if (useWithoutRowId)
- sqlStatementBuilder.bind(Utf8StringLiteral("$withoutRowId"), Utf8StringLiteral(" WITHOUT ROWID"));
+void CreateTableSqlStatementBuilder::bindWithoutRowId() const
+{
+ if (m_useWithoutRowId)
+ m_sqlStatementBuilder.bind("$withoutRowId", " WITHOUT ROWID");
+ else
+ m_sqlStatementBuilder.bindEmptyText("$withoutRowId");
+}
+
+void CreateTableSqlStatementBuilder::bindIfNotExists() const
+{
+ if (m_useIfNotExits)
+ m_sqlStatementBuilder.bind("$ifNotExits", "IF NOT EXISTS ");
else
- sqlStatementBuilder.bindEmptyText(Utf8StringLiteral("$withoutRowId"));
+ m_sqlStatementBuilder.bindEmptyText("$ifNotExits");
}
+void CreateTableSqlStatementBuilder::bindTemporary() const
+{
+ if (m_useTemporaryTable)
+ m_sqlStatementBuilder.bind("$temporary", "TEMPORARY ");
+ else
+ m_sqlStatementBuilder.bindEmptyText("$temporary");
}
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.h b/src/libs/sqlite/createtablesqlstatementbuilder.h
index 3445d4946fa..00c9ebd45a1 100644
--- a/src/libs/sqlite/createtablesqlstatementbuilder.h
+++ b/src/libs/sqlite/createtablesqlstatementbuilder.h
@@ -25,39 +25,46 @@
#pragma once
-#include "columndefinition.h"
+#include "sqlitecolumn.h"
#include "sqlstatementbuilder.h"
-#include <QVector>
-
-namespace Internal {
+namespace Sqlite {
class SQLITE_EXPORT CreateTableSqlStatementBuilder
{
public:
CreateTableSqlStatementBuilder();
- void setTable(const Utf8String &tableName);
- void addColumnDefinition(const Utf8String &columnName, ColumnType columnType, bool isPrimaryKey = false);
- void setColumnDefinitions(const QVector<ColumnDefinition> & columnDefinitions);
+ void setTableName(Utils::SmallString &&tableName);
+ void addColumn(Utils::SmallString &&columnName,
+ ColumnType columnType,
+ Contraint constraint = Contraint::NoConstraint);
+ void setColumns(const SqliteColumns &columns);
void setUseWithoutRowId(bool useWithoutRowId);
+ void setUseIfNotExists(bool useIfNotExists);
+ void setUseTemporaryTable(bool useTemporaryTable);
void clear();
void clearColumns();
- Utf8String sqlStatement() const;
+ Utils::SmallStringView sqlStatement() const;
bool isValid() const;
protected:
void bindColumnDefinitions() const;
void bindAll() const;
+ void bindWithoutRowId() const;
+ void bindIfNotExists() const;
+ void bindTemporary() const;
private:
- mutable SqlStatementBuilder sqlStatementBuilder;
- Utf8String tableName;
- QVector<ColumnDefinition> columnDefinitions;
- bool useWithoutRowId;
+ mutable SqlStatementBuilder m_sqlStatementBuilder;
+ Utils::SmallString m_tableName;
+ SqliteColumns m_columns;
+ bool m_useWithoutRowId = false;
+ bool m_useIfNotExits = false;
+ bool m_useTemporaryTable = false;
};
-}
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlite-lib.pri b/src/libs/sqlite/sqlite-lib.pri
index 9160fba4cc6..67c8c6b9372 100644
--- a/src/libs/sqlite/sqlite-lib.pri
+++ b/src/libs/sqlite/sqlite-lib.pri
@@ -11,19 +11,14 @@ unix:!bsd: LIBS += -ldl
include(../3rdparty/sqlite/sqlite.pri)
SOURCES += \
- $$PWD/columndefinition.cpp \
- $$PWD/createtablecommand.cpp \
$$PWD/createtablesqlstatementbuilder.cpp \
$$PWD/sqlitedatabasebackend.cpp \
- $$PWD/sqlitedatabaseconnection.cpp \
- $$PWD/sqlitedatabaseconnectionproxy.cpp \
$$PWD/sqliteexception.cpp \
$$PWD/sqliteglobal.cpp \
$$PWD/sqlitereadstatement.cpp \
$$PWD/sqlitereadwritestatement.cpp \
$$PWD/sqlitestatement.cpp \
$$PWD/sqlitetransaction.cpp \
- $$PWD/sqliteworkerthread.cpp \
$$PWD/sqlitewritestatement.cpp \
$$PWD/sqlstatementbuilder.cpp \
$$PWD/sqlstatementbuilderexception.cpp \
@@ -31,22 +26,16 @@ SOURCES += \
$$PWD/utf8stringvector.cpp \
$$PWD/sqlitedatabase.cpp \
$$PWD/sqlitetable.cpp \
- $$PWD/sqlitecolumn.cpp \
- $$PWD/tablewriteworker.cpp \
- $$PWD/tablewriteworkerproxy.cpp
+ $$PWD/sqlitecolumn.cpp
HEADERS += \
- $$PWD/columndefinition.h \
$$PWD/createtablesqlstatementbuilder.h \
$$PWD/sqlitedatabasebackend.h \
- $$PWD/sqlitedatabaseconnection.h \
- $$PWD/sqlitedatabaseconnectionproxy.h \
$$PWD/sqliteexception.h \
$$PWD/sqliteglobal.h \
$$PWD/sqlitereadstatement.h \
$$PWD/sqlitereadwritestatement.h \
$$PWD/sqlitestatement.h \
$$PWD/sqlitetransaction.h \
- $$PWD/sqliteworkerthread.h \
$$PWD/sqlitewritestatement.h \
$$PWD/sqlstatementbuilder.h \
$$PWD/sqlstatementbuilderexception.h \
@@ -55,9 +44,7 @@ HEADERS += \
$$PWD/sqlitedatabase.h \
$$PWD/sqlitetable.h \
$$PWD/sqlitecolumn.h \
- $$PWD/tablewriteworker.h \
- $$PWD/tablewriteworkerproxy.h \
- $$PWD/createtablecommand.h
+ $$PWD/sqliteindex.h
DEFINES += SQLITE_THREADSAFE=2 SQLITE_ENABLE_FTS4 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_UNLOCK_NOTIFY SQLITE_ENABLE_COLUMN_METADATA
diff --git a/src/libs/sqlite/sqlitecolumn.cpp b/src/libs/sqlite/sqlitecolumn.cpp
index 6f7adfd679e..201f1fbcb9d 100644
--- a/src/libs/sqlite/sqlitecolumn.cpp
+++ b/src/libs/sqlite/sqlitecolumn.cpp
@@ -25,57 +25,7 @@
#include "sqlitecolumn.h"
-SqliteColumn::SqliteColumn()
- : type_(ColumnType::Numeric),
- isPrimaryKey_(false)
-{
+namespace Sqlite {
-}
-void SqliteColumn::clear()
-{
- name_.clear();
- type_ = ColumnType::Numeric;
- isPrimaryKey_ = false;
-}
-
-void SqliteColumn::setName(const Utf8String &newName)
-{
- name_ = newName;
-}
-
-const Utf8String &SqliteColumn::name() const
-{
- return name_;
-}
-
-void SqliteColumn::setType(ColumnType newType)
-{
- type_ = newType;
-}
-
-ColumnType SqliteColumn::type() const
-{
- return type_;
-}
-
-void SqliteColumn::setIsPrimaryKey(bool isPrimaryKey)
-{
- isPrimaryKey_ = isPrimaryKey;
-}
-
-bool SqliteColumn::isPrimaryKey() const
-{
- return isPrimaryKey_;
-}
-
-Internal::ColumnDefinition SqliteColumn::columnDefintion() const
-{
- Internal::ColumnDefinition columnDefinition;
-
- columnDefinition.setName(name_);
- columnDefinition.setType(type_);
- columnDefinition.setIsPrimaryKey(isPrimaryKey_);
-
- return columnDefinition;
-}
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitecolumn.h b/src/libs/sqlite/sqlitecolumn.h
index 136691e36dd..d6401d299b2 100644
--- a/src/libs/sqlite/sqlitecolumn.h
+++ b/src/libs/sqlite/sqlitecolumn.h
@@ -25,32 +25,92 @@
#pragma once
-#include "columndefinition.h"
-#include "utf8string.h"
+#include "sqliteglobal.h"
-#include <QObject>
+#include <utils/smallstring.h>
-class SQLITE_EXPORT SqliteColumn : public QObject
+#include <functional>
+
+namespace Sqlite {
+
+class Column
{
- Q_OBJECT
public:
- SqliteColumn();
+ Column() = default;
+
+ Column(Utils::SmallString &&name,
+ ColumnType type = ColumnType::Numeric,
+ Contraint constraint = Contraint::NoConstraint)
+ : m_name(std::move(name)),
+ m_type(type),
+ m_constraint(constraint)
+ {}
+
+ void clear()
+ {
+ m_name.clear();
+ m_type = ColumnType::Numeric;
+ m_constraint = Contraint::NoConstraint;
+ }
+
+ void setName(Utils::SmallString &&newName)
+ {
+ m_name = newName;
+ }
- void clear();
+ const Utils::SmallString &name() const
+ {
+ return m_name;
+ }
- void setName(const Utf8String &newName);
- const Utf8String &name() const;
+ void setType(ColumnType newType)
+ {
+ m_type = newType;
+ }
- void setType(ColumnType newType);
- ColumnType type() const;
+ ColumnType type() const
+ {
+ return m_type;
+ }
- void setIsPrimaryKey(bool isPrimaryKey);
- bool isPrimaryKey() const;
+ void setContraint(Contraint constraint)
+ {
+ m_constraint = constraint;
+ }
- Internal::ColumnDefinition columnDefintion() const;
+ Contraint constraint() const
+ {
+ return m_constraint;
+ }
+
+ Utils::SmallString typeString() const
+ {
+ switch (m_type) {
+ case ColumnType::None: return {};
+ case ColumnType::Numeric: return "NUMERIC";
+ case ColumnType::Integer: return "INTEGER";
+ case ColumnType::Real: return "REAL";
+ case ColumnType::Text: return "TEXT";
+ }
+
+ Q_UNREACHABLE();
+ }
+
+ friend bool operator==(const Column &first, const Column &second)
+ {
+ return first.m_name == second.m_name
+ && first.m_type == second.m_type
+ && first.m_constraint == second.m_constraint;
+ }
private:
- Utf8String name_;
- ColumnType type_;
- bool isPrimaryKey_;
+ Utils::SmallString m_name;
+ ColumnType m_type = ColumnType::Numeric;
+ Contraint m_constraint = Contraint::NoConstraint;
};
+
+using SqliteColumns = std::vector<Column>;
+using SqliteColumnConstReference = std::reference_wrapper<const Column>;
+using SqliteColumnConstReferences = std::vector<SqliteColumnConstReference>;
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitedatabase.cpp b/src/libs/sqlite/sqlitedatabase.cpp
index 7fe349eeaf7..aa265593c5a 100644
--- a/src/libs/sqlite/sqlitedatabase.cpp
+++ b/src/libs/sqlite/sqlitedatabase.cpp
@@ -26,116 +26,106 @@
#include "sqlitedatabase.h"
#include "sqlitetable.h"
+#include "sqlitetransaction.h"
-SqliteDatabase::SqliteDatabase()
- : readDatabaseConnection(QStringLiteral("ReadWorker")),
- writeDatabaseConnection(QStringLiteral("WriterWorker")),
- journalMode_(JournalMode::Wal)
-{
- connect(&readDatabaseConnection, &SqliteDatabaseConnectionProxy::connectionIsOpened, this, &SqliteDatabase::handleReadDatabaseConnectionIsOpened);
- connect(&writeDatabaseConnection, &SqliteDatabaseConnectionProxy::connectionIsOpened, this, &SqliteDatabase::handleWriteDatabaseConnectionIsOpened);
- connect(&readDatabaseConnection, &SqliteDatabaseConnectionProxy::connectionIsClosed, this, &SqliteDatabase::handleReadDatabaseConnectionIsClosed);
- connect(&writeDatabaseConnection, &SqliteDatabaseConnectionProxy::connectionIsClosed, this, &SqliteDatabase::handleWriteDatabaseConnectionIsClosed);
-}
+namespace Sqlite {
-SqliteDatabase::~SqliteDatabase()
+Database::Database()
+ : m_databaseBackend(*this)
{
- qDeleteAll(sqliteTables);
}
-void SqliteDatabase::open()
+Database::Database(Utils::PathString &&databaseFilePath)
+ : m_databaseBackend(*this)
{
- writeDatabaseConnection.setDatabaseFilePath(databaseFilePath());
- writeDatabaseConnection.setJournalMode(journalMode());
+ open(std::move(databaseFilePath));
}
-void SqliteDatabase::close()
+void Database::open()
{
- writeDatabaseConnection.close();
+ m_databaseBackend.open(m_databaseFilePath, m_openMode);
+ m_databaseBackend.setJournalMode(m_journalMode);
+ initializeTables();
+ m_isOpen = true;
}
-bool SqliteDatabase::isOpen() const
+void Database::open(Utils::PathString &&databaseFilePath)
{
- return readDatabaseConnection.isOpen() && writeDatabaseConnection.isOpen();
+ setDatabaseFilePath(std::move(databaseFilePath));
+ open();
}
-void SqliteDatabase::addTable(SqliteTable *newSqliteTable)
+void Database::close()
{
- newSqliteTable->setSqliteDatabase(this);
- sqliteTables.append(newSqliteTable);
+ m_isOpen = false;
+ m_databaseBackend.close();
}
-const QVector<SqliteTable *> &SqliteDatabase::tables() const
+bool Database::isOpen() const
{
- return sqliteTables;
+ return m_isOpen;
}
-void SqliteDatabase::setDatabaseFilePath(const QString &databaseFilePath)
+Table &Database::addTable()
{
- databaseFilePath_ = databaseFilePath;
-}
+ m_sqliteTables.emplace_back();
-const QString &SqliteDatabase::databaseFilePath() const
-{
- return databaseFilePath_;
+ return m_sqliteTables.back();
}
-void SqliteDatabase::setJournalMode(JournalMode journalMode)
+const std::vector<Table> &Database::tables() const
{
- journalMode_ = journalMode;
+ return m_sqliteTables;
}
-JournalMode SqliteDatabase::journalMode() const
+void Database::setDatabaseFilePath(Utils::PathString &&databaseFilePath)
{
- return journalMode_;
+ m_databaseFilePath = std::move(databaseFilePath);
}
-QThread *SqliteDatabase::writeWorkerThread() const
+const Utils::PathString &Database::databaseFilePath() const
{
- return writeDatabaseConnection.connectionThread();
+ return m_databaseFilePath;
}
-QThread *SqliteDatabase::readWorkerThread() const
+void Database::setJournalMode(JournalMode journalMode)
{
- return readDatabaseConnection.connectionThread();
+ m_journalMode = journalMode;
}
-void SqliteDatabase::handleReadDatabaseConnectionIsOpened()
+JournalMode Database::journalMode() const
{
- if (writeDatabaseConnection.isOpen() && readDatabaseConnection.isOpen()) {
- initializeTables();
- emit databaseIsOpened();
- }
+ return m_journalMode;
}
-void SqliteDatabase::handleWriteDatabaseConnectionIsOpened()
+void Database::setOpenMode(OpenMode openMode)
{
- readDatabaseConnection.setDatabaseFilePath(databaseFilePath());
+ m_openMode = openMode;
}
-void SqliteDatabase::handleReadDatabaseConnectionIsClosed()
+OpenMode Database::openMode() const
{
- if (!writeDatabaseConnection.isOpen() && !readDatabaseConnection.isOpen()) {
- shutdownTables();
- emit databaseIsClosed();
- }
+ return m_openMode;
}
-void SqliteDatabase::handleWriteDatabaseConnectionIsClosed()
+void Database::execute(Utils::SmallStringView sqlStatement)
{
- readDatabaseConnection.close();
+ m_databaseBackend.execute(sqlStatement);
}
-void SqliteDatabase::initializeTables()
+void Database::initializeTables()
{
- for (SqliteTable *table: tables())
- table->initialize();
+ ImmediateTransaction<Database> transaction(*this);
+
+ for (Table &table : m_sqliteTables)
+ table.initialize(*this);
+
+ transaction.commit();
}
-void SqliteDatabase::shutdownTables()
+DatabaseBackend &Database::backend()
{
- for (SqliteTable *table: tables())
- table->shutdown();
+ return m_databaseBackend;
}
-
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h
index 91454329ee8..125bccaf24a 100644
--- a/src/libs/sqlite/sqlitedatabase.h
+++ b/src/libs/sqlite/sqlitedatabase.h
@@ -25,55 +25,85 @@
#pragma once
-#include "sqlitedatabaseconnectionproxy.h"
+#include "sqlitedatabasebackend.h"
#include "sqliteglobal.h"
+#include "sqlitetable.h"
-#include <QString>
-#include <QVector>
+#include <utils/smallstring.h>
-class SqliteTable;
+#include <mutex>
+#include <vector>
-class SQLITE_EXPORT SqliteDatabase : public QObject
+namespace Sqlite {
+
+class SQLITE_EXPORT Database
{
- Q_OBJECT
+ template <typename Database>
+ friend class AbstractTransaction;
+ friend class Statement;
+ friend class Backend;
public:
- SqliteDatabase();
- ~SqliteDatabase();
+ using MutexType = std::mutex;
+
+ Database();
+ Database(Utils::PathString &&databaseFilePath);
+
+ Database(const Database &) = delete;
+ bool operator=(const Database &) = delete;
+
+ Database(Database &&) = delete;
+ bool operator=(Database &&) = delete;
void open();
+ void open(Utils::PathString &&databaseFilePath);
void close();
bool isOpen() const;
- void addTable(SqliteTable *newSqliteTable);
- const QVector<SqliteTable *> &tables() const;
+ Table &addTable();
+ const std::vector<Table> &tables() const;
- void setDatabaseFilePath(const QString &databaseFilePath);
- const QString &databaseFilePath() const;
+ void setDatabaseFilePath(Utils::PathString &&databaseFilePath);
+ const Utils::PathString &databaseFilePath() const;
void setJournalMode(JournalMode journalMode);
JournalMode journalMode() const;
- QThread *writeWorkerThread() const;
- QThread *readWorkerThread() const;
+ void setOpenMode(OpenMode openMode);
+ OpenMode openMode() const;
+
+ void execute(Utils::SmallStringView sqlStatement);
-signals:
- void databaseIsOpened();
- void databaseIsClosed();
+ DatabaseBackend &backend();
+
+ int64_t lastInsertedRowId() const
+ {
+ return m_databaseBackend.lastInsertedRowId();
+ }
+
+ int changesCount()
+ {
+ return m_databaseBackend.changesCount();
+ }
+
+ int totalChangesCount()
+ {
+ return m_databaseBackend.totalChangesCount();
+ }
private:
- void handleReadDatabaseConnectionIsOpened();
- void handleWriteDatabaseConnectionIsOpened();
- void handleReadDatabaseConnectionIsClosed();
- void handleWriteDatabaseConnectionIsClosed();
void initializeTables();
- void shutdownTables();
+ std::mutex &databaseMutex() { return m_databaseMutex; }
private:
- SqliteDatabaseConnectionProxy readDatabaseConnection;
- SqliteDatabaseConnectionProxy writeDatabaseConnection;
- QVector<SqliteTable*> sqliteTables;
- QString databaseFilePath_;
- JournalMode journalMode_;
+ Utils::PathString m_databaseFilePath;
+ DatabaseBackend m_databaseBackend;
+ std::vector<Table> m_sqliteTables;
+ std::mutex m_databaseMutex;
+ JournalMode m_journalMode = JournalMode::Wal;
+ OpenMode m_openMode = OpenMode::ReadWrite;
+ bool m_isOpen = false;
};
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitedatabasebackend.cpp b/src/libs/sqlite/sqlitedatabasebackend.cpp
index 31ea378d129..5c4fc95e732 100644
--- a/src/libs/sqlite/sqlitedatabasebackend.cpp
+++ b/src/libs/sqlite/sqlitedatabasebackend.cpp
@@ -31,6 +31,7 @@
#include "sqlitestatement.h"
#include "sqlitewritestatement.h"
+#include <QFileInfo>
#include <QThread>
#include <QDebug>
@@ -38,36 +39,27 @@
#include "sqlite3.h"
-#if defined(Q_OS_DARWIN) && defined(Q_CC_GNU)
-#define QTC_THREAD_LOCAL __thread
-#else
-#define QTC_THREAD_LOCAL thread_local
-#endif
-
-#define SIZE_OF_BYTEARRAY_ARRAY(array) sizeof(array)/sizeof(QByteArray)
-
-QTC_THREAD_LOCAL SqliteDatabaseBackend *sqliteDatabaseBackend = nullptr;
+namespace Sqlite {
-SqliteDatabaseBackend::SqliteDatabaseBackend()
- : databaseHandle(nullptr),
- cachedTextEncoding(Utf8)
+DatabaseBackend::DatabaseBackend(Database &database)
+ : m_database(database),
+ m_databaseHandle(nullptr),
+ m_cachedTextEncoding(Utf8)
{
- sqliteDatabaseBackend = this;
}
-SqliteDatabaseBackend::~SqliteDatabaseBackend()
+DatabaseBackend::~DatabaseBackend()
{
closeWithoutException();
- sqliteDatabaseBackend = nullptr;
}
-void SqliteDatabaseBackend::setMmapSize(qint64 defaultSize, qint64 maximumSize)
+void DatabaseBackend::setMmapSize(qint64 defaultSize, qint64 maximumSize)
{
int resultCode = sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, defaultSize, maximumSize);
checkMmapSizeIsSet(resultCode);
}
-void SqliteDatabaseBackend::activateMultiThreading()
+void DatabaseBackend::activateMultiThreading()
{
int resultCode = sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
checkIfMultithreadingIsActivated(resultCode);
@@ -78,39 +70,38 @@ static void sqliteLog(void*,int errorCode,const char *errorMessage)
qWarning() << sqlite3_errstr(errorCode) << errorMessage;
}
-void SqliteDatabaseBackend::activateLogging()
+void DatabaseBackend::activateLogging()
{
int resultCode = sqlite3_config(SQLITE_CONFIG_LOG, sqliteLog, nullptr);
checkIfLoogingIsActivated(resultCode);
}
-void SqliteDatabaseBackend::initializeSqliteLibrary()
+void DatabaseBackend::initializeSqliteLibrary()
{
int resultCode = sqlite3_initialize();
checkInitializeSqliteLibraryWasSuccesful(resultCode);
}
-void SqliteDatabaseBackend::shutdownSqliteLibrary()
+void DatabaseBackend::shutdownSqliteLibrary()
{
int resultCode = sqlite3_shutdown();
checkShutdownSqliteLibraryWasSuccesful(resultCode);
}
-void SqliteDatabaseBackend::checkpointFullWalLog()
+void DatabaseBackend::checkpointFullWalLog()
{
int resultCode = sqlite3_wal_checkpoint_v2(sqliteDatabaseHandle(), nullptr, SQLITE_CHECKPOINT_FULL, nullptr, nullptr);
checkIfLogCouldBeCheckpointed(resultCode);
}
-void SqliteDatabaseBackend::open(const QString &databaseFilePath)
+void DatabaseBackend::open(Utils::SmallStringView databaseFilePath, OpenMode mode)
{
checkCanOpenDatabase(databaseFilePath);
- QByteArray databaseUtf8Path = databaseFilePath.toUtf8();
- int resultCode = sqlite3_open_v2(databaseUtf8Path.data(),
- &databaseHandle,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
- NULL);
+ int resultCode = sqlite3_open_v2(databaseFilePath.data(),
+ &m_databaseHandle,
+ openMode(mode),
+ NULL);
checkDatabaseCouldBeOpened(resultCode);
@@ -119,110 +110,114 @@ void SqliteDatabaseBackend::open(const QString &databaseFilePath)
cacheTextEncoding();
}
-sqlite3 *SqliteDatabaseBackend::sqliteDatabaseHandle()
+sqlite3 *DatabaseBackend::sqliteDatabaseHandle() const
{
- checkDatabaseBackendIsNotNull();
checkDatabaseHandleIsNotNull();
- return threadLocalInstance()->databaseHandle;
+ return m_databaseHandle;
}
-void SqliteDatabaseBackend::setPragmaValue(const Utf8String &pragmaKey, const Utf8String &newPragmaValue)
+void DatabaseBackend::setPragmaValue(Utils::SmallStringView pragmaKey, Utils::SmallStringView newPragmaValue)
{
- SqliteReadWriteStatement::execute(Utf8StringLiteral("PRAGMA ") + pragmaKey + Utf8StringLiteral("='") + newPragmaValue + Utf8StringLiteral("'"));
- Utf8String pragmeValueInDatabase = SqliteReadWriteStatement::toValue<Utf8String>(Utf8StringLiteral("PRAGMA ") + pragmaKey);
+ execute(Utils::SmallString{"PRAGMA ", pragmaKey, "='", newPragmaValue, "'"});
+ Utils::SmallString pragmeValueInDatabase = toValue<Utils::SmallString>("PRAGMA " + pragmaKey);
checkPragmaValue(pragmeValueInDatabase, newPragmaValue);
}
-Utf8String SqliteDatabaseBackend::pragmaValue(const Utf8String &pragma) const
+Utils::SmallString DatabaseBackend::pragmaValue(Utils::SmallStringView pragma)
{
- return SqliteReadWriteStatement::toValue<Utf8String>(Utf8StringLiteral("PRAGMA ") + pragma);
+ return toValue<Utils::SmallString>("PRAGMA " + pragma);
}
-void SqliteDatabaseBackend::setJournalMode(JournalMode journalMode)
+void DatabaseBackend::setJournalMode(JournalMode journalMode)
{
- setPragmaValue(Utf8StringLiteral("journal_mode"), journalModeToPragma(journalMode));
+ setPragmaValue("journal_mode", journalModeToPragma(journalMode));
}
-JournalMode SqliteDatabaseBackend::journalMode() const
+JournalMode DatabaseBackend::journalMode()
{
- return pragmaToJournalMode(pragmaValue(Utf8StringLiteral("journal_mode")));
+ return pragmaToJournalMode(pragmaValue("journal_mode"));
}
-void SqliteDatabaseBackend::setTextEncoding(TextEncoding textEncoding)
+void DatabaseBackend::setTextEncoding(TextEncoding textEncoding)
{
- setPragmaValue(Utf8StringLiteral("encoding"), textEncodingToPragma(textEncoding));
+ setPragmaValue("encoding", textEncodingToPragma(textEncoding));
cacheTextEncoding();
}
-TextEncoding SqliteDatabaseBackend::textEncoding()
+TextEncoding DatabaseBackend::textEncoding()
{
- return cachedTextEncoding;
+ return m_cachedTextEncoding;
}
-Utf8StringVector SqliteDatabaseBackend::columnNames(const Utf8String &tableName)
+Utils::SmallStringVector DatabaseBackend::columnNames(Utils::SmallStringView tableName)
{
- SqliteReadStatement statement(Utf8StringLiteral("SELECT * FROM ") + tableName);
+ ReadWriteStatement statement("SELECT * FROM " + tableName, m_database);
return statement.columnNames();
}
-int SqliteDatabaseBackend::changesCount()
+int DatabaseBackend::changesCount() const
{
return sqlite3_changes(sqliteDatabaseHandle());
}
-int SqliteDatabaseBackend::totalChangesCount()
+int DatabaseBackend::totalChangesCount() const
{
return sqlite3_total_changes(sqliteDatabaseHandle());
}
-void SqliteDatabaseBackend::close()
+int64_t DatabaseBackend::lastInsertedRowId() const
+{
+ return sqlite3_last_insert_rowid(sqliteDatabaseHandle());
+}
+
+void DatabaseBackend::execute(Utils::SmallStringView sqlStatement)
+{
+ ReadWriteStatement statement(sqlStatement, m_database);
+ statement.step();
+}
+
+void DatabaseBackend::close()
{
checkForOpenDatabaseWhichCanBeClosed();
- int resultCode = sqlite3_close(databaseHandle);
+ int resultCode = sqlite3_close(m_databaseHandle);
checkDatabaseClosing(resultCode);
- databaseHandle = nullptr;
-
-}
+ m_databaseHandle = nullptr;
-SqliteDatabaseBackend *SqliteDatabaseBackend::threadLocalInstance()
-{
- checkDatabaseBackendIsNotNull();
- return sqliteDatabaseBackend;
}
-bool SqliteDatabaseBackend::databaseIsOpen() const
+bool DatabaseBackend::databaseIsOpen() const
{
- return databaseHandle != nullptr;
+ return m_databaseHandle != nullptr;
}
-void SqliteDatabaseBackend::closeWithoutException()
+void DatabaseBackend::closeWithoutException()
{
- if (databaseHandle) {
- int resultCode = sqlite3_close_v2(databaseHandle);
- databaseHandle = nullptr;
+ if (m_databaseHandle) {
+ int resultCode = sqlite3_close_v2(m_databaseHandle);
+ m_databaseHandle = nullptr;
if (resultCode != SQLITE_OK)
qWarning() << "SqliteDatabaseBackend::closeWithoutException: Unexpected error at closing the database!";
}
}
-void SqliteDatabaseBackend::registerBusyHandler()
+void DatabaseBackend::registerBusyHandler()
{
sqlite3_busy_handler(sqliteDatabaseHandle(), &busyHandlerCallback, nullptr);
}
-void SqliteDatabaseBackend::registerRankingFunction()
+void DatabaseBackend::registerRankingFunction()
{
sqlite3_create_function_v2(sqliteDatabaseHandle(), "okapi_bm25", -1, SQLITE_ANY, 0, okapi_bm25, 0, 0, 0);
sqlite3_create_function_v2(sqliteDatabaseHandle(), "okapi_bm25f", -1, SQLITE_UTF8, 0, okapi_bm25f, 0, 0, 0);
sqlite3_create_function_v2(sqliteDatabaseHandle(), "okapi_bm25f_kb", -1, SQLITE_UTF8, 0, okapi_bm25f_kb, 0, 0, 0);
}
-int SqliteDatabaseBackend::busyHandlerCallback(void *, int counter)
+int DatabaseBackend::busyHandlerCallback(void *, int counter)
{
Q_UNUSED(counter);
#ifdef QT_DEBUG
@@ -233,158 +228,199 @@ int SqliteDatabaseBackend::busyHandlerCallback(void *, int counter)
return true;
}
-void SqliteDatabaseBackend::cacheTextEncoding()
+void DatabaseBackend::cacheTextEncoding()
{
- cachedTextEncoding = pragmaToTextEncoding(pragmaValue(Utf8StringLiteral("encoding")));
+ m_cachedTextEncoding = pragmaToTextEncoding(pragmaValue("encoding"));
}
-void SqliteDatabaseBackend::checkForOpenDatabaseWhichCanBeClosed()
+void DatabaseBackend::checkForOpenDatabaseWhichCanBeClosed()
{
- if (databaseHandle == nullptr)
- throwException("SqliteDatabaseBackend::close: database is not open so it can not be closed.");
+ if (m_databaseHandle == nullptr)
+ throw DatabaseIsAlreadyClosed("SqliteDatabaseBackend::close: database is not open so it can not be closed.");
}
-void SqliteDatabaseBackend::checkDatabaseClosing(int resultCode)
+void DatabaseBackend::checkDatabaseClosing(int resultCode)
{
switch (resultCode) {
case SQLITE_OK: return;
- default: throwException("SqliteDatabaseBackend::close: unknown error happens at closing!");
+ case SQLITE_BUSY: throw DatabaseIsBusy("SqliteDatabaseBackend::close: database is busy because of e.g. unfinalized statements and will stay open!");
+ default: throwUnknowError("SqliteDatabaseBackend::close: unknown error happens at closing!");
}
}
-void SqliteDatabaseBackend::checkCanOpenDatabase(const QString &databaseFilePath)
+void DatabaseBackend::checkCanOpenDatabase(Utils::SmallStringView databaseFilePath)
{
if (databaseFilePath.isEmpty())
- throw SqliteException("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened:", "database file path is empty!");
+ throw DatabaseFilePathIsEmpty("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened because the file path is empty!");
+
+ if (!QFileInfo::exists(QFileInfo(QString(databaseFilePath)).path()))
+ throw WrongFilePath("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened because of wrong file path!",
+ Utils::SmallString(databaseFilePath));
if (databaseIsOpen())
- throw SqliteException("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened:", "database is already open!");
+ throw DatabaseIsAlreadyOpen("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened because it is already open!");
}
-void SqliteDatabaseBackend::checkDatabaseCouldBeOpened(int resultCode)
+void DatabaseBackend::checkDatabaseCouldBeOpened(int resultCode)
{
switch (resultCode) {
case SQLITE_OK:
return;
default:
closeWithoutException();
- throw SqliteException("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened:", sqlite3_errmsg(sqliteDatabaseHandle()));
+ throw Exception("SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened:", sqlite3_errmsg(sqliteDatabaseHandle()));
}
}
-void SqliteDatabaseBackend::checkPragmaValue(const Utf8String &databaseValue, const Utf8String &expectedValue)
+void DatabaseBackend::checkPragmaValue(Utils::SmallStringView databaseValue,
+ Utils::SmallStringView expectedValue)
{
if (databaseValue != expectedValue)
- throwException("SqliteDatabaseBackend::setPragmaValue: pragma value is not set!");
-}
-
-void SqliteDatabaseBackend::checkDatabaseHandleIsNotNull()
-{
- if (sqliteDatabaseBackend->databaseHandle == nullptr)
- throwException("SqliteDatabaseBackend: database is not open!");
+ throw PragmaValueNotSet("SqliteDatabaseBackend::setPragmaValue: pragma value is not set!");
}
-void SqliteDatabaseBackend::checkDatabaseBackendIsNotNull()
+void DatabaseBackend::checkDatabaseHandleIsNotNull() const
{
- if (sqliteDatabaseBackend == nullptr)
- throwException("SqliteDatabaseBackend: database backend is not initialized!");
+ if (m_databaseHandle == nullptr)
+ throwDatabaseIsNotOpen("SqliteDatabaseBackend: database is not open!");
}
-void SqliteDatabaseBackend::checkIfMultithreadingIsActivated(int resultCode)
+void DatabaseBackend::checkIfMultithreadingIsActivated(int resultCode)
{
if (resultCode != SQLITE_OK)
throwException("SqliteDatabaseBackend::activateMultiThreading: multithreading can't be activated!");
}
-void SqliteDatabaseBackend::checkIfLoogingIsActivated(int resultCode)
+void DatabaseBackend::checkIfLoogingIsActivated(int resultCode)
{
if (resultCode != SQLITE_OK)
throwException("SqliteDatabaseBackend::activateLogging: logging can't be activated!");
}
-void SqliteDatabaseBackend::checkMmapSizeIsSet(int resultCode)
+void DatabaseBackend::checkMmapSizeIsSet(int resultCode)
{
if (resultCode != SQLITE_OK)
throwException("SqliteDatabaseBackend::checkMmapSizeIsSet: mmap size can't be changed!");
}
-void SqliteDatabaseBackend::checkInitializeSqliteLibraryWasSuccesful(int resultCode)
+void DatabaseBackend::checkInitializeSqliteLibraryWasSuccesful(int resultCode)
{
if (resultCode != SQLITE_OK)
throwException("SqliteDatabaseBackend::initializeSqliteLibrary: SqliteLibrary cannot initialized!");
}
-void SqliteDatabaseBackend::checkShutdownSqliteLibraryWasSuccesful(int resultCode)
+void DatabaseBackend::checkShutdownSqliteLibraryWasSuccesful(int resultCode)
{
if (resultCode != SQLITE_OK)
throwException("SqliteDatabaseBackend::shutdownSqliteLibrary: SqliteLibrary cannot be shutdowned!");
}
-void SqliteDatabaseBackend::checkIfLogCouldBeCheckpointed(int resultCode)
+void DatabaseBackend::checkIfLogCouldBeCheckpointed(int resultCode)
{
if (resultCode != SQLITE_OK)
throwException("SqliteDatabaseBackend::checkpointFullWalLog: WAL log could not be checkpointed!");
}
-int SqliteDatabaseBackend::indexOfPragma(const Utf8String pragma, const Utf8String pragmas[], size_t pragmaCount)
+namespace {
+template<std::size_t Size>
+int indexOfPragma(Utils::SmallStringView pragma, const Utils::SmallStringView (&pragmas)[Size])
{
- for (unsigned int index = 0; index < pragmaCount; index++) {
+ for (unsigned int index = 0; index < Size; index++) {
if (pragma == pragmas[index])
return int(index);
}
return -1;
-
+}
}
-static const Utf8String journalModeStrings[] = {
- Utf8StringLiteral("delete"),
- Utf8StringLiteral("truncate"),
- Utf8StringLiteral("persist"),
- Utf8StringLiteral("memory"),
- Utf8StringLiteral("wal")
+constexpr const Utils::SmallStringView journalModeStrings[] = {
+ "delete",
+ "truncate",
+ "persist",
+ "memory",
+ "wal"
};
-const Utf8String &SqliteDatabaseBackend::journalModeToPragma(JournalMode journalMode)
+Utils::SmallStringView DatabaseBackend::journalModeToPragma(JournalMode journalMode)
{
return journalModeStrings[int(journalMode)];
}
-JournalMode SqliteDatabaseBackend::pragmaToJournalMode(const Utf8String &pragma)
+JournalMode DatabaseBackend::pragmaToJournalMode(Utils::SmallStringView pragma)
{
- int index = indexOfPragma(pragma, journalModeStrings, SIZE_OF_BYTEARRAY_ARRAY(journalModeStrings));
+ int index = indexOfPragma(pragma, journalModeStrings);
if (index < 0)
- throwException("SqliteDatabaseBackend::pragmaToJournalMode: pragma can't be transformed in a journal mode enumeration!");
+ throwExceptionStatic("SqliteDatabaseBackend::pragmaToJournalMode: pragma can't be transformed in a journal mode enumeration!");
return static_cast<JournalMode>(index);
}
-static const Utf8String textEncodingStrings[] = {
- Utf8StringLiteral("UTF-8"),
- Utf8StringLiteral("UTF-16le"),
- Utf8StringLiteral("UTF-16be")
+constexpr const Utils::SmallStringView textEncodingStrings[] = {
+ "UTF-8",
+ "UTF-16le",
+ "UTF-16be"
};
-const Utf8String &SqliteDatabaseBackend::textEncodingToPragma(TextEncoding textEncoding)
+Utils::SmallStringView DatabaseBackend::textEncodingToPragma(TextEncoding textEncoding)
{
return textEncodingStrings[textEncoding];
}
-TextEncoding SqliteDatabaseBackend::pragmaToTextEncoding(const Utf8String &pragma)
+TextEncoding DatabaseBackend::pragmaToTextEncoding(Utils::SmallStringView pragma)
{
- int index = indexOfPragma(pragma, textEncodingStrings, SIZE_OF_BYTEARRAY_ARRAY(textEncodingStrings));
+ int index = indexOfPragma(pragma, textEncodingStrings);
if (index < 0)
- throwException("SqliteDatabaseBackend::pragmaToTextEncoding: pragma can't be transformed in a text encoding enumeration!");
+ throwExceptionStatic("SqliteDatabaseBackend::pragmaToTextEncoding: pragma can't be transformed in a text encoding enumeration!");
return static_cast<TextEncoding>(index);
}
-void SqliteDatabaseBackend::throwException(const char *whatHasHappens)
+int DatabaseBackend::openMode(OpenMode mode)
{
- if (sqliteDatabaseBackend && sqliteDatabaseBackend->databaseHandle)
- throw SqliteException(whatHasHappens, sqlite3_errmsg(sqliteDatabaseBackend->databaseHandle));
+ int sqliteMode = SQLITE_OPEN_CREATE;
+
+ switch (mode) {
+ case OpenMode::ReadOnly: sqliteMode |= SQLITE_OPEN_READONLY; break;
+ case OpenMode::ReadWrite: sqliteMode |= SQLITE_OPEN_READWRITE; break;
+ }
+
+ return sqliteMode;
+}
+
+void DatabaseBackend::throwExceptionStatic(const char *whatHasHappens)
+{
+ throw Exception(whatHasHappens);
+}
+
+void DatabaseBackend::throwException(const char *whatHasHappens) const
+{
+ if (m_databaseHandle)
+ throw Exception(whatHasHappens, sqlite3_errmsg(m_databaseHandle));
else
- throw SqliteException(whatHasHappens);
+ throw Exception(whatHasHappens);
+}
+
+void DatabaseBackend::throwUnknowError(const char *whatHasHappens) const
+{
+ throw UnknowError(whatHasHappens);
}
+
+void DatabaseBackend::throwDatabaseIsNotOpen(const char *whatHasHappens) const
+{
+ throw DatabaseIsNotOpen(whatHasHappens);
+}
+
+template <typename Type>
+Type DatabaseBackend::toValue(Utils::SmallStringView sqlStatement)
+{
+ ReadWriteStatement statement(sqlStatement, m_database);
+
+ statement.next();
+
+ return statement.fetchValue<Type>(0);
+}
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitedatabasebackend.h b/src/libs/sqlite/sqlitedatabasebackend.h
index 7d86519922c..6ff56b11b22 100644
--- a/src/libs/sqlite/sqlitedatabasebackend.h
+++ b/src/libs/sqlite/sqlitedatabasebackend.h
@@ -27,51 +27,64 @@
#include "sqliteglobal.h"
-#include "utf8stringvector.h"
-
-#include <QStringList>
+#include <utils/smallstringvector.h>
struct sqlite3;
-class SQLITE_EXPORT SqliteDatabaseBackend
+namespace Sqlite {
+
+class Database;
+
+class SQLITE_EXPORT DatabaseBackend
{
public:
+ DatabaseBackend(Database &database);
+ ~DatabaseBackend();
+
+ DatabaseBackend(const Database &) = delete;
+ Database &operator=(const Database &) = delete;
- SqliteDatabaseBackend();
- ~SqliteDatabaseBackend();
+ DatabaseBackend(Database &&) = delete;
+ Database &operator=(Database &&) = delete;
- static void setMmapSize(qint64 defaultSize, qint64 maximumSize);
- static void activateMultiThreading();
- static void activateLogging();
- static void initializeSqliteLibrary();
- static void shutdownSqliteLibrary();
- static void checkpointFullWalLog();
+ void setMmapSize(qint64 defaultSize, qint64 maximumSize);
+ void activateMultiThreading();
+ void activateLogging();
+ void initializeSqliteLibrary();
+ void shutdownSqliteLibrary();
+ void checkpointFullWalLog();
- void open(const QString &databaseFilePath);
+ void open(Utils::SmallStringView databaseFilePath, OpenMode openMode);
void close();
void closeWithoutException();
- static SqliteDatabaseBackend *threadLocalInstance();
- static sqlite3* sqliteDatabaseHandle();
+ sqlite3* sqliteDatabaseHandle() const;
void setJournalMode(JournalMode journalMode);
- JournalMode journalMode() const;
+ JournalMode journalMode();
void setTextEncoding(TextEncoding textEncoding);
TextEncoding textEncoding();
+ Utils::SmallStringVector columnNames(Utils::SmallStringView tableName);
+ int changesCount() const;
+ int totalChangesCount() const;
- static Utf8StringVector columnNames(const Utf8String &tableName);
+ int64_t lastInsertedRowId() const;
- static int changesCount();
- static int totalChangesCount();
+ void execute(Utils::SmallStringView sqlStatement);
+
+ template <typename Type>
+ Type toValue(Utils::SmallStringView sqlStatement);
+
+ static int openMode(OpenMode);
protected:
bool databaseIsOpen() const;
- void setPragmaValue(const Utf8String &pragma, const Utf8String &value);
- Utf8String pragmaValue(const Utf8String &pragma) const;
+ void setPragmaValue(Utils::SmallStringView pragma, Utils::SmallStringView value);
+ Utils::SmallString pragmaValue(Utils::SmallStringView pragma);
void registerBusyHandler();
void registerRankingFunction();
@@ -81,28 +94,33 @@ protected:
void checkForOpenDatabaseWhichCanBeClosed();
void checkDatabaseClosing(int resultCode);
- void checkCanOpenDatabase(const QString &databaseFilePath);
+ void checkCanOpenDatabase(Utils::SmallStringView databaseFilePath);
void checkDatabaseCouldBeOpened(int resultCode);
- void checkPragmaValue(const Utf8String &databaseValue, const Utf8String &expectedValue);
- static void checkDatabaseHandleIsNotNull();
- static void checkDatabaseBackendIsNotNull();
- static void checkIfMultithreadingIsActivated(int resultCode);
- static void checkIfLoogingIsActivated(int resultCode);
- static void checkMmapSizeIsSet(int resultCode);
- static void checkInitializeSqliteLibraryWasSuccesful(int resultCode);
- static void checkShutdownSqliteLibraryWasSuccesful(int resultCode);
- static void checkIfLogCouldBeCheckpointed(int resultCode);
-
- static int indexOfPragma(const Utf8String pragma, const Utf8String pragmas[], size_t pragmaCount);
- static const Utf8String &journalModeToPragma(JournalMode journalMode);
- static JournalMode pragmaToJournalMode(const Utf8String &pragma);
- static const Utf8String &textEncodingToPragma(TextEncoding textEncoding);
- static TextEncoding pragmaToTextEncoding(const Utf8String &pragma);
-
- Q_NORETURN static void throwException(const char *whatHasHappens);
+ void checkPragmaValue(Utils::SmallStringView databaseValue, Utils::SmallStringView expectedValue);
+ void checkDatabaseHandleIsNotNull() const;
+ void checkIfMultithreadingIsActivated(int resultCode);
+ void checkIfLoogingIsActivated(int resultCode);
+ void checkMmapSizeIsSet(int resultCode);
+ void checkInitializeSqliteLibraryWasSuccesful(int resultCode);
+ void checkShutdownSqliteLibraryWasSuccesful(int resultCode);
+ void checkIfLogCouldBeCheckpointed(int resultCode);
+
+ static Utils::SmallStringView journalModeToPragma(JournalMode journalMode);
+ static JournalMode pragmaToJournalMode(Utils::SmallStringView pragma);
+ Utils::SmallStringView textEncodingToPragma(TextEncoding textEncoding);
+ static TextEncoding pragmaToTextEncoding(Utils::SmallStringView pragma);
+
+
+ Q_NORETURN static void throwExceptionStatic(const char *whatHasHappens);
+ [[noreturn]] void throwException(const char *whatHasHappens) const;
+ [[noreturn]] void throwUnknowError(const char *whatHasHappens) const;
+ [[noreturn]] void throwDatabaseIsNotOpen(const char *whatHasHappens) const;
private:
- sqlite3 *databaseHandle;
- TextEncoding cachedTextEncoding;
+ Database &m_database;
+ sqlite3 *m_databaseHandle;
+ TextEncoding m_cachedTextEncoding;
};
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitedatabaseconnection.cpp b/src/libs/sqlite/sqlitedatabaseconnection.cpp
deleted file mode 100644
index f4fe79b7d4b..00000000000
--- a/src/libs/sqlite/sqlitedatabaseconnection.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "sqlitedatabaseconnection.h"
-
-#include "sqliteexception.h"
-#include "sqliteglobal.h"
-
-#include <sqlite3.h>
-
-#include <QDebug>
-
-#ifdef Q_OS_LINUX
-#include <cerrno>
-#include <cstring>
-#include <sys/resource.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <unistd.h>
-#endif
-
-SqliteDatabaseConnection::SqliteDatabaseConnection(QObject *parent) :
- QObject(parent)
-{
-}
-
-SqliteDatabaseConnection::~SqliteDatabaseConnection()
-{
-
-}
-
-sqlite3 *SqliteDatabaseConnection::currentSqliteDatabase()
-{
- return SqliteDatabaseBackend::sqliteDatabaseHandle();
-}
-
-void SqliteDatabaseConnection::setDatabaseFilePath(const QString &databaseFilePath)
-{
-
- prioritizeThreadDown();
-
- try {
- databaseBackend.open(databaseFilePath);
-
- emit databaseConnectionIsOpened();
- } catch (SqliteException &exception) {
- exception.printWarning();
- }
-}
-
-void SqliteDatabaseConnection::setJournalMode(JournalMode journalMode)
-{
- try {
- databaseBackend.setJournalMode(journalMode);
- } catch (SqliteException &exception) {
- exception.printWarning();
- }
-}
-
-void SqliteDatabaseConnection::close()
-{
- databaseBackend.closeWithoutException();
-
- emit databaseConnectionIsClosed();
-}
-
-void SqliteDatabaseConnection::prioritizeThreadDown()
-{
-#ifdef Q_OS_LINUX
- pid_t processId = syscall(SYS_gettid);
- int returnCode = setpriority(PRIO_PROCESS, processId, 10);
- if (returnCode == -1)
- qWarning() << "cannot renice" << strerror(errno);
-#endif
-}
diff --git a/src/libs/sqlite/sqlitedatabaseconnectionproxy.cpp b/src/libs/sqlite/sqlitedatabaseconnectionproxy.cpp
deleted file mode 100644
index 70fef050987..00000000000
--- a/src/libs/sqlite/sqlitedatabaseconnectionproxy.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "sqlitedatabaseconnectionproxy.h"
-
-#include "sqlitedatabaseconnection.h"
-#include "sqliteworkerthread.h"
-
-#include <QCoreApplication>
-
-
-SqliteDatabaseConnectionProxy::SqliteDatabaseConnectionProxy(const QString &threadName) :
- QObject(),
- databaseConnectionIsOpen(false)
-{
-
- databaseConnectionThread = new SqliteWorkerThread;
- databaseConnectionThread->setObjectName(threadName);
-
- databaseConnectionThread->start(QThread::LowPriority);
-
- SqliteDatabaseConnection *connection = databaseConnectionThread->databaseConnection();
-
-
- connect(this, &SqliteDatabaseConnectionProxy::setDatabaseFilePath, connection, &SqliteDatabaseConnection::setDatabaseFilePath);
- connect(this, &SqliteDatabaseConnectionProxy::setJournalMode, connection, &SqliteDatabaseConnection::setJournalMode);
- connect(this, &SqliteDatabaseConnectionProxy::close, connection, &SqliteDatabaseConnection::close);
-
- connect(connection, &SqliteDatabaseConnection::databaseConnectionIsOpened, this, &SqliteDatabaseConnectionProxy::handleDatabaseConnectionIsOpened);
- connect(connection, &SqliteDatabaseConnection::databaseConnectionIsClosed, this, &SqliteDatabaseConnectionProxy::handleDatabaseConnectionIsClosed);
-
-}
-
-SqliteDatabaseConnectionProxy::~SqliteDatabaseConnectionProxy()
-{
- if (databaseConnectionThread) {
- databaseConnectionThread->quit();
- databaseConnectionThread->wait();
- databaseConnectionThread->deleteLater();
- }
-}
-
-QThread *SqliteDatabaseConnectionProxy::connectionThread() const
-{
- return databaseConnectionThread;
-}
-
-bool SqliteDatabaseConnectionProxy::isOpen() const
-{
- return databaseConnectionIsOpen;
-}
-
-void SqliteDatabaseConnectionProxy::registerTypes()
-{
- qRegisterMetaType<JournalMode>("JournalMode");
-}
-
-void SqliteDatabaseConnectionProxy::handleDatabaseConnectionIsOpened()
-{
- databaseConnectionIsOpen = true;
-
- emit connectionIsOpened();
-}
-
-void SqliteDatabaseConnectionProxy::handleDatabaseConnectionIsClosed()
-{
- databaseConnectionIsOpen = false;
-
- emit connectionIsClosed();
-}
diff --git a/src/libs/sqlite/sqliteexception.cpp b/src/libs/sqlite/sqliteexception.cpp
index f4c8e0c976f..d760ff2b7f9 100644
--- a/src/libs/sqlite/sqliteexception.cpp
+++ b/src/libs/sqlite/sqliteexception.cpp
@@ -25,19 +25,18 @@
#include "sqliteexception.h"
+#include <utils/smallstringio.h>
+
#include <QDebug>
-SqliteException::SqliteException(const char *whatErrorHasHappen, const char *sqliteErrorMessage)
- : whatErrorHasHappen(whatErrorHasHappen),
- sqliteErrorMessage_(sqliteErrorMessage)
-{
-}
+namespace Sqlite {
-void SqliteException::printWarning() const
+void Exception::printWarning() const
{
- if (!sqliteErrorMessage_.isEmpty())
- qWarning() << whatErrorHasHappen << sqliteErrorMessage_;
+ if (!m_sqliteErrorMessage.isEmpty())
+ qWarning() << m_whatErrorHasHappen << m_sqliteErrorMessage;
else
- qWarning() << whatErrorHasHappen;
+ qWarning() << m_whatErrorHasHappen;
}
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqliteexception.h b/src/libs/sqlite/sqliteexception.h
index b778d39b58e..319141d2573 100644
--- a/src/libs/sqlite/sqliteexception.h
+++ b/src/libs/sqlite/sqliteexception.h
@@ -27,16 +27,232 @@
#include "sqliteglobal.h"
-#include <QByteArray>
+#include <utils/smallstring.h>
-class SQLITE_EXPORT SqliteException
+namespace Sqlite {
+
+class SQLITE_EXPORT Exception
{
public:
- SqliteException(const char *whatErrorHasHappen, const char *sqliteErrorMessage = 0);
+ Exception(const char *whatErrorHasHappen,
+ Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
+ : m_whatErrorHasHappen(whatErrorHasHappen),
+ m_sqliteErrorMessage(std::move(sqliteErrorMessage))
+ {
+ }
void printWarning() const;
private:
- const char *whatErrorHasHappen;
- QByteArray sqliteErrorMessage_;
+ const char *m_whatErrorHasHappen;
+ Utils::SmallString m_sqliteErrorMessage;
+};
+
+class StatementIsBusy : public Exception
+{
+public:
+ StatementIsBusy(const char *whatErrorHasHappen,
+ Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
+ : Exception(whatErrorHasHappen, std::move(sqliteErrorMessage))
+ {
+ }
+};
+
+class DatabaseIsBusy : public Exception
+{
+public:
+ DatabaseIsBusy(const char *whatErrorHasHappen)
+ : Exception(whatErrorHasHappen)
+ {
+ }
+};
+
+class StatementHasError : public Exception
+{
+public:
+ StatementHasError(const char *whatErrorHasHappen,
+ Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
+ : Exception(whatErrorHasHappen, std::move(sqliteErrorMessage))
+ {
+ }
+};
+
+class StatementIsMisused : public Exception
+{
+public:
+ StatementIsMisused(const char *whatErrorHasHappen,
+ Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
+ : Exception(whatErrorHasHappen, std::move(sqliteErrorMessage))
+ {
+ }
+};
+
+class ContraintPreventsModification : public Exception
+{
+public:
+ ContraintPreventsModification(const char *whatErrorHasHappen,
+ Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
+ : Exception(whatErrorHasHappen, std::move(sqliteErrorMessage))
+ {
+ }
+};
+
+class NoValuesToFetch : public Exception
+{
+public:
+ NoValuesToFetch(const char *whatErrorHasHappen)
+ : Exception(whatErrorHasHappen)
+ {
+ }
+};
+
+class InvalidColumnFetched : public Exception
+{
+public:
+ InvalidColumnFetched(const char *whatErrorHasHappen)
+ : Exception(whatErrorHasHappen)
+ {
+ }
+};
+
+class BindingIndexIsOutOfRange : public Exception
+{
+public:
+ BindingIndexIsOutOfRange(const char *whatErrorHasHappen,
+ Utils::SmallString &&sqliteErrorMessage = Utils::SmallString())
+ : Exception(whatErrorHasHappen, std::move(sqliteErrorMessage))
+ {
+ }
+};
+
+class WrongBingingName : public Exception
+{
+public:
+ WrongBingingName(const char *whatErrorHasHappen)
+ : Exception(whatErrorHasHappen)
+ {
+ }
+};
+
+class DatabaseIsNotOpen : public Exception
+{
+public:
+ DatabaseIsNotOpen(const char *whatErrorHasHappen)
+ : Exception(whatErrorHasHappen)
+ {
+ }
+};
+
+class DatabaseCannotBeOpened : public Exception
+{
+public:
+ DatabaseCannotBeOpened(const char *whatErrorHasHappen,
+ Utils::SmallString &&errorMessage = Utils::SmallString())
+ : Exception(whatErrorHasHappen, std::move(errorMessage))
+ {
+ }
};
+
+class DatabaseFilePathIsEmpty : public DatabaseCannotBeOpened
+{
+public:
+ DatabaseFilePathIsEmpty(const char *whatErrorHasHappen)
+ : DatabaseCannotBeOpened(whatErrorHasHappen)
+ {
+ }
+};
+
+class DatabaseIsAlreadyOpen : public DatabaseCannotBeOpened
+{
+public:
+ DatabaseIsAlreadyOpen(const char *whatErrorHasHappen)
+ : DatabaseCannotBeOpened(whatErrorHasHappen)
+ {
+ }
+};
+
+class DatabaseCannotBeClosed : public Exception
+{
+public:
+ DatabaseCannotBeClosed(const char *whatErrorHasHappen)
+ : Exception(whatErrorHasHappen)
+ {
+ }
+};
+
+class DatabaseIsAlreadyClosed : public DatabaseCannotBeClosed
+{
+public:
+ DatabaseIsAlreadyClosed(const char *whatErrorHasHappen)
+ : DatabaseCannotBeClosed(whatErrorHasHappen)
+ {
+ }
+};
+
+class WrongFilePath : public DatabaseCannotBeOpened
+{
+public:
+ WrongFilePath(const char *whatErrorHasHappen,
+ Utils::SmallString &&errorMessage = Utils::SmallString())
+ : DatabaseCannotBeOpened(whatErrorHasHappen, std::move(errorMessage))
+ {
+ }
+};
+
+class PragmaValueNotSet : public Exception
+{
+public:
+ PragmaValueNotSet(const char *whatErrorHasHappen)
+ : Exception(whatErrorHasHappen)
+ {
+ }
+};
+
+class NotReadOnlySqlStatement : public Exception
+{
+public:
+ NotReadOnlySqlStatement(const char *whatErrorHasHappen)
+ : Exception(whatErrorHasHappen)
+ {
+ }
+};
+
+class NotWriteSqlStatement : public Exception
+{
+public:
+ NotWriteSqlStatement(const char *whatErrorHasHappen)
+ : Exception(whatErrorHasHappen)
+ {
+ }
+};
+
+class DeadLock : public Exception
+{
+public:
+ DeadLock(const char *whatErrorHasHappen)
+ : Exception(whatErrorHasHappen)
+ {
+ }
+};
+
+class UnknowError : public Exception
+{
+public:
+ UnknowError(const char *whatErrorHasHappen,
+ Utils::SmallString &&errorMessage = Utils::SmallString())
+ : Exception(whatErrorHasHappen, std::move(errorMessage))
+ {
+ }
+};
+
+class BindingTooBig : public Exception
+{
+public:
+ BindingTooBig(const char *whatErrorHasHappen,
+ Utils::SmallString &&errorMessage = Utils::SmallString())
+ : Exception(whatErrorHasHappen, std::move(errorMessage))
+ {
+ }
+};
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqliteglobal.cpp b/src/libs/sqlite/sqliteglobal.cpp
index 90f2719b3b7..3f9b05ce1c4 100644
--- a/src/libs/sqlite/sqliteglobal.cpp
+++ b/src/libs/sqlite/sqliteglobal.cpp
@@ -25,15 +25,7 @@
#include "sqliteglobal.h"
-#include "createtablecommand.h"
namespace Sqlite {
-void registerTypes()
-{
- Internal::CreateTableCommand::registerType();
-
- qRegisterMetaType<JournalMode>("JournalMode");
-}
-
}
diff --git a/src/libs/sqlite/sqliteglobal.h b/src/libs/sqlite/sqliteglobal.h
index 9349230faba..af9d9ac36c0 100644
--- a/src/libs/sqlite/sqliteglobal.h
+++ b/src/libs/sqlite/sqliteglobal.h
@@ -25,6 +25,8 @@
#pragma once
+#include <utils/smallstringfwd.h>
+
#include <QtGlobal>
#if defined(BUILD_SQLITE_LIBRARY)
@@ -35,12 +37,10 @@
# define SQLITE_EXPORT Q_DECL_IMPORT
#endif
-
namespace Sqlite {
-SQLITE_EXPORT void registerTypes();
-}
-enum class ColumnType {
+enum class ColumnType : char
+{
Numeric,
Integer,
Real,
@@ -48,11 +48,20 @@ enum class ColumnType {
None
};
-enum class ColumnConstraint {
+enum class Contraint : char
+{
+ NoConstraint,
+ PrimaryKey,
+ Unique
+};
+
+enum class ColumnConstraint : char
+{
PrimaryKey
};
-enum class JournalMode {
+enum class JournalMode : char
+{
Delete,
Truncate,
Persist,
@@ -60,7 +69,14 @@ enum class JournalMode {
Wal
};
-enum TextEncoding {
+enum class OpenMode : char
+{
+ ReadOnly,
+ ReadWrite
+};
+
+enum TextEncoding : char
+{
Utf8,
Utf16le,
Utf16be,
@@ -72,16 +88,4 @@ enum TextEncoding {
};
-QT_BEGIN_NAMESPACE
-template <typename T> class QVector;
-template <typename T> class QSet;
-template <class Key, class T> class QHash;
-template <class Key, class T> class QMap;
-class QVariant;
-QT_END_NAMESPACE
-
-class Utf8String;
-class Utf8StringVector;
-
-typedef QMap<Utf8String, QVariant> RowDictionary;
-typedef QVector<RowDictionary> RowDictionaries;
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqliteindex.h b/src/libs/sqlite/sqliteindex.h
new file mode 100644
index 00000000000..503a6cc341c
--- /dev/null
+++ b/src/libs/sqlite/sqliteindex.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+
+#include "sqliteglobal.h"
+
+#include "sqliteexception.h"
+
+#include <utils/smallstringvector.h>
+
+namespace Sqlite {
+
+class Index
+{
+public:
+ Index(Utils::SmallString &&tableName, Utils::SmallStringVector &&columnNames)
+ : m_tableName(std::move(tableName)),
+ m_columnNames(std::move(columnNames))
+ {
+ }
+
+ Utils::SmallString sqlStatement() const
+ {
+ checkTableName();
+ checkColumns();
+
+ return {"CREATE INDEX IF NOT EXISTS index_",
+ m_tableName,
+ "_",
+ m_columnNames.join("_"),
+ " ON ",
+ m_tableName,
+ "(",
+ m_columnNames.join(", "),
+ ")"
+ };
+ }
+
+ void checkTableName() const
+ {
+ if (m_tableName.isEmpty())
+ throw Exception("SqliteIndex has not table name!");
+ }
+
+ void checkColumns() const
+ {
+ if (m_columnNames.empty())
+ throw Exception("SqliteIndex has no columns!");
+ }
+
+private:
+ Utils::SmallString m_tableName;
+ Utils::SmallStringVector m_columnNames;
+};
+
+using SqliteIndices = std::vector<Index>;
+
+} //
diff --git a/src/libs/sqlite/sqlitereadstatement.cpp b/src/libs/sqlite/sqlitereadstatement.cpp
index cc348768b0a..9af95f1cffa 100644
--- a/src/libs/sqlite/sqlitereadstatement.cpp
+++ b/src/libs/sqlite/sqlitereadstatement.cpp
@@ -27,14 +27,19 @@
#include "sqlite3.h"
-SqliteReadStatement::SqliteReadStatement(const Utf8String &sqlStatementUtf8)
- : SqliteStatement(sqlStatementUtf8)
+namespace Sqlite {
+
+ReadStatement::ReadStatement(Utils::SmallStringView sqlStatement,
+ Database &database)
+ : Statement(sqlStatement, database)
{
checkIsReadOnlyStatement();
}
-void SqliteReadStatement::checkIsReadOnlyStatement()
+void ReadStatement::checkIsReadOnlyStatement()
{
if (!isReadOnlyStatement())
- throwException("SqliteStatement::SqliteReadStatement: is not read only statement!");
+ throw NotReadOnlySqlStatement("SqliteStatement::SqliteReadStatement: is not read only statement!");
}
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitereadstatement.h b/src/libs/sqlite/sqlitereadstatement.h
index 4f27c8657bd..828d1f7c377 100644
--- a/src/libs/sqlite/sqlitereadstatement.h
+++ b/src/libs/sqlite/sqlitereadstatement.h
@@ -27,25 +27,20 @@
#include "sqlitestatement.h"
-class SQLITE_EXPORT SqliteReadStatement final : private SqliteStatement
+namespace Sqlite {
+
+class SQLITE_EXPORT ReadStatement final : private Statement
{
public:
- explicit SqliteReadStatement(const Utf8String &sqlStatementUtf8);
+ explicit ReadStatement(Utils::SmallStringView sqlStatement, Database &database);
- using SqliteStatement::next;
- using SqliteStatement::reset;
- using SqliteStatement::value;
- using SqliteStatement::values;
- using SqliteStatement::rowColumnValueMap;
- using SqliteStatement::twoColumnValueMap;
- using SqliteStatement::columnCount;
- using SqliteStatement::columnNames;
- using SqliteStatement::bind;
- using SqliteStatement::bindingIndexForName;
- using SqliteStatement::setBindingColumnNames;
- using SqliteStatement::bindingColumnNames;
- using SqliteStatement::toValue;
+ using Statement::value;
+ using Statement::values;
+ using Statement::toValue;
+ using Statement::database;
protected:
void checkIsReadOnlyStatement();
};
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitereadwritestatement.cpp b/src/libs/sqlite/sqlitereadwritestatement.cpp
index 3d6be2e61c5..74190deae1b 100644
--- a/src/libs/sqlite/sqlitereadwritestatement.cpp
+++ b/src/libs/sqlite/sqlitereadwritestatement.cpp
@@ -25,8 +25,12 @@
#include "sqlitereadwritestatement.h"
-SqliteReadWriteStatement::SqliteReadWriteStatement(const Utf8String &sqlStatementUft8)
- : SqliteStatement(sqlStatementUft8)
+namespace Sqlite {
+
+ReadWriteStatement::ReadWriteStatement(Utils::SmallStringView sqlStatement,
+ Database &database)
+ : Statement(sqlStatement, database)
{
}
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitereadwritestatement.h b/src/libs/sqlite/sqlitereadwritestatement.h
index cb3c0707d46..8645a6eae8a 100644
--- a/src/libs/sqlite/sqlitereadwritestatement.h
+++ b/src/libs/sqlite/sqlitereadwritestatement.h
@@ -27,24 +27,22 @@
#include "sqlitestatement.h"
-class SQLITE_EXPORT SqliteReadWriteStatement final : private SqliteStatement
+namespace Sqlite {
+
+class SQLITE_EXPORT ReadWriteStatement final : private Statement
{
+ friend class DatabaseBackend;
+
public:
- explicit SqliteReadWriteStatement(const Utf8String &sqlStatementUft8);
+ ReadWriteStatement(Utils::SmallStringView sqlStatement, Database &database);
- using SqliteStatement::next;
- using SqliteStatement::step;
- using SqliteStatement::reset;
- using SqliteStatement::bind;
- using SqliteStatement::bindingIndexForName;
- using SqliteStatement::setBindingColumnNames;
- using SqliteStatement::bindingColumnNames;
- using SqliteStatement::write;
- using SqliteStatement::value;
- using SqliteStatement::values;
- using SqliteStatement::rowColumnValueMap;
- using SqliteStatement::columnCount;
- using SqliteStatement::columnNames;
- using SqliteStatement::toValue;
- using SqliteStatement::execute;
+ using Statement::execute;
+ using Statement::value;
+ using Statement::values;
+ using Statement::toValue;
+ using Statement::database;
+ using Statement::write;
+ using Statement::writeNamed;
};
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitestatement.cpp b/src/libs/sqlite/sqlitestatement.cpp
index cf0fa904185..0e70b5aaca6 100644
--- a/src/libs/sqlite/sqlitestatement.cpp
+++ b/src/libs/sqlite/sqlitestatement.cpp
@@ -25,43 +25,43 @@
#include "sqlitestatement.h"
+#include "sqlitedatabase.h"
#include "sqlitedatabasebackend.h"
#include "sqliteexception.h"
-#include <QMutex>
-#include <QtGlobal>
-#include <QVariant>
-#include <QWaitCondition>
-
#include "sqlite3.h"
+#include <condition_variable>
+#include <mutex>
+
#if defined(__GNUC__)
# pragma GCC diagnostic ignored "-Wignored-qualifiers"
#endif
-SqliteStatement::SqliteStatement(const Utf8String &sqlStatementUtf8)
- : compiledStatement(nullptr, deleteCompiledStatement),
- bindingParameterCount(0),
- columnCount_(0),
- isReadyToFetchValues(false)
+namespace Sqlite {
+
+Statement::Statement(Utils::SmallStringView sqlStatement, Database &database)
+ : m_compiledStatement(nullptr, deleteCompiledStatement),
+ m_database(database),
+ m_bindingParameterCount(0),
+ m_columnCount(0),
+ m_isReadyToFetchValues(false)
{
- prepare(sqlStatementUtf8);
+ prepare(sqlStatement);
setBindingParameterCount();
setBindingColumnNamesFromStatement();
setColumnCount();
}
-void SqliteStatement::deleteCompiledStatement(sqlite3_stmt *compiledStatement)
+void Statement::deleteCompiledStatement(sqlite3_stmt *compiledStatement)
{
if (compiledStatement)
sqlite3_finalize(compiledStatement);
}
-class UnlockNotification {
-
+class UnlockNotification
+{
public:
- UnlockNotification() : fired(false) {};
-
static void unlockNotifyCallBack(void **arguments, int argumentCount)
{
for (int index = 0; index < argumentCount; index++) {
@@ -72,58 +72,62 @@ public:
void wakeupWaitCondition()
{
- mutex.lock();
- fired = 1;
- waitCondition.wakeAll();
- mutex.unlock();
+ {
+ std::lock_guard<std::mutex> lock(m_mutex);
+ m_fired = 1;
+ }
+ m_waitCondition.notify_all();
}
void wait()
{
- mutex.lock();
+ std::unique_lock<std::mutex> lock(m_mutex);
- if (!fired) {
- waitCondition.wait(&mutex);
- }
-
- mutex.unlock();
+ m_waitCondition.wait(lock, [&] () { return m_fired; });
}
private:
- bool fired;
- QWaitCondition waitCondition;
- QMutex mutex;
+ bool m_fired = false;
+ std::condition_variable m_waitCondition;
+ std::mutex m_mutex;
};
-void SqliteStatement::waitForUnlockNotify() const
+void Statement::waitForUnlockNotify() const
{
UnlockNotification unlockNotification;
- int resultCode = sqlite3_unlock_notify(sqliteDatabaseHandle(), UnlockNotification::unlockNotifyCallBack, &unlockNotification);
+ int resultCode = sqlite3_unlock_notify(sqliteDatabaseHandle(),
+ UnlockNotification::unlockNotifyCallBack,
+ &unlockNotification);
- if (resultCode == SQLITE_OK)
- unlockNotification.wait();
- else
- throwException("SqliteStatement::waitForUnlockNotify: database is in a dead lock!");
+ if (resultCode == SQLITE_LOCKED)
+ throw DeadLock("SqliteStatement::waitForUnlockNotify: database is in a dead lock!");
+
+ unlockNotification.wait();
}
-void SqliteStatement::reset() const
+void Statement::reset() const
{
- int resultCode = sqlite3_reset(compiledStatement.get());
- if (resultCode != SQLITE_OK)
- throwException("SqliteStatement::reset: can't reset statement!");
+ int resultCode = sqlite3_reset(m_compiledStatement.get());
+ switch (resultCode) {
+ case SQLITE_OK: return;
+ case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::stepStatement: database engine was unable to acquire the database locks!");
+ case SQLITE_ERROR : throwStatementHasError("SqliteStatement::stepStatement: run-time error (such as a constraint violation) has occurred!");
+ case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::stepStatement: was called inappropriately!");
+ case SQLITE_CONSTRAINT: throwConstraintPreventsModification("SqliteStatement::stepStatement: contraint prevent insert or update!");
+ }
- isReadyToFetchValues = false;
+ m_isReadyToFetchValues = false;
}
-bool SqliteStatement::next() const
+bool Statement::next() const
{
int resultCode;
do {
- resultCode = sqlite3_step(compiledStatement.get());
+ resultCode = sqlite3_step(m_compiledStatement.get());
if (resultCode == SQLITE_LOCKED) {
waitForUnlockNotify();
- sqlite3_reset(compiledStatement.get());
+ sqlite3_reset(m_compiledStatement.get());
}
} while (resultCode == SQLITE_LOCKED);
@@ -133,180 +137,102 @@ bool SqliteStatement::next() const
return checkForStepError(resultCode);
}
-void SqliteStatement::step() const
+void Statement::step() const
{
next();
}
-void SqliteStatement::write(const RowDictionary &rowDictionary)
-{
- bind(rowDictionary);
- step();
- reset();
-}
-
-void SqliteStatement::writeUnchecked(const RowDictionary &rowDictionary)
+void Statement::execute() const
{
- bindUnchecked(rowDictionary);
- step();
+ next();
reset();
}
-int SqliteStatement::columnCount() const
+int Statement::columnCount() const
{
- return columnCount_;
+ return m_columnCount;
}
-Utf8StringVector SqliteStatement::columnNames() const
+Utils::SmallStringVector Statement::columnNames() const
{
- Utf8StringVector columnNames;
- int columnCount = SqliteStatement::columnCount();
- columnNames.reserve(columnCount);
+ Utils::SmallStringVector columnNames;
+ int columnCount = Statement::columnCount();
+ columnNames.reserve(std::size_t(columnCount));
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++)
- columnNames.append(Utf8String(sqlite3_column_origin_name(compiledStatement.get(), columnIndex), -1));
+ columnNames.emplace_back(sqlite3_column_origin_name(m_compiledStatement.get(), columnIndex));
return columnNames;
}
-void SqliteStatement::bind(int index, int value)
+void Statement::bind(int index, int value)
{
- int resultCode = sqlite3_bind_int(compiledStatement.get(), index, value);
- if (resultCode != SQLITE_OK)
- throwException("SqliteStatement::bind: cant' bind 32 bit integer!");
+ int resultCode = sqlite3_bind_int(m_compiledStatement.get(), index, value);
+ checkForBindingError(resultCode);
}
-void SqliteStatement::bind(int index, qint64 value)
+void Statement::bind(int index, long long value)
{
- int resultCode = sqlite3_bind_int64(compiledStatement.get(), index, value);
- if (resultCode != SQLITE_OK)
- throwException("SqliteStatement::bind: cant' bind 64 bit integer!");
+ int resultCode = sqlite3_bind_int64(m_compiledStatement.get(), index, value);
+ checkForBindingError(resultCode);
}
-void SqliteStatement::bind(int index, double value)
+void Statement::bind(int index, double value)
{
- int resultCode = sqlite3_bind_double(compiledStatement.get(), index, value);
- if (resultCode != SQLITE_OK)
- throwException("SqliteStatement::bind: cant' bind double!");
+ int resultCode = sqlite3_bind_double(m_compiledStatement.get(), index, value);
+ checkForBindingError(resultCode);
}
-void SqliteStatement::bind(int index, const QString &text)
+void Statement::bind(int index, Utils::SmallStringView text)
{
- int resultCode;
- if (databaseTextEncoding() == Utf8) {
- QByteArray textUtf8 = text.toUtf8();
- resultCode = sqlite3_bind_text(compiledStatement.get(), index, textUtf8.constData(), textUtf8.size(), SQLITE_TRANSIENT);
- } else {
- resultCode = sqlite3_bind_text16(compiledStatement.get(), index, text.constData(), text.size() * 2, SQLITE_TRANSIENT);
- }
-
- if (resultCode != SQLITE_OK)
- throwException("SqliteStatement::bind: cant' not bind text!");
-}
-
-void SqliteStatement::bind(int index, const QByteArray &blob)
-{
- sqlite3_bind_blob(compiledStatement.get(), index, blob.constData(), blob.size(), SQLITE_TRANSIENT);
-}
-
-void SqliteStatement::bind(int index, const QVariant &value)
-{
- checkBindingIndex(index);
-
- switch (value.type()) {
- case QVariant::Bool:
- case QVariant::Int:
- bind(index, value.toInt());
- break;
- case QVariant::UInt:
- case QVariant::LongLong:
- case QVariant::ULongLong:
- bind(index, value.toLongLong());
- break;
- case QVariant::Double:
- bind(index, value.toDouble());
- break;
- case QVariant::String:
- bind(index, value.toString());
- break;
- case QVariant::ByteArray:
- bind(index, value.toByteArray());
- break;
- default:
- sqlite3_bind_null(compiledStatement.get(), index);
- }
+ int resultCode = sqlite3_bind_text(m_compiledStatement.get(),
+ index,
+ text.data(),
+ int(text.size()),
+ SQLITE_STATIC);
+ checkForBindingError(resultCode);
}
template <typename Type>
-void SqliteStatement::bind(const Utf8String &name, const Type &value)
+void Statement::bind(Utils::SmallStringView name, Type value)
{
int index = bindingIndexForName(name);
checkBindingName(index);
bind(index, value);
}
-template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const int &value);
-template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const qint64 &value);
-template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const double &value);
-template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const QString &text);
-template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const QByteArray &blob);
-template SQLITE_EXPORT void SqliteStatement::bind(const Utf8String &name, const QVariant &value);
+template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, int value);
+template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, long value);
+template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, long long value);
+template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, double value);
+template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, Utils::SmallStringView text);
-int SqliteStatement::bindingIndexForName(const Utf8String &name)
+int Statement::bindingIndexForName(Utils::SmallStringView name) const
{
- return sqlite3_bind_parameter_index(compiledStatement.get(), name.constData());
+ return sqlite3_bind_parameter_index(m_compiledStatement.get(), name.data());
}
-void SqliteStatement::bind(const RowDictionary &rowDictionary)
+void Statement::setBindingColumnNames(const Utils::SmallStringVector &bindingColumnNames)
{
- checkBindingValueMapIsEmpty(rowDictionary);
-
- int columnIndex = 1;
- foreach (const Utf8String &columnName, bindingColumnNames_) {
- checkParameterCanBeBound(rowDictionary, columnName);
- QVariant value = rowDictionary.value(columnName);
- bind(columnIndex, value);
- columnIndex += 1;
- }
-}
-
-void SqliteStatement::bindUnchecked(const RowDictionary &rowDictionary)
-{
- checkBindingValueMapIsEmpty(rowDictionary);
-
- int columnIndex = 1;
- foreach (const Utf8String &columnName, bindingColumnNames_) {
- if (rowDictionary.contains(columnName)) {
- QVariant value = rowDictionary.value(columnName);
- bind(columnIndex, value);
- }
- columnIndex += 1;
- }
+ m_bindingColumnNames = bindingColumnNames;
}
-void SqliteStatement::setBindingColumnNames(const Utf8StringVector &bindingColumnNames)
+const Utils::SmallStringVector &Statement::bindingColumnNames() const
{
- bindingColumnNames_ = bindingColumnNames;
+ return m_bindingColumnNames;
}
-const Utf8StringVector &SqliteStatement::bindingColumnNames() const
-{
- return bindingColumnNames_;
-}
-
-void SqliteStatement::execute(const Utf8String &sqlStatementUtf8)
-{
- SqliteStatement statement(sqlStatementUtf8);
- statement.step();
-}
-
-void SqliteStatement::prepare(const Utf8String &sqlStatementUtf8)
+void Statement::prepare(Utils::SmallStringView sqlStatement)
{
int resultCode;
do {
sqlite3_stmt *sqliteStatement = nullptr;
- resultCode = sqlite3_prepare_v2(sqliteDatabaseHandle(), sqlStatementUtf8.constData(), sqlStatementUtf8.byteSize(), &sqliteStatement, nullptr);
- compiledStatement.reset(sqliteStatement);
+ resultCode = sqlite3_prepare_v2(sqliteDatabaseHandle(),
+ sqlStatement.data(),
+ int(sqlStatement.size()),
+ &sqliteStatement,
+ nullptr);
+ m_compiledStatement.reset(sqliteStatement);
if (resultCode == SQLITE_LOCKED)
waitForUnlockNotify();
@@ -316,356 +242,310 @@ void SqliteStatement::prepare(const Utf8String &sqlStatementUtf8)
checkForPrepareError(resultCode);
}
-sqlite3 *SqliteStatement::sqliteDatabaseHandle()
+sqlite3 *Statement::sqliteDatabaseHandle() const
{
-return SqliteDatabaseBackend::sqliteDatabaseHandle();
+ return m_database.backend().sqliteDatabaseHandle();
}
-TextEncoding SqliteStatement::databaseTextEncoding()
+TextEncoding Statement::databaseTextEncoding()
{
- if (SqliteDatabaseBackend::threadLocalInstance())
- return SqliteDatabaseBackend::threadLocalInstance()->textEncoding();
-
- throwException("SqliteStatement::databaseTextEncoding: database backend instance is null!");
-
- Q_UNREACHABLE();
+ return m_database.backend().textEncoding();
}
-bool SqliteStatement::checkForStepError(int resultCode) const
+bool Statement::checkForStepError(int resultCode) const
{
switch (resultCode) {
case SQLITE_ROW: return true;
case SQLITE_DONE: return false;
- case SQLITE_BUSY: throwException("SqliteStatement::stepStatement: database engine was unable to acquire the database locks!");
- case SQLITE_ERROR : throwException("SqliteStatement::stepStatement: run-time error (such as a constraint violation) has occurred!");
- case SQLITE_MISUSE: throwException("SqliteStatement::stepStatement: was called inappropriately!");
- case SQLITE_CONSTRAINT: throwException("SqliteStatement::stepStatement: contraint prevent insert or update!");
+ case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::stepStatement: database engine was unable to acquire the database locks!");
+ case SQLITE_ERROR : throwStatementHasError("SqliteStatement::stepStatement: run-time error (such as a constraint violation) has occurred!");
+ case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::stepStatement: was called inappropriately!");
+ case SQLITE_CONSTRAINT: throwConstraintPreventsModification("SqliteStatement::stepStatement: contraint prevent insert or update!");
}
- throwException("SqliteStatement::stepStatement: unknown error has happened");
+ throwUnknowError("SqliteStatement::stepStatement: unknown error has happened");
Q_UNREACHABLE();
}
-void SqliteStatement::checkForPrepareError(int resultCode) const
+void Statement::checkForPrepareError(int resultCode) const
{
switch (resultCode) {
case SQLITE_OK: return;
- case SQLITE_BUSY: throwException("SqliteStatement::prepareStatement: database engine was unable to acquire the database locks!");
- case SQLITE_ERROR : throwException("SqliteStatement::prepareStatement: run-time error (such as a constraint violation) has occurred!");
- case SQLITE_MISUSE: throwException("SqliteStatement::prepareStatement: was called inappropriately!");
+ case SQLITE_BUSY: throwStatementIsBusy("SqliteStatement::prepareStatement: database engine was unable to acquire the database locks!");
+ case SQLITE_ERROR : throwStatementHasError("SqliteStatement::prepareStatement: run-time error (such as a constraint violation) has occurred!");
+ case SQLITE_MISUSE: throwStatementIsMisused("SqliteStatement::prepareStatement: was called inappropriately!");
}
- throwException("SqliteStatement::prepareStatement: unknown error has happened");
+ throwUnknowError("SqliteStatement::prepareStatement: unknown error has happened");
}
-void SqliteStatement::setIfIsReadyToFetchValues(int resultCode) const
+void Statement::checkForBindingError(int resultCode) const
+{
+ switch (resultCode) {
+ case SQLITE_OK: return;
+ case SQLITE_TOOBIG: throwBingingTooBig("SqliteStatement::bind: string or blob are over size limits(SQLITE_LIMIT_LENGTH)!");
+ case SQLITE_RANGE : throwBindingIndexIsOutOfRange("SqliteStatement::bind: binding index is out of range!");
+ case SQLITE_NOMEM: throw std::bad_alloc();
+ }
+
+ throwUnknowError("SqliteStatement::bind: unknown error has happened");
+}
+
+void Statement::setIfIsReadyToFetchValues(int resultCode) const
{
if (resultCode == SQLITE_ROW)
- isReadyToFetchValues = true;
+ m_isReadyToFetchValues = true;
else
- isReadyToFetchValues = false;
+ m_isReadyToFetchValues = false;
}
-void SqliteStatement::checkIfIsReadyToFetchValues() const
+void Statement::checkIfIsReadyToFetchValues() const
{
- if (!isReadyToFetchValues)
- throwException("SqliteStatement::value: there are no values to fetch!");
+ if (!m_isReadyToFetchValues)
+ throwNoValuesToFetch("SqliteStatement::value: there are no values to fetch!");
}
-void SqliteStatement::checkColumnsAreValid(const QVector<int> &columns) const
+void Statement::checkColumnsAreValid(const std::vector<int> &columns) const
{
- foreach (int column, columns) {
- if (column < 0 || column >= columnCount_)
- throwException("SqliteStatement::values: column index out of bound!");
+ for (int column : columns) {
+ if (column < 0 || column >= m_columnCount)
+ throwInvalidColumnFetched("SqliteStatement::values: column index out of bound!");
}
}
-void SqliteStatement::checkColumnIsValid(int column) const
+void Statement::checkColumnIsValid(int column) const
{
- if (column < 0 || column >= columnCount_)
- throwException("SqliteStatement::values: column index out of bound!");
+ if (column < 0 || column >= m_columnCount)
+ throwInvalidColumnFetched("SqliteStatement::values: column index out of bound!");
}
-void SqliteStatement::checkBindingIndex(int index) const
+void Statement::checkBindingName(int index) const
{
- if (index <= 0 || index > bindingParameterCount)
- throwException("SqliteStatement::bind: binding index is out of bound!");
+ if (index <= 0 || index > m_bindingParameterCount)
+ throwWrongBingingName("SqliteStatement::bind: binding name are not exists in this statement!");
}
-void SqliteStatement::checkBindingName(int index) const
+void Statement::setBindingParameterCount()
{
- if (index <= 0 || index > bindingParameterCount)
- throwException("SqliteStatement::bind: binding name are not exists in this statement!");
+ m_bindingParameterCount = sqlite3_bind_parameter_count(m_compiledStatement.get());
}
-void SqliteStatement::checkParameterCanBeBound(const RowDictionary &rowDictionary, const Utf8String &columnName)
+Utils::SmallStringView chopFirstLetter(const char *rawBindingName)
{
- if (!rowDictionary.contains(columnName))
- throwException("SqliteStatement::bind: Not all parameters are bound!");
+ if (rawBindingName != nullptr)
+ return Utils::SmallStringView(++rawBindingName);
+
+ return Utils::SmallStringView("");
}
-void SqliteStatement::setBindingParameterCount()
+void Statement::setBindingColumnNamesFromStatement()
{
- bindingParameterCount = sqlite3_bind_parameter_count(compiledStatement.get());
+ for (int index = 1; index <= m_bindingParameterCount; index++) {
+ Utils::SmallStringView bindingName = chopFirstLetter(sqlite3_bind_parameter_name(m_compiledStatement.get(), index));
+ m_bindingColumnNames.push_back(Utils::SmallString(bindingName));
+ }
}
-Utf8String chopFirstLetter(const char *rawBindingName)
+void Statement::setColumnCount()
{
- QByteArray bindingName(rawBindingName);
- bindingName = bindingName.mid(1);
-
- return Utf8String::fromByteArray(bindingName);
+ m_columnCount = sqlite3_column_count(m_compiledStatement.get());
}
-void SqliteStatement::setBindingColumnNamesFromStatement()
+bool Statement::isReadOnlyStatement() const
{
- for (int index = 1; index <= bindingParameterCount; index++) {
- Utf8String bindingName = chopFirstLetter(sqlite3_bind_parameter_name(compiledStatement.get(), index));
- bindingColumnNames_.append(bindingName);
- }
+ return sqlite3_stmt_readonly(m_compiledStatement.get());
}
-void SqliteStatement::setColumnCount()
+void Statement::throwStatementIsBusy(const char *whatHasHappened) const
{
- columnCount_ = sqlite3_column_count(compiledStatement.get());
+ throw StatementIsBusy(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
}
-void SqliteStatement::checkBindingValueMapIsEmpty(const RowDictionary &rowDictionary) const
+void Statement::throwStatementHasError(const char *whatHasHappened) const
{
- if (rowDictionary.isEmpty())
- throwException("SqliteStatement::bind: can't bind empty row!");
+ throw StatementHasError(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
}
-bool SqliteStatement::isReadOnlyStatement() const
+void Statement::throwStatementIsMisused(const char *whatHasHappened) const
{
- return sqlite3_stmt_readonly(compiledStatement.get());
+ throw StatementIsMisused(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
}
-void SqliteStatement::throwException(const char *whatHasHappened)
+void Statement::throwConstraintPreventsModification(const char *whatHasHappened) const
{
- throw SqliteException(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
+ throw ContraintPreventsModification(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
}
-QString SqliteStatement::columnName(int column) const
+void Statement::throwNoValuesToFetch(const char *whatHasHappened) const
{
- return QString::fromUtf8(sqlite3_column_name(compiledStatement.get(), column));
+ throw NoValuesToFetch(whatHasHappened);
}
-static bool columnIsBlob(sqlite3_stmt *sqlStatment, int column)
+void Statement::throwInvalidColumnFetched(const char *whatHasHappened) const
{
- return sqlite3_column_type(sqlStatment, column) == SQLITE_BLOB;
+ throw InvalidColumnFetched(whatHasHappened);
}
-static QByteArray byteArrayForColumn(sqlite3_stmt *sqlStatment, int column)
+void Statement::throwBindingIndexIsOutOfRange(const char *whatHasHappened) const
{
- if (columnIsBlob(sqlStatment, column)) {
- const char *blob = static_cast<const char*>(sqlite3_column_blob(sqlStatment, column));
- int size = sqlite3_column_bytes(sqlStatment, column);
-
- return QByteArray(blob, size);
- }
-
- return QByteArray();
+ throw BindingIndexIsOutOfRange(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
}
-static QString textForColumn(sqlite3_stmt *sqlStatment, int column)
+void Statement::throwWrongBingingName(const char *whatHasHappened) const
{
- const QChar *text = static_cast<const QChar*>(sqlite3_column_text16(sqlStatment, column));
- int size = sqlite3_column_bytes16(sqlStatment, column) / 2;
+ throw WrongBingingName(whatHasHappened);
+}
- return QString(text, size);
+void Statement::throwUnknowError(const char *whatHasHappened) const
+{
+ if (sqliteDatabaseHandle())
+ throw UnknowError(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
+ else
+ throw UnknowError(whatHasHappened);
}
-static Utf8String utf8TextForColumn(sqlite3_stmt *sqlStatment, int column)
+void Statement::throwBingingTooBig(const char *whatHasHappened) const
{
- const char *text = reinterpret_cast<const char*>(sqlite3_column_text(sqlStatment, column));
- int size = sqlite3_column_bytes(sqlStatment, column);
+ throw BindingTooBig(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
+}
- return Utf8String(text, size);
+QString Statement::columnName(int column) const
+{
+ return QString::fromUtf8(sqlite3_column_name(m_compiledStatement.get(), column));
}
+Database &Statement::database() const
+{
+ return m_database;
+}
-static Utf8String convertedToUtf8StringForColumn(sqlite3_stmt *sqlStatment, int column)
+template <typename StringType>
+static StringType textForColumn(sqlite3_stmt *sqlStatment, int column)
{
- int dataType = sqlite3_column_type(sqlStatment, column);
- switch (dataType) {
- case SQLITE_INTEGER: return Utf8String::fromByteArray(QByteArray::number(sqlite3_column_int64(sqlStatment, column)));
- case SQLITE_FLOAT: return Utf8String::fromByteArray(QByteArray::number(sqlite3_column_double(sqlStatment, column)));
- case SQLITE_BLOB: return Utf8String();
- case SQLITE3_TEXT: return utf8TextForColumn(sqlStatment, column);
- case SQLITE_NULL: return Utf8String();
- }
+ const char *text = reinterpret_cast<const char*>(sqlite3_column_text(sqlStatment, column));
+ std::size_t size = std::size_t(sqlite3_column_bytes(sqlStatment, column));
- Q_UNREACHABLE();
+ return StringType(text, size);
}
-
-static QVariant variantForColumn(sqlite3_stmt *sqlStatment, int column)
+template <typename StringType>
+static StringType convertToTextForColumn(sqlite3_stmt *sqlStatment, int column)
{
int dataType = sqlite3_column_type(sqlStatment, column);
switch (dataType) {
- case SQLITE_INTEGER: return QVariant::fromValue(sqlite3_column_int64(sqlStatment, column));
- case SQLITE_FLOAT: return QVariant::fromValue(sqlite3_column_double(sqlStatment, column));
- case SQLITE_BLOB: return QVariant::fromValue(byteArrayForColumn(sqlStatment, column));
- case SQLITE3_TEXT: return QVariant::fromValue(textForColumn(sqlStatment, column));
- case SQLITE_NULL: return QVariant();
+ case SQLITE_INTEGER:
+ case SQLITE_FLOAT:
+ case SQLITE3_TEXT: return textForColumn<StringType>(sqlStatment, column);
+ case SQLITE_BLOB:
+ case SQLITE_NULL: return {};
}
Q_UNREACHABLE();
}
-template<>
-int SqliteStatement::value<int>(int column) const
+int Statement::fetchIntValue(int column) const
{
checkIfIsReadyToFetchValues();
checkColumnIsValid(column);
- return sqlite3_column_int(compiledStatement.get(), column);
+ return sqlite3_column_int(m_compiledStatement.get(), column);
}
template<>
-qint64 SqliteStatement::value<qint64>(int column) const
+int Statement::fetchValue<int>(int column) const
{
- checkIfIsReadyToFetchValues();
- checkColumnIsValid(column);
- return sqlite3_column_int64(compiledStatement.get(), column);
+ return fetchIntValue(column);
}
-template<>
-double SqliteStatement::value<double>(int column) const
+long Statement::fetchLongValue(int column) const
{
- checkIfIsReadyToFetchValues();
- checkColumnIsValid(column);
- return sqlite3_column_double(compiledStatement.get(), column);
+ return long(fetchValue<long long>(column));
}
template<>
-QByteArray SqliteStatement::value<QByteArray>(int column) const
+long Statement::fetchValue<long>(int column) const
{
- checkIfIsReadyToFetchValues();
- checkColumnIsValid(column);
- return byteArrayForColumn(compiledStatement.get(), column);
+ return fetchLongValue(column);
}
-template<>
-Utf8String SqliteStatement::value<Utf8String>(int column) const
+long long Statement::fetchLongLongValue(int column) const
{
checkIfIsReadyToFetchValues();
checkColumnIsValid(column);
- return convertedToUtf8StringForColumn(compiledStatement.get(), column);
+ return sqlite3_column_int64(m_compiledStatement.get(), column);
}
template<>
-QString SqliteStatement::value<QString>(int column) const
+long long Statement::fetchValue<long long>(int column) const
{
- checkIfIsReadyToFetchValues();
- checkColumnIsValid(column);
- return textForColumn(compiledStatement.get(), column);
+ return fetchLongLongValue(column);
}
-template<>
-QVariant SqliteStatement::value<QVariant>(int column) const
+double Statement::fetchDoubleValue(int column) const
{
checkIfIsReadyToFetchValues();
checkColumnIsValid(column);
- return variantForColumn(compiledStatement.get(), column);
+ return sqlite3_column_double(m_compiledStatement.get(), column);
}
-template <typename ContainerType>
- ContainerType SqliteStatement::columnValues(const QVector<int> &columnIndices) const
+template<>
+double Statement::fetchValue<double>(int column) const
{
- typedef typename ContainerType::value_type ElementType;
- ContainerType valueContainer;
- valueContainer.reserve(columnIndices.count());
- for (int columnIndex : columnIndices)
- valueContainer += value<ElementType>(columnIndex);
-
- return valueContainer;
+ return fetchDoubleValue(column);
}
-QMap<QString, QVariant> SqliteStatement::rowColumnValueMap() const
+template<typename StringType>
+StringType Statement::fetchValue(int column) const
{
- QMap<QString, QVariant> values;
-
- reset();
-
- if (next()) {
- for (int column = 0; column < columnCount(); column++)
- values.insert(columnName(column), variantForColumn(compiledStatement.get(), column));
- }
-
- return values;
+ checkIfIsReadyToFetchValues();
+ checkColumnIsValid(column);
+ return convertToTextForColumn<StringType>(m_compiledStatement.get(), column);
}
-QMap<QString, QVariant> SqliteStatement::twoColumnValueMap() const
+Utils::SmallString Statement::fetchSmallStringValue(int column) const
{
- QMap<QString, QVariant> values;
-
- reset();
-
- while (next())
- values.insert(textForColumn(compiledStatement.get(), 0), variantForColumn(compiledStatement.get(), 1));
-
- return values;
+ return fetchValue<Utils::SmallString>(column);
}
-template <typename ContainerType>
-ContainerType SqliteStatement::values(const QVector<int> &columns, int size) const
+Utils::PathString Statement::fetchPathStringValue(int column) const
{
- checkColumnsAreValid(columns);
-
- ContainerType resultValues;
- resultValues.reserve(size);
-
- reset();
+ return fetchValue<Utils::PathString>(column);
+}
- while (next()) {
- resultValues += columnValues<ContainerType>(columns);
- }
+template SQLITE_EXPORT Utils::SmallString Statement::fetchValue<Utils::SmallString>(int column) const;
+template SQLITE_EXPORT Utils::PathString Statement::fetchValue<Utils::PathString>(int column) const;
- return resultValues;
+Utils::SmallString Statement::text(int column) const
+{
+ return fetchValue<Utils::SmallString>(column);
}
-template SQLITE_EXPORT QVector<QVariant> SqliteStatement::values<QVector<QVariant>>(const QVector<int> &columnIndices, int size) const;
-template SQLITE_EXPORT QVector<Utf8String> SqliteStatement::values<QVector<Utf8String>>(const QVector<int> &columnIndices, int size) const;
-
template <typename ContainerType>
-ContainerType SqliteStatement::values(int column) const
+ContainerType Statement::columnValues(const std::vector<int> &columnIndices) const
{
- typedef typename ContainerType::value_type ElementType;
- ContainerType resultValues;
-
- reset();
-
- while (next()) {
- resultValues += value<ElementType>(column);
- }
+ using ElementType = typename ContainerType::value_type;
+ ContainerType valueContainer;
+ valueContainer.reserve(columnIndices.size());
+ for (int columnIndex : columnIndices)
+ valueContainer.push_back(fetchValue<ElementType>(columnIndex));
- return resultValues;
+ return valueContainer;
}
-template SQLITE_EXPORT QVector<qint64> SqliteStatement::values<QVector<qint64>>(int column) const;
-template SQLITE_EXPORT QVector<double> SqliteStatement::values<QVector<double>>(int column) const;
-template SQLITE_EXPORT QVector<QByteArray> SqliteStatement::values<QVector<QByteArray>>(int column) const;
-template SQLITE_EXPORT Utf8StringVector SqliteStatement::values<Utf8StringVector>(int column) const;
-template SQLITE_EXPORT QVector<QString> SqliteStatement::values<QVector<QString>>(int column) const;
-
template <typename Type>
-Type SqliteStatement::toValue(const Utf8String &sqlStatementUtf8)
+Type Statement::toValue(Utils::SmallStringView sqlStatement, Database &database)
{
- SqliteStatement statement(sqlStatementUtf8);
+ Statement statement(sqlStatement, database);
statement.next();
- return statement.value<Type>(0);
+ return statement.fetchValue<Type>(0);
}
-template SQLITE_EXPORT int SqliteStatement::toValue<int>(const Utf8String &sqlStatementUtf8);
-template SQLITE_EXPORT qint64 SqliteStatement::toValue<qint64>(const Utf8String &sqlStatementUtf8);
-template SQLITE_EXPORT double SqliteStatement::toValue<double>(const Utf8String &sqlStatementUtf8);
-template SQLITE_EXPORT QString SqliteStatement::toValue<QString>(const Utf8String &sqlStatementUtf8);
-template SQLITE_EXPORT QByteArray SqliteStatement::toValue<QByteArray>(const Utf8String &sqlStatementUtf8);
-template SQLITE_EXPORT Utf8String SqliteStatement::toValue<Utf8String>(const Utf8String &sqlStatementUtf8);
-template SQLITE_EXPORT QVariant SqliteStatement::toValue<QVariant>(const Utf8String &sqlStatementUtf8);
+template SQLITE_EXPORT int Statement::toValue<int>(Utils::SmallStringView sqlStatement, Database &database);
+template SQLITE_EXPORT long long Statement::toValue<long long>(Utils::SmallStringView sqlStatement, Database &database);
+template SQLITE_EXPORT double Statement::toValue<double>(Utils::SmallStringView sqlStatement, Database &database);
+template SQLITE_EXPORT Utils::SmallString Statement::toValue<Utils::SmallString>(Utils::SmallStringView sqlStatement, Database &database);
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitestatement.h b/src/libs/sqlite/sqlitestatement.h
index 4cdf5ac262d..3e93b7ba8d6 100644
--- a/src/libs/sqlite/sqlitestatement.h
+++ b/src/libs/sqlite/sqlitestatement.h
@@ -28,101 +28,373 @@
#include "sqliteglobal.h"
#include "sqliteexception.h"
-#include "utf8stringvector.h"
-#include <QString>
-#include <QVariant>
-#include <QVector>
+#include <utils/smallstringvector.h>
-#include <type_traits>
+#include <utils/optional.h>
+
+#include <cstdint>
#include <memory>
+#include <type_traits>
+#include <tuple>
+
+using std::int64_t;
struct sqlite3_stmt;
struct sqlite3;
-class SQLITE_EXPORT SqliteStatement
+namespace Sqlite {
+
+class Database;
+class DatabaseBackend;
+
+class SQLITE_EXPORT Statement
{
protected:
- explicit SqliteStatement(const Utf8String &sqlStatementUtf8);
+ explicit Statement(Utils::SmallStringView sqlStatement, Database &database);
- static void deleteCompiledStatement(sqlite3_stmt *compiledStatement);
+ static void deleteCompiledStatement(sqlite3_stmt *m_compiledStatement);
bool next() const;
void step() const;
+ void execute() const;
void reset() const;
+ int fetchIntValue(int column) const;
+ long fetchLongValue(int column) const;
+ long long fetchLongLongValue(int column) const;
+ double fetchDoubleValue(int column) const;
+ Utils::SmallString fetchSmallStringValue(int column) const;
+ Utils::PathString fetchPathStringValue(int column) const;
template<typename Type>
- Type value(int column) const;
+ Type fetchValue(int column) const;
+ Utils::SmallString text(int column) const;
int columnCount() const;
- Utf8StringVector columnNames() const;
+ Utils::SmallStringVector columnNames() const;
+
+ void bind(int index, int fetchValue);
+ void bind(int index, long long fetchValue);
+ void bind(int index, double fetchValue);
+ void bind(int index, Utils::SmallStringView fetchValue);
+
+ void bind(int index, uint value)
+ {
+ bind(index, static_cast<long long>(value));
+ }
- void bind(int index, int value);
- void bind(int index, qint64 value);
- void bind(int index, double value);
- void bind(int index, const QString &text);
- void bind(int index, const QByteArray &blob);
- void bind(int index, const QVariant &value);
+ void bind(int index, long value)
+ {
+ bind(index, static_cast<long long>(value));
+ }
+
+ void bindValues()
+ {
+ }
+
+ template<typename... ValueType>
+ void bindValues(const ValueType&... values)
+ {
+ bindValuesByIndex(1, values...);
+ }
+
+ template<typename... ValueType>
+ void write(const ValueType&... values)
+ {
+ bindValuesByIndex(1, values...);
+ execute();
+ }
+
+ template<typename... ValueType>
+ void bindNameValues(const ValueType&... values)
+ {
+ bindValuesByName(values...);
+ }
+
+ template<typename... ValueType>
+ void writeNamed(const ValueType&... values)
+ {
+ bindValuesByName(values...);
+ execute();
+ }
template <typename Type>
- void bind(const Utf8String &name, const Type &value);
+ void bind(Utils::SmallStringView name, Type fetchValue);
- int bindingIndexForName(const Utf8String &name);
+ int bindingIndexForName(Utils::SmallStringView name) const;
- void bind(const RowDictionary &rowDictionary);
- void bindUnchecked(const RowDictionary &rowDictionary);
+ void setBindingColumnNames(const Utils::SmallStringVector &bindingColumnNames);
+ const Utils::SmallStringVector &bindingColumnNames() const;
- void setBindingColumnNames(const Utf8StringVector &bindingColumnNames);
- const Utf8StringVector &bindingColumnNames() const;
+ template <typename ResultType,
+ int ResultTypeCount = 1>
+ std::vector<ResultType> values(std::size_t reserveSize)
+ {
+ std::vector<ResultType> resultValues;
+ resultValues.reserve(reserveSize);
- template <typename ContainerType>
- ContainerType values(const QVector<int> &columns, int size = 0) const;
+ while (next())
+ emplaceBackValues<ResultTypeCount>(resultValues);
- template <typename ContainerType>
- ContainerType values(int column = 0) const;
+ reset();
- QMap<QString, QVariant> rowColumnValueMap() const;
- QMap<QString, QVariant> twoColumnValueMap() const;
+ return resultValues;
+ }
- static void execute(const Utf8String &sqlStatementUtf8);
+ template <typename ResultType,
+ int ResultTypeCount = 1,
+ typename... QueryTypes>
+ std::vector<ResultType> values(std::size_t reserveSize, const QueryTypes&... queryValues)
+ {
+ std::vector<ResultType> resultValues;
+ resultValues.reserve(reserveSize);
- template <typename Type>
- static Type toValue(const Utf8String &sqlStatementUtf8);
+ bindValues(queryValues...);
- void prepare(const Utf8String &sqlStatementUtf8);
- void waitForUnlockNotify() const;
+ while (next())
+ emplaceBackValues<ResultTypeCount>(resultValues);
+
+ reset();
+
+ return resultValues;
+ }
+
+ template <typename ResultType,
+ int ResultTypeCount = 1,
+ typename QueryElementType>
+ std::vector<ResultType> values(std::size_t reserveSize,
+ const std::vector<QueryElementType> &queryValues)
+ {
+ std::vector<ResultType> resultValues;
+ resultValues.reserve(reserveSize);
+
+ for (const QueryElementType &queryValue : queryValues) {
+ bindValues(queryValue);
+
+ while (next())
+ emplaceBackValues<ResultTypeCount>(resultValues);
+
+ reset();
+ }
+
+ return resultValues;
+ }
+
+ template <typename ResultType,
+ int ResultTypeCount = 1,
+ typename... QueryElementTypes>
+ std::vector<ResultType> values(std::size_t reserveSize,
+ const std::vector<std::tuple<QueryElementTypes...>> &queryTuples)
+ {
+ using Container = std::vector<ResultType>;
+ Container resultValues;
+ resultValues.reserve(reserveSize);
+
+ for (const auto &queryTuple : queryTuples) {
+ bindTupleValues(queryTuple);
+
+ while (next())
+ emplaceBackValues<ResultTypeCount>(resultValues);
+
+ reset();
+ }
+
+ return resultValues;
+ }
+
+ template <typename ResultType,
+ int ResultTypeCount = 1,
+ typename... QueryTypes>
+ Utils::optional<ResultType> value( const QueryTypes&... queryValues)
+ {
+ Utils::optional<ResultType> resultValue;
+
+ bindValues(queryValues...);
- void write(const RowDictionary &rowDictionary);
- void writeUnchecked(const RowDictionary &rowDictionary);
+ if (next())
+ resultValue = assignValue<Utils::optional<ResultType>, ResultTypeCount>();
- static sqlite3 *sqliteDatabaseHandle();
- static TextEncoding databaseTextEncoding();
+ reset();
+ return resultValue;
+ }
+
+ template <typename Type>
+ static Type toValue(Utils::SmallStringView sqlStatement, Database &database);
+
+ void prepare(Utils::SmallStringView sqlStatement);
+ void waitForUnlockNotify() const;
+
+ sqlite3 *sqliteDatabaseHandle() const;
+ TextEncoding databaseTextEncoding();
bool checkForStepError(int resultCode) const;
void checkForPrepareError(int resultCode) const;
+ void checkForBindingError(int resultCode) const;
void setIfIsReadyToFetchValues(int resultCode) const;
void checkIfIsReadyToFetchValues() const;
- void checkColumnsAreValid(const QVector<int> &columns) const;
+ void checkColumnsAreValid(const std::vector<int> &columns) const;
void checkColumnIsValid(int column) const;
- void checkBindingIndex(int index) const;
void checkBindingName(int index) const;
- void checkParameterCanBeBound(const RowDictionary &rowDictionary, const Utf8String &columnName);
void setBindingParameterCount();
void setBindingColumnNamesFromStatement();
void setColumnCount();
- void checkBindingValueMapIsEmpty(const RowDictionary &rowDictionary) const;
bool isReadOnlyStatement() const;
- Q_NORETURN static void throwException(const char *whatHasHappened);
+ [[noreturn]] void throwStatementIsBusy(const char *whatHasHappened) const;
+ [[noreturn]] void throwStatementHasError(const char *whatHasHappened) const;
+ [[noreturn]] void throwStatementIsMisused(const char *whatHasHappened) const;
+ [[noreturn]] void throwConstraintPreventsModification(const char *whatHasHappened) const;
+ [[noreturn]] void throwNoValuesToFetch(const char *whatHasHappened) const;
+ [[noreturn]] void throwInvalidColumnFetched(const char *whatHasHappened) const;
+ [[noreturn]] void throwBindingIndexIsOutOfRange(const char *whatHasHappened) const;
+ [[noreturn]] void throwWrongBingingName(const char *whatHasHappened) const;
+ [[noreturn]] void throwUnknowError(const char *whatHasHappened) const;
+ [[noreturn]] void throwBingingTooBig(const char *whatHasHappened) const;
template <typename ContainerType>
- ContainerType columnValues(const QVector<int> &columnIndices) const;
+ ContainerType columnValues(const std::vector<int> &columnIndices) const;
QString columnName(int column) const;
+ Database &database() const;
+
+protected:
+ explicit Statement(Utils::SmallStringView sqlStatement,
+ DatabaseBackend &databaseBackend);
+
+private:
+ class ValueGetter
+ {
+ public:
+ ValueGetter(Statement &statement, int column)
+ : statement(statement),
+ column(column)
+ {}
+
+ operator int()
+ {
+ return statement.fetchIntValue(column);
+ }
+
+ operator long()
+ {
+ return statement.fetchLongValue(column);
+ }
+
+ operator long long()
+ {
+ return statement.fetchLongLongValue(column);
+ }
+
+ operator double()
+ {
+ return statement.fetchDoubleValue(column);
+ }
+
+ operator Utils::SmallString()
+ {
+ return statement.fetchSmallStringValue(column);
+ }
+
+ operator Utils::PathString()
+ {
+ return statement.fetchPathStringValue(column);
+ }
+
+ Statement &statement;
+ int column;
+ };
+
+ template <typename ContainerType,
+ int... ColumnIndices>
+ void emplaceBackValues(ContainerType &container, std::integer_sequence<int, ColumnIndices...>)
+ {
+ container.emplace_back(ValueGetter(*this, ColumnIndices)...);
+ }
+
+ template <int ResultTypeCount,
+ typename ContainerType>
+ void emplaceBackValues(ContainerType &container)
+ {
+ emplaceBackValues(container, std::make_integer_sequence<int, ResultTypeCount>{});
+ }
+
+ template <typename ResultOptionalType,
+ int... ColumnIndices>
+ ResultOptionalType assignValue(std::integer_sequence<int, ColumnIndices...>)
+ {
+ return ResultOptionalType(Utils::in_place, ValueGetter(*this, ColumnIndices)...);
+ }
+
+ template <typename ResultOptionalType,
+ int ResultTypeCount>
+ ResultOptionalType assignValue()
+ {
+ return assignValue<ResultOptionalType>(std::make_integer_sequence<int, ResultTypeCount>{});
+ }
+
+ template<typename ValueType>
+ void bindValuesByIndex(int index, const ValueType &value)
+ {
+ bind(index, value);
+ }
+
+ template<typename ValueType, typename... ValueTypes>
+ void bindValuesByIndex(int index, const ValueType &value, const ValueTypes&... values)
+ {
+ bind(index, value);
+ bindValuesByIndex(index + 1, values...);
+ }
+
+ template<typename ValueType>
+ void bindValuesByName(Utils::SmallStringView name, const ValueType &value)
+ {
+ bind(bindingIndexForName(name), value);
+ }
+
+ template<typename ValueType, typename... ValueTypes>
+ void bindValuesByName(Utils::SmallStringView name, const ValueType &value, const ValueTypes&... values)
+ {
+ bind(bindingIndexForName(name), value);
+ bindValuesByName(values...);
+ }
+
+ template <typename TupleType, std::size_t... ColumnIndices>
+ void bindTupleValuesElement(const TupleType &tuple, std::index_sequence<ColumnIndices...>)
+ {
+ bindValues(std::get<ColumnIndices>(tuple)...);
+ }
+
+ template <typename TupleType,
+ typename ColumnIndices = std::make_index_sequence<std::tuple_size<TupleType>::value>>
+ void bindTupleValues(const TupleType &element)
+ {
+ bindTupleValuesElement(element, ColumnIndices());
+ }
+
private:
- std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt*)> compiledStatement;
- Utf8StringVector bindingColumnNames_;
- int bindingParameterCount;
- int columnCount_;
- mutable bool isReadyToFetchValues;
+ std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt*)> m_compiledStatement;
+ Utils::SmallStringVector m_bindingColumnNames;
+ Database &m_database;
+ int m_bindingParameterCount;
+ int m_columnCount;
+ mutable bool m_isReadyToFetchValues;
};
+
+extern template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, int value);
+extern template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, long value);
+extern template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, long long value);
+extern template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, double value);
+extern template SQLITE_EXPORT void Statement::bind(Utils::SmallStringView name, Utils::SmallStringView text);
+
+extern template SQLITE_EXPORT int Statement::toValue<int>(Utils::SmallStringView sqlStatement, Database &database);
+extern template SQLITE_EXPORT long long Statement::toValue<long long>(Utils::SmallStringView sqlStatement, Database &database);
+extern template SQLITE_EXPORT double Statement::toValue<double>(Utils::SmallStringView sqlStatement, Database &database);
+extern template SQLITE_EXPORT Utils::SmallString Statement::toValue<Utils::SmallString>(Utils::SmallStringView sqlStatement, Database &database);
+
+template <> SQLITE_EXPORT int Statement::fetchValue<int>(int column) const;
+template <> SQLITE_EXPORT long Statement::fetchValue<long>(int column) const;
+template <> SQLITE_EXPORT long long Statement::fetchValue<long long>(int column) const;
+template <> SQLITE_EXPORT double Statement::fetchValue<double>(int column) const;
+extern template SQLITE_EXPORT Utils::SmallString Statement::fetchValue<Utils::SmallString>(int column) const;
+extern template SQLITE_EXPORT Utils::PathString Statement::fetchValue<Utils::PathString>(int column) const;
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitetable.cpp b/src/libs/sqlite/sqlitetable.cpp
index 671afe1a7cb..99b0e95938c 100644
--- a/src/libs/sqlite/sqlitetable.cpp
+++ b/src/libs/sqlite/sqlitetable.cpp
@@ -25,90 +25,8 @@
#include "sqlitetable.h"
-#include "sqlitecolumn.h"
-#include "sqlitedatabase.h"
+namespace Sqlite {
-SqliteTable::SqliteTable()
- : withoutRowId(false)
-{
-}
-SqliteTable::~SqliteTable()
-{
- qDeleteAll(sqliteColumns);
-}
-
-void SqliteTable::setName(const Utf8String &name)
-{
- tableName = name;
-}
-
-const Utf8String &SqliteTable::name() const
-{
- return tableName;
-}
-
-void SqliteTable::setUseWithoutRowId(bool useWithoutWorId)
-{
- withoutRowId = useWithoutWorId;
-}
-
-bool SqliteTable::useWithoutRowId() const
-{
- return withoutRowId;
-}
-
-void SqliteTable::addColumn(SqliteColumn *newColumn)
-{
- sqliteColumns.append(newColumn);
-}
-
-const QVector<SqliteColumn *> &SqliteTable::columns() const
-{
- return sqliteColumns;
-}
-
-void SqliteTable::setSqliteDatabase(SqliteDatabase *database)
-{
- sqliteDatabase = database;
- writeWorker.moveWorkerToThread(sqliteDatabase->writeWorkerThread());
-}
-
-void SqliteTable::initialize()
-{
- writeWorker.connectWithWorker(this);
-
- writeWorker.createTable(createTableCommand());
-}
-
-void SqliteTable::shutdown()
-{
- writeWorker.disconnectWithWorker(this);
-}
-
-void SqliteTable::handleTableCreated()
-{
- emit tableIsReady();
-}
-
-Internal::CreateTableCommand SqliteTable::createTableCommand() const
-{
- Internal::CreateTableCommand createTableCommand;
-
- createTableCommand.tableName = tableName;
- createTableCommand.useWithoutRowId = withoutRowId;
- createTableCommand.definitions = createColumnDefintions();
-
- return createTableCommand;
-}
-
-QVector<Internal::ColumnDefinition> SqliteTable::createColumnDefintions() const
-{
- QVector<Internal::ColumnDefinition> columnDefintions;
-
- for (SqliteColumn *sqliteColumn: sqliteColumns)
- columnDefintions.append(sqliteColumn->columnDefintion());
-
- return columnDefintions;
-}
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitetable.h b/src/libs/sqlite/sqlitetable.h
index 16a0661909b..d692bf6c236 100644
--- a/src/libs/sqlite/sqlitetable.h
+++ b/src/libs/sqlite/sqlitetable.h
@@ -25,52 +25,133 @@
#pragma once
+#include "createtablesqlstatementbuilder.h"
#include "sqliteglobal.h"
-#include "tablewriteworkerproxy.h"
-#include "utf8string.h"
+#include "sqlitecolumn.h"
+#include "sqliteindex.h"
+#include "sqliteexception.h"
-#include <QObject>
-#include <QVector>
+namespace Sqlite {
-class SqliteColumn;
-class SqliteDatabase;
+class Database;
-class SQLITE_EXPORT SqliteTable : public QObject
+class Table
{
- Q_OBJECT
+public:
+ Table(std::size_t reserve = 10)
+ {
+ m_sqliteColumns.reserve(reserve);
+ m_sqliteIndices.reserve(reserve);
+ }
- friend class Internal::TableWriteWorkerProxy;
+ void setName(Utils::SmallString &&name)
+ {
+ m_tableName = std::move(name);
+ }
-public:
- SqliteTable();
- ~SqliteTable();
+ Utils::SmallStringView name() const
+ {
+ return m_tableName;
+ }
+
+ void setUseWithoutRowId(bool useWithoutWorId)
+ {
+ m_withoutRowId = useWithoutWorId;
+ }
+
+ bool useWithoutRowId() const
+ {
+ return m_withoutRowId;
+ }
+
+ void setUseIfNotExists(bool useIfNotExists)
+ {
+ m_useIfNotExists = useIfNotExists;
+ }
+
+ void setUseTemporaryTable(bool useTemporaryTable)
+ {
+ m_useTemporaryTable = useTemporaryTable;
+ }
+
+ Column &addColumn(Utils::SmallString &&name,
+ ColumnType type = ColumnType::Numeric,
+ Contraint constraint = Contraint::NoConstraint)
+ {
+ m_sqliteColumns.emplace_back(std::move(name), type, constraint);
+
+ return m_sqliteColumns.back();
+ }
- void setName(const Utf8String &name);
- const Utf8String &name() const;
+ Index &addIndex(const SqliteColumnConstReferences &columns)
+ {
+ m_sqliteIndices.emplace_back(m_tableName.clone(), sqliteColumnNames(columns));
- void setUseWithoutRowId(bool useWithoutWorId);
- bool useWithoutRowId() const;
+ return m_sqliteIndices.back();
+ }
- void addColumn(SqliteColumn *newColumn);
- const QVector<SqliteColumn *> &columns() const;
+ const SqliteColumns &columns() const
+ {
+ return m_sqliteColumns;
+ }
- void setSqliteDatabase(SqliteDatabase *database);
+ bool isReady() const
+ {
+ return m_isReady;
+ }
- void initialize();
- void shutdown();
+ template <typename Database>
+ void initialize(Database &database)
+ {
+ CreateTableSqlStatementBuilder builder;
-signals:
- void tableIsReady();
+ builder.setTableName(m_tableName.clone());
+ builder.setUseWithoutRowId(m_withoutRowId);
+ builder.setUseIfNotExists(m_useIfNotExists);
+ builder.setUseTemporaryTable(m_useTemporaryTable);
+ builder.setColumns(m_sqliteColumns);
+
+ database.execute(builder.sqlStatement());
+
+ initializeIndices(database);
+
+ m_isReady = true;
+ }
+ template <typename Database>
+ void initializeIndices(Database &database)
+ {
+ for (const Index &index : m_sqliteIndices)
+ database.execute(index.sqlStatement());
+ }
+
+ friend bool operator==(const Table &first, const Table &second)
+ {
+ return first.m_tableName == second.m_tableName
+ && first.m_withoutRowId == second.m_withoutRowId
+ && first.m_useIfNotExists == second.m_useIfNotExists
+ && first.m_isReady == second.m_isReady
+ && first.m_sqliteColumns == second.m_sqliteColumns;
+ }
private:
- void handleTableCreated();
- Internal::CreateTableCommand createTableCommand() const;
- QVector<Internal::ColumnDefinition> createColumnDefintions() const;
+ Utils::SmallStringVector sqliteColumnNames(const SqliteColumnConstReferences &columns)
+ {
+ Utils::SmallStringVector columnNames;
+
+ for (const Column &column : columns)
+ columnNames.push_back(column.name());
+
+ return columnNames;
+ }
private:
- Internal::TableWriteWorkerProxy writeWorker;
- QVector<SqliteColumn*> sqliteColumns;
- Utf8String tableName;
- SqliteDatabase *sqliteDatabase;
- bool withoutRowId;
+ Utils::SmallString m_tableName;
+ SqliteColumns m_sqliteColumns;
+ SqliteIndices m_sqliteIndices;
+ bool m_withoutRowId = false;
+ bool m_useIfNotExists = false;
+ bool m_useTemporaryTable = false;
+ bool m_isReady = false;
};
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitetransaction.cpp b/src/libs/sqlite/sqlitetransaction.cpp
index 48283e9401a..2ee17131c25 100644
--- a/src/libs/sqlite/sqlitetransaction.cpp
+++ b/src/libs/sqlite/sqlitetransaction.cpp
@@ -25,31 +25,10 @@
#include "sqlitetransaction.h"
+#include "sqlitedatabase.h"
+#include "sqlitedatabasebackend.h"
#include "sqlitewritestatement.h"
-SqliteAbstractTransaction::~SqliteAbstractTransaction()
-{
- if (!isAlreadyCommited)
- SqliteWriteStatement::execute(Utf8StringLiteral("ROLLBACK"));
-}
+namespace Sqlite {
-void SqliteAbstractTransaction::commit()
-{
- SqliteWriteStatement::execute(Utf8StringLiteral("COMMIT"));
- isAlreadyCommited = true;
-}
-
-SqliteTransaction::SqliteTransaction()
-{
- SqliteWriteStatement::execute(Utf8StringLiteral("BEGIN"));
-}
-
-SqliteImmediateTransaction::SqliteImmediateTransaction()
-{
- SqliteWriteStatement::execute(Utf8StringLiteral("BEGIN IMMEDIATE"));
-}
-
-SqliteExclusiveTransaction::SqliteExclusiveTransaction()
-{
- SqliteWriteStatement::execute(Utf8StringLiteral("BEGIN EXCLUSIVE"));
-}
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitetransaction.h b/src/libs/sqlite/sqlitetransaction.h
index 3ff6c8c7396..d271728baea 100644
--- a/src/libs/sqlite/sqlitetransaction.h
+++ b/src/libs/sqlite/sqlitetransaction.h
@@ -27,35 +27,73 @@
#include "sqliteglobal.h"
-class SQLITE_EXPORT SqliteAbstractTransaction
+#include <mutex>
+
+namespace Sqlite {
+
+class DatabaseBackend;
+class Database;
+
+template <typename Database>
+class AbstractTransaction
{
public:
- virtual ~SqliteAbstractTransaction();
+ ~AbstractTransaction()
+ {
+ if (!m_isAlreadyCommited)
+ m_database.execute("ROLLBACK");
+ }
- void commit();
+ void commit()
+ {
+ m_database.execute("COMMIT");
+ m_isAlreadyCommited = true;
+ }
+
+protected:
+ AbstractTransaction(Database &database)
+ : m_databaseLock(database.databaseMutex()),
+ m_database(database)
+ {
+ }
private:
- bool isAlreadyCommited = false;
+ std::lock_guard<typename Database::MutexType> m_databaseLock;
+ Database &m_database;
+ bool m_isAlreadyCommited = false;
};
-
-class SQLITE_EXPORT SqliteTransaction final : public SqliteAbstractTransaction
+template <typename Database>
+class DeferredTransaction final : public AbstractTransaction<Database>
{
public:
- SqliteTransaction();
-
+ DeferredTransaction(Database &database)
+ : AbstractTransaction<Database>(database)
+ {
+ database.execute("BEGIN");
+ }
};
-class SQLITE_EXPORT SqliteImmediateTransaction final : public SqliteAbstractTransaction
+template <typename Database>
+class ImmediateTransaction final : public AbstractTransaction<Database>
{
public:
- SqliteImmediateTransaction();
-
+ ImmediateTransaction(Database &database)
+ : AbstractTransaction<Database>(database)
+ {
+ database.execute("BEGIN IMMEDIATE");
+ }
};
-class SQLITE_EXPORT SqliteExclusiveTransaction final : public SqliteAbstractTransaction
+template <typename Database>
+class ExclusiveTransaction final : public AbstractTransaction<Database>
{
public:
- SqliteExclusiveTransaction();
-
+ ExclusiveTransaction(Database &database)
+ : AbstractTransaction<Database>(database)
+ {
+ database.execute("BEGIN EXCLUSIVE");
+ }
};
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqliteworkerthread.cpp b/src/libs/sqlite/sqliteworkerthread.cpp
deleted file mode 100644
index 8b02a16c7a3..00000000000
--- a/src/libs/sqlite/sqliteworkerthread.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "sqliteworkerthread.h"
-
-#include "sqlitedatabaseconnection.h"
-
-#include <QMutexLocker>
-
-SqliteWorkerThread::SqliteWorkerThread(QObject *parent) :
- QThread(parent)
-{
-}
-
-void SqliteWorkerThread::run()
-{
- QMutexLocker locker(&connectionMutex);
-
- connection = new SqliteDatabaseConnection;
-
- locker.unlock();
- connectionChanged.wakeAll();
-
- QThread::run();
-
- locker.relock();
- delete connection;
- connection = 0;
-}
-
-SqliteDatabaseConnection *SqliteWorkerThread::databaseConnection() const
-{
- QMutexLocker locker(&connectionMutex);
- connectionChanged.wait(&connectionMutex);
-
- return connection;
-}
diff --git a/src/libs/sqlite/sqliteworkerthread.h b/src/libs/sqlite/sqliteworkerthread.h
deleted file mode 100644
index b76852434ac..00000000000
--- a/src/libs/sqlite/sqliteworkerthread.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <QMutex>
-#include <QPointer>
-#include <QThread>
-#include <QWaitCondition>
-
-class SqliteDatabaseConnection;
-
-class SqliteWorkerThread : public QThread
-{
- Q_OBJECT
-public:
- explicit SqliteWorkerThread(QObject *parent = 0);
-
- void run() override;
-
- SqliteDatabaseConnection *databaseConnection() const;
-
-private:
- mutable QMutex connectionMutex;
- mutable QWaitCondition connectionChanged;
- QPointer<SqliteDatabaseConnection> connection;
-};
diff --git a/src/libs/sqlite/sqlitewritestatement.cpp b/src/libs/sqlite/sqlitewritestatement.cpp
index 15fdfaccfe1..26c8522b8a5 100644
--- a/src/libs/sqlite/sqlitewritestatement.cpp
+++ b/src/libs/sqlite/sqlitewritestatement.cpp
@@ -25,14 +25,19 @@
#include "sqlitewritestatement.h"
-SqliteWriteStatement::SqliteWriteStatement(const Utf8String &sqlStatementUtf8)
- : SqliteStatement(sqlStatementUtf8)
+namespace Sqlite {
+
+WriteStatement::WriteStatement(Utils::SmallStringView sqlStatement,
+ Database &database)
+ : Statement(sqlStatement, database)
{
checkIsWritableStatement();
}
-void SqliteWriteStatement::checkIsWritableStatement()
+void WriteStatement::checkIsWritableStatement()
{
if (isReadOnlyStatement())
- throwException("SqliteStatement::SqliteWriteStatement: is not a writable statement!");
+ throw NotWriteSqlStatement("SqliteStatement::SqliteWriteStatement: is not a writable statement!");
}
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitewritestatement.h b/src/libs/sqlite/sqlitewritestatement.h
index abfb27d7416..ec00ae4e8f1 100644
--- a/src/libs/sqlite/sqlitewritestatement.h
+++ b/src/libs/sqlite/sqlitewritestatement.h
@@ -27,22 +27,20 @@
#include "sqlitestatement.h"
-class SQLITE_EXPORT SqliteWriteStatement : private SqliteStatement
+namespace Sqlite {
+
+class SQLITE_EXPORT WriteStatement : private Statement
{
public:
- explicit SqliteWriteStatement(const Utf8String &sqlStatementUtf8);
+ explicit WriteStatement(Utils::SmallStringView sqlStatement, Database &database);
- using SqliteStatement::step;
- using SqliteStatement::reset;
- using SqliteStatement::bind;
- using SqliteStatement::bindUnchecked;
- using SqliteStatement::bindingIndexForName;
- using SqliteStatement::setBindingColumnNames;
- using SqliteStatement::bindingColumnNames;
- using SqliteStatement::write;
- using SqliteStatement::writeUnchecked;
- using SqliteStatement::execute;
+ using Statement::execute;
+ using Statement::database;
+ using Statement::write;
+ using Statement::writeNamed;
protected:
void checkIsWritableStatement();
};
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlstatementbuilder.cpp b/src/libs/sqlite/sqlstatementbuilder.cpp
index d100c2df1a1..cfa08a2b7b3 100644
--- a/src/libs/sqlite/sqlstatementbuilder.cpp
+++ b/src/libs/sqlite/sqlstatementbuilder.cpp
@@ -26,137 +26,164 @@
#include "sqlstatementbuilder.h"
#include "sqlstatementbuilderexception.h"
-#include "utf8stringvector.h"
+
+#include <utils/smallstringvector.h>
#include <algorithm>
-SqlStatementBuilder::SqlStatementBuilder(const Utf8String &sqlTemplate)
- : sqlTemplate(sqlTemplate)
+namespace Sqlite {
+
+SqlStatementBuilder::SqlStatementBuilder(Utils::SmallStringView sqlTemplate)
+ : m_sqlTemplate(std::move(sqlTemplate))
{
}
-void SqlStatementBuilder::bindEmptyText(const Utf8String &name)
+void SqlStatementBuilder::bindEmptyText(Utils::SmallString &&name)
{
clearSqlStatement();
checkIfPlaceHolderExists(name);
- changeBinding(name, Utf8String());
+ changeBinding(std::move(name), {});
}
-void SqlStatementBuilder::bind(const Utf8String &name, const Utf8String &text)
+void SqlStatementBuilder::bind(Utils::SmallString &&name, Utils::SmallString &&text)
{
clearSqlStatement();
checkBindingTextIsNotEmpty(text);
checkIfPlaceHolderExists(name);
- changeBinding(name, text);
+ changeBinding(std::move(name), std::move(text));
}
-void SqlStatementBuilder::bind(const Utf8String &name, const Utf8StringVector &textVector)
+void SqlStatementBuilder::bind(Utils::SmallString &&name, const Utils::SmallStringVector &textVector)
{
clearSqlStatement();
checkBindingTextVectorIsNotEmpty(textVector);
checkIfPlaceHolderExists(name);
- changeBinding(name, textVector.join(Utf8StringLiteral(", ")));
+ changeBinding(std::move(name), textVector.join(", "));
}
-void SqlStatementBuilder::bind(const Utf8String &name, int value)
+void SqlStatementBuilder::bind(Utils::SmallString &&name, int value)
{
clearSqlStatement();
checkIfPlaceHolderExists(name);
- changeBinding(name, Utf8String::number(value));
+ changeBinding(std::move(name), Utils::SmallString::number(value));
}
-void SqlStatementBuilder::bind(const Utf8String &name, const QVector<int> &integerVector)
+namespace {
+Utils::SmallStringVector integerVectorToStringVector(const std::vector<int> &integerVector)
+{
+ Utils::SmallStringVector stringVector;
+ stringVector.reserve(integerVector.size());
+
+ std::transform(integerVector.begin(),
+ integerVector.end(),
+ std::back_inserter(stringVector),
+ [] (int i) { return Utils::SmallString::number(i); });
+
+ return stringVector;
+}
+}
+void SqlStatementBuilder::bind(Utils::SmallString &&name, const std::vector<int> &integerVector)
{
clearSqlStatement();
checkBindingIntegerVectorIsNotEmpty(integerVector);
checkIfPlaceHolderExists(name);
- changeBinding(name, Utf8StringVector::fromIntegerVector(integerVector).join(Utf8StringLiteral(", ")));
+ changeBinding(std::move(name), integerVectorToStringVector(integerVector).join(", "));
}
-void SqlStatementBuilder::bindWithInsertTemplateParameters(const Utf8String &name, const Utf8StringVector &columns)
+void SqlStatementBuilder::bindWithInsertTemplateParameters(Utils::SmallString &&name,
+ const Utils::SmallStringVector &columns)
{
clearSqlStatement();
checkBindingTextVectorIsNotEmpty(columns);
checkIfPlaceHolderExists(name);
- changeBinding(name, insertTemplateParameters(columns));
+ changeBinding(std::move(name), insertTemplateParameters(columns));
}
-void SqlStatementBuilder::bindWithUpdateTemplateParameters(const Utf8String &name, const Utf8StringVector &columns)
+void SqlStatementBuilder::bindWithUpdateTemplateParameters(Utils::SmallString &&name,
+ const Utils::SmallStringVector &columns)
{
clearSqlStatement();
checkBindingTextVectorIsNotEmpty(columns);
checkIfPlaceHolderExists(name);
- changeBinding(name, updateTemplateParameters(columns));
+ changeBinding(std::move(name), updateTemplateParameters(columns));
}
-void SqlStatementBuilder::bindWithUpdateTemplateNames(const Utf8String &name, const Utf8StringVector &columns)
+void SqlStatementBuilder::bindWithUpdateTemplateNames(Utils::SmallString &&name,
+ const Utils::SmallStringVector &columns)
{
clearSqlStatement();
checkBindingTextVectorIsNotEmpty(columns);
checkIfPlaceHolderExists(name);
- changeBinding(name, updateTemplateNames(columns));
+ changeBinding(std::move(name), updateTemplateNames(columns));
}
void SqlStatementBuilder::clear()
{
- bindings.clear();
- sqlStatement_.clear();
+ m_bindings.clear();
+ m_sqlStatement.clear();
}
-const Utf8String SqlStatementBuilder::insertTemplateParameters(const Utf8StringVector &columns)
+Utils::SmallString SqlStatementBuilder::insertTemplateParameters(const Utils::SmallStringVector &columns)
{
- const Utf8StringVector templateParamters(columns.count(), Utf8StringLiteral("?"));
+ const Utils::SmallStringVector templateParamters(columns.size(), "?");
- return templateParamters.join(Utf8StringLiteral(", "));
+ return templateParamters.join(", ");
}
-const Utf8String SqlStatementBuilder::updateTemplateParameters(const Utf8StringVector &columns)
+Utils::SmallString SqlStatementBuilder::updateTemplateParameters(const Utils::SmallStringVector &columns)
{
- Utf8String templateParamters = columns.join(Utf8StringLiteral("=?, "));
- templateParamters.append(Utf8StringLiteral("=?"));
+ Utils::SmallString templateParamters = columns.join("=?, ");
+ templateParamters.append("=?");
return templateParamters;
}
-const Utf8String SqlStatementBuilder::updateTemplateNames(const Utf8StringVector &columns)
+Utils::SmallString SqlStatementBuilder::updateTemplateNames(const Utils::SmallStringVector &columns)
{
- Utf8StringVector templateNames;
+ Utils::SmallStringVector templateNames;
+ templateNames.reserve(columns.size());
+
+ auto convertToTemplateNames = [] (const Utils::SmallString &column) {
+ return Utils::SmallString::join({column, "=@", column});
+ };
- foreach (const Utf8String &columnName, columns)
- templateNames.append(columnName+Utf8StringLiteral("=@")+columnName);
+ std::transform(columns.begin(),
+ columns.end(),
+ std::back_inserter(templateNames),
+ convertToTemplateNames);
- return templateNames.join(Utf8StringLiteral(", "));
+ return templateNames.join(", ");
}
void SqlStatementBuilder::sortBindings() const
{
- std::sort(bindings.begin(), bindings.end(), [] (const BindingPair &lhs,const BindingPair &rhs)
+ std::sort(m_bindings.begin(), m_bindings.end(), [] (const BindingPair &lhs,const BindingPair &rhs)
{
- return lhs.first.byteSize() == rhs.first.byteSize() ? lhs.first.toByteArray() < rhs.first.toByteArray() : lhs.first.byteSize() > rhs.first.byteSize();
+ return lhs.first.size() == rhs.first.size() ? lhs.first < rhs.first : lhs.first.size() > rhs.first.size();
});
}
-Utf8String SqlStatementBuilder::sqlStatement() const
+Utils::SmallStringView SqlStatementBuilder::sqlStatement() const
{
if (!isBuild())
generateSqlStatement();
- return sqlStatement_;
+ return m_sqlStatement;
}
bool SqlStatementBuilder::isBuild() const
{
- return sqlStatement_.hasContent();
+ return m_sqlStatement.hasContent();
}
-Utf8String SqlStatementBuilder::columnTypeToString(ColumnType columnType)
+Utils::SmallString SqlStatementBuilder::columnTypeToString(ColumnType columnType)
{
switch (columnType) {
- case ColumnType::Numeric: return Utf8StringLiteral("NUMERIC");
- case ColumnType::Integer: return Utf8StringLiteral("INTEGER");
- case ColumnType::Real: return Utf8StringLiteral("REAL");
- case ColumnType::Text: return Utf8StringLiteral("TEXT");
- case ColumnType::None: return Utf8String();
+ case ColumnType::Numeric: return "NUMERIC";
+ case ColumnType::Integer: return "INTEGER";
+ case ColumnType::Real: return "REAL";
+ case ColumnType::Text: return "TEXT";
+ case ColumnType::None: return {};
}
Q_UNREACHABLE();
@@ -164,70 +191,71 @@ Utf8String SqlStatementBuilder::columnTypeToString(ColumnType columnType)
void SqlStatementBuilder::generateSqlStatement() const
{
- sqlStatement_ = sqlTemplate;
+ m_sqlStatement = m_sqlTemplate;
sortBindings();
- auto bindingIterator = bindings.cbegin();
- while (bindingIterator != bindings.cend()) {
- const Utf8String &placeHolderToken = bindingIterator->first;
- const Utf8String &replacementToken = bindingIterator->second;
- sqlStatement_.replace(placeHolderToken, replacementToken);
- ++bindingIterator;
+ for (const auto &entry : m_bindings) {
+ const Utils::SmallStringView placeHolderToken = entry.first;
+ const Utils::SmallStringView replacementToken = entry.second;
+ m_sqlStatement.replace(placeHolderToken, replacementToken);
}
checkIfNoPlaceHoldersAynmoreExists();
}
-void SqlStatementBuilder::changeBinding(const Utf8String &name, const Utf8String &text)
+void SqlStatementBuilder::changeBinding(Utils::SmallString &&name, Utils::SmallString &&text)
{
-
- auto findBindingIterator = std::find_if(bindings.begin(), bindings.end(), [name] (const BindingPair &binding) {
+ auto findBindingIterator = std::find_if(m_bindings.begin(),
+ m_bindings.end(),
+ [&] (const BindingPair &binding) {
return binding.first == name;
});
- if (findBindingIterator == bindings.end())
- bindings.push_back(std::make_pair(name, text));
+ if (findBindingIterator == m_bindings.end())
+ m_bindings.push_back(std::make_pair(std::move(name), std::move(text)));
else
- findBindingIterator->second = text;
+ findBindingIterator->second = std::move(text);
}
void SqlStatementBuilder::clearSqlStatement()
{
- sqlStatement_.clear();
+ m_sqlStatement.clear();
}
-void SqlStatementBuilder::checkIfPlaceHolderExists(const Utf8String &name) const
+void SqlStatementBuilder::checkIfPlaceHolderExists(Utils::SmallStringView name) const
{
- if (name.byteSize() < 2 || !name.startsWith('$') || !sqlTemplate.contains(name))
- throwException("SqlStatementBuilder::bind: placeholder name does not exists!", name.constData());
+ if (name.size() < 2 || !name.startsWith('$') || !m_sqlTemplate.contains(name))
+ throwException("SqlStatementBuilder::bind: placeholder name does not exists!", name.data());
}
void SqlStatementBuilder::checkIfNoPlaceHoldersAynmoreExists() const
{
- if (sqlStatement_.contains('$'))
- throwException("SqlStatementBuilder::bind: there are still placeholder in the sql statement!", sqlTemplate.constData());
+ if (m_sqlStatement.contains('$'))
+ throwException("SqlStatementBuilder::bind: there are still placeholder in the sql statement!", m_sqlTemplate.constData());
}
-void SqlStatementBuilder::checkBindingTextIsNotEmpty(const Utf8String &text) const
+void SqlStatementBuilder::checkBindingTextIsNotEmpty(Utils::SmallStringView text) const
{
if (text.isEmpty())
- throwException("SqlStatementBuilder::bind: binding text it empty!", sqlTemplate.constData());
+ throwException("SqlStatementBuilder::bind: binding text it empty!", m_sqlTemplate.constData());
}
-void SqlStatementBuilder::checkBindingTextVectorIsNotEmpty(const Utf8StringVector &textVector) const
+void SqlStatementBuilder::checkBindingTextVectorIsNotEmpty(const Utils::SmallStringVector &textVector) const
{
- if (textVector.isEmpty())
- throwException("SqlStatementBuilder::bind: binding text vector it empty!", sqlTemplate.constData());
+ if (textVector.empty())
+ throwException("SqlStatementBuilder::bind: binding text vector it empty!", m_sqlTemplate.constData());
}
-void SqlStatementBuilder::checkBindingIntegerVectorIsNotEmpty(const QVector<int> &integerVector) const
+void SqlStatementBuilder::checkBindingIntegerVectorIsNotEmpty(const std::vector<int> &integerVector) const
{
- if (integerVector.isEmpty())
- throwException("SqlStatementBuilder::bind: binding integer vector it empty!", sqlTemplate.constData());
+ if (integerVector.empty())
+ throwException("SqlStatementBuilder::bind: binding integer vector it empty!", m_sqlTemplate.constData());
}
void SqlStatementBuilder::throwException(const char *whatHasHappened, const char *errorMessage)
{
throw SqlStatementBuilderException(whatHasHappened, errorMessage);
}
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlstatementbuilder.h b/src/libs/sqlite/sqlstatementbuilder.h
index 6bc092900e1..670455dc41a 100644
--- a/src/libs/sqlite/sqlstatementbuilder.h
+++ b/src/libs/sqlite/sqlstatementbuilder.h
@@ -25,54 +25,63 @@
#pragma once
-#include "utf8string.h"
+#include "sqliteglobal.h"
+
+#include <utils/smallstringvector.h>
#include <utility>
#include <vector>
+namespace Sqlite {
+
class SQLITE_EXPORT SqlStatementBuilder
{
- using BindingPair = std::pair<Utf8String, Utf8String>;
+ using BindingPair = std::pair<Utils::SmallString, Utils::SmallString>;
public:
- SqlStatementBuilder(const Utf8String &sqlTemplate);
-
- void bindEmptyText(const Utf8String &name);
- void bind(const Utf8String &name, const Utf8String &text);
- void bind(const Utf8String &name, const Utf8StringVector &textVector);
- void bind(const Utf8String &name, int value);
- void bind(const Utf8String &name, const QVector<int> &integerVector);
- void bindWithInsertTemplateParameters(const Utf8String &name, const Utf8StringVector &columns);
- void bindWithUpdateTemplateParameters(const Utf8String &name, const Utf8StringVector &columns);
- void bindWithUpdateTemplateNames(const Utf8String &name, const Utf8StringVector &columns);
+ SqlStatementBuilder(Utils::SmallStringView m_sqlTemplate);
+
+ void bindEmptyText(Utils::SmallString &&name);
+ void bind(Utils::SmallString &&name, Utils::SmallString &&text);
+ void bind(Utils::SmallString &&name, const Utils::SmallStringVector &textVector);
+ void bind(Utils::SmallString &&name, int value);
+ void bind(Utils::SmallString &&name, const std::vector<int> &integerVector);
+ void bindWithInsertTemplateParameters(Utils::SmallString &&name,
+ const Utils::SmallStringVector &columns);
+ void bindWithUpdateTemplateParameters(Utils::SmallString &&name,
+ const Utils::SmallStringVector &columns);
+ void bindWithUpdateTemplateNames(Utils::SmallString &&name,
+ const Utils::SmallStringVector &columns);
void clear();
- Utf8String sqlStatement() const;
+ Utils::SmallStringView sqlStatement() const;
bool isBuild() const;
- static Utf8String columnTypeToString(ColumnType columnType);
+ static Utils::SmallString columnTypeToString(ColumnType columnType);
protected:
- static const Utf8String insertTemplateParameters(const Utf8StringVector &columns);
- static const Utf8String updateTemplateParameters(const Utf8StringVector &columns);
- static const Utf8String updateTemplateNames(const Utf8StringVector &columns);
+ static Utils::SmallString insertTemplateParameters(const Utils::SmallStringVector &columns);
+ static Utils::SmallString updateTemplateParameters(const Utils::SmallStringVector &columns);
+ static Utils::SmallString updateTemplateNames(const Utils::SmallStringVector &columns);
void sortBindings() const;
void generateSqlStatement() const;
- void changeBinding(const Utf8String &name, const Utf8String &text);
+ void changeBinding(Utils::SmallString &&name, Utils::SmallString &&text);
void clearSqlStatement();
- void checkIfPlaceHolderExists(const Utf8String &name) const;
+ void checkIfPlaceHolderExists(Utils::SmallStringView name) const;
void checkIfNoPlaceHoldersAynmoreExists() const;
- void checkBindingTextIsNotEmpty(const Utf8String &text) const;
- void checkBindingTextVectorIsNotEmpty(const Utf8StringVector &textVector) const;
- void checkBindingIntegerVectorIsNotEmpty(const QVector<int> &integerVector) const;
+ void checkBindingTextIsNotEmpty(Utils::SmallStringView text) const;
+ void checkBindingTextVectorIsNotEmpty(const Utils::SmallStringVector &textVector) const;
+ void checkBindingIntegerVectorIsNotEmpty(const std::vector<int> &integerVector) const;
Q_NORETURN static void throwException(const char *whatHasHappened, const char *errorMessage);
private:
- Utf8String sqlTemplate;
- mutable Utf8String sqlStatement_;
- mutable std::vector<BindingPair> bindings;
+ Utils::BasicSmallString<510> m_sqlTemplate;
+ mutable Utils::BasicSmallString<510> m_sqlStatement;
+ mutable std::vector<BindingPair> m_bindings;
};
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlstatementbuilderexception.cpp b/src/libs/sqlite/sqlstatementbuilderexception.cpp
index dcd814987f8..82f5b4f7929 100644
--- a/src/libs/sqlite/sqlstatementbuilderexception.cpp
+++ b/src/libs/sqlite/sqlstatementbuilderexception.cpp
@@ -25,7 +25,10 @@
#include "sqlstatementbuilderexception.h"
-SqlStatementBuilderException::SqlStatementBuilderException(const char *whatErrorHasHappen, const char *errorMessage)
- : SqliteException(whatErrorHasHappen, errorMessage)
-{
-}
+namespace Sqlite {
+
+
+
+
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlstatementbuilderexception.h b/src/libs/sqlite/sqlstatementbuilderexception.h
index 17e215ad4f3..05d07c25a97 100644
--- a/src/libs/sqlite/sqlstatementbuilderexception.h
+++ b/src/libs/sqlite/sqlstatementbuilderexception.h
@@ -27,8 +27,12 @@
#include "sqliteexception.h"
-class SQLITE_EXPORT SqlStatementBuilderException : public SqliteException
+namespace Sqlite {
+
+class SQLITE_EXPORT SqlStatementBuilderException : public Exception
{
public:
- SqlStatementBuilderException(const char *whatErrorHasHappen, const char *errorMessage = 0);
+ using Exception::Exception;
};
+
+} // namespace Sqlite
diff --git a/src/libs/sqlite/tablewriteworker.cpp b/src/libs/sqlite/tablewriteworker.cpp
deleted file mode 100644
index ac84a43a5e4..00000000000
--- a/src/libs/sqlite/tablewriteworker.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "tablewriteworker.h"
-
-#include "createtablesqlstatementbuilder.h"
-#include "sqlitetransaction.h"
-#include "sqlitewritestatement.h"
-
-namespace Internal {
-
-TableWriteWorker::TableWriteWorker(QObject *parent)
- : QObject(parent)
-{
-
-}
-
-TableWriteWorker::~TableWriteWorker()
-{
-
-}
-
-void TableWriteWorker::createTable(const CreateTableCommand &command)
-{
- try {
- CreateTableSqlStatementBuilder createTableSqlStatementBuilder;
-
- createTableSqlStatementBuilder.setTable(command.tableName);
- createTableSqlStatementBuilder.setUseWithoutRowId(command.useWithoutRowId);
- createTableSqlStatementBuilder.setColumnDefinitions(command.definitions);
-
- SqliteImmediateTransaction transaction;
- SqliteWriteStatement::execute(createTableSqlStatementBuilder.sqlStatement());
- transaction.commit();
-
- emit tableCreated();
- } catch (const SqliteException &exception) {
- exception.printWarning();
- }
-}
-
-} // namespace Internal
-
diff --git a/src/libs/sqlite/tablewriteworkerproxy.cpp b/src/libs/sqlite/tablewriteworkerproxy.cpp
deleted file mode 100644
index a36463b0654..00000000000
--- a/src/libs/sqlite/tablewriteworkerproxy.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "tablewriteworkerproxy.h"
-
-#include "createtablecommand.h"
-#include "sqlitetable.h"
-#include "tablewriteworker.h"
-
-namespace Internal {
-
-TableWriteWorkerProxy::TableWriteWorkerProxy()
- : worker(new TableWriteWorker)
-{
-}
-
-TableWriteWorkerProxy::~TableWriteWorkerProxy()
-{
- delete worker;
-}
-
-void TableWriteWorkerProxy::connectWithWorker(SqliteTable *sqliterTable)
-{
- connect(this, &TableWriteWorkerProxy::createTable, worker, &TableWriteWorker::createTable);
- connect(worker, &TableWriteWorker::tableCreated, sqliterTable, &SqliteTable::handleTableCreated);
-}
-
-void TableWriteWorkerProxy::disconnectWithWorker(SqliteTable *sqliterTable)
-{
- disconnect(this, &TableWriteWorkerProxy::createTable, worker, &TableWriteWorker::createTable);
- disconnect(worker, &TableWriteWorker::tableCreated, sqliterTable, &SqliteTable::handleTableCreated);
-}
-
-void TableWriteWorkerProxy::moveWorkerToThread(QThread *workerThread)
-{
- worker->moveToThread(workerThread);
-}
-
-} // namespace Internal
-
diff --git a/src/libs/utils/images/dir.png b/src/libs/ssh/images/dir.png
index 57cec6bcd31..57cec6bcd31 100644
--- a/src/libs/utils/images/dir.png
+++ b/src/libs/ssh/images/dir.png
Binary files differ
diff --git a/src/libs/utils/images/help.png b/src/libs/ssh/images/help.png
index a12ef281d47..a12ef281d47 100644
--- a/src/libs/utils/images/help.png
+++ b/src/libs/ssh/images/help.png
Binary files differ
diff --git a/src/libs/utils/images/unknownfile.png b/src/libs/ssh/images/unknownfile.png
index 88f77592d1f..88f77592d1f 100644
--- a/src/libs/utils/images/unknownfile.png
+++ b/src/libs/ssh/images/unknownfile.png
Binary files differ
diff --git a/src/libs/ssh/sftpfilesystemmodel.cpp b/src/libs/ssh/sftpfilesystemmodel.cpp
index d3432c5528e..b1a173759c6 100644
--- a/src/libs/ssh/sftpfilesystemmodel.cpp
+++ b/src/libs/ssh/sftpfilesystemmodel.cpp
@@ -166,11 +166,11 @@ QVariant SftpFileSystemModel::data(const QModelIndex &index, int role) const
switch (node->fileInfo.type) {
case FileTypeRegular:
case FileTypeOther:
- return QIcon(":/utils/images/unknownfile.png");
+ return QIcon(":/ssh/images/unknownfile.png");
case FileTypeDirectory:
- return QIcon(":/utils/images/dir.png");
+ return QIcon(":/ssh/images/dir.png");
case FileTypeUnknown:
- return QIcon(":/utils/images/help.png"); // Shows a question mark.
+ return QIcon(":/ssh/images/help.png"); // Shows a question mark.
}
}
if (index.column() == 1) {
diff --git a/src/libs/ssh/ssh.pro b/src/libs/ssh/ssh.pro
index 27be1ec1876..499540ac72e 100644
--- a/src/libs/ssh/ssh.pro
+++ b/src/libs/ssh/ssh.pro
@@ -82,4 +82,6 @@ HEADERS = $$PWD/sshsendfacility_p.h \
FORMS = $$PWD/sshkeycreationdialog.ui
+RESOURCES += $$PWD/ssh.qrc
+
include(../3rdparty/botan/botan.pri)
diff --git a/src/libs/ssh/ssh.qbs b/src/libs/ssh/ssh.qbs
index 54dad5bf754..3aa95a16d53 100644
--- a/src/libs/ssh/ssh.qbs
+++ b/src/libs/ssh/ssh.qbs
@@ -22,6 +22,7 @@ Project {
"sftpoperation.cpp", "sftpoperation_p.h",
"sftpoutgoingpacket.cpp", "sftpoutgoingpacket_p.h",
"sftppacket.cpp", "sftppacket_p.h",
+ "ssh.qrc",
"sshagent.cpp", "sshagent_p.h",
"sshbotanconversions_p.h",
"sshcapabilities_p.h", "sshcapabilities.cpp",
diff --git a/src/libs/ssh/ssh.qrc b/src/libs/ssh/ssh.qrc
new file mode 100644
index 00000000000..4b0c6a8c51c
--- /dev/null
+++ b/src/libs/ssh/ssh.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/ssh">
+ <file>images/dir.png</file>
+ <file>images/help.png</file>
+ <file>images/unknownfile.png</file>
+ </qresource>
+</RCC>
diff --git a/src/libs/ssh/sshagent.cpp b/src/libs/ssh/sshagent.cpp
index 1ada40fcd14..4e581fac0a0 100644
--- a/src/libs/ssh/sshagent.cpp
+++ b/src/libs/ssh/sshagent.cpp
@@ -57,7 +57,7 @@ void SshAgent::refreshKeysImpl()
if (state() != Connected)
return;
const auto keysRequestIt = std::find_if(m_pendingRequests.constBegin(),
- m_pendingRequests.constEnd(), [this](const Request &r) { return r.isKeysRequest(); });
+ m_pendingRequests.constEnd(), [](const Request &r) { return r.isKeysRequest(); });
if (keysRequestIt != m_pendingRequests.constEnd()) {
qCDebug(sshLog) << "keys request already pending, not adding another one";
return;
diff --git a/src/libs/ssh/sshagent_p.h b/src/libs/ssh/sshagent_p.h
index 346d9aab9d0..f30867b9343 100644
--- a/src/libs/ssh/sshagent_p.h
+++ b/src/libs/ssh/sshagent_p.h
@@ -76,7 +76,7 @@ private:
QByteArray key;
QByteArray dataToSign;
- uint token;
+ uint token = 0;
};
struct Packet {
diff --git a/src/libs/ssh/sshexception_p.h b/src/libs/ssh/sshexception_p.h
index b51ce4b04c8..94697df19ed 100644
--- a/src/libs/ssh/sshexception_p.h
+++ b/src/libs/ssh/sshexception_p.h
@@ -31,6 +31,8 @@
#include <QCoreApplication>
#include <QString>
+#include <exception>
+
namespace QSsh {
namespace Internal {
@@ -57,25 +59,28 @@ enum SshErrorCode {
#define SSH_SERVER_EXCEPTION(error, errorString) \
SshServerException((error), (errorString), SSH_TR(errorString))
-struct SshServerException
+struct SshServerException : public std::exception
{
SshServerException(SshErrorCode error, const QByteArray &errorStringServer,
const QString &errorStringUser)
: error(error), errorStringServer(errorStringServer),
errorStringUser(errorStringUser) {}
+ const char *what() const noexcept override { return errorStringServer.constData(); }
const SshErrorCode error;
const QByteArray errorStringServer;
const QString errorStringUser;
};
-struct SshClientException
+struct SshClientException : public std::exception
{
SshClientException(SshError error, const QString &errorString)
- : error(error), errorString(errorString) {}
+ : error(error), errorString(errorString), errorStringPrintable(errorString.toLocal8Bit()) {}
+ const char *what() const noexcept override { return errorStringPrintable.constData(); }
const SshError error;
const QString errorString;
+ const QByteArray errorStringPrintable;
};
} // namespace Internal
diff --git a/src/libs/timeline/qml/MainView.qml b/src/libs/timeline/qml/MainView.qml
index e6aa2bb15e6..2c0aa1258e5 100644
--- a/src/libs/timeline/qml/MainView.qml
+++ b/src/libs/timeline/qml/MainView.qml
@@ -36,7 +36,6 @@ Rectangle {
property bool lockItemSelection : false
- signal updateCursorPosition
property string fileName: ""
property int lineNumber: -1
property int columnNumber: 0
@@ -242,7 +241,7 @@ Rectangle {
var newTypeId = model.typeId(selectedItem);
if (newTypeId !== typeId) {
typeId = newTypeId;
- root.updateCursorPosition();
+ timelineModelAggregator.updateCursorPosition();
}
} else {
selectedModel = -1;
diff --git a/src/libs/timeline/qml/lock_closed@2x.png b/src/libs/timeline/qml/lock_closed@2x.png
deleted file mode 100644
index 99bb0fc85da..00000000000
--- a/src/libs/timeline/qml/lock_closed@2x.png
+++ /dev/null
Binary files differ
diff --git a/src/libs/timeline/qml/lock_open@2x.png b/src/libs/timeline/qml/lock_open@2x.png
deleted file mode 100644
index b84580cb244..00000000000
--- a/src/libs/timeline/qml/lock_open@2x.png
+++ /dev/null
Binary files differ
diff --git a/src/libs/timeline/timelinemodelaggregator.h b/src/libs/timeline/timelinemodelaggregator.h
index fb0e5a1162c..b0173543303 100644
--- a/src/libs/timeline/timelinemodelaggregator.h
+++ b/src/libs/timeline/timelinemodelaggregator.h
@@ -61,6 +61,7 @@ public:
signals:
void modelsChanged();
void heightChanged();
+ void updateCursorPosition();
private:
class TimelineModelAggregatorPrivate;
diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp
index abe01ada6e1..29c531e1cc5 100644
--- a/src/libs/utils/basetreeview.cpp
+++ b/src/libs/utils/basetreeview.cpp
@@ -355,7 +355,7 @@ void BaseTreeView::showEvent(QShowEvent *ev)
void BaseTreeView::showProgressIndicator()
{
if (!d->m_progressIndicator) {
- d->m_progressIndicator = new ProgressIndicator(ProgressIndicator::Large);
+ d->m_progressIndicator = new ProgressIndicator(ProgressIndicatorSize::Large);
d->m_progressIndicator->attachToWidget(this);
}
d->m_progressIndicator->show();
diff --git a/src/libs/utils/camelhumpmatcher.cpp b/src/libs/utils/camelhumpmatcher.cpp
new file mode 100644
index 00000000000..0661499c7a3
--- /dev/null
+++ b/src/libs/utils/camelhumpmatcher.cpp
@@ -0,0 +1,143 @@
+/**************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2017 BlackBerry Limited <qt@blackberry.com>
+** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "camelhumpmatcher.h"
+
+#include <QRegularExpression>
+#include <QString>
+
+/**
+ * \brief Creates a regexp that represents a specified camel hump pattern,
+ * underscores are not included.
+ *
+ * \param pattern the camel hump pattern
+ * \param caseSensitivity case sensitivity used for camel hump matching;
+ * does not affect wildcard style matching
+ * \return the regexp
+ */
+QRegularExpression CamelHumpMatcher::createCamelHumpRegExp(
+ const QString &pattern, CamelHumpMatcher::CaseSensitivity caseSensitivity)
+{
+ if (pattern.isEmpty())
+ return QRegularExpression();
+
+ /*
+ * This code builds a regular expression in order to more intelligently match
+ * camel-case and underscore names.
+ *
+ * For any but the first letter, the following replacements are made:
+ * A => [a-z0-9_]*A
+ * a => (?:[a-zA-Z0-9]*_)?a
+ *
+ * That means any sequence of lower-case or underscore characters can preceed an
+ * upper-case character. And any sequence of lower-case or upper case characters -
+ * followed by an underscore can preceed a lower-case character.
+ *
+ * Examples: (case sensitive mode)
+ * gAC matches getActionController
+ * gac matches get_action_controller
+ *
+ * It also implements the fully and first-letter-only case sensitivity.
+ */
+
+ QString keyRegExp;
+ bool first = true;
+ const QChar asterisk = '*';
+ const QChar question = '?';
+ const QLatin1String uppercaseWordFirst("(?<=\\b|[a-z0-9_])");
+ const QLatin1String lowercaseWordFirst("(?<=\\b|[A-Z0-9_])");
+ const QLatin1String uppercaseWordContinuation("[a-z0-9_]*");
+ const QLatin1String lowercaseWordContinuation("(?:[a-zA-Z0-9]*_)?");
+ const QLatin1String upperSnakeWordContinuation("[A-Z0-9]*_");
+ for (const QChar &c : pattern) {
+ if (!c.isLetter()) {
+ if (c == question)
+ keyRegExp += '.';
+ else if (c == asterisk)
+ keyRegExp += ".*";
+ else
+ keyRegExp += '(' + QRegularExpression::escape(c) + ')';
+ } else if (caseSensitivity == CaseSensitivity::CaseInsensitive ||
+ (caseSensitivity == CaseSensitivity::FirstLetterCaseSensitive && !first)) {
+
+ keyRegExp += "(?:";
+ keyRegExp += first ? uppercaseWordFirst : uppercaseWordContinuation;
+ keyRegExp += '(' + QRegularExpression::escape(c.toUpper());
+ if (first) {
+ keyRegExp += '|' + lowercaseWordFirst + QRegularExpression::escape(c.toLower()) + ')';
+ } else {
+ keyRegExp += ")|" + lowercaseWordContinuation;
+ keyRegExp += '(' + QRegularExpression::escape(c.toLower()) + ")|";
+ keyRegExp += upperSnakeWordContinuation;
+ keyRegExp += '(' + QRegularExpression::escape(c.toUpper()) + ')';
+ }
+ keyRegExp += ')';
+ } else {
+ if (!first) {
+ if (c.isUpper())
+ keyRegExp += uppercaseWordContinuation;
+ else
+ keyRegExp += lowercaseWordContinuation;
+ }
+ keyRegExp += QRegularExpression::escape(c);
+ }
+
+ first = false;
+ }
+ return QRegularExpression(keyRegExp);
+}
+
+/*!
+ * \brief Returns a list of matched character positions and their matched lengths for the
+ * given regular expression \a match.
+ *
+ * The list is minimized by combining adjacent highlighting positions to a single position.
+ */
+CamelHumpMatcher::HighlightingPositions CamelHumpMatcher::highlightingPositions(
+ const QRegularExpressionMatch &match)
+{
+ HighlightingPositions result;
+
+ for (int i = 1, size = match.capturedTexts().size(); i < size; ++i) {
+ // skip unused positions, they can appear because upper- and lowercase
+ // checks for one character are done using two capture groups
+ if (match.capturedStart(i) < 0)
+ continue;
+
+ // check for possible highlighting continuation to keep the list minimal
+ if (!result.starts.isEmpty()
+ && (result.starts.last() + result.lengths.last() == match.capturedStart(i))) {
+ result.lengths.last() += match.capturedLength(i);
+ } else {
+ // no continuation, append as different chunk
+ result.starts.append(match.capturedStart(i));
+ result.lengths.append(match.capturedLength(i));
+ }
+ }
+
+ return result;
+}
diff --git a/src/libs/sqlite/tablewriteworkerproxy.h b/src/libs/utils/camelhumpmatcher.h
index 0bf481e69d6..8021c4ddf68 100644
--- a/src/libs/sqlite/tablewriteworkerproxy.h
+++ b/src/libs/utils/camelhumpmatcher.h
@@ -1,6 +1,8 @@
-/****************************************************************************
+/**************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2017 BlackBerry Limited <qt@blackberry.com>
+** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de>
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,39 +27,32 @@
#pragma once
-#include "createtablecommand.h"
+#include "utils_global.h"
-#include <QObject>
-
-#include <memory>
+#include <QVector>
QT_BEGIN_NAMESPACE
-class QThread;
+class QRegularExpression;
+class QRegularExpressionMatch;
+class QString;
QT_END_NAMESPACE
-class SqliteTable;
-
-namespace Internal {
-
-class TableWriteWorker;
-
-class TableWriteWorkerProxy : public QObject
+class QTCREATOR_UTILS_EXPORT CamelHumpMatcher
{
- Q_OBJECT
public:
- explicit TableWriteWorkerProxy();
- ~TableWriteWorkerProxy();
-
- void connectWithWorker(SqliteTable *sqliterTable);
- void disconnectWithWorker(SqliteTable *sqliterTable);
-
- void moveWorkerToThread(QThread *workerThread);
-
-signals:
- void createTable(const CreateTableCommand &command);
-
-private:
- TableWriteWorker *worker;
+ enum class CaseSensitivity {
+ CaseInsensitive,
+ CaseSensitive,
+ FirstLetterCaseSensitive
+ };
+
+ class HighlightingPositions {
+ public:
+ QVector<int> starts;
+ QVector<int> lengths;
+ };
+
+ static QRegularExpression createCamelHumpRegExp(const QString &pattern,
+ CaseSensitivity caseSensitivity = CaseSensitivity::CaseInsensitive);
+ static HighlightingPositions highlightingPositions(const QRegularExpressionMatch &match);
};
-
-} // namespace Internal
diff --git a/src/libs/utils/environment.cpp b/src/libs/utils/environment.cpp
index 60bf3ae4cc1..0d312d8b8db 100644
--- a/src/libs/utils/environment.cpp
+++ b/src/libs/utils/environment.cpp
@@ -57,6 +57,31 @@ public:
Q_GLOBAL_STATIC(SystemEnvironment, staticSystemEnvironment)
+static QMap<QString, QString>::iterator findKey(QMap<QString, QString> &input, Utils::OsType osType,
+ const QString &key)
+{
+ const Qt::CaseSensitivity casing
+ = (osType == Utils::OsTypeWindows) ? Qt::CaseInsensitive : Qt::CaseSensitive;
+ for (auto it = input.begin(); it != input.end(); ++it) {
+ if (key.compare(it.key(), casing) == 0)
+ return it;
+ }
+ return input.end();
+}
+
+static QMap<QString, QString>::const_iterator findKey(const QMap<QString, QString> &input,
+ Utils::OsType osType,
+ const QString &key)
+{
+ const Qt::CaseSensitivity casing
+ = (osType == Utils::OsTypeWindows) ? Qt::CaseInsensitive : Qt::CaseSensitive;
+ for (auto it = input.constBegin(); it != input.constEnd(); ++it) {
+ if (key.compare(it.key(), casing) == 0)
+ return it;
+ }
+ return input.constEnd();
+}
+
namespace Utils {
enum : char
@@ -88,14 +113,11 @@ QList<EnvironmentItem> EnvironmentItem::fromStringList(const QStringList &list)
QStringList EnvironmentItem::toStringList(const QList<EnvironmentItem> &list)
{
- QStringList result;
- for (const EnvironmentItem &item : list) {
+ return Utils::transform(list, [](const EnvironmentItem &item) {
if (item.operation == EnvironmentItem::Unset)
- result << QString(item.name);
- else
- result << QString(item.name + '=' + item.value);
- }
- return result;
+ return QString(item.name);
+ return QString(item.name + '=' + item.value);
+ });
}
static QString expand(const Environment *e, QString value)
@@ -207,10 +229,9 @@ Environment::Environment(const QStringList &env, OsType osType) : m_osType(osTyp
for (const QString &s : env) {
int i = s.indexOf('=', 1);
if (i >= 0) {
- if (m_osType == OsTypeWindows)
- m_values.insert(s.left(i).toUpper(), s.mid(i+1));
- else
- m_values.insert(s.left(i), s.mid(i+1));
+ const QString key = s.left(i);
+ const QString value = s.mid(i + 1);
+ set(key, value);
}
}
}
@@ -218,41 +239,40 @@ Environment::Environment(const QStringList &env, OsType osType) : m_osType(osTyp
QStringList Environment::toStringList() const
{
QStringList result;
- const QMap<QString, QString>::const_iterator end = m_values.constEnd();
- for (QMap<QString, QString>::const_iterator it = m_values.constBegin(); it != end; ++it) {
- QString entry = it.key();
- entry += '=';
- entry += it.value();
- result.push_back(entry);
- }
+ for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it)
+ result.append(it.key() + '=' + it.value());
return result;
}
QProcessEnvironment Environment::toProcessEnvironment() const
{
QProcessEnvironment result;
- const QMap<QString, QString>::const_iterator end = m_values.constEnd();
- for (QMap<QString, QString>::const_iterator it = m_values.constBegin(); it != end; ++it)
+ for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it)
result.insert(it.key(), it.value());
return result;
}
void Environment::set(const QString &key, const QString &value)
{
- m_values.insert(m_osType == OsTypeWindows ? key.toUpper() : key, value);
+ auto it = findKey(m_values, m_osType, key);
+ if (it == m_values.end())
+ m_values.insert(key, value);
+ else
+ it.value() = value;
}
void Environment::unset(const QString &key)
{
- m_values.remove(m_osType == OsTypeWindows ? key.toUpper() : key);
+ auto it = findKey(m_values, m_osType, key);
+ if (it != m_values.end())
+ m_values.erase(it);
}
void Environment::appendOrSet(const QString &key, const QString &value, const QString &sep)
{
- const QString &_key = m_osType == OsTypeWindows ? key.toUpper() : key;
- QMap<QString, QString>::iterator it = m_values.find(_key);
+ auto it = findKey(m_values, m_osType, key);
if (it == m_values.end()) {
- m_values.insert(_key, value);
+ m_values.insert(key, value);
} else {
// Append unless it is already there
const QString toAppend = sep + value;
@@ -263,10 +283,9 @@ void Environment::appendOrSet(const QString &key, const QString &value, const QS
void Environment::prependOrSet(const QString&key, const QString &value, const QString &sep)
{
- const QString &_key = m_osType == OsTypeWindows ? key.toUpper() : key;
- QMap<QString, QString>::iterator it = m_values.find(_key);
+ auto it = findKey(m_values, m_osType, key);
if (it == m_values.end()) {
- m_values.insert(_key, value);
+ m_values.insert(key, value);
} else {
// Prepend unless it is already there
const QString toPrepend = value + sep;
@@ -278,7 +297,7 @@ void Environment::prependOrSet(const QString&key, const QString &value, const QS
void Environment::appendOrSetPath(const QString &value)
{
appendOrSet("PATH", QDir::toNativeSeparators(value),
- QString(OsSpecificAspects(m_osType).pathListSeparator()));
+ QString(OsSpecificAspects(m_osType).pathListSeparator()));
}
void Environment::prependOrSetPath(const QString &value)
@@ -563,7 +582,7 @@ QString Environment::expandVariables(const QString &input) const
for (int vStart = -1, i = 0; i < result.length(); ) {
if (result.at(i++) == '%') {
if (vStart > 0) {
- const_iterator it = m_values.constFind(result.mid(vStart, i - vStart - 1).toUpper());
+ const_iterator it = findKey(m_values, m_osType, result.mid(vStart, i - vStart - 1));
if (it != m_values.constEnd()) {
result.replace(vStart - 1, i - vStart + 1, *it);
i = vStart - 1 + it->length();
diff --git a/src/libs/utils/fancylineedit.cpp b/src/libs/utils/fancylineedit.cpp
index 20a26733527..17455f45f17 100644
--- a/src/libs/utils/fancylineedit.cpp
+++ b/src/libs/utils/fancylineedit.cpp
@@ -38,6 +38,7 @@
#include <QStylePainter>
#include <QPropertyAnimation>
#include <QStyle>
+#include <QWindow>
/*!
\class Utils::FancyLineEdit
@@ -91,7 +92,6 @@ public:
HistoryCompleter *m_historyCompleter = 0;
FancyLineEdit::ValidationFunction m_validationFunction = &FancyLineEdit::validateWithValidator;
QString m_oldText;
- QPixmap m_pixmap[2];
QMenu *m_menu[2];
FancyLineEdit::State m_state = FancyLineEdit::Invalid;
bool m_menuTabFocusTrigger[2];
@@ -256,17 +256,17 @@ void FancyLineEdit::resizeEvent(QResizeEvent *)
updateButtonPositions();
}
-void FancyLineEdit::setButtonPixmap(Side side, const QPixmap &buttonPixmap)
+void FancyLineEdit::setButtonIcon(Side side, const QIcon &icon)
{
- d->m_iconbutton[side]->setPixmap(buttonPixmap);
+ d->m_iconbutton[side]->setIcon(icon);
updateMargins();
updateButtonPositions();
update();
}
-QPixmap FancyLineEdit::buttonPixmap(Side side) const
+QIcon FancyLineEdit::buttonIcon(Side side) const
{
- return d->m_pixmap[side];
+ return d->m_iconbutton[side]->icon();
}
void FancyLineEdit::setButtonMenu(Side side, QMenu *buttonMenu)
@@ -360,9 +360,9 @@ void FancyLineEdit::setFiltering(bool on)
QLatin1String("edit-clear-locationbar-rtl") :
QLatin1String("edit-clear-locationbar-ltr"),
QIcon::fromTheme(QLatin1String("edit-clear"),
- Icons::EDIT_CLEAR.pixmap()));
+ Icons::EDIT_CLEAR.icon()));
- setButtonPixmap(Right, icon.pixmap(16));
+ setButtonIcon(Right, icon);
setButtonVisible(Right, true);
setPlaceholderText(tr("Filter"));
setButtonToolTip(Right, tr("Clear text"));
@@ -517,15 +517,16 @@ IconButton::IconButton(QWidget *parent)
void IconButton::paintEvent(QPaintEvent *)
{
- const qreal pixmapRatio = m_pixmap.devicePixelRatio();
+ QWindow *window = this->window()->windowHandle();
+ const QPixmap iconPixmap = icon().pixmap(window, sizeHint());
QStylePainter painter(this);
- QRect pixmapRect = QRect(0, 0, m_pixmap.width()/pixmapRatio, m_pixmap.height()/pixmapRatio);
+ QRect pixmapRect(QPoint(), iconPixmap.size() / window->devicePixelRatio());
pixmapRect.moveCenter(rect().center());
if (m_autoHide)
painter.setOpacity(m_iconOpacity);
- painter.drawPixmap(pixmapRect, m_pixmap);
+ painter.drawPixmap(pixmapRect, iconPixmap);
if (hasFocus()) {
QStyleOptionFocusRect focusOption;
@@ -550,8 +551,8 @@ void IconButton::animateShow(bool visible)
QSize IconButton::sizeHint() const
{
- const qreal pixmapRatio = m_pixmap.devicePixelRatio();
- return QSize(m_pixmap.width()/pixmapRatio, m_pixmap.height()/pixmapRatio);
+ QWindow *window = this->window()->windowHandle();
+ return icon().actualSize(window, QSize(32, 16)); // Find flags icon can be wider than 16px
}
void IconButton::keyPressEvent(QKeyEvent *ke)
diff --git a/src/libs/utils/fancylineedit.h b/src/libs/utils/fancylineedit.h
index 9df78961bb0..ba3918ab8f5 100644
--- a/src/libs/utils/fancylineedit.h
+++ b/src/libs/utils/fancylineedit.h
@@ -45,12 +45,9 @@ class QTCREATOR_UTILS_EXPORT IconButton: public QAbstractButton
Q_OBJECT
Q_PROPERTY(float iconOpacity READ iconOpacity WRITE setIconOpacity)
Q_PROPERTY(bool autoHide READ hasAutoHide WRITE setAutoHide)
- Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
public:
explicit IconButton(QWidget *parent = 0);
void paintEvent(QPaintEvent *event);
- void setPixmap(const QPixmap &pixmap) { m_pixmap = pixmap; update(); }
- QPixmap pixmap() const { return m_pixmap; }
float iconOpacity() { return m_iconOpacity; }
void setIconOpacity(float value) { m_iconOpacity = value; update(); }
void animateShow(bool visible);
@@ -67,7 +64,7 @@ protected:
private:
float m_iconOpacity;
bool m_autoHide;
- QPixmap m_pixmap;
+ QIcon m_icon;
};
class QTCREATOR_UTILS_EXPORT FancyLineEdit : public CompletingLineEdit
@@ -86,8 +83,8 @@ public:
explicit FancyLineEdit(QWidget *parent = 0);
~FancyLineEdit();
- QPixmap buttonPixmap(Side side) const;
- void setButtonPixmap(Side side, const QPixmap &pixmap);
+ QIcon buttonIcon(Side side) const;
+ void setButtonIcon(Side side, const QIcon &icon);
QMenu *buttonMenu(Side side) const;
void setButtonMenu(Side side, QMenu *menu);
diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp
index 338ae657d8b..160d1b9deaa 100644
--- a/src/libs/utils/fileutils.cpp
+++ b/src/libs/utils/fileutils.cpp
@@ -238,7 +238,7 @@ FileName FileUtils::resolveSymlinks(const FileName &path)
*/
FileName FileUtils::canonicalPath(const FileName &path)
{
- const QString result = QFileInfo(path.toString()).canonicalFilePath();
+ const QString result = path.toFileInfo().canonicalFilePath();
if (result.isEmpty())
return path;
return FileName::fromString(result);
@@ -592,7 +592,6 @@ QString FileName::fileName(int pathComponents) const
if (pathComponents < 0)
return *this;
const QChar slash = QLatin1Char('/');
- QTC_CHECK(!endsWith(slash));
int i = lastIndexOf(slash);
if (pathComponents == 0 || i == -1)
return mid(i + 1);
diff --git a/src/libs/utils/highlightingitemdelegate.cpp b/src/libs/utils/highlightingitemdelegate.cpp
index fe2525122c8..c9bb43eb948 100644
--- a/src/libs/utils/highlightingitemdelegate.cpp
+++ b/src/libs/utils/highlightingitemdelegate.cpp
@@ -155,28 +155,37 @@ void HighlightingItemDelegate::drawText(QPainter *painter,
if (index.model()->hasChildren(index))
text += " (" + QString::number(index.model()->rowCount(index)) + ')';
- int searchTermStart = index.model()->data(index, int(HighlightingItemRole::StartColumn)).toInt();
- int searchTermLength = index.model()->data(index, int(HighlightingItemRole::Length)).toInt();
- if (searchTermStart < 0 || searchTermStart >= text.length() || searchTermLength < 1) {
+ QVector<int> searchTermStarts =
+ index.model()->data(index, int(HighlightingItemRole::StartColumn)).value<QVector<int>>();
+ QVector<int> searchTermLengths =
+ index.model()->data(index, int(HighlightingItemRole::Length)).value<QVector<int>>();
+
+ if (searchTermStarts.isEmpty()) {
drawDisplay(painter, option, rect, text.replace('\t', m_tabString), {});
return;
}
// replace tabs with searchTerm bookkeeping
- int searchTermEnd = searchTermStart + searchTermLength;
const int tabDiff = m_tabString.size() - 1;
for (int i = 0; i < text.length(); i++) {
- if (text.at(i) == '\t') {
- text.replace(i, 1, m_tabString);
- if (i < searchTermStart) {
- searchTermStart += tabDiff;
- searchTermEnd += tabDiff;
- } else if (i < searchTermEnd) {
- searchTermEnd += tabDiff;
- searchTermLength += tabDiff;
- }
- i += tabDiff;
+ if (text.at(i) != '\t')
+ continue;
+
+ text.replace(i, 1, m_tabString);
+
+ // adjust highlighting length if tab is highlighted
+ for (int j = 0; j < searchTermStarts.size(); ++j) {
+ if (i >= searchTermStarts.at(j) && i < searchTermStarts.at(j) + searchTermLengths.at(j))
+ searchTermLengths[j] += tabDiff;
}
+
+ // adjust all following highlighting starts
+ for (int j = 0; j < searchTermStarts.size(); ++j) {
+ if (searchTermStarts.at(j) > i)
+ searchTermStarts[j] += tabDiff;
+ }
+
+ i += tabDiff;
}
const QColor highlightForeground =
@@ -187,7 +196,11 @@ void HighlightingItemDelegate::drawText(QPainter *painter,
highlightFormat.setForeground(highlightForeground);
highlightFormat.setBackground(highlightBackground);
- drawDisplay(painter, option, rect, text, {{searchTermStart, searchTermLength, highlightFormat}});
+ QVector<QTextLayout::FormatRange> formats;
+ for (int i = 0, size = searchTermStarts.size(); i < size; ++i)
+ formats.append({searchTermStarts.at(i), searchTermLengths.at(i), highlightFormat});
+
+ drawDisplay(painter, option, rect, text, formats);
}
// copied from QItemDelegate for drawDisplay
diff --git a/src/libs/utils/images/empty16.png b/src/libs/utils/images/empty16.png
new file mode 100644
index 00000000000..4d7beb80658
--- /dev/null
+++ b/src/libs/utils/images/empty16.png
Binary files differ
diff --git a/src/libs/utils/images/magnifier.png b/src/libs/utils/images/magnifier.png
index 6a7af805b84..692a32d9a36 100644
--- a/src/libs/utils/images/magnifier.png
+++ b/src/libs/utils/images/magnifier.png
Binary files differ
diff --git a/src/libs/utils/images/magnifier@2x.png b/src/libs/utils/images/magnifier@2x.png
index f6fce89a3c3..60f93e10cb1 100644
--- a/src/libs/utils/images/magnifier@2x.png
+++ b/src/libs/utils/images/magnifier@2x.png
Binary files differ
diff --git a/src/libs/utils/optional.h b/src/libs/utils/optional.h
index 1960297de43..e4f943259f7 100644
--- a/src/libs/utils/optional.h
+++ b/src/libs/utils/optional.h
@@ -41,6 +41,8 @@ namespace Utils {
using std::experimental::optional;
// --> Utils::nullopt
using std::experimental::nullopt;
+// --> Utils::in_place
+using std::experimental::in_place;
// TODO: make_optional is a copy, since there is no sensible way to import functions in C++
template <class T>
diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp
index a5f9688acee..ee5165e70af 100644
--- a/src/libs/utils/pathchooser.cpp
+++ b/src/libs/utils/pathchooser.cpp
@@ -51,11 +51,11 @@
static QString appBundleExpandedPath(const QString &path)
{
- if (Utils::HostOsInfo::hostOs() == Utils::OsTypeMac && path.endsWith(QLatin1String(".app"))) {
+ if (Utils::HostOsInfo::hostOs() == Utils::OsTypeMac && path.endsWith(".app")) {
// possibly expand to Foo.app/Contents/MacOS/Foo
QFileInfo info(path);
if (info.isDir()) {
- QString exePath = path + QLatin1String("/Contents/MacOS/") + info.completeBaseName();
+ QString exePath = path + "/Contents/MacOS/" + info.completeBaseName();
if (QFileInfo::exists(exePath))
return exePath;
}
@@ -110,16 +110,16 @@ bool BinaryVersionToolTipEventFilter::eventFilter(QObject *o, QEvent *e)
const QString version = BinaryVersionToolTipEventFilter::toolVersion(QDir::cleanPath(binary), m_arguments);
if (!version.isEmpty()) {
// Concatenate tooltips.
- QString tooltip = QLatin1String("<html><head/><body>");
+ QString tooltip = "<html><head/><body>";
const QString defaultValue = defaultToolTip();
if (!defaultValue.isEmpty()) {
- tooltip += QLatin1String("<p>");
+ tooltip += "<p>";
tooltip += defaultValue;
- tooltip += QLatin1String("</p>");
+ tooltip += "</p>";
}
- tooltip += QLatin1String("<pre>");
+ tooltip += "<pre>";
tooltip += version;
- tooltip += QLatin1String("</pre><body></html>");
+ tooltip += "</pre><body></html>";
le->setToolTip(tooltip);
}
}
@@ -150,7 +150,7 @@ private:
virtual QString defaultToolTip() const
{ return m_pathChooser->errorMessage(); }
- const PathChooser *m_pathChooser;
+ const PathChooser *m_pathChooser = nullptr;
};
// ------------------ PathChooserPrivate
@@ -162,8 +162,8 @@ public:
QString expandedPath(const QString &path) const;
- QHBoxLayout *m_hLayout;
- FancyLineEdit *m_lineEdit;
+ QHBoxLayout *m_hLayout = nullptr;
+ FancyLineEdit *m_lineEdit = nullptr;
PathChooser::Kind m_acceptingKind;
QString m_dialogTitleOverride;
@@ -171,15 +171,14 @@ public:
QString m_initialBrowsePathOverride;
QString m_baseDirectory;
Environment m_environment;
- BinaryVersionToolTipEventFilter *m_binaryVersionToolTipEventFilter;
+ BinaryVersionToolTipEventFilter *m_binaryVersionToolTipEventFilter = nullptr;
QList<QAbstractButton *> m_buttons;
};
PathChooserPrivate::PathChooserPrivate() :
m_hLayout(new QHBoxLayout),
m_lineEdit(new FancyLineEdit),
- m_acceptingKind(PathChooser::ExistingDirectory),
- m_binaryVersionToolTipEventFilter(0)
+ m_acceptingKind(PathChooser::ExistingDirectory)
{
}
@@ -194,7 +193,7 @@ QString PathChooserPrivate::expandedPath(const QString &input) const
switch (m_acceptingKind) {
case PathChooser::Command:
case PathChooser::ExistingCommand: {
- const FileName expanded = m_environment.searchInPath(path, QStringList(m_baseDirectory));
+ const FileName expanded = m_environment.searchInPath(path, {m_baseDirectory});
return expanded.isEmpty() ? path : expanded.toString();
}
case PathChooser::Any:
@@ -204,7 +203,7 @@ QString PathChooserPrivate::expandedPath(const QString &input) const
case PathChooser::File:
case PathChooser::SaveFile:
if (!m_baseDirectory.isEmpty() && QFileInfo(path).isRelative())
- return QFileInfo(m_baseDirectory + QLatin1Char('/') + path).absoluteFilePath();
+ return QFileInfo(m_baseDirectory + '/' + path).absoluteFilePath();
break;
}
return path;
@@ -337,7 +336,7 @@ QString PathChooser::expandedDirectory(const QString &input, const Environment &
if (path.isEmpty())
return path;
if (!baseDir.isEmpty() && QFileInfo(path).isRelative())
- return QFileInfo(baseDir + QLatin1Char('/') + path).absoluteFilePath();
+ return QFileInfo(baseDir + '/' + path).absoluteFilePath();
return path;
}
@@ -369,7 +368,8 @@ bool PathChooser::isReadOnly() const
void PathChooser::setReadOnly(bool b)
{
d->m_lineEdit->setReadOnly(b);
- foreach (QAbstractButton *button, d->m_buttons)
+ const auto buttons = d->m_buttons;
+ for (QAbstractButton *button : buttons)
button->setEnabled(!b);
}
@@ -663,7 +663,7 @@ FancyLineEdit *PathChooser::lineEdit() const
{
// HACK: Make it work with HistoryCompleter.
if (d->m_lineEdit->objectName().isEmpty())
- d->m_lineEdit->setObjectName(objectName() + QLatin1String("LineEdit"));
+ d->m_lineEdit->setObjectName(objectName() + "LineEdit");
return d->m_lineEdit;
}
@@ -695,7 +695,7 @@ void PathChooser::setCommandVersionArguments(const QStringList &arguments)
if (arguments.isEmpty()) {
if (d->m_binaryVersionToolTipEventFilter) {
delete d->m_binaryVersionToolTipEventFilter;
- d->m_binaryVersionToolTipEventFilter = 0;
+ d->m_binaryVersionToolTipEventFilter = nullptr;
}
} else {
if (!d->m_binaryVersionToolTipEventFilter)
diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h
index 17b572310df..94f4a19b49f 100644
--- a/src/libs/utils/pathchooser.h
+++ b/src/libs/utils/pathchooser.h
@@ -62,7 +62,7 @@ class QTCREATOR_UTILS_EXPORT PathChooser : public QWidget
public:
static QString browseButtonLabel();
- explicit PathChooser(QWidget *parent = 0);
+ explicit PathChooser(QWidget *parent = nullptr);
virtual ~PathChooser();
enum Kind {
@@ -172,7 +172,7 @@ public slots:
void setOkColor(const QColor &okColor);
private:
- PathChooserPrivate *d;
+ PathChooserPrivate *d = nullptr;
static AboutToShowContextMenuHandler s_aboutToShowContextMenuHandler;
};
diff --git a/src/libs/utils/persistentsettings.h b/src/libs/utils/persistentsettings.h
index 4fba07ae611..3ea7fac904f 100644
--- a/src/libs/utils/persistentsettings.h
+++ b/src/libs/utils/persistentsettings.h
@@ -26,6 +26,7 @@
#pragma once
#include "fileutils.h"
+#include "utils_global.h"
#include <QVariant>
diff --git a/src/libs/utils/progressindicator.cpp b/src/libs/utils/progressindicator.cpp
index 009d57c009d..4efd9871372 100644
--- a/src/libs/utils/progressindicator.cpp
+++ b/src/libs/utils/progressindicator.cpp
@@ -33,51 +33,114 @@
#include <QPainter>
#include <QPixmap>
-using namespace Utils;
+namespace {
-ProgressIndicator::ProgressIndicator(IndicatorSize size, QWidget *parent)
- : QWidget(parent),
- m_rotation(0)
-{
- setAttribute(Qt::WA_TransparentForMouseEvents);
- m_timer.setSingleShot(false);
- connect(&m_timer, &QTimer::timeout, this, &ProgressIndicator::step);
- setIndicatorSize(size);
-}
-
-static QString imageFileNameForIndicatorSize(ProgressIndicator::IndicatorSize size)
+static QString imageFileNameForIndicatorSize(Utils::ProgressIndicatorSize size)
{
switch (size) {
- case ProgressIndicator::Large:
- return QLatin1String(":/utils/images/progressindicator_big.png");
- case ProgressIndicator::Medium:
- return QLatin1String(":/utils/images/progressindicator_medium.png");
- case ProgressIndicator::Small:
- default:
+ case Utils::ProgressIndicatorSize::Large:
+ return QLatin1String(":/utils/images/progressindicator_big.png");
+ case Utils::ProgressIndicatorSize::Medium:
+ return QLatin1String(":/utils/images/progressindicator_medium.png");
+ case Utils::ProgressIndicatorSize::Small:
+ default:
return QLatin1String(":/utils/images/progressindicator_small.png");
}
}
-void ProgressIndicator::setIndicatorSize(ProgressIndicator::IndicatorSize size)
+} // namespace
+
+namespace Utils {
+
+ProgressIndicatorPainter::ProgressIndicatorPainter(ProgressIndicatorSize size)
+{
+ m_timer.setSingleShot(false);
+ QObject::connect(&m_timer, &QTimer::timeout, [this]() {
+ nextAnimationStep();
+ if (m_callback)
+ m_callback();
+ });
+
+ setIndicatorSize(size);
+}
+
+void ProgressIndicatorPainter::setIndicatorSize(ProgressIndicatorSize size)
{
m_size = size;
- m_rotationStep = size == Small ? 45 : 30;
- m_timer.setInterval(size == Small ? 100 : 80);
+ m_rotationStep = size == ProgressIndicatorSize::Small ? 45 : 30;
+ m_timer.setInterval(size == ProgressIndicatorSize::Small ? 100 : 80);
m_pixmap = Icon({{imageFileNameForIndicatorSize(size),
Theme::PanelTextColorMid}}, Icon::Tint).pixmap();
- updateGeometry();
}
-ProgressIndicator::IndicatorSize ProgressIndicator::indicatorSize() const
+ProgressIndicatorSize ProgressIndicatorPainter::indicatorSize() const
{
return m_size;
}
-QSize ProgressIndicator::sizeHint() const
+void ProgressIndicatorPainter::setUpdateCallback(const UpdateCallback &cb)
+{
+ m_callback = cb;
+}
+
+QSize ProgressIndicatorPainter::size() const
{
return m_pixmap.size() / m_pixmap.devicePixelRatio();
}
+// Paint indicator centered on the rect
+void ProgressIndicatorPainter::paint(QPainter &painter, const QRect &rect) const
+{
+ painter.save();
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+ QPoint translate(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2);
+ QTransform t;
+ t.translate(translate.x(), translate.y());
+ t.rotate(m_rotation);
+ t.translate(-translate.x(), -translate.y());
+ painter.setTransform(t);
+ QSize pixmapUserSize(m_pixmap.size() / m_pixmap.devicePixelRatio());
+ painter.drawPixmap(QPoint(rect.x() + ((rect.width() - pixmapUserSize.width()) / 2),
+ rect.y() + ((rect.height() - pixmapUserSize.height()) / 2)),
+ m_pixmap);
+ painter.restore();
+}
+
+void ProgressIndicatorPainter::startAnimation()
+{
+ QTC_ASSERT(m_callback, return);
+ m_timer.start();
+}
+
+void ProgressIndicatorPainter::stopAnimation()
+{
+ m_timer.stop();
+}
+
+void Utils::ProgressIndicatorPainter::nextAnimationStep()
+{
+ m_rotation = (m_rotation + m_rotationStep + 360) % 360;
+}
+
+ProgressIndicator::ProgressIndicator(ProgressIndicatorSize size, QWidget *parent)
+ : QWidget(parent), m_paint(size)
+{
+ setAttribute(Qt::WA_TransparentForMouseEvents);
+ m_paint.setUpdateCallback([this]() { update(); });
+ updateGeometry();
+}
+
+void ProgressIndicator::setIndicatorSize(ProgressIndicatorSize size)
+{
+ m_paint.setIndicatorSize(size);
+ updateGeometry();
+}
+
+QSize ProgressIndicator::sizeHint() const
+{
+ return m_paint.size();
+}
+
void ProgressIndicator::attachToWidget(QWidget *parent)
{
if (parentWidget())
@@ -91,27 +154,17 @@ void ProgressIndicator::attachToWidget(QWidget *parent)
void ProgressIndicator::paintEvent(QPaintEvent *)
{
QPainter p(this);
- p.setRenderHint(QPainter::SmoothPixmapTransform);
- QPoint translate(rect().width() / 2, rect().height() / 2);
- QTransform t;
- t.translate(translate.x(), translate.y());
- t.rotate(m_rotation);
- t.translate(-translate.x(), -translate.y());
- p.setTransform(t);
- QSize pixmapUserSize(m_pixmap.size() / m_pixmap.devicePixelRatio());
- p.drawPixmap(QPoint((rect().width() - pixmapUserSize.width()) / 2,
- (rect().height() - pixmapUserSize.height()) / 2),
- m_pixmap);
+ m_paint.paint(p, rect());
}
void ProgressIndicator::showEvent(QShowEvent *)
{
- m_timer.start();
+ m_paint.startAnimation();
}
void ProgressIndicator::hideEvent(QHideEvent *)
{
- m_timer.stop();
+ m_paint.stopAnimation();
}
bool ProgressIndicator::eventFilter(QObject *obj, QEvent *ev)
@@ -122,15 +175,10 @@ bool ProgressIndicator::eventFilter(QObject *obj, QEvent *ev)
return QWidget::eventFilter(obj, ev);
}
-void ProgressIndicator::step()
-{
- m_rotation = (m_rotation + m_rotationStep + 360) % 360;
- update();
-}
-
void ProgressIndicator::resizeToParent()
{
QTC_ASSERT(parentWidget(), return);
setGeometry(QRect(QPoint(0, 0), parentWidget()->size()));
}
+} // namespace Utils
diff --git a/src/libs/utils/progressindicator.h b/src/libs/utils/progressindicator.h
index 4fee8b19569..6713709c1b0 100644
--- a/src/libs/utils/progressindicator.h
+++ b/src/libs/utils/progressindicator.h
@@ -30,44 +30,74 @@
#include <QTimer>
#include <QWidget>
+#include <functional>
+#include <memory>
+
namespace Utils {
namespace Internal { class ProgressIndicatorPrivate; }
+enum class ProgressIndicatorSize
+{
+ Small,
+ Medium,
+ Large
+};
+
+class QTCREATOR_UTILS_EXPORT ProgressIndicatorPainter
+{
+public:
+ using UpdateCallback = std::function<void()>;
+
+ ProgressIndicatorPainter(ProgressIndicatorSize size);
+ virtual ~ProgressIndicatorPainter() = default;
+
+ virtual void setIndicatorSize(ProgressIndicatorSize size);
+ ProgressIndicatorSize indicatorSize() const;
+
+ void setUpdateCallback(const UpdateCallback &cb);
+
+ QSize size() const;
+
+ void paint(QPainter &painter, const QRect &rect) const;
+
+ void startAnimation();
+ void stopAnimation();
+
+protected:
+ void nextAnimationStep();
+
+private:
+ ProgressIndicatorSize m_size = ProgressIndicatorSize::Small;
+ int m_rotationStep = 45;
+ int m_rotation = 0;
+ QTimer m_timer;
+ QPixmap m_pixmap;
+ UpdateCallback m_callback;
+};
+
class QTCREATOR_UTILS_EXPORT ProgressIndicator : public QWidget
{
Q_OBJECT
public:
- enum IndicatorSize {
- Small,
- Medium,
- Large
- };
-
- explicit ProgressIndicator(IndicatorSize size, QWidget *parent = 0);
+ explicit ProgressIndicator(ProgressIndicatorSize size, QWidget *parent = nullptr);
- void setIndicatorSize(IndicatorSize size);
- IndicatorSize indicatorSize() const;
+ void setIndicatorSize(ProgressIndicatorSize size);
- QSize sizeHint() const;
+ QSize sizeHint() const final;
void attachToWidget(QWidget *parent);
protected:
- void paintEvent(QPaintEvent *);
- void showEvent(QShowEvent *);
- void hideEvent(QHideEvent *);
- bool eventFilter(QObject *obj, QEvent *ev);
+ void paintEvent(QPaintEvent *) final;
+ void showEvent(QShowEvent *) final;
+ void hideEvent(QHideEvent *) final;
+ bool eventFilter(QObject *obj, QEvent *ev) final;
private:
- void step();
void resizeToParent();
- ProgressIndicator::IndicatorSize m_size;
- int m_rotationStep;
- int m_rotation;
- QTimer m_timer;
- QPixmap m_pixmap;
+ ProgressIndicatorPainter m_paint;
};
} // Utils
diff --git a/src/libs/utils/reloadpromptutils.cpp b/src/libs/utils/reloadpromptutils.cpp
index 798a4876a70..2270053be0f 100644
--- a/src/libs/utils/reloadpromptutils.cpp
+++ b/src/libs/utils/reloadpromptutils.cpp
@@ -44,11 +44,11 @@ QTCREATOR_UTILS_EXPORT ReloadPromptAnswer reloadPrompt(const FileName &fileName,
if (modified) {
msg = QCoreApplication::translate("Utils::reloadPrompt",
- "The unsaved file <i>%1</i> has changed outside Qt Creator. "
+ "The unsaved file <i>%1</i> has been changed on disk. "
"Do you want to reload it and discard your changes?");
} else {
msg = QCoreApplication::translate("Utils::reloadPrompt",
- "The file <i>%1</i> has changed outside Qt Creator. Do you want to reload it?");
+ "The file <i>%1</i> has been changed on disk. Do you want to reload it?");
}
msg = msg.arg(fileName.fileName());
return reloadPrompt(title, msg, fileName.toUserOutput(), enableDiffOption, parent);
@@ -102,16 +102,16 @@ QTCREATOR_UTILS_EXPORT FileDeletedPromptAnswer
fileDeletedPrompt(const QString &fileName, bool triggerExternally, QWidget *parent)
{
const QString title = QCoreApplication::translate("Utils::fileDeletedPrompt",
- "File has been removed");
+ "File Has Been Removed");
QString msg;
if (triggerExternally) {
msg = QCoreApplication::translate("Utils::fileDeletedPrompt",
- "The file %1 has been removed outside Qt Creator. "
+ "The file %1 has been removed from disk. "
"Do you want to save it under a different name, or close "
"the editor?").arg(QDir::toNativeSeparators(fileName));
} else {
msg = QCoreApplication::translate("Utils::fileDeletedPrompt",
- "The file %1 was removed. "
+ "The file %1 has been removed from disk. "
"Do you want to save it under a different name, or close "
"the editor?").arg(QDir::toNativeSeparators(fileName));
}
diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp
index 59c7f97fd0d..6ea2099211e 100644
--- a/src/libs/utils/shellcommand.cpp
+++ b/src/libs/utils/shellcommand.cpp
@@ -42,6 +42,8 @@
#include <QThread>
#include <QVariant>
+#include <numeric>
+
/*!
\fn void Utils::ProgressParser::parseProgress(const QString &text)
@@ -241,6 +243,14 @@ void ShellCommand::addTask(QFuture<void> &future)
Q_UNUSED(future);
}
+int ShellCommand::timeoutS() const
+{
+ return std::accumulate(d->m_jobs.cbegin(), d->m_jobs.cend(), 0,
+ [](int sum, const Internal::ShellCommandPrivate::Job &job) {
+ return sum + job.timeoutS;
+ });
+}
+
QString ShellCommand::workDirectory(const QString &wd) const
{
if (!wd.isEmpty())
@@ -474,6 +484,11 @@ void ShellCommand::setProgressParser(ProgressParser *parser)
d->m_progressParser = parser;
}
+bool ShellCommand::hasProgressParser() const
+{
+ return d->m_progressParser;
+}
+
void ShellCommand::setProgressiveOutput(bool progressive)
{
d->m_progressiveOutput = progressive;
diff --git a/src/libs/utils/shellcommand.h b/src/libs/utils/shellcommand.h
index ce5957c40af..c8bf38af111 100644
--- a/src/libs/utils/shellcommand.h
+++ b/src/libs/utils/shellcommand.h
@@ -136,6 +136,7 @@ public:
void setCodec(QTextCodec *codec);
void setProgressParser(ProgressParser *parser);
+ bool hasProgressParser() const;
void setProgressiveOutput(bool progressive);
void setOutputProxyFactory(const std::function<OutputProxy *()> &factory);
@@ -161,6 +162,7 @@ signals:
protected:
virtual unsigned processFlags() const;
virtual void addTask(QFuture<void> &future);
+ int timeoutS() const;
QString workDirectory(const QString &wd) const;
private:
diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h
index eb301586915..5b30662592c 100644
--- a/src/libs/utils/smallstring.h
+++ b/src/libs/utils/smallstring.h
@@ -143,6 +143,7 @@ public:
}
BasicSmallString(std::initializer_list<Utils::SmallStringView> list)
+ : m_data(Internal::StringDataLayout<Size>())
{
std::size_t size = std::accumulate(list.begin(),
list.end(),
@@ -206,7 +207,9 @@ public:
BasicSmallString clonedString(m_data);
if (Q_UNLIKELY(hasAllocatedMemory()))
- new (&clonedString) BasicSmallString{m_data.allocated.data.pointer, m_data.allocated.data.size};
+ new (&clonedString) BasicSmallString{m_data.allocated.data.pointer,
+ m_data.allocated.data.size,
+ m_data.allocated.data.capacity};
return clonedString;
}
@@ -229,16 +232,23 @@ public:
return QString::fromUtf8(data(), int(size()));
}
+ SmallStringView toView() const
+ {
+ return SmallStringView(data(), size());
+ }
+
operator SmallStringView() const
{
return SmallStringView(data(), size());
}
+ explicit
operator QString() const
{
return toQString();
}
+ explicit
operator std::string() const
{
return std::string(data(), size());
@@ -255,8 +265,10 @@ public:
if (fitsNotInCapacity(newCapacity)) {
if (Q_UNLIKELY(hasAllocatedMemory())) {
m_data.allocated.data.pointer = Memory::reallocate(m_data.allocated.data.pointer,
- newCapacity + 1);
+ newCapacity + 1);
m_data.allocated.data.capacity = newCapacity;
+ } else if (newCapacity <= shortStringCapacity()) {
+ new (this) BasicSmallString{m_data.allocated.data.pointer, m_data.allocated.data.size};
} else {
const size_type oldSize = size();
newCapacity = std::max(newCapacity, oldSize);
@@ -310,22 +322,22 @@ public:
reverse_iterator rbegin() noexcept
{
- return reverse_iterator(end() - static_cast<std::size_t>(1));
+ return reverse_iterator(end());
}
reverse_iterator rend() noexcept
{
- return reverse_iterator(begin() - static_cast<std::size_t>(1));
+ return reverse_iterator(begin());
}
const_reverse_iterator rbegin() const noexcept
{
- return const_reverse_iterator(end() - static_cast<std::size_t>(1));
+ return const_reverse_iterator(end());
}
const_reverse_iterator rend() const noexcept
{
- return const_reverse_iterator(begin() - static_cast<std::size_t>(1));
+ return const_reverse_iterator(begin());
}
const_iterator begin() const noexcept
@@ -362,19 +374,17 @@ public:
return BasicSmallString(utf8ByteArray.constData(), uint(utf8ByteArray.size()));
}
+ // precondition: has to be null terminated
bool contains(SmallStringView subStringToSearch) const
{
- auto found = std::search(begin(),
- end(),
- subStringToSearch.begin(),
- subStringToSearch.end());
+ const char *found = std::strstr(data(), subStringToSearch.data());
- return found != end();
+ return found != nullptr;
}
bool contains(char characterToSearch) const
{
- auto found = std::strchr(data(), characterToSearch);
+ auto found = std::memchr(data(), characterToSearch, size());
return found != nullptr;
}
@@ -532,131 +542,93 @@ public:
}
static
- BasicSmallString join(std::initializer_list<BasicSmallString> list)
+ BasicSmallString join(std::initializer_list<SmallStringView> list)
{
size_type totalSize = 0;
- for (const BasicSmallString &string : list)
+ for (SmallStringView string : list)
totalSize += string.size();
BasicSmallString joinedString;
joinedString.reserve(totalSize);
- for (const BasicSmallString &string : list)
+ for (SmallStringView string : list)
joinedString.append(string);
return joinedString;
}
- char &operator[](std::size_t index)
- {
- return *(data() + index);
- }
-
- char operator[](std::size_t index) const
+ static
+ BasicSmallString number(int number)
{
- return *(data() + index);
- }
+ char buffer[12];
+ std::size_t size = itoa(number, buffer, 10);
- template<size_type ArraySize>
- friend bool operator==(const BasicSmallString& first, const char(&second)[ArraySize]) noexcept
- {
- return first == SmallStringView(second);
+ return BasicSmallString(buffer, size);
}
- template<size_type ArraySize>
- friend bool operator==(const char(&first)[ArraySize], const BasicSmallString& second) noexcept
+ static
+ BasicSmallString number(long long int number)
{
- return second == first;
- }
+ char buffer[22];
+ std::size_t size = itoa(number, buffer, 10);
- template<typename Type,
- typename = std::enable_if_t<std::is_pointer<Type>::value>
- >
- friend bool operator==(const BasicSmallString& first, Type second) noexcept
- {
- return first == SmallStringView(second);
+ return BasicSmallString(buffer, size);
}
- template<typename Type,
- typename = std::enable_if_t<std::is_pointer<Type>::value>
- >
- friend bool operator==(Type first, const BasicSmallString& second) noexcept
+ static
+ BasicSmallString number(double number)
{
- return second == first;
+ return std::to_string(number);
}
- friend bool operator==(const BasicSmallString& first, const SmallStringView& second) noexcept
+ char &operator[](std::size_t index)
{
- return first.size() == second.size()
- && std::memcmp(first.data(), second.data(), first.size()) == 0;
+ return *(data() + index);
}
- friend bool operator==(const SmallStringView& first, const BasicSmallString& second) noexcept
+ char operator[](std::size_t index) const
{
- return second == first;
+ return *(data() + index);
}
- friend bool operator!=(const BasicSmallString& first, const SmallStringView& second) noexcept
+ friend BasicSmallString operator+(const BasicSmallString &first, const BasicSmallString &second)
{
- return !(first == second);
- }
+ BasicSmallString text;
+ text.reserve(first.size() + second.size());
- friend bool operator!=(const SmallStringView& first, const BasicSmallString& second) noexcept
- {
- return second == first;
- }
+ text.append(first);
+ text.append(second);
- friend bool operator!=(const BasicSmallString& first, const BasicSmallString& second) noexcept
- {
- return !(first == second);
+ return text;
}
- template<size_type ArraySize>
- friend bool operator!=(const BasicSmallString& first, const char(&second)[ArraySize]) noexcept
+ friend BasicSmallString operator+(const BasicSmallString &first, SmallStringView second)
{
- return !(first == second);
- }
+ BasicSmallString text;
+ text.reserve(first.size() + second.size());
- template<size_type ArraySize>
- friend bool operator!=(const char(&first)[ArraySize], const BasicSmallString& second) noexcept
- {
- return second != first;
- }
+ text.append(first);
+ text.append(second);
- template<typename Type,
- typename = std::enable_if_t<std::is_pointer<Type>::value>
- >
- friend bool operator!=(const BasicSmallString& first, Type second) noexcept
- {
- return !(first == second);
+ return text;
}
- template<typename Type,
- typename = std::enable_if_t<std::is_pointer<Type>::value>
- >
- friend bool operator!=(Type first, const BasicSmallString& second) noexcept
+ friend BasicSmallString operator+(SmallStringView first, const BasicSmallString &second)
{
- return second != first;
+ return operator+(second, first);
}
- friend bool operator<(const BasicSmallString& first, SmallStringView second) noexcept
+ template<size_type ArraySize>
+ friend BasicSmallString operator+(const BasicSmallString &first, const char(&second)[ArraySize])
{
- if (first.size() != second.size())
- return first.size() < second.size();
-
- const int comparison = std::memcmp(first.data(), second.data(), first.size());
- return comparison < 0;
+ return operator+(first, SmallStringView(second));
}
- friend bool operator<(SmallStringView first, const BasicSmallString& second) noexcept
+ template<size_type ArraySize>
+ friend BasicSmallString operator+(const char(&first)[ArraySize], const BasicSmallString &second)
{
- if (first.size() != second.size())
- return first.size() < second.size();
-
- const int comparison = std::memcmp(first.data(), second.data(), first.size());
-
- return comparison < 0;
+ return operator+(SmallStringView(first), second);
}
unittest_public:
@@ -686,22 +658,34 @@ unittest_public:
{
const size_type cacheLineSize = 64;
- const auto divisionByCacheLineSize = std::div(int64_t(size), int64_t(cacheLineSize));
+ size_type cacheLineBlocks = (size - 1) / cacheLineSize;
+
+ return (cacheLineBlocks + 1) * cacheLineSize;
+ }
+
+ size_type countOccurrence(SmallStringView text)
+ {
+ auto found = begin();
+
+ size_type count = 0;
- size_type cacheLineBlocks = size_type(divisionByCacheLineSize.quot);
- const size_type supplement = divisionByCacheLineSize.rem ? 1 : 0;
+ while (true) {
+ found = std::search(found,
+ end(),
+ text.begin(),
+ text.end());
+ if (found == end())
+ break;
- cacheLineBlocks += supplement;
- int exponent;
- const double significand = std::frexp(cacheLineBlocks, &exponent);
- const double factorOneDotFiveSignificant = std::ceil(significand * 4.) / 4.;
- cacheLineBlocks = size_type(std::ldexp(factorOneDotFiveSignificant, exponent));
+ ++count;
+ found += text.size();
+ }
- return cacheLineBlocks * cacheLineSize;
+ return count;
}
private:
- BasicSmallString(Internal::StringDataLayout<Size> data) noexcept
+ BasicSmallString(const Internal::StringDataLayout<Size> &data) noexcept
: m_data(data)
{
}
@@ -751,41 +735,44 @@ private:
void replaceSmallerSized(SmallStringView fromText, SmallStringView toText)
{
- size_type newSize = size();
- reserve(newSize);
-
- auto start = begin();
-
- auto found = std::search(start,
+ auto found = std::search(begin(),
end(),
fromText.begin(),
fromText.end());
- size_type sizeDifference = 0;
-
- while (found != end()) {
- start = found + fromText.size();
-
- auto nextFound = std::search(start,
- end(),
- fromText.begin(),
- fromText.end());
-
- auto replacedTextEndPosition = found + fromText.size();
- auto replacementTextEndPosition = found + toText.size() - sizeDifference;
- auto replacementTextStartPosition = found - sizeDifference;
-
- std::memmove(replacementTextEndPosition.data(),
- replacedTextEndPosition.data(),
- nextFound - start);
- std::memcpy(replacementTextStartPosition.data(), toText.data(), toText.size());
+ if (found != end()) {
+ size_type newSize = size();
+ {
+ size_type foundIndex = found - begin();
+ reserve(newSize);
+ found = begin() + foundIndex;
+ }
+ size_type sizeDifference = 0;
+
+ while (found != end()) {
+ auto start = found + fromText.size();
+
+ auto nextFound = std::search(start,
+ end(),
+ fromText.begin(),
+ fromText.end());
+
+ auto replacedTextEndPosition = found + fromText.size();
+ auto replacementTextEndPosition = found + toText.size() - sizeDifference;
+ auto replacementTextStartPosition = found - sizeDifference;
+ std::memmove(replacementTextEndPosition.data(),
+ replacedTextEndPosition.data(),
+ std::distance(start, nextFound));
+ std::memcpy(replacementTextStartPosition.data(), toText.data(), toText.size());
+
+ sizeDifference += fromText.size() - toText.size();
+ found = nextFound;
+ }
- sizeDifference += fromText.size() - toText.size();
- found = nextFound;
+ newSize -= sizeDifference;
+ setSize(newSize);
+ at(newSize) = '\0';
}
- newSize -= sizeDifference;
- setSize(newSize);
- *end() = 0;
}
iterator replaceLargerSizedRecursive(size_type startIndex,
@@ -801,36 +788,32 @@ private:
auto foundIndex = found - begin();
if (found != end()) {
- startIndex = foundIndex + fromText.size();
-
- size_type newSizeDifference = sizeDifference + toText.size() - fromText.size();
+ size_type startNextSearchIndex = foundIndex + fromText.size();
+ size_type newSizeDifference = sizeDifference + (toText.size() - fromText.size());
- auto nextFound = replaceLargerSizedRecursive(startIndex,
+ auto nextFound = replaceLargerSizedRecursive(startNextSearchIndex,
fromText,
toText,
newSizeDifference);
- found = begin() + foundIndex;
- auto start = begin() + startIndex;
-
- auto replacedTextEndPosition = found + fromText.size();
- auto replacementTextEndPosition = found + fromText.size() + newSizeDifference;
- auto replacementTextStartPosition = found + sizeDifference;
+ auto startFound = begin() + foundIndex;
+ auto endOfFound = begin() + startNextSearchIndex;
+ auto replacedTextEndPosition = endOfFound;
+ auto replacementTextEndPosition = endOfFound + newSizeDifference;
+ auto replacementTextStartPosition = startFound + sizeDifference;
std::memmove(replacementTextEndPosition.data(),
replacedTextEndPosition.data(),
- nextFound - start);
+ std::distance(endOfFound, nextFound));
std::memcpy(replacementTextStartPosition.data(), toText.data(), toText.size());
- } else {
+ } else if (startIndex != 0) {
size_type newSize = size() + sizeDifference;
- reserve(optimalCapacity(newSize));
setSize(newSize);
- found = end();
- *end() = 0;
+ at(newSize) = 0;
}
- return found;
+ return begin() + foundIndex;
}
void replaceLargerSized(SmallStringView fromText, SmallStringView toText)
@@ -838,7 +821,15 @@ private:
size_type sizeDifference = 0;
size_type startIndex = 0;
- replaceLargerSizedRecursive(startIndex, fromText, toText, sizeDifference);
+ size_type replacementTextSizeDifference = toText.size() - fromText.size();
+ size_type occurrences = countOccurrence(fromText);
+ size_type newSize = size() + (replacementTextSizeDifference * occurrences);
+
+ if (occurrences > 0) {
+ reserve(optimalCapacity(newSize));
+
+ replaceLargerSizedRecursive(startIndex, fromText, toText, sizeDifference);
+ }
}
void setSize(size_type size)
@@ -849,6 +840,51 @@ private:
m_data.allocated.data.size = size;
}
+ static
+ std::size_t itoa(long long int number, char* string, uint base)
+ {
+ using llint = long long int;
+ using lluint = long long unsigned int;
+ std::size_t size = 0;
+ bool isNegative = false;
+ lluint unsignedNumber = 0;
+
+ if (number == 0)
+ {
+ string[size] = '0';
+ string[++size] = '\0';
+
+ return size;
+ }
+
+ if (number < 0 && base == 10)
+ {
+ isNegative = true;
+ if (number == std::numeric_limits<llint>::min())
+ unsignedNumber = lluint(std::numeric_limits<llint>::max()) + 1;
+ else
+ unsignedNumber = lluint(-number);
+ } else {
+ unsignedNumber = lluint(number);
+ }
+
+ while (unsignedNumber != 0)
+ {
+ int remainder = int(unsignedNumber % base);
+ string[size++] = (remainder > 9) ? char((remainder - 10) + 'a') : char(remainder + '0');
+ unsignedNumber /= base;
+ }
+
+ if (isNegative)
+ string[size++] = '-';
+
+ string[size] = '\0';
+
+ std::reverse(string, string+size);
+
+ return size;
+ }
+
private:
Internal::StringDataLayout<Size> m_data;
};
@@ -857,33 +893,6 @@ template<template<uint> class String, uint Size>
using isSameString = std::is_same<std::remove_reference_t<std::remove_cv_t<String<Size>>>,
BasicSmallString<Size>>;
-template<template<uint> class String,
- uint SizeOne,
- uint SizeTwo,
- typename = std::enable_if_t<isSameString<String, SizeOne>::value
- || isSameString<String, SizeTwo>::value>>
-bool operator==(const String<SizeOne> &first, const String<SizeTwo> &second) noexcept
-{
- return first.size() == second.size()
- && std::memcmp(first.data(), second.data(), first.size()) == 0;
-}
-
-
-template<template<uint> class String,
- uint SizeOne,
- uint SizeTwo,
- typename = std::enable_if_t<isSameString<String, SizeOne>::value
- || isSameString<String, SizeTwo>::value>>
-bool operator<(const String<SizeOne> &first, const String<SizeTwo> &second) noexcept
-{
- if (first.size() != second.size())
- return first.size() < second.size();
-
- const int comparison = std::memcmp(first.data(), second.data(), first.size() + 1);
-
- return comparison < 0;
-}
-
template<typename Key,
typename Value,
typename Hash = std::hash<Key>,
@@ -916,4 +925,30 @@ std::vector<Type> clone(const std::vector<Type> &vector)
using SmallString = BasicSmallString<31>;
using PathString = BasicSmallString<190>;
+inline
+SmallString operator+(SmallStringView first, SmallStringView second)
+{
+ SmallString text;
+ text.reserve(first.size() + second.size());
+
+ text.append(first);
+ text.append(second);
+
+ return text;
+}
+
+template<std::size_t Size>
+inline
+SmallString operator+(SmallStringView first, const char(&second)[Size])
+{
+ return operator+(first, SmallStringView(second));
+}
+
+template<std::size_t Size>
+inline
+SmallString operator+(const char(&first)[Size], SmallStringView second)
+{
+ return operator+(SmallStringView(first), second);
+}
+
} // namespace Utils
diff --git a/src/libs/utils/smallstringfwd.h b/src/libs/utils/smallstringfwd.h
index 90af2c7b42c..f3b343f9616 100644
--- a/src/libs/utils/smallstringfwd.h
+++ b/src/libs/utils/smallstringfwd.h
@@ -29,9 +29,15 @@ namespace Utils {
using uint = unsigned int;
+class SmallStringView;
template <uint Size>
class BasicSmallString;
using SmallString = BasicSmallString<31>;
using PathString = BasicSmallString<190>;
+inline
+int compare(SmallStringView first, SmallStringView second) noexcept;
+inline
+int reverseCompare(SmallStringView first, SmallStringView second) noexcept;
+
} // namespace Utils
diff --git a/src/libs/utils/smallstringio.h b/src/libs/utils/smallstringio.h
index e212fc85672..8e2b3f598be 100644
--- a/src/libs/utils/smallstringio.h
+++ b/src/libs/utils/smallstringio.h
@@ -62,7 +62,7 @@ QDataStream &operator>>(QDataStream &in, BasicSmallString<Size> &string)
char *data = string.data();
- in.readRawData(data, size);
+ in.readRawData(data, int(size));
}
return in;
@@ -79,42 +79,30 @@ QDebug &operator<<(QDebug &debug, const String &string)
}
template <uint Size>
-std::ostream &operator<<(std::ostream &stream, const BasicSmallString<Size> &string)
+std::ostream &operator<<(std::ostream &out, const BasicSmallString<Size> &string)
{
- using std::operator<<;
+ BasicSmallString<Size> formatedString = string.clone();
- stream.write(string.data(), std::streamsize(string.size()));
+ formatedString.replace("\n", "\\n");
+ formatedString.replace("\t", "\\t");
- return stream;
-}
+ out << "\"";
-inline
-std::ostream &operator<<(std::ostream &stream, SmallStringView string)
-{
- using std::operator<<;
+ out.write(formatedString.data(), std::streamsize(formatedString.size()));
- stream.write(string.data(), std::streamsize(string.size()));
+ out << "\"";
- return stream;
+ return out;
}
-template <uint Size>
-void PrintTo(const BasicSmallString<Size> &string, ::std::ostream *os)
+inline
+std::ostream &operator<<(std::ostream &out, SmallStringView string)
{
- BasicSmallString<Size> formatedString = string.clone();
-
- formatedString.replace("\n", "\\n");
- formatedString.replace("\t", "\\t");
-
- *os << "'";
-
- os->write(formatedString.data(), formatedString.size());
-
- *os<< "'";
+ return out << PathString(string);
}
-template <uint Size>
-QDataStream &operator<<(QDataStream &out, const BasicSmallStringVector<Size> &stringVector)
+template <typename String>
+QDataStream &operator<<(QDataStream &out, const BasicSmallStringVector<String> &stringVector)
{
out << quint64(stringVector.size());
@@ -124,8 +112,8 @@ QDataStream &operator<<(QDataStream &out, const BasicSmallStringVector<Size> &s
return out;
}
-template <uint Size>
-QDataStream &operator>>(QDataStream &in, BasicSmallStringVector<Size> &stringVector)
+template <typename String>
+QDataStream &operator>>(QDataStream &in, BasicSmallStringVector<String> &stringVector)
{
stringVector.clear();
@@ -136,7 +124,7 @@ QDataStream &operator>>(QDataStream &in, BasicSmallStringVector<Size> &stringVe
stringVector.reserve(size);
for (quint64 i = 0; i < size; ++i) {
- BasicSmallString<Size> string;
+ String string;
in >> string;
@@ -146,18 +134,18 @@ QDataStream &operator>>(QDataStream &in, BasicSmallStringVector<Size> &stringVe
return in;
}
-template <uint Size>
-QDebug operator<<(QDebug debug, const BasicSmallStringVector<Size> &stringVector)
+template <typename String>
+QDebug operator<<(QDebug debug, const BasicSmallStringVector<String> &stringVector)
{
- debug << "StringVector(" << stringVector.join(BasicSmallString<Size>(", ")).constData() << ")";
+ debug << "StringVector(" << stringVector.join(", ").constData() << ")";
return debug;
}
-template <uint Size>
-void PrintTo(const BasicSmallStringVector<Size> &textVector, ::std::ostream* os)
+template <typename String>
+std::ostream &operator<<(std::ostream &out, const BasicSmallStringVector<String> &textVector)
{
- *os << "[" << textVector.join(BasicSmallString<Size>(", ")).constData() << "]";
+ return out << "[" << textVector.join("\", \"") << "]";
}
} // namespace Utils
diff --git a/src/libs/utils/smallstringiterator.h b/src/libs/utils/smallstringiterator.h
index 026a8b78b56..1217e4bd2b9 100644
--- a/src/libs/utils/smallstringiterator.h
+++ b/src/libs/utils/smallstringiterator.h
@@ -39,8 +39,10 @@ template <class Category,
typename Reference = Type&>
struct SmallStringIterator : public std::iterator<Category, Type, DistanceType, Pointer, Reference>
{
+ constexpr
SmallStringIterator() noexcept = default;
+ constexpr
SmallStringIterator(Pointer ptr) noexcept : pointer_(ptr)
{
}
diff --git a/src/libs/utils/smallstringlayout.h b/src/libs/utils/smallstringlayout.h
index a9f2be56093..f831ac0aa9a 100644
--- a/src/libs/utils/smallstringlayout.h
+++ b/src/libs/utils/smallstringlayout.h
@@ -92,7 +92,7 @@ struct ShortStringLayout {
template <uint MaximumShortStringDataAreaSize>
struct ALIGNAS_16 StringDataLayout {
- static_assert( MaximumShortStringDataAreaSize >= 15, "Size must be greater equal than 15 bytes!");
+ static_assert(MaximumShortStringDataAreaSize >= 15, "Size must be greater equal than 15 bytes!");
static_assert(MaximumShortStringDataAreaSize < 64
? ((MaximumShortStringDataAreaSize + 1) % 16) == 0
: ((MaximumShortStringDataAreaSize + 2) % 16) == 0,
@@ -139,9 +139,7 @@ struct ALIGNAS_16 StringDataLayout {
constexpr static
size_type shortStringCapacity() noexcept
{
- return MaximumShortStringDataAreaSize < 64
- ? MaximumShortStringDataAreaSize - 1
- : MaximumShortStringDataAreaSize - 2;
+ return MaximumShortStringDataAreaSize - 1;
}
union {
diff --git a/src/libs/utils/smallstringliteral.h b/src/libs/utils/smallstringliteral.h
index 3d5e1fef1e0..eedcf45d139 100644
--- a/src/libs/utils/smallstringliteral.h
+++ b/src/libs/utils/smallstringliteral.h
@@ -56,21 +56,23 @@ public:
{
}
- const char *data() const
+ const char *data() const noexcept
{
return Q_LIKELY(isShortString()) ? m_data.shortString.string : m_data.allocated.data.pointer;
}
- size_type size() const
+ size_type size() const noexcept
{
return Q_LIKELY(isShortString()) ? m_data.shortString.shortStringSize : m_data.allocated.data.size;
}
+ constexpr
const_iterator begin() const noexcept
{
return data();
}
+ constexpr
const_iterator end() const noexcept
{
return data() + size();
@@ -78,12 +80,12 @@ public:
const_reverse_iterator rbegin() const noexcept
{
- return const_reverse_iterator(end() - static_cast<std::size_t>(1));
+ return const_reverse_iterator(end());
}
const_reverse_iterator rend() const noexcept
{
- return const_reverse_iterator(begin() - static_cast<std::size_t>(1));
+ return const_reverse_iterator(begin());
}
constexpr static
@@ -102,6 +104,7 @@ public:
return m_data.shortString.isReadOnlyReference;
}
+ constexpr
operator SmallStringView() const
{
return SmallStringView(data(), size());
diff --git a/src/libs/utils/smallstringvector.h b/src/libs/utils/smallstringvector.h
index 700a333ffb8..ed1acc2e7bc 100644
--- a/src/libs/utils/smallstringvector.h
+++ b/src/libs/utils/smallstringvector.h
@@ -35,25 +35,27 @@
namespace Utils {
-template<uint SmallStringSize>
-class BasicSmallStringVector : public std::vector<BasicSmallString<SmallStringSize>>
+template<typename String>
+class BasicSmallStringVector : public std::vector<String>
{
- using SmallString = BasicSmallString<SmallStringSize>;
- using Base = std::vector<SmallString>;
+ using Base = std::vector<String>;
+
public:
BasicSmallStringVector() = default;
+ using Base::Base;
+
explicit BasicSmallStringVector(const Base &stringVector)
: Base(stringVector.begin(), stringVector.end())
{
}
- BasicSmallStringVector(std::initializer_list<SmallString> list)
+ BasicSmallStringVector(std::initializer_list<String> list)
{
Base::reserve(list.size());
for (auto &&entry : list)
- Base::push_back(entry.clone());
+ Base::push_back(std::move(entry));
}
explicit BasicSmallStringVector(const QStringList &stringList)
@@ -79,7 +81,7 @@ public:
BasicSmallStringVector &operator=(BasicSmallStringVector &&)
noexcept(std::is_nothrow_move_assignable<Base>::value) = default;
- SmallString join(SmallString &&separator) const
+ SmallString join(SmallStringView separator) const
{
SmallString joinedString;
@@ -110,7 +112,7 @@ public:
return hasEntry;
}
- void append(SmallString &&string)
+ void append(String &&string)
{
push_back(std::move(string));
}
@@ -136,7 +138,8 @@ public:
QStringList qStringList;
qStringList.reserve(int(Base::size()));
- std::copy(Base::begin(), Base::end(), std::back_inserter(qStringList));
+ for (const auto &entry : *this)
+ qStringList.push_back(QString(entry));
return qStringList;
}
@@ -153,6 +156,9 @@ private:
}
};
-using SmallStringVector = BasicSmallStringVector<31>;
-using PathStringVector = BasicSmallStringVector<190>;
+
+
+using SmallStringVector = BasicSmallStringVector<BasicSmallString<31>>;
+using PathStringVector = BasicSmallStringVector<BasicSmallString<190>>;
+using StringViewVector = BasicSmallStringVector<SmallStringView>;
} // namespace Utils;
diff --git a/src/libs/utils/smallstringview.h b/src/libs/utils/smallstringview.h
index 14be9bbb693..3d479195f17 100644
--- a/src/libs/utils/smallstringview.h
+++ b/src/libs/utils/smallstringview.h
@@ -27,7 +27,7 @@
#include "smallstringiterator.h"
-#include <QtGlobal>
+#include <QString>
#include <cstring>
#include <string>
@@ -67,6 +67,12 @@ public:
{
}
+ SmallStringView(const std::string &string) noexcept
+ : m_pointer(string.data()),
+ m_size(string.size())
+ {
+ }
+
static
SmallStringView fromUtf8(const char *const characterPointer)
{
@@ -74,22 +80,36 @@ public:
}
constexpr
- const char *data() const
+ const char *data() const noexcept
{
return m_pointer;
}
constexpr
- size_type size() const
+ size_type size() const noexcept
{
return m_size;
}
+ constexpr
+ size_type isEmpty() const noexcept
+ {
+ return m_size == 0;
+ }
+
+ constexpr
+ size_type empty() const noexcept
+ {
+ return m_size == 0;
+ }
+
+ constexpr
const_iterator begin() const noexcept
{
return data();
}
+ constexpr
const_iterator end() const noexcept
{
return data() + size();
@@ -97,12 +117,12 @@ public:
const_reverse_iterator rbegin() const noexcept
{
- return const_reverse_iterator(end() - static_cast<std::size_t>(1));
+ return const_reverse_iterator(end());
}
const_reverse_iterator rend() const noexcept
{
- return const_reverse_iterator(begin() - static_cast<std::size_t>(1));
+ return const_reverse_iterator(begin());
}
operator std::string() const
@@ -110,24 +130,105 @@ public:
return std::string(data(), size());
}
+ explicit operator QString() const
+ {
+ return QString::fromUtf8(data(), int(size()));
+ }
+
+ bool startsWith(SmallStringView subStringToSearch) const noexcept
+ {
+ if (size() >= subStringToSearch.size())
+ return !std::memcmp(m_pointer, subStringToSearch.data(), subStringToSearch.size());
+
+ return false;
+ }
+
+ bool startsWith(char characterToSearch) const noexcept
+ {
+ return m_pointer[0] == characterToSearch;
+ }
+
private:
const char *m_pointer;
size_type m_size;
};
inline
-bool operator==(const SmallStringView& first, const SmallStringView& second) noexcept
+bool operator==(SmallStringView first, SmallStringView second) noexcept
{
- if (Q_LIKELY(first.size() != second.size()))
- return false;
-
- return !std::memcmp(first.data(), second.data(), first.size());
+ return first.size() == second.size() && std::memcmp(first.data(), second.data(), first.size()) == 0;
}
inline
-bool operator!=(const SmallStringView& first, const SmallStringView& second) noexcept
+bool operator!=(SmallStringView first, SmallStringView second) noexcept
{
return !(first == second);
}
+inline
+int compare(SmallStringView first, SmallStringView second) noexcept
+{
+ int sizeDifference = int(first.size() - second.size());
+
+ if (sizeDifference == 0)
+ return std::memcmp(first.data(), second.data(), first.size());
+
+ return sizeDifference;
+}
+
+inline
+bool operator<(SmallStringView first, SmallStringView second) noexcept
+{
+ return compare(first, second) < 0;
+}
+
+inline
+bool operator>(SmallStringView first, SmallStringView second) noexcept
+{
+ return second < first;
+}
+
+namespace Internal {
+inline
+int reverse_memcmp(const char *first, const char *second, size_t n)
+{
+
+ const char *currentFirst = first + n;
+ const char *currentSecond = second + n;
+
+ while (n > 0)
+ {
+ // If the current characters differ, return an appropriately signed
+ // value; otherwise, keep searching backwards
+ if (*currentFirst != *currentSecond)
+ return *currentFirst - *currentSecond;
+
+ --currentFirst;
+ --currentSecond;
+ --n;
+ }
+
+ return 0;
+}
+}
+
+inline
+int reverseCompare(SmallStringView first, SmallStringView second) noexcept
+{
+ int sizeDifference = int(first.size() - second.size());
+
+ if (sizeDifference == 0)
+ return Internal::reverse_memcmp(first.data(), second.data(), first.size());
+
+ return sizeDifference;
+}
+
} // namespace Utils
+
+#ifdef __cpp_user_defined_literals
+inline
+constexpr Utils::SmallStringView operator""_sv(const char *const string, size_t size)
+{
+ return Utils::SmallStringView(string, size);
+}
+#endif
diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp
index fd270a5a860..b70ea7b07c4 100644
--- a/src/libs/utils/stylehelper.cpp
+++ b/src/libs/utils/stylehelper.cpp
@@ -34,6 +34,7 @@
#include <QFileInfo>
#include <QCommonStyle>
#include <QStyleOption>
+#include <QWindow>
#include <qmath.h>
// Clamps float color values within (0, 255)
@@ -397,7 +398,9 @@ void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
QPainter *p, QIcon::Mode iconMode, int dipRadius, const QColor &color, const QPoint &dipOffset)
{
QPixmap cache;
- QString pixmapName = QString::fromLatin1("icon %0 %1 %2").arg(icon.cacheKey()).arg(iconMode).arg(rect.height());
+ const int devicePixelRatio = p->device()->devicePixelRatio();
+ QString pixmapName = QString::fromLatin1("icon %0 %1 %2 %3")
+ .arg(icon.cacheKey()).arg(iconMode).arg(rect.height()).arg(devicePixelRatio);
if (!QPixmapCache::find(pixmapName, cache)) {
// High-dpi support: The in parameters (rect, radius, offset) are in
@@ -405,9 +408,8 @@ void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
// return a high-dpi pixmap, which will in that case have a devicePixelRatio
// different than 1. The shadow drawing caluculations are done in device
// pixels.
- QWindow *window = QApplication::allWidgets().first()->windowHandle();
+ QWindow *window = dynamic_cast<QWidget*>(p->device())->window()->windowHandle();
QPixmap px = icon.pixmap(window, rect.size(), iconMode);
- int devicePixelRatio = qCeil(px.devicePixelRatio());
int radius = dipRadius * devicePixelRatio;
QPoint offset = dipOffset * devicePixelRatio;
cache = QPixmap(px.size() + QSize(radius * 2, radius * 2));
@@ -415,7 +417,8 @@ void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
QPainter cachePainter(&cache);
if (iconMode == QIcon::Disabled) {
- const bool hasDisabledState = icon.availableSizes(QIcon::Disabled).contains(px.size());
+ const bool hasDisabledState =
+ icon.availableSizes().count() == icon.availableSizes(QIcon::Disabled).count();
if (!hasDisabledState)
px = disabledSideBarIcon(icon.pixmap(window, rect.size()));
} else if (creatorTheme()->flag(Theme::ToolBarIconShadow)) {
diff --git a/src/plugins/texteditor/convenience.cpp b/src/libs/utils/textutils.cpp
index 8ee92147ddc..65b7093c5a6 100644
--- a/src/plugins/texteditor/convenience.cpp
+++ b/src/libs/utils/textutils.cpp
@@ -23,14 +23,14 @@
**
****************************************************************************/
-#include "convenience.h"
+#include "textutils.h"
#include <QTextDocument>
#include <QTextBlock>
#include <QTextCursor>
-namespace TextEditor {
-namespace Convenience {
+namespace Utils {
+namespace Text {
bool convertPosition(const QTextDocument *document, int pos, int *line, int *column)
{
@@ -95,6 +95,13 @@ static bool isValidIdentifierChar(const QChar &c)
|| c.isLowSurrogate();
}
+static bool isAfterOperatorKeyword(QTextCursor cursor)
+{
+ cursor.movePosition(QTextCursor::PreviousWord);
+ cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+ return cursor.selectedText() == "operator";
+}
+
QTextCursor wordStartCursor(const QTextCursor &textCursor)
{
const int originalPosition = textCursor.position();
@@ -108,9 +115,11 @@ QTextCursor wordStartCursor(const QTextCursor &textCursor)
if (isValidIdentifierChar(c))
cursor.movePosition(QTextCursor::PreviousWord);
}
+ if (isAfterOperatorKeyword(cursor))
+ cursor.movePosition(QTextCursor::PreviousWord);
return cursor;
}
-} // Util
-} // TextEditor
+} // Text
+} // Utils
diff --git a/src/plugins/texteditor/convenience.h b/src/libs/utils/textutils.h
index f4302cd5f31..9e818842711 100644
--- a/src/plugins/texteditor/convenience.h
+++ b/src/libs/utils/textutils.h
@@ -25,30 +25,28 @@
#pragma once
-#include "texteditor_global.h"
+#include "utils_global.h"
#include <QString>
-QT_BEGIN_NAMESPACE
-class QTextDocument;
-class QTextCursor;
-QT_END_NAMESPACE
+QT_FORWARD_DECLARE_CLASS(QTextDocument)
+QT_FORWARD_DECLARE_CLASS(QTextCursor)
-namespace TextEditor {
-namespace Convenience {
+namespace Utils {
+namespace Text {
// line is 1-based, column is 0-based
-TEXTEDITOR_EXPORT bool convertPosition(const QTextDocument *document,
- int pos,
- int *line, int *column);
+QTCREATOR_UTILS_EXPORT bool convertPosition(const QTextDocument *document,
+ int pos,
+ int *line, int *column);
-TEXTEDITOR_EXPORT QString textAt(QTextCursor tc, int pos, int length);
+QTCREATOR_UTILS_EXPORT QString textAt(QTextCursor tc, int pos, int length);
-TEXTEDITOR_EXPORT QTextCursor selectAt(QTextCursor textCursor, uint line, uint column, uint length);
+QTCREATOR_UTILS_EXPORT QTextCursor selectAt(QTextCursor textCursor, uint line, uint column, uint length);
-TEXTEDITOR_EXPORT QTextCursor flippedCursor(const QTextCursor &cursor);
+QTCREATOR_UTILS_EXPORT QTextCursor flippedCursor(const QTextCursor &cursor);
-TEXTEDITOR_EXPORT QTextCursor wordStartCursor(const QTextCursor &cursor);
+QTCREATOR_UTILS_EXPORT QTextCursor wordStartCursor(const QTextCursor &cursor);
-} // Util
-} // TextEditor
+} // Text
+} // Utils
diff --git a/src/libs/utils/theme/theme.cpp b/src/libs/utils/theme/theme.cpp
index 061ff335ccf..7a4227cd751 100644
--- a/src/libs/utils/theme/theme.cpp
+++ b/src/libs/utils/theme/theme.cpp
@@ -172,7 +172,7 @@ void Theme::readSettings(QSettings &settings)
{
d->displayName = settings.value(QLatin1String("ThemeName"), QLatin1String("unnamed")).toString();
d->preferredStyles = settings.value(QLatin1String("PreferredStyles")).toStringList();
- d->preferredStyles.removeAll(QLatin1String(""));
+ d->preferredStyles.removeAll(QString());
d->defaultTextEditorColorScheme =
settings.value(QLatin1String("DefaultTextEditorColorScheme")).toString();
}
diff --git a/src/libs/utils/tooltip/tooltip.cpp b/src/libs/utils/tooltip/tooltip.cpp
index 47799b75a90..857ec071a79 100644
--- a/src/libs/utils/tooltip/tooltip.cpp
+++ b/src/libs/utils/tooltip/tooltip.cpp
@@ -305,9 +305,11 @@ bool ToolTip::eventFilter(QObject *o, QEvent *event)
switch (event->type()) {
case QEvent::KeyPress:
- case QEvent::KeyRelease:
+ case QEvent::KeyRelease: {
+ int key = static_cast<QKeyEvent *>(event)->key();
+ if (key == Qt::Key_Escape)
+ hideTipImmediately();
if (HostOsInfo::isMacHost()) {
- int key = static_cast<QKeyEvent *>(event)->key();
Qt::KeyboardModifiers mody = static_cast<QKeyEvent *>(event)->modifiers();
if (!(mody & Qt::KeyboardModifierMask)
&& key != Qt::Key_Shift && key != Qt::Key_Control
@@ -315,6 +317,7 @@ bool ToolTip::eventFilter(QObject *o, QEvent *event)
hideTipWithDelay();
}
break;
+ }
case QEvent::Leave:
if (o == m_tip && !m_tip->isAncestorOf(QApplication::focusWidget()))
hideTipWithDelay();
diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp
index 2b94d56311c..61a6a8974c1 100644
--- a/src/libs/utils/treemodel.cpp
+++ b/src/libs/utils/treemodel.cpp
@@ -966,6 +966,18 @@ QModelIndex BaseTreeModel::parent(const QModelIndex &idx) const
return createIndex(i, 0, static_cast<void*>(parent));
}
+QModelIndex BaseTreeModel::sibling(int row, int column, const QModelIndex &idx) const
+{
+ const TreeItem *item = itemForIndex(idx);
+ QTC_ASSERT(item, return QModelIndex());
+ QModelIndex result;
+ if (TreeItem *parent = item->parent()) {
+ if (TreeItem *sibl = parent->childAt(row))
+ result = createIndex(row, column, static_cast<void*>(sibl));
+ }
+ return result;
+}
+
int BaseTreeModel::rowCount(const QModelIndex &idx) const
{
CHECK_INDEX(idx);
@@ -974,8 +986,7 @@ int BaseTreeModel::rowCount(const QModelIndex &idx) const
if (idx.column() > 0)
return 0;
const TreeItem *item = itemForIndex(idx);
- QTC_ASSERT(item, return 0);
- return item->childCount();
+ return item ? item->childCount() : 0;
}
int BaseTreeModel::columnCount(const QModelIndex &idx) const
@@ -1053,9 +1064,10 @@ void BaseTreeModel::setRootItem(TreeItem *item)
QTC_ASSERT(item, return);
QTC_ASSERT(item->m_model == 0, return);
QTC_ASSERT(item->m_parent == 0, return);
+ QTC_ASSERT(item != m_root, return);
QTC_CHECK(m_root);
- emit layoutAboutToBeChanged();
+ beginResetModel();
if (m_root) {
QTC_CHECK(m_root->m_parent == 0);
QTC_CHECK(m_root->m_model == this);
@@ -1067,7 +1079,7 @@ void BaseTreeModel::setRootItem(TreeItem *item)
}
m_root = item;
item->propagateModel(this);
- emit layoutChanged();
+ endResetModel();
}
void BaseTreeModel::setHeader(const QStringList &displays)
@@ -1099,7 +1111,7 @@ TreeItem *BaseTreeModel::itemForIndex(const QModelIndex &idx) const
CHECK_INDEX(idx);
TreeItem *item = idx.isValid() ? static_cast<TreeItem*>(idx.internalPointer()) : m_root;
QTC_ASSERT(item, return 0);
- QTC_ASSERT(item->m_model == this, return 0);
+ QTC_ASSERT(item->m_model == static_cast<const BaseTreeModel *>(this), return 0);
return item;
}
diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h
index 63818b27c22..41300b7dbc4 100644
--- a/src/libs/utils/treemodel.h
+++ b/src/libs/utils/treemodel.h
@@ -188,6 +188,7 @@ protected:
QVariant data(const QModelIndex &idx, int role) const override;
QModelIndex index(int, int, const QModelIndex &idx = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &idx) const override;
+ QModelIndex sibling(int row, int column, const QModelIndex &idx) const override;
Qt::ItemFlags flags(const QModelIndex &idx) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
bool hasChildren(const QModelIndex &idx) const override;
@@ -314,7 +315,7 @@ public:
}
template <class Predicate>
- BestItem *findNonRooItem(const Predicate &pred) const {
+ BestItem *findNonRootItem(const Predicate &pred) const {
const auto pred0 = [pred](TreeItem *treeItem) -> bool { return pred(static_cast<BestItem *>(treeItem)); };
return static_cast<BestItem *>(m_root->findAnyChild(pred0));
}
diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri
index 924d9ba54fc..c181a8e25ae 100644
--- a/src/libs/utils/utils-lib.pri
+++ b/src/libs/utils/utils-lib.pri
@@ -114,7 +114,9 @@ SOURCES += $$PWD/environment.cpp \
$$PWD/runextensions.cpp \
$$PWD/utilsicons.cpp \
$$PWD/guard.cpp \
- $$PWD/highlightingitemdelegate.cpp
+ $$PWD/highlightingitemdelegate.cpp \
+ $$PWD/camelhumpmatcher.cpp \
+ $$PWD/textutils.cpp
win32:SOURCES += $$PWD/consoleprocess_win.cpp
else:SOURCES += $$PWD/consoleprocess_unix.cpp
@@ -242,7 +244,9 @@ HEADERS += \
$$PWD/optional.h \
$$PWD/../3rdparty/optional/optional.hpp \
$$PWD/qtcfallthrough.h \
- $$PWD/highlightingitemdelegate.h
+ $$PWD/highlightingitemdelegate.h \
+ $$PWD/camelhumpmatcher.h \
+ $$PWD/textutils.h
FORMS += $$PWD/filewizardpage.ui \
$$PWD/projectintropage.ui \
diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs
index 0c0562acaf7..56b1b31e608 100644
--- a/src/libs/utils/utils.qbs
+++ b/src/libs/utils/utils.qbs
@@ -52,6 +52,8 @@ Project {
"bracematcher.h",
"buildablehelperlibrary.cpp",
"buildablehelperlibrary.h",
+ "camelhumpmatcher.cpp",
+ "camelhumpmatcher.h",
"categorysortfiltermodel.cpp",
"categorysortfiltermodel.h",
"changeset.cpp",
@@ -230,6 +232,8 @@ Project {
"textfieldcombobox.h",
"textfileformat.cpp",
"textfileformat.h",
+ "textutils.cpp",
+ "textutils.h",
"treemodel.cpp",
"treemodel.h",
"treeviewcombobox.cpp",
diff --git a/src/libs/utils/utils.qrc b/src/libs/utils/utils.qrc
index da30fa3c511..63ca09e10f5 100644
--- a/src/libs/utils/utils.qrc
+++ b/src/libs/utils/utils.qrc
@@ -35,7 +35,6 @@
<file>images/clean_pane_small@2x.png</file>
<file>images/compile_error_taskbar.png</file>
<file>images/compile_error_taskbar@2x.png</file>
- <file>images/dir.png</file>
<file>images/editcopy.png</file>
<file>images/editcopy@2x.png</file>
<file>images/editcut.png</file>
@@ -43,6 +42,7 @@
<file>images/editpaste.png</file>
<file>images/editpaste@2x.png</file>
<file>images/empty14.png</file>
+ <file>images/empty16.png</file>
<file>images/filenew.png</file>
<file>images/filenew@2x.png</file>
<file>images/fileopen.png</file>
@@ -88,12 +88,10 @@
<file>images/splitbutton_horizontal@2x.png</file>
<file>images/undo.png</file>
<file>images/undo@2x.png</file>
- <file>images/unknownfile.png</file>
<file>images/extension.png</file>
<file>images/extension@2x.png</file>
<file>images/progressbar.png</file>
<file>images/progressbar@2x.png</file>
- <file>images/help.png</file>
<file>images/editclear.png</file>
<file>images/editclear@2x.png</file>
<file>images/arrowdown.png</file>
diff --git a/src/libs/utils/utilsicons.cpp b/src/libs/utils/utilsicons.cpp
index 27db225e0c0..271d3122f66 100644
--- a/src/libs/utils/utilsicons.cpp
+++ b/src/libs/utils/utilsicons.cpp
@@ -215,6 +215,7 @@ const Icon COLLAPSE_TOOLBAR({
const Icon PAN_TOOLBAR({
{QLatin1String(":/utils/images/pan.png"), Theme::IconsBaseColor}});
const Icon EMPTY14(":/utils/images/empty14.png");
+const Icon EMPTY16(":/utils/images/empty16.png");
const Icon OVERLAY_ADD({
{":/utils/images/iconoverlay_add_background.png", Theme::BackgroundColorNormal},
{":/utils/images/iconoverlay_add.png", Theme::IconsRunColor}}, Icon::Tint);
diff --git a/src/libs/utils/utilsicons.h b/src/libs/utils/utilsicons.h
index 2e3e083e19b..5725e9a5382 100644
--- a/src/libs/utils/utilsicons.h
+++ b/src/libs/utils/utilsicons.h
@@ -125,6 +125,7 @@ QTCREATOR_UTILS_EXPORT extern const Icon COLLAPSE;
QTCREATOR_UTILS_EXPORT extern const Icon COLLAPSE_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon PAN_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon EMPTY14;
+QTCREATOR_UTILS_EXPORT extern const Icon EMPTY16;
QTCREATOR_UTILS_EXPORT extern const Icon OVERLAY_ADD;
QTCREATOR_UTILS_EXPORT extern const Icon OVERLAY_WARNING;
QTCREATOR_UTILS_EXPORT extern const Icon OVERLAY_ERROR;
diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs
index 4fccdaddcf8..e886ab8c3e0 100644
--- a/src/plugins/android/android.qbs
+++ b/src/plugins/android/android.qbs
@@ -15,6 +15,7 @@ Project {
Depends { name: "QtSupport" }
Depends { name: "TextEditor" }
Depends { name: "Utils" }
+ Depends { name: "app_version_header" }
files: [
"android_global.h",
diff --git a/src/plugins/android/androidanalyzesupport.cpp b/src/plugins/android/androidanalyzesupport.cpp
index 59ccb047ca4..391be4b500a 100644
--- a/src/plugins/android/androidanalyzesupport.cpp
+++ b/src/plugins/android/androidanalyzesupport.cpp
@@ -42,7 +42,7 @@ AndroidQmlProfilerSupport::AndroidQmlProfilerSupport(RunControl *runControl)
auto profiler = runControl->createWorker(runControl->runMode());
profiler->addStartDependency(this);
- connect(runner, &AndroidRunner::qmlServerReady, [this, runner, profiler](const QUrl &server) {
+ connect(runner, &AndroidRunner::qmlServerReady, this, [this, profiler](const QUrl &server) {
profiler->recordData("QmlServerUrl", server);
reportStarted();
});
diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp
index a8bb143a756..8ed1316a253 100644
--- a/src/plugins/android/androidbuildapkstep.cpp
+++ b/src/plugins/android/androidbuildapkstep.cpp
@@ -65,8 +65,6 @@ const char DeployActionKey[] = "Qt4ProjectManager.AndroidDeployQtStep.DeployQtAc
const char KeystoreLocationKey[] = "KeystoreLocation";
const char BuildTargetSdkKey[] = "BuildTargetSdk";
const char VerboseOutputKey[] = "VerboseOutput";
-const char UseGradleKey[] = "UseGradle";
-
class PasswordInputDialog : public QDialog {
public:
@@ -96,9 +94,6 @@ AndroidBuildApkStep::AndroidBuildApkStep(ProjectExplorer::BuildStepList *parent,
: ProjectExplorer::AbstractProcessStep(parent, id),
m_buildTargetSdk(AndroidConfig::apiLevelNameFor(AndroidConfigurations::currentConfig().highestAndroidSdk()))
{
- const QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit());
- if (version && version->qtVersion() >= QtSupport::QtVersionNumber(5, 4, 0))
- m_useGradle = AndroidConfigurations::currentConfig().useGrandle();
//: AndroidBuildApkStep default display name
setDefaultDisplayName(tr("Build Android APK"));
}
@@ -109,18 +104,10 @@ AndroidBuildApkStep::AndroidBuildApkStep(ProjectExplorer::BuildStepList *parent,
m_deployAction(other->deployAction()),
m_signPackage(other->signPackage()),
m_verbose(other->m_verbose),
- m_useGradle(other->m_useGradle),
m_openPackageLocation(other->m_openPackageLocation),
// leave m_openPackageLocationForRun at false
m_buildTargetSdk(other->m_buildTargetSdk)
{
- const QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit());
- if (version->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0)) {
- if (m_deployAction == DebugDeployment)
- m_deployAction = BundleLibrariesDeployment;
- if (m_useGradle)
- m_useGradle = false;
- }
}
bool AndroidBuildApkStep::init(QList<const BuildStep *> &earlierSteps)
@@ -142,11 +129,18 @@ bool AndroidBuildApkStep::init(QList<const BuildStep *> &earlierSteps)
return false;
const QVersionNumber sdkToolsVersion = AndroidConfigurations::currentConfig().sdkToolsVersion();
- if (sdkToolsVersion >= gradleScriptRevokedSdkVersion &&
- !version->sourcePath().appendPath("src/3rdparty/gradle").exists()) {
- emit addOutput(tr("The installed SDK tools version (%1) does not include Gradle scripts. The "
- "minimum Qt version required for Gradle build to work is %2")
- .arg(sdkToolsVersion.toString()).arg("5.9.0/5.6.3"), OutputFormat::Stderr);
+ if (sdkToolsVersion >= gradleScriptRevokedSdkVersion) {
+ if (!version->sourcePath().appendPath("src/3rdparty/gradle").exists()) {
+ emit addOutput(tr("The installed SDK tools version (%1) does not include Gradle "
+ "scripts. The minimum Qt version required for Gradle build to work "
+ "is %2").arg(sdkToolsVersion.toString()).arg("5.9.0/5.6.3"),
+ OutputFormat::Stderr);
+ return false;
+ }
+ } else if (version->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0)) {
+ emit addOutput(tr("The minimum Qt version required for Gradle build to work is %2. "
+ "It is recommended to install the latest Qt version.")
+ .arg("5.4.0"), OutputFormat::Stderr);
return false;
}
@@ -193,7 +187,7 @@ void AndroidBuildApkStep::processFinished(int exitCode, QProcess::ExitStatus sta
bool AndroidBuildApkStep::verifyKeystorePassword()
{
if (!m_keystorePath.exists()) {
- addOutput(tr("Cannot sign the package. Invalid keystore path(%1).")
+ addOutput(tr("Cannot sign the package. Invalid keystore path (%1).")
.arg(m_keystorePath.toString()), OutputFormat::ErrorMessage);
return false;
}
@@ -237,18 +231,14 @@ bool AndroidBuildApkStep::verifyCertificatePassword()
bool AndroidBuildApkStep::fromMap(const QVariantMap &map)
{
m_deployAction = AndroidDeployAction(map.value(DeployActionKey, BundleLibrariesDeployment).toInt());
- if ( m_deployAction == DebugDeployment
- && QtSupport::QtKitInformation::qtVersion(target()->kit())->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0)) {
- m_deployAction = BundleLibrariesDeployment;
- }
-
+ if (m_deployAction > BundleLibrariesDeployment)
+ m_deployAction = BundleLibrariesDeployment; // BundleLibrariesDeployment used to be 2
m_keystorePath = Utils::FileName::fromString(map.value(KeystoreLocationKey).toString());
m_signPackage = false; // don't restore this
m_buildTargetSdk = map.value(BuildTargetSdkKey).toString();
if (m_buildTargetSdk.isEmpty())
m_buildTargetSdk = AndroidConfig::apiLevelNameFor(AndroidConfigurations::currentConfig().highestAndroidSdk());
m_verbose = map.value(VerboseOutputKey).toBool();
- m_useGradle = map.value(UseGradleKey).toBool();
return ProjectExplorer::BuildStep::fromMap(map);
}
@@ -259,7 +249,6 @@ QVariantMap AndroidBuildApkStep::toMap() const
map.insert(KeystoreLocationKey, m_keystorePath.toString());
map.insert(BuildTargetSdkKey, m_buildTargetSdk);
map.insert(VerboseOutputKey, m_verbose);
- map.insert(UseGradleKey, m_useGradle);
return map;
}
@@ -276,8 +265,7 @@ QString AndroidBuildApkStep::buildTargetSdk() const
void AndroidBuildApkStep::setBuildTargetSdk(const QString &sdk)
{
m_buildTargetSdk = sdk;
- if (m_useGradle)
- AndroidManager::updateGradleProperties(target());
+ AndroidManager::updateGradleProperties(target());
}
AndroidBuildApkStep::AndroidDeployAction AndroidBuildApkStep::deployAction() const
@@ -337,21 +325,6 @@ void AndroidBuildApkStep::setVerboseOutput(bool verbose)
m_verbose = verbose;
}
-bool AndroidBuildApkStep::useGradle() const
-{
- return m_useGradle;
-}
-
-void AndroidBuildApkStep::setUseGradle(bool b)
-{
- if (m_useGradle != b) {
- m_useGradle = b;
- if (m_useGradle)
- AndroidManager::updateGradleProperties(target());
- emit useGradleChanged();
- }
-}
-
bool AndroidBuildApkStep::addDebugger() const
{
return m_addDebugger;
diff --git a/src/plugins/android/androidbuildapkstep.h b/src/plugins/android/androidbuildapkstep.h
index eae827eb15f..ce9edebc110 100644
--- a/src/plugins/android/androidbuildapkstep.h
+++ b/src/plugins/android/androidbuildapkstep.h
@@ -44,7 +44,6 @@ public:
enum AndroidDeployAction
{
MinistroDeployment, // use ministro
- DebugDeployment,
BundleLibrariesDeployment
};
@@ -70,9 +69,6 @@ public:
bool verboseOutput() const;
void setVerboseOutput(bool verbose);
- bool useGradle() const;
- void setUseGradle(bool b);
-
bool addDebugger() const;
void setAddDebugger(bool debug);
@@ -82,9 +78,6 @@ public:
virtual Utils::FileName androidPackageSourceDir() const = 0;
void setDeployAction(AndroidDeployAction deploy);
-signals:
- void useGradleChanged();
-
protected:
Q_INVOKABLE void showInGraphicalShell();
@@ -102,7 +95,6 @@ protected:
AndroidDeployAction m_deployAction = BundleLibrariesDeployment;
bool m_signPackage = false;
bool m_verbose = false;
- bool m_useGradle = true; // Ant builds are deprecated.
bool m_openPackageLocation = false;
bool m_openPackageLocationForRun = false;
bool m_addDebugger = true;
diff --git a/src/plugins/android/androidbuildapkwidget.cpp b/src/plugins/android/androidbuildapkwidget.cpp
index 97dd4695bde..73c1ad531c3 100644
--- a/src/plugins/android/androidbuildapkwidget.cpp
+++ b/src/plugins/android/androidbuildapkwidget.cpp
@@ -54,8 +54,6 @@ AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
{
m_ui->setupUi(this);
- m_ui->deprecatedInfoIconLabel->setPixmap(Utils::Icons::INFO.pixmap());
-
// Target sdk combobox
int minApiLevel = 9;
const AndroidConfig &config = AndroidConfigurations::currentConfig();
@@ -69,9 +67,6 @@ AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
case AndroidBuildApkStep::MinistroDeployment:
m_ui->ministroOption->setChecked(true);
break;
- case AndroidBuildApkStep::DebugDeployment:
- m_ui->temporaryQtOption->setChecked(true);
- break;
case AndroidBuildApkStep::BundleLibrariesDeployment:
m_ui->bundleQtOption->setChecked(true);
break;
@@ -91,12 +86,8 @@ AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
m_ui->signingDebugWarningIcon->setPixmap(Utils::Icons::WARNING.pixmap());
m_ui->signingDebugWarningIcon->hide();
m_ui->signingDebugWarningLabel->hide();
- m_ui->signingDebugDeployErrorIcon->setPixmap(Utils::Icons::CRITICAL.pixmap());
signPackageCheckBoxToggled(m_step->signPackage());
- m_ui->useGradleCheckBox->setEnabled(config.antScriptsAvailable());
- m_ui->useGradleCheckBox->setChecked(!config.antScriptsAvailable() ||
- m_step->useGradle());
m_ui->verboseOutputCheckBox->setChecked(m_step->verboseOutput());
m_ui->openPackageLocationCheckBox->setChecked(m_step->openPackageLocation());
m_ui->addDebuggerCheckBox->setChecked(m_step->addDebugger());
@@ -109,19 +100,9 @@ AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
// deployment options
connect(m_ui->ministroOption, &QAbstractButton::clicked,
this, &AndroidBuildApkWidget::setMinistro);
- connect(m_ui->temporaryQtOption, &QAbstractButton::clicked,
- this, &AndroidBuildApkWidget::setDeployLocalQtLibs);
connect(m_ui->bundleQtOption, &QAbstractButton::clicked,
this, &AndroidBuildApkWidget::setBundleQtLibs);
- connect(m_ui->ministroOption, &QAbstractButton::clicked,
- this, &AndroidBuildApkWidget::updateDebugDeploySigningWarning);
- connect(m_ui->temporaryQtOption, &QAbstractButton::clicked,
- this, &AndroidBuildApkWidget::updateDebugDeploySigningWarning);
- connect(m_ui->bundleQtOption, &QAbstractButton::clicked,
- this, &AndroidBuildApkWidget::updateDebugDeploySigningWarning);
- connect(m_ui->useGradleCheckBox, &QAbstractButton::toggled,
- this, &AndroidBuildApkWidget::useGradleCheckBoxToggled);
connect(m_ui->openPackageLocationCheckBox, &QAbstractButton::toggled,
this, &AndroidBuildApkWidget::openPackageLocationCheckBoxToggled);
connect(m_ui->verboseOutputCheckBox, &QAbstractButton::toggled,
@@ -147,11 +128,6 @@ AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
this, &AndroidBuildApkWidget::updateSigningWarning);
updateSigningWarning();
- updateDebugDeploySigningWarning();
- QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(step->target()->kit());
- bool qt54 = qt->qtVersion() >= QtSupport::QtVersionNumber(5, 4, 0);
- m_ui->temporaryQtOption->setVisible(qt54);
- m_ui->useGradleCheckBox->setVisible(qt54);
}
AndroidBuildApkWidget::~AndroidBuildApkWidget()
@@ -179,11 +155,6 @@ void AndroidBuildApkWidget::setMinistro()
m_step->setDeployAction(AndroidBuildApkStep::MinistroDeployment);
}
-void AndroidBuildApkWidget::setDeployLocalQtLibs()
-{
- m_step->setDeployAction(AndroidBuildApkStep::DebugDeployment);
-}
-
void AndroidBuildApkWidget::setBundleQtLibs()
{
m_step->setDeployAction(AndroidBuildApkStep::BundleLibrariesDeployment);
@@ -266,22 +237,3 @@ void AndroidBuildApkWidget::updateSigningWarning()
m_ui->signingDebugWarningLabel->setVisible(false);
}
}
-
-void AndroidBuildApkWidget::updateDebugDeploySigningWarning()
-{
- if (m_step->deployAction() == AndroidBuildApkStep::DebugDeployment) {
- m_ui->signingDebugDeployError->setVisible(true);
- m_ui->signingDebugDeployErrorIcon->setVisible(true);
- m_ui->signPackageCheckBox->setChecked(false);
- m_ui->signPackageCheckBox->setEnabled(false);
- } else {
- m_ui->signingDebugDeployError->setVisible(false);
- m_ui->signingDebugDeployErrorIcon->setVisible(false);
- m_ui->signPackageCheckBox->setEnabled(true);
- }
-}
-
-void AndroidBuildApkWidget::useGradleCheckBoxToggled(bool checked)
-{
- m_step->setUseGradle(checked);
-}
diff --git a/src/plugins/android/androidbuildapkwidget.h b/src/plugins/android/androidbuildapkwidget.h
index e4d46a99a23..3a0576d6df6 100644
--- a/src/plugins/android/androidbuildapkwidget.h
+++ b/src/plugins/android/androidbuildapkwidget.h
@@ -52,14 +52,11 @@ public:
private:
void setTargetSdk(const QString &sdk);
void setMinistro();
- void setDeployLocalQtLibs();
void setBundleQtLibs();
void createKeyStore();
void certificatesAliasComboBoxCurrentIndexChanged(const QString &alias);
void certificatesAliasComboBoxActivated(const QString &alias);
void updateSigningWarning();
- void updateDebugDeploySigningWarning();
- void useGradleCheckBoxToggled(bool checked);
void openPackageLocationCheckBoxToggled(bool checked);
void verboseOutputCheckBoxToggled(bool checked);
void updateKeyStorePath(const QString &path);
diff --git a/src/plugins/android/androidbuildapkwidget.ui b/src/plugins/android/androidbuildapkwidget.ui
index fa3c1ef3d66..8e22e4043a3 100644
--- a/src/plugins/android/androidbuildapkwidget.ui
+++ b/src/plugins/android/androidbuildapkwidget.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>819</width>
- <height>478</height>
+ <width>641</width>
+ <height>331</height>
</rect>
</property>
<property name="windowTitle">
@@ -117,37 +117,6 @@
</item>
</layout>
</item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <item>
- <widget class="QLabel" name="signingDebugDeployErrorIcon">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="signingDebugDeployError">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Signing an APK that uses &quot;Deploy local Qt libraries&quot; is not allowed.
-Deploying local Qt libraries is incompatible with Android 5.</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
</layout>
</widget>
</item>
@@ -176,66 +145,21 @@ Deploying local Qt libraries is incompatible with Android 5.</string>
<string>Advanced Actions</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QCheckBox" name="useGradleCheckBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Use Gradle (Ant builds are deprecated)</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="deprecatedInfoIconLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Gradle builds are forced from Android SDK tools version 25.3.0 onwards as Ant scripts are no longer available.</string>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Preferred</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="0" colspan="3">
+ <item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="openPackageLocationCheckBox">
<property name="text">
<string>Open package location after build</string>
</property>
</widget>
</item>
- <item row="2" column="0" colspan="3">
+ <item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="verboseOutputCheckBox">
<property name="text">
<string>Verbose output</string>
</property>
</widget>
</item>
- <item row="3" column="0" colspan="3">
+ <item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="addDebuggerCheckBox">
<property name="enabled">
<bool>false</bool>
@@ -280,17 +204,6 @@ Deploying local Qt libraries is incompatible with Android 5.</string>
</property>
</widget>
</item>
- <item>
- <widget class="QRadioButton" name="temporaryQtOption">
- <property name="toolTip">
- <string>Pushes local Qt libraries to device. You must have Qt libraries compiled for that platform.
-The APK will not be usable on any other device.</string>
- </property>
- <property name="text">
- <string>Deploy local Qt libraries to temporary directory</string>
- </property>
- </widget>
- </item>
</layout>
</widget>
</item>
diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp
index cba8f4d438d..b52810e93f0 100644
--- a/src/plugins/android/androidconfigurations.cpp
+++ b/src/plugins/android/androidconfigurations.cpp
@@ -84,16 +84,13 @@ using namespace Internal;
namespace {
const char jdkSettingsPath[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit";
- const QVersionNumber sdkToolsAntMissingVersion(25, 3, 0);
const QLatin1String SettingsGroup("AndroidConfigurations");
const QLatin1String SDKLocationKey("SDKLocation");
const QLatin1String NDKLocationKey("NDKLocation");
- const QLatin1String AntLocationKey("AntLocation");
const QLatin1String OpenJDKLocationKey("OpenJDKLocation");
const QLatin1String KeystoreLocationKey("KeystoreLocation");
const QLatin1String AutomaticKitCreationKey("AutomatiKitCreation");
- const QLatin1String UseGradleKey("UseGradle");
const QLatin1String MakeExtraSearchDirectory("MakeExtraSearchDirectory");
const QLatin1String PartitionSizeKey("PartitionSize");
const QLatin1String ToolchainHostKey("ToolchainHost");
@@ -250,8 +247,6 @@ void AndroidConfig::load(const QSettings &settings)
m_partitionSize = settings.value(PartitionSizeKey, 1024).toInt();
m_sdkLocation = FileName::fromString(settings.value(SDKLocationKey).toString());
m_ndkLocation = FileName::fromString(settings.value(NDKLocationKey).toString());
- m_antLocation = FileName::fromString(settings.value(AntLocationKey).toString());
- m_useGradle = settings.value(UseGradleKey, false).toBool();
m_openJDKLocation = FileName::fromString(settings.value(OpenJDKLocationKey).toString());
m_keystoreLocation = FileName::fromString(settings.value(KeystoreLocationKey).toString());
m_toolchainHost = settings.value(ToolchainHostKey).toString();
@@ -267,7 +262,6 @@ void AndroidConfig::load(const QSettings &settings)
// persisten settings
m_sdkLocation = FileName::fromString(reader.restoreValue(SDKLocationKey, m_sdkLocation.toString()).toString());
m_ndkLocation = FileName::fromString(reader.restoreValue(NDKLocationKey, m_ndkLocation.toString()).toString());
- m_antLocation = FileName::fromString(reader.restoreValue(AntLocationKey, m_antLocation.toString()).toString());
m_openJDKLocation = FileName::fromString(reader.restoreValue(OpenJDKLocationKey, m_openJDKLocation.toString()).toString());
m_keystoreLocation = FileName::fromString(reader.restoreValue(KeystoreLocationKey, m_keystoreLocation.toString()).toString());
m_toolchainHost = reader.restoreValue(ToolchainHostKey, m_toolchainHost).toString();
@@ -291,8 +285,6 @@ void AndroidConfig::save(QSettings &settings) const
// user settings
settings.setValue(SDKLocationKey, m_sdkLocation.toString());
settings.setValue(NDKLocationKey, m_ndkLocation.toString());
- settings.setValue(AntLocationKey, m_antLocation.toString());
- settings.setValue(UseGradleKey, m_useGradle);
settings.setValue(OpenJDKLocationKey, m_openJDKLocation.toString());
settings.setValue(KeystoreLocationKey, m_keystoreLocation.toString());
settings.setValue(PartitionSizeKey, m_partitionSize);
@@ -400,14 +392,6 @@ FileName AndroidConfig::androidToolPath() const
}
}
-FileName AndroidConfig::antToolPath() const
-{
- if (!m_antLocation.isEmpty())
- return m_antLocation;
- else
- return FileName::fromLatin1("ant");
-}
-
FileName AndroidConfig::emulatorToolPath() const
{
FileName path = m_sdkLocation;
@@ -775,6 +759,17 @@ QVersionNumber AndroidConfig::sdkToolsVersion() const
return version;
}
+QVersionNumber AndroidConfig::buildToolsVersion() const
+{
+ QVersionNumber maxVersion;
+ Utils::FileName buildtoolsDir = m_sdkLocation;
+ buildtoolsDir.appendPath("build-tools");
+ QDir buildToolsDir(buildtoolsDir.toString());
+ for (const QFileInfo &file: buildToolsDir.entryList(QDir::Dirs|QDir::NoDotAndDotDot))
+ maxVersion = qMax(maxVersion, QVersionNumber::fromString(file.fileName()));
+ return maxVersion;
+}
+
FileName AndroidConfig::ndkLocation() const
{
return m_ndkLocation;
@@ -833,16 +828,6 @@ void AndroidConfig::setNdkLocation(const FileName &ndkLocation)
m_NdkInformationUpToDate = false;
}
-FileName AndroidConfig::antLocation() const
-{
- return m_antLocation;
-}
-
-void AndroidConfig::setAntLocation(const FileName &antLocation)
-{
- m_antLocation = antLocation;
-}
-
FileName AndroidConfig::openJDKLocation() const
{
return m_openJDKLocation;
@@ -895,25 +880,6 @@ void AndroidConfig::setAutomaticKitCreation(bool b)
m_automaticKitCreation = b;
}
-bool AndroidConfig::antScriptsAvailable() const
-{
- return sdkToolsVersion() < sdkToolsAntMissingVersion;
-}
-
-bool AndroidConfig::useGrandle() const
-{
- if (antScriptsAvailable()) {
- return m_useGradle;
- }
- // Force gradle builds.
- return true;
-}
-
-void AndroidConfig::setUseGradle(bool b)
-{
- m_useGradle = b;
-}
-
///////////////////////////////////
// AndroidConfigurations
///////////////////////////////////
@@ -930,11 +896,10 @@ void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs)
}
AndroidDeviceInfo AndroidConfigurations::showDeviceDialog(Project *project,
- int apiLevel, const QString &abi,
- Options options)
+ int apiLevel, const QString &abi)
{
QString serialNumber = defaultDevice(project, abi);
- AndroidDeviceDialog dialog(apiLevel, abi, options, serialNumber, Core::ICore::mainWindow());
+ AndroidDeviceDialog dialog(apiLevel, abi, serialNumber, Core::ICore::mainWindow());
AndroidDeviceInfo info = dialog.device();
if (dialog.saveDeviceSelection() && info.isValid()) {
const QString serialNumber = info.type == AndroidDeviceInfo::Hardware ?
@@ -1215,16 +1180,6 @@ void AndroidConfigurations::load()
settings->beginGroup(SettingsGroup);
m_config.load(*settings);
- if (m_config.antLocation().isEmpty()) {
- Environment env = Environment::systemEnvironment();
- FileName location = env.searchInPath(QLatin1String("ant"));
- QFileInfo fi = location.toFileInfo();
- if (fi.exists() && fi.isExecutable() && !fi.isDir()) {
- m_config.setAntLocation(location);
- saveSettings = true;
- }
- }
-
if (m_config.openJDKLocation().isEmpty()) {
if (HostOsInfo::isLinuxHost()) {
Environment env = Environment::systemEnvironment();
diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h
index d5c59936d32..75b6dd16abc 100644
--- a/src/plugins/android/androidconfigurations.h
+++ b/src/plugins/android/androidconfigurations.h
@@ -113,14 +113,12 @@ public:
Utils::FileName sdkLocation() const;
void setSdkLocation(const Utils::FileName &sdkLocation);
QVersionNumber sdkToolsVersion() const;
+ QVersionNumber buildToolsVersion() const;
Utils::FileName ndkLocation() const;
QVersionNumber ndkVersion() const;
void setNdkLocation(const Utils::FileName &ndkLocation);
- Utils::FileName antLocation() const;
- void setAntLocation(const Utils::FileName &antLocation);
-
Utils::FileName openJDKLocation() const;
void setOpenJDKLocation(const Utils::FileName &openJDKLocation);
@@ -136,14 +134,8 @@ public:
bool automaticKitCreation() const;
void setAutomaticKitCreation(bool b);
- bool antScriptsAvailable() const;
-
- bool useGrandle() const;
- void setUseGradle(bool b);
-
Utils::FileName adbToolPath() const;
Utils::FileName androidToolPath() const;
- Utils::FileName antToolPath() const;
Utils::FileName emulatorToolPath() const;
Utils::FileName sdkManagerToolPath() const;
Utils::FileName avdManagerToolPath() const;
@@ -202,13 +194,11 @@ private:
Utils::FileName m_sdkLocation;
Utils::FileName m_ndkLocation;
- Utils::FileName m_antLocation;
Utils::FileName m_openJDKLocation;
Utils::FileName m_keystoreLocation;
QStringList m_makeExtraSearchDirectories;
unsigned m_partitionSize = 1024;
bool m_automaticKitCreation = true;
- bool m_useGradle = true; // Ant builds are deprecated.
//caches
mutable bool m_availableSdkPlatformsUpToDate = false;
@@ -232,8 +222,7 @@ public:
static AndroidConfigurations *instance();
static void updateAndroidDevice();
- enum Options { None, FilterAndroid5 };
- static AndroidDeviceInfo showDeviceDialog(ProjectExplorer::Project *project, int apiLevel, const QString &abi, Options options);
+ static AndroidDeviceInfo showDeviceDialog(ProjectExplorer::Project *project, int apiLevel, const QString &abi);
static void setDefaultDevice(ProjectExplorer::Project *project, const QString &abi, const QString &serialNumber); // serial number or avd name
static QString defaultDevice(ProjectExplorer::Project *project, const QString &abi); // serial number or avd name
static void clearDefaultDevices(ProjectExplorer::Project *project);
diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp
index d6036231cb0..e7ada2d28b1 100644
--- a/src/plugins/android/androiddebugsupport.cpp
+++ b/src/plugins/android/androiddebugsupport.cpp
@@ -33,7 +33,6 @@
#include <debugger/debuggerkitinformation.h>
#include <debugger/debuggerrunconfigurationaspect.h>
#include <debugger/debuggerruncontrol.h>
-#include <debugger/debuggerstartparameters.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/project.h>
@@ -108,43 +107,40 @@ void AndroidDebugSupport::start()
Target *target = runConfig->target();
Kit *kit = target->kit();
- DebuggerStartParameters params;
- params.startMode = AttachToRemoteServer;
- params.displayName = AndroidManager::packageName(target);
- params.useContinueInsteadOfRun = true;
- params.attachPID = m_runner->pid();
+ setStartMode(AttachToRemoteServer);
+ setRunControlName(AndroidManager::packageName(target));
+ setUseContinueInsteadOfRun(true);
+ setAttachPid(m_runner->pid());
+
if (!Utils::HostOsInfo::isWindowsHost() &&
AndroidConfigurations::currentConfig().ndkVersion() >= QVersionNumber(11, 0, 0)) {
- params.useTargetAsync = true;
+ setUseTargetAsync(true);
}
+ QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(kit);
+
if (isCppDebugging()) {
- Utils::Port gdbServerPort = m_runner->gdbServerPort();
- params.symbolFile = target->activeBuildConfiguration()->buildDirectory().toString() + "/app_process";
- params.skipExecutableValidation = true;
- params.useExtendedRemote = true;
- params.remoteChannel = ":" + gdbServerPort.toString();
- params.solibSearchPath = AndroidManager::androidQtSupport(target)->soLibSearchPath(target);
- QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit);
- params.solibSearchPath.append(qtSoPaths(version));
- params.solibSearchPath.append(uniquePaths(AndroidManager::androidQtSupport(target)->androidExtraLibs(target)));
- params.sysRoot = AndroidConfigurations::currentConfig().ndkLocation().appendPath("platforms")
- .appendPath(QString("android-%1").arg(AndroidManager::minimumSDK(target)))
- .appendPath(toNdkArch(AndroidManager::targetArch(target))).toString();
+ AndroidQtSupport *qtSupport = AndroidManager::androidQtSupport(target);
+ QStringList solibSearchPath = qtSupport->soLibSearchPath(target);
+ solibSearchPath.append(qtSoPaths(qtVersion));
+ solibSearchPath.append(uniquePaths(qtSupport->androidExtraLibs(target)));
+ setSolibSearchPath(solibSearchPath);
+ setSymbolFile(target->activeBuildConfiguration()->buildDirectory().toString()
+ + "/app_process");
+ setSkipExecutableValidation(true);
+ setUseExtendedRemote(true);
+ setRemoteChannel(":" + m_runner->gdbServerPort().toString());
+ setSysRoot(AndroidConfigurations::currentConfig().ndkLocation().appendPath("platforms")
+ .appendPath(QString("android-%1").arg(AndroidManager::minimumSDK(target)))
+ .appendPath(toNdkArch(AndroidManager::targetArch(target))).toString());
}
if (isQmlDebugging()) {
- params.qmlServer.host = m_runner->qmlServerHost();
- params.qmlServer.port = m_runner->qmlServerPort();
+ setQmlServer(m_runner->qmlServer());
//TODO: Not sure if these are the right paths.
- QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit);
- if (version) {
- const QString qmlQtDir = version->qmakeProperty("QT_INSTALL_QML");
- params.additionalSearchDirectories = QStringList(qmlQtDir);
- }
+ if (qtVersion)
+ addSearchDirectory(qtVersion->qmakeProperty("QT_INSTALL_QML"));
}
- setStartParameters(params);
-
// FIXME: Move signal to base class and generalize handling.
connect(this, &DebuggerRunTool::aboutToNotifyInferiorSetupOk,
m_runner, &AndroidRunner::remoteDebuggerRunning);
diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp
index b4bfbc7bc16..79693a0896e 100644
--- a/src/plugins/android/androiddeployqtstep.cpp
+++ b/src/plugins/android/androiddeployqtstep.cpp
@@ -161,12 +161,9 @@ bool AndroidDeployQtStep::init(QList<const BuildStep *> &earlierSteps)
}
int deviceAPILevel = AndroidManager::minimumSDK(target());
- AndroidConfigurations::Options options = AndroidConfigurations::None;
- if (androidBuildApkStep->deployAction() == AndroidBuildApkStep::DebugDeployment)
- options = AndroidConfigurations::FilterAndroid5;
AndroidDeviceInfo info = earlierDeviceInfo(earlierSteps, Id);
if (!info.isValid()) {
- info = AndroidConfigurations::showDeviceDialog(project(), deviceAPILevel, m_targetArch, options);
+ info = AndroidConfigurations::showDeviceDialog(project(), deviceAPILevel, m_targetArch);
m_deviceInfo = info; // Keep around for later steps
}
@@ -232,15 +229,12 @@ bool AndroidDeployQtStep::init(QList<const BuildStep *> &earlierSteps)
case AndroidBuildApkStep::MinistroDeployment:
Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("ministro"));
break;
- case AndroidBuildApkStep::DebugDeployment:
- Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("debug"));
- break;
case AndroidBuildApkStep::BundleLibrariesDeployment:
Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("bundled"));
break;
}
- if (androidBuildApkStep->useGradle())
- Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("--gradle"));
+
+ Utils::QtcProcess::addArg(&m_androiddeployqtArgs, QLatin1String("--gradle"));
if (androidBuildApkStep->signPackage()) {
// The androiddeployqt tool is not really written to do stand-alone installations.
diff --git a/src/plugins/android/androiddevicedialog.cpp b/src/plugins/android/androiddevicedialog.cpp
index 451abf2dc53..67cd02e9f84 100644
--- a/src/plugins/android/androiddevicedialog.cpp
+++ b/src/plugins/android/androiddevicedialog.cpp
@@ -237,7 +237,7 @@ class AndroidDeviceModel : public QAbstractItemModel
{
Q_OBJECT
public:
- AndroidDeviceModel(int apiLevel, const QString &abi, AndroidConfigurations::Options options);
+ AndroidDeviceModel(int apiLevel, const QString &abi);
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &child) const;
@@ -253,7 +253,6 @@ public:
private:
int m_apiLevel;
QString m_abi;
- AndroidConfigurations::Options m_options;
AndroidDeviceModelNode *m_root;
};
@@ -262,8 +261,8 @@ private:
/////////////////
// AndroidDeviceModel
/////////////////
-AndroidDeviceModel::AndroidDeviceModel(int apiLevel, const QString &abi, AndroidConfigurations::Options options)
- : m_apiLevel(apiLevel), m_abi(abi), m_options(options), m_root(0)
+AndroidDeviceModel::AndroidDeviceModel(int apiLevel, const QString &abi)
+ : m_apiLevel(apiLevel), m_abi(abi), m_root(0)
{
}
@@ -372,8 +371,6 @@ void AndroidDeviceModel::setDevices(const QVector<AndroidDeviceInfo> &devices)
} else if (device.sdk < m_apiLevel) {
error = AndroidDeviceDialog::tr("API Level of device is: %1.")
.arg(device.sdk);
- } else if (device.sdk > 20 && (m_options & AndroidConfigurations::FilterAndroid5)) {
- error = AndroidDeviceDialog::tr("Android 5 devices are incompatible with deploying Qt to a temporary directory.");
} else {
new AndroidDeviceModelNode(compatibleDevices, device);
continue;
@@ -417,10 +414,10 @@ static inline QString msgAdbListDevices()
return AndroidDeviceDialog::tr("<p>The adb tool in the Android SDK lists all connected devices if run via &quot;adb devices&quot;.</p>");
}
-AndroidDeviceDialog::AndroidDeviceDialog(int apiLevel, const QString &abi, AndroidConfigurations::Options options,
+AndroidDeviceDialog::AndroidDeviceDialog(int apiLevel, const QString &abi,
const QString &serialNumber, QWidget *parent) :
QDialog(parent),
- m_model(new AndroidDeviceModel(apiLevel, abi, options)),
+ m_model(new AndroidDeviceModel(apiLevel, abi)),
m_ui(new Ui::AndroidDeviceDialog),
m_apiLevel(apiLevel),
m_abi(abi),
@@ -462,7 +459,7 @@ AndroidDeviceDialog::AndroidDeviceDialog(int apiLevel, const QString &abi, Andro
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
- m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicator::Large, this);
+ m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Large, this);
m_progressIndicator->attachToWidget(m_ui->deviceView);
if (serialNumber.isEmpty()) {
diff --git a/src/plugins/android/androiddevicedialog.h b/src/plugins/android/androiddevicedialog.h
index 8f957aa0b20..f882b0bfcd2 100644
--- a/src/plugins/android/androiddevicedialog.h
+++ b/src/plugins/android/androiddevicedialog.h
@@ -52,7 +52,7 @@ class AndroidDeviceDialog : public QDialog
Q_OBJECT
public:
- explicit AndroidDeviceDialog(int apiLevel, const QString &abi, AndroidConfigurations::Options opts,
+ explicit AndroidDeviceDialog(int apiLevel, const QString &abi,
const QString &serialNumber, QWidget *parent = 0);
~AndroidDeviceDialog();
diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp
index 54f2bdd4821..3691d959004 100644
--- a/src/plugins/android/androidmanager.cpp
+++ b/src/plugins/android/androidmanager.cpp
@@ -341,7 +341,7 @@ void AndroidManager::cleanLibsOnDevice(ProjectExplorer::Target *target)
if (targetArch.isEmpty())
return;
const int deviceAPILevel = AndroidManager::minimumSDK(target);
- AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(target->project(), deviceAPILevel, targetArch, AndroidConfigurations::None);
+ AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(target->project(), deviceAPILevel, targetArch);
if (!info.isValid()) // aborted
return;
@@ -371,7 +371,7 @@ void AndroidManager::installQASIPackage(ProjectExplorer::Target *target, const Q
if (targetArch.isEmpty())
return;
const int deviceAPILevel = AndroidManager::minimumSDK(target);
- AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(target->project(), deviceAPILevel, targetArch, AndroidConfigurations::None);
+ AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(target->project(), deviceAPILevel, targetArch);
if (!info.isValid()) // aborted
return;
@@ -463,15 +463,6 @@ AndroidQtSupport *AndroidManager::androidQtSupport(ProjectExplorer::Target *targ
return 0;
}
-bool AndroidManager::useGradle(ProjectExplorer::Target *target)
-{
- if (!target)
- return false;
- AndroidBuildApkStep *buildApkStep
- = AndroidGlobal::buildStep<AndroidBuildApkStep>(target->activeBuildConfiguration());
- return buildApkStep && buildApkStep->useGradle();
-}
-
typedef QMap<QByteArray, QByteArray> GradleProperties;
static GradleProperties readGradleProperties(const QString &path)
@@ -543,7 +534,7 @@ bool AndroidManager::updateGradleProperties(ProjectExplorer::Target *target)
AndroidBuildApkStep *buildApkStep
= AndroidGlobal::buildStep<AndroidBuildApkStep>(target->activeBuildConfiguration());
- if (!buildApkStep || !buildApkStep->useGradle() || !buildApkStep->androidPackageSourceDir().appendPath(QLatin1String("gradlew")).exists())
+ if (!buildApkStep || !buildApkStep->androidPackageSourceDir().appendPath(QLatin1String("gradlew")).exists())
return false;
Utils::FileName wrapperProps(buildApkStep->androidPackageSourceDir());
@@ -570,16 +561,10 @@ bool AndroidManager::updateGradleProperties(ProjectExplorer::Target *target)
gradleProperties["buildDir"] = ".build";
gradleProperties["androidCompileSdkVersion"] = buildTargetSDK(target).split(QLatin1Char('-')).last().toLocal8Bit();
if (gradleProperties["androidBuildToolsVersion"].isEmpty()) {
- QVersionNumber maxVersion;
- QDir buildToolsDir(AndroidConfigurations::currentConfig().sdkLocation().appendPath(QLatin1String("build-tools")).toString());
- foreach (const QFileInfo &file, buildToolsDir.entryList(QDir::Dirs|QDir::NoDotAndDotDot)) {
- QVersionNumber ver = QVersionNumber::fromString(file.fileName());
- if (maxVersion < ver)
- maxVersion = ver;
- }
- if (maxVersion.isNull())
+ QVersionNumber buildtoolVersion = AndroidConfigurations::currentConfig().buildToolsVersion();
+ if (buildtoolVersion.isNull())
return false;
- gradleProperties["androidBuildToolsVersion"] = maxVersion.toString().toLocal8Bit();
+ gradleProperties["androidBuildToolsVersion"] = buildtoolVersion.toString().toLocal8Bit();
}
return mergeGradleProperties(gradlePropertiesPath, gradleProperties);
}
diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h
index ad50f455290..e9d8fc5062a 100644
--- a/src/plugins/android/androidmanager.h
+++ b/src/plugins/android/androidmanager.h
@@ -87,7 +87,6 @@ public:
const QString &alias);
static bool checkForQt51Files(Utils::FileName fileName);
static AndroidQtSupport *androidQtSupport(ProjectExplorer::Target *target);
- static bool useGradle(ProjectExplorer::Target *target);
static bool updateGradleProperties(ProjectExplorer::Target *target);
static int findApiLevel(const Utils::FileName &platformPath);
};
diff --git a/src/plugins/android/androidpotentialkit.cpp b/src/plugins/android/androidpotentialkit.cpp
index c01c7d0ecc4..8264415a121 100644
--- a/src/plugins/android/androidpotentialkit.cpp
+++ b/src/plugins/android/androidpotentialkit.cpp
@@ -27,6 +27,8 @@
#include "androidconstants.h"
#include "androidconfigurations.h"
+#include <app/app_version.h>
+
#include <utils/detailswidget.h>
#include <utils/utilsicons.h>
@@ -91,8 +93,9 @@ AndroidPotentialKitWidget::AndroidPotentialKitWidget(QWidget *parent)
auto layout = new QGridLayout(mainWidget);
layout->setMargin(0);
auto label = new QLabel;
- label->setText(tr("Qt Creator needs additional settings to enable Android support."
- " You can configure those settings in the Options dialog."));
+ label->setText(tr("%1 needs additional settings to enable Android support."
+ " You can configure those settings in the Options dialog.")
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
label->setWordWrap(true);
layout->addWidget(label, 0, 0, 1, 2);
diff --git a/src/plugins/android/androidqtsupport.cpp b/src/plugins/android/androidqtsupport.cpp
index 8cc4a86a9ff..1e3aa8ce7d5 100644
--- a/src/plugins/android/androidqtsupport.cpp
+++ b/src/plugins/android/androidqtsupport.cpp
@@ -41,11 +41,7 @@ Utils::FileName Android::AndroidQtSupport::apkPath(ProjectExplorer::Target *targ
if (!buildApkStep)
return Utils::FileName();
- QString apkPath;
- if (buildApkStep->useGradle())
- apkPath = QLatin1String("build/outputs/apk/android-build-");
- else
- apkPath = QLatin1String("bin/QtApp-");
+ QString apkPath("build/outputs/apk/android-build-");
if (buildApkStep->signPackage())
apkPath += QLatin1String("release.apk");
else
diff --git a/src/plugins/android/androidrunconfiguration.cpp b/src/plugins/android/androidrunconfiguration.cpp
index 79bfa1007fa..f6a1e858a4c 100644
--- a/src/plugins/android/androidrunconfiguration.cpp
+++ b/src/plugins/android/androidrunconfiguration.cpp
@@ -45,13 +45,8 @@ const char amStartArgsKey[] = "Android.AmStartArgsKey";
const char preStartShellCmdsKey[] = "Android.PreStartShellCmdListKey";
const char postFinishShellCmdsKey[] = "Android.PostFinishShellCmdListKey";
-AndroidRunConfiguration::AndroidRunConfiguration(Target *parent, Core::Id id)
- : RunConfiguration(parent, id)
-{
-}
-
-AndroidRunConfiguration::AndroidRunConfiguration(Target *parent, AndroidRunConfiguration *source)
- : RunConfiguration(parent, source)
+AndroidRunConfiguration::AndroidRunConfiguration(Target *target)
+ : RunConfiguration(target)
{
}
diff --git a/src/plugins/android/androidrunconfiguration.h b/src/plugins/android/androidrunconfiguration.h
index 45b00d8a845..358871dc193 100644
--- a/src/plugins/android/androidrunconfiguration.h
+++ b/src/plugins/android/androidrunconfiguration.h
@@ -29,17 +29,13 @@
#include <projectexplorer/runconfiguration.h>
-QT_BEGIN_NAMESPACE
-class QToolButton;
-QT_END_NAMESPACE
-
namespace Android {
class ANDROID_EXPORT AndroidRunConfiguration : public ProjectExplorer::RunConfiguration
{
Q_OBJECT
public:
- AndroidRunConfiguration(ProjectExplorer::Target *parent, Core::Id id);
+ explicit AndroidRunConfiguration(ProjectExplorer::Target *target);
QWidget *createConfigurationWidget() override;
Utils::OutputFormatter *createOutputFormatter() const override;
@@ -51,15 +47,12 @@ public:
const QStringList &preStartShellCommands() const;
const QStringList &postFinishShellCommands() const;
-protected:
- AndroidRunConfiguration(ProjectExplorer::Target *parent, AndroidRunConfiguration *source);
-
private:
+ // FIXME: This appears to miss a copyFrom() implementation.
void setPreStartShellCommands(const QStringList &cmdList);
void setPostFinishShellCommands(const QStringList &cmdList);
void setAmStartExtraArgs(const QStringList &args);
-private:
QStringList m_amStartExtraArgs;
QStringList m_preStartShellCommands;
QStringList m_postFinishShellCommands;
diff --git a/src/plugins/android/androidrunconfigurationwidget.cpp b/src/plugins/android/androidrunconfigurationwidget.cpp
index a9560fdaaa1..a7327ce917a 100644
--- a/src/plugins/android/androidrunconfigurationwidget.cpp
+++ b/src/plugins/android/androidrunconfigurationwidget.cpp
@@ -69,9 +69,7 @@ AndroidRunConfigurationWidget::AndroidRunConfigurationWidget(QWidget *parent):
});
}
-AndroidRunConfigurationWidget::~AndroidRunConfigurationWidget()
-{
-}
+AndroidRunConfigurationWidget::~AndroidRunConfigurationWidget() = default;
void AndroidRunConfigurationWidget::setAmStartArgs(const QStringList &args)
{
diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp
index 04d87284af8..5eaaaf5241d 100644
--- a/src/plugins/android/androidrunner.cpp
+++ b/src/plugins/android/androidrunner.cpp
@@ -223,11 +223,8 @@ public:
void setAndroidRunnable(const AndroidRunnable &runnable);
void handleRemoteDebuggerRunning();
- Utils::Port localGdbServerPort() const { return m_localGdbServerPort; }
-
signals:
- void remoteProcessStarted(Utils::Port gdbServerPort, Utils::Port qmlServerPort,
- QString qmlServerHost, int pid);
+ void remoteProcessStarted(Utils::Port gdbServerPort, const QUrl &qmlServer, int pid);
void remoteProcessFinished(const QString &errString = QString());
void remoteOutput(const QString &output);
@@ -258,8 +255,7 @@ private:
bool m_useCppDebugger = false;
QmlDebug::QmlDebugServicesPreset m_qmlDebugServices;
Utils::Port m_localGdbServerPort; // Local end of forwarded debug socket.
- QString m_qmlServerHost;
- Utils::Port m_qmlPort;
+ QUrl m_qmlServer;
QString m_pingFile;
QString m_pongFile;
QString m_gdbserverPath;
@@ -297,10 +293,9 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunControl *runControl, const AndroidRu
QTC_ASSERT(server.listen(QHostAddress::LocalHost)
|| server.listen(QHostAddress::LocalHostIPv6),
qDebug() << tr("No free ports available on host for QML debugging."));
- m_qmlServerHost = server.serverAddress().toString();
- m_qmlPort = Utils::Port(server.serverPort());
- } else {
- m_qmlPort = Utils::Port();
+ m_qmlServer.setScheme(urlTcpScheme());
+ m_qmlServer.setHost(server.serverAddress().toString());
+ m_qmlServer.setPort(server.serverPort());
}
m_adb = AndroidConfigurations::currentConfig().adbToolPath().toString();
@@ -418,7 +413,7 @@ void AndroidRunnerWorker::asyncStart()
if (m_qmlDebugServices != QmlDebug::NoQmlDebugServices) {
// currently forward to same port on device and host
- const QString port = QString("tcp:%1").arg(m_qmlPort.number());
+ const QString port = QString("tcp:%1").arg(m_qmlServer.port());
if (!runAdb({"forward", port, port}, &errorMessage)) {
emit remoteProcessFinished(tr("Failed to forward QML debugging ports. Reason: %1.")
.arg(errorMessage));
@@ -428,7 +423,7 @@ void AndroidRunnerWorker::asyncStart()
args << "-e" << "qml_debug" << "true"
<< "-e" << "qmljsdebugger"
<< QString("port:%1,block,services:%2")
- .arg(m_qmlPort.number()).arg(QmlDebug::qmlDebugServices(m_qmlDebugServices));
+ .arg(m_qmlServer.port()).arg(QmlDebug::qmlDebugServices(m_qmlDebugServices));
}
if (!runAdb(args, &errorMessage)) {
@@ -641,7 +636,7 @@ void AndroidRunnerWorker::onProcessIdChanged(qint64 pid)
} else {
// In debugging cases this will be funneled to the engine to actually start
// and attach gdb. Afterwards this ends up in handleRemoteDebuggerRunning() below.
- emit remoteProcessStarted(m_localGdbServerPort, m_qmlPort, m_qmlServerHost, m_processPID);
+ emit remoteProcessStarted(m_localGdbServerPort, m_qmlServer, m_processPID);
logcatReadStandardOutput();
QTC_ASSERT(!m_psIsAlive, /**/);
m_psIsAlive.reset(new QProcess);
@@ -785,13 +780,12 @@ void AndroidRunner::remoteErrorOutput(const QString &output)
m_outputParser.processOutput(output);
}
-void AndroidRunner::handleRemoteProcessStarted(Utils::Port gdbServerPort, Utils::Port qmlServerPort,
- QString qmlServerHost, int pid)
+void AndroidRunner::handleRemoteProcessStarted(Utils::Port gdbServerPort,
+ const QUrl &qmlServer, int pid)
{
m_pid = ProcessHandle(pid);
m_gdbServerPort = gdbServerPort;
- m_qmlServerHost = qmlServerHost;
- m_qmlServerPort = qmlServerPort;
+ m_qmlServer = qmlServer;
reportStarted();
}
@@ -821,8 +815,7 @@ void AndroidRunner::launchAVD()
// Get AVD info.
AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(
- m_target->project(), deviceAPILevel, targetArch,
- AndroidConfigurations::None);
+ m_target->project(), deviceAPILevel, targetArch);
AndroidManager::setDeviceSerialNumber(m_target, info.serialNumber);
m_androidRunnable.deviceSerialNumber = info.serialNumber;
emit androidRunnableChanged(m_androidRunnable);
diff --git a/src/plugins/android/androidrunner.h b/src/plugins/android/androidrunner.h
index 6215cc49a58..c878f95e9a6 100644
--- a/src/plugins/android/androidrunner.h
+++ b/src/plugins/android/androidrunner.h
@@ -57,8 +57,7 @@ public:
const AndroidRunnable &runnable() const { return m_androidRunnable; }
Utils::Port gdbServerPort() const { return m_gdbServerPort; }
- QString qmlServerHost() const { return m_qmlServerHost; }
- Utils::Port qmlServerPort() const { return m_qmlServerPort; }
+ QUrl qmlServer() const { return m_qmlServer; }
Utils::ProcessHandle pid() const { return m_pid; }
void start() override;
@@ -77,8 +76,7 @@ private:
void remoteOutput(const QString &output);
void remoteErrorOutput(const QString &output);
void gotRemoteOutput(const QString &output);
- void handleRemoteProcessStarted(Utils::Port gdbServerPort, Utils::Port qmlServerPort,
- QString qmlServerHost, int pid);
+ void handleRemoteProcessStarted(Utils::Port gdbServerPort, const QUrl &qmlServer, int pid);
void handleRemoteProcessFinished(const QString &errString = QString());
void checkAVD();
void launchAVD();
@@ -90,8 +88,7 @@ private:
QScopedPointer<AndroidRunnerWorker> m_worker;
QPointer<ProjectExplorer::Target> m_target;
Utils::Port m_gdbServerPort;
- QString m_qmlServerHost;
- Utils::Port m_qmlServerPort;
+ QUrl m_qmlServer;
Utils::ProcessHandle m_pid;
QmlDebug::QmlOutputParser m_outputParser;
};
diff --git a/src/plugins/android/androidsdkmanager.cpp b/src/plugins/android/androidsdkmanager.cpp
index c28fef27a18..ee4f14ae93b 100644
--- a/src/plugins/android/androidsdkmanager.cpp
+++ b/src/plugins/android/androidsdkmanager.cpp
@@ -82,12 +82,9 @@ static bool sdkManagerCommand(const AndroidConfig config, const QStringList &arg
proc.setTimeoutS(timeout);
proc.setTimeOutMessageBoxEnabled(true);
SynchronousProcessResponse response = proc.run(sdkManagerToolPath, args);
- if (response.result == SynchronousProcessResponse::Finished) {
- if (output)
- *output = response.allOutput();
- return true;
- }
- return false;
+ if (output)
+ *output = response.allOutput();
+ return response.result == SynchronousProcessResponse::Finished;
}
/*!
diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp
index a0a24ea0875..d5c49623b1b 100644
--- a/src/plugins/android/androidsettingswidget.cpp
+++ b/src/plugins/android/androidsettingswidget.cpp
@@ -134,37 +134,11 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
{
m_ui->setupUi(this);
- m_ui->deprecatedInfoIconLabel->setPixmap(Utils::Icons::INFO.pixmap());
-
- connect(&m_checkGdbWatcher, &QFutureWatcherBase::finished,
- this, &AndroidSettingsWidget::checkGdbFinished);
-
m_ui->SDKLocationPathChooser->setFileName(m_androidConfig.sdkLocation());
m_ui->SDKLocationPathChooser->setPromptDialogTitle(tr("Select Android SDK folder"));
m_ui->NDKLocationPathChooser->setFileName(m_androidConfig.ndkLocation());
m_ui->NDKLocationPathChooser->setPromptDialogTitle(tr("Select Android NDK folder"));
- QString dir;
- QString filter;
- if (Utils::HostOsInfo::isWindowsHost()) {
- dir = QDir::homePath() + QLatin1String("/ant.bat");
- filter = QLatin1String("ant (ant.bat)");
- } else if (Utils::HostOsInfo::isMacHost()) {
- // work around QTBUG-7739 that prohibits filters that don't start with *
- dir = QLatin1String("/usr/bin/ant");
- filter = QLatin1String("ant (*ant)");
- } else {
- dir = QLatin1String("/usr/bin/ant");
- filter = QLatin1String("ant (ant)");
- }
- m_ui->AntLocationPathChooser->setFileName(m_androidConfig.antLocation());
- m_ui->AntLocationPathChooser->setExpectedKind(Utils::PathChooser::Command);
- m_ui->AntLocationPathChooser->setPromptDialogTitle(tr("Select ant Script"));
- m_ui->AntLocationPathChooser->setInitialBrowsePathBackup(dir);
- m_ui->AntLocationPathChooser->setPromptDialogFilter(filter);
-
- updateGradleBuildUi();
-
m_ui->OpenJDKLocationPathChooser->setFileName(m_androidConfig.openJDKLocation());
m_ui->OpenJDKLocationPathChooser->setPromptDialogTitle(tr("Select JDK Path"));
m_ui->DataPartitionSizeSpinBox->setValue(m_androidConfig.partitionSize());
@@ -173,7 +147,6 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
m_ui->AVDTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
m_ui->AVDTableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
- m_ui->downloadAntToolButton->setVisible(!Utils::HostOsInfo::isLinuxHost());
m_ui->downloadOpenJDKToolButton->setVisible(!Utils::HostOsInfo::isLinuxHost());
const QPixmap warningPixmap = Utils::Icons::WARNING.pixmap();
@@ -182,12 +155,8 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
const QPixmap errorPixmap = Utils::Icons::CRITICAL.pixmap();
m_ui->sdkWarningIconLabel->setPixmap(errorPixmap);
- m_ui->gdbWarningIconLabel->setPixmap(errorPixmap);
m_ui->ndkWarningIconLabel->setPixmap(errorPixmap);
- connect(m_ui->gdbWarningLabel, &QLabel::linkActivated,
- this, &AndroidSettingsWidget::showGdbWarningDialog);
-
connect(&m_virtualDevicesWatcher, &QFutureWatcherBase::finished,
this, &AndroidSettingsWidget::updateAvds);
@@ -201,8 +170,6 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
this, &AndroidSettingsWidget::ndkLocationEditingFinished);
connect(m_ui->SDKLocationPathChooser, &Utils::PathChooser::rawPathChanged,
this, &AndroidSettingsWidget::sdkLocationEditingFinished);
- connect(m_ui->AntLocationPathChooser, &Utils::PathChooser::rawPathChanged,
- this, &AndroidSettingsWidget::antLocationEditingFinished);
connect(m_ui->OpenJDKLocationPathChooser, &Utils::PathChooser::rawPathChanged,
this, &AndroidSettingsWidget::openJDKLocationEditingFinished);
connect(m_ui->AVDAddPushButton, &QAbstractButton::clicked,
@@ -225,13 +192,8 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
this, &AndroidSettingsWidget::openSDKDownloadUrl);
connect(m_ui->downloadNDKToolButton, &QAbstractButton::clicked,
this, &AndroidSettingsWidget::openNDKDownloadUrl);
- connect(m_ui->downloadAntToolButton, &QAbstractButton::clicked,
- this, &AndroidSettingsWidget::openAntDownloadUrl);
connect(m_ui->downloadOpenJDKToolButton, &QAbstractButton::clicked,
this, &AndroidSettingsWidget::openOpenJDKDownloadUrl);
- connect(m_ui->UseGradleCheckBox, &QAbstractButton::toggled,
- this, &AndroidSettingsWidget::useGradleToggled);
-
}
AndroidSettingsWidget::~AndroidSettingsWidget()
@@ -240,58 +202,10 @@ AndroidSettingsWidget::~AndroidSettingsWidget()
m_futureWatcher.waitForFinished();
}
-// NOTE: Will be run via QFuture
-static QPair<QStringList, bool> checkGdbForBrokenPython(const QStringList &paths)
-{
- foreach (const QString &path, paths) {
- QTime timer;
- timer.start();
- QProcess proc;
- proc.setProcessChannelMode(QProcess::MergedChannels);
- proc.start(path);
- proc.waitForStarted();
-
- QByteArray output;
- while (proc.waitForReadyRead(300)) {
- output += proc.readAll();
- if (output.contains("(gdb)"))
- break;
- if (timer.elapsed() > 7 * 1000)
- return qMakePair(paths, true); // Took too long, abort
- }
-
- output.clear();
-
- proc.write("python import string\n");
- proc.write("python print(string.ascii_uppercase)\n");
- proc.write("python import struct\n");
- proc.write("quit\n");
- while (proc.waitForFinished(300)) {
- if (timer.elapsed() > 9 * 1000)
- return qMakePair(paths, true); // Took too long, abort
- }
- proc.waitForFinished();
-
- output = proc.readAll();
-
- bool error = output.contains("_PyObject_Free")
- || output.contains("_PyExc_IOError")
- || output.contains("_sysconfigdata_nd ")
- || !output.contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
- if (error)
- return qMakePair(paths, error);
- }
- return qMakePair(paths, false);
-}
-
void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
{
if (mode & Sdk) {
- m_sdkState = Okay;
- if (m_androidConfig.sdkLocation().isEmpty())
- m_sdkState = NotSet;
- else if (!(sdkLocationIsValid() && sdkPlatformToolsInstalled()))
- m_sdkState = Error;
+ m_sdkState = verifySdkInstallation(&m_sdkInstallationError) ? Okay : Error;
}
if (mode & Ndk) {
@@ -299,8 +213,6 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
Utils::FileName platformPath = m_androidConfig.ndkLocation();
Utils::FileName toolChainPath = m_androidConfig.ndkLocation();
Utils::FileName sourcesPath = m_androidConfig.ndkLocation();
- m_ui->gdbWarningIconLabel->setVisible(false);
- m_ui->gdbWarningLabel->setVisible(false);
if (m_androidConfig.ndkLocation().isEmpty()) {
m_ndkState = NotSet;
} else if (!platformPath.appendPath(QLatin1String("platforms")).exists()
@@ -317,24 +229,6 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
= AndroidToolChainFactory::toolchainPathsForNdk(m_androidConfig.ndkLocation());
m_ndkCompilerCount = compilerPaths.count();
- // Check for a gdb with a broken python
- QStringList gdbPaths;
- foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) {
- if (ati.language == Core::Id(ProjectExplorer::Constants::C_LANGUAGE_ID))
- continue;
- // we only check the arm gdbs, that's indicative enough
- if (ati.abi.architecture() != ProjectExplorer::Abi::ArmArchitecture)
- continue;
- Utils::FileName gdbPath = m_androidConfig.gdbPath(ati.abi, ati.version);
- if (gdbPath.exists())
- gdbPaths << gdbPath.toString();
- }
-
- if (!gdbPaths.isEmpty()) {
- m_checkGdbWatcher.setFuture(Utils::runAsync(&checkGdbForBrokenPython, gdbPaths));
- m_gdbCheckPaths = gdbPaths;
- }
-
// See if we have qt versions for those toolchains
QSet<ProjectExplorer::Abi> toolchainsForAbi;
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) {
@@ -386,11 +280,7 @@ void AndroidSettingsWidget::applyToUi(AndroidSettingsWidget::Mode mode)
if (m_sdkState == Error) {
m_ui->sdkWarningIconLabel->setVisible(true);
m_ui->sdkWarningLabel->setVisible(true);
- Utils::FileName location = Utils::FileName::fromUserInput(m_ui->SDKLocationPathChooser->rawPath());
- if (sdkLocationIsValid())
- m_ui->sdkWarningLabel->setText(tr("The Platform tools are missing. Please use the Android SDK Manager to install them."));
- else
- m_ui->sdkWarningLabel->setText(tr("\"%1\" does not seem to be an Android SDK top folder.").arg(location.toUserOutput()));
+ m_ui->sdkWarningLabel->setText(m_sdkInstallationError);
} else {
m_ui->sdkWarningIconLabel->setVisible(false);
m_ui->sdkWarningLabel->setVisible(false);
@@ -481,34 +371,48 @@ void AndroidSettingsWidget::updateAvds()
enableAvdControls();
}
-void AndroidSettingsWidget::updateGradleBuildUi()
+bool AndroidSettingsWidget::verifySdkInstallation(QString *errorDetails) const
{
- m_ui->UseGradleCheckBox->setEnabled(m_androidConfig.antScriptsAvailable());
- m_ui->UseGradleCheckBox->setChecked(!m_androidConfig.antScriptsAvailable() ||
- m_androidConfig.useGrandle());
-}
+ if (m_androidConfig.sdkLocation().isEmpty()) {
+ if (errorDetails)
+ *errorDetails = tr("Android SDK path not set.");
+ return false;
+ }
-bool AndroidSettingsWidget::sdkLocationIsValid() const
-{
- Utils::FileName androidExe = m_androidConfig.sdkLocation();
- Utils::FileName androidBat = m_androidConfig.sdkLocation();
- Utils::FileName emulator = m_androidConfig.sdkLocation();
- return (androidExe.appendPath(QLatin1String("/tools/android" QTC_HOST_EXE_SUFFIX)).exists()
- || androidBat.appendPath(QLatin1String("/tools/android" ANDROID_BAT_SUFFIX)).exists())
- && emulator.appendPath(QLatin1String("/tools/emulator" QTC_HOST_EXE_SUFFIX)).exists();
-}
+ if (!m_androidConfig.sdkLocation().exists()) {
+ if (errorDetails)
+ *errorDetails = tr("Android SDK path does not exist.");
+ return false;
+ }
-bool AndroidSettingsWidget::sdkPlatformToolsInstalled() const
-{
- Utils::FileName adb = m_androidConfig.sdkLocation();
- return adb.appendPath(QLatin1String("platform-tools/adb" QTC_HOST_EXE_SUFFIX)).exists();
+ if (m_androidConfig.sdkToolsVersion().isNull()) {
+ if (errorDetails)
+ *errorDetails = tr("The SDK path does not seem to be a valid Android SDK top folder.");
+ return false;
+ }
+
+ QStringList missingComponents;
+ if (!m_androidConfig.adbToolPath().exists())
+ missingComponents << "Platform Tools";
+
+ if (m_androidConfig.buildToolsVersion().isNull())
+ missingComponents << "Build Tools";
+
+ if (m_androidConfig.sdkTargets().isEmpty())
+ missingComponents << "Platform SDK";
+
+ if (!missingComponents.isEmpty() && errorDetails) {
+ *errorDetails = tr("Android SDK components missing (%1).\nUse Android SDK Manager to "
+ "manage SDK components.").arg(missingComponents.join(", "));
+ }
+
+ return missingComponents.isEmpty();
}
void AndroidSettingsWidget::saveSettings()
{
sdkLocationEditingFinished();
ndkLocationEditingFinished();
- antLocationEditingFinished();
openJDKLocationEditingFinished();
dataPartitionSizeEditingFinished();
AndroidConfigurations::setConfig(m_androidConfig);
@@ -517,13 +421,8 @@ void AndroidSettingsWidget::saveSettings()
void AndroidSettingsWidget::sdkLocationEditingFinished()
{
m_androidConfig.setSdkLocation(Utils::FileName::fromUserInput(m_ui->SDKLocationPathChooser->rawPath()));
- updateGradleBuildUi();
check(Sdk);
-
- if (m_sdkState == Okay)
- searchForAnt(m_androidConfig.sdkLocation());
-
applyToUi(Sdk);
}
@@ -532,41 +431,9 @@ void AndroidSettingsWidget::ndkLocationEditingFinished()
m_androidConfig.setNdkLocation(Utils::FileName::fromUserInput(m_ui->NDKLocationPathChooser->rawPath()));
check(Ndk);
-
- if (m_ndkState == Okay)
- searchForAnt(m_androidConfig.ndkLocation());
-
applyToUi(Ndk);
}
-void AndroidSettingsWidget::searchForAnt(const Utils::FileName &location)
-{
- if (!m_androidConfig.antLocation().isEmpty())
- return;
- if (location.isEmpty())
- return;
- QDir parentFolder = location.toFileInfo().absoluteDir();
- foreach (const QString &file, parentFolder.entryList()) {
- if (file.startsWith(QLatin1String("apache-ant"))) {
- Utils::FileName ant = Utils::FileName::fromString(parentFolder.absolutePath());
- ant.appendPath(file).appendPath(QLatin1String("bin"));
- if (Utils::HostOsInfo::isWindowsHost())
- ant.appendPath(QLatin1String("ant.bat"));
- else
- ant.appendPath(QLatin1String("ant"));
- if (ant.exists()) {
- m_androidConfig.setAntLocation(ant);
- m_ui->AntLocationPathChooser->setFileName(ant);
- }
- }
- }
-}
-
-void AndroidSettingsWidget::antLocationEditingFinished()
-{
- m_androidConfig.setAntLocation(Utils::FileName::fromUserInput(m_ui->AntLocationPathChooser->rawPath()));
-}
-
void AndroidSettingsWidget::openJDKLocationEditingFinished()
{
m_androidConfig.setOpenJDKLocation(Utils::FileName::fromUserInput(m_ui->OpenJDKLocationPathChooser->rawPath()));
@@ -585,11 +452,6 @@ void AndroidSettingsWidget::openNDKDownloadUrl()
QDesktopServices::openUrl(QUrl::fromUserInput("https://developer.android.com/ndk/downloads/"));
}
-void AndroidSettingsWidget::openAntDownloadUrl()
-{
- QDesktopServices::openUrl(QUrl::fromUserInput("http://ant.apache.org/bindownload.cgi"));
-}
-
void AndroidSettingsWidget::openOpenJDKDownloadUrl()
{
QDesktopServices::openUrl(QUrl::fromUserInput("http://www.oracle.com/technetwork/java/javase/downloads/"));
@@ -658,30 +520,6 @@ void AndroidSettingsWidget::createKitToggled()
m_androidConfig.setAutomaticKitCreation(m_ui->CreateKitCheckBox->isChecked());
}
-void AndroidSettingsWidget::useGradleToggled()
-{
- m_androidConfig.setUseGradle(m_ui->UseGradleCheckBox->isChecked());
-}
-
-void AndroidSettingsWidget::checkGdbFinished()
-{
- QPair<QStringList, bool> result = m_checkGdbWatcher.future().result();
- if (result.first != m_gdbCheckPaths) // no longer relevant
- return;
- m_ui->gdbWarningIconLabel->setVisible(result.second);
- m_ui->gdbWarningLabel->setVisible(result.second);
-}
-
-void AndroidSettingsWidget::showGdbWarningDialog()
-{
- QMessageBox::warning(this,
- tr("Unsupported GDB"),
- tr("The GDB inside this NDK seems to not support Python. "
- "The Qt Project offers fixed GDB builds at: "
- "<a href=\"http://download.qt.io/official_releases/gdb/\">"
- "http://download.qt.io/official_releases/gdb/</a>"));
-}
-
void AndroidSettingsWidget::manageAVD()
{
if (m_avdManager->avdManagerUiToolAvailable()) {
diff --git a/src/plugins/android/androidsettingswidget.h b/src/plugins/android/androidsettingswidget.h
index 50be7c1049d..32127543657 100644
--- a/src/plugins/android/androidsettingswidget.h
+++ b/src/plugins/android/androidsettingswidget.h
@@ -75,12 +75,9 @@ public:
private:
void sdkLocationEditingFinished();
void ndkLocationEditingFinished();
- void searchForAnt(const Utils::FileName &location);
- void antLocationEditingFinished();
void openJDKLocationEditingFinished();
void openSDKDownloadUrl();
void openNDKDownloadUrl();
- void openAntDownloadUrl();
void openOpenJDKDownloadUrl();
void addAVD();
void avdAdded();
@@ -90,25 +87,21 @@ private:
void dataPartitionSizeEditingFinished();
void manageAVD();
void createKitToggled();
- void useGradleToggled();
- void checkGdbFinished();
- void showGdbWarningDialog();
void updateAvds();
- void updateGradleBuildUi();
private:
enum Mode { Sdk = 1, Ndk = 2, Java = 4, All = Sdk | Ndk | Java };
enum State { NotSet = 0, Okay = 1, Error = 2 };
+ bool verifySdkInstallation(QString *errorDetails = nullptr) const;
void check(Mode mode);
void applyToUi(Mode mode);
- bool sdkLocationIsValid() const;
- bool sdkPlatformToolsInstalled() const;
void startUpdateAvd();
void enableAvdControls();
void disableAvdControls();
State m_sdkState;
+ QString m_sdkInstallationError;
State m_ndkState;
QString m_ndkErrorMessage;
int m_ndkCompilerCount;
@@ -119,8 +112,6 @@ private:
AndroidConfig m_androidConfig;
AvdModel m_AVDModel;
QFutureWatcher<AndroidConfig::CreateAvdInfo> m_futureWatcher;
- QFutureWatcher<QPair<QStringList, bool>> m_checkGdbWatcher;
- QStringList m_gdbCheckPaths;
QFutureWatcher<AndroidDeviceInfoList> m_virtualDevicesWatcher;
QString m_lastAddedAvd;
diff --git a/src/plugins/android/androidsettingswidget.ui b/src/plugins/android/androidsettingswidget.ui
index 338c73da043..0d8bcb774d5 100644
--- a/src/plugins/android/androidsettingswidget.ui
+++ b/src/plugins/android/androidsettingswidget.ui
@@ -14,25 +14,134 @@
<string>Android Configuration</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="OpenJDKLocationLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>JDK location:</string>
+ <item row="9" column="0" colspan="2">
+ <widget class="QFrame" name="AVDManagerFrame">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
</property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
</property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="3" column="1">
+ <widget class="QPushButton" name="AVDStartPushButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Start...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="AVDManagerLabel">
+ <property name="text">
+ <string>AVD Manager</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="DataPartitionSizeLable">
+ <property name="text">
+ <string>System/data partition size:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="DataPartitionSizeSpinBox">
+ <property name="suffix">
+ <string> Mb</string>
+ </property>
+ <property name="maximum">
+ <number>99999</number>
+ </property>
+ <property name="value">
+ <number>1024</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="manageAVDPushButton">
+ <property name="text">
+ <string>Start AVD Manager...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="1">
+ <widget class="QPushButton" name="AVDRemovePushButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="AVDAddPushButton">
+ <property name="text">
+ <string>Add...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" rowspan="4">
+ <widget class="QTableView" name="AVDTableView">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="textElideMode">
+ <enum>Qt::ElideMiddle</enum>
+ </property>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>129</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
</widget>
</item>
<item row="0" column="1">
<widget class="Utils::PathChooser" name="OpenJDKLocationPathChooser" native="true"/>
</item>
+ <item row="2" column="1">
+ <widget class="Utils::PathChooser" name="SDKLocationPathChooser" native="true"/>
+ </item>
+ <item row="4" column="1">
+ <widget class="Utils::PathChooser" name="NDKLocationPathChooser" native="true"/>
+ </item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
@@ -66,10 +175,10 @@
</item>
</layout>
</item>
- <item row="0" column="2">
- <widget class="QToolButton" name="downloadOpenJDKToolButton">
+ <item row="4" column="2">
+ <widget class="QToolButton" name="downloadNDKToolButton">
<property name="toolTip">
- <string>Download JDK</string>
+ <string>Download Android NDK</string>
</property>
<property name="icon">
<iconset resource="android.qrc">
@@ -93,13 +202,10 @@
</property>
</widget>
</item>
- <item row="2" column="1">
- <widget class="Utils::PathChooser" name="SDKLocationPathChooser" native="true"/>
- </item>
- <item row="2" column="2">
- <widget class="QToolButton" name="downloadSDKToolButton">
+ <item row="0" column="2">
+ <widget class="QToolButton" name="downloadOpenJDKToolButton">
<property name="toolTip">
- <string>Download Android SDK</string>
+ <string>Download JDK</string>
</property>
<property name="icon">
<iconset resource="android.qrc">
@@ -107,62 +213,10 @@
</property>
</widget>
</item>
- <item row="3" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <item>
- <widget class="QLabel" name="sdkWarningIconLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="sdkWarningLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="NDKLocationLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Android NDK location:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="Utils::PathChooser" name="NDKLocationPathChooser" native="true"/>
- </item>
- <item row="4" column="2">
- <widget class="QToolButton" name="downloadNDKToolButton">
+ <item row="2" column="2">
+ <widget class="QToolButton" name="downloadSDKToolButton">
<property name="toolTip">
- <string>Download Android NDK</string>
+ <string>Download Android SDK</string>
</property>
<property name="icon">
<iconset resource="android.qrc">
@@ -170,13 +224,13 @@
</property>
</widget>
</item>
- <item row="5" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item row="8" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
- <widget class="QLabel" name="gdbWarningIconLabel">
+ <widget class="QLabel" name="kitWarningIconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -189,29 +243,9 @@
</widget>
</item>
<item>
- <widget class="QLabel" name="gdbWarningLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>&lt;a href=&quot;xx&quot;&gt;The GDB in the NDK appears to have broken python support.&lt;/a&gt;</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="6" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <property name="spacing">
- <number>2</number>
- </property>
- <item>
- <widget class="QLabel" name="ndkWarningIconLabel">
+ <widget class="QLabel" name="kitWarningLabel">
<property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -219,24 +253,14 @@
<property name="text">
<string/>
</property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="toolchainFoundLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
+ <property name="wordWrap">
+ <bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
- <item row="8" column="1">
+ <item row="7" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="spacing">
<number>2</number>
@@ -262,13 +286,29 @@
</item>
</layout>
</item>
- <item row="9" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item row="4" column="0">
+ <widget class="QLabel" name="NDKLocationLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Android NDK location:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>2</number>
</property>
<item>
- <widget class="QLabel" name="kitWarningIconLabel">
+ <widget class="QLabel" name="ndkWarningIconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -281,9 +321,9 @@
</widget>
</item>
<item>
- <widget class="QLabel" name="kitWarningLabel">
+ <widget class="QLabel" name="toolchainFoundLabel">
<property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -291,70 +331,45 @@
<property name="text">
<string/>
</property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
</widget>
</item>
</layout>
</item>
- <item row="10" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_7">
- <property name="spacing">
- <number>4</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
+ <item row="3" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
- <widget class="QCheckBox" name="UseGradleCheckBox">
+ <widget class="QLabel" name="sdkWarningIconLabel">
<property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
- <string>Use Gradle instead of Ant (Ant builds are deprecated)</string>
- </property>
- <property name="checked">
- <bool>true</bool>
+ <string/>
</property>
</widget>
</item>
<item>
- <widget class="QLabel" name="deprecatedInfoIconLabel">
+ <widget class="QLabel" name="sdkWarningLabel">
<property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="toolTip">
- <string>Gradle builds are forced from Android SDK tools version 25.3.0 onwards as Ant scripts are no longer available.</string>
- </property>
<property name="text">
<string/>
</property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
+ <property name="wordWrap">
+ <bool>true</bool>
</property>
- </spacer>
+ </widget>
</item>
</layout>
</item>
- <item row="11" column="0">
- <widget class="QLabel" name="AntLocationLabel">
+ <item row="0" column="0">
+ <widget class="QLabel" name="OpenJDKLocationLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -362,146 +377,13 @@
</sizepolicy>
</property>
<property name="text">
- <string>Ant executable:</string>
+ <string>JDK location:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
- <item row="11" column="1">
- <widget class="Utils::PathChooser" name="AntLocationPathChooser" native="true"/>
- </item>
- <item row="11" column="2">
- <widget class="QToolButton" name="downloadAntToolButton">
- <property name="toolTip">
- <string>Download Ant</string>
- </property>
- <property name="icon">
- <iconset resource="android.qrc">
- <normaloff>:/android/images/download.png</normaloff>:/android/images/download.png</iconset>
- </property>
- </widget>
- </item>
- <item row="12" column="0" colspan="2">
- <widget class="QFrame" name="AVDManagerFrame">
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="3" column="1">
- <widget class="QPushButton" name="AVDStartPushButton">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Start...</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="2">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QLabel" name="AVDManagerLabel">
- <property name="text">
- <string>AVD Manager</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="DataPartitionSizeLable">
- <property name="text">
- <string>System/data partition size:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="DataPartitionSizeSpinBox">
- <property name="suffix">
- <string> Mb</string>
- </property>
- <property name="maximum">
- <number>99999</number>
- </property>
- <property name="value">
- <number>1024</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="manageAVDPushButton">
- <property name="text">
- <string>Start AVD Manager...</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="1">
- <widget class="QPushButton" name="AVDRemovePushButton">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Remove</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QPushButton" name="AVDAddPushButton">
- <property name="text">
- <string>Add...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" rowspan="4">
- <widget class="QTableView" name="AVDTableView">
- <property name="selectionMode">
- <enum>QAbstractItemView::SingleSelection</enum>
- </property>
- <property name="selectionBehavior">
- <enum>QAbstractItemView::SelectRows</enum>
- </property>
- <property name="textElideMode">
- <enum>Qt::ElideMiddle</enum>
- </property>
- <attribute name="verticalHeaderVisible">
- <bool>false</bool>
- </attribute>
- </widget>
- </item>
- <item row="4" column="1">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>129</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
</layout>
</widget>
<customwidgets>
diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp
index bb3b10ee92b..3d89d3018d3 100644
--- a/src/plugins/android/androidtoolchain.cpp
+++ b/src/plugins/android/androidtoolchain.cpp
@@ -213,7 +213,7 @@ QString AndroidToolChain::makeCommand(const Environment &env) const
if (HostOsInfo::isWindowsHost()) {
FileName tmp = env.searchInPath(QLatin1String("ma-make.exe"), extraDirectories);
if (!tmp.isEmpty())
- return QString();
+ return tmp.toString();
tmp = env.searchInPath(QLatin1String("mingw32-make"), extraDirectories);
return tmp.isEmpty() ? QLatin1String("mingw32-make") : tmp.toString();
}
diff --git a/src/plugins/android/images/androiddevice.png b/src/plugins/android/images/androiddevice.png
index f72af6020b1..fd68e6aa3aa 100644
--- a/src/plugins/android/images/androiddevice.png
+++ b/src/plugins/android/images/androiddevice.png
Binary files differ
diff --git a/src/plugins/android/images/androiddevice@2x.png b/src/plugins/android/images/androiddevice@2x.png
index 1a2116ba3e7..b76fa151776 100644
--- a/src/plugins/android/images/androiddevice@2x.png
+++ b/src/plugins/android/images/androiddevice@2x.png
Binary files differ
diff --git a/src/plugins/autotest/autotest.qrc b/src/plugins/autotest/autotest.qrc
index a62ab49d8fb..554a14344e1 100644
--- a/src/plugins/autotest/autotest.qrc
+++ b/src/plugins/autotest/autotest.qrc
@@ -6,6 +6,7 @@
<file>images/leafsort.png</file>
<file>images/leafsort@2x.png</file>
<file>images/benchmark.png</file>
+ <file>images/benchmark@2x.png</file>
<file>images/runselected_boxes.png</file>
<file>images/runselected_boxes@2x.png</file>
<file>images/runselected_tickmarks.png</file>
diff --git a/src/plugins/autotest/autotestconstants.h b/src/plugins/autotest/autotestconstants.h
index 7c1aaa0dac2..5a1accdde70 100644
--- a/src/plugins/autotest/autotestconstants.h
+++ b/src/plugins/autotest/autotestconstants.h
@@ -39,10 +39,20 @@ const char AUTOTEST_CONTEXT[] = "Auto Tests";
const char TASK_INDEX[] = "AutoTest.Task.Index";
const char TASK_PARSE[] = "AutoTest.Task.Parse";
const char AUTOTEST_SETTINGS_CATEGORY[] = "ZY.Tests";
-const char AUTOTEST_SETTINGS_TR[] = QT_TRANSLATE_NOOP("AutoTest", "Test Settings");
+const char AUTOTEST_SETTINGS_TR[] = QT_TRANSLATE_NOOP("AutoTest", "Testing");
const char FRAMEWORK_PREFIX[] = "AutoTest.Framework.";
const char SETTINGSPAGE_PREFIX[] = "A.AutoTest.";
const char SETTINGSGROUP[] = "Autotest";
} // namespace Constants
+
+namespace Internal {
+enum class TestRunMode
+{
+ Run,
+ RunWithoutDeploy,
+ Debug,
+ DebugWithoutDeploy
+};
+} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/autotesticons.h b/src/plugins/autotest/autotesticons.h
index 1420be31ad8..632fc375e16 100644
--- a/src/plugins/autotest/autotesticons.h
+++ b/src/plugins/autotest/autotesticons.h
@@ -61,7 +61,9 @@ const Utils::Icon RESULT_BLACKLISTEDFAIL({
{":/utils/images/filledcircle.png", Utils::Theme::OutputPanes_TestFailTextColor},
{":/projectexplorer/images/buildstepdisable.png", Utils::Theme::PanelTextColorDark}},
Utils::Icon::Tint | Utils::Icon::PunchEdges);
-const Utils::Icon RESULT_BENCHMARK(":/images/benchmark.png");
+const Utils::Icon RESULT_BENCHMARK({
+ {":/utils/images/filledcircle.png", Utils::Theme::BackgroundColorNormal},
+ {":/images/benchmark.png", Utils::Theme::PanelTextColorDark}}, Utils::Icon::Tint);
const Utils::Icon RESULT_MESSAGEDEBUG({
{":/utils/images/filledcircle.png", Utils::Theme::OutputPanes_TestDebugTextColor}},
Utils::Icon::Tint);
diff --git a/src/plugins/autotest/autotestplugin.cpp b/src/plugins/autotest/autotestplugin.cpp
index 3d00400ccdc..316667ddf3a 100644
--- a/src/plugins/autotest/autotestplugin.cpp
+++ b/src/plugins/autotest/autotestplugin.cpp
@@ -116,7 +116,7 @@ void AutotestPlugin::initializeMenuEntries()
action = new QAction(tr("Re&scan Tests"), this);
command = ActionManager::registerAction(action, Constants::ACTION_SCAN_ID);
command->setDefaultKeySequence(QKeySequence(tr("Alt+Shift+T,Alt+S")));
- connect(action, &QAction::triggered, [this] () {
+ connect(action, &QAction::triggered, this, [] () {
TestTreeModel::instance()->parser()->updateTestTree();
});
menu->addAction(command);
@@ -170,7 +170,7 @@ void AutotestPlugin::onRunAllTriggered()
TestRunner *runner = TestRunner::instance();
TestTreeModel *model = TestTreeModel::instance();
runner->setSelectedTests(model->getAllTestCases());
- runner->prepareToRunTests(TestRunner::Run);
+ runner->prepareToRunTests(TestRunMode::Run);
}
void AutotestPlugin::onRunSelectedTriggered()
@@ -178,7 +178,7 @@ void AutotestPlugin::onRunSelectedTriggered()
TestRunner *runner = TestRunner::instance();
TestTreeModel *model = TestTreeModel::instance();
runner->setSelectedTests(model->getSelectedTests());
- runner->prepareToRunTests(TestRunner::Run);
+ runner->prepareToRunTests(TestRunMode::Run);
}
void AutotestPlugin::updateMenuItemsEnabledState()
diff --git a/src/plugins/autotest/gtest/gtestconfiguration.cpp b/src/plugins/autotest/gtest/gtestconfiguration.cpp
index 7be52a69c12..3e146f2db72 100644
--- a/src/plugins/autotest/gtest/gtestconfiguration.cpp
+++ b/src/plugins/autotest/gtest/gtestconfiguration.cpp
@@ -27,7 +27,11 @@
#include "gtestconstants.h"
#include "gtestoutputreader.h"
#include "gtestsettings.h"
+#include "../autotestplugin.h"
#include "../testframeworkmanager.h"
+#include "../testsettings.h"
+
+#include <utils/algorithm.h>
namespace Autotest {
namespace Internal {
@@ -38,12 +42,46 @@ TestOutputReader *GTestConfiguration::outputReader(const QFutureInterface<TestRe
return new GTestOutputReader(fi, app, buildDirectory(), projectFile());
}
-QStringList GTestConfiguration::argumentsForTestRunner() const
+QStringList filterInterfering(const QStringList &provided, QStringList *omitted)
+{
+ static const QSet<QString> knownInterferingOptions { "--gtest_list_tests",
+ "--gtest_filter=",
+ "--gtest_also_run_disabled_tests",
+ "--gtest_repeat=",
+ "--gtest_shuffle",
+ "--gtest_random_seed=",
+ "--gtest_output=",
+ "--gtest_stream_result_to=",
+ "--gtest_break_on_failure",
+ "--gtest_throw_on_failure",
+ "--gtest_color="
+ };
+
+ QSet<QString> allowed = Utils::filtered(provided.toSet(), [] (const QString &arg) {
+ return Utils::allOf(knownInterferingOptions, [&arg] (const QString &interfering) {
+ return !arg.startsWith(interfering);
+ });
+ });
+
+ if (omitted) {
+ QSet<QString> providedSet = provided.toSet();
+ providedSet.subtract(allowed);
+ omitted->append(providedSet.toList());
+ }
+ return allowed.toList();
+}
+
+QStringList GTestConfiguration::argumentsForTestRunner(QStringList *omitted) const
{
static const Core::Id id
= Core::Id(Constants::FRAMEWORK_PREFIX).withSuffix(GTest::Constants::FRAMEWORK_NAME);
QStringList arguments;
+ if (AutotestPlugin::instance()->settings()->processArgs) {
+ arguments << filterInterfering(runnable().commandLineArguments.split(
+ ' ', QString::SkipEmptyParts), omitted);
+ }
+
const QStringList &testSets = testCases();
if (testSets.size())
arguments << "--gtest_filter=" + testSets.join(':');
@@ -62,7 +100,7 @@ QStringList GTestConfiguration::argumentsForTestRunner() const
if (gSettings->throwOnFailure)
arguments << "--gtest_throw_on_failure";
- if (runMode() == DebuggableTestConfiguration::Debug) {
+ if (isDebugRunMode()) {
if (gSettings->breakOnFailure)
arguments << "--gtest_break_on_failure";
}
diff --git a/src/plugins/autotest/gtest/gtestconfiguration.h b/src/plugins/autotest/gtest/gtestconfiguration.h
index 141e7709378..9e2d63b1e97 100644
--- a/src/plugins/autotest/gtest/gtestconfiguration.h
+++ b/src/plugins/autotest/gtest/gtestconfiguration.h
@@ -36,7 +36,7 @@ public:
explicit GTestConfiguration() {}
TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
QProcess *app) const override;
- QStringList argumentsForTestRunner() const override;
+ QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
};
} // namespace Internal
diff --git a/src/plugins/autotest/gtest/gtestoutputreader.cpp b/src/plugins/autotest/gtest/gtestoutputreader.cpp
index 19712035110..764cf543a1b 100644
--- a/src/plugins/autotest/gtest/gtestoutputreader.cpp
+++ b/src/plugins/autotest/gtest/gtestoutputreader.cpp
@@ -206,7 +206,7 @@ GTestResult *GTestOutputReader::createDefaultResult() const
const TestTreeItem *GTestOutputReader::findTestTreeItemForCurrentLine() const
{
- const auto item = TestTreeModel::instance()->findNonRooItem([&](const Utils::TreeItem *item) {
+ const auto item = TestTreeModel::instance()->findNonRootItem([&](const Utils::TreeItem *item) {
const TestTreeItem &treeItem = static_cast<const TestTreeItem &>(*item);
return matches(treeItem);
});
diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp
index f41afacf7a4..92d24bc5a39 100644
--- a/src/plugins/autotest/gtest/gtesttreeitem.cpp
+++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp
@@ -115,7 +115,7 @@ TestConfiguration *GTestTreeItem::debugConfiguration() const
{
GTestConfiguration *config = static_cast<GTestConfiguration *>(testConfiguration());
if (config)
- config->setRunMode(DebuggableTestConfiguration::Debug);
+ config->setRunMode(TestRunMode::Debug);
return config;
}
@@ -294,6 +294,8 @@ QSet<QString> GTestTreeItem::internalTargets() const
const auto cppMM = CppTools::CppModelManager::instance();
const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject());
for (const CppTools::ProjectPart::Ptr projectPart : projectInfo.projectParts()) {
+ if (projectPart->buildTargetType != CppTools::ProjectPart::Executable)
+ continue;
if (projectPart->projectFile == proFile())
result.insert(projectPart->buildSystemTarget + '|' + projectPart->projectFile);
}
diff --git a/src/plugins/autotest/images/benchmark.png b/src/plugins/autotest/images/benchmark.png
index c9d3c5b2b50..021ac069ad1 100644
--- a/src/plugins/autotest/images/benchmark.png
+++ b/src/plugins/autotest/images/benchmark.png
Binary files differ
diff --git a/src/plugins/autotest/images/benchmark@2x.png b/src/plugins/autotest/images/benchmark@2x.png
new file mode 100644
index 00000000000..64eb95f7dcd
--- /dev/null
+++ b/src/plugins/autotest/images/benchmark@2x.png
Binary files differ
diff --git a/src/plugins/autotest/images/text.png b/src/plugins/autotest/images/text.png
index b43b92e09a1..7d4c35c70e6 100644
--- a/src/plugins/autotest/images/text.png
+++ b/src/plugins/autotest/images/text.png
Binary files differ
diff --git a/src/plugins/autotest/images/text@2x.png b/src/plugins/autotest/images/text@2x.png
index c93133a2d77..534acad25bf 100644
--- a/src/plugins/autotest/images/text@2x.png
+++ b/src/plugins/autotest/images/text@2x.png
Binary files differ
diff --git a/src/plugins/autotest/images/visual.png b/src/plugins/autotest/images/visual.png
index 092367618c0..62fd49061f5 100644
--- a/src/plugins/autotest/images/visual.png
+++ b/src/plugins/autotest/images/visual.png
Binary files differ
diff --git a/src/plugins/autotest/images/visual@2x.png b/src/plugins/autotest/images/visual@2x.png
index 1426597449f..99e612fa343 100644
--- a/src/plugins/autotest/images/visual@2x.png
+++ b/src/plugins/autotest/images/visual@2x.png
Binary files differ
diff --git a/src/plugins/autotest/qtest/qttest_utils.cpp b/src/plugins/autotest/qtest/qttest_utils.cpp
index e596ae71830..a832a093ce0 100644
--- a/src/plugins/autotest/qtest/qttest_utils.cpp
+++ b/src/plugins/autotest/qtest/qttest_utils.cpp
@@ -27,9 +27,11 @@
#include "qttesttreeitem.h"
#include "../testframeworkmanager.h"
+#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <QByteArrayList>
+#include <QSet>
namespace Autotest {
namespace Internal {
@@ -83,6 +85,62 @@ QMultiHash<QString, QString> alternativeFiles(const Core::Id &id, const QStringL
return result;
}
+QStringList filterInterfering(const QStringList &provided, QStringList *omitted, bool isQuickTest)
+{
+ static const QSet<QString> knownInterferingSingleOptions {
+ "-txt", "-xml", "-csv", "-xunitxml", "-lightxml", "-silent", "-v1", "-v2", "-vs", "-vb",
+ "-functions", "-datatags", "-nocrashhandler", "-callgrind", "-perf", "-perfcounterlist",
+ "-tickcounter", "-eventcounter", "-help"
+ };
+ static const QSet<QString> knownInterferingOptionWithParameter = { "-o" };
+ static const QSet<QString> knownAllowedOptionsWithParameter {
+ "-eventdelay", "-keydelay", "-mousedelay", "-maxwarnings", "-perfcounter",
+ "-minimumvalue", "-minimumtotal", "-iterations", "-median"
+ };
+
+ // handle Quick options as well
+ static const QSet<QString> knownInterferingQuickOption = { "-qtquick1" };
+ static const QSet<QString> knownAllowedQuickOptionsWithParameter {
+ "-import", "-plugins", "-input"
+ };
+
+ QStringList allowed;
+ auto it = provided.cbegin();
+ auto end = provided.cend();
+ for ( ; it != end; ++it) {
+ QString currentOpt = *it;
+ if (knownAllowedOptionsWithParameter.contains(currentOpt)) {
+ allowed.append(currentOpt);
+ ++it;
+ QTC_ASSERT(it != end, return QStringList());
+ allowed.append(*it);
+ } else if (knownInterferingOptionWithParameter.contains(currentOpt)) {
+ if (omitted) {
+ omitted->append(currentOpt);
+ ++it;
+ QTC_ASSERT(it != end, return QStringList());
+ omitted->append(*it);
+ }
+ } else if (knownInterferingSingleOptions.contains(currentOpt)) {
+ if (omitted)
+ omitted->append(currentOpt);
+ } else if (isQuickTest) {
+ if (knownAllowedQuickOptionsWithParameter.contains(currentOpt)) {
+ allowed.append(currentOpt);
+ ++it;
+ QTC_ASSERT(it != end, return QStringList());
+ allowed.append(*it);
+ } else if (knownInterferingQuickOption.contains(currentOpt)) {
+ if (omitted)
+ omitted->append(currentOpt);
+ }
+ } else { // might be bad, but we cannot know anything
+ allowed.append(currentOpt);
+ }
+ }
+ return allowed;
+}
+
} // namespace QTestUtils
} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/qtest/qttest_utils.h b/src/plugins/autotest/qtest/qttest_utils.h
index be4fb0a2ca8..30dfa85055d 100644
--- a/src/plugins/autotest/qtest/qttest_utils.h
+++ b/src/plugins/autotest/qtest/qttest_utils.h
@@ -36,6 +36,7 @@ namespace QTestUtils {
bool isQTestMacro(const QByteArray &macro);
QHash<QString, QString> testCaseNamesForFiles(const Core::Id &id, const QStringList &files);
QMultiHash<QString, QString> alternativeFiles(const Core::Id &id, const QStringList &files);
+QStringList filterInterfering(const QStringList &provided, QStringList *omitted, bool isQuickTest);
} // namespace QTestUtils
} // namespace Internal
diff --git a/src/plugins/autotest/qtest/qttestconfiguration.cpp b/src/plugins/autotest/qtest/qttestconfiguration.cpp
index 0875ec18a63..bb8f62aacfb 100644
--- a/src/plugins/autotest/qtest/qttestconfiguration.cpp
+++ b/src/plugins/autotest/qtest/qttestconfiguration.cpp
@@ -27,7 +27,10 @@
#include "qttestconstants.h"
#include "qttestoutputreader.h"
#include "qttestsettings.h"
+#include "qttest_utils.h"
+#include "../autotestplugin.h"
#include "../testframeworkmanager.h"
+#include "../testsettings.h"
namespace Autotest {
namespace Internal {
@@ -48,12 +51,17 @@ TestOutputReader *QtTestConfiguration::outputReader(const QFutureInterface<TestR
return new QtTestOutputReader(fi, app, buildDirectory(), QtTestOutputReader::PlainText);
}
-QStringList QtTestConfiguration::argumentsForTestRunner() const
+QStringList QtTestConfiguration::argumentsForTestRunner(QStringList *omitted) const
{
static const Core::Id id
= Core::Id(Constants::FRAMEWORK_PREFIX).withSuffix(QtTest::Constants::FRAMEWORK_NAME);
QStringList arguments;
+ if (AutotestPlugin::instance()->settings()->processArgs) {
+ arguments.append(QTestUtils::filterInterfering(
+ runnable().commandLineArguments.split(' ', QString::SkipEmptyParts),
+ omitted, false));
+ }
TestFrameworkManager *manager = TestFrameworkManager::instance();
auto qtSettings = qSharedPointerCast<QtTestSettings>(manager->settingsForTestFramework(id));
if (qtSettings.isNull())
@@ -73,7 +81,7 @@ QStringList QtTestConfiguration::argumentsForTestRunner() const
if (qtSettings->logSignalsSlots)
arguments << "-vs";
- if (runMode() == DebuggableTestConfiguration::Debug) {
+ if (isDebugRunMode()) {
if (qtSettings->noCrashHandler)
arguments << "-nocrashhandler";
}
diff --git a/src/plugins/autotest/qtest/qttestconfiguration.h b/src/plugins/autotest/qtest/qttestconfiguration.h
index f32737e7659..1dbc73be20f 100644
--- a/src/plugins/autotest/qtest/qttestconfiguration.h
+++ b/src/plugins/autotest/qtest/qttestconfiguration.h
@@ -36,7 +36,7 @@ public:
explicit QtTestConfiguration() {}
TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
QProcess *app) const override;
- QStringList argumentsForTestRunner() const override;
+ QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
};
} // namespace Internal
diff --git a/src/plugins/autotest/qtest/qttestparser.cpp b/src/plugins/autotest/qtest/qttestparser.cpp
index 93376cba7c9..a262148eccf 100644
--- a/src/plugins/autotest/qtest/qttestparser.cpp
+++ b/src/plugins/autotest/qtest/qttestparser.cpp
@@ -85,8 +85,11 @@ static bool qtTestLibDefined(const QString &fileName)
{
const QList<CppTools::ProjectPart::Ptr> parts =
CppTools::CppModelManager::instance()->projectPart(fileName);
- if (parts.size() > 0)
- return parts.at(0)->projectDefines.contains("#define QT_TESTLIB_LIB");
+ if (parts.size() > 0) {
+ return Utils::anyOf(parts.at(0)->projectMacros, [] (const ProjectExplorer::Macro &macro) {
+ return macro.key == "QT_TESTLIB_LIB";
+ });
+ }
return false;
}
diff --git a/src/plugins/autotest/qtest/qttesttreeitem.cpp b/src/plugins/autotest/qtest/qttesttreeitem.cpp
index 48fa4a9de9e..850ba6dc542 100644
--- a/src/plugins/autotest/qtest/qttesttreeitem.cpp
+++ b/src/plugins/autotest/qtest/qttesttreeitem.cpp
@@ -142,7 +142,7 @@ TestConfiguration *QtTestTreeItem::debugConfiguration() const
{
QtTestConfiguration *config = static_cast<QtTestConfiguration *>(testConfiguration());
if (config)
- config->setRunMode(DebuggableTestConfiguration::Debug);
+ config->setRunMode(TestRunMode::Debug);
return config;
}
diff --git a/src/plugins/autotest/quick/quicktestconfiguration.cpp b/src/plugins/autotest/quick/quicktestconfiguration.cpp
index 4d3241f0f27..88920e0352f 100644
--- a/src/plugins/autotest/quick/quicktestconfiguration.cpp
+++ b/src/plugins/autotest/quick/quicktestconfiguration.cpp
@@ -27,7 +27,10 @@
#include "../qtest/qttestconstants.h"
#include "../qtest/qttestoutputreader.h"
#include "../qtest/qttestsettings.h"
+#include "../qtest/qttest_utils.h"
+#include "../autotestplugin.h"
#include "../testframeworkmanager.h"
+#include "../testsettings.h"
namespace Autotest {
namespace Internal {
@@ -47,12 +50,18 @@ TestOutputReader *QuickTestConfiguration::outputReader(const QFutureInterface<Te
return new QtTestOutputReader(fi, app, buildDirectory(), QtTestOutputReader::PlainText);
}
-QStringList QuickTestConfiguration::argumentsForTestRunner() const
+QStringList QuickTestConfiguration::argumentsForTestRunner(QStringList *omitted) const
{
static const Core::Id id
= Core::Id(Constants::FRAMEWORK_PREFIX).withSuffix(QtTest::Constants::FRAMEWORK_NAME);
QStringList arguments;
+ if (AutotestPlugin::instance()->settings()->processArgs) {
+ arguments.append(QTestUtils::filterInterfering
+ (runnable().commandLineArguments.split(' ', QString::SkipEmptyParts),
+ omitted, true));
+ }
+
TestFrameworkManager *manager = TestFrameworkManager::instance();
auto qtSettings = qSharedPointerCast<QtTestSettings>(manager->settingsForTestFramework(id));
if (qtSettings.isNull())
diff --git a/src/plugins/autotest/quick/quicktestconfiguration.h b/src/plugins/autotest/quick/quicktestconfiguration.h
index 8ff754202ba..ecab2f4a2f3 100644
--- a/src/plugins/autotest/quick/quicktestconfiguration.h
+++ b/src/plugins/autotest/quick/quicktestconfiguration.h
@@ -36,7 +36,7 @@ public:
explicit QuickTestConfiguration() {}
TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
QProcess *app) const override;
- QStringList argumentsForTestRunner() const override;
+ QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
void setUnnamedOnly(bool unnamedOnly);
bool unnamedOnly() const { return m_unnamedOnly; }
diff --git a/src/plugins/autotest/quick/quicktestframework.cpp b/src/plugins/autotest/quick/quicktestframework.cpp
index 17e2c449be7..ef5423bb6f8 100644
--- a/src/plugins/autotest/quick/quicktestframework.cpp
+++ b/src/plugins/autotest/quick/quicktestframework.cpp
@@ -37,7 +37,7 @@ ITestParser *QuickTestFramework::createTestParser() const
TestTreeItem *QuickTestFramework::createRootNode() const
{
- return new QuickTestTreeItem(QCoreApplication::translate("QuickTestFramework", "Quick Tests"),
+ return new QuickTestTreeItem(QCoreApplication::translate("QuickTestFramework", "Quick Test"),
QString(), TestTreeItem::Root);
}
diff --git a/src/plugins/autotest/quick/quicktestparser.cpp b/src/plugins/autotest/quick/quicktestparser.cpp
index 0d897fe04e2..46566952ff9 100644
--- a/src/plugins/autotest/quick/quicktestparser.cpp
+++ b/src/plugins/autotest/quick/quicktestparser.cpp
@@ -89,20 +89,21 @@ static bool includesQtQuickTest(const CPlusPlus::Document::Ptr &doc,
static QString quickTestSrcDir(const CppTools::CppModelManager *cppMM,
const QString &fileName)
{
- static const QByteArray qtsd(" QUICK_TEST_SOURCE_DIR ");
const QList<CppTools::ProjectPart::Ptr> parts = cppMM->projectPart(fileName);
if (parts.size() > 0) {
- QByteArray projDefines(parts.at(0)->projectDefines);
- for (const QByteArray &line : projDefines.split('\n')) {
- if (line.contains(qtsd)) {
- QByteArray result = line.mid(line.indexOf(qtsd) + qtsd.length());
- if (result.startsWith('"'))
- result.remove(result.length() - 1, 1).remove(0, 1);
- if (result.startsWith("\\\""))
- result.remove(result.length() - 2, 2).remove(0, 2);
- return QLatin1String(result);
- }
- }
+ const ProjectExplorer::Macros &macros = parts.at(0)->projectMacros;
+ auto found = std::find_if(
+ macros.begin(),
+ macros.end(),
+ [] (const ProjectExplorer::Macro &macro) { return macro.key == "QUICK_TEST_SOURCE_DIR"; });
+ if (found != macros.end()) {
+ QByteArray result = found->value;
+ if (result.startsWith('"'))
+ result.remove(result.length() - 1, 1).remove(0, 1);
+ if (result.startsWith("\\\""))
+ result.remove(result.length() - 2, 2).remove(0, 2);
+ return QLatin1String(result);
+ }
}
return QString();
}
diff --git a/src/plugins/autotest/quick/quicktesttreeitem.cpp b/src/plugins/autotest/quick/quicktesttreeitem.cpp
index 9ebcdd48c6e..35202696364 100644
--- a/src/plugins/autotest/quick/quicktesttreeitem.cpp
+++ b/src/plugins/autotest/quick/quicktesttreeitem.cpp
@@ -292,6 +292,8 @@ QSet<QString> QuickTestTreeItem::internalTargets() const
const auto cppMM = CppTools::CppModelManager::instance();
const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject());
for (const CppTools::ProjectPart::Ptr projectPart : projectInfo.projectParts()) {
+ if (projectPart->buildTargetType != CppTools::ProjectPart::Executable)
+ continue;
if (projectPart->projectFile == proFile()) {
result.insert(projectPart->buildSystemTarget + '|' + projectPart->projectFile);
break;
diff --git a/src/plugins/autotest/testcodeparser.cpp b/src/plugins/autotest/testcodeparser.cpp
index ce0a655c2c6..feb32c58dbe 100644
--- a/src/plugins/autotest/testcodeparser.cpp
+++ b/src/plugins/autotest/testcodeparser.cpp
@@ -402,7 +402,7 @@ void TestCodeParser::scanForTests(const QStringList &fileList, ITestParser *pars
parser->init(list);
QFuture<TestParseResultPtr> future = Utils::map(list,
- [this, codeParsers](QFutureInterface<TestParseResultPtr> &fi, const QString &file) {
+ [codeParsers](QFutureInterface<TestParseResultPtr> &fi, const QString &file) {
parseFileForTests(codeParsers, fi, file);
},
Utils::MapReduceOption::Unordered,
diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp
index 7606b4827b7..396fbb4f1c8 100644
--- a/src/plugins/autotest/testconfiguration.cpp
+++ b/src/plugins/autotest/testconfiguration.cpp
@@ -26,7 +26,6 @@
#include "testconfiguration.h"
#include "testoutputreader.h"
#include "testrunconfiguration.h"
-#include "testrunner.h"
#include <cpptools/cppmodelmanager.h>
#include <cpptools/projectinfo.h>
@@ -73,7 +72,7 @@ static QString ensureExeEnding(const QString& file)
return Utils::HostOsInfo::withExecutableSuffix(file);
}
-void TestConfiguration::completeTestInformation(int runMode)
+void TestConfiguration::completeTestInformation(TestRunMode runMode)
{
QTC_ASSERT(!m_projectFile.isEmpty(), return);
QTC_ASSERT(!m_buildTargets.isEmpty(), return);
@@ -154,12 +153,11 @@ void TestConfiguration::completeTestInformation(int runMode)
return b.startsWith(currentBST);
}))) {
qCDebug(LOG) << " Using this RunConfig.";
- m_executableFile = currentExecutable;
+ m_runnable = stdRunnable;
+ m_runnable.executable = currentExecutable;
m_displayName = runConfig->displayName();
- m_workingDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory);
- m_environment = stdRunnable.environment;
m_project = project;
- if (runMode == TestRunner::Debug)
+ if (runMode == TestRunMode::Debug || runMode == TestRunMode::DebugWithoutDeploy)
m_runConfig = new TestRunConfiguration(runConfig->target(), this);
break;
}
@@ -169,9 +167,9 @@ void TestConfiguration::completeTestInformation(int runMode)
// or we might have end up using the (wrong) path of a locally installed executable
// for this case try the original executable path of the BuildTargetInfo (the executable
// before installation) to have at least something to execute
- if (m_executableFile.isEmpty() && !localExecutable.isEmpty())
- m_executableFile = localExecutable;
- if (m_displayName.isEmpty() && !m_executableFile.isEmpty()) {
+ if (m_runnable.executable.isEmpty() && !localExecutable.isEmpty())
+ m_runnable.executable = localExecutable;
+ if (m_displayName.isEmpty() && !m_runnable.executable.isEmpty()) {
qCDebug(LOG) << " Fallback";
// we failed to find a valid runconfiguration - but we've got the executable already
if (auto rc = target->activeRunConfiguration()) {
@@ -179,11 +177,11 @@ void TestConfiguration::completeTestInformation(int runMode)
Runnable runnable = rc->runnable();
if (runnable.is<StandardRunnable>()) {
StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
- m_environment = stdRunnable.environment;
+ m_runnable.environment = stdRunnable.environment;
m_project = project;
m_guessedConfiguration = true;
m_guessedFrom = rc->displayName();
- if (runMode == TestRunner::Debug)
+ if (runMode == TestRunMode::Debug)
m_runConfig = new TestRunConfiguration(rc->target(), this);
}
} else {
@@ -219,7 +217,7 @@ void TestConfiguration::setTestCaseCount(int count)
void TestConfiguration::setExecutableFile(const QString &executableFile)
{
- m_executableFile = executableFile;
+ m_runnable.executable = executableFile;
}
void TestConfiguration::setProjectFile(const QString &projectFile)
@@ -229,7 +227,7 @@ void TestConfiguration::setProjectFile(const QString &projectFile)
void TestConfiguration::setWorkingDirectory(const QString &workingDirectory)
{
- m_workingDir = workingDirectory;
+ m_runnable.workingDirectory = workingDirectory;
}
void TestConfiguration::setBuildDirectory(const QString &buildDirectory)
@@ -244,7 +242,7 @@ void TestConfiguration::setDisplayName(const QString &displayName)
void TestConfiguration::setEnvironment(const Utils::Environment &env)
{
- m_environment = env;
+ m_runnable.environment = env;
}
void TestConfiguration::setProject(Project *project)
@@ -259,17 +257,17 @@ void TestConfiguration::setInternalTargets(const QSet<QString> &targets)
QString TestConfiguration::executableFilePath() const
{
- if (m_executableFile.isEmpty())
+ if (m_runnable.executable.isEmpty())
return QString();
- QFileInfo commandFileInfo(m_executableFile);
+ QFileInfo commandFileInfo(m_runnable.executable);
if (commandFileInfo.isExecutable() && commandFileInfo.path() != ".") {
return commandFileInfo.absoluteFilePath();
} else if (commandFileInfo.path() == "."){
- QString fullCommandFileName = m_executableFile;
+ QString fullCommandFileName = m_runnable.executable;
// TODO: check if we can use searchInPath() from Utils::Environment
- const QStringList &pathList = m_environment.toProcessEnvironment().value("PATH").split(
- Utils::HostOsInfo::pathListSeparator());
+ const QStringList &pathList = m_runnable.environment.toProcessEnvironment().value("PATH")
+ .split(Utils::HostOsInfo::pathListSeparator());
foreach (const QString &path, pathList) {
QString filePath(path + QDir::separator() + fullCommandFileName);
@@ -282,8 +280,8 @@ QString TestConfiguration::executableFilePath() const
QString TestConfiguration::workingDirectory() const
{
- if (!m_workingDir.isEmpty()) {
- const QFileInfo info(m_workingDir);
+ if (!m_runnable.workingDirectory.isEmpty()) {
+ const QFileInfo info(m_runnable.workingDirectory);
if (info.isDir()) // ensure wanted working dir does exist
return info.absoluteFilePath();
}
@@ -292,5 +290,10 @@ QString TestConfiguration::workingDirectory() const
return executable.isEmpty() ? executable : QFileInfo(executable).absolutePath();
}
+bool DebuggableTestConfiguration::isDebugRunMode() const
+{
+ return m_runMode == TestRunMode::Debug || m_runMode == TestRunMode::DebugWithoutDeploy;
+}
+
} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/testconfiguration.h b/src/plugins/autotest/testconfiguration.h
index 248b9aaeb76..7ec208af2a9 100644
--- a/src/plugins/autotest/testconfiguration.h
+++ b/src/plugins/autotest/testconfiguration.h
@@ -28,6 +28,7 @@
#include "autotestconstants.h"
#include <projectexplorer/project.h>
+#include <projectexplorer/runnables.h>
#include <utils/environment.h>
#include <QFutureInterface>
@@ -49,13 +50,12 @@ class TestRunConfiguration;
using TestResultPtr = QSharedPointer<TestResult>;
class TestConfiguration
-
{
public:
explicit TestConfiguration();
virtual ~TestConfiguration();
- void completeTestInformation(int runMode);
+ void completeTestInformation(TestRunMode runMode);
void setTestCases(const QStringList &testCases);
void setTestCaseCount(int count);
@@ -75,51 +75,44 @@ public:
QString buildDirectory() const { return m_buildDir; }
QString projectFile() const { return m_projectFile; }
QString displayName() const { return m_displayName; }
- Utils::Environment environment() const { return m_environment; }
+ Utils::Environment environment() const { return m_runnable.environment; }
ProjectExplorer::Project *project() const { return m_project.data(); }
TestRunConfiguration *runConfiguration() const { return m_runConfig; }
bool isGuessed() const { return m_guessedConfiguration; }
QString runConfigDisplayName() const { return m_guessedConfiguration ? m_guessedFrom
: m_displayName; }
+ ProjectExplorer::StandardRunnable runnable() const { return m_runnable; }
virtual TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
QProcess *app) const = 0;
- virtual QStringList argumentsForTestRunner() const = 0;
+ virtual QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const = 0;
private:
QStringList m_testCases;
int m_testCaseCount = 0;
QString m_projectFile;
- QString m_executableFile;
- QString m_workingDir;
QString m_buildDir;
QString m_displayName;
QString m_guessedFrom;
- Utils::Environment m_environment;
QPointer<ProjectExplorer::Project> m_project;
bool m_guessedConfiguration = false;
TestRunConfiguration *m_runConfig = 0;
QSet<QString> m_buildTargets;
+ ProjectExplorer::StandardRunnable m_runnable;
};
class DebuggableTestConfiguration : public TestConfiguration
{
public:
- enum RunMode
- {
- Run,
- Debug
- };
-
- explicit DebuggableTestConfiguration(RunMode runMode = Run) : m_runMode(runMode) {}
+ explicit DebuggableTestConfiguration(TestRunMode runMode = TestRunMode::Run)
+ : m_runMode(runMode) {}
~DebuggableTestConfiguration() {}
- void setRunMode(RunMode mode) { m_runMode = mode; }
- RunMode runMode() const { return m_runMode; }
-
-
+ void setRunMode(TestRunMode mode) { m_runMode = mode; }
+ TestRunMode runMode() const { return m_runMode; }
+ bool isDebugRunMode() const;
private:
- RunMode m_runMode;
+ TestRunMode m_runMode;
};
} // namespace Internal
diff --git a/src/plugins/autotest/testnavigationwidget.cpp b/src/plugins/autotest/testnavigationwidget.cpp
index 5e34c666e00..ddc010ef0d2 100644
--- a/src/plugins/autotest/testnavigationwidget.cpp
+++ b/src/plugins/autotest/testnavigationwidget.cpp
@@ -86,7 +86,7 @@ TestNavigationWidget::TestNavigationWidget(QWidget *parent) :
connect(m_view, &TestTreeView::activated, this, &TestNavigationWidget::onItemActivated);
- m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicator::Medium, this);
+ m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Medium, this);
m_progressIndicator->attachToWidget(m_view);
m_progressIndicator->hide();
@@ -136,13 +136,13 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event)
runThisTest->setEnabled(enabled);
connect(runThisTest, &QAction::triggered,
this, [this] () {
- onRunThisTestTriggered(TestRunner::Run);
+ onRunThisTestTriggered(TestRunMode::Run);
});
runWithoutDeploy = new QAction(tr("Run Without Deployment"), &menu);
runWithoutDeploy->setEnabled(enabled);
connect(runWithoutDeploy, &QAction::triggered,
this, [this] () {
- onRunThisTestTriggered(TestRunner::RunWithoutDeploy);
+ onRunThisTestTriggered(TestRunMode::RunWithoutDeploy);
});
}
if (item->canProvideDebugConfiguration()) {
@@ -150,13 +150,13 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event)
debugThisTest->setEnabled(enabled);
connect(debugThisTest, &QAction::triggered,
this, [this] () {
- onRunThisTestTriggered(TestRunner::Debug);
+ onRunThisTestTriggered(TestRunMode::Debug);
});
debugWithoutDeploy = new QAction(tr("Debug Without Deployment"), &menu);
debugWithoutDeploy->setEnabled(enabled);
connect(debugWithoutDeploy, &QAction::triggered,
this, [this] () {
- onRunThisTestTriggered(TestRunner::DebugWithoutDeploy);
+ onRunThisTestTriggered(TestRunMode::DebugWithoutDeploy);
});
}
}
@@ -291,7 +291,7 @@ void TestNavigationWidget::initializeFilterMenu()
m_filterMenu->addAction(action);
}
-void TestNavigationWidget::onRunThisTestTriggered(TestRunner::Mode runMode)
+void TestNavigationWidget::onRunThisTestTriggered(TestRunMode runMode)
{
const QModelIndexList selected = m_view->selectionModel()->selectedIndexes();
if (selected.isEmpty())
@@ -303,12 +303,12 @@ void TestNavigationWidget::onRunThisTestTriggered(TestRunner::Mode runMode)
TestTreeItem *item = static_cast<TestTreeItem *>(sourceIndex.internalPointer());
TestConfiguration *configuration;
switch (runMode) {
- case TestRunner::Run:
- case TestRunner::RunWithoutDeploy:
+ case TestRunMode::Run:
+ case TestRunMode::RunWithoutDeploy:
configuration = item->testConfiguration();
break;
- case TestRunner::Debug:
- case TestRunner::DebugWithoutDeploy:
+ case TestRunMode::Debug:
+ case TestRunMode::DebugWithoutDeploy:
configuration = item->debugConfiguration();
break;
default:
diff --git a/src/plugins/autotest/testnavigationwidget.h b/src/plugins/autotest/testnavigationwidget.h
index 90031b4804e..163547c9c16 100644
--- a/src/plugins/autotest/testnavigationwidget.h
+++ b/src/plugins/autotest/testnavigationwidget.h
@@ -72,7 +72,7 @@ private:
void onParsingStarted();
void onParsingFinished();
void initializeFilterMenu();
- void onRunThisTestTriggered(TestRunner::Mode runMode);
+ void onRunThisTestTriggered(TestRunMode runMode);
TestTreeModel *m_model;
TestTreeSortFilterModel *m_sortFilterModel;
diff --git a/src/plugins/autotest/testresultspane.cpp b/src/plugins/autotest/testresultspane.cpp
index 41c9e216e69..332a518d94f 100644
--- a/src/plugins/autotest/testresultspane.cpp
+++ b/src/plugins/autotest/testresultspane.cpp
@@ -423,14 +423,14 @@ void TestResultsPane::onRunAllTriggered()
{
TestRunner *runner = TestRunner::instance();
runner->setSelectedTests(TestTreeModel::instance()->getAllTestCases());
- runner->prepareToRunTests(TestRunner::Run);
+ runner->prepareToRunTests(TestRunMode::Run);
}
void TestResultsPane::onRunSelectedTriggered()
{
TestRunner *runner = TestRunner::instance();
runner->setSelectedTests(TestTreeModel::instance()->getSelectedTests());
- runner->prepareToRunTests(TestRunner::Run);
+ runner->prepareToRunTests(TestRunMode::Run);
}
void TestResultsPane::initializeFilterMenu()
diff --git a/src/plugins/autotest/testrunconfiguration.h b/src/plugins/autotest/testrunconfiguration.h
index 593746dab5d..b0cd1c8e1d2 100644
--- a/src/plugins/autotest/testrunconfiguration.h
+++ b/src/plugins/autotest/testrunconfiguration.h
@@ -47,8 +47,9 @@ class TestRunConfiguration : public ProjectExplorer::RunConfiguration
public:
TestRunConfiguration(ProjectExplorer::Target *parent, TestConfiguration *config)
- : ProjectExplorer::RunConfiguration(parent, "AutoTest.TestRunConfig")
+ : ProjectExplorer::RunConfiguration(parent)
{
+ initialize("AutoTest.TestRunConfig");
setDefaultDisplayName(tr("AutoTest Debug"));
// disable QmlDebugger that is enabled by default
diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp
index dccaebaaf1d..4c9ba7f645d 100644
--- a/src/plugins/autotest/testrunner.cpp
+++ b/src/plugins/autotest/testrunner.cpp
@@ -51,7 +51,6 @@
#include <debugger/debuggerkitinformation.h>
#include <debugger/debuggerruncontrol.h>
-#include <debugger/debuggerstartparameters.h>
namespace Autotest {
namespace Internal {
@@ -119,6 +118,15 @@ static QString rcInfo(const TestConfiguration * const config)
return info + " \"" + config->runConfigDisplayName() + '"';
}
+static QString constructOmittedDetailsString(const QStringList &omitted)
+{
+ QString details = TestRunner::tr("Omitted the following arguments specified on the run "
+ "configuration page for \"%1\":");
+ for (const QString &arg : omitted)
+ details += "\n" + arg;
+ return details;
+}
+
static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface,
const QList<TestConfiguration *> selectedTests,
const TestSettings &settings)
@@ -128,7 +136,7 @@ static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface,
QEventLoop eventLoop;
int testCaseCount = 0;
for (TestConfiguration *config : selectedTests) {
- config->completeTestInformation(TestRunner::Run);
+ config->completeTestInformation(TestRunMode::Run);
if (config->project()) {
testCaseCount += config->testCaseCount();
if (!omitRunConfigWarnings && config->isGuessed()) {
@@ -174,7 +182,13 @@ static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface,
continue;
}
- testProcess.setArguments(testConfiguration->argumentsForTestRunner());
+ QStringList omitted;
+ testProcess.setArguments(testConfiguration->argumentsForTestRunner(&omitted));
+ if (!omitted.isEmpty()) {
+ const QString &details = constructOmittedDetailsString(omitted);
+ futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageWarn,
+ details.arg(testConfiguration->displayName()))));
+ }
testProcess.setWorkingDirectory(testConfiguration->workingDirectory());
if (Utils::HostOsInfo::isWindowsHost())
environment.insert("QT_LOGGING_TO_CONSOLE", "1");
@@ -225,7 +239,7 @@ static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface,
futureInterface.setProgressValue(testCaseCount);
}
-void TestRunner::prepareToRunTests(Mode mode)
+void TestRunner::prepareToRunTests(TestRunMode mode)
{
m_runMode = mode;
ProjectExplorer::Internal::ProjectExplorerSettings projectExplorerSettings =
@@ -258,8 +272,8 @@ void TestRunner::prepareToRunTests(Mode mode)
return;
}
- if (!projectExplorerSettings.buildBeforeDeploy || mode == TestRunner::DebugWithoutDeploy
- || mode == TestRunner::RunWithoutDeploy) {
+ if (!projectExplorerSettings.buildBeforeDeploy || mode == TestRunMode::DebugWithoutDeploy
+ || mode == TestRunMode::RunWithoutDeploy) {
runOrDebugTests();
} else if (project->hasActiveBuildSettings()) {
buildProject(project);
@@ -312,7 +326,7 @@ void TestRunner::debugTests()
QTC_ASSERT(m_selectedTests.size() == 1, onFinished();return);
TestConfiguration *config = m_selectedTests.first();
- config->completeTestInformation(Debug);
+ config->completeTestInformation(TestRunMode::Debug);
if (!config->runConfiguration()) {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
TestRunner::tr("Failed to get run configuration."))));
@@ -330,13 +344,6 @@ void TestRunner::debugTests()
return;
}
- Debugger::DebuggerStartParameters sp;
- sp.inferior.executable = commandFilePath;
- sp.inferior.commandLineArguments = config->argumentsForTestRunner().join(' ');
- sp.inferior.environment = config->environment();
- sp.inferior.workingDirectory = config->workingDirectory();
- sp.displayName = config->displayName();
-
QString errorMessage;
auto runControl = new ProjectExplorer::RunControl(config->runConfiguration(),
ProjectExplorer::Constants::DEBUG_RUN_MODE);
@@ -347,7 +354,18 @@ void TestRunner::debugTests()
return;
}
- (void) new Debugger::DebuggerRunTool(runControl, sp);
+ QStringList omitted;
+ ProjectExplorer::StandardRunnable inferior = config->runnable();
+ inferior.executable = commandFilePath;
+ inferior.commandLineArguments = config->argumentsForTestRunner(&omitted).join(' ');
+ if (!omitted.isEmpty()) {
+ const QString &details = constructOmittedDetailsString(omitted);
+ emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn,
+ details.arg(config->displayName()))));
+ }
+ auto debugger = new Debugger::DebuggerRunTool(runControl);
+ debugger->setInferior(inferior);
+ debugger->setRunControlName(config->displayName());
bool useOutputProcessor = true;
if (ProjectExplorer::Target *targ = config->project()->activeTarget()) {
@@ -369,7 +387,7 @@ void TestRunner::debugTests()
connect(outputreader, &TestOutputReader::newOutputAvailable,
TestResultsPane::instance(), &TestResultsPane::addOutput);
connect(runControl, &ProjectExplorer::RunControl::appendMessageRequested,
- this, [this, outputreader]
+ this, [outputreader]
(ProjectExplorer::RunControl *, const QString &msg, Utils::OutputFormat format) {
processOutput(outputreader, msg, format);
});
@@ -387,12 +405,12 @@ void TestRunner::debugTests()
void TestRunner::runOrDebugTests()
{
switch (m_runMode) {
- case Run:
- case RunWithoutDeploy:
+ case TestRunMode::Run:
+ case TestRunMode::RunWithoutDeploy:
runTests();
break;
- case Debug:
- case DebugWithoutDeploy:
+ case TestRunMode::Debug:
+ case TestRunMode::DebugWithoutDeploy:
debugTests();
break;
default:
diff --git a/src/plugins/autotest/testrunner.h b/src/plugins/autotest/testrunner.h
index cb796ae5a0b..b146d7fb95e 100644
--- a/src/plugins/autotest/testrunner.h
+++ b/src/plugins/autotest/testrunner.h
@@ -44,21 +44,13 @@ class TestRunner : public QObject
Q_OBJECT
public:
- enum Mode
- {
- Run,
- RunWithoutDeploy,
- Debug,
- DebugWithoutDeploy
- };
-
static TestRunner* instance();
~TestRunner();
void setSelectedTests(const QList<TestConfiguration *> &selected);
bool isTestRunning() const { return m_executingTests; }
- void prepareToRunTests(Mode mode);
+ void prepareToRunTests(TestRunMode mode);
signals:
void testRunStarted();
@@ -79,7 +71,7 @@ private:
QFutureWatcher<TestResultPtr> m_futureWatcher;
QList<TestConfiguration *> m_selectedTests;
bool m_executingTests;
- Mode m_runMode = Run;
+ TestRunMode m_runMode = TestRunMode::Run;
// temporarily used if building before running is necessary
QMetaObject::Connection m_buildConnect;
diff --git a/src/plugins/autotest/testsettings.cpp b/src/plugins/autotest/testsettings.cpp
index 0b24390b958..3756ef3cc23 100644
--- a/src/plugins/autotest/testsettings.cpp
+++ b/src/plugins/autotest/testsettings.cpp
@@ -41,6 +41,7 @@ static const char limitResultOutputKey[] = "LimitResultOutput";
static const char autoScrollKey[] = "AutoScrollResults";
static const char filterScanKey[] = "FilterScan";
static const char filtersKey[] = "WhiteListFilters";
+static const char processArgsKey[] = "ProcessArgs";
static const int defaultTimeout = 60000;
@@ -57,6 +58,7 @@ void TestSettings::toSettings(QSettings *s) const
s->setValue(omitRunConfigWarnKey, omitRunConfigWarn);
s->setValue(limitResultOutputKey, limitResultOutput);
s->setValue(autoScrollKey, autoScroll);
+ s->setValue(processArgsKey, processArgs);
s->setValue(filterScanKey, filterScan);
s->setValue(filtersKey, whiteListFilters);
// store frameworks and their current active state
@@ -73,6 +75,7 @@ void TestSettings::fromSettings(QSettings *s)
omitRunConfigWarn = s->value(omitRunConfigWarnKey, false).toBool();
limitResultOutput = s->value(limitResultOutputKey, true).toBool();
autoScroll = s->value(autoScrollKey, true).toBool();
+ processArgs = s->value(processArgsKey, false).toBool();
filterScan = s->value(filterScanKey, false).toBool();
whiteListFilters = s->value(filtersKey, QStringList()).toStringList();
// try to get settings for registered frameworks
diff --git a/src/plugins/autotest/testsettings.h b/src/plugins/autotest/testsettings.h
index b3e0893b9d0..449a56f322f 100644
--- a/src/plugins/autotest/testsettings.h
+++ b/src/plugins/autotest/testsettings.h
@@ -48,6 +48,7 @@ struct TestSettings
bool limitResultOutput = true;
bool autoScroll = true;
bool filterScan = false;
+ bool processArgs = false;
QHash<Core::Id, bool> frameworks;
QStringList whiteListFilters;
};
diff --git a/src/plugins/autotest/testsettingspage.cpp b/src/plugins/autotest/testsettingspage.cpp
index 4f2322ab03a..92bf473b736 100644
--- a/src/plugins/autotest/testsettingspage.cpp
+++ b/src/plugins/autotest/testsettingspage.cpp
@@ -148,6 +148,7 @@ void TestSettingsWidget::setSettings(const TestSettings &settings)
m_ui.omitRunConfigWarnCB->setChecked(settings.omitRunConfigWarn);
m_ui.limitResultOutputCB->setChecked(settings.limitResultOutput);
m_ui.autoScrollCB->setChecked(settings.autoScroll);
+ m_ui.processArgsCB->setChecked(settings.processArgs);
m_ui.filterGroupBox->setChecked(settings.filterScan);
populateFrameworksListWidget(settings.frameworks);
populateFiltersWidget(settings.whiteListFilters);
@@ -161,6 +162,7 @@ TestSettings TestSettingsWidget::settings() const
result.omitRunConfigWarn = m_ui.omitRunConfigWarnCB->isChecked();
result.limitResultOutput = m_ui.limitResultOutputCB->isChecked();
result.autoScroll = m_ui.autoScrollCB->isChecked();
+ result.processArgs = m_ui.processArgsCB->isChecked();
result.filterScan = m_ui.filterGroupBox->isChecked();
result.frameworks = frameworks();
result.whiteListFilters = filters();
diff --git a/src/plugins/autotest/testsettingspage.ui b/src/plugins/autotest/testsettingspage.ui
index 9ab4a5951f7..dd0d43ed114 100644
--- a/src/plugins/autotest/testsettingspage.ui
+++ b/src/plugins/autotest/testsettingspage.ui
@@ -74,6 +74,17 @@
</widget>
</item>
<item>
+ <widget class="QCheckBox" name="processArgsCB">
+ <property name="toolTip">
+ <string>Allow passing arguments specified on the respective run configuration.
+Warning: this is an experimental feature and might lead to failing to execute the test executable.</string>
+ </property>
+ <property name="text">
+ <string>Process arguments</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0,0">
<property name="spacing">
<number>6</number>
diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp
index d5fba23b2ac..626fda93d3b 100644
--- a/src/plugins/autotest/testtreeitem.cpp
+++ b/src/plugins/autotest/testtreeitem.cpp
@@ -288,8 +288,11 @@ QSet<QString> TestTreeItem::internalTargets() const
auto cppMM = CppTools::CppModelManager::instance();
const QList<CppTools::ProjectPart::Ptr> projectParts = cppMM->projectPart(filePath());
QSet<QString> targets;
- for (const CppTools::ProjectPart::Ptr part : projectParts)
+ for (const CppTools::ProjectPart::Ptr part : projectParts) {
+ if (part->buildTargetType != CppTools::ProjectPart::Executable)
+ continue;
targets.insert(part->buildSystemTarget + '|' + part->projectFile);
+ }
return targets;
}
diff --git a/src/plugins/autotoolsprojectmanager/autogenstep.cpp b/src/plugins/autotoolsprojectmanager/autogenstep.cpp
index 09e9c9a75dc..6f62126e9b2 100644
--- a/src/plugins/autotoolsprojectmanager/autogenstep.cpp
+++ b/src/plugins/autotoolsprojectmanager/autogenstep.cpp
@@ -110,7 +110,7 @@ bool AutogenStep::init(QList<const BuildStep *> &earlierSteps)
pp->setEnvironment(bc->environment());
const QString projectDir(bc->target()->project()->projectDirectory().toString());
pp->setWorkingDirectory(projectDir);
- pp->setCommand(QLatin1String("./autogen.sh"));
+ pp->setCommand("./autogen.sh");
pp->setArguments(additionalArguments());
pp->resolveAll();
@@ -123,9 +123,9 @@ void AutogenStep::run(QFutureInterface<bool> &fi)
// Check whether we need to run autogen.sh
const QString projectDir(bc->target()->project()->projectDirectory().toString());
- const QFileInfo configureInfo(projectDir + QLatin1String("/configure"));
- const QFileInfo configureAcInfo(projectDir + QLatin1String("/configure.ac"));
- const QFileInfo makefileAmInfo(projectDir + QLatin1String("/Makefile.am"));
+ const QFileInfo configureInfo(projectDir + "/configure");
+ const QFileInfo configureAcInfo(projectDir + "/configure.ac");
+ const QFileInfo makefileAmInfo(projectDir + "/Makefile.am");
if (!configureInfo.exists()
|| configureInfo.lastModified() < configureAcInfo.lastModified()
@@ -173,13 +173,13 @@ QVariantMap AutogenStep::toMap() const
{
QVariantMap map(AbstractProcessStep::toMap());
- map.insert(QLatin1String(AUTOGEN_ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments);
+ map.insert(AUTOGEN_ADDITIONAL_ARGUMENTS_KEY, m_additionalArguments);
return map;
}
bool AutogenStep::fromMap(const QVariantMap &map)
{
- m_additionalArguments = map.value(QLatin1String(AUTOGEN_ADDITIONAL_ARGUMENTS_KEY)).toString();
+ m_additionalArguments = map.value(AUTOGEN_ADDITIONAL_ARGUMENTS_KEY).toString();
return BuildStep::fromMap(map);
}
@@ -226,7 +226,7 @@ void AutogenStepConfigWidget::updateDetails()
param.setEnvironment(bc->environment());
const QString projectDir(bc->target()->project()->projectDirectory().toString());
param.setWorkingDirectory(projectDir);
- param.setCommand(QLatin1String("./autogen.sh"));
+ param.setCommand("./autogen.sh");
param.setArguments(m_autogenStep->additionalArguments());
m_summaryText = param.summary(displayName());
emit updateSummary();
diff --git a/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp
index 5512f5ecb49..0277ca91c9d 100644
--- a/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp
+++ b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp
@@ -111,7 +111,7 @@ bool AutoreconfStep::init(QList<const BuildStep *> &earlierSteps)
pp->setEnvironment(bc->environment());
const QString projectDir(bc->target()->project()->projectDirectory().toString());
pp->setWorkingDirectory(projectDir);
- pp->setCommand(QLatin1String("autoreconf"));
+ pp->setCommand("autoreconf");
pp->setArguments(additionalArguments());
pp->resolveAll();
@@ -125,7 +125,7 @@ void AutoreconfStep::run(QFutureInterface<bool> &fi)
// Check whether we need to run autoreconf
const QString projectDir(bc->target()->project()->projectDirectory().toString());
- if (!QFileInfo::exists(projectDir + QLatin1String("/configure")))
+ if (!QFileInfo::exists(projectDir + "/configure"))
m_runAutoreconf = true;
if (!m_runAutoreconf) {
@@ -168,13 +168,13 @@ QVariantMap AutoreconfStep::toMap() const
{
QVariantMap map = AbstractProcessStep::toMap();
- map.insert(QLatin1String(AUTORECONF_ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments);
+ map.insert(AUTORECONF_ADDITIONAL_ARGUMENTS_KEY, m_additionalArguments);
return map;
}
bool AutoreconfStep::fromMap(const QVariantMap &map)
{
- m_additionalArguments = map.value(QLatin1String(AUTORECONF_ADDITIONAL_ARGUMENTS_KEY)).toString();
+ m_additionalArguments = map.value(AUTORECONF_ADDITIONAL_ARGUMENTS_KEY).toString();
return BuildStep::fromMap(map);
}
@@ -221,7 +221,7 @@ void AutoreconfStepConfigWidget::updateDetails()
param.setEnvironment(bc->environment());
const QString projectDir(bc->target()->project()->projectDirectory().toString());
param.setWorkingDirectory(projectDir);
- param.setCommand(QLatin1String("autoreconf"));
+ param.setCommand("autoreconf");
param.setArguments(m_autoreconfStep->additionalArguments());
m_summaryText = param.summary(displayName());
emit updateSummary();
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp b/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp
index 82bc2e01627..37a8d6fd927 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp
@@ -81,7 +81,7 @@ BuildPathPage::BuildPathPage(AutotoolsOpenProjectWizard *w) : QWizardPage(w),
QLabel *label = new QLabel(this);
label->setWordWrap(true);
label->setText(tr("Please enter the directory in which you want to build your project. "
- "Qt Creator recommends to not use the source directory for building. "
+ "It is not recommended to use the source directory for building. "
"This ensures that the source directory remains clean and enables multiple builds "
"with different settings."));
fl->addWidget(label);
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
index e4a89e9edc5..01105d84979 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
@@ -119,6 +119,7 @@ Project::RestoreResult AutotoolsProject::fromMap(const QVariantMap &map, QString
void AutotoolsProject::loadProjectTree()
{
+ emitParsingStarted();
if (m_makefileParserThread) {
// The thread is still busy parsing a previus configuration.
// Wait until the thread has been finished and delete it.
@@ -218,7 +219,7 @@ void AutotoolsProject::makefileParsingFinished()
m_makefileParserThread->deleteLater();
m_makefileParserThread = nullptr;
- emit parsingFinished();
+ emitParsingFinished(true);
}
void AutotoolsProject::onFileChanged(const QString &file)
@@ -297,7 +298,7 @@ void AutotoolsProject::updateCppCodeModel()
? target->activeBuildConfiguration()->buildDirectory().toString() : QString();
rpp.setIncludePaths(filterIncludes(absSrc, absBuild, m_makefileParserThread->includePaths()));
- rpp.setDefines(m_makefileParserThread->defines());
+ rpp.setMacros(m_makefileParserThread->macros());
rpp.setFiles(m_files);
m_cppCodeModelUpdater->update({this, cToolChain, cxxToolChain, k, {rpp}});
diff --git a/src/plugins/autotoolsprojectmanager/configurestep.cpp b/src/plugins/autotoolsprojectmanager/configurestep.cpp
index fbfd5f47e67..8fdb2c67281 100644
--- a/src/plugins/autotoolsprojectmanager/configurestep.cpp
+++ b/src/plugins/autotoolsprojectmanager/configurestep.cpp
@@ -58,9 +58,9 @@ static QString projectDirRelativeToBuildDir(BuildConfiguration *bc) {
QString projDirToBuildDir = buildDir.relativeFilePath(
bc->target()->project()->projectDirectory().toString());
if (projDirToBuildDir.isEmpty())
- return QLatin1String("./");
- if (!projDirToBuildDir.endsWith(QLatin1Char('/')))
- projDirToBuildDir.append(QLatin1Char('/'));
+ return QString("./");
+ if (!projDirToBuildDir.endsWith('/'))
+ projDirToBuildDir.append('/');
return projDirToBuildDir;
}
@@ -125,7 +125,7 @@ bool ConfigureStep::init(QList<const BuildStep *> &earlierSteps)
pp->setMacroExpander(bc->macroExpander());
pp->setEnvironment(bc->environment());
pp->setWorkingDirectory(bc->buildDirectory().toString());
- pp->setCommand(projectDirRelativeToBuildDir(bc) + QLatin1String("configure"));
+ pp->setCommand(projectDirRelativeToBuildDir(bc) + "configure");
pp->setArguments(additionalArguments());
pp->resolveAll();
@@ -138,8 +138,8 @@ void ConfigureStep::run(QFutureInterface<bool>& fi)
//Check whether we need to run configure
const QString projectDir(bc->target()->project()->projectDirectory().toString());
- const QFileInfo configureInfo(projectDir + QLatin1String("/configure"));
- const QFileInfo configStatusInfo(bc->buildDirectory().toString() + QLatin1String("/config.status"));
+ const QFileInfo configureInfo(projectDir + "/configure");
+ const QFileInfo configStatusInfo(bc->buildDirectory().toString() + "/config.status");
if (!configStatusInfo.exists()
|| configStatusInfo.lastModified() < configureInfo.lastModified()) {
@@ -191,13 +191,13 @@ QVariantMap ConfigureStep::toMap() const
{
QVariantMap map = AbstractProcessStep::toMap();
- map.insert(QLatin1String(CONFIGURE_ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments);
+ map.insert(CONFIGURE_ADDITIONAL_ARGUMENTS_KEY, m_additionalArguments);
return map;
}
bool ConfigureStep::fromMap(const QVariantMap &map)
{
- m_additionalArguments = map.value(QLatin1String(CONFIGURE_ADDITIONAL_ARGUMENTS_KEY)).toString();
+ m_additionalArguments = map.value(CONFIGURE_ADDITIONAL_ARGUMENTS_KEY).toString();
return BuildStep::fromMap(map);
}
@@ -245,7 +245,7 @@ void ConfigureStepConfigWidget::updateDetails()
param.setMacroExpander(bc->macroExpander());
param.setEnvironment(bc->environment());
param.setWorkingDirectory(bc->buildDirectory().toString());
- param.setCommand(projectDirRelativeToBuildDir(bc) + QLatin1String("configure"));
+ param.setCommand(projectDirRelativeToBuildDir(bc) + "configure");
param.setArguments(m_configureStep->additionalArguments());
m_summaryText = param.summaryInWorkdir(displayName());
emit updateSummary();
diff --git a/src/plugins/autotoolsprojectmanager/makefileparser.cpp b/src/plugins/autotoolsprojectmanager/makefileparser.cpp
index 74e29054ec6..9c3e32216b6 100644
--- a/src/plugins/autotoolsprojectmanager/makefileparser.cpp
+++ b/src/plugins/autotoolsprojectmanager/makefileparser.cpp
@@ -108,9 +108,9 @@ QStringList MakefileParser::includePaths() const
return m_includePaths;
}
-QByteArray MakefileParser::defines() const
+ProjectExplorer::Macros MakefileParser::macros() const
{
- return m_defines;
+ return m_macros;
}
QStringList MakefileParser::cflags() const
@@ -449,11 +449,7 @@ bool MakefileParser::maybeParseDefine(const QString &term)
{
if (term.startsWith(QLatin1String("-D"))) {
QString def = term.mid(2); // remove the "-D"
- QByteArray data = def.toUtf8();
- int pos = data.indexOf('=');
- if (pos >= 0)
- data[pos] = ' ';
- m_defines += (QByteArray("#define ") + data + '\n');
+ m_macros += ProjectExplorer::Macro::fromKeyValue(def);
return true;
}
return false;
diff --git a/src/plugins/autotoolsprojectmanager/makefileparser.h b/src/plugins/autotoolsprojectmanager/makefileparser.h
index beaa1a57dbb..d6387bc29c7 100644
--- a/src/plugins/autotoolsprojectmanager/makefileparser.h
+++ b/src/plugins/autotoolsprojectmanager/makefileparser.h
@@ -27,10 +27,13 @@
#pragma once
+#include <projectexplorer/projectmacro.h>
+
#include <QMutex>
#include <QStringList>
#include <QTextStream>
#include <QObject>
+#include <QVector>
QT_FORWARD_DECLARE_CLASS(QDir)
@@ -49,6 +52,8 @@ class MakefileParser : public QObject
{
Q_OBJECT
+ using Macros = ProjectExplorer::Macros;
+
public:
/**
* @param makefile Filename including path of the autotools
@@ -98,7 +103,7 @@ public:
* #define X12_HAS_DEPRECATED
* @endcode
*/
- QByteArray defines() const;
+ Macros macros() const;
/**
* @return List of compiler flags for C.
@@ -267,7 +272,7 @@ private:
QStringList m_sources; ///< Return value for MakefileParser::sources()
QStringList m_makefiles; ///< Return value for MakefileParser::makefiles()
QStringList m_includePaths; ///< Return value for MakefileParser::includePaths()
- QByteArray m_defines; ///< Return value for MakefileParser::defines()
+ Macros m_macros; ///< Return value for MakefileParser::macros()
QStringList m_cflags; ///< Return value for MakefileParser::cflags()
QStringList m_cxxflags; ///< Return value for MakefileParser::cxxflags()
QStringList m_cppflags; ///< The cpp flags, which will be part of both cflags and cxxflags
diff --git a/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp b/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp
index cfe7e9757fd..a33d39599b0 100644
--- a/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp
+++ b/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp
@@ -61,10 +61,10 @@ QStringList MakefileParserThread::includePaths() const
return m_includePaths;
}
-QByteArray MakefileParserThread::defines() const
+ProjectExplorer::Macros MakefileParserThread::macros() const
{
QMutexLocker locker(&m_mutex);
- return m_defines;
+ return m_macros;
}
QStringList MakefileParserThread::cflags() const
@@ -109,7 +109,7 @@ void MakefileParserThread::run()
m_sources = m_parser.sources();
m_makefiles = m_parser.makefiles();
m_includePaths = m_parser.includePaths();
- m_defines = m_parser.defines();
+ m_macros = m_parser.macros();
m_cflags = m_parser.cflags();
m_cxxflags = m_parser.cxxflags();
}
diff --git a/src/plugins/autotoolsprojectmanager/makefileparserthread.h b/src/plugins/autotoolsprojectmanager/makefileparserthread.h
index 94b965d133b..3e16bdccc44 100644
--- a/src/plugins/autotoolsprojectmanager/makefileparserthread.h
+++ b/src/plugins/autotoolsprojectmanager/makefileparserthread.h
@@ -29,9 +29,12 @@
#include "makefileparser.h"
+#include <projectexplorer/projectmacro.h>
+
#include <QMutex>
#include <QStringList>
#include <QThread>
+#include <QVector>
namespace AutotoolsProjectManager {
namespace Internal {
@@ -47,6 +50,8 @@ class MakefileParserThread : public QThread
{
Q_OBJECT
+ using Macros = ProjectExplorer::Macros;
+
public:
MakefileParserThread(const QString &makefile);
@@ -82,10 +87,10 @@ public:
QStringList includePaths() const;
/**
- * @return Concatenated defines. Should be invoked, after the signal
+ * @return Concatenated macros. Should be invoked, after the signal
* finished() has been emitted.
*/
- QByteArray defines() const;
+ Macros macros() const;
/**
* @return List of compiler flags for C. Should be invoked, after the signal
@@ -134,7 +139,7 @@ private:
QStringList m_sources; ///< Return value for MakefileParserThread::sources()
QStringList m_makefiles; ///< Return value for MakefileParserThread::makefiles()
QStringList m_includePaths; ///< Return value for MakefileParserThread::includePaths()
- QByteArray m_defines; ///< Return value for MakefileParserThread::defines()
+ Macros m_macros; ///< Return value for MakefileParserThread::macros()
QStringList m_cflags; ///< Return value for MakefileParserThread::cflags()
QStringList m_cxxflags; ///< Return value for MakefileParserThread::cxxflags()
};
diff --git a/src/plugins/autotoolsprojectmanager/makestep.cpp b/src/plugins/autotoolsprojectmanager/makestep.cpp
index ce8be4c9b9d..3fb0ec41053 100644
--- a/src/plugins/autotoolsprojectmanager/makestep.cpp
+++ b/src/plugins/autotoolsprojectmanager/makestep.cpp
@@ -60,7 +60,7 @@ const char MAKE_STEP_ADDITIONAL_ARGUMENTS_KEY[] = "AutotoolsProjectManager.MakeS
// MakeStepFactory class
//////////////////////////
MakeStepFactory::MakeStepFactory(QObject *parent) : IBuildStepFactory(parent)
-{ setObjectName(QLatin1String("Autotools::MakeStepFactory")); }
+{ setObjectName("Autotools::MakeStepFactory"); }
QList<BuildStepInfo> MakeStepFactory::availableSteps(BuildStepList *parent) const
{
@@ -198,17 +198,17 @@ QVariantMap MakeStep::toMap() const
{
QVariantMap map = AbstractProcessStep::toMap();
- map.insert(QLatin1String(BUILD_TARGETS_KEY), m_buildTargets);
- map.insert(QLatin1String(MAKE_STEP_ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments);
- map.insert(QLatin1String(CLEAN_KEY), m_clean);
+ map.insert(BUILD_TARGETS_KEY, m_buildTargets);
+ map.insert(MAKE_STEP_ADDITIONAL_ARGUMENTS_KEY, m_additionalArguments);
+ map.insert(CLEAN_KEY, m_clean);
return map;
}
bool MakeStep::fromMap(const QVariantMap &map)
{
- m_buildTargets = map.value(QLatin1String(BUILD_TARGETS_KEY)).toStringList();
- m_additionalArguments = map.value(QLatin1String(MAKE_STEP_ADDITIONAL_ARGUMENTS_KEY)).toString();
- m_clean = map.value(QLatin1String(CLEAN_KEY)).toBool();
+ m_buildTargets = map.value(BUILD_TARGETS_KEY).toStringList();
+ m_additionalArguments = map.value(MAKE_STEP_ADDITIONAL_ARGUMENTS_KEY).toString();
+ m_clean = map.value(CLEAN_KEY).toBool();
return BuildStep::fromMap(map);
}
@@ -236,8 +236,15 @@ MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep) :
makeStep, &MakeStep::setAdditionalArguments);
connect(makeStep, &MakeStep::additionalArgumentsChanged,
this, &MakeStepConfigWidget::updateDetails);
- connect(m_makeStep->project(), &Project::environmentChanged,
- this, &MakeStepConfigWidget::updateDetails);
+ m_makeStep->project()->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
+ if (static_cast<BuildConfiguration *>(sender())->isActive())
+ updateDetails();
+ });
+ connect(makeStep->project(), &Project::activeProjectConfigurationChanged,
+ this, [this](ProjectConfiguration *pc) {
+ if (pc && pc->isActive())
+ updateDetails();
+ });
}
QString MakeStepConfigWidget::displayName() const
@@ -269,7 +276,7 @@ void MakeStepConfigWidget::updateDetails()
param.setArguments(arguments);
m_summaryText = param.summary(displayName());
} else {
- m_summaryText = QLatin1String("<b>") + ToolChainKitInformation::msgNoToolChainInTarget() + QLatin1String("</b>");
+ m_summaryText = "<b>" + ToolChainKitInformation::msgNoToolChainInTarget() + "</b>";
}
emit updateSummary();
diff --git a/src/plugins/baremetal/baremetalcustomrunconfiguration.cpp b/src/plugins/baremetal/baremetalcustomrunconfiguration.cpp
index 54ae4a596b8..9b7b8606be1 100644
--- a/src/plugins/baremetal/baremetalcustomrunconfiguration.cpp
+++ b/src/plugins/baremetal/baremetalcustomrunconfiguration.cpp
@@ -113,15 +113,19 @@ private:
};
BareMetalCustomRunConfiguration::BareMetalCustomRunConfiguration(ProjectExplorer::Target *parent)
- : BareMetalRunConfiguration(parent, runConfigId(), QString())
+ : BareMetalRunConfiguration(parent)
{
}
-BareMetalCustomRunConfiguration::BareMetalCustomRunConfiguration(ProjectExplorer::Target *parent,
- BareMetalCustomRunConfiguration *source)
- : BareMetalRunConfiguration(parent, source)
- , m_localExecutable(source->m_localExecutable)
+void BareMetalCustomRunConfiguration::initialize()
{
+ BareMetalRunConfiguration::initialize(runConfigId(), QString());
+}
+
+void BareMetalCustomRunConfiguration::copyFrom(const BareMetalCustomRunConfiguration *source)
+{
+ BareMetalRunConfiguration::copyFrom(source);
+ m_localExecutable = source->m_localExecutable;
}
bool BareMetalCustomRunConfiguration::isConfigured() const
diff --git a/src/plugins/baremetal/baremetalcustomrunconfiguration.h b/src/plugins/baremetal/baremetalcustomrunconfiguration.h
index 9c9118033a3..30812fc3cd9 100644
--- a/src/plugins/baremetal/baremetalcustomrunconfiguration.h
+++ b/src/plugins/baremetal/baremetalcustomrunconfiguration.h
@@ -36,11 +36,11 @@ class BareMetalCustomRunConfiguration : public BareMetalRunConfiguration
{
Q_OBJECT
public:
- BareMetalCustomRunConfiguration(ProjectExplorer::Target *parent);
- BareMetalCustomRunConfiguration(ProjectExplorer::Target *parent,
- BareMetalCustomRunConfiguration *source);
+ explicit BareMetalCustomRunConfiguration(ProjectExplorer::Target *parent);
+
+ void initialize();
+ void copyFrom(const BareMetalCustomRunConfiguration *source);
- bool isEnabled() const override { return true; }
bool isConfigured() const override;
ConfigurationState ensureConfigured(QString *errorMessage) override;
QWidget *createConfigurationWidget() override;
diff --git a/src/plugins/baremetal/baremetaldebugsupport.cpp b/src/plugins/baremetal/baremetaldebugsupport.cpp
index c4615daa6e3..b6d85ae4bc2 100644
--- a/src/plugins/baremetal/baremetaldebugsupport.cpp
+++ b/src/plugins/baremetal/baremetaldebugsupport.cpp
@@ -106,28 +106,32 @@ void BareMetalDebugSupport::start()
const GdbServerProvider *p = GdbServerProviderManager::findProvider(dev->gdbServerProviderId());
QTC_ASSERT(p, reportFailure(); return);
- Debugger::DebuggerStartParameters sp;
-
+#if 0
+ // Currently baremetal plugin does not provide way to configure deployments steps
+ // FIXME: Should it?
+ QString commands;
if (const BuildConfiguration *bc = target->activeBuildConfiguration()) {
if (BuildStepList *bsl = bc->stepList(BareMetalGdbCommandsDeployStep::stepId())) {
foreach (const BareMetalGdbCommandsDeployStep *bs, bsl->allOfType<BareMetalGdbCommandsDeployStep>()) {
- if (!sp.commandsAfterConnect.endsWith("\n"))
- sp.commandsAfterConnect.append("\n");
- sp.commandsAfterConnect.append(bs->gdbCommands());
+ if (!commands.endsWith("\n"))
+ commands.append("\n");
+ commands.append(bs->gdbCommands());
}
}
}
-
- sp.inferior.executable = bin;
- sp.inferior.commandLineArguments = rc->arguments();
- sp.symbolFile = bin;
- sp.startMode = AttachToRemoteServer;
- sp.commandsAfterConnect = p->initCommands();
- sp.commandsForReset = p->resetCommands();
- sp.remoteChannel = p->channel();
- sp.useContinueInsteadOfRun = true;
-
- setStartParameters(sp);
+ setCommandsAfterConnect(commands);
+#endif
+
+ StandardRunnable inferior;
+ inferior.executable = bin;
+ inferior.commandLineArguments = rc->arguments();
+ setInferior(inferior);
+ setSymbolFile(bin);
+ setStartMode(AttachToRemoteServer);
+ setCommandsAfterConnect(p->initCommands()); // .. and here?
+ setCommandsForReset(p->resetCommands());
+ setRemoteChannel(p->channel());
+ setUseContinueInsteadOfRun(true);
DebuggerRunTool::start();
}
diff --git a/src/plugins/baremetal/baremetalrunconfiguration.cpp b/src/plugins/baremetal/baremetalrunconfiguration.cpp
index 26d495f9b67..d950f6cc349 100644
--- a/src/plugins/baremetal/baremetalrunconfiguration.cpp
+++ b/src/plugins/baremetal/baremetalrunconfiguration.cpp
@@ -45,45 +45,33 @@ const char ProFileKey[] = "Qt4ProjectManager.MaemoRunConfiguration.ProFile";
const char WorkingDirectoryKey[] = "BareMetal.RunConfig.WorkingDirectory";
-BareMetalRunConfiguration::BareMetalRunConfiguration(Target *parent, BareMetalRunConfiguration *other)
- : RunConfiguration(parent, other),
- m_projectFilePath(other->m_projectFilePath),
- m_workingDirectory(other->m_workingDirectory)
+BareMetalRunConfiguration::BareMetalRunConfiguration(Target *target)
+ : RunConfiguration(target)
{
- init();
-}
-
-BareMetalRunConfiguration::BareMetalRunConfiguration(Target *parent,
- const Core::Id id,
- const QString &projectFilePath)
- : RunConfiguration(parent, id),
- m_projectFilePath(projectFilePath)
-{
- addExtraAspect(new ArgumentsAspect(this, QLatin1String("Qt4ProjectManager.MaemoRunConfiguration.Arguments")));
- init();
-}
-
-void BareMetalRunConfiguration::init()
-{
- setDefaultDisplayName(defaultDisplayName());
-
- connect(target(), &Target::deploymentDataChanged,
+ addExtraAspect(new ArgumentsAspect(this, "Qt4ProjectManager.MaemoRunConfiguration.Arguments"));
+ connect(target, &Target::deploymentDataChanged,
this, &BareMetalRunConfiguration::handleBuildSystemDataUpdated);
- connect(target(), &Target::applicationTargetsChanged,
+ connect(target, &Target::applicationTargetsChanged,
this, &BareMetalRunConfiguration::handleBuildSystemDataUpdated);
- connect(target(), &Target::kitChanged,
+ connect(target, &Target::kitChanged,
this, &BareMetalRunConfiguration::handleBuildSystemDataUpdated); // Handles device changes, etc.
}
-bool BareMetalRunConfiguration::isEnabled() const
+void BareMetalRunConfiguration::copyFrom(const BareMetalRunConfiguration *other)
{
- m_disabledReason.clear(); // FIXME: Check this makes sense.
- return true;
+ RunConfiguration::copyFrom(other);
+ m_projectFilePath = other->m_projectFilePath;
+ m_workingDirectory = other->m_workingDirectory;
+
+ setDefaultDisplayName(defaultDisplayName());
}
-QString BareMetalRunConfiguration::disabledReason() const
+void BareMetalRunConfiguration::initialize(const Core::Id id, const QString &projectFilePath)
{
- return m_disabledReason;
+ RunConfiguration::initialize(id);
+ m_projectFilePath = projectFilePath;
+
+ setDefaultDisplayName(defaultDisplayName());
}
QWidget *BareMetalRunConfiguration::createConfigurationWidget()
@@ -167,11 +155,6 @@ QString BareMetalRunConfiguration::buildSystemTarget() const
return (bst == targets.list.constEnd()) ? QString() : bst->targetName;
}
-void BareMetalRunConfiguration::setDisabledReason(const QString &reason) const
-{
- m_disabledReason = reason;
-}
-
void BareMetalRunConfiguration::handleBuildSystemDataUpdated()
{
emit targetInformationChanged();
diff --git a/src/plugins/baremetal/baremetalrunconfiguration.h b/src/plugins/baremetal/baremetalrunconfiguration.h
index ef400cb203f..c5e8e47b00a 100644
--- a/src/plugins/baremetal/baremetalrunconfiguration.h
+++ b/src/plugins/baremetal/baremetalrunconfiguration.h
@@ -37,15 +37,12 @@ class BareMetalRunConfiguration : public ProjectExplorer::RunConfiguration
Q_OBJECT
Q_DISABLE_COPY(BareMetalRunConfiguration)
- friend class BareMetalRunConfigurationFactory;
+ friend class ProjectExplorer::IRunConfigurationFactory;
friend class BareMetalRunConfigurationWidget;
public:
- explicit BareMetalRunConfiguration(ProjectExplorer::Target *parent, Core::Id id,
- const QString &projectFilePath);
+ explicit BareMetalRunConfiguration(ProjectExplorer::Target *target);
- bool isEnabled() const override;
- QString disabledReason() const override;
QWidget *createConfigurationWidget() override;
Utils::OutputFormatter *createOutputFormatter() const override;
@@ -67,17 +64,15 @@ signals:
void targetInformationChanged() const;
protected:
- BareMetalRunConfiguration(ProjectExplorer::Target *parent, BareMetalRunConfiguration *source);
bool fromMap(const QVariantMap &map) override;
QString defaultDisplayName();
- void setDisabledReason(const QString &reason) const;
+ void initialize(Core::Id id, const QString &projectFilePath);
+ void copyFrom(const BareMetalRunConfiguration *source);
private:
void handleBuildSystemDataUpdated();
- void init();
QString m_projectFilePath;
- mutable QString m_disabledReason;
QString m_workingDirectory;
};
diff --git a/src/plugins/baremetal/baremetalrunconfigurationfactory.cpp b/src/plugins/baremetal/baremetalrunconfigurationfactory.cpp
index b2381c62e2a..31d00c7f39f 100644
--- a/src/plugins/baremetal/baremetalrunconfigurationfactory.cpp
+++ b/src/plugins/baremetal/baremetalrunconfigurationfactory.cpp
@@ -107,7 +107,7 @@ RunConfiguration *BareMetalRunConfigurationFactory::doCreate(Target *parent, Cor
{
if (id == BareMetalCustomRunConfiguration::runConfigId())
return new BareMetalCustomRunConfiguration(parent);
- return new BareMetalRunConfiguration(parent, id, pathFromId(id));
+ return createHelper<BareMetalRunConfiguration>(parent, id, pathFromId(id));
}
RunConfiguration *BareMetalRunConfigurationFactory::doRestore(Target *parent, const QVariantMap &map)
@@ -120,10 +120,9 @@ RunConfiguration *BareMetalRunConfigurationFactory::doRestore(Target *parent, co
RunConfiguration *BareMetalRunConfigurationFactory::clone(Target *parent, RunConfiguration *source)
{
QTC_ASSERT(canClone(parent, source), return 0);
- if (BareMetalCustomRunConfiguration *old = qobject_cast<BareMetalCustomRunConfiguration *>(source))
- return new BareMetalCustomRunConfiguration(parent, old);
- BareMetalRunConfiguration *old = static_cast<BareMetalRunConfiguration*>(source);
- return new BareMetalRunConfiguration(parent,old);
+ if (qobject_cast<BareMetalCustomRunConfiguration *>(source))
+ return cloneHelper<BareMetalCustomRunConfiguration>(parent, source);
+ return cloneHelper<BareMetalRunConfiguration>(parent, source);
}
bool BareMetalRunConfigurationFactory::canHandle(const Target *target) const
diff --git a/src/plugins/baremetal/baremetalrunconfigurationwidget.cpp b/src/plugins/baremetal/baremetalrunconfigurationwidget.cpp
index 4973ba16a8b..942702ca235 100644
--- a/src/plugins/baremetal/baremetalrunconfigurationwidget.cpp
+++ b/src/plugins/baremetal/baremetalrunconfigurationwidget.cpp
@@ -49,9 +49,6 @@ public:
{ }
BareMetalRunConfiguration * const runConfiguration;
- QWidget topWidget;
- QLabel disabledIcon;
- QLabel disabledReason;
QLineEdit workingDirLineEdit;
QLabel localExecutableLabel;
QFormLayout genericWidgetsLayout;
@@ -63,13 +60,9 @@ using namespace Internal;
BareMetalRunConfigurationWidget::BareMetalRunConfigurationWidget(BareMetalRunConfiguration *runConfiguration,
QWidget *parent)
- : QWidget(parent),d(new BareMetalRunConfigurationWidgetPrivate(runConfiguration))
+ : QWidget(parent), d(new BareMetalRunConfigurationWidgetPrivate(runConfiguration))
{
- QVBoxLayout *topLayout = new QVBoxLayout(this);
- topLayout->setMargin(0);
- addDisabledLabel(topLayout);
- topLayout->addWidget(&d->topWidget);
- QVBoxLayout *mainLayout = new QVBoxLayout(&d->topWidget);
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setMargin(0);
Utils::DetailsWidget *detailsContainer = new Utils::DetailsWidget(this);
@@ -97,9 +90,6 @@ BareMetalRunConfigurationWidget::BareMetalRunConfigurationWidget(BareMetalRunCon
this, &BareMetalRunConfigurationWidget::updateTargetInformation);
connect(&d->workingDirLineEdit, &QLineEdit::textEdited,
this, &BareMetalRunConfigurationWidget::handleWorkingDirectoryChanged);
- connect(d->runConfiguration, &ProjectExplorer::RunConfiguration::enabledChanged,
- this, &BareMetalRunConfigurationWidget::runConfigurationEnabledChange);
- runConfigurationEnabledChange();
}
BareMetalRunConfigurationWidget::~BareMetalRunConfigurationWidget()
@@ -107,18 +97,6 @@ BareMetalRunConfigurationWidget::~BareMetalRunConfigurationWidget()
delete d;
}
-void BareMetalRunConfigurationWidget::addDisabledLabel(QVBoxLayout *topLayout)
-{
- QHBoxLayout * const hl = new QHBoxLayout;
- hl->addStretch();
- d->disabledIcon.setPixmap(Utils::Icons::WARNING.pixmap());
- hl->addWidget(&d->disabledIcon);
- d->disabledReason.setVisible(false);
- hl->addWidget(&d->disabledReason);
- hl->addStretch();
- topLayout->addLayout(hl);
-}
-
void BareMetalRunConfigurationWidget::updateTargetInformation()
{
setLabelText(d->localExecutableLabel,
@@ -138,13 +116,4 @@ void BareMetalRunConfigurationWidget::setLabelText(QLabel &label, const QString
label.setText(regularText.isEmpty() ? errorMessage : regularText);
}
-void BareMetalRunConfigurationWidget::runConfigurationEnabledChange()
-{
- bool enabled = d->runConfiguration->isEnabled();
- d->topWidget.setEnabled(enabled);
- d->disabledIcon.setVisible(!enabled);
- d->disabledReason.setVisible(!enabled);
- d->disabledReason.setText(d->runConfiguration->disabledReason());
-}
-
} // namespace BareMetal
diff --git a/src/plugins/baremetal/baremetalrunconfigurationwidget.h b/src/plugins/baremetal/baremetalrunconfigurationwidget.h
index 76f9cc86b77..d5a5a271cdd 100644
--- a/src/plugins/baremetal/baremetalrunconfigurationwidget.h
+++ b/src/plugins/baremetal/baremetalrunconfigurationwidget.h
@@ -46,9 +46,6 @@ public:
explicit BareMetalRunConfigurationWidget(BareMetalRunConfiguration *runConfiguration,
QWidget *parent = 0);
~BareMetalRunConfigurationWidget();
- void addDisabledLabel(QVBoxLayout *topLayout);
-
- Q_SLOT void runConfigurationEnabledChange();
private:
void updateTargetInformation();
diff --git a/src/plugins/baremetal/images/baremetaldevice.png b/src/plugins/baremetal/images/baremetaldevice.png
index 34ac48c118a..cc7f96a7fdb 100644
--- a/src/plugins/baremetal/images/baremetaldevice.png
+++ b/src/plugins/baremetal/images/baremetaldevice.png
Binary files differ
diff --git a/src/plugins/baremetal/images/baremetaldevice@2x.png b/src/plugins/baremetal/images/baremetaldevice@2x.png
index d1341f90ee6..f99932ab5e4 100644
--- a/src/plugins/baremetal/images/baremetaldevice@2x.png
+++ b/src/plugins/baremetal/images/baremetaldevice@2x.png
Binary files differ
diff --git a/src/plugins/bazaar/bazaarplugin.cpp b/src/plugins/bazaar/bazaarplugin.cpp
index 49b0d9f4af7..a41710b24b0 100644
--- a/src/plugins/bazaar/bazaarplugin.cpp
+++ b/src/plugins/bazaar/bazaarplugin.cpp
@@ -154,8 +154,7 @@ bool BazaarPlugin::initialize(const QStringList &arguments, QString *errorMessag
Context context(Constants::BAZAAR_CONTEXT);
m_client = new BazaarClient;
- auto vcsCtrl = new BazaarControl(m_client);
- initializeVcs(vcsCtrl, context);
+ auto vcsCtrl = initializeVcs<BazaarControl>(context, m_client);
connect(m_client, &VcsBaseClient::changed, vcsCtrl, &BazaarControl::changed);
addAutoReleasedObject(new OptionsPage(vcsCtrl));
@@ -510,6 +509,9 @@ void BazaarPlugin::createSubmitEditorActions()
void BazaarPlugin::commit()
{
+ if (!promptBeforeCommit())
+ return;
+
if (raiseSubmitEditor())
return;
diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp
index 0dcfbf7c0ef..ec0065ed954 100644
--- a/src/plugins/beautifier/beautifierplugin.cpp
+++ b/src/plugins/beautifier/beautifierplugin.cpp
@@ -45,12 +45,12 @@
#include <diffeditor/differ.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h>
-#include <texteditor/convenience.h>
#include <texteditor/textdocument.h>
#include <texteditor/textdocumentlayout.h>
#include <texteditor/texteditor.h>
#include <texteditor/texteditorconstants.h>
#include <utils/algorithm.h>
+#include <utils/textutils.h>
#include <utils/fileutils.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
@@ -169,7 +169,7 @@ QString sourceData(TextEditorWidget *editor, int startPos, int endPos)
{
return (startPos < 0)
? editor->toPlainText()
- : Convenience::textAt(editor->textCursor(), startPos, (endPos - startPos));
+ : Utils::Text::textAt(editor->textCursor(), startPos, (endPos - startPos));
}
bool isAutoFormatApplicable(const Core::IDocument *document,
@@ -496,6 +496,18 @@ QString BeautifierPlugin::msgFormatSelectedText()
return tr("Format &Selected Text");
}
+QString BeautifierPlugin::msgFormatAtCursor()
+{
+ //: Menu entry
+ return tr("&Format at Cursor");
+}
+
+QString BeautifierPlugin::msgDisableFormattingSelectedText()
+{
+ //: Menu entry
+ return tr("&Disable Formatting for Selected Text");
+}
+
QString BeautifierPlugin::msgCommandPromptDialogTitle(const QString &command)
{
//: File dialog title for path chooser when choosing binary
diff --git a/src/plugins/beautifier/beautifierplugin.h b/src/plugins/beautifier/beautifierplugin.h
index 14d6674ab8a..f298063f0ae 100644
--- a/src/plugins/beautifier/beautifierplugin.h
+++ b/src/plugins/beautifier/beautifierplugin.h
@@ -80,6 +80,8 @@ public:
static QString msgCannotGetConfigurationFile(const QString &command);
static QString msgFormatCurrentFile();
static QString msgFormatSelectedText();
+ static QString msgFormatAtCursor();
+ static QString msgDisableFormattingSelectedText();
static QString msgCommandPromptDialogTitle(const QString &command);
static void showError(const QString &error);
diff --git a/src/plugins/beautifier/clangformat/clangformat.cpp b/src/plugins/beautifier/clangformat/clangformat.cpp
index 13f7caab24f..97298ffc39e 100644
--- a/src/plugins/beautifier/clangformat/clangformat.cpp
+++ b/src/plugins/beautifier/clangformat/clangformat.cpp
@@ -48,6 +48,7 @@
#include <QAction>
#include <QMenu>
+#include <QTextBlock>
namespace Beautifier {
namespace Internal {
@@ -82,11 +83,19 @@ bool ClangFormat::initialize()
menu->addAction(cmd);
connect(m_formatFile, &QAction::triggered, this, &ClangFormat::formatFile);
- m_formatRange = new QAction(BeautifierPlugin::msgFormatSelectedText(), this);
+ m_formatRange = new QAction(BeautifierPlugin::msgFormatAtCursor(), this);
cmd = Core::ActionManager::registerAction(m_formatRange,
- Constants::ClangFormat::ACTION_FORMATSELECTED);
+ Constants::ClangFormat::ACTION_FORMATATCURSOR);
menu->addAction(cmd);
- connect(m_formatRange, &QAction::triggered, this, &ClangFormat::formatSelectedText);
+ connect(m_formatRange, &QAction::triggered, this, &ClangFormat::formatAtCursor);
+
+ m_disableFormattingSelectedText
+ = new QAction(BeautifierPlugin::msgDisableFormattingSelectedText(), this);
+ cmd = Core::ActionManager::registerAction(
+ m_disableFormattingSelectedText, Constants::ClangFormat::ACTION_DISABLEFORMATTINGSELECTED);
+ menu->addAction(cmd);
+ connect(m_disableFormattingSelectedText, &QAction::triggered,
+ this, &ClangFormat::disableFormattingSelectedText);
Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu);
@@ -113,7 +122,7 @@ void ClangFormat::formatFile()
m_beautifierPlugin->formatCurrentFile(command());
}
-void ClangFormat::formatSelectedText()
+void ClangFormat::formatAtCursor()
{
const TextEditor::TextEditorWidget *widget
= TextEditor::TextEditorWidget::currentTextEditorWidget();
@@ -125,11 +134,53 @@ void ClangFormat::formatSelectedText()
const int offset = tc.selectionStart();
const int length = tc.selectionEnd() - offset;
m_beautifierPlugin->formatCurrentFile(command(offset, length));
- } else if (m_settings->formatEntireFileFallback()) {
- formatFile();
+ } else {
+ // Pretend that the current line was selected.
+ // Note that clang-format will extend the range to the next bigger
+ // syntactic construct if needed.
+ const QTextBlock block = tc.block();
+ const int offset = block.position();
+ const int length = block.length();
+ m_beautifierPlugin->formatCurrentFile(command(offset, length));
}
}
+void ClangFormat::disableFormattingSelectedText()
+{
+ TextEditor::TextEditorWidget *widget = TextEditor::TextEditorWidget::currentTextEditorWidget();
+ if (!widget)
+ return;
+
+ const QTextCursor tc = widget->textCursor();
+ if (!tc.hasSelection())
+ return;
+
+ // Insert start marker
+ const QTextBlock selectionStartBlock = tc.document()->findBlock(tc.selectionStart());
+ QTextCursor insertCursor(tc.document());
+ insertCursor.beginEditBlock();
+ insertCursor.setPosition(selectionStartBlock.position());
+ insertCursor.insertText("// clang-format off\n");
+ const int positionToRestore = tc.position();
+
+ // Insert end marker
+ QTextBlock selectionEndBlock = tc.document()->findBlock(tc.selectionEnd());
+ insertCursor.setPosition(selectionEndBlock.position() + selectionEndBlock.length() - 1);
+ insertCursor.insertText("\n// clang-format on");
+ insertCursor.endEditBlock();
+
+ // Reset the cursor position in order to clear the selection.
+ QTextCursor restoreCursor(tc.document());
+ restoreCursor.setPosition(positionToRestore);
+ widget->setTextCursor(restoreCursor);
+
+ // The indentation of these markers might be undesired, so reformat.
+ // This is not optimal because two undo steps will be needed to remove the markers.
+ const int reformatTextLength = insertCursor.position() - selectionStartBlock.position();
+ m_beautifierPlugin->formatCurrentFile(command(selectionStartBlock.position(),
+ reformatTextLength));
+}
+
Command ClangFormat::command() const
{
Command command;
diff --git a/src/plugins/beautifier/clangformat/clangformat.h b/src/plugins/beautifier/clangformat/clangformat.h
index 86037fac0cc..34cccb5fbcc 100644
--- a/src/plugins/beautifier/clangformat/clangformat.h
+++ b/src/plugins/beautifier/clangformat/clangformat.h
@@ -54,10 +54,12 @@ public:
private:
void formatFile();
- void formatSelectedText();
+ void formatAtCursor();
+ void disableFormattingSelectedText();
BeautifierPlugin *m_beautifierPlugin;
QAction *m_formatFile = nullptr;
QAction *m_formatRange = nullptr;
+ QAction *m_disableFormattingSelectedText = nullptr;
ClangFormatSettings *m_settings;
Command command(int offset, int length) const;
};
diff --git a/src/plugins/beautifier/clangformat/clangformatconstants.h b/src/plugins/beautifier/clangformat/clangformatconstants.h
index 837d3323069..2c94b347a51 100644
--- a/src/plugins/beautifier/clangformat/clangformatconstants.h
+++ b/src/plugins/beautifier/clangformat/clangformatconstants.h
@@ -33,7 +33,8 @@ namespace ClangFormat {
const char DISPLAY_NAME[] = QT_TRANSLATE_NOOP("Beautifier::Internal::ClangFormat::ClangFormat", "ClangFormat");
const char ACTION_FORMATFILE[] = "ClangFormat.FormatFile";
-const char ACTION_FORMATSELECTED[] = "ClangFormat.FormatSelectedText";
+const char ACTION_FORMATATCURSOR[] = "ClangFormat.FormatAtCursor";
+const char ACTION_DISABLEFORMATTINGSELECTED[] = "ClangFormat.DisableFormattingSelectedText";
const char MENU_ID[] = "ClangFormat.Menu";
const char OPTION_ID[] = "ClangFormat";
const char SETTINGS_NAME[] = "clangformat";
diff --git a/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp b/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp
index ddac14461f1..d9f881dc415 100644
--- a/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp
+++ b/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp
@@ -78,7 +78,6 @@ void ClangFormatOptionsPageWidget::restore()
const int fallbackStyleIndex = ui->fallbackStyle->findText(m_settings->fallbackStyle());
if (fallbackStyleIndex != -1)
ui->fallbackStyle->setCurrentIndex(fallbackStyleIndex);
- ui->formatEntireFileFallback->setChecked(m_settings->formatEntireFileFallback());
ui->configurations->setSettings(m_settings);
ui->configurations->setCurrentConfiguration(m_settings->customStyle());
@@ -96,7 +95,6 @@ void ClangFormatOptionsPageWidget::apply()
m_settings->setPredefinedStyle(ui->predefinedStyle->currentText());
m_settings->setFallbackStyle(ui->fallbackStyle->currentText());
m_settings->setCustomStyle(ui->configurations->currentConfiguration());
- m_settings->setFormatEntireFileFallback(ui->formatEntireFileFallback->isChecked());
m_settings->save();
// update since not all MIME types are accepted (invalids or duplicates)
diff --git a/src/plugins/beautifier/clangformat/clangformatoptionspage.ui b/src/plugins/beautifier/clangformat/clangformatoptionspage.ui
index c40b28c0417..7d060611b4b 100644
--- a/src/plugins/beautifier/clangformat/clangformatoptionspage.ui
+++ b/src/plugins/beautifier/clangformat/clangformatoptionspage.ui
@@ -20,6 +20,19 @@
<string>Options</string>
</property>
<layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="0">
+ <widget class="QRadioButton" name="useCustomizedStyle">
+ <property name="text">
+ <string>Use customized style:</string>
+ </property>
+ <property name="autoExclusive">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="Beautifier::Internal::ConfigurationPanel" name="configurations" native="true"/>
+ </item>
<item row="0" column="0">
<widget class="QRadioButton" name="usePredefinedStyle">
<property name="sizePolicy">
@@ -62,29 +75,6 @@
</property>
</widget>
</item>
- <item row="2" column="0">
- <widget class="QRadioButton" name="useCustomizedStyle">
- <property name="text">
- <string>Use customized style:</string>
- </property>
- <property name="autoExclusive">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="1" colspan="2">
- <widget class="Beautifier::Internal::ConfigurationPanel" name="configurations" native="true"/>
- </item>
- <item row="3" column="0" colspan="2">
- <widget class="QCheckBox" name="formatEntireFileFallback">
- <property name="toolTip">
- <string>For action Format Selected Text.</string>
- </property>
- <property name="text">
- <string>Format entire file if no text was selected</string>
- </property>
- </widget>
- </item>
</layout>
</widget>
</item>
diff --git a/src/plugins/beautifier/clangformat/clangformatsettings.cpp b/src/plugins/beautifier/clangformat/clangformatsettings.cpp
index f4c2189181b..6369c60510f 100644
--- a/src/plugins/beautifier/clangformat/clangformatsettings.cpp
+++ b/src/plugins/beautifier/clangformat/clangformatsettings.cpp
@@ -43,7 +43,6 @@ const char USE_PREDEFINED_STYLE[] = "usePredefinedStyle";
const char PREDEFINED_STYLE[] = "predefinedStyle";
const char FALLBACK_STYLE[] = "fallbackStyle";
const char CUSTOM_STYLE[] = "customStyle";
-const char FORMAT_ENTIRE_FILE_FALLBACK[] = "formatEntireFileFallback";
}
ClangFormatSettings::ClangFormatSettings() :
@@ -54,7 +53,6 @@ ClangFormatSettings::ClangFormatSettings() :
m_settings.insert(PREDEFINED_STYLE, "LLVM");
m_settings.insert(FALLBACK_STYLE, "Default");
m_settings.insert(CUSTOM_STYLE, QVariant());
- m_settings.insert(FORMAT_ENTIRE_FILE_FALLBACK, QVariant(true));
read();
}
@@ -215,16 +213,6 @@ void ClangFormatSettings::setCustomStyle(const QString &customStyle)
m_settings.insert(CUSTOM_STYLE, QVariant(customStyle));
}
-bool ClangFormatSettings::formatEntireFileFallback() const
-{
- return m_settings.value(FORMAT_ENTIRE_FILE_FALLBACK).toBool();
-}
-
-void ClangFormatSettings::setFormatEntireFileFallback(bool formatEntireFileFallback)
-{
- m_settings.insert(FORMAT_ENTIRE_FILE_FALLBACK, QVariant(formatEntireFileFallback));
-}
-
QStringList ClangFormatSettings::predefinedStyles() const
{
return {"LLVM", "Google", "Chromium", "Mozilla", "WebKit", "File"};
diff --git a/src/plugins/beautifier/clangformat/clangformatsettings.h b/src/plugins/beautifier/clangformat/clangformatsettings.h
index b8a62be6bdc..4fca7ddc248 100644
--- a/src/plugins/beautifier/clangformat/clangformatsettings.h
+++ b/src/plugins/beautifier/clangformat/clangformatsettings.h
@@ -54,9 +54,6 @@ public:
QString customStyle() const;
void setCustomStyle(const QString &customStyle);
- bool formatEntireFileFallback() const;
- void setFormatEntireFileFallback(bool formatEntireFileFallback);
-
QStringList predefinedStyles() const;
QStringList fallbackStyles() const;
diff --git a/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp b/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp
index 80b42c11b43..62573c70fde 100644
--- a/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp
+++ b/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp
@@ -247,10 +247,33 @@ int ActivationSequenceContextProcessor::findStartOfName(
{
int position = startPosition;
QChar character;
+ if (position > 2 && assistInterface->characterAt(position - 1) == '>'
+ && assistInterface->characterAt(position - 2) != '-') {
+ uint unbalancedLessGreater = 1;
+ --position;
+ while (unbalancedLessGreater > 0 && position > 2) {
+ character = assistInterface->characterAt(--position);
+ // Do not count -> usage inside temlate argument list
+ if (character == '<')
+ --unbalancedLessGreater;
+ else if (character == '>' && assistInterface->characterAt(position-1) != '-')
+ ++unbalancedLessGreater;
+ }
+ position = skipPrecedingWhitespace(assistInterface, position) - 1;
+ }
+
do {
character = assistInterface->characterAt(--position);
} while (isValidIdentifierChar(character));
+ int prevPosition = skipPrecedingWhitespace(assistInterface, position);
+ if (assistInterface->characterAt(prevPosition) == ':'
+ && assistInterface->characterAt(prevPosition - 1) == ':') {
+ // Handle :: case - go recursive
+ prevPosition = skipPrecedingWhitespace(assistInterface, prevPosition - 2);
+ return findStartOfName(assistInterface, prevPosition + 1);
+ }
+
return position + 1;
}
diff --git a/src/plugins/clangcodemodel/clangassistproposalmodel.h b/src/plugins/clangcodemodel/clangassistproposalmodel.h
index 6a722145139..b71d2568564 100644
--- a/src/plugins/clangcodemodel/clangassistproposalmodel.h
+++ b/src/plugins/clangcodemodel/clangassistproposalmodel.h
@@ -29,7 +29,7 @@
#include <texteditor/codeassist/genericproposalmodel.h>
-#include <clangbackendipc/clangbackendipc_global.h>
+#include <clangsupport/clangsupport_global.h>
namespace ClangCodeModel {
namespace Internal {
diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp
index bb4d4c30104..ff1cf8f0750 100644
--- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp
+++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp
@@ -48,9 +48,9 @@
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
-#include <clangbackendipc/clangcodemodelservermessages.h>
-#include <clangbackendipc/clangcodemodelclientmessages.h>
-#include <clangbackendipc/filecontainer.h>
+#include <clangsupport/clangcodemodelservermessages.h>
+#include <clangsupport/clangcodemodelclientmessages.h>
+#include <clangsupport/filecontainer.h>
#include <cplusplus/Icons.h>
@@ -146,6 +146,18 @@ QFuture<CppTools::CursorInfo> IpcReceiver::addExpectedReferencesMessage(
return futureInterface.future();
}
+QFuture<CppTools::SymbolInfo> IpcReceiver::addExpectedRequestFollowSymbolMessage(quint64 ticket)
+{
+ QTC_CHECK(!m_followTable.contains(ticket));
+
+ QFutureInterface<CppTools::SymbolInfo> futureInterface;
+ futureInterface.reportStarted();
+
+ m_followTable.insert(ticket, futureInterface);
+
+ return futureInterface.future();
+}
+
bool IpcReceiver::isExpectingCodeCompletedMessage() const
{
return !m_assistProcessorsTable.isEmpty();
@@ -161,6 +173,9 @@ void IpcReceiver::reset()
for (ReferencesEntry &entry : m_referencesTable)
entry.futureInterface.cancel();
m_referencesTable.clear();
+ for (QFutureInterface<CppTools::SymbolInfo> &futureInterface : m_followTable)
+ futureInterface.cancel();
+ m_followTable.clear();
}
void IpcReceiver::alive()
@@ -247,6 +262,23 @@ CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument,
return result;
}
+static
+CppTools::SymbolInfo toSymbolInfo(const FollowSymbolMessage &message)
+{
+ CppTools::SymbolInfo result;
+ const SourceRangeContainer &range = message.sourceRange();
+
+ const SourceLocationContainer start = range.start();
+ const SourceLocationContainer end = range.end();
+ result.startLine = static_cast<int>(start.line());
+ result.startColumn = static_cast<int>(start.column());
+ result.endLine = static_cast<int>(end.line());
+ result.endColumn = static_cast<int>(end.column());
+ result.fileName = start.filePath();
+
+ return result;
+}
+
void IpcReceiver::references(const ReferencesMessage &message)
{
qCDebug(log) << "<<< ReferencesMessage with"
@@ -265,6 +297,22 @@ void IpcReceiver::references(const ReferencesMessage &message)
futureInterface.reportFinished();
}
+void IpcReceiver::followSymbol(const ClangBackEnd::FollowSymbolMessage &message)
+{
+ qCDebug(log) << "<<< FollowSymbolMessage with"
+ << message.sourceRange() << "range";
+
+ const quint64 ticket = message.ticketNumber();
+ QFutureInterface<CppTools::SymbolInfo> futureInterface = m_followTable.take(ticket);
+ QTC_CHECK(futureInterface != QFutureInterface<CppTools::SymbolInfo>());
+
+ if (futureInterface.isCanceled())
+ return; // Editor document closed or a new request was issued making this result outdated.
+
+ futureInterface.reportResult(toSymbolInfo(message));
+ futureInterface.reportFinished();
+}
+
class IpcSender : public IpcSenderInterface
{
public:
@@ -283,6 +331,7 @@ public:
void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override;
void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &message) override;
void requestReferences(const ClangBackEnd::RequestReferencesMessage &message) override;
+ void requestFollowSymbol(const ClangBackEnd::RequestFollowSymbolMessage &message) override;
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
private:
@@ -366,6 +415,13 @@ void IpcSender::requestReferences(const RequestReferencesMessage &message)
m_connection.serverProxy().requestReferences(message);
}
+void IpcSender::requestFollowSymbol(const RequestFollowSymbolMessage &message)
+{
+ QTC_CHECK(m_connection.isConnected());
+ qCDebug(log) << ">>>" << message;
+ m_connection.serverProxy().requestFollowSymbol(message);
+}
+
void IpcSender::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
{
QTC_CHECK(m_connection.isConnected());
@@ -387,6 +443,7 @@ public:
void completeCode(const ClangBackEnd::CompleteCodeMessage &) override {}
void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &) override {}
void requestReferences(const ClangBackEnd::RequestReferencesMessage &) override {}
+ void requestFollowSymbol(const RequestFollowSymbolMessage &) override {}
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &) override {}
};
@@ -686,6 +743,21 @@ QFuture<CppTools::CursorInfo> IpcCommunicator::requestReferences(
localUses);
}
+QFuture<CppTools::SymbolInfo> IpcCommunicator::requestFollowSymbol(
+ const FileContainer &curFileContainer,
+ const QVector<Utf8String> &dependentFiles,
+ quint32 line,
+ quint32 column)
+{
+ const RequestFollowSymbolMessage message(curFileContainer,
+ dependentFiles,
+ line,
+ column);
+ m_ipcSender->requestFollowSymbol(message);
+
+ return m_ipcReceiver.addExpectedRequestFollowSymbolMessage(message.ticketNumber());
+}
+
void IpcCommunicator::updateTranslationUnitWithRevisionCheck(Core::IDocument *document)
{
const auto textDocument = qobject_cast<TextDocument*>(document);
@@ -858,9 +930,12 @@ void IpcCommunicator::completeCode(ClangCompletionAssistProcessor *assistProcess
const QString &filePath,
quint32 line,
quint32 column,
- const QString &projectFilePath)
+ const QString &projectFilePath,
+ qint32 funcNameStartLine,
+ qint32 funcNameStartColumn)
{
- const CompleteCodeMessage message(filePath, line, column, projectFilePath);
+ const CompleteCodeMessage message(filePath, line, column, projectFilePath, funcNameStartLine,
+ funcNameStartColumn);
m_ipcSender->completeCode(message);
m_ipcReceiver.addExpectedCodeCompletedMessage(message.ticketNumber(), assistProcessor);
}
diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.h b/src/plugins/clangcodemodel/clangbackendipcintegration.h
index 842d68f2662..63c9d768017 100644
--- a/src/plugins/clangcodemodel/clangbackendipcintegration.h
+++ b/src/plugins/clangcodemodel/clangbackendipcintegration.h
@@ -27,11 +27,12 @@
#include <cpptools/projectpart.h>
#include <cpptools/cppcursorinfo.h>
+#include <cpptools/cppsymbolinfo.h>
-#include <clangbackendipc/clangcodemodelconnectionclient.h>
-#include <clangbackendipc/filecontainer.h>
-#include <clangbackendipc/clangcodemodelclientinterface.h>
-#include <clangbackendipc/projectpartcontainer.h>
+#include <clangsupport/clangcodemodelconnectionclient.h>
+#include <clangsupport/filecontainer.h>
+#include <clangsupport/clangcodemodelclientinterface.h>
+#include <clangsupport/projectpartcontainer.h>
#include <QFuture>
#include <QObject>
@@ -79,6 +80,7 @@ public:
addExpectedReferencesMessage(quint64 ticket,
QTextDocument *textDocument,
const CppTools::SemanticInfo::LocalUseMap &localUses);
+ QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket);
bool isExpectingCodeCompletedMessage() const;
void reset();
@@ -90,6 +92,7 @@ private:
void documentAnnotationsChanged(const ClangBackEnd::DocumentAnnotationsChangedMessage &message) override;
void references(const ClangBackEnd::ReferencesMessage &message) override;
+ void followSymbol(const ClangBackEnd::FollowSymbolMessage &message) override;
void translationUnitDoesNotExist(const ClangBackEnd::TranslationUnitDoesNotExistMessage &) override {}
void projectPartsDoNotExist(const ClangBackEnd::ProjectPartsDoNotExistMessage &) override {}
@@ -111,6 +114,8 @@ private:
CppTools::SemanticInfo::LocalUseMap localUses;
};
QHash<quint64, ReferencesEntry> m_referencesTable;
+
+ QHash<quint64, QFutureInterface<CppTools::SymbolInfo>> m_followTable;
};
class IpcSenderInterface
@@ -129,6 +134,7 @@ public:
virtual void completeCode(const ClangBackEnd::CompleteCodeMessage &message) = 0;
virtual void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &message) = 0;
virtual void requestReferences(const ClangBackEnd::RequestReferencesMessage &message) = 0;
+ virtual void requestFollowSymbol(const ClangBackEnd::RequestFollowSymbolMessage &message) = 0;
virtual void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) = 0;
};
@@ -160,10 +166,16 @@ public:
quint32 column,
QTextDocument *textDocument,
const CppTools::SemanticInfo::LocalUseMap &localUses);
+ QFuture<CppTools::SymbolInfo> requestFollowSymbol(const FileContainer &curFileContainer,
+ const QVector<Utf8String> &dependentFiles,
+ quint32 line,
+ quint32 column);
void completeCode(ClangCompletionAssistProcessor *assistProcessor, const QString &filePath,
quint32 line,
quint32 column,
- const QString &projectFilePath);
+ const QString &projectFilePath,
+ qint32 funcNameStartLine = -1,
+ qint32 funcNameStartColumn = -1);
void registerProjectsParts(const QVector<CppTools::ProjectPart::Ptr> projectParts);
diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro
index 4b44cce6c6f..d48ce960ded 100644
--- a/src/plugins/clangcodemodel/clangcodemodel.pro
+++ b/src/plugins/clangcodemodel/clangcodemodel.pro
@@ -23,6 +23,7 @@ SOURCES += \
clangeditordocumentprocessor.cpp \
clangfixitoperation.cpp \
clangfixitoperationsextractor.cpp \
+ clangfollowsymbol.cpp \
clangfunctionhintmodel.cpp \
clanghighlightingmarksreporter.cpp \
clangmodelmanagersupport.cpp \
@@ -54,6 +55,7 @@ HEADERS += \
clangeditordocumentprocessor.h \
clangfixitoperation.h \
clangfixitoperationsextractor.h \
+ clangfollowsymbol.h \
clangfunctionhintmodel.h \
clanghighlightingmarksreporter.h \
clangisdiagnosticrelatedtolocation.h \
diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs
index eb46d8f2bd0..699e5730329 100644
--- a/src/plugins/clangcodemodel/clangcodemodel.qbs
+++ b/src/plugins/clangcodemodel/clangcodemodel.qbs
@@ -10,7 +10,7 @@ QtcPlugin {
Depends { name: "ProjectExplorer" }
Depends { name: "TextEditor" }
Depends { name: "Utils" }
- Depends { name: "ClangBackEndIpc" }
+ Depends { name: "ClangSupport" }
Depends { name: "libclang"; required: false }
pluginTestDepends: [
@@ -71,6 +71,8 @@ QtcPlugin {
"clangfixitoperation.h",
"clangfixitoperationsextractor.cpp",
"clangfixitoperationsextractor.h",
+ "clangfollowsymbol.cpp",
+ "clangfollowsymbol.h",
"clangfunctionhintmodel.cpp",
"clangfunctionhintmodel.h",
"clanghighlightingmarksreporter.cpp",
diff --git a/src/plugins/clangcodemodel/clangcodemodel_dependencies.pri b/src/plugins/clangcodemodel/clangcodemodel_dependencies.pri
index 335569d766d..9b44838b011 100644
--- a/src/plugins/clangcodemodel/clangcodemodel_dependencies.pri
+++ b/src/plugins/clangcodemodel/clangcodemodel_dependencies.pri
@@ -1,7 +1,7 @@
QTC_PLUGIN_NAME = ClangCodeModel
QTC_LIB_DEPENDS += \
utils \
- clangbackendipc
+ clangsupport
QTC_PLUGIN_DEPENDS += \
coreplugin \
cpptools \
diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
index 9d84b3ba813..e60ac37ec6c 100644
--- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
+++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
@@ -42,16 +42,16 @@
#include <texteditor/codeassist/assistproposalitem.h>
#include <texteditor/codeassist/functionhintproposal.h>
#include <texteditor/codeassist/ifunctionhintproposalmodel.h>
-#include <texteditor/convenience.h>
#include <cplusplus/BackwardsScanner.h>
#include <cplusplus/ExpressionUnderCursor.h>
#include <cplusplus/Icons.h>
#include <cplusplus/SimpleLexer.h>
-#include <clangbackendipc/filecontainer.h>
+#include <clangsupport/filecontainer.h>
#include <utils/algorithm.h>
+#include <utils/textutils.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
@@ -253,7 +253,8 @@ IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper()
}
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen: {
m_sentRequestType = FunctionHintCompletion;
- const bool requestSent = sendCompletionRequest(analyzer.positionForClang(), QByteArray());
+ const bool requestSent = sendCompletionRequest(analyzer.positionForClang(), QByteArray(),
+ analyzer.functionNameStart());
setPerformWasApplicable(requestSent);
break;
}
@@ -548,14 +549,23 @@ void setLastCompletionPosition(const QString &filePath,
}
-bool ClangCompletionAssistProcessor::sendCompletionRequest(int position,
- const QByteArray &customFileContent)
+ClangCompletionAssistProcessor::Position
+ClangCompletionAssistProcessor::extractLineColumn(int position)
{
- int line, column;
- TextEditor::Convenience::convertPosition(m_interface->textDocument(), position, &line, &column);
+ if (position < 0)
+ return {-1, -1};
+
+ int line = -1, column = -1;
+ ::Utils::Text::convertPosition(m_interface->textDocument(), position, &line, &column);
const QTextBlock block = m_interface->textDocument()->findBlock(position);
column += ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), column) + 1;
+ return {line, column};
+}
+bool ClangCompletionAssistProcessor::sendCompletionRequest(int position,
+ const QByteArray &customFileContent,
+ int functionNameStartPosition)
+{
const QString filePath = m_interface->fileName();
auto &ipcCommunicator = m_interface->ipcCommunicator();
@@ -567,8 +577,12 @@ bool ClangCompletionAssistProcessor::sendCompletionRequest(int position,
setLastDocumentRevision(filePath);
}
+ const Position cursorPosition = extractLineColumn(position);
+ const Position functionNameStart = extractLineColumn(functionNameStartPosition);
const QString projectPartId = CppTools::CppToolsBridge::projectPartIdForFile(filePath);
- ipcCommunicator.completeCode(this, filePath, uint(line), uint(column), projectPartId);
+ ipcCommunicator.completeCode(this, filePath, uint(cursorPosition.line),
+ uint(cursorPosition.column), projectPartId,
+ functionNameStart.line, functionNameStart.column);
setLastCompletionPosition(filePath, position);
return true;
}
diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.h b/src/plugins/clangcodemodel/clangcompletionassistprocessor.h
index 8b67116e874..0f23b1a0fee 100644
--- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.h
+++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.h
@@ -29,7 +29,7 @@
#include <cpptools/cppcompletionassistprocessor.h>
-#include <clangbackendipc/codecompletion.h>
+#include <clangsupport/codecompletion.h>
#include <QCoreApplication>
#include <QTextCursor>
@@ -82,9 +82,14 @@ private:
UnsavedFileContentInfo unsavedFileContent(const QByteArray &customFileContent) const;
void sendFileContent(const QByteArray &customFileContent);
- bool sendCompletionRequest(int position, const QByteArray &customFileContent);
+ bool sendCompletionRequest(int position,
+ const QByteArray &customFileContent,
+ int functionNameStartPosition = -1);
private:
+ struct Position { int line; int column; };
+ Position extractLineColumn(int position);
+
QScopedPointer<const ClangCompletionAssistInterface> m_interface;
unsigned m_completionOperator;
enum CompletionRequestType { NormalCompletion, FunctionHintCompletion } m_sentRequestType;
diff --git a/src/plugins/clangcodemodel/clangcompletionchunkstotextconverter.h b/src/plugins/clangcodemodel/clangcompletionchunkstotextconverter.h
index 4a8f6b8a958..27eccbcf169 100644
--- a/src/plugins/clangcodemodel/clangcompletionchunkstotextconverter.h
+++ b/src/plugins/clangcodemodel/clangcompletionchunkstotextconverter.h
@@ -25,7 +25,7 @@
#pragma once
-#include <clangbackendipc/codecompletion.h>
+#include <clangsupport/codecompletion.h>
#include <sqlite/utf8string.h>
diff --git a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp
index 00a8f96c6d7..bb8308eada5 100644
--- a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp
+++ b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp
@@ -91,7 +91,7 @@ void ClangCompletionContextAnalyzer::analyze()
}
}
-bool ClangCompletionContextAnalyzer::looksLikeAFunctionCall(int endOfOperator) const
+int ClangCompletionContextAnalyzer::startOfFunctionCall(int endOfOperator) const
{
int index = ActivationSequenceContextProcessor::skipPrecedingWhitespace(m_interface,
endOfOperator);
@@ -104,22 +104,24 @@ bool ClangCompletionContextAnalyzer::looksLikeAFunctionCall(int endOfOperator) c
const int functionNameStart = ActivationSequenceContextProcessor::findStartOfName(m_interface,
index);
if (functionNameStart == -1)
- return false;
+ return -1;
QTextCursor functionNameSelector(m_interface->textDocument());
functionNameSelector.setPosition(functionNameStart);
functionNameSelector.setPosition(index, QTextCursor::KeepAnchor);
const QString functionName = functionNameSelector.selectedText().trimmed();
- return !functionName.isEmpty();
+ return functionName.isEmpty() ? -1 : functionNameStart;
}
void ClangCompletionContextAnalyzer::setActionAndClangPosition(CompletionAction action,
- int position)
+ int position,
+ int functionNameStart)
{
QTC_CHECK(position >= -1);
m_completionAction = action;
m_positionForClang = position;
+ m_functionNameStart = functionNameStart;
}
void
@@ -157,15 +159,19 @@ void ClangCompletionContextAnalyzer::handleFunctionCall(int afterOperatorPositio
// No function completion if cursor is not after '(' or ','
m_positionForProposal = afterOperatorPosition;
setActionAndClangPosition(PassThroughToLibClang, afterOperatorPosition);
- } else if (looksLikeAFunctionCall(afterOperatorPosition)) {
- // Always pass the position right after '(' to libclang because
- // positions after the comma might be problematic if a preceding
- // argument is invalid code.
- setActionAndClangPosition(PassThroughToLibClangAfterLeftParen,
- m_positionForProposal);
- } else { // e.g. "(" without any function name in front
- m_positionForProposal = afterOperatorPosition;
- setActionAndClangPosition(PassThroughToLibClang, afterOperatorPosition);
+ } else {
+ const int functionNameStart = startOfFunctionCall(afterOperatorPosition);
+ if (functionNameStart >= 0) {
+ // Always pass the position right after '(' to libclang because
+ // positions after the comma might be problematic if a preceding
+ // argument is invalid code.
+ setActionAndClangPosition(PassThroughToLibClangAfterLeftParen,
+ m_positionForProposal,
+ functionNameStart);
+ } else { // e.g. "(" without any function name in front
+ m_positionForProposal = afterOperatorPosition;
+ setActionAndClangPosition(PassThroughToLibClang, afterOperatorPosition);
+ }
}
}
}
diff --git a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.h b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.h
index 3aa3bc58045..113384c7610 100644
--- a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.h
+++ b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.h
@@ -56,14 +56,17 @@ public:
unsigned completionOperator() const { return m_completionOperator; }
int positionForProposal() const { return m_positionForProposal; }
int positionForClang() const { return m_positionForClang; }
+ int functionNameStart() const { return m_functionNameStart; }
int positionEndOfExpression() const { return m_positionEndOfExpression; }
private:
ClangCompletionContextAnalyzer();
- bool looksLikeAFunctionCall(int endOfExpression) const;
+ int startOfFunctionCall(int endOfExpression) const;
- void setActionAndClangPosition(CompletionAction action, int position);
+ void setActionAndClangPosition(CompletionAction action,
+ int position,
+ int functionNameStart = -1);
void setAction(CompletionAction action);
bool handleNonFunctionCall(int position);
@@ -79,6 +82,7 @@ private:
CPlusPlus::Kind m_completionOperator = CPlusPlus::T_EOF_SYMBOL;
int m_positionForProposal = -1;
int m_positionForClang = -1;
+ int m_functionNameStart = -1;
int m_positionEndOfExpression = -1;
};
diff --git a/src/plugins/clangcodemodel/clangdiagnosticfilter.h b/src/plugins/clangcodemodel/clangdiagnosticfilter.h
index 9329d43ceba..0fe164ecf07 100644
--- a/src/plugins/clangcodemodel/clangdiagnosticfilter.h
+++ b/src/plugins/clangcodemodel/clangdiagnosticfilter.h
@@ -25,7 +25,7 @@
#pragma once
-#include <clangbackendipc/diagnosticcontainer.h>
+#include <clangsupport/diagnosticcontainer.h>
#include <QVector>
diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp
index 1dd003c7c11..eb43f6556ee 100644
--- a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp
+++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp
@@ -33,11 +33,11 @@
#include <cpptools/cpptoolsconstants.h>
-#include <texteditor/convenience.h>
#include <texteditor/fontsettings.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditorsettings.h>
+#include <utils/textutils.h>
#include <utils/fileutils.h>
#include <utils/proxyaction.h>
#include <utils/qtcassert.h>
@@ -176,7 +176,7 @@ void addErrorSelections(const QVector<ClangBackEnd::DiagnosticContainer> &diagno
ClangBackEnd::SourceLocationContainer toSourceLocation(QTextDocument *textDocument, int position)
{
int line, column;
- if (TextEditor::Convenience::convertPosition(textDocument, position, &line, &column))
+ if (Utils::Text::convertPosition(textDocument, position, &line, &column))
return ClangBackEnd::SourceLocationContainer(Utf8String(), line, column);
return ClangBackEnd::SourceLocationContainer();
diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.h b/src/plugins/clangcodemodel/clangdiagnosticmanager.h
index 1321702c99c..dff768a09d4 100644
--- a/src/plugins/clangcodemodel/clangdiagnosticmanager.h
+++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.h
@@ -29,7 +29,7 @@
#include <texteditor/refactoroverlay.h>
-#include <clangbackendipc/diagnosticcontainer.h>
+#include <clangsupport/diagnosticcontainer.h>
#include <QList>
#include <QSet>
diff --git a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h
index 3ea1bfb0ada..91fdfc67d6b 100644
--- a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h
+++ b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.h
@@ -25,7 +25,7 @@
#pragma once
-#include <clangbackendipc/diagnosticcontainer.h>
+#include <clangsupport/diagnosticcontainer.h>
QT_BEGIN_NAMESPACE
class QLayout;
diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
index 943c126c59f..81053cef60e 100644
--- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
+++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
@@ -47,7 +47,6 @@
#include <cpptools/cppworkingcopy.h>
#include <cpptools/editordocumenthandle.h>
-#include <texteditor/convenience.h>
#include <texteditor/displaysettings.h>
#include <texteditor/fontsettings.h>
#include <texteditor/texteditor.h>
@@ -56,6 +55,7 @@
#include <cplusplus/CppDocument.h>
+#include <utils/textutils.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
@@ -225,6 +225,12 @@ toTextEditorBlocks(QTextDocument *textDocument,
}
}
+const QVector<ClangBackEnd::HighlightingMarkContainer>
+&ClangEditorDocumentProcessor::highlightingMarks() const
+{
+ return m_highlightingMarks;
+}
+
void ClangEditorDocumentProcessor::updateHighlighting(
const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks,
const QVector<ClangBackEnd::SourceRangeContainer> &skippedPreprocessorRanges,
@@ -234,6 +240,7 @@ void ClangEditorDocumentProcessor::updateHighlighting(
const auto skippedPreprocessorBlocks = toTextEditorBlocks(textDocument(), skippedPreprocessorRanges);
emit ifdefedOutBlocksUpdated(documentRevision, skippedPreprocessorBlocks);
+ m_highlightingMarks = highlightingMarks;
m_semanticHighlighter.setHighlightingRunner(
[highlightingMarks]() {
auto *reporter = new HighlightingMarksReporter(highlightingMarks);
@@ -246,10 +253,8 @@ void ClangEditorDocumentProcessor::updateHighlighting(
static int currentLine(const TextEditor::AssistInterface &assistInterface)
{
int line, column;
- TextEditor::Convenience::convertPosition(assistInterface.textDocument(),
- assistInterface.position(),
- &line,
- &column);
+ ::Utils::Text::convertPosition(assistInterface.textDocument(), assistInterface.position(),
+ &line, &column);
return line;
}
@@ -315,10 +320,10 @@ static QFuture<CppTools::CursorInfo> defaultCursorInfoFuture()
static bool convertPosition(const QTextCursor &textCursor, int *line, int *column)
{
- const bool converted = TextEditor::Convenience::convertPosition(textCursor.document(),
- textCursor.position(),
- line,
- column);
+ const bool converted = ::Utils::Text::convertPosition(textCursor.document(),
+ textCursor.position(),
+ line,
+ column);
QTC_CHECK(converted);
return converted;
}
@@ -345,6 +350,54 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams &param
localUses);
}
+static QVector<Utf8String> prioritizeByBaseName(const QString &curPath,
+ const ::Utils::FileNameList &fileDeps)
+{
+ QList<Utf8String> dependentFiles;
+ dependentFiles.reserve(fileDeps.size());
+ for (const ::Utils::FileName &dep: fileDeps)
+ dependentFiles.push_back(dep.toString());
+
+ const QString curFilename = QFileInfo(curPath).fileName();
+ if (CppTools::ProjectFile::isHeader(CppTools::ProjectFile::classify(curFilename))) {
+ const QString withoutExt = QFileInfo(curFilename).baseName();
+ int posToMove = 0;
+ // Move exact match to the first place and partial matches after it
+ for (int i = 0; i < dependentFiles.size(); ++i) {
+ const QString baseName = QFileInfo(dependentFiles[i]).baseName();
+ if (withoutExt == baseName) {
+ dependentFiles.move(i, 0);
+ posToMove++;
+ continue;
+ }
+ if (baseName.contains(withoutExt))
+ dependentFiles.move(i, posToMove++);
+ }
+ }
+ // Limit the number of scans (don't search for overrides)
+ if (dependentFiles.size() > 5)
+ dependentFiles.erase(dependentFiles.begin() + 5, dependentFiles.end());
+ return QVector<Utf8String>::fromList(dependentFiles);
+}
+
+QFuture<CppTools::SymbolInfo>
+ClangEditorDocumentProcessor::requestFollowSymbol(int line, int column)
+{
+ QVector<Utf8String> dependentFiles;
+ CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
+ if (modelManager && !modelManager->projectPart(filePath()).isEmpty()) {
+ // This might be not so fast - index will change that
+ const ::Utils::FileNameList fileDeps
+ = modelManager->snapshot().filesDependingOn(filePath());
+ dependentFiles = prioritizeByBaseName(filePath(), fileDeps);
+ }
+
+ return m_ipcCommunicator.requestFollowSymbol(simpleFileContainer(),
+ dependentFiles,
+ static_cast<quint32>(line),
+ static_cast<quint32>(column));
+}
+
ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithArguments() const
{
return fileContainerWithArguments(m_projectPart.data());
diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h
index d7c27a79ff2..d7f7f966f50 100644
--- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h
+++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h
@@ -86,11 +86,14 @@ public:
void setParserConfig(const CppTools::BaseEditorDocumentParser::Configuration config) override;
QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams &params) override;
+ QFuture<CppTools::SymbolInfo> requestFollowSymbol(int line, int column) override;
ClangBackEnd::FileContainer fileContainerWithArguments() const;
void clearDiagnosticsWithFixIts();
+ const QVector<ClangBackEnd::HighlightingMarkContainer> &highlightingMarks() const;
+
public:
static ClangEditorDocumentProcessor *get(const QString &filePath);
@@ -119,6 +122,7 @@ private:
QTimer m_updateTranslationUnitTimer;
unsigned m_parserRevision;
+ QVector<ClangBackEnd::HighlightingMarkContainer> m_highlightingMarks;
CppTools::SemanticHighlighter m_semanticHighlighter;
CppTools::BuiltinEditorDocumentProcessor m_builtinProcessor;
};
diff --git a/src/plugins/clangcodemodel/clangfixitoperation.h b/src/plugins/clangcodemodel/clangfixitoperation.h
index e4183451b49..1270e98f36c 100644
--- a/src/plugins/clangcodemodel/clangfixitoperation.h
+++ b/src/plugins/clangcodemodel/clangfixitoperation.h
@@ -27,7 +27,7 @@
#include <texteditor/quickfix.h>
-#include <clangbackendipc/fixitcontainer.h>
+#include <clangsupport/fixitcontainer.h>
#include <utils/changeset.h>
diff --git a/src/plugins/clangcodemodel/clangfixitoperationsextractor.h b/src/plugins/clangcodemodel/clangfixitoperationsextractor.h
index f0b1fb83abf..ee2da9a4b21 100644
--- a/src/plugins/clangcodemodel/clangfixitoperationsextractor.h
+++ b/src/plugins/clangcodemodel/clangfixitoperationsextractor.h
@@ -27,7 +27,7 @@
#include <texteditor/quickfix.h>
-#include <clangbackendipc/diagnosticcontainer.h>
+#include <clangsupport/diagnosticcontainer.h>
namespace ClangCodeModel {
diff --git a/src/plugins/clangcodemodel/clangfollowsymbol.cpp b/src/plugins/clangcodemodel/clangfollowsymbol.cpp
new file mode 100644
index 00000000000..66db810e4a4
--- /dev/null
+++ b/src/plugins/clangcodemodel/clangfollowsymbol.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "clangeditordocumentprocessor.h"
+#include "clangfollowsymbol.h"
+
+#include <texteditor/texteditor.h>
+
+#include <clangsupport/highlightingmarkcontainer.h>
+
+#include <utils/textutils.h>
+#include <utils/algorithm.h>
+
+namespace ClangCodeModel {
+namespace Internal {
+
+// Returns invalid Mark if it is not found at (line, column)
+static bool findMark(const QVector<ClangBackEnd::HighlightingMarkContainer> &marks,
+ uint line,
+ uint column,
+ ClangBackEnd::HighlightingMarkContainer &mark)
+{
+ mark = Utils::findOrDefault(marks,
+ [line, column](const ClangBackEnd::HighlightingMarkContainer &curMark) {
+ if (curMark.line() != line)
+ return false;
+ if (curMark.column() == column)
+ return true;
+ if (curMark.column() < column && curMark.column() + curMark.length() >= column)
+ return true;
+ return false;
+ });
+ if (mark.isInvalid())
+ return false;
+ return true;
+}
+
+static int getMarkPos(QTextCursor cursor, const ClangBackEnd::HighlightingMarkContainer &mark)
+{
+ cursor.setPosition(0);
+ cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, mark.line() - 1);
+ cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, mark.column() - 1);
+ return cursor.position();
+}
+
+static TextEditor::TextEditorWidget::Link linkAtCursor(QTextCursor cursor,
+ const QString &filePath,
+ uint line,
+ uint column,
+ ClangEditorDocumentProcessor *processor)
+{
+ using Link = TextEditor::TextEditorWidget::Link;
+
+ const QVector<ClangBackEnd::HighlightingMarkContainer> &marks
+ = processor->highlightingMarks();
+ ClangBackEnd::HighlightingMarkContainer mark;
+ if (!findMark(marks, line, column, mark))
+ return Link();
+
+ cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+ const QString tokenStr = cursor.selectedText();
+
+ Link token(filePath, mark.line(), mark.column());
+ token.linkTextStart = getMarkPos(cursor, mark);
+ token.linkTextEnd = token.linkTextStart + mark.length();
+ if (mark.isIncludeDirectivePath()) {
+ if (tokenStr != "include" && tokenStr != "#" && tokenStr != "<")
+ return token;
+ return Link();
+ }
+ if (mark.isIdentifier() || tokenStr == "operator")
+ return token;
+ return Link();
+}
+
+TextEditor::TextEditorWidget::Link ClangFollowSymbol::findLink(
+ const CppTools::CursorInEditor &data,
+ bool resolveTarget,
+ const CPlusPlus::Snapshot &,
+ const CPlusPlus::Document::Ptr &,
+ CppTools::SymbolFinder *,
+ bool)
+{
+ int lineNumber = 0, positionInBlock = 0;
+ QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor());
+ Utils::Text::convertPosition(cursor.document(), cursor.position(), &lineNumber,
+ &positionInBlock);
+
+ const uint line = lineNumber;
+ const uint column = positionInBlock + 1;
+
+ ClangEditorDocumentProcessor *processor = ClangEditorDocumentProcessor::get(
+ data.filePath().toString());
+ if (!processor)
+ return Link();
+
+ if (!resolveTarget)
+ return linkAtCursor(cursor, data.filePath().toString(), line, column, processor);
+
+ QFuture<CppTools::SymbolInfo> info
+ = processor->requestFollowSymbol(static_cast<int>(line),
+ static_cast<int>(column));
+
+ if (info.isCanceled())
+ return Link();
+
+ while (!info.isFinished()) {
+ if (info.isCanceled())
+ return Link();
+ QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ }
+ CppTools::SymbolInfo result = info.result();
+
+ // We did not fail but the result is empty
+ if (result.fileName.isEmpty())
+ return Link();
+
+ return Link(result.fileName, result.startLine, result.startColumn - 1);
+}
+
+} // namespace Internal
+} // namespace ClangCodeModel
diff --git a/src/libs/sqlite/createtablecommand.h b/src/plugins/clangcodemodel/clangfollowsymbol.h
index b4387e7ab7f..5dcf5d389dd 100644
--- a/src/libs/sqlite/createtablecommand.h
+++ b/src/plugins/clangcodemodel/clangfollowsymbol.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,25 +25,21 @@
#pragma once
-#include "columndefinition.h"
-#include "utf8string.h"
-
-#include <QMetaType>
-#include <QVector>
+#include <cpptools/followsymbolinterface.h>
+namespace ClangCodeModel {
namespace Internal {
-class CreateTableCommand
+class ClangFollowSymbol : public CppTools::FollowSymbolInterface
{
public:
- QVector<ColumnDefinition> definitions;
- Utf8String tableName;
- bool useWithoutRowId;
-
- static void registerType();
-
+ Link findLink(const CppTools::CursorInEditor &data,
+ bool resolveTarget,
+ const CPlusPlus::Snapshot &,
+ const CPlusPlus::Document::Ptr &,
+ CppTools::SymbolFinder *,
+ bool) override;
};
} // namespace Internal
-
-Q_DECLARE_METATYPE(Internal::CreateTableCommand)
+} // namespace ClangCodeModel
diff --git a/src/plugins/clangcodemodel/clangfunctionhintmodel.cpp b/src/plugins/clangcodemodel/clangfunctionhintmodel.cpp
index 67d58d9cb68..1641f24a714 100644
--- a/src/plugins/clangcodemodel/clangfunctionhintmodel.cpp
+++ b/src/plugins/clangcodemodel/clangfunctionhintmodel.cpp
@@ -61,6 +61,15 @@ QString ClangFunctionHintModel::text(int index) const
return signatureWithEmphasizedCurrentParameter;
}
+QString ClangFunctionHintModel::id(int index) const
+{
+ QString chunks;
+ for (const ClangBackEnd::CodeCompletionChunk &chunk : m_functionSymbols.at(index).chunks())
+ chunks += chunk.text();
+
+ return chunks;
+}
+
int ClangFunctionHintModel::activeArgument(const QString &prefix) const
{
int activeArgumentNumber = 0;
diff --git a/src/plugins/clangcodemodel/clangfunctionhintmodel.h b/src/plugins/clangcodemodel/clangfunctionhintmodel.h
index edfb2f6d74c..9a848025a4d 100644
--- a/src/plugins/clangcodemodel/clangfunctionhintmodel.h
+++ b/src/plugins/clangcodemodel/clangfunctionhintmodel.h
@@ -40,6 +40,7 @@ public:
void reset() override;
int size() const override;
QString text(int index) const override;
+ QString id(int index) const override;
int activeArgument(const QString &prefix) const override;
private:
diff --git a/src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp b/src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp
index 6090b73f415..747070a317a 100644
--- a/src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp
+++ b/src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp
@@ -158,8 +158,15 @@ void HighlightingMarksReporter::run_internal()
if (isCanceled())
return;
- for (const auto &highlightingMark : m_highlightingMarks)
+ using ClangBackEnd::HighlightingType;
+
+ for (const auto &highlightingMark : m_highlightingMarks) {
+ const HighlightingType mainType = highlightingMark.types().mainHighlightingType;
+ if (mainType == HighlightingType::StringLiteral)
+ continue;
+
reportChunkWise(toHighlightingResult(highlightingMark));
+ }
if (isCanceled())
return;
diff --git a/src/plugins/clangcodemodel/clanghighlightingmarksreporter.h b/src/plugins/clangcodemodel/clanghighlightingmarksreporter.h
index af4f1773b0e..379e2c55f62 100644
--- a/src/plugins/clangcodemodel/clanghighlightingmarksreporter.h
+++ b/src/plugins/clangcodemodel/clanghighlightingmarksreporter.h
@@ -32,7 +32,7 @@
#include <texteditor/semantichighlighter.h>
-#include <clangbackendipc/highlightingmarkcontainer.h>
+#include <clangsupport/highlightingmarkcontainer.h>
namespace ClangCodeModel {
diff --git a/src/plugins/clangcodemodel/clangisdiagnosticrelatedtolocation.h b/src/plugins/clangcodemodel/clangisdiagnosticrelatedtolocation.h
index 8d44634bacd..2676bbffded 100644
--- a/src/plugins/clangcodemodel/clangisdiagnosticrelatedtolocation.h
+++ b/src/plugins/clangcodemodel/clangisdiagnosticrelatedtolocation.h
@@ -25,7 +25,7 @@
#pragma once
-#include <clangbackendipc/diagnosticcontainer.h>
+#include <clangsupport/diagnosticcontainer.h>
namespace ClangCodeModel {
namespace Internal {
diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
index a2dd65103b4..c5d85045c51 100644
--- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
+++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
@@ -28,8 +28,10 @@
#include "clangconstants.h"
#include "clangeditordocumentprocessor.h"
#include "clangutils.h"
+#include "clangfollowsymbol.h"
#include <coreplugin/editormanager/editormanager.h>
+#include <cpptools/cppfollowsymbolundercursor.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/editordocumenthandle.h>
#include <cpptools/projectinfo.h>
@@ -38,9 +40,9 @@
#include <projectexplorer/project.h>
-#include <clangbackendipc/cmbregisterprojectsforeditormessage.h>
-#include <clangbackendipc/filecontainer.h>
-#include <clangbackendipc/projectpartcontainer.h>
+#include <clangsupport/cmbregisterprojectsforeditormessage.h>
+#include <clangsupport/filecontainer.h>
+#include <clangsupport/projectpartcontainer.h>
#include <utils/qtcassert.h>
#include <QCoreApplication>
@@ -52,6 +54,12 @@ using namespace ClangCodeModel::Internal;
static ModelManagerSupportClang *m_instance = 0;
+static bool useClangFollowSymbol()
+{
+ static bool use = qEnvironmentVariableIntValue("QTC_CLANG_FOLLOW_SYMBOL");
+ return use;
+}
+
static CppTools::CppModelManager *cppModelManager()
{
return CppTools::CppModelManager::instance();
@@ -63,6 +71,11 @@ ModelManagerSupportClang::ModelManagerSupportClang()
QTC_CHECK(!m_instance);
m_instance = this;
+ if (useClangFollowSymbol())
+ m_followSymbol.reset(new ClangFollowSymbol);
+ else
+ m_followSymbol.reset(new CppTools::FollowSymbolUnderCursor);
+
Core::EditorManager *editorManager = Core::EditorManager::instance();
connect(editorManager, &Core::EditorManager::editorOpened,
this, &ModelManagerSupportClang::onEditorOpened);
@@ -96,6 +109,11 @@ CppTools::CppCompletionAssistProvider *ModelManagerSupportClang::completionAssis
return &m_completionAssistProvider;
}
+CppTools::FollowSymbolInterface &ModelManagerSupportClang::followSymbolInterface()
+{
+ return *m_followSymbol;
+}
+
CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument)
{
diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h
index d315bbb359e..78e5cd5694a 100644
--- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h
+++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h
@@ -33,6 +33,8 @@
#include <QObject>
#include <QScopedPointer>
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QMenu;
class QWidget;
@@ -40,6 +42,7 @@ QT_END_NAMESPACE
namespace Core { class IDocument; }
namespace TextEditor { class TextEditorWidget; }
+namespace CppTools { class FollowSymbolInterface; }
namespace ClangCodeModel {
namespace Internal {
@@ -57,6 +60,7 @@ public:
CppTools::CppCompletionAssistProvider *completionAssistProvider() override;
CppTools::BaseEditorDocumentProcessor *editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) override;
+ CppTools::FollowSymbolInterface &followSymbolInterface() override;
IpcCommunicator &ipcCommunicator();
QString dummyUiHeaderOnDiskDirPath() const;
@@ -100,6 +104,7 @@ private:
UiHeaderOnDiskManager m_uiHeaderOnDiskManager;
IpcCommunicator m_ipcCommunicator;
ClangCompletionAssistProvider m_completionAssistProvider;
+ std::unique_ptr<CppTools::FollowSymbolInterface> m_followSymbol;
};
class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider
diff --git a/src/plugins/clangcodemodel/clangtextmark.h b/src/plugins/clangcodemodel/clangtextmark.h
index ae5478168a3..5c794d970c3 100644
--- a/src/plugins/clangcodemodel/clangtextmark.h
+++ b/src/plugins/clangcodemodel/clangtextmark.h
@@ -25,8 +25,8 @@
#pragma once
-#include <clangbackendipc_global.h>
-#include <clangbackendipc/diagnosticcontainer.h>
+#include <clangsupport_global.h>
+#include <clangsupport/diagnosticcontainer.h>
#include <texteditor/textmark.h>
diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp
index e436ec275fb..0058ee4023b 100644
--- a/src/plugins/clangcodemodel/clangutils.cpp
+++ b/src/plugins/clangcodemodel/clangutils.cpp
@@ -70,46 +70,21 @@ QStringList createClangOptions(const ProjectPart::Ptr &pPart, const QString &fil
return createClangOptions(pPart, fileKind);
}
-class LibClangOptionsBuilder : public ClangCompilerOptionsBuilder
+class LibClangOptionsBuilder final : public ClangCompilerOptionsBuilder
{
public:
- static QStringList build(const ProjectPart::Ptr &projectPart, ProjectFile::Kind fileKind)
+ LibClangOptionsBuilder(const ProjectPart &projectPart)
+ : ClangCompilerOptionsBuilder(projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR)
{
- if (projectPart.isNull())
- return QStringList();
-
- LibClangOptionsBuilder optionsBuilder(*projectPart.data());
-
- optionsBuilder.addWordWidth();
- optionsBuilder.addTargetTriple();
- optionsBuilder.addLanguageOption(fileKind);
- optionsBuilder.addOptionsForLanguage(/*checkForBorlandExtensions*/ true);
- optionsBuilder.enableExceptions();
-
- optionsBuilder.addDefineToAvoidIncludingGccOrMinGwIntrinsics();
- optionsBuilder.addDefineFloat128ForMingw();
- optionsBuilder.addToolchainAndProjectDefines();
- optionsBuilder.undefineCppLanguageFeatureMacrosForMsvc2015();
-
- optionsBuilder.addPredefinedMacrosAndHeaderPathsOptions();
- optionsBuilder.addWrappedQtHeadersIncludePath();
- optionsBuilder.addHeaderPathOptions();
- optionsBuilder.addDummyUiHeaderOnDiskIncludePath();
- optionsBuilder.addProjectConfigFileInclude();
-
- optionsBuilder.addMsvcCompatibilityVersion();
-
- optionsBuilder.addExtraOptions();
-
- return optionsBuilder.options();
}
-private:
- LibClangOptionsBuilder(const CppTools::ProjectPart &projectPart)
- : ClangCompilerOptionsBuilder(projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR)
+ void addExtraOptions() final
{
+ addDummyUiHeaderOnDiskIncludePath();
+ ClangCompilerOptionsBuilder::addExtraOptions();
}
+private:
void addDummyUiHeaderOnDiskIncludePath()
{
const QString path = ModelManagerSupportClang::instance()->dummyUiHeaderOnDiskDirPath();
@@ -125,7 +100,9 @@ private:
*/
QStringList createClangOptions(const ProjectPart::Ptr &pPart, ProjectFile::Kind fileKind)
{
- return LibClangOptionsBuilder::build(pPart, fileKind);
+ if (!pPart)
+ return QStringList();
+ return LibClangOptionsBuilder(*pPart).build(fileKind, CompilerOptionsBuilder::PchUsage::None);
}
ProjectPart::Ptr projectPartForFile(const QString &filePath)
diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp
index 07c10c0f7ee..7a5e0446d8e 100644
--- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp
+++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp
@@ -44,7 +44,7 @@
#include <texteditor/textdocument.h>
#include <texteditor/texteditor.h>
-#include <clangbackendipc/clangcodemodelservermessages.h>
+#include <clangsupport/clangcodemodelservermessages.h>
#include <utils/changeset.h>
#include <utils/qtcassert.h>
@@ -58,9 +58,6 @@ using namespace ClangCodeModel::Internal;
namespace {
-QString _(const char text[])
-{ return QString::fromUtf8(text); }
-
QString qrcPath(const QByteArray relativeFilePath)
{ return QLatin1String(":/unittests/ClangCodeModel/") + QString::fromUtf8(relativeFilePath); }
@@ -324,6 +321,11 @@ QString toString(const RequestReferencesMessage &)
return QStringLiteral("RequestReferencesMessage\n");
}
+QString toString(const RequestFollowSymbolMessage &)
+{
+ return QStringLiteral("RequestFollowSymbolMessage\n");
+}
+
QString toString(const UpdateVisibleTranslationUnitsMessage &)
{
return QStringLiteral("UpdateVisibleTranslationUnitsMessage\n");
@@ -365,6 +367,9 @@ public:
void requestReferences(const RequestReferencesMessage &message) override
{ senderLog.append(toString(message)); }
+ void requestFollowSymbol(const RequestFollowSymbolMessage &message) override
+ { senderLog.append(toString(message)); }
+
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override
{ senderLog.append(toString(message)); }
@@ -504,7 +509,7 @@ bool OpenEditorAtCursorPosition::waitUntil(const std::function<bool ()> &conditi
}
CppTools::ProjectPart::Ptr createProjectPart(const QStringList &files,
- const QString &defines)
+ const ProjectExplorer::Macros &macros)
{
using namespace CppTools;
@@ -513,19 +518,19 @@ CppTools::ProjectPart::Ptr createProjectPart(const QStringList &files,
foreach (const QString &file, files)
projectPart->files.append(ProjectFile(file, ProjectFile::classify(file)));
projectPart->qtVersion = ProjectPart::NoQt;
- projectPart->projectDefines = defines.toUtf8();
+ projectPart->projectMacros = macros;
return projectPart;
}
CppTools::ProjectInfo createProjectInfo(ProjectExplorer::Project *project,
const QStringList &files,
- const QString &defines)
+ const ProjectExplorer::Macros &macros)
{
using namespace CppTools;
QTC_ASSERT(project, return ProjectInfo());
- const CppTools::ProjectPart::Ptr projectPart = createProjectPart(files, defines);
+ const CppTools::ProjectPart::Ptr projectPart = createProjectPart(files, macros);
ProjectInfo projectInfo = ProjectInfo(project);
projectInfo.appendProjectPart(projectPart);
return projectInfo;
@@ -535,11 +540,11 @@ class ProjectLoader
{
public:
ProjectLoader(const QStringList &projectFiles,
- const QString &projectDefines,
+ const ProjectExplorer::Macros &projectMacros,
bool testOnlyForCleanedProjects = false)
: m_project(0)
, m_projectFiles(projectFiles)
- , m_projectDefines(projectDefines)
+ , m_projectMacros(projectMacros)
, m_helper(0, testOnlyForCleanedProjects)
{
}
@@ -549,17 +554,17 @@ public:
m_project = m_helper.createProject(QLatin1String("testProject"));
const CppTools::ProjectInfo projectInfo = createProjectInfo(m_project,
m_projectFiles,
- m_projectDefines);
+ m_projectMacros);
const QSet<QString> filesIndexedAfterLoading = m_helper.updateProjectInfo(projectInfo);
return m_projectFiles.size() == filesIndexedAfterLoading.size();
}
- bool updateProject(const QString &updatedProjectDefines)
+ bool updateProject(const ProjectExplorer::Macros &updatedProjectMacros)
{
QTC_ASSERT(m_project, return false);
const CppTools::ProjectInfo updatedProjectInfo = createProjectInfo(m_project,
m_projectFiles,
- updatedProjectDefines);
+ updatedProjectMacros);
return updateProjectInfo(updatedProjectInfo);
}
@@ -573,7 +578,7 @@ private:
ProjectExplorer::Project *m_project;
QStringList m_projectFiles;
- QString m_projectDefines;
+ ProjectExplorer::Macros m_projectMacros;
CppTools::Tests::ModelManagerTestHelper m_helper;
};
@@ -857,8 +862,7 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCode()
const TestDocument testDocument("completionWithProject.cpp");
QVERIFY(testDocument.isCreatedAndHasValidCursorPosition());
- ProjectLoader projectLoader(QStringList(testDocument.filePath),
- _("#define PROJECT_CONFIGURATION_1\n"));
+ ProjectLoader projectLoader(QStringList(testDocument.filePath), {{"PROJECT_CONFIGURATION_1"}});
QVERIFY(projectLoader.load());
OpenEditorAtCursorPosition openEditor(testDocument);
@@ -883,7 +887,7 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCodeAfterChangingProje
{
// Check completion with project configuration 1
ProjectLoader projectLoader(QStringList(testDocument.filePath),
- _("#define PROJECT_CONFIGURATION_1\n"),
+ {{"PROJECT_CONFIGURATION_1"}},
/* testOnlyForCleanedProjects= */ true);
QVERIFY(projectLoader.load());
openEditor.waitUntilProjectPartChanged(QLatin1String("myproject.project"));
@@ -894,7 +898,7 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCodeAfterChangingProje
QVERIFY(!hasItem(proposal, "projectConfiguration2"));
// Check completion with project configuration 2
- QVERIFY(projectLoader.updateProject(_("#define PROJECT_CONFIGURATION_2\n")));
+ QVERIFY(projectLoader.updateProject({{"PROJECT_CONFIGURATION_2"}}));
proposal = completionResults(openEditor.editor());
QVERIFY(!hasItem(proposal, "projectConfiguration1"));
diff --git a/src/plugins/clangpchmanager/clangpchmanager-source.pri b/src/plugins/clangpchmanager/clangpchmanager-source.pri
index fd5b61a24d4..25d8d637305 100644
--- a/src/plugins/clangpchmanager/clangpchmanager-source.pri
+++ b/src/plugins/clangpchmanager/clangpchmanager-source.pri
@@ -11,12 +11,14 @@ HEADERS += \
$$PWD/pchmanagernotifierinterface.h \
$$PWD/pchmanagerconnectionclient.h \
$$PWD/clangpchmanager_global.h \
- $$PWD/projectupdater.h
+ $$PWD/projectupdater.h \
+ $$PWD/pchmanagerprojectupdater.h
SOURCES += \
$$PWD/pchmanagerclient.cpp \
$$PWD/pchmanagernotifierinterface.cpp \
$$PWD/pchmanagerconnectionclient.cpp \
- $$PWD/projectupdater.cpp
+ $$PWD/projectupdater.cpp \
+ $$PWD/pchmanagerprojectupdater.cpp
diff --git a/src/plugins/clangpchmanager/clangpchmanager_dependencies.pri b/src/plugins/clangpchmanager/clangpchmanager_dependencies.pri
index 281eca80d5e..197da5a97cf 100644
--- a/src/plugins/clangpchmanager/clangpchmanager_dependencies.pri
+++ b/src/plugins/clangpchmanager/clangpchmanager_dependencies.pri
@@ -1,7 +1,7 @@
QTC_PLUGIN_NAME = ClangPchManager
QTC_LIB_DEPENDS += \
utils \
- clangbackendipc
+ clangsupport
QTC_PLUGIN_DEPENDS += \
coreplugin \
cpptools
diff --git a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
index 4c536968075..086b2fce8ef 100644
--- a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
+++ b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
@@ -52,7 +52,7 @@ class ClangPchManagerPluginData
public:
PchManagerClient pchManagerClient;
PchManagerConnectionClient connectionClient{&pchManagerClient};
- QtCreatorProjectUpdater projectUpdate{connectionClient.serverProxy(), pchManagerClient};
+ QtCreatorProjectUpdater<PchManagerProjectUpdater> projectUpdate{connectionClient.serverProxy(), pchManagerClient};
};
std::unique_ptr<ClangPchManagerPluginData> ClangPchManagerPlugin::d;
diff --git a/src/plugins/clangpchmanager/pchmanagerclient.cpp b/src/plugins/clangpchmanager/pchmanagerclient.cpp
index d901946fb6f..60c06476534 100644
--- a/src/plugins/clangpchmanager/pchmanagerclient.cpp
+++ b/src/plugins/clangpchmanager/pchmanagerclient.cpp
@@ -43,7 +43,7 @@ void PchManagerClient::alive()
void PchManagerClient::precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message)
{
for (const ClangBackEnd::ProjectPartPch &projectPartPch : message.projectPartPchs())
- precompiledHeaderUpdated(projectPartPch.id(), projectPartPch.path());
+ precompiledHeaderUpdated(QString(projectPartPch.id()), QString(projectPartPch.path()));
}
void PchManagerClient::precompiledHeaderRemoved(const QString &projectPartId)
diff --git a/src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp b/src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp
new file mode 100644
index 00000000000..d74ea2a7b06
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "pchmanagerprojectupdater.h"
+
+#include "pchmanagerclient.h"
+
+namespace ClangPchManager {
+
+PchManagerProjectUpdater::PchManagerProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
+ PchManagerClient &client)
+ : ProjectUpdater(server),
+ m_client(client)
+{
+}
+
+void PchManagerProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
+{
+ ProjectUpdater::removeProjectParts(projectPartIds);
+
+ for (const QString &projectPartiId : projectPartIds)
+ m_client.precompiledHeaderRemoved(projectPartiId);
+}
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/pchmanagerprojectupdater.h b/src/plugins/clangpchmanager/pchmanagerprojectupdater.h
new file mode 100644
index 00000000000..0849554751e
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagerprojectupdater.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "projectupdater.h"
+
+namespace ClangPchManager {
+
+class PchManagerProjectUpdater : public ProjectUpdater
+{
+public:
+ PchManagerProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
+ PchManagerClient &client);
+
+ void removeProjectParts(const QStringList &projectPartIds);
+
+private:
+ PchManagerClient &m_client;
+};
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/projectupdater.cpp b/src/plugins/clangpchmanager/projectupdater.cpp
index 9d5d7c75773..8327f85a221 100644
--- a/src/plugins/clangpchmanager/projectupdater.cpp
+++ b/src/plugins/clangpchmanager/projectupdater.cpp
@@ -52,10 +52,8 @@ public:
Utils::PathStringVector sources;
};
-ProjectUpdater::ProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
- PchManagerClient &client)
- : m_server(server),
- m_client(client)
+ProjectUpdater::ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server)
+ : m_server(server)
{
}
@@ -75,9 +73,6 @@ void ProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
ClangBackEnd::RemovePchProjectPartsMessage message{Utils::SmallStringVector(projectPartIds)};
m_server.removePchProjectParts(std::move(message));
-
- for (const QString &projectPartiId : projectPartIds)
- m_client.precompiledHeaderRemoved(projectPartiId);
}
void ProjectUpdater::setExcludedPaths(Utils::PathStringVector &&excludedPaths)
@@ -113,35 +108,9 @@ HeaderAndSources ProjectUpdater::headerAndSourcesFromProjectPart(
QStringList ProjectUpdater::compilerArguments(CppTools::ProjectPart *projectPart)
{
- using CppTools::ClangCompilerOptionsBuilder;
-
- ClangCompilerOptionsBuilder builder(*projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR);
-
- builder.addWordWidth();
- builder.addTargetTriple();
- builder.addLanguageOption(CppTools::ProjectFile::CXXHeader);
- builder.addOptionsForLanguage(/*checkForBorlandExtensions*/ true);
- builder.enableExceptions();
-
- builder.addDefineToAvoidIncludingGccOrMinGwIntrinsics();
- builder.addDefineFloat128ForMingw();
- builder.addToolchainAndProjectDefines();
- builder.undefineCppLanguageFeatureMacrosForMsvc2015();
-
- builder.addPredefinedMacrosAndHeaderPathsOptions();
- builder.addWrappedQtHeadersIncludePath();
- builder.addPrecompiledHeaderOptions(ClangCompilerOptionsBuilder::PchUsage::None);
- builder.addHeaderPathOptions();
- builder.addProjectConfigFileInclude();
-
- builder.addMsvcCompatibilityVersion();
-
- builder.add("-fmessage-length=0");
- builder.add("-fmacro-backtrace-limit=0");
- builder.add("-w");
- builder.add("-ferror-limit=100000");
-
- return builder.options();
+ using ClangCOBuilder = CppTools::ClangCompilerOptionsBuilder;
+ ClangCOBuilder builder(*projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR);
+ return builder.build(CppTools::ProjectFile::CXXHeader, ClangCOBuilder::PchUsage::None);
}
ClangBackEnd::V2::ProjectPartContainer ProjectUpdater::toProjectPartContainer(
diff --git a/src/plugins/clangpchmanager/projectupdater.h b/src/plugins/clangpchmanager/projectupdater.h
index 5850e0c7e9f..e207a88971f 100644
--- a/src/plugins/clangpchmanager/projectupdater.h
+++ b/src/plugins/clangpchmanager/projectupdater.h
@@ -25,7 +25,7 @@
#pragma once
-#include <clangpchmanager_global.h>
+#include "clangpchmanager_global.h"
#include <filecontainerv2.h>
@@ -35,7 +35,7 @@ class ProjectFile;
}
namespace ClangBackEnd {
-class PchManagerServerInterface;
+class ProjectManagementServerInterface;
namespace V2 {
class ProjectPartContainer;
@@ -51,11 +51,10 @@ namespace ClangPchManager {
class HeaderAndSources;
class PchManagerClient;
-class ProjectUpdater
+class CLANGPCHMANAGER_EXPORT ProjectUpdater
{
public:
- ProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
- PchManagerClient &client);
+ ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server);
void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
ClangBackEnd::V2::FileContainers &&generatedFiles);
@@ -77,8 +76,7 @@ unittest_public:
private:
Utils::PathStringVector m_excludedPaths;
- ClangBackEnd::PchManagerServerInterface &m_server;
- PchManagerClient &m_client;
+ ClangBackEnd::ProjectManagementServerInterface &m_server;
};
} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp b/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
index 6ac93c747a7..53b37ee2b5f 100644
--- a/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
+++ b/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
@@ -26,26 +26,18 @@
#include "qtcreatorprojectupdater.h"
#include <cpptools/abstracteditorsupport.h>
-#include <cpptools/cppmodelmanager.h>
#include <projectexplorer/project.h>
namespace ClangPchManager {
-static CppTools::CppModelManager *cppModelManager()
-{
- return CppTools::CppModelManager::instance();
-}
+namespace Internal {
-QtCreatorProjectUpdater::QtCreatorProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
- PchManagerClient &client)
- : ProjectUpdater(server, client)
+CppTools::CppModelManager *cppModelManager()
{
- connectToCppModelManager();
+ return CppTools::CppModelManager::instance();
}
-namespace {
-
std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles()
{
auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports();
@@ -85,30 +77,7 @@ std::vector<CppTools::ProjectPart*> createProjectParts(ProjectExplorer::Project
convertToRawPointer);
return projectParts;
-}
-
-}
-void QtCreatorProjectUpdater::projectPartsUpdated(ProjectExplorer::Project *project)
-{
- updateProjectParts(createProjectParts(project), createGeneratedFiles());
-}
-
-void QtCreatorProjectUpdater::projectPartsRemoved(const QStringList &projectPartIds)
-{
- removeProjectParts(projectPartIds);
}
-
-void QtCreatorProjectUpdater::connectToCppModelManager()
-{
- connect(cppModelManager(),
- &CppTools::CppModelManager::projectPartsUpdated,
- this,
- &QtCreatorProjectUpdater::projectPartsUpdated);
- connect(cppModelManager(),
- &CppTools::CppModelManager::projectPartsRemoved,
- this,
- &QtCreatorProjectUpdater::projectPartsRemoved);
-}
-
+} // namespace Internal
} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/qtcreatorprojectupdater.h b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
index ec99eab50e5..44858ef9367 100644
--- a/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
+++ b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
@@ -25,7 +25,11 @@
#pragma once
-#include "projectupdater.h"
+#include "pchmanagerprojectupdater.h"
+
+#include <cpptools/cppmodelmanager.h>
+
+#include <filecontainerv2.h>
#include <QObject>
@@ -33,19 +37,57 @@ namespace ProjectExplorer {
class Project;
}
+namespace CppTools {
+class CppModelManager;
+}
+
namespace ClangPchManager {
-class QtCreatorProjectUpdater : public QObject, public ProjectUpdater
+namespace Internal {
+CLANGPCHMANAGER_EXPORT CppTools::CppModelManager *cppModelManager();
+CLANGPCHMANAGER_EXPORT std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles();
+CLANGPCHMANAGER_EXPORT std::vector<CppTools::ProjectPart*> createProjectParts(ProjectExplorer::Project *project);
+}
+
+template <typename ProjectUpdaterType>
+class QtCreatorProjectUpdater : public ProjectUpdaterType
{
public:
- QtCreatorProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
- PchManagerClient &client);
+ template <typename ClientType>
+ QtCreatorProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
+ ClientType &client)
+ : ProjectUpdaterType(server, client)
+ {
+ connectToCppModelManager();
+ }
+
+ QtCreatorProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server)
+ : ProjectUpdaterType(server)
+ {
+ connectToCppModelManager();
+ }
+
+ void projectPartsUpdated(ProjectExplorer::Project *project)
+ {
+ ProjectUpdaterType::updateProjectParts(Internal::createProjectParts(project),
+ Internal::createGeneratedFiles());
+ }
- void projectPartsUpdated(ProjectExplorer::Project *project);
- void projectPartsRemoved(const QStringList &projectPartIds);
+ void projectPartsRemoved(const QStringList &projectPartIds)
+ {
+ ProjectUpdaterType::removeProjectParts(projectPartIds);
+ }
private:
- void connectToCppModelManager();
+ void connectToCppModelManager()
+ {
+ QObject::connect(Internal::cppModelManager(),
+ &CppTools::CppModelManager::projectPartsUpdated,
+ [&] (ProjectExplorer::Project *project) { projectPartsUpdated(project); });
+ QObject::connect(Internal::cppModelManager(),
+ &CppTools::CppModelManager::projectPartsRemoved,
+ [&] (const QStringList &projectPartIds) { projectPartsRemoved(projectPartIds); });
+ }
};
} // namespace ClangPchManager
diff --git a/src/plugins/clangrefactoring/clangqueryhoverhandler.cpp b/src/plugins/clangrefactoring/clangqueryhoverhandler.cpp
index 47ca0dbe791..e8ce90c297c 100644
--- a/src/plugins/clangrefactoring/clangqueryhoverhandler.cpp
+++ b/src/plugins/clangrefactoring/clangqueryhoverhandler.cpp
@@ -52,9 +52,9 @@ void ClangQueryHoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorW
Contexts contexts = m_highligher->contextsForLineAndColumn(uint(line), uint(column));
if (!messages.empty())
- setToolTip(QString("%1: %2").arg(messages[0].errorTypeText()).arg(messages[0].arguments().join(", ")));
+ setToolTip(QString("%1: %2").arg(QString(messages[0].errorTypeText())).arg(QString(messages[0].arguments().join(", "))));
else if (!contexts.empty())
- setToolTip(QString("%1: %2").arg(contexts[0].contextTypeText()).arg(contexts[0].arguments().join(", ")));
+ setToolTip(QString("%1: %2").arg(QString(contexts[0].contextTypeText())).arg(QString(contexts[0].arguments().join(", "))));
}
} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp
index d4e210c04e8..14d8a1620ec 100644
--- a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp
+++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp
@@ -155,31 +155,8 @@ Utils::SmallStringVector ClangQueryProjectsFindFilter::compilerArguments(CppTool
ClangCompilerOptionsBuilder builder(*projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR);
- builder.addWordWidth();
- builder.addTargetTriple();
- builder.addLanguageOption(fileKind);
- builder.addOptionsForLanguage(/*checkForBorlandExtensions*/ true);
- builder.enableExceptions();
-
- builder.addDefineToAvoidIncludingGccOrMinGwIntrinsics();
- builder.addDefineFloat128ForMingw();
- builder.addToolchainAndProjectDefines();
- builder.undefineCppLanguageFeatureMacrosForMsvc2015();
-
- builder.addPredefinedMacrosAndHeaderPathsOptions();
- builder.addWrappedQtHeadersIncludePath();
- builder.addPrecompiledHeaderOptions(ClangCompilerOptionsBuilder::PchUsage::None);
- builder.addHeaderPathOptions();
- builder.addProjectConfigFileInclude();
-
- builder.addMsvcCompatibilityVersion();
-
- builder.add("-fmessage-length=0");
- builder.add("-fmacro-backtrace-limit=0");
- builder.add("-w");
- builder.add("-ferror-limit=1000000");
-
- return Utils::SmallStringVector(builder.options());
+ return Utils::SmallStringVector(builder.build(fileKind,
+ ClangCompilerOptionsBuilder::PchUsage::None));
}
QWidget *ClangQueryProjectsFindFilter::widget() const
diff --git a/src/plugins/clangrefactoring/clangrefactoring-source.pri b/src/plugins/clangrefactoring/clangrefactoring-source.pri
index 24102dfd99d..b08d292190c 100644
--- a/src/plugins/clangrefactoring/clangrefactoring-source.pri
+++ b/src/plugins/clangrefactoring/clangrefactoring-source.pri
@@ -11,7 +11,8 @@ HEADERS += \
$$PWD/clangqueryexamplehighlightmarker.h \
$$PWD/clangqueryhighlightmarker.h \
$$PWD/clangqueryexamplehighlighter.h \
- $$PWD/clangqueryhighlighter.h
+ $$PWD/clangqueryhighlighter.h \
+ $$PWD/refactoringprojectupdater.h
SOURCES += \
$$PWD/refactoringengine.cpp \
@@ -22,4 +23,5 @@ SOURCES += \
$$PWD/projectpartutilities.cpp \
$$PWD/clangqueryprojectsfindfilter.cpp \
$$PWD/clangqueryexamplehighlighter.cpp \
- $$PWD/clangqueryhighlighter.cpp
+ $$PWD/clangqueryhighlighter.cpp \
+ $$PWD/refactoringprojectupdater.cpp
diff --git a/src/plugins/clangrefactoring/clangrefactoring.pro b/src/plugins/clangrefactoring/clangrefactoring.pro
index 918398bef0f..d60de99636b 100644
--- a/src/plugins/clangrefactoring/clangrefactoring.pro
+++ b/src/plugins/clangrefactoring/clangrefactoring.pro
@@ -15,7 +15,10 @@ HEADERS += \
clangqueryexampletexteditorwidget.h \
clangquerytexteditorwidget.h \
baseclangquerytexteditorwidget.h \
- clangqueryhoverhandler.h
+ clangqueryhoverhandler.h \
+ symbolquery.h \
+ querysqlitestatementfactory.h \
+ sourcelocations.h
SOURCES += \
clangrefactoringplugin.cpp \
@@ -26,7 +29,8 @@ SOURCES += \
clangqueryexampletexteditorwidget.cpp \
clangquerytexteditorwidget.cpp \
baseclangquerytexteditorwidget.cpp \
- clangqueryhoverhandler.cpp
+ clangqueryhoverhandler.cpp \
+ symbolquery.cpp
FORMS += \
clangqueryprojectsfindfilter.ui
diff --git a/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri b/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
index 15005bd6893..8a082361770 100644
--- a/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
+++ b/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
@@ -1,8 +1,9 @@
QTC_PLUGIN_NAME = ClangRefactoring
QTC_LIB_DEPENDS += \
utils \
- clangbackendipc
+ clangsupport
QTC_PLUGIN_DEPENDS += \
coreplugin \
cpptools \
- texteditor
+ texteditor \
+ clangpchmanager
diff --git a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
index 921cc240053..a2638212d65 100644
--- a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
+++ b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
@@ -25,6 +25,8 @@
#include "clangrefactoringplugin.h"
+#include <clangpchmanager/qtcreatorprojectupdater.h>
+
#include <cpptools/cppmodelmanager.h>
#include <coreplugin/icore.h>
@@ -50,6 +52,7 @@ std::unique_ptr<ClangRefactoringPluginData> ClangRefactoringPlugin::d;
class ClangRefactoringPluginData
{
+ using ProjectUpdater = ClangPchManager::QtCreatorProjectUpdater<ClangPchManager::ProjectUpdater>;
public:
RefactoringClient refactoringClient;
ClangBackEnd::RefactoringConnectionClient connectionClient{&refactoringClient};
@@ -58,6 +61,9 @@ public:
QtCreatorClangQueryFindFilter qtCreatorfindFilter{connectionClient.serverProxy(),
qtCreatorSearch,
refactoringClient};
+ ProjectUpdater projectUpdate{connectionClient.serverProxy()};
+
+
};
ClangRefactoringPlugin::ClangRefactoringPlugin()
@@ -90,6 +96,7 @@ void ClangRefactoringPlugin::extensionsInitialized()
ExtensionSystem::IPlugin::ShutdownFlag ClangRefactoringPlugin::aboutToShutdown()
{
ExtensionSystem::PluginManager::removeObject(&d->qtCreatorfindFilter);
+ CppTools::CppModelManager::setRefactoringEngine(nullptr);
d->refactoringClient.setRefactoringConnectionClient(nullptr);
d->refactoringClient.setRefactoringEngine(nullptr);
diff --git a/src/plugins/clangrefactoring/querysqlitestatementfactory.h b/src/plugins/clangrefactoring/querysqlitestatementfactory.h
new file mode 100644
index 00000000000..dec404f89b0
--- /dev/null
+++ b/src/plugins/clangrefactoring/querysqlitestatementfactory.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+namespace ClangRefactoring {
+
+template<typename Database,
+ typename ReadStatement>
+class QuerySqliteStatementFactory
+{
+public:
+ using DatabaseType = Database;
+ using ReadStatementType = ReadStatement;
+
+ QuerySqliteStatementFactory(Database &database)
+ : database(database)
+ {}
+ Database &database;
+ ReadStatement selectLocationsForSymbolLocation{
+ "SELECT sourceId, line, column FROM locations WHERE symbolId = "
+ " (SELECT symbolId FROM locations WHERE sourceId="
+ " (SELECT sourceId FROM sources WHERE sourcePath =?)"
+ " AND line=? AND column=?) "
+ "ORDER BY sourceId, line, column",
+ database}; // alternatively SELECT l2.symbolid, l2.sourceId, l2.line, l2.column FROM locations AS l2, sources, locations AS l1 ON sources.sourceId = l1.sourceId AND l2.symbolId=l1.symbolId WHERE sourcePath = ? AND l1.line=? AND l1.column=? ORDER BY l2.sourceId, l2.line, l2.column
+ ReadStatement selectSourcePathForId{
+ "SELECT sourceId, sourcePath FROM sources WHERE sourceId = ?",
+ database};
+};
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/refactoringclient.cpp b/src/plugins/clangrefactoring/refactoringclient.cpp
index e4904b53cc8..189e2bd4806 100644
--- a/src/plugins/clangrefactoring/refactoringclient.cpp
+++ b/src/plugins/clangrefactoring/refactoringclient.cpp
@@ -154,7 +154,7 @@ void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextC
std::unordered_map<uint, QString> &filePaths)
{
m_searchHandle->addResult(filePaths[sourceRangeWithText.fileHash()],
- sourceRangeWithText.text(),
+ QString(sourceRangeWithText.text()),
{{int(sourceRangeWithText.start().line()),
int(sourceRangeWithText.start().column() - 1),
int(sourceRangeWithText.start().offset())},
diff --git a/src/plugins/clangrefactoring/refactoringengine.cpp b/src/plugins/clangrefactoring/refactoringengine.cpp
index e0d61ae9084..696e38c468c 100644
--- a/src/plugins/clangrefactoring/refactoringengine.cpp
+++ b/src/plugins/clangrefactoring/refactoringengine.cpp
@@ -34,6 +34,8 @@
#include <cpptools/clangcompileroptionsbuilder.h>
#include <cpptools/cpptoolsreuse.h>
+#include <texteditor/textdocument.h>
+
#include <QTextCursor>
#include <QTextDocument>
@@ -50,9 +52,7 @@ RefactoringEngine::RefactoringEngine(ClangBackEnd::RefactoringServerInterface &s
{
}
-void RefactoringEngine::startLocalRenaming(const QTextCursor &textCursor,
- const Utils::FileName &filePath,
- int revision,
+void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data,
CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback)
{
@@ -62,26 +62,31 @@ void RefactoringEngine::startLocalRenaming(const QTextCursor &textCursor,
client.setLocalRenamingCallback(std::move(renameSymbolsCallback));
- Utils::SmallStringVector commandLine{ClangCompilerOptionsBuilder::build(
- projectPart,
- fileKindInProjectPart(projectPart, filePath.toString()),
- CppTools::getPchUsage(),
- CLANG_VERSION,
- CLANG_RESOURCE_DIR)};
+ QString filePath = data.filePath().toString();
+ QTextCursor textCursor = data.cursor();
+ ClangCompilerOptionsBuilder clangCOBuilder{*projectPart, CLANG_VERSION, CLANG_RESOURCE_DIR};
+ Utils::SmallStringVector commandLine{clangCOBuilder.build(
+ fileKindInProjectPart(projectPart, filePath),
+ CppTools::getPchUsage())};
- commandLine.push_back(filePath.toString());
+ commandLine.push_back(filePath);
- RequestSourceLocationsForRenamingMessage message(ClangBackEnd::FilePath(filePath.toString()),
+ RequestSourceLocationsForRenamingMessage message(ClangBackEnd::FilePath(filePath),
uint(textCursor.blockNumber() + 1),
uint(textCursor.positionInBlock() + 1),
textCursor.document()->toPlainText(),
std::move(commandLine),
- revision);
+ textCursor.document()->revision());
server.requestSourceLocationsForRenamingMessage(std::move(message));
}
+void RefactoringEngine::startGlobalRenaming(const CppTools::CursorInEditor &)
+{
+ // TODO: implement
+}
+
bool RefactoringEngine::isUsable() const
{
return server.isUsable();
diff --git a/src/plugins/clangrefactoring/refactoringengine.h b/src/plugins/clangrefactoring/refactoringengine.h
index 453c52775cb..83e67bfe27a 100644
--- a/src/plugins/clangrefactoring/refactoringengine.h
+++ b/src/plugins/clangrefactoring/refactoringengine.h
@@ -39,11 +39,10 @@ class RefactoringEngine : public CppTools::RefactoringEngineInterface
public:
RefactoringEngine(ClangBackEnd::RefactoringServerInterface &server,
ClangBackEnd::RefactoringClientInterface &client);
- void startLocalRenaming(const QTextCursor &textCursor,
- const Utils::FileName &filePath,
- int revision,
+ void startLocalRenaming(const CppTools::CursorInEditor &data,
CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) override;
+ void startGlobalRenaming(const CppTools::CursorInEditor &data) override;
bool isUsable() const override;
void setUsable(bool isUsable);
diff --git a/src/plugins/clangrefactoring/refactoringprojectupdater.cpp b/src/plugins/clangrefactoring/refactoringprojectupdater.cpp
new file mode 100644
index 00000000000..07a9e97163f
--- /dev/null
+++ b/src/plugins/clangrefactoring/refactoringprojectupdater.cpp
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "refactoringprojectupdater.h"
+
+namespace ClangRefactoring {
+
+RefactoringProjectUpdater::RefactoringProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
+ RefactoringClient &)
+ : ClangPchManager::ProjectUpdater(server)
+{
+
+}
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/refactoringprojectupdater.h b/src/plugins/clangrefactoring/refactoringprojectupdater.h
new file mode 100644
index 00000000000..3debed0c4dc
--- /dev/null
+++ b/src/plugins/clangrefactoring/refactoringprojectupdater.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <clangpchmanager/projectupdater.h>
+
+namespace ClangRefactoring {
+
+class RefactoringClient;
+
+class RefactoringProjectUpdater : public ClangPchManager::ProjectUpdater
+{
+public:
+ RefactoringProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
+ RefactoringClient &client);
+};
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/sourcelocations.h b/src/plugins/clangrefactoring/sourcelocations.h
new file mode 100644
index 00000000000..9ae4241c01a
--- /dev/null
+++ b/src/plugins/clangrefactoring/sourcelocations.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <utils/smallstring.h>
+
+#include <cstdint>
+#include <vector>
+#include <tuple>
+#include <unordered_map>
+
+namespace ClangRefactoring {
+
+class SourceLocations
+{
+public:
+ struct Location
+ {
+ Location(qint64 sourceId, qint64 line, qint64 column)
+ : sourceId(sourceId), line(line), column(column)
+ {}
+
+ qint64 sourceId;
+ qint64 line;
+ qint64 column;
+ };
+
+ struct Source
+ {
+ Source(qint64 sourceId, Utils::PathString &&sourcePath)
+ : sourceId(sourceId), sourcePath(std::move(sourcePath))
+ {}
+
+ qint64 sourceId;
+ Utils::PathString sourcePath;
+ };
+
+ std::vector<Location> locations;
+ std::unordered_map<qint64, Utils::PathString> sources;
+};
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/symbolquery.cpp b/src/plugins/clangrefactoring/symbolquery.cpp
new file mode 100644
index 00000000000..a5f946266f6
--- /dev/null
+++ b/src/plugins/clangrefactoring/symbolquery.cpp
@@ -0,0 +1,30 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "symbolquery.h"
+
+namespace ClangRefactoring {
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/symbolquery.h b/src/plugins/clangrefactoring/symbolquery.h
new file mode 100644
index 00000000000..19faf972294
--- /dev/null
+++ b/src/plugins/clangrefactoring/symbolquery.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <utils/smallstring.h>
+
+#include <sourcelocations.h>
+
+#include <algorithm>
+
+namespace ClangRefactoring {
+
+template <typename StatementFactory>
+class SymbolQuery
+{
+ using ReadStatement = typename StatementFactory::ReadStatementType;
+
+public:
+ using Location = SourceLocations::Location;
+ using Source = SourceLocations::Source;
+
+ SymbolQuery(StatementFactory &statementFactory)
+ : m_statementFactory(statementFactory)
+ {}
+
+ SourceLocations locationsAt(const Utils::PathString &filePath, uint line, uint utf8Column)
+ {
+ ReadStatement &locationsStatement = m_statementFactory.selectLocationsForSymbolLocation;
+
+ const std::size_t reserveSize = 128;
+
+ auto locations = locationsStatement.template values<Location, 3>(
+ reserveSize,
+ filePath,
+ line,
+ utf8Column);
+
+ const std::vector<qint64> sourceIds = uniqueSourceIds(locations);
+
+ ReadStatement &sourcesStatement = m_statementFactory.selectSourcePathForId;
+
+ auto sources = sourcesStatement.template values<Source, 2>(
+ reserveSize,
+ sourceIds);
+
+ return {locations, sourcesToHashMap(sources)};
+ }
+
+ static
+ qint64 sourceId(const Location &location)
+ {
+ return location.sourceId;
+ }
+
+ static
+ std::vector<qint64> uniqueSourceIds(const std::vector<Location> &locations)
+ {
+ std::vector<qint64> ids;
+ ids.reserve(locations.size());
+
+ std::transform(locations.begin(),
+ locations.end(),
+ std::back_inserter(ids),
+ sourceId);
+
+ auto newEnd = std::unique(ids.begin(), ids.end());
+ ids.erase(newEnd, ids.end());
+
+ return ids;
+ }
+
+ static
+ std::unordered_map<qint64, Utils::PathString> sourcesToHashMap(const std::vector<Source> &sources)
+ {
+ std::unordered_map<qint64, Utils::PathString> dictonary;
+
+ for (const Source &source : sources)
+ dictonary.emplace(source.sourceId, std::move(source.sourcePath));
+
+ return dictonary;
+ }
+
+private:
+ StatementFactory &m_statementFactory;
+};
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerpreconfiguredsessiontests.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerpreconfiguredsessiontests.cpp
index 0cb7c976ee1..c9ff00558db 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerpreconfiguredsessiontests.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerpreconfiguredsessiontests.cpp
@@ -167,7 +167,7 @@ static QList<Target *> validTargets(Project *project)
const ToolChain * const toolchain = ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID);
QTC_ASSERT(toolchain, return false);
bool hasClangExecutable;
- clangExecutableFromSettings(toolchain->typeId(), &hasClangExecutable);
+ clangExecutableFromSettings(&hasClangExecutable);
if (!hasClangExecutable) {
qWarning("Project \"%s\": Skipping target \"%s\" since no suitable clang was found for the toolchain.",
qPrintable(projectFileName),
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
index ad6363bc0e6..94468e913e4 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
@@ -38,7 +38,7 @@
#include <coreplugin/progressmanager/futureprogress.h>
#include <coreplugin/progressmanager/progressmanager.h>
-#include <cpptools/compileroptionsbuilder.h>
+#include <cpptools/clangcompileroptionsbuilder.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cppprojectfile.h>
#include <cpptools/cpptoolsreuse.h>
@@ -161,8 +161,7 @@ static void prependTargetTripleIfNotIncludedAndNotEmpty(QStringList *arguments,
}
// Removes (1) inputFile (2) -o <somePath>.
-QStringList inputAndOutputArgumentsRemoved(const QString &inputFile, const QStringList &arguments,
- bool isMsvc)
+QStringList inputAndOutputArgumentsRemoved(const QString &inputFile, const QStringList &arguments)
{
QStringList newArguments;
@@ -174,9 +173,6 @@ QStringList inputAndOutputArgumentsRemoved(const QString &inputFile, const QStri
} else if (argument == QLatin1String("-o")) {
skip = true;
continue;
- } else if (isMsvc && argument == QLatin1String("-target")) {
- skip = true;
- continue;
} else if (QDir::fromNativeSeparators(argument) == inputFile) {
continue; // TODO: Let it in?
}
@@ -188,55 +184,11 @@ QStringList inputAndOutputArgumentsRemoved(const QString &inputFile, const QStri
return newArguments;
}
-static QString createLanguageOptionMsvc(ProjectFile::Kind fileKind)
-{
- switch (fileKind) {
- case ProjectFile::CHeader:
- case ProjectFile::CSource:
- return QLatin1String("/TC");
- break;
- case ProjectFile::CXXHeader:
- case ProjectFile::CXXSource:
- return QLatin1String("/TP");
- break;
- default:
- break;
- }
- return QString();
-}
-
-class ClangStaticAnalyzerOptionsBuilder : public CompilerOptionsBuilder
+class ClangStaticAnalyzerOptionsBuilder final : public ClangCompilerOptionsBuilder
{
public:
- static QStringList build(const CppTools::ProjectPart &projectPart,
- CppTools::ProjectFile::Kind fileKind,
- PchUsage pchUsage)
- {
- ClangStaticAnalyzerOptionsBuilder optionsBuilder(projectPart);
-
- optionsBuilder.addWordWidth();
- optionsBuilder.addTargetTriple();
- optionsBuilder.addLanguageOption(fileKind);
- optionsBuilder.addOptionsForLanguage(false);
- optionsBuilder.enableExceptions();
-
- optionsBuilder.addDefineFloat128ForMingw();
- optionsBuilder.addDefineToAvoidIncludingGccOrMinGwIntrinsics();
- const Core::Id type = projectPart.toolchainType;
- if (type != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
- optionsBuilder.addDefines(projectPart.toolchainDefines);
- optionsBuilder.addDefines(projectPart.projectDefines);
- optionsBuilder.undefineClangVersionMacrosForMsvc();
- optionsBuilder.undefineCppLanguageFeatureMacrosForMsvc2015();
- optionsBuilder.addHeaderPathOptions();
- optionsBuilder.addPrecompiledHeaderOptions(pchUsage);
- optionsBuilder.addMsvcCompatibilityVersion();
-
- return optionsBuilder.options();
- }
-
ClangStaticAnalyzerOptionsBuilder(const CppTools::ProjectPart &projectPart)
- : CompilerOptionsBuilder(projectPart)
+ : ClangCompilerOptionsBuilder(projectPart)
, m_isMsvcToolchain(m_projectPart.toolchainType
== ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
, m_isMinGWToolchain(m_projectPart.toolchainType
@@ -244,91 +196,28 @@ public:
{
}
-public:
- bool excludeHeaderPath(const QString &headerPath) const override
+ bool excludeHeaderPath(const QString &headerPath) const final
{
- if (CompilerOptionsBuilder::excludeHeaderPath(headerPath))
- return true;
if (m_isMinGWToolchain && headerPath.contains(m_projectPart.toolChainTargetTriple))
return true;
- return false;
+ return ClangCompilerOptionsBuilder::excludeHeaderPath(headerPath);
}
- void undefineClangVersionMacrosForMsvc()
+ void addPredefinedHeaderPathsOptions() final
{
- if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
- static QStringList macroNames {
- "__clang__",
- "__clang_major__",
- "__clang_minor__",
- "__clang_patchlevel__",
- "__clang_version__"
- };
-
- foreach (const QString &macroName, macroNames)
- add(QLatin1String("/U") + macroName);
+ add("-undef");
+ if (m_isMsvcToolchain) {
+ // exclude default clang path to use msvc includes
+ add("-nostdinc");
+ add("-nostdlibinc");
}
}
-private:
- void addTargetTriple() override
- {
- // For MSVC toolchains we use clang-cl.exe, so there is nothing to do here since
- // 1) clang-cl.exe does not understand the "-triple" option
- // 2) clang-cl.exe already hardcodes the right triple value (even if built with mingw)
- if (!m_isMsvcToolchain)
- CompilerOptionsBuilder::addTargetTriple();
- }
-
- void addLanguageOption(ProjectFile::Kind fileKind) override
- {
- if (m_isMsvcToolchain)
- add(createLanguageOptionMsvc(fileKind));
- else
- CompilerOptionsBuilder::addLanguageOption(fileKind);
- }
-
- void addOptionsForLanguage(bool checkForBorlandExtensions) override
- {
- if (m_isMsvcToolchain)
- return;
- CompilerOptionsBuilder::addOptionsForLanguage(checkForBorlandExtensions);
- }
-
- QString includeOption() const override
- {
- if (m_isMsvcToolchain)
- return QLatin1String("/FI");
- return CompilerOptionsBuilder::includeOption();
- }
+ void addExtraOptions() final {}
- QString includeDirOption() const override
+ void addWrappedQtHeadersIncludePath() final
{
- if (m_isMsvcToolchain)
- return QLatin1String("/I");
- return CompilerOptionsBuilder::includeDirOption();
- }
-
- QString defineOption() const override
- {
- if (m_isMsvcToolchain)
- return QLatin1String("/D");
- return CompilerOptionsBuilder::defineOption();
- }
-
- QString undefineOption() const override
- {
- if (m_isMsvcToolchain)
- return QLatin1String("/U");
- return CompilerOptionsBuilder::undefineOption();
- }
-
- void enableExceptions() override
- {
- if (m_isMsvcToolchain)
- add(QLatin1String("/EHsc"));
- else
- CompilerOptionsBuilder::enableExceptions();
+ // Empty, analyzer doesn't need them
}
private:
@@ -383,7 +272,7 @@ static QStringList tweakedArguments(const ProjectPart &projectPart,
{
const bool isMsvc = projectPart.toolchainType
== ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID;
- QStringList newArguments = inputAndOutputArgumentsRemoved(filePath, arguments, isMsvc);
+ QStringList newArguments = inputAndOutputArgumentsRemoved(filePath, arguments);
prependWordWidthArgumentIfNotIncluded(&newArguments, projectPart.toolChainWordWidth);
if (!isMsvc)
prependTargetTripleIfNotIncludedAndNotEmpty(&newArguments, targetTriple);
@@ -434,7 +323,7 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Pt
AnalyzeUnits unitsToAnalyze;
foreach (const ProjectPart::Ptr &projectPart, projectParts) {
- if (!projectPart->selectedForBuilding)
+ if (!projectPart->selectedForBuilding || !projectPart.data())
continue;
foreach (const ProjectFile &file, projectPart->files) {
@@ -445,7 +334,7 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Pt
if (ProjectFile::isSource(file.kind)) {
const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage();
const QStringList arguments
- = ClangStaticAnalyzerOptionsBuilder::build(*projectPart.data(), file.kind, pchUsage);
+ = ClangStaticAnalyzerOptionsBuilder(*projectPart).build(file.kind, pchUsage);
unitsToAnalyze << AnalyzeUnit(file.path, arguments);
}
}
@@ -501,21 +390,6 @@ static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits)
return debug;
}
-static QString executableForVersionCheck(Core::Id toolchainType, const QString &executable)
-{
- if (toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
- const QString suffix = QLatin1String("-cl.exe");
- if (executable.endsWith(suffix, Utils::HostOsInfo::fileNameCaseSensitivity())) {
- QString modified = executable;
- modified.chop(suffix.length());
- modified.append(QLatin1String(".exe"));
- return modified;
- }
- }
-
- return executable;
-}
-
void ClangStaticAnalyzerToolRunner::start()
{
m_success = false;
@@ -532,8 +406,7 @@ void ClangStaticAnalyzerToolRunner::start()
// Check clang executable
bool isValidClangExecutable;
- const QString executable = clangExecutableFromSettings(m_toolChainType,
- &isValidClangExecutable);
+ const QString executable = clangExecutableFromSettings(&isValidClangExecutable);
if (!isValidClangExecutable) {
const QString errorMessage = tr("Clang Static Analyzer: Invalid executable \"%1\", stop.")
.arg(executable);
@@ -545,13 +418,12 @@ void ClangStaticAnalyzerToolRunner::start()
}
// Check clang version
- const QString versionCheckExecutable = executableForVersionCheck(m_toolChainType, executable);
- const ClangExecutableVersion version = clangExecutableVersion(versionCheckExecutable);
+ const ClangExecutableVersion version = clangExecutableVersion(executable);
if (!version.isValid()) {
const QString warningMessage
= tr("Clang Static Analyzer: Running with possibly unsupported version, "
"could not determine version from executable \"%1\".")
- .arg(versionCheckExecutable);
+ .arg(executable);
appendMessage(warningMessage, Utils::StdErrFormat);
TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup();
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
index 461f31049b4..9e90a024676 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
@@ -71,9 +71,11 @@ class DummyRunConfiguration : public RunConfiguration
public:
DummyRunConfiguration(Target *parent)
- : RunConfiguration(parent, "ClangStaticAnalyzer.DummyRunConfig")
+ : RunConfiguration(parent)
{
+ initialize("ClangStaticAnalyzer.DummyRunConfig");
setDefaultDisplayName(tr("Clang Static Analyzer"));
+ setEnabled(true);
}
private:
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp
index 2ab8c18d9ba..f589a978b39 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp
@@ -58,7 +58,7 @@ void ClangStaticAnalyzerUnitTests::initTestCase()
if (!toolchain)
QSKIP("This test requires that there is a kit with a toolchain.");
bool hasClangExecutable;
- clangExecutableFromSettings(toolchain->typeId(), &hasClangExecutable);
+ clangExecutableFromSettings(&hasClangExecutable);
if (!hasClangExecutable)
QSKIP("No clang suitable for analyzing found");
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp
index a1a1bee67a4..7a433aac49f 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp
@@ -50,7 +50,7 @@ static bool isFileExecutable(const QString &executablePath)
namespace ClangStaticAnalyzer {
namespace Internal {
-QString clangExecutableFromSettings(Core::Id toolchainType, bool *isValid)
+QString clangExecutableFromSettings(bool *isValid)
{
QString executable = ClangStaticAnalyzerSettings::instance()->clangExecutable();
if (executable.isEmpty()) {
@@ -62,14 +62,6 @@ QString clangExecutableFromSettings(Core::Id toolchainType, bool *isValid)
const Qt::CaseSensitivity caseSensitivity = Utils::HostOsInfo::fileNameCaseSensitivity();
const bool hasSuffix = executable.endsWith(hostExeSuffix, caseSensitivity);
- if (toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
- if (hasSuffix)
- executable.chop(hostExeSuffix.length());
- executable.append(QLatin1String("-cl"));
- if (hasSuffix)
- executable.append(hostExeSuffix);
- }
-
const QFileInfo fileInfo = QFileInfo(executable);
if (fileInfo.isAbsolute()) {
if (!hasSuffix)
@@ -126,7 +118,9 @@ ClangExecutableVersion clangExecutableVersion(const QString &executable)
Utils::SynchronousProcess runner;
runner.setEnvironment(environment.toStringList());
runner.setTimeoutS(10);
- // We would prefer "-dumpversion", but that one returns some old version number.
+ // We would prefer "-dumpversion", but that one is only there for GCC compatibility
+ // and returns some static/old version.
+ // See also https://bugs.llvm.org/show_bug.cgi?id=28597
const QStringList arguments(QLatin1String(("--version")));
const Utils::SynchronousProcessResponse response = runner.runBlocking(executable, arguments);
if (response.result != Utils::SynchronousProcessResponse::Finished)
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h
index e170d8b7f01..c18317237c6 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h
@@ -41,7 +41,7 @@ namespace Internal {
bool isClangExecutableUsable(const QString &filePath, QString *errorMessage = 0);
-QString clangExecutableFromSettings(Core::Id toolchainType, bool *isValid);
+QString clangExecutableFromSettings(bool *isValid);
QString createFullLocationString(const Debugger::DiagnosticLocation &location);
diff --git a/src/plugins/clearcase/clearcaseplugin.cpp b/src/plugins/clearcase/clearcaseplugin.cpp
index f4ba55d0930..9eea4a6cfb0 100644
--- a/src/plugins/clearcase/clearcaseplugin.cpp
+++ b/src/plugins/clearcase/clearcaseplugin.cpp
@@ -410,7 +410,7 @@ bool ClearCasePlugin::initialize(const QStringList & /*arguments */, QString *er
Context context(CLEARCASE_CONTEXT);
- initializeVcs(new ClearCaseControl(this), context);
+ initializeVcs<ClearCaseControl>(context, this);
m_clearcasePluginInstance = this;
connect(ICore::instance(), &ICore::coreAboutToClose, this, &ClearCasePlugin::closing);
@@ -837,6 +837,11 @@ void ClearCasePlugin::updateActions(VcsBasePlugin::ActionState as)
updateStatusActions();
}
+QString ClearCasePlugin::commitDisplayName() const
+{
+ return tr("check in", "\"commit\" action for ClearCase.");
+}
+
void ClearCasePlugin::checkOutCurrentFile()
{
const VcsBasePluginState state = currentState();
@@ -1206,6 +1211,9 @@ void ClearCasePlugin::startCheckInActivity()
* check in will start. */
void ClearCasePlugin::startCheckIn(const QString &workingDir, const QStringList &files)
{
+ if (!promptBeforeCommit())
+ return;
+
if (raiseSubmitEditor())
return;
@@ -1660,10 +1668,12 @@ bool ClearCasePlugin::vcsCheckIn(const QString &messageFile, const QStringList &
replaceActivity &= (activity != QLatin1String(Constants::KEEP_ACTIVITY));
if (replaceActivity && !vcsSetActivity(m_checkInView, title, activity))
return false;
+ QString message;
QFile msgFile(messageFile);
- msgFile.open(QFile::ReadOnly | QFile::Text);
- QString message = QString::fromLocal8Bit(msgFile.readAll().trimmed().constData());
- msgFile.close();
+ if (msgFile.open(QFile::ReadOnly | QFile::Text)) {
+ message = QString::fromLocal8Bit(msgFile.readAll().trimmed());
+ msgFile.close();
+ }
QStringList args;
args << QLatin1String("checkin");
if (message.isEmpty())
@@ -2315,7 +2325,7 @@ public:
m_editor(0)
{
ClearCasePlugin::instance()->setFakeCleartool(true);
- VcsManager::instance()->clearVersionControlCache();
+ VcsManager::clearVersionControlCache();
FileSaver srcSaver(fileName);
srcSaver.write(QByteArray());
diff --git a/src/plugins/clearcase/clearcaseplugin.h b/src/plugins/clearcase/clearcaseplugin.h
index d2db83a8ac8..70c18334263 100644
--- a/src/plugins/clearcase/clearcaseplugin.h
+++ b/src/plugins/clearcase/clearcaseplugin.h
@@ -199,6 +199,7 @@ private:
void syncSlot();
Q_INVOKABLE void updateStatusActions();
+ QString commitDisplayName() const final;
void checkOutCurrentFile();
void addCurrentFile();
void undoCheckOutCurrent();
diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
index 86d9e0945f6..67ae9387af0 100644
--- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
@@ -44,6 +44,7 @@
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
+#include <QDir>
#include <QMessageBox>
#include <QPushButton>
#include <QSet>
@@ -72,12 +73,22 @@ BuildDirManager::~BuildDirManager() = default;
const Utils::FileName BuildDirManager::workDirectory() const
{
const Utils::FileName bdir = m_buildConfiguration->buildDirectory();
- if (bdir.exists())
+ const CMakeTool *cmake = CMakeKitInformation::cmakeTool(m_buildConfiguration->target()->kit());
+ if (bdir.exists()) {
return bdir;
+ } else {
+ if (cmake && cmake->autoCreateBuildDirectory()) {
+ if (!QDir().mkpath(bdir.toString()))
+ emitErrorOccured(tr("Failed to create build directory \"%1\".").arg(bdir.toUserOutput()));
+ return bdir;
+ }
+ }
if (!m_tempDir) {
m_tempDir.reset(new Utils::TemporaryDirectory("qtc-cmake-XXXXXXXX"));
- if (!m_tempDir->isValid())
- emitErrorOccured(tr("Failed to create temporary directory \"%1\".").arg(m_tempDir->path()));
+ if (!m_tempDir->isValid()) {
+ emitErrorOccured(tr("Failed to create temporary directory \"%1\".")
+ .arg(QDir::toNativeSeparators(m_tempDir->path())));
+ }
}
return Utils::FileName::fromString(m_tempDir->path());
}
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
index ef828919faa..59bdaf1168b 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
@@ -144,17 +144,18 @@ void CMakeBuildConfiguration::ctor()
connect(m_buildDirManager.get(), &BuildDirManager::dataAvailable,
this, [this, project]() {
- project->updateProjectData(this);
clearError();
- emit dataAvailable();
+ project->updateProjectData(this);
});
connect(m_buildDirManager.get(), &BuildDirManager::errorOccured,
- this, &CMakeBuildConfiguration::setError);
+ this, [this, project](const QString &msg) {
+ setError(msg);
+ project->handleParsingError(this);
+ });
connect(m_buildDirManager.get(), &BuildDirManager::configurationStarted,
this, [this, project]() {
- project->handleParsingStarted();
+ project->handleParsingStarted(this);
clearError(ForceEnabledChanged::True);
- emit parsingStarted();
});
connect(this, &CMakeBuildConfiguration::environmentChanged,
@@ -276,7 +277,7 @@ QList<ConfigModel::DataItem> CMakeBuildConfiguration::completeCMakeConfiguration
return QList<ConfigModel::DataItem>();
return Utils::transform(m_buildDirManager->parsedConfiguration(),
- [this](const CMakeConfigItem &i) {
+ [](const CMakeConfigItem &i) {
ConfigModel::DataItem j;
j.key = QString::fromUtf8(i.key);
j.value = QString::fromUtf8(i.value);
@@ -408,7 +409,7 @@ CMakeConfig CMakeBuildConfiguration::cmakeConfiguration() const
void CMakeBuildConfiguration::setError(const QString &message)
{
- QString oldMessage = m_error;
+ const QString oldMessage = m_error;
if (m_error != message)
m_error = message;
if (oldMessage.isEmpty() && !message.isEmpty())
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
index 1796108574f..5cc58bbdcb4 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
@@ -100,9 +100,6 @@ signals:
void errorOccured(const QString &message);
void warningOccured(const QString &message);
- void parsingStarted();
- void dataAvailable();
-
protected:
CMakeBuildConfiguration(ProjectExplorer::Target *parent, CMakeBuildConfiguration *source);
bool fromMap(const QVariantMap &map) override;
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
index fe85283ad2a..8985a0799e3 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
@@ -34,9 +34,11 @@
#include <coreplugin/icore.h>
#include <coreplugin/find/itemviewfind.h>
#include <projectexplorer/kitmanager.h>
+#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/target.h>
+#include <utils/asconst.h>
#include <utils/detailswidget.h>
#include <utils/fancylineedit.h>
#include <utils/headerviewstretcher.h>
@@ -46,12 +48,14 @@
#include <QBoxLayout>
#include <QCheckBox>
+#include <QComboBox>
#include <QFrame>
#include <QGridLayout>
#include <QLabel>
#include <QPushButton>
#include <QSortFilterProxyModel>
#include <QSpacerItem>
+#include <QStyledItemDelegate>
#include <QMenu>
namespace CMakeProjectManager {
@@ -139,26 +143,34 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
connect(tree, &Utils::TreeView::activated,
tree, [tree](const QModelIndex &idx) { tree->edit(idx); });
m_configView = tree;
+
+ m_configView->viewport()->installEventFilter(this);
+
m_configFilterModel->setSourceModel(m_configModel);
- m_configFilterModel->setFilterKeyColumn(2);
- m_configFilterModel->setFilterFixedString(QLatin1String("0"));
+ m_configFilterModel->setFilterKeyColumn(0);
+ m_configFilterModel->setFilterRole(ConfigModel::ItemIsAdvancedRole);
+ m_configFilterModel->setFilterFixedString("0");
+
m_configTextFilterModel->setSourceModel(m_configFilterModel);
+ m_configTextFilterModel->setSortRole(Qt::DisplayRole);
m_configTextFilterModel->setFilterKeyColumn(-1);
m_configTextFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+
m_configView->setModel(m_configTextFilterModel);
m_configView->setMinimumHeight(300);
- m_configView->setRootIsDecorated(false);
m_configView->setUniformRowHeights(true);
+ m_configView->setSortingEnabled(true);
+ m_configView->sortByColumn(0, Qt::AscendingOrder);
auto stretcher = new Utils::HeaderViewStretcher(m_configView->header(), 1);
m_configView->setSelectionMode(QAbstractItemView::SingleSelection);
m_configView->setSelectionBehavior(QAbstractItemView::SelectItems);
m_configView->setFrameShape(QFrame::NoFrame);
- m_configView->hideColumn(2); // Hide isAdvanced column
- m_configView->setItemDelegate(new ConfigModelItemDelegate(m_configView));
+ m_configView->setItemDelegate(new ConfigModelItemDelegate(m_buildConfiguration->project()->projectDirectory(),
+ m_configView));
QFrame *findWrapper = Core::ItemViewFind::createSearchableWrapper(m_configView, Core::ItemViewFind::LightColored);
findWrapper->setFrameStyle(QFrame::StyledPanel);
- m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicator::Large, findWrapper);
+ m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Large, findWrapper);
m_progressIndicator->attachToWidget(findWrapper);
m_progressIndicator->raise();
m_progressIndicator->hide();
@@ -195,6 +207,9 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
mainLayout->addLayout(buttonLayout, row, 2);
+ connect(m_configView->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &CMakeBuildSettingsWidget::updateSelection);
+
++row;
m_reconfigureButton = new QPushButton(tr("Apply Configuration Changes"));
m_reconfigureButton->setEnabled(false);
@@ -204,21 +219,24 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
setError(bc->error());
setWarning(bc->warning());
- connect(project, &CMakeProject::parsingStarted, this, [this]() {
+ connect(project, &ProjectExplorer::Project::parsingStarted, this, [this]() {
updateButtonState();
m_showProgressTimer.start();
});
if (m_buildConfiguration->isParsing())
m_showProgressTimer.start();
- else
+ else {
m_configModel->setConfiguration(m_buildConfiguration->completeCMakeConfiguration());
+ m_configView->expandAll();
+ }
- connect(m_buildConfiguration, &CMakeBuildConfiguration::dataAvailable,
+ connect(m_buildConfiguration->target()->project(), &ProjectExplorer::Project::parsingFinished,
this, [this, buildDirChooser, stretcher]() {
- updateButtonState();
m_configModel->setConfiguration(m_buildConfiguration->completeCMakeConfiguration());
+ m_configView->expandAll();
stretcher->stretch();
+ updateButtonState();
buildDirChooser->triggerChanged(); // refresh valid state...
m_showProgressTimer.stop();
m_progressIndicator->hide();
@@ -228,6 +246,10 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
m_showProgressTimer.stop();
m_progressIndicator->hide();
});
+ connect(m_configTextFilterModel, &QAbstractItemModel::modelReset, this, [this, stretcher]() {
+ m_configView->expandAll();
+ stretcher->stretch();
+ });
connect(m_configModel, &QAbstractItemModel::dataChanged,
this, &CMakeBuildSettingsWidget::updateButtonState);
@@ -311,8 +333,15 @@ void CMakeBuildSettingsWidget::updateButtonState()
void CMakeBuildSettingsWidget::updateAdvancedCheckBox()
{
- // Switch between Qt::DisplayRole (everything is "0") and Qt::EditRole (advanced is "1").
- m_configFilterModel->setFilterRole(m_showAdvancedCheckBox->isChecked() ? Qt::EditRole : Qt::DisplayRole);
+ if (m_showAdvancedCheckBox->isChecked()) {
+ m_configFilterModel->setSourceModel(nullptr);
+ m_configTextFilterModel->setSourceModel(m_configModel);
+
+ } else {
+ m_configTextFilterModel->setSourceModel(nullptr);
+ m_configFilterModel->setSourceModel(m_configModel);
+ m_configTextFilterModel->setSourceModel(m_configFilterModel);
+ }
}
void CMakeBuildSettingsWidget::updateFromKit()
@@ -327,5 +356,84 @@ void CMakeBuildSettingsWidget::updateFromKit()
m_configModel->setKitConfiguration(configHash);
}
+static QModelIndex mapToSource(const QAbstractItemView *view, const QModelIndex &idx)
+{
+ if (!idx.isValid())
+ return idx;
+
+ QAbstractItemModel *model = view->model();
+ QModelIndex result = idx;
+ while (QSortFilterProxyModel *proxy = qobject_cast<QSortFilterProxyModel *>(model)) {
+ result = proxy->mapToSource(result);
+ model = proxy->sourceModel();
+ }
+ return result;
+}
+
+void CMakeBuildSettingsWidget::updateSelection(const QModelIndex &current, const QModelIndex &previous)
+{
+ Q_UNUSED(previous);
+ const QModelIndex currentModelIndex = mapToSource(m_configView, current);
+ if (currentModelIndex.isValid())
+ m_editButton->setEnabled(currentModelIndex.flags().testFlag(Qt::ItemIsEditable));
+}
+
+QAction *CMakeBuildSettingsWidget::createForceAction(int type, const QModelIndex &idx)
+{
+ ConfigModel::DataItem::Type t = static_cast<ConfigModel::DataItem::Type>(type);
+ QString typeString;
+ switch (type) {
+ case ConfigModel::DataItem::BOOLEAN:
+ typeString = tr("bool", "display string for cmake type BOOLEAN");
+ break;
+ case ConfigModel::DataItem::FILE:
+ typeString = tr("file", "display string for cmake type FILE");
+ break;
+ case ConfigModel::DataItem::DIRECTORY:
+ typeString = tr("directory", "display string for cmake type DIRECTORY");
+ break;
+ case ConfigModel::DataItem::STRING:
+ typeString = tr("string", "display string for cmake type STRING");
+ break;
+ case ConfigModel::DataItem::UNKNOWN:
+ return nullptr;
+ }
+ QAction *forceAction = new QAction(tr("Force to %1").arg(typeString), nullptr);
+ forceAction->setEnabled(m_configModel->canForceTo(idx, t));
+ connect(forceAction, &QAction::triggered,
+ this, [this, idx, t]() { m_configModel->forceTo(idx, t); });
+ return forceAction;
+}
+
+bool CMakeBuildSettingsWidget::eventFilter(QObject *target, QEvent *event)
+{
+ // handle context menu events:
+ if (target != m_configView->viewport() || event->type() != QEvent::ContextMenu)
+ return false;
+
+ auto e = static_cast<QContextMenuEvent *>(event);
+ const QModelIndex idx = mapToSource(m_configView, m_configView->indexAt(e->pos()));
+ if (!idx.isValid())
+ return false;
+
+ QMenu *menu = new QMenu(this);
+ connect(menu, &QMenu::triggered, menu, &QMenu::deleteLater);
+
+ QAction *action = nullptr;
+ if ((action = createForceAction(ConfigModel::DataItem::BOOLEAN, idx)))
+ menu->addAction(action);
+ if ((action = createForceAction(ConfigModel::DataItem::FILE, idx)))
+ menu->addAction(action);
+ if ((action = createForceAction(ConfigModel::DataItem::DIRECTORY, idx)))
+ menu->addAction(action);
+ if ((action = createForceAction(ConfigModel::DataItem::STRING, idx)))
+ menu->addAction(action);
+
+ menu->move(e->globalPos());
+ menu->show();
+
+ return true;
+}
+
} // namespace Internal
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h
index e76a2a6bbf7..e6e4b1e21c2 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h
@@ -64,6 +64,11 @@ private:
void updateAdvancedCheckBox();
void updateFromKit();
+ void updateSelection(const QModelIndex &current, const QModelIndex &previous);
+ QAction *createForceAction(int type, const QModelIndex &idx);
+
+ bool eventFilter(QObject *target, QEvent *event);
+
CMakeBuildConfiguration *m_buildConfiguration;
QTreeView *m_configView;
ConfigModel *m_configModel;
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
index ff2a3d2c9a6..d512c5138bc 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
@@ -71,7 +71,7 @@ const char ADD_RUNCONFIGURATION_TEXT[] = "Current executable";
static bool isCurrentExecutableTarget(const QString &target)
{
- return target == QLatin1String(ADD_RUNCONFIGURATION_TEXT);
+ return target == ADD_RUNCONFIGURATION_TEXT;
}
CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl) :
@@ -95,9 +95,9 @@ CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl, CMakeBuildStep *bs) :
void CMakeBuildStep::ctor(BuildStepList *bsl)
{
- m_percentProgress = QRegExp(QLatin1String("^\\[\\s*(\\d*)%\\]"));
- m_ninjaProgress = QRegExp(QLatin1String("^\\[\\s*(\\d*)/\\s*(\\d*)"));
- m_ninjaProgressString = QLatin1String("[%f/%t "); // ninja: [33/100
+ m_percentProgress = QRegExp("^\\[\\s*(\\d*)%\\]");
+ m_ninjaProgress = QRegExp("^\\[\\s*(\\d*)/\\s*(\\d*)");
+ m_ninjaProgressString = "[%f/%t "; // ninja: [33/100
//: Default display name for the cmake make step.
setDefaultDisplayName(tr("CMake Build"));
@@ -119,7 +119,8 @@ void CMakeBuildStep::ctor(BuildStepList *bsl)
}
connect(target(), &Target::kitChanged, this, &CMakeBuildStep::cmakeCommandChanged);
- connect(bc, &CMakeBuildConfiguration::dataAvailable, this, &CMakeBuildStep::handleBuildTargetChanges);
+ connect(project(), &Project::parsingFinished,
+ this, &CMakeBuildStep::handleBuildTargetChanges);
}
CMakeBuildConfiguration *CMakeBuildStep::cmakeBuildConfiguration() const
@@ -150,23 +151,23 @@ QVariantMap CMakeBuildStep::toMap() const
{
QVariantMap map(AbstractProcessStep::toMap());
// Use QStringList for compatibility with old files
- map.insert(QLatin1String(BUILD_TARGETS_KEY), QStringList(m_buildTarget));
- map.insert(QLatin1String(TOOL_ARGUMENTS_KEY), m_toolArguments);
+ map.insert(BUILD_TARGETS_KEY, QStringList(m_buildTarget));
+ map.insert(TOOL_ARGUMENTS_KEY, m_toolArguments);
return map;
}
bool CMakeBuildStep::fromMap(const QVariantMap &map)
{
- if (map.value(QLatin1String(CLEAN_KEY), false).toBool()) {
+ if (map.value(CLEAN_KEY, false).toBool()) {
m_buildTarget = CMakeBuildStep::cleanTarget();
} else {
- const QStringList targetList = map.value(QLatin1String(BUILD_TARGETS_KEY)).toStringList();
+ const QStringList targetList = map.value(BUILD_TARGETS_KEY).toStringList();
if (!targetList.isEmpty())
m_buildTarget = targetList.last();
- m_toolArguments = map.value(QLatin1String(TOOL_ARGUMENTS_KEY)).toString();
+ m_toolArguments = map.value(TOOL_ARGUMENTS_KEY).toString();
}
- if (map.value(QLatin1String(ADD_RUNCONFIGURATION_ARGUMENT_KEY), false).toBool())
- m_buildTarget = QLatin1String(ADD_RUNCONFIGURATION_TEXT);
+ if (map.value(ADD_RUNCONFIGURATION_ARGUMENT_KEY, false).toBool())
+ m_buildTarget = ADD_RUNCONFIGURATION_TEXT;
return BuildStep::fromMap(map);
}
@@ -193,8 +194,8 @@ bool CMakeBuildStep::init(QList<const BuildStep *> &earlierSteps)
CMakeTool *tool = CMakeKitInformation::cmakeTool(target()->kit());
if (!tool || !tool->isValid()) {
emit addTask(Task(Task::Error,
- tr("Qt Creator needs a CMake Tool set up to build. "
- "Configure a CMake Tool in the kit options."),
+ tr("A CMake tool must be set up for building. "
+ "Configure a CMake tool in the kit options."),
Utils::FileName(), -1,
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
canInit = false;
@@ -241,8 +242,8 @@ bool CMakeBuildStep::init(QList<const BuildStep *> &earlierSteps)
pp->setMacroExpander(bc->macroExpander());
Utils::Environment env = bc->environment();
Utils::Environment::setupEnglishOutput(&env);
- if (!env.value(QLatin1String("NINJA_STATUS")).startsWith(m_ninjaProgressString))
- env.set(QLatin1String("NINJA_STATUS"), m_ninjaProgressString + QLatin1String("%o/sec] "));
+ if (!env.value("NINJA_STATUS").startsWith(m_ninjaProgressString))
+ env.set("NINJA_STATUS", m_ninjaProgressString + "%o/sec] ");
pp->setEnvironment(env);
pp->setWorkingDirectory(bc->buildDirectory().toString());
pp->setCommand(cmakeCommand());
@@ -279,10 +280,8 @@ void CMakeBuildStep::run(QFutureInterface<bool> &fi)
}
if (mustDelay) {
- m_runTrigger = connect(bc, &CMakeBuildConfiguration::dataAvailable,
- this, [this, &fi]() { runImpl(fi); });
- m_errorTrigger = connect(bc, &CMakeBuildConfiguration::errorOccured,
- this, [this, &fi](const QString& em) { handleCMakeError(fi, em); });
+ m_runTrigger = connect(project(), &Project::parsingFinished,
+ this, [this, &fi](bool success) { handleProjectWasParsed(fi, success); });
} else {
runImpl(fi);
}
@@ -291,21 +290,18 @@ void CMakeBuildStep::run(QFutureInterface<bool> &fi)
void CMakeBuildStep::runImpl(QFutureInterface<bool> &fi)
{
// Do the actual build:
- disconnectTriggers();
AbstractProcessStep::run(fi);
}
-void CMakeBuildStep::handleCMakeError(QFutureInterface<bool> &fi, const QString& errorMessage)
-{
- disconnectTriggers();
- AbstractProcessStep::stdError(tr("Error parsing CMake: %1\n").arg(errorMessage));
- reportRunResult(fi, false);
-}
-
-void CMakeBuildStep::disconnectTriggers()
+void CMakeBuildStep::handleProjectWasParsed(QFutureInterface<bool> &fi, bool success)
{
disconnect(m_runTrigger);
- disconnect(m_errorTrigger);
+ if (success) {
+ runImpl(fi);
+ } else {
+ AbstractProcessStep::stdError(tr("Project did not parse successfully, can not build."));
+ reportRunResult(fi, false);
+ }
}
BuildStepConfigWidget *CMakeBuildStep::createConfigWidget()
@@ -384,8 +380,8 @@ QString CMakeBuildStep::allArguments(const CMakeRunConfiguration *rc) const
{
QString arguments;
- Utils::QtcProcess::addArg(&arguments, QLatin1String("--build"));
- Utils::QtcProcess::addArg(&arguments, QLatin1String("."));
+ Utils::QtcProcess::addArg(&arguments, "--build");
+ Utils::QtcProcess::addArg(&arguments, ".");
QString target;
@@ -393,17 +389,17 @@ QString CMakeBuildStep::allArguments(const CMakeRunConfiguration *rc) const
if (rc)
target = rc->buildSystemTarget();
else
- target = QLatin1String("<i>&lt;") + tr(ADD_RUNCONFIGURATION_TEXT) + QLatin1String("&gt;</i>");
+ target = "<i>&lt;" + tr(ADD_RUNCONFIGURATION_TEXT) + "&gt;</i>";
} else {
target = m_buildTarget;
}
- Utils::QtcProcess::addArg(&arguments, QLatin1String("--target"));
+ Utils::QtcProcess::addArg(&arguments, "--target");
Utils::QtcProcess::addArg(&arguments, target);
if (!m_toolArguments.isEmpty()) {
- Utils::QtcProcess::addArg(&arguments, QLatin1String("--"));
- arguments += QLatin1Char(' ') + m_toolArguments;
+ Utils::QtcProcess::addArg(&arguments, "--");
+ arguments += ' ' + m_toolArguments;
}
return arguments;
@@ -479,8 +475,15 @@ CMakeBuildStepConfigWidget::CMakeBuildStepConfigWidget(CMakeBuildStep *buildStep
connect(m_buildStep, &CMakeBuildStep::buildTargetsChanged, this, &CMakeBuildStepConfigWidget::buildTargetsChanged);
connect(m_buildStep, &CMakeBuildStep::targetToBuildChanged, this, &CMakeBuildStepConfigWidget::selectedBuildTargetsChanged);
- connect(static_cast<CMakeProject *>(m_buildStep->project()), &CMakeProject::environmentChanged,
- this, &CMakeBuildStepConfigWidget::updateDetails);
+ m_buildStep->project()->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
+ if (static_cast<BuildConfiguration *>(sender())->isActive())
+ updateDetails();
+ });
+ connect(m_buildStep->project(), &Project::activeProjectConfigurationChanged,
+ this, [this](ProjectConfiguration *pc) {
+ if (pc && pc->isActive())
+ updateDetails();
+ });
}
void CMakeBuildStepConfigWidget::toolArgumentsEdited()
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.h b/src/plugins/cmakeprojectmanager/cmakebuildstep.h
index 08cee9a01cb..754aae52cbd 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildstep.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.h
@@ -104,14 +104,12 @@ private:
void ctor(ProjectExplorer::BuildStepList *bsl);
void runImpl(QFutureInterface<bool> &fi);
- void handleCMakeError(QFutureInterface<bool> &fi, const QString& errorMessage);
- void disconnectTriggers();
+ void handleProjectWasParsed(QFutureInterface<bool> &fi, bool success);
void handleBuildTargetChanges();
CMakeRunConfiguration *targetsActiveRunConfiguration() const;
QMetaObject::Connection m_runTrigger;
- QMetaObject::Connection m_errorTrigger;
QRegExp m_percentProgress;
QRegExp m_ninjaProgress;
diff --git a/src/plugins/cmakeprojectmanager/cmakecbpparser.cpp b/src/plugins/cmakeprojectmanager/cmakecbpparser.cpp
index 591768f515e..96cf7d138df 100644
--- a/src/plugins/cmakeprojectmanager/cmakecbpparser.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakecbpparser.cpp
@@ -30,6 +30,7 @@
#include <utils/fileutils.h>
#include <utils/stringutils.h>
#include <utils/algorithm.h>
+#include <projectexplorer/projectmacro.h>
#include <projectexplorer/projectnodes.h>
#include <QLoggingCategory>
@@ -71,8 +72,9 @@ void CMakeCbpParser::sortFiles()
qCDebug(log) << "# Pre Dump #";
qCDebug(log) << "###############";
foreach (const CMakeBuildTarget &target, m_buildTargets)
- qCDebug(log) << target.title << target.sourceDirectory <<
- target.includeFiles << target.defines << target.files << "\n";
+ qCDebug(log) << target.title << target.sourceDirectory << target.includeFiles
+ << ProjectExplorer::Macro::toByteArray(target.macros)
+ << target.files << "\n";
// find a good build target to fall back
int fallbackIndex = 0;
@@ -153,7 +155,9 @@ void CMakeCbpParser::sortFiles()
qCDebug(log) << "# After Dump #";
qCDebug(log) << "###############";
foreach (const CMakeBuildTarget &target, m_buildTargets)
- qCDebug(log) << target.title << target.sourceDirectory << target.includeFiles << target.defines << target.files << "\n";
+ qCDebug(log) << target.title << target.sourceDirectory << target.includeFiles
+ << ProjectExplorer::Macro::toByteArray(target.macros)
+ << target.files << "\n";
}
bool CMakeCbpParser::parseCbpFile(CMakeTool::PathMapper mapper, const FileName &fileName,
@@ -397,12 +401,8 @@ void CMakeCbpParser::parseAdd()
m_buildTarget.compilerOptions.append(compilerOption);
int macroNameIndex = compilerOption.indexOf("-D") + 2;
if (macroNameIndex != 1) {
- int assignIndex = compilerOption.indexOf('=', macroNameIndex);
- if (assignIndex != -1)
- compilerOption[assignIndex] = ' ';
- m_buildTarget.defines.append("#define ");
- m_buildTarget.defines.append(compilerOption.mid(macroNameIndex).toUtf8());
- m_buildTarget.defines.append('\n');
+ const QString keyValue = compilerOption.mid(macroNameIndex);
+ m_buildTarget.macros.append(ProjectExplorer::Macro::fromKeyValue(keyValue));
}
}
diff --git a/src/plugins/cmakeprojectmanager/cmakekitconfigwidget.cpp b/src/plugins/cmakeprojectmanager/cmakekitconfigwidget.cpp
index f0be80b42e2..47eeef30a80 100644
--- a/src/plugins/cmakeprojectmanager/cmakekitconfigwidget.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakekitconfigwidget.cpp
@@ -334,7 +334,7 @@ void CMakeGeneratorKitConfigWidget::changeGenerator()
for (auto it = generatorList.constBegin(); it != generatorList.constEnd(); ++it)
generatorCombo->addItem(it->name);
- auto updateDialog = [this, &generatorList, generatorCombo, extraGeneratorCombo,
+ auto updateDialog = [&generatorList, generatorCombo, extraGeneratorCombo,
platformEdit, toolsetEdit](const QString &name) {
auto it = std::find_if(generatorList.constBegin(), generatorList.constEnd(),
[name](const CMakeTool::Generator &g) { return g.name == name; });
diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
index 9e5962d3aef..3a52d6911ce 100644
--- a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
@@ -29,6 +29,7 @@
#include "cmaketoolmanager.h"
#include "cmaketool.h"
+#include <app/app_version.h>
#include <projectexplorer/task.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/kit.h>
@@ -147,7 +148,7 @@ KitConfigWidget *CMakeKitInformation::createConfigWidget(Kit *k) const
void CMakeKitInformation::addToMacroExpander(Kit *k, Utils::MacroExpander *expander) const
{
expander->registerFileVariables("CMake:Executable", tr("Path to the cmake executable"),
- [this, k]() -> QString {
+ [k]() -> QString {
CMakeTool *tool = CMakeKitInformation::cmakeTool(k);
return tool ? tool->cmakeExecutable().toString() : QString();
});
@@ -383,7 +384,8 @@ QList<Task> CMakeGeneratorKitInformation::validate(const Kit *k) const
if (!tool->hasServerMode() && info.extraGenerator != "CodeBlocks") {
result << Task(Task::Warning, tr("The selected CMake binary has no server-mode and the CMake "
"generator does not generate a CodeBlocks file. "
- "Qt Creator will not be able to parse CMake projects."),
+ "%1 will not be able to parse CMake projects.")
+ .arg(Core::Constants::IDE_DISPLAY_NAME),
Utils::FileName(), -1, Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
}
}
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index 988a39652a9..57de95ad1fa 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -190,7 +190,18 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc)
emit bc->emitBuildTypeChanged();
- emit parsingFinished();
+ emitParsingFinished(true);
+}
+
+void CMakeProject::handleParsingError(CMakeBuildConfiguration *bc)
+{
+ QTC_ASSERT(bc, return);
+
+ Target *t = activeTarget();
+ if (!t || t->activeBuildConfiguration() != bc)
+ return;
+
+ emitParsingFinished(false);
}
void CMakeProject::updateQmlJSCodeModel()
@@ -368,10 +379,10 @@ void CMakeProject::handleActiveBuildConfigurationChanged()
}
}
-void CMakeProject::handleParsingStarted()
+void CMakeProject::handleParsingStarted(const CMakeBuildConfiguration *bc)
{
- if (activeTarget() && activeTarget()->activeBuildConfiguration() == sender())
- emit parsingStarted();
+ if (activeTarget() && activeTarget()->activeBuildConfiguration() == bc)
+ emitParsingStarted();
}
void CMakeProject::handleTreeScanningFinished()
@@ -455,7 +466,6 @@ void CMakeProject::updateTargetRunConfigurations(Target *t)
continue;
auto btIt = buildTargetHash.constFind(cmakeRc->title());
- cmakeRc->setEnabled(btIt != buildTargetHash.constEnd());
if (btIt != buildTargetHash.constEnd()) {
cmakeRc->setExecutable(btIt.value()->executable.toString());
cmakeRc->setBaseWorkingDirectory(btIt.value()->workingDirectory);
@@ -577,7 +587,7 @@ void CMakeBuildTarget::clear()
targetType = UtilityType;
includeFiles.clear();
compilerOptions.clear();
- defines.clear();
+ macros.clear();
files.clear();
}
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h
index 2b20a7479cc..1d3e047683f 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.h
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.h
@@ -30,6 +30,7 @@
#include "treescanner.h"
#include <projectexplorer/extracompiler.h>
+#include <projectexplorer/projectmacro.h>
#include <projectexplorer/project.h>
#include <utils/fileutils.h>
@@ -72,7 +73,7 @@ public:
// code model
QList<Utils::FileName> includeFiles;
QStringList compilerOptions;
- QByteArray defines;
+ ProjectExplorer::Macros macros;
QList<Utils::FileName> files;
void clear();
@@ -105,10 +106,6 @@ public:
ProjectExplorer::ProjectImporter *projectImporter() const final;
-signals:
- /// emitted when cmake is running:
- void parsingStarted();
-
protected:
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
bool setupTarget(ProjectExplorer::Target *t) final;
@@ -118,9 +115,10 @@ private:
void handleActiveTargetChanged();
void handleActiveBuildConfigurationChanged();
- void handleParsingStarted();
+ void handleParsingStarted(const Internal::CMakeBuildConfiguration *bc);
void handleTreeScanningFinished();
- void updateProjectData(Internal::CMakeBuildConfiguration *cmakeBc);
+ void updateProjectData(Internal::CMakeBuildConfiguration *bc);
+ void handleParsingError(Internal::CMakeBuildConfiguration *bc);
void updateQmlJSCodeModel();
void createGeneratedCodeModelSupport();
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs
index 654234cbec5..fb3c3104643 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs
@@ -12,6 +12,7 @@ QtcPlugin {
Depends { name: "ProjectExplorer" }
Depends { name: "TextEditor" }
Depends { name: "QtSupport" }
+ Depends { name: "app_version_header" }
pluginRecommends: [
"Designer"
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
index 56e35f019f9..ae7afdd3932 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
@@ -31,8 +31,6 @@
#include <utils/algorithm.h>
-#include <QApplication>
-
using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
@@ -57,13 +55,7 @@ bool CMakeInputsNode::showInSimpleTree() const
CMakeListsNode::CMakeListsNode(const Utils::FileName &cmakeListPath) :
ProjectExplorer::ProjectNode(cmakeListPath)
{
- static QIcon folderIcon;
- if (folderIcon.isNull()) {
- const QIcon overlayIcon(Constants::FILEOVERLAY_CMAKE);
- QPixmap dirPixmap = QApplication::style()->standardIcon(QStyle::SP_DirIcon).pixmap(QSize(16, 16));
-
- folderIcon.addPixmap(Core::FileIconProvider::overlayIcon(dirPixmap, overlayIcon));
- }
+ static QIcon folderIcon = Core::FileIconProvider::directoryIcon(Constants::FILEOVERLAY_CMAKE);
setIcon(folderIcon);
}
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
index 79a59a528ca..4a132316328 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
@@ -114,8 +114,8 @@ void CMakeProjectPlugin::extensionsInitialized()
void CMakeProjectPlugin::updateContextActions()
{
Project *project = ProjectTree::currentProject();
- Node *node = ProjectTree::currentNode();
- CMakeTargetNode *targetNode = dynamic_cast<CMakeTargetNode *>(node);
+ const Node *node = ProjectTree::findCurrentNode();
+ const CMakeTargetNode *targetNode = dynamic_cast<const CMakeTargetNode *>(node);
// as targetNode can be deleted while the menu is open, we keep only the
const QString targetDisplayName = targetNode ? targetNode->displayName() : QString();
CMakeProject *cmProject = dynamic_cast<CMakeProject *>(project);
diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp
index bfb4fcbc71f..6b821b26b69 100644
--- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp
@@ -37,6 +37,7 @@
#include <projectexplorer/target.h>
#include <utils/detailswidget.h>
+#include <utils/fancylineedit.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
@@ -59,36 +60,36 @@ const char CMAKE_RC_PREFIX[] = "CMakeProjectManager.CMakeRunConfiguration.";
const char TITLE_KEY[] = "CMakeProjectManager.CMakeRunConfiguation.Title";
} // namespace
-CMakeRunConfiguration::CMakeRunConfiguration(Target *parent, Core::Id id, const QString &target,
- const Utils::FileName &workingDirectory, const QString &title) :
- RunConfiguration(parent, id),
- m_buildSystemTarget(target),
- m_executable(target),
- m_title(title)
+CMakeRunConfiguration::CMakeRunConfiguration(Target *target)
+ : RunConfiguration(target)
{
addExtraAspect(new LocalEnvironmentAspect(this, LocalEnvironmentAspect::BaseEnvironmentModifier()));
- addExtraAspect(new ArgumentsAspect(this, QStringLiteral("CMakeProjectManager.CMakeRunConfiguration.Arguments")));
- addExtraAspect(new TerminalAspect(this, QStringLiteral("CMakeProjectManager.CMakeRunConfiguration.UseTerminal")));
-
- auto wd = new WorkingDirectoryAspect(this, QStringLiteral("CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory"));
- wd->setDefaultWorkingDirectory(workingDirectory);
- addExtraAspect(wd);
-
- ctor();
+ addExtraAspect(new ArgumentsAspect(this, "CMakeProjectManager.CMakeRunConfiguration.Arguments"));
+ addExtraAspect(new TerminalAspect(this, "CMakeProjectManager.CMakeRunConfiguration.UseTerminal"));
+ addExtraAspect(new WorkingDirectoryAspect(this, "CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory"));
}
-CMakeRunConfiguration::CMakeRunConfiguration(Target *parent, CMakeRunConfiguration *source) :
- RunConfiguration(parent, source),
- m_buildSystemTarget(source->m_buildSystemTarget),
- m_executable(source->m_executable),
- m_title(source->m_title),
- m_enabled(source->m_enabled)
+void CMakeRunConfiguration::initialize(Core::Id id, const QString &target,
+ const Utils::FileName &workingDirectory, const QString &title)
{
- ctor();
+ RunConfiguration::initialize(id);
+ m_buildSystemTarget = target;
+ m_executable = target;
+ m_title = title;
+
+ extraAspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(workingDirectory);
+
+ setDefaultDisplayName(defaultDisplayName());
}
-void CMakeRunConfiguration::ctor()
+void CMakeRunConfiguration::copyFrom(const CMakeRunConfiguration *source)
{
+ RunConfiguration::copyFrom(source);
+
+ m_buildSystemTarget = source->m_buildSystemTarget;
+ m_executable = source->m_executable;
+ m_title = source->m_title;
+
setDefaultDisplayName(defaultDisplayName());
}
@@ -143,38 +144,39 @@ QString CMakeRunConfiguration::defaultDisplayName() const
{
if (m_title.isEmpty())
return tr("Run CMake kit");
- QString result = m_title;
- if (!m_enabled) {
- result += QLatin1Char(' ');
- result += tr("(disabled)");
- }
- return result;
+ return m_title;
}
-QWidget *CMakeRunConfiguration::createConfigurationWidget()
+void CMakeRunConfiguration::updateEnabledState()
{
- return new CMakeRunConfigurationWidget(this);
+ auto cp = qobject_cast<CMakeProject *>(target()->project());
+ if (!cp->hasBuildTarget(m_buildSystemTarget))
+ setEnabled(false);
+ else
+ RunConfiguration::updateEnabledState();
}
-void CMakeRunConfiguration::setEnabled(bool b)
+QWidget *CMakeRunConfiguration::createConfigurationWidget()
{
- if (m_enabled == b)
- return;
- m_enabled = b;
- emit enabledChanged();
- setDefaultDisplayName(defaultDisplayName());
+ return new CMakeRunConfigurationWidget(this);
}
-bool CMakeRunConfiguration::isEnabled() const
+QString CMakeRunConfiguration::disabledReason() const
{
- return m_enabled;
+ auto cp = qobject_cast<CMakeProject *>(target()->project());
+ QTC_ASSERT(cp, return QString());
+
+ if (cp->hasParsingData() && !cp->hasBuildTarget(m_buildSystemTarget))
+ return tr("The project no longer builds the target associated with this run configuration.");
+ return RunConfiguration::disabledReason();
}
-QString CMakeRunConfiguration::disabledReason() const
+static void updateExecutable(CMakeRunConfiguration *rc, Utils::FancyLineEdit *fle)
{
- if (!m_enabled)
- return tr("The executable is not built by the current build configuration");
- return QString();
+ const Runnable runnable = rc->runnable();
+ fle->setText(runnable.is<StandardRunnable>()
+ ? Utils::FileName::fromString(runnable.as<StandardRunnable>().executable).toUserOutput()
+ : QString());
}
// Configuration widget
@@ -185,6 +187,16 @@ CMakeRunConfigurationWidget::CMakeRunConfigurationWidget(CMakeRunConfiguration *
fl->setMargin(0);
fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
+ auto executableLabel = new QLabel(tr("Executable:"));
+ auto executable = new Utils::FancyLineEdit;
+ executable->setReadOnly(true);
+ executable->setPlaceholderText(tr("<unknown>"));
+ connect(cmakeRunConfiguration, &CMakeRunConfiguration::enabledChanged,
+ this, std::bind(updateExecutable, cmakeRunConfiguration, executable));
+ updateExecutable(cmakeRunConfiguration, executable);
+
+ fl->addRow(executableLabel, executable);
+
cmakeRunConfiguration->extraAspect<ArgumentsAspect>()->addToMainConfigurationWidget(this, fl);
cmakeRunConfiguration->extraAspect<WorkingDirectoryAspect>()->addToMainConfigurationWidget(this, fl);
cmakeRunConfiguration->extraAspect<TerminalAspect>()->addToMainConfigurationWidget(this, fl);
@@ -199,8 +211,6 @@ CMakeRunConfigurationWidget::CMakeRunConfigurationWidget(CMakeRunConfiguration *
auto vbx = new QVBoxLayout(this);
vbx->setMargin(0);
vbx->addWidget(detailsContainer);
-
- setEnabled(cmakeRunConfiguration->isEnabled());
}
// Factory
@@ -247,7 +257,7 @@ RunConfiguration *CMakeRunConfigurationFactory::doCreate(Target *parent, Core::I
CMakeProject *project = static_cast<CMakeProject *>(parent->project());
const QString title(buildTargetFromId(id));
const CMakeBuildTarget &ct = project->buildTargetForTitle(title);
- return new CMakeRunConfiguration(parent, id, title, ct.workingDirectory, ct.title);
+ return createHelper<CMakeRunConfiguration>(parent, id, title, ct.workingDirectory, ct.title);
}
bool CMakeRunConfigurationFactory::canClone(Target *parent, RunConfiguration *source) const
@@ -261,8 +271,7 @@ RunConfiguration *CMakeRunConfigurationFactory::clone(Target *parent, RunConfigu
{
if (!canClone(parent, source))
return 0;
- CMakeRunConfiguration *crc(static_cast<CMakeRunConfiguration *>(source));
- return new CMakeRunConfiguration(parent, crc);
+ return cloneHelper<CMakeRunConfiguration>(parent, source);
}
bool CMakeRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
@@ -275,7 +284,7 @@ bool CMakeRunConfigurationFactory::canRestore(Target *parent, const QVariantMap
RunConfiguration *CMakeRunConfigurationFactory::doRestore(Target *parent, const QVariantMap &map)
{
const Core::Id id = idFromMap(map);
- return new CMakeRunConfiguration(parent, id, buildTargetFromId(id), Utils::FileName(), QString());
+ return createHelper<CMakeRunConfiguration>(parent, id, buildTargetFromId(id), Utils::FileName(), QString());
}
QString CMakeRunConfigurationFactory::buildTargetFromId(Core::Id id)
diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h
index 02ed4df6078..1b4ceffc234 100644
--- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h
+++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h
@@ -35,11 +35,10 @@ class CMakeRunConfiguration : public ProjectExplorer::RunConfiguration
{
Q_OBJECT
friend class CMakeRunConfigurationWidget;
- friend class CMakeRunConfigurationFactory;
+ friend class ProjectExplorer::IRunConfigurationFactory;
public:
- CMakeRunConfiguration(ProjectExplorer::Target *parent, Core::Id id, const QString &target,
- const Utils::FileName &workingDirectory, const QString &title);
+ explicit CMakeRunConfiguration(ProjectExplorer::Target *target);
ProjectExplorer::Runnable runnable() const override;
QWidget *createConfigurationWidget() override;
@@ -51,26 +50,25 @@ public:
QVariantMap toMap() const override;
- void setEnabled(bool b);
-
- bool isEnabled() const override;
QString disabledReason() const override;
QString buildSystemTarget() const final { return m_buildSystemTarget; }
-protected:
- CMakeRunConfiguration(ProjectExplorer::Target *parent, CMakeRunConfiguration *source);
+private:
+ void initialize(Core::Id id, const QString &target,
+ const Utils::FileName &workingDirectory, const QString &title);
+ void copyFrom(const CMakeRunConfiguration *source);
+
bool fromMap(const QVariantMap &map) override;
QString defaultDisplayName() const;
-private:
+ void updateEnabledState() final;
+
QString baseWorkingDirectory() const;
- void ctor();
- const QString m_buildSystemTarget;
+ QString m_buildSystemTarget;
QString m_executable;
QString m_title;
- bool m_enabled = true;
};
class CMakeRunConfigurationWidget : public QWidget
diff --git a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp
index 8381323759d..9f1b7538924 100644
--- a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp
@@ -66,13 +66,13 @@ public:
CMakeToolTreeItem *cmakeToolItem(const Core::Id &id) const;
CMakeToolTreeItem *cmakeToolItem(const QModelIndex &index) const;
- QModelIndex addCMakeTool(const QString &name, const FileName &executable, const bool autoRun, const bool isAutoDetected);
+ QModelIndex addCMakeTool(const QString &name, const FileName &executable, const bool autoRun, const bool autoCreate, const bool isAutoDetected);
void addCMakeTool(const CMakeTool *item, bool changed);
TreeItem *autoGroupItem() const;
TreeItem *manualGroupItem() const;
void reevaluateChangedFlag(CMakeToolTreeItem *item) const;
void updateCMakeTool(const Core::Id &id, const QString &displayName, const FileName &executable,
- bool autoRun);
+ bool autoRun, bool autoCreate);
void removeCMakeTool(const Core::Id &id);
void apply();
@@ -95,16 +95,18 @@ public:
m_name(item->displayName()),
m_executable(item->cmakeExecutable()),
m_isAutoRun(item->isAutoRun()),
+ m_autoCreateBuildDirectory(item->autoCreateBuildDirectory()),
m_autodetected(item->isAutoDetected()),
m_changed(changed)
{}
CMakeToolTreeItem(const QString &name, const Utils::FileName &executable,
- bool autoRun, bool autodetected) :
+ bool autoRun, bool autoCreate, bool autodetected) :
m_id(Core::Id::fromString(QUuid::createUuid().toString())),
m_name(name),
m_executable(executable),
m_isAutoRun(autoRun),
+ m_autoCreateBuildDirectory(autoCreate),
m_autodetected(autodetected),
m_changed(true)
{}
@@ -143,6 +145,7 @@ public:
QString m_name;
FileName m_executable;
bool m_isAutoRun = true;
+ bool m_autoCreateBuildDirectory = false;
bool m_autodetected = false;
bool m_changed = true;
};
@@ -166,9 +169,10 @@ CMakeToolItemModel::CMakeToolItemModel()
}
QModelIndex CMakeToolItemModel::addCMakeTool(const QString &name, const FileName &executable,
- const bool autoRun, const bool isAutoDetected)
+ const bool autoRun, const bool autoCreate,
+ const bool isAutoDetected)
{
- CMakeToolTreeItem *item = new CMakeToolTreeItem(name, executable, autoRun, isAutoDetected);
+ CMakeToolTreeItem *item = new CMakeToolTreeItem(name, executable, autoRun, autoCreate, isAutoDetected);
if (isAutoDetected)
autoGroupItem()->appendChild(item);
else
@@ -219,7 +223,8 @@ void CMakeToolItemModel::reevaluateChangedFlag(CMakeToolTreeItem *item) const
}
void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &displayName,
- const FileName &executable, bool autoRun)
+ const FileName &executable, bool autoRun,
+ bool autoCreate)
{
CMakeToolTreeItem *treeItem = cmakeToolItem(id);
QTC_ASSERT(treeItem, return);
@@ -227,6 +232,7 @@ void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &disp
treeItem->m_name = displayName;
treeItem->m_executable = executable;
treeItem->m_isAutoRun = autoRun;
+ treeItem->m_autoCreateBuildDirectory = autoCreate;
reevaluateChangedFlag(treeItem);
}
@@ -262,6 +268,7 @@ void CMakeToolItemModel::apply()
cmake->setDisplayName(item->m_name);
cmake->setCMakeExecutable(item->m_executable);
cmake->setAutorun(item->m_isAutoRun);
+ cmake->setAutoCreateBuildDirectory(item->m_autoCreateBuildDirectory);
} else {
toRegister.append(item);
}
@@ -329,6 +336,7 @@ private:
CMakeToolItemModel *m_model;
QLineEdit *m_displayNameLineEdit;
QCheckBox *m_autoRunCheckBox;
+ QCheckBox *m_autoCreateBuildDirectoryCheckBox;
PathChooser *m_binaryChooser;
Core::Id m_id;
bool m_loadingItem;
@@ -349,11 +357,16 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model)
m_autoRunCheckBox->setText(tr("Autorun CMake"));
m_autoRunCheckBox->setToolTip(tr("Automatically run CMake after changes to CMake project files."));
+ m_autoCreateBuildDirectoryCheckBox = new QCheckBox;
+ m_autoCreateBuildDirectoryCheckBox->setText(tr("Auto-create build directories"));
+ m_autoCreateBuildDirectoryCheckBox->setToolTip(tr("Automatically create build directories for CMake projects."));
+
QFormLayout *formLayout = new QFormLayout(this);
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit);
formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser);
formLayout->addRow(m_autoRunCheckBox);
+ formLayout->addRow(m_autoCreateBuildDirectoryCheckBox);
connect(m_binaryChooser, &PathChooser::rawPathChanged,
this, &CMakeToolItemConfigWidget::store);
@@ -361,13 +374,16 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model)
this, &CMakeToolItemConfigWidget::store);
connect(m_autoRunCheckBox, &QCheckBox::toggled,
this, &CMakeToolItemConfigWidget::store);
+ connect(m_autoCreateBuildDirectoryCheckBox, &QCheckBox::toggled,
+ this, &CMakeToolItemConfigWidget::store);
}
void CMakeToolItemConfigWidget::store() const
{
if (!m_loadingItem && m_id.isValid())
m_model->updateCMakeTool(m_id, m_displayNameLineEdit->text(), m_binaryChooser->fileName(),
- m_autoRunCheckBox->checkState() == Qt::Checked);
+ m_autoRunCheckBox->checkState() == Qt::Checked,
+ m_autoCreateBuildDirectoryCheckBox->checkState() == Qt::Checked);
}
void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
@@ -387,6 +403,7 @@ void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
m_binaryChooser->setFileName(item->m_executable);
m_autoRunCheckBox->setChecked(item->m_isAutoRun);
+ m_autoCreateBuildDirectoryCheckBox->setChecked(item->m_autoCreateBuildDirectory);
m_id = item->m_id;
m_loadingItem = false;
@@ -492,7 +509,8 @@ void CMakeToolConfigWidget::cloneCMakeTool()
QModelIndex newItem = m_model.addCMakeTool(tr("Clone of %1").arg(m_currentItem->m_name),
m_currentItem->m_executable,
- m_currentItem->m_isAutoRun, false);
+ m_currentItem->m_isAutoRun,
+ m_currentItem->m_autoCreateBuildDirectory, false);
m_cmakeToolsView->setCurrentIndex(newItem);
}
@@ -500,7 +518,7 @@ void CMakeToolConfigWidget::cloneCMakeTool()
void CMakeToolConfigWidget::addCMakeTool()
{
QModelIndex newItem = m_model.addCMakeTool(m_model.uniqueDisplayName(tr("New CMake")),
- FileName(), true, false);
+ FileName(), true, false, false);
m_cmakeToolsView->setCurrentIndex(newItem);
}
diff --git a/src/plugins/cmakeprojectmanager/cmaketool.cpp b/src/plugins/cmakeprojectmanager/cmaketool.cpp
index 1a107ccd554..9c071dacb85 100644
--- a/src/plugins/cmakeprojectmanager/cmaketool.cpp
+++ b/src/plugins/cmakeprojectmanager/cmaketool.cpp
@@ -46,6 +46,7 @@ const char CMAKE_INFORMATION_ID[] = "Id";
const char CMAKE_INFORMATION_COMMAND[] = "Binary";
const char CMAKE_INFORMATION_DISPLAYNAME[] = "DisplayName";
const char CMAKE_INFORMATION_AUTORUN[] = "AutoRun";
+const char CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY[] = "AutoCreateBuildDirectory";
const char CMAKE_INFORMATION_AUTODETECTED[] = "AutoDetected";
@@ -68,6 +69,7 @@ CMakeTool::CMakeTool(const QVariantMap &map, bool fromSdk) : m_isAutoDetected(fr
m_id = Core::Id::fromSetting(map.value(CMAKE_INFORMATION_ID));
m_displayName = map.value(CMAKE_INFORMATION_DISPLAYNAME).toString();
m_isAutoRun = map.value(CMAKE_INFORMATION_AUTORUN, true).toBool();
+ m_autoCreateBuildDirectory = map.value(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, false).toBool();
//loading a CMakeTool from SDK is always autodetection
if (!fromSdk)
@@ -102,6 +104,15 @@ void CMakeTool::setAutorun(bool autoRun)
CMakeToolManager::notifyAboutUpdate(this);
}
+void CMakeTool::setAutoCreateBuildDirectory(bool autoBuildDir)
+{
+ if (m_autoCreateBuildDirectory == autoBuildDir)
+ return;
+
+ m_autoCreateBuildDirectory = autoBuildDir;
+ CMakeToolManager::notifyAboutUpdate(this);
+}
+
bool CMakeTool::isValid() const
{
if (!m_id.isValid())
@@ -142,6 +153,7 @@ QVariantMap CMakeTool::toMap() const
data.insert(CMAKE_INFORMATION_ID, m_id.toSetting());
data.insert(CMAKE_INFORMATION_COMMAND, m_executable.toString());
data.insert(CMAKE_INFORMATION_AUTORUN, m_isAutoRun);
+ data.insert(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, m_autoCreateBuildDirectory);
data.insert(CMAKE_INFORMATION_AUTODETECTED, m_isAutoDetected);
return data;
}
@@ -162,6 +174,11 @@ bool CMakeTool::isAutoRun() const
return m_isAutoRun;
}
+bool CMakeTool::autoCreateBuildDirectory() const
+{
+ return m_autoCreateBuildDirectory;
+}
+
QList<CMakeTool::Generator> CMakeTool::supportedGenerators() const
{
readInformation(QueryType::GENERATORS);
diff --git a/src/plugins/cmakeprojectmanager/cmaketool.h b/src/plugins/cmakeprojectmanager/cmaketool.h
index 5851c75bfc7..95556cefd70 100644
--- a/src/plugins/cmakeprojectmanager/cmaketool.h
+++ b/src/plugins/cmakeprojectmanager/cmaketool.h
@@ -90,9 +90,11 @@ public:
void setCMakeExecutable(const Utils::FileName &executable);
void setAutorun(bool autoRun);
+ void setAutoCreateBuildDirectory(bool autoBuildDir);
Utils::FileName cmakeExecutable() const;
bool isAutoRun() const;
+ bool autoCreateBuildDirectory() const;
QList<Generator> supportedGenerators() const;
TextEditor::Keywords keywords();
bool hasServerMode() const;
@@ -127,6 +129,7 @@ private:
bool m_isAutoRun = true;
bool m_isAutoDetected = false;
+ bool m_autoCreateBuildDirectory = false;
mutable bool m_didAttemptToRun = false;
mutable bool m_didRun = false;
diff --git a/src/plugins/cmakeprojectmanager/configmodel.cpp b/src/plugins/cmakeprojectmanager/configmodel.cpp
index 7336a2a7a2b..ff43d0cc63e 100644
--- a/src/plugins/cmakeprojectmanager/configmodel.cpp
+++ b/src/plugins/cmakeprojectmanager/configmodel.cpp
@@ -25,12 +25,15 @@
#include "configmodel.h"
+#include <utils/asconst.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <utils/theme/theme.h>
#include <QCoreApplication>
#include <QFont>
+#include <QString>
+#include <QSortFilterProxyModel>
namespace CMakeProjectManager {
@@ -41,215 +44,165 @@ static bool isTrue(const QString &value)
|| lower == QStringLiteral("1") || lower == QStringLiteral("yes");
}
-ConfigModel::ConfigModel(QObject *parent) : QAbstractTableModel(parent)
-{ }
-
-int ConfigModel::rowCount(const QModelIndex &parent) const
+ConfigModel::ConfigModel(QObject *parent) : Utils::TreeModel<>(parent)
{
- return parent.isValid() ? 0 : m_configuration.count();
+ setHeader({tr("Key"), tr("Value")});
}
-int ConfigModel::columnCount(const QModelIndex &parent) const
+QVariant ConfigModel::data(const QModelIndex &idx, int role) const
{
- return parent.isValid() ? 0 : 3;
+ // Hide/show groups according to "isAdvanced" setting:
+ Utils::TreeItem *item = static_cast<Utils::TreeItem *>(idx.internalPointer());
+ if (role == ItemIsAdvancedRole && item->childCount() > 0) {
+ const bool hasNormalChildren = item->findAnyChild([](const Utils::TreeItem *ti) {
+ if (auto cmti = dynamic_cast<const Internal::ConfigModelTreeItem*>(ti))
+ return !cmti->dataItem->isAdvanced;
+ return false;
+ }) != nullptr;
+ return hasNormalChildren ? "0" : "1";
+ }
+ return Utils::TreeModel<>::data(idx, role);
}
-Qt::ItemFlags ConfigModel::flags(const QModelIndex &index) const
+ConfigModel::~ConfigModel() = default;
+
+void ConfigModel::appendConfiguration(const QString &key,
+ const QString &value,
+ const ConfigModel::DataItem::Type type,
+ const QString &description,
+ const QStringList &values)
{
- QTC_ASSERT(index.model() == this, return Qt::NoItemFlags);
- QTC_ASSERT(index.isValid(), return Qt::NoItemFlags);
- QTC_ASSERT(index.column() >= 0 && index.column() < columnCount(QModelIndex()), return Qt::NoItemFlags);
- QTC_ASSERT(index.row() >= 0 && index.row() < rowCount(QModelIndex()), return Qt::NoItemFlags);
+ DataItem item;
+ item.key = key;
+ item.type = type;
+ item.value = value;
+ item.description = description;
+ item.values = values;
- const InternalDataItem &item = itemAtRow(index.row());
+ InternalDataItem internalItem(item);
+ internalItem.isUserNew = true;
- if (index.column() == 1) {
- if (item.type == DataItem::BOOLEAN)
- return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
- else
- return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
- } else {
- Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
- if (item.isUserNew)
- return flags |= Qt::ItemIsEditable;
- return flags;
- }
+ if (m_kitConfiguration.contains(key))
+ internalItem.kitValue = m_kitConfiguration.value(key);
+
+ m_configuration.append(internalItem);
+ setConfiguration(m_configuration);
}
-QVariant ConfigModel::data(const QModelIndex &index, int role) const
+void ConfigModel::setConfiguration(const QList<DataItem> &config)
{
- QTC_ASSERT(index.model() == this, return QVariant());
- QTC_ASSERT(index.isValid(), return QVariant());
- QTC_ASSERT(index.row() >= 0 && index.row() < rowCount(QModelIndex()), return QVariant());
- QTC_ASSERT(index.column() >= 0 && index.column() < columnCount(QModelIndex()), return QVariant());
+ setConfiguration(Utils::transform(config, [](const DataItem &di) { return InternalDataItem(di); }));
+}
- const InternalDataItem &item = m_configuration[index.row()];
+void ConfigModel::setKitConfiguration(const QHash<QString, QString> &kitConfig)
+{
+ m_kitConfiguration = kitConfig;
- if (index.column() < 2) {
- switch (role) {
- case ItemTypeRole:
- return item.type;
- case ItemValuesRole:
- return item.values;
+ for (InternalDataItem &i : m_configuration) {
+ if (m_kitConfiguration.contains(i.key)) {
+ i.kitValue = m_kitConfiguration.value(i.key);
}
}
+ setConfiguration(m_configuration);
+}
- switch (index.column()) {
- case 0:
- switch (role) {
- case Qt::DisplayRole:
- return item.key.isEmpty() ? tr("<UNSET>") : item.key;
- case Qt::EditRole:
- return item.key;
- case Qt::ToolTipRole:
- return item.toolTip();
- case Qt::FontRole: {
- QFont font;
- font.setItalic(item.isCMakeChanged);
- font.setBold(item.isUserNew);
- font.setStrikeOut(!item.inCMakeCache && !item.isUserNew);
- return font;
- }
- default:
- return QVariant();
- }
- case 1: {
- const QString value = item.currentValue();
- const QString kitValue = m_kitConfiguartion.value(item.key);
+void ConfigModel::flush()
+{
+ setConfiguration(QList<InternalDataItem>());
+}
- switch (role) {
- case Qt::CheckStateRole:
- return (item.type == DataItem::BOOLEAN)
- ? QVariant(isTrue(value) ? Qt::Checked : Qt::Unchecked) : QVariant();
- case Qt::DisplayRole:
- return value;
- case Qt::EditRole:
- return (item.type == DataItem::BOOLEAN) ? QVariant(isTrue(value)) : QVariant(value);
- case Qt::FontRole: {
- QFont font;
- font.setBold(item.isUserChanged || item.isUserNew);
- font.setItalic(item.isCMakeChanged);
- return font;
- }
- case Qt::ForegroundRole:
- return Utils::creatorTheme()->color((!kitValue.isNull() && kitValue != value)
- ? Utils::Theme::TextColorHighlight : Utils::Theme::TextColorNormal);
- case Qt::ToolTipRole: {
- QString tooltip = item.toolTip();
- const QString kitValue = m_kitConfiguartion.value(item.key);
- if (!kitValue.isNull()) {
- if (!tooltip.isEmpty())
- tooltip.append("<br>");
- tooltip.append(tr("Kit value: %1").arg(kitValue));
- }
- return tooltip;
- }
- default:
- return QVariant();
- }
- }
- case 2:
- switch (role) {
- case Qt::EditRole:
- return "0";
- case Qt::DisplayRole:
- return QString::fromLatin1(item.isAdvanced ? "1" : "0");
- case Qt::CheckStateRole:
- return item.isAdvanced ? Qt::Checked : Qt::Unchecked;
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
+void ConfigModel::resetAllChanges()
+{
+ const QList<InternalDataItem> tmp
+ = Utils::filtered(m_configuration,
+ [](const InternalDataItem &i) { return !i.isUserNew; });
+
+ setConfiguration(Utils::transform(tmp, [](const InternalDataItem &i) {
+ InternalDataItem ni(i);
+ ni.newValue.clear();
+ ni.isUserChanged = false;
+ return ni;
+ }));
}
-bool ConfigModel::setData(const QModelIndex &index, const QVariant &value, int role)
+bool ConfigModel::hasChanges() const
{
- QTC_ASSERT(index.model() == this, return false);
- QTC_ASSERT(index.isValid(), return false);
- QTC_ASSERT(index.row() >= 0 && index.row() < rowCount(QModelIndex()), return false);
- QTC_ASSERT(index.column() >= 0 && index.column() < 2, return false);
+ return Utils::contains(m_configuration, [](const InternalDataItem &i) { return i.isUserChanged || i.isUserNew; });
+}
- QString newValue = value.toString();
- if (role == Qt::CheckStateRole) {
- if (index.column() != 1)
- return false;
- newValue = QString::fromLatin1(value.toInt() == 0 ? "OFF" : "ON");
- } else if (role != Qt::EditRole) {
- return false;
- }
+bool ConfigModel::hasCMakeChanges() const
+{
+ return Utils::contains(m_configuration, [](const InternalDataItem &i) { return i.isCMakeChanged; });
+}
- InternalDataItem &item = itemAtRow(index.row());
- switch (index.column()) {
- case 0:
- if (!item.key.isEmpty() && !item.isUserNew)
- return false;
- item.key = newValue;
- item.isUserNew = true;
- item.isUserChanged = false;
- emit dataChanged(index, index);
- return true;
- case 1:
- if (item.value == newValue) {
- item.newValue.clear();
- item.isUserChanged = false;
- } else {
- item.newValue = newValue;
- item.isUserChanged = true;
- }
- emit dataChanged(index, index);
- return true;
- case 2:
- default:
+bool ConfigModel::canForceTo(const QModelIndex &idx, const ConfigModel::DataItem::Type type) const
+{
+ if (idx.model() != const_cast<ConfigModel *>(this) || idx.column() != 1)
return false;
- }
+ Utils::TreeItem *item = itemForIndex(idx);
+ auto cmti = dynamic_cast<Internal::ConfigModelTreeItem *>(item);
+ return cmti && (cmti->dataItem->type != type);
}
-QVariant ConfigModel::headerData(int section, Qt::Orientation orientation, int role) const
+void ConfigModel::forceTo(const QModelIndex &idx, const ConfigModel::DataItem::Type type)
{
- if (orientation == Qt::Vertical || role != Qt::DisplayRole)
- return QVariant();
- switch (section) {
- case 0:
- return tr("Setting");
- case 1:
- return tr("Value");
- case 2:
- return tr("Advanced");
- default:
- return QVariant();
- }
+ QTC_ASSERT(canForceTo(idx, type), return);
+ Utils::TreeItem *item = itemForIndex(idx);
+ auto cmti = dynamic_cast<Internal::ConfigModelTreeItem *>(item);
+
+ cmti->dataItem->type = type;
+ const QModelIndex valueIdx = idx.sibling(idx.row(), 1);
+ emit dataChanged(valueIdx, valueIdx);
}
-void ConfigModel::appendConfiguration(const QString &key,
- const QString &value,
- const ConfigModel::DataItem::Type type,
- const QString &description,
- const QStringList &values)
+ConfigModel::DataItem ConfigModel::dataItemFromIndex(const QModelIndex &idx)
{
- DataItem item;
- item.key = key;
- item.type = type;
- item.value = value;
- item.description = description;
- item.values = values;
-
- InternalDataItem internalItem(item);
- internalItem.isUserNew = true;
+ const QAbstractItemModel *m = idx.model();
+ QModelIndex mIdx = idx;
+ while (auto sfpm = qobject_cast<const QSortFilterProxyModel *>(m)) {
+ m = sfpm->sourceModel();
+ mIdx = sfpm->mapToSource(mIdx);
+ }
+ auto model = qobject_cast<const ConfigModel *>(m);
+ QTC_ASSERT(model, return DataItem());
+ const QModelIndex modelIdx = mIdx;
+
+ Utils::TreeItem *item = model->itemForIndex(modelIdx);
+ auto cmti = dynamic_cast<Internal::ConfigModelTreeItem *>(item);
+
+ if (cmti && cmti->dataItem) {
+ DataItem di;
+ di.key = cmti->dataItem->key;
+ di.type = cmti->dataItem->type;
+ di.isHidden = cmti->dataItem->isHidden;
+ di.isAdvanced = cmti->dataItem->isAdvanced;
+ di.inCMakeCache = cmti->dataItem->inCMakeCache;
+ di.value = cmti->dataItem->currentValue();
+ di.description = cmti->dataItem->description;
+ di.values = cmti->dataItem->values;
+
+ return di;
+ }
+ return DataItem();
+}
- beginResetModel();
- m_configuration.append(internalItem);
- endResetModel();
+QList<ConfigModel::DataItem> ConfigModel::configurationChanges() const
+{
+ const QList<InternalDataItem> tmp
+ = Utils::filtered(m_configuration, [](const InternalDataItem &i) {
+ return i.isUserChanged || i.isUserNew || !i.inCMakeCache;
+ });
+ return Utils::transform(tmp, [](const InternalDataItem &item) {
+ DataItem newItem(item);
+ if (item.isUserChanged)
+ newItem.value = item.newValue;
+ return newItem;
+ });
}
-void ConfigModel::setConfiguration(const QList<ConfigModel::DataItem> &config)
+void ConfigModel::setConfiguration(const QList<ConfigModel::InternalDataItem> &config)
{
- QList<DataItem> tmp = config;
- Utils::sort(tmp,
- [](const ConfigModel::DataItem &i, const ConfigModel::DataItem &j) {
- return i.key < j.key;
- });
+ QList<InternalDataItem> tmp = config;
auto newIt = tmp.constBegin();
auto newEndIt = tmp.constEnd();
auto oldIt = m_configuration.constBegin();
@@ -261,7 +214,7 @@ void ConfigModel::setConfiguration(const QList<ConfigModel::DataItem> &config)
++newIt;
} else if (newIt->key < oldIt->key) {
// Add new entry:
- result << InternalDataItem(*newIt);
+ result << *newIt;
++newIt;
} else if (newIt->key > oldIt->key) {
// Keep old user settings, but skip other entries:
@@ -287,93 +240,230 @@ void ConfigModel::setConfiguration(const QList<ConfigModel::DataItem> &config)
result << InternalDataItem(*newIt);
}
- beginResetModel();
m_configuration = result;
- endResetModel();
-}
-void ConfigModel::setKitConfiguration(const QHash<QString, QString> &kitConfig)
-{
- m_kitConfiguartion = kitConfig;
+ generateTree();
}
-void ConfigModel::flush()
+static QString prefix(const QString &key)
{
- beginResetModel();
- m_configuration.clear();
- endResetModel();
+ int pos = key.indexOf('_');
+ if (pos > 0)
+ return key.left(pos);
+ return key;
}
-void ConfigModel::resetAllChanges()
+void ConfigModel::generateTree()
{
- const QList<InternalDataItem> tmp
- = Utils::filtered(m_configuration,
- [](const InternalDataItem &i) { return !i.isUserNew; });
+ QList<QString> prefixList;
+
+ // Generate nodes for *all* prefixes
+ QHash<QString, QList<Utils::TreeItem *>> prefixes;
+ for (const InternalDataItem &di : m_configuration) {
+ const QString p = prefix(di.key);
+ if (!prefixes.contains(p)) {
+ prefixes.insert(p, {});
+ prefixList.append(p);
+ }
+ }
- beginResetModel();
- m_configuration = Utils::transform(tmp, [](const InternalDataItem &i) -> InternalDataItem {
- InternalDataItem ni(i);
- ni.newValue.clear();
- ni.isUserChanged = false;
- return ni;
- });
- endResetModel();
+ // Fill prefix nodes:
+ for (InternalDataItem &di : m_configuration)
+ prefixes[prefix(di.key)].append(new Internal::ConfigModelTreeItem(&di));
+
+ Utils::TreeItem *root = new Utils::TreeItem;
+
+ for (const QString &p : Utils::asConst(prefixList)) {
+ const QList<Utils::TreeItem *> &prefixItemList = prefixes.value(p);
+ QTC_ASSERT(!prefixItemList.isEmpty(), continue);
+
+ if (prefixItemList.count() == 1) {
+ root->appendChild(prefixItemList.at(0));
+ } else {
+ Utils::TreeItem *sti = new Utils::StaticTreeItem(p);
+ for (Utils::TreeItem *const ti : prefixItemList)
+ sti->appendChild(ti);
+ root->appendChild(sti);
+ }
+ prefixes.remove(p);
+ }
+ QTC_CHECK(prefixes.isEmpty());
+
+ setRootItem(root);
}
-bool ConfigModel::hasChanges() const
+ConfigModel::InternalDataItem::InternalDataItem(const ConfigModel::DataItem &item) : DataItem(item)
+{ }
+
+QString ConfigModel::InternalDataItem::toolTip() const
{
- return Utils::contains(m_configuration, [](const InternalDataItem &i) { return i.isUserChanged || i.isUserNew; });
+ QString desc = description;
+ if (isAdvanced)
+ desc += QCoreApplication::translate("CMakeProjectManager::ConfigModel", " (ADVANCED)");
+ QStringList tooltip(desc);
+ if (inCMakeCache) {
+ if (value != newValue)
+ tooltip << QCoreApplication::translate("CMakeProjectManager", "Current CMake: %1").arg(value);
+ } else {
+ tooltip << QCoreApplication::translate("CMakeProjectManager", "Not in CMakeCache.txt").arg(value);
+ }
+ if (!kitValue.isEmpty())
+ tooltip << QCoreApplication::translate("CMakeProjectManager::ConfigModel", "Current Kit: %1").arg(kitValue);
+ return tooltip.join("<br>");
}
-bool ConfigModel::hasCMakeChanges() const
+QString ConfigModel::InternalDataItem::currentValue() const
{
- return Utils::contains(m_configuration, [](const InternalDataItem &i) { return i.isCMakeChanged; });
+ return isUserChanged ? newValue : value;
}
-QList<ConfigModel::DataItem> ConfigModel::configurationChanges() const
+namespace Internal {
+
+ConfigModelTreeItem::~ConfigModelTreeItem() = default;
+
+QVariant ConfigModelTreeItem::data(int column, int role) const
{
- const QList<InternalDataItem> tmp
- = Utils::filtered(m_configuration, [](const InternalDataItem &i) {
- return i.isUserChanged || i.isUserNew || !i.inCMakeCache;
- });
- return Utils::transform(tmp, [](const InternalDataItem &item) {
- DataItem newItem(item);
- if (item.isUserChanged)
- newItem.value = item.newValue;
- return newItem;
- });
+ QTC_ASSERT(column >= 0 && column < 2, return QVariant());
+
+ QTC_ASSERT(dataItem, return QVariant());
+
+ if (firstChild()) {
+ // Node with children: Only ever show name:
+ if (column == 0)
+ return dataItem->key;
+ return QVariant();
+ }
+
+ // Leaf node:
+ if (role == ConfigModel::ItemIsAdvancedRole)
+ return dataItem->isAdvanced ? "1" : "0";
+
+ switch (column) {
+ case 0:
+ switch (role) {
+ case Qt::DisplayRole:
+ return dataItem->key.isEmpty() ? QCoreApplication::translate("CMakeProjectManager::ConfigModel", "<UNSET>") : dataItem->key;
+ case Qt::EditRole:
+ return dataItem->key;
+ case Qt::ToolTipRole:
+ return toolTip();
+ case Qt::FontRole: {
+ QFont font;
+ font.setItalic(dataItem->isCMakeChanged);
+ font.setBold(dataItem->isUserNew);
+ font.setStrikeOut(!dataItem->inCMakeCache && !dataItem->isUserNew);
+ return font;
+ }
+ default:
+ return QVariant();
+ }
+ case 1: {
+ const QString value = currentValue();
+
+ switch (role) {
+ case Qt::CheckStateRole:
+ return (dataItem->type == ConfigModel::DataItem::BOOLEAN)
+ ? QVariant(isTrue(value) ? Qt::Checked : Qt::Unchecked) : QVariant();
+ case Qt::DisplayRole:
+ return value;
+ case Qt::EditRole:
+ return (dataItem->type == ConfigModel::DataItem::BOOLEAN) ? QVariant(isTrue(value)) : QVariant(value);
+ case Qt::FontRole: {
+ QFont font;
+ font.setBold(dataItem->isUserChanged || dataItem->isUserNew);
+ font.setItalic(dataItem->isCMakeChanged);
+ return font;
+ }
+ case Qt::ForegroundRole:
+ return Utils::creatorTheme()->color((!dataItem->kitValue.isNull() && dataItem->kitValue != value)
+ ? Utils::Theme::TextColorHighlight : Utils::Theme::TextColorNormal);
+ case Qt::ToolTipRole: {
+ return toolTip();
+ }
+ default:
+ return QVariant();
+ }
+ }
+ default:
+ return QVariant();
+ }
}
-ConfigModel::InternalDataItem &ConfigModel::itemAtRow(int row)
+bool ConfigModelTreeItem::setData(int column, const QVariant &value, int role)
{
- QTC_CHECK(row >= 0);
- return m_configuration[row];
+ QTC_ASSERT(column >= 0 && column < 2, return false);
+ QTC_ASSERT(dataItem, return false);
+
+ QString newValue = value.toString();
+ if (role == Qt::CheckStateRole) {
+ if (column != 1)
+ return false;
+ newValue = QString::fromLatin1(value.toInt() == 0 ? "OFF" : "ON");
+ } else if (role != Qt::EditRole) {
+ return false;
+ }
+
+ switch (column) {
+ case 0:
+ if (!dataItem->key.isEmpty() && !dataItem->isUserNew)
+ return false;
+ dataItem->key = newValue;
+ dataItem->isUserNew = true;
+ return true;
+ case 1:
+ if (dataItem->value == newValue) {
+ dataItem->newValue.clear();
+ dataItem->isUserChanged = false;
+ } else {
+ dataItem->newValue = newValue;
+ dataItem->isUserChanged = true;
+ }
+ return true;
+ default:
+ return false;
+ }
}
-const ConfigModel::InternalDataItem &ConfigModel::itemAtRow(int row) const
+Qt::ItemFlags ConfigModelTreeItem::flags(int column) const
{
- QTC_CHECK(row >= 0);
- return m_configuration[row];
-}
+ if (column < 0 || column >= 2)
+ return Qt::NoItemFlags;
-ConfigModel::InternalDataItem::InternalDataItem(const ConfigModel::DataItem &item) : DataItem(item)
-{ }
+ QTC_ASSERT(dataItem, return Qt::NoItemFlags);
-QString ConfigModel::InternalDataItem::toolTip() const
+ if (column == 1) {
+ if (dataItem->type == ConfigModel::DataItem::BOOLEAN)
+ return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
+ else
+ return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
+ } else {
+ Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ if (dataItem->isUserNew)
+ return flags |= Qt::ItemIsEditable;
+ return flags;
+ }
+}
+
+QString ConfigModelTreeItem::toolTip() const
{
- QStringList tooltip(description);
- if (inCMakeCache) {
- if (value != newValue)
- tooltip << QCoreApplication::translate("CMakeProjectManager", "Current CMake: %1").arg(value);
+ QTC_ASSERT(dataItem, return QString());
+ QStringList tooltip(dataItem->description);
+ if (!dataItem->kitValue.isEmpty())
+ tooltip << QCoreApplication::translate("CMakeProjectManager", "Value requested by Kit: %1").arg(dataItem->kitValue);
+ if (dataItem->inCMakeCache) {
+ if (dataItem->value != dataItem->newValue)
+ tooltip << QCoreApplication::translate("CMakeProjectManager", "Current CMake: %1").arg(dataItem->value);
} else {
- tooltip << QCoreApplication::translate("CMakeProjectManager", "Not in CMakeCache.txt").arg(value);
+ tooltip << QCoreApplication::translate("CMakeProjectManager", "Not in CMakeCache.txt");
}
return tooltip.join("<br>");
}
-QString ConfigModel::InternalDataItem::currentValue() const
+QString ConfigModelTreeItem::currentValue() const
{
- return isUserChanged ? newValue : value;
+ QTC_ASSERT(dataItem, return QString());
+ return dataItem->isUserChanged ? dataItem->newValue : dataItem->value;
}
+} // namespace Internal
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/configmodel.h b/src/plugins/cmakeprojectmanager/configmodel.h
index f9629f702fa..626d487ac63 100644
--- a/src/plugins/cmakeprojectmanager/configmodel.h
+++ b/src/plugins/cmakeprojectmanager/configmodel.h
@@ -26,17 +26,19 @@
#pragma once
#include <QAbstractTableModel>
+#include <utils/treemodel.h>
namespace CMakeProjectManager {
-class ConfigModel : public QAbstractTableModel
+namespace Internal { class ConfigModelTreeItem; }
+
+class ConfigModel : public Utils::TreeModel<>
{
Q_OBJECT
public:
enum Roles {
- ItemTypeRole = Qt::UserRole,
- ItemValuesRole
+ ItemIsAdvancedRole = Qt::UserRole,
};
class DataItem {
@@ -54,14 +56,9 @@ public:
};
explicit ConfigModel(QObject *parent = nullptr);
+ ~ConfigModel() override;
- // QAbstractItemModel interface
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
- Qt::ItemFlags flags(const QModelIndex &index) const override;
- QVariant data(const QModelIndex &index, int role) const override;
- bool setData(const QModelIndex &index, const QVariant &value, int role) override;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+ QVariant data(const QModelIndex &idx, int role) const final;
void appendConfiguration(const QString &key,
const QString &value = QString(),
@@ -76,6 +73,11 @@ public:
bool hasChanges() const;
bool hasCMakeChanges() const;
+ bool canForceTo(const QModelIndex &idx, const DataItem::Type type) const;
+ void forceTo(const QModelIndex &idx, const DataItem::Type type);
+
+ static DataItem dataItemFromIndex(const QModelIndex &idx);
+
QList<DataItem> configurationChanges() const;
private:
@@ -92,12 +94,35 @@ private:
bool isUserNew = false;
bool isCMakeChanged = false;
QString newValue;
+ QString kitValue;
};
- InternalDataItem &itemAtRow(int row);
- const InternalDataItem &itemAtRow(int row) const;
+ void setConfiguration(const QList<InternalDataItem> &config);
+ void generateTree();
+
QList<InternalDataItem> m_configuration;
- QHash<QString, QString> m_kitConfiguartion;
+ QHash<QString, QString> m_kitConfiguration;
+
+ friend class Internal::ConfigModelTreeItem;
+};
+
+namespace Internal {
+
+class ConfigModelTreeItem : public Utils::TreeItem
+{
+public:
+ ConfigModelTreeItem(ConfigModel::InternalDataItem *di = nullptr) : dataItem(di) {}
+ virtual ~ConfigModelTreeItem() override;
+
+ QVariant data(int column, int role) const final;
+ bool setData(int column, const QVariant &data, int role) final;
+ Qt::ItemFlags flags(int column) const final;
+
+ QString toolTip() const;
+ QString currentValue() const;
+
+ ConfigModel::InternalDataItem *dataItem;
};
+} // namespace Internal
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp b/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp
index b2b19b837e2..f5d24b5174c 100644
--- a/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp
+++ b/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp
@@ -19,59 +19,117 @@
#include "configmodelitemdelegate.h"
#include "configmodel.h"
+#include <utils/asconst.h>
+#include <utils/pathchooser.h>
+
#include <QComboBox>
+#include <QCheckBox>
+#include <QLineEdit>
+#include <QPainter>
namespace CMakeProjectManager {
-ConfigModelItemDelegate::ConfigModelItemDelegate(QObject* parent)
+ConfigModelItemDelegate::ConfigModelItemDelegate(const Utils::FileName &base, QObject* parent)
: QStyledItemDelegate(parent)
+ , m_base(base)
{ }
-ConfigModelItemDelegate::~ConfigModelItemDelegate()
-{ }
+QWidget *ConfigModelItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
-QWidget* ConfigModelItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
- // ComboBox ony in column 2
- if (index.column() != 1)
- return QStyledItemDelegate::createEditor(parent, option, index);
-
- auto model = index.model();
- auto values = model->data(index, ConfigModel::ItemValuesRole).toStringList();
- if (values.isEmpty())
- return QStyledItemDelegate::createEditor(parent, option, index);
+ if (index.column() == 1) {
+ ConfigModel::DataItem data = ConfigModel::dataItemFromIndex(index);
+ if (data.type == ConfigModel::DataItem::FILE || data.type == ConfigModel::DataItem::DIRECTORY) {
+ auto edit = new Utils::PathChooser(parent);
+ edit->setFocusPolicy(Qt::StrongFocus);
+ edit->setBaseFileName(m_base);
+ edit->setAutoFillBackground(true);
+ if (data.type == ConfigModel::DataItem::FILE) {
+ edit->setExpectedKind(Utils::PathChooser::File);
+ edit->setPromptDialogTitle(tr("Select a file for %1").arg(data.key));
+ } else {
+ edit->setExpectedKind(Utils::PathChooser::Directory);
+ edit->setPromptDialogTitle(tr("Select a directory for %1").arg(data.key));
+ }
+ return edit;
+ } else if (!data.values.isEmpty()) {
+ auto edit = new QComboBox(parent);
+ edit->setFocusPolicy(Qt::StrongFocus);
+ for (const QString &s : Utils::asConst(data.values))
+ edit->addItem(s);
+ return edit;
+ } else if (data.type == ConfigModel::DataItem::BOOLEAN) {
+ auto edit = new QCheckBox(parent);
+ edit->setFocusPolicy(Qt::StrongFocus);
+ return edit;
+ } else if (data.type == ConfigModel::DataItem::STRING) {
+ auto edit = new QLineEdit(parent);
+ edit->setFocusPolicy(Qt::StrongFocus);
+ return edit;
+ }
+ }
- // Create the combobox and populate it
- auto cb = new QComboBox(parent);
- cb->addItems(values);
- cb->setEditable(true);
+ return QStyledItemDelegate::createEditor(parent, option, index);
+}
- return cb;
+void ConfigModelItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ if (index.column() == 1) {
+ ConfigModel::DataItem data = ConfigModel::dataItemFromIndex(index);
+ if (data.type == ConfigModel::DataItem::FILE || data.type == ConfigModel::DataItem::DIRECTORY) {
+ auto edit = static_cast<Utils::PathChooser *>(editor);
+ edit->setFileName(Utils::FileName::fromUserInput(data.value));
+ return;
+ } else if (!data.values.isEmpty()) {
+ auto edit = static_cast<QComboBox *>(editor);
+ edit->setCurrentText(data.value);
+ return;
+ } else if (data.type == ConfigModel::DataItem::BOOLEAN) {
+ auto edit = static_cast<QCheckBox *>(editor);
+ edit->setChecked(index.data(Qt::CheckStateRole).toBool());
+ edit->setText(data.value);
+ return;
+ } else if (data.type == ConfigModel::DataItem::STRING) {
+ auto edit = static_cast<QLineEdit *>(editor);
+ edit->setText(data.value);
+ return;
+ }
+ }
+ QStyledItemDelegate::setEditorData(editor, index);
}
-void ConfigModelItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
+void ConfigModelItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const
{
- if (QComboBox* cb = qobject_cast<QComboBox*>(editor)) {
- // get the index of the text in the combobox that matches the current value of the itenm
- QString currentText = index.data(Qt::EditRole).toString();
- int cbIndex = cb->findText(currentText);
- // if it is valid, adjust the combobox
- if (cbIndex >= 0)
- cb->setCurrentIndex(cbIndex);
- else
- cb->setEditText(currentText);
- } else {
- QStyledItemDelegate::setEditorData(editor, index);
+ if (index.column() == 1) {
+ ConfigModel::DataItem data = ConfigModel::dataItemFromIndex(index);
+ if (data.type == ConfigModel::DataItem::FILE || data.type == ConfigModel::DataItem::DIRECTORY) {
+ auto edit = static_cast<Utils::PathChooser *>(editor);
+ if (edit->rawPath() != data.value)
+ model->setData(index, edit->fileName().toUserOutput(), Qt::EditRole);
+ return;
+ } else if (!data.values.isEmpty()) {
+ auto edit = static_cast<QComboBox *>(editor);
+ model->setData(index, edit->currentText(), Qt::EditRole);
+ return;
+ } else if (data.type == ConfigModel::DataItem::BOOLEAN) {
+ auto edit = static_cast<QCheckBox *>(editor);
+ model->setData(index, edit->text(), Qt::EditRole);
+ } else if (data.type == ConfigModel::DataItem::STRING) {
+ auto edit = static_cast<QLineEdit *>(editor);
+ model->setData(index, edit->text(), Qt::EditRole);
+ }
}
+ QStyledItemDelegate::setModelData(editor, model, index);
}
-void ConfigModelItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
+QSize CMakeProjectManager::ConfigModelItemDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
{
- if (QComboBox* cb = qobject_cast<QComboBox*>(editor))
- // save the current text of the combo box as the current value of the item
- model->setData(index, cb->currentText(), Qt::EditRole);
- else
- QStyledItemDelegate::setModelData(editor, model, index);
+ Q_UNUSED(option);
+ Q_UNUSED(index);
+ return QSize(100, m_measurement.sizeHint().height());
}
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/configmodelitemdelegate.h b/src/plugins/cmakeprojectmanager/configmodelitemdelegate.h
index 8c20f7b8313..ce5571b6be2 100644
--- a/src/plugins/cmakeprojectmanager/configmodelitemdelegate.h
+++ b/src/plugins/cmakeprojectmanager/configmodelitemdelegate.h
@@ -18,20 +18,30 @@
#pragma once
+#include <QComboBox>
#include <QStyledItemDelegate>
+#include <utils/fileutils.h>
+
namespace CMakeProjectManager {
class ConfigModelItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
+
public:
- ConfigModelItemDelegate(QObject* parent=0);
- ~ConfigModelItemDelegate();
+ ConfigModelItemDelegate(const Utils::FileName &base, QObject *parent = nullptr);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const final;
+ void setEditorData(QWidget *editor, const QModelIndex &index) const final;
+ void setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const final;
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const final;
- QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
- void setEditorData(QWidget* editor, const QModelIndex& index) const override;
- void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
+private:
+ Utils::FileName m_base;
+ QComboBox m_measurement;
};
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp
index 04c69af89fc..7f85e1cae4c 100644
--- a/src/plugins/cmakeprojectmanager/servermodereader.cpp
+++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp
@@ -32,6 +32,7 @@
#include "servermode.h"
#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/fileiconprovider.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
@@ -44,6 +45,8 @@
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
+#include <QVector>
+
using namespace ProjectExplorer;
using namespace Utils;
@@ -56,7 +59,10 @@ const char CONFIGURE_TYPE[] = "configure";
const char CMAKE_INPUTS_TYPE[] = "cmakeInputs";
const char COMPUTE_TYPE[] = "compute";
+const char BACKTRACE_KEY[] = "backtrace";
+const char LINE_KEY[] = "line";
const char NAME_KEY[] = "name";
+const char PATH_KEY[] = "path";
const char SOURCE_DIRECTORY_KEY[] = "sourceDirectory";
const char SOURCES_KEY[] = "sources";
@@ -154,7 +160,7 @@ void ServerModeReader::resetData()
void ServerModeReader::parse(bool force)
{
emit configurationStarted();
- Core::MessageManager::write(tr("Starting to parse CMake project for Qt Creator."));
+ Core::MessageManager::write(tr("Starting to parse CMake project."));
QTC_ASSERT(m_cmakeServer, return);
QVariantMap extra;
@@ -307,10 +313,10 @@ void ServerModeReader::generateProjectTree(CMakeProjectNode *root,
const FileName path = fn->filePath();
if (path.fileName().compare("CMakeLists.txt", HostOsInfo::fileNameCaseSensitivity()) == 0)
cmakeLists.append(fn);
- else if (path.isChildOf(m_parameters.sourceDirectory))
- cmakeFilesSource.append(fn);
else if (path.isChildOf(m_parameters.buildDirectory))
cmakeFilesBuild.append(fn);
+ else if (path.isChildOf(m_parameters.sourceDirectory))
+ cmakeFilesSource.append(fn);
else
cmakeFilesOther.append(fn);
}
@@ -338,14 +344,6 @@ void ServerModeReader::updateCodeModel(CppTools::RawProjectParts &rpps)
int counter = 0;
for (const FileGroup *fg : Utils::asConst(m_fileGroups)) {
++counter;
- const QString defineArg
- = transform(fg->defines, [](const QString &s) -> QString {
- QString result = QString::fromLatin1("#define ") + s;
- int assignIndex = result.indexOf('=');
- if (assignIndex != -1)
- result[assignIndex] = ' ';
- return result;
- }).join('\n');
const QStringList flags = QtcProcess::splitArgs(fg->compileFlags);
const QStringList includes = transform(fg->includePaths, [](const IncludePath *ip) { return ip->path.toString(); });
@@ -353,7 +351,7 @@ void ServerModeReader::updateCodeModel(CppTools::RawProjectParts &rpps)
rpp.setProjectFileLocation(fg->target->sourceDirectory.toString() + "/CMakeLists.txt");
rpp.setBuildSystemTarget(fg->target->name);
rpp.setDisplayName(fg->target->name + QString::number(counter));
- rpp.setDefines(defineArg.toUtf8());
+ rpp.setMacros(fg->macros);
rpp.setIncludePaths(includes);
CppTools::RawProjectPartFlags cProjectFlags;
@@ -366,6 +364,9 @@ void ServerModeReader::updateCodeModel(CppTools::RawProjectParts &rpps)
rpp.setFiles(transform(fg->sources, &FileName::toString));
+ const bool isExecutable = fg->target->type == "EXECUTABLE";
+ rpp.setBuildTargetType(isExecutable ? CppTools::ProjectPart::Executable
+ : CppTools::ProjectPart::Library);
rpps.append(rpp);
}
@@ -509,6 +510,8 @@ ServerModeReader::Target *ServerModeReader::extractTargetData(const QVariantMap
target->sourceDirectory = FileName::fromString(data.value(SOURCE_DIRECTORY_KEY).toString());
target->buildDirectory = FileName::fromString(data.value("buildDirectory").toString());
+ target->crossReferences = extractCrossReferences(data.value("crossReferences").toMap());
+
QDir srcDir(target->sourceDirectory.toString());
target->type = data.value("type").toString();
@@ -534,7 +537,9 @@ ServerModeReader::FileGroup *ServerModeReader::extractFileGroupData(const QVaria
auto fileGroup = new FileGroup;
fileGroup->target = t;
fileGroup->compileFlags = data.value("compileFlags").toString();
- fileGroup->defines = data.value("defines").toStringList();
+ fileGroup->macros = Utils::transform<QVector>(data.value("defines").toStringList(), [](const QString &s) {
+ return ProjectExplorer::Macro::fromKeyValue(s);
+ });
fileGroup->includePaths = transform(data.value("includePath").toList(),
[](const QVariant &i) -> IncludePath* {
const QVariantMap iData = i.toMap();
@@ -553,6 +558,72 @@ ServerModeReader::FileGroup *ServerModeReader::extractFileGroupData(const QVaria
return fileGroup;
}
+QList<ServerModeReader::CrossReference *> ServerModeReader::extractCrossReferences(const QVariantMap &data)
+{
+ QList<CrossReference *> crossReferences;
+
+ if (data.isEmpty())
+ return crossReferences;
+
+ auto cr = std::make_unique<CrossReference>();
+ cr->backtrace = extractBacktrace(data.value(BACKTRACE_KEY, QVariantList()).toList());
+ QTC_ASSERT(!cr->backtrace.isEmpty(), return {});
+ crossReferences.append(cr.release());
+
+ const QVariantList related = data.value("relatedStatements", QVariantList()).toList();
+ for (const QVariant &relatedData : related) {
+ auto cr = std::make_unique<CrossReference>();
+
+ // extract information:
+ const QVariantMap map = relatedData.toMap();
+ const QString typeString = map.value("type", QString()).toString();
+ if (typeString.isEmpty())
+ cr->type = CrossReference::TARGET;
+ else if (typeString == "target_link_libraries")
+ cr->type = CrossReference::LIBRARIES;
+ else if (typeString == "target_compile_defines")
+ cr->type = CrossReference::DEFINES;
+ else if (typeString == "target_include_directories")
+ cr->type = CrossReference::INCLUDES;
+ else
+ cr->type = CrossReference::UNKNOWN;
+ cr->backtrace = extractBacktrace(map.value(BACKTRACE_KEY, QVariantList()).toList());
+
+ // sanity check:
+ if (cr->backtrace.isEmpty())
+ continue;
+
+ // store information:
+ crossReferences.append(cr.release());
+ }
+ return crossReferences;
+}
+
+ServerModeReader::BacktraceItem *ServerModeReader::extractBacktraceItem(const QVariantMap &data)
+{
+ QTC_ASSERT(!data.isEmpty(), return nullptr);
+ auto item = std::make_unique<BacktraceItem>();
+
+ item->line = data.value(LINE_KEY, -1).toInt();
+ item->name = data.value(NAME_KEY, QString()).toString();
+ item->path = data.value(PATH_KEY, QString()).toString();
+
+ QTC_ASSERT(!item->path.isEmpty(), return nullptr);
+ return item.release();
+}
+
+QList<ServerModeReader::BacktraceItem *> ServerModeReader::extractBacktrace(const QVariantList &data)
+{
+ QList<BacktraceItem *> btResult;
+ for (const QVariant &bt : data) {
+ BacktraceItem *btItem = extractBacktraceItem(bt.toMap());
+ QTC_ASSERT(btItem, continue);
+
+ btResult.append(btItem);
+ }
+ return btResult;
+}
+
void ServerModeReader::extractCMakeInputsData(const QVariantMap &data)
{
const FileName src = FileName::fromString(data.value(SOURCE_DIRECTORY_KEY).toString());
@@ -607,7 +678,7 @@ void ServerModeReader::fixTarget(ServerModeReader::Target *target) const
for (const FileGroup *group : Utils::asConst(target->fileGroups)) {
if (group->includePaths.isEmpty() && group->compileFlags.isEmpty()
- && group->defines.isEmpty())
+ && group->macros.isEmpty())
continue;
const FileGroup *fallback = languageFallbacks.value(group->language);
@@ -633,13 +704,13 @@ void ServerModeReader::fixTarget(ServerModeReader::Target *target) const
(*it)->language = fallback->language.isEmpty() ? "CXX" : fallback->language;
if (*it == fallback
- || !(*it)->includePaths.isEmpty() || !(*it)->defines.isEmpty()
+ || !(*it)->includePaths.isEmpty() || !(*it)->macros.isEmpty()
|| !(*it)->compileFlags.isEmpty())
continue;
for (const IncludePath *ip : fallback->includePaths)
(*it)->includePaths.append(new IncludePath(*ip));
- (*it)->defines = fallback->defines;
+ (*it)->macros = fallback->macros;
(*it)->compileFlags = fallback->compileFlags;
}
}
@@ -725,6 +796,36 @@ void ServerModeReader::addTargets(const QHash<Utils::FileName, ProjectExplorer::
CMakeTargetNode *tNode = createTargetNode(cmakeListsNodes, t->sourceDirectory, t->name);
QTC_ASSERT(tNode, qDebug() << "No target node for" << t->sourceDirectory << t->name; continue);
tNode->setTargetInformation(t->artifacts, t->type);
+ QList<FolderNode::LocationInfo> info;
+ // Set up a default target path:
+ FileName targetPath = t->sourceDirectory;
+ targetPath.appendPath("CMakeLists.txt");
+ for (CrossReference *cr : Utils::asConst(t->crossReferences)) {
+ BacktraceItem *bt = cr->backtrace.isEmpty() ? nullptr : cr->backtrace.at(0);
+ if (bt) {
+ const QString btName = bt->name.toLower();
+ const FileName path = Utils::FileName::fromUserInput(bt->path);
+ QString dn;
+ if (cr->type != CrossReference::TARGET) {
+ if (path == targetPath) {
+ if (bt->line >= 0)
+ dn = tr("%1 in line %3").arg(btName).arg(bt->line);
+ else
+ dn = tr("%1").arg(btName);
+ } else {
+ if (bt->line >= 0)
+ dn = tr("%1 in %2:%3").arg(btName, path.toUserOutput()).arg(bt->line);
+ else
+ dn = tr("%1 in %2").arg(btName, path.toUserOutput());
+ }
+ } else {
+ dn = tr("Target Definition");
+ targetPath = path;
+ }
+ info.append(FolderNode::LocationInfo(dn, path, bt->line));
+ }
+ }
+ tNode->setLocationInfo(info);
addFileGroups(tNode, t->sourceDirectory, t->buildDirectory, t->fileGroups, knownHeaderNodes);
}
}
@@ -778,8 +879,10 @@ void ServerModeReader::addHeaderNodes(ProjectNode *root, const QList<FileNode *>
if (root->isEmpty())
return;
+ static QIcon headerNodeIcon = Core::FileIconProvider::directoryIcon(ProjectExplorer::Constants::FILEOVERLAY_H);
auto headerNode = new VirtualFolderNode(root->filePath(), Node::DefaultPriority - 5);
headerNode->setDisplayName(tr("<Headers>"));
+ headerNode->setIcon(headerNodeIcon);
// knownHeaders are already listed in their targets:
QSet<Utils::FileName> seenHeaders = Utils::transform<QSet>(knownHeaders, &FileNode::filePath);
diff --git a/src/plugins/cmakeprojectmanager/servermodereader.h b/src/plugins/cmakeprojectmanager/servermodereader.h
index 461bc00e05e..f861483227a 100644
--- a/src/plugins/cmakeprojectmanager/servermodereader.h
+++ b/src/plugins/cmakeprojectmanager/servermodereader.h
@@ -29,6 +29,8 @@
#include "servermode.h"
#include "cmakeparser.h"
+#include <QList>
+
#include <memory>
namespace CMakeProjectManager {
@@ -84,15 +86,33 @@ private:
Target *target = nullptr;
QString compileFlags;
- QStringList defines;
+ ProjectExplorer::Macros macros;
QList<IncludePath *> includePaths;
QString language;
QList<Utils::FileName> sources;
bool isGenerated;
};
+ struct BacktraceItem {
+ int line = -1;
+ QString path;
+ QString name;
+ };
+
+ struct CrossReference {
+ ~CrossReference() { qDeleteAll(backtrace); backtrace.clear(); }
+ QList<BacktraceItem *> backtrace;
+ enum Type { TARGET, LIBRARIES, DEFINES, INCLUDES, UNKNOWN };
+ Type type;
+ };
+
struct Target {
- ~Target() { qDeleteAll(fileGroups); fileGroups.clear(); }
+ ~Target() {
+ qDeleteAll(fileGroups);
+ fileGroups.clear();
+ qDeleteAll(crossReferences);
+ crossReferences.clear();
+ }
Project *project = nullptr;
QString name;
@@ -101,6 +121,7 @@ private:
Utils::FileName sourceDirectory;
Utils::FileName buildDirectory;
QList<FileGroup *> fileGroups;
+ QList<CrossReference *> crossReferences;
};
struct Project {
@@ -115,6 +136,9 @@ private:
Project *extractProjectData(const QVariantMap &data, QSet<QString> &knownTargets);
Target *extractTargetData(const QVariantMap &data, Project *p, QSet<QString> &knownTargets);
FileGroup *extractFileGroupData(const QVariantMap &data, const QDir &srcDir, Target *t);
+ QList<CrossReference *> extractCrossReferences(const QVariantMap &data);
+ QList<BacktraceItem *> extractBacktrace(const QVariantList &data);
+ BacktraceItem *extractBacktraceItem(const QVariantMap &data);
void extractCMakeInputsData(const QVariantMap &data);
void extractCacheData(const QVariantMap &data);
diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
index eed99dad19c..2fbe12d28d0 100644
--- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp
+++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
@@ -384,10 +384,13 @@ void TeaLeafReader::updateCodeModel(CppTools::RawProjectParts &rpps)
cxxProjectFlags.commandLineFlags = cxxflags;
rpp.setFlagsForCxx(cxxProjectFlags);
- rpp.setDefines(cbt.defines);
+ rpp.setMacros(cbt.macros);
rpp.setDisplayName(cbt.title);
rpp.setFiles(transform(cbt.files, [](const FileName &fn) { return fn.toString(); }));
+ const bool isExecutable = cbt.targetType == ExecutableType;
+ rpp.setBuildTargetType(isExecutable ? CppTools::ProjectPart::Executable
+ : CppTools::ProjectPart::Library);
rpps.append(rpp);
}
}
@@ -554,7 +557,7 @@ void TeaLeafReader::processCMakeOutput()
{
static QString rest;
rest = lineSplit(rest, m_cmakeProcess->readAllStandardOutput(),
- [this](const QString &s) { MessageManager::write(s); });
+ [](const QString &s) { MessageManager::write(s); });
}
void TeaLeafReader::processCMakeError()
diff --git a/src/plugins/coreplugin/actionmanager/commandsfile.cpp b/src/plugins/coreplugin/actionmanager/commandsfile.cpp
index 5eba33f8bd0..d6bbd7f2cbb 100644
--- a/src/plugins/coreplugin/actionmanager/commandsfile.cpp
+++ b/src/plugins/coreplugin/actionmanager/commandsfile.cpp
@@ -26,11 +26,10 @@
#include "commandsfile.h"
#include "command_p.h"
#include <coreplugin/dialogs/shortcutsettings.h>
+#include <coreplugin/icore.h>
#include <app/app_version.h>
-
#include <utils/qtcassert.h>
-
#include <utils/fileutils.h>
#include <QKeySequence>
@@ -137,8 +136,8 @@ bool CommandsFile::exportCommands(const QList<ShortcutItem *> &items)
w.setAutoFormattingIndent(1); // Historical, used to be QDom.
w.writeStartDocument();
w.writeDTD(QLatin1String("<!DOCTYPE KeyboardMappingScheme>"));
- w.writeComment(QString::fromLatin1(" Written by Qt Creator %1, %2. ").
- arg(QLatin1String(Constants::IDE_VERSION_LONG),
+ w.writeComment(QString::fromLatin1(" Written by %1, %2. ").
+ arg(ICore::versionString(),
QDateTime::currentDateTime().toString(Qt::ISODate)));
w.writeStartElement(ctx.mappingElement);
foreach (const ShortcutItem *item, items) {
diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h
index 78c7ae6011a..aa9b9fbbc25 100644
--- a/src/plugins/coreplugin/coreconstants.h
+++ b/src/plugins/coreplugin/coreconstants.h
@@ -207,7 +207,8 @@ const char TR_CLEAR_MENU[] = QT_TRANSLATE_NOOP("Core", "Clear Menu");
const char DEFAULT_BUILD_DIRECTORY[] = "../%{JS: Util.asciify(\"build-%{CurrentProject:Name}-%{CurrentKit:FileSystemName}-%{CurrentBuild:Name}\")}";
-const int TARGET_ICON_SIZE = 32;
+const int MODEBAR_ICON_SIZE = 34;
+const int DEFAULT_MAX_LINE_COUNT = 100000;
} // namespace Constants
} // namespace Core
diff --git a/src/plugins/coreplugin/corejsextensions.cpp b/src/plugins/coreplugin/corejsextensions.cpp
index 21017f8aacc..7398d60a944 100644
--- a/src/plugins/coreplugin/corejsextensions.cpp
+++ b/src/plugins/coreplugin/corejsextensions.cpp
@@ -144,7 +144,7 @@ QString UtilsJsExtension::mktemp(const QString &pattern) const
QString UtilsJsExtension::asciify(const QString &input) const
{
QString result;
- for (const QChar c : input) {
+ for (const QChar &c : input) {
if (c.isPrint() && c.unicode() < 128)
result.append(c);
else
diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp
index c005b90eaa9..b644906cd79 100644
--- a/src/plugins/coreplugin/coreplugin.cpp
+++ b/src/plugins/coreplugin/coreplugin.cpp
@@ -44,6 +44,7 @@
#include <coreplugin/coreconstants.h>
#include <coreplugin/fileutils.h>
+#include <app/app_version.h>
#include <extensionsystem/pluginerroroverview.h>
#include <extensionsystem/pluginmanager.h>
#include <extensionsystem/pluginspec.h>
@@ -183,18 +184,25 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage)
expander->registerVariable("CurrentTime:Locale", tr("The current time (Locale)."),
[]() { return QTime::currentTime().toString(Qt::DefaultLocaleShortDate); });
expander->registerVariable("Config:DefaultProjectDirectory", tr("The configured default directory for projects."),
- []() { return DocumentManager::projectsDirectory(); });
+ []() { return DocumentManager::projectsDirectory().toString(); });
expander->registerVariable("Config:LastFileDialogDirectory", tr("The directory last visited in a file dialog."),
[]() { return DocumentManager::fileDialogLastVisitedDirectory(); });
- expander->registerVariable("HostOs:isWindows", tr("Is Qt Creator running on Windows?"),
+ expander->registerVariable("HostOs:isWindows",
+ tr("Is %1 running on Windows?").arg(Constants::IDE_DISPLAY_NAME),
[]() { return QVariant(Utils::HostOsInfo::isWindowsHost()).toString(); });
- expander->registerVariable("HostOs:isOSX", tr("Is Qt Creator running on OS X?"),
+ expander->registerVariable("HostOs:isOSX",
+ tr("Is %1 running on OS X?").arg(Constants::IDE_DISPLAY_NAME),
[]() { return QVariant(Utils::HostOsInfo::isMacHost()).toString(); });
- expander->registerVariable("HostOs:isLinux", tr("Is Qt Creator running on Linux?"),
+ expander->registerVariable("HostOs:isLinux",
+ tr("Is %1 running on Linux?").arg(Constants::IDE_DISPLAY_NAME),
[]() { return QVariant(Utils::HostOsInfo::isLinuxHost()).toString(); });
- expander->registerVariable("HostOs:isUnix", tr("Is Qt Creator running on any unix-based platform?"),
+ expander->registerVariable("HostOs:isUnix",
+ tr("Is %1 running on any unix-based platform?")
+ .arg(Constants::IDE_DISPLAY_NAME),
[]() { return QVariant(Utils::HostOsInfo::isAnyUnixHost()).toString(); });
- expander->registerVariable("IDE:ResourcePath", tr("The directory where Qt Creator finds its pre-installed resources."),
+ expander->registerVariable("IDE:ResourcePath",
+ tr("The directory where %1 finds its pre-installed resources.")
+ .arg(Constants::IDE_DISPLAY_NAME),
[]() { return ICore::resourcePath(); });
expander->registerPrefix("CurrentDate:", tr("The current date (QDate formatstring)."),
[](const QString &fmt) { return QDate::currentDate().toString(fmt); });
@@ -203,7 +211,7 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage)
expander->registerVariable("UUID", tr("Generate a new UUID."),
[]() { return QUuid::createUuid().toString(); });
- expander->registerPrefix("#:", tr("A comment."), [](const QString &) { return QStringLiteral(""); });
+ expander->registerPrefix("#:", tr("A comment."), [](const QString &) { return QString(); });
// Make sure all wizards are there when the user might access the keyboard shortcuts:
connect(ICore::instance(), &ICore::optionsDialogRequested, []() { IWizardFactory::allWizardFactories(); });
diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp
index 30da372eaf9..c4744e75931 100644
--- a/src/plugins/coreplugin/documentmanager.cpp
+++ b/src/plugins/coreplugin/documentmanager.cpp
@@ -54,6 +54,7 @@
#include <QFile>
#include <QFileInfo>
#include <QFileSystemWatcher>
+#include <QLoggingCategory>
#include <QSettings>
#include <QTimer>
#include <QAction>
@@ -62,6 +63,8 @@
#include <QMenu>
#include <QMessageBox>
+Q_LOGGING_CATEGORY(log, "qtc.core.documentmanager")
+
/*!
\class Core::DocumentManager
\mainclass
@@ -124,6 +127,7 @@ struct FileStateItem
struct FileState
{
+ QString watchedFilePath;
QMap<IDocument *, FileStateItem> lastUpdatedState;
FileStateItem expected;
};
@@ -140,11 +144,11 @@ public:
void checkOnNextFocusChange();
void onApplicationFocusChange();
- QMap<QString, FileState> m_states;
- QSet<QString> m_changedFiles;
+ QMap<QString, FileState> m_states; // filePathKey -> FileState
+ QSet<QString> m_changedFiles; // watched file paths collected from file watcher notifications
QList<IDocument *> m_documentsWithoutWatch;
- QMap<IDocument *, QStringList> m_documentsWithWatch;
- QSet<QString> m_expectedFileNames;
+ QMap<IDocument *, QStringList> m_documentsWithWatch; // document -> list of filePathKeys
+ QSet<QString> m_expectedFileNames; // set of file names without normalization
QList<DocumentManager::RecentFile> m_recentFiles;
static const int m_maxRecentFiles = 7;
@@ -155,7 +159,7 @@ public:
bool m_checkOnFocusChange = false;
QString m_lastVisitedDirectory;
QString m_defaultLocationForNewFiles;
- QString m_projectsDirectory;
+ FileName m_projectsDirectory;
bool m_useProjectsDirectory;
QString m_buildDirectory;
// When we are calling into an IDocument
@@ -234,7 +238,7 @@ DocumentManager::DocumentManager(QObject *parent)
readSettings();
if (d->m_useProjectsDirectory)
- setFileDialogLastVisitedDirectory(d->m_projectsDirectory);
+ setFileDialogLastVisitedDirectory(d->m_projectsDirectory.toString());
}
DocumentManager::~DocumentManager()
@@ -248,28 +252,34 @@ DocumentManager *DocumentManager::instance()
}
/* only called from addFileInfo(IDocument *) */
-static void addFileInfo(const QString &fileName, IDocument *document, bool isLink)
+static void addFileInfo(IDocument *document, const QString &filePath,
+ const QString &filePathKey, bool isLink)
{
FileStateItem state;
- if (!fileName.isEmpty()) {
- const QFileInfo fi(fileName);
+ if (!filePath.isEmpty()) {
+ qCDebug(log) << "adding document for" << filePath << "(" << filePathKey << ")";
+ const QFileInfo fi(filePath);
state.modified = fi.lastModified();
state.permissions = fi.permissions();
// Add watcher if we don't have that already
- if (!d->m_states.contains(fileName))
- d->m_states.insert(fileName, FileState());
-
- QFileSystemWatcher *watcher = 0;
- if (isLink)
- watcher = d->linkWatcher();
- else
- watcher = d->fileWatcher();
- if (!watcher->files().contains(fileName))
- watcher->addPath(fileName);
+ if (!d->m_states.contains(filePathKey)) {
+ FileState state;
+ state.watchedFilePath = filePath;
+ d->m_states.insert(filePathKey, state);
+
+ qCDebug(log) << "adding (" << (isLink ? "link" : "full") << ") watch for"
+ << state.watchedFilePath;
+ QFileSystemWatcher *watcher = 0;
+ if (isLink)
+ watcher = d->linkWatcher();
+ else
+ watcher = d->fileWatcher();
+ watcher->addPath(state.watchedFilePath);
+ }
- d->m_states[fileName].lastUpdatedState.insert(document, state);
+ d->m_states[filePathKey].lastUpdatedState.insert(document, state);
}
- d->m_documentsWithWatch[document].append(fileName); // inserts a new QStringList if not already there
+ d->m_documentsWithWatch[document].append(filePathKey); // inserts a new QStringList if not already there
}
/* Adds the IDocument's file and possibly it's final link target to both m_states
@@ -278,11 +288,19 @@ static void addFileInfo(const QString &fileName, IDocument *document, bool isLin
(The added file names are guaranteed to be absolute and cleaned.) */
static void addFileInfo(IDocument *document)
{
- const QString fixedName = DocumentManager::fixFileName(document->filePath().toString(), DocumentManager::KeepLinks);
- const QString fixedResolvedName = DocumentManager::fixFileName(document->filePath().toString(), DocumentManager::ResolveLinks);
- addFileInfo(fixedResolvedName, document, false);
- if (fixedName != fixedResolvedName)
- addFileInfo(fixedName, document, true);
+ const QString documentFilePath = document->filePath().toString();
+ const QString filePath = DocumentManager::cleanAbsoluteFilePath(
+ documentFilePath, DocumentManager::KeepLinks);
+ const QString filePathKey = DocumentManager::filePathKey(
+ documentFilePath, DocumentManager::KeepLinks);
+ const QString resolvedFilePath = DocumentManager::cleanAbsoluteFilePath(
+ documentFilePath, DocumentManager::ResolveLinks);
+ const QString resolvedFilePathKey = DocumentManager::filePathKey(
+ documentFilePath, DocumentManager::ResolveLinks);
+ const bool isLink = filePath != resolvedFilePath;
+ addFileInfo(document, filePath, filePathKey, isLink);
+ if (isLink)
+ addFileInfo(document, resolvedFilePath, resolvedFilePathKey, false);
}
/*!
@@ -330,12 +348,18 @@ static void removeFileInfo(IDocument *document)
foreach (const QString &fileName, d->m_documentsWithWatch.value(document)) {
if (!d->m_states.contains(fileName))
continue;
+ qCDebug(log) << "removing document (" << fileName << ")";
d->m_states[fileName].lastUpdatedState.remove(document);
if (d->m_states.value(fileName).lastUpdatedState.isEmpty()) {
- if (d->m_fileWatcher && d->m_fileWatcher->files().contains(fileName))
- d->m_fileWatcher->removePath(fileName);
- if (d->m_linkWatcher && d->m_linkWatcher->files().contains(fileName))
- d->m_linkWatcher->removePath(fileName);
+ const QString &watchedFilePath = d->m_states.value(fileName).watchedFilePath;
+ if (d->m_fileWatcher && d->m_fileWatcher->files().contains(watchedFilePath)) {
+ qCDebug(log) << "removing watch for" << watchedFilePath;
+ d->m_fileWatcher->removePath(watchedFilePath);
+ }
+ if (d->m_linkWatcher && d->m_linkWatcher->files().contains(watchedFilePath)) {
+ qCDebug(log) << "removing watch for" << watchedFilePath;
+ d->m_linkWatcher->removePath(watchedFilePath);
+ }
d->m_states.remove(fileName);
}
}
@@ -388,14 +412,14 @@ static void dump()
*/
void DocumentManager::renamedFile(const QString &from, const QString &to)
{
- const QString &fixedFrom = fixFileName(from, KeepLinks);
+ const QString &fromKey = filePathKey(from, KeepLinks);
// gather the list of IDocuments
QList<IDocument *> documentsToRename;
QMapIterator<IDocument *, QStringList> it(d->m_documentsWithWatch);
while (it.hasNext()) {
it.next();
- if (it.value().contains(fixedFrom))
+ if (it.value().contains(fromKey))
documentsToRename.append(it.key());
}
@@ -478,23 +502,29 @@ void DocumentManager::checkForNewFileName()
}
/*!
- Returns a guaranteed cleaned path in native form. If the file exists,
- it will either be a cleaned absolute file path (fixmode == KeepLinks), or
- a cleaned canonical file path (fixmode == ResolveLinks).
+ Returns a guaranteed cleaned absolute file path for \a filePath in portable form.
+ Resolves symlinks if \a resolveMode is ResolveLinks.
*/
-QString DocumentManager::fixFileName(const QString &fileName, FixMode fixmode)
+QString DocumentManager::cleanAbsoluteFilePath(const QString &filePath, ResolveMode resolveMode)
{
- QString s = fileName;
- QFileInfo fi(s);
- if (fi.exists()) {
- if (fixmode == ResolveLinks)
- s = fi.canonicalFilePath();
- else
- s = QDir::cleanPath(fi.absoluteFilePath());
- } else {
- s = QDir::cleanPath(s);
+ QFileInfo fi(QDir::fromNativeSeparators(filePath));
+ if (fi.exists() && resolveMode == ResolveLinks) {
+ // if the filePath is no link, we want this method to return the same for both ResolveModes
+ // so wrap with absoluteFilePath because that forces drive letters upper case
+ return QFileInfo(fi.canonicalFilePath()).absoluteFilePath();
}
- s = QDir::toNativeSeparators(s);
+ return QDir::cleanPath(fi.absoluteFilePath());
+}
+
+/*!
+ Returns a representation of \a filePath that can be used as a key for maps.
+ (A cleaned absolute file path in portable form, that is all lowercase
+ if the file system is case insensitive (in the host OS settings).)
+ Resolves symlinks if \a resolveMode is ResolveLinks.
+*/
+QString DocumentManager::filePathKey(const QString &filePath, ResolveMode resolveMode)
+{
+ QString s = cleanAbsoluteFilePath(filePath, resolveMode);
if (HostOsInfo::fileNameCaseSensitivity() == Qt::CaseInsensitive)
s = s.toLower();
return s;
@@ -533,14 +563,14 @@ void DocumentManager::expectFileChange(const QString &fileName)
}
/* only called from unblock and unexpect file change functions */
-static void updateExpectedState(const QString &fileName)
+static void updateExpectedState(const QString &filePathKey)
{
- if (fileName.isEmpty())
+ if (filePathKey.isEmpty())
return;
- if (d->m_states.contains(fileName)) {
- QFileInfo fi(fileName);
- d->m_states[fileName].expected.modified = fi.lastModified();
- d->m_states[fileName].expected.permissions = fi.permissions();
+ if (d->m_states.contains(filePathKey)) {
+ QFileInfo fi(d->m_states.value(filePathKey).watchedFilePath);
+ d->m_states[filePathKey].expected.modified = fi.lastModified();
+ d->m_states[filePathKey].expected.permissions = fi.permissions();
}
}
@@ -559,11 +589,11 @@ void DocumentManager::unexpectFileChange(const QString &fileName)
if (fileName.isEmpty())
return;
d->m_expectedFileNames.remove(fileName);
- const QString fixedName = fixFileName(fileName, KeepLinks);
- updateExpectedState(fixedName);
- const QString fixedResolvedName = fixFileName(fileName, ResolveLinks);
- if (fixedName != fixedResolvedName)
- updateExpectedState(fixedResolvedName);
+ const QString cleanAbsFilePath = cleanAbsoluteFilePath(fileName, KeepLinks);
+ updateExpectedState(filePathKey(fileName, KeepLinks));
+ const QString resolvedCleanAbsFilePath = cleanAbsoluteFilePath(fileName, ResolveLinks);
+ if (cleanAbsFilePath != resolvedCleanAbsFilePath)
+ updateExpectedState(filePathKey(fileName, ResolveLinks));
}
static bool saveModifiedFilesHelper(const QList<IDocument *> &documents,
@@ -907,8 +937,9 @@ void DocumentManager::changedFile(const QString &fileName)
{
const bool wasempty = d->m_changedFiles.isEmpty();
- if (d->m_states.contains(fileName))
+ if (d->m_states.contains(filePathKey(fileName, KeepLinks)))
d->m_changedFiles.insert(fileName);
+ qCDebug(log) << "file change notification for" << fileName;
if (wasempty && !d->m_changedFiles.isEmpty())
QTimer::singleShot(200, this, &DocumentManager::checkForReload);
@@ -948,18 +979,23 @@ void DocumentManager::checkForReload()
QMap<QString, IDocument::ChangeType> changeTypes;
QSet<IDocument *> changedIDocuments;
foreach (const QString &fileName, d->m_changedFiles) {
+ const QString fileKey = filePathKey(fileName, KeepLinks);
+ qCDebug(log) << "handling file change for" << fileName << "(" << fileKey << ")";
IDocument::ChangeType type = IDocument::TypeContents;
FileStateItem state;
QFileInfo fi(fileName);
if (!fi.exists()) {
+ qCDebug(log) << "file was removed";
type = IDocument::TypeRemoved;
} else {
state.modified = fi.lastModified();
state.permissions = fi.permissions();
+ qCDebug(log) << "file was modified, time:" << state.modified
+ << "permissions: " << state.permissions;
}
- currentStates.insert(fileName, state);
- changeTypes.insert(fileName, type);
- foreach (IDocument *document, d->m_states.value(fileName).lastUpdatedState.keys())
+ currentStates.insert(fileKey, state);
+ changeTypes.insert(fileKey, type);
+ foreach (IDocument *document, d->m_states.value(fileKey).lastUpdatedState.keys())
changedIDocuments.insert(document);
}
@@ -971,13 +1007,13 @@ void DocumentManager::checkForReload()
// we can't do the "resolving" already in expectFileChange, because
// if the resolved names are different when unexpectFileChange is called
// we would end up with never-unexpected file names
- QSet<QString> expectedFileNames;
+ QSet<QString> expectedFileKeys;
foreach (const QString &fileName, d->m_expectedFileNames) {
- const QString fixedName = fixFileName(fileName, KeepLinks);
- expectedFileNames.insert(fixedName);
- const QString fixedResolvedName = fixFileName(fileName, ResolveLinks);
- if (fixedName != fixedResolvedName)
- expectedFileNames.insert(fixedResolvedName);
+ const QString cleanAbsFilePath = cleanAbsoluteFilePath(fileName, KeepLinks);
+ expectedFileKeys.insert(filePathKey(fileName, KeepLinks));
+ const QString resolvedCleanAbsFilePath = cleanAbsoluteFilePath(fileName, ResolveLinks);
+ if (cleanAbsFilePath != resolvedCleanAbsFilePath)
+ expectedFileKeys.insert(filePathKey(fileName, ResolveLinks));
}
// handle the IDocuments
@@ -990,14 +1026,14 @@ void DocumentManager::checkForReload()
// find out the type & behavior from the two possible files
// behavior is internal if all changes are expected (and none removed)
// type is "max" of both types (remove > contents > permissions)
- foreach (const QString & fileName, d->m_documentsWithWatch.value(document)) {
+ foreach (const QString &fileKey, d->m_documentsWithWatch.value(document)) {
// was the file reported?
- if (!currentStates.contains(fileName))
+ if (!currentStates.contains(fileKey))
continue;
- FileStateItem currentState = currentStates.value(fileName);
- FileStateItem expectedState = d->m_states.value(fileName).expected;
- FileStateItem lastState = d->m_states.value(fileName).lastUpdatedState.value(document);
+ FileStateItem currentState = currentStates.value(fileKey);
+ FileStateItem expectedState = d->m_states.value(fileKey).expected;
+ FileStateItem lastState = d->m_states.value(fileKey).lastUpdatedState.value(document);
// did the file actually change?
if (lastState.modified == currentState.modified && lastState.permissions == currentState.permissions)
@@ -1010,12 +1046,12 @@ void DocumentManager::checkForReload()
// was the change unexpected?
if ((currentState.modified != expectedState.modified || currentState.permissions != expectedState.permissions)
- && !expectedFileNames.contains(fileName)) {
+ && !expectedFileKeys.contains(fileKey)) {
trigger = IDocument::TriggerExternal;
}
// find out the type
- IDocument::ChangeType fileChange = changeTypes.value(fileName);
+ IDocument::ChangeType fileChange = changeTypes.value(fileKey);
if (fileChange == IDocument::TypeRemoved)
type = IDocument::TypeRemoved;
else if (fileChange == IDocument::TypeContents && type == IDocument::TypePermissions)
@@ -1179,12 +1215,12 @@ void DocumentManager::addToRecentFiles(const QString &fileName, Id editorId)
{
if (fileName.isEmpty())
return;
- QString unifiedForm(fixFileName(fileName, KeepLinks));
+ QString fileKey = filePathKey(fileName, KeepLinks);
QMutableListIterator<RecentFile > it(d->m_recentFiles);
while (it.hasNext()) {
RecentFile file = it.next();
- QString recentUnifiedForm(fixFileName(file.first, DocumentManager::KeepLinks));
- if (unifiedForm == recentUnifiedForm)
+ QString recentFileKey(filePathKey(file.first, DocumentManager::KeepLinks));
+ if (fileKey == recentFileKey)
it.remove();
}
if (d->m_recentFiles.count() > d->m_maxRecentFiles)
@@ -1224,7 +1260,7 @@ void DocumentManager::saveSettings()
s->setValue(QLatin1String(editorsKeyC), recentEditorIds);
s->endGroup();
s->beginGroup(QLatin1String(directoryGroupC));
- s->setValue(QLatin1String(projectDirectoryKeyC), d->m_projectsDirectory);
+ s->setValue(QLatin1String(projectDirectoryKeyC), d->m_projectsDirectory.toString());
s->setValue(QLatin1String(useProjectDirectoryKeyC), d->m_useProjectsDirectory);
s->setValue(QLatin1String(buildDirectoryKeyC), d->m_buildDirectory);
s->endGroup();
@@ -1250,12 +1286,12 @@ void readSettings()
}
s->beginGroup(QLatin1String(directoryGroupC));
- const QString settingsProjectDir = s->value(QLatin1String(projectDirectoryKeyC),
- QString()).toString();
- if (!settingsProjectDir.isEmpty() && QFileInfo(settingsProjectDir).isDir())
+ const FileName settingsProjectDir = FileName::fromString(s->value(QLatin1String(projectDirectoryKeyC),
+ QString()).toString());
+ if (!settingsProjectDir.isEmpty() && settingsProjectDir.toFileInfo().isDir())
d->m_projectsDirectory = settingsProjectDir;
else
- d->m_projectsDirectory = PathChooser::homePath();
+ d->m_projectsDirectory = FileName::fromString(PathChooser::homePath());
d->m_useProjectsDirectory = s->value(QLatin1String(useProjectDirectoryKeyC),
d->m_useProjectsDirectory).toBool();
@@ -1315,7 +1351,7 @@ void DocumentManager::setDefaultLocationForNewFiles(const QString &location)
\sa setProjectsDirectory, setUseProjectsDirectory
*/
-QString DocumentManager::projectsDirectory()
+FileName DocumentManager::projectsDirectory()
{
return d->m_projectsDirectory;
}
@@ -1327,9 +1363,9 @@ QString DocumentManager::projectsDirectory()
\sa projectsDirectory, useProjectsDirectory
*/
-void DocumentManager::setProjectsDirectory(const QString &dir)
+void DocumentManager::setProjectsDirectory(const FileName &directory)
{
- d->m_projectsDirectory = dir;
+ d->m_projectsDirectory = directory;
}
/*!
diff --git a/src/plugins/coreplugin/documentmanager.h b/src/plugins/coreplugin/documentmanager.h
index b259dfcaa53..d8a243ea6f6 100644
--- a/src/plugins/coreplugin/documentmanager.h
+++ b/src/plugins/coreplugin/documentmanager.h
@@ -53,7 +53,7 @@ class CORE_EXPORT DocumentManager : public QObject
{
Q_OBJECT
public:
- enum FixMode {
+ enum ResolveMode {
ResolveLinks,
KeepLinks
};
@@ -81,7 +81,8 @@ public:
static void saveSettings();
// helper functions
- static QString fixFileName(const QString &fileName, FixMode fixmode);
+ static QString cleanAbsoluteFilePath(const QString &filePath, ResolveMode resolveMode);
+ static QString filePathKey(const QString &filePath, ResolveMode resolveMode);
static bool saveDocument(IDocument *document, const QString &fileName = QString(), bool *isReadOnly = 0);
@@ -127,8 +128,8 @@ public:
static bool useProjectsDirectory();
static void setUseProjectsDirectory(bool);
- static QString projectsDirectory();
- static void setProjectsDirectory(const QString &);
+ static Utils::FileName projectsDirectory();
+ static void setProjectsDirectory(const Utils::FileName &directory);
static QString buildDirectory();
static void setBuildDirectory(const QString &directory);
diff --git a/src/plugins/coreplugin/editormanager/documentmodel.cpp b/src/plugins/coreplugin/editormanager/documentmodel.cpp
index bf88039cc81..10960e47934 100644
--- a/src/plugins/coreplugin/editormanager/documentmodel.cpp
+++ b/src/plugins/coreplugin/editormanager/documentmodel.cpp
@@ -73,7 +73,7 @@ void DocumentModelPrivate::addEntry(DocumentModel::Entry *entry)
const Utils::FileName fileName = entry->fileName();
QString fixedPath;
if (!fileName.isEmpty())
- fixedPath = DocumentManager::fixFileName(fileName.toString(), DocumentManager::ResolveLinks);
+ fixedPath = DocumentManager::filePathKey(fileName.toString(), DocumentManager::ResolveLinks);
// replace a non-loaded entry (aka 'suspended') if possible
int previousIndex = indexOfFilePath(fileName);
@@ -184,7 +184,7 @@ int DocumentModelPrivate::indexOfFilePath(const Utils::FileName &filePath) const
{
if (filePath.isEmpty())
return -1;
- const QString fixedPath = DocumentManager::fixFileName(filePath.toString(),
+ const QString fixedPath = DocumentManager::filePathKey(filePath.toString(),
DocumentManager::ResolveLinks);
return m_entries.indexOf(m_entryByFixedPath.value(fixedPath));
}
@@ -201,7 +201,7 @@ void DocumentModelPrivate::removeDocument(int idx)
const QString fileName = entry->fileName().toString();
if (!fileName.isEmpty()) {
- const QString fixedPath = DocumentManager::fixFileName(fileName,
+ const QString fixedPath = DocumentManager::filePathKey(fileName,
DocumentManager::ResolveLinks);
m_entryByFixedPath.remove(fixedPath);
}
@@ -298,7 +298,7 @@ void DocumentModelPrivate::itemChanged()
const QString fileName = document->filePath().toString();
QString fixedPath;
if (!fileName.isEmpty())
- fixedPath = DocumentManager::fixFileName(fileName, DocumentManager::ResolveLinks);
+ fixedPath = DocumentManager::filePathKey(fileName, DocumentManager::ResolveLinks);
DocumentModel::Entry *entry = m_entries.at(idx);
bool found = false;
// The entry's fileName might have changed, so find the previous fileName that was associated
diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp
index 9b2bd61748e..e6a56ab9b6e 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.cpp
+++ b/src/plugins/coreplugin/editormanager/editormanager.cpp
@@ -34,6 +34,8 @@
#include "documentmodel_p.h"
#include "ieditor.h"
+#include <app/app_version.h>
+
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
@@ -248,6 +250,11 @@ void EditorManagerPrivate::init()
DocumentModel::init();
connect(ICore::instance(), &ICore::contextAboutToChange,
this, &EditorManagerPrivate::handleContextChange);
+ connect(qApp, &QApplication::applicationStateChanged,
+ this, [](Qt::ApplicationState state) {
+ if (state == Qt::ApplicationActive)
+ EditorManager::updateWindowTitles();
+ });
const Context editManagerContext(Constants::C_EDITORMANAGER);
// combined context for edit & design modes
@@ -380,7 +387,7 @@ void EditorManagerPrivate::init()
cmd = ActionManager::registerAction(m_splitAction, Constants::SPLIT, editManagerContext);
cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,2") : tr("Ctrl+E,2")));
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
- connect(m_splitAction, &QAction::triggered, this, [this]() { split(Qt::Vertical); });
+ connect(m_splitAction, &QAction::triggered, this, []() { split(Qt::Vertical); });
m_splitSideBySideAction = new QAction(Utils::Icons::SPLIT_VERTICAL.icon(),
tr("Split Side by Side"), this);
@@ -394,7 +401,7 @@ void EditorManagerPrivate::init()
cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,4") : tr("Ctrl+E,4")));
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
connect(m_splitNewWindowAction, &QAction::triggered,
- this, [this]() { splitNewWindow(currentEditorView()); });
+ this, []() { splitNewWindow(currentEditorView()); });
m_removeCurrentSplitAction = new QAction(tr("Remove Current Split"), this);
cmd = ActionManager::registerAction(m_removeCurrentSplitAction, Constants::REMOVE_CURRENT_SPLIT, editManagerContext);
@@ -1789,7 +1796,7 @@ void EditorManagerPrivate::updateWindowTitleForDocument(IDocument *document, QWi
if (!windowTitle.isEmpty())
windowTitle.append(dashSep);
- windowTitle.append(tr("Qt Creator"));
+ windowTitle.append(Core::Constants::IDE_DISPLAY_NAME);
window->window()->setWindowTitle(windowTitle);
window->window()->setWindowFilePath(filePath);
diff --git a/src/plugins/coreplugin/externaltool.cpp b/src/plugins/coreplugin/externaltool.cpp
index 9903d58125b..58abcae5b16 100644
--- a/src/plugins/coreplugin/externaltool.cpp
+++ b/src/plugins/coreplugin/externaltool.cpp
@@ -26,6 +26,7 @@
#include "externaltool.h"
#include "externaltoolmanager.h"
+#include "icore.h"
#include "idocument.h"
#include "messagemanager.h"
#include "documentmanager.h"
@@ -480,8 +481,8 @@ bool ExternalTool::save(QString *errorMessage) const
QXmlStreamWriter out(saver.file());
out.setAutoFormatting(true);
out.writeStartDocument(QLatin1String("1.0"));
- out.writeComment(QString::fromLatin1("Written on %1 by Qt Creator %2")
- .arg(QDateTime::currentDateTime().toString(), QLatin1String(Constants::IDE_VERSION_LONG)));
+ out.writeComment(QString::fromLatin1("Written on %1 by %2")
+ .arg(QDateTime::currentDateTime().toString(), ICore::versionString()));
out.writeStartElement(QLatin1String(kExternalTool));
out.writeAttribute(QLatin1String(kId), m_id);
out.writeTextElement(QLatin1String(kDescription), m_description);
diff --git a/src/plugins/coreplugin/externaltoolmanager.cpp b/src/plugins/coreplugin/externaltoolmanager.cpp
index c6ec74f28b2..80d98243b61 100644
--- a/src/plugins/coreplugin/externaltoolmanager.cpp
+++ b/src/plugins/coreplugin/externaltoolmanager.cpp
@@ -77,7 +77,7 @@ ExternalToolManager::ExternalToolManager()
d->m_configureSeparator = new QAction(this);
d->m_configureSeparator->setSeparator(true);
d->m_configureAction = new QAction(ICore::msgShowOptionsDialog(), this);
- connect(d->m_configureAction, &QAction::triggered, [this] {
+ connect(d->m_configureAction, &QAction::triggered, this, [] {
ICore::showOptionsDialog(Constants::SETTINGS_ID_TOOLS);
});
diff --git a/src/plugins/coreplugin/fancyactionbar.cpp b/src/plugins/coreplugin/fancyactionbar.cpp
index 6cbaeea716b..206e5e4d6ed 100644
--- a/src/plugins/coreplugin/fancyactionbar.cpp
+++ b/src/plugins/coreplugin/fancyactionbar.cpp
@@ -178,7 +178,7 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
const QIcon::Mode iconMode = isEnabled() ? ((isDown() || isChecked()) ? QIcon::Active : QIcon::Normal)
: QIcon::Disabled;
- QRect iconRect(0, 0, Constants::TARGET_ICON_SIZE, Constants::TARGET_ICON_SIZE);
+ QRect iconRect(0, 0, Constants::MODEBAR_ICON_SIZE, Constants::MODEBAR_ICON_SIZE);
// draw popup texts
if (isTitledAction) {
@@ -203,7 +203,7 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
painter.setFont(normalFont);
QPoint textOffset = centerRect.center() - QPoint(iconRect.width()/2, iconRect.height()/2);
- textOffset = textOffset - QPoint(0, lineHeight + 4);
+ textOffset = textOffset - QPoint(0, lineHeight + 3);
QRectF r(0, textOffset.y(), rect().width(), lineHeight);
painter.setPen(creatorTheme()->color(isEnabled()
? Theme::PanelTextColorLight
@@ -218,8 +218,8 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
// draw build configuration name
textOffset = iconRect.center() + QPoint(iconRect.width()/2, iconRect.height()/2);
QRectF buildConfigRect[2];
- buildConfigRect[0] = QRectF(0, textOffset.y() + 5, rect().width(), lineHeight);
- buildConfigRect[1] = QRectF(0, textOffset.y() + 5 + lineHeight, rect().width(), lineHeight);
+ buildConfigRect[0] = QRectF(0, textOffset.y() + 4, rect().width(), lineHeight);
+ buildConfigRect[1] = QRectF(0, textOffset.y() + 4 + lineHeight, rect().width(), lineHeight);
painter.setFont(boldFont);
QVector<QString> splitBuildConfiguration(2);
const QString buildConfiguration = defaultAction()->property("subtitle").toString();
diff --git a/src/plugins/coreplugin/fancytabwidget.cpp b/src/plugins/coreplugin/fancytabwidget.cpp
index e741aa87e67..cc0da7b7533 100644
--- a/src/plugins/coreplugin/fancytabwidget.cpp
+++ b/src/plugins/coreplugin/fancytabwidget.cpp
@@ -25,6 +25,7 @@
#include "fancytabwidget.h"
#include "fancyactionbar.h"
+#include "coreconstants.h"
#include <utils/hostosinfo.h>
#include <utils/stylehelper.h>
@@ -48,9 +49,6 @@ using namespace Core;
using namespace Internal;
using namespace Utils;
-const int FancyTabBar::m_rounding = 22;
-const int FancyTabBar::m_textPadding = 4;
-
static const int kMenuButtonWidth = 16;
void FancyTab::fadeIn()
@@ -81,18 +79,12 @@ FancyTabBar::FancyTabBar(QWidget *parent)
m_hoverIndex = -1;
m_currentIndex = -1;
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
- setStyle(QStyleFactory::create(QLatin1String("windows")));
- setMinimumWidth(qMax(2 * m_rounding, 40));
+ setMinimumWidth(44);
setAttribute(Qt::WA_Hover, true);
setFocusPolicy(Qt::NoFocus);
setMouseTracking(true); // Needed for hover events
}
-FancyTabBar::~FancyTabBar()
-{
- delete style();
-}
-
QSize FancyTabBar::tabSizeHint(bool minimum) const
{
QFont boldFont(font());
@@ -333,7 +325,10 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const
tabIconRect.adjust(0, 4, 0, -textHeight);
const QIcon::Mode iconMode = enabled ? (selected ? QIcon::Active : QIcon::Normal)
: QIcon::Disabled;
- StyleHelper::drawIconWithShadow(tab->icon, tabIconRect, painter, iconMode);
+ QRect iconRect(0, 0, Core::Constants::MODEBAR_ICON_SIZE, Core::Constants::MODEBAR_ICON_SIZE);
+ iconRect.moveCenter(tabIconRect.center());
+ iconRect = iconRect.intersected(tabIconRect);
+ StyleHelper::drawIconWithShadow(tab->icon, iconRect, painter, iconMode);
}
painter->setOpacity(1.0); //FIXME: was 0.7 before?
diff --git a/src/plugins/coreplugin/fancytabwidget.h b/src/plugins/coreplugin/fancytabwidget.h
index e6a871ea4ea..5e71e4f1831 100644
--- a/src/plugins/coreplugin/fancytabwidget.h
+++ b/src/plugins/coreplugin/fancytabwidget.h
@@ -74,7 +74,6 @@ class FancyTabBar : public QWidget
public:
FancyTabBar(QWidget *parent = 0);
- ~FancyTabBar();
bool event(QEvent *event);
@@ -122,8 +121,6 @@ signals:
void menuTriggered(int index, QMouseEvent *event);
private:
- static const int m_rounding;
- static const int m_textPadding;
QRect m_hoverRect;
int m_hoverIndex;
int m_currentIndex;
diff --git a/src/plugins/coreplugin/fileiconprovider.cpp b/src/plugins/coreplugin/fileiconprovider.cpp
index 4d6cf5ea489..e5606097cdd 100644
--- a/src/plugins/coreplugin/fileiconprovider.cpp
+++ b/src/plugins/coreplugin/fileiconprovider.cpp
@@ -217,5 +217,18 @@ void registerIconOverlayForFilename(const QString &path, const QString &filename
instance()->registerIconOverlayForFilename(QIcon(path), filename);
}
+// Return a standard directory icon with the specified overlay:
+QIcon directoryIcon(const QString &overlay)
+{
+ // Overlay the SP_DirIcon with the custom icons
+ const QSize desiredSize = QSize(16, 16);
+
+ const QPixmap dirPixmap = QApplication::style()->standardIcon(QStyle::SP_DirIcon).pixmap(desiredSize);
+ const QIcon overlayIcon(overlay);
+ QIcon result;
+ result.addPixmap(Core::FileIconProvider::overlayIcon(dirPixmap, overlayIcon));
+ return result;
+}
+
} // namespace FileIconProvider
} // namespace Core
diff --git a/src/plugins/coreplugin/fileiconprovider.h b/src/plugins/coreplugin/fileiconprovider.h
index dc7f57c2996..9bfbc588e94 100644
--- a/src/plugins/coreplugin/fileiconprovider.h
+++ b/src/plugins/coreplugin/fileiconprovider.h
@@ -49,5 +49,7 @@ CORE_EXPORT void registerIconOverlayForFilename(const QString &path, const QStri
CORE_EXPORT void registerIconOverlayForMimeType(const QString &path, const QString &mimeType);
CORE_EXPORT void registerIconOverlayForMimeType(const QIcon &icon, const QString &mimeType);
+CORE_EXPORT QIcon directoryIcon(const QString &overlay);
+
} // namespace FileIconProvider
} // namespace Core
diff --git a/src/plugins/coreplugin/find/findplugin.cpp b/src/plugins/coreplugin/find/findplugin.cpp
index 9e8d3207bec..7509d5c0df9 100644
--- a/src/plugins/coreplugin/find/findplugin.cpp
+++ b/src/plugins/coreplugin/find/findplugin.cpp
@@ -192,7 +192,7 @@ void FindPrivate::setupMenu()
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+F")));
mfindadvanced->addAction(cmd);
connect(m_openFindDialog, &QAction::triggered,
- this, [this] { Find::openFindDialog(nullptr); });
+ this, [] { Find::openFindDialog(nullptr); });
}
static QString filterActionName(const IFindFilter *filter)
@@ -220,8 +220,7 @@ void FindPrivate::setupFilterMenuItems()
cmd->setDefaultKeySequence(filter->defaultShortcut());
cmd->setAttribute(Command::CA_UpdateText);
mfindadvanced->addAction(cmd);
- connect(action, &QAction::triggered,
- this, [filter, action] { Find::openFindDialog(filter); });
+ connect(action, &QAction::triggered, this, [filter] { Find::openFindDialog(filter); });
connect(filter, &IFindFilter::enabledChanged, this, [filter, action] {
action->setEnabled(filter->isEnabled());
d->m_openFindDialog->setEnabled(d->isAnyFilterEnabled());
diff --git a/src/plugins/coreplugin/find/findtoolbar.cpp b/src/plugins/coreplugin/find/findtoolbar.cpp
index c4cfe718cfb..8b9016d8f29 100644
--- a/src/plugins/coreplugin/find/findtoolbar.cpp
+++ b/src/plugins/coreplugin/find/findtoolbar.cpp
@@ -666,11 +666,11 @@ void FindToolBar::updateIcons()
bool regexp = effectiveFlags & FindRegularExpression;
bool preserveCase = effectiveFlags & FindPreserveCase;
if (!casesensitive && !wholewords && !regexp && !preserveCase) {
- const QPixmap pixmap = Utils::Icons::MAGNIFIER.pixmap();
- m_ui.findEdit->setButtonPixmap(Utils::FancyLineEdit::Left, pixmap);
+ const QIcon icon = Utils::Icons::MAGNIFIER.icon();
+ m_ui.findEdit->setButtonIcon(Utils::FancyLineEdit::Left, icon);
} else {
- m_ui.findEdit->setButtonPixmap(Utils::FancyLineEdit::Left,
- IFindFilter::pixmapForFindFlags(effectiveFlags));
+ m_ui.findEdit->setButtonIcon(Utils::FancyLineEdit::Left,
+ IFindFilter::pixmapForFindFlags(effectiveFlags));
}
}
diff --git a/src/plugins/coreplugin/generalsettings.cpp b/src/plugins/coreplugin/generalsettings.cpp
index fcf8d07f96a..2a0036616e6 100644
--- a/src/plugins/coreplugin/generalsettings.cpp
+++ b/src/plugins/coreplugin/generalsettings.cpp
@@ -164,7 +164,7 @@ void GeneralSettings::setLanguage(const QString &locale)
QSettings *settings = ICore::settings();
if (settings->value(QLatin1String("General/OverrideLanguage")).toString() != locale)
QMessageBox::information(ICore::mainWindow(), tr("Restart Required"),
- tr("The language change will take effect after a restart of Qt Creator."));
+ tr("The language change will take effect after restart."));
if (locale.isEmpty())
settings->remove(QLatin1String("General/OverrideLanguage"));
diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp
index e5a1bc8a5f2..ab2a7f97703 100644
--- a/src/plugins/coreplugin/icore.cpp
+++ b/src/plugins/coreplugin/icore.cpp
@@ -461,8 +461,9 @@ QString ICore::versionString()
QString ideVersionDescription;
if (QLatin1String(Constants::IDE_VERSION_LONG) != QLatin1String(Constants::IDE_VERSION_DISPLAY))
ideVersionDescription = tr(" (%1)").arg(QLatin1String(Constants::IDE_VERSION_LONG));
- return tr("Qt Creator %1%2").arg(QLatin1String(Constants::IDE_VERSION_DISPLAY),
- ideVersionDescription);
+ return tr("%1 %2%3").arg(QLatin1String(Constants::IDE_DISPLAY_NAME),
+ QLatin1String(Constants::IDE_VERSION_DISPLAY),
+ ideVersionDescription);
}
QString ICore::buildCompatibilityString()
diff --git a/src/plugins/coreplugin/images/mode_Design.png b/src/plugins/coreplugin/images/mode_Design.png
index 268376e5fe7..9f155db22ad 100644
--- a/src/plugins/coreplugin/images/mode_Design.png
+++ b/src/plugins/coreplugin/images/mode_Design.png
Binary files differ
diff --git a/src/plugins/coreplugin/images/mode_Design@2x.png b/src/plugins/coreplugin/images/mode_Design@2x.png
index 85e08c360b8..ce1baa8c7af 100644
--- a/src/plugins/coreplugin/images/mode_Design@2x.png
+++ b/src/plugins/coreplugin/images/mode_Design@2x.png
Binary files differ
diff --git a/src/plugins/coreplugin/images/mode_Edit.png b/src/plugins/coreplugin/images/mode_Edit.png
index 494f84baa77..fecee991add 100644
--- a/src/plugins/coreplugin/images/mode_Edit.png
+++ b/src/plugins/coreplugin/images/mode_Edit.png
Binary files differ
diff --git a/src/plugins/coreplugin/images/mode_Edit@2x.png b/src/plugins/coreplugin/images/mode_Edit@2x.png
index d223679dc36..032d37a2223 100644
--- a/src/plugins/coreplugin/images/mode_Edit@2x.png
+++ b/src/plugins/coreplugin/images/mode_Edit@2x.png
Binary files differ
diff --git a/src/plugins/coreplugin/images/mode_design_mask.png b/src/plugins/coreplugin/images/mode_design_mask.png
index 3225507f81a..42013edf352 100644
--- a/src/plugins/coreplugin/images/mode_design_mask.png
+++ b/src/plugins/coreplugin/images/mode_design_mask.png
Binary files differ
diff --git a/src/plugins/coreplugin/images/mode_design_mask@2x.png b/src/plugins/coreplugin/images/mode_design_mask@2x.png
index f4eced6284d..2aef9018a8a 100644
--- a/src/plugins/coreplugin/images/mode_design_mask@2x.png
+++ b/src/plugins/coreplugin/images/mode_design_mask@2x.png
Binary files differ
diff --git a/src/plugins/coreplugin/images/mode_edit_mask.png b/src/plugins/coreplugin/images/mode_edit_mask.png
index 8e2a971f15f..51197249c0a 100644
--- a/src/plugins/coreplugin/images/mode_edit_mask.png
+++ b/src/plugins/coreplugin/images/mode_edit_mask.png
Binary files differ
diff --git a/src/plugins/coreplugin/images/mode_edit_mask@2x.png b/src/plugins/coreplugin/images/mode_edit_mask@2x.png
index d683f154e0e..389ac6dc4e3 100644
--- a/src/plugins/coreplugin/images/mode_edit_mask@2x.png
+++ b/src/plugins/coreplugin/images/mode_edit_mask@2x.png
Binary files differ
diff --git a/src/plugins/coreplugin/iversioncontrol.cpp b/src/plugins/coreplugin/iversioncontrol.cpp
index 1c11437d6cb..678e4ecc8c5 100644
--- a/src/plugins/coreplugin/iversioncontrol.cpp
+++ b/src/plugins/coreplugin/iversioncontrol.cpp
@@ -140,21 +140,21 @@ namespace Core {
TestVersionControl::~TestVersionControl()
{
- VcsManager::instance()->clearVersionControlCache();
+ VcsManager::clearVersionControlCache();
}
void TestVersionControl::setManagedDirectories(const QHash<QString, QString> &dirs)
{
m_managedDirs = dirs;
m_dirCount = 0;
- VcsManager::instance()->clearVersionControlCache();
+ VcsManager::clearVersionControlCache();
}
void TestVersionControl::setManagedFiles(const QSet<QString> &files)
{
m_managedFiles = files;
m_fileCount = 0;
- VcsManager::instance()->clearVersionControlCache();
+ VcsManager::clearVersionControlCache();
}
bool TestVersionControl::managesDirectory(const QString &filename, QString *topLevel) const
diff --git a/src/plugins/coreplugin/iwizardfactory.cpp b/src/plugins/coreplugin/iwizardfactory.cpp
index 238f992a32e..8e8afc304fa 100644
--- a/src/plugins/coreplugin/iwizardfactory.cpp
+++ b/src/plugins/coreplugin/iwizardfactory.cpp
@@ -33,6 +33,7 @@
#include <extensionsystem/pluginspec.h>
#include <extensionsystem/pluginmanager.h>
+#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <utils/wizard.h>
@@ -255,9 +256,9 @@ QString IWizardFactory::runPath(const QString &defaultPath)
// Project wizards: Check for projects directory or
// use last visited directory of file dialog. Never start
// at current.
- path = DocumentManager::useProjectsDirectory() ?
- DocumentManager::projectsDirectory() :
- DocumentManager::fileDialogLastVisitedDirectory();
+ path = DocumentManager::useProjectsDirectory()
+ ? DocumentManager::projectsDirectory().toString()
+ : DocumentManager::fileDialogLastVisitedDirectory();
break;
default:
path = DocumentManager::fileDialogInitialDirectory();
@@ -287,7 +288,7 @@ Utils::Wizard *IWizardFactory::runWizard(const QString &path, QWidget *parent, I
s_reopenData.clear();
wizard->deleteLater();
});
- connect(wizard, &QObject::destroyed, this, [wizard]() {
+ connect(wizard, &QObject::destroyed, this, []() {
s_isWizardRunning = false;
s_currentWizard = nullptr;
s_inspectWizardAction->setEnabled(false);
diff --git a/src/plugins/coreplugin/jsexpander.cpp b/src/plugins/coreplugin/jsexpander.cpp
index 8eee9950949..0c44512497a 100644
--- a/src/plugins/coreplugin/jsexpander.cpp
+++ b/src/plugins/coreplugin/jsexpander.cpp
@@ -84,7 +84,7 @@ JsExpander::JsExpander()
QCoreApplication::translate("Core::JsExpander",
"Evaluate simple JavaScript statements.<br>"
"The statements may not contain '{' nor '}' characters."),
- [this](QString in) -> QString {
+ [](QString in) -> QString {
QString errorMessage;
QString result = JsExpander::evaluate(in, &errorMessage);
if (!errorMessage.isEmpty()) {
diff --git a/src/plugins/coreplugin/locator/basefilefilter.cpp b/src/plugins/coreplugin/locator/basefilefilter.cpp
index 4d7cb124f38..86fe5078f85 100644
--- a/src/plugins/coreplugin/locator/basefilefilter.cpp
+++ b/src/plugins/coreplugin/locator/basefilefilter.cpp
@@ -26,12 +26,12 @@
#include "basefilefilter.h"
#include <coreplugin/editormanager/editormanager.h>
+#include <utils/camelhumpmatcher.h>
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <QDir>
-#include <QRegExp>
-#include <QStringMatcher>
+#include <QRegularExpression>
#include <QTimer>
using namespace Core;
@@ -100,16 +100,15 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil
QList<LocatorFilterEntry> goodEntries;
const QString entry = QDir::fromNativeSeparators(origEntry);
const EditorManager::FilePathInfo fp = EditorManager::splitLineAndColumnNumber(entry);
- const Qt::CaseSensitivity cs = caseSensitivity(fp.filePath);
- QStringMatcher matcher(fp.filePath, cs);
- QRegExp regexp(fp.filePath, cs, QRegExp::Wildcard);
+ const QRegularExpression regexp = containsWildcard(entry)
+ ? createWildcardRegExp(entry) : CamelHumpMatcher::createCamelHumpRegExp(entry);
+
if (!regexp.isValid()) {
d->m_current.clear(); // free memory
return betterEntries;
}
const QChar pathSeparator(QLatin1Char('/'));
const bool hasPathSeparator = fp.filePath.contains(pathSeparator);
- const bool hasWildcard = containsWildcard(fp.filePath);
const bool containsPreviousEntry = !d->m_current.previousEntry.isEmpty()
&& fp.filePath.contains(d->m_current.previousEntry);
const bool pathSeparatorAdded = !d->m_current.previousEntry.contains(pathSeparator)
@@ -136,27 +135,24 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil
QString path = d->m_current.iterator->filePath();
QString name = d->m_current.iterator->fileName();
QString matchText = hasPathSeparator ? path : name;
- int index = hasWildcard ? regexp.indexIn(matchText) : matcher.indexIn(matchText);
+ QRegularExpressionMatch match = regexp.match(matchText);
- if (index >= 0) {
+ if (match.hasMatch()) {
QFileInfo fi(path);
LocatorFilterEntry filterEntry(this, fi.fileName(), QString(path + fp.postfix));
filterEntry.fileName = path;
filterEntry.extraInfo = FileUtils::shortNativePath(FileName(fi));
LocatorFilterEntry::HighlightInfo::DataType hDataType = LocatorFilterEntry::HighlightInfo::DisplayName;
- int length = hasWildcard ? regexp.matchedLength() : fp.filePath.length();
- const bool betterMatch = index == 0;
+ const bool betterMatch = match.capturedStart() == 0;
if (hasPathSeparator) {
- const int indexCandidate = index + filterEntry.extraInfo.length() - path.length();
- const int cutOff = indexCandidate < 0 ? -indexCandidate : 0;
- index = qMax(indexCandidate, 0);
- length = qMax(length - cutOff, 1);
+ match = regexp.match(filterEntry.extraInfo);
hDataType = LocatorFilterEntry::HighlightInfo::ExtraInfo;
}
-
- if (index >= 0)
- filterEntry.highlightInfo = LocatorFilterEntry::HighlightInfo(index, length, hDataType);
+ const CamelHumpMatcher::HighlightingPositions positions =
+ CamelHumpMatcher::highlightingPositions(match);
+ filterEntry.highlightInfo =
+ LocatorFilterEntry::HighlightInfo(positions.starts, positions.lengths, hDataType);
if (betterMatch)
betterEntries.append(filterEntry);
diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp
index 3b5736f95ba..3a0d897a63f 100644
--- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp
+++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp
@@ -34,6 +34,7 @@
#include <QDialogButtonBox>
#include <QLabel>
#include <QLineEdit>
+#include <QRegularExpression>
using namespace Core;
@@ -202,6 +203,25 @@ bool ILocatorFilter::containsWildcard(const QString &str)
}
/*!
+ * \brief Returns a simple regular expression to search for \a text.
+ *
+ * \a text may contain the simple '?' and '*' wildcards known from the shell.
+ * '?' matches exactly one character, '*' matches a number of characters
+ * (including none).
+ *
+ * The regular expression contains capture groups to allow highlighting
+ * matched characters after a match.
+ */
+QRegularExpression ILocatorFilter::createWildcardRegExp(const QString &text)
+{
+ QString pattern = '(' + text + ')';
+ pattern.replace('?', ").(");
+ pattern.replace('*', ").*(");
+ pattern.remove("()");
+ return QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption);
+}
+
+/*!
Specifies a title for configuration dialogs.
*/
QString ILocatorFilter::msgConfigureDialogTitle()
diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.h b/src/plugins/coreplugin/locator/ilocatorfilter.h
index e649a1c959d..e48464f86fc 100644
--- a/src/plugins/coreplugin/locator/ilocatorfilter.h
+++ b/src/plugins/coreplugin/locator/ilocatorfilter.h
@@ -46,13 +46,19 @@ struct LocatorFilterEntry
};
HighlightInfo(int startIndex, int length, DataType type = DataType::DisplayName)
- : startIndex(startIndex)
- , length(length)
+ : starts{startIndex}
+ , lengths{length}
, dataType(type)
{}
- int startIndex;
- int length;
+ HighlightInfo(QVector<int> startIndex, QVector<int> length, DataType type = DataType::DisplayName)
+ : starts(startIndex)
+ , lengths(length)
+ , dataType(type)
+ {}
+
+ QVector<int> starts;
+ QVector<int> lengths;
DataType dataType;
};
@@ -138,6 +144,7 @@ public:
static Qt::CaseSensitivity caseSensitivity(const QString &str);
static bool containsWildcard(const QString &str);
+ static QRegularExpression createWildcardRegExp(const QString &text);
static QString msgConfigureDialogTitle();
static QString msgPrefixLabel();
diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp
index 9dbcde15f40..8d0dbe6292b 100644
--- a/src/plugins/coreplugin/locator/locatorwidget.cpp
+++ b/src/plugins/coreplugin/locator/locatorwidget.cpp
@@ -217,7 +217,8 @@ QVariant LocatorModel::data(const QModelIndex &index, int role) const
: ExtraInfoColumn;
if (highlightColumn == index.column()) {
const bool startIndexRole = role == int(HighlightingItemRole::StartColumn);
- return startIndexRole ? entry.highlightInfo.startIndex : entry.highlightInfo.length;
+ return startIndexRole ? QVariant::fromValue(entry.highlightInfo.starts)
+ : QVariant::fromValue(entry.highlightInfo.lengths);
}
break;
}
@@ -538,9 +539,9 @@ LocatorWidget::LocatorWidget(Locator *locator) :
layout->setMargin(0);
layout->addWidget(m_fileLineEdit);
- const QPixmap pixmap = Utils::Icons::MAGNIFIER.pixmap();
+ const QIcon icon = Utils::Icons::MAGNIFIER.icon();
m_fileLineEdit->setFiltering(true);
- m_fileLineEdit->setButtonPixmap(Utils::FancyLineEdit::Left, pixmap);
+ m_fileLineEdit->setButtonIcon(Utils::FancyLineEdit::Left, icon);
m_fileLineEdit->setButtonToolTip(Utils::FancyLineEdit::Left, tr("Options"));
m_fileLineEdit->setFocusPolicy(Qt::ClickFocus);
m_fileLineEdit->setButtonVisible(Utils::FancyLineEdit::Left, true);
@@ -572,7 +573,7 @@ LocatorWidget::LocatorWidget(Locator *locator) :
m_showPopupTimer.setSingleShot(true);
connect(&m_showPopupTimer, &QTimer::timeout, this, &LocatorWidget::showPopupNow);
- m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicator::Small,
+ m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Small,
m_fileLineEdit);
m_progressIndicator->raise();
m_progressIndicator->hide();
diff --git a/src/plugins/coreplugin/locator/opendocumentsfilter.cpp b/src/plugins/coreplugin/locator/opendocumentsfilter.cpp
index 16b14ba9767..b9b1779529e 100644
--- a/src/plugins/coreplugin/locator/opendocumentsfilter.cpp
+++ b/src/plugins/coreplugin/locator/opendocumentsfilter.cpp
@@ -27,15 +27,15 @@
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
+#include <utils/camelhumpmatcher.h>
#include <utils/fileutils.h>
#include <QAbstractItemModel>
#include <QFileInfo>
#include <QMutexLocker>
-#include <QRegExp>
+#include <QRegularExpression>
using namespace Core;
-using namespace Core;
using namespace Core::Internal;
using namespace Utils;
@@ -61,7 +61,9 @@ QList<LocatorFilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locat
QList<LocatorFilterEntry> goodEntries;
QList<LocatorFilterEntry> betterEntries;
const EditorManager::FilePathInfo fp = EditorManager::splitLineAndColumnNumber(entry);
- QRegExp regexp(fp.filePath, caseSensitivity(fp.filePath), QRegExp::Wildcard);
+ const QRegularExpression regexp = containsWildcard(entry)
+ ? createWildcardRegExp(entry) : CamelHumpMatcher::createCamelHumpRegExp(entry);
+
if (!regexp.isValid())
return goodEntries;
@@ -72,13 +74,16 @@ QList<LocatorFilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locat
if (fileName.isEmpty())
continue;
QString displayName = editorEntry.displayName;
- const int index = regexp.indexIn(displayName);
- if (index >= 0) {
+ const QRegularExpressionMatch match = regexp.match(displayName);
+ if (match.hasMatch()) {
+ const CamelHumpMatcher::HighlightingPositions positions =
+ CamelHumpMatcher::highlightingPositions(match);
LocatorFilterEntry filterEntry(this, displayName, QString(fileName + fp.postfix));
filterEntry.extraInfo = FileUtils::shortNativePath(FileName::fromString(fileName));
filterEntry.fileName = fileName;
- filterEntry.highlightInfo = {index, regexp.matchedLength()};
- if (index == 0)
+ filterEntry.highlightInfo.starts = positions.starts;
+ filterEntry.highlightInfo.lengths = positions.lengths;
+ if (match.capturedStart() == 0)
betterEntries.append(filterEntry);
else
goodEntries.append(filterEntry);
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index 9010fd8da3c..13d7036d8fb 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -109,7 +109,7 @@ MainWindow::MainWindow() :
m_coreImpl(new ICore(this)),
m_lowPrioAdditionalContexts(Constants::C_GLOBAL),
m_settingsDatabase(new SettingsDatabase(QFileInfo(PluginManager::settings()->fileName()).path(),
- QLatin1String("QtCreator"),
+ QLatin1String(Constants::IDE_CASED_ID),
this)),
m_progressManager(new ProgressManagerPrivate),
m_jsExpander(new JsExpander),
@@ -130,10 +130,10 @@ MainWindow::MainWindow() :
HistoryCompleter::setSettings(PluginManager::settings());
- setWindowTitle(tr("Qt Creator"));
+ setWindowTitle(Constants::IDE_DISPLAY_NAME);
if (HostOsInfo::isLinuxHost())
QApplication::setWindowIcon(Icons::QTCREATORLOGO_BIG.icon());
- QCoreApplication::setApplicationName(QLatin1String("QtCreator"));
+ QCoreApplication::setApplicationName(QLatin1String(Constants::IDE_CASED_ID));
QCoreApplication::setApplicationVersion(QLatin1String(Constants::IDE_VERSION_LONG));
QCoreApplication::setOrganizationName(QLatin1String(Constants::IDE_SETTINGSVARIANT_STR));
QString baseName = QApplication::style()->objectName();
@@ -505,7 +505,7 @@ void MainWindow::registerDefaultActions()
cmd = ActionManager::registerAction(m_newAction, Constants::NEW);
cmd->setDefaultKeySequence(QKeySequence::New);
mfile->addAction(cmd, Constants::G_FILE_NEW);
- connect(m_newAction, &QAction::triggered, this, [this]() {
+ connect(m_newAction, &QAction::triggered, this, []() {
if (!ICore::isNewItemDialogRunning()) {
ICore::showNewItemDialog(tr("New File or Project", "Title of dialog"),
IWizardFactory::allWizardFactories(), QString());
@@ -741,9 +741,9 @@ void MainWindow::registerDefaultActions()
// About IDE Action
icon = QIcon::fromTheme(QLatin1String("help-about"));
if (HostOsInfo::isMacHost())
- tmpaction = new QAction(icon, tr("About &Qt Creator"), this); // it's convention not to add dots to the about menu
+ tmpaction = new QAction(icon, tr("About &%1").arg(Constants::IDE_DISPLAY_NAME), this); // it's convention not to add dots to the about menu
else
- tmpaction = new QAction(icon, tr("About &Qt Creator..."), this);
+ tmpaction = new QAction(icon, tr("About &%1...").arg(Constants::IDE_DISPLAY_NAME), this);
tmpaction->setMenuRole(QAction::AboutRole);
cmd = ActionManager::registerAction(tmpaction, Constants::ABOUT_QTCREATOR);
mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
diff --git a/src/plugins/coreplugin/messagemanager.cpp b/src/plugins/coreplugin/messagemanager.cpp
index ee522b534a5..f8d2b975069 100644
--- a/src/plugins/coreplugin/messagemanager.cpp
+++ b/src/plugins/coreplugin/messagemanager.cpp
@@ -38,6 +38,19 @@ MessageManager *MessageManager::instance()
return m_instance;
}
+void MessageManager::showOutputPane(Core::MessageManager::PrintToOutputPaneFlags flags)
+{
+ if (!m_messageOutputWindow)
+ return;
+ if (flags & Flash) {
+ m_messageOutputWindow->flash();
+ } else if (flags & Silent) {
+ // Do nothing
+ } else {
+ m_messageOutputWindow->popup(IOutputPane::Flag(int(flags)));
+ }
+}
+
MessageManager::MessageManager()
{
m_instance = this;
@@ -60,24 +73,11 @@ void MessageManager::init()
ExtensionSystem::PluginManager::addObject(m_messageOutputWindow);
}
-void MessageManager::showOutputPane()
-{
- if (m_messageOutputWindow)
- m_messageOutputWindow->popup(IOutputPane::ModeSwitch);
-}
-
void MessageManager::write(const QString &text, PrintToOutputPaneFlags flags)
{
if (!m_messageOutputWindow)
return;
- if (flags & Flash) {
- m_messageOutputWindow->flash();
- } else if (flags & Silent) {
- // Do nothing
- } else {
- m_messageOutputWindow->popup(IOutputPane::Flag(int(flags)));
- }
-
+ showOutputPane(flags);
m_messageOutputWindow->append(text + QLatin1Char('\n'));
}
diff --git a/src/plugins/coreplugin/messagemanager.h b/src/plugins/coreplugin/messagemanager.h
index 395ac75e5d2..485807d76ea 100644
--- a/src/plugins/coreplugin/messagemanager.h
+++ b/src/plugins/coreplugin/messagemanager.h
@@ -42,8 +42,6 @@ class CORE_EXPORT MessageManager : public QObject
public:
static MessageManager *instance();
- static void showOutputPane();
-
enum PrintToOutputPaneFlag {
NoModeSwitch = IOutputPane::NoModeSwitch,
ModeSwitch = IOutputPane::ModeSwitch,
@@ -55,6 +53,8 @@ public:
Q_DECLARE_FLAGS(PrintToOutputPaneFlags, PrintToOutputPaneFlag)
+ static void showOutputPane(Core::MessageManager::PrintToOutputPaneFlags flags = NoModeSwitch);
+
public slots:
static void write(const QString &text,
Core::MessageManager::PrintToOutputPaneFlags flags = NoModeSwitch);
diff --git a/src/plugins/coreplugin/mimetypemagicdialog.ui b/src/plugins/coreplugin/mimetypemagicdialog.ui
index f638354881b..6dfcb1caccf 100644
--- a/src/plugins/coreplugin/mimetypemagicdialog.ui
+++ b/src/plugins/coreplugin/mimetypemagicdialog.ui
@@ -136,7 +136,7 @@
<bool>false</bool>
</property>
<property name="text">
- <string>&lt;i&gt;Note: Wide range values might impact Qt Creator's performance when opening files.&lt;/i&gt;</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Note: Wide range values might impact performance when opening files.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
diff --git a/src/plugins/coreplugin/mimetypesettings.cpp b/src/plugins/coreplugin/mimetypesettings.cpp
index 8573ae5f870..44b34131073 100644
--- a/src/plugins/coreplugin/mimetypesettings.cpp
+++ b/src/plugins/coreplugin/mimetypesettings.cpp
@@ -31,6 +31,7 @@
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditorfactory.h>
#include <coreplugin/editormanager/iexternaleditor.h>
+
#include <utils/algorithm.h>
#include <utils/headerviewstretcher.h>
#include <utils/mimetypes/mimedatabase.h>
@@ -400,7 +401,7 @@ void MimeTypeSettingsPrivate::resetMimeTypes()
m_userModifiedMimeTypes.clear(); // settings file will be removed with next settings-save
QMessageBox::information(ICore::dialogParent(),
tr("Reset MIME Types"),
- tr("Changes will take effect after Qt Creator restart."));
+ tr("Changes will take effect after restart."));
}
void MimeTypeSettingsPrivate::setFilterPattern(const QString &pattern)
diff --git a/src/plugins/coreplugin/outputwindow.cpp b/src/plugins/coreplugin/outputwindow.cpp
index 7e3f83ac2b2..2d69b09e54a 100644
--- a/src/plugins/coreplugin/outputwindow.cpp
+++ b/src/plugins/coreplugin/outputwindow.cpp
@@ -64,7 +64,7 @@ public:
Qt::MouseButton mouseButtonPressed = Qt::NoButton;
bool m_zoomEnabled = false;
float m_originalFontSize = 0.;
- int maxLineCount = 100000;
+ int maxLineCount = Core::Constants::DEFAULT_MAX_LINE_COUNT;
QTextCursor cursor;
};
diff --git a/src/plugins/coreplugin/patchtool.cpp b/src/plugins/coreplugin/patchtool.cpp
index 10a48817def..724fabd1335 100644
--- a/src/plugins/coreplugin/patchtool.cpp
+++ b/src/plugins/coreplugin/patchtool.cpp
@@ -88,6 +88,12 @@ static bool runPatchHelper(const QByteArray &input, const QString &workingDirect
return false;
}
+ if (!Utils::FileName::fromString(patch).exists()
+ && !Utils::Environment::systemEnvironment().searchInPath(patch).exists()) {
+ MessageManager::write(QApplication::translate("Core::PatchTool", "The patch-command configured in the general \"Environment\" settings does not exist."));
+ return false;
+ }
+
QProcess patchProcess;
if (!workingDirectory.isEmpty())
patchProcess.setWorkingDirectory(workingDirectory);
diff --git a/src/plugins/coreplugin/shellcommand.cpp b/src/plugins/coreplugin/shellcommand.cpp
index 4f6a028e51c..a236c906e4d 100644
--- a/src/plugins/coreplugin/shellcommand.cpp
+++ b/src/plugins/coreplugin/shellcommand.cpp
@@ -28,6 +28,9 @@
#include "icore.h"
#include "progressmanager/progressmanager.h"
+#include <QFutureInterface>
+#include <QFutureWatcher>
+
namespace Core {
ShellCommand::ShellCommand(const QString &workingDirectory, const QProcessEnvironment &environment) :
@@ -40,7 +43,23 @@ ShellCommand::ShellCommand(const QString &workingDirectory, const QProcessEnviro
void ShellCommand::addTask(QFuture<void> &future)
{
const QString name = displayName();
- Core::ProgressManager::addTask(future, name, Core::Id::fromString(name + QLatin1String(".action")));
+ const auto id = Core::Id::fromString(name + QLatin1String(".action"));
+ if (hasProgressParser()) {
+ ProgressManager::addTask(future, name, id);
+ } else {
+ // add a timed tasked based on timeout
+ // we cannot access the future interface directly, so we need to create a new one
+ // with the same lifetime
+ auto fi = new QFutureInterface<void>();
+ auto watcher = new QFutureWatcher<void>();
+ connect(watcher, &QFutureWatcherBase::finished, [fi, watcher] {
+ fi->reportFinished();
+ delete fi;
+ watcher->deleteLater();
+ });
+ watcher->setFuture(future);
+ ProgressManager::addTimedTask(*fi, name, id, qMax(2, timeoutS() / 5)/*itsmagic*/);
+ }
}
void ShellCommand::coreAboutToClose()
diff --git a/src/plugins/coreplugin/systemsettings.cpp b/src/plugins/coreplugin/systemsettings.cpp
index 74d097e7282..69f21929f8a 100644
--- a/src/plugins/coreplugin/systemsettings.cpp
+++ b/src/plugins/coreplugin/systemsettings.cpp
@@ -31,6 +31,7 @@
#include "patchtool.h"
#include "vcsmanager.h"
+#include <app/app_version.h>
#include <utils/checkablemessagebox.h>
#include <utils/consoleprocess.h>
#include <utils/environment.h>
@@ -97,6 +98,11 @@ QWidget *SystemSettings::widget()
m_page->patchChooser->setHistoryCompleter(QLatin1String("General.PatchCommand.History"));
m_page->patchChooser->setPath(PatchTool::patchCommand());
m_page->autoSaveCheckBox->setChecked(EditorManagerPrivate::autoSaveEnabled());
+ m_page->autoSaveCheckBox->setToolTip(tr("Automatically creates temporary copies of "
+ "modified files. If %1 is restarted after "
+ "a crash or power failure, it asks whether to "
+ "recover the auto-saved content.")
+ .arg(Constants::IDE_DISPLAY_NAME));
m_page->autoSaveInterval->setValue(EditorManagerPrivate::autoSaveInterval());
m_page->autoSuspendCheckBox->setChecked(EditorManagerPrivate::autoSuspendEnabled());
m_page->autoSuspendMinDocumentCount->setValue(EditorManagerPrivate::autoSuspendMinDocumentCount());
diff --git a/src/plugins/coreplugin/systemsettings.ui b/src/plugins/coreplugin/systemsettings.ui
index b2928f9d47c..4d36f3c9182 100644
--- a/src/plugins/coreplugin/systemsettings.ui
+++ b/src/plugins/coreplugin/systemsettings.ui
@@ -22,10 +22,6 @@
<property name="text">
<string>?</string>
</property>
- <property name="icon">
- <iconset resource="../../libs/utils/utils.qrc">
- <normaloff>:/utils/images/help.png</normaloff>:/utils/images/help.png</iconset>
- </property>
</widget>
</item>
<item row="1" column="2">
@@ -86,9 +82,6 @@
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QCheckBox" name="autoSaveCheckBox">
- <property name="toolTip">
- <string>Automatically creates temporary copies of modified files. If Qt Creator is restarted after a crash or power failure, it asks whether to recover the auto-saved content.</string>
- </property>
<property name="text">
<string>Auto-save modified files</string>
</property>
@@ -309,7 +302,7 @@
<item>
<widget class="QLabel" name="autoSuspendLabel">
<property name="toolTip">
- <string>Minimum number of open documents that should be kept in memory. Increasing this number will lead to greater resource usage of Qt Creator when not manually closing documents.</string>
+ <string>Minimum number of open documents that should be kept in memory. Increasing this number will lead to greater resource usage when not manually closing documents.</string>
</property>
<property name="text">
<string>Files to keep open:</string>
@@ -389,8 +382,6 @@
<tabstop>warnBeforeOpeningBigFiles</tabstop>
<tabstop>bigFilesLimitSpinBox</tabstop>
</tabstops>
- <resources>
- <include location="../../libs/utils/utils.qrc"/>
- </resources>
+ <resources/>
<connections/>
</ui>
diff --git a/src/plugins/coreplugin/themechooser.cpp b/src/plugins/coreplugin/themechooser.cpp
index ff62406dba0..18f0a4040b5 100644
--- a/src/plugins/coreplugin/themechooser.cpp
+++ b/src/plugins/coreplugin/themechooser.cpp
@@ -179,7 +179,7 @@ void ThemeChooser::apply()
const QString currentThemeId = ThemeEntry::themeSetting().toString();
if (currentThemeId != themeId) {
QMessageBox::information(ICore::mainWindow(), tr("Restart Required"),
- tr("The theme change will take effect after a restart of Qt Creator."));
+ tr("The theme change will take effect after restart."));
// save filename of selected theme in global config
settings->setValue(QLatin1String(Constants::SETTINGS_THEME), themeId);
diff --git a/src/plugins/coreplugin/variablechooser.cpp b/src/plugins/coreplugin/variablechooser.cpp
index 109b81a8d89..5f675de7a37 100644
--- a/src/plugins/coreplugin/variablechooser.cpp
+++ b/src/plugins/coreplugin/variablechooser.cpp
@@ -107,7 +107,7 @@ public:
void createIconButton()
{
m_iconButton = new IconButton;
- m_iconButton->setPixmap(Utils::Icons::REPLACE.pixmap());
+ m_iconButton->setIcon(Utils::Icons::REPLACE.icon());
m_iconButton->setToolTip(VariableChooser::tr("Insert Variable"));
m_iconButton->hide();
connect(m_iconButton.data(), static_cast<void(QAbstractButton::*)(bool)>(&QAbstractButton::clicked),
@@ -457,11 +457,7 @@ void VariableChooserPrivate::updateDescription(const QModelIndex &index)
*/
int VariableChooserPrivate::buttonMargin() const
{
- int margin = m_iconButton->pixmap().width() + 8;
- if (q->style()->inherits("OxygenStyle"))
- margin = qMax(24, margin);
-
- return margin;
+ return 24;
}
void VariableChooserPrivate::updateButtonGeometry()
diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp
index 28ebd382707..e83f110ea50 100644
--- a/src/plugins/coreplugin/vcsmanager.cpp
+++ b/src/plugins/coreplugin/vcsmanager.cpp
@@ -37,6 +37,7 @@
#include <vcsbase/vcsbaseconstants.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/algorithm.h>
+#include <utils/optional.h>
#include <utils/qtcassert.h>
#include <QDir>
@@ -49,8 +50,6 @@
namespace Core {
-typedef QList<IVersionControl *> VersionControlList;
-
#if defined(WITH_TESTS)
const char TEST_PREFIX[] = "/8E3A9BA0-0B97-40DF-AEC1-2BDF9FC9EDBE/";
#endif
@@ -63,35 +62,29 @@ class VcsManagerPrivate
public:
class VcsInfo {
public:
+ VcsInfo() = default;
VcsInfo(IVersionControl *vc, const QString &tl) :
versionControl(vc), topLevel(tl)
{ }
+ VcsInfo(const VcsInfo &other) = default;
bool operator == (const VcsInfo &other) const
{
- return versionControl == other.versionControl &&
- topLevel == other.topLevel;
+ return versionControl == other.versionControl && topLevel == other.topLevel;
}
- IVersionControl *versionControl;
+ IVersionControl *versionControl = nullptr;
QString topLevel;
};
- ~VcsManagerPrivate()
- {
- qDeleteAll(m_vcsInfoList);
- }
-
- VcsInfo *findInCache(const QString &dir)
+ Utils::optional<VcsInfo> findInCache(const QString &dir)
{
- QTC_ASSERT(QDir(dir).isAbsolute(), return nullptr);
- QTC_ASSERT(!dir.endsWith(QLatin1Char('/')), return nullptr);
- QTC_ASSERT(QDir::fromNativeSeparators(dir) == dir, return nullptr);
+ QTC_ASSERT(QDir(dir).isAbsolute(), return Utils::nullopt);
+ QTC_ASSERT(!dir.endsWith(QLatin1Char('/')), return Utils::nullopt);
+ QTC_ASSERT(QDir::fromNativeSeparators(dir) == dir, return Utils::nullopt);
- const QMap<QString, VcsInfo *>::const_iterator it = m_cachedMatches.constFind(dir);
- if (it != m_cachedMatches.constEnd())
- return it.value();
- return nullptr;
+ const auto it = m_cachedMatches.constFind(dir);
+ return it == m_cachedMatches.constEnd() ? Utils::nullopt : Utils::make_optional(it.value());
}
void clearCache()
@@ -121,24 +114,10 @@ public:
|| topLevel == dir || topLevel.isEmpty(), return);
QTC_ASSERT((topLevel.isEmpty() && !vc) || (!topLevel.isEmpty() && vc), return);
- VcsInfo *newInfo = new VcsInfo(vc, topLevel);
- bool createdNewInfo(true);
- // Do we have a matching VcsInfo already?
- foreach (VcsInfo *i, m_vcsInfoList) {
- if (*i == *newInfo) {
- delete newInfo;
- newInfo = i;
- createdNewInfo = false;
- break;
- }
- }
- if (createdNewInfo)
- m_vcsInfoList.append(newInfo);
-
QString tmpDir = dir;
const QChar slash = QLatin1Char('/');
while (tmpDir.count() >= topLevel.count() && !tmpDir.isEmpty()) {
- m_cachedMatches.insert(tmpDir, newInfo);
+ m_cachedMatches.insert(tmpDir, VcsInfo(vc, topLevel));
// if no vc was found, this might mean we're inside a repo internal directory (.git)
// Cache only input directory, not parents
if (!vc)
@@ -151,8 +130,8 @@ public:
}
}
- QMap<QString, VcsInfo *> m_cachedMatches;
- QList<VcsInfo *> m_vcsInfoList;
+ QList<IVersionControl *> m_versionControlList;
+ QMap<QString, VcsInfo> m_cachedMatches;
IVersionControl *m_unconfiguredVcs = nullptr;
QStringList m_cachedAdditionalToolsPaths;
@@ -177,6 +156,12 @@ VcsManager::~VcsManager()
delete d;
}
+void VcsManager::addVersionControl(IVersionControl *vc)
+{
+ QTC_ASSERT(!d->m_versionControlList.contains(vc), return);
+ d->m_versionControlList.append(vc);
+}
+
VcsManager *VcsManager::instance()
{
return m_instance;
@@ -195,9 +180,9 @@ void VcsManager::extensionsInitialized()
}
}
-QList<IVersionControl *> VcsManager::versionControls()
+const QList<IVersionControl *> VcsManager::versionControls()
{
- return ExtensionSystem::PluginManager::getObjects<IVersionControl>();
+ return d->m_versionControlList;
}
IVersionControl *VcsManager::versionControl(Id id)
@@ -240,7 +225,7 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const QString &input
if (directory[0].isLetter() && directory.indexOf(QLatin1Char(':') + QLatin1String(TEST_PREFIX)) == 1)
directory = directory.mid(2);
#endif
- VcsManagerPrivate::VcsInfo *cachedData = d->findInCache(directory);
+ auto cachedData = d->findInCache(directory);
if (cachedData) {
if (topLevelDirectory)
*topLevelDirectory = cachedData->topLevel;
@@ -341,9 +326,10 @@ QString VcsManager::findTopLevelForDirectory(const QString &directory)
QStringList VcsManager::repositories(const IVersionControl *vc)
{
QStringList result;
- foreach (const VcsManagerPrivate::VcsInfo *vi, d->m_vcsInfoList)
- if (vi->versionControl == vc)
- result.push_back(vi->topLevel);
+ for (auto it = d->m_cachedMatches.constBegin(); it != d->m_cachedMatches.constEnd(); ++it) {
+ if (it.value().versionControl == vc)
+ result.append(it.value().topLevel);
+ }
return result;
}
@@ -478,31 +464,6 @@ const char ID_VCS_B[] = "B";
typedef QHash<QString, QString> FileHash;
-template<class T>
-class ObjectPoolGuard
-{
-public:
- ObjectPoolGuard(T *watch) : m_watched(watch)
- {
- ExtensionSystem::PluginManager::addObject(watch);
- }
-
- explicit operator bool() { return m_watched; }
- bool operator !() { return !m_watched; }
- T &operator*() { return *m_watched; }
- T *operator->() { return m_watched; }
- T *value() { return m_watched; }
-
- ~ObjectPoolGuard()
- {
- ExtensionSystem::PluginManager::removeObject(m_watched);
- delete m_watched;
- }
-
-private:
- T *m_watched;
-};
-
static FileHash makeHash(const QStringList &list)
{
FileHash result;
@@ -577,8 +538,11 @@ void CorePlugin::testVcsManager_data()
void CorePlugin::testVcsManager()
{
// setup:
- ObjectPoolGuard<TestVersionControl> vcsA(new TestVersionControl(ID_VCS_A, QLatin1String("A")));
- ObjectPoolGuard<TestVersionControl> vcsB(new TestVersionControl(ID_VCS_B, QLatin1String("B")));
+ QList<IVersionControl *> orig = Core::d->m_versionControlList;
+ TestVersionControl *vcsA(new TestVersionControl(ID_VCS_A, QLatin1String("A")));
+ TestVersionControl *vcsB(new TestVersionControl(ID_VCS_B, QLatin1String("B")));
+
+ Core::d->m_versionControlList = {vcsA, vcsB};
// test:
QFETCH(QStringList, dirsVcsA);
@@ -622,7 +586,8 @@ void CorePlugin::testVcsManager()
}
// teardown:
- // handled by guards
+ qDeleteAll(Core::d->m_versionControlList);
+ Core::d->m_versionControlList = orig;
}
} // namespace Internal
diff --git a/src/plugins/coreplugin/vcsmanager.h b/src/plugins/coreplugin/vcsmanager.h
index 71e3adeaf83..147d7a4aee2 100644
--- a/src/plugins/coreplugin/vcsmanager.h
+++ b/src/plugins/coreplugin/vcsmanager.h
@@ -56,9 +56,17 @@ class CORE_EXPORT VcsManager : public QObject
public:
static VcsManager *instance();
+ template <typename T, typename... Args>
+ static T *registerVersionControl(Args&&... args)
+ {
+ T *vc = new T(std::forward<Args>(args)...);
+ addVersionControl(vc);
+ return vc;
+ }
+
static void extensionsInitialized();
- static QList<IVersionControl *> versionControls();
+ static const QList<IVersionControl *> versionControls();
static IVersionControl *versionControl(Id id);
static void resetVersionControlForDirectory(const QString &inputDirectory);
@@ -92,17 +100,18 @@ public:
*/
static QStringList additionalToolsPath();
+ static void clearVersionControlCache();
+
signals:
void repositoryChanged(const QString &repository);
void configurationChanged(const IVersionControl *vcs);
-public slots:
- static void clearVersionControlCache();
-
private:
explicit VcsManager(QObject *parent = 0);
~VcsManager();
+ static void addVersionControl(IVersionControl *vc);
+
void handleConfigurationChanges();
friend class Core::Internal::MainWindow;
diff --git a/src/plugins/coreplugin/versiondialog.cpp b/src/plugins/coreplugin/versiondialog.cpp
index ded2e13dae3..06962971ea7 100644
--- a/src/plugins/coreplugin/versiondialog.cpp
+++ b/src/plugins/coreplugin/versiondialog.cpp
@@ -51,7 +51,7 @@ VersionDialog::VersionDialog(QWidget *parent)
if (Utils::HostOsInfo::isLinuxHost())
setWindowIcon(Icons::QTCREATORLOGO_BIG.icon());
- setWindowTitle(tr("About Qt Creator"));
+ setWindowTitle(tr("About %1").arg(Core::Constants::IDE_DISPLAY_NAME));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
QGridLayout *layout = new QGridLayout(this);
layout->setSizeConstraint(QLayout::SetFixedSize);
diff --git a/src/plugins/coreplugin/windowsupport.cpp b/src/plugins/coreplugin/windowsupport.cpp
index 4af9d7343ba..7d9c3ef6ad9 100644
--- a/src/plugins/coreplugin/windowsupport.cpp
+++ b/src/plugins/coreplugin/windowsupport.cpp
@@ -31,6 +31,7 @@
#include "coreconstants.h"
#include "icore.h"
+#include <app/app_version.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
@@ -191,7 +192,7 @@ void WindowList::updateTitle(QWidget *window)
QTC_ASSERT(index >= 0, return);
QTC_ASSERT(index < m_windowActions.size(), return);
QString title = window->windowTitle();
- if (title.endsWith(QStringLiteral("- Qt Creator")))
+ if (title.endsWith(QStringLiteral("- ") + Constants::IDE_DISPLAY_NAME))
title.chop(12);
m_windowActions.at(index)->setText(title.trimmed());
}
diff --git a/src/plugins/cppeditor/cppautocompleter.cpp b/src/plugins/cppeditor/cppautocompleter.cpp
index 8c1315b973a..6bc60d2093a 100644
--- a/src/plugins/cppeditor/cppautocompleter.cpp
+++ b/src/plugins/cppeditor/cppautocompleter.cpp
@@ -86,6 +86,7 @@ QString CppAutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) co
#ifdef WITH_TESTS
#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditorconstants.h"
#include "cppeditorplugin.h"
diff --git a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp
index fed7c4c8549..7a701ab6928 100644
--- a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp
+++ b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp
@@ -25,7 +25,7 @@
#include "cppcodemodelinspectordialog.h"
#include "ui_cppcodemodelinspectordialog.h"
-#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditordocument.h"
#include <coreplugin/editormanager/editormanager.h>
@@ -35,6 +35,7 @@
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cpptoolsbridge.h>
#include <cpptools/cppworkingcopy.h>
+#include <projectexplorer/projectmacro.h>
#include <projectexplorer/project.h>
#include <cplusplus/CppDocument.h>
@@ -49,6 +50,7 @@
#include <QSortFilterProxyModel>
#include <algorithm>
+#include <numeric>
using namespace CPlusPlus;
using namespace CppTools;
@@ -756,7 +758,7 @@ class MacrosModel : public QAbstractListModel
Q_OBJECT
public:
MacrosModel(QObject *parent);
- void configure(const QList<Macro> &macros);
+ void configure(const QList<CPlusPlus::Macro> &macros);
void clear();
enum Columns { LineNumberColumn, MacroColumn, ColumnCount };
@@ -767,14 +769,14 @@ public:
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
private:
- QList<Macro> m_macros;
+ QList<CPlusPlus::Macro> m_macros;
};
MacrosModel::MacrosModel(QObject *parent) : QAbstractListModel(parent)
{
}
-void MacrosModel::configure(const QList<Macro> &macros)
+void MacrosModel::configure(const QList<CPlusPlus::Macro> &macros)
{
emit layoutAboutToBeChanged();
m_macros = macros;
@@ -802,7 +804,7 @@ QVariant MacrosModel::data(const QModelIndex &index, int role) const
{
const int column = index.column();
if (role == Qt::DisplayRole || (role == Qt::ToolTipRole && column == MacroColumn)) {
- const Macro macro = m_macros.at(index.row());
+ const CPlusPlus::Macro macro = m_macros.at(index.row());
if (column == LineNumberColumn)
return macro.line();
else if (column == MacroColumn)
@@ -1614,7 +1616,8 @@ void CppCodeModelInspectorDialog::refresh()
}
// Merged entities
- dumper.dumpMergedEntities(cmmi->headerPaths(), cmmi->definedMacros());
+ dumper.dumpMergedEntities(cmmi->headerPaths(),
+ ProjectExplorer::Macro::toByteArray(cmmi->definedMacros()));
}
enum DocumentTabs {
@@ -1758,6 +1761,15 @@ void CppCodeModelInspectorDialog::clearProjectPartData()
partTabName(ProjectPartPrecompiledHeadersTab));
}
+static int defineCount(const ProjectExplorer::Macros &macros)
+{
+ using ProjectExplorer::Macro;
+ return int(std::count_if(
+ macros.begin(),
+ macros.end(),
+ [](const Macro &macro) { return macro.type == ProjectExplorer::MacroType::Define; }));
+}
+
void CppCodeModelInspectorDialog::updateProjectPartData(const ProjectPart::Ptr &part)
{
QTC_ASSERT(part, return);
@@ -1788,6 +1800,7 @@ void CppCodeModelInspectorDialog::updateProjectPartData(const ProjectPart::Ptr &
{QString::fromLatin1("Callgroup Id"), callGroupId},
{QString::fromLatin1("Precompiled Headers"), precompiledHeaders},
{QString::fromLatin1("Selected For Building"), CMI::Utils::toString(part->selectedForBuilding)},
+ {QString::fromLatin1("Build Target Type"), CMI::Utils::toString(part->buildTargetType)},
{QString::fromLatin1("Language Version"), CMI::Utils::toString(part->languageVersion)},
{QString::fromLatin1("Language Extensions"), CMI::Utils::toString(part->languageExtensions)},
{QString::fromLatin1("Qt Version"), CMI::Utils::toString(part->qtVersion)}
@@ -1802,16 +1815,10 @@ void CppCodeModelInspectorDialog::updateProjectPartData(const ProjectPart::Ptr &
m_ui->projectPartTab->setTabText(ProjectPartFilesTab,
partTabName(ProjectPartFilesTab, part->files.size()));
- // Defines
- const QList<QByteArray> defineLines = part->toolchainDefines.split('\n')
- + part->projectDefines.split('\n');
- int numberOfDefines = 0;
- foreach (const QByteArray &line, defineLines) {
- if (line.startsWith("#define "))
- ++numberOfDefines;
- }
- m_ui->partToolchainDefinesEdit->setPlainText(QString::fromUtf8(part->toolchainDefines));
- m_ui->partProjectDefinesEdit->setPlainText(QString::fromUtf8(part->projectDefines));
+ int numberOfDefines = defineCount(part->toolChainMacros) + defineCount(part->projectMacros);
+
+ m_ui->partToolchainDefinesEdit->setPlainText(QString::fromUtf8(ProjectExplorer::Macro::toByteArray(part->toolChainMacros)));
+ m_ui->partProjectDefinesEdit->setPlainText(QString::fromUtf8(ProjectExplorer::Macro::toByteArray(part->projectMacros)));
m_ui->projectPartTab->setTabText(ProjectPartDefinesTab,
partTabName(ProjectPartDefinesTab, numberOfDefines));
diff --git a/src/plugins/cppeditor/cppdoxygen_test.cpp b/src/plugins/cppeditor/cppdoxygen_test.cpp
index 6dde8cb4c09..639e0d5b8ae 100644
--- a/src/plugins/cppeditor/cppdoxygen_test.cpp
+++ b/src/plugins/cppeditor/cppdoxygen_test.cpp
@@ -23,6 +23,8 @@
**
****************************************************************************/
+#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppdoxygen_test.h"
#include "cppeditortestcase.h"
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index c20d46ed40d..a2b622a2f94 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -24,81 +24,12 @@
****************************************************************************/
#include "cppeditor.h"
-
#include "cppautocompleter.h"
-#include "cppdocumentationcommenthelper.h"
-#include "cppeditorconstants.h"
-#include "cppeditordocument.h"
-#include "cppeditorplugin.h"
-#include "cppfollowsymbolundercursor.h"
#include "cpphighlighter.h"
-#include "cpplocalrenaming.h"
-#include "cppminimizableinfobars.h"
-#include "cpppreprocessordialog.h"
-#include "cppquickfixassistant.h"
-#include "cppuseselectionsupdater.h"
-
-#include <clangbackendipc/sourcelocationscontainer.h>
-
-#include <coreplugin/actionmanager/actioncontainer.h>
-#include <coreplugin/actionmanager/actionmanager.h>
-#include <coreplugin/editormanager/editormanager.h>
-#include <coreplugin/editormanager/documentmodel.h>
-#include <coreplugin/infobar.h>
-#include <cpptools/cppcanonicalsymbol.h>
-#include <cpptools/cppchecksymbols.h>
-#include <cpptools/cppcodeformatter.h>
-#include <cpptools/cppcompletionassistprovider.h>
-#include <cpptools/cppeditoroutline.h>
-#include <cpptools/cppmodelmanager.h>
#include <cpptools/cppqtstyleindenter.h>
-#include <cpptools/cppselectionchanger.h>
-#include <cpptools/cppsemanticinfo.h>
-#include <cpptools/cpptoolsconstants.h>
-#include <cpptools/cpptoolsplugin.h>
-#include <cpptools/cpptoolsreuse.h>
-#include <cpptools/cpptoolssettings.h>
-#include <cpptools/cppworkingcopy.h>
-#include <cpptools/symbolfinder.h>
-#include <cpptools/refactoringengineinterface.h>
-
-#include <texteditor/behaviorsettings.h>
-#include <texteditor/completionsettings.h>
-#include <texteditor/convenience.h>
+#include <projectexplorer/projectexplorerconstants.h>
#include <texteditor/textdocument.h>
-#include <texteditor/textdocumentlayout.h>
-#include <texteditor/texteditorsettings.h>
-#include <texteditor/codeassist/assistproposalitem.h>
-#include <texteditor/codeassist/genericproposalmodel.h>
-#include <texteditor/codeassist/genericproposal.h>
-#include <texteditor/fontsettings.h>
-#include <texteditor/refactoroverlay.h>
-
-#include <projectexplorer/projecttree.h>
-
-#include <cplusplus/ASTPath.h>
-#include <cplusplus/FastPreprocessor.h>
-#include <cplusplus/MatchingText.h>
-#include <utils/qtcassert.h>
-#include <utils/utilsicons.h>
-
-#include <QApplication>
-#include <QAction>
-#include <QElapsedTimer>
-#include <QFutureWatcher>
-#include <QMenu>
-#include <QPointer>
-#include <QTextEdit>
-#include <QTimer>
-#include <QToolButton>
-
-enum { UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL = 200 };
-
-using namespace Core;
-using namespace CPlusPlus;
-using namespace CppTools;
-using namespace TextEditor;
namespace CppEditor {
namespace Internal {
@@ -108,931 +39,12 @@ CppEditor::CppEditor()
addContext(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
}
-void CppEditor::decorateEditor(TextEditorWidget *editor)
+void CppEditor::decorateEditor(TextEditor::TextEditorWidget *editor)
{
editor->textDocument()->setSyntaxHighlighter(new CppHighlighter);
editor->textDocument()->setIndenter(new CppTools::CppQtStyleIndenter);
editor->setAutoCompleter(new CppAutoCompleter);
}
-class CppEditorWidgetPrivate
-{
-public:
- CppEditorWidgetPrivate(CppEditorWidget *q);
-
-public:
- QPointer<CppModelManager> m_modelManager;
-
- CppEditorDocument *m_cppEditorDocument;
- CppEditorOutline *m_cppEditorOutline;
-
- QTimer m_updateFunctionDeclDefLinkTimer;
-
- CppLocalRenaming m_localRenaming;
-
- SemanticInfo m_lastSemanticInfo;
-
- CppUseSelectionsUpdater m_useSelectionsUpdater;
-
- FunctionDeclDefLinkFinder *m_declDefLinkFinder;
- QSharedPointer<FunctionDeclDefLink> m_declDefLink;
-
- QScopedPointer<FollowSymbolUnderCursor> m_followSymbolUnderCursor;
-
- QAction *m_parseContextAction = nullptr;
- ParseContextWidget *m_parseContextWidget = nullptr;
- QToolButton *m_preprocessorButton = nullptr;
- MinimizableInfoBars::Actions m_showInfoBarActions;
-
- CppSelectionChanger m_cppSelectionChanger;
-};
-
-CppEditorWidgetPrivate::CppEditorWidgetPrivate(CppEditorWidget *q)
- : m_modelManager(CppModelManager::instance())
- , m_cppEditorDocument(qobject_cast<CppEditorDocument *>(q->textDocument()))
- , m_cppEditorOutline(new CppEditorOutline(q))
- , m_localRenaming(q)
- , m_useSelectionsUpdater(q)
- , m_declDefLinkFinder(new FunctionDeclDefLinkFinder(q))
- , m_followSymbolUnderCursor(new FollowSymbolUnderCursor(q))
- , m_cppSelectionChanger()
-{
-}
-
-CppEditorWidget::CppEditorWidget()
- : d(new CppEditorWidgetPrivate(this))
-{
- qRegisterMetaType<SemanticInfo>("CppTools::SemanticInfo");
-}
-
-void CppEditorWidget::finalizeInitialization()
-{
- d->m_cppEditorDocument = qobject_cast<CppEditorDocument *>(textDocument());
-
- setLanguageSettingsId(CppTools::Constants::CPP_SETTINGS_ID);
-
- // function combo box sorting
- connect(CppEditorPlugin::instance(), &CppEditorPlugin::outlineSortingChanged,
- outline(), &CppEditorOutline::setSorted);
-
- connect(d->m_cppEditorDocument, &CppEditorDocument::codeWarningsUpdated,
- this, &CppEditorWidget::onCodeWarningsUpdated);
- connect(d->m_cppEditorDocument, &CppEditorDocument::ifdefedOutBlocksUpdated,
- this, &CppEditorWidget::onIfdefedOutBlocksUpdated);
- connect(d->m_cppEditorDocument, &CppEditorDocument::cppDocumentUpdated,
- this, &CppEditorWidget::onCppDocumentUpdated);
- connect(d->m_cppEditorDocument, &CppEditorDocument::semanticInfoUpdated,
- this, [this](const CppTools::SemanticInfo &info) { updateSemanticInfo(info); });
-
- connect(d->m_declDefLinkFinder, &FunctionDeclDefLinkFinder::foundLink,
- this, &CppEditorWidget::onFunctionDeclDefLinkFound);
-
- connect(&d->m_useSelectionsUpdater,
- &CppUseSelectionsUpdater::selectionsForVariableUnderCursorUpdated,
- &d->m_localRenaming,
- &CppLocalRenaming::updateSelectionsForVariableUnderCursor);
-
- connect(&d->m_useSelectionsUpdater, &CppUseSelectionsUpdater::finished, this,
- [this] (SemanticInfo::LocalUseMap localUses) {
- d->m_lastSemanticInfo.localUsesUpdated = true;
- d->m_lastSemanticInfo.localUses = localUses;
- });
-
- connect(document(), &QTextDocument::contentsChange,
- &d->m_localRenaming, &CppLocalRenaming::onContentsChangeOfEditorWidgetDocument);
- connect(&d->m_localRenaming, &CppLocalRenaming::finished, [this] {
- cppEditorDocument()->recalculateSemanticInfoDetached();
- });
- connect(&d->m_localRenaming, &CppLocalRenaming::processKeyPressNormally,
- this, &CppEditorWidget::processKeyNormally);
- connect(this, &QPlainTextEdit::cursorPositionChanged,
- d->m_cppEditorOutline, &CppEditorOutline::updateIndex);
-
- connect(cppEditorDocument(), &CppEditorDocument::preprocessorSettingsChanged, this,
- [this](bool customSettings) {
- updateWidgetHighlighting(d->m_preprocessorButton, customSettings);
- });
-
- // set up function declaration - definition link
- d->m_updateFunctionDeclDefLinkTimer.setSingleShot(true);
- d->m_updateFunctionDeclDefLinkTimer.setInterval(UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL);
- connect(&d->m_updateFunctionDeclDefLinkTimer, &QTimer::timeout,
- this, &CppEditorWidget::updateFunctionDeclDefLinkNow);
- connect(this, &QPlainTextEdit::cursorPositionChanged, this, &CppEditorWidget::updateFunctionDeclDefLink);
- connect(this, &QPlainTextEdit::textChanged, this, &CppEditorWidget::updateFunctionDeclDefLink);
-
- // set up the use highlighitng
- connect(this, &CppEditorWidget::cursorPositionChanged, this, [this]() {
- if (!d->m_localRenaming.isActive())
- d->m_useSelectionsUpdater.scheduleUpdate();
-
- // Notify selection expander about the changed cursor.
- d->m_cppSelectionChanger.onCursorPositionChanged(textCursor());
- });
-
- // Toolbar: Outline/Overview combo box
- insertExtraToolBarWidget(TextEditorWidget::Left, d->m_cppEditorOutline->widget());
-
- // Toolbar: Parse context
- ParseContextModel &parseContextModel = cppEditorDocument()->parseContextModel();
- d->m_parseContextWidget = new ParseContextWidget(parseContextModel, this);
- d->m_parseContextAction = insertExtraToolBarWidget(TextEditorWidget::Left,
- d->m_parseContextWidget);
- d->m_parseContextAction->setVisible(false);
- connect(&parseContextModel, &ParseContextModel::updated,
- this, [this](bool areMultipleAvailable) {
- d->m_parseContextAction->setVisible(areMultipleAvailable);
- });
-
- // Toolbar: '#' Button
- // TODO: Make "Additional Preprocessor Directives" also useful with Clang Code Model.
- if (!d->m_modelManager->isClangCodeModelActive()) {
- d->m_preprocessorButton = new QToolButton(this);
- d->m_preprocessorButton->setText(QLatin1String("#"));
- Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
- connect(cmd, &Command::keySequenceChanged,
- this, &CppEditorWidget::updatePreprocessorButtonTooltip);
- updatePreprocessorButtonTooltip();
- connect(d->m_preprocessorButton, &QAbstractButton::clicked,
- this, &CppEditorWidget::showPreProcessorWidget);
-
- insertExtraToolBarWidget(TextEditorWidget::Left, d->m_preprocessorButton);
- }
-
- // Toolbar: Actions to show minimized info bars
- d->m_showInfoBarActions = MinimizableInfoBars::createShowInfoBarActions([this](QWidget *w) {
- return this->insertExtraToolBarWidget(TextEditorWidget::Left, w);
- });
- connect(&cppEditorDocument()->minimizableInfoBars(), &MinimizableInfoBars::showAction,
- this, &CppEditorWidget::onShowInfoBarAction);
-}
-
-void CppEditorWidget::finalizeInitializationAfterDuplication(TextEditorWidget *other)
-{
- QTC_ASSERT(other, return);
- CppEditorWidget *cppEditorWidget = qobject_cast<CppEditorWidget *>(other);
- QTC_ASSERT(cppEditorWidget, return);
-
- if (cppEditorWidget->isSemanticInfoValidExceptLocalUses())
- updateSemanticInfo(cppEditorWidget->semanticInfo());
- d->m_cppEditorOutline->update();
- const Id selectionKind = CodeWarningsSelection;
- setExtraSelections(selectionKind, cppEditorWidget->extraSelections(selectionKind));
-
- if (isWidgetHighlighted(cppEditorWidget->d->m_preprocessorButton))
- updateWidgetHighlighting(d->m_preprocessorButton, true);
-
- d->m_parseContextWidget->syncToModel();
- d->m_parseContextAction->setVisible(
- d->m_cppEditorDocument->parseContextModel().areMultipleAvailable());
-}
-
-CppEditorWidget::~CppEditorWidget()
-{
- // non-inline destructor, see section "Forward Declared Pointers" of QScopedPointer.
-}
-
-CppEditorDocument *CppEditorWidget::cppEditorDocument() const
-{
- return d->m_cppEditorDocument;
-}
-
-CppEditorOutline *CppEditorWidget::outline() const
-{
- return d->m_cppEditorOutline;
-}
-
-void CppEditorWidget::paste()
-{
- if (d->m_localRenaming.handlePaste())
- return;
-
- TextEditorWidget::paste();
-}
-
-void CppEditorWidget::cut()
-{
- if (d->m_localRenaming.handleCut())
- return;
-
- TextEditorWidget::cut();
-}
-
-void CppEditorWidget::selectAll()
-{
- if (d->m_localRenaming.handleSelectAll())
- return;
-
- TextEditorWidget::selectAll();
-}
-
-void CppEditorWidget::onCppDocumentUpdated()
-{
- d->m_cppEditorOutline->update();
-}
-
-void CppEditorWidget::onCodeWarningsUpdated(unsigned revision,
- const QList<QTextEdit::ExtraSelection> selections,
- const TextEditor::RefactorMarkers &refactorMarkers)
-{
- if (revision != documentRevision())
- return;
-
- setExtraSelections(TextEditorWidget::CodeWarningsSelection, selections);
- setRefactorMarkers(refactorMarkersWithoutClangMarkers() + refactorMarkers);
-}
-
-void CppEditorWidget::onIfdefedOutBlocksUpdated(unsigned revision,
- const QList<BlockRange> ifdefedOutBlocks)
-{
- if (revision != documentRevision())
- return;
- setIfdefedOutBlocks(ifdefedOutBlocks);
-}
-
-void CppEditorWidget::onShowInfoBarAction(const Id &id, bool show)
-{
- QAction *action = d->m_showInfoBarActions.value(id);
- QTC_ASSERT(action, return);
- action->setVisible(show);
-}
-
-void CppEditorWidget::findUsages()
-{
- if (!d->m_modelManager)
- return;
-
- SemanticInfo info = d->m_lastSemanticInfo;
- info.snapshot = CppModelManager::instance()->snapshot();
- info.snapshot.insert(info.doc);
-
- if (const Macro *macro = CppTools::findCanonicalMacro(textCursor(), info.doc)) {
- d->m_modelManager->findMacroUsages(*macro);
- } else {
- CanonicalSymbol cs(info.doc, info.snapshot);
- Symbol *canonicalSymbol = cs(textCursor());
- if (canonicalSymbol)
- d->m_modelManager->findUsages(canonicalSymbol, cs.context());
- }
-}
-
-void CppEditorWidget::renameUsages(const QString &replacement)
-{
- if (!d->m_modelManager)
- return;
-
- SemanticInfo info = d->m_lastSemanticInfo;
- info.snapshot = CppModelManager::instance()->snapshot();
- info.snapshot.insert(info.doc);
-
- if (const Macro *macro = CppTools::findCanonicalMacro(textCursor(), info.doc)) {
- d->m_modelManager->renameMacroUsages(*macro, replacement);
- } else {
- CanonicalSymbol cs(info.doc, info.snapshot);
- if (Symbol *canonicalSymbol = cs(textCursor()))
- if (canonicalSymbol->identifier() != 0)
- d->m_modelManager->renameUsages(canonicalSymbol, cs.context(), replacement);
- }
-}
-
-bool CppEditorWidget::selectBlockUp()
-{
- if (!behaviorSettings().m_smartSelectionChanging)
- return TextEditorWidget::selectBlockUp();
-
- QTextCursor cursor = textCursor();
- d->m_cppSelectionChanger.startChangeSelection();
- const bool changed =
- d->m_cppSelectionChanger.changeSelection(
- CppSelectionChanger::ExpandSelection,
- cursor,
- d->m_lastSemanticInfo.doc);
- if (changed)
- setTextCursor(cursor);
- d->m_cppSelectionChanger.stopChangeSelection();
-
- return changed;
-}
-
-bool CppEditorWidget::selectBlockDown()
-{
- if (!behaviorSettings().m_smartSelectionChanging)
- return TextEditorWidget::selectBlockDown();
-
- QTextCursor cursor = textCursor();
- d->m_cppSelectionChanger.startChangeSelection();
- const bool changed =
- d->m_cppSelectionChanger.changeSelection(
- CppSelectionChanger::ShrinkSelection,
- cursor,
- d->m_lastSemanticInfo.doc);
- if (changed)
- setTextCursor(cursor);
- d->m_cppSelectionChanger.stopChangeSelection();
-
- return changed;
-}
-
-void CppEditorWidget::updateWidgetHighlighting(QWidget *widget, bool highlight)
-{
- if (!widget)
- return;
-
- widget->setProperty("highlightWidget", highlight);
- widget->update();
-}
-
-bool CppEditorWidget::isWidgetHighlighted(QWidget *widget)
-{
- return widget ? widget->property("highlightWidget").toBool() : false;
-}
-
-void CppEditorWidget::renameSymbolUnderCursor()
-{
- if (refactoringEngine())
- renameSymbolUnderCursorClang();
- else
- renameSymbolUnderCursorBuiltin();
-}
-
-void CppEditorWidget::renameSymbolUnderCursorBuiltin()
-{
- updateSemanticInfo(d->m_cppEditorDocument->recalculateSemanticInfo(),
- /*updateUseSelectionSynchronously=*/ true);
-
- if (!d->m_localRenaming.start()) // Rename local symbol
- renameUsages(); // Rename non-local symbol or macro
-}
-
-namespace {
-
-QList<ProjectPart::Ptr> fetchProjectParts(CppTools::CppModelManager *modelManager,
- const Utils::FileName &filePath)
-{
- QList<ProjectPart::Ptr> projectParts = modelManager->projectPart(filePath);
-
- if (projectParts.isEmpty())
- projectParts = modelManager->projectPartFromDependencies(filePath);
- if (projectParts.isEmpty())
- projectParts.append(modelManager->fallbackProjectPart());
-
- return projectParts;
-}
-
-ProjectPart *findProjectPartForCurrentProject(const QList<ProjectPart::Ptr> &projectParts,
- ProjectExplorer::Project *currentProject)
-{
- auto found = std::find_if(projectParts.cbegin(),
- projectParts.cend(),
- [&] (const CppTools::ProjectPart::Ptr &projectPart) {
- return projectPart->project == currentProject;
- });
-
- if (found != projectParts.cend())
- return (*found).data();
-
- return 0;
-}
-
-}
-
-ProjectPart *CppEditorWidget::projectPart() const
-{
- if (!d->m_modelManager)
- return 0;
-
- auto projectParts = fetchProjectParts(d->m_modelManager, textDocument()->filePath());
-
- return findProjectPartForCurrentProject(projectParts,
- ProjectExplorer::ProjectTree::currentProject());
-}
-
-namespace {
-
-using ClangBackEnd::V2::SourceLocationContainer;
-using TextEditor::Convenience::selectAt;
-
-QTextCharFormat occurrencesTextCharFormat()
-{
- using TextEditor::TextEditorSettings;
-
- return TextEditorSettings::fontSettings().toTextCharFormat(TextEditor::C_OCCURRENCES);
-}
-
-QList<QTextEdit::ExtraSelection>
-sourceLocationsToExtraSelections(const std::vector<SourceLocationContainer> &sourceLocations,
- uint selectionLength,
- CppEditorWidget *cppEditorWidget)
-{
- const auto textCharFormat = occurrencesTextCharFormat();
-
- QList<QTextEdit::ExtraSelection> selections;
- selections.reserve(int(sourceLocations.size()));
-
- auto sourceLocationToExtraSelection = [&] (const SourceLocationContainer &sourceLocation) {
- QTextEdit::ExtraSelection selection;
-
- selection.cursor = selectAt(cppEditorWidget->textCursor(),
- sourceLocation.line(),
- sourceLocation.column(),
- selectionLength);
- selection.format = textCharFormat;
-
- return selection;
- };
-
-
- std::transform(sourceLocations.begin(),
- sourceLocations.end(),
- std::back_inserter(selections),
- sourceLocationToExtraSelection);
-
- return selections;
-};
-
-}
-
-void CppEditorWidget::renameSymbolUnderCursorClang()
-{
- using ClangBackEnd::SourceLocationsContainer;
-
- ProjectPart *theProjectPart = projectPart();
- if (refactoringEngine()->isUsable() && theProjectPart) {
- d->m_useSelectionsUpdater.abortSchedule();
-
- QPointer<CppEditorWidget> cppEditorWidget = this;
-
- auto renameSymbols = [=] (const QString &symbolName,
- const SourceLocationsContainer &sourceLocations,
- int revision) {
- if (cppEditorWidget) {
- viewport()->setCursor(Qt::IBeamCursor);
-
- if (revision == document()->revision()) {
- auto selections = sourceLocationsToExtraSelections(sourceLocations.sourceLocationContainers(),
- symbolName.size(),
- cppEditorWidget);
- setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection,
- selections);
- d->m_localRenaming.updateSelectionsForVariableUnderCursor(selections);
- if (!d->m_localRenaming.start())
- renameUsages();
- }
- }
- };
-
- refactoringEngine()->startLocalRenaming(textCursor(),
- textDocument()->filePath(),
- document()->revision(),
- theProjectPart,
- std::move(renameSymbols));
-
- viewport()->setCursor(Qt::BusyCursor);
- }
-}
-
-void CppEditorWidget::updatePreprocessorButtonTooltip()
-{
- if (!d->m_preprocessorButton)
- return;
-
- Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
- QTC_ASSERT(cmd, return);
- d->m_preprocessorButton->setToolTip(cmd->action()->toolTip());
-}
-
-void CppEditorWidget::switchDeclarationDefinition(bool inNextSplit)
-{
- if (!d->m_modelManager)
- return;
-
- if (!d->m_lastSemanticInfo.doc)
- return;
-
- // Find function declaration or definition under cursor
- Function *functionDefinitionSymbol = 0;
- Symbol *functionDeclarationSymbol = 0;
-
- ASTPath astPathFinder(d->m_lastSemanticInfo.doc);
- const QList<AST *> astPath = astPathFinder(textCursor());
-
- for (int i = 0, size = astPath.size(); i < size; ++i) {
- AST *ast = astPath.at(i);
- if (FunctionDefinitionAST *functionDefinitionAST = ast->asFunctionDefinition()) {
- if ((functionDefinitionSymbol = functionDefinitionAST->symbol))
- break; // Function definition found!
- } else if (SimpleDeclarationAST *simpleDeclaration = ast->asSimpleDeclaration()) {
- if (List<Symbol *> *symbols = simpleDeclaration->symbols) {
- if (Symbol *symbol = symbols->value) {
- if (symbol->isDeclaration() && symbol->type()->isFunctionType()) {
- functionDeclarationSymbol = symbol;
- break; // Function declaration found!
- }
- }
- }
- }
- }
-
- // Link to function definition/declaration
- CppEditorWidget::Link symbolLink;
- if (functionDeclarationSymbol) {
- symbolLink = linkToSymbol(d->m_modelManager->symbolFinder()
- ->findMatchingDefinition(functionDeclarationSymbol, d->m_modelManager->snapshot()));
- } else if (functionDefinitionSymbol) {
- const Snapshot snapshot = d->m_modelManager->snapshot();
- LookupContext context(d->m_lastSemanticInfo.doc, snapshot);
- ClassOrNamespace *binding = context.lookupType(functionDefinitionSymbol);
- const QList<LookupItem> declarations = context.lookup(functionDefinitionSymbol->name(),
- functionDefinitionSymbol->enclosingScope());
-
- QList<Symbol *> best;
- foreach (const LookupItem &r, declarations) {
- if (Symbol *decl = r.declaration()) {
- if (Function *funTy = decl->type()->asFunctionType()) {
- if (funTy->match(functionDefinitionSymbol)) {
- if (decl != functionDefinitionSymbol && binding == r.binding())
- best.prepend(decl);
- else
- best.append(decl);
- }
- }
- }
- }
-
- if (best.isEmpty())
- return;
- symbolLink = linkToSymbol(best.first());
- }
-
- // Open Editor at link position
- if (symbolLink.hasValidTarget())
- openLink(symbolLink, inNextSplit != alwaysOpenLinksInNextSplit());
-}
-
-CppEditorWidget::Link CppEditorWidget::findLinkAt(const QTextCursor &cursor, bool resolveTarget,
- bool inNextSplit)
-{
- if (!d->m_modelManager)
- return Link();
-
- return d->m_followSymbolUnderCursor->findLink(cursor, resolveTarget,
- d->m_modelManager->snapshot(),
- d->m_lastSemanticInfo.doc,
- d->m_modelManager->symbolFinder(),
- inNextSplit);
-}
-
-unsigned CppEditorWidget::documentRevision() const
-{
- return document()->revision();
-}
-
-static bool isClangFixItAvailableMarker(const RefactorMarker &marker)
-{
- return marker.data.toString()
- == QLatin1String(CppTools::Constants::CPP_CLANG_FIXIT_AVAILABLE_MARKER_ID);
-}
-
-RefactorMarkers CppEditorWidget::refactorMarkersWithoutClangMarkers() const
-{
- RefactorMarkers clearedRefactorMarkers;
-
- foreach (const RefactorMarker &marker, refactorMarkers()) {
- if (isClangFixItAvailableMarker(marker))
- continue;
-
- clearedRefactorMarkers.append(marker);
- }
-
- return clearedRefactorMarkers;
-}
-
-RefactoringEngineInterface *CppEditorWidget::refactoringEngine() const
-{
- return CppTools::CppModelManager::refactoringEngine();
-}
-
-bool CppEditorWidget::isSemanticInfoValidExceptLocalUses() const
-{
- return d->m_lastSemanticInfo.doc
- && d->m_lastSemanticInfo.revision == documentRevision()
- && !d->m_lastSemanticInfo.snapshot.isEmpty();
-}
-
-bool CppEditorWidget::isSemanticInfoValid() const
-{
- return isSemanticInfoValidExceptLocalUses() && d->m_lastSemanticInfo.localUsesUpdated;
-}
-
-SemanticInfo CppEditorWidget::semanticInfo() const
-{
- return d->m_lastSemanticInfo;
-}
-
-bool CppEditorWidget::event(QEvent *e)
-{
- switch (e->type()) {
- case QEvent::ShortcutOverride:
- // handle escape manually if a rename is active
- if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape && d->m_localRenaming.isActive()) {
- e->accept();
- return true;
- }
- break;
- default:
- break;
- }
-
- return TextEditorWidget::event(e);
-}
-
-void CppEditorWidget::processKeyNormally(QKeyEvent *e)
-{
- TextEditorWidget::keyPressEvent(e);
-}
-
-void CppEditorWidget::contextMenuEvent(QContextMenuEvent *e)
-{
- // ### enable
- // updateSemanticInfo(m_semanticHighlighter->semanticInfo(currentSource()));
-
- QPointer<QMenu> menu(new QMenu(this));
-
- ActionContainer *mcontext = ActionManager::actionContainer(Constants::M_CONTEXT);
- QMenu *contextMenu = mcontext->menu();
-
- QMenu *quickFixMenu = new QMenu(tr("&Refactor"), menu);
- quickFixMenu->addAction(ActionManager::command(Constants::RENAME_SYMBOL_UNDER_CURSOR)->action());
-
- if (isSemanticInfoValidExceptLocalUses()) {
- d->m_useSelectionsUpdater.update(CppUseSelectionsUpdater::Synchronous);
- AssistInterface *interface = createAssistInterface(QuickFix, ExplicitlyInvoked);
- if (interface) {
- QScopedPointer<IAssistProcessor> processor(
- CppEditorPlugin::instance()->quickFixProvider()->createProcessor());
- QScopedPointer<IAssistProposal> proposal(processor->perform(interface));
- if (!proposal.isNull()) {
- auto model = static_cast<GenericProposalModel *>(proposal->model());
- for (int index = 0; index < model->size(); ++index) {
- auto item = static_cast<AssistProposalItem *>(model->proposalItem(index));
- QuickFixOperation::Ptr op = item->data().value<QuickFixOperation::Ptr>();
- QAction *action = quickFixMenu->addAction(op->description());
- connect(action, &QAction::triggered, this, [op] { op->perform(); });
- }
- delete model;
- }
- }
- }
-
- foreach (QAction *action, contextMenu->actions()) {
- menu->addAction(action);
- if (action->objectName() == QLatin1String(Constants::M_REFACTORING_MENU_INSERTION_POINT))
- menu->addMenu(quickFixMenu);
- }
-
- appendStandardContextMenuActions(menu);
-
- menu->exec(e->globalPos());
- if (!menu)
- return;
- delete menu;
-}
-
-void CppEditorWidget::keyPressEvent(QKeyEvent *e)
-{
- if (d->m_localRenaming.handleKeyPressEvent(e))
- return;
-
- if (handleStringSplitting(e))
- return;
-
- if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
- if (trySplitComment(this, semanticInfo().snapshot)) {
- e->accept();
- return;
- }
- }
-
- TextEditorWidget::keyPressEvent(e);
-}
-
-bool CppEditorWidget::handleStringSplitting(QKeyEvent *e) const
-{
- if (!TextEditorSettings::completionSettings().m_autoSplitStrings)
- return false;
-
- if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
- QTextCursor cursor = textCursor();
-
- const Kind stringKind = CPlusPlus::MatchingText::stringKindAtCursor(cursor);
- if (stringKind >= T_FIRST_STRING_LITERAL && stringKind < T_FIRST_RAW_STRING_LITERAL) {
- cursor.beginEditBlock();
- if (cursor.positionInBlock() > 0
- && cursor.block().text().at(cursor.positionInBlock() - 1) == QLatin1Char('\\')) {
- // Already escaped: simply go back to line, but do not indent.
- cursor.insertText(QLatin1String("\n"));
- } else if (e->modifiers() & Qt::ShiftModifier) {
- // With 'shift' modifier, escape the end of line character
- // and start at beginning of next line.
- cursor.insertText(QLatin1String("\\\n"));
- } else {
- // End the current string, and start a new one on the line, properly indented.
- cursor.insertText(QLatin1String("\"\n\""));
- textDocument()->autoIndent(cursor);
- }
- cursor.endEditBlock();
- e->accept();
- return true;
- }
- }
-
- return false;
-}
-
-void CppEditorWidget::slotCodeStyleSettingsChanged(const QVariant &)
-{
- QtStyleCodeFormatter formatter;
- formatter.invalidateCache(document());
-}
-
-void CppEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo,
- bool updateUseSelectionSynchronously)
-{
- if (semanticInfo.revision != documentRevision())
- return;
-
- d->m_lastSemanticInfo = semanticInfo;
-
- if (!d->m_localRenaming.isActive()) {
- const CppUseSelectionsUpdater::CallType type = updateUseSelectionSynchronously
- ? CppUseSelectionsUpdater::Synchronous
- : CppUseSelectionsUpdater::Asynchronous;
- d->m_useSelectionsUpdater.update(type);
- }
-
- // schedule a check for a decl/def link
- updateFunctionDeclDefLink();
-}
-
-AssistInterface *CppEditorWidget::createAssistInterface(AssistKind kind, AssistReason reason) const
-{
- if (kind == Completion) {
- if (CppCompletionAssistProvider *cap =
- qobject_cast<CppCompletionAssistProvider *>(cppEditorDocument()->completionAssistProvider())) {
- LanguageFeatures features = LanguageFeatures::defaultFeatures();
- if (Document::Ptr doc = d->m_lastSemanticInfo.doc)
- features = doc->languageFeatures();
- features.objCEnabled |= cppEditorDocument()->isObjCEnabled();
- return cap->createAssistInterface(
- textDocument()->filePath().toString(),
- this,
- features,
- position(),
- reason);
- }
- } else if (kind == QuickFix) {
- if (isSemanticInfoValid())
- return new CppQuickFixInterface(const_cast<CppEditorWidget *>(this), reason);
- } else {
- return TextEditorWidget::createAssistInterface(kind, reason);
- }
- return 0;
-}
-
-QSharedPointer<FunctionDeclDefLink> CppEditorWidget::declDefLink() const
-{
- return d->m_declDefLink;
-}
-
-void CppEditorWidget::onRefactorMarkerClicked(const RefactorMarker &marker)
-{
- if (marker.data.canConvert<FunctionDeclDefLink::Marker>()) {
- applyDeclDefLinkChanges(true);
- } else if (isClangFixItAvailableMarker(marker)) {
- int line, column;
- if (Convenience::convertPosition(document(), marker.cursor.position(), &line, &column)) {
- setTextCursor(marker.cursor);
- invokeAssist(TextEditor::QuickFix);
- }
- }
-}
-
-void CppEditorWidget::updateFunctionDeclDefLink()
-{
- const int pos = textCursor().selectionStart();
-
- // if there's already a link, abort it if the cursor is outside or the name changed
- // (adding a prefix is an exception since the user might type a return type)
- if (d->m_declDefLink
- && (pos < d->m_declDefLink->linkSelection.selectionStart()
- || pos > d->m_declDefLink->linkSelection.selectionEnd()
- || !d->m_declDefLink->nameSelection.selectedText().trimmed()
- .endsWith(d->m_declDefLink->nameInitial))) {
- abortDeclDefLink();
- return;
- }
-
- // don't start a new scan if there's one active and the cursor is already in the scanned area
- const QTextCursor scannedSelection = d->m_declDefLinkFinder->scannedSelection();
- if (!scannedSelection.isNull()
- && scannedSelection.selectionStart() <= pos
- && scannedSelection.selectionEnd() >= pos) {
- return;
- }
-
- d->m_updateFunctionDeclDefLinkTimer.start();
-}
-
-void CppEditorWidget::updateFunctionDeclDefLinkNow()
-{
- IEditor *editor = EditorManager::currentEditor();
- if (!editor || editor->widget() != this)
- return;
-
- const Snapshot semanticSnapshot = d->m_lastSemanticInfo.snapshot;
- const Document::Ptr semanticDoc = d->m_lastSemanticInfo.doc;
-
- if (d->m_declDefLink) {
- // update the change marker
- const Utils::ChangeSet changes = d->m_declDefLink->changes(semanticSnapshot);
- if (changes.isEmpty())
- d->m_declDefLink->hideMarker(this);
- else
- d->m_declDefLink->showMarker(this);
- return;
- }
-
- if (!isSemanticInfoValidExceptLocalUses())
- return;
-
- Snapshot snapshot = CppModelManager::instance()->snapshot();
- snapshot.insert(semanticDoc);
-
- d->m_declDefLinkFinder->startFindLinkAt(textCursor(), semanticDoc, snapshot);
-}
-
-void CppEditorWidget::onFunctionDeclDefLinkFound(QSharedPointer<FunctionDeclDefLink> link)
-{
- abortDeclDefLink();
- d->m_declDefLink = link;
- IDocument *targetDocument = DocumentModel::documentForFilePath( d->m_declDefLink->targetFile->fileName());
- if (textDocument() != targetDocument) {
- if (auto textDocument = qobject_cast<BaseTextDocument *>(targetDocument))
- connect(textDocument, &IDocument::contentsChanged,
- this, &CppEditorWidget::abortDeclDefLink);
- }
-
-}
-
-void CppEditorWidget::applyDeclDefLinkChanges(bool jumpToMatch)
-{
- if (!d->m_declDefLink)
- return;
- d->m_declDefLink->apply(this, jumpToMatch);
- abortDeclDefLink();
- updateFunctionDeclDefLink();
-}
-
-FollowSymbolUnderCursor *CppEditorWidget::followSymbolUnderCursorDelegate()
-{
- return d->m_followSymbolUnderCursor.data();
-}
-
-void CppEditorWidget::encourageApply()
-{
- if (d->m_localRenaming.encourageApply())
- return;
-
- TextEditorWidget::encourageApply();
-}
-
-void CppEditorWidget::abortDeclDefLink()
-{
- if (!d->m_declDefLink)
- return;
-
- IDocument *targetDocument = DocumentModel::documentForFilePath(d->m_declDefLink->targetFile->fileName());
- if (textDocument() != targetDocument) {
- if (auto textDocument = qobject_cast<BaseTextDocument *>(targetDocument))
- disconnect(textDocument, &IDocument::contentsChanged,
- this, &CppEditorWidget::abortDeclDefLink);
- }
-
- d->m_declDefLink->hideMarker(this);
- d->m_declDefLink.clear();
-}
-
-void CppEditorWidget::showPreProcessorWidget()
-{
- const QString filePath = textDocument()->filePath().toString();
-
- CppPreProcessorDialog dialog(filePath, this);
- if (dialog.exec() == QDialog::Accepted) {
- const QByteArray extraDirectives = dialog.extraPreprocessorDirectives().toUtf8();
- cppEditorDocument()->setExtraPreprocessorDirectives(extraDirectives);
- cppEditorDocument()->scheduleProcessDocument();
- }
-}
-
} // namespace Internal
} // namespace CppEditor
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index 5dc6ee7d49c..fdc19cb6c30 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -25,28 +25,11 @@
#pragma once
-#include "cppfunctiondecldeflink.h"
-
#include <texteditor/texteditor.h>
-#include <QScopedPointer>
-
-namespace CppTools {
-class CppEditorOutline;
-class RefactoringEngineInterface;
-class SemanticInfo;
-class ProjectPart;
-}
-
namespace CppEditor {
namespace Internal {
-class CppEditorDocument;
-
-class CppEditorWidgetPrivate;
-class FollowSymbolUnderCursor;
-class FunctionDeclDefLink;
-
class CppEditor : public TextEditor::BaseTextEditor
{
Q_OBJECT
@@ -55,103 +38,6 @@ public:
CppEditor();
static void decorateEditor(TextEditor::TextEditorWidget *editor);
-
-};
-
-class CppEditorWidget : public TextEditor::TextEditorWidget
-{
- Q_OBJECT
-
-public:
- CppEditorWidget();
- ~CppEditorWidget() override;
-
- CppEditorDocument *cppEditorDocument() const;
- CppTools::CppEditorOutline *outline() const;
-
- CppTools::SemanticInfo semanticInfo() const;
- bool isSemanticInfoValidExceptLocalUses() const;
- bool isSemanticInfoValid() const;
-
- QSharedPointer<FunctionDeclDefLink> declDefLink() const;
- void applyDeclDefLinkChanges(bool jumpToMatch);
-
- TextEditor::AssistInterface *createAssistInterface(
- TextEditor::AssistKind kind,
- TextEditor::AssistReason reason) const override;
-
- FollowSymbolUnderCursor *followSymbolUnderCursorDelegate(); // exposed for tests
-
- void encourageApply() override;
-
- void paste() override;
- void cut() override;
- void selectAll() override;
-
- void switchDeclarationDefinition(bool inNextSplit);
- void showPreProcessorWidget();
-
- void findUsages();
- void renameSymbolUnderCursor();
- void renameUsages(const QString &replacement = QString());
-
- bool selectBlockUp() override;
- bool selectBlockDown() override;
-
- static void updateWidgetHighlighting(QWidget *widget, bool highlight);
- static bool isWidgetHighlighted(QWidget *widget);
-
-protected:
- bool event(QEvent *e) override;
- void contextMenuEvent(QContextMenuEvent *) override;
- void keyPressEvent(QKeyEvent *e) override;
- bool handleStringSplitting(QKeyEvent *e) const;
-
- Link findLinkAt(const QTextCursor &, bool resolveTarget = true,
- bool inNextSplit = false) override;
-
- void onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker) override;
-
- void slotCodeStyleSettingsChanged(const QVariant &) override;
-
-private:
- void updateFunctionDeclDefLink();
- void updateFunctionDeclDefLinkNow();
- void abortDeclDefLink();
- void onFunctionDeclDefLinkFound(QSharedPointer<FunctionDeclDefLink> link);
-
- void onCppDocumentUpdated();
-
- void onCodeWarningsUpdated(unsigned revision,
- const QList<QTextEdit::ExtraSelection> selections,
- const TextEditor::RefactorMarkers &refactorMarkers);
- void onIfdefedOutBlocksUpdated(unsigned revision,
- const QList<TextEditor::BlockRange> ifdefedOutBlocks);
-
- void onShowInfoBarAction(const Core::Id &id, bool show);
-
- void updateSemanticInfo(const CppTools::SemanticInfo &semanticInfo,
- bool updateUseSelectionSynchronously = false);
- void updatePreprocessorButtonTooltip();
-
- void processKeyNormally(QKeyEvent *e);
-
- void finalizeInitialization() override;
- void finalizeInitializationAfterDuplication(TextEditorWidget *other) override;
-
- unsigned documentRevision() const;
-
- TextEditor::RefactorMarkers refactorMarkersWithoutClangMarkers() const;
-
- CppTools::RefactoringEngineInterface *refactoringEngine() const;
-
- void renameSymbolUnderCursorClang();
- void renameSymbolUnderCursorBuiltin();
-
- CppTools::ProjectPart *projectPart() const;
-
-private:
- QScopedPointer<CppEditorWidgetPrivate> d;
};
} // namespace Internal
diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro
index 8efb3cd4f0d..0bc3391ce81 100644
--- a/src/plugins/cppeditor/cppeditor.pro
+++ b/src/plugins/cppeditor/cppeditor.pro
@@ -11,8 +11,8 @@ HEADERS += \
cppeditorconstants.h \
cppeditorenums.h \
cppeditorplugin.h \
+ cppeditorwidget.h \
cppelementevaluator.h \
- cppfollowsymbolundercursor.h \
cppfunctiondecldeflink.h \
cpphighlighter.h \
cpphoverhandler.h \
@@ -28,8 +28,6 @@ HEADERS += \
cppquickfixes.h \
cpptypehierarchy.h \
cppuseselectionsupdater.h \
- cppvirtualfunctionassistprovider.h \
- cppvirtualfunctionproposalitem.h \
resourcepreviewhoverhandler.h
SOURCES += \
@@ -39,8 +37,8 @@ SOURCES += \
cppeditor.cpp \
cppeditordocument.cpp \
cppeditorplugin.cpp \
+ cppeditorwidget.cpp \
cppelementevaluator.cpp \
- cppfollowsymbolundercursor.cpp \
cppfunctiondecldeflink.cpp \
cpphighlighter.cpp \
cpphoverhandler.cpp \
@@ -56,8 +54,6 @@ SOURCES += \
cppquickfixes.cpp \
cpptypehierarchy.cpp \
cppuseselectionsupdater.cpp \
- cppvirtualfunctionassistprovider.cpp \
- cppvirtualfunctionproposalitem.cpp \
resourcepreviewhoverhandler.cpp
FORMS += \
diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs
index 32a403ea4c7..5d8b17adb41 100644
--- a/src/plugins/cppeditor/cppeditor.qbs
+++ b/src/plugins/cppeditor/cppeditor.qbs
@@ -29,6 +29,8 @@ QtcPlugin {
"cppdocumentationcommenthelper.h",
"cppeditor.cpp",
"cppeditor.h",
+ "cppeditorwidget.cpp",
+ "cppeditorwidget.h",
"cppeditor.qrc",
"cppeditor_global.h",
"cppeditorconstants.h",
@@ -39,8 +41,6 @@ QtcPlugin {
"cppeditorplugin.h",
"cppelementevaluator.cpp",
"cppelementevaluator.h",
- "cppfollowsymbolundercursor.cpp",
- "cppfollowsymbolundercursor.h",
"cppfunctiondecldeflink.cpp",
"cppfunctiondecldeflink.h",
"cpphighlighter.cpp",
@@ -72,10 +72,6 @@ QtcPlugin {
"cpptypehierarchy.h",
"cppuseselectionsupdater.cpp",
"cppuseselectionsupdater.h",
- "cppvirtualfunctionassistprovider.cpp",
- "cppvirtualfunctionassistprovider.h",
- "cppvirtualfunctionproposalitem.cpp",
- "cppvirtualfunctionproposalitem.h",
"resourcepreviewhoverhandler.cpp",
"resourcepreviewhoverhandler.h",
]
diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp
index 1fec96aae6e..3f352f1ffe8 100644
--- a/src/plugins/cppeditor/cppeditorplugin.cpp
+++ b/src/plugins/cppeditor/cppeditorplugin.cpp
@@ -28,7 +28,7 @@
#include "cppautocompleter.h"
#include "cppcodemodelinspectordialog.h"
#include "cppeditorconstants.h"
-#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditordocument.h"
#include "cpphighlighter.h"
#include "cpphoverhandler.h"
diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h
index a6653942879..aa2f06fad76 100644
--- a/src/plugins/cppeditor/cppeditorplugin.h
+++ b/src/plugins/cppeditor/cppeditorplugin.h
@@ -93,6 +93,9 @@ private slots:
void test_FollowSymbolUnderCursor_data();
void test_FollowSymbolUnderCursor();
+ void test_FollowSymbolUnderCursor_QTCREATORBUG7903_data();
+ void test_FollowSymbolUnderCursor_QTCREATORBUG7903();
+
void test_FollowSymbolUnderCursor_followCall_data();
void test_FollowSymbolUnderCursor_followCall();
diff --git a/src/plugins/cppeditor/cppeditortestcase.cpp b/src/plugins/cppeditor/cppeditortestcase.cpp
index 7e62dbbc470..027523a02d7 100644
--- a/src/plugins/cppeditor/cppeditortestcase.cpp
+++ b/src/plugins/cppeditor/cppeditortestcase.cpp
@@ -26,6 +26,7 @@
#include "cppeditortestcase.h"
#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditordocument.h"
#include <coreplugin/editormanager/editormanager.h>
diff --git a/src/plugins/cppeditor/cppeditortestcase.h b/src/plugins/cppeditor/cppeditortestcase.h
index dafca4ec14f..6eb9821bddb 100644
--- a/src/plugins/cppeditor/cppeditortestcase.h
+++ b/src/plugins/cppeditor/cppeditortestcase.h
@@ -25,8 +25,6 @@
#pragma once
-#include "cppeditor.h"
-
#include <cpptools/cpptoolstestcase.h>
#include <QVector>
diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp
new file mode 100644
index 00000000000..c14bb541bef
--- /dev/null
+++ b/src/plugins/cppeditor/cppeditorwidget.cpp
@@ -0,0 +1,1085 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "cppeditorwidget.h"
+
+#include "cppautocompleter.h"
+#include "cppdocumentationcommenthelper.h"
+#include "cppeditorconstants.h"
+#include "cppeditordocument.h"
+#include "cppeditorplugin.h"
+#include "cppfunctiondecldeflink.h"
+#include "cpphighlighter.h"
+#include "cpplocalrenaming.h"
+#include "cppminimizableinfobars.h"
+#include "cpppreprocessordialog.h"
+#include "cppquickfixassistant.h"
+#include "cppuseselectionsupdater.h"
+
+#include <clangsupport/sourcelocationscontainer.h>
+
+#include <coreplugin/actionmanager/actioncontainer.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/editormanager/documentmodel.h>
+#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/infobar.h>
+
+#include <cpptools/cppcanonicalsymbol.h>
+#include <cpptools/cppchecksymbols.h>
+#include <cpptools/cppcodeformatter.h>
+#include <cpptools/cppcompletionassistprovider.h>
+#include <cpptools/cppeditoroutline.h>
+#include <cpptools/cppmodelmanager.h>
+#include <cpptools/cppqtstyleindenter.h>
+#include <cpptools/cppselectionchanger.h>
+#include <cpptools/cppsemanticinfo.h>
+#include <cpptools/cpptoolsconstants.h>
+#include <cpptools/cpptoolsplugin.h>
+#include <cpptools/cpptoolsreuse.h>
+#include <cpptools/cpptoolssettings.h>
+#include <cpptools/cppworkingcopy.h>
+#include <cpptools/refactoringengineinterface.h>
+#include <cpptools/followsymbolinterface.h>
+#include <cpptools/symbolfinder.h>
+
+#include <texteditor/behaviorsettings.h>
+#include <texteditor/codeassist/assistproposalitem.h>
+#include <texteditor/codeassist/genericproposal.h>
+#include <texteditor/codeassist/genericproposalmodel.h>
+#include <texteditor/completionsettings.h>
+#include <texteditor/fontsettings.h>
+#include <texteditor/refactoroverlay.h>
+#include <texteditor/textdocument.h>
+#include <texteditor/textdocumentlayout.h>
+#include <texteditor/texteditorsettings.h>
+
+#include <projectexplorer/projecttree.h>
+
+#include <cplusplus/ASTPath.h>
+#include <cplusplus/FastPreprocessor.h>
+#include <cplusplus/MatchingText.h>
+#include <utils/progressindicator.h>
+#include <utils/qtcassert.h>
+#include <utils/textutils.h>
+#include <utils/utilsicons.h>
+
+#include <QAction>
+#include <QApplication>
+#include <QElapsedTimer>
+#include <QFutureWatcher>
+#include <QMenu>
+#include <QPointer>
+#include <QTextEdit>
+#include <QTimer>
+#include <QToolButton>
+#include <QWidgetAction>
+
+enum { UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL = 200 };
+
+using namespace Core;
+using namespace CPlusPlus;
+using namespace CppTools;
+using namespace TextEditor;
+
+namespace CppEditor {
+namespace Internal {
+
+class CppEditorWidgetPrivate
+{
+public:
+ CppEditorWidgetPrivate(CppEditorWidget *q);
+
+public:
+ QPointer<CppModelManager> m_modelManager;
+
+ CppEditorDocument *m_cppEditorDocument;
+ CppEditorOutline *m_cppEditorOutline;
+
+ QTimer m_updateFunctionDeclDefLinkTimer;
+ SemanticInfo m_lastSemanticInfo;
+
+ FunctionDeclDefLinkFinder *m_declDefLinkFinder;
+ QSharedPointer<FunctionDeclDefLink> m_declDefLink;
+
+ QAction *m_parseContextAction = nullptr;
+ ParseContextWidget *m_parseContextWidget = nullptr;
+ QToolButton *m_preprocessorButton = nullptr;
+ MinimizableInfoBars::Actions m_showInfoBarActions;
+
+ CppLocalRenaming m_localRenaming;
+ CppUseSelectionsUpdater m_useSelectionsUpdater;
+ CppSelectionChanger m_cppSelectionChanger;
+};
+
+CppEditorWidgetPrivate::CppEditorWidgetPrivate(CppEditorWidget *q)
+ : m_modelManager(CppModelManager::instance())
+ , m_cppEditorDocument(qobject_cast<CppEditorDocument *>(q->textDocument()))
+ , m_cppEditorOutline(new CppEditorOutline(q))
+ , m_declDefLinkFinder(new FunctionDeclDefLinkFinder(q))
+ , m_localRenaming(q)
+ , m_useSelectionsUpdater(q)
+ , m_cppSelectionChanger()
+{}
+
+CppEditorWidget::CppEditorWidget()
+ : d(new CppEditorWidgetPrivate(this))
+{
+ qRegisterMetaType<SemanticInfo>("CppTools::SemanticInfo");
+}
+
+void CppEditorWidget::finalizeInitialization()
+{
+ d->m_cppEditorDocument = qobject_cast<CppEditorDocument *>(textDocument());
+
+ setLanguageSettingsId(CppTools::Constants::CPP_SETTINGS_ID);
+
+ // clang-format off
+ // function combo box sorting
+ connect(CppEditorPlugin::instance(), &CppEditorPlugin::outlineSortingChanged,
+ outline(), &CppEditorOutline::setSorted);
+
+ connect(d->m_cppEditorDocument, &CppEditorDocument::codeWarningsUpdated,
+ this, &CppEditorWidget::onCodeWarningsUpdated);
+ connect(d->m_cppEditorDocument, &CppEditorDocument::ifdefedOutBlocksUpdated,
+ this, &CppEditorWidget::onIfdefedOutBlocksUpdated);
+ connect(d->m_cppEditorDocument, &CppEditorDocument::cppDocumentUpdated,
+ this, &CppEditorWidget::onCppDocumentUpdated);
+ connect(d->m_cppEditorDocument, &CppEditorDocument::semanticInfoUpdated,
+ this, [this](const CppTools::SemanticInfo &info) { updateSemanticInfo(info); });
+
+ connect(d->m_declDefLinkFinder, &FunctionDeclDefLinkFinder::foundLink,
+ this, &CppEditorWidget::onFunctionDeclDefLinkFound);
+
+ connect(&d->m_useSelectionsUpdater,
+ &CppUseSelectionsUpdater::selectionsForVariableUnderCursorUpdated,
+ &d->m_localRenaming,
+ &CppLocalRenaming::updateSelectionsForVariableUnderCursor);
+
+ connect(&d->m_useSelectionsUpdater, &CppUseSelectionsUpdater::finished, this,
+ [this] (SemanticInfo::LocalUseMap localUses, bool success) {
+ if (success) {
+ d->m_lastSemanticInfo.localUsesUpdated = true;
+ d->m_lastSemanticInfo.localUses = localUses;
+ }
+ });
+
+ connect(document(), &QTextDocument::contentsChange,
+ &d->m_localRenaming, &CppLocalRenaming::onContentsChangeOfEditorWidgetDocument);
+ connect(&d->m_localRenaming, &CppLocalRenaming::finished, [this] {
+ cppEditorDocument()->recalculateSemanticInfoDetached();
+ });
+ connect(&d->m_localRenaming, &CppLocalRenaming::processKeyPressNormally,
+ this, &CppEditorWidget::processKeyNormally);
+ connect(this, &QPlainTextEdit::cursorPositionChanged,
+ d->m_cppEditorOutline, &CppEditorOutline::updateIndex);
+
+ connect(cppEditorDocument(), &CppEditorDocument::preprocessorSettingsChanged, this,
+ [this](bool customSettings) {
+ updateWidgetHighlighting(d->m_preprocessorButton, customSettings);
+ });
+
+ // set up function declaration - definition link
+ d->m_updateFunctionDeclDefLinkTimer.setSingleShot(true);
+ d->m_updateFunctionDeclDefLinkTimer.setInterval(UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL);
+ connect(&d->m_updateFunctionDeclDefLinkTimer, &QTimer::timeout,
+ this, &CppEditorWidget::updateFunctionDeclDefLinkNow);
+ connect(this, &QPlainTextEdit::cursorPositionChanged, this, &CppEditorWidget::updateFunctionDeclDefLink);
+ connect(this, &QPlainTextEdit::textChanged, this, &CppEditorWidget::updateFunctionDeclDefLink);
+
+ // set up the use highlighitng
+ connect(this, &CppEditorWidget::cursorPositionChanged, this, [this]() {
+ if (!d->m_localRenaming.isActive())
+ d->m_useSelectionsUpdater.scheduleUpdate();
+
+ // Notify selection expander about the changed cursor.
+ d->m_cppSelectionChanger.onCursorPositionChanged(textCursor());
+ });
+
+ // Toolbar: Outline/Overview combo box
+ insertExtraToolBarWidget(TextEditorWidget::Left, d->m_cppEditorOutline->widget());
+
+ // Toolbar: Parse context
+ ParseContextModel &parseContextModel = cppEditorDocument()->parseContextModel();
+ d->m_parseContextWidget = new ParseContextWidget(parseContextModel, this);
+ d->m_parseContextAction = insertExtraToolBarWidget(TextEditorWidget::Left,
+ d->m_parseContextWidget);
+ d->m_parseContextAction->setVisible(false);
+ connect(&parseContextModel, &ParseContextModel::updated,
+ this, [this](bool areMultipleAvailable) {
+ d->m_parseContextAction->setVisible(areMultipleAvailable);
+ });
+ // clang-format on
+ // Toolbar: '#' Button
+ // TODO: Make "Additional Preprocessor Directives" also useful with Clang Code Model.
+ if (!d->m_modelManager->isClangCodeModelActive()) {
+ d->m_preprocessorButton = new QToolButton(this);
+ d->m_preprocessorButton->setText(QLatin1String("#"));
+ Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
+ connect(cmd, &Command::keySequenceChanged,
+ this, &CppEditorWidget::updatePreprocessorButtonTooltip);
+ updatePreprocessorButtonTooltip();
+ connect(d->m_preprocessorButton, &QAbstractButton::clicked,
+ this, &CppEditorWidget::showPreProcessorWidget);
+
+ insertExtraToolBarWidget(TextEditorWidget::Left, d->m_preprocessorButton);
+ }
+
+ // Toolbar: Actions to show minimized info bars
+ d->m_showInfoBarActions = MinimizableInfoBars::createShowInfoBarActions([this](QWidget *w) {
+ return this->insertExtraToolBarWidget(TextEditorWidget::Left, w);
+ });
+ connect(&cppEditorDocument()->minimizableInfoBars(), &MinimizableInfoBars::showAction,
+ this, &CppEditorWidget::onShowInfoBarAction);
+}
+
+void CppEditorWidget::finalizeInitializationAfterDuplication(TextEditorWidget *other)
+{
+ QTC_ASSERT(other, return);
+ CppEditorWidget *cppEditorWidget = qobject_cast<CppEditorWidget *>(other);
+ QTC_ASSERT(cppEditorWidget, return);
+
+ if (cppEditorWidget->isSemanticInfoValidExceptLocalUses())
+ updateSemanticInfo(cppEditorWidget->semanticInfo());
+ d->m_cppEditorOutline->update();
+ const Id selectionKind = CodeWarningsSelection;
+ setExtraSelections(selectionKind, cppEditorWidget->extraSelections(selectionKind));
+
+ if (isWidgetHighlighted(cppEditorWidget->d->m_preprocessorButton))
+ updateWidgetHighlighting(d->m_preprocessorButton, true);
+
+ d->m_parseContextWidget->syncToModel();
+ d->m_parseContextAction->setVisible(
+ d->m_cppEditorDocument->parseContextModel().areMultipleAvailable());
+}
+
+CppEditorWidget::~CppEditorWidget()
+{
+ // non-inline destructor, see section "Forward Declared Pointers" of QScopedPointer.
+}
+
+CppEditorDocument *CppEditorWidget::cppEditorDocument() const
+{
+ return d->m_cppEditorDocument;
+}
+
+CppEditorOutline *CppEditorWidget::outline() const
+{
+ return d->m_cppEditorOutline;
+}
+
+void CppEditorWidget::paste()
+{
+ if (d->m_localRenaming.handlePaste())
+ return;
+
+ TextEditorWidget::paste();
+}
+
+void CppEditorWidget::cut()
+{
+ if (d->m_localRenaming.handleCut())
+ return;
+
+ TextEditorWidget::cut();
+}
+
+void CppEditorWidget::selectAll()
+{
+ if (d->m_localRenaming.handleSelectAll())
+ return;
+
+ TextEditorWidget::selectAll();
+}
+
+void CppEditorWidget::onCppDocumentUpdated()
+{
+ d->m_cppEditorOutline->update();
+}
+
+void CppEditorWidget::onCodeWarningsUpdated(unsigned revision,
+ const QList<QTextEdit::ExtraSelection> selections,
+ const TextEditor::RefactorMarkers &refactorMarkers)
+{
+ if (revision != documentRevision())
+ return;
+
+ setExtraSelections(TextEditorWidget::CodeWarningsSelection, selections);
+ setRefactorMarkers(refactorMarkersWithoutClangMarkers() + refactorMarkers);
+}
+
+void CppEditorWidget::onIfdefedOutBlocksUpdated(unsigned revision,
+ const QList<BlockRange> ifdefedOutBlocks)
+{
+ if (revision != documentRevision())
+ return;
+ setIfdefedOutBlocks(ifdefedOutBlocks);
+}
+
+void CppEditorWidget::onShowInfoBarAction(const Id &id, bool show)
+{
+ QAction *action = d->m_showInfoBarActions.value(id);
+ QTC_ASSERT(action, return);
+ action->setVisible(show);
+}
+
+void CppEditorWidget::findUsages()
+{
+ if (!d->m_modelManager)
+ return;
+
+ SemanticInfo info = d->m_lastSemanticInfo;
+ info.snapshot = CppModelManager::instance()->snapshot();
+ info.snapshot.insert(info.doc);
+
+ if (const Macro *macro = CppTools::findCanonicalMacro(textCursor(), info.doc)) {
+ d->m_modelManager->findMacroUsages(*macro);
+ } else {
+ CanonicalSymbol cs(info.doc, info.snapshot);
+ Symbol *canonicalSymbol = cs(textCursor());
+ if (canonicalSymbol)
+ d->m_modelManager->findUsages(canonicalSymbol, cs.context());
+ }
+}
+
+void CppEditorWidget::renameUsagesInternal(const QString &replacement)
+{
+ if (!d->m_modelManager)
+ return;
+
+ SemanticInfo info = d->m_lastSemanticInfo;
+ info.snapshot = CppModelManager::instance()->snapshot();
+ info.snapshot.insert(info.doc);
+
+ if (const Macro *macro = CppTools::findCanonicalMacro(textCursor(), info.doc)) {
+ d->m_modelManager->renameMacroUsages(*macro, replacement);
+ } else {
+ CanonicalSymbol cs(info.doc, info.snapshot);
+ if (Symbol *canonicalSymbol = cs(textCursor()))
+ if (canonicalSymbol->identifier() != 0)
+ d->m_modelManager->renameUsages(canonicalSymbol, cs.context(), replacement);
+ }
+}
+
+bool CppEditorWidget::selectBlockUp()
+{
+ if (!behaviorSettings().m_smartSelectionChanging)
+ return TextEditorWidget::selectBlockUp();
+
+ QTextCursor cursor = textCursor();
+ d->m_cppSelectionChanger.startChangeSelection();
+ const bool changed = d->m_cppSelectionChanger
+ .changeSelection(CppSelectionChanger::ExpandSelection,
+ cursor,
+ d->m_lastSemanticInfo.doc);
+ if (changed)
+ setTextCursor(cursor);
+ d->m_cppSelectionChanger.stopChangeSelection();
+
+ return changed;
+}
+
+bool CppEditorWidget::selectBlockDown()
+{
+ if (!behaviorSettings().m_smartSelectionChanging)
+ return TextEditorWidget::selectBlockDown();
+
+ QTextCursor cursor = textCursor();
+ d->m_cppSelectionChanger.startChangeSelection();
+ const bool changed = d->m_cppSelectionChanger
+ .changeSelection(CppSelectionChanger::ShrinkSelection,
+ cursor,
+ d->m_lastSemanticInfo.doc);
+ if (changed)
+ setTextCursor(cursor);
+ d->m_cppSelectionChanger.stopChangeSelection();
+
+ return changed;
+}
+
+void CppEditorWidget::updateWidgetHighlighting(QWidget *widget, bool highlight)
+{
+ if (!widget)
+ return;
+
+ widget->setProperty("highlightWidget", highlight);
+ widget->update();
+}
+
+bool CppEditorWidget::isWidgetHighlighted(QWidget *widget)
+{
+ return widget ? widget->property("highlightWidget").toBool() : false;
+}
+
+namespace {
+
+QList<ProjectPart::Ptr> fetchProjectParts(CppTools::CppModelManager *modelManager,
+ const Utils::FileName &filePath)
+{
+ QList<ProjectPart::Ptr> projectParts = modelManager->projectPart(filePath);
+
+ if (projectParts.isEmpty())
+ projectParts = modelManager->projectPartFromDependencies(filePath);
+ if (projectParts.isEmpty())
+ projectParts.append(modelManager->fallbackProjectPart());
+
+ return projectParts;
+}
+
+ProjectPart *findProjectPartForCurrentProject(const QList<ProjectPart::Ptr> &projectParts,
+ ProjectExplorer::Project *currentProject)
+{
+ auto found = std::find_if(projectParts.cbegin(),
+ projectParts.cend(),
+ [&](const CppTools::ProjectPart::Ptr &projectPart) {
+ return projectPart->project == currentProject;
+ });
+
+ if (found != projectParts.cend())
+ return (*found).data();
+
+ return 0;
+}
+
+} // namespace
+
+ProjectPart *CppEditorWidget::projectPart() const
+{
+ if (!d->m_modelManager)
+ return 0;
+
+ auto projectParts = fetchProjectParts(d->m_modelManager, textDocument()->filePath());
+
+ return findProjectPartForCurrentProject(projectParts,
+ ProjectExplorer::ProjectTree::currentProject());
+}
+
+namespace {
+
+using ClangBackEnd::V2::SourceLocationContainer;
+using Utils::Text::selectAt;
+
+QTextCharFormat occurrencesTextCharFormat()
+{
+ using TextEditor::TextEditorSettings;
+
+ return TextEditorSettings::fontSettings().toTextCharFormat(TextEditor::C_OCCURRENCES);
+}
+
+QList<QTextEdit::ExtraSelection> sourceLocationsToExtraSelections(
+ const std::vector<SourceLocationContainer> &sourceLocations,
+ uint selectionLength,
+ CppEditorWidget *cppEditorWidget)
+{
+ const auto textCharFormat = occurrencesTextCharFormat();
+
+ QList<QTextEdit::ExtraSelection> selections;
+ selections.reserve(int(sourceLocations.size()));
+
+ auto sourceLocationToExtraSelection = [&](const SourceLocationContainer &sourceLocation) {
+ QTextEdit::ExtraSelection selection;
+
+ selection.cursor = selectAt(cppEditorWidget->textCursor(),
+ sourceLocation.line(),
+ sourceLocation.column(),
+ selectionLength);
+ selection.format = textCharFormat;
+
+ return selection;
+ };
+
+ std::transform(sourceLocations.begin(),
+ sourceLocations.end(),
+ std::back_inserter(selections),
+ sourceLocationToExtraSelection);
+
+ return selections;
+};
+
+}
+
+void CppEditorWidget::renameSymbolUnderCursor()
+{
+ using ClangBackEnd::SourceLocationsContainer;
+
+ ProjectPart *projPart = projectPart();
+ if (!refactoringEngine().isUsable() || !projPart)
+ return;
+
+ d->m_useSelectionsUpdater.abortSchedule();
+
+ QPointer<CppEditorWidget> cppEditorWidget = this;
+
+ auto renameSymbols = [=](const QString &symbolName,
+ const SourceLocationsContainer &sourceLocations,
+ int revision) {
+ if (cppEditorWidget) {
+ viewport()->setCursor(Qt::IBeamCursor);
+
+ if (revision != document()->revision())
+ return;
+ if (sourceLocations.hasContent()) {
+ QList<QTextEdit::ExtraSelection> selections
+ = sourceLocationsToExtraSelections(sourceLocations.sourceLocationContainers(),
+ static_cast<uint>(symbolName.size()),
+ cppEditorWidget);
+ setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection, selections);
+ d->m_localRenaming.updateSelectionsForVariableUnderCursor(selections);
+ }
+ if (!d->m_localRenaming.start()) {
+ refactoringEngine().startGlobalRenaming(
+ CppTools::CursorInEditor{textCursor(), textDocument()->filePath(), this});
+ }
+ }
+ };
+
+ viewport()->setCursor(Qt::BusyCursor);
+ refactoringEngine().startLocalRenaming(CppTools::CursorInEditor{textCursor(),
+ textDocument()->filePath(),
+ this},
+ projPart,
+ std::move(renameSymbols));
+}
+
+void CppEditorWidget::updatePreprocessorButtonTooltip()
+{
+ if (!d->m_preprocessorButton)
+ return;
+
+ Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
+ QTC_ASSERT(cmd, return );
+ d->m_preprocessorButton->setToolTip(cmd->action()->toolTip());
+}
+
+void CppEditorWidget::switchDeclarationDefinition(bool inNextSplit)
+{
+ if (!d->m_modelManager)
+ return;
+
+ if (!d->m_lastSemanticInfo.doc)
+ return;
+
+ // Find function declaration or definition under cursor
+ Function *functionDefinitionSymbol = 0;
+ Symbol *functionDeclarationSymbol = 0;
+
+ ASTPath astPathFinder(d->m_lastSemanticInfo.doc);
+ const QList<AST *> astPath = astPathFinder(textCursor());
+
+ for (int i = 0, size = astPath.size(); i < size; ++i) {
+ AST *ast = astPath.at(i);
+ if (FunctionDefinitionAST *functionDefinitionAST = ast->asFunctionDefinition()) {
+ if ((functionDefinitionSymbol = functionDefinitionAST->symbol))
+ break; // Function definition found!
+ } else if (SimpleDeclarationAST *simpleDeclaration = ast->asSimpleDeclaration()) {
+ if (List<Symbol *> *symbols = simpleDeclaration->symbols) {
+ if (Symbol *symbol = symbols->value) {
+ if (symbol->isDeclaration() && symbol->type()->isFunctionType()) {
+ functionDeclarationSymbol = symbol;
+ break; // Function declaration found!
+ }
+ }
+ }
+ }
+ }
+
+ // Link to function definition/declaration
+ CppEditorWidget::Link symbolLink;
+ if (functionDeclarationSymbol) {
+ symbolLink = linkToSymbol(
+ d->m_modelManager->symbolFinder()
+ ->findMatchingDefinition(functionDeclarationSymbol, d->m_modelManager->snapshot()));
+ } else if (functionDefinitionSymbol) {
+ const Snapshot snapshot = d->m_modelManager->snapshot();
+ LookupContext context(d->m_lastSemanticInfo.doc, snapshot);
+ ClassOrNamespace *binding = context.lookupType(functionDefinitionSymbol);
+ const QList<LookupItem> declarations
+ = context.lookup(functionDefinitionSymbol->name(),
+ functionDefinitionSymbol->enclosingScope());
+
+ QList<Symbol *> best;
+ foreach (const LookupItem &r, declarations) {
+ if (Symbol *decl = r.declaration()) {
+ if (Function *funTy = decl->type()->asFunctionType()) {
+ if (funTy->match(functionDefinitionSymbol)) {
+ if (decl != functionDefinitionSymbol && binding == r.binding())
+ best.prepend(decl);
+ else
+ best.append(decl);
+ }
+ }
+ }
+ }
+
+ if (best.isEmpty())
+ return;
+ symbolLink = linkToSymbol(best.first());
+ }
+
+ // Open Editor at link position
+ if (symbolLink.hasValidTarget())
+ openLink(symbolLink, inNextSplit != alwaysOpenLinksInNextSplit());
+}
+
+CppEditorWidget::Link CppEditorWidget::findLinkAt(const QTextCursor &cursor,
+ bool resolveTarget,
+ bool inNextSplit)
+{
+ if (!d->m_modelManager)
+ return Link();
+
+ const Utils::FileName &filePath = textDocument()->filePath();
+
+ return followSymbolInterface().findLink(CppTools::CursorInEditor{cursor, filePath, this},
+ resolveTarget,
+ d->m_modelManager->snapshot(),
+ d->m_lastSemanticInfo.doc,
+ d->m_modelManager->symbolFinder(),
+ inNextSplit);
+}
+
+unsigned CppEditorWidget::documentRevision() const
+{
+ return document()->revision();
+}
+
+static bool isClangFixItAvailableMarker(const RefactorMarker &marker)
+{
+ return marker.data.toString()
+ == QLatin1String(CppTools::Constants::CPP_CLANG_FIXIT_AVAILABLE_MARKER_ID);
+}
+
+RefactorMarkers CppEditorWidget::refactorMarkersWithoutClangMarkers() const
+{
+ RefactorMarkers clearedRefactorMarkers;
+
+ foreach (const RefactorMarker &marker, refactorMarkers()) {
+ if (isClangFixItAvailableMarker(marker))
+ continue;
+
+ clearedRefactorMarkers.append(marker);
+ }
+
+ return clearedRefactorMarkers;
+}
+
+RefactoringEngineInterface &CppEditorWidget::refactoringEngine() const
+{
+ return CppTools::CppModelManager::refactoringEngine();
+}
+
+CppTools::FollowSymbolInterface &CppEditorWidget::followSymbolInterface() const
+{
+ return CppTools::CppModelManager::instance()->followSymbolInterface();
+}
+
+bool CppEditorWidget::isSemanticInfoValidExceptLocalUses() const
+{
+ return d->m_lastSemanticInfo.doc && d->m_lastSemanticInfo.revision == documentRevision()
+ && !d->m_lastSemanticInfo.snapshot.isEmpty();
+}
+
+bool CppEditorWidget::isSemanticInfoValid() const
+{
+ return isSemanticInfoValidExceptLocalUses() && d->m_lastSemanticInfo.localUsesUpdated;
+}
+
+SemanticInfo CppEditorWidget::semanticInfo() const
+{
+ return d->m_lastSemanticInfo;
+}
+
+bool CppEditorWidget::event(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::ShortcutOverride:
+ // handle escape manually if a rename is active
+ if (static_cast<QKeyEvent *>(e)->key() == Qt::Key_Escape && d->m_localRenaming.isActive()) {
+ e->accept();
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return TextEditorWidget::event(e);
+}
+
+void CppEditorWidget::processKeyNormally(QKeyEvent *e)
+{
+ TextEditorWidget::keyPressEvent(e);
+}
+
+static void addRefactoringActions(QMenu *menu, AssistInterface *iface)
+{
+ if (!iface || !menu)
+ return;
+
+ using Processor = QScopedPointer<IAssistProcessor>;
+ using Proposal = QScopedPointer<IAssistProposal>;
+ using Model = QScopedPointer<GenericProposalModel>;
+
+ const Processor processor(CppEditorPlugin::instance()->quickFixProvider()->createProcessor());
+ const Proposal proposal(processor->perform(iface)); // OK, perform() takes ownership of iface.
+ if (proposal) {
+ Model model(static_cast<GenericProposalModel *>(proposal->model()));
+ for (int index = 0; index < model->size(); ++index) {
+ const auto item = static_cast<AssistProposalItem *>(model->proposalItem(index));
+ const QuickFixOperation::Ptr op = item->data().value<QuickFixOperation::Ptr>();
+ const QAction *action = menu->addAction(op->description());
+ QObject::connect(action, &QAction::triggered, menu, [op] { op->perform(); });
+ }
+ }
+}
+
+class ProgressIndicatorMenuItem : public QWidgetAction
+{
+ Q_OBJECT
+
+public:
+ ProgressIndicatorMenuItem(QObject *parent) : QWidgetAction(parent) {}
+
+protected:
+ QWidget *createWidget(QWidget *parent = nullptr) override
+ {
+ return new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Small, parent);
+ }
+};
+
+QMenu *CppEditorWidget::createRefactorMenu(QWidget *parent) const
+{
+ auto *menu = new QMenu(tr("&Refactor"), parent);
+ menu->addAction(ActionManager::command(Constants::RENAME_SYMBOL_UNDER_CURSOR)->action());
+
+ // ### enable
+ // updateSemanticInfo(m_semanticHighlighter->semanticInfo(currentSource()));
+
+ if (isSemanticInfoValidExceptLocalUses()) {
+ d->m_useSelectionsUpdater.abortSchedule();
+
+ const CppUseSelectionsUpdater::RunnerInfo runnerInfo = d->m_useSelectionsUpdater.update();
+ switch (runnerInfo) {
+ case CppUseSelectionsUpdater::RunnerInfo::AlreadyUpToDate:
+ addRefactoringActions(menu, createAssistInterface(QuickFix, ExplicitlyInvoked));
+ break;
+ case CppUseSelectionsUpdater::RunnerInfo::Started: {
+ // Update the refactor menu once we get the results.
+ auto *progressIndicatorMenuItem = new ProgressIndicatorMenuItem(menu);
+ menu->addAction(progressIndicatorMenuItem);
+
+ connect(&d->m_useSelectionsUpdater, &CppUseSelectionsUpdater::finished,
+ menu, [=] (SemanticInfo::LocalUseMap, bool success) {
+ QTC_CHECK(success);
+ menu->removeAction(progressIndicatorMenuItem);
+ addRefactoringActions(menu, createAssistInterface(QuickFix, ExplicitlyInvoked));
+ });
+ break;
+ }
+ case CppUseSelectionsUpdater::RunnerInfo::FailedToStart:
+ case CppUseSelectionsUpdater::RunnerInfo::Invalid:
+ QTC_CHECK(false && "Unexpected CppUseSelectionsUpdater runner result");
+ }
+ }
+
+ return menu;
+}
+
+static void appendCustomContextMenuActionsAndMenus(QMenu *menu, QMenu *refactorMenu)
+{
+ bool isRefactoringMenuAdded = false;
+ const QMenu *contextMenu = ActionManager::actionContainer(Constants::M_CONTEXT)->menu();
+ for (QAction *action : contextMenu->actions()) {
+ menu->addAction(action);
+ if (action->objectName() == Constants::M_REFACTORING_MENU_INSERTION_POINT) {
+ isRefactoringMenuAdded = true;
+ menu->addMenu(refactorMenu);
+ }
+ }
+
+ QTC_CHECK(isRefactoringMenuAdded);
+}
+
+void CppEditorWidget::contextMenuEvent(QContextMenuEvent *e)
+{
+ const QPointer<QMenu> menu(new QMenu(this));
+
+ appendCustomContextMenuActionsAndMenus(menu, createRefactorMenu(menu));
+ appendStandardContextMenuActions(menu);
+
+ menu->exec(e->globalPos());
+ if (menu)
+ delete menu; // OK, menu was not already deleted by closed editor widget.
+}
+
+void CppEditorWidget::keyPressEvent(QKeyEvent *e)
+{
+ if (d->m_localRenaming.handleKeyPressEvent(e))
+ return;
+
+ if (handleStringSplitting(e))
+ return;
+
+ if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
+ if (trySplitComment(this, semanticInfo().snapshot)) {
+ e->accept();
+ return;
+ }
+ }
+
+ TextEditorWidget::keyPressEvent(e);
+}
+
+bool CppEditorWidget::handleStringSplitting(QKeyEvent *e) const
+{
+ if (!TextEditorSettings::completionSettings().m_autoSplitStrings)
+ return false;
+
+ if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
+ QTextCursor cursor = textCursor();
+
+ const Kind stringKind = CPlusPlus::MatchingText::stringKindAtCursor(cursor);
+ if (stringKind >= T_FIRST_STRING_LITERAL && stringKind < T_FIRST_RAW_STRING_LITERAL) {
+ cursor.beginEditBlock();
+ if (cursor.positionInBlock() > 0
+ && cursor.block().text().at(cursor.positionInBlock() - 1) == QLatin1Char('\\')) {
+ // Already escaped: simply go back to line, but do not indent.
+ cursor.insertText(QLatin1String("\n"));
+ } else if (e->modifiers() & Qt::ShiftModifier) {
+ // With 'shift' modifier, escape the end of line character
+ // and start at beginning of next line.
+ cursor.insertText(QLatin1String("\\\n"));
+ } else {
+ // End the current string, and start a new one on the line, properly indented.
+ cursor.insertText(QLatin1String("\"\n\""));
+ textDocument()->autoIndent(cursor);
+ }
+ cursor.endEditBlock();
+ e->accept();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void CppEditorWidget::slotCodeStyleSettingsChanged(const QVariant &)
+{
+ QtStyleCodeFormatter formatter;
+ formatter.invalidateCache(document());
+}
+
+void CppEditorWidget::updateSemanticInfo()
+{
+ updateSemanticInfo(d->m_cppEditorDocument->recalculateSemanticInfo(),
+ /*updateUseSelectionSynchronously=*/ true);
+}
+
+void CppEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo,
+ bool updateUseSelectionSynchronously)
+{
+ if (semanticInfo.revision != documentRevision())
+ return;
+
+ d->m_lastSemanticInfo = semanticInfo;
+
+ if (!d->m_localRenaming.isActive()) {
+ const CppUseSelectionsUpdater::CallType type = updateUseSelectionSynchronously
+ ? CppUseSelectionsUpdater::CallType::Synchronous
+ : CppUseSelectionsUpdater::CallType::Asynchronous;
+ d->m_useSelectionsUpdater.update(type);
+ }
+
+ // schedule a check for a decl/def link
+ updateFunctionDeclDefLink();
+}
+
+AssistInterface *CppEditorWidget::createAssistInterface(AssistKind kind, AssistReason reason) const
+{
+ if (kind == Completion) {
+ if (CppCompletionAssistProvider *cap = qobject_cast<CppCompletionAssistProvider *>(
+ cppEditorDocument()->completionAssistProvider())) {
+ LanguageFeatures features = LanguageFeatures::defaultFeatures();
+ if (Document::Ptr doc = d->m_lastSemanticInfo.doc)
+ features = doc->languageFeatures();
+ features.objCEnabled |= cppEditorDocument()->isObjCEnabled();
+ return cap->createAssistInterface(textDocument()->filePath().toString(),
+ this,
+ features,
+ position(),
+ reason);
+ }
+ } else if (kind == QuickFix) {
+ if (isSemanticInfoValid())
+ return new CppQuickFixInterface(const_cast<CppEditorWidget *>(this), reason);
+ } else {
+ return TextEditorWidget::createAssistInterface(kind, reason);
+ }
+ return 0;
+}
+
+QSharedPointer<FunctionDeclDefLink> CppEditorWidget::declDefLink() const
+{
+ return d->m_declDefLink;
+}
+
+void CppEditorWidget::onRefactorMarkerClicked(const RefactorMarker &marker)
+{
+ if (marker.data.canConvert<FunctionDeclDefLink::Marker>()) {
+ applyDeclDefLinkChanges(true);
+ } else if (isClangFixItAvailableMarker(marker)) {
+ int line, column;
+ if (Utils::Text::convertPosition(document(), marker.cursor.position(), &line, &column)) {
+ setTextCursor(marker.cursor);
+ invokeAssist(TextEditor::QuickFix);
+ }
+ }
+}
+
+void CppEditorWidget::updateFunctionDeclDefLink()
+{
+ const int pos = textCursor().selectionStart();
+
+ // if there's already a link, abort it if the cursor is outside or the name changed
+ // (adding a prefix is an exception since the user might type a return type)
+ if (d->m_declDefLink
+ && (pos < d->m_declDefLink->linkSelection.selectionStart()
+ || pos > d->m_declDefLink->linkSelection.selectionEnd()
+ || !d->m_declDefLink->nameSelection.selectedText().trimmed().endsWith(
+ d->m_declDefLink->nameInitial))) {
+ abortDeclDefLink();
+ return;
+ }
+
+ // don't start a new scan if there's one active and the cursor is already in the scanned area
+ const QTextCursor scannedSelection = d->m_declDefLinkFinder->scannedSelection();
+ if (!scannedSelection.isNull() && scannedSelection.selectionStart() <= pos
+ && scannedSelection.selectionEnd() >= pos) {
+ return;
+ }
+
+ d->m_updateFunctionDeclDefLinkTimer.start();
+}
+
+void CppEditorWidget::updateFunctionDeclDefLinkNow()
+{
+ IEditor *editor = EditorManager::currentEditor();
+ if (!editor || editor->widget() != this)
+ return;
+
+ const Snapshot semanticSnapshot = d->m_lastSemanticInfo.snapshot;
+ const Document::Ptr semanticDoc = d->m_lastSemanticInfo.doc;
+
+ if (d->m_declDefLink) {
+ // update the change marker
+ const Utils::ChangeSet changes = d->m_declDefLink->changes(semanticSnapshot);
+ if (changes.isEmpty())
+ d->m_declDefLink->hideMarker(this);
+ else
+ d->m_declDefLink->showMarker(this);
+ return;
+ }
+
+ if (!isSemanticInfoValidExceptLocalUses())
+ return;
+
+ Snapshot snapshot = CppModelManager::instance()->snapshot();
+ snapshot.insert(semanticDoc);
+
+ d->m_declDefLinkFinder->startFindLinkAt(textCursor(), semanticDoc, snapshot);
+}
+
+void CppEditorWidget::onFunctionDeclDefLinkFound(QSharedPointer<FunctionDeclDefLink> link)
+{
+ abortDeclDefLink();
+ d->m_declDefLink = link;
+ IDocument *targetDocument = DocumentModel::documentForFilePath(
+ d->m_declDefLink->targetFile->fileName());
+ if (textDocument() != targetDocument) {
+ if (auto textDocument = qobject_cast<BaseTextDocument *>(targetDocument))
+ connect(textDocument,
+ &IDocument::contentsChanged,
+ this,
+ &CppEditorWidget::abortDeclDefLink);
+ }
+}
+
+void CppEditorWidget::applyDeclDefLinkChanges(bool jumpToMatch)
+{
+ if (!d->m_declDefLink)
+ return;
+ d->m_declDefLink->apply(this, jumpToMatch);
+ abortDeclDefLink();
+ updateFunctionDeclDefLink();
+}
+
+void CppEditorWidget::encourageApply()
+{
+ if (d->m_localRenaming.encourageApply())
+ return;
+
+ TextEditorWidget::encourageApply();
+}
+
+void CppEditorWidget::abortDeclDefLink()
+{
+ if (!d->m_declDefLink)
+ return;
+
+ IDocument *targetDocument = DocumentModel::documentForFilePath(
+ d->m_declDefLink->targetFile->fileName());
+ if (textDocument() != targetDocument) {
+ if (auto textDocument = qobject_cast<BaseTextDocument *>(targetDocument))
+ disconnect(textDocument,
+ &IDocument::contentsChanged,
+ this,
+ &CppEditorWidget::abortDeclDefLink);
+ }
+
+ d->m_declDefLink->hideMarker(this);
+ d->m_declDefLink.clear();
+}
+
+void CppEditorWidget::showPreProcessorWidget()
+{
+ const QString filePath = textDocument()->filePath().toString();
+
+ CppPreProcessorDialog dialog(filePath, this);
+ if (dialog.exec() == QDialog::Accepted) {
+ const QByteArray extraDirectives = dialog.extraPreprocessorDirectives().toUtf8();
+ cppEditorDocument()->setExtraPreprocessorDirectives(extraDirectives);
+ cppEditorDocument()->scheduleProcessDocument();
+ }
+}
+
+void CppEditorWidget::invokeTextEditorWidgetAssist(TextEditor::AssistKind assistKind,
+ TextEditor::IAssistProvider *provider)
+{
+ invokeAssist(assistKind, provider);
+}
+
+} // namespace Internal
+} // namespace CppEditor
+
+#include "cppeditorwidget.moc"
diff --git a/src/plugins/cppeditor/cppeditorwidget.h b/src/plugins/cppeditor/cppeditorwidget.h
new file mode 100644
index 00000000000..166ff10557d
--- /dev/null
+++ b/src/plugins/cppeditor/cppeditorwidget.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <texteditor/texteditor.h>
+
+#include <cpptools/cppeditorwidgetinterface.h>
+
+#include <QScopedPointer>
+
+namespace CppTools {
+class CppEditorOutline;
+class RefactoringEngineInterface;
+class FollowSymbolInterface;
+class SemanticInfo;
+class ProjectPart;
+}
+
+namespace CppEditor {
+namespace Internal {
+
+class CppEditorDocument;
+
+class CppEditorWidgetPrivate;
+class FunctionDeclDefLink;
+
+class CppEditorWidget : public TextEditor::TextEditorWidget,
+ public CppTools::CppEditorWidgetInterface
+{
+ Q_OBJECT
+
+public:
+ CppEditorWidget();
+ ~CppEditorWidget() override;
+
+ CppEditorDocument *cppEditorDocument() const;
+ CppTools::CppEditorOutline *outline() const;
+
+ CppTools::SemanticInfo semanticInfo() const;
+ bool isSemanticInfoValidExceptLocalUses() const;
+ bool isSemanticInfoValid() const;
+
+ QSharedPointer<FunctionDeclDefLink> declDefLink() const;
+ void applyDeclDefLinkChanges(bool jumpToMatch);
+
+ TextEditor::AssistInterface *createAssistInterface(
+ TextEditor::AssistKind kind,
+ TextEditor::AssistReason reason) const override;
+
+ void encourageApply() override;
+
+ void paste() override;
+ void cut() override;
+ void selectAll() override;
+
+ void switchDeclarationDefinition(bool inNextSplit);
+ void showPreProcessorWidget() override;
+
+ void findUsages();
+ void renameSymbolUnderCursor();
+
+ bool selectBlockUp() override;
+ bool selectBlockDown() override;
+
+ static void updateWidgetHighlighting(QWidget *widget, bool highlight);
+ static bool isWidgetHighlighted(QWidget *widget);
+
+ void updateSemanticInfo() override;
+ void invokeTextEditorWidgetAssist(TextEditor::AssistKind assistKind,
+ TextEditor::IAssistProvider *provider) override;
+
+protected:
+ bool event(QEvent *e) override;
+ void contextMenuEvent(QContextMenuEvent *) override;
+ void keyPressEvent(QKeyEvent *e) override;
+ bool handleStringSplitting(QKeyEvent *e) const;
+
+ Link findLinkAt(const QTextCursor &, bool resolveTarget = true,
+ bool inNextSplit = false) override;
+
+ void onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker) override;
+
+ void slotCodeStyleSettingsChanged(const QVariant &) override;
+
+ void renameUsagesInternal(const QString &replacement) override;
+
+private:
+ void updateFunctionDeclDefLink();
+ void updateFunctionDeclDefLinkNow();
+ void abortDeclDefLink();
+ void onFunctionDeclDefLinkFound(QSharedPointer<FunctionDeclDefLink> link);
+
+ void onCppDocumentUpdated();
+
+ void onCodeWarningsUpdated(unsigned revision,
+ const QList<QTextEdit::ExtraSelection> selections,
+ const TextEditor::RefactorMarkers &refactorMarkers);
+ void onIfdefedOutBlocksUpdated(unsigned revision,
+ const QList<TextEditor::BlockRange> ifdefedOutBlocks);
+
+ void onShowInfoBarAction(const Core::Id &id, bool show);
+
+ void updateSemanticInfo(const CppTools::SemanticInfo &semanticInfo,
+ bool updateUseSelectionSynchronously = false);
+ void updatePreprocessorButtonTooltip();
+
+ void processKeyNormally(QKeyEvent *e);
+
+ void finalizeInitialization() override;
+ void finalizeInitializationAfterDuplication(TextEditorWidget *other) override;
+
+ unsigned documentRevision() const;
+
+ QMenu *createRefactorMenu(QWidget *parent) const;
+
+ TextEditor::RefactorMarkers refactorMarkersWithoutClangMarkers() const;
+
+ CppTools::FollowSymbolInterface &followSymbolInterface() const;
+ CppTools::RefactoringEngineInterface &refactoringEngine() const;
+
+ CppTools::ProjectPart *projectPart() const;
+
+private:
+ QScopedPointer<CppEditorWidgetPrivate> d;
+};
+
+} // namespace Internal
+} // namespace CppEditor
diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
index 9eaf09ab11c..86bdf2a0cf7 100644
--- a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
+++ b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
@@ -25,7 +25,7 @@
#include "cppfunctiondecldeflink.h"
-#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppquickfixassistant.h"
#include <coreplugin/actionmanager/actionmanager.h>
diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp
index 75b5913f17b..dcb182435d4 100644
--- a/src/plugins/cppeditor/cpphoverhandler.cpp
+++ b/src/plugins/cppeditor/cpphoverhandler.cpp
@@ -32,9 +32,9 @@
#include <cpptools/baseeditordocumentprocessor.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/editordocumenthandle.h>
-#include <texteditor/convenience.h>
#include <texteditor/texteditor.h>
+#include <utils/textutils.h>
#include <utils/qtcassert.h>
#include <utils/tooltip/tooltip.h>
@@ -63,7 +63,7 @@ bool editorDocumentProcessorHasDiagnosticAt(TextEditorWidget *editorWidget, int
{
if (CppTools::BaseEditorDocumentProcessor *processor = editorDocumentProcessor(editorWidget)) {
int line, column;
- if (Convenience::convertPosition(editorWidget->document(), pos, &line, &column))
+ if (Utils::Text::convertPosition(editorWidget->document(), pos, &line, &column))
return processor->hasDiagnosticsAt(line, column);
}
@@ -77,7 +77,7 @@ void processWithEditorDocumentProcessor(TextEditorWidget *editorWidget,
{
if (CppTools::BaseEditorDocumentProcessor *processor = editorDocumentProcessor(editorWidget)) {
int line, column;
- if (Convenience::convertPosition(editorWidget->document(), position, &line, &column)) {
+ if (Utils::Text::convertPosition(editorWidget->document(), position, &line, &column)) {
auto layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(2);
diff --git a/src/plugins/cppeditor/cppincludehierarchy.cpp b/src/plugins/cppeditor/cppincludehierarchy.cpp
index c47b39b21df..9baa067af12 100644
--- a/src/plugins/cppeditor/cppincludehierarchy.cpp
+++ b/src/plugins/cppeditor/cppincludehierarchy.cpp
@@ -26,6 +26,7 @@
#include "cppincludehierarchy.h"
#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditorconstants.h"
#include "cppeditorplugin.h"
#include "cppelementevaluator.h"
@@ -407,7 +408,7 @@ void CppIncludeHierarchyWidget::perform()
m_inspectedFile->setText(m_editor->textDocument()->displayName());
m_inspectedFile->setLink(TextEditorWidget::Link(document));
- // expand "Includes" adn "Included by"
+ // expand "Includes" and "Included by"
m_treeView->expand(m_model.index(0, 0));
m_treeView->expand(m_model.index(1, 0));
diff --git a/src/plugins/cppeditor/cppincludehierarchy_test.cpp b/src/plugins/cppeditor/cppincludehierarchy_test.cpp
index 95995e732a7..33a58400cc7 100644
--- a/src/plugins/cppeditor/cppincludehierarchy_test.cpp
+++ b/src/plugins/cppeditor/cppincludehierarchy_test.cpp
@@ -23,6 +23,8 @@
**
****************************************************************************/
+#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditorplugin.h"
#include "cppeditortestcase.h"
#include "cppincludehierarchy.h"
diff --git a/src/plugins/cppeditor/cppoutline.h b/src/plugins/cppeditor/cppoutline.h
index 9e28506027a..2176fde2e20 100644
--- a/src/plugins/cppeditor/cppoutline.h
+++ b/src/plugins/cppeditor/cppoutline.h
@@ -26,6 +26,7 @@
#pragma once
#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include <texteditor/ioutlinewidget.h>
diff --git a/src/plugins/cppeditor/cppparsecontext.cpp b/src/plugins/cppeditor/cppparsecontext.cpp
index 1519f0e71af..b3a3f1b1a3d 100644
--- a/src/plugins/cppeditor/cppparsecontext.cpp
+++ b/src/plugins/cppeditor/cppparsecontext.cpp
@@ -25,7 +25,7 @@
#include "cppparsecontext.h"
-#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include <QAction>
#include <QDir>
diff --git a/src/plugins/cppeditor/cpppreprocessordialog.cpp b/src/plugins/cppeditor/cpppreprocessordialog.cpp
index 167e373a2da..f66ee92a89c 100644
--- a/src/plugins/cppeditor/cpppreprocessordialog.cpp
+++ b/src/plugins/cppeditor/cpppreprocessordialog.cpp
@@ -27,6 +27,7 @@
#include "ui_cpppreprocessordialog.h"
#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditorconstants.h"
#include <projectexplorer/session.h>
diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp
index 7882fef70ee..bfc35a67c4d 100644
--- a/src/plugins/cppeditor/cppquickfix_test.cpp
+++ b/src/plugins/cppeditor/cppquickfix_test.cpp
@@ -23,6 +23,8 @@
**
****************************************************************************/
+#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditorplugin.h"
#include "cppeditortestcase.h"
#include "cppquickfixassistant.h"
diff --git a/src/plugins/cppeditor/cppquickfixassistant.cpp b/src/plugins/cppeditor/cppquickfixassistant.cpp
index bde1f759bc6..8ded187d889 100644
--- a/src/plugins/cppeditor/cppquickfixassistant.cpp
+++ b/src/plugins/cppeditor/cppquickfixassistant.cpp
@@ -26,7 +26,8 @@
#include "cppquickfixassistant.h"
#include "cppeditorconstants.h"
-#include "cppeditor.h"
+#include "cppeditorwidget.h"
+#include "cppquickfixes.h"
#include <cpptools/cppmodelmanager.h>
#include <texteditor/textdocument.h>
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index 640fa794ef0..9f51f15febb 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -25,16 +25,16 @@
#include "cppquickfixes.h"
-#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditordocument.h"
#include "cppfunctiondecldeflink.h"
#include "cppquickfixassistant.h"
-#include "cppvirtualfunctionassistprovider.h"
#include "cppinsertvirtualmethods.h"
#include <coreplugin/icore.h>
#include <coreplugin/messagebox.h>
+#include <cpptools/cppvirtualfunctionassistprovider.h>
#include <cpptools/baseeditordocumentprocessor.h>
#include <cpptools/cppclassesfilter.h>
#include <cpptools/cppcodestylesettings.h>
@@ -2934,8 +2934,6 @@ public:
updateDescriptionAndPriority();
}
- void determineGetterSetterNames();
-
// Clones "other" in order to prevent all the initial detection made in the ctor.
GenerateGetterSetterOperation(const CppQuickFixInterface &interface,
GenerateGetterSetterOperation *other, OperationType type)
@@ -2968,6 +2966,28 @@ public:
return (m_type == GetterSetterType || m_type == SetterType);
}
+ void determineGetterSetterNames()
+ {
+ m_baseName = memberBaseName(m_variableString);
+ if (m_baseName.isEmpty())
+ m_baseName = QLatin1String("value");
+
+ // Getter Name
+ const CppCodeStyleSettings settings = CppCodeStyleSettings::currentProjectCodeStyle();
+ const bool hasValidBaseName = m_baseName != m_variableString;
+ const bool getPrefixIsAlreadyUsed = hasClassMemberWithGetPrefix(m_classSpecifier->symbol);
+ if (settings.preferGetterNameWithoutGetPrefix && hasValidBaseName && !getPrefixIsAlreadyUsed) {
+ m_getterName = m_baseName;
+ } else {
+ const QString baseNameWithCapital = m_baseName.left(1).toUpper() + m_baseName.mid(1);
+ m_getterName = QLatin1String("get") + baseNameWithCapital;
+ }
+
+ // Setter Name
+ const QString baseNameWithCapital = m_baseName.left(1).toUpper() + m_baseName.mid(1);
+ m_setterName = QLatin1String("set") + baseNameWithCapital;
+ }
+
void updateDescriptionAndPriority()
{
switch (m_type) {
@@ -3370,7 +3390,7 @@ public:
auto layout = new QFormLayout(&dlg);
auto funcNameEdit = new Utils::FancyLineEdit;
- funcNameEdit->setValidationFunction([this](Utils::FancyLineEdit *edit, QString *) {
+ funcNameEdit->setValidationFunction([](Utils::FancyLineEdit *edit, QString *) {
return ExtractFunctionOptions::isValidFunctionName(edit->text());
});
layout->addRow(QCoreApplication::translate("QuickFix::ExtractFunction",
@@ -6018,27 +6038,7 @@ void ExtraRefactoringOperations::match(const CppQuickFixInterface &interface,
}
}
-void GenerateGetterSetterOperation::determineGetterSetterNames()
-{
- m_baseName = memberBaseName(m_variableString);
- if (m_baseName.isEmpty())
- m_baseName = QLatin1String("value");
-
- // Getter Name
- const CppCodeStyleSettings settings = CppCodeStyleSettings::currentProjectCodeStyle();
- const bool hasValidBaseName = m_baseName != m_variableString;
- const bool getPrefixIsAlreadyUsed = hasClassMemberWithGetPrefix(m_classSpecifier->symbol);
- if (settings.preferGetterNameWithoutGetPrefix && hasValidBaseName && !getPrefixIsAlreadyUsed) {
- m_getterName = m_baseName;
- } else {
- const QString baseNameWithCapital = m_baseName.left(1).toUpper() + m_baseName.mid(1);
- m_getterName = QLatin1String("get") + baseNameWithCapital;
- }
- // Setter Name
- const QString baseNameWithCapital = m_baseName.left(1).toUpper() + m_baseName.mid(1);
- m_setterName = QLatin1String("set") + baseNameWithCapital;
-}
} // namespace Internal
} // namespace CppEditor
diff --git a/src/plugins/cppeditor/cpptypehierarchy.cpp b/src/plugins/cppeditor/cpptypehierarchy.cpp
index 47ca64f9a26..cac2269de6a 100644
--- a/src/plugins/cppeditor/cpptypehierarchy.cpp
+++ b/src/plugins/cppeditor/cpptypehierarchy.cpp
@@ -27,6 +27,7 @@
#include "cppeditorconstants.h"
#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppelementevaluator.h"
#include "cppeditorplugin.h"
diff --git a/src/plugins/cppeditor/cppuseselections_test.cpp b/src/plugins/cppeditor/cppuseselections_test.cpp
index 943f1d4ec69..8de8048a892 100644
--- a/src/plugins/cppeditor/cppuseselections_test.cpp
+++ b/src/plugins/cppeditor/cppuseselections_test.cpp
@@ -24,6 +24,7 @@
****************************************************************************/
#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditorplugin.h"
#include "cppeditortestcase.h"
diff --git a/src/plugins/cppeditor/cppuseselectionsupdater.cpp b/src/plugins/cppeditor/cppuseselectionsupdater.cpp
index ac071a02b01..da7a7a1d92a 100644
--- a/src/plugins/cppeditor/cppuseselectionsupdater.cpp
+++ b/src/plugins/cppeditor/cppuseselectionsupdater.cpp
@@ -25,11 +25,11 @@
#include "cppuseselectionsupdater.h"
-#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditordocument.h"
#include <cpptools/cpptoolsreuse.h>
-#include <texteditor/convenience.h>
+#include <utils/textutils.h>
#include <QTextBlock>
#include <QTextCursor>
@@ -66,21 +66,21 @@ void CppUseSelectionsUpdater::abortSchedule()
m_timer.stop();
}
-void CppUseSelectionsUpdater::update(CallType callType)
+CppUseSelectionsUpdater::RunnerInfo CppUseSelectionsUpdater::update(CallType callType)
{
auto *cppEditorWidget = qobject_cast<CppEditorWidget *>(m_editorWidget);
- QTC_ASSERT(cppEditorWidget, return);
+ QTC_ASSERT(cppEditorWidget, return RunnerInfo::FailedToStart);
auto *cppEditorDocument = qobject_cast<CppEditorDocument *>(cppEditorWidget->textDocument());
- QTC_ASSERT(cppEditorDocument, return);
+ QTC_ASSERT(cppEditorDocument, return RunnerInfo::FailedToStart);
CppTools::CursorInfoParams params;
params.semanticInfo = cppEditorWidget->semanticInfo();
- params.textCursor = TextEditor::Convenience::wordStartCursor(cppEditorWidget->textCursor());
+ params.textCursor = Utils::Text::wordStartCursor(cppEditorWidget->textCursor());
- if (callType == Asynchronous) {
+ if (callType == CallType::Asynchronous) {
if (isSameIdentifierAsBefore(params.textCursor))
- return;
+ return RunnerInfo::AlreadyUpToDate;
if (m_runnerWatcher)
m_runnerWatcher->cancel();
@@ -93,25 +93,28 @@ void CppUseSelectionsUpdater::update(CallType callType)
m_runnerWordStartPosition = params.textCursor.position();
m_runnerWatcher->setFuture(cppEditorDocument->cursorInfo(params));
+ return RunnerInfo::Started;
} else { // synchronous case
abortSchedule();
const int startRevision = cppEditorDocument->document()->revision();
QFuture<CursorInfo> future = cppEditorDocument->cursorInfo(params);
if (future.isCanceled())
- return;
+ return RunnerInfo::Invalid;
// QFuture::waitForFinished seems to block completely, not even
// allowing to process events from QLocalSocket.
while (!future.isFinished()) {
if (future.isCanceled())
- return;
+ return RunnerInfo::Invalid;
- QTC_ASSERT(startRevision == cppEditorDocument->document()->revision(), return);
+ QTC_ASSERT(startRevision == cppEditorDocument->document()->revision(),
+ return RunnerInfo::Invalid);
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
}
processResults(future.result());
+ return RunnerInfo::Invalid;
}
}
@@ -134,18 +137,25 @@ void CppUseSelectionsUpdater::processResults(const CursorInfo &result)
updateUnusedSelections(result.unusedVariablesRanges);
emit selectionsForVariableUnderCursorUpdated(localVariableSelections);
- emit finished(result.localUses);
+ emit finished(result.localUses, true);
}
void CppUseSelectionsUpdater::onFindUsesFinished()
{
- QTC_ASSERT(m_runnerWatcher, return);
- if (m_runnerWatcher->isCanceled())
+ QTC_ASSERT(m_runnerWatcher,
+ emit finished(CppTools::SemanticInfo::LocalUseMap(), false); return);
+
+ if (m_runnerWatcher->isCanceled()) {
+ emit finished(CppTools::SemanticInfo::LocalUseMap(), false);
return;
- if (m_runnerRevision != m_editorWidget->document()->revision())
+ }
+ if (m_runnerRevision != m_editorWidget->document()->revision()) {
+ emit finished(CppTools::SemanticInfo::LocalUseMap(), false);
return;
+ }
if (m_runnerWordStartPosition
- != TextEditor::Convenience::wordStartCursor(m_editorWidget->textCursor()).position()) {
+ != Utils::Text::wordStartCursor(m_editorWidget->textCursor()).position()) {
+ emit finished(CppTools::SemanticInfo::LocalUseMap(), false);
return;
}
diff --git a/src/plugins/cppeditor/cppuseselectionsupdater.h b/src/plugins/cppeditor/cppuseselectionsupdater.h
index 478a816f980..ec18b222f45 100644
--- a/src/plugins/cppeditor/cppuseselectionsupdater.h
+++ b/src/plugins/cppeditor/cppuseselectionsupdater.h
@@ -49,11 +49,12 @@ public:
void scheduleUpdate();
void abortSchedule();
- enum CallType { Synchronous, Asynchronous };
- void update(CallType callType = Asynchronous);
+ enum class CallType { Synchronous, Asynchronous };
+ enum class RunnerInfo { AlreadyUpToDate, Started, FailedToStart, Invalid }; // For async case.
+ RunnerInfo update(CallType callType = CallType::Asynchronous);
signals:
- void finished(CppTools::SemanticInfo::LocalUseMap localUses);
+ void finished(CppTools::SemanticInfo::LocalUseMap localUses, bool success);
void selectionsForVariableUnderCursorUpdated(const QList<QTextEdit::ExtraSelection> &);
private:
diff --git a/src/plugins/cppeditor/fileandtokenactions_test.cpp b/src/plugins/cppeditor/fileandtokenactions_test.cpp
index 9bf053bb941..463172d45bd 100644
--- a/src/plugins/cppeditor/fileandtokenactions_test.cpp
+++ b/src/plugins/cppeditor/fileandtokenactions_test.cpp
@@ -24,6 +24,7 @@
****************************************************************************/
#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditorplugin.h"
#include "cppeditortestcase.h"
#include "cppquickfix.h"
diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
index b2e1c982949..1f7576c49b1 100644
--- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
+++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
@@ -23,14 +23,17 @@
**
****************************************************************************/
+#include "cppeditor.h"
+#include "cppeditorwidget.h"
#include "cppeditorplugin.h"
#include "cppeditortestcase.h"
#include "cppelementevaluator.h"
-#include "cppfollowsymbolundercursor.h"
-#include "cppvirtualfunctionassistprovider.h"
-#include "cppvirtualfunctionproposalitem.h"
+#include <cpptools/cppfollowsymbolundercursor.h>
+#include <cpptools/cppvirtualfunctionassistprovider.h>
+#include <cpptools/cppvirtualfunctionproposalitem.h>
#include <cpptools/cpptoolstestcase.h>
+#include <cpptools/cppmodelmanager.h>
#include <texteditor/codeassist/genericproposalmodel.h>
#include <texteditor/codeassist/iassistprocessor.h>
@@ -324,19 +327,35 @@ F2TestCase::F2TestCase(CppEditorAction action,
switch (action) {
case FollowSymbolUnderCursorAction: {
CppEditorWidget *widget = initialTestFile->m_editorWidget;
- FollowSymbolUnderCursor *delegate = widget->followSymbolUnderCursorDelegate();
- VirtualFunctionAssistProvider *original = delegate->virtualFunctionAssistProvider();
+ FollowSymbolInterface &delegate = CppModelManager::instance()->followSymbolInterface();
+ auto* builtinFollowSymbol = dynamic_cast<FollowSymbolUnderCursor *>(&delegate);
+ if (!builtinFollowSymbol) {
+ if (filePaths.size() > 1)
+ QSKIP("Clang FollowSymbol does not currently support multiple files (except cpp+header)");
+ const QString curTestName = QLatin1String(QTest::currentTestFunction());
+ if (curTestName == "test_FollowSymbolUnderCursor_QObject_connect"
+ || curTestName == "test_FollowSymbolUnderCursor_virtualFunctionCall"
+ || curTestName == "test_FollowSymbolUnderCursor_QTCREATORBUG7903") {
+ QSKIP((curTestName + " is not supported by Clang FollowSymbol").toLatin1());
+ }
+
+ initialTestFile->m_editorWidget->openLinkUnderCursor();
+ break;
+ }
+
+ QSharedPointer<VirtualFunctionAssistProvider> original
+ = builtinFollowSymbol->virtualFunctionAssistProvider();
// Set test provider, run and get results
- QScopedPointer<VirtualFunctionTestAssistProvider> testProvider(
+ QSharedPointer<VirtualFunctionTestAssistProvider> testProvider(
new VirtualFunctionTestAssistProvider(widget));
- delegate->setVirtualFunctionAssistProvider(testProvider.data());
+ builtinFollowSymbol->setVirtualFunctionAssistProvider(testProvider);
initialTestFile->m_editorWidget->openLinkUnderCursor();
immediateVirtualSymbolResults = testProvider->m_immediateItems;
finalVirtualSymbolResults = testProvider->m_finalItems;
// Restore original test provider
- delegate->setVirtualFunctionAssistProvider(original);
+ builtinFollowSymbol->setVirtualFunctionAssistProvider(original);
break;
}
case SwitchBetweenMethodDeclarationDefinitionAction:
@@ -868,41 +887,6 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_data()
"@Container<int> container;\n"
);
- QTest::newRow("using_QTCREATORBUG7903_globalNamespace") << _(
- "namespace NS {\n"
- "class Foo {};\n"
- "}\n"
- "using NS::$Foo;\n"
- "void fun()\n"
- "{\n"
- " @Foo foo;\n"
- "}\n"
- );
-
- QTest::newRow("using_QTCREATORBUG7903_namespace") << _(
- "namespace NS {\n"
- "class Foo {};\n"
- "}\n"
- "namespace NS1 {\n"
- "void fun()\n"
- "{\n"
- " using NS::$Foo;\n"
- " @Foo foo;\n"
- "}\n"
- "}\n"
- );
-
- QTest::newRow("using_QTCREATORBUG7903_insideFunction") << _(
- "namespace NS {\n"
- "class Foo {};\n"
- "}\n"
- "void fun()\n"
- "{\n"
- " using NS::$Foo;\n"
- " @Foo foo;\n"
- "}\n"
- );
-
QTest::newRow("matchFunctionSignature_Follow_1") << _(
"class Foo {\n"
" void @foo(int);\n"
@@ -941,6 +925,34 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_data()
"};\n"
);
+ QTest::newRow("matchFunctionSignature_Follow_6") << _(
+ "class Foo {\n"
+ " void $foo(int);\n"
+ "};\n"
+ "void Foo::@foo(const volatile int) {}\n"
+ );
+
+ QTest::newRow("matchFunctionSignature_Follow_7") << _(
+ "class Foo {\n"
+ " void $foo(const volatile int);\n"
+ "};\n"
+ "void Foo::@foo(int) {}\n"
+ );
+
+ QTest::newRow("matchFunctionSignature_Follow_8") << _(
+ "class Foo {\n"
+ " void @$foo(int *);\n"
+ "};\n"
+ "void Foo::foo(const int *) {}\n"
+ );
+
+ QTest::newRow("matchFunctionSignature_Follow_9") << _(
+ "class Foo {\n"
+ " void @$foo(int&);\n"
+ "};\n"
+ "void Foo::foo(const int&) {}\n"
+ );
+
QTest::newRow("infiniteLoopLocalTypedef_QTCREATORBUG-11999") << _(
"template<class MyTree>\n"
"class TreeConstIterator\n"
@@ -963,6 +975,8 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_data()
);
QTest::newRow("template_alias") << _(
+ "template<class T>"
+ "class Bar;"
"template<class $T>\n"
"using Foo = Bar<@T>;\n"
);
@@ -974,6 +988,51 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor()
F2TestCase(F2TestCase::FollowSymbolUnderCursorAction, singleDocument(source));
}
+void CppEditorPlugin::test_FollowSymbolUnderCursor_QTCREATORBUG7903_data()
+{
+ QTest::addColumn<QByteArray>("source");
+ QTest::newRow("using_QTCREATORBUG7903_globalNamespace") << _(
+ "namespace NS {\n"
+ "class Foo {};\n"
+ "}\n"
+ "using NS::$Foo;\n"
+ "void fun()\n"
+ "{\n"
+ " @Foo foo;\n"
+ "}\n"
+ );
+
+ QTest::newRow("using_QTCREATORBUG7903_namespace") << _(
+ "namespace NS {\n"
+ "class Foo {};\n"
+ "}\n"
+ "namespace NS1 {\n"
+ "void fun()\n"
+ "{\n"
+ " using NS::$Foo;\n"
+ " @Foo foo;\n"
+ "}\n"
+ "}\n"
+ );
+
+ QTest::newRow("using_QTCREATORBUG7903_insideFunction") << _(
+ "namespace NS {\n"
+ "class Foo {};\n"
+ "}\n"
+ "void fun()\n"
+ "{\n"
+ " using NS::$Foo;\n"
+ " @Foo foo;\n"
+ "}\n"
+ );
+}
+
+void CppEditorPlugin::test_FollowSymbolUnderCursor_QTCREATORBUG7903()
+{
+ QFETCH(QByteArray, source);
+ F2TestCase(F2TestCase::FollowSymbolUnderCursorAction, singleDocument(source));
+}
+
void CppEditorPlugin::test_FollowSymbolUnderCursor_followCall_data()
{
QTest::addColumn<QByteArray>("variableDeclaration"); // without semicolon, can be ""
diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h
index 3c9d864aeb9..1ac31a6ebc8 100644
--- a/src/plugins/cpptools/baseeditordocumentprocessor.h
+++ b/src/plugins/cpptools/baseeditordocumentprocessor.h
@@ -27,6 +27,7 @@
#include "baseeditordocumentparser.h"
#include "cppcursorinfo.h"
+#include "cppsymbolinfo.h"
#include "cppsemanticinfo.h"
#include "cpptools_global.h"
@@ -75,6 +76,7 @@ public:
virtual void setParserConfig(const BaseEditorDocumentParser::Configuration config);
virtual QFuture<CursorInfo> cursorInfo(const CursorInfoParams &params) = 0;
+ virtual QFuture<SymbolInfo> requestFollowSymbol(int line, int column) = 0;
public:
using HeaderErrorDiagnosticWidgetCreator = std::function<QWidget*()>;
diff --git a/src/plugins/cpptools/builtincursorinfo.cpp b/src/plugins/cpptools/builtincursorinfo.cpp
index 8902fa05ca9..17f40c7d26d 100644
--- a/src/plugins/cpptools/builtincursorinfo.cpp
+++ b/src/plugins/cpptools/builtincursorinfo.cpp
@@ -32,12 +32,11 @@
#include "cppsemanticinfo.h"
#include "cpptoolsreuse.h"
-#include <texteditor/convenience.h>
-
#include <cplusplus/CppDocument.h>
#include <cplusplus/Macro.h>
#include <cplusplus/TranslationUnit.h>
+#include <utils/textutils.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
@@ -346,8 +345,7 @@ QFuture<CursorInfo> BuiltinCursorInfo::run(const CursorInfoParams &cursorInfoPar
const QTextCursor &textCursor = cursorInfoParams.textCursor;
int line, column;
- TextEditor::Convenience::convertPosition(textCursor.document(), textCursor.position(),
- &line, &column);
+ Utils::Text::convertPosition(textCursor.document(), textCursor.position(), &line, &column);
CanonicalSymbol canonicalSymbol(document, snapshot);
QString expression;
Scope *scope = canonicalSymbol.getScopeAndExpression(textCursor, &expression);
diff --git a/src/plugins/cpptools/builtineditordocumentparser.cpp b/src/plugins/cpptools/builtineditordocumentparser.cpp
index ac3cf3ee2a3..3fb407cb2da 100644
--- a/src/plugins/cpptools/builtineditordocumentparser.cpp
+++ b/src/plugins/cpptools/builtineditordocumentparser.cpp
@@ -26,6 +26,7 @@
#include "builtineditordocumentparser.h"
#include "cppsourceprocessor.h"
+#include <projectexplorer/projectmacro.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/qtcassert.h>
@@ -91,9 +92,9 @@ void BuiltinEditorDocumentParser::updateImpl(const QFutureInterface<void> &futur
}
if (const ProjectPart::Ptr part = baseState.projectPartInfo.projectPart) {
- configFile += part->toolchainDefines;
+ configFile += ProjectExplorer::Macro::toByteArray(part->toolChainMacros);
configFile += overwrittenToolchainDefines(*part.data());
- configFile += part->projectDefines;
+ configFile += ProjectExplorer::Macro::toByteArray(part->projectMacros);
if (!part->projectConfigFile.isEmpty())
configFile += ProjectPart::readProjectConfigFile(part);
headerPaths = part->headerPaths;
diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.cpp b/src/plugins/cpptools/builtineditordocumentprocessor.cpp
index 95f4932e085..bfdabe53629 100644
--- a/src/plugins/cpptools/builtineditordocumentprocessor.cpp
+++ b/src/plugins/cpptools/builtineditordocumentprocessor.cpp
@@ -33,7 +33,6 @@
#include "cpptoolsreuse.h"
#include "cppworkingcopy.h"
-#include <texteditor/convenience.h>
#include <texteditor/fontsettings.h>
#include <texteditor/refactoroverlay.h>
#include <texteditor/texteditorsettings.h>
@@ -41,6 +40,7 @@
#include <cplusplus/CppDocument.h>
#include <cplusplus/SimpleLexer.h>
+#include <utils/textutils.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
@@ -105,7 +105,7 @@ CppTools::CheckSymbols *createHighlighter(const CPlusPlus::Document::Ptr &doc,
typedef TextEditor::HighlightingResult Result;
QList<Result> macroUses;
- using TextEditor::Convenience::convertPosition;
+ using Utils::Text::convertPosition;
// Get macro definitions
foreach (const CPlusPlus::Macro& macro, doc->definedMacros()) {
diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.h b/src/plugins/cpptools/builtineditordocumentprocessor.h
index 32a50d6e23f..800bff085a6 100644
--- a/src/plugins/cpptools/builtineditordocumentprocessor.h
+++ b/src/plugins/cpptools/builtineditordocumentprocessor.h
@@ -52,6 +52,8 @@ public:
bool isParserRunning() const override;
QFuture<CursorInfo> cursorInfo(const CursorInfoParams &params) override;
+ QFuture<SymbolInfo> requestFollowSymbol(int, int) override
+ { return QFuture<SymbolInfo>(); }
private:
void onParserFinished(CPlusPlus::Document::Ptr document, CPlusPlus::Snapshot snapshot);
diff --git a/src/plugins/cpptools/clangcompileroptionsbuilder.cpp b/src/plugins/cpptools/clangcompileroptionsbuilder.cpp
index 160bf6b4c6c..0b2209cc628 100644
--- a/src/plugins/cpptools/clangcompileroptionsbuilder.cpp
+++ b/src/plugins/cpptools/clangcompileroptionsbuilder.cpp
@@ -26,7 +26,6 @@
#include "clangcompileroptionsbuilder.h"
#include <coreplugin/icore.h>
-
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/qtcassert.h>
@@ -38,46 +37,46 @@ namespace CppTools {
static QString creatorResourcePath()
{
#ifndef UNIT_TESTS
- return Core::ICore::instance()->libexecPath();
+ return Core::ICore::instance()->resourcePath();
#else
return QString();
#endif
}
-QStringList ClangCompilerOptionsBuilder::build(const CppTools::ProjectPart *projectPart,
- CppTools::ProjectFile::Kind fileKind,
- PchUsage pchUsage,
- const QString &clangVersion,
- const QString &clangResourceDirectory)
+static QString creatorLibexecPath()
{
- if (projectPart) {
- ClangCompilerOptionsBuilder builder(*projectPart, clangVersion, clangResourceDirectory);
-
- builder.addWordWidth();
- builder.addTargetTriple();
- builder.addLanguageOption(fileKind);
- builder.addOptionsForLanguage(/*checkForBorlandExtensions*/ true);
- builder.enableExceptions();
+#ifndef UNIT_TESTS
+ return Core::ICore::instance()->libexecPath();
+#else
+ return QString();
+#endif
+}
- builder.addDefineToAvoidIncludingGccOrMinGwIntrinsics();
- builder.addDefineFloat128ForMingw();
- builder.addToolchainAndProjectDefines();
- builder.undefineCppLanguageFeatureMacrosForMsvc2015();
+QStringList ClangCompilerOptionsBuilder::build(CppTools::ProjectFile::Kind fileKind,
+ PchUsage pchUsage)
+{
+ addWordWidth();
+ addTargetTriple();
+ addLanguageOption(fileKind);
+ addOptionsForLanguage(/*checkForBorlandExtensions*/ true);
+ enableExceptions();
- builder.addPredefinedMacrosAndHeaderPathsOptions();
- builder.addWrappedQtHeadersIncludePath();
- builder.addPrecompiledHeaderOptions(pchUsage);
- builder.addHeaderPathOptions();
- builder.addProjectConfigFileInclude();
+ addDefineFloat128ForMingw();
+ addToolchainAndProjectMacros();
+ undefineClangVersionMacrosForMsvc();
+ undefineCppLanguageFeatureMacrosForMsvc2015();
- builder.addMsvcCompatibilityVersion();
+ addPredefinedHeaderPathsOptions();
+ addWrappedQtHeadersIncludePath();
+ addPrecompiledHeaderOptions(pchUsage);
+ addHeaderPathOptions();
+ addProjectConfigFileInclude();
- builder.addExtraOptions();
+ addMsvcCompatibilityVersion();
- return builder.options();
- }
+ addExtraOptions();
- return QStringList();
+ return options();
}
ClangCompilerOptionsBuilder::ClangCompilerOptionsBuilder(const CppTools::ProjectPart &projectPart,
@@ -91,47 +90,35 @@ ClangCompilerOptionsBuilder::ClangCompilerOptionsBuilder(const CppTools::Project
bool ClangCompilerOptionsBuilder::excludeHeaderPath(const QString &path) const
{
- if (m_projectPart.toolchainType == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID) {
- if (path.contains("lib/gcc/i686-apple-darwin"))
- return true;
+ if (m_projectPart.toolchainType == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID
+ && path.contains("lib/gcc/i686-apple-darwin")) {
+ return true;
}
return CompilerOptionsBuilder::excludeHeaderPath(path);
}
-void ClangCompilerOptionsBuilder::addPredefinedMacrosAndHeaderPathsOptions()
+void ClangCompilerOptionsBuilder::addPredefinedHeaderPathsOptions()
{
- if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
- addPredefinedMacrosAndHeaderPathsOptionsForMsvc();
- else
- addPredefinedMacrosAndHeaderPathsOptionsForNonMsvc();
-}
-
-void ClangCompilerOptionsBuilder::addPredefinedMacrosAndHeaderPathsOptionsForMsvc()
-{
- add("-nostdinc");
add("-undef");
-}
+ add("-nostdinc");
+ add("-nostdlibinc");
-void ClangCompilerOptionsBuilder::addPredefinedMacrosAndHeaderPathsOptionsForNonMsvc()
-{
- static const QString resourceDir = clangIncludeDirectory();
- if (QTC_GUARD(!resourceDir.isEmpty())) {
- add("-nostdlibinc");
- add("-I" + QDir::toNativeSeparators(resourceDir));
- add("-undef");
- }
+ if (m_projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
+ add(includeDirOption() + clangIncludeDirectory());
}
void ClangCompilerOptionsBuilder::addWrappedQtHeadersIncludePath()
{
- static const QString wrappedQtHeadersPath = creatorResourcePath()
- + "/cplusplus/wrappedQtHeaders";
+ static const QString resourcePath = creatorResourcePath();
+ static QString wrappedQtHeadersPath = resourcePath + "/cplusplus/wrappedQtHeaders";
+ QDir dir(wrappedQtHeadersPath);
+ QTC_ASSERT(QDir(wrappedQtHeadersPath).exists(), return;);
if (m_projectPart.qtVersion != CppTools::ProjectPart::NoQt) {
const QString wrappedQtCoreHeaderPath = wrappedQtHeadersPath + "/QtCore";
- add("-I" + QDir::toNativeSeparators(wrappedQtHeadersPath));
- add("-I" + QDir::toNativeSeparators(wrappedQtCoreHeaderPath));
+ add(includeDirOption() + QDir::toNativeSeparators(wrappedQtHeadersPath));
+ add(includeDirOption() + QDir::toNativeSeparators(wrappedQtCoreHeaderPath));
}
}
@@ -154,12 +141,26 @@ void ClangCompilerOptionsBuilder::addExtraOptions()
QString ClangCompilerOptionsBuilder::clangIncludeDirectory() const
{
- QDir dir(creatorResourcePath() + "/clang/lib/clang/" + m_clangVersion + "/include");
-
+ QDir dir(creatorLibexecPath() + "/clang/lib/clang/" + m_clangVersion + "/include");
if (!dir.exists() || !QFileInfo(dir, "stdint.h").exists())
dir = QDir(m_clangResourceDirectory);
+ return QDir::toNativeSeparators(dir.canonicalPath());
+}
- return dir.canonicalPath();
+void ClangCompilerOptionsBuilder::undefineClangVersionMacrosForMsvc()
+{
+ if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
+ static QStringList macroNames {
+ "__clang__",
+ "__clang_major__",
+ "__clang_minor__",
+ "__clang_patchlevel__",
+ "__clang_version__"
+ };
+
+ foreach (const QString &macroName, macroNames)
+ add(undefineOption() + macroName);
+ }
}
} // namespace CppTools
diff --git a/src/plugins/cpptools/clangcompileroptionsbuilder.h b/src/plugins/cpptools/clangcompileroptionsbuilder.h
index 4dadb6bed96..fbe2a5baad2 100644
--- a/src/plugins/cpptools/clangcompileroptionsbuilder.h
+++ b/src/plugins/cpptools/clangcompileroptionsbuilder.h
@@ -34,33 +34,24 @@ namespace CppTools {
class CPPTOOLS_EXPORT ClangCompilerOptionsBuilder : public CompilerOptionsBuilder
{
public:
- static QStringList build(const ProjectPart *projectPart,
- ProjectFile::Kind fileKind,
- PchUsage pchUsage,
- const QString &clangVersion,
- const QString &clangResourceDirectory);
+ QStringList build(ProjectFile::Kind fileKind,
+ PchUsage pchUsage);
ClangCompilerOptionsBuilder(const ProjectPart &projectPart,
- const QString &clangVersion,
- const QString &clangResourceDirectory);
+ const QString &clangVersion = QString(),
+ const QString &clangResourceDirectory = QString());
- bool excludeHeaderPath(const QString &path) const override;
-
- void addPredefinedMacrosAndHeaderPathsOptions();
-
- void addPredefinedMacrosAndHeaderPathsOptionsForMsvc();
-
- void addPredefinedMacrosAndHeaderPathsOptionsForNonMsvc();
+ virtual void addPredefinedHeaderPathsOptions();
+ virtual void addExtraOptions();
- void addWrappedQtHeadersIncludePath();
+ bool excludeHeaderPath(const QString &path) const override;
+ virtual void addWrappedQtHeadersIncludePath();
void addProjectConfigFileInclude();
- void addExtraOptions();
+ void undefineClangVersionMacrosForMsvc();
private:
QString clangIncludeDirectory() const;
-
-private:
QString m_clangVersion;
QString m_clangResourceDirectory;
};
diff --git a/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp b/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp
index 6b8a04ac337..288b5e3a8d7 100644
--- a/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp
+++ b/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp
@@ -28,6 +28,7 @@
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
+#include <utils/utilsicons.h>
#include <QDebug>
#include <QInputDialog>
@@ -107,15 +108,61 @@ void ClangDiagnosticConfigsWidget::onRemoveButtonClicked()
syncConfigChooserToModel();
}
+static bool isAcceptedWarningOption(const QString &option)
+{
+ return option == "-w"
+ || option == "-pedantic"
+ || option == "-pedantic-errors";
+}
+
+// Reference:
+// https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
+// https://clang.llvm.org/docs/DiagnosticsReference.html
+static bool isValidOption(const QString &option)
+{
+ if (option == "-Werror")
+ return false; // Avoid errors due to unknown or misspelled warnings.
+ return option.startsWith("-W") || isAcceptedWarningOption(option);
+}
+
+static QString validateDiagnosticOptions(const QStringList &options)
+{
+ // This is handy for testing, allow disabling validation.
+ if (qEnvironmentVariableIntValue("QTC_CLANG_NO_DIAGNOSTIC_CHECK"))
+ return QString();
+
+ for (const QString &option : options) {
+ if (!isValidOption(option))
+ return ClangDiagnosticConfigsWidget::tr("Option \"%1\" is invalid.").arg(option);
+ }
+
+ return QString();
+}
+
+static QStringList normalizeDiagnosticInputOptions(const QString &options)
+{
+ return options.simplified().split(QLatin1Char(' '), QString::SkipEmptyParts);
+}
+
void ClangDiagnosticConfigsWidget::onDiagnosticOptionsEdited()
{
- const QString diagnosticOptions
- = m_ui->diagnosticOptionsTextEdit->document()->toPlainText().trimmed();
- const QStringList updatedCommandLine
- = diagnosticOptions.trimmed().split(QLatin1Char(' '), QString::SkipEmptyParts);
+ // Clean up input
+ const QString diagnosticOptions = m_ui->diagnosticOptionsTextEdit->document()->toPlainText();
+ const QStringList normalizedOptions = normalizeDiagnosticInputOptions(diagnosticOptions);
+
+ // Validate
+ const QString errorMessage = validateDiagnosticOptions(normalizedOptions);
+ updateValidityWidgets(errorMessage);
+ if (!errorMessage.isEmpty()) {
+ // Remember the entered options in case the user will switch back.
+ m_notAcceptedOptions.insert(currentConfigId(), diagnosticOptions);
+ return;
+ }
+ m_notAcceptedOptions.remove(currentConfigId());
+ // Commit valid changes
ClangDiagnosticConfig updatedConfig = currentConfig();
- updatedConfig.setCommandLineWarnings(updatedCommandLine);
+ updatedConfig.setCommandLineWarnings(normalizedOptions);
m_diagnosticConfigsModel.appendOrUpdate(updatedConfig);
emit customConfigsChanged(customConfigs());
@@ -167,8 +214,10 @@ void ClangDiagnosticConfigsWidget::syncOtherWidgetsToComboBox()
m_ui->removeButton->setEnabled(!config.isReadOnly());
// Update child widgets
- const QString commandLineWarnings = config.commandLineWarnings().join(QLatin1Char(' '));
- setDiagnosticOptions(commandLineWarnings);
+ const QString options = m_notAcceptedOptions.contains(config.id())
+ ? m_notAcceptedOptions.value(config.id())
+ : config.commandLineWarnings().join(QLatin1Char(' '));
+ setDiagnosticOptions(options);
m_ui->diagnosticOptionsTextEdit->setReadOnly(config.isReadOnly());
}
@@ -186,11 +235,35 @@ void ClangDiagnosticConfigsWidget::setDiagnosticOptions(const QString &options)
{
if (options != m_ui->diagnosticOptionsTextEdit->document()->toPlainText()) {
disconnectDiagnosticOptionsChanged();
+
m_ui->diagnosticOptionsTextEdit->document()->setPlainText(options);
+ const QString errorMessage
+ = validateDiagnosticOptions(normalizeDiagnosticInputOptions(options));
+ updateValidityWidgets(errorMessage);
+
connectDiagnosticOptionsChanged();
}
}
+void ClangDiagnosticConfigsWidget::updateValidityWidgets(const QString &errorMessage)
+{
+ QString validationResult;
+ const Utils::Icon *icon = nullptr;
+ QString styleSheet;
+ if (errorMessage.isEmpty()) {
+ icon = &Utils::Icons::INFO;
+ validationResult = tr("Configuration passes sanity checks.");
+ } else {
+ icon = &Utils::Icons::CRITICAL;
+ validationResult = tr("%1").arg(errorMessage);
+ styleSheet = "color: red;";
+ }
+
+ m_ui->validationResultIcon->setPixmap(icon->pixmap());
+ m_ui->validationResultLabel->setText(validationResult);
+ m_ui->validationResultLabel->setStyleSheet(styleSheet);
+}
+
void ClangDiagnosticConfigsWidget::connectConfigChooserCurrentIndex()
{
connect(m_ui->configChooserComboBox,
diff --git a/src/plugins/cpptools/clangdiagnosticconfigswidget.h b/src/plugins/cpptools/clangdiagnosticconfigswidget.h
index e22de1b97d0..ff11815a229 100644
--- a/src/plugins/cpptools/clangdiagnosticconfigswidget.h
+++ b/src/plugins/cpptools/clangdiagnosticconfigswidget.h
@@ -30,6 +30,7 @@
#include "clangdiagnosticconfig.h"
#include "clangdiagnosticconfigsmodel.h"
+#include <QHash>
#include <QWidget>
namespace CppTools {
@@ -72,6 +73,7 @@ private:
const ClangDiagnosticConfig &currentConfig() const;
void setDiagnosticOptions(const QString &options);
+ void updateValidityWidgets(const QString &errorMessage);
void connectConfigChooserCurrentIndex();
void disconnectConfigChooserCurrentIndex();
@@ -81,6 +83,7 @@ private:
private:
Ui::ClangDiagnosticConfigsWidget *m_ui;
ClangDiagnosticConfigsModel m_diagnosticConfigsModel;
+ QHash<Core::Id, QString> m_notAcceptedOptions;
};
} // CppTools namespace
diff --git a/src/plugins/cpptools/clangdiagnosticconfigswidget.ui b/src/plugins/cpptools/clangdiagnosticconfigswidget.ui
index 25d0c0b598d..251868faca1 100644
--- a/src/plugins/cpptools/clangdiagnosticconfigswidget.ui
+++ b/src/plugins/cpptools/clangdiagnosticconfigswidget.ui
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>597</width>
+ <width>665</width>
<height>300</height>
</rect>
</property>
@@ -14,18 +14,6 @@
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
@@ -62,7 +50,38 @@
</layout>
</item>
<item>
- <widget class="QPlainTextEdit" name="diagnosticOptionsTextEdit"/>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="validationResultIcon">
+ <property name="text">
+ <string>ValidationIcon</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="validationResultLabel">
+ <property name="text">
+ <string>ValidationText</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="CppTools::WrappableLineEdit" name="diagnosticOptionsTextEdit"/>
</item>
<item>
<widget class="QLabel" name="label">
@@ -76,6 +95,13 @@
</item>
</layout>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>CppTools::WrappableLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header location="global">cpptools/wrappablelineedit.h</header>
+ </customwidget>
+ </customwidgets>
<tabstops>
<tabstop>configChooserComboBox</tabstop>
<tabstop>copyButton</tabstop>
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp
index 170279c9b8f..88a85e17cda 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.cpp
+++ b/src/plugins/cpptools/compileroptionsbuilder.cpp
@@ -48,44 +48,9 @@ void CompilerOptionsBuilder::add(const QString &option)
m_options.append(option);
}
-struct Macro {
- static Macro fromDefineDirective(const QByteArray &defineDirective);
- QByteArray toDefineOption(const QByteArray &option) const;
-
- QByteArray name;
- QByteArray value;
-};
-
-Macro Macro::fromDefineDirective(const QByteArray &defineDirective)
+void CompilerOptionsBuilder::addDefine(const ProjectExplorer::Macro &macro)
{
- const QByteArray str = defineDirective.mid(8);
- const int spaceIdx = str.indexOf(' ');
- const bool hasValue = spaceIdx != -1;
-
- Macro macro;
- macro.name = str.left(hasValue ? spaceIdx : str.size());
- if (hasValue)
- macro.value = str.mid(spaceIdx + 1);
-
- return macro;
-}
-
-QByteArray Macro::toDefineOption(const QByteArray &option) const
-{
- QByteArray result;
-
- result.append(option);
- result.append(name);
- result.append('=');
- if (!value.isEmpty())
- result.append(value);
-
- return result;
-}
-
-void CompilerOptionsBuilder::addDefine(const QByteArray &defineDirective)
-{
- m_options.append(defineDirectiveToDefineOption(defineDirective));
+ m_options.append(defineDirectiveToDefineOption(macro));
}
void CompilerOptionsBuilder::addWordWidth()
@@ -160,21 +125,21 @@ void CompilerOptionsBuilder::addPrecompiledHeaderOptions(PchUsage pchUsage)
m_options.append(result);
}
-void CompilerOptionsBuilder::addToolchainAndProjectDefines()
+void CompilerOptionsBuilder::addToolchainAndProjectMacros()
{
- addDefines(m_projectPart.toolchainDefines);
- addDefines(m_projectPart.projectDefines);
+ addMacros(m_projectPart.toolChainMacros);
+ addMacros(m_projectPart.projectMacros);
}
-void CompilerOptionsBuilder::addDefines(const QByteArray &defineDirectives)
+void CompilerOptionsBuilder::addMacros(const ProjectExplorer::Macros &macros)
{
QStringList result;
- foreach (QByteArray def, defineDirectives.split('\n')) {
- if (def.isEmpty() || excludeDefineDirective(def))
+ for (const ProjectExplorer::Macro &macro : macros) {
+ if (excludeDefineDirective(macro))
continue;
- const QString defineOption = defineDirectiveToDefineOption(def);
+ const QString defineOption = defineDirectiveToDefineOption(macro);
if (!result.contains(defineOption))
result.append(defineOption);
}
@@ -293,21 +258,6 @@ void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtension
m_options.append(opts);
}
-void CompilerOptionsBuilder::addDefineToAvoidIncludingGccOrMinGwIntrinsics()
-{
- // In gcc headers, lots of built-ins are referenced that clang does not understand.
- // Therefore, prevent the inclusion of the header that references them. Of course, this
- // will break if code actually requires stuff from there, but that should be the less common
- // case.
-
- const Core::Id type = m_projectPart.toolchainType;
- if (type == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID
- || type == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID) {
- addDefine("#define _X86INTRIN_H_INCLUDED");
- addDefine("#define BOOST_UUID_NO_SIMD");
- }
-}
-
static QByteArray toMsCompatibilityVersionFormat(const QByteArray &mscFullVer)
{
return mscFullVer.left(2)
@@ -315,14 +265,10 @@ static QByteArray toMsCompatibilityVersionFormat(const QByteArray &mscFullVer)
+ mscFullVer.mid(2, 2);
}
-static QByteArray msCompatibilityVersionFromDefines(const QByteArray &defineDirectives)
+static QByteArray msCompatibilityVersionFromDefines(const ProjectExplorer::Macros &macros)
{
- foreach (QByteArray defineDirective, defineDirectives.split('\n')) {
- if (defineDirective.isEmpty())
- continue;
-
- const Macro macro = Macro::fromDefineDirective(defineDirective);
- if (macro.name == "_MSC_FULL_VER")
+ for (const ProjectExplorer::Macro &macro : macros) {
+ if (macro.key == "_MSC_FULL_VER")
return toMsCompatibilityVersionFormat(macro.value);
}
@@ -332,8 +278,8 @@ static QByteArray msCompatibilityVersionFromDefines(const QByteArray &defineDire
void CompilerOptionsBuilder::addMsvcCompatibilityVersion()
{
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
- const QByteArray defines = m_projectPart.toolchainDefines + m_projectPart.projectDefines;
- const QByteArray msvcVersion = msCompatibilityVersionFromDefines(defines);
+ const ProjectExplorer::Macros macros = m_projectPart.toolChainMacros + m_projectPart.projectMacros;
+ const QByteArray msvcVersion = msCompatibilityVersionFromDefines(macros);
if (!msvcVersion.isEmpty()) {
const QString option = QLatin1String("-fms-compatibility-version=")
@@ -398,7 +344,7 @@ void CompilerOptionsBuilder::addDefineFloat128ForMingw()
// CLANG-UPGRADE-CHECK: Workaround still needed?
// https://llvm.org/bugs/show_bug.cgi?id=30685
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID)
- addDefine("#define __float128 short");
+ addDefine({"__float128", "short", ProjectExplorer::MacroType::Define});
}
QString CompilerOptionsBuilder::includeDirOption() const
@@ -406,12 +352,25 @@ QString CompilerOptionsBuilder::includeDirOption() const
return QLatin1String("-I");
}
-QString CompilerOptionsBuilder::defineDirectiveToDefineOption(const QByteArray &defineDirective)
+QByteArray CompilerOptionsBuilder::macroOption(const ProjectExplorer::Macro &macro) const
+{
+ switch (macro.type) {
+ case ProjectExplorer::MacroType::Define: return defineOption().toUtf8();
+ case ProjectExplorer::MacroType::Undefine: return undefineOption().toUtf8();
+ default: return QByteArray();
+ }
+}
+
+QByteArray CompilerOptionsBuilder::toDefineOption(const ProjectExplorer::Macro &macro) const
+{
+ return macro.toKeyValue(macroOption(macro));
+}
+
+QString CompilerOptionsBuilder::defineDirectiveToDefineOption(const ProjectExplorer::Macro &macro) const
{
- const Macro macro = Macro::fromDefineDirective(defineDirective);
- const QByteArray option = macro.toDefineOption(defineOption().toLatin1());
+ const QByteArray option = toDefineOption(macro);
- return QString::fromLatin1(option);
+ return QString::fromUtf8(option);
}
QString CompilerOptionsBuilder::defineOption() const
@@ -435,11 +394,11 @@ static bool isGccOrMinGwToolchain(const Core::Id &toolchainType)
|| toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID;
}
-bool CompilerOptionsBuilder::excludeDefineDirective(const QByteArray &defineDirective) const
+bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro &macro) const
{
// This is a quick fix for QTCREATORBUG-11501.
// TODO: do a proper fix, see QTCREATORBUG-11709.
- if (defineDirective.startsWith("#define __cplusplus"))
+ if (macro.key == "__cplusplus")
return true;
// gcc 4.9 has:
@@ -449,7 +408,7 @@ bool CompilerOptionsBuilder::excludeDefineDirective(const QByteArray &defineDire
// override clang's own (non-macro, it seems) definitions of the symbols on the left-hand
// side.
if (isGccOrMinGwToolchain(m_projectPart.toolchainType)
- && defineDirective.contains("has_include")) {
+ && macro.key.contains("has_include")) {
return true;
}
@@ -459,14 +418,14 @@ bool CompilerOptionsBuilder::excludeDefineDirective(const QByteArray &defineDire
// __builtin_va_arg_pack, which clang does not support (yet), so avoid
// including those.
if (m_projectPart.toolchainType == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID
- && defineDirective.startsWith("#define _FORTIFY_SOURCE")) {
+ && macro.key == "_FORTIFY_SOURCE") {
return true;
}
// MinGW 6 supports some fancy asm output flags and uses them in an
// intrinsics header pulled in by windows.h. Clang does not know them.
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID
- && defineDirective.startsWith("#define __GCC_ASM_FLAG_OUTPUTS__")) {
+ && macro.key == "__GCC_ASM_FLAG_OUTPUTS__") {
return true;
}
diff --git a/src/plugins/cpptools/compileroptionsbuilder.h b/src/plugins/cpptools/compileroptionsbuilder.h
index 75b0c4f530d..8ca985dc28c 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.h
+++ b/src/plugins/cpptools/compileroptionsbuilder.h
@@ -46,7 +46,7 @@ public:
// Add custom options
void add(const QString &option);
- void addDefine(const QByteArray &defineDirective);
+ void addDefine(const ProjectExplorer::Macro &marco);
// Add options based on project part
void addWordWidth();
@@ -54,20 +54,18 @@ public:
virtual void enableExceptions();
void addHeaderPathOptions();
void addPrecompiledHeaderOptions(PchUsage pchUsage);
- void addToolchainAndProjectDefines();
- void addDefines(const QByteArray &defineDirectives);
+ void addToolchainAndProjectMacros();
+ void addMacros(const ProjectExplorer::Macros &macros);
virtual void addLanguageOption(ProjectFile::Kind fileKind);
virtual void addOptionsForLanguage(bool checkForBorlandExtensions = true);
- void addDefineToAvoidIncludingGccOrMinGwIntrinsics();
-
void addMsvcCompatibilityVersion();
void undefineCppLanguageFeatureMacrosForMsvc2015();
void addDefineFloat128ForMingw();
protected:
- virtual bool excludeDefineDirective(const QByteArray &defineDirective) const;
+ virtual bool excludeDefineDirective(const ProjectExplorer::Macro &macro) const;
virtual bool excludeHeaderPath(const QString &headerPath) const;
virtual QString defineOption() const;
@@ -78,7 +76,9 @@ protected:
const ProjectPart m_projectPart;
private:
- QString defineDirectiveToDefineOption(const QByteArray &defineDirective);
+ QByteArray macroOption(const ProjectExplorer::Macro &macro) const;
+ QByteArray toDefineOption(const ProjectExplorer::Macro &macro) const;
+ QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const;
QStringList m_options;
};
diff --git a/src/plugins/cpptools/cppcanonicalsymbol.cpp b/src/plugins/cpptools/cppcanonicalsymbol.cpp
index 0532ae8b2d2..3f1869de63b 100644
--- a/src/plugins/cpptools/cppcanonicalsymbol.cpp
+++ b/src/plugins/cpptools/cppcanonicalsymbol.cpp
@@ -26,10 +26,11 @@
#include "cppcanonicalsymbol.h"
#include <cpptools/cpptoolsreuse.h>
-#include <texteditor/convenience.h>
#include <cplusplus/ExpressionUnderCursor.h>
+#include <utils/textutils.h>
+
#include <QTextCursor>
#include <QTextDocument>
@@ -58,7 +59,7 @@ Scope *CanonicalSymbol::getScopeAndExpression(const QTextCursor &cursor, QString
QTextCursor tc = cursor;
int line, column;
- TextEditor::Convenience::convertPosition(cursor.document(), tc.position(), &line, &column);
+ Utils::Text::convertPosition(cursor.document(), tc.position(), &line, &column);
++column; // 1-based line and 1-based column
int pos = tc.position();
diff --git a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp
index 199f185d639..60f7bb32421 100644
--- a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp
+++ b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp
@@ -31,6 +31,7 @@
#include <app/app_version.h>
#include <coreplugin/icore.h>
#include <cpptools/cppprojectfile.h>
+#include <projectexplorer/projectmacro.h>
#include <projectexplorer/project.h>
#include <utils/algorithm.h>
#include <utils/temporarydirectory.h>
@@ -153,6 +154,18 @@ QString Utils::toString(ProjectPart::QtVersion qtVersion)
return QString();
}
+QString Utils::toString(ProjectPart::BuildTargetType buildTargetType)
+{
+#define CASE_BUILDTARGETTYPE(x) case ProjectPart::x: return QLatin1String(#x)
+ switch (buildTargetType) {
+ CASE_BUILDTARGETTYPE(Unknown);
+ CASE_BUILDTARGETTYPE(Executable);
+ CASE_BUILDTARGETTYPE(Library);
+ }
+#undef CASE_BUILDTARGETTYPE
+ return QString();
+}
+
QString Utils::toString(ProjectFile::Kind kind)
{
return QString::fromLatin1(projectFileKindToText(kind));
@@ -482,6 +495,7 @@ void Dumper::dumpProjectInfos( const QList<ProjectInfo> &projectInfos)
m_out << i3 << "Project Name : " << projectName << "\n";
m_out << i3 << "Project File : " << projectFilePath << "\n";
m_out << i3 << "Selected For Building: " << part->selectedForBuilding << "\n";
+ m_out << i3 << "Build Target Type : " << Utils::toString(part->buildTargetType) << "\n";
m_out << i3 << "Lanugage Version : " << Utils::toString(part->languageVersion)<<"\n";
m_out << i3 << "Lanugage Extensions : " << Utils::toString(part->languageExtensions)
<< "\n";
@@ -495,15 +509,17 @@ void Dumper::dumpProjectInfos( const QList<ProjectInfo> &projectInfos)
}
}
- if (!part->toolchainDefines.isEmpty()) {
+ if (!part->toolChainMacros.isEmpty()) {
m_out << i3 << "Toolchain Defines:{{{4\n";
- const QList<QByteArray> defineLines = part->toolchainDefines.split('\n');
+ const QList<QByteArray> defineLines =
+ ProjectExplorer::Macro::toByteArray(part->toolChainMacros).split('\n');
foreach (const QByteArray &defineLine, defineLines)
m_out << i4 << defineLine << "\n";
}
- if (!part->projectDefines.isEmpty()) {
+ if (!part->projectMacros.isEmpty()) {
m_out << i3 << "Project Defines:{{{4\n";
- const QList<QByteArray> defineLines = part->projectDefines.split('\n');
+ const QList<QByteArray> defineLines =
+ ProjectExplorer::Macro::toByteArray(part->projectMacros).split('\n');
foreach (const QByteArray &defineLine, defineLines)
m_out << i4 << defineLine << "\n";
}
diff --git a/src/plugins/cpptools/cppcodemodelinspectordumper.h b/src/plugins/cpptools/cppcodemodelinspectordumper.h
index d281722790a..a21bb5acbd2 100644
--- a/src/plugins/cpptools/cppcodemodelinspectordumper.h
+++ b/src/plugins/cpptools/cppcodemodelinspectordumper.h
@@ -50,6 +50,7 @@ struct CPPTOOLS_EXPORT Utils
static QString toString(CppTools::ProjectPart::LanguageVersion languageVersion);
static QString toString(CppTools::ProjectPart::LanguageExtensions languageExtension);
static QString toString(CppTools::ProjectPart::QtVersion qtVersion);
+ static QString toString(CppTools::ProjectPart::BuildTargetType buildTargetType);
static QString toString(const QVector<CppTools::ProjectFile> &projectFiles);
static QString toString(CppTools::ProjectFile::Kind kind);
static QString toString(CPlusPlus::Kind kind);
diff --git a/src/plugins/cpptools/cppcodemodelsettingspage.ui b/src/plugins/cpptools/cppcodemodelsettingspage.ui
index 025b91dba98..36ce48f28a4 100644
--- a/src/plugins/cpptools/cppcodemodelsettingspage.ui
+++ b/src/plugins/cpptools/cppcodemodelsettingspage.ui
@@ -30,10 +30,10 @@
<item>
<widget class="QCheckBox" name="ignorePCHCheckBox">
<property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When pre-compiled headers are not ignored, the parsing for code completion and semantic highlighting will process the pre-compiled header before processing any file.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When precompiled headers are not ignored, the parsing for code completion and semantic highlighting will process the precompiled header before processing any file.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
- <string>Ignore pre-compiled headers</string>
+ <string>Ignore precompiled headers</string>
</property>
</widget>
</item>
diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp
index b4944763515..147ae4e4554 100644
--- a/src/plugins/cpptools/cppcompletion_test.cpp
+++ b/src/plugins/cpptools/cppcompletion_test.cpp
@@ -30,12 +30,12 @@
#include "cpptoolstestcase.h"
#include <texteditor/codeassist/iassistproposal.h>
-#include <texteditor/convenience.h>
#include <texteditor/texteditor.h>
#include <texteditor/textdocument.h>
#include <coreplugin/editormanager/editormanager.h>
#include <utils/changeset.h>
+#include <utils/textutils.h>
#include <utils/fileutils.h>
#include <QDebug>
@@ -127,8 +127,7 @@ public:
const int pos = proposal.d->basePosition();
const int length = m_position - pos;
- const QString prefix = Convenience::textAt(QTextCursor(m_textDocument), pos,
- length);
+ const QString prefix = Utils::Text::textAt(QTextCursor(m_textDocument), pos, length);
if (!prefix.isEmpty())
listmodel->filter(prefix);
if (listmodel->isSortable(prefix))
diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp
index 26b139e6478..9b7cdc45127 100644
--- a/src/plugins/cpptools/cppcompletionassist.cpp
+++ b/src/plugins/cpptools/cppcompletionassist.cpp
@@ -38,11 +38,11 @@
#include <texteditor/codeassist/genericproposal.h>
#include <texteditor/codeassist/ifunctionhintproposalmodel.h>
#include <texteditor/codeassist/functionhintproposal.h>
-#include <texteditor/convenience.h>
#include <texteditor/snippets/snippet.h>
#include <texteditor/texteditorsettings.h>
#include <texteditor/completionsettings.h>
+#include <utils/textutils.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
@@ -1091,7 +1091,7 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
}
int line = 0, column = 0;
- Convenience::convertPosition(m_interface->textDocument(), startOfExpression, &line, &column);
+ Utils::Text::convertPosition(m_interface->textDocument(), startOfExpression, &line, &column);
const QString fileName = m_interface->fileName();
return startCompletionInternal(fileName, line, column, expression, endOfExpression);
}
@@ -1124,7 +1124,8 @@ bool InternalCppCompletionAssistProcessor::tryObjCCompletion()
m_model->m_typeOfExpression->init(thisDocument, m_interface->snapshot());
int line = 0, column = 0;
- Convenience::convertPosition(m_interface->textDocument(), m_interface->position(), &line, &column);
+ Utils::Text::convertPosition(m_interface->textDocument(), m_interface->position(), &line,
+ &column);
Scope *scope = thisDocument->scopeAt(line, column);
if (!scope)
return false;
@@ -1902,7 +1903,7 @@ void InternalCppCompletionAssistProcessor::addMacros_helper(const Snapshot &snap
foreach (const Document::Include &i, doc->resolvedIncludes())
addMacros_helper(snapshot, i.resolvedFileName(), processed, definedMacros);
- foreach (const Macro &macro, doc->definedMacros()) {
+ foreach (const CPlusPlus::Macro &macro, doc->definedMacros()) {
const QString macroName = macro.nameToQString();
if (!macro.isHidden())
definedMacros->insert(macroName);
@@ -2014,7 +2015,8 @@ bool InternalCppCompletionAssistProcessor::completeConstructorOrFunction(const Q
// get current line and column
int lineSigned = 0, columnSigned = 0;
- Convenience::convertPosition(m_interface->textDocument(), m_interface->position(), &lineSigned, &columnSigned);
+ Utils::Text::convertPosition(m_interface->textDocument(), m_interface->position(),
+ &lineSigned, &columnSigned);
unsigned line = lineSigned, column = columnSigned;
// find a scope that encloses the current location, starting from the lastVisibileSymbol
diff --git a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
index bc0584a0a56..6f528a3f4f5 100644
--- a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
+++ b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
@@ -30,9 +30,9 @@
#include <coreplugin/idocument.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
+#include <utils/camelhumpmatcher.h>
-#include <QRegExp>
-#include <QStringMatcher>
+#include <QRegularExpression>
using namespace CppTools::Internal;
using namespace CPlusPlus;
@@ -66,12 +66,12 @@ QList<Core::LocatorFilterEntry> CppCurrentDocumentFilter::matchesFor(
{
QList<Core::LocatorFilterEntry> goodEntries;
QList<Core::LocatorFilterEntry> betterEntries;
- const Qt::CaseSensitivity cs = caseSensitivity(entry);
- QStringMatcher matcher(entry, cs);
- QRegExp regexp(entry, cs, QRegExp::Wildcard);
+
+ const QRegularExpression regexp = containsWildcard(entry)
+ ? createWildcardRegExp(entry) : CamelHumpMatcher::createCamelHumpRegExp(entry);
+
if (!regexp.isValid())
return goodEntries;
- bool hasWildcard = containsWildcard(entry);
foreach (IndexItem::Ptr info, itemsOfCurrentDocument()) {
if (future.isCanceled())
@@ -83,29 +83,30 @@ QList<Core::LocatorFilterEntry> CppCurrentDocumentFilter::matchesFor(
else if (info->type() == IndexItem::Function)
matchString += info->symbolType();
- int index = hasWildcard ? regexp.indexIn(matchString) : matcher.indexIn(matchString);
- if (index >= 0) {
- const bool betterMatch = index == 0;
+ QRegularExpressionMatch match = regexp.match(matchString);
+ if (match.hasMatch()) {
+ const bool betterMatch = match.capturedStart() == 0;
QVariant id = qVariantFromValue(info);
QString name = matchString;
QString extraInfo = info->symbolScope();
if (info->type() == IndexItem::Function) {
if (info->unqualifiedNameAndScope(matchString, &name, &extraInfo)) {
name += info->symbolType();
- index = hasWildcard ? regexp.indexIn(name) : matcher.indexIn(name);
+ match = regexp.match(name);
}
}
Core::LocatorFilterEntry filterEntry(this, name, id, info->icon());
filterEntry.extraInfo = extraInfo;
- if (index < 0) {
- index = hasWildcard ? regexp.indexIn(extraInfo) : matcher.indexIn(extraInfo);
+ if (!match.hasMatch()) {
+ match = regexp.match(extraInfo);
filterEntry.highlightInfo.dataType = Core::LocatorFilterEntry::HighlightInfo::ExtraInfo;
}
- if (index >= 0) {
- filterEntry.highlightInfo.startIndex = index;
- filterEntry.highlightInfo.length = hasWildcard ? regexp.matchedLength() : entry.length();
- }
+ const CamelHumpMatcher::HighlightingPositions positions =
+ CamelHumpMatcher::highlightingPositions(match);
+ filterEntry.highlightInfo.starts = positions.starts;
+ filterEntry.highlightInfo.lengths = positions.lengths;
+
if (betterMatch)
betterEntries.append(filterEntry);
else
diff --git a/src/plugins/cpptools/cppeditorwidgetinterface.h b/src/plugins/cpptools/cppeditorwidgetinterface.h
new file mode 100644
index 00000000000..309fa581cdd
--- /dev/null
+++ b/src/plugins/cpptools/cppeditorwidgetinterface.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "cpptools_global.h"
+
+#include <texteditor/codeassist/assistenums.h>
+
+#include <QString>
+
+namespace TextEditor { class IAssistProvider; }
+
+namespace CppTools {
+
+class CPPTOOLS_EXPORT CppEditorWidgetInterface
+{
+public:
+ void renameUsages(const QString &replacement = QString())
+ {
+ return renameUsagesInternal(replacement);
+ }
+
+ virtual void showPreProcessorWidget() = 0;
+ virtual void updateSemanticInfo() = 0;
+ virtual void renameUsagesInternal(const QString &replacement) = 0;
+
+ virtual void invokeTextEditorWidgetAssist(TextEditor::AssistKind assistKind,
+ TextEditor::IAssistProvider *provider) = 0;
+};
+
+} // namespace CppTools
diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp
index c069b3514e7..9e521ac46ff 100644
--- a/src/plugins/cpptools/cppfindreferences.cpp
+++ b/src/plugins/cpptools/cppfindreferences.cpp
@@ -580,7 +580,7 @@ static void searchFinished(SearchResult *search, QFutureWatcher<Usage> *watcher)
auto renameCheckBox = qobject_cast<QCheckBox *>(search->additionalReplaceWidget());
if (renameCheckBox) {
- renameCheckBox->setText(CppFindReferences::tr("Re&name %1 files").arg(filesToRename.size()));
+ renameCheckBox->setText(CppFindReferences::tr("Re&name %n files", nullptr, filesToRename.size()));
renameCheckBox->setToolTip(CppFindReferences::tr("Files:\n%1").arg(filesToRename.join('\n')));
renameCheckBox->setVisible(true);
}
@@ -607,13 +607,13 @@ class FindMacroUsesInFile: public std::unary_function<QString, QList<Usage> >
{
const WorkingCopy workingCopy;
const Snapshot snapshot;
- const Macro &macro;
+ const CPlusPlus::Macro &macro;
QFutureInterface<Usage> *future;
public:
FindMacroUsesInFile(const WorkingCopy &workingCopy,
const Snapshot snapshot,
- const Macro &macro,
+ const CPlusPlus::Macro &macro,
QFutureInterface<Usage> *future)
: workingCopy(workingCopy), snapshot(snapshot), macro(macro), future(future)
{ }
@@ -632,7 +632,7 @@ restart_search:
usages.clear();
foreach (const Document::MacroUse &use, doc->macroUses()) {
- const Macro &useMacro = use.macro();
+ const CPlusPlus::Macro &useMacro = use.macro();
if (useMacro.fileName() == macro.fileName()) { // Check if this is a match, but possibly against an outdated document.
if (source.isEmpty())
@@ -687,7 +687,7 @@ restart_search:
static void findMacroUses_helper(QFutureInterface<Usage> &future,
const WorkingCopy workingCopy,
const Snapshot snapshot,
- const Macro macro)
+ const CPlusPlus::Macro macro)
{
const Utils::FileName sourceFile = Utils::FileName::fromString(macro.fileName());
Utils::FileNameList files{sourceFile};
@@ -704,12 +704,13 @@ static void findMacroUses_helper(QFutureInterface<Usage> &future,
future.setProgressValue(files.size());
}
-void CppFindReferences::findMacroUses(const Macro &macro)
+void CppFindReferences::findMacroUses(const CPlusPlus::Macro &macro)
{
findMacroUses(macro, QString(), false);
}
-void CppFindReferences::findMacroUses(const Macro &macro, const QString &replacement, bool replace)
+void CppFindReferences::findMacroUses(const CPlusPlus::Macro &macro, const QString &replacement,
+ bool replace)
{
SearchResult *search = SearchResultWindow::instance()->startNewSearch(
tr("C++ Macro Usages:"),
@@ -753,7 +754,7 @@ void CppFindReferences::findMacroUses(const Macro &macro, const QString &replace
connect(progress, &FutureProgress::clicked, search, &SearchResult::popup);
}
-void CppFindReferences::renameMacroUses(const Macro &macro, const QString &replacement)
+void CppFindReferences::renameMacroUses(const CPlusPlus::Macro &macro, const QString &replacement)
{
const QString textToReplace = replacement.isEmpty() ? macro.nameToQString() : replacement;
findMacroUses(macro, textToReplace, true);
diff --git a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp
index 6e95cc63fca..ed82a3f9a84 100644
--- a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp
+++ b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp
@@ -24,8 +24,11 @@
****************************************************************************/
#include "cppfollowsymbolundercursor.h"
-#include "cppeditor.h"
#include "cppvirtualfunctionassistprovider.h"
+#include "cppmodelmanager.h"
+#include "functionutils.h"
+#include "cpptoolsreuse.h"
+#include "symbolfinder.h"
#include <cplusplus/ASTPath.h>
#include <cplusplus/BackwardsScanner.h>
@@ -33,24 +36,20 @@
#include <cplusplus/ResolveExpression.h>
#include <cplusplus/SimpleLexer.h>
#include <cplusplus/TypeOfExpression.h>
-#include <cpptools/cppmodelmanager.h>
-#include <cpptools/functionutils.h>
-#include <cpptools/cpptoolsreuse.h>
-#include <cpptools/symbolfinder.h>
#include <texteditor/textdocumentlayout.h>
+#include <utils/textutils.h>
#include <utils/qtcassert.h>
#include <QList>
#include <QSet>
using namespace CPlusPlus;
-using namespace CppTools;
-using namespace CppEditor;
-using namespace CppEditor::Internal;
using namespace TextEditor;
typedef TextEditorWidget::Link Link;
+namespace CppTools {
+
namespace {
class VirtualFunctionHelper {
@@ -297,9 +296,9 @@ inline LookupItem skipForwardDeclarations(const QList<LookupItem> &resolvedSymbo
return result;
}
-CppEditorWidget::Link attemptFuncDeclDef(const QTextCursor &cursor,
- CppEditorWidget *, Snapshot snapshot, const Document::Ptr &document,
- SymbolFinder *symbolFinder)
+Link attemptFuncDeclDef(const QTextCursor &cursor, Snapshot snapshot,
+ const Document::Ptr &document,
+ SymbolFinder *symbolFinder)
{
Link result;
QTC_ASSERT(document, return result);
@@ -459,15 +458,9 @@ QString expressionUnderCursorAsString(const QTextCursor &textCursor,
} // anonymous namespace
-FollowSymbolUnderCursor::FollowSymbolUnderCursor(CppEditorWidget *widget)
- : m_widget(widget)
- , m_virtualFunctionAssistProvider(new VirtualFunctionAssistProvider)
-{
-}
-
-FollowSymbolUnderCursor::~FollowSymbolUnderCursor()
+FollowSymbolUnderCursor::FollowSymbolUnderCursor()
+ : m_virtualFunctionAssistProvider(new VirtualFunctionAssistProvider)
{
- delete m_virtualFunctionAssistProvider;
}
static int skipMatchingParentheses(const Tokens &tokens, int idx, int initialDepth)
@@ -487,17 +480,27 @@ static int skipMatchingParentheses(const Tokens &tokens, int idx, int initialDep
return j;
}
-TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &cursor,
- bool resolveTarget, const Snapshot &theSnapshot, const Document::Ptr &documentFromSemanticInfo,
- SymbolFinder *symbolFinder, bool inNextSplit)
+Link FollowSymbolUnderCursor::findLink(
+ const CppTools::CursorInEditor &data,
+ bool resolveTarget,
+ const Snapshot &theSnapshot,
+ const Document::Ptr &documentFromSemanticInfo,
+ SymbolFinder *symbolFinder,
+ bool inNextSplit)
{
Link link;
+ int lineNumber = 0, positionInBlock = 0;
+ QTextCursor cursor = data.cursor();
+ QTextDocument *document = cursor.document();
+ Utils::Text::convertPosition(document, cursor.position(), &lineNumber, &positionInBlock);
+ const unsigned line = lineNumber;
+ const unsigned column = positionInBlock + 1;
+
Snapshot snapshot = theSnapshot;
// Move to end of identifier
QTextCursor tc = cursor;
- QTextDocument *document = m_widget->document();
QChar ch = document->characterAt(tc.position());
while (CppTools::isValidIdentifierChar(ch)) {
tc.movePosition(QTextCursor::NextCharacter);
@@ -512,18 +515,13 @@ TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &curs
while (document->characterAt(pos).isSpace())
++pos;
if (document->characterAt(pos) == QLatin1Char('(')) {
- link = attemptFuncDeclDef(cursor, m_widget, snapshot, documentFromSemanticInfo,
+ link = attemptFuncDeclDef(cursor, snapshot, documentFromSemanticInfo,
symbolFinder);
if (link.hasValidLinkText())
return link;
}
}
- int lineNumber = 0, positionInBlock = 0;
- m_widget->convertPosition(cursor.position(), &lineNumber, &positionInBlock);
- const unsigned line = lineNumber;
- const unsigned column = positionInBlock + 1;
-
// Try to find a signal or slot inside SIGNAL() or SLOT()
int beginOfToken = 0;
int endOfToken = 0;
@@ -589,7 +587,7 @@ TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &curs
&& unsigned(positionInBlock) <= tk.utf16charsEnd()) {
cursorRegionReached = true;
if (tk.is(T_OPERATOR)) {
- link = attemptFuncDeclDef(cursor, m_widget, theSnapshot,
+ link = attemptFuncDeclDef(cursor, theSnapshot,
documentFromSemanticInfo, symbolFinder);
if (link.hasValidLinkText())
return link;
@@ -597,7 +595,7 @@ TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &curs
QTextCursor c = cursor;
c.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor,
positionInBlock - tokens.at(i - 1).utf16charsBegin());
- link = attemptFuncDeclDef(c, m_widget, theSnapshot, documentFromSemanticInfo,
+ link = attemptFuncDeclDef(c, theSnapshot, documentFromSemanticInfo,
symbolFinder);
if (link.hasValidLinkText())
return link;
@@ -608,8 +606,11 @@ TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &curs
}
}
+ CppEditorWidgetInterface *editorWidget = data.editorWidget();
+ if (!editorWidget)
+ return link;
// Now we prefer the doc from the snapshot with macros expanded.
- Document::Ptr doc = snapshot.document(m_widget->textDocument()->filePath());
+ Document::Ptr doc = snapshot.document(data.filePath());
if (!doc) {
doc = documentFromSemanticInfo;
if (!doc)
@@ -658,7 +659,7 @@ TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &curs
} else if (const Document::MacroUse *use = doc->findMacroUseAt(endOfToken - 1)) {
const QString fileName = use->macro().fileName();
if (fileName == CppModelManager::editorConfigurationFileName()) {
- m_widget->showPreProcessorWidget();
+ editorWidget->showPreProcessorWidget();
} else if (fileName != CppModelManager::configurationFileName()) {
const Macro &macro = use->macro();
link.targetFileName = macro.fileName();
@@ -692,7 +693,7 @@ TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &curs
if (Symbol *d = r.declaration()) {
if (d->isDeclaration() || d->isFunction()) {
const QString fileName = QString::fromUtf8(d->fileName(), d->fileNameLength());
- if (m_widget->textDocument()->filePath().toString() == fileName) {
+ if (data.filePath().toString() == fileName) {
if (unsigned(lineNumber) == d->line()
&& unsigned(positionInBlock) >= d->column()) { // TODO: check the end
result = r; // take the symbol under cursor.
@@ -701,8 +702,8 @@ TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &curs
}
} else if (d->isUsingDeclaration()) {
int tokenBeginLineNumber = 0, tokenBeginColumnNumber = 0;
- m_widget->convertPosition(beginOfToken, &tokenBeginLineNumber,
- &tokenBeginColumnNumber);
+ Utils::Text::convertPosition(document, beginOfToken, &tokenBeginLineNumber,
+ &tokenBeginColumnNumber);
if (unsigned(tokenBeginLineNumber) > d->line()
|| (unsigned(tokenBeginLineNumber) == d->line()
&& unsigned(tokenBeginColumnNumber) > d->column())) {
@@ -731,7 +732,8 @@ TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &curs
params.openInNextSplit = inNextSplit;
if (m_virtualFunctionAssistProvider->configure(params)) {
- m_widget->invokeAssist(FollowSymbol, m_virtualFunctionAssistProvider);
+ editorWidget->invokeTextEditorWidgetAssist(
+ FollowSymbol,m_virtualFunctionAssistProvider.data());
m_virtualFunctionAssistProvider->clearParams();
}
@@ -780,12 +782,15 @@ TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &curs
return Link();
}
-VirtualFunctionAssistProvider *FollowSymbolUnderCursor::virtualFunctionAssistProvider()
+QSharedPointer<VirtualFunctionAssistProvider> FollowSymbolUnderCursor::virtualFunctionAssistProvider()
{
return m_virtualFunctionAssistProvider;
}
-void FollowSymbolUnderCursor::setVirtualFunctionAssistProvider(VirtualFunctionAssistProvider *provider)
+void FollowSymbolUnderCursor::setVirtualFunctionAssistProvider(
+ const QSharedPointer<VirtualFunctionAssistProvider> &provider)
{
m_virtualFunctionAssistProvider = provider;
}
+
+} // namespace CppTools
diff --git a/src/plugins/cppeditor/cppfollowsymbolundercursor.h b/src/plugins/cpptools/cppfollowsymbolundercursor.h
index 3121fe00e83..8e93a7097d6 100644
--- a/src/plugins/cppeditor/cppfollowsymbolundercursor.h
+++ b/src/plugins/cpptools/cppfollowsymbolundercursor.h
@@ -25,41 +25,30 @@
#pragma once
-#include <cplusplus/CppDocument.h>
-#include <texteditor/texteditor.h>
+#include "followsymbolinterface.h"
-QT_BEGIN_NAMESPACE
-class QTextCursor;
-QT_END_NAMESPACE
+namespace CppTools {
-namespace CppTools { class SymbolFinder; }
-
-namespace CppEditor {
-namespace Internal {
-
-class CppEditorWidget;
class VirtualFunctionAssistProvider;
-class FollowSymbolUnderCursor
+class CPPTOOLS_EXPORT FollowSymbolUnderCursor : public CppTools::FollowSymbolInterface
{
public:
- typedef TextEditor::TextEditorWidget::Link Link;
-
- FollowSymbolUnderCursor(CppEditorWidget *widget);
- ~FollowSymbolUnderCursor();
+ FollowSymbolUnderCursor();
- Link findLink(const QTextCursor &cursor, bool resolveTarget,
+ Link findLink(const CppTools::CursorInEditor &data,
+ bool resolveTarget,
const CPlusPlus::Snapshot &snapshot,
const CPlusPlus::Document::Ptr &documentFromSemanticInfo,
- CppTools::SymbolFinder *symbolFinder, bool inNextSplit);
+ CppTools::SymbolFinder *symbolFinder,
+ bool inNextSplit) override;
- VirtualFunctionAssistProvider *virtualFunctionAssistProvider();
- void setVirtualFunctionAssistProvider(VirtualFunctionAssistProvider *provider);
+ QSharedPointer<VirtualFunctionAssistProvider> virtualFunctionAssistProvider();
+ void setVirtualFunctionAssistProvider(
+ const QSharedPointer<VirtualFunctionAssistProvider> &provider);
private:
- CppEditorWidget *m_widget;
- VirtualFunctionAssistProvider *m_virtualFunctionAssistProvider;
+ QSharedPointer<VirtualFunctionAssistProvider> m_virtualFunctionAssistProvider;
};
-} // namespace Internal
-} // namespace CppEditor
+} // namespace CppTools
diff --git a/src/plugins/cpptools/cpplocatorfilter.cpp b/src/plugins/cpptools/cpplocatorfilter.cpp
index f8bf53dd325..86028fbe624 100644
--- a/src/plugins/cpptools/cpplocatorfilter.cpp
+++ b/src/plugins/cpptools/cpplocatorfilter.cpp
@@ -28,9 +28,9 @@
#include <coreplugin/editormanager/editormanager.h>
#include <utils/algorithm.h>
+#include <utils/camelhumpmatcher.h>
-#include <QRegExp>
-#include <QStringMatcher>
+#include <QRegularExpression>
#include <algorithm>
@@ -72,34 +72,37 @@ QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor(
{
QList<Core::LocatorFilterEntry> goodEntries;
QList<Core::LocatorFilterEntry> betterEntries;
- const Qt::CaseSensitivity cs = caseSensitivity(entry);
- QStringMatcher matcher(entry, cs);
- QRegExp regexp(entry, cs, QRegExp::Wildcard);
- if (!regexp.isValid())
- return goodEntries;
- bool hasWildcard = containsWildcard(entry);
+ QList<Core::LocatorFilterEntry> bestEntries;
+ const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
bool hasColonColon = entry.contains(QLatin1String("::"));
const IndexItem::ItemType wanted = matchTypes();
+ const QRegularExpression regexp = containsWildcard(entry)
+ ? createWildcardRegExp(entry) : CamelHumpMatcher::createCamelHumpRegExp(entry);
+
+ if (!regexp.isValid())
+ return goodEntries;
m_data->filterAllFiles([&](const IndexItem::Ptr &info) -> IndexItem::VisitorResult {
if (future.isCanceled())
return IndexItem::Break;
if (info->type() & wanted) {
- const QString matchString = hasColonColon ? info->scopedSymbolName() : info->symbolName();
- int index = hasWildcard ? regexp.indexIn(matchString) : matcher.indexIn(matchString);
- if (index >= 0) {
- const bool betterMatch = index == 0;
+ QString matchString = hasColonColon ? info->scopedSymbolName() : info->symbolName();
+ QRegularExpressionMatch match = regexp.match(matchString);
+ if (match.hasMatch()) {
Core::LocatorFilterEntry filterEntry = filterEntryFromIndexItem(info);
- if (matchString != filterEntry.displayName) {
- index = hasWildcard ? regexp.indexIn(filterEntry.displayName)
- : matcher.indexIn(filterEntry.displayName);
- }
-
- if (index >= 0)
- filterEntry.highlightInfo = {index, (hasWildcard ? regexp.matchedLength() : entry.length())};
-
- if (betterMatch)
+ // Highlight the matched characters, therefore it may be necessary
+ // to update the match if the displayName is different from matchString
+ if (matchString != filterEntry.displayName)
+ match = regexp.match(filterEntry.displayName);
+ const CamelHumpMatcher::HighlightingPositions positions =
+ CamelHumpMatcher::highlightingPositions(match);
+ filterEntry.highlightInfo.starts = positions.starts;
+ filterEntry.highlightInfo.lengths = positions.lengths;
+
+ if (matchString.startsWith(entry, caseSensitivityForPrefix))
+ bestEntries.append(filterEntry);
+ else if (matchString.contains(entry, caseSensitivityForPrefix))
betterEntries.append(filterEntry);
else
goodEntries.append(filterEntry);
@@ -116,9 +119,12 @@ QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor(
Utils::sort(goodEntries, Core::LocatorFilterEntry::compareLexigraphically);
if (betterEntries.size() < 1000)
Utils::sort(betterEntries, Core::LocatorFilterEntry::compareLexigraphically);
+ if (bestEntries.size() < 1000)
+ Utils::sort(bestEntries, Core::LocatorFilterEntry::compareLexigraphically);
- betterEntries += goodEntries;
- return betterEntries;
+ bestEntries += betterEntries;
+ bestEntries += goodEntries;
+ return bestEntries;
}
void CppLocatorFilter::accept(Core::LocatorFilterEntry selection,
diff --git a/src/plugins/cpptools/cpplocatorfilter_test.cpp b/src/plugins/cpptools/cpplocatorfilter_test.cpp
index 27258855d80..501a396eb13 100644
--- a/src/plugins/cpptools/cpplocatorfilter_test.cpp
+++ b/src/plugins/cpptools/cpplocatorfilter_test.cpp
@@ -190,6 +190,16 @@ void CppToolsPlugin::test_cpplocatorfilters_CppLocatorFilter_data()
<< ResultData(_("myFunction(bool, int)"), _("<anonymous namespace> (file1.cpp)"))
);
+ QTest::newRow("CppFunctionsFilter-Sorting")
+ << testFile
+ << cppFunctionsFilter
+ << _("pos")
+ << (QList<ResultData>()
+ << ResultData(_("positiveNumber()"), testFileShort)
+ << ResultData(_("getPosition()"), testFileShort)
+ << ResultData(_("pointOfService()"), testFileShort)
+ );
+
QTest::newRow("CppFunctionsFilter-WithNamespacePrefix")
<< testFile
<< cppFunctionsFilter
@@ -280,6 +290,9 @@ void CppToolsPlugin::test_cpplocatorfilters_CppCurrentDocumentFilter()
QList<ResultData> expectedResults = QList<ResultData>()
<< ResultData(_("int myVariable"), _(""))
<< ResultData(_("myFunction(bool, int)"), _(""))
+ << ResultData(_("pointOfService()"), _(""))
+ << ResultData(_("getPosition()"), _(""))
+ << ResultData(_("positiveNumber()"), _(""))
<< ResultData(_("MyEnum"), _(""))
<< ResultData(_("int V1"), _("MyEnum"))
<< ResultData(_("int V2"), _("MyEnum"))
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index d2493e2e457..da453017822 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -33,12 +33,14 @@
#include "cppindexingsupport.h"
#include "cppmodelmanagersupportinternal.h"
#include "cpprefactoringchanges.h"
+#include "cpprefactoringengine.h"
#include "cppsourceprocessor.h"
#include "cpptoolsconstants.h"
#include "cpptoolsplugin.h"
#include "cpptoolsreuse.h"
#include "editordocumenthandle.h"
#include "symbolfinder.h"
+#include "followsymbolinterface.h"
#include <coreplugin/documentmanager.h>
#include <coreplugin/icore.h>
@@ -47,6 +49,7 @@
#include <texteditor/textdocument.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/projectmacro.h>
#include <projectexplorer/session.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/fileutils.h>
@@ -138,7 +141,7 @@ public:
bool m_dirty;
QStringList m_projectFiles;
ProjectPartHeaderPaths m_headerPaths;
- QByteArray m_definedMacros;
+ ProjectExplorer::Macros m_definedMacros;
// Editor integration
mutable QMutex m_cppEditorDocumentsMutex;
@@ -163,7 +166,8 @@ public:
QTimer m_delayedGcTimer;
// Refactoring
- RefactoringEngineInterface *m_refactoringEngine = nullptr;
+ CppRefactoringEngine m_builtInRefactoringEngine;
+ RefactoringEngineInterface *m_refactoringEngine { &m_builtInRefactoringEngine };
};
} // namespace Internal
@@ -265,12 +269,20 @@ QString CppModelManager::editorConfigurationFileName()
void CppModelManager::setRefactoringEngine(RefactoringEngineInterface *refactoringEngine)
{
- instance()->d->m_refactoringEngine = refactoringEngine;
+ if (refactoringEngine)
+ instance()->d->m_refactoringEngine = refactoringEngine;
+ else
+ instance()->d->m_refactoringEngine = &instance()->d->m_builtInRefactoringEngine;
}
-RefactoringEngineInterface *CppModelManager::refactoringEngine()
+RefactoringEngineInterface &CppModelManager::refactoringEngine()
{
- return instance()->d->m_refactoringEngine;
+ return *instance()->d->m_refactoringEngine;
+}
+
+FollowSymbolInterface &CppModelManager::followSymbolInterface() const
+{
+ return d->m_activeModelManagerSupport->followSymbolInterface();
}
QString CppModelManager::configurationFileName()
@@ -446,35 +458,31 @@ ProjectPartHeaderPaths CppModelManager::internalHeaderPaths() const
return headerPaths;
}
-static void addUnique(const QList<QByteArray> &defs, QByteArray *macros, QSet<QByteArray> *alreadyIn)
+static void addUnique(const ProjectExplorer::Macros &newMacros,
+ ProjectExplorer::Macros &macros,
+ QSet<ProjectExplorer::Macro> &alreadyIn)
{
- Q_ASSERT(macros);
- Q_ASSERT(alreadyIn);
-
- foreach (const QByteArray &def, defs) {
- if (def.trimmed().isEmpty())
- continue;
- if (!alreadyIn->contains(def)) {
- macros->append(def);
- macros->append('\n');
- alreadyIn->insert(def);
+ for (const ProjectExplorer::Macro &macro : newMacros) {
+ if (!alreadyIn.contains(macro)) {
+ macros += macro;
+ alreadyIn.insert(macro);
}
}
}
-QByteArray CppModelManager::internalDefinedMacros() const
+ProjectExplorer::Macros CppModelManager::internalDefinedMacros() const
{
- QByteArray macros;
- QSet<QByteArray> alreadyIn;
+ ProjectExplorer::Macros macros;
+ QSet<ProjectExplorer::Macro> alreadyIn;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(d->m_projectToProjectsInfo);
while (it.hasNext()) {
it.next();
const ProjectInfo pinfo = it.value();
- foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) {
- addUnique(part->toolchainDefines.split('\n'), &macros, &alreadyIn);
- addUnique(part->projectDefines.split('\n'), &macros, &alreadyIn);
+ for (const ProjectPart::Ptr &part : pinfo.projectParts()) {
+ addUnique(part->toolChainMacros, macros, alreadyIn);
+ addUnique(part->projectMacros, macros, alreadyIn);
if (!part->projectConfigFile.isEmpty())
- macros += ProjectPart::readProjectConfigFile(part);
+ macros += ProjectExplorer::Macro::toMacros(ProjectPart::readProjectConfigFile(part));
}
}
return macros;
@@ -491,7 +499,8 @@ void CppModelManager::dumpModelManagerConfiguration(const QString &logFileId)
dumper.dumpProjectInfos(projectInfos());
dumper.dumpSnapshot(globalSnapshot, globalSnapshotTitle, /*isGlobalSnapshot=*/ true);
dumper.dumpWorkingCopy(workingCopy());
- dumper.dumpMergedEntities(headerPaths(), definedMacros());
+ dumper.dumpMergedEntities(headerPaths(),
+ ProjectExplorer:: Macro::toByteArray(definedMacros()));
}
QSet<AbstractEditorSupport *> CppModelManager::abstractEditorSupports() const
@@ -569,12 +578,12 @@ void CppModelManager::renameUsages(Symbol *symbol,
d->m_findReferences->renameUsages(symbol, context, replacement);
}
-void CppModelManager::findMacroUsages(const Macro &macro)
+void CppModelManager::findMacroUsages(const CPlusPlus::Macro &macro)
{
d->m_findReferences->findMacroUses(macro);
}
-void CppModelManager::renameMacroUsages(const Macro &macro, const QString &replacement)
+void CppModelManager::renameMacroUsages(const CPlusPlus::Macro &macro, const QString &replacement)
{
d->m_findReferences->renameMacroUses(macro, replacement);
}
@@ -603,7 +612,7 @@ WorkingCopy CppModelManager::buildWorkingCopyList()
// Add the project configuration file
QByteArray conf = codeModelConfiguration();
- conf += definedMacros();
+ conf += ProjectExplorer::Macro::toByteArray(definedMacros());
workingCopy.insert(configurationFileName(), conf);
return workingCopy;
@@ -991,7 +1000,7 @@ ProjectPart::Ptr CppModelManager::fallbackProjectPart()
{
ProjectPart::Ptr part(new ProjectPart);
- part->projectDefines = definedMacros();
+ part->projectMacros = definedMacros();
part->headerPaths = headerPaths();
// Do not activate ObjectiveCExtensions since this will lead to the
@@ -1270,7 +1279,7 @@ void CppModelManager::setHeaderPaths(const ProjectPartHeaderPaths &headerPaths)
d->m_headerPaths = headerPaths;
}
-QByteArray CppModelManager::definedMacros()
+ProjectExplorer::Macros CppModelManager::definedMacros()
{
QMutexLocker locker(&d->m_projectMutex);
ensureUpdated();
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index 97a93fce60b..df04beec3a1 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -54,6 +54,7 @@ class CppEditorDocumentHandle;
class CppIndexingSupport;
class ModelManagerSupportProvider;
class RefactoringEngineInterface;
+class FollowSymbolInterface;
class SymbolFinder;
class WorkingCopy;
@@ -152,6 +153,7 @@ public:
CppCompletionAssistProvider *completionAssistProvider() const;
BaseEditorDocumentProcessor *editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) const;
+ FollowSymbolInterface &followSymbolInterface() const;
void setIndexingSupport(CppIndexingSupport *indexingSupport);
CppIndexingSupport *indexingSupport();
@@ -163,7 +165,7 @@ public:
// Use this *only* for auto tests
void setHeaderPaths(const ProjectPartHeaderPaths &headerPaths);
- QByteArray definedMacros();
+ ProjectExplorer::Macros definedMacros();
void enableGarbageCollector(bool enable);
@@ -178,7 +180,7 @@ public:
static QString editorConfigurationFileName();
static void setRefactoringEngine(RefactoringEngineInterface *refactoringEngine);
- static RefactoringEngineInterface *refactoringEngine();
+ static RefactoringEngineInterface &refactoringEngine();
void renameIncludes(const QString &oldFileName, const QString &newFileName);
@@ -229,7 +231,7 @@ private:
void ensureUpdated();
QStringList internalProjectFiles() const;
ProjectPartHeaderPaths internalHeaderPaths() const;
- QByteArray internalDefinedMacros() const;
+ ProjectExplorer::Macros internalDefinedMacros() const;
void dumpModelManagerConfiguration(const QString &logFileId);
diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp
index 35f9931f219..c50c12402cc 100644
--- a/src/plugins/cpptools/cppmodelmanager_test.cpp
+++ b/src/plugins/cpptools/cppmodelmanager_test.cpp
@@ -187,7 +187,7 @@ void CppToolsPlugin::test_modelmanager_paths_are_clean()
ProjectPart::Ptr part(new ProjectPart);
part->qtVersion = ProjectPart::Qt5;
- part->projectDefines = QByteArray("#define OH_BEHAVE -1\n");
+ part->projectMacros = {ProjectExplorer::Macro("OH_BEHAVE", "-1")};
part->headerPaths = {HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath),
HeaderPath(testDataDir.frameworksDir(false), HeaderPath::FrameworkPath)};
pi.appendProjectPart(part);
@@ -219,7 +219,7 @@ void CppToolsPlugin::test_modelmanager_framework_headers()
ProjectPart::Ptr part(new ProjectPart);
part->qtVersion = ProjectPart::Qt5;
- part->projectDefines = QByteArray("#define OH_BEHAVE -1\n");
+ part->projectMacros = {{"OH_BEHAVE", "-1"}};
part->headerPaths = {HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath),
HeaderPath(testDataDir.frameworksDir(false), HeaderPath::FrameworkPath)};
const QString &source = testDataDir.fileFromSourcesDir(
@@ -268,7 +268,7 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files()
ProjectPart::Ptr part(new ProjectPart);
part->qtVersion = ProjectPart::Qt5;
- part->projectDefines = QByteArray("#define OH_BEHAVE -1\n");
+ part->projectMacros = {{"OH_BEHAVE", "-1"}};
part->headerPaths = {HeaderPath(testDataDir.includeDir(false), HeaderPath::IncludePath)};
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
pi.appendProjectPart(part);
@@ -286,7 +286,7 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files()
QVERIFY(macrosInHeaderBefore.first().name() == "test_modelmanager_refresh_h");
// Introduce a define that will enable another define once the document is reparsed.
- part->projectDefines = QByteArray("#define TEST_DEFINE 1\n");
+ part->projectMacros = {{"TEST_DEFINE", "1"}};
pi = ProjectInfo(project);
pi.appendProjectPart(part);
@@ -334,13 +334,13 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times()
QSet<QString> refreshedFiles;
CPlusPlus::Document::Ptr document;
- QByteArray defines = "#define FIRST_DEFINE";
+ ProjectExplorer::Macros macros = {{"FIRST_DEFINE"}};
for (int i = 0; i < 2; ++i) {
pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
// Simulate project configuration change by having different defines each time.
- defines += "\n#define ANOTHER_DEFINE";
- part->projectDefines = defines;
+ macros += {"ANOTHER_DEFINE"};
+ part->projectMacros = macros;
part->qtVersion = ProjectPart::Qt5;
part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader));
part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader));
@@ -762,7 +762,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_project()
part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource));
part1->files.append(ProjectFile(header, ProjectFile::CXXHeader));
part1->qtVersion = ProjectPart::NoQt;
- part1->projectDefines = QByteArray("#define SUB1\n");
+ part1->projectMacros = {{"SUB1"}};
part1->headerPaths = {HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath)};
ProjectPart::Ptr part2(new ProjectPart);
@@ -770,7 +770,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_project()
part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource));
part2->files.append(ProjectFile(header, ProjectFile::CXXHeader));
part2->qtVersion = ProjectPart::NoQt;
- part2->projectDefines = QByteArray("#define SUB2\n");
+ part2->projectMacros = {{"SUB2"}};
part2->headerPaths = {HeaderPath(testDataDirectory.includeDir(false), HeaderPath::IncludePath)};
ProjectInfo pi = ProjectInfo(project);
diff --git a/src/plugins/cpptools/cppmodelmanagersupport.h b/src/plugins/cpptools/cppmodelmanagersupport.h
index cfef02e1a08..cb74f00efdd 100644
--- a/src/plugins/cpptools/cppmodelmanagersupport.h
+++ b/src/plugins/cpptools/cppmodelmanagersupport.h
@@ -36,6 +36,7 @@ namespace CppTools {
class BaseEditorDocumentProcessor;
class CppCompletionAssistProvider;
+class FollowSymbolInterface;
class CPPTOOLS_EXPORT ModelManagerSupport
{
@@ -48,6 +49,7 @@ public:
virtual CppCompletionAssistProvider *completionAssistProvider() = 0;
virtual BaseEditorDocumentProcessor *editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) = 0;
+ virtual FollowSymbolInterface &followSymbolInterface() = 0;
};
class CPPTOOLS_EXPORT ModelManagerSupportProvider
diff --git a/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp b/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp
index b8754653443..c03e2ed57e9 100644
--- a/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp
+++ b/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp
@@ -25,8 +25,11 @@
#include "cppcompletionassist.h"
#include "cppmodelmanagersupportinternal.h"
+#include "cppfollowsymbolundercursor.h"
#include "builtineditordocumentprocessor.h"
+#include <app/app_version.h>
+
#include <QCoreApplication>
using namespace CppTools;
@@ -40,7 +43,7 @@ QString ModelManagerSupportProviderInternal::id() const
QString ModelManagerSupportProviderInternal::displayName() const
{
return QCoreApplication::translate("ModelManagerSupportInternal::displayName",
- "Qt Creator Built-in");
+ "%1 Built-in").arg(Core::Constants::IDE_DISPLAY_NAME);
}
ModelManagerSupport::Ptr ModelManagerSupportProviderInternal::createModelManagerSupport()
@@ -49,7 +52,8 @@ ModelManagerSupport::Ptr ModelManagerSupportProviderInternal::createModelManager
}
ModelManagerSupportInternal::ModelManagerSupportInternal()
- : m_completionAssistProvider(new InternalCompletionAssistProvider)
+ : m_completionAssistProvider(new InternalCompletionAssistProvider),
+ m_followSymbol(new FollowSymbolUnderCursor)
{
}
@@ -67,3 +71,8 @@ CppCompletionAssistProvider *ModelManagerSupportInternal::completionAssistProvid
{
return m_completionAssistProvider.data();
}
+
+FollowSymbolInterface &ModelManagerSupportInternal::followSymbolInterface()
+{
+ return *m_followSymbol;
+}
diff --git a/src/plugins/cpptools/cppmodelmanagersupportinternal.h b/src/plugins/cpptools/cppmodelmanagersupportinternal.h
index 0a2290f5956..cd35ea5abce 100644
--- a/src/plugins/cpptools/cppmodelmanagersupportinternal.h
+++ b/src/plugins/cpptools/cppmodelmanagersupportinternal.h
@@ -40,12 +40,14 @@ public:
ModelManagerSupportInternal();
virtual ~ModelManagerSupportInternal();
- virtual CppCompletionAssistProvider *completionAssistProvider();
- virtual BaseEditorDocumentProcessor *editorDocumentProcessor(
- TextEditor::TextDocument *baseTextDocument);
+ CppCompletionAssistProvider *completionAssistProvider() final;
+ BaseEditorDocumentProcessor *editorDocumentProcessor(
+ TextEditor::TextDocument *baseTextDocument) final;
+ FollowSymbolInterface &followSymbolInterface() final;
private:
QScopedPointer<CppCompletionAssistProvider> m_completionAssistProvider;
+ QScopedPointer<FollowSymbolInterface> m_followSymbol;
};
class ModelManagerSupportProviderInternal : public ModelManagerSupportProvider
diff --git a/src/plugins/cpptools/cppprojectinfogenerator.cpp b/src/plugins/cpptools/cppprojectinfogenerator.cpp
index bff5d36ec48..4a32d255fc8 100644
--- a/src/plugins/cpptools/cppprojectinfogenerator.cpp
+++ b/src/plugins/cpptools/cppprojectinfogenerator.cpp
@@ -143,7 +143,7 @@ private:
if (!m_tcInfo.predefinedMacrosRunner)
return; // No compiler set in kit.
- m_projectPart.toolchainDefines = m_tcInfo.predefinedMacrosRunner(m_flags.commandLineFlags);
+ m_projectPart.toolChainMacros = m_tcInfo.predefinedMacrosRunner(m_flags.commandLineFlags);
}
private:
@@ -186,8 +186,9 @@ static ProjectPart::Ptr projectPartFromRawProjectPart(const RawProjectPart &rawP
part->projectFileColumn = rawProjectPart.projectFileColumn;
part->callGroupId = rawProjectPart.callGroupId;
part->buildSystemTarget = rawProjectPart.buildSystemTarget;
+ part->buildTargetType = rawProjectPart.buildTargetType;
part->qtVersion = rawProjectPart.qtVersion;
- part->projectDefines = rawProjectPart.projectDefines;
+ part->projectMacros = rawProjectPart.projectMacros;
part->headerPaths = rawProjectPart.headerPaths;
part->precompiledHeaders = rawProjectPart.precompiledHeaders;
part->selectedForBuilding = rawProjectPart.selectedForBuilding;
diff --git a/src/plugins/cpptools/cpprawprojectpart.cpp b/src/plugins/cpptools/cpprawprojectpart.cpp
index 3668f8caec0..fc66420323a 100644
--- a/src/plugins/cpptools/cpprawprojectpart.cpp
+++ b/src/plugins/cpptools/cpprawprojectpart.cpp
@@ -81,9 +81,9 @@ void RawProjectPart::setQtVersion(ProjectPart::QtVersion qtVersion)
this->qtVersion = qtVersion;
}
-void RawProjectPart::setDefines(const QByteArray &defines)
+void RawProjectPart::setMacros(const ProjectExplorer::Macros &macros)
{
- this->projectDefines = defines;
+ this->projectMacros = macros;
}
void RawProjectPart::setHeaderPaths(const ProjectPartHeaderPaths &headerPaths)
@@ -133,4 +133,9 @@ void RawProjectPart::setFlagsForCxx(const RawProjectPartFlags &flags)
flagsForCxx = flags;
}
+void RawProjectPart::setBuildTargetType(ProjectPart::BuildTargetType type)
+{
+ buildTargetType = type;
+}
+
} // namespace CppTools
diff --git a/src/plugins/cpptools/cpprawprojectpart.h b/src/plugins/cpptools/cpprawprojectpart.h
index 18f0591ec26..cc4a1ee8787 100644
--- a/src/plugins/cpptools/cpprawprojectpart.h
+++ b/src/plugins/cpptools/cpprawprojectpart.h
@@ -67,7 +67,7 @@ public:
void setQtVersion(ProjectPart::QtVersion qtVersion);
- void setDefines(const QByteArray &defines);
+ void setMacros(const ProjectExplorer::Macros &macros);
void setHeaderPaths(const ProjectPartHeaderPaths &headerPaths);
void setIncludePaths(const QStringList &includePaths);
@@ -78,6 +78,7 @@ public:
void setFlagsForC(const RawProjectPartFlags &flags);
void setFlagsForCxx(const RawProjectPartFlags &flags);
+ void setBuildTargetType(ProjectPart::BuildTargetType type);
public:
QString displayName;
QString projectFile;
@@ -88,7 +89,7 @@ public:
QString buildSystemTarget;
QStringList precompiledHeaders;
ProjectPartHeaderPaths headerPaths;
- QByteArray projectDefines;
+ ProjectExplorer::Macros projectMacros;
ProjectPart::QtVersion qtVersion = ProjectPart::UnknownQt;
bool selectedForBuilding = true;
@@ -97,6 +98,7 @@ public:
QStringList files;
FileClassifier fileClassifier;
+ ProjectPart::BuildTargetType buildTargetType = ProjectPart::BuildTargetType::Unknown;
};
using RawProjectParts = QVector<RawProjectPart>;
diff --git a/src/plugins/cpptools/cpprefactoringengine.cpp b/src/plugins/cpptools/cpprefactoringengine.cpp
new file mode 100644
index 00000000000..705a8ecc99e
--- /dev/null
+++ b/src/plugins/cpptools/cpprefactoringengine.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "cpprefactoringengine.h"
+#include "texteditor/texteditor.h"
+
+#include "utils/qtcassert.h"
+
+namespace CppTools {
+
+void CppRefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data,
+ CppTools::ProjectPart *,
+ RenameCallback &&renameSymbolsCallback)
+{
+ CppEditorWidgetInterface *editorWidget = data.editorWidget();
+ QTC_ASSERT(editorWidget, renameSymbolsCallback(QString(),
+ ClangBackEnd::SourceLocationsContainer(),
+ 0); return;);
+ editorWidget->updateSemanticInfo();
+ // Call empty callback
+ renameSymbolsCallback(QString(),
+ ClangBackEnd::SourceLocationsContainer(),
+ data.cursor().document()->revision());
+}
+
+void CppRefactoringEngine::startGlobalRenaming(const CppTools::CursorInEditor &data)
+{
+ CppEditorWidgetInterface *editorWidget = data.editorWidget();
+ QTC_ASSERT(editorWidget, return;);
+ editorWidget->renameUsages();
+}
+
+} // namespace CppEditor
diff --git a/src/plugins/cpptools/cpprefactoringengine.h b/src/plugins/cpptools/cpprefactoringengine.h
new file mode 100644
index 00000000000..acbf02e5e65
--- /dev/null
+++ b/src/plugins/cpptools/cpprefactoringengine.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "refactoringengineinterface.h"
+
+namespace CppTools {
+
+class CPPTOOLS_EXPORT CppRefactoringEngine : public RefactoringEngineInterface
+{
+public:
+ void startLocalRenaming(const CppTools::CursorInEditor &data,
+ CppTools::ProjectPart *projectPart,
+ RenameCallback &&renameSymbolsCallback) override;
+ void startGlobalRenaming(const CppTools::CursorInEditor &data) override;
+
+ bool isUsable() const override { return true; }
+};
+
+} // namespace CppEditor
diff --git a/src/plugins/cpptools/cppselectionchanger.cpp b/src/plugins/cpptools/cppselectionchanger.cpp
index cee56aa21f5..5ac29f97cac 100644
--- a/src/plugins/cpptools/cppselectionchanger.cpp
+++ b/src/plugins/cpptools/cppselectionchanger.cpp
@@ -25,7 +25,7 @@
#include "cppselectionchanger.h"
-#include <texteditor/convenience.h>
+#include <utils/textutils.h>
#include <utils/qtcassert.h>
#include <QDebug>
@@ -34,7 +34,7 @@
#include <QTextDocument>
using namespace CPlusPlus;
-using namespace TextEditor::Convenience;
+using namespace Utils::Text;
enum {
debug = false
diff --git a/src/plugins/cpptools/cppsourceprocessor.cpp b/src/plugins/cpptools/cppsourceprocessor.cpp
index fc28a6135e7..507e33c90ba 100644
--- a/src/plugins/cpptools/cppsourceprocessor.cpp
+++ b/src/plugins/cpptools/cppsourceprocessor.cpp
@@ -62,11 +62,12 @@ static Q_LOGGING_CATEGORY(log, "qtc.cpptools.sourceprocessor")
namespace {
-inline QByteArray generateFingerPrint(const QList<Macro> &definedMacros, const QByteArray &code)
+inline QByteArray generateFingerPrint(const QList<CPlusPlus::Macro> &definedMacros,
+ const QByteArray &code)
{
QCryptographicHash hash(QCryptographicHash::Sha1);
hash.addData(code);
- foreach (const Macro &macro, definedMacros) {
+ foreach (const CPlusPlus::Macro &macro, definedMacros) {
if (macro.isHidden()) {
static const QByteArray undef("#undef ");
hash.addData(undef);
@@ -98,10 +99,10 @@ inline Message messageNoFileContents(Document::Ptr &document, const QString &fil
return Message(Message::Warning, document->fileName(), line, /*column =*/ 0, text);
}
-inline const Macro revision(const WorkingCopy &workingCopy,
- const Macro &macro)
+inline const CPlusPlus::Macro revision(const WorkingCopy &workingCopy,
+ const CPlusPlus::Macro &macro)
{
- Macro newMacro(macro);
+ CPlusPlus::Macro newMacro(macro);
newMacro.setFileRevision(workingCopy.get(macro.fileName()).second);
return newMacro;
}
@@ -316,7 +317,7 @@ QString CppSourceProcessor::resolveFile_helper(const QString &fileName,
return QString();
}
-void CppSourceProcessor::macroAdded(const Macro &macro)
+void CppSourceProcessor::macroAdded(const CPlusPlus::Macro &macro)
{
if (!m_currentDoc)
return;
@@ -325,7 +326,7 @@ void CppSourceProcessor::macroAdded(const Macro &macro)
}
void CppSourceProcessor::passedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset,
- unsigned line, const Macro &macro)
+ unsigned line, const CPlusPlus::Macro &macro)
{
if (!m_currentDoc)
return;
@@ -347,7 +348,7 @@ void CppSourceProcessor::failedMacroDefinitionCheck(unsigned bytesOffset, unsign
}
void CppSourceProcessor::notifyMacroReference(unsigned bytesOffset, unsigned utf16charOffset,
- unsigned line, const Macro &macro)
+ unsigned line, const CPlusPlus::Macro &macro)
{
if (!m_currentDoc)
return;
@@ -359,7 +360,7 @@ void CppSourceProcessor::notifyMacroReference(unsigned bytesOffset, unsigned utf
}
void CppSourceProcessor::startExpandingMacro(unsigned bytesOffset, unsigned utf16charOffset,
- unsigned line, const Macro &macro,
+ unsigned line, const CPlusPlus::Macro &macro,
const QVector<MacroArgumentReference> &actuals)
{
if (!m_currentDoc)
@@ -371,7 +372,7 @@ void CppSourceProcessor::startExpandingMacro(unsigned bytesOffset, unsigned utf1
line, actuals);
}
-void CppSourceProcessor::stopExpandingMacro(unsigned, const Macro &)
+void CppSourceProcessor::stopExpandingMacro(unsigned, const CPlusPlus::Macro &)
{
if (!m_currentDoc)
return;
diff --git a/src/plugins/cpptools/cppsymbolinfo.h b/src/plugins/cpptools/cppsymbolinfo.h
new file mode 100644
index 00000000000..dcd00dd3c21
--- /dev/null
+++ b/src/plugins/cpptools/cppsymbolinfo.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "cpptools_global.h"
+
+#include <QString>
+
+namespace CppTools {
+
+class CPPTOOLS_EXPORT SymbolInfo
+{
+public:
+ int startLine = 0;
+ int startColumn = 0;
+ int endLine = 0;
+ int endColumn = 0;
+ QString fileName;
+};
+
+} // namespace CppTools
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index 8381a3fdfaa..c9ca4e4c18d 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -29,11 +29,13 @@ HEADERS += \
cppcompletionassistprovider.h \
cppcursorinfo.h \
cppcurrentdocumentfilter.h \
- cppeditoroutline.h \
cppdoxygen.h \
+ cppeditoroutline.h \
+ cppeditorwidgetinterface.h \
cppfileiterationorder.h \
cppfilesettingspage.h \
cppfindreferences.h \
+ cppfollowsymbolundercursor.h \
cppfunctionsfilter.h \
cppincludesfilter.h \
cppindexingsupport.h \
@@ -49,6 +51,7 @@ HEADERS += \
cppqtstyleindenter.h \
cpprawprojectpart.h \
cpprefactoringchanges.h \
+ cpprefactoringengine.h \
cppselectionchanger.h \
cppsemanticinfo.h \
cppsemanticinfoupdater.h \
@@ -60,9 +63,12 @@ HEADERS += \
cpptoolsplugin.h \
cpptoolsreuse.h \
cpptoolssettings.h \
+ cppvirtualfunctionassistprovider.h \
+ cppvirtualfunctionproposalitem.h \
cppworkingcopy.h \
doxygengenerator.h \
editordocumenthandle.h \
+ followsymbolinterface.h \
functionutils.h \
generatedcodemodelsupport.h \
includeutils.h \
@@ -87,6 +93,9 @@ HEADERS += \
cppprojectfilecategorizer.h \
clangcompileroptionsbuilder.h \
cppprojectpartchooser.h \
+ cppsymbolinfo.h \
+ cursorineditor.h \
+ wrappablelineedit.h \
SOURCES += \
abstracteditorsupport.cpp \
@@ -119,6 +128,7 @@ SOURCES += \
cppfileiterationorder.cpp \
cppfilesettingspage.cpp \
cppfindreferences.cpp \
+ cppfollowsymbolundercursor.cpp \
cppfunctionsfilter.cpp \
cppincludesfilter.cpp \
cppindexingsupport.cpp \
@@ -134,6 +144,7 @@ SOURCES += \
cppqtstyleindenter.cpp \
cpprawprojectpart.cpp \
cpprefactoringchanges.cpp \
+ cpprefactoringengine.cpp \
cppselectionchanger.cpp \
cppsemanticinfoupdater.cpp \
cppsourceprocessor.cpp \
@@ -141,6 +152,8 @@ SOURCES += \
cpptoolsplugin.cpp \
cpptoolsreuse.cpp \
cpptoolssettings.cpp \
+ cppvirtualfunctionassistprovider.cpp \
+ cppvirtualfunctionproposalitem.cpp \
cppworkingcopy.cpp \
doxygengenerator.cpp \
editordocumenthandle.cpp \
@@ -165,6 +178,7 @@ SOURCES += \
cppprojectfilecategorizer.cpp \
clangcompileroptionsbuilder.cpp \
cppprojectpartchooser.cpp \
+ wrappablelineedit.cpp \
FORMS += \
clangdiagnosticconfigswidget.ui \
diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs
index 2fcda3ae101..cad4da41a56 100644
--- a/src/plugins/cpptools/cpptools.qbs
+++ b/src/plugins/cpptools/cpptools.qbs
@@ -90,6 +90,7 @@ Project {
"cppdoxygen.h",
"cppeditoroutline.cpp",
"cppeditoroutline.h",
+ "cppeditorwidgetinterface.h",
"cppfileiterationorder.cpp",
"cppfileiterationorder.h",
"cppfilesettingspage.cpp",
@@ -97,6 +98,8 @@ Project {
"cppfilesettingspage.ui",
"cppfindreferences.cpp",
"cppfindreferences.h",
+ "cppfollowsymbolundercursor.cpp",
+ "cppfollowsymbolundercursor.h",
"cppfunctionsfilter.cpp",
"cppfunctionsfilter.h",
"cppincludesfilter.cpp",
@@ -133,6 +136,8 @@ Project {
"cpprawprojectpart.h",
"cpprefactoringchanges.cpp",
"cpprefactoringchanges.h",
+ "cpprefactoringengine.cpp",
+ "cpprefactoringengine.h",
"cppselectionchanger.cpp",
"cppselectionchanger.h",
"cppsemanticinfo.h",
@@ -157,12 +162,18 @@ Project {
"cpptoolsreuse.h",
"cpptoolssettings.cpp",
"cpptoolssettings.h",
+ "cppvirtualfunctionassistprovider.cpp",
+ "cppvirtualfunctionassistprovider.h",
+ "cppvirtualfunctionproposalitem.cpp",
+ "cppvirtualfunctionproposalitem.h",
"cppworkingcopy.cpp",
"cppworkingcopy.h",
+ "cursorineditor.h",
"doxygengenerator.cpp",
"doxygengenerator.h",
"editordocumenthandle.cpp",
"editordocumenthandle.h",
+ "followsymbolinterface.h",
"functionutils.cpp",
"functionutils.h",
"generatedcodemodelsupport.cpp",
@@ -173,6 +184,8 @@ Project {
"indexitem.h",
"insertionpointlocator.cpp",
"insertionpointlocator.h",
+ "wrappablelineedit.cpp",
+ "wrappablelineedit.h",
"projectinfo.cpp",
"projectinfo.h",
"projectpart.cpp",
diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp
index e8fe2145f2f..d0dfec3a56d 100644
--- a/src/plugins/cpptools/cpptoolsplugin.cpp
+++ b/src/plugins/cpptools/cpptoolsplugin.cpp
@@ -205,10 +205,10 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
Utils::MacroExpander *expander = Utils::globalMacroExpander();
expander->registerVariable("Cpp:LicenseTemplate",
tr("The license template."),
- [this]() { return CppToolsPlugin::licenseTemplate(); });
+ []() { return CppToolsPlugin::licenseTemplate(); });
expander->registerFileVariables("Cpp:LicenseTemplatePath",
tr("The configured path to the license template"),
- [this]() { return CppToolsPlugin::licenseTemplatePath().toString(); });
+ []() { return CppToolsPlugin::licenseTemplatePath().toString(); });
return true;
}
diff --git a/src/plugins/cpptools/cpptoolsreuse.cpp b/src/plugins/cpptools/cpptoolsreuse.cpp
index fcb3c8b878e..bd011c0c05d 100644
--- a/src/plugins/cpptools/cpptoolsreuse.cpp
+++ b/src/plugins/cpptools/cpptoolsreuse.cpp
@@ -32,11 +32,11 @@
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/idocument.h>
#include <coreplugin/messagemanager.h>
-#include <texteditor/convenience.h>
#include <cplusplus/Overview.h>
#include <cplusplus/LookupContext.h>
#include <utils/algorithm.h>
+#include <utils/textutils.h>
#include <utils/qtcassert.h>
#include <QDebug>
@@ -216,7 +216,7 @@ const Macro *findCanonicalMacro(const QTextCursor &cursor, Document::Ptr documen
QTC_ASSERT(document, return 0);
int line, column;
- TextEditor::Convenience::convertPosition(cursor.document(), cursor.position(), &line, &column);
+ Utils::Text::convertPosition(cursor.document(), cursor.position(), &line, &column);
if (const Macro *macro = document->findMacroDefinitionAt(line)) {
QTextCursor macroCursor = cursor;
diff --git a/src/plugins/cpptools/cpptoolsunittestfiles.pri b/src/plugins/cpptools/cpptoolsunittestfiles.pri
index 6960ccbde94..48c70fce6e2 100644
--- a/src/plugins/cpptools/cpptoolsunittestfiles.pri
+++ b/src/plugins/cpptools/cpptoolsunittestfiles.pri
@@ -1,11 +1,7 @@
-# Currently there are no tests for the project explorer plugin, but we include
-# headers from it that needs to have the export/import adapted for Windows.
shared {
DEFINES += CPPTOOLS_LIBRARY
- DEFINES += PROJECTEXPLORER_LIBRARY
} else {
DEFINES += CPPTOOLS_STATIC_LIBRARY
- DEFINES += PROJECTEXPLORER_STATIC_LIBRARY
}
HEADERS += \
diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp b/src/plugins/cpptools/cppvirtualfunctionassistprovider.cpp
index 74444e0e793..5711eb912ca 100644
--- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
+++ b/src/plugins/cpptools/cppvirtualfunctionassistprovider.cpp
@@ -24,21 +24,19 @@
****************************************************************************/
#include "cppvirtualfunctionassistprovider.h"
-
-#include "cppeditorconstants.h"
#include "cppvirtualfunctionproposalitem.h"
+#include "cpptoolsreuse.h"
+#include "functionutils.h"
+#include "symbolfinder.h"
+#include "typehierarchybuilder.h"
+
#include <cplusplus/Icons.h>
#include <cplusplus/Overview.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
-#include <cpptools/cpptoolsreuse.h>
-#include <cpptools/functionutils.h>
-#include <cpptools/symbolfinder.h>
-#include <cpptools/typehierarchybuilder.h>
-
#include <texteditor/codeassist/genericproposalmodel.h>
#include <texteditor/codeassist/genericproposal.h>
#include <texteditor/codeassist/genericproposalwidget.h>
@@ -50,10 +48,10 @@
#include <utils/qtcassert.h>
using namespace CPlusPlus;
-using namespace CppEditor::Internal;
-using namespace CppTools;
using namespace TextEditor;
+namespace CppTools {
+
/// Activate current item with the same shortcut that is configured for Follow Symbol Under Cursor.
/// This is limited to single-key shortcuts without modifiers.
class VirtualFunctionProposalWidget : public GenericProposalWidget
@@ -106,9 +104,9 @@ public:
bool openInSplit)
: GenericProposal(cursorPos, items)
, m_openInSplit(openInSplit)
- {}
-
- bool isFragile() const override { return true; }
+ {
+ setFragile(true);
+ }
IAssistProposalWidget *createWidget() const override
{ return new VirtualFunctionProposalWidget(m_openInSplit); }
@@ -211,3 +209,5 @@ IAssistProcessor *VirtualFunctionAssistProvider::createProcessor() const
{
return new VirtualFunctionAssistProcessor(m_params);
}
+
+} // namespace CppTools
diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h b/src/plugins/cpptools/cppvirtualfunctionassistprovider.h
index 363981b7ca6..08ff2018d49 100644
--- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h
+++ b/src/plugins/cpptools/cppvirtualfunctionassistprovider.h
@@ -25,6 +25,8 @@
#pragma once
+#include "cpptools_global.h"
+
#include <texteditor/codeassist/iassistprovider.h>
#include <cplusplus/CppDocument.h>
@@ -34,10 +36,9 @@
#include <QSharedPointer>
#include <QTextCursor>
-namespace CppEditor {
-namespace Internal {
+namespace CppTools {
-class VirtualFunctionAssistProvider : public TextEditor::IAssistProvider
+class CPPTOOLS_EXPORT VirtualFunctionAssistProvider : public TextEditor::IAssistProvider
{
public:
VirtualFunctionAssistProvider();
@@ -64,5 +65,4 @@ private:
Parameters m_params;
};
-} // namespace Internal
-} // namespace CppEditor
+} // namespace CppTools
diff --git a/src/plugins/cppeditor/cppvirtualfunctionproposalitem.cpp b/src/plugins/cpptools/cppvirtualfunctionproposalitem.cpp
index 44bd8d01cfe..474aecac467 100644
--- a/src/plugins/cppeditor/cppvirtualfunctionproposalitem.cpp
+++ b/src/plugins/cpptools/cppvirtualfunctionproposalitem.cpp
@@ -25,11 +25,11 @@
#include "cppvirtualfunctionproposalitem.h"
-#include "cppeditorconstants.h"
+#include <cppeditor/cppeditorconstants.h>
#include <coreplugin/editormanager/editormanager.h>
-using namespace CppEditor::Internal;
+namespace CppTools {
VirtualFunctionProposalItem::VirtualFunctionProposalItem(
const TextEditor::TextEditorWidget::Link &link, bool openInSplit)
@@ -52,3 +52,5 @@ void VirtualFunctionProposalItem::apply(TextEditor::TextDocumentManipulatorInter
CppEditor::Constants::CPPEDITOR_ID,
flags);
}
+
+} // namespace CppTools
diff --git a/src/plugins/cppeditor/cppvirtualfunctionproposalitem.h b/src/plugins/cpptools/cppvirtualfunctionproposalitem.h
index 5d86d4b3906..19bb7715ea1 100644
--- a/src/plugins/cppeditor/cppvirtualfunctionproposalitem.h
+++ b/src/plugins/cpptools/cppvirtualfunctionproposalitem.h
@@ -25,13 +25,14 @@
#pragma once
+#include "cpptools_global.h"
+
#include <texteditor/texteditor.h>
#include <texteditor/codeassist/assistproposalitem.h>
-namespace CppEditor {
-namespace Internal {
+namespace CppTools {
-class VirtualFunctionProposalItem final : public TextEditor::AssistProposalItem
+class CPPTOOLS_EXPORT VirtualFunctionProposalItem final : public TextEditor::AssistProposalItem
{
public:
VirtualFunctionProposalItem(const TextEditor::TextEditorWidget::Link &link,
@@ -46,5 +47,4 @@ private:
bool m_openInSplit;
};
-} // namespace Internal
} // namespace CppEditor
diff --git a/src/plugins/cpptools/cursorineditor.h b/src/plugins/cpptools/cursorineditor.h
new file mode 100644
index 00000000000..18097e5dbd3
--- /dev/null
+++ b/src/plugins/cpptools/cursorineditor.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "cppeditorwidgetinterface.h"
+
+#include <utils/fileutils.h>
+
+#include <QTextCursor>
+
+namespace CppTools {
+
+class CursorInEditor
+{
+public:
+ CursorInEditor(const QTextCursor &cursor, const Utils::FileName &filePath,
+ CppEditorWidgetInterface *editorWidget = nullptr)
+ : m_cursor(cursor)
+ , m_filePath(filePath)
+ , m_editorWidget(editorWidget)
+ {}
+ CppEditorWidgetInterface *editorWidget() const { return m_editorWidget; }
+ const QTextCursor &cursor() const { return m_cursor; }
+ const Utils::FileName &filePath() const { return m_filePath; }
+private:
+ QTextCursor m_cursor;
+ Utils::FileName m_filePath;
+ CppEditorWidgetInterface *m_editorWidget = nullptr;
+};
+
+} // namespace CppTools
diff --git a/src/plugins/cpptools/doxygengenerator.cpp b/src/plugins/cpptools/doxygengenerator.cpp
index e94ce3468e0..39e2e252757 100644
--- a/src/plugins/cpptools/doxygengenerator.cpp
+++ b/src/plugins/cpptools/doxygengenerator.cpp
@@ -25,11 +25,10 @@
#include "doxygengenerator.h"
-#include <texteditor/convenience.h>
-
#include <cplusplus/CppDocument.h>
#include <cplusplus/SimpleLexer.h>
+#include <utils/textutils.h>
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
@@ -73,10 +72,8 @@ void DoxygenGenerator::setAddLeadingAsterisks(bool add)
static int lineBeforeCursor(const QTextCursor &cursor)
{
int line, column;
- const bool converted = TextEditor::Convenience::convertPosition(cursor.document(),
- cursor.position(),
- &line,
- &column);
+ const bool converted = Utils::Text::convertPosition(cursor.document(), cursor.position(), &line,
+ &column);
QTC_ASSERT(converted, return std::numeric_limits<int>::max());
return line - 1;
diff --git a/src/plugins/cpptools/followsymbolinterface.h b/src/plugins/cpptools/followsymbolinterface.h
new file mode 100644
index 00000000000..1d662ae65a1
--- /dev/null
+++ b/src/plugins/cpptools/followsymbolinterface.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "cpptools_global.h"
+#include "cursorineditor.h"
+
+#include <cplusplus/CppDocument.h>
+
+#include <texteditor/texteditor.h>
+
+namespace CppTools {
+
+class SymbolFinder;
+
+class CPPTOOLS_EXPORT FollowSymbolInterface
+{
+public:
+ using Link = TextEditor::TextEditorWidget::Link;
+
+ virtual ~FollowSymbolInterface() {}
+ virtual Link findLink(const CursorInEditor &data,
+ bool resolveTarget,
+ const CPlusPlus::Snapshot &snapshot,
+ const CPlusPlus::Document::Ptr &documentFromSemanticInfo,
+ SymbolFinder *symbolFinder,
+ bool inNextSplit) = 0;
+};
+
+} // namespace CppTools
diff --git a/src/plugins/cpptools/projectinfo.cpp b/src/plugins/cpptools/projectinfo.cpp
index 1ca95e3e9c0..e0dbee363fc 100644
--- a/src/plugins/cpptools/projectinfo.cpp
+++ b/src/plugins/cpptools/projectinfo.cpp
@@ -160,13 +160,10 @@ void ProjectInfo::finish()
m_sourceFiles.insert(file.path);
// Update defines
- m_defines.append(part->toolchainDefines);
- m_defines.append(part->projectDefines);
- if (!part->projectConfigFile.isEmpty()) {
- m_defines.append('\n');
- m_defines += ProjectPart::readProjectConfigFile(part);
- m_defines.append('\n');
- }
+ m_defines.append(part->toolChainMacros);
+ m_defines.append(part->projectMacros);
+ if (!part->projectConfigFile.isEmpty())
+ m_defines += ProjectExplorer::Macro::toMacros(ProjectPart::readProjectConfigFile(part));
}
}
diff --git a/src/plugins/cpptools/projectinfo.h b/src/plugins/cpptools/projectinfo.h
index 9096322989d..ee016f5b3ea 100644
--- a/src/plugins/cpptools/projectinfo.h
+++ b/src/plugins/cpptools/projectinfo.h
@@ -123,7 +123,7 @@ private:
// The members below are (re)calculated from the project parts with finish()
ProjectPartHeaderPaths m_headerPaths;
QSet<QString> m_sourceFiles;
- QByteArray m_defines;
+ ProjectExplorer::Macros m_defines;
};
} // namespace CppTools
diff --git a/src/plugins/cpptools/projectpart.cpp b/src/plugins/cpptools/projectpart.cpp
index 6a87adf93f7..e77e079c808 100644
--- a/src/plugins/cpptools/projectpart.cpp
+++ b/src/plugins/cpptools/projectpart.cpp
@@ -25,6 +25,8 @@
#include "projectpart.h"
+#include <utils/algorithm.h>
+
#include <QFile>
#include <QDir>
#include <QTextStream>
@@ -43,16 +45,9 @@ void ProjectPart::updateLanguageFeatures()
if (!hasQt) {
languageFeatures.qtKeywordsEnabled = false;
} else {
- const QByteArray noKeywordsMacro = "#define QT_NO_KEYWORDS";
- const int noKeywordsIndex = projectDefines.indexOf(noKeywordsMacro);
- if (noKeywordsIndex == -1) {
- languageFeatures.qtKeywordsEnabled = true;
- } else {
- const char nextChar = projectDefines.at(noKeywordsIndex + noKeywordsMacro.length());
- // Detect "#define QT_NO_KEYWORDS" and "#define QT_NO_KEYWORDS 1", but exclude
- // "#define QT_NO_KEYWORDS_FOO"
- languageFeatures.qtKeywordsEnabled = nextChar != '\n' && nextChar != ' ';
- }
+ languageFeatures.qtKeywordsEnabled = !Utils::contains(
+ projectMacros,
+ [] (const ProjectExplorer::Macro &macro) { return macro.key == "QT_NO_KEYWORDS"; });
}
}
diff --git a/src/plugins/cpptools/projectpart.h b/src/plugins/cpptools/projectpart.h
index c04a18c61f5..51b620f0c35 100644
--- a/src/plugins/cpptools/projectpart.h
+++ b/src/plugins/cpptools/projectpart.h
@@ -31,6 +31,7 @@
#include "projectpartheaderpath.h"
#include <projectexplorer/projectexplorer_global.h>
+#include <projectexplorer/projectmacro.h>
#include <coreplugin/id.h>
@@ -90,6 +91,12 @@ public:
WordWidth64Bit,
};
+ enum BuildTargetType {
+ Unknown,
+ Executable,
+ Library
+ };
+
using Ptr = QSharedPointer<ProjectPart>;
public:
@@ -118,7 +125,7 @@ public:
QStringList precompiledHeaders;
ProjectPartHeaderPaths headerPaths;
- QByteArray projectDefines;
+ ProjectExplorer::Macros projectMacros;
LanguageVersion languageVersion = LatestCxxVersion;
LanguageExtensions languageExtensions = NoExtensions;
@@ -130,9 +137,10 @@ public:
Core::Id toolchainType;
bool isMsvc2015Toolchain = false;
- QByteArray toolchainDefines;
+ ProjectExplorer::Macros toolChainMacros;
ToolChainWordWidth toolChainWordWidth = WordWidth32Bit;
QString toolChainTargetTriple;
+ BuildTargetType buildTargetType = Unknown;
};
} // namespace CppTools
diff --git a/src/plugins/cpptools/refactoringengineinterface.h b/src/plugins/cpptools/refactoringengineinterface.h
index 2076a379d8a..afb6025c036 100644
--- a/src/plugins/cpptools/refactoringengineinterface.h
+++ b/src/plugins/cpptools/refactoringengineinterface.h
@@ -25,18 +25,20 @@
#pragma once
+#include "cpptools_global.h"
+#include "cursorineditor.h"
+
#include <utils/fileutils.h>
-#include <clangbackendipc/sourcelocationscontainer.h>
-#include <clangbackendipc/refactoringclientinterface.h>
+#include <clangsupport/sourcelocationscontainer.h>
+#include <clangsupport/refactoringclientinterface.h>
-QT_BEGIN_NAMESPACE
-class QTextCursor;
-QT_END_NAMESPACE
+namespace TextEditor {
+class TextEditorWidget;
+} // namespace TextEditor
namespace CppTools {
-class CppEditorWidget;
class ProjectPart;
enum class CallType
@@ -45,19 +47,18 @@ enum class CallType
Asynchronous
};
-class RefactoringEngineInterface
+// NOTE: This interface is not supposed to be owned as an interface pointer
+class CPPTOOLS_EXPORT RefactoringEngineInterface
{
public:
using RenameCallback = ClangBackEnd::RefactoringClientInterface::RenameCallback;
- virtual void startLocalRenaming(const QTextCursor &textCursor,
- const Utils::FileName &filePath,
- int revision,
+ virtual void startLocalRenaming(const CursorInEditor &data,
CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) = 0;
+ virtual void startGlobalRenaming(const CursorInEditor &data) = 0;
virtual bool isUsable() const = 0;
-
};
} // namespace CppTools
diff --git a/src/plugins/cpptools/wrappablelineedit.cpp b/src/plugins/cpptools/wrappablelineedit.cpp
new file mode 100644
index 00000000000..786486a23fe
--- /dev/null
+++ b/src/plugins/cpptools/wrappablelineedit.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "wrappablelineedit.h"
+
+#include <QMimeData>
+
+namespace CppTools {
+
+WrappableLineEdit::WrappableLineEdit(QWidget *parent)
+ : QPlainTextEdit(parent)
+{
+ setMaximumBlockCount(1); // Restrict to a single line.
+}
+
+void WrappableLineEdit::keyPressEvent(QKeyEvent *event)
+{
+ switch (event->key()) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ return; // Eat these to avoid new lines.
+ case Qt::Key_Backtab:
+ case Qt::Key_Tab:
+ // Let the parent handle these because they might be used for navigation purposes.
+ event->ignore();
+ return;
+ default:
+ return QPlainTextEdit::keyPressEvent(event);
+ }
+}
+
+void WrappableLineEdit::insertFromMimeData(const QMimeData *source)
+{
+ insertPlainText(source->text().simplified()); // Filter out new lines.
+}
+
+} // namespace CppTools
diff --git a/src/libs/sqlite/tablewriteworker.h b/src/plugins/cpptools/wrappablelineedit.h
index 8ae95c44c36..411a2d49a98 100644
--- a/src/libs/sqlite/tablewriteworker.h
+++ b/src/plugins/cpptools/wrappablelineedit.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,24 +25,20 @@
#pragma once
-#include "createtablecommand.h"
+#include <QPlainTextEdit>
-#include <QObject>
+namespace CppTools {
-namespace Internal {
-
-class TableWriteWorker : public QObject
+class WrappableLineEdit : public QPlainTextEdit
{
Q_OBJECT
-public:
- explicit TableWriteWorker(QObject *parent = 0);
- ~TableWriteWorker();
- void createTable(const CreateTableCommand &command);
-
-signals:
- void tableCreated();
+public:
+ explicit WrappableLineEdit(QWidget *parent = nullptr);
+protected:
+ void keyPressEvent(QKeyEvent *event) override;
+ void insertFromMimeData(const QMimeData *source) override;
};
-} // namespace Internal
+} // namespace CppTools
diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp
index 9360051f2b6..e312cda6398 100644
--- a/src/plugins/cvs/cvsplugin.cpp
+++ b/src/plugins/cvs/cvsplugin.cpp
@@ -198,7 +198,7 @@ bool CvsPlugin::initialize(const QStringList &arguments, QString *errorMessage)
Context context(CVS_CONTEXT);
- initializeVcs(new CvsControl(this), context);
+ initializeVcs<CvsControl>(context, this);
m_cvsPluginInstance = this;
@@ -651,6 +651,9 @@ void CvsPlugin::startCommitAll()
* commit will start. */
void CvsPlugin::startCommit(const QString &workingDir, const QString &file)
{
+ if (!promptBeforeCommit())
+ return;
+
if (raiseSubmitEditor())
return;
if (isCommitEditorOpen()) {
diff --git a/src/plugins/cvs/cvssettings.cpp b/src/plugins/cvs/cvssettings.cpp
index 10fb8c51e71..12a46bba26b 100644
--- a/src/plugins/cvs/cvssettings.cpp
+++ b/src/plugins/cvs/cvssettings.cpp
@@ -44,7 +44,7 @@ CvsSettings::CvsSettings()
{
setSettingsGroup(QLatin1String("CVS"));
declareKey(binaryPathKey, QLatin1String("cvs" QTC_HOST_EXE_SUFFIX));
- declareKey(cvsRootKey, QLatin1String(""));
+ declareKey(cvsRootKey, QString());
declareKey(diffOptionsKey, QLatin1String("-du"));
declareKey(describeByCommitIdKey, true);
declareKey(diffIgnoreWhiteSpaceKey, false);
diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp
index ab80f73c163..df579b8a602 100644
--- a/src/plugins/debugger/breakhandler.cpp
+++ b/src/plugins/debugger/breakhandler.cpp
@@ -2012,7 +2012,7 @@ bool BreakHandler::contextMenuEvent(const ItemViewEvent &ev)
addAction(menu, tr("Synchronize Breakpoints"),
Internal::hasSnapshots(),
- [this] { Internal::synchronizeBreakpoints(); });
+ [] { Internal::synchronizeBreakpoints(); });
menu->addSeparator();
menu->addAction(action(UseToolTipsInBreakpointsView));
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index b8f240e5d88..6d64a7e4409 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -445,7 +445,7 @@ void CdbEngine::consoleStubExited()
void CdbEngine::createFullBacktrace()
{
- runCommand({"~*kp", BuiltinCommand, [this](const DebuggerResponse &response) {
+ runCommand({"~*kp", BuiltinCommand, [](const DebuggerResponse &response) {
Internal::openTextEditor("Backtrace $", response.data.data());
}});
}
@@ -455,9 +455,6 @@ void CdbEngine::setupEngine()
if (debug)
qDebug(">setupEngine");
- if (!prepareCommand())
- return;
-
init();
if (!m_logTime.elapsed())
m_logTime.start();
@@ -843,17 +840,9 @@ void CdbEngine::shutdownEngine()
}
}
-void CdbEngine::abortDebugger()
+void CdbEngine::abortDebuggerProcess()
{
- if (isDying()) {
- // We already tried. Try harder.
- showMessage("ABORTING DEBUGGER. SECOND TIME.");
- m_process.kill();
- } else {
- // Be friendly the first time. This will change targetState().
- showMessage("ABORTING DEBUGGER. FIRST TIME.");
- quitDebugger();
- }
+ m_process.kill();
}
void CdbEngine::processFinished()
@@ -1426,7 +1415,7 @@ void CdbEngine::postDisassemblerCommand(quint64 address, quint64 endAddress,
str << "u " << hex <<hexPrefixOn << address << ' ' << endAddress;
DebuggerCommand cmd;
cmd.function = ba;
- cmd.callback = [this, agent](const DebuggerResponse &response) {
+ cmd.callback = [agent](const DebuggerResponse &response) {
// Parse: "00000000`77606060 cc int 3"
agent->setContents(parseCdbDisassembler(response.data.data()));
};
@@ -2514,7 +2503,7 @@ void CdbEngine::parseOutputLine(QString line)
// output(32): ModLoad: 00007ffb 00007ffb C:\Windows\system32\KERNEL32.DLL
QRegExp moduleRegExp("[0-9a-fA-F]+(`[0-9a-fA-F]+)? [0-9a-fA-F]+(`[0-9a-fA-F]+)? (.*)");
if (moduleRegExp.indexIn(line) > -1)
- showStatusMessage(tr("Module loaded: ") + moduleRegExp.cap(3).trimmed(), 3000);
+ showStatusMessage(tr("Module loaded: %1").arg(moduleRegExp.cap(3).trimmed()), 3000);
} else {
showMessage(line, LogMisc);
}
diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h
index 30bccb4a116..7a80e48dbac 100644
--- a/src/plugins/debugger/cdb/cdbengine.h
+++ b/src/plugins/debugger/cdb/cdbengine.h
@@ -70,7 +70,7 @@ public:
void runEngine() override;
void shutdownInferior() override;
void shutdownEngine() override;
- void abortDebugger() override;
+ void abortDebuggerProcess() override;
void detachDebugger() override;
bool hasCapability(unsigned cap) const override;
void watchPoint(const QPoint &) override;
diff --git a/src/plugins/debugger/cdb/cdboptionspagewidget.ui b/src/plugins/debugger/cdb/cdboptionspagewidget.ui
index 4b80ff1d26c..38f434688c5 100644
--- a/src/plugins/debugger/cdb/cdboptionspagewidget.ui
+++ b/src/plugins/debugger/cdb/cdboptionspagewidget.ui
@@ -44,7 +44,7 @@
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="consoleCheckBox">
<property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Uses CDB's native console instead of Qt Creator's console for console applications. The native console does not prompt on application exit. It is suitable for diagnosing cases in which the application does not start up properly in Qt Creator's console and the subsequent attach fails.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Uses CDB's native console for console applications. This overrides the setting in Environment &gt; System. The native console does not prompt on application exit. It is suitable for diagnosing cases in which the application does not start up properly in the configured console and the subsequent attach fails.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use CDB &amp;console</string>
diff --git a/src/plugins/debugger/commonoptionspage.cpp b/src/plugins/debugger/commonoptionspage.cpp
index 2f510a4184f..7aeb3a7cb5e 100644
--- a/src/plugins/debugger/commonoptionspage.cpp
+++ b/src/plugins/debugger/commonoptionspage.cpp
@@ -32,6 +32,7 @@
#include <coreplugin/icore.h>
#include <coreplugin/variablechooser.h>
+#include <app/app_version.h>
#include <utils/hostosinfo.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
@@ -129,7 +130,9 @@ QWidget *CommonOptionsPage::widget()
checkBoxSwitchModeOnExit->setText(tr("Switch to previous mode on debugger exit"));
auto checkBoxBringToForegroundOnInterrrupt = new QCheckBox(behaviorBox);
- checkBoxBringToForegroundOnInterrrupt->setText(tr("Bring Qt Creator to foreground when application interrupts"));
+ checkBoxBringToForegroundOnInterrrupt->setText(
+ tr("Bring %1 to foreground when application interrupts")
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
auto checkBoxShowQmlObjectTree = new QCheckBox(behaviorBox);
checkBoxShowQmlObjectTree->setToolTip(tr("Shows QML object tree in Locals and Expressions when connected and not stepping."));
@@ -140,8 +143,12 @@ QWidget *CommonOptionsPage::widget()
checkBoxBreakpointsFullPath->setText(tr("Set breakpoints using a full absolute path"));
auto checkBoxRegisterForPostMortem = new QCheckBox(behaviorBox);
- checkBoxRegisterForPostMortem->setToolTip(tr("Registers Qt Creator for debugging crashed applications."));
- checkBoxRegisterForPostMortem->setText(tr("Use Qt Creator for post-mortem debugging"));
+ checkBoxRegisterForPostMortem->setToolTip(
+ tr("Registers %1 for debugging crashed applications.")
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
+ checkBoxRegisterForPostMortem->setText(
+ tr("Use %1 for post-mortem debugging")
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
auto checkBoxWarnOnReleaseBuilds = new QCheckBox(behaviorBox);
checkBoxWarnOnReleaseBuilds->setText(tr("Warn when debugging \"Release\" builds"));
@@ -308,13 +315,13 @@ QWidget *LocalsAndExpressionsOptionsPage::widget()
label->setText(QLatin1String("<html><head/><body>\n<p>")
+ tr("The debugging helpers are used to produce a nice "
"display of objects of certain types like QString or "
- "std::map in the &quot;Locals and Expressions&quot; view. ")
+ "std::map in the &quot;Locals and Expressions&quot; view.")
+ QLatin1String("</p></body></html>"));
auto groupBoxCustomDumperCommands = new QGroupBox(debuggingHelperGroupBox);
groupBoxCustomDumperCommands->setTitle(tr("Debugging Helper Customization"));
groupBoxCustomDumperCommands->setToolTip(tr(
- "<html><head/><body><p>Python commands entered here will be executed after Qt Creator's "
+ "<html><head/><body><p>Python commands entered here will be executed after built-in "
"debugging helpers have been loaded and fully initialized. You can load additional "
"debugging helpers or modify existing ones here.</p></body></html>"));
diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index c8c67b01fe1..f5a34aa0d5f 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -29,7 +29,6 @@ HEADERS += \
debuggerprotocol.h \
debuggerrunconfigurationaspect.h \
debuggerruncontrol.h \
- debuggerstartparameters.h \
debuggerkitconfigwidget.h \
debuggerkitinformation.h \
disassembleragent.h \
diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs
index b27af6cff61..08faeb3d1e6 100644
--- a/src/plugins/debugger/debugger.qbs
+++ b/src/plugins/debugger/debugger.qbs
@@ -20,6 +20,7 @@ Project {
Depends { name: "ProjectExplorer" }
Depends { name: "QtSupport" }
Depends { name: "TextEditor" }
+ Depends { name: "app_version_header" }
pluginTestDepends: [
"QmakeProjectManager"
@@ -58,7 +59,6 @@ Project {
"debuggerrunconfigurationaspect.cpp", "debuggerrunconfigurationaspect.h",
"debuggerruncontrol.cpp", "debuggerruncontrol.h",
"debuggersourcepathmappingwidget.cpp", "debuggersourcepathmappingwidget.h",
- "debuggerstartparameters.h",
"debuggertooltipmanager.cpp", "debuggertooltipmanager.h",
"disassembleragent.cpp", "disassembleragent.h",
"disassemblerlines.cpp", "disassemblerlines.h",
@@ -108,14 +108,9 @@ Project {
name: "gdb"
prefix: "gdb/"
files: [
- "attachgdbadapter.cpp", "attachgdbadapter.h",
- "coregdbadapter.cpp", "coregdbadapter.h",
"gdbengine.cpp", "gdbengine.h",
"gdboptionspage.cpp",
- "gdbplainengine.cpp", "gdbplainengine.h",
- "remotegdbserveradapter.cpp", "remotegdbserveradapter.h",
"startgdbserverdialog.cpp", "startgdbserverdialog.h",
- "termgdbadapter.cpp", "termgdbadapter.h"
]
}
diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h
index 0cac2e26287..1027c773c11 100644
--- a/src/plugins/debugger/debuggerconstants.h
+++ b/src/plugins/debugger/debuggerconstants.h
@@ -120,6 +120,7 @@ enum DebuggerStartMode
AttachCore, // Attach to a core file
AttachToRemoteServer, // Attach to a running gdbserver
AttachToRemoteProcess, // Attach to a running remote process
+ AttachToQmlServer, // Attach to a running QmlServer
StartRemoteProcess // Start and attach to a remote process
};
diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp
index 60ddebcd711..8668243ab46 100644
--- a/src/plugins/debugger/debuggerdialogs.cpp
+++ b/src/plugins/debugger/debuggerdialogs.cpp
@@ -26,7 +26,6 @@
#include "debuggerdialogs.h"
#include "debuggerkitinformation.h"
-#include "debuggerstartparameters.h"
#include "debuggerruncontrol.h"
#include "cdb/cdbengine.h"
@@ -34,10 +33,14 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/toolchain.h>
+
+#include <app/app_version.h>
#include <utils/pathchooser.h>
#include <utils/fancylineedit.h>
#include <utils/qtcassert.h>
+#include <ssh/sshconnection.h>
+
#include <QButtonGroup>
#include <QCheckBox>
#include <QComboBox>
@@ -226,7 +229,7 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
setWindowTitle(tr("Start Debugger"));
d->kitChooser = new KitChooser(this);
- d->kitChooser->setKitPredicate([this](const Kit *k) {
+ d->kitChooser->setKitPredicate([](const Kit *k) {
return !DebuggerKitInformation::configurationErrors(k);
});
d->kitChooser->populate();
@@ -264,7 +267,7 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
d->serverStartScriptPathChooser->setPromptDialogTitle(tr("Select Server Start Script"));
d->serverStartScriptPathChooser->setToolTip(tr(
"This option can be used to point to a script that will be used "
- "to start a debug server. If the field is empty, Qt Creator's "
+ "to start a debug server. If the field is empty, "
"default methods to set up debug servers will be used."));
d->serverStartScriptLabel = new QLabel(tr("&Server start script:"), this);
d->serverStartScriptLabel->setBuddy(d->serverStartScriptPathChooser);
@@ -365,9 +368,8 @@ void StartApplicationDialog::updateState()
d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(okEnabled);
}
-bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp, Kit **kit)
+void StartApplicationDialog::run(bool attachRemote)
{
- const bool attachRemote = rp->startMode == AttachToRemoteServer;
const QString settingsGroup = QLatin1String("DebugMode");
const QString arrayName = QLatin1String("StartApplication");
@@ -387,7 +389,7 @@ bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp, Kit
settings->endArray();
settings->endGroup();
- StartApplicationDialog dialog(parent);
+ StartApplicationDialog dialog(ICore::dialogParent());
dialog.setHistory(history);
dialog.setParameters(history.back());
if (!attachRemote) {
@@ -399,11 +401,14 @@ bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp, Kit
dialog.d->channelOverrideEdit->setVisible(false);
}
if (dialog.exec() != QDialog::Accepted)
- return false;
+ return;
Kit *k = dialog.d->kitChooser->currentKit();
IDevice::ConstPtr dev = DeviceKitInformation::device(k);
+ DebuggerRunTool *debugger = DebuggerRunTool::createFromKit(k);
+ QTC_ASSERT(debugger, return);
+
const StartApplicationParameters newParameters = dialog.parameters();
if (newParameters != history.back()) {
history.append(newParameters);
@@ -419,29 +424,40 @@ bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp, Kit
settings->endGroup();
}
- rp->inferior.executable = newParameters.runnable.executable;
+ StandardRunnable inferior = newParameters.runnable;
+ debugger->setUseTerminal(newParameters.runnable.runMode == ApplicationLauncher::Console);
const QString inputAddress = dialog.d->channelOverrideEdit->text();
if (!inputAddress.isEmpty())
- rp->remoteChannel = inputAddress;
+ debugger->setRemoteChannel(inputAddress);
else
- rp->remoteChannel = QString("%1:%2").arg(dev->sshParameters().host).arg(newParameters.serverPort);
- rp->displayName = newParameters.displayName();
- rp->inferior.workingDirectory = newParameters.runnable.workingDirectory;
- rp->inferior.runMode = newParameters.runnable.runMode;
- rp->needFixup = false;
- rp->useTerminal = newParameters.runnable.runMode == ApplicationLauncher::Console;
- if (!newParameters.runnable.commandLineArguments.isEmpty())
- rp->inferior.commandLineArguments = newParameters.runnable.commandLineArguments;
- rp->breakOnMain = newParameters.breakAtMain;
- rp->serverStartScript = newParameters.serverStartScript;
- rp->debugInfoLocation = newParameters.debugInfoLocation;
+ debugger->setRemoteChannel(dev->sshParameters().host, newParameters.serverPort);
+ debugger->setRunControlName(newParameters.displayName());
+ debugger->setBreakOnMain(newParameters.breakAtMain);
+ debugger->setDebugInfoLocation(newParameters.debugInfoLocation);
+ debugger->setInferior(inferior);
+ debugger->setServerStartScript(newParameters.serverStartScript); // Note: This requires inferior.
+ debugger->setNeedFixup(false);
bool isLocal = !dev || (dev->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
if (!attachRemote)
- rp->startMode = isLocal ? StartExternal : StartRemoteProcess;
- if (kit)
- *kit = k;
- return true;
+ debugger->setStartMode(isLocal ? StartExternal : StartRemoteProcess);
+
+ if (attachRemote) {
+ debugger->setStartMode(AttachToRemoteServer);
+ debugger->setCloseMode(KillAtClose);
+ debugger->setUseContinueInsteadOfRun(true);
+ }
+ debugger->startRunControl();
+}
+
+void StartApplicationDialog::attachToRemoteServer()
+{
+ run(true);
+}
+
+void StartApplicationDialog::startAndDebugApplication()
+{
+ run(false);
}
StartApplicationParameters StartApplicationDialog::parameters() const
@@ -560,15 +576,16 @@ static QString cdbRemoteHelp()
const QString ext32 = QDir::toNativeSeparators(CdbEngine::extensionLibraryName(false));
const QString ext64 = QDir::toNativeSeparators(CdbEngine::extensionLibraryName(true));
return StartRemoteCdbDialog::tr(
- "<html><body><p>The remote CDB needs to load the matching Qt Creator CDB extension "
- "(<code>%1</code> or <code>%2</code>, respectively).</p><p>Copy it onto the remote machine and set the "
- "environment variable <code>%3</code> to point to its folder.</p><p>"
- "Launch the remote CDB as <code>%4 &lt;executable&gt;</code> "
+ "<html><body><p>The remote CDB needs to load the matching %1 CDB extension "
+ "(<code>%2</code> or <code>%3</code>, respectively).</p><p>Copy it onto the remote machine and set the "
+ "environment variable <code>%4</code> to point to its folder.</p><p>"
+ "Launch the remote CDB as <code>%5 &lt;executable&gt;</code> "
"to use TCP/IP as communication protocol.</p><p>Enter the connection parameters as:</p>"
- "<pre>%5</pre></body></html>").
- arg(ext32, ext64, QLatin1String("_NT_DEBUGGER_EXTENSION_PATH"),
- QLatin1String("cdb.exe -server tcp:port=1234"),
- QLatin1String(cdbConnectionSyntax));
+ "<pre>%6</pre></body></html>")
+ .arg(Core::Constants::IDE_DISPLAY_NAME,
+ ext32, ext64, QLatin1String("_NT_DEBUGGER_EXTENSION_PATH"),
+ QLatin1String("cdb.exe -server tcp:port=1234"),
+ QLatin1String(cdbConnectionSyntax));
}
StartRemoteCdbDialog::StartRemoteCdbDialog(QWidget *parent) :
diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h
index b291dbbe26d..d9f3790a146 100644
--- a/src/plugins/debugger/debuggerdialogs.h
+++ b/src/plugins/debugger/debuggerdialogs.h
@@ -72,7 +72,8 @@ public:
explicit StartApplicationDialog(QWidget *parent);
~StartApplicationDialog();
- static bool run(QWidget *parent, DebuggerRunParameters *rp, ProjectExplorer::Kit **kit);
+ static void attachToRemoteServer();
+ static void startAndDebugApplication();
private:
void historyIndexChanged(int);
@@ -81,6 +82,7 @@ private:
void setParameters(const StartApplicationParameters &p);
void setHistory(const QList<StartApplicationParameters> &l);
void onChannelOverrideChanged(const QString &channel);
+ static void run(bool);
StartApplicationDialogPrivate *d;
};
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index 93a2d69aada..ecf31ab8410 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -30,7 +30,6 @@
#include "debuggercore.h"
#include "debuggericons.h"
#include "debuggerruncontrol.h"
-#include "debuggerstartparameters.h"
#include "debuggertooltipmanager.h"
#include "breakhandler.h"
@@ -109,7 +108,6 @@ QDebug operator<<(QDebug str, const DebuggerRunParameters &sp)
<< " attachPID=" << sp.attachPID.pid()
<< " useTerminal=" << sp.useTerminal
<< " remoteChannel=" << sp.remoteChannel
- << " serverStartScript=" << sp.serverStartScript
<< " abi=" << sp.toolChainAbi.toString() << '\n';
return str;
}
@@ -535,14 +533,11 @@ void DebuggerEngine::start()
fp->setKeepOnFinish(FutureProgress::HideOnFinish);
d->m_progress.reportStarted();
- DebuggerRunParameters &rp = runParameters();
+ const DebuggerRunParameters &rp = runParameters();
d->m_inferiorPid = rp.attachPID.isValid() ? rp.attachPID : ProcessHandle();
if (d->m_inferiorPid.isValid())
runControl()->setApplicationProcessHandle(d->m_inferiorPid);
- if (isNativeMixedActive())
- rp.inferior.environment.set("QV4_FORCE_INTERPRETER", "1");
-
action(OperateByInstruction)->setEnabled(hasCapability(DisassemblerCapability));
QTC_ASSERT(state() == DebuggerNotReady || state() == DebuggerFinished,
@@ -633,11 +628,6 @@ const DebuggerRunParameters &DebuggerEngine::runParameters() const
return runTool()->runParameters();
}
-DebuggerRunParameters &DebuggerEngine::runParameters()
-{
- return runTool()->runParameters();
-}
-
DebuggerState DebuggerEngine::state() const
{
return d->m_state;
@@ -730,7 +720,6 @@ void DebuggerEnginePrivate::doSetupEngine()
{
m_engine->showMessage("CALL: SETUP ENGINE");
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << m_engine << state());
- m_engine->validateExecutable();
m_engine->setupEngine();
}
@@ -1239,30 +1228,6 @@ QString DebuggerEngine::nativeStartupCommands() const
runParameters().additionalStartupCommands}).join('\n'));
}
-bool DebuggerEngine::prepareCommand()
-{
- if (HostOsInfo::isWindowsHost()) {
- DebuggerRunParameters &rp = runParameters();
- QtcProcess::SplitError perr;
- rp.inferior.commandLineArguments =
- QtcProcess::prepareArgs(rp.inferior.commandLineArguments, &perr,
- HostOsInfo::hostOs(), nullptr,
- &rp.inferior.workingDirectory).toWindowsArgs();
- if (perr != QtcProcess::SplitOk) {
- // perr == BadQuoting is never returned on Windows
- // FIXME? QTCREATORBUG-2809
- showMessage("ADAPTER START FAILED");
- const QString title = tr("Adapter start failed");
- const QString msg = tr("Debugging complex command lines "
- "is currently not supported on Windows.");
- ICore::showWarningWithOptions(title, msg);
- notifyEngineSetupFailed();
- return false;
- }
- }
- return true;
-}
-
void DebuggerEngine::updateBreakpointMarker(const Breakpoint &bp)
{
d->m_disassemblerAgent.updateBreakpointMarker(bp);
@@ -1379,8 +1344,17 @@ void DebuggerEngine::quitDebugger()
void DebuggerEngine::abortDebugger()
{
- // Overridden in e.g. GdbEngine.
- quitDebugger();
+ if (!isDying()) {
+ // Be friendly the first time. This will change targetState().
+ showMessage("ABORTING DEBUGGER. FIRST TIME.");
+ quitDebugger();
+ } else {
+ // We already tried. Try harder.
+ showMessage("ABORTING DEBUGGER. SECOND TIME.");
+ abortDebuggerProcess();
+ if (runControl())
+ runControl()->initiateFinish();
+ }
}
void DebuggerEngine::requestInterruptInferior()
@@ -1771,42 +1745,30 @@ void DebuggerEngine::setStateDebugging(bool on)
d->m_isStateDebugging = on;
}
-void DebuggerEngine::validateExecutable()
+void DebuggerRunParameters::validateExecutable()
{
- DebuggerRunParameters *sp = &runParameters();
- if (sp->skipExecutableValidation)
- return;
- if (sp->languages == QmlLanguage)
- return;
-
- QString symbolFile = sp->symbolFile;
- if (symbolFile.isEmpty())
- symbolFile = sp->inferior.executable;
- if (symbolFile.isEmpty())
- return;
-
const bool warnOnRelease = boolSetting(WarnOnReleaseBuilds);
bool warnOnInappropriateDebugger = false;
QString detailedWarning;
- switch (sp->toolChainAbi.binaryFormat()) {
+ switch (toolChainAbi.binaryFormat()) {
case Abi::PEFormat: {
QString preferredDebugger;
- if (sp->toolChainAbi.osFlavor() == Abi::WindowsMSysFlavor) {
- if (sp->cppEngineType == CdbEngineType)
+ if (toolChainAbi.osFlavor() == Abi::WindowsMSysFlavor) {
+ if (cppEngineType == CdbEngineType)
preferredDebugger = "GDB";
- } else if (sp->cppEngineType != CdbEngineType) {
+ } else if (cppEngineType != CdbEngineType) {
// osFlavor() is MSVC, so the recommended debugger is CDB
preferredDebugger = "CDB";
}
if (!preferredDebugger.isEmpty()) {
warnOnInappropriateDebugger = true;
- detailedWarning = tr(
+ detailedWarning = DebuggerEngine::tr(
"The inferior is in the Portable Executable format.\n"
"Selecting %1 as debugger would improve the debugging "
"experience for this binary format.").arg(preferredDebugger);
break;
}
- if (warnOnRelease && sp->cppEngineType == CdbEngineType) {
+ if (warnOnRelease && cppEngineType == CdbEngineType) {
if (!symbolFile.endsWith(".exe", Qt::CaseInsensitive))
symbolFile.append(".exe");
QString errorMessage;
@@ -1823,9 +1785,9 @@ void DebuggerEngine::validateExecutable()
break;
}
case Abi::ElfFormat: {
- if (sp->cppEngineType == CdbEngineType) {
+ if (cppEngineType == CdbEngineType) {
warnOnInappropriateDebugger = true;
- detailedWarning = tr(
+ detailedWarning = DebuggerEngine::tr(
"The inferior is in the ELF format.\n"
"Selecting GDB or LLDB as debugger would improve the debugging "
"experience for this binary format.");
@@ -1898,7 +1860,7 @@ void DebuggerEngine::validateExecutable()
QRegExp exp = itExp->first;
int index = exp.indexIn(string);
if (index != -1) {
- sp->sourcePathMap.insert(string.left(index) + exp.cap(1), itExp->second);
+ sourcePathMap.insert(string.left(index) + exp.cap(1), itExp->second);
found = true;
break;
}
@@ -1917,8 +1879,9 @@ void DebuggerEngine::validateExecutable()
return;
foreach (const QByteArray &name, interesting) {
- const QString found = seen.contains(name) ? tr("Found.") : tr("Not found.");
- detailedWarning.append('\n' + tr("Section %1: %2").arg(QString::fromUtf8(name)).arg(found));
+ const QString found = seen.contains(name) ? DebuggerEngine::tr("Found.")
+ : DebuggerEngine::tr("Not found.");
+ detailedWarning.append('\n' + DebuggerEngine::tr("Section %1: %2").arg(QString::fromUtf8(name)).arg(found));
}
break;
}
@@ -1926,14 +1889,14 @@ void DebuggerEngine::validateExecutable()
return;
}
if (warnOnInappropriateDebugger) {
- AsynchronousMessageBox::information(tr("Warning"),
- tr("The selected debugger may be inappropriate for the inferior.\n"
+ AsynchronousMessageBox::information(DebuggerEngine::tr("Warning"),
+ DebuggerEngine::tr("The selected debugger may be inappropriate for the inferior.\n"
"Examining symbols and setting breakpoints by file name and line number "
"may fail.\n")
+ '\n' + detailedWarning);
} else if (warnOnRelease) {
- AsynchronousMessageBox::information(tr("Warning"),
- tr("This does not seem to be a \"Debug\" build.\n"
+ AsynchronousMessageBox::information(DebuggerEngine::tr("Warning"),
+ DebuggerEngine::tr("This does not seem to be a \"Debug\" build.\n"
"Setting breakpoints by file name and line number may fail.")
+ '\n' + detailedWarning);
}
@@ -2028,10 +1991,8 @@ void DebuggerEngine::checkState(DebuggerState state, const char *file, int line)
bool DebuggerEngine::isNativeMixedEnabled() const
{
- if (DebuggerRunTool *rt = runTool()) {
- const DebuggerRunParameters &runParams = rt->runParameters();
- return runParams.nativeMixedEnabled && (runParams.languages & QmlLanguage);
- }
+ if (DebuggerRunTool *rt = runTool())
+ return rt->runParameters().isNativeMixedDebugging();
return false;
}
@@ -2050,6 +2011,11 @@ bool DebuggerEngine::isNativeMixedActiveFrame() const
return frame.language == QmlLanguage;
}
+bool DebuggerRunParameters::isNativeMixedDebugging() const
+{
+ return nativeMixedEnabled && isCppDebugging && isQmlDebugging;
+}
+
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h
index 04e1196ad43..89723096d06 100644
--- a/src/plugins/debugger/debuggerengine.h
+++ b/src/plugins/debugger/debuggerengine.h
@@ -29,7 +29,6 @@
#include "debuggerconstants.h"
#include "debuggeritem.h"
#include "debuggerprotocol.h"
-#include "debuggerstartparameters.h"
#include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/runnables.h>
@@ -46,10 +45,7 @@ QT_END_NAMESPACE
namespace Core { class IOptionsPage; }
-namespace Utils {
-class MacroExpander;
-class ProcessHandle;
-} // Utils
+namespace Utils { class MacroExpander; }
namespace Debugger {
@@ -80,16 +76,63 @@ class MemoryViewSetupData;
class Terminal;
class ThreadId;
-class DebuggerRunParameters : public DebuggerStartParameters
+class DebuggerRunParameters
{
public:
- DebuggerRunParameters() {}
- DebuggerRunParameters(const DebuggerStartParameters &sp) : DebuggerStartParameters(sp) {}
+ DebuggerStartMode startMode = NoStartMode;
+ DebuggerCloseMode closeMode = KillAtClose;
+
+ ProjectExplorer::StandardRunnable inferior;
+ QString displayName; // Used in the Snapshots view.
+ Utils::Environment stubEnvironment;
+ Utils::ProcessHandle attachPID;
+ QStringList solibSearchPath;
+ bool useTerminal = false;
+
+ // Used by Qml debugging.
+ QUrl qmlServer;
+
+ // Used by general remote debugging.
+ QString remoteChannel;
+ bool useExtendedRemote = false; // Whether to use GDB's target extended-remote or not.
+ QString symbolFile;
+
+ // Used by Mer plugin (3rd party)
+ QMap<QString, QString> sourcePathMap;
+
+ // Used by baremetal plugin
+ QString commandsForReset; // commands used for resetting the inferior
+ bool useContinueInsteadOfRun = false; // if connected to a hw debugger run is not possible but continue is used
+ QString commandsAfterConnect; // additional commands to post after connection to debug target
+
+ // Used by Valgrind
+ QStringList expectedSignals;
+
+ // For QNX debugging
+ bool useCtrlCStub = false;
+
+ // Used by Android to avoid false positives on warnOnRelease
+ bool skipExecutableValidation = false;
+ bool useTargetAsync = false;
+ QStringList additionalSearchDirectories;
+
+ // Used by iOS.
+ QString platform;
+ QString deviceSymbolsRoot;
+ bool continueAfterAttach = false;
+ QString sysRoot;
+
+ // Used by general core file debugging. Public access requested in QTCREATORBUG-17158.
+ QString coreFile;
+
+ // Macro-expanded and passed to debugger startup.
+ QString additionalStartupCommands;
DebuggerEngineType masterEngineType = NoEngineType;
DebuggerEngineType cppEngineType = NoEngineType;
- DebuggerLanguages languages = NoLanguage;
+ bool isCppDebugging = true;
+ bool isQmlDebugging = false;
bool breakOnMain = false;
bool multiProcess = false; // Whether to set detach-on-fork off.
@@ -98,7 +141,6 @@ public:
QString startMessage; // First status message shown.
QString debugInfoLocation; // Gdb "set-debug-file-directory".
QStringList debugSourceLocation; // Gdb "directory"
- QString serverStartScript;
bool isSnapshot = false; // Set if created internally.
ProjectExplorer::Abi toolChainAbi;
@@ -114,10 +156,15 @@ public:
bool nativeMixedEnabled = false;
+ bool isNativeMixedDebugging() const;
+ void validateExecutable();
+
Utils::MacroExpander *macroExpander = 0;
// For Debugger testing.
int testCase = 0;
+
+ QStringList validationErrors;
};
class UpdateParameters
@@ -195,7 +242,7 @@ public:
virtual ~DebuggerEngine();
const DebuggerRunParameters &runParameters() const;
- DebuggerRunParameters &runParameters();
+
virtual void setRunTool(DebuggerRunTool *runTool);
DebuggerRunTool *runTool() const;
@@ -316,7 +363,8 @@ public:
virtual void resetLocation();
virtual void gotoLocation(const Internal::Location &location);
virtual void quitDebugger(); // called when pressing the stop button
- virtual void abortDebugger(); // called from the debug menu action
+
+ void abortDebugger(); // called from the debug menu action
void updateViews();
bool isSlaveEngine() const;
@@ -336,50 +384,49 @@ public:
QString expand(const QString &string) const;
QString nativeStartupCommands() const;
- bool prepareCommand();
-
protected:
// The base notify*() function implementation should be sufficient
// in most cases, but engines are free to override them to do some
// engine specific cleanup like stopping timers etc.
- virtual void notifyEngineSetupOk();
- virtual void notifyEngineSetupFailed();
- virtual void notifyEngineRunFailed();
+ void notifyEngineSetupOk();
+ void notifyEngineSetupFailed();
+ void notifyEngineRunFailed();
- virtual void notifyInferiorSetupOk();
- virtual void notifyInferiorSetupFailed();
+ void notifyInferiorSetupOk();
+ void notifyInferiorSetupFailed();
- virtual void notifyEngineRunAndInferiorRunOk();
- virtual void notifyEngineRunAndInferiorStopOk();
- virtual void notifyEngineRunOkAndInferiorUnrunnable(); // Called by CoreAdapter.
+ void notifyEngineRunAndInferiorRunOk();
+ void notifyEngineRunAndInferiorStopOk();
+ void notifyEngineRunOkAndInferiorUnrunnable(); // Called by CoreAdapter.
// Use notifyInferiorRunRequested() plus notifyInferiorRunOk() instead.
- //virtual void notifyInferiorSpontaneousRun();
+ // void notifyInferiorSpontaneousRun();
+
+ void notifyInferiorRunRequested();
+ void notifyInferiorRunOk();
+ void notifyInferiorRunFailed();
- virtual void notifyInferiorRunRequested();
- virtual void notifyInferiorRunOk();
- virtual void notifyInferiorRunFailed();
+ void notifyInferiorStopOk();
+ void notifyInferiorSpontaneousStop();
+ void notifyInferiorStopFailed();
- virtual void notifyInferiorStopOk();
- virtual void notifyInferiorSpontaneousStop();
- virtual void notifyInferiorStopFailed();
+ public: // FIXME: Remove, currently needed for Android.
+ void notifyInferiorExited();
- public:
- virtual void notifyInferiorExited();
+ protected:
void notifyDebuggerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus,
const QString &backendName);
-protected:
virtual void setState(DebuggerState state, bool forced = false);
- virtual void notifyInferiorShutdownOk();
- virtual void notifyInferiorShutdownFailed();
+ void notifyInferiorShutdownOk();
+ void notifyInferiorShutdownFailed();
- virtual void notifyEngineSpontaneousShutdown();
- virtual void notifyEngineShutdownOk();
- virtual void notifyEngineShutdownFailed();
+ void notifyEngineSpontaneousShutdown();
+ void notifyEngineShutdownOk();
+ void notifyEngineShutdownFailed();
- virtual void notifyEngineIll();
+ void notifyEngineIll();
virtual void setupEngine() = 0;
virtual void setupInferior() = 0;
@@ -407,6 +454,8 @@ protected:
virtual void frameUp();
virtual void frameDown();
+ virtual void abortDebuggerProcess() {} // second attempt
+
virtual void doUpdateLocals(const UpdateParameters &params);
void setMasterEngine(DebuggerEngine *masterEngine);
@@ -425,8 +474,6 @@ protected:
bool isStateDebugging() const;
void setStateDebugging(bool on);
- void validateExecutable();
-
virtual void setupSlaveInferior();
virtual void setupSlaveEngine();
virtual void runSlaveEngine();
@@ -464,8 +511,6 @@ private:
QPointer<DebuggerEngine> m_engine;
};
-ProjectExplorer::RunControl *createAndScheduleRun(const DebuggerRunParameters &rp, ProjectExplorer::Kit *kit);
-
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp
index 5bc634fed84..d5ab9d0aae1 100644
--- a/src/plugins/debugger/debuggerkitinformation.cpp
+++ b/src/plugins/debugger/debuggerkitinformation.cpp
@@ -300,26 +300,26 @@ KitConfigWidget *DebuggerKitInformation::createConfigWidget(Kit *k) const
void DebuggerKitInformation::addToMacroExpander(Kit *kit, MacroExpander *expander) const
{
expander->registerVariable("Debugger:Name", tr("Name of Debugger"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
const DebuggerItem *item = debugger(kit);
return item ? item->displayName() : tr("Unknown debugger");
});
expander->registerVariable("Debugger:Type", tr("Type of Debugger Backend"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
const DebuggerItem *item = debugger(kit);
return item ? item->engineTypeName() : tr("Unknown debugger type");
});
expander->registerVariable("Debugger:Version", tr("Debugger"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
const DebuggerItem *item = debugger(kit);
return item && !item->version().isEmpty()
? item->version() : tr("Unknown debugger version");
});
expander->registerVariable("Debugger:Abi", tr("Debugger"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
const DebuggerItem *item = debugger(kit);
return item && !item->abis().isEmpty()
? item->abiNames().join(QLatin1Char(' '))
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index c992fe85074..dcc07a6d87d 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -26,7 +26,6 @@
#include "debuggerplugin.h"
#include "debuggermainwindow.h"
-#include "debuggerstartparameters.h"
#include "debuggeractions.h"
#include "debuggerinternalconstants.h"
#include "debuggercore.h"
@@ -67,6 +66,8 @@
#include "analyzer/analyzerconstants.h"
#include "analyzer/analyzermanager.h"
+#include <app/app_version.h>
+
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
@@ -103,6 +104,7 @@
#include <projectexplorer/target.h>
#include <projectexplorer/taskhub.h>
#include <projectexplorer/toolchain.h>
+#include <ssh/sshconnection.h>
#include <texteditor/texteditor.h>
#include <texteditor/textdocument.h>
@@ -731,10 +733,8 @@ public:
void onModeChanged(Id mode);
void updateDebugWithoutDeployMenu();
- void startAndDebugApplication();
void startRemoteCdbSession();
void startRemoteServerAndAttachToProcess();
- void attachToRemoteServer();
void attachToRunningApplication();
void attachToUnstartedApplicationDialog();
void attachToQmlPort();
@@ -970,14 +970,12 @@ public:
ActionContainer *m_menu = 0;
- QHash<DebuggerLanguage, Core::Context> m_contextsForLanguage;
-
Project *m_previousProject = 0;
QPointer<Target> m_previousTarget;
QPointer<RunConfiguration> m_previousRunConfiguration;
Id m_previousMode;
- QVector<QPair<DebuggerRunParameters, Kit *>> m_scheduledStarts;
+ QVector<DebuggerRunTool *> m_scheduledStarts;
ProxyAction *m_visibleStartAction = 0;
ProxyAction *m_hiddenStopAction = 0;
@@ -1073,11 +1071,6 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin)
dd = this;
m_plugin = plugin;
-
-// m_toolBars.insert(CppLanguage, 0);
-// m_toolBars.insert(QmlLanguage, 0);
- m_contextsForLanguage.insert(CppLanguage, Context(C_CPPDEBUGGER));
- m_contextsForLanguage.insert(QmlLanguage, Context(C_QMLDEBUGGER));
}
DebuggerPluginPrivate::~DebuggerPluginPrivate()
@@ -1107,17 +1100,11 @@ static QString msgParameterMissing(const QString &a)
return DebuggerPlugin::tr("Option \"%1\" is missing the parameter.").arg(a);
}
-static Kit *guessKitFromParameters(const DebuggerRunParameters &rp)
+static Kit *guessKitFromAbis(const QList<Abi> &abis)
{
Kit *kit = 0;
// Try to find a kit via ABI.
- QList<Abi> abis;
- if (rp.toolChainAbi.isValid())
- abis.push_back(rp.toolChainAbi);
- else if (!rp.inferior.executable.isEmpty())
- abis = Abi::abisOfBinary(FileName::fromString(rp.inferior.executable));
-
if (!abis.isEmpty()) {
// Try exact abis.
kit = KitManager::kit([abis](const Kit *k) {
@@ -1152,60 +1139,74 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
*errorMessage = msgParameterMissing(*it);
return false;
}
- Kit *kit = 0;
- DebuggerRunParameters rp;
- qulonglong pid = it->toULongLong();
- if (pid) {
- rp.startMode = AttachExternal;
- rp.closeMode = DetachAtClose;
- rp.attachPID = ProcessHandle(pid);
- rp.displayName = tr("Process %1").arg(rp.attachPID.pid());
- rp.startMessage = tr("Attaching to local process %1.").arg(rp.attachPID.pid());
- } else {
- rp.startMode = StartExternal;
- QStringList args = it->split(QLatin1Char(','));
+ const qulonglong pid = it->toULongLong();
+ const QStringList args = it->split(',');
+
+ Kit *kit = nullptr;
+ DebuggerStartMode startMode = StartExternal;
+ QString executable;
+ QString remoteChannel;
+ QString coreFile;
+ bool useTerminal = false;
+
+ if (!pid) {
foreach (const QString &arg, args) {
- QString key = arg.section(QLatin1Char('='), 0, 0);
- QString val = arg.section(QLatin1Char('='), 1, 1);
+ const QString key = arg.section('=', 0, 0);
+ const QString val = arg.section('=', 1, 1);
if (val.isEmpty()) {
if (key.isEmpty()) {
continue;
- } else if (rp.inferior.executable.isEmpty()) {
- rp.inferior.executable = key;
+ } else if (executable.isEmpty()) {
+ executable = key;
} else {
*errorMessage = DebuggerPlugin::tr("Only one executable allowed.");
return false;
}
- }
- if (key == QLatin1String("server")) {
- rp.startMode = AttachToRemoteServer;
- rp.remoteChannel = val;
- rp.displayName = tr("Remote: \"%1\"").arg(rp.remoteChannel);
- rp.startMessage = tr("Attaching to remote server %1.").arg(rp.remoteChannel);
- } else if (key == QLatin1String("core")) {
- rp.startMode = AttachCore;
- rp.closeMode = DetachAtClose;
- rp.coreFile = val;
- rp.displayName = tr("Core file \"%1\"").arg(rp.coreFile);
- rp.startMessage = tr("Attaching to core file %1.").arg(rp.coreFile);
- } else if (key == QLatin1String("terminal")) {
- rp.useTerminal = bool(val.toInt());
- } else if (key == QLatin1String("kit")) {
+ } else if (key == "kit") {
kit = KitManager::kit(Id::fromString(val));
+ } else if (key == "server") {
+ startMode = AttachToRemoteServer;
+ remoteChannel = remoteChannel;
+ } else if (key == "core") {
+ startMode = AttachCore;
+ coreFile = val;
+ } else if (key == "terminal") {
+ useTerminal = true;
}
}
}
- if (rp.startMode == StartExternal) {
- rp.displayName = tr("Executable file \"%1\"").arg(rp.inferior.executable);
- rp.startMessage = tr("Debugging file %1.").arg(rp.inferior.executable);
+ if (!kit)
+ kit = guessKitFromAbis(Abi::abisOfBinary(FileName::fromString(executable)));
+
+ auto debugger = DebuggerRunTool::createFromKit(kit);
+ QTC_ASSERT(debugger, return false);
+
+ if (pid) {
+ debugger->setStartMode(AttachExternal);
+ debugger->setCloseMode(DetachAtClose);
+ debugger->setAttachPid(pid);
+ debugger->setRunControlName(tr("Process %1").arg(pid));
+ debugger->setStartMessage(tr("Attaching to local process %1.").arg(pid));
+ } else if (startMode == AttachToRemoteServer) {
+ debugger->setStartMode(AttachToRemoteServer);
+ debugger->setRemoteChannel(remoteChannel);
+ debugger->setRunControlName(tr("Remote: \"%1\"").arg(remoteChannel));
+ debugger->setStartMessage(tr("Attaching to remote server %1.").arg(remoteChannel));
+ } else if (startMode == AttachCore) {
+ debugger->setStartMode(AttachCore);
+ debugger->setCloseMode(DetachAtClose);
+ debugger->setCoreFileName(coreFile);
+ debugger->setRunControlName(tr("Core file \"%1\"").arg(coreFile));
+ debugger->setStartMessage(tr("Attaching to core file %1.").arg(coreFile));
+ } else {
+ debugger->setStartMode(StartExternal);
+ debugger->setInferiorExecutable(executable);
+ debugger->setRunControlName(tr("Executable file \"%1\"").arg(executable));
+ debugger->setStartMessage(tr("Debugging file %1.").arg(executable));
}
- rp.inferior.environment = Utils::Environment::systemEnvironment();
- rp.stubEnvironment = Utils::Environment::systemEnvironment();
- rp.debugger.environment = Utils::Environment::systemEnvironment();
+ debugger->setUseTerminal(useTerminal);
- if (!kit)
- kit = guessKitFromParameters(rp);
- m_scheduledStarts.append(QPair<DebuggerRunParameters, Kit *>(rp, kit));
+ m_scheduledStarts.append(debugger);
return true;
}
// -wincrashevent <event-handle>:<pid>. A handle used for
@@ -1219,18 +1220,20 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
*errorMessage = msgParameterMissing(*it);
return false;
}
- DebuggerRunParameters rp;
- rp.startMode = AttachCrashedExternal;
- rp.crashParameter = it->section(QLatin1Char(':'), 0, 0);
- rp.attachPID = ProcessHandle(it->section(QLatin1Char(':'), 1, 1).toULongLong());
- rp.displayName = tr("Crashed process %1").arg(rp.attachPID.pid());
- rp.startMessage = tr("Attaching to crashed process %1").arg(rp.attachPID.pid());
- if (!rp.attachPID.isValid()) {
+ qint64 pid = it->section(':', 1, 1).toULongLong();
+ auto debugger = DebuggerRunTool::createFromKit(findUniversalCdbKit());
+ QTC_ASSERT(debugger, return false);
+ debugger->setStartMode(AttachCrashedExternal);
+ debugger->setCrashParameter(it->section(':', 0, 0));
+ debugger->setAttachPid(pid);
+ debugger->setRunControlName(tr("Crashed process %1").arg(pid));
+ debugger->setStartMessage(tr("Attaching to crashed process %1").arg(pid));
+ if (pid < 1) {
*errorMessage = DebuggerPlugin::tr("The parameter \"%1\" of option \"%2\" "
"does not match the pattern <handle>:<pid>.").arg(*it, option);
return false;
}
- m_scheduledStarts.append(QPair<DebuggerRunParameters, Kit *>(rp, findUniversalCdbKit()));
+ m_scheduledStarts.append(debugger);
return true;
}
@@ -1497,7 +1500,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
act = m_startAndDebugApplicationAction = new QAction(this);
act->setText(tr("Start and Debug External Application..."));
- connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::startAndDebugApplication);
+ connect(act, &QAction::triggered, this, &StartApplicationDialog::startAndDebugApplication);
act = m_attachToCoreAction = new QAction(this);
act->setText(tr("Load Core File..."));
@@ -1505,7 +1508,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
act = m_attachToRemoteServerAction = new QAction(this);
act->setText(tr("Attach to Running Debug Server..."));
- connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToRemoteServer);
+ connect(act, &QAction::triggered, this, &StartApplicationDialog::attachToRemoteServer);
act = m_startRemoteServerAction = new QAction(this);
act->setText(tr("Start Debug Server Attached to Process..."));
@@ -1934,14 +1937,6 @@ void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project)
setProxyAction(m_visibleStartAction, Id(Constants::DEBUG));
}
-void DebuggerPluginPrivate::startAndDebugApplication()
-{
- DebuggerRunParameters rp;
- Kit *kit;
- if (StartApplicationDialog::run(ICore::dialogParent(), &rp, &kit))
- createAndScheduleRun(rp, kit);
-}
-
void DebuggerPluginPrivate::attachCore()
{
AttachCoreDialog dlg(ICore::dialogParent());
@@ -1965,48 +1960,40 @@ void DebuggerPluginPrivate::attachCore()
setConfigValue("LastExternalStartScript", dlg.overrideStartScript());
setConfigValue("LastForceLocalCoreFile", dlg.forcesLocalCoreFile());
- QString display = dlg.useLocalCoreFile() ? dlg.localCoreFile() : dlg.remoteCoreFile();
- DebuggerRunParameters rp;
- rp.masterEngineType = DebuggerKitInformation::engineType(dlg.kit());
- rp.inferior.executable = dlg.localExecutableFile();
- rp.coreFile = dlg.localCoreFile();
- rp.displayName = tr("Core file \"%1\"").arg(display);
- rp.startMode = AttachCore;
- rp.closeMode = DetachAtClose;
- rp.overrideStartScript = dlg.overrideStartScript();
- createAndScheduleRun(rp, dlg.kit());
+ auto debugger = DebuggerRunTool::createFromKit(dlg.kit());
+ QTC_ASSERT(debugger, return);
+ debugger->setMasterEngineType(DebuggerKitInformation::engineType(dlg.kit()));
+ debugger->setInferiorExecutable(dlg.localExecutableFile());
+ debugger->setCoreFileName(dlg.localCoreFile());
+ debugger->setRunControlName(tr("Core file \"%1\"")
+ .arg(dlg.useLocalCoreFile() ? dlg.localCoreFile() : dlg.remoteCoreFile()));
+ debugger->setStartMode(AttachCore);
+ debugger->setCloseMode(DetachAtClose);
+ debugger->setOverrideStartScript(dlg.overrideStartScript());
+ debugger->startRunControl();
}
void DebuggerPluginPrivate::startRemoteCdbSession()
{
const QString connectionKey = "CdbRemoteConnection";
- DebuggerRunParameters rp;
Kit *kit = findUniversalCdbKit();
QTC_ASSERT(kit, return);
- rp.startMode = AttachToRemoteServer;
- rp.closeMode = KillAtClose;
+
StartRemoteCdbDialog dlg(ICore::dialogParent());
QString previousConnection = configValue(connectionKey).toString();
if (previousConnection.isEmpty())
- previousConnection = QLatin1String("localhost:1234");
+ previousConnection = "localhost:1234";
dlg.setConnection(previousConnection);
if (dlg.exec() != QDialog::Accepted)
return;
- rp.remoteChannel = dlg.connection();
- setConfigValue(connectionKey, rp.remoteChannel);
- createAndScheduleRun(rp, kit);
-}
+ setConfigValue(connectionKey, dlg.connection());
-void DebuggerPluginPrivate::attachToRemoteServer()
-{
- DebuggerRunParameters rp;
- Kit *kit;
- rp.startMode = AttachToRemoteServer;
- rp.useContinueInsteadOfRun = true;
- if (StartApplicationDialog::run(ICore::dialogParent(), &rp, &kit)) {
- rp.closeMode = KillAtClose;
- createAndScheduleRun(rp, kit);
- }
+ auto debugger = DebuggerRunTool::createFromKit(kit);
+ QTC_ASSERT(debugger, return);
+ debugger->setStartMode(AttachToRemoteServer);
+ debugger->setCloseMode(KillAtClose);
+ debugger->setRemoteChannel(dlg.connection());
+ debugger->startRunControl();
}
void DebuggerPluginPrivate::startRemoteServerAndAttachToProcess()
@@ -2089,9 +2076,11 @@ RunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
const Abi tcAbi = ToolChainKitInformation::targetAbi(kit);
const bool isWindows = (tcAbi.os() == Abi::WindowsOS);
if (isWindows && isWinProcessBeingDebugged(process.pid)) {
- AsynchronousMessageBox::warning(tr("Process Already Under Debugger Control"),
- tr("The process %1 is already under the control of a debugger.\n"
- "Qt Creator cannot attach to it.").arg(process.pid));
+ AsynchronousMessageBox::warning(
+ tr("Process Already Under Debugger Control"),
+ tr("The process %1 is already under the control of a debugger.\n"
+ "%2 cannot attach to it.").arg(process.pid)
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
return 0;
}
@@ -2101,32 +2090,37 @@ RunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
return 0;
}
- DebuggerRunParameters rp;
- rp.attachPID = ProcessHandle(process.pid);
- rp.displayName = tr("Process %1").arg(process.pid);
- rp.inferior.executable = process.exe;
- rp.startMode = AttachExternal;
- rp.closeMode = DetachAtClose;
- rp.continueAfterAttach = contAfterAttach;
- return createAndScheduleRun(rp, kit);
+ auto debugger = DebuggerRunTool::createFromKit(kit);
+ QTC_ASSERT(debugger, return nullptr);
+ debugger->setAttachPid(ProcessHandle(process.pid));
+ debugger->setRunControlName(tr("Process %1").arg(process.pid));
+ debugger->setInferiorExecutable(process.exe);
+ debugger->setStartMode(AttachExternal);
+ debugger->setCloseMode(DetachAtClose);
+ debugger->setContinueAfterAttach(contAfterAttach);
+
+ debugger->startRunControl();
+
+ return debugger->runControl();
}
void DebuggerPlugin::attachExternalApplication(RunControl *rc)
{
- DebuggerRunParameters rp;
- rp.attachPID = rc->applicationProcessHandle();
- rp.displayName = tr("Process %1").arg(rp.attachPID.pid());
- rp.startMode = AttachExternal;
- rp.closeMode = DetachAtClose;
- rp.toolChainAbi = rc->abi();
- rp.languages = CppLanguage;
+ DebuggerRunTool *debugger;
if (RunConfiguration *runConfig = rc->runConfiguration()) {
- auto runControl = new RunControl(runConfig, ProjectExplorer::Constants::DEBUG_RUN_MODE);
- (void) new DebuggerRunTool(runControl, rp);
- ProjectExplorerPlugin::startRunControl(runControl);
+ debugger = DebuggerRunTool::createFromRunConfiguration(runConfig);
} else {
- createAndScheduleRun(rp, guessKitFromParameters(rp));
+ Kit *kit = guessKitFromAbis({rc->abi()});
+ debugger = DebuggerRunTool::createFromKit(kit);
}
+ QTC_ASSERT(debugger, return);
+ ProcessHandle pid = rc->applicationProcessHandle();
+ debugger->setAttachPid(pid);
+ debugger->setRunControlName(tr("Process %1").arg(pid.pid()));
+ debugger->setStartMode(AttachExternal);
+ debugger->setCloseMode(DetachAtClose);
+ debugger->setToolChainAbi(rc->abi());
+ debugger->startRunControl();
}
void DebuggerPlugin::getEnginesState(QByteArray *json) const
@@ -2154,14 +2148,11 @@ void DebuggerPlugin::getEnginesState(QByteArray *json) const
void DebuggerPluginPrivate::attachToQmlPort()
{
- DebuggerRunParameters rp;
AttachToQmlPortDialog dlg(ICore::mainWindow());
const QVariant qmlServerPort = configValue("LastQmlServerPort");
if (qmlServerPort.isValid())
dlg.setPort(qmlServerPort.toInt());
- else if (rp.qmlServer.port.isValid())
- dlg.setPort(rp.qmlServer.port.number());
else
dlg.setPort(-1);
@@ -2178,35 +2169,20 @@ void DebuggerPluginPrivate::attachToQmlPort()
setConfigValue("LastProfile", kit->id().toSetting());
IDevice::ConstPtr device = DeviceKitInformation::device(kit);
- if (device) {
- QSsh::SshConnectionParameters sshParameters = device->sshParameters();
- rp.remoteChannel = QString("%1:%2").arg(sshParameters.host).arg(sshParameters.port);
- QUrl toolControl = device->toolControlChannel(IDevice::QmlControlChannel);
- rp.qmlServer.host = toolControl.host();
- }
- rp.qmlServer.port = Utils::Port(dlg.port());
- rp.startMode = AttachToRemoteProcess;
- rp.closeMode = KillAtClose;
- rp.languages = QmlLanguage;
- rp.masterEngineType = QmlEngineType;
+ QTC_ASSERT(device, return);
- //
- // get files from all the projects in the session
- //
- QList<Project *> projects = SessionManager::projects();
- if (Project *startupProject = SessionManager::startupProject()) {
- // startup project first
- projects.removeOne(startupProject);
- projects.insert(0, startupProject);
- }
- QStringList sourceFiles;
- foreach (Project *project, projects)
- sourceFiles << project->files(Project::SourceFiles);
+ auto debugger = DebuggerRunTool::createFromKit(kit);
+ QTC_ASSERT(debugger, return);
+
+ QUrl qmlServer = device->toolControlChannel(IDevice::QmlControlChannel);
+ qmlServer.setPort(dlg.port());
+ debugger->setQmlServer(qmlServer);
- rp.projectSourceDirectory =
- !projects.isEmpty() ? projects.first()->projectDirectory().toString() : QString();
- rp.projectSourceFiles = sourceFiles;
- createAndScheduleRun(rp, kit);
+ QSsh::SshConnectionParameters sshParameters = device->sshParameters();
+ debugger->setRemoteChannel(sshParameters.host, sshParameters.port);
+ debugger->setStartMode(AttachToQmlServer);
+
+ debugger->startRunControl();
}
void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &value)
@@ -2219,8 +2195,8 @@ void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &valu
void DebuggerPluginPrivate::runScheduled()
{
- for (const QPair<DebuggerRunParameters, Kit *> pair : m_scheduledStarts)
- createAndScheduleRun(pair.first, pair.second);
+ for (DebuggerRunTool *debugger : m_scheduledStarts)
+ debugger->startRunControl();
}
void DebuggerPluginPrivate::editorOpened(IEditor *editor)
@@ -2312,7 +2288,7 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
auto act = menu->addAction(args.address
? DebuggerEngine::tr("Run to Address 0x%1").arg(args.address, 0, 16)
: DebuggerEngine::tr("Run to Line %1").arg(args.lineNumber));
- connect(act, &QAction::triggered, [this, args] {
+ connect(act, &QAction::triggered, this, [args] {
DebuggerEngine *engine = currentEngine();
QTC_ASSERT(engine, return);
engine->executeRunToLine(args);
@@ -2322,7 +2298,7 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
auto act = menu->addAction(args.address
? DebuggerEngine::tr("Jump to Address 0x%1").arg(args.address, 0, 16)
: DebuggerEngine::tr("Jump to Line %1").arg(args.lineNumber));
- connect(act, &QAction::triggered, [this, args] {
+ connect(act, &QAction::triggered, this, [args] {
DebuggerEngine *engine = currentEngine();
QTC_ASSERT(engine, return);
engine->executeJumpToLine(args);
@@ -2337,7 +2313,7 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
const QString text = tr("Disassemble Function \"%1\"")
.arg(frame.function);
auto act = new QAction(text, menu);
- connect(act, &QAction::triggered, [this, frame] {
+ connect(act, &QAction::triggered, this, [frame] {
DebuggerEngine *engine = currentEngine();
QTC_ASSERT(engine, return);
engine->openDisassemblerView(Location(frame));
@@ -2902,18 +2878,16 @@ static void createNewDock(QWidget *widget)
dockWidget->show();
}
-static QString formatStartParameters(DebuggerRunParameters &sp)
+static QString formatStartParameters(const DebuggerRunParameters &sp)
{
QString rc;
QTextStream str(&rc);
str << "Start parameters: '" << sp.displayName << "' mode: " << sp.startMode
<< "\nABI: " << sp.toolChainAbi.toString() << '\n';
str << "Languages: ";
- if (sp.languages == AnyLanguage)
- str << "any ";
- if (sp.languages & CppLanguage)
+ if (sp.isCppDebugging)
str << "c++ ";
- if (sp.languages & QmlLanguage)
+ if (sp.isQmlDebugging)
str << "qml";
str << '\n';
if (!sp.inferior.executable.isEmpty()) {
@@ -2940,9 +2914,8 @@ static QString formatStartParameters(DebuggerRunParameters &sp)
}
if (!sp.remoteChannel.isEmpty())
str << "Remote: " << sp.remoteChannel << '\n';
- if (!sp.qmlServer.host.isEmpty())
- str << "QML server: " << sp.qmlServer.host << ':'
- << (sp.qmlServer.port.isValid() ? sp.qmlServer.port.number() : -1) << '\n';
+ if (!sp.qmlServer.host().isEmpty())
+ str << "QML server: " << sp.qmlServer.host() << ':' << sp.qmlServer.port() << '\n';
str << "Sysroot: " << sp.sysRoot << '\n';
str << "Debug Source Location: " << sp.debugSourceLocation.join(QLatin1Char(':')) << '\n';
return rc;
@@ -3386,17 +3359,19 @@ void DebuggerPluginPrivate::updateActiveLanguages()
{
if (!dd->m_currentRunTool)
return;
- const DebuggerLanguages languages = dd->m_currentRunTool->runParameters().languages;
+ const DebuggerRunParameters &rp = dd->m_currentRunTool->runParameters();
// Id perspective = (languages & QmlLanguage) && !(languages & CppLanguage)
// ? QmlPerspectiveId : CppPerspectiveId;
// m_mainWindow->restorePerspective(perspective);
- for (DebuggerLanguage language: {QmlLanguage, CppLanguage}) {
- const Context context = m_contextsForLanguage.value(language);
- if (languages & language)
- ICore::addAdditionalContext(context);
- else
- ICore::removeAdditionalContext(context);
- }
+ if (rp.isCppDebugging)
+ ICore::addAdditionalContext(Context(C_CPPDEBUGGER));
+ else
+ ICore::removeAdditionalContext(Context(C_CPPDEBUGGER));
+
+ if (rp.isQmlDebugging)
+ ICore::addAdditionalContext(Context(C_QMLDEBUGGER));
+ else
+ ICore::removeAdditionalContext(Context(C_QMLDEBUGGER));
}
void DebuggerPluginPrivate::onModeChanged(Id mode)
@@ -3666,25 +3641,21 @@ void DebuggerUnitTests::testStateMachine()
ProjectExplorerPlugin::buildProject(SessionManager::startupProject());
loop.exec();
- ExecuteOnDestruction guard([] () {
- EditorManager::closeAllEditors(false);
- });
- DebuggerRunParameters rp;
+ ExecuteOnDestruction guard([] { EditorManager::closeAllEditors(false); });
+
Target *t = SessionManager::startupProject()->activeTarget();
QVERIFY(t);
RunConfiguration *rc = t->activeRunConfiguration();
QVERIFY(rc);
- rp.inferior = rc->runnable().as<StandardRunnable>();
- rp.testCase = TestNoBoundsOfCurrentFunction;
- auto runControl = new RunControl(rc, ProjectExplorer::Constants::DEBUG_RUN_MODE);
- auto runTool = new DebuggerRunTool(runControl, rp);
+ auto debugger = DebuggerRunTool::createFromRunConfiguration(rc);
+ debugger->setInferior(rc->runnable().as<StandardRunnable>());
+ debugger->setTestCase(TestNoBoundsOfCurrentFunction);
- connect(runTool, &DebuggerRunTool::stopped, this, [this] {
- QTestEventLoop::instance().exitLoop();
- });
+ connect(debugger, &DebuggerRunTool::stopped,
+ &QTestEventLoop::instance(), &QTestEventLoop::exitLoop);
- ProjectExplorerPlugin::startRunControl(runControl);
+ debugger->startRunControl();
QTestEventLoop::instance().enterLoop(5);
}
diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp
index f2c7036557e..eeff836bc2f 100644
--- a/src/plugins/debugger/debuggerruncontrol.cpp
+++ b/src/plugins/debugger/debuggerruncontrol.cpp
@@ -33,7 +33,6 @@
#include "debuggerkitinformation.h"
#include "debuggerplugin.h"
#include "debuggerrunconfigurationaspect.h"
-#include "debuggerstartparameters.h"
#include "breakhandler.h"
#include "shared/peutils.h"
@@ -58,10 +57,13 @@
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
+#include <coreplugin/messagebox.h>
#include <qmldebug/qmldebugcommandlinearguments.h>
#include <qtsupport/qtkitinformation.h>
+#include <ssh/sshconnection.h>
+
#include <QTcpServer>
using namespace Debugger::Internal;
@@ -80,6 +82,97 @@ DebuggerEngine *createQmlEngine(bool useTerminal);
DebuggerEngine *createQmlCppEngine(DebuggerEngine *cppEngine, bool useTerminal);
DebuggerEngine *createLldbEngine();
+class LocalProcessRunner : public RunWorker
+{
+public:
+ LocalProcessRunner(RunControl *runControl, const StandardRunnable &runnable)
+ : RunWorker(runControl), m_runnable(runnable)
+ {
+ connect(&m_proc, &QProcess::errorOccurred,
+ this, &LocalProcessRunner::handleError);
+ connect(&m_proc, &QProcess::readyReadStandardOutput,
+ this, &LocalProcessRunner::handleStandardOutput);
+ connect(&m_proc, &QProcess::readyReadStandardError,
+ this, &LocalProcessRunner::handleStandardError);
+ connect(&m_proc, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
+ this, &LocalProcessRunner::handleFinished);
+ }
+
+ void start() override
+ {
+ m_proc.setCommand(m_runnable.executable, m_runnable.commandLineArguments);
+ m_proc.start();
+ }
+
+ void stop() override
+ {
+ m_proc.terminate();
+ }
+
+ void handleStandardOutput()
+ {
+ const QByteArray ba = m_proc.readAllStandardOutput();
+ const QString msg = QString::fromLocal8Bit(ba, ba.length());
+ showMessage(msg, LogOutput);
+ showMessage(msg, AppOutput);
+ }
+
+ void handleStandardError()
+ {
+ const QByteArray ba = m_proc.readAllStandardError();
+ const QString msg = QString::fromLocal8Bit(ba, ba.length());
+ showMessage(msg, LogOutput);
+ showMessage(msg, AppError);
+ }
+
+ void handleFinished()
+ {
+ if (m_proc.exitStatus() == QProcess::NormalExit && m_proc.exitCode() == 0) {
+ // all good.
+ reportDone();
+ } else {
+ reportFailure(tr("Upload failed: %1").arg(m_proc.errorString()));
+ }
+ }
+
+ void handleError(QProcess::ProcessError error)
+ {
+ QString msg;
+ switch (error) {
+ case QProcess::FailedToStart:
+ msg = tr("The upload process failed to start. Shell missing?");
+ break;
+ case QProcess::Crashed:
+ msg = tr("The upload process crashed some time after starting "
+ "successfully.");
+ break;
+ case QProcess::Timedout:
+ msg = tr("The last waitFor...() function timed out. "
+ "The state of QProcess is unchanged, and you can try calling "
+ "waitFor...() again.");
+ break;
+ case QProcess::WriteError:
+ msg = tr("An error occurred when attempting to write "
+ "to the upload process. For example, the process may not be running, "
+ "or it may have closed its input channel.");
+ break;
+ case QProcess::ReadError:
+ msg = tr("An error occurred when attempting to read from "
+ "the upload process. For example, the process may not be running.");
+ break;
+ default:
+ msg = tr("An unknown error in the upload process occurred. "
+ "This is the default return value of error().");
+ }
+
+ showMessage(msg, StatusBar);
+ Core::AsynchronousMessageBox::critical(tr("Error"), msg);
+ }
+
+ StandardRunnable m_runnable;
+ Utils::QtcProcess m_proc;
+};
+
} // namespace Internal
@@ -90,6 +183,240 @@ void DebuggerRunTool::setBreakOnMainNextTime()
breakOnMainNextTime = true;
}
+void DebuggerRunTool::setStartMode(DebuggerStartMode startMode)
+{
+ if (startMode == AttachToQmlServer) {
+ m_runParameters.startMode = AttachToRemoteProcess;
+ m_runParameters.isCppDebugging = false;
+ m_runParameters.isQmlDebugging = true;
+ m_runParameters.masterEngineType = QmlEngineType;
+ m_runParameters.closeMode = KillAtClose;
+
+ // FIXME: This is horribly wrong.
+ // get files from all the projects in the session
+ QList<Project *> projects = SessionManager::projects();
+ if (Project *startupProject = SessionManager::startupProject()) {
+ // startup project first
+ projects.removeOne(startupProject);
+ projects.insert(0, startupProject);
+ }
+ foreach (Project *project, projects)
+ m_runParameters.projectSourceFiles.append(project->files(Project::SourceFiles));
+ if (!projects.isEmpty())
+ m_runParameters.projectSourceDirectory = projects.first()->projectDirectory().toString();
+
+ } else {
+ m_runParameters.startMode = startMode;
+ }
+}
+
+void DebuggerRunTool::setCloseMode(DebuggerCloseMode closeMode)
+{
+ m_runParameters.closeMode = closeMode;
+}
+
+void DebuggerRunTool::setAttachPid(ProcessHandle pid)
+{
+ m_runParameters.attachPID = pid;
+}
+
+void DebuggerRunTool::setAttachPid(qint64 pid)
+{
+ m_runParameters.attachPID = ProcessHandle(pid);
+}
+
+void DebuggerRunTool::setSysRoot(const QString &sysRoot)
+{
+ m_runParameters.sysRoot = sysRoot;
+}
+
+void DebuggerRunTool::setSymbolFile(const QString &symbolFile)
+{
+ if (symbolFile.isEmpty())
+ reportFailure(tr("Cannot debug: Local executable is not set."));
+ m_runParameters.symbolFile = symbolFile;
+}
+
+void DebuggerRunTool::setRemoteChannel(const QString &channel)
+{
+ m_runParameters.remoteChannel = channel;
+}
+
+void DebuggerRunTool::setRemoteChannel(const QString &host, int port)
+{
+ m_runParameters.remoteChannel = QString("%1:%2").arg(host).arg(port);
+}
+
+void DebuggerRunTool::setUseExtendedRemote(bool on)
+{
+ m_runParameters.useExtendedRemote = on;
+}
+
+void DebuggerRunTool::setUseContinueInsteadOfRun(bool on)
+{
+ m_runParameters.useContinueInsteadOfRun = on;
+}
+
+void DebuggerRunTool::setUseTargetAsync(bool on)
+{
+ m_runParameters.useTargetAsync = on;
+}
+
+void DebuggerRunTool::setContinueAfterAttach(bool on)
+{
+ m_runParameters.continueAfterAttach = on;
+}
+
+void DebuggerRunTool::setSkipExecutableValidation(bool on)
+{
+ m_runParameters.skipExecutableValidation = on;
+}
+
+void DebuggerRunTool::setUseCtrlCStub(bool on)
+{
+ m_runParameters.useCtrlCStub = on;
+}
+
+void DebuggerRunTool::setBreakOnMain(bool on)
+{
+ m_runParameters.breakOnMain = on;
+}
+
+void DebuggerRunTool::setUseTerminal(bool on)
+{
+ m_runParameters.useTerminal = on;
+}
+
+void DebuggerRunTool::setCommandsAfterConnect(const QString &commands)
+{
+ m_runParameters.commandsAfterConnect = commands;
+}
+
+void DebuggerRunTool::setCommandsForReset(const QString &commands)
+{
+ m_runParameters.commandsForReset = commands;
+}
+
+void DebuggerRunTool::setServerStartScript(const QString &serverStartScript)
+{
+ if (!serverStartScript.isEmpty()) {
+ // Provide script information about the environment
+ StandardRunnable serverStarter;
+ serverStarter.executable = serverStartScript;
+ QtcProcess::addArg(&serverStarter.commandLineArguments, m_runParameters.inferior.executable);
+ QtcProcess::addArg(&serverStarter.commandLineArguments, m_runParameters.remoteChannel);
+ addStartDependency(new LocalProcessRunner(runControl(), serverStarter));
+ }
+}
+
+void DebuggerRunTool::setDebugInfoLocation(const QString &debugInfoLocation)
+{
+ m_runParameters.debugInfoLocation = debugInfoLocation;
+}
+
+void DebuggerRunTool::setQmlServer(const QUrl &qmlServer)
+{
+ m_runParameters.qmlServer = qmlServer;
+}
+
+void DebuggerRunTool::setIosPlatform(const QString &platform)
+{
+ m_runParameters.platform = platform;
+}
+
+void DebuggerRunTool::setDeviceSymbolsRoot(const QString &deviceSymbolsRoot)
+{
+ m_runParameters.deviceSymbolsRoot = deviceSymbolsRoot;
+}
+
+void DebuggerRunTool::setTestCase(int testCase)
+{
+ m_runParameters.testCase = testCase;
+}
+
+void DebuggerRunTool::setOverrideStartScript(const QString &script)
+{
+ m_runParameters.overrideStartScript = script;
+}
+
+void DebuggerRunTool::setToolChainAbi(const Abi &abi)
+{
+ m_runParameters.toolChainAbi = abi;
+}
+
+void DebuggerRunTool::setInferior(const Runnable &runnable)
+{
+ QTC_ASSERT(runnable.is<StandardRunnable>(), reportFailure(); return);
+ m_runParameters.inferior = runnable.as<StandardRunnable>();
+}
+
+void DebuggerRunTool::setInferiorExecutable(const QString &executable)
+{
+ m_runParameters.inferior.executable = executable;
+}
+
+void DebuggerRunTool::setRunControlName(const QString &name)
+{
+ m_runParameters.displayName = name;
+}
+
+void DebuggerRunTool::setStartMessage(const QString &msg)
+{
+ m_runParameters.startMessage = msg;
+}
+
+void DebuggerRunTool::setCoreFileName(const QString &coreFile, bool isSnapshot)
+{
+ m_runParameters.coreFile = coreFile;
+ m_runParameters.isSnapshot = isSnapshot;
+}
+
+void DebuggerRunTool::appendInferiorCommandLineArgument(const QString &arg)
+{
+ if (!m_runParameters.inferior.commandLineArguments.isEmpty())
+ m_runParameters.inferior.commandLineArguments.append(' ');
+ m_runParameters.inferior.commandLineArguments.append(arg);
+}
+
+void DebuggerRunTool::prependInferiorCommandLineArgument(const QString &arg)
+{
+ if (!m_runParameters.inferior.commandLineArguments.isEmpty())
+ m_runParameters.inferior.commandLineArguments.prepend(' ');
+ m_runParameters.inferior.commandLineArguments.prepend(arg);
+}
+
+void DebuggerRunTool::addQmlServerInferiorCommandLineArgumentIfNeeded()
+{
+ if (isQmlDebugging() && isCppDebugging()) {
+ using namespace QmlDebug;
+ int qmlServerPort = m_runParameters.qmlServer.port();
+ QTC_ASSERT(qmlServerPort > 0, reportFailure(); return);
+ QString mode = QString("port:%1").arg(qmlServerPort);
+ QString qmlServerArg = qmlDebugCommandLineArguments(QmlDebuggerServices, mode, true);
+ prependInferiorCommandLineArgument(qmlServerArg);
+ }
+}
+
+void DebuggerRunTool::setMasterEngineType(DebuggerEngineType engineType)
+{
+ m_runParameters.masterEngineType = engineType;
+}
+
+void DebuggerRunTool::setCrashParameter(const QString &event)
+{
+ m_runParameters.crashParameter = event;
+}
+
+void DebuggerRunTool::addExpectedSignal(const QString &signal)
+{
+ m_runParameters.expectedSignals.append(signal);
+}
+
+void DebuggerRunTool::addSearchDirectory(const QString &dir)
+{
+ m_runParameters.additionalSearchDirectories.append(dir);
+}
+
static QLatin1String engineTypeName(DebuggerEngineType et)
{
switch (et) {
@@ -120,23 +447,85 @@ void DebuggerRunTool::start()
TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO);
TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME);
- setupEngine();
- DebuggerEngine *engine = m_engine;
-
- QTC_ASSERT(engine, return);
- const DebuggerRunParameters &rp = engine->runParameters();
// User canceled input dialog asking for executable when working on library project.
- if (rp.startMode == StartInternal
- && rp.inferior.executable.isEmpty()
- && rp.interpreter.isEmpty()) {
- reportFailure(tr("No executable specified.") + '\n');
+ if (m_runParameters.startMode == StartInternal
+ && m_runParameters.inferior.executable.isEmpty()
+ && m_runParameters.interpreter.isEmpty()) {
+ reportFailure(tr("No executable specified."));
+ return;
+ }
+
+ // QML and/or mixed are not prepared for it.
+ setSupportsReRunning(!m_runParameters.isQmlDebugging);
+
+ // FIXME: Disabled due to Android. Make Android device report available ports instead.
+// int portsUsed = portsUsedByDebugger();
+// if (portsUsed > device()->freePorts().count()) {
+// reportFailure(tr("Cannot debug: Not enough free ports available."));
+// return;
+// }
+
+ if (!fixupParameters())
+ return;
+
+ Utils::globalMacroExpander()->registerFileVariables(
+ "DebuggedExecutable", tr("Debugged executable"),
+ [this] { return m_runParameters.inferior.executable; }
+ );
+
+ runControl()->setDisplayName(m_runParameters.displayName);
+
+ DebuggerEngine *cppEngine = nullptr;
+
+ switch (m_runParameters.cppEngineType) {
+ case GdbEngineType:
+ cppEngine = createGdbEngine(m_runParameters.useTerminal, m_runParameters.startMode);
+ break;
+ case CdbEngineType: {
+ QStringList errors;
+ cppEngine = createCdbEngine(&errors, m_runParameters.startMode);
+ if (!errors.isEmpty()) {
+ reportFailure(errors.join('\n'));
+ return;
+ }
+ }
+ break;
+ case LldbEngineType:
+ cppEngine = createLldbEngine();
+ break;
+ case PdbEngineType: // FIXME: Yes, Python counts as C++...
+ cppEngine = createPdbEngine();
+ break;
+ default:
+ QTC_CHECK(false);
+ break;
+ }
+
+ switch (m_runParameters.masterEngineType) {
+ case QmlEngineType:
+ m_engine = createQmlEngine(m_runParameters.useTerminal);
+ break;
+ case QmlCppEngineType:
+ if (cppEngine)
+ m_engine = createQmlCppEngine(cppEngine, m_runParameters.useTerminal);
+ break;
+ default:
+ m_engine = cppEngine;
+ break;
+ }
+
+ if (!m_engine) {
+ reportFailure(DebuggerPlugin::tr("Unable to create a debugging engine of the type \"%1\"").
+ arg(engineTypeName(m_runParameters.masterEngineType)));
return;
}
- if (rp.startMode == StartInternal) {
+ m_engine->setRunTool(this);
+
+ if (m_runParameters.startMode == StartInternal) {
QStringList unhandledIds;
foreach (Breakpoint bp, breakHandler()->allBreakpoints()) {
- if (bp.isEnabled() && !engine->acceptsBreakpoint(bp))
+ if (bp.isEnabled() && !m_engine->acceptsBreakpoint(bp))
unhandledIds.append(bp.id().toString());
}
if (!unhandledIds.isEmpty()) {
@@ -160,7 +549,7 @@ void DebuggerRunTool::start()
appendMessage(tr("Debugging starts"), NormalMessageFormat);
Internal::runControlStarted(this);
- engine->start();
+ m_engine->start();
}
void DebuggerRunTool::startFailed()
@@ -193,11 +582,26 @@ const DebuggerRunParameters &DebuggerRunTool::runParameters() const
return m_runParameters;
}
+bool DebuggerRunTool::isCppDebugging() const
+{
+ return m_runParameters.isCppDebugging;
+}
+
+bool DebuggerRunTool::isQmlDebugging() const
+{
+ return m_runParameters.isQmlDebugging;
+}
+
int DebuggerRunTool::portsUsedByDebugger() const
{
return isCppDebugging() + isQmlDebugging();
}
+void DebuggerRunTool::setSolibSearchPath(const QStringList &list)
+{
+ m_runParameters.solibSearchPath = list;
+}
+
void DebuggerRunTool::notifyInferiorIll()
{
m_engine->notifyInferiorIll();
@@ -219,191 +623,34 @@ void DebuggerRunTool::abortDebugger()
m_engine->abortDebugger();
}
-///////////////////////////////////////////////////////////////////////
-//
-// DebuggerRunControlCreator
-//
-///////////////////////////////////////////////////////////////////////
-
-namespace Internal {
-
-// Re-used for Combined C++/QML engine.
-DebuggerEngine *createEngine(DebuggerEngineType cppEngineType,
- DebuggerEngineType et,
- DebuggerStartMode sm,
- bool useTerminal,
- QStringList *errors)
+bool DebuggerRunTool::fixupParameters()
{
- DebuggerEngine *engine = nullptr;
- switch (et) {
- case GdbEngineType:
- engine = createGdbEngine(useTerminal, sm);
- break;
- case CdbEngineType:
- engine = createCdbEngine(errors, sm);
- break;
- case PdbEngineType:
- engine = createPdbEngine();
- break;
- case QmlEngineType:
- engine = createQmlEngine(useTerminal);
- break;
- case LldbEngineType:
- engine = createLldbEngine();
- break;
- case QmlCppEngineType: {
- DebuggerEngine *cppEngine = createEngine(cppEngineType, cppEngineType, sm, useTerminal, errors);
- if (cppEngine) {
- engine = createQmlCppEngine(cppEngine, useTerminal);
- } else {
- errors->append(DebuggerPlugin::tr("The debugging engine required for combined "
- "QML/C++ debugging could not be created: %1"));
- }
- break;
- }
- default:
- errors->append(DebuggerPlugin::tr("Unknown debugger type \"%1\"")
- .arg(engineTypeName(et)));
- }
- if (!engine)
- errors->append(DebuggerPlugin::tr("Unable to create a debugging engine of the type \"%1\"").
- arg(engineTypeName(et)));
- return engine;
-}
-
-static bool fixupParameters(DebuggerRunParameters &rp, RunControl *runControl, QStringList &m_errors)
-{
- RunConfiguration *runConfig = runControl->runConfiguration();
- if (!runConfig)
- return false;
-
- const Kit *kit = runConfig->target()->kit();
- QTC_ASSERT(kit, return false);
-
- // Extract as much as possible from available RunConfiguration.
- const Runnable runnable = runConfig->runnable();
- if (rp.needFixup && runnable.is<StandardRunnable>()) {
- // FIXME: Needed for core dump which stores the executable in inferior, but not in runConfig
- // executable.
- const QString prevExecutable = rp.inferior.executable;
- rp.inferior = runnable.as<StandardRunnable>();
- if (rp.inferior.executable.isEmpty())
- rp.inferior.executable = prevExecutable;
- rp.useTerminal = rp.inferior.runMode == ApplicationLauncher::Console;
- // Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...)
- rp.inferior.workingDirectory = FileUtils::normalizePathName(rp.inferior.workingDirectory);
- }
-
- // We might get an executable from a local PID.
- if (rp.needFixup && rp.inferior.executable.isEmpty() && rp.attachPID.isValid()) {
- foreach (const DeviceProcessItem &p, DeviceProcessList::localProcesses()) {
- if (p.pid == rp.attachPID.pid()) {
- rp.inferior.executable = p.exe;
- break;
- }
- }
- }
-
- rp.macroExpander = kit->macroExpander();
+ DebuggerRunParameters &rp = m_runParameters;
if (rp.symbolFile.isEmpty())
rp.symbolFile = rp.inferior.executable;
- rp.debugger = DebuggerKitInformation::runnable(kit);
- const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH");
- if (!envBinary.isEmpty())
- rp.debugger.executable = QString::fromLocal8Bit(envBinary);
-
- if (rp.needFixup) {
- if (auto envAspect = runConfig->extraAspect<EnvironmentAspect>()) {
- rp.inferior.environment = envAspect->environment(); // Correct.
- rp.stubEnvironment = rp.inferior.environment; // FIXME: Wrong, but contains DYLD_IMAGE_SUFFIX
+ rp.stubEnvironment = rp.inferior.environment; // FIXME: Wrong, but contains DYLD_IMAGE_SUFFIX
- // Copy over DYLD_IMAGE_SUFFIX etc
- for (auto var : QStringList({"DYLD_IMAGE_SUFFIX", "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH"}))
- if (rp.inferior.environment.hasKey(var))
- rp.debugger.environment.set(var, rp.inferior.environment.value(var));
- }
- }
- if (Project *project = runConfig->target()->project()) {
- rp.projectSourceDirectory = project->projectDirectory().toString();
- rp.projectSourceFiles = project->files(Project::SourceFiles);
- }
-
- rp.toolChainAbi = ToolChainKitInformation::targetAbi(kit);
-
- bool ok = false;
- int nativeMixedOverride = qgetenv("QTC_DEBUGGER_NATIVE_MIXED").toInt(&ok);
- if (ok)
- rp.nativeMixedEnabled = bool(nativeMixedOverride);
-
- rp.cppEngineType = DebuggerKitInformation::engineType(kit);
- if (rp.sysRoot.isEmpty())
- rp.sysRoot = SysRootKitInformation::sysRoot(kit).toString();
-
- if (rp.displayName.isEmpty())
- rp.displayName = runConfig->displayName();
-
- if (runConfig->property("supportsDebugger").toBool()) {
- QString mainScript = runConfig->property("mainScript").toString();
- QString interpreter = runConfig->property("interpreter").toString();
- if (!interpreter.isEmpty() && mainScript.endsWith(".py")) {
- rp.mainScript = mainScript;
- rp.interpreter = interpreter;
- QString args = runConfig->property("arguments").toString();
- if (!args.isEmpty()) {
- if (!rp.inferior.commandLineArguments.isEmpty())
- rp.inferior.commandLineArguments.append(QLatin1Char(' '));
- rp.inferior.commandLineArguments.append(args);
- }
- rp.masterEngineType = PdbEngineType;
- }
- }
-
- if (auto debuggerAspect = runConfig->extraAspect<DebuggerRunConfigurationAspect>()) {
- rp.multiProcess = debuggerAspect->useMultiProcess();
- if (rp.languages == NoLanguage) {
- if (debuggerAspect->useCppDebugger())
- rp.languages |= CppLanguage;
- if (debuggerAspect->useQmlDebugger())
- rp.languages |= QmlLanguage;
- }
- }
-
- // This can happen e.g. when started from the command line.
- if (rp.languages == NoLanguage)
- rp.languages = CppLanguage;
+ // Copy over DYLD_IMAGE_SUFFIX etc
+ for (auto var : QStringList({"DYLD_IMAGE_SUFFIX", "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH"}))
+ if (rp.inferior.environment.hasKey(var))
+ rp.debugger.environment.set(var, rp.inferior.environment.value(var));
// validate debugger if C++ debugging is enabled
- if (rp.languages & CppLanguage) {
- const QList<Task> tasks = DebuggerKitInformation::validateDebugger(kit);
- if (!tasks.isEmpty()) {
- foreach (const Task &t, tasks) {
- if (t.type == Task::Warning)
- continue;
- m_errors.append(t.description);
- }
- if (!m_errors.isEmpty())
- return false;
- }
+ if (rp.isCppDebugging && !rp.validationErrors.isEmpty()) {
+ reportFailure(rp.validationErrors.join('\n'));
+ return false;
}
- IDevice::ConstPtr device = runControl->device();
- if (rp.languages & QmlLanguage) {
- if (device && device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
- if (rp.qmlServer.host.isEmpty() || !rp.qmlServer.port.isValid()) {
- QTcpServer server;
- const bool canListen = server.listen(QHostAddress::LocalHost)
- || server.listen(QHostAddress::LocalHostIPv6);
- if (!canListen) {
- m_errors.append(DebuggerPlugin::tr("Not enough free ports for QML debugging.") + ' ');
+ if (rp.isQmlDebugging) {
+ if (device() && device()->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
+ if (rp.qmlServer.port() <= 0) {
+ rp.qmlServer = ProjectExplorer::urlFromLocalHostAndFreePort();
+ if (rp.qmlServer.port() <= 0) {
+ reportFailure(DebuggerPlugin::tr("Not enough free ports for QML debugging."));
return false;
}
- TcpServerConnection conn;
- conn.host = server.serverAddress().toString();
- conn.port = Utils::Port(server.serverPort());
- rp.qmlServer = conn;
}
-
// Makes sure that all bindings go through the JavaScript engine, so that
// breakpoints are actually hit!
const QString optimizerKey = "QML_DISABLE_OPTIMIZER";
@@ -425,9 +672,9 @@ static bool fixupParameters(DebuggerRunParameters &rp, RunControl *runControl, Q
}
if (rp.masterEngineType == NoEngineType) {
- if (rp.languages & QmlLanguage) {
+ if (rp.isQmlDebugging) {
QmlDebug::QmlDebugServicesPreset service;
- if (rp.languages & CppLanguage) {
+ if (rp.isCppDebugging) {
if (rp.nativeMixedEnabled) {
service = QmlDebug::QmlNativeDebuggerServices;
} else {
@@ -439,10 +686,10 @@ static bool fixupParameters(DebuggerRunParameters &rp, RunControl *runControl, Q
service = QmlDebug::QmlDebuggerServices;
}
if (rp.startMode != AttachExternal && rp.startMode != AttachCrashedExternal) {
- QtcProcess::addArg(&rp.inferior.commandLineArguments,
- (rp.languages & CppLanguage) && rp.nativeMixedEnabled ?
- QmlDebug::qmlDebugNativeArguments(service, false) :
- QmlDebug::qmlDebugTcpArguments(service, rp.qmlServer.port));
+ QString qmlarg = rp.isCppDebugging && rp.nativeMixedEnabled
+ ? QmlDebug::qmlDebugNativeArguments(service, false)
+ : QmlDebug::qmlDebugTcpArguments(service, Port(rp.qmlServer.port()));
+ QtcProcess::addArg(&rp.inferior.commandLineArguments, qmlarg);
}
}
}
@@ -458,36 +705,45 @@ static bool fixupParameters(DebuggerRunParameters &rp, RunControl *runControl, Q
breakOnMainNextTime = false;
}
- return true;
-}
+ if (HostOsInfo::isWindowsHost()) {
+ QtcProcess::SplitError perr;
+ rp.inferior.commandLineArguments =
+ QtcProcess::prepareArgs(rp.inferior.commandLineArguments, &perr,
+ HostOsInfo::hostOs(), nullptr,
+ &rp.inferior.workingDirectory).toWindowsArgs();
+ if (perr != QtcProcess::SplitOk) {
+ // perr == BadQuoting is never returned on Windows
+ // FIXME? QTCREATORBUG-2809
+ reportFailure(DebuggerPlugin::tr("Debugging complex command lines "
+ "is currently not supported on Windows."));
+ return false;
+ }
+ }
-} // Internal
+ // FIXME: We can't handle terminals yet.
+ if (rp.useTerminal && rp.cppEngineType == LldbEngineType) {
+ qWarning("Run in Terminal is not supported yet with the LLDB backend");
+ appendMessage(DebuggerPlugin::tr("Run in Terminal is not supported with the LLDB backend."),
+ ErrorMessageFormat);
+ rp.useTerminal = false;
+ }
-static DebuggerRunConfigurationAspect *debuggerAspect(const RunControl *runControl)
-{
- return runControl->runConfiguration()->extraAspect<DebuggerRunConfigurationAspect>();
-}
+ if (rp.isNativeMixedDebugging())
+ rp.inferior.environment.set("QV4_FORCE_INTERPRETER", "1");
-static bool cppDebugging(const RunControl *runControl)
-{
- auto aspect = debuggerAspect(runControl);
- return aspect ? aspect->useCppDebugger() : true; // For cases like valgrind-with-gdb.
-}
+ if (rp.isCppDebugging && !rp.skipExecutableValidation)
+ rp.validateExecutable();
-static bool qmlDebugging(const RunControl *runControl)
-{
- auto aspect = debuggerAspect(runControl);
- return aspect ? aspect->useQmlDebugger() : false; // For cases like valgrind-with-gdb.
+ return true;
}
-/// DebuggerRunTool
-
DebuggerRunTool::DebuggerRunTool(RunControl *runControl)
- : RunWorker(runControl),
- m_isCppDebugging(cppDebugging(runControl)),
- m_isQmlDebugging(qmlDebugging(runControl))
+ : RunWorker(runControl)
{
setDisplayName("DebuggerRunTool");
+
+ RunConfiguration *runConfig = runControl->runConfiguration();
+
runControl->setIcon(ProjectExplorer::Icons::DEBUG_START_SMALL_TOOLBAR);
runControl->setPromptToStop([](bool *optionalPrompt) {
return RunControl::showPromptToStopDialog(
@@ -498,70 +754,121 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl)
" Would you still like to terminate it?"),
QString(), QString(), optionalPrompt);
});
+
+ Runnable r = runnable();
+ if (r.is<StandardRunnable>()) {
+ m_runParameters.inferior = r.as<StandardRunnable>();
+ m_runParameters.useTerminal = m_runParameters.inferior.runMode == ApplicationLauncher::Console;
+ // Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...)
+ m_runParameters.inferior.workingDirectory =
+ FileUtils::normalizePathName(m_runParameters.inferior.workingDirectory);
+ }
+
+ if (auto aspect = runConfig ? runConfig->extraAspect<DebuggerRunConfigurationAspect>() : nullptr) {
+ m_runParameters.isCppDebugging = aspect->useCppDebugger();
+ m_runParameters.isQmlDebugging = aspect->useQmlDebugger();
+ m_runParameters.multiProcess = aspect->useMultiProcess();
+ }
+
+ if (runConfig)
+ m_runParameters.displayName = runConfig->displayName();
+
+ const Kit *kit = runConfig->target()->kit();
+ QTC_ASSERT(kit, return);
+
+ m_runParameters.macroExpander = kit->macroExpander();
+
+ m_runParameters.debugger = DebuggerKitInformation::runnable(kit);
+ const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH");
+ if (!envBinary.isEmpty())
+ m_runParameters.debugger.executable = QString::fromLocal8Bit(envBinary);
+
+ Project *project = runConfig ? runConfig->target()->project() : nullptr;
+ if (project) {
+ m_runParameters.projectSourceDirectory = project->projectDirectory().toString();
+ m_runParameters.projectSourceFiles = project->files(Project::SourceFiles);
+ }
+
+ m_runParameters.toolChainAbi = ToolChainKitInformation::targetAbi(kit);
+
+ bool ok = false;
+ int nativeMixedOverride = qgetenv("QTC_DEBUGGER_NATIVE_MIXED").toInt(&ok);
+ if (ok)
+ m_runParameters.nativeMixedEnabled = bool(nativeMixedOverride);
+
+ m_runParameters.cppEngineType = DebuggerKitInformation::engineType(kit);
+ m_runParameters.sysRoot = SysRootKitInformation::sysRoot(kit).toString();
+
+ // This will only be shown in some cases, but we don't want to access
+ // the kit at that time anymore.
+ const QList<Task> tasks = DebuggerKitInformation::validateDebugger(kit);
+ for (const Task &t : tasks) {
+ if (t.type != Task::Warning)
+ m_runParameters.validationErrors.append(t.description);
+ }
+
+ if (runConfig->property("supportsDebugger").toBool()) {
+ const QString mainScript = runConfig->property("mainScript").toString();
+ const QString interpreter = runConfig->property("interpreter").toString();
+ if (!interpreter.isEmpty() && mainScript.endsWith(".py")) {
+ m_runParameters.mainScript = mainScript;
+ m_runParameters.interpreter = interpreter;
+ const QString args = runConfig->property("arguments").toString();
+ if (!args.isEmpty()) {
+ if (!m_runParameters.inferior.commandLineArguments.isEmpty())
+ m_runParameters.inferior.commandLineArguments.append(' ');
+ m_runParameters.inferior.commandLineArguments.append(args);
+ }
+ m_runParameters.masterEngineType = PdbEngineType;
+ }
+ }
}
-DebuggerRunTool::DebuggerRunTool(RunControl *runControl, const DebuggerStartParameters &sp)
- : DebuggerRunTool(runControl)
+DebuggerEngine *DebuggerRunTool::activeEngine() const
{
- setStartParameters(sp);
+ return m_engine ? m_engine->activeEngine() : nullptr;
}
-DebuggerRunTool::DebuggerRunTool(RunControl *runControl, const DebuggerRunParameters &rp)
- : DebuggerRunTool(runControl)
+class DummyProject : public Project
{
- setRunParameters(rp);
-}
+public:
+ DummyProject() : Project(QString(""), FileName::fromString("")) {}
+};
-void DebuggerRunTool::setStartParameters(const DebuggerStartParameters &sp)
+RunConfiguration *dummyRunConfigForKit(ProjectExplorer::Kit *kit)
{
- setRunParameters(sp);
+ QTC_ASSERT(kit, return nullptr); // Caller needs to look for a suitable kit.
+ Project *project = SessionManager::startupProject();
+ Target *target = project ? project->target(kit) : nullptr;
+ if (!target || !target->activeRunConfiguration()) {
+ project = new DummyProject; // FIXME: Leaks.
+ target = project->createTarget(kit);
+ }
+ QTC_ASSERT(target, return nullptr);
+ auto runConfig = target->activeRunConfiguration();
+ return runConfig;
}
-void DebuggerRunTool::setRunParameters(const DebuggerRunParameters &rp)
+DebuggerRunTool *DebuggerRunTool::createFromKit(Kit *kit)
{
- m_runParameters = rp;
+ RunConfiguration *runConfig = dummyRunConfigForKit(kit);
+ return createFromRunConfiguration(runConfig);
}
-void DebuggerRunTool::setupEngine()
+void DebuggerRunTool::startRunControl()
{
- // QML and/or mixed are not prepared for it.
- setSupportsReRunning(!(m_runParameters.languages & QmlLanguage));
-
- // FIXME: Disabled due to Android. Make Android device report available ports instead.
-// int portsUsed = portsUsedByDebugger();
-// if (portsUsed > device()->freePorts().count()) {
-// reportFailure(tr("Cannot debug: Not enough free ports available."));
-// return;
-// }
-
- if (Internal::fixupParameters(m_runParameters, runControl(), m_errors)) {
- m_engine = createEngine(m_runParameters.cppEngineType,
- m_runParameters.masterEngineType,
- m_runParameters.startMode,
- m_runParameters.useTerminal,
- &m_errors);
- if (!m_engine) {
- reportFailure(m_errors.join('\n'));
- return;
- }
-
- Utils::globalMacroExpander()->registerFileVariables(
- "DebuggedExecutable", tr("Debugged executable"),
- [this] { return m_runParameters.inferior.executable; }
- );
- }
-
- runControl()->setDisplayName(m_runParameters.displayName);
-
- m_engine->setRunTool(this);
+ ProjectExplorerPlugin::startRunControl(runControl());
}
-DebuggerEngine *DebuggerRunTool::activeEngine() const
+DebuggerRunTool *DebuggerRunTool::createFromRunConfiguration(RunConfiguration *runConfig)
{
- return m_engine ? m_engine->activeEngine() : nullptr;
+ QTC_ASSERT(runConfig, return nullptr);
+ auto runControl = new RunControl(runConfig, ProjectExplorer::Constants::DEBUG_RUN_MODE);
+ auto debugger = new DebuggerRunTool(runControl);
+ return debugger;
}
-void DebuggerRunTool::appendSolibSearchPath(const QString &str)
+void DebuggerRunTool::addSolibSearchDir(const QString &str)
{
QString path = str;
path.replace("%{sysroot}", m_runParameters.sysRoot);
@@ -606,44 +913,6 @@ void DebuggerRunTool::showMessage(const QString &msg, int channel, int timeout)
//
////////////////////////////////////////////////////////////////////////
-namespace Internal {
-
-/**
- * Used for direct "special" starts from actions in the debugger plugin.
- */
-
-class DummyProject : public Project
-{
-public:
- DummyProject() : Project(QString(""), FileName::fromString("")) {}
-};
-
-RunConfiguration *dummyRunConfigForKit(ProjectExplorer::Kit *kit)
-{
- QTC_ASSERT(kit, return nullptr); // Caller needs to look for a suitable kit.
- Project *project = SessionManager::startupProject();
- Target *target = project ? project->target(kit) : nullptr;
- if (!target || !target->activeRunConfiguration()) {
- project = new DummyProject;
- target = project->createTarget(kit);
- }
- QTC_ASSERT(target, return nullptr);
- auto runConfig = target->activeRunConfiguration();
- return runConfig;
-}
-
-RunControl *createAndScheduleRun(const DebuggerRunParameters &rp, Kit *kit)
-{
- RunConfiguration *runConfig = dummyRunConfigForKit(kit);
- QTC_ASSERT(runConfig, return nullptr);
- auto runControl = new RunControl(runConfig, ProjectExplorer::Constants::DEBUG_RUN_MODE);
- (void) new DebuggerRunTool(runControl, rp);
- ProjectExplorerPlugin::startRunControl(runControl);
- return runControl;
-}
-
-} // Internal
-
// GdbServerPortGatherer
GdbServerPortsGatherer::GdbServerPortsGatherer(RunControl *runControl)
@@ -661,6 +930,19 @@ GdbServerPortsGatherer::~GdbServerPortsGatherer()
{
}
+QString GdbServerPortsGatherer::gdbServerChannel() const
+{
+ const QString host = device()->sshParameters().host;
+ return QString("%1:%2").arg(host).arg(m_gdbServerPort.number());
+}
+
+QUrl GdbServerPortsGatherer::qmlServer() const
+{
+ QUrl server = device()->toolControlChannel(IDevice::QmlControlChannel);
+ server.setPort(m_qmlServerPort.number());
+ return server;
+}
+
void GdbServerPortsGatherer::start()
{
appendMessage(tr("Checking available ports..."), NormalMessageFormat);
@@ -670,7 +952,7 @@ void GdbServerPortsGatherer::start()
void GdbServerPortsGatherer::handlePortListReady()
{
Utils::PortList portList = device()->freePorts();
- appendMessage(tr("Found %1 free ports").arg(portList.count()), NormalMessageFormat);
+ appendMessage(tr("Found %n free ports.", nullptr, portList.count()), NormalMessageFormat);
if (m_useGdbServer) {
m_gdbServerPort = m_portsGatherer.getNextFreePort(&portList);
if (!m_gdbServerPort.isValid()) {
@@ -685,7 +967,8 @@ void GdbServerPortsGatherer::handlePortListReady()
return;
}
}
- reportDone();
+// reportDone();
+ reportStarted();
}
// GdbServerRunner
diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h
index ec5dffaac0e..ff46db5059f 100644
--- a/src/plugins/debugger/debuggerruncontrol.h
+++ b/src/plugins/debugger/debuggerruncontrol.h
@@ -32,29 +32,26 @@
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
-namespace Debugger {
+#include <ssh/sshconnection.h> // FIXME: Remove after downstream was adapted
+#include <QHostAddress> // FIXME: Remove after downstream was adapted
-class DebuggerStartParameters;
+namespace Debugger {
class DEBUGGER_EXPORT DebuggerRunTool : public ProjectExplorer::RunWorker
{
Q_OBJECT
public:
- DebuggerRunTool(ProjectExplorer::RunControl *runControl); // Use.
-
- DebuggerRunTool(ProjectExplorer::RunControl *runControl,
- const DebuggerStartParameters &sp); // Use rarely.
- DebuggerRunTool(ProjectExplorer::RunControl *runControl,
- const Internal::DebuggerRunParameters &rp); // FIXME: Don't use.
+ explicit DebuggerRunTool(ProjectExplorer::RunControl *runControl);
~DebuggerRunTool();
- void setStartParameters(const DebuggerStartParameters &sp); // Use rarely.
- void setRunParameters(const Internal::DebuggerRunParameters &rp); // FIXME: Don't use.
-
Internal::DebuggerEngine *engine() const { return m_engine; }
Internal::DebuggerEngine *activeEngine() const;
+ static DebuggerRunTool *createFromRunConfiguration(ProjectExplorer::RunConfiguration *runConfig);
+ static DebuggerRunTool *createFromKit(ProjectExplorer::Kit *kit); // Avoid, it's guessing.
+ void startRunControl();
+
void showMessage(const QString &msg, int channel = LogDebug, int timeout = -1);
void start() override;
@@ -73,26 +70,76 @@ public:
void startDying() { m_isDying = true; }
bool isDying() const { return m_isDying; }
- bool isCppDebugging() const { return m_isCppDebugging; }
- bool isQmlDebugging() const { return m_isQmlDebugging; }
+ bool isCppDebugging() const;
+ bool isQmlDebugging() const;
int portsUsedByDebugger() const;
- void appendSolibSearchPath(const QString &str);
+ void setSolibSearchPath(const QStringList &list);
+ void addSolibSearchDir(const QString &str);
static void setBreakOnMainNextTime();
+ void setInferior(const ProjectExplorer::Runnable &runnable);
+ void setInferiorExecutable(const QString &executable);
+ void setRunControlName(const QString &name);
+ void setStartMessage(const QString &msg);
+ void appendInferiorCommandLineArgument(const QString &arg);
+ void prependInferiorCommandLineArgument(const QString &arg);
+ void addQmlServerInferiorCommandLineArgumentIfNeeded();
+
+ void setMasterEngineType(DebuggerEngineType engineType);
+ void setCrashParameter(const QString &event);
+
+ void addExpectedSignal(const QString &signal);
+ void addSearchDirectory(const QString &dir);
+
+ void setStartMode(DebuggerStartMode startMode);
+ void setCloseMode(DebuggerCloseMode closeMode);
+
+ void setAttachPid(Utils::ProcessHandle pid);
+ void setAttachPid(qint64 pid);
+
+ void setSysRoot(const QString &sysRoot);
+ void setSymbolFile(const QString &symbolFile);
+ void setRemoteChannel(const QString &channel);
+ void setRemoteChannel(const QString &host, int port);
+
+ void setUseExtendedRemote(bool on);
+ void setUseContinueInsteadOfRun(bool on);
+ void setUseTargetAsync(bool on);
+ void setContinueAfterAttach(bool on);
+ void setSkipExecutableValidation(bool on);
+ void setUseCtrlCStub(bool on);
+ void setBreakOnMain(bool on);
+ void setUseTerminal(bool on);
+
+ void setCommandsAfterConnect(const QString &commands);
+ void setCommandsForReset(const QString &commands);
+
+ void setServerStartScript(const QString &serverStartScript);
+ void setDebugInfoLocation(const QString &debugInfoLocation);
+
+ void setQmlServer(const QUrl &qmlServer);
+
+ void setCoreFileName(const QString &core, bool isSnapshot = false);
+
+ void setIosPlatform(const QString &platform);
+ void setDeviceSymbolsRoot(const QString &deviceSymbolsRoot);
+
+ void setNeedFixup(bool) {} // FIXME: Remove after use in QtAppMan is gone.
+ void setTestCase(int testCase);
+ void setOverrideStartScript(const QString &script);
+ void setToolChainAbi(const ProjectExplorer::Abi &abi);
+
signals:
void aboutToNotifyInferiorSetupOk();
private:
- void setupEngine();
+ bool fixupParameters();
QPointer<Internal::DebuggerEngine> m_engine; // Master engine
Internal::DebuggerRunParameters m_runParameters;
- QStringList m_errors;
bool m_isDying = false;
- const bool m_isCppDebugging;
- const bool m_isQmlDebugging;
};
class DEBUGGER_EXPORT GdbServerPortsGatherer : public ProjectExplorer::RunWorker
@@ -106,10 +153,12 @@ public:
void setUseGdbServer(bool useIt) { m_useGdbServer = useIt; }
bool useGdbServer() const { return m_useGdbServer; }
Utils::Port gdbServerPort() const { return m_gdbServerPort; }
+ QString gdbServerChannel() const;
void setUseQmlServer(bool useIt) { m_useQmlServer = useIt; }
bool useQmlServer() const { return m_useQmlServer; }
Utils::Port qmlServerPort() const { return m_qmlServerPort; }
+ QUrl qmlServer() const;
private:
void start() override;
diff --git a/src/plugins/debugger/debuggersourcepathmappingwidget.cpp b/src/plugins/debugger/debuggersourcepathmappingwidget.cpp
index 313cecefd79..f1a5e17d350 100644
--- a/src/plugins/debugger/debuggersourcepathmappingwidget.cpp
+++ b/src/plugins/debugger/debuggersourcepathmappingwidget.cpp
@@ -215,7 +215,7 @@ DebuggerSourcePathMappingWidget::DebuggerSourcePathMappingWidget(QWidget *parent
"at which the modules where built, for example, while "
"doing remote debugging.</p>"
"<p>If source is specified as a regular expression by starting it with an "
- "open parenthesis, Qt Creator matches the paths in the ELF with the "
+ "open parenthesis, the paths in the ELF are matched with the "
"regular expression to automatically determine the source path.</p>"
"<p>Example: <b>(/home/.*/Project)/KnownSubDir -> D:\\Project</b> will "
"substitute ELF built by any user to your local project directory.</p>"));
diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h
index db055341ce2..da1bca17234 100644
--- a/src/plugins/debugger/debuggerstartparameters.h
+++ b/src/plugins/debugger/debuggerstartparameters.h
@@ -1,112 +1,2 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-#pragma once
-
-#include "debugger_global.h"
-#include "debuggerconstants.h"
-
-#include <ssh/sshconnection.h>
-#include <utils/environment.h>
-#include <utils/port.h>
-#include <utils/processhandle.h>
-#include <projectexplorer/abi.h>
-#include <projectexplorer/runconfiguration.h>
-#include <projectexplorer/runnables.h>
-#include <projectexplorer/devicesupport/idevice.h>
-
-#include <QMetaType>
-#include <QVector>
-#include <QPointer>
-
-namespace Debugger {
-
-// Note: This is part of the "soft interface" of the debugger plugin.
-// Do not add anything that needs implementation in a .cpp file.
-
-class DEBUGGER_EXPORT TcpServerConnection
-{
-public:
- QString host;
- Utils::Port port;
-};
-
-class DEBUGGER_EXPORT DebuggerStartParameters
-{
-public:
- DebuggerStartMode startMode = NoStartMode;
- DebuggerCloseMode closeMode = KillAtClose;
-
- ProjectExplorer::StandardRunnable inferior;
- QString displayName; // Used in the Snapshots view.
- Utils::Environment stubEnvironment;
- Utils::ProcessHandle attachPID;
- QStringList solibSearchPath;
- bool useTerminal = false;
- bool needFixup = true; // FIXME: Make false the default...
-
- // Used by Qml debugging.
- TcpServerConnection qmlServer;
-
- // Used by general remote debugging.
- QString remoteChannel;
- bool useExtendedRemote = false; // Whether to use GDB's target extended-remote or not.
- QString symbolFile;
-
- // Used by Mer plugin (3rd party)
- QMap<QString, QString> sourcePathMap;
-
- // Used by baremetal plugin
- QString commandsForReset; // commands used for resetting the inferior
- bool useContinueInsteadOfRun = false; // if connected to a hw debugger run is not possible but continue is used
- QString commandsAfterConnect; // additional commands to post after connection to debug target
-
- // Used by Valgrind
- QStringList expectedSignals;
-
- // For QNX debugging
- bool useCtrlCStub = false;
-
- // Used by Android to avoid false positives on warnOnRelease
- bool skipExecutableValidation = false;
- bool useTargetAsync = false;
- QStringList additionalSearchDirectories;
-
- // Used by iOS.
- QString platform;
- QString deviceSymbolsRoot;
- bool continueAfterAttach = false;
- QString sysRoot;
-
- // Used by general core file debugging. Public access requested in QTCREATORBUG-17158.
- QString coreFile;
-
- // Macro-expanded and passed to debugger startup.
- QString additionalStartupCommands;
-};
-
-} // namespace Debugger
-
-Q_DECLARE_METATYPE(Debugger::DebuggerStartParameters)
+// Remove after downstream was adapted
diff --git a/src/plugins/debugger/disassembleragent.cpp b/src/plugins/debugger/disassembleragent.cpp
index 7e2b01b7bdd..6ed4255247b 100644
--- a/src/plugins/debugger/disassembleragent.cpp
+++ b/src/plugins/debugger/disassembleragent.cpp
@@ -30,7 +30,6 @@
#include "debuggercore.h"
#include "debuggerengine.h"
#include "debuggerinternalconstants.h"
-#include "debuggerstartparameters.h"
#include "disassemblerlines.h"
#include "sourceutils.h"
diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp
deleted file mode 100644
index 519647d7035..00000000000
--- a/src/plugins/debugger/gdb/attachgdbadapter.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "attachgdbadapter.h"
-
-#include <coreplugin/messagebox.h>
-
-#include <debugger/debuggerprotocol.h>
-#include <debugger/debuggerstartparameters.h>
-
-#include <utils/qtcassert.h>
-#include <utils/qtcfallthrough.h>
-
-namespace Debugger {
-namespace Internal {
-
-GdbAttachEngine::GdbAttachEngine(bool useTerminal)
- : GdbEngine(useTerminal)
-{
-}
-
-void GdbAttachEngine::setupEngine()
-{
- QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
- showMessage("TRYING TO START ADAPTER");
-
- startGdb();
-}
-
-void GdbAttachEngine::setupInferior()
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- // Task 254674 does not want to remove them
- //qq->breakHandler()->removeAllBreakpoints();
- handleInferiorPrepared();
-}
-
-void GdbAttachEngine::runEngine()
-{
- QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
- const qint64 pid = runParameters().attachPID.pid();
- showStatusMessage(tr("Attaching to process %1.").arg(pid));
- runCommand({"attach " + QString::number(pid),
- [this](const DebuggerResponse &r) { handleAttach(r); }});
- // In some cases we get only output like
- // "Could not attach to process. If your uid matches the uid of the target\n"
- // "process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try\n"
- // " again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf\n"
- // " ptrace: Operation not permitted.\n"
- // but no(!) ^ response. Use a second command to force *some* output
- runCommand({"print 24"});
-}
-
-void GdbAttachEngine::handleAttach(const DebuggerResponse &response)
-{
- QTC_ASSERT(state() == EngineRunRequested || state() == InferiorStopOk,
- qDebug() << state());
- switch (response.resultClass) {
- case ResultDone:
- case ResultRunning:
- showMessage("INFERIOR ATTACHED");
- if (state() == EngineRunRequested) {
- // Happens e.g. for "Attach to unstarted application"
- // We will get a '*stopped' later that we'll interpret as 'spontaneous'
- // So acknowledge the current state and put a delayed 'continue' in the pipe.
- showMessage(tr("Attached to running application"), StatusBar);
- notifyEngineRunAndInferiorRunOk();
- } else {
- // InferiorStopOk, e.g. for "Attach to running application".
- // The *stopped came in between sending the 'attach' and
- // receiving its '^done'.
- if (runParameters().continueAfterAttach)
- continueInferiorInternal();
- }
- break;
- case ResultError:
- if (response.data["msg"].data() == "ptrace: Operation not permitted.") {
- QString msg = msgPtraceError(runParameters().startMode);
- showStatusMessage(tr("Failed to attach to application: %1").arg(msg));
- Core::AsynchronousMessageBox::warning(tr("Debugger Error"), msg);
- notifyEngineIll();
- break;
- }
- Q_FALLTHROUGH(); // if msg != "ptrace: ..."
- default:
- showStatusMessage(tr("Failed to attach to application: %1")
- .arg(QString(response.data["msg"].data())));
- notifyEngineIll();
- }
-}
-
-void GdbAttachEngine::interruptInferior2()
-{
- interruptLocalInferior(runParameters().attachPID.pid());
-}
-
-void GdbAttachEngine::shutdownEngine()
-{
- notifyAdapterShutdownOk();
-}
-
-} // namespace Internal
-} // namespace Debugger
diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp
deleted file mode 100644
index df6d040ccdd..00000000000
--- a/src/plugins/debugger/gdb/coregdbadapter.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "coregdbadapter.h"
-
-#include <coreplugin/messagebox.h>
-
-#include <debugger/debuggercore.h>
-#include <debugger/debuggerprotocol.h>
-#include <debugger/debuggerstartparameters.h>
-
-#include <utils/fileutils.h>
-#include <utils/qtcassert.h>
-#include <utils/synchronousprocess.h>
-#include <utils/temporarydirectory.h>
-#include <utils/temporaryfile.h>
-
-#include <QDir>
-
-using namespace Utils;
-using namespace ProjectExplorer;
-
-namespace Debugger {
-namespace Internal {
-
-#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
-#define CHECK_STATE(s) do { checkState(s, __FILE__, __LINE__); } while (0)
-
-///////////////////////////////////////////////////////////////////////
-//
-// CoreGdbAdapter
-//
-///////////////////////////////////////////////////////////////////////
-
-GdbCoreEngine::GdbCoreEngine(bool useTerminal)
- : GdbEngine(useTerminal)
-{}
-
-GdbCoreEngine::~GdbCoreEngine()
-{
- if (m_coreUnpackProcess) {
- m_coreUnpackProcess->blockSignals(true);
- m_coreUnpackProcess->terminate();
- m_coreUnpackProcess->deleteLater();
- m_coreUnpackProcess = 0;
- if (m_tempCoreFile.isOpen())
- m_tempCoreFile.close();
- }
- if (!m_tempCoreName.isEmpty()) {
- QFile tmpFile(m_tempCoreName);
- tmpFile.remove();
- }
-}
-
-void GdbCoreEngine::setupEngine()
-{
- QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
- showMessage("TRYING TO START ADAPTER");
-
- const DebuggerRunParameters &rp = runParameters();
- m_executable = rp.inferior.executable;
- QFileInfo fi(rp.coreFile);
- m_coreName = fi.absoluteFilePath();
-
- unpackCoreIfNeeded();
-}
-
-static QString findExecutableFromName(const QString &fileNameFromCore, const QString &coreFile)
-{
- if (fileNameFromCore.isEmpty())
- return fileNameFromCore;
- QFileInfo fi(fileNameFromCore);
- if (fi.isFile())
- return fileNameFromCore;
-
- // turn the filename into an absolute path, using the location of the core as a hint
- QString absPath;
- if (fi.isAbsolute()) {
- absPath = fileNameFromCore;
- } else {
- QFileInfo coreInfo(coreFile);
- QDir coreDir = coreInfo.dir();
- absPath = FileUtils::resolvePath(coreDir.absolutePath(), fileNameFromCore);
- }
- if (QFileInfo(absPath).isFile() || absPath.isEmpty())
- return absPath;
-
- // remove possible trailing arguments
- QLatin1Char sep(' ');
- QStringList pathFragments = absPath.split(sep);
- while (pathFragments.size() > 0) {
- QString joined_path = pathFragments.join(sep);
- if (QFileInfo(joined_path).isFile()) {
- return joined_path;
- }
- pathFragments.pop_back();
- }
-
- return QString();
-}
-
-GdbCoreEngine::CoreInfo
-GdbCoreEngine::readExecutableNameFromCore(const StandardRunnable &debugger, const QString &coreFile)
-{
- CoreInfo cinfo;
-#if 0
- ElfReader reader(coreFile);
- cinfo.rawStringFromCore = QString::fromLocal8Bit(reader.readCoreName(&cinfo.isCore));
- cinfo.foundExecutableName = findExecutableFromName(cinfo.rawStringFromCore, coreFile);
-#else
- QStringList args;
- args.append(QLatin1String("-nx"));
- args.append(QLatin1String("-batch"));
- args.append(QLatin1String("-c"));
- args.append(coreFile);
-
- SynchronousProcess proc;
- QStringList envLang = QProcess::systemEnvironment();
- Utils::Environment::setupEnglishOutput(&envLang);
- proc.setEnvironment(envLang);
- SynchronousProcessResponse response = proc.runBlocking(debugger.executable, args);
-
- if (response.result == SynchronousProcessResponse::Finished) {
- QString output = response.stdOut();
- // Core was generated by `/data/dev/creator-2.6/bin/qtcreator'.
- // Program terminated with signal 11, Segmentation fault.
- int pos1 = output.indexOf("Core was generated by");
- if (pos1 != -1) {
- pos1 += 23;
- int pos2 = output.indexOf('\'', pos1);
- if (pos2 != -1) {
- cinfo.isCore = true;
- cinfo.rawStringFromCore = output.mid(pos1, pos2 - pos1);
- cinfo.foundExecutableName = findExecutableFromName(cinfo.rawStringFromCore, coreFile);
- }
- }
- }
-#endif
- return cinfo;
-}
-
-void GdbCoreEngine::continueSetupEngine()
-{
- bool isCore = true;
- if (m_coreUnpackProcess) {
- isCore = m_coreUnpackProcess->exitCode() == 0;
- m_coreUnpackProcess->deleteLater();
- m_coreUnpackProcess = 0;
- if (m_tempCoreFile.isOpen())
- m_tempCoreFile.close();
- }
- if (isCore && m_executable.isEmpty()) {
- GdbCoreEngine::CoreInfo cinfo =
- readExecutableNameFromCore(runParameters().debugger, coreFileName());
-
- if (cinfo.isCore) {
- m_executable = cinfo.foundExecutableName;
- if (m_executable.isEmpty()) {
- Core::AsynchronousMessageBox::warning(
- tr("Error Loading Symbols"),
- tr("No executable to load symbols from specified core."));
- notifyEngineSetupFailed();
- return;
- }
- }
- }
- if (isCore) {
- startGdb();
- } else {
- Core::AsynchronousMessageBox::warning(
- tr("Error Loading Core File"),
- tr("The specified file does not appear to be a core file."));
- notifyEngineSetupFailed();
- }
-}
-
-void GdbCoreEngine::writeCoreChunk()
-{
- m_tempCoreFile.write(m_coreUnpackProcess->readAll());
-}
-
-void GdbCoreEngine::setupInferior()
-{
- CHECK_STATE(InferiorSetupRequested);
- setLinuxOsAbi();
- // Do that first, otherwise no symbols are loaded.
- QFileInfo fi(m_executable);
- QString path = fi.absoluteFilePath();
- runCommand({"-file-exec-and-symbols \"" + path + '"',
- CB(handleFileExecAndSymbols)});
-}
-
-void GdbCoreEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
-{
- CHECK_STATE(InferiorSetupRequested);
- QString core = coreFileName();
- if (response.resultClass == ResultDone) {
- showMessage(tr("Symbols found."), StatusBar);
- handleInferiorPrepared();
- } else {
- QString msg = tr("No symbols found in core file <i>%1</i>.").arg(core)
- + ' ' + tr("This can be caused by a path length limitation "
- "in the core file.")
- + ' ' + tr("Try to specify the binary using the "
- "<i>Debug->Start Debugging->Attach to Core</i> dialog.");
- notifyInferiorSetupFailed(msg);
- }
-}
-
-void GdbCoreEngine::runEngine()
-{
- CHECK_STATE(EngineRunRequested);
- runCommand({"target core " + coreFileName(), CB(handleTargetCore)});
-}
-
-void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response)
-{
- CHECK_STATE(EngineRunRequested);
- notifyEngineRunOkAndInferiorUnrunnable();
- showMessage(tr("Attached to core."), StatusBar);
- if (response.resultClass == ResultError) {
- // We'll accept any kind of error e.g. &"Cannot access memory at address 0x2abc2a24\n"
- // Even without the stack, the user can find interesting stuff by exploring
- // the memory, globals etc.
- showStatusMessage(tr("Attach to core \"%1\" failed:").arg(runParameters().coreFile)
- + '\n' + response.data["msg"].data()
- + '\n' + tr("Continuing nevertheless."));
- }
- // Due to the auto-solib-add off setting, we don't have any
- // symbols yet. Load them in order of importance.
- reloadStack();
- reloadModulesInternal();
- runCommand({"p 5", CB(handleRoundTrip)});
-}
-
-void GdbCoreEngine::handleRoundTrip(const DebuggerResponse &response)
-{
- CHECK_STATE(InferiorUnrunnable);
- Q_UNUSED(response);
- loadSymbolsForStack();
- handleStop3();
- QTimer::singleShot(1000, this, &GdbEngine::loadAllSymbols);
-}
-
-void GdbCoreEngine::interruptInferior()
-{
- // A core never runs, so this cannot be called.
- QTC_CHECK(false);
-}
-
-void GdbCoreEngine::shutdownEngine()
-{
- notifyAdapterShutdownOk();
-}
-
-static QString tempCoreFilename()
-{
- Utils::TemporaryFile tmp("tmpcore-XXXXXX");
- tmp.open();
- return tmp.fileName();
-}
-
-void GdbCoreEngine::unpackCoreIfNeeded()
-{
- QStringList arguments;
- const QString msg = "Unpacking core file to %1";
- if (m_coreName.endsWith(QLatin1String(".lzo"))) {
- m_tempCoreName = tempCoreFilename();
- showMessage(msg.arg(m_tempCoreName));
- arguments << QLatin1String("-o") << m_tempCoreName << QLatin1String("-x") << m_coreName;
- m_coreUnpackProcess = new QProcess(this);
- m_coreUnpackProcess->setWorkingDirectory(Utils::TemporaryDirectory::masterDirectoryPath());
- m_coreUnpackProcess->start(QLatin1String("lzop"), arguments);
- connect(m_coreUnpackProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
- this, &GdbCoreEngine::continueSetupEngine);
- } else if (m_coreName.endsWith(QLatin1String(".gz"))) {
- m_tempCoreName = tempCoreFilename();
- showMessage(msg.arg(m_tempCoreName));
- m_tempCoreFile.setFileName(m_tempCoreName);
- m_tempCoreFile.open(QFile::WriteOnly);
- arguments << QLatin1String("-c") << QLatin1String("-d") << m_coreName;
- m_coreUnpackProcess = new QProcess(this);
- m_coreUnpackProcess->setWorkingDirectory(Utils::TemporaryDirectory::masterDirectoryPath());
- m_coreUnpackProcess->start(QLatin1String("gzip"), arguments);
- connect(m_coreUnpackProcess, &QProcess::readyRead, this, &GdbCoreEngine::writeCoreChunk);
- connect(m_coreUnpackProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
- this, &GdbCoreEngine::continueSetupEngine);
- } else {
- continueSetupEngine();
- }
-}
-
-QString GdbCoreEngine::coreFileName() const
-{
- return m_tempCoreName.isEmpty() ? m_coreName : m_tempCoreName;
-}
-
-} // namespace Internal
-} // namespace Debugger
diff --git a/src/plugins/debugger/gdb/coregdbadapter.h b/src/plugins/debugger/gdb/coregdbadapter.h
deleted file mode 100644
index b4b70814550..00000000000
--- a/src/plugins/debugger/gdb/coregdbadapter.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "gdbengine.h"
-
-#include <QFile>
-
-namespace Debugger {
-namespace Internal {
-
-class GdbCoreEngine : public GdbEngine
-{
- Q_OBJECT
-
-public:
- explicit GdbCoreEngine(bool useTerminal);
- ~GdbCoreEngine() override;
-
- struct CoreInfo
- {
- QString rawStringFromCore;
- QString foundExecutableName; // empty if no corresponding exec could be found
- bool isCore = false;
- };
- static CoreInfo readExecutableNameFromCore(const ProjectExplorer::StandardRunnable &debugger,
- const QString &coreFile);
-
-private:
- void setupEngine() override;
- void setupInferior() override;
- void runEngine() override;
- void interruptInferior() override;
- void shutdownEngine() override;
-
- void handleFileExecAndSymbols(const DebuggerResponse &response);
- void handleTargetCore(const DebuggerResponse &response);
- void handleRoundTrip(const DebuggerResponse &response);
- void unpackCoreIfNeeded();
- QString coreFileName() const;
- QString coreName() const;
-
- void continueSetupEngine();
- void writeCoreChunk();
-
-private:
- QString m_executable;
- QString m_coreName;
- QString m_tempCoreName;
- QProcess *m_coreUnpackProcess = nullptr;
- QFile m_tempCoreFile;
-};
-
-} // namespace Internal
-} // namespace Debugger
diff --git a/src/plugins/debugger/gdb/gdb.pri b/src/plugins/debugger/gdb/gdb.pri
index 3bed54bcc4a..4e0883fa034 100644
--- a/src/plugins/debugger/gdb/gdb.pri
+++ b/src/plugins/debugger/gdb/gdb.pri
@@ -1,18 +1,8 @@
HEADERS += \
$$PWD/gdbengine.h \
- $$PWD/attachgdbadapter.h \
- $$PWD/coregdbadapter.h \
- $$PWD/termgdbadapter.h \
- $$PWD/remotegdbserveradapter.h \
- $$PWD/gdbplainengine.h \
$$PWD/startgdbserverdialog.h
SOURCES += \
$$PWD/gdbengine.cpp \
$$PWD/gdboptionspage.cpp \
- $$PWD/attachgdbadapter.cpp \
- $$PWD/coregdbadapter.cpp \
- $$PWD/termgdbadapter.cpp \
- $$PWD/remotegdbserveradapter.cpp \
- $$PWD/gdbplainengine.cpp \
$$PWD/startgdbserverdialog.cpp
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index a49f469b875..ece1d1c87c4 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -25,13 +25,6 @@
#include "gdbengine.h"
-#include "attachgdbadapter.h"
-#include "coregdbadapter.h"
-#include "gdbplainengine.h"
-#include "termgdbadapter.h"
-#include "remotegdbserveradapter.h"
-
-#include <debugger/debuggerstartparameters.h>
#include <debugger/debuggerinternalconstants.h>
#include <debugger/debuggerruncontrol.h>
#include <debugger/disassemblerlines.h>
@@ -66,15 +59,17 @@
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/taskhub.h>
+#include <app/app_version.h>
#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
#include <utils/macroexpander.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/savedaction.h>
+#include <utils/synchronousprocess.h>
+#include <utils/temporarydirectory.h>
#include <utils/temporaryfile.h>
-#include <QBuffer>
#include <QDirIterator>
#include <QMessageBox>
#include <QProcess>
@@ -96,11 +91,6 @@ enum { debugPending = 0 };
#define CHECK_STATE(s) do { checkState(s, __FILE__, __LINE__); } while (0)
-QString GdbEngine::tooltipIName(const QString &exp)
-{
- return "tooltip." + toHex(exp);
-}
-
static bool stateAcceptsGdbCommands(DebuggerState state)
{
switch (state) {
@@ -204,27 +194,13 @@ private:
//
///////////////////////////////////////////////////////////////////////
-GdbEngine::GdbEngine(bool useTerminal)
+GdbEngine::GdbEngine(bool useTerminal, DebuggerStartMode startMode)
+ : m_startMode(startMode), m_useTerminal(useTerminal), m_terminalTrap(useTerminal)
{
setObjectName("GdbEngine");
- m_busy = false;
- m_gdbVersion = 100;
- m_pythonVersion = 0;
- m_isQnxGdb = false;
- m_registerNamesListed = false;
- m_sourcesListUpdating = false;
- m_oldestAcceptableToken = -1;
- m_nonDiscardableCount = 0;
m_gdbOutputCodec = QTextCodec::codecForLocale();
m_inferiorOutputCodec = QTextCodec::codecForLocale();
- m_pendingBreakpointRequests = 0;
- m_commandsDoneCallback = 0;
- m_stackNeeded = false;
- m_terminalTrap = useTerminal;
- m_systemDumpersLoaded = false;
- m_rerunPending = false;
- m_inUpdateLocals = false;
m_debugInfoTaskHandler = new DebugInfoTaskHandler(this);
//ExtensionSystem::PluginManager::addObject(m_debugInfoTaskHandler);
@@ -241,10 +217,45 @@ GdbEngine::GdbEngine(bool useTerminal)
this, &GdbEngine::reloadLocals);
connect(action(UseDynamicType), &SavedAction::valueChanged,
this, &GdbEngine::reloadLocals);
+
+ // Output
+ connect(&m_outputCollector, &OutputCollector::byteDelivery,
+ this, &GdbEngine::readDebuggeeOutput);
+
+ if (isTermEngine()) {
+ if (HostOsInfo::isWindowsHost()) {
+ // Windows up to xp needs a workaround for attaching to freshly started processes. see proc_stub_win
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
+ m_stubProc.setMode(ConsoleProcess::Suspend);
+ else
+ m_stubProc.setMode(ConsoleProcess::Debug);
+ } else {
+ m_stubProc.setMode(ConsoleProcess::Debug);
+ m_stubProc.setSettings(ICore::settings());
+ }
+ }
}
GdbEngine::~GdbEngine()
{
+ if (isTermEngine())
+ m_stubProc.disconnect(); // Avoid spurious state transitions from late exiting stub
+
+ if (isCoreEngine()) {
+ if (m_coreUnpackProcess) {
+ m_coreUnpackProcess->blockSignals(true);
+ m_coreUnpackProcess->terminate();
+ m_coreUnpackProcess->deleteLater();
+ m_coreUnpackProcess = nullptr;
+ if (m_tempCoreFile.isOpen())
+ m_tempCoreFile.close();
+ }
+ if (!m_tempCoreName.isEmpty()) {
+ QFile tmpFile(m_tempCoreName);
+ tmpFile.remove();
+ }
+ }
+
//ExtensionSystem::PluginManager::removeObject(m_debugInfoTaskHandler);
delete m_debugInfoTaskHandler;
m_debugInfoTaskHandler = 0;
@@ -253,35 +264,14 @@ GdbEngine::~GdbEngine()
disconnect();
}
-DebuggerStartMode GdbEngine::startMode() const
-{
- return runParameters().startMode;
-}
-
QString GdbEngine::failedToStartMessage()
{
return tr("The gdb process failed to start.");
}
-#if 0
-static void dump(const char *first, const char *middle, const QString & to)
-{
- QString ba(first, middle - first);
- Q_UNUSED(to)
- // note that qDebug cuts off output after a certain size... (bug?)
- qDebug("\n>>>>> %s\n%s\n====\n%s\n<<<<<\n",
- qPrintable(currentTime()),
- qPrintable(QString(ba).trimmed()),
- qPrintable(to.trimmed()));
- //qDebug() << "";
- //qDebug() << qPrintable(currentTime())
- // << " Reading response: " << QString(ba).trimmed() << "\n";
-}
-#endif
-
// Parse "~:gdb: unknown target exception 0xc0000139 at 0x77bef04e\n"
// and return an exception message
-static inline QString msgWinException(const QString &data, unsigned *exCodeIn = 0)
+static QString msgWinException(const QString &data, unsigned *exCodeIn = 0)
{
if (exCodeIn)
*exCodeIn = 0;
@@ -786,6 +776,9 @@ void GdbEngine::readGdbStandardOutput()
void GdbEngine::interruptInferior()
{
+ // A core never runs, so this cannot be called.
+ QTC_ASSERT(!isCoreEngine(), return);
+
CHECK_STATE(InferiorStopRequested);
if (terminal()->sendInterrupt())
@@ -798,33 +791,26 @@ void GdbEngine::interruptInferior()
showMessage("TRYING TO INTERRUPT INFERIOR");
if (HostOsInfo::isWindowsHost() && !m_isQnxGdb) {
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); notifyInferiorStopFailed());
- QTC_ASSERT(!m_signalOperation, notifyInferiorStopFailed());
- m_signalOperation = runTool()->device()->signalOperation();
- QTC_ASSERT(m_signalOperation, notifyInferiorStopFailed(); return);
- connect(m_signalOperation.data(), &DeviceProcessSignalOperation::finished,
- this, &GdbEngine::handleInterruptDeviceInferior);
-
- m_signalOperation->setDebuggerCommand(runParameters().debugger.executable);
- m_signalOperation->interruptProcess(inferiorPid());
+ DeviceProcessSignalOperation::Ptr signalOperation = runTool()->device()->signalOperation();
+ QTC_ASSERT(signalOperation, notifyInferiorStopFailed(); return);
+ connect(signalOperation.data(), &DeviceProcessSignalOperation::finished,
+ this, [this, signalOperation](const QString &error) {
+ if (error.isEmpty()) {
+ showMessage("Interrupted " + QString::number(inferiorPid()));
+ notifyInferiorStopOk();
+ } else {
+ showMessage(error, LogError);
+ notifyInferiorStopFailed();
+ }
+ });
+ signalOperation->setDebuggerCommand(runParameters().debugger.executable);
+ signalOperation->interruptProcess(inferiorPid());
} else {
interruptInferior2();
}
}
}
-void GdbEngine::handleInterruptDeviceInferior(const QString &error)
-{
- if (error.isEmpty()) {
- showMessage("Interrupted " + QString::number(inferiorPid()));
- notifyInferiorStopOk();
- } else {
- showMessage(error, LogError);
- notifyInferiorStopFailed();
- }
- m_signalOperation->disconnect(this);
- m_signalOperation.clear();
-}
-
void GdbEngine::runCommand(const DebuggerCommand &command)
{
const int token = ++currentToken();
@@ -1023,7 +1009,7 @@ void GdbEngine::handleResultRecord(DebuggerResponse *response)
//notifyInferiorIll();
//showStatusMessage(tr("Executable failed: %1").arg(msg));
//shutdown();
- //Core::AsynchronousMessageBox::critical(tr("Executable failed"), msg);
+ //AsynchronousMessageBox::critical(tr("Executable failed"), msg);
} else if (msg.contains("Cannot insert breakpoint")) {
// For breakpoints set by address to non-existent addresses we
// might get something like "6^error,msg="Warning:\nCannot insert
@@ -1643,8 +1629,9 @@ void GdbEngine::handlePythonSetup(const DebuggerResponse &response)
QString out = "<p>"
+ tr("The selected build of GDB supports Python scripting, "
"but the used version %1.%2 is not sufficient for "
- "Qt Creator. Supported versions are Python 2.7 and 3.x.")
- .arg(pythonMajor).arg(pythonMinor);
+ "%3. Supported versions are Python 2.7 and 3.x.")
+ .arg(pythonMajor).arg(pythonMinor)
+ .arg(Core::Constants::IDE_DISPLAY_NAME);
showStatusMessage(out);
AsynchronousMessageBox::critical(tr("Execution Error"), out);
}
@@ -1656,7 +1643,8 @@ void GdbEngine::handlePythonSetup(const DebuggerResponse &response)
QString msg = response.data["msg"].data();
if (msg.contains("Python scripting is not supported in this copy of GDB.")) {
QString out1 = "The selected build of GDB does not support Python scripting.";
- QString out2 = "It cannot be used in Qt Creator.";
+ QString out2 = QStringLiteral("It cannot be used in %1.")
+ .arg(Core::Constants::IDE_DISPLAY_NAME);
showStatusMessage(out1 + ' ' + out2);
AsynchronousMessageBox::critical(tr("Execution Error"), out1 + "<br>" + out2);
}
@@ -1866,7 +1854,7 @@ void GdbEngine::setLinuxOsAbi()
void GdbEngine::detachDebugger()
{
CHECK_STATE(InferiorStopOk);
- QTC_ASSERT(startMode() != AttachCore, qDebug() << startMode());
+ QTC_ASSERT(m_startMode != AttachCore, qDebug() << m_startMode);
DebuggerCommand cmd("detach", ExitRequest);
cmd.callback = [this](const DebuggerResponse &) {
CHECK_STATE(InferiorStopOk);
@@ -3298,9 +3286,6 @@ void GdbEngine::createSnapshot()
void GdbEngine::handleMakeSnapshot(const DebuggerResponse &response, const QString &coreFile)
{
if (response.resultClass == ResultDone) {
- DebuggerRunParameters rp = runParameters();
- rp.startMode = AttachCore;
- rp.coreFile = coreFile;
//snapshot.setDate(QDateTime::currentDateTime());
StackFrames frames = stackHandler()->frames();
QString function = "<unknown>";
@@ -3308,11 +3293,12 @@ void GdbEngine::handleMakeSnapshot(const DebuggerResponse &response, const QStri
const StackFrame &frame = frames.at(0);
function = frame.function + ":" + QString::number(frame.line);
}
- rp.displayName = function + ": " + QDateTime::currentDateTime().toString();
- rp.isSnapshot = true;
- auto rc = new RunControl(runControl()->runConfiguration(), ProjectExplorer::Constants::DEBUG_RUN_MODE);
- (void) new DebuggerRunTool(rc, rp);
- ProjectExplorerPlugin::startRunControl(rc);
+ auto debugger = DebuggerRunTool::createFromRunConfiguration(runControl()->runConfiguration());
+ QTC_ASSERT(debugger, return);
+ debugger->setStartMode(AttachCore);
+ debugger->setRunControlName(function + ": " + QDateTime::currentDateTime().toString());
+ debugger->setCoreFileName(coreFile, true);
+ debugger->startRunControl();
} else {
QString msg = response.data["msg"].data();
AsynchronousMessageBox::critical(tr("Snapshot Creation Error"),
@@ -3990,6 +3976,10 @@ void GdbEngine::startGdb(const QStringList &args)
void GdbEngine::handleGdbStartFailed()
{
+ if (isTermEngine())
+ m_stubProc.stop();
+ else if (isPlainEngine())
+ m_outputCollector.shutdown();
}
void GdbEngine::loadInitScript()
@@ -4003,7 +3993,7 @@ void GdbEngine::loadInitScript()
tr("Cannot find debugger initialization script"),
tr("The debugger settings point to a script file at \"%1\" "
"which is not accessible. If a script file is not needed, "
- "consider clearing that entry to avoid this warning. "
+ "consider clearing that entry to avoid this warning."
).arg(script));
}
} else {
@@ -4072,17 +4062,9 @@ void GdbEngine::handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus)
notifyDebuggerProcessFinished(exitCode, exitStatus, "GDB");
}
-void GdbEngine::abortDebugger()
+void GdbEngine::abortDebuggerProcess()
{
- if (isDying()) {
- // We already tried. Try harder.
- showMessage("ABORTING DEBUGGER. SECOND TIME.");
- m_gdbProc.kill();
- } else {
- // Be friendly the first time. This will change targetState().
- showMessage("ABORTING DEBUGGER. FIRST TIME.");
- quitDebugger();
- }
+ m_gdbProc.kill();
}
void GdbEngine::resetInferior()
@@ -4115,14 +4097,6 @@ void GdbEngine::handleAdapterStartFailed(const QString &msg, Id settingsIdHint)
notifyEngineSetupFailed();
}
-void GdbEngine::notifyInferiorSetupFailed()
-{
- // FIXME: that's not enough to stop gdb from getting confused
- // by a timeout of the adapter.
- //resetCommandQueue();
- DebuggerEngine::notifyInferiorSetupFailed();
-}
-
void GdbEngine::prepareForRestart()
{
m_rerunPending = false;
@@ -4200,7 +4174,7 @@ void GdbEngine::handleDebugInfoLocation(const DebuggerResponse &response)
}
}
-void GdbEngine::notifyInferiorSetupFailed(const QString &msg)
+void GdbEngine::notifyInferiorSetupFailedHelper(const QString &msg)
{
showStatusMessage(tr("Failed to start application:") + ' ' + msg);
if (state() == EngineSetupFailed) {
@@ -4209,7 +4183,7 @@ void GdbEngine::notifyInferiorSetupFailed(const QString &msg)
}
showMessage("INFERIOR START FAILED");
AsynchronousMessageBox::critical(tr("Failed to start application"), msg);
- DebuggerEngine::notifyInferiorSetupFailed();
+ notifyInferiorSetupFailed();
}
void GdbEngine::handleAdapterCrashed(const QString &msg)
@@ -4236,7 +4210,7 @@ void GdbEngine::handleAdapterCrashed(const QString &msg)
void GdbEngine::createFullBacktrace()
{
DebuggerCommand cmd("thread apply all bt full", NeedsTemporaryStop | ConsoleCommand);
- cmd.callback = [this](const DebuggerResponse &response) {
+ cmd.callback = [](const DebuggerResponse &response) {
if (response.resultClass == ResultDone) {
Internal::openTextEditor("Backtrace $",
response.consoleStreamOutput + response.logStreamOutput);
@@ -4320,7 +4294,7 @@ QString GdbEngine::msgConnectRemoteServerFailed(const QString &why)
void GdbEngine::interruptLocalInferior(qint64 pid)
{
- QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); return);
+ CHECK_STATE(InferiorStopRequested);
if (pid <= 0) {
showMessage("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED", LogError);
return;
@@ -4339,27 +4313,841 @@ void GdbEngine::debugLastCommand()
runCommand(m_lastDebuggableCommand);
}
-//
-// Factory
-//
+bool GdbEngine::isPlainEngine() const
+{
+ return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && !m_terminalTrap;
+}
+
+bool GdbEngine::isCoreEngine() const
+{
+ return m_startMode == AttachCore;
+}
+
+bool GdbEngine::isRemoteEngine() const
+{
+ return m_startMode == StartRemoteProcess || m_startMode == AttachToRemoteServer;
+}
+
+bool GdbEngine::isAttachEngine() const
+{
+ return m_startMode == AttachExternal;
+}
+
+bool GdbEngine::isTermEngine() const
+{
+ return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && m_terminalTrap;
+}
+
+void GdbEngine::setupEngine()
+{
+ CHECK_STATE(EngineSetupRequested);
+ showMessage("TRYING TO START ADAPTER");
+
+ if (isAttachEngine()) {
+
+ startGdb();
+
+ } else if (isRemoteEngine()) {
+
+ if (HostOsInfo::isWindowsHost())
+ m_gdbProc.setUseCtrlCStub(runParameters().useCtrlCStub); // This is only set for QNX
+
+ startGdb();
+
+ } else if (isTermEngine()) {
+
+ showMessage("TRYING TO START ADAPTER");
+
+ // Currently, GdbEngines are not re-used
+ // // We leave the console open, so recycle it now.
+ // m_stubProc.blockSignals(true);
+ // m_stubProc.stop();
+ // m_stubProc.blockSignals(false);
+
+ m_stubProc.setWorkingDirectory(runParameters().inferior.workingDirectory);
+ // Set environment + dumper preload.
+ m_stubProc.setEnvironment(runParameters().stubEnvironment);
+
+ connect(&m_stubProc, &ConsoleProcess::processError,
+ this, &GdbEngine::stubError);
+ connect(&m_stubProc, &ConsoleProcess::processStarted,
+ this, [this] { startGdb(); });
+ connect(&m_stubProc, &ConsoleProcess::stubStopped,
+ this, &GdbEngine::stubExited);
+ // FIXME: Starting the stub implies starting the inferior. This is
+ // fairly unclean as far as the state machine and error reporting go.
+
+ if (!m_stubProc.start(runParameters().inferior.executable,
+ runParameters().inferior.commandLineArguments)) {
+ // Error message for user is delivered via a signal.
+ handleAdapterStartFailed(QString());
+ }
+
+ } else if (isCoreEngine()) {
+
+ CHECK_STATE(EngineSetupRequested);
+ showMessage("TRYING TO START ADAPTER");
+
+ const DebuggerRunParameters &rp = runParameters();
+ m_executable = rp.inferior.executable;
+ QFileInfo fi(rp.coreFile);
+ m_coreName = fi.absoluteFilePath();
+
+ unpackCoreIfNeeded();
+
+ } else if (isPlainEngine()) {
+
+ QStringList gdbArgs;
+
+ if (!m_outputCollector.listen()) {
+ handleAdapterStartFailed(tr("Cannot set up communication with child process: %1")
+ .arg(m_outputCollector.errorString()));
+ return;
+ }
+ gdbArgs.append("--tty=" + m_outputCollector.serverName());
+
+ startGdb(gdbArgs);
+ }
+}
+
+void GdbEngine::setupInferior()
+{
+ CHECK_STATE(InferiorSetupRequested);
+
+ if (isAttachEngine()) {
+ // Task 254674 does not want to remove them
+ //qq->breakHandler()->removeAllBreakpoints();
+ handleInferiorPrepared();
+
+ } else if (isRemoteEngine()) {
+
+ setLinuxOsAbi();
+ const DebuggerRunParameters &rp = runParameters();
+ QString symbolFile;
+ if (!rp.symbolFile.isEmpty()) {
+ QFileInfo fi(rp.symbolFile);
+ symbolFile = fi.absoluteFilePath();
+ }
+
+ //const QByteArray sysroot = sp.sysroot.toLocal8Bit();
+ //const QByteArray remoteArch = sp.remoteArchitecture.toLatin1();
+ const QString args = runParameters().inferior.commandLineArguments;
+
+ // if (!remoteArch.isEmpty())
+ // postCommand("set architecture " + remoteArch);
+ if (!rp.solibSearchPath.isEmpty()) {
+ DebuggerCommand cmd("appendSolibSearchPath");
+ cmd.arg("path", rp.solibSearchPath);
+ cmd.arg("separator", HostOsInfo::pathListSeparator());
+ runCommand(cmd);
+ }
+
+ if (!args.isEmpty())
+ runCommand({"-exec-arguments " + args});
+
+ setEnvironmentVariables();
+
+ // This has to be issued before 'target remote'. On pre-7.0 the
+ // command is not present and will result in ' No symbol table is
+ // loaded. Use the "file" command.' as gdb tries to set the
+ // value of a variable with name 'target-async'.
+ //
+ // Testing with -list-target-features which was introduced at
+ // the same time would not work either, as this need an existing
+ // target.
+ //
+ // Using it even without a target and having it fail might still
+ // be better as:
+ // Some external comment: '[but] "set target-async on" with a native
+ // windows gdb will work, but then fail when you actually do
+ // "run"/"attach", I think..
+
+
+ // gdb/mi/mi-main.c:1958: internal-error:
+ // mi_execute_async_cli_command: Assertion `is_running (inferior_ptid)'
+ // failed.\nA problem internal to GDB has been detected,[...]
+ if (usesTargetAsync())
+ runCommand({"set target-async on", CB(handleSetTargetAsync)});
+
+ if (symbolFile.isEmpty()) {
+ showMessage(tr("No symbol file given."), StatusBar);
+ callTargetRemote();
+ return;
+ }
+
+ if (!symbolFile.isEmpty()) {
+ runCommand({"-file-exec-and-symbols \"" + symbolFile + '"',
+ CB(handleFileExecAndSymbols)});
+ }
+
+ } else if (isCoreEngine()) {
+
+ setLinuxOsAbi();
+ // Do that first, otherwise no symbols are loaded.
+ QFileInfo fi(m_executable);
+ QString path = fi.absoluteFilePath();
+ runCommand({"-file-exec-and-symbols \"" + path + '"',
+ CB(handleFileExecAndSymbols)});
+
+ } else if (isTermEngine()) {
+
+ const qint64 attachedPID = m_stubProc.applicationPID();
+ const qint64 attachedMainThreadID = m_stubProc.applicationMainThreadID();
+ notifyInferiorPid(ProcessHandle(attachedPID));
+ const QString msg = (attachedMainThreadID != -1)
+ ? QString("Going to attach to %1 (%2)").arg(attachedPID).arg(attachedMainThreadID)
+ : QString("Going to attach to %1").arg(attachedPID);
+ showMessage(msg, LogMisc);
+ handleInferiorPrepared();
+
+ } else if (isPlainEngine()) {
+
+ setEnvironmentVariables();
+ const DebuggerRunParameters &rp = runParameters();
+ if (!rp.inferior.workingDirectory.isEmpty())
+ runCommand({"cd " + rp.inferior.workingDirectory});
+ if (!rp.inferior.commandLineArguments.isEmpty()) {
+ QString args = rp.inferior.commandLineArguments;
+ runCommand({"-exec-arguments " + args});
+ }
+
+ QString executable = QFileInfo(runParameters().inferior.executable).absoluteFilePath();
+ runCommand({"-file-exec-and-symbols \"" + executable + '"',
+ CB(handleFileExecAndSymbols)});
+ }
+}
+
+void GdbEngine::runEngine()
+{
+ CHECK_STATE(EngineRunRequested);
+
+ if (isAttachEngine()) {
+
+ const qint64 pid = runParameters().attachPID.pid();
+ showStatusMessage(tr("Attaching to process %1.").arg(pid));
+ runCommand({"attach " + QString::number(pid),
+ [this](const DebuggerResponse &r) { handleAttach(r); }});
+ // In some cases we get only output like
+ // "Could not attach to process. If your uid matches the uid of the target\n"
+ // "process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try\n"
+ // " again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf\n"
+ // " ptrace: Operation not permitted.\n"
+ // but no(!) ^ response. Use a second command to force *some* output
+ runCommand({"print 24"});
+
+ } else if (isRemoteEngine()) {
+
+ if (runParameters().useContinueInsteadOfRun) {
+ notifyEngineRunAndInferiorStopOk();
+ continueInferiorInternal();
+ } else {
+ runCommand({"-exec-run", DebuggerCommand::RunRequest, CB(handleExecRun)});
+ }
+
+ } else if (isCoreEngine()) {
+
+ runCommand({"target core " + coreFileName(), CB(handleTargetCore)});
+
+ } else if (isTermEngine()) {
+
+ const qint64 attachedPID = m_stubProc.applicationPID();
+ runCommand({"attach " + QString::number(attachedPID),
+ [this](const DebuggerResponse &r) { handleStubAttached(r); }});
+
+ } else if (isPlainEngine()) {
+
+ if (runParameters().useContinueInsteadOfRun)
+ runCommand({"-exec-continue", DebuggerCommand::RunRequest, CB(handleExecuteContinue)});
+ else
+ runCommand({"-exec-run", DebuggerCommand::RunRequest, CB(handleExecRun)});
+
+ }
+}
+
+void GdbEngine::handleAttach(const DebuggerResponse &response)
+{
+ if (isAttachEngine()) {
+
+ QTC_ASSERT(state() == EngineRunRequested || state() == InferiorStopOk, qDebug() << state());
+ switch (response.resultClass) {
+ case ResultDone:
+ case ResultRunning:
+ showMessage("INFERIOR ATTACHED");
+ if (state() == EngineRunRequested) {
+ // Happens e.g. for "Attach to unstarted application"
+ // We will get a '*stopped' later that we'll interpret as 'spontaneous'
+ // So acknowledge the current state and put a delayed 'continue' in the pipe.
+ showMessage(tr("Attached to running application"), StatusBar);
+ notifyEngineRunAndInferiorRunOk();
+ } else {
+ // InferiorStopOk, e.g. for "Attach to running application".
+ // The *stopped came in between sending the 'attach' and
+ // receiving its '^done'.
+ if (runParameters().continueAfterAttach)
+ continueInferiorInternal();
+ }
+ break;
+ case ResultError:
+ if (response.data["msg"].data() == "ptrace: Operation not permitted.") {
+ QString msg = msgPtraceError(runParameters().startMode);
+ showStatusMessage(tr("Failed to attach to application: %1").arg(msg));
+ AsynchronousMessageBox::warning(tr("Debugger Error"), msg);
+ notifyEngineIll();
+ break;
+ }
+ showStatusMessage(tr("Failed to attach to application: %1")
+ .arg(QString(response.data["msg"].data())));
+ notifyEngineIll();
+ break;
+ default:
+ showStatusMessage(tr("Failed to attach to application: %1")
+ .arg(QString(response.data["msg"].data())));
+ notifyEngineIll();
+ break;
+ }
+
+ } else if (isRemoteEngine()) {
+
+ CHECK_STATE(InferiorSetupRequested);
+ switch (response.resultClass) {
+ case ResultDone:
+ case ResultRunning: {
+ showMessage("INFERIOR ATTACHED");
+ showMessage(msgAttachedToStoppedInferior(), StatusBar);
+ handleInferiorPrepared();
+ break;
+ }
+ case ResultError:
+ if (response.data["msg"].data() == "ptrace: Operation not permitted.") {
+ notifyInferiorSetupFailedHelper(msgPtraceError(runParameters().startMode));
+ break;
+ }
+ notifyInferiorSetupFailedHelper(response.data["msg"].data());
+ break;
+ default:
+ notifyInferiorSetupFailedHelper(response.data["msg"].data());
+ break;
+ }
+
+ }
+}
+
+void GdbEngine::interruptInferior2()
+{
+ if (isAttachEngine()) {
+
+ interruptLocalInferior(runParameters().attachPID.pid());
+
+ } else if (isRemoteEngine()) {
+
+ CHECK_STATE(InferiorStopRequested);
+ if (usesTargetAsync()) {
+ runCommand({"-exec-interrupt", CB(handleInterruptInferior)});
+ } else if (m_isQnxGdb && HostOsInfo::isWindowsHost()) {
+ m_gdbProc.interrupt();
+ } else {
+ qint64 pid = m_gdbProc.processId();
+ bool ok = interruptProcess(pid, GdbEngineType, &m_errorString);
+ if (!ok) {
+ // FIXME: Extra state needed?
+ showMessage("NOTE: INFERIOR STOP NOT POSSIBLE");
+ showStatusMessage(tr("Interrupting not possible"));
+ notifyInferiorRunOk();
+ }
+ }
+
+ } else if (isTermEngine() || isPlainEngine()) {
+
+ interruptLocalInferior(inferiorPid());
+
+ }
+}
+
+void GdbEngine::shutdownEngine()
+{
+ if (isPlainEngine()) {
+ showMessage(QString("PLAIN ADAPTER SHUTDOWN %1").arg(state()));
+ m_outputCollector.shutdown();
+ }
+
+ notifyAdapterShutdownOk();
+}
+
+void GdbEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
+{
+ CHECK_STATE(InferiorSetupRequested);
+
+ if (isRemoteEngine()) {
+ if (response.resultClass == ResultDone) {
+ callTargetRemote();
+ } else {
+ QString reason = response.data["msg"].data();
+ QString msg = tr("Reading debug information failed:") + '\n' + reason;
+ if (reason.endsWith("No such file or directory.")) {
+ showMessage("INFERIOR STARTUP: BINARY NOT FOUND");
+ showMessage(msg, StatusBar);
+ callTargetRemote(); // Proceed nevertheless.
+ } else {
+ notifyInferiorSetupFailedHelper(msg);
+ }
+ }
+
+ } else if (isCoreEngine()) {
+
+ QString core = coreFileName();
+ if (response.resultClass == ResultDone) {
+ showMessage(tr("Symbols found."), StatusBar);
+ handleInferiorPrepared();
+ } else {
+ QString msg = tr("No symbols found in core file <i>%1</i>.").arg(core)
+ + ' ' + tr("This can be caused by a path length limitation "
+ "in the core file.")
+ + ' ' + tr("Try to specify the binary using the "
+ "<i>Debug->Start Debugging->Attach to Core</i> dialog.");
+ notifyInferiorSetupFailedHelper(msg);
+ }
+
+ } else if (isPlainEngine()) {
+
+ if (response.resultClass == ResultDone) {
+ handleInferiorPrepared();
+ } else {
+ QString msg = response.data["msg"].data();
+ // Extend the message a bit in unknown cases.
+ if (!msg.endsWith("File format not recognized"))
+ msg = tr("Starting executable failed:") + '\n' + msg;
+ notifyInferiorSetupFailedHelper(msg);
+ }
+
+ }
+}
+
+void GdbEngine::handleExecRun(const DebuggerResponse &response)
+{
+ CHECK_STATE(EngineRunRequested);
+
+ if (isRemoteEngine()) {
+
+ if (response.resultClass == ResultRunning) {
+ notifyEngineRunAndInferiorRunOk();
+ showMessage("INFERIOR STARTED");
+ showMessage(msgInferiorSetupOk(), StatusBar);
+ } else {
+ showMessage(response.data["msg"].data());
+ notifyEngineRunFailed();
+ }
+
+ } else if (isPlainEngine()) {
+
+ if (response.resultClass == ResultRunning) {
+ notifyEngineRunAndInferiorRunOk(); // For gdb < 7.0
+ //showStatusMessage(tr("Running..."));
+ showMessage("INFERIOR STARTED");
+ showMessage(msgInferiorSetupOk(), StatusBar);
+ // FIXME: That's the wrong place for it.
+ if (boolSetting(EnableReverseDebugging))
+ runCommand({"target record"});
+ } else {
+ QString msg = response.data["msg"].data();
+ //QTC_CHECK(status() == InferiorRunOk);
+ //interruptInferior();
+ showMessage(msg);
+ notifyEngineRunFailed();
+ }
+
+ }
+}
+
+void GdbEngine::handleSetTargetAsync(const DebuggerResponse &response)
+{
+ CHECK_STATE(InferiorSetupRequested);
+ if (response.resultClass == ResultError)
+ qDebug() << "Adapter too old: does not support asynchronous mode.";
+}
+
+void GdbEngine::callTargetRemote()
+{
+ QString channel = runParameters().remoteChannel;
+
+ // Don't touch channels with explicitly set protocols.
+ if (!channel.startsWith("tcp:") && !channel.startsWith("udp:")
+ && !channel.startsWith("file:") && channel.contains(':')
+ && !channel.startsWith('|'))
+ {
+ // "Fix" the IPv6 case with host names without '['...']'
+ if (!channel.startsWith('[') && channel.count(':') >= 2) {
+ channel.insert(0, '[');
+ channel.insert(channel.lastIndexOf(':'), ']');
+ }
+ channel = "tcp:" + channel;
+ }
+
+ if (m_isQnxGdb)
+ runCommand({"target qnx " + channel, CB(handleTargetQnx)});
+ else if (runParameters().useExtendedRemote)
+ runCommand({"target extended-remote " + channel, CB(handleTargetExtendedRemote)});
+ else
+ runCommand({"target remote " + channel, CB(handleTargetRemote)});
+}
+
+void GdbEngine::handleTargetRemote(const DebuggerResponse &response)
+{
+ CHECK_STATE(InferiorSetupRequested);
+ if (response.resultClass == ResultDone) {
+ // gdb server will stop the remote application itself.
+ showMessage("INFERIOR STARTED");
+ showMessage(msgAttachedToStoppedInferior(), StatusBar);
+ QString commands = expand(stringSetting(GdbPostAttachCommands));
+ if (!commands.isEmpty())
+ runCommand({commands, NativeCommand});
+ handleInferiorPrepared();
+ } else {
+ // 16^error,msg="hd:5555: Connection timed out."
+ notifyInferiorSetupFailedHelper(msgConnectRemoteServerFailed(response.data["msg"].data()));
+ }
+}
+
+void GdbEngine::handleTargetExtendedRemote(const DebuggerResponse &response)
+{
+ CHECK_STATE(InferiorSetupRequested);
+ if (response.resultClass == ResultDone) {
+ showMessage("ATTACHED TO GDB SERVER STARTED");
+ showMessage(msgAttachedToStoppedInferior(), StatusBar);
+ QString commands = expand(stringSetting(GdbPostAttachCommands));
+ if (!commands.isEmpty())
+ runCommand({commands, NativeCommand});
+ if (runParameters().attachPID.isValid()) { // attach to pid if valid
+ // gdb server will stop the remote application itself.
+ runCommand({"attach " + QString::number(runParameters().attachPID.pid()),
+ CB(handleTargetExtendedAttach)});
+ } else if (!runParameters().inferior.executable.isEmpty()) {
+ runCommand({"-gdb-set remote exec-file " + runParameters().inferior.executable,
+ CB(handleTargetExtendedAttach)});
+ } else {
+ const QString title = tr("No Remote Executable or Process ID Specified");
+ const QString msg = tr(
+ "No remote executable could be determined from your build system files.<p>"
+ "In case you use qmake, consider adding<p>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;target.path = /tmp/your_executable # path on device<br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;INSTALLS += target</p>"
+ "to your .pro file.");
+ QMessageBox *mb = showMessageBox(QMessageBox::Critical, title, msg,
+ QMessageBox::Ok | QMessageBox::Cancel);
+ mb->button(QMessageBox::Cancel)->setText(tr("Continue Debugging"));
+ mb->button(QMessageBox::Ok)->setText(tr("Stop Debugging"));
+ if (mb->exec() == QMessageBox::Ok) {
+ showMessage("KILLING DEBUGGER AS REQUESTED BY USER");
+ notifyInferiorSetupFailedHelper(title);
+ } else {
+ showMessage("CONTINUE DEBUGGER AS REQUESTED BY USER");
+ handleInferiorPrepared(); // This will likely fail.
+ }
+ }
+ } else {
+ notifyInferiorSetupFailedHelper(msgConnectRemoteServerFailed(response.data["msg"].data()));
+ }
+}
+
+void GdbEngine::handleTargetExtendedAttach(const DebuggerResponse &response)
+{
+ CHECK_STATE(InferiorSetupRequested);
+ if (response.resultClass == ResultDone) {
+ // gdb server will stop the remote application itself.
+ handleInferiorPrepared();
+ } else {
+ notifyInferiorSetupFailedHelper(msgConnectRemoteServerFailed(response.data["msg"].data()));
+ }
+}
+
+void GdbEngine::handleTargetQnx(const DebuggerResponse &response)
+{
+ CHECK_STATE(InferiorSetupRequested);
+ if (response.resultClass == ResultDone) {
+ // gdb server will stop the remote application itself.
+ showMessage("INFERIOR STARTED");
+ showMessage(msgAttachedToStoppedInferior(), StatusBar);
+
+ const DebuggerRunParameters &rp = runParameters();
+ const QString remoteExecutable = rp.inferior.executable;
+ if (rp.attachPID.isValid())
+ runCommand({"attach " + QString::number(rp.attachPID.pid()), CB(handleAttach)});
+ else if (!remoteExecutable.isEmpty())
+ runCommand({"set nto-executable " + remoteExecutable, CB(handleSetNtoExecutable)});
+ else
+ handleInferiorPrepared();
+ } else {
+ // 16^error,msg="hd:5555: Connection timed out."
+ notifyInferiorSetupFailedHelper(response.data["msg"].data());
+ }
+}
+
+void GdbEngine::handleSetNtoExecutable(const DebuggerResponse &response)
+{
+ CHECK_STATE(InferiorSetupRequested);
+ switch (response.resultClass) {
+ case ResultDone:
+ case ResultRunning: {
+ showMessage("EXECUTABLE SET");
+ showMessage(msgAttachedToStoppedInferior(), StatusBar);
+ handleInferiorPrepared();
+ break;
+ }
+ case ResultError:
+ default:
+ notifyInferiorSetupFailedHelper(response.data["msg"].data());
+ }
+}
-DebuggerEngine *createGdbEngine(bool useTerminal, DebuggerStartMode sm)
+void GdbEngine::handleInterruptInferior(const DebuggerResponse &response)
{
- switch (sm) {
- case AttachCore:
- return new GdbCoreEngine(useTerminal);
- case StartRemoteProcess:
- case AttachToRemoteServer:
- return new GdbRemoteServerEngine(useTerminal);
- case AttachExternal:
- return new GdbAttachEngine(useTerminal);
+ if (response.resultClass == ResultDone) {
+ // The gdb server will trigger extra output that we will pick up
+ // to do a proper state transition.
+ } else {
+ // FIXME: On some gdb versions like git 170ffa5d7dd this produces
+ // >810^error,msg="mi_cmd_exec_interrupt: Inferior not executing."
+ notifyInferiorStopOk();
+ }
+}
+
+void GdbEngine::handleStubAttached(const DebuggerResponse &response)
+{
+ // InferiorStopOk can happen if the "*stopped" in response to the
+ // 'attach' comes in before its '^done'
+ QTC_ASSERT(state() == EngineRunRequested || state() == InferiorStopOk, qDebug() << state());
+
+ switch (response.resultClass) {
+ case ResultDone:
+ case ResultRunning:
+ if (runParameters().toolChainAbi.os() == ProjectExplorer::Abi::WindowsOS) {
+ QString errorMessage;
+ // Resume thread that was suspended by console stub process (see stub code).
+ const qint64 mainThreadId = m_stubProc.applicationMainThreadID();
+ if (winResumeThread(mainThreadId, &errorMessage)) {
+ showMessage(QString("Inferior attached, thread %1 resumed").
+ arg(mainThreadId), LogMisc);
+ } else {
+ showMessage(QString("Inferior attached, unable to resume thread %1: %2").
+ arg(mainThreadId).arg(errorMessage),
+ LogWarning);
+ }
+ notifyEngineRunAndInferiorStopOk();
+ continueInferiorInternal();
+ } else {
+ showMessage("INFERIOR ATTACHED AND RUNNING");
+ //notifyEngineRunAndInferiorRunOk();
+ // Wait for the upcoming *stopped and handle it there.
+ }
+ break;
+ case ResultError:
+ if (response.data["msg"].data() == "ptrace: Operation not permitted.") {
+ showMessage(msgPtraceError(runParameters().startMode));
+ notifyEngineRunFailed();
+ break;
+ }
+ showMessage(response.data["msg"].data());
+ notifyEngineIll();
+ break;
default:
- if (useTerminal)
- return new GdbTermEngine(useTerminal);
- return new GdbPlainEngine(useTerminal);
+ showMessage(QString("Invalid response %1").arg(response.resultClass));
+ notifyEngineIll();
+ break;
+ }
+}
+
+void GdbEngine::stubError(const QString &msg)
+{
+ AsynchronousMessageBox::critical(tr("Debugger Error"), msg);
+ notifyEngineIll();
+}
+
+void GdbEngine::stubExited()
+{
+ if (state() == EngineShutdownRequested || state() == DebuggerFinished) {
+ showMessage("STUB EXITED EXPECTEDLY");
+ } else {
+ showMessage("STUB EXITED");
+ notifyEngineIll();
}
}
+static QString findExecutableFromName(const QString &fileNameFromCore, const QString &coreFile)
+{
+ if (fileNameFromCore.isEmpty())
+ return fileNameFromCore;
+ QFileInfo fi(fileNameFromCore);
+ if (fi.isFile())
+ return fileNameFromCore;
+
+ // turn the filename into an absolute path, using the location of the core as a hint
+ QString absPath;
+ if (fi.isAbsolute()) {
+ absPath = fileNameFromCore;
+ } else {
+ QFileInfo coreInfo(coreFile);
+ QDir coreDir = coreInfo.dir();
+ absPath = FileUtils::resolvePath(coreDir.absolutePath(), fileNameFromCore);
+ }
+ if (QFileInfo(absPath).isFile() || absPath.isEmpty())
+ return absPath;
+
+ // remove possible trailing arguments
+ QLatin1Char sep(' ');
+ QStringList pathFragments = absPath.split(sep);
+ while (pathFragments.size() > 0) {
+ QString joined_path = pathFragments.join(sep);
+ if (QFileInfo(joined_path).isFile()) {
+ return joined_path;
+ }
+ pathFragments.pop_back();
+ }
+
+ return QString();
+}
+
+CoreInfo CoreInfo::readExecutableNameFromCore(const StandardRunnable &debugger, const QString &coreFile)
+{
+ CoreInfo cinfo;
+#if 0
+ ElfReader reader(coreFile);
+ cinfo.rawStringFromCore = QString::fromLocal8Bit(reader.readCoreName(&cinfo.isCore));
+ cinfo.foundExecutableName = findExecutableFromName(cinfo.rawStringFromCore, coreFile);
+#else
+ QStringList args = {"-nx", "-batch", "-c", coreFile};
+
+ SynchronousProcess proc;
+ QStringList envLang = QProcess::systemEnvironment();
+ Utils::Environment::setupEnglishOutput(&envLang);
+ proc.setEnvironment(envLang);
+ SynchronousProcessResponse response = proc.runBlocking(debugger.executable, args);
+
+ if (response.result == SynchronousProcessResponse::Finished) {
+ QString output = response.stdOut();
+ // Core was generated by `/data/dev/creator-2.6/bin/qtcreator'.
+ // Program terminated with signal 11, Segmentation fault.
+ int pos1 = output.indexOf("Core was generated by");
+ if (pos1 != -1) {
+ pos1 += 23;
+ int pos2 = output.indexOf('\'', pos1);
+ if (pos2 != -1) {
+ cinfo.isCore = true;
+ cinfo.rawStringFromCore = output.mid(pos1, pos2 - pos1);
+ cinfo.foundExecutableName = findExecutableFromName(cinfo.rawStringFromCore, coreFile);
+ }
+ }
+ }
+#endif
+ return cinfo;
+}
+
+void GdbEngine::continueSetupEngine()
+{
+ if (isCoreEngine()) {
+ bool isCore = true;
+ if (m_coreUnpackProcess) {
+ isCore = m_coreUnpackProcess->exitCode() == 0;
+ m_coreUnpackProcess->deleteLater();
+ m_coreUnpackProcess = 0;
+ if (m_tempCoreFile.isOpen())
+ m_tempCoreFile.close();
+ }
+ if (isCore && m_executable.isEmpty()) {
+ CoreInfo cinfo =
+ CoreInfo::readExecutableNameFromCore(runParameters().debugger, coreFileName());
+
+ if (cinfo.isCore) {
+ m_executable = cinfo.foundExecutableName;
+ if (m_executable.isEmpty()) {
+ AsynchronousMessageBox::warning(tr("Error Loading Symbols"),
+ tr("No executable to load symbols from specified core."));
+ notifyEngineSetupFailed();
+ return;
+ }
+ }
+ }
+ if (isCore) {
+ startGdb();
+ } else {
+ AsynchronousMessageBox::warning(tr("Error Loading Core File"),
+ tr("The specified file does not appear to be a core file."));
+ notifyEngineSetupFailed();
+ }
+ }
+}
+
+void GdbEngine::handleTargetCore(const DebuggerResponse &response)
+{
+ CHECK_STATE(EngineRunRequested);
+ notifyEngineRunOkAndInferiorUnrunnable();
+ showMessage(tr("Attached to core."), StatusBar);
+ if (response.resultClass == ResultError) {
+ // We'll accept any kind of error e.g. &"Cannot access memory at address 0x2abc2a24\n"
+ // Even without the stack, the user can find interesting stuff by exploring
+ // the memory, globals etc.
+ showStatusMessage(tr("Attach to core \"%1\" failed:").arg(runParameters().coreFile)
+ + '\n' + response.data["msg"].data()
+ + '\n' + tr("Continuing nevertheless."));
+ }
+ // Due to the auto-solib-add off setting, we don't have any
+ // symbols yet. Load them in order of importance.
+ reloadStack();
+ reloadModulesInternal();
+ runCommand({"p 5", CB(handleCoreRoundTrip)});
+}
+
+void GdbEngine::handleCoreRoundTrip(const DebuggerResponse &response)
+{
+ CHECK_STATE(InferiorUnrunnable);
+ Q_UNUSED(response);
+ loadSymbolsForStack();
+ handleStop3();
+ QTimer::singleShot(1000, this, &GdbEngine::loadAllSymbols);
+}
+
+static QString tempCoreFilename()
+{
+ Utils::TemporaryFile tmp("tmpcore-XXXXXX");
+ tmp.open();
+ return tmp.fileName();
+}
+
+void GdbEngine::unpackCoreIfNeeded()
+{
+ QStringList arguments;
+ const QString msg = "Unpacking core file to %1";
+ if (m_coreName.endsWith(".lzo")) {
+ m_tempCoreName = tempCoreFilename();
+ showMessage(msg.arg(m_tempCoreName));
+ arguments << "-o" << m_tempCoreName << "-x" << m_coreName;
+ m_coreUnpackProcess = new QProcess(this);
+ m_coreUnpackProcess->setWorkingDirectory(TemporaryDirectory::masterDirectoryPath());
+ m_coreUnpackProcess->start("lzop", arguments);
+ connect(m_coreUnpackProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
+ this, &GdbEngine::continueSetupEngine);
+ } else if (m_coreName.endsWith(".gz")) {
+ m_tempCoreName = tempCoreFilename();
+ showMessage(msg.arg(m_tempCoreName));
+ m_tempCoreFile.setFileName(m_tempCoreName);
+ m_tempCoreFile.open(QFile::WriteOnly);
+ arguments << "-c" << "-d" << m_coreName;
+ m_coreUnpackProcess = new QProcess(this);
+ m_coreUnpackProcess->setWorkingDirectory(TemporaryDirectory::masterDirectoryPath());
+ m_coreUnpackProcess->start("gzip", arguments);
+ connect(m_coreUnpackProcess, &QProcess::readyRead, this, [this] {
+ m_tempCoreFile.write(m_coreUnpackProcess->readAll());
+ });
+ connect(m_coreUnpackProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
+ this, &GdbEngine::continueSetupEngine);
+ } else {
+ continueSetupEngine();
+ }
+}
+
+QString GdbEngine::coreFileName() const
+{
+ return m_tempCoreName.isEmpty() ? m_coreName : m_tempCoreName;
+}
+
void GdbEngine::doUpdateLocals(const UpdateParameters &params)
{
m_pendingBreakpointRequests = 0;
@@ -4423,6 +5211,15 @@ QString GdbEngine::msgPtraceError(DebuggerStartMode sm)
"For more details, see /etc/sysctl.d/10-ptrace.conf\n");
}
+//
+// Factory
+//
+
+DebuggerEngine *createGdbEngine(bool useTerminal, DebuggerStartMode startMode)
+{
+ return new GdbEngine(useTerminal, startMode);
+}
+
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 70abb82f1e8..a7537cfdebd 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -33,66 +33,68 @@
#include <debugger/watchutils.h>
#include <debugger/debuggeritem.h>
#include <debugger/debuggertooltipmanager.h>
+#include <debugger/outputcollector.h>
#include <coreplugin/id.h>
-#include <projectexplorer/devicesupport/idevice.h>
#include <utils/qtcprocess.h>
+#include <utils/consoleprocess.h>
#include <QProcess>
#include <QTextCodec>
-#include <QTime>
#include <QTimer>
-#include <functional>
-
namespace Debugger {
namespace Internal {
-class GdbProcess;
+class BreakpointParameters;
+class BreakpointResponse;
class DebugInfoTask;
class DebugInfoTaskHandler;
class DebuggerResponse;
+class DisassemblerAgentCookie;
class GdbMi;
class MemoryAgentCookie;
-class BreakpointParameters;
-class BreakpointResponse;
-class DisassemblerAgentCookie;
-class DisassemblerLines;
+struct CoreInfo
+{
+ QString rawStringFromCore;
+ QString foundExecutableName; // empty if no corresponding exec could be found
+ bool isCore = false;
+
+ static CoreInfo readExecutableNameFromCore(const ProjectExplorer::StandardRunnable &debugger,
+ const QString &coreFile);
+};
class GdbEngine : public DebuggerEngine
{
Q_OBJECT
public:
- explicit GdbEngine(bool useTerminal);
- ~GdbEngine() override;
+ explicit GdbEngine(bool useTerminal, DebuggerStartMode startMode);
+ ~GdbEngine() final;
private: ////////// General Interface //////////
- DebuggerEngine *cppEngine() override { return this; }
+ DebuggerEngine *cppEngine() final { return this; }
- virtual void handleGdbStartFailed();
- void notifyInferiorSetupFailed() override;
- void prepareForRestart() override;
+ void handleGdbStartFailed();
+ void prepareForRestart() final;
- bool hasCapability(unsigned) const override;
- void detachDebugger() override;
- void shutdownInferior() override;
- void abortDebugger() override;
- void resetInferior() override;
+ bool hasCapability(unsigned) const final;
+ void detachDebugger() final;
+ void shutdownInferior() final;
+ void abortDebuggerProcess() final;
+ void resetInferior() final;
- bool acceptsDebuggerCommands() const override;
- void executeDebuggerCommand(const QString &command, DebuggerLanguages languages) override;
+ bool acceptsDebuggerCommands() const final;
+ void executeDebuggerCommand(const QString &command, DebuggerLanguages languages) final;
-private: ////////// General State //////////
+ ////////// General State //////////
- DebuggerStartMode startMode() const;
- void reloadLocals();
-
- bool m_registerNamesListed;
+ const DebuggerStartMode m_startMode;
+ bool m_registerNamesListed = false;
-protected: ////////// Gdb Process Management //////////
+ ////////// Gdb Process Management //////////
void startGdb(const QStringList &args = QStringList());
void handleInferiorShutdown(const DebuggerResponse &response);
@@ -115,8 +117,8 @@ protected: ////////// Gdb Process Management //////////
void handleDebugInfoLocation(const DebuggerResponse &response);
- // The adapter is still running just fine, but it failed to acquire a debuggee.
- void notifyInferiorSetupFailed(const QString &msg);
+ // The engine is still running just fine, but it failed to acquire a debuggee.
+ void notifyInferiorSetupFailedHelper(const QString &msg);
void notifyAdapterShutdownOk();
void notifyAdapterShutdownFailed();
@@ -125,10 +127,6 @@ protected: ////////// Gdb Process Management //////////
// Make sure to clean up everything before emitting this signal.
void handleAdapterCrashed(const QString &msg);
-private:
- friend class GdbPlainEngine;
- friend class GdbCoreEngine;
- void handleInterruptDeviceInferior(const QString &error);
void handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus);
void handleGdbError(QProcess::ProcessError error);
void readGdbStandardOutput();
@@ -141,17 +139,16 @@ private:
QTextCodec::ConverterState m_inferiorOutputCodecState;
QByteArray m_inbuffer;
- bool m_busy;
+ bool m_busy = false;
// Name of the convenience variable containing the last
// known function return value.
QString m_resultVarName;
-protected: ////////// Gdb Command Management //////////
+ ////////// Gdb Command Management //////////
- void runCommand(const DebuggerCommand &command) override;
+ void runCommand(const DebuggerCommand &command) final;
-private:
void commandTimeout();
void setTokenBarrier();
@@ -169,19 +166,19 @@ private:
// This contains the first token number for the current round
// of evaluation. Responses with older tokens are considers
// out of date and discarded.
- int m_oldestAcceptableToken;
- int m_nonDiscardableCount;
+ int m_oldestAcceptableToken = -1;
+ int m_nonDiscardableCount = 0;
- int m_pendingBreakpointRequests; // Watch updating commands in flight
+ int m_pendingBreakpointRequests = 0; // Watch updating commands in flight
typedef void (GdbEngine::*CommandsDoneCallback)();
// This function is called after all previous responses have been received.
- CommandsDoneCallback m_commandsDoneCallback;
+ CommandsDoneCallback m_commandsDoneCallback = nullptr;
+
+ bool m_rerunPending = false;
- bool m_rerunPending;
+ ////////// Gdb Output, State & Capability Handling //////////
-private: ////////// Gdb Output, State & Capability Handling //////////
-protected:
Q_INVOKABLE void handleResponse(const QString &buff);
void handleAsyncOutput(const QString &asyncClass, const GdbMi &result);
void handleStopResponse(const GdbMi &data);
@@ -191,42 +188,40 @@ protected:
void handleStop3();
void resetCommandQueue();
- bool isSynchronous() const override { return true; }
+ bool isSynchronous() const final { return true; }
// Gdb initialization sequence
void handleShowVersion(const DebuggerResponse &response);
void handleListFeatures(const DebuggerResponse &response);
void handlePythonSetup(const DebuggerResponse &response);
- int m_gdbVersion; // 7.6.1 is 70601
- int m_pythonVersion; // 2.7.2 is 20702
- bool m_isQnxGdb;
+ int m_gdbVersion = 100; // 7.6.1 is 70601
+ int m_pythonVersion = 0; // 2.7.2 is 20702
+ bool m_isQnxGdb = false;
-private: ////////// Inferior Management //////////
+ ////////// Inferior Management //////////
// This should be always the last call in a function.
- bool stateAcceptsBreakpointChanges() const override;
- bool acceptsBreakpoint(Breakpoint bp) const override;
- void insertBreakpoint(Breakpoint bp) override;
- void removeBreakpoint(Breakpoint bp) override;
- void changeBreakpoint(Breakpoint bp) override;
-
- void executeStep() override;
- void executeStepOut() override;
- void executeNext() override;
- void executeStepI() override;
- void executeNextI() override;
-
- protected:
+ bool stateAcceptsBreakpointChanges() const final;
+ bool acceptsBreakpoint(Breakpoint bp) const final;
+ void insertBreakpoint(Breakpoint bp) final;
+ void removeBreakpoint(Breakpoint bp) final;
+ void changeBreakpoint(Breakpoint bp) final;
+
+ void executeStep() final;
+ void executeStepOut() final;
+ void executeNext() final;
+ void executeStepI() final;
+ void executeNextI() final;
+
void continueInferiorInternal();
- void continueInferior() override;
- void interruptInferior() override;
- virtual void interruptInferior2() {}
+ void continueInferior() final;
+ void interruptInferior() final;
- void executeRunToLine(const ContextData &data) override;
- void executeRunToFunction(const QString &functionName) override;
- void executeJumpToLine(const ContextData &data) override;
- void executeReturn() override;
+ void executeRunToLine(const ContextData &data) final;
+ void executeRunToFunction(const QString &functionName) final;
+ void executeJumpToLine(const ContextData &data) final;
+ void executeReturn() final;
void handleExecuteContinue(const DebuggerResponse &response);
void handleExecuteStep(const DebuggerResponse &response);
@@ -237,10 +232,10 @@ private: ////////// Inferior Management //////////
QString msgPtraceError(DebuggerStartMode sm);
-private: ////////// View & Data Stuff //////////
+ ////////// View & Data Stuff //////////
- void selectThread(ThreadId threadId) override;
- void activateFrame(int index) override;
+ void selectThread(ThreadId threadId) final;
+ void activateFrame(int index) final;
void handleAutoContinueInferior();
//
@@ -268,14 +263,13 @@ private: ////////// View & Data Stuff //////////
//
// Modules specific stuff
//
- protected:
- void loadSymbols(const QString &moduleName) override;
- void loadAllSymbols() override;
- void loadSymbolsForStack() override;
- void requestModuleSymbols(const QString &moduleName) override;
- void requestModuleSections(const QString &moduleName) override;
- void reloadModules() override;
- void examineModules() override;
+ void loadSymbols(const QString &moduleName) final;
+ void loadAllSymbols() final;
+ void loadSymbolsForStack() final;
+ void requestModuleSymbols(const QString &moduleName) final;
+ void requestModuleSections(const QString &moduleName) final;
+ void reloadModules() final;
+ void examineModules() final;
void reloadModulesInternal();
void handleModulesList(const DebuggerResponse &response);
@@ -284,14 +278,14 @@ private: ////////// View & Data Stuff //////////
//
// Snapshot specific stuff
//
- virtual void createSnapshot() override;
+ void createSnapshot() final;
void handleMakeSnapshot(const DebuggerResponse &response, const QString &coreFile);
//
// Register specific stuff
//
- void reloadRegisters() override;
- void setRegisterValue(const QString &name, const QString &value) override;
+ void reloadRegisters() final;
+ void setRegisterValue(const QString &name, const QString &value) final;
void handleRegisterListNames(const DebuggerResponse &response);
void handleRegisterListing(const DebuggerResponse &response);
void handleRegisterListValues(const DebuggerResponse &response);
@@ -302,7 +296,7 @@ private: ////////// View & Data Stuff //////////
// Disassembler specific stuff
//
// Chain of fallbacks: PointMixed -> PointPlain -> RangeMixed -> RangePlain.
- void fetchDisassembler(DisassemblerAgent *agent) override;
+ void fetchDisassembler(DisassemblerAgent *agent) final;
void fetchDisassemblerByCliPointMixed(const DisassemblerAgentCookie &ac);
void fetchDisassemblerByCliRangeMixed(const DisassemblerAgentCookie &ac);
void fetchDisassemblerByCliRangePlain(const DisassemblerAgentCookie &ac);
@@ -311,7 +305,7 @@ private: ////////// View & Data Stuff //////////
//
// Source file specific stuff
//
- void reloadSourceFiles() override;
+ void reloadSourceFiles() final;
void reloadSourceFilesInternal();
void handleQuerySources(const DebuggerResponse &response);
@@ -323,13 +317,12 @@ private: ////////// View & Data Stuff //////////
QMap<QString, QString> m_fullToShortName;
QMultiMap<QString, QString> m_baseNameToFullName;
- bool m_sourcesListUpdating;
+ bool m_sourcesListUpdating = false;
//
// Stack specific stuff
//
-protected:
- void updateAll() override;
+ void updateAll() final;
void handleStackListFrames(const DebuggerResponse &response, bool isFull);
void handleStackSelectThread(const DebuggerResponse &response);
void handleThreadListIds(const DebuggerResponse &response);
@@ -337,20 +330,21 @@ protected:
void handleThreadNames(const DebuggerResponse &response);
DebuggerCommand stackCommand(int depth);
void reloadStack();
- void reloadFullStack() override;
- void loadAdditionalQmlStack() override;
+ void reloadFullStack() final;
+ void loadAdditionalQmlStack() final;
int currentFrame() const;
//
// Watch specific stuff
//
- virtual void assignValueInDebugger(WatchItem *item,
- const QString &expr, const QVariant &value) override;
+ void reloadLocals();
+ void assignValueInDebugger(WatchItem *item,
+ const QString &expr, const QVariant &value) final;
- void fetchMemory(MemoryAgent *agent, quint64 addr, quint64 length) override;
+ void fetchMemory(MemoryAgent *agent, quint64 addr, quint64 length) final;
void fetchMemoryHelper(const MemoryAgentCookie &cookie);
void handleChangeMemory(const DebuggerResponse &response);
- void changeMemory(MemoryAgent *agent, quint64 addr, const QByteArray &data) override;
+ void changeMemory(MemoryAgent *agent, quint64 addr, const QByteArray &data) final;
void handleFetchMemory(const DebuggerResponse &response, MemoryAgentCookie ac);
void showToolTip();
@@ -361,7 +355,7 @@ protected:
void createFullBacktrace();
- void doUpdateLocals(const UpdateParameters &parameters) override;
+ void doUpdateLocals(const UpdateParameters &parameters) final;
void handleFetchVariables(const DebuggerResponse &response);
void setLocals(const QList<GdbMi> &locals);
@@ -369,7 +363,7 @@ protected:
//
// Dumper Management
//
- void reloadDebuggingHelpers() override;
+ void reloadDebuggingHelpers() final;
//
// Convenience Functions
@@ -377,19 +371,18 @@ protected:
void showExecutionError(const QString &message);
QString failedToStartMessage();
- static QString tooltipIName(const QString &exp);
-
// For short-circuiting stack and thread list evaluation.
- bool m_stackNeeded;
+ bool m_stackNeeded = false;
// For suppressing processing *stopped and *running responses
// while updating locals.
- bool m_inUpdateLocals;
+ bool m_inUpdateLocals = false;
// HACK:
QString m_currentThread;
QString m_lastWinException;
QString m_lastMissingDebugInfo;
+ const bool m_useTerminal;
bool m_terminalTrap;
bool usesExecInterrupt() const;
bool usesTargetAsync() const;
@@ -404,7 +397,7 @@ protected:
void requestDebugInformation(const DebugInfoTask &task);
DebugInfoTaskHandler *m_debugInfoTaskHandler;
- bool m_systemDumpersLoaded;
+ bool m_systemDumpersLoaded = false;
static QString msgGdbStopFailed(const QString &why);
static QString msgInferiorStopFailed(const QString &why);
@@ -413,16 +406,64 @@ protected:
static QString msgInferiorRunOk();
static QString msgConnectRemoteServerFailed(const QString &why);
- void debugLastCommand() override;
+ void debugLastCommand() final;
DebuggerCommand m_lastDebuggableCommand;
-protected:
+ bool isPlainEngine() const;
+ bool isCoreEngine() const;
+ bool isRemoteEngine() const;
+ bool isAttachEngine() const;
+ bool isTermEngine() const;
+
+ void setupEngine() final;
+ void setupInferior() final;
+ void runEngine() final;
+ void shutdownEngine() final;
+
+ void interruptInferior2();
+
+ // Plain
+ void handleExecRun(const DebuggerResponse &response);
+ void handleFileExecAndSymbols(const DebuggerResponse &response);
+
+ // Attach
+ void handleAttach(const DebuggerResponse &response);
+
+ // Remote
+ void callTargetRemote();
+ void handleSetTargetAsync(const DebuggerResponse &response);
+ void handleTargetRemote(const DebuggerResponse &response);
+ void handleTargetExtendedRemote(const DebuggerResponse &response);
+ void handleTargetExtendedAttach(const DebuggerResponse &response);
+ void handleTargetQnx(const DebuggerResponse &response);
+ void handleSetNtoExecutable(const DebuggerResponse &response);
+ void handleInterruptInferior(const DebuggerResponse &response);
void interruptLocalInferior(qint64 pid);
-protected:
+ // Terminal
+ void handleStubAttached(const DebuggerResponse &response);
+ void stubExited();
+ void stubError(const QString &msg);
+ Utils::ConsoleProcess m_stubProc;
+
+ // Core
+ void handleTargetCore(const DebuggerResponse &response);
+ void handleCoreRoundTrip(const DebuggerResponse &response);
+ void unpackCoreIfNeeded();
+ QString coreFileName() const;
+ QString coreName() const;
+
+ void continueSetupEngine();
+
+ QString m_executable;
+ QString m_coreName;
+ QString m_tempCoreName;
+ QProcess *m_coreUnpackProcess = nullptr;
+ QFile m_tempCoreFile;
+
Utils::QtcProcess m_gdbProc;
+ OutputCollector m_outputCollector;
QString m_errorString;
- ProjectExplorer::DeviceProcessSignalOperation::Ptr m_signalOperation;
};
} // namespace Internal
diff --git a/src/plugins/debugger/gdb/gdboptionspage.cpp b/src/plugins/debugger/gdb/gdboptionspage.cpp
index cecf8ccaeae..822e7d8b8cf 100644
--- a/src/plugins/debugger/gdb/gdboptionspage.cpp
+++ b/src/plugins/debugger/gdb/gdboptionspage.cpp
@@ -86,11 +86,11 @@ GdbOptionsPageWidget::GdbOptionsPageWidget()
auto labelGdbWatchdogTimeout = new QLabel(groupBoxGeneral);
labelGdbWatchdogTimeout->setText(GdbOptionsPage::tr("GDB timeout:"));
labelGdbWatchdogTimeout->setToolTip(GdbOptionsPage::tr(
- "The number of seconds Qt Creator will wait before it terminates\n"
- "a non-responsive GDB process. The default value of 20 seconds should\n"
- "be sufficient for most applications, but there are situations when\n"
- "loading big libraries or listing source files takes much longer than\n"
- "that on slow machines. In this case, the value should be increased."));
+ "The number of seconds before a non-responsive GDB process is terminated.\n"
+ "The default value of 20 seconds should be sufficient for most\n"
+ "applications, but there are situations when loading big libraries or\n"
+ "listing source files takes much longer than that on slow machines.\n"
+ "In this case, the value should be increased."));
auto spinBoxGdbWatchdogTimeout = new QSpinBox(groupBoxGeneral);
spinBoxGdbWatchdogTimeout->setToolTip(labelGdbWatchdogTimeout->toolTip());
diff --git a/src/plugins/debugger/gdb/gdbplainengine.cpp b/src/plugins/debugger/gdb/gdbplainengine.cpp
deleted file mode 100644
index d957336891a..00000000000
--- a/src/plugins/debugger/gdb/gdbplainengine.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "gdbplainengine.h"
-
-#include <debugger/debuggeractions.h>
-#include <debugger/debuggercore.h>
-#include <debugger/debuggerprotocol.h>
-#include <debugger/debuggerstartparameters.h>
-
-#include <utils/hostosinfo.h>
-#include <utils/qtcassert.h>
-
-#include <QFileInfo>
-
-namespace Debugger {
-namespace Internal {
-
-#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
-
-GdbPlainEngine::GdbPlainEngine(bool useTerminal)
- : GdbEngine(useTerminal)
-{
- // Output
- connect(&m_outputCollector, &OutputCollector::byteDelivery,
- this, &GdbEngine::readDebuggeeOutput);
-}
-
-void GdbPlainEngine::setupInferior()
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- setEnvironmentVariables();
- const DebuggerRunParameters &rp = runParameters();
- if (!rp.inferior.workingDirectory.isEmpty())
- runCommand({"cd " + rp.inferior.workingDirectory});
- if (!rp.inferior.commandLineArguments.isEmpty()) {
- QString args = rp.inferior.commandLineArguments;
- runCommand({"-exec-arguments " + args});
- }
-
- QString executable = QFileInfo(runParameters().inferior.executable).absoluteFilePath();
- runCommand({"-file-exec-and-symbols \"" + executable + '"',
- CB(handleFileExecAndSymbols)});
-}
-
-void GdbPlainEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == ResultDone) {
- handleInferiorPrepared();
- } else {
- QString msg = response.data["msg"].data();
- // Extend the message a bit in unknown cases.
- if (!msg.endsWith("File format not recognized"))
- msg = tr("Starting executable failed:") + '\n' + msg;
- notifyInferiorSetupFailed(msg);
- }
-}
-
-void GdbPlainEngine::runEngine()
-{
- if (runParameters().useContinueInsteadOfRun)
- runCommand({"-exec-continue", DebuggerCommand::RunRequest, CB(handleExecuteContinue)});
- else
- runCommand({"-exec-run", DebuggerCommand::RunRequest, CB(handleExecRun)});
-}
-
-void GdbPlainEngine::handleExecRun(const DebuggerResponse &response)
-{
- QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
- if (response.resultClass == ResultRunning) {
- notifyEngineRunAndInferiorRunOk(); // For gdb < 7.0
- //showStatusMessage(tr("Running..."));
- showMessage("INFERIOR STARTED");
- showMessage(msgInferiorSetupOk(), StatusBar);
- // FIXME: That's the wrong place for it.
- if (boolSetting(EnableReverseDebugging))
- runCommand({"target record"});
- } else {
- QString msg = response.data["msg"].data();
- //QTC_CHECK(status() == InferiorRunOk);
- //interruptInferior();
- showMessage(msg);
- notifyEngineRunFailed();
- }
-}
-
-void GdbPlainEngine::setupEngine()
-{
- QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
- showMessage("TRYING TO START ADAPTER");
-
- if (!prepareCommand())
- return;
-
- QStringList gdbArgs;
-
- if (!m_outputCollector.listen()) {
- handleAdapterStartFailed(tr("Cannot set up communication with child process: %1")
- .arg(m_outputCollector.errorString()));
- return;
- }
- gdbArgs.append("--tty=" + m_outputCollector.serverName());
-
- startGdb(gdbArgs);
-}
-
-void GdbPlainEngine::handleGdbStartFailed()
-{
- m_outputCollector.shutdown();
-}
-
-void GdbPlainEngine::interruptInferior2()
-{
- interruptLocalInferior(inferiorPid());
-}
-
-void GdbPlainEngine::shutdownEngine()
-{
- showMessage(QString("PLAIN ADAPTER SHUTDOWN %1").arg(state()));
- m_outputCollector.shutdown();
- notifyAdapterShutdownOk();
-}
-
-} // namespace Debugger
-} // namespace Internal
diff --git a/src/plugins/debugger/gdb/gdbplainengine.h b/src/plugins/debugger/gdb/gdbplainengine.h
deleted file mode 100644
index a2f6e04a6b6..00000000000
--- a/src/plugins/debugger/gdb/gdbplainengine.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "gdbengine.h"
-#include <debugger/outputcollector.h>
-
-namespace Debugger {
-namespace Internal {
-
-class GdbPlainEngine : public GdbEngine
-{
- // Needs tr - Context
- Q_OBJECT
-
-public:
- explicit GdbPlainEngine(bool useTerminal);
-
-private:
- void handleExecRun(const DebuggerResponse &response);
- void handleFileExecAndSymbols(const DebuggerResponse &response);
-
- void setupInferior() override;
- void runEngine() override;
- void setupEngine() override;
- void handleGdbStartFailed() override;
- void interruptInferior2() override;
- void shutdownEngine() override;
-
- OutputCollector m_outputCollector;
-};
-
-} // namespace Debugger
-} // namespace Internal
diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
deleted file mode 100644
index 20dfce02612..00000000000
--- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
+++ /dev/null
@@ -1,459 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "remotegdbserveradapter.h"
-
-#include <debugger/debuggeractions.h>
-#include <debugger/debuggercore.h>
-#include <debugger/debuggerprotocol.h>
-#include <debugger/debuggerruncontrol.h>
-#include <debugger/procinterrupt.h>
-
-#include <coreplugin/messagebox.h>
-
-#include <utils/hostosinfo.h>
-#include <utils/qtcfallthrough.h>
-#include <utils/qtcassert.h>
-#include <utils/qtcprocess.h>
-
-#include <QAbstractButton>
-#include <QFileInfo>
-#include <QMessageBox>
-
-using namespace Utils;
-
-namespace Debugger {
-namespace Internal {
-
-#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
-
-///////////////////////////////////////////////////////////////////////
-//
-// RemoteGdbAdapter
-//
-///////////////////////////////////////////////////////////////////////
-
-GdbRemoteServerEngine::GdbRemoteServerEngine(bool useTerminal)
- : GdbEngine(useTerminal)
-{
- connect(&m_uploadProc, &QProcess::errorOccurred, this, &GdbRemoteServerEngine::uploadProcError);
- connect(&m_uploadProc, &QProcess::readyReadStandardOutput,
- this, &GdbRemoteServerEngine::readUploadStandardOutput);
- connect(&m_uploadProc, &QProcess::readyReadStandardError,
- this, &GdbRemoteServerEngine::readUploadStandardError);
- connect(&m_uploadProc, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
- this, &GdbRemoteServerEngine::uploadProcFinished);
-}
-
-void GdbRemoteServerEngine::setupEngine()
-{
- if (HostOsInfo::isWindowsHost())
- m_gdbProc.setUseCtrlCStub(runParameters().useCtrlCStub); // This is only set for QNX
-
- QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
- showMessage("TRYING TO START ADAPTER");
- QString serverStartScript = runParameters().serverStartScript;
- if (!serverStartScript.isEmpty()) {
-
- // Provide script information about the environment
- QString arglist;
- QtcProcess::addArg(&arglist, serverStartScript);
- QtcProcess::addArg(&arglist, runParameters().inferior.executable);
- QtcProcess::addArg(&arglist, runParameters().remoteChannel);
-
- m_uploadProc.start(arglist);
- m_uploadProc.waitForStarted();
- m_uploadProc.waitForFinished();
- }
-
- startGdb();
-}
-
-void GdbRemoteServerEngine::uploadProcError(QProcess::ProcessError error)
-{
- QString msg;
- switch (error) {
- case QProcess::FailedToStart:
- msg = tr("The upload process failed to start. Shell missing?");
- break;
- case QProcess::Crashed:
- msg = tr("The upload process crashed some time after starting "
- "successfully.");
- break;
- case QProcess::Timedout:
- msg = tr("The last waitFor...() function timed out. "
- "The state of QProcess is unchanged, and you can try calling "
- "waitFor...() again.");
- break;
- case QProcess::WriteError:
- msg = tr("An error occurred when attempting to write "
- "to the upload process. For example, the process may not be running, "
- "or it may have closed its input channel.");
- break;
- case QProcess::ReadError:
- msg = tr("An error occurred when attempting to read from "
- "the upload process. For example, the process may not be running.");
- break;
- default:
- msg = tr("An unknown error in the upload process occurred. "
- "This is the default return value of error().");
- }
-
- showMessage(msg, StatusBar);
- Core::AsynchronousMessageBox::critical(tr("Error"), msg);
-}
-
-void GdbRemoteServerEngine::readUploadStandardOutput()
-{
- const QByteArray ba = m_uploadProc.readAllStandardOutput();
- const QString msg = QString::fromLocal8Bit(ba, ba.length());
- showMessage(msg, LogOutput);
- showMessage(msg, AppOutput);
-}
-
-void GdbRemoteServerEngine::readUploadStandardError()
-{
- const QByteArray ba = m_uploadProc.readAllStandardError();
- const QString msg = QString::fromLocal8Bit(ba, ba.length());
- showMessage(msg, LogOutput);
- showMessage(msg, AppError);
-}
-
-void GdbRemoteServerEngine::uploadProcFinished()
-{
- if (m_uploadProc.exitStatus() == QProcess::NormalExit && m_uploadProc.exitCode() == 0) {
- // all good.
- } else {
- runTool()->reportFailure(tr("Upload failed: %1").arg(m_uploadProc.errorString()));
- }
-}
-
-void GdbRemoteServerEngine::setupInferior()
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- setLinuxOsAbi();
- const DebuggerRunParameters &rp = runParameters();
- QString symbolFile;
- if (!rp.symbolFile.isEmpty()) {
- QFileInfo fi(rp.symbolFile);
- symbolFile = fi.absoluteFilePath();
- }
-
- //const QByteArray sysroot = sp.sysroot.toLocal8Bit();
- //const QByteArray remoteArch = sp.remoteArchitecture.toLatin1();
- const QString args = runParameters().inferior.commandLineArguments;
-
-// if (!remoteArch.isEmpty())
-// postCommand("set architecture " + remoteArch);
- if (!rp.solibSearchPath.isEmpty()) {
- DebuggerCommand cmd("appendSolibSearchPath");
- cmd.arg("path", rp.solibSearchPath);
- cmd.arg("separator", HostOsInfo::pathListSeparator());
- runCommand(cmd);
- }
-
- if (!args.isEmpty())
- runCommand({"-exec-arguments " + args});
-
- setEnvironmentVariables();
-
- // This has to be issued before 'target remote'. On pre-7.0 the
- // command is not present and will result in ' No symbol table is
- // loaded. Use the "file" command.' as gdb tries to set the
- // value of a variable with name 'target-async'.
- //
- // Testing with -list-target-features which was introduced at
- // the same time would not work either, as this need an existing
- // target.
- //
- // Using it even without a target and having it fail might still
- // be better as:
- // Some external comment: '[but] "set target-async on" with a native
- // windows gdb will work, but then fail when you actually do
- // "run"/"attach", I think..
-
-
- // gdb/mi/mi-main.c:1958: internal-error:
- // mi_execute_async_cli_command: Assertion `is_running (inferior_ptid)'
- // failed.\nA problem internal to GDB has been detected,[...]
- if (usesTargetAsync())
- runCommand({"set target-async on", CB(handleSetTargetAsync)});
-
- if (symbolFile.isEmpty()) {
- showMessage(tr("No symbol file given."), StatusBar);
- callTargetRemote();
- return;
- }
-
- if (!symbolFile.isEmpty()) {
- runCommand({"-file-exec-and-symbols \"" + symbolFile + '"',
- CB(handleFileExecAndSymbols)});
- }
-}
-
-void GdbRemoteServerEngine::handleSetTargetAsync(const DebuggerResponse &response)
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == ResultError)
- qDebug() << "Adapter too old: does not support asynchronous mode.";
-}
-
-void GdbRemoteServerEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == ResultDone) {
- callTargetRemote();
- } else {
- QString reason = response.data["msg"].data();
- QString msg = tr("Reading debug information failed:") + '\n' + reason;
- if (reason.endsWith("No such file or directory.")) {
- showMessage("INFERIOR STARTUP: BINARY NOT FOUND");
- showMessage(msg, StatusBar);
- callTargetRemote(); // Proceed nevertheless.
- } else {
- notifyInferiorSetupFailed(msg);
- }
- }
-}
-
-void GdbRemoteServerEngine::callTargetRemote()
-{
- QString channel = runParameters().remoteChannel;
-
- // Don't touch channels with explicitly set protocols.
- if (!channel.startsWith("tcp:") && !channel.startsWith("udp:")
- && !channel.startsWith("file:") && channel.contains(':')
- && !channel.startsWith('|'))
- {
- // "Fix" the IPv6 case with host names without '['...']'
- if (!channel.startsWith('[') && channel.count(':') >= 2) {
- channel.insert(0, '[');
- channel.insert(channel.lastIndexOf(':'), ']');
- }
- channel = "tcp:" + channel;
- }
-
- if (m_isQnxGdb)
- runCommand({"target qnx " + channel, CB(handleTargetQnx)});
- else if (runParameters().useExtendedRemote)
- runCommand({"target extended-remote " + channel, CB(handleTargetExtendedRemote)});
- else
- runCommand({"target remote " + channel, CB(handleTargetRemote)});
-}
-
-void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response)
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == ResultDone) {
- // gdb server will stop the remote application itself.
- showMessage("INFERIOR STARTED");
- showMessage(msgAttachedToStoppedInferior(), StatusBar);
- QString commands = expand(stringSetting(GdbPostAttachCommands));
- if (!commands.isEmpty())
- runCommand({commands, NativeCommand});
- handleInferiorPrepared();
- } else {
- // 16^error,msg="hd:5555: Connection timed out."
- notifyInferiorSetupFailed(msgConnectRemoteServerFailed(response.data["msg"].data()));
- }
-}
-
-void GdbRemoteServerEngine::handleTargetExtendedRemote(const DebuggerResponse &response)
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == ResultDone) {
- showMessage("ATTACHED TO GDB SERVER STARTED");
- showMessage(msgAttachedToStoppedInferior(), StatusBar);
- QString commands = expand(stringSetting(GdbPostAttachCommands));
- if (!commands.isEmpty())
- runCommand({commands, NativeCommand});
- if (runParameters().attachPID.isValid()) { // attach to pid if valid
- // gdb server will stop the remote application itself.
- runCommand({"attach " + QString::number(runParameters().attachPID.pid()),
- CB(handleTargetExtendedAttach)});
- } else if (!runParameters().inferior.executable.isEmpty()) {
- runCommand({"-gdb-set remote exec-file " + runParameters().inferior.executable,
- CB(handleTargetExtendedAttach)});
- } else {
- const QString title = tr("No Remote Executable or Process ID Specified");
- const QString msg = tr(
- "No remote executable could be determined from your build system files.<p>"
- "In case you use qmake, consider adding<p>"
- "&nbsp;&nbsp;&nbsp;&nbsp;target.path = /tmp/your_executable # path on device<br>"
- "&nbsp;&nbsp;&nbsp;&nbsp;INSTALLS += target</p>"
- "to your .pro file.");
- QMessageBox *mb = showMessageBox(QMessageBox::Critical, title, msg,
- QMessageBox::Ok | QMessageBox::Cancel);
- mb->button(QMessageBox::Cancel)->setText(tr("Continue Debugging"));
- mb->button(QMessageBox::Ok)->setText(tr("Stop Debugging"));
- if (mb->exec() == QMessageBox::Ok) {
- showMessage("KILLING DEBUGGER AS REQUESTED BY USER");
- notifyInferiorSetupFailed(title);
- } else {
- showMessage("CONTINUE DEBUGGER AS REQUESTED BY USER");
- handleInferiorPrepared(); // This will likely fail.
- }
- }
- } else {
- notifyInferiorSetupFailed(msgConnectRemoteServerFailed(response.data["msg"].data()));
- }
-}
-
-void GdbRemoteServerEngine::handleTargetExtendedAttach(const DebuggerResponse &response)
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == ResultDone) {
- // gdb server will stop the remote application itself.
- handleInferiorPrepared();
- } else {
- notifyInferiorSetupFailed(msgConnectRemoteServerFailed(response.data["msg"].data()));
- }
-}
-
-void GdbRemoteServerEngine::handleTargetQnx(const DebuggerResponse &response)
-{
- QTC_ASSERT(m_isQnxGdb, qDebug() << m_isQnxGdb);
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- if (response.resultClass == ResultDone) {
- // gdb server will stop the remote application itself.
- showMessage("INFERIOR STARTED");
- showMessage(msgAttachedToStoppedInferior(), StatusBar);
-
- const DebuggerRunParameters &rp = isMasterEngine() ? runParameters() : masterEngine()->runParameters();
- const QString remoteExecutable = rp.inferior.executable;
- if (rp.attachPID.isValid())
- runCommand({"attach " + QString::number(rp.attachPID.pid()), CB(handleAttach)});
- else if (!remoteExecutable.isEmpty())
- runCommand({"set nto-executable " + remoteExecutable, CB(handleSetNtoExecutable)});
- else
- handleInferiorPrepared();
- } else {
- // 16^error,msg="hd:5555: Connection timed out."
- notifyInferiorSetupFailed(response.data["msg"].data());
- }
-}
-
-void GdbRemoteServerEngine::handleAttach(const DebuggerResponse &response)
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- switch (response.resultClass) {
- case ResultDone:
- case ResultRunning: {
- showMessage("INFERIOR ATTACHED");
- showMessage(msgAttachedToStoppedInferior(), StatusBar);
- handleInferiorPrepared();
- break;
- }
- case ResultError:
- if (response.data["msg"].data() == "ptrace: Operation not permitted.") {
- notifyInferiorSetupFailed(msgPtraceError(runParameters().startMode));
- break;
- }
- Q_FALLTHROUGH(); // if msg != "ptrace: ..."
- default:
- notifyInferiorSetupFailed(response.data["msg"].data());
- }
-}
-
-void GdbRemoteServerEngine::handleSetNtoExecutable(const DebuggerResponse &response)
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- switch (response.resultClass) {
- case ResultDone:
- case ResultRunning: {
- showMessage("EXECUTABLE SET");
- showMessage(msgAttachedToStoppedInferior(), StatusBar);
- handleInferiorPrepared();
- break;
- }
- case ResultError:
- default:
- notifyInferiorSetupFailed(response.data["msg"].data());
- }
-}
-
-void GdbRemoteServerEngine::runEngine()
-{
- QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
-
- if (runParameters().useContinueInsteadOfRun) {
- notifyEngineRunAndInferiorStopOk();
- continueInferiorInternal();
- } else {
- runCommand({"-exec-run", DebuggerCommand::RunRequest, CB(handleExecRun)});
- }
-}
-
-void GdbRemoteServerEngine::handleExecRun(const DebuggerResponse &response)
-{
- QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
- if (response.resultClass == ResultRunning) {
- notifyEngineRunAndInferiorRunOk();
- showMessage("INFERIOR STARTED");
- showMessage(msgInferiorSetupOk(), StatusBar);
- } else {
- showMessage(response.data["msg"].data());
- notifyEngineRunFailed();
- }
-}
-
-void GdbRemoteServerEngine::interruptInferior2()
-{
- QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
- if (usesTargetAsync()) {
- runCommand({"-exec-interrupt", CB(handleInterruptInferior)});
- } else if (m_isQnxGdb && HostOsInfo::isWindowsHost()) {
- m_gdbProc.interrupt();
- } else {
- qint64 pid = m_gdbProc.processId();
- bool ok = interruptProcess(pid, GdbEngineType, &m_errorString);
- if (!ok) {
- // FIXME: Extra state needed?
- showMessage("NOTE: INFERIOR STOP NOT POSSIBLE");
- showStatusMessage(tr("Interrupting not possible"));
- notifyInferiorRunOk();
- }
- }
-}
-
-void GdbRemoteServerEngine::handleInterruptInferior(const DebuggerResponse &response)
-{
- if (response.resultClass == ResultDone) {
- // The gdb server will trigger extra output that we will pick up
- // to do a proper state transition.
- } else {
- // FIXME: On some gdb versions like git 170ffa5d7dd this produces
- // >810^error,msg="mi_cmd_exec_interrupt: Inferior not executing."
- notifyInferiorStopOk();
- }
-}
-
-void GdbRemoteServerEngine::shutdownEngine()
-{
- notifyAdapterShutdownOk();
-}
-
-} // namespace Internal
-} // namespace Debugger
diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.h b/src/plugins/debugger/gdb/remotegdbserveradapter.h
deleted file mode 100644
index 0f042b669a2..00000000000
--- a/src/plugins/debugger/gdb/remotegdbserveradapter.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "gdbengine.h"
-
-namespace Debugger {
-namespace Internal {
-
-class GdbRemoteServerEngine : public GdbEngine
-{
- Q_OBJECT
-
-public:
- explicit GdbRemoteServerEngine(bool useTerminal);
-
-private:
- void setupEngine() override;
- void setupInferior() override;
- void runEngine() override;
- void interruptInferior2() override;
- void shutdownEngine() override;
-
- void readUploadStandardOutput();
- void readUploadStandardError();
- void uploadProcError(QProcess::ProcessError error);
- void uploadProcFinished();
- void callTargetRemote();
-
- void handleSetTargetAsync(const DebuggerResponse &response);
- void handleFileExecAndSymbols(const DebuggerResponse &response);
- void handleTargetRemote(const DebuggerResponse &response);
- void handleTargetExtendedRemote(const DebuggerResponse &response);
- void handleTargetExtendedAttach(const DebuggerResponse &response);
- void handleTargetQnx(const DebuggerResponse &response);
- void handleAttach(const DebuggerResponse &response);
- void handleSetNtoExecutable(const DebuggerResponse &response);
- void handleInterruptInferior(const DebuggerResponse &response);
- void handleExecRun(const DebuggerResponse &response);
-
- QProcess m_uploadProc;
-};
-
-} // namespace Internal
-} // namespace Debugger
diff --git a/src/plugins/debugger/gdb/startgdbserverdialog.cpp b/src/plugins/debugger/gdb/startgdbserverdialog.cpp
index 1a583f6f5c9..7a0c8c65e3f 100644
--- a/src/plugins/debugger/gdb/startgdbserverdialog.cpp
+++ b/src/plugins/debugger/gdb/startgdbserverdialog.cpp
@@ -207,14 +207,18 @@ void GdbServerStarter::attach(int port)
return;
}
- DebuggerRunParameters rp;
- rp.masterEngineType = GdbEngineType;
- rp.remoteChannel = QString("%1:%2").arg(d->device->sshParameters().host).arg(port);
- rp.displayName = tr("Remote: \"%1\"").arg(rp.remoteChannel);
- rp.inferior.executable = localExecutable;
- rp.startMode = AttachToRemoteServer;
- rp.closeMode = KillAtClose;
- createAndScheduleRun(rp, d->kit);
+ QString remoteChannel = QString("%1:%2").arg(d->device->sshParameters().host).arg(port);
+
+ auto debugger = DebuggerRunTool::createFromKit(d->kit);
+ QTC_ASSERT(debugger, return);
+ debugger->setMasterEngineType(GdbEngineType);
+ debugger->setRemoteChannel(remoteChannel);
+ debugger->setRunControlName(tr("Remote: \"%1\"").arg(remoteChannel));
+ debugger->setInferiorExecutable(localExecutable);
+ debugger->setStartMode(AttachToRemoteServer);
+ debugger->setCloseMode(KillAtClose);
+
+ debugger->startRunControl();
}
void GdbServerStarter::handleProcessClosed(int status)
diff --git a/src/plugins/debugger/gdb/termgdbadapter.cpp b/src/plugins/debugger/gdb/termgdbadapter.cpp
deleted file mode 100644
index 60a66cb9f7a..00000000000
--- a/src/plugins/debugger/gdb/termgdbadapter.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "termgdbadapter.h"
-
-#include <debugger/debuggercore.h>
-#include <debugger/debuggerprotocol.h>
-#include <debugger/debuggerstartparameters.h>
-#include <debugger/shared/hostutils.h>
-
-#include <utils/hostosinfo.h>
-#include <utils/qtcassert.h>
-#include <coreplugin/icore.h>
-#include <coreplugin/messagebox.h>
-
-using namespace Utils;
-
-namespace Debugger {
-namespace Internal {
-
-///////////////////////////////////////////////////////////////////////
-//
-// TermGdbAdapter
-//
-///////////////////////////////////////////////////////////////////////
-
-GdbTermEngine::GdbTermEngine(bool useTerminal)
- : GdbEngine(useTerminal)
-{
- if (HostOsInfo::isWindowsHost()) {
- // Windows up to xp needs a workaround for attaching to freshly started processes. see proc_stub_win
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
- m_stubProc.setMode(ConsoleProcess::Suspend);
- else
- m_stubProc.setMode(ConsoleProcess::Debug);
- } else {
- m_stubProc.setMode(ConsoleProcess::Debug);
- m_stubProc.setSettings(Core::ICore::settings());
- }
-}
-
-GdbTermEngine::~GdbTermEngine()
-{
- m_stubProc.disconnect(); // Avoid spurious state transitions from late exiting stub
-}
-
-void GdbTermEngine::setupEngine()
-{
- QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
- showMessage("TRYING TO START ADAPTER");
-
-// Currently, adapters are not re-used
-// // We leave the console open, so recycle it now.
-// m_stubProc.blockSignals(true);
-// m_stubProc.stop();
-// m_stubProc.blockSignals(false);
-
- if (!prepareCommand())
- return;
-
- m_stubProc.setWorkingDirectory(runParameters().inferior.workingDirectory);
- // Set environment + dumper preload.
- m_stubProc.setEnvironment(runParameters().stubEnvironment);
-
- connect(&m_stubProc, &ConsoleProcess::processError,
- this, &GdbTermEngine::stubError);
- connect(&m_stubProc, &ConsoleProcess::processStarted,
- this, &GdbTermEngine::stubStarted);
- connect(&m_stubProc, &ConsoleProcess::stubStopped,
- this, &GdbTermEngine::stubExited);
- // FIXME: Starting the stub implies starting the inferior. This is
- // fairly unclean as far as the state machine and error reporting go.
-
- if (!m_stubProc.start(runParameters().inferior.executable,
- runParameters().inferior.commandLineArguments)) {
- // Error message for user is delivered via a signal.
- handleAdapterStartFailed(QString());
- return;
- }
-}
-
-void GdbTermEngine::stubStarted()
-{
- startGdb();
-}
-
-void GdbTermEngine::handleGdbStartFailed()
-{
- m_stubProc.stop();
-}
-
-void GdbTermEngine::setupInferior()
-{
- QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
- const qint64 attachedPID = m_stubProc.applicationPID();
- const qint64 attachedMainThreadID = m_stubProc.applicationMainThreadID();
- notifyInferiorPid(ProcessHandle(attachedPID));
- const QString msg = (attachedMainThreadID != -1)
- ? QString("Going to attach to %1 (%2)").arg(attachedPID).arg(attachedMainThreadID)
- : QString("Going to attach to %1").arg(attachedPID);
- showMessage(msg, LogMisc);
- handleInferiorPrepared();
-}
-
-void GdbTermEngine::runEngine()
-{
- QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
- const qint64 attachedPID = m_stubProc.applicationPID();
- runCommand({"attach " + QString::number(attachedPID),
- [this](const DebuggerResponse &r) { handleStubAttached(r); }});
-}
-
-void GdbTermEngine::handleStubAttached(const DebuggerResponse &response)
-{
- // InferiorStopOk can happen if the "*stopped" in response to the
- // 'attach' comes in before its '^done'
- QTC_ASSERT(state() == EngineRunRequested || state() == InferiorStopOk,
- qDebug() << state());
-
- switch (response.resultClass) {
- case ResultDone:
- case ResultRunning:
- if (runParameters().toolChainAbi.os() == ProjectExplorer::Abi::WindowsOS) {
- QString errorMessage;
- // Resume thread that was suspended by console stub process (see stub code).
- const qint64 mainThreadId = m_stubProc.applicationMainThreadID();
- if (winResumeThread(mainThreadId, &errorMessage)) {
- showMessage(QString("Inferior attached, thread %1 resumed").
- arg(mainThreadId), LogMisc);
- } else {
- showMessage(QString("Inferior attached, unable to resume thread %1: %2").
- arg(mainThreadId).arg(errorMessage),
- LogWarning);
- }
- notifyEngineRunAndInferiorStopOk();
- continueInferiorInternal();
- } else {
- showMessage("INFERIOR ATTACHED AND RUNNING");
- //notifyEngineRunAndInferiorRunOk();
- // Wait for the upcoming *stopped and handle it there.
- }
- break;
- case ResultError:
- if (response.data["msg"].data() == "ptrace: Operation not permitted.") {
- showMessage(msgPtraceError(runParameters().startMode));
- notifyEngineRunFailed();
- break;
- }
- showMessage(response.data["msg"].data());
- notifyEngineIll();
- break;
- default:
- showMessage(QString("Invalid response %1").arg(response.resultClass));
- notifyEngineIll();
- break;
- }
-}
-
-void GdbTermEngine::interruptInferior2()
-{
- interruptLocalInferior(inferiorPid());
-}
-
-void GdbTermEngine::stubError(const QString &msg)
-{
- Core::AsynchronousMessageBox::critical(tr("Debugger Error"), msg);
- notifyEngineIll();
-}
-
-void GdbTermEngine::stubExited()
-{
- if (state() == EngineShutdownRequested || state() == DebuggerFinished) {
- showMessage("STUB EXITED EXPECTEDLY");
- return;
- }
- showMessage("STUB EXITED");
- notifyEngineIll();
-}
-
-void GdbTermEngine::shutdownEngine()
-{
- notifyAdapterShutdownOk();
-}
-
-} // namespace Internal
-} // namespace Debugger
diff --git a/src/plugins/debugger/gdb/termgdbadapter.h b/src/plugins/debugger/gdb/termgdbadapter.h
deleted file mode 100644
index 73a2413637b..00000000000
--- a/src/plugins/debugger/gdb/termgdbadapter.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "gdbengine.h"
-
-#include <utils/consoleprocess.h>
-
-namespace Debugger {
-namespace Internal {
-
-///////////////////////////////////////////////////////////////////////
-//
-// TermGdbAdapter
-//
-///////////////////////////////////////////////////////////////////////
-
-class GdbTermEngine : public GdbEngine
-{
- Q_OBJECT
-
-public:
- explicit GdbTermEngine(bool useTerminal);
- ~GdbTermEngine() override;
-
-private:
- void setupEngine() override;
- void handleGdbStartFailed() override;
- void setupInferior() override;
- void runEngine() override;
- void interruptInferior2() override;
- void shutdownEngine() override;
-
- void handleStubAttached(const DebuggerResponse &response);
-
- void stubStarted();
- void stubExited();
- void stubError(const QString &msg);
-
- Utils::ConsoleProcess m_stubProc;
-};
-
-} // namespace Internal
-} // namespace Debugger
diff --git a/src/plugins/debugger/images/debugger_continue.png b/src/plugins/debugger/images/debugger_continue.png
index 6ec4eddc1a1..e15d7e72624 100644
--- a/src/plugins/debugger/images/debugger_continue.png
+++ b/src/plugins/debugger/images/debugger_continue.png
Binary files differ
diff --git a/src/plugins/debugger/images/debugger_continue@2x.png b/src/plugins/debugger/images/debugger_continue@2x.png
index 69552eb9808..d28c87d835b 100644
--- a/src/plugins/debugger/images/debugger_continue@2x.png
+++ b/src/plugins/debugger/images/debugger_continue@2x.png
Binary files differ
diff --git a/src/plugins/debugger/images/debugger_continue_1_mask.png b/src/plugins/debugger/images/debugger_continue_1_mask.png
index 522e5f36cc3..1f5c0c56551 100644
--- a/src/plugins/debugger/images/debugger_continue_1_mask.png
+++ b/src/plugins/debugger/images/debugger_continue_1_mask.png
Binary files differ
diff --git a/src/plugins/debugger/images/debugger_continue_1_mask@2x.png b/src/plugins/debugger/images/debugger_continue_1_mask@2x.png
index 217ddc826f7..e3e06daa9d2 100644
--- a/src/plugins/debugger/images/debugger_continue_1_mask@2x.png
+++ b/src/plugins/debugger/images/debugger_continue_1_mask@2x.png
Binary files differ
diff --git a/src/plugins/debugger/images/debugger_continue_2_mask.png b/src/plugins/debugger/images/debugger_continue_2_mask.png
index 756ba959f03..8b83259ed13 100644
--- a/src/plugins/debugger/images/debugger_continue_2_mask.png
+++ b/src/plugins/debugger/images/debugger_continue_2_mask.png
Binary files differ
diff --git a/src/plugins/debugger/images/debugger_continue_2_mask@2x.png b/src/plugins/debugger/images/debugger_continue_2_mask@2x.png
index a4801fa6bac..860f76ca187 100644
--- a/src/plugins/debugger/images/debugger_continue_2_mask@2x.png
+++ b/src/plugins/debugger/images/debugger_continue_2_mask@2x.png
Binary files differ
diff --git a/src/plugins/debugger/images/debugger_interrupt.png b/src/plugins/debugger/images/debugger_interrupt.png
index f61bf0881b9..fccdf1149ef 100644
--- a/src/plugins/debugger/images/debugger_interrupt.png
+++ b/src/plugins/debugger/images/debugger_interrupt.png
Binary files differ
diff --git a/src/plugins/debugger/images/debugger_interrupt@2x.png b/src/plugins/debugger/images/debugger_interrupt@2x.png
index 6c99c073db4..8e493ca1f25 100644
--- a/src/plugins/debugger/images/debugger_interrupt@2x.png
+++ b/src/plugins/debugger/images/debugger_interrupt@2x.png
Binary files differ
diff --git a/src/plugins/debugger/images/debugger_interrupt_mask.png b/src/plugins/debugger/images/debugger_interrupt_mask.png
index 87f195f5c08..52f4f275b9f 100644
--- a/src/plugins/debugger/images/debugger_interrupt_mask.png
+++ b/src/plugins/debugger/images/debugger_interrupt_mask.png
Binary files differ
diff --git a/src/plugins/debugger/images/debugger_interrupt_mask@2x.png b/src/plugins/debugger/images/debugger_interrupt_mask@2x.png
index 6c477085d7b..c7794000177 100644
--- a/src/plugins/debugger/images/debugger_interrupt_mask@2x.png
+++ b/src/plugins/debugger/images/debugger_interrupt_mask@2x.png
Binary files differ
diff --git a/src/plugins/debugger/images/mode_debug.png b/src/plugins/debugger/images/mode_debug.png
index 55bdf6bc501..32a93258f1a 100644
--- a/src/plugins/debugger/images/mode_debug.png
+++ b/src/plugins/debugger/images/mode_debug.png
Binary files differ
diff --git a/src/plugins/debugger/images/mode_debug@2x.png b/src/plugins/debugger/images/mode_debug@2x.png
index 0dc56c6d93c..2bb24b99eef 100644
--- a/src/plugins/debugger/images/mode_debug@2x.png
+++ b/src/plugins/debugger/images/mode_debug@2x.png
Binary files differ
diff --git a/src/plugins/debugger/images/mode_debug_mask.png b/src/plugins/debugger/images/mode_debug_mask.png
index ed72f606c44..fe7b6819a5b 100644
--- a/src/plugins/debugger/images/mode_debug_mask.png
+++ b/src/plugins/debugger/images/mode_debug_mask.png
Binary files differ
diff --git a/src/plugins/debugger/images/mode_debug_mask@2x.png b/src/plugins/debugger/images/mode_debug_mask@2x.png
index 510c817c821..5340947ec75 100644
--- a/src/plugins/debugger/images/mode_debug_mask@2x.png
+++ b/src/plugins/debugger/images/mode_debug_mask@2x.png
Binary files differ
diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp
index 256f3ce4eeb..bf00138e9b4 100644
--- a/src/plugins/debugger/lldb/lldbengine.cpp
+++ b/src/plugins/debugger/lldb/lldbengine.cpp
@@ -31,7 +31,6 @@
#include <debugger/debuggerinternalconstants.h>
#include <debugger/debuggermainwindow.h>
#include <debugger/debuggerprotocol.h>
-#include <debugger/debuggerstartparameters.h>
#include <debugger/debuggertooltipmanager.h>
#include <debugger/breakhandler.h>
@@ -161,28 +160,13 @@ void LldbEngine::shutdownEngine()
notifyEngineShutdownOk();
}
-void LldbEngine::abortDebugger()
+void LldbEngine::abortDebuggerProcess()
{
- if (isDying()) {
- // We already tried. Try harder.
- showMessage("ABORTING DEBUGGER. SECOND TIME.");
- m_lldbProc.kill();
- } else {
- // Be friendly the first time. This will change targetState().
- showMessage("ABORTING DEBUGGER. FIRST TIME.");
- quitDebugger();
- }
+ m_lldbProc.kill();
}
void LldbEngine::setupEngine()
{
- // FIXME: We can't handle terminals yet.
- if (runParameters().useTerminal) {
- qWarning("Run in Terminal is not supported yet with the LLDB backend");
- showMessage(tr("Run in Terminal is not supported with the LLDB backend."), AppError);
- runParameters().useTerminal = false;
- }
-
if (runParameters().useTerminal) {
QTC_CHECK(false); // See above.
if (HostOsInfo::isWindowsHost()) {
@@ -205,9 +189,6 @@ void LldbEngine::setupEngine()
// m_stubProc.stop();
// m_stubProc.blockSignals(false);
- if (!prepareCommand())
- return;
-
m_stubProc.setWorkingDirectory(runParameters().inferior.workingDirectory);
// Set environment + dumper preload.
m_stubProc.setEnvironment(runParameters().stubEnvironment);
@@ -584,7 +565,7 @@ void LldbEngine::removeBreakpoint(Breakpoint bp)
if (response.id.isValid()) {
DebuggerCommand cmd("removeBreakpoint");
cmd.arg("lldbid", response.id.toString());
- cmd.callback = [this, bp](const DebuggerResponse &) {
+ cmd.callback = [bp](const DebuggerResponse &) {
QTC_CHECK(bp.state() == BreakpointRemoveProceeding);
Breakpoint bp0 = bp;
bp0.notifyBreakpointRemoveOk();
@@ -689,7 +670,7 @@ void LldbEngine::requestModuleSymbols(const QString &moduleName)
{
DebuggerCommand cmd("fetchSymbols");
cmd.arg("module", moduleName);
- cmd.callback = [this, moduleName](const DebuggerResponse &response) {
+ cmd.callback = [moduleName](const DebuggerResponse &response) {
const GdbMi &symbols = response.data["symbols"];
QString moduleName = response.data["module"].data();
Symbols syms;
@@ -1053,7 +1034,7 @@ void LldbEngine::fetchMemory(MemoryAgent *agent, quint64 addr, quint64 length)
DebuggerCommand cmd("fetchMemory");
cmd.arg("address", addr);
cmd.arg("length", length);
- cmd.callback = [this, agent](const DebuggerResponse &response) {
+ cmd.callback = [agent](const DebuggerResponse &response) {
qulonglong addr = response.data["address"].toAddress();
QByteArray ba = QByteArray::fromHex(response.data["contents"].data().toUtf8());
agent->addData(addr, ba);
@@ -1067,7 +1048,7 @@ void LldbEngine::changeMemory(MemoryAgent *agent, quint64 addr, const QByteArray
DebuggerCommand cmd("writeMemory");
cmd.arg("address", addr);
cmd.arg("data", QString::fromUtf8(data.toHex()));
- cmd.callback = [this](const DebuggerResponse &response) { Q_UNUSED(response); };
+ cmd.callback = [](const DebuggerResponse &response) { Q_UNUSED(response); };
runCommand(cmd);
}
diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h
index 19932d56c76..dff437497b6 100644
--- a/src/plugins/debugger/lldb/lldbengine.h
+++ b/src/plugins/debugger/lldb/lldbengine.h
@@ -78,7 +78,7 @@ private:
void runEngine() override;
void shutdownInferior() override;
void shutdownEngine() override;
- void abortDebugger() override;
+ void abortDebuggerProcess() override;
bool canHandleToolTip(const DebuggerToolTipContext &) const override;
diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp
index d0e8d876363..8b0b1bf271a 100644
--- a/src/plugins/debugger/loadcoredialog.cpp
+++ b/src/plugins/debugger/loadcoredialog.cpp
@@ -25,14 +25,14 @@
#include "loadcoredialog.h"
-#include "debuggerstartparameters.h"
#include "debuggerdialogs.h"
#include "debuggerkitinformation.h"
-#include "gdb/coregdbadapter.h"
+#include "gdb/gdbengine.h"
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <ssh/sftpfilesystemmodel.h>
+#include <ssh/sshconnection.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/temporaryfile.h>
@@ -364,7 +364,7 @@ void AttachCoreDialog::coreFileChanged(const QString &core)
Kit *k = d->kitChooser->currentKit();
QTC_ASSERT(k, return);
StandardRunnable debugger = DebuggerKitInformation::runnable(k);
- GdbCoreEngine::CoreInfo cinfo = GdbCoreEngine::readExecutableNameFromCore(debugger, core);
+ CoreInfo cinfo = CoreInfo::readExecutableNameFromCore(debugger, core);
if (!cinfo.foundExecutableName.isEmpty())
d->localExecFileName->setFileName(FileName::fromString(cinfo.foundExecutableName));
else if (!d->localExecFileName->isValid() && !cinfo.rawStringFromCore.isEmpty())
diff --git a/src/plugins/debugger/logwindow.cpp b/src/plugins/debugger/logwindow.cpp
index 22c2e73ed9e..98dc0f91437 100644
--- a/src/plugins/debugger/logwindow.cpp
+++ b/src/plugins/debugger/logwindow.cpp
@@ -43,6 +43,9 @@
#include <QToolButton>
#include <aggregation/aggregate.h>
+
+#include <app/app_version.h>
+
#include <coreplugin/findplaceholder.h>
#include <coreplugin/minisplitter.h>
#include <coreplugin/find/basetextfind.h>
@@ -432,12 +435,13 @@ LogWindow::LogWindow(QWidget *parent)
showOutput(LogWarning,
tr("Note: This log contains possibly confidential information about your machine, "
"environment variables, in-memory data of the processes you are debugging, and more. "
- "It is never transferred over the internet by Qt Creator, and only stored "
+ "It is never transferred over the internet by %1, and only stored "
"to disk if you manually use the respective option from the context menu, or through "
- "mechanisms that are not under Qt Creator's control, for instance in swap files.\n"
+ "mechanisms that are not under the control of %1, for instance in swap files.\n"
"You may be asked to share the contents of this log when reporting bugs related "
"to debugger operation. In this case, make sure your submission does not "
- "contain data you do not want to or you are not allowed to share.\n\n"));
+ "contain data you do not want to or you are not allowed to share.\n\n")
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
}
void LogWindow::executeLine()
diff --git a/src/plugins/debugger/memoryagent.cpp b/src/plugins/debugger/memoryagent.cpp
index 0142d53d4df..8e79ff994e6 100644
--- a/src/plugins/debugger/memoryagent.cpp
+++ b/src/plugins/debugger/memoryagent.cpp
@@ -27,7 +27,6 @@
#include "breakhandler.h"
#include "debuggerengine.h"
-#include "debuggerstartparameters.h"
#include "debuggercore.h"
#include "debuggerinternalconstants.h"
#include "registerhandler.h"
diff --git a/src/plugins/debugger/moduleshandler.cpp b/src/plugins/debugger/moduleshandler.cpp
index e37c44ccbba..5139989b0ef 100644
--- a/src/plugins/debugger/moduleshandler.cpp
+++ b/src/plugins/debugger/moduleshandler.cpp
@@ -196,7 +196,7 @@ bool ModulesModel::contextMenuEvent(const ItemViewEvent &ev)
addAction(menu, tr("Show Dependencies of \"%1\"").arg(moduleName),
tr("Show Dependencies"),
moduleNameValid && !moduleName.isEmpty() && HostOsInfo::isWindowsHost(),
- [this, modulePath] { QProcess::startDetached("depends", {modulePath}); });
+ [modulePath] { QProcess::startDetached("depends", {modulePath}); });
addAction(menu, tr("Load Symbols for All Modules"),
enabled && canLoadSymbols,
diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp
index 6334f18a3a4..5e74ac920e4 100644
--- a/src/plugins/debugger/pdb/pdbengine.cpp
+++ b/src/plugins/debugger/pdb/pdbengine.cpp
@@ -30,7 +30,6 @@
#include <debugger/debuggerdialogs.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerprotocol.h>
-#include <debugger/debuggerstartparameters.h>
#include <debugger/debuggertooltipmanager.h>
#include <debugger/threaddata.h>
diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp
index d8d0a66404e..a5a9810b9ba 100644
--- a/src/plugins/debugger/qml/qmlcppengine.cpp
+++ b/src/plugins/debugger/qml/qmlcppengine.cpp
@@ -29,7 +29,6 @@
#include <debugger/debuggercore.h>
#include <debugger/debuggerruncontrol.h>
#include <debugger/debuggertooltipmanager.h>
-#include <debugger/debuggerstartparameters.h>
#include <debugger/breakhandler.h>
#include <debugger/stackhandler.h>
#include <debugger/threaddata.h>
@@ -378,36 +377,6 @@ void QmlCppEngine::setupEngine()
m_cppEngine->setupSlaveEngine();
}
-void QmlCppEngine::notifyEngineRunAndInferiorRunOk()
-{
- EDEBUG("\nMASTER NOTIFY ENGINE RUN AND INFERIOR RUN OK");
- DebuggerEngine::notifyEngineRunAndInferiorRunOk();
-}
-
-void QmlCppEngine::notifyInferiorRunOk()
-{
- EDEBUG("\nMASTER NOTIFY INFERIOR RUN OK");
- DebuggerEngine::notifyInferiorRunOk();
-}
-
-void QmlCppEngine::notifyInferiorSpontaneousStop()
-{
- EDEBUG("\nMASTER SPONTANEOUS STOP OK");
- DebuggerEngine::notifyInferiorSpontaneousStop();
-}
-
-void QmlCppEngine::notifyInferiorShutdownOk()
-{
- EDEBUG("\nMASTER INFERIOR SHUTDOWN OK");
- DebuggerEngine::notifyInferiorShutdownOk();
-}
-
-void QmlCppEngine::notifyInferiorSetupOk()
-{
- EDEBUG("\nMASTER INFERIOR SETUP OK");
- DebuggerEngine::notifyInferiorSetupOk();
-}
-
void QmlCppEngine::setupInferior()
{
EDEBUG("\nMASTER SETUP INFERIOR");
@@ -441,10 +410,10 @@ void QmlCppEngine::quitDebugger()
m_cppEngine->quitDebugger();
}
-void QmlCppEngine::abortDebugger()
+void QmlCppEngine::abortDebuggerProcess()
{
EDEBUG("\nMASTER ABORT DEBUGGER");
- m_cppEngine->abortDebugger();
+ m_cppEngine->abortDebuggerProcess();
}
void QmlCppEngine::setState(DebuggerState newState, bool forced)
diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h
index 52442d0e898..9dcfb3284a4 100644
--- a/src/plugins/debugger/qml/qmlcppengine.h
+++ b/src/plugins/debugger/qml/qmlcppengine.h
@@ -112,14 +112,8 @@ protected:
void shutdownInferior() override;
void shutdownEngine() override;
void quitDebugger() override;
- void abortDebugger() override;
+ void abortDebuggerProcess() override;
- void notifyInferiorRunOk() override;
- void notifyInferiorSpontaneousStop() override;
- void notifyEngineRunAndInferiorRunOk() override;
- void notifyInferiorShutdownOk() override;
-
- void notifyInferiorSetupOk() override;
void loadAdditionalQmlStack() override;
private:
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index 4dc8280851f..11ffcfd8e4e 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -57,6 +57,7 @@
#include <texteditor/textdocument.h>
#include <texteditor/texteditor.h>
+#include <app/app_version.h>
#include <utils/treemodel.h>
#include <utils/basetreeview.h>
#include <utils/qtcassert.h>
@@ -66,6 +67,7 @@
#include <QDir>
#include <QDockWidget>
#include <QFileInfo>
+#include <QHostAddress>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
@@ -139,15 +141,14 @@ typedef QHash<int, LookupData> LookupItems; // id -> (iname, exp)
class QmlEnginePrivate : public QmlDebugClient
{
public:
- QmlEnginePrivate(QmlEngine *engine_, QmlDebugConnection *connection_)
- : QmlDebugClient("V8Debugger", connection_),
+ QmlEnginePrivate(QmlEngine *engine_, QmlDebugConnection *connection)
+ : QmlDebugClient("V8Debugger", connection),
engine(engine_),
- inspectorAgent(engine, connection_),
- connection(connection_)
+ inspectorAgent(engine, connection)
{}
- void messageReceived(const QByteArray &data);
- void stateChanged(State state);
+ void messageReceived(const QByteArray &data) override;
+ void stateChanged(State state) override;
void continueDebugging(StepAction stepAction);
@@ -189,17 +190,6 @@ public:
void checkForFinishedUpdate();
ConsoleItem *constructLogItemTree(const QmlV8ObjectData &objectData);
- void filterApplicationMessage(ProjectExplorer::RunControl *runControl,
- const QString &msg, Utils::OutputFormat format)
- {
- if (runControl != engine->runControl())
- return;
- if (format == StdErrFormatSameLine
- || format == StdOutFormatSameLine
- || format == DebugFormat)
- outputParser.processOutput(msg);
- }
-
public:
QHash<int, QmlV8ObjectData> refVals; // The mapping of target object handles to retrieved values.
int sequence = -1;
@@ -223,9 +213,7 @@ public:
InteractiveInterpreter interpreter;
ApplicationLauncher applicationLauncher;
QmlInspectorAgent inspectorAgent;
- QmlOutputParser outputParser;
- QTimer noDebugOutputTimer;
QList<quint32> queryIds;
bool retryOnConnectFail = false;
bool automaticConnect = false;
@@ -233,7 +221,6 @@ public:
bool contextEvaluate = false;
QTimer connectionTimer;
- QmlDebug::QmlDebugConnection *connection;
QmlDebug::QDebugMessageClient *msgClient = 0;
QHash<int, QmlCallback> callbackForToken;
@@ -262,6 +249,7 @@ QmlEngine::QmlEngine(bool useTerminal)
: d(new QmlEnginePrivate(this, new QmlDebugConnection(this)))
{
setObjectName("QmlEngine");
+ QmlDebugConnection *connection = d->connection();
connect(stackHandler(), &StackHandler::stackChanged,
this, &QmlEngine::updateCurrentContext);
@@ -277,24 +265,8 @@ QmlEngine::QmlEngine(bool useTerminal)
connect(&d->applicationLauncher, &ApplicationLauncher::processStarted,
this, &QmlEngine::handleLauncherStarted);
- d->outputParser.setNoOutputText(ApplicationLauncher::msgWinCannotRetrieveDebuggingOutput());
- connect(&d->outputParser, &QmlOutputParser::waitingForConnectionOnPort,
- this, &QmlEngine::beginConnection);
- connect(&d->outputParser, &QmlOutputParser::noOutputMessage,
- this, [this] { tryToConnect(); });
- connect(&d->outputParser, &QmlOutputParser::errorMessage,
- this, &QmlEngine::appStartupFailed);
-
- // Only wait 8 seconds for the 'Waiting for connection' on application output,
- // then just try to connect (application output might be redirected / blocked)
- d->noDebugOutputTimer.setSingleShot(true);
- d->noDebugOutputTimer.setInterval(8000);
- connect(&d->noDebugOutputTimer, &QTimer::timeout,
- this, [this] { tryToConnect(); });
-
// we won't get any debug output
if (useTerminal) {
- d->noDebugOutputTimer.setInterval(0);
d->retryOnConnectFail = true;
d->automaticConnect = true;
}
@@ -308,21 +280,21 @@ QmlEngine::QmlEngine(bool useTerminal)
connect(&d->connectionTimer, &QTimer::timeout,
this, &QmlEngine::checkConnectionState);
- connect(d->connection, &QmlDebugConnection::logStateChange,
+ connect(connection, &QmlDebugConnection::logStateChange,
this, &QmlEngine::showConnectionStateMessage);
- connect(d->connection, &QmlDebugConnection::logError, this,
+ connect(connection, &QmlDebugConnection::logError, this,
[this](const QString &error) { showMessage("QML Debugger: " + error, LogWarning); });
- connect(d->connection, &QmlDebugConnection::connectionFailed,
+ connect(connection, &QmlDebugConnection::connectionFailed,
this, &QmlEngine::connectionFailed);
- connect(d->connection, &QmlDebugConnection::connected,
+ connect(connection, &QmlDebugConnection::connected,
&d->connectionTimer, &QTimer::stop);
- connect(d->connection, &QmlDebugConnection::connected,
+ connect(connection, &QmlDebugConnection::connected,
this, &QmlEngine::connectionEstablished);
- connect(d->connection, &QmlDebugConnection::disconnected,
+ connect(connection, &QmlDebugConnection::disconnected,
this, &QmlEngine::disconnected);
- d->msgClient = new QDebugMessageClient(d->connection);
+ d->msgClient = new QDebugMessageClient(connection);
connect(d->msgClient, &QDebugMessageClient::newState,
this, [this](QmlDebugClient::State state) {
logServiceStateChange(d->msgClient->name(), d->msgClient->serviceVersion(), state);
@@ -354,15 +326,6 @@ void QmlEngine::setState(DebuggerState state, bool forced)
updateCurrentContext();
}
-void QmlEngine::setRunTool(DebuggerRunTool *runTool)
-{
- DebuggerEngine::setRunTool(runTool);
-
- d->startupMessageFilterConnection = connect(
- runTool->runControl(), &RunControl::appendMessageRequested,
- d, &QmlEnginePrivate::filterApplicationMessage);
-}
-
void QmlEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
@@ -378,7 +341,7 @@ void QmlEngine::handleLauncherStarted()
// FIXME: The QmlEngine never calls notifyInferiorPid() triggering the
// raising, so do it here manually for now.
runControl()->applicationProcessHandle().activate();
- d->noDebugOutputTimer.start();
+ tryToConnect();
}
void QmlEngine::appMessage(const QString &msg, Utils::OutputFormat /* format */)
@@ -394,29 +357,27 @@ void QmlEngine::connectionEstablished()
notifyEngineRunAndInferiorRunOk();
}
-void QmlEngine::tryToConnect(Utils::Port port)
+void QmlEngine::tryToConnect()
{
- showMessage("QML Debugger: No application output received in time, trying to connect ...", LogStatus);
+ showMessage("QML Debugger: Trying to connect ...", LogStatus);
d->retryOnConnectFail = true;
if (state() == EngineRunRequested) {
if (isSlaveEngine()) {
// Probably cpp is being debugged and hence we did not get the output yet.
if (!masterEngine()->isDying())
- beginConnection(port);
+ beginConnection();
else
appStartupFailed(tr("No application output received in time"));
} else {
- beginConnection(port);
+ beginConnection();
}
} else {
d->automaticConnect = true;
}
}
-void QmlEngine::beginConnection(Utils::Port port)
+void QmlEngine::beginConnection()
{
- d->noDebugOutputTimer.stop();
-
if (state() != EngineRunRequested && d->retryOnConnectFail)
return;
@@ -424,11 +385,12 @@ void QmlEngine::beginConnection(Utils::Port port)
QObject::disconnect(d->startupMessageFilterConnection);
- QString host = runParameters().qmlServer.host;
+ QString host = runParameters().qmlServer.host();
// Use localhost as default
if (host.isEmpty())
host = QHostAddress(QHostAddress::LocalHost).toString();
+ // FIXME: Not needed?
/*
* Let plugin-specific code override the port printed by the application. This is necessary
* in the case of port forwarding, when the port the application listens on is not the same that
@@ -440,13 +402,13 @@ void QmlEngine::beginConnection(Utils::Port port)
* the connection will be closed again (instead of returning the "connection refused"
* error that we expect).
*/
- if (runParameters().qmlServer.port.isValid())
- port = runParameters().qmlServer.port;
+ int port = runParameters().qmlServer.port();
- if (!d->connection || d->connection->isConnected())
+ QmlDebugConnection *connection = d->connection();
+ if (!connection || connection->isConnected())
return;
- d->connection->connectToHost(host, port.number());
+ connection->connectToHost(host, port);
//A timeout to check the connection state
d->connectionTimer.start();
@@ -462,7 +424,7 @@ void QmlEngine::connectionStartupFailed()
QMessageBox *infoBox = new QMessageBox(ICore::mainWindow());
infoBox->setIcon(QMessageBox::Critical);
- infoBox->setWindowTitle(tr("Qt Creator"));
+ infoBox->setWindowTitle(Core::Constants::IDE_DISPLAY_NAME);
infoBox->setText(tr("Could not connect to the in-process QML debugger."
"\nDo you want to retry?"));
infoBox->setStandardButtons(QMessageBox::Retry | QMessageBox::Cancel |
@@ -483,7 +445,7 @@ void QmlEngine::appStartupFailed(const QString &errorMessage)
if (isMasterEngine()) {
QMessageBox *infoBox = new QMessageBox(ICore::mainWindow());
infoBox->setIcon(QMessageBox::Critical);
- infoBox->setWindowTitle(tr("Qt Creator"));
+ infoBox->setWindowTitle(Core::Constants::IDE_DISPLAY_NAME);
infoBox->setText(error);
infoBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Help);
infoBox->setDefaultButton(QMessageBox::Ok);
@@ -552,8 +514,8 @@ void QmlEngine::closeConnection()
if (d->connectionTimer.isActive()) {
d->connectionTimer.stop();
} else {
- if (d->connection)
- d->connection->close();
+ if (QmlDebugConnection *connection = d->connection())
+ connection->close();
}
}
@@ -563,13 +525,13 @@ void QmlEngine::runEngine()
if (!isSlaveEngine()) {
if (runParameters().startMode == AttachToRemoteServer)
- d->noDebugOutputTimer.start();
+ tryToConnect();
else if (runParameters().startMode == AttachToRemoteProcess)
beginConnection();
else
startApplicationLauncher();
} else {
- d->noDebugOutputTimer.start();
+ tryToConnect();
}
}
@@ -594,39 +556,6 @@ void QmlEngine::stopApplicationLauncher()
}
}
-// FIXME: Is the timeout raise still needed? Since the RunWorker conversion,
-// the debugger tool only starts when the remote setup has all interesting
-// ports gathered, so much less chance for waiting on longer operations.
-//void QmlEngine::notifyEngineRemoteSetupFinished()
-//{
-// QObject::disconnect(d->startupMessageFilterConnection);
-// switch (state()) {
-// case InferiorSetupOk:
-// // FIXME: This is not a legal transition, but we need to
-// // get to EngineSetupOk somehow from InferiorSetupOk.
-// // fallthrough. QTCREATORBUG-14089.
-// case EngineSetupRequested:
-// notifyEngineSetupOk();
-// break;
-// case EngineSetupOk:
-// case EngineRunRequested:
-// // QTCREATORBUG-17718: On Android while doing debugging in mixed mode, the QML debug engine
-// // sometimes reports EngineSetupOK after the EngineRunRequested thus overwriting the state
-// // which eventually results into app to waiting for the QML engine connection.
-// // Skipping the EngineSetupOK in aforementioned case.
-// // Nothing to do here. The setup is already done.
-// break;
-// default:
-// QTC_ASSERT(false, qDebug() << "Unexpected state" << state());
-// }
-
-// // The remote setup can take while especialy with mixed debugging.
-// // Just waiting for 8 seconds is not enough. Increase the timeout
-// // to 60 s
-// // In case we get an output the d->outputParser will start the connection.
-// d->noDebugOutputTimer.setInterval(60000);
-//}
-
void QmlEngine::shutdownInferior()
{
// End session.
@@ -649,7 +578,6 @@ void QmlEngine::shutdownEngine()
clearExceptionSelection();
debuggerConsole()->setScriptEvaluator(ScriptEvaluator());
- d->noDebugOutputTimer.stop();
// double check (ill engine?):
stopApplicationLauncher();
@@ -1095,7 +1023,6 @@ bool QmlEngine::hasCapability(unsigned cap) const
void QmlEngine::quitDebugger()
{
- d->noDebugOutputTimer.stop();
d->automaticConnect = false;
d->retryOnConnectFail = false;
shutdownInferior();
@@ -1268,7 +1195,10 @@ void QmlEngine::checkConnectionState()
bool QmlEngine::isConnected() const
{
- return d->connection->isConnected();
+ if (QmlDebugConnection *connection = d->connection())
+ return connection->isConnected();
+ else
+ return false;
}
void QmlEngine::showConnectionStateMessage(const QString &message)
@@ -1526,7 +1456,7 @@ void QmlEnginePrivate::setBreakpoint(const QString type, const QString target,
// }
// }
if (type == EVENT) {
- QPacket rs(connection->currentDataStreamVersion());
+ QPacket rs(dataStreamVersion());
rs << target.toUtf8() << enabled;
engine->showMessage(QString("%1 %2 %3")
.arg(BREAKONSIGNAL, target, QLatin1String(enabled ? "enabled" : "disabled")), LogInput);
@@ -1746,7 +1676,7 @@ void QmlEnginePrivate::runDirectCommand(const QString &type, const QByteArray &m
engine->showMessage(QString("%1 %2").arg(type, QString::fromLatin1(msg)), LogInput);
- QPacket rs(connection->currentDataStreamVersion());
+ QPacket rs(dataStreamVersion());
rs << cmd << type.toLatin1() << msg;
if (state() == Enabled)
@@ -1768,7 +1698,7 @@ void QmlEnginePrivate::memorizeRefs(const QVariant &refs)
void QmlEnginePrivate::messageReceived(const QByteArray &data)
{
- QPacket ds(connection->currentDataStreamVersion(), data);
+ QPacket ds(dataStreamVersion(), data);
QByteArray command;
ds >> command;
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index 1319f98e56a..9e95d0041c2 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -46,8 +46,6 @@ public:
explicit QmlEngine(bool useTerminal);
~QmlEngine() override;
- void setRunTool(DebuggerRunTool *runTool) override;
-
void logServiceStateChange(const QString &service, float version,
QmlDebug::QmlDebugClient::State newState);
void logServiceActivity(const QString &service, const QString &logMessage);
@@ -59,8 +57,8 @@ private:
void errorMessageBoxFinished(int result);
void updateCurrentContext();
- void tryToConnect(Utils::Port port = Utils::Port());
- void beginConnection(Utils::Port port = Utils::Port());
+ void tryToConnect();
+ void beginConnection();
void handleLauncherStarted();
void connectionEstablished();
void connectionStartupFailed();
diff --git a/src/plugins/debugger/registerhandler.cpp b/src/plugins/debugger/registerhandler.cpp
index 0cf5de70c74..5ae39c1af5f 100644
--- a/src/plugins/debugger/registerhandler.cpp
+++ b/src/plugins/debugger/registerhandler.cpp
@@ -742,8 +742,10 @@ bool RegisterHandler::contextMenuEvent(const ItemViewEvent &ev)
? registerSubItem->parent()->m_format
: HexadecimalFormat;
- auto addFormatAction = [this, menu, currentFormat, registerItem](const QString &display, RegisterFormat format) {
- addCheckableAction(menu, display, registerItem, currentFormat == format, [this, registerItem, format] {
+ auto addFormatAction =
+ [menu, currentFormat, registerItem](const QString &display, RegisterFormat format) {
+ addCheckableAction(menu, display, registerItem, currentFormat == format,
+ [registerItem, format] {
registerItem->m_format = format;
registerItem->update();
});
diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp
index 0afb0ba9bca..a4f6c650e20 100644
--- a/src/plugins/debugger/stackhandler.cpp
+++ b/src/plugins/debugger/stackhandler.cpp
@@ -418,7 +418,7 @@ bool StackHandler::contextMenuEvent(const ItemViewEvent &ev)
});
addAction(menu, tr("Disassemble Function..."), true,
- [this, address] {
+ [this] {
const StackFrame frame = inputFunctionForDisassembly();
if (!frame.function.isEmpty())
m_engine->openDisassemblerView(Location(frame));
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index 32aaa3bbc02..96194f869a9 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -46,6 +46,7 @@
#include <texteditor/syntaxhighlighter.h>
+#include <app/app_version.h>
#include <utils/algorithm.h>
#include <utils/basetreeview.h>
#include <utils/checkablemessagebox.h>
@@ -271,7 +272,7 @@ public:
setTabsClosable(true);
connect(this, &QTabWidget::tabCloseRequested, this, &SeparatedView::closeTab);
setWindowFlags(windowFlags() | Qt::Window);
- setWindowTitle(WatchHandler::tr("Debugger - Qt Creator"));
+ setWindowTitle(WatchHandler::tr("Debugger - %1").arg(Core::Constants::IDE_DISPLAY_NAME));
QVariant geometry = sessionValue("DebuggerSeparateWidgetGeometry");
if (geometry.isValid()) {
@@ -516,7 +517,7 @@ void WatchModel::reinitialize(bool includeInspectData)
WatchItem *WatchModel::findItem(const QString &iname) const
{
- return findNonRooItem([iname](WatchItem *item) { return item->iname == iname; });
+ return findNonRootItem([iname](WatchItem *item) { return item->iname == iname; });
}
static QString parentName(const QString &iname)
@@ -1678,7 +1679,7 @@ bool WatchModel::contextMenuEvent(const ItemViewEvent &ev)
addAction(menu, tr("Close Editor Tooltips"),
DebuggerToolTipManager::hasToolTips(),
- [this] { DebuggerToolTipManager::closeAllToolTips(); });
+ [] { DebuggerToolTipManager::closeAllToolTips(); });
addAction(menu, tr("Copy View Contents to Clipboard"),
true,
@@ -1686,7 +1687,7 @@ bool WatchModel::contextMenuEvent(const ItemViewEvent &ev)
addAction(menu, tr("Copy Current Value to Clipboard"),
item,
- [this, item] { copyToClipboard(item->value); });
+ [item] { copyToClipboard(item->value); });
// addAction(menu, tr("Copy Selected Rows to Clipboard"),
// selectionModel()->hasSelection(),
@@ -1790,7 +1791,7 @@ QMenu *WatchModel::createMemoryMenu(WatchItem *item)
addAction(menu, tr("Open Memory Editor Showing Stack Layout"),
item && item->isLocal(),
- [this, item, pos] { addStackLayoutMemoryView(false, pos); });
+ [this, pos] { addStackLayoutMemoryView(false, pos); });
addAction(menu, tr("Open Memory Editor..."),
true,
@@ -1834,8 +1835,6 @@ QMenu *WatchModel::createFormatMenu(WatchItem *item)
addBaseChangeAction(tr("Show Unprintable Characters as Octal"), 8);
addBaseChangeAction(tr("Show Unprintable Characters as Hexadecimal"), 16);
- QAction *act = 0;
-
const QString spacer = " ";
menu->addSeparator();
@@ -1857,7 +1856,7 @@ QMenu *WatchModel::createFormatMenu(WatchItem *item)
for (int format : alternativeFormats) {
addCheckableAction(menu, spacer + nameForFormat(format), true, format == individualFormat,
- [this, act, format, iname] {
+ [this, format, iname] {
setIndividualFormat(iname, format);
m_engine->updateLocals();
});
@@ -1877,7 +1876,7 @@ QMenu *WatchModel::createFormatMenu(WatchItem *item)
for (int format : alternativeFormats) {
addCheckableAction(menu, spacer + nameForFormat(format), true, format == typeFormat,
- [this, act, format, item] {
+ [this, format, item] {
setTypeFormat(item->type, format);
m_engine->updateLocals();
});
@@ -2093,7 +2092,7 @@ void WatchHandler::notifyUpdateStarted(const UpdateParameters &updateParameters)
void WatchHandler::notifyUpdateFinished()
{
QList<WatchItem *> toRemove;
- m_model->forSelectedItems([this, &toRemove](WatchItem *item) {
+ m_model->forSelectedItems([&toRemove](WatchItem *item) {
if (item->outdated) {
toRemove.append(item);
return false;
diff --git a/src/plugins/designer/formeditorplugin.cpp b/src/plugins/designer/formeditorplugin.cpp
index 8a4f0af3de7..a0fc7c47a2c 100644
--- a/src/plugins/designer/formeditorplugin.cpp
+++ b/src/plugins/designer/formeditorplugin.cpp
@@ -82,7 +82,7 @@ bool FormEditorPlugin::initialize(const QStringList &arguments, QString *error)
#ifdef CPP_ENABLED
IWizardFactory::registerFactoryCreator(
- [this]() -> QList<IWizardFactory *> {
+ []() -> QList<IWizardFactory *> {
IWizardFactory *wizard = new FormClassWizard;
wizard->setCategory(QLatin1String(Core::Constants::WIZARD_CATEGORY_QT));
wizard->setDisplayCategory(QCoreApplication::translate("Core", Core::Constants::WIZARD_TR_CATEGORY_QT));
diff --git a/src/plugins/diffeditor/diffeditorwidgetcontroller.cpp b/src/plugins/diffeditor/diffeditorwidgetcontroller.cpp
index 6197da5296f..6e7b947bb18 100644
--- a/src/plugins/diffeditor/diffeditorwidgetcontroller.cpp
+++ b/src/plugins/diffeditor/diffeditorwidgetcontroller.cpp
@@ -65,7 +65,7 @@ DiffEditorWidgetController::DiffEditorWidgetController(QWidget *diffEditorWidget
void DiffEditorWidgetController::setDocument(DiffEditorDocument *document)
{
if (!m_progressIndicator) {
- m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicator::Large);
+ m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Large);
m_progressIndicator->attachToWidget(m_diffEditorWidget);
m_progressIndicator->hide();
}
diff --git a/src/plugins/diffeditor/differ.cpp b/src/plugins/diffeditor/differ.cpp
index 63a0014d372..3dd8d90dd3e 100644
--- a/src/plugins/diffeditor/differ.cpp
+++ b/src/plugins/diffeditor/differ.cpp
@@ -1275,7 +1275,7 @@ QStringList Differ::encode(const QString &text1,
QString *encodedText2)
{
QStringList lines;
- lines.append(QLatin1String("")); // don't use code: 0
+ lines.append(QString()); // don't use code: 0
QMap<QString, int> lineToCode;
*encodedText1 = encode(text1, &lines, &lineToCode);
diff --git a/src/plugins/fakevim/fakevimoptions.ui b/src/plugins/fakevim/fakevimoptions.ui
index 8db93d585f1..db3cb7df450 100644
--- a/src/plugins/fakevim/fakevimoptions.ui
+++ b/src/plugins/fakevim/fakevimoptions.ui
@@ -92,7 +92,7 @@
<item row="6" column="1">
<widget class="QCheckBox" name="checkBoxPassControlKey">
<property name="toolTip">
- <string>Passes key sequences like Ctrl-S to Qt Creator core instead of interpreting them in FakeVim. This gives easier access to Qt Creator core functionality at the price of losing some features of FakeVim.</string>
+ <string>Does not interpret key sequences like Ctrl-S in FakeVim but handles them as regular shortcuts. This gives easier access to core functionality at the price of losing some features of FakeVim.</string>
</property>
<property name="text">
<string>Pass control key</string>
@@ -123,7 +123,7 @@
<item row="7" column="0">
<widget class="QCheckBox" name="checkBoxPassKeys">
<property name="toolTip">
- <string>Lets Qt Creator handle some key presses in insert mode so that code can be properly completed and expanded.</string>
+ <string>Does not interpret some key presses in insert mode so that code can be properly completed and expanded.</string>
</property>
<property name="text">
<string>Pass keys in insert mode</string>
diff --git a/src/plugins/genericprojectmanager/genericmakestep.cpp b/src/plugins/genericprojectmanager/genericmakestep.cpp
index 8569a994efa..be9f30854de 100644
--- a/src/plugins/genericprojectmanager/genericmakestep.cpp
+++ b/src/plugins/genericprojectmanager/genericmakestep.cpp
@@ -232,7 +232,7 @@ GenericMakeStepConfigWidget::GenericMakeStepConfigWidget(GenericMakeStep *makeSt
m_ui->makeLineEdit->setText(m_makeStep->m_makeCommand);
m_ui->makeArgumentsLineEdit->setText(m_makeStep->m_makeArguments);
- updateMakeOverrrideLabel();
+ updateMakeOverrideLabel();
updateDetails();
connect(m_ui->targetsList, &QListWidget::itemChanged,
@@ -243,17 +243,26 @@ GenericMakeStepConfigWidget::GenericMakeStepConfigWidget(GenericMakeStep *makeSt
this, &GenericMakeStepConfigWidget::makeArgumentsLineEditTextEdited);
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
- this, &GenericMakeStepConfigWidget::updateMakeOverrrideLabel);
+ this, &GenericMakeStepConfigWidget::updateMakeOverrideLabel);
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
this, &GenericMakeStepConfigWidget::updateDetails);
connect(m_makeStep->target(), &Target::kitChanged,
- this, &GenericMakeStepConfigWidget::updateMakeOverrrideLabel);
-
- connect(pro, &GenericProject::environmentChanged,
- this, &GenericMakeStepConfigWidget::updateMakeOverrrideLabel);
- connect(pro, &GenericProject::environmentChanged,
- this, &GenericMakeStepConfigWidget::updateDetails);
+ this, &GenericMakeStepConfigWidget::updateMakeOverrideLabel);
+
+ pro->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
+ if (static_cast<BuildConfiguration *>(sender())->isActive()) {
+ updateMakeOverrideLabel();
+ updateDetails();
+ }
+ });
+ connect(pro, &Project::activeProjectConfigurationChanged,
+ this, [this](ProjectConfiguration *pc) {
+ if (pc && pc->isActive()) {
+ updateMakeOverrideLabel();
+ updateDetails();
+ }
+ });
}
GenericMakeStepConfigWidget::~GenericMakeStepConfigWidget()
@@ -266,7 +275,7 @@ QString GenericMakeStepConfigWidget::displayName() const
return tr("Make", "GenericMakestep display name.");
}
-void GenericMakeStepConfigWidget::updateMakeOverrrideLabel()
+void GenericMakeStepConfigWidget::updateMakeOverrideLabel()
{
BuildConfiguration *bc = m_makeStep->buildConfiguration();
if (!bc)
diff --git a/src/plugins/genericprojectmanager/genericmakestep.h b/src/plugins/genericprojectmanager/genericmakestep.h
index 4228de35eee..de23ffda396 100644
--- a/src/plugins/genericprojectmanager/genericmakestep.h
+++ b/src/plugins/genericprojectmanager/genericmakestep.h
@@ -91,7 +91,7 @@ private:
void itemChanged(QListWidgetItem *item);
void makeLineEditTextEdited();
void makeArgumentsLineEditTextEdited();
- void updateMakeOverrrideLabel();
+ void updateMakeOverrideLabel();
void updateDetails();
Ui::GenericMakeStep *m_ui;
diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp
index 11d57bc6b19..104f52bc052 100644
--- a/src/plugins/genericprojectmanager/genericproject.cpp
+++ b/src/plugins/genericprojectmanager/genericproject.cpp
@@ -126,7 +126,7 @@ public:
bool showInSimpleTree() const override { return true; }
- bool supportsAction(ProjectAction action, Node *) const override
+ bool supportsAction(ProjectAction action, const Node *) const override
{
return action == AddNewFile
|| action == AddExistingFile
@@ -336,6 +336,7 @@ void GenericProject::parseProject(RefreshOptions options)
void GenericProject::refresh(RefreshOptions options)
{
+ emitParsingStarted();
parseProject(options);
if (options & Files) {
@@ -362,7 +363,7 @@ void GenericProject::refresh(RefreshOptions options)
}
refreshCppCodeModel();
- emit parsingFinished();
+ emitParsingFinished(true);
}
/**
@@ -501,7 +502,7 @@ Project::RestoreResult GenericProject::fromMap(const QVariantMap &map, QString *
continue;
}
if (!t->activeRunConfiguration())
- t->addRunConfiguration(new CustomExecutableRunConfiguration(t));
+ t->addRunConfiguration(IRunConfigurationFactory::createHelper<CustomExecutableRunConfiguration>(t));
}
m_activeTarget = activeTarget();
diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.qbs b/src/plugins/genericprojectmanager/genericprojectmanager.qbs
index be30ddffad6..cb062d1f522 100644
--- a/src/plugins/genericprojectmanager/genericprojectmanager.qbs
+++ b/src/plugins/genericprojectmanager/genericprojectmanager.qbs
@@ -12,6 +12,7 @@ QtcPlugin {
Depends { name: "TextEditor" }
Depends { name: "ProjectExplorer" }
Depends { name: "QtSupport" }
+ Depends { name: "app_version_header" }
pluginTestDepends: [
"CppEditor",
diff --git a/src/plugins/genericprojectmanager/genericprojectwizard.cpp b/src/plugins/genericprojectmanager/genericprojectwizard.cpp
index c91abba26d9..f38be2003b5 100644
--- a/src/plugins/genericprojectmanager/genericprojectwizard.cpp
+++ b/src/plugins/genericprojectmanager/genericprojectwizard.cpp
@@ -31,6 +31,7 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/customwizard/customwizard.h>
+#include <app/app_version.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/filewizardpage.h>
@@ -115,7 +116,8 @@ GenericProjectWizard::GenericProjectWizard()
setDisplayName(tr("Import Existing Project"));
setId("Z.Makefile");
setDescription(tr("Imports existing projects that do not use qmake, CMake or Autotools. "
- "This allows you to use Qt Creator as a code editor."));
+ "This allows you to use %1 as a code editor.")
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
setCategory(QLatin1String(ProjectExplorer::Constants::IMPORT_WIZARD_CATEGORY));
setDisplayCategory(QLatin1String(ProjectExplorer::Constants::IMPORT_WIZARD_CATEGORY_DISPLAY));
setFlags(Core::IWizardFactory::PlatformIndependent);
diff --git a/src/plugins/git/gerrit/gerritdialog.cpp b/src/plugins/git/gerrit/gerritdialog.cpp
index 21ccef371a5..be1d79af902 100644
--- a/src/plugins/git/gerrit/gerritdialog.cpp
+++ b/src/plugins/git/gerrit/gerritdialog.cpp
@@ -97,7 +97,7 @@ GerritDialog::GerritDialog(const QSharedPointer<GerritParameters> &p,
m_progressIndicatorTimer.setSingleShot(true);
m_progressIndicatorTimer.setInterval(50); // don't show progress for < 50ms tasks
- m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicator::Large,
+ m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Large,
m_ui->treeView);
m_progressIndicator->attachToWidget(m_ui->treeView->viewport());
m_progressIndicator->hide();
diff --git a/src/plugins/git/gerrit/gerritplugin.cpp b/src/plugins/git/gerrit/gerritplugin.cpp
index b9f4fca2015..5e088aa5a8b 100644
--- a/src/plugins/git/gerrit/gerritplugin.cpp
+++ b/src/plugins/git/gerrit/gerritplugin.cpp
@@ -520,7 +520,7 @@ QString GerritPlugin::findLocalRepository(QString project, const QString &branch
} // for repositories
// No match, do we have a projects folder?
if (DocumentManager::useProjectsDirectory())
- return DocumentManager::projectsDirectory();
+ return DocumentManager::projectsDirectory().toString();
return QDir::currentPath();
}
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index ae1c324c304..8deea9816d8 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -694,7 +694,7 @@ void GitClient::diffFiles(const QString &workingDirectory,
+ QLatin1String(".DiffFiles.") + workingDirectory;
requestReload(documentId,
workingDirectory, tr("Git Diff Files"),
- [this, workingDirectory, stagedFileNames, unstagedFileNames]
+ [workingDirectory, stagedFileNames, unstagedFileNames]
(IDocument *doc) -> DiffEditorController* {
return new FileListDiffController(doc, workingDirectory,
stagedFileNames, unstagedFileNames);
@@ -707,7 +707,7 @@ void GitClient::diffProject(const QString &workingDirectory, const QString &proj
+ QLatin1String(".DiffProject.") + workingDirectory;
requestReload(documentId,
workingDirectory, tr("Git Diff Project"),
- [this, workingDirectory, projectDirectory]
+ [workingDirectory, projectDirectory]
(IDocument *doc) -> DiffEditorController* {
return new ProjectDiffController(doc, workingDirectory, {projectDirectory});
});
@@ -719,7 +719,7 @@ void GitClient::diffRepository(const QString &workingDirectory)
+ QLatin1String(".DiffRepository.") + workingDirectory;
requestReload(documentId,
workingDirectory, tr("Git Diff Repository"),
- [this, workingDirectory](IDocument *doc) -> DiffEditorController* {
+ [workingDirectory](IDocument *doc) -> DiffEditorController* {
return new RepositoryDiffController(doc, workingDirectory);
});
}
@@ -731,7 +731,7 @@ void GitClient::diffFile(const QString &workingDirectory, const QString &fileNam
const QString documentId = QLatin1String(Constants::GIT_PLUGIN)
+ QLatin1String(".DifFile.") + sourceFile;
requestReload(documentId, sourceFile, title,
- [this, workingDirectory, fileName]
+ [workingDirectory, fileName]
(IDocument *doc) -> DiffEditorController* {
return new FileDiffController(doc, workingDirectory, fileName);
});
@@ -744,7 +744,7 @@ void GitClient::diffBranch(const QString &workingDirectory,
const QString documentId = QLatin1String(Constants::GIT_PLUGIN)
+ QLatin1String(".DiffBranch.") + branchName;
requestReload(documentId, workingDirectory, title,
- [this, workingDirectory, branchName]
+ [workingDirectory, branchName]
(IDocument *doc) -> DiffEditorController* {
return new BranchDiffController(doc, workingDirectory, branchName);
});
@@ -851,7 +851,7 @@ void GitClient::show(const QString &source, const QString &id, const QString &na
const QString documentId = QLatin1String(Constants::GIT_PLUGIN)
+ QLatin1String(".Show.") + id;
requestReload(documentId, source, title,
- [this, workingDirectory, id]
+ [workingDirectory, id]
(IDocument *doc) -> DiffEditorController* {
return new ShowController(doc, workingDirectory, id);
});
@@ -1768,7 +1768,7 @@ bool GitClient::cleanList(const QString &workingDirectory, const QString &module
const QString relativeBase = modulePath.isEmpty() ? QString() : modulePath + '/';
const QString prefix = "Would remove ";
const QStringList removeLines = Utils::filtered(
- splitLines(resp.stdOut()), [&prefix](const QString &s) {
+ splitLines(resp.stdOut()), [](const QString &s) {
return s.startsWith("Would remove ");
});
*files = Utils::transform(removeLines, [&relativeBase, &prefix](const QString &s) -> QString {
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index 5070fef544a..a310e132cb4 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -296,10 +296,10 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
m_gitClient = new GitClient;
- initializeVcs(new GitVersionControl(m_gitClient), context);
+ auto vc = initializeVcs<GitVersionControl>(context, m_gitClient);
// Create the settings Page
- auto settingsPage = new SettingsPage(versionControl());
+ auto settingsPage = new SettingsPage(vc);
addAutoReleasedObject(settingsPage);
connect(settingsPage, &SettingsPage::settingsChanged,
this, &GitPlugin::updateRepositoryBrowserAction);
@@ -926,6 +926,9 @@ void GitPlugin::gitGui()
void GitPlugin::startCommit(CommitType commitType)
{
+ if (!promptBeforeCommit())
+ return;
+
if (raiseSubmitEditor())
return;
if (isCommitEditorOpen()) {
diff --git a/src/plugins/git/remotemodel.cpp b/src/plugins/git/remotemodel.cpp
index 7cd14b12582..59164963d66 100644
--- a/src/plugins/git/remotemodel.cpp
+++ b/src/plugins/git/remotemodel.cpp
@@ -188,9 +188,6 @@ bool RemoteModel::refresh(const QString &workingDirectory, QString *errorMessage
QMap<QString,QString> remotesList
= GitPlugin::client()->synchronousRemotesList(workingDirectory, errorMessage);
- if (remotesList.isEmpty())
- return false;
-
beginResetModel();
m_remotes.clear();
const QList<QString> remotes = remotesList.keys();
diff --git a/src/plugins/help/images/mode_help.png b/src/plugins/help/images/mode_help.png
index 7247e639eb8..e2e3eb64d14 100644
--- a/src/plugins/help/images/mode_help.png
+++ b/src/plugins/help/images/mode_help.png
Binary files differ
diff --git a/src/plugins/help/images/mode_help@2x.png b/src/plugins/help/images/mode_help@2x.png
index ae8db24fd75..51e4ed8ff87 100644
--- a/src/plugins/help/images/mode_help@2x.png
+++ b/src/plugins/help/images/mode_help@2x.png
Binary files differ
diff --git a/src/plugins/help/images/mode_help_mask.png b/src/plugins/help/images/mode_help_mask.png
index 43eb4d120b2..144871e8542 100644
--- a/src/plugins/help/images/mode_help_mask.png
+++ b/src/plugins/help/images/mode_help_mask.png
Binary files differ
diff --git a/src/plugins/help/images/mode_help_mask@2x.png b/src/plugins/help/images/mode_help_mask@2x.png
index 611769bd968..50f12d8e117 100644
--- a/src/plugins/help/images/mode_help_mask@2x.png
+++ b/src/plugins/help/images/mode_help_mask@2x.png
Binary files differ
diff --git a/src/plugins/imageviewer/imageviewerplugin.cpp b/src/plugins/imageviewer/imageviewerplugin.cpp
index 6d1419da44a..6a453eb90e2 100644
--- a/src/plugins/imageviewer/imageviewerplugin.cpp
+++ b/src/plugins/imageviewer/imageviewerplugin.cpp
@@ -64,56 +64,56 @@ void ImageViewerPlugin::extensionsInitialized()
{
QAction *a = registerNewAction(Constants::ACTION_ZOOM_IN, tr("Zoom In"),
QKeySequence(tr("Ctrl++")));
- connect(a, &QAction::triggered, this, [this]() {
+ connect(a, &QAction::triggered, this, []() {
if (ImageViewer *iv = currentImageViewer())
iv->zoomIn();
});
a = registerNewAction(Constants::ACTION_ZOOM_OUT, tr("Zoom Out"),
QKeySequence(tr("Ctrl+-")));
- connect(a, &QAction::triggered, this, [this]() {
+ connect(a, &QAction::triggered, this, []() {
if (ImageViewer *iv = currentImageViewer())
iv->zoomOut();
});
a = registerNewAction(Constants::ACTION_ORIGINAL_SIZE, tr("Original Size"),
QKeySequence(Core::UseMacShortcuts ? tr("Meta+0") : tr("Ctrl+0")));
- connect(a, &QAction::triggered, this, [this]() {
+ connect(a, &QAction::triggered, this, []() {
if (ImageViewer *iv = currentImageViewer())
iv->resetToOriginalSize();
});
a = registerNewAction(Constants::ACTION_FIT_TO_SCREEN, tr("Fit to Screen"),
QKeySequence(tr("Ctrl+=")));
- connect(a, &QAction::triggered, this, [this]() {
+ connect(a, &QAction::triggered, this, []() {
if (ImageViewer *iv = currentImageViewer())
iv->fitToScreen();
});
a = registerNewAction(Constants::ACTION_BACKGROUND, tr("Switch Background"),
QKeySequence(tr("Ctrl+[")));
- connect(a, &QAction::triggered, this, [this]() {
+ connect(a, &QAction::triggered, this, []() {
if (ImageViewer *iv = currentImageViewer())
iv->switchViewBackground();
});
a = registerNewAction(Constants::ACTION_OUTLINE, tr("Switch Outline"),
QKeySequence(tr("Ctrl+]")));
- connect(a, &QAction::triggered, this, [this]() {
+ connect(a, &QAction::triggered, this, []() {
if (ImageViewer *iv = currentImageViewer())
iv->switchViewOutline();
});
a = registerNewAction(Constants::ACTION_TOGGLE_ANIMATION, tr("Toggle Animation"),
QKeySequence());
- connect(a, &QAction::triggered, this, [this]() {
+ connect(a, &QAction::triggered, this, []() {
if (ImageViewer *iv = currentImageViewer())
iv->togglePlay();
});
a = registerNewAction(Constants::ACTION_EXPORT_IMAGE, tr("Export Image"),
QKeySequence());
- connect(a, &QAction::triggered, this, [this]() {
+ connect(a, &QAction::triggered, this, []() {
if (ImageViewer *iv = currentImageViewer())
iv->exportImage();
});
diff --git a/src/plugins/ios/images/iosdevice.png b/src/plugins/ios/images/iosdevice.png
index 9b3fabeaf35..892e09c7787 100644
--- a/src/plugins/ios/images/iosdevice.png
+++ b/src/plugins/ios/images/iosdevice.png
Binary files differ
diff --git a/src/plugins/ios/images/iosdevice@2x.png b/src/plugins/ios/images/iosdevice@2x.png
index 1e078270c64..89bbaf03477 100644
--- a/src/plugins/ios/images/iosdevice@2x.png
+++ b/src/plugins/ios/images/iosdevice@2x.png
Binary files differ
diff --git a/src/plugins/ios/iosbuildstep.cpp b/src/plugins/ios/iosbuildstep.cpp
index f7f0dc7219b..c088b1ede48 100644
--- a/src/plugins/ios/iosbuildstep.cpp
+++ b/src/plugins/ios/iosbuildstep.cpp
@@ -60,17 +60,13 @@ const char BUILD_ARGUMENTS_KEY[] = "Ios.IosBuildStep.XcodeArguments";
const char CLEAN_KEY[] = "Ios.IosBuildStep.Clean";
IosBuildStep::IosBuildStep(BuildStepList *parent) :
- AbstractProcessStep(parent, Id(IOS_BUILD_STEP_ID)),
- m_useDefaultArguments(true),
- m_clean(false)
+ AbstractProcessStep(parent, Id(IOS_BUILD_STEP_ID))
{
ctor();
}
IosBuildStep::IosBuildStep(BuildStepList *parent, const Id id) :
- AbstractProcessStep(parent, id),
- m_useDefaultArguments(true),
- m_clean(false)
+ AbstractProcessStep(parent, id)
{
ctor();
}
@@ -264,7 +260,15 @@ IosBuildStepConfigWidget::IosBuildStepConfigWidget(IosBuildStep *buildStep)
this, &IosBuildStepConfigWidget::updateDetails);
connect(m_buildStep->target(), &Target::kitChanged,
this, &IosBuildStepConfigWidget::updateDetails);
- connect(pro, &Project::environmentChanged, this, &IosBuildStepConfigWidget::updateDetails);
+ pro->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
+ if (static_cast<BuildConfiguration *>(sender())->isActive())
+ updateDetails();
+ });
+ connect(pro, &Project::activeProjectConfigurationChanged,
+ this, [this](ProjectConfiguration *pc) {
+ if (pc && pc->isActive())
+ updateDetails();
+ });
}
IosBuildStepConfigWidget::~IosBuildStepConfigWidget()
diff --git a/src/plugins/ios/iosbuildstep.h b/src/plugins/ios/iosbuildstep.h
index 05caaf9303e..047eb799f9e 100644
--- a/src/plugins/ios/iosbuildstep.h
+++ b/src/plugins/ios/iosbuildstep.h
@@ -74,9 +74,8 @@ private:
QStringList m_baseBuildArguments;
QStringList m_extraArguments;
- QString m_buildCommand;
- bool m_useDefaultArguments;
- bool m_clean;
+ bool m_useDefaultArguments = true;
+ bool m_clean = false;
};
class IosBuildStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget
diff --git a/src/plugins/ios/iosdsymbuildstep.cpp b/src/plugins/ios/iosdsymbuildstep.cpp
index c6c5ce02277..3d876621e9f 100644
--- a/src/plugins/ios/iosdsymbuildstep.cpp
+++ b/src/plugins/ios/iosdsymbuildstep.cpp
@@ -260,7 +260,15 @@ IosPresetBuildStepConfigWidget::IosPresetBuildStepConfigWidget(IosPresetBuildSte
this, &IosPresetBuildStepConfigWidget::updateDetails);
connect(m_buildStep->target(), &Target::kitChanged,
this, &IosPresetBuildStepConfigWidget::updateDetails);
- connect(pro, &Project::environmentChanged, this, &IosPresetBuildStepConfigWidget::updateDetails);
+ pro->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
+ if (static_cast<BuildConfiguration *>(sender())->isActive())
+ updateDetails();
+ });
+ connect(pro, &Project::activeProjectConfigurationChanged,
+ this, [this](ProjectConfiguration *pc) {
+ if (pc && pc->isActive())
+ updateDetails();
+ });
}
IosPresetBuildStepConfigWidget::~IosPresetBuildStepConfigWidget()
diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp
index 093f9100e4d..d1c5cc69845 100644
--- a/src/plugins/ios/iosrunconfiguration.cpp
+++ b/src/plugins/ios/iosrunconfiguration.cpp
@@ -94,65 +94,37 @@ private:
QComboBox *m_deviceTypeComboBox;
};
-IosRunConfiguration::IosRunConfiguration(Target *parent, Core::Id id, const FileName &path)
- : RunConfiguration(parent, id)
- , m_profilePath(path)
+IosRunConfiguration::IosRunConfiguration(Target *target)
+ : RunConfiguration(target)
{
- addExtraAspect(new ArgumentsAspect(this, QLatin1String("Ios.run_arguments")));
- init();
-}
+ addExtraAspect(new ArgumentsAspect(this, "Ios.run_arguments"));
-IosRunConfiguration::IosRunConfiguration(Target *parent, IosRunConfiguration *source)
- : RunConfiguration(parent, source)
- , m_profilePath(source->m_profilePath)
-{
- init();
-}
-
-void IosRunConfiguration::init()
-{
- QmakeProject *project = static_cast<QmakeProject *>(target()->project());
- m_parseSuccess = project->validParse(m_profilePath);
- m_parseInProgress = project->parseInProgress(m_profilePath);
- m_lastIsEnabled = isEnabled();
- m_lastDisabledReason = disabledReason();
- updateDisplayNames();
connect(DeviceManager::instance(), &DeviceManager::updated,
this, &IosRunConfiguration::deviceChanges);
connect(KitManager::instance(), &KitManager::kitsChanged,
this, &IosRunConfiguration::deviceChanges);
- connect(project, &QmakeProject::proFileUpdated,
- this, &IosRunConfiguration::proFileUpdated);
}
-void IosRunConfiguration::enabledCheck()
+
+void IosRunConfiguration::initialize(Core::Id id, const FileName &path)
{
- bool newIsEnabled = isEnabled();
- QString newDisabledReason = disabledReason();
- if (newDisabledReason != m_lastDisabledReason || newIsEnabled != m_lastIsEnabled) {
- m_lastDisabledReason = newDisabledReason;
- m_lastIsEnabled = newIsEnabled;
- emit enabledChanged();
- }
-}
+ RunConfiguration::initialize(id);
+ m_profilePath = path;
-void IosRunConfiguration::deviceChanges() {
updateDisplayNames();
- enabledCheck();
}
-void IosRunConfiguration::proFileUpdated(QmakeProFile *pro, bool success,
- bool parseInProgress)
+void IosRunConfiguration::copyFrom(const IosRunConfiguration *source)
{
- if (m_profilePath != pro->filePath())
- return;
- m_parseSuccess = success;
- m_parseInProgress = parseInProgress;
- if (success && !parseInProgress) {
- updateDisplayNames();
- emit localExecutableChanged();
- }
- enabledCheck();
+ RunConfiguration::copyFrom(source);
+ m_profilePath = source->m_profilePath;
+
+ updateDisplayNames();
+}
+
+void IosRunConfiguration::deviceChanges() {
+ updateDisplayNames();
+ updateEnabledState();
}
QWidget *IosRunConfiguration::createConfigurationWidget()
@@ -182,6 +154,21 @@ void IosRunConfiguration::updateDisplayNames()
setDisplayName(tr("Run %1 on %2").arg(applicationName()).arg(devName));
}
+void IosRunConfiguration::updateEnabledState()
+{
+ Core::Id devType = DeviceTypeKitInformation::deviceTypeId(target()->kit());
+ if (devType != Constants::IOS_DEVICE_TYPE && devType != Constants::IOS_SIMULATOR_TYPE) {
+ setEnabled(false);
+ return;
+ }
+ IDevice::ConstPtr dev = DeviceKitInformation::device(target()->kit());
+ if (dev.isNull() || dev->deviceState() != IDevice::DeviceReadyToUse) {
+ setEnabled(false);
+ return;
+ }
+ return RunConfiguration::updateEnabledState();
+}
+
IosDeployStep *IosRunConfiguration::deployStep() const
{
DeployConfiguration *config = target()->activeDeployConfiguration();
@@ -287,26 +274,8 @@ QString IosRunConfiguration::buildSystemTarget() const
return static_cast<QmakeProject *>(target()->project())->mapProFilePathToTarget(m_profilePath);
}
-bool IosRunConfiguration::isEnabled() const
-{
- if (m_parseInProgress || !m_parseSuccess)
- return false;
- Core::Id devType = DeviceTypeKitInformation::deviceTypeId(target()->kit());
- if (devType != Constants::IOS_DEVICE_TYPE && devType != Constants::IOS_SIMULATOR_TYPE)
- return false;
- IDevice::ConstPtr dev = DeviceKitInformation::device(target()->kit());
- if (dev.isNull() || dev->deviceState() != IDevice::DeviceReadyToUse)
- return false;
- return RunConfiguration::isEnabled();
-}
-
QString IosRunConfiguration::disabledReason() const
{
- if (m_parseInProgress)
- return tr("The .pro file \"%1\" is currently being parsed.").arg(m_profilePath.fileName());
- if (!m_parseSuccess)
- return static_cast<QmakeProject *>(target()->project())
- ->disabledReasonForRunConfiguration(m_profilePath);
Core::Id devType = DeviceTypeKitInformation::deviceTypeId(target()->kit());
if (devType != Constants::IOS_DEVICE_TYPE && devType != Constants::IOS_SIMULATOR_TYPE)
return tr("Kit has incorrect device type for running on iOS devices.");
diff --git a/src/plugins/ios/iosrunconfiguration.h b/src/plugins/ios/iosrunconfiguration.h
index 9a33177e8c1..86401ea094c 100644
--- a/src/plugins/ios/iosrunconfiguration.h
+++ b/src/plugins/ios/iosrunconfiguration.h
@@ -44,10 +44,9 @@ class IosRunConfigurationWidget;
class IosRunConfiguration : public ProjectExplorer::RunConfiguration
{
Q_OBJECT
- friend class IosRunConfigurationFactory;
public:
- IosRunConfiguration(ProjectExplorer::Target *parent, Core::Id id, const Utils::FileName &path);
+ explicit IosRunConfiguration(ProjectExplorer::Target *target);
QWidget *createConfigurationWidget() override;
Utils::OutputFormatter *createOutputFormatter() const override;
@@ -58,7 +57,6 @@ public:
QString applicationName() const;
Utils::FileName bundleDirectory() const;
Utils::FileName localExecutable() const;
- bool isEnabled() const override;
QString disabledReason() const override;
IosDeviceType deviceType() const;
void setDeviceType(const IosDeviceType &deviceType);
@@ -68,25 +66,20 @@ public:
QString buildSystemTarget() const final;
-protected:
- IosRunConfiguration(ProjectExplorer::Target *parent, IosRunConfiguration *source);
-
signals:
void localExecutableChanged();
private:
- void proFileUpdated(QmakeProjectManager::QmakeProFile *pro, bool success, bool parseInProgress);
+ friend class ProjectExplorer::IRunConfigurationFactory;
+ void initialize(Core::Id id, const Utils::FileName &path);
+ void copyFrom(const IosRunConfiguration *source);
+
void deviceChanges();
- void init();
- void enabledCheck();
friend class IosRunConfigurationWidget;
void updateDisplayNames();
+ void updateEnabledState() final;
Utils::FileName m_profilePath;
- QString m_lastDisabledReason;
- bool m_lastIsEnabled;
- bool m_parseInProgress;
- bool m_parseSuccess;
IosDeviceType m_deviceType;
};
diff --git a/src/plugins/ios/iosrunfactories.cpp b/src/plugins/ios/iosrunfactories.cpp
index c41dcb8263f..de36ec7948f 100644
--- a/src/plugins/ios/iosrunfactories.cpp
+++ b/src/plugins/ios/iosrunfactories.cpp
@@ -108,8 +108,7 @@ RunConfiguration *IosRunConfigurationFactory::clone(Target *parent, RunConfigura
if (!canClone(parent, source))
return 0;
- IosRunConfiguration *old = qobject_cast<IosRunConfiguration *>(source);
- return new IosRunConfiguration(parent, old);
+ return cloneHelper<IosRunConfiguration>(parent, source);
}
bool IosRunConfigurationFactory::canHandle(Target *t) const
@@ -133,13 +132,13 @@ QList<RunConfiguration *> IosRunConfigurationFactory::runConfigurationsForNode(T
RunConfiguration *IosRunConfigurationFactory::doCreate(Target *parent, Core::Id id)
{
- return new IosRunConfiguration(parent, id, pathFromId(id));
+ return createHelper<IosRunConfiguration>(parent, id, pathFromId(id));
}
RunConfiguration *IosRunConfigurationFactory::doRestore(Target *parent, const QVariantMap &map)
{
Core::Id id = ProjectExplorer::idFromMap(map);
- return new IosRunConfiguration(parent, id, pathFromId(id));
+ return createHelper<IosRunConfiguration>(parent, id, pathFromId(id));
}
} // namespace Internal
diff --git a/src/plugins/ios/iosrunner.cpp b/src/plugins/ios/iosrunner.cpp
index a57dbd461f7..18264317bb8 100644
--- a/src/plugins/ios/iosrunner.cpp
+++ b/src/plugins/ios/iosrunner.cpp
@@ -440,11 +440,10 @@ void IosDebugSupport::start()
RunConfiguration *runConfig = runControl()->runConfiguration();
- DebuggerStartParameters params;
if (device()->type() == Ios::Constants::IOS_DEVICE_TYPE) {
IosDevice::ConstPtr dev = device().dynamicCast<const IosDevice>();
- params.startMode = AttachToRemoteProcess;
- params.platform = "remote-ios";
+ setStartMode(AttachToRemoteProcess);
+ setIosPlatform("remote-ios");
QString osVersion = dev->osVersion();
FileName deviceSdk1 = FileName::fromString(QDir::homePath()
+ "/Library/Developer/Xcode/iOS DeviceSupport/"
@@ -467,25 +466,25 @@ void IosDebugSupport::start()
ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT);
}
}
- params.deviceSymbolsRoot = deviceSdk;
+ setDeviceSymbolsRoot(deviceSdk);
} else {
- params.startMode = AttachExternal;
- params.platform = "ios-simulator";
+ setStartMode(AttachExternal);
+ setIosPlatform("ios-simulator");
}
auto iosRunConfig = qobject_cast<IosRunConfiguration *>(runConfig);
- params.displayName = iosRunConfig->applicationName();
- params.continueAfterAttach = true;
+ setRunControlName(iosRunConfig->applicationName());
+ setContinueAfterAttach(true);
Utils::Port gdbServerPort = m_runner->gdbServerPort();
Utils::Port qmlServerPort = m_runner->qmlServerPort();
- params.attachPID = ProcessHandle(m_runner->pid());
+ setAttachPid(ProcessHandle(m_runner->pid()));
const bool cppDebug = isCppDebugging();
const bool qmlDebug = isQmlDebugging();
if (cppDebug) {
- params.inferior.executable = iosRunConfig->localExecutable().toString();
- params.remoteChannel = "connect://localhost:" + gdbServerPort.toString();
+ setInferiorExecutable(iosRunConfig->localExecutable().toString());
+ setRemoteChannel("connect://localhost:" + gdbServerPort.toString());
FileName xcodeInfo = IosConfigurations::developerPath().parentDir().appendPath("Info.plist");
bool buggyLldb = false;
@@ -514,21 +513,20 @@ void IosDebugSupport::start()
}
}
+ QUrl qmlServer;
if (qmlDebug) {
QTcpServer server;
QTC_ASSERT(server.listen(QHostAddress::LocalHost)
|| server.listen(QHostAddress::LocalHostIPv6), return);
- params.qmlServer.host = server.serverAddress().toString();
+ qmlServer.setHost(server.serverAddress().toString());
if (!cppDebug)
- params.startMode = AttachToRemoteServer;
+ setStartMode(AttachToRemoteServer);
}
- if (qmlServerPort.isValid()) {
- params.qmlServer.port = qmlServerPort;
- params.inferior.commandLineArguments.replace("%qml_port%", qmlServerPort.toString());
- }
+ if (qmlServerPort.isValid())
+ qmlServer.setPort(qmlServerPort.number());
- setStartParameters(params);
+ setQmlServer(qmlServer);
DebuggerRunTool::start();
}
diff --git a/src/plugins/ios/iossettingswidget.cpp b/src/plugins/ios/iossettingswidget.cpp
index 6e99dadca29..0cb54bd28bc 100644
--- a/src/plugins/ios/iossettingswidget.cpp
+++ b/src/plugins/ios/iossettingswidget.cpp
@@ -148,7 +148,7 @@ void IosSettingsWidget::onCreate()
QPointer<SimulatorOperationDialog> statusDialog = new SimulatorOperationDialog(this);
statusDialog->setAttribute(Qt::WA_DeleteOnClose);
statusDialog->addMessage(tr("Creating simulator device..."), Utils::NormalMessageFormat);
- const auto onSimulatorCreate = [this, statusDialog](const QString &name,
+ const auto onSimulatorCreate = [statusDialog](const QString &name,
const SimulatorControl::ResponseData &response) {
if (response.success) {
statusDialog->addMessage(tr("Simulator device (%1) created.\nUDID: %2")
diff --git a/src/plugins/mercurial/mercurialplugin.cpp b/src/plugins/mercurial/mercurialplugin.cpp
index 8254f91d677..5c12b42c519 100644
--- a/src/plugins/mercurial/mercurialplugin.cpp
+++ b/src/plugins/mercurial/mercurialplugin.cpp
@@ -37,12 +37,12 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/command.h>
+#include <coreplugin/documentmanager.h>
#include <coreplugin/id.h>
#include <coreplugin/vcsmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
-#include <coreplugin/documentmanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/locator/commandlocator.h>
@@ -122,12 +122,11 @@ bool MercurialPlugin::initialize(const QStringList & /* arguments */, QString *
Core::Context context(Constants::MERCURIAL_CONTEXT);
m_client = new MercurialClient;
- initializeVcs(new MercurialControl(m_client), context);
+ auto vc = initializeVcs<MercurialControl>(context, m_client);
- addAutoReleasedObject(new OptionsPage(versionControl()));
+ addAutoReleasedObject(new OptionsPage(vc));
- connect(m_client, &VcsBaseClient::changed,
- static_cast<MercurialControl *>(versionControl()), &MercurialControl::changed);
+ connect(m_client, &VcsBaseClient::changed, vc, &MercurialControl::changed);
connect(m_client, &MercurialClient::needUpdate, this, &MercurialPlugin::update);
const auto describeFunc = [this](const QString &source, const QString &id) {
@@ -495,6 +494,9 @@ void MercurialPlugin::createSubmitEditorActions()
void MercurialPlugin::commit()
{
+ if (!promptBeforeCommit())
+ return;
+
if (raiseSubmitEditor())
return;
diff --git a/src/plugins/modeleditor/actionhandler.cpp b/src/plugins/modeleditor/actionhandler.cpp
index 2bb98d85b8b..016a0ad027f 100644
--- a/src/plugins/modeleditor/actionhandler.cpp
+++ b/src/plugins/modeleditor/actionhandler.cpp
@@ -46,20 +46,20 @@ namespace Internal {
class ActionHandler::ActionHandlerPrivate {
public:
Core::Context context;
- QAction *undoAction = 0;
- QAction *redoAction = 0;
- QAction *cutAction = 0;
- QAction *copyAction = 0;
- QAction *pasteAction = 0;
- QAction *removeAction = 0;
- QAction *deleteAction = 0;
- QAction *selectAllAction = 0;
- QAction *openParentDiagramAction = 0;
- QAction *synchronizeBrowserAction = 0;
- QAction *exportDiagramAction = 0;
- QAction *zoomInAction = 0;
- QAction *zoomOutAction = 0;
- QAction *resetZoomAction = 0;
+ QAction *undoAction = nullptr;
+ QAction *redoAction = nullptr;
+ QAction *cutAction = nullptr;
+ QAction *copyAction = nullptr;
+ QAction *pasteAction = nullptr;
+ QAction *removeAction = nullptr;
+ QAction *deleteAction = nullptr;
+ QAction *selectAllAction = nullptr;
+ QAction *openParentDiagramAction = nullptr;
+ QAction *synchronizeBrowserAction = nullptr;
+ QAction *exportDiagramAction = nullptr;
+ QAction *zoomInAction = nullptr;
+ QAction *zoomOutAction = nullptr;
+ QAction *resetZoomAction = nullptr;
};
ActionHandler::ActionHandler(const Core::Context &context, QObject *parent)
@@ -160,7 +160,7 @@ void ActionHandler::createActions()
d->removeAction = removeCommand->action();
Core::Command *deleteCommand = registerCommand(
Constants::DELETE_SELECTED_ELEMENTS, [this]() { deleteSelectedElements(); }, d->context, true,
- tr("&Delete"), QKeySequence(QStringLiteral("Ctrl+D")));
+ tr("&Delete"), QKeySequence("Ctrl+D"));
medit->addAction(deleteCommand, Core::Constants::G_EDIT_COPYPASTE);
d->deleteAction = deleteCommand->action();
d->selectAllAction = registerCommand(Core::Constants::SELECTALL, [this]() { selectAll(); }, d->context)->action();
@@ -180,26 +180,26 @@ void ActionHandler::createActions()
Core::Command *zoomInCommand = registerCommand(
Constants::ZOOM_IN, [this]() { zoomIn(); }, d->context, true,
- tr("Zoom In"), QKeySequence(QStringLiteral("Ctrl++")));
+ tr("Zoom In"), QKeySequence("Ctrl++"));
menuModelEditor->addAction(zoomInCommand);
d->zoomInAction = zoomInCommand->action();
Core::Command *zoomOutCommand = registerCommand(
Constants::ZOOM_OUT, [this]() { zoomOut(); }, d->context, true,
- tr("Zoom Out"), QKeySequence(QStringLiteral("Ctrl+-")));
+ tr("Zoom Out"), QKeySequence("Ctrl+-"));
menuModelEditor->addAction(zoomOutCommand);
d->zoomOutAction = zoomOutCommand->action();
Core::Command *resetZoomCommand = registerCommand(
Constants::RESET_ZOOM, [this]() { resetZoom(); }, d->context, true,
- tr("Reset Zoom"), QKeySequence(QStringLiteral("Ctrl+0")));
+ tr("Reset Zoom"), QKeySequence("Ctrl+0"));
menuModelEditor->addAction(resetZoomCommand);
d->zoomOutAction = resetZoomCommand->action();
d->openParentDiagramAction = registerCommand(
Constants::OPEN_PARENT_DIAGRAM, [this]() { openParentDiagram(); }, Core::Context(), true,
- tr("Open Parent Diagram"), QKeySequence(QStringLiteral("Ctrl+Shift+P")))->action();
- d->openParentDiagramAction->setIcon(QIcon(QStringLiteral(":/modeleditor/up.png")));
+ tr("Open Parent Diagram"), QKeySequence("Ctrl+Shift+P"))->action();
+ d->openParentDiagramAction->setIcon(QIcon(":/modeleditor/up.png"));
registerCommand(Constants::ACTION_ADD_PACKAGE, nullptr, Core::Context(), true, tr("Add Package"));
registerCommand(Constants::ACTION_ADD_COMPONENT, nullptr, Core::Context(), true, tr("Add Component"));
registerCommand(Constants::ACTION_ADD_CLASS, nullptr, Core::Context(), true, tr("Add Class"));
diff --git a/src/plugins/modeleditor/actionhandler.h b/src/plugins/modeleditor/actionhandler.h
index af2793d3fe8..e2ad8f7e02d 100644
--- a/src/plugins/modeleditor/actionhandler.h
+++ b/src/plugins/modeleditor/actionhandler.h
@@ -50,7 +50,7 @@ class ActionHandler :
class ActionHandlerPrivate;
public:
- ActionHandler(const Core::Context &context, QObject *parent = 0);
+ ActionHandler(const Core::Context &context, QObject *parent = nullptr);
~ActionHandler();
public:
diff --git a/src/plugins/modeleditor/classviewcontroller.cpp b/src/plugins/modeleditor/classviewcontroller.cpp
index 059c800a920..32cd3d1ac2c 100644
--- a/src/plugins/modeleditor/classviewcontroller.cpp
+++ b/src/plugins/modeleditor/classviewcontroller.cpp
@@ -78,7 +78,7 @@ void ClassViewController::appendClassDeclarationsFromSymbol(CPlusPlus::Symbol *s
QString className = overview.prettyName(
CPlusPlus::LookupContext::fullyQualifiedName(symbol));
// Ignore private class created by Q_OBJECT macro
- if (!className.endsWith(QStringLiteral("::QPrivateSignal")))
+ if (!className.endsWith("::QPrivateSignal"))
classNames->insert(className);
}
diff --git a/src/plugins/modeleditor/classviewcontroller.h b/src/plugins/modeleditor/classviewcontroller.h
index 4bf67d480e5..f9534204523 100644
--- a/src/plugins/modeleditor/classviewcontroller.h
+++ b/src/plugins/modeleditor/classviewcontroller.h
@@ -38,7 +38,7 @@ class ClassViewController :
Q_OBJECT
public:
- explicit ClassViewController(QObject *parent = 0);
+ explicit ClassViewController(QObject *parent = nullptr);
~ClassViewController() = default;
QSet<QString> findClassDeclarations(const QString &fileName);
diff --git a/src/plugins/modeleditor/componentviewcontroller.cpp b/src/plugins/modeleditor/componentviewcontroller.cpp
index c90aaa49b2b..b9fadc2bd1f 100644
--- a/src/plugins/modeleditor/componentviewcontroller.cpp
+++ b/src/plugins/modeleditor/componentviewcontroller.cpp
@@ -64,7 +64,7 @@ private:
QString m_elementName;
QStringList m_elementsPath;
int m_maxPathLength = 0;
- qmt::MComponent *m_bestComponent = 0;
+ qmt::MComponent *m_bestComponent = nullptr;
};
void FindComponentFromFilePath::setFilePath(const QString &filePath)
@@ -131,7 +131,7 @@ private:
bool haveDependency(const qmt::MObject *source, const QList<qmt::MPackage *> &targets);
private:
- qmt::ModelController *m_modelController = 0;
+ qmt::ModelController *m_modelController = nullptr;
QMultiHash<QString, Node> m_filePaths;
};
@@ -167,7 +167,7 @@ void UpdateIncludeDependenciesVisitor::visitMComponent(qmt::MComponent *componen
if (!haveDependency(component, includeComponent)) {
auto dependency = new qmt::MDependency;
dependency->setFlags(qmt::MElement::ReverseEngineered);
- dependency->setStereotypes(QStringList() << QStringLiteral("include"));
+ dependency->setStereotypes(QStringList() << "include");
dependency->setDirection(qmt::MDependency::AToB);
dependency->setSource(component->uid());
dependency->setTarget(includeComponent->uid());
@@ -190,7 +190,7 @@ void UpdateIncludeDependenciesVisitor::visitMComponent(qmt::MComponent *componen
int componentHighestAncestorIndex = componentAncestors.size() - 1;
int includeComponentHighestAncestorIndex = includeComponentAncestors.size() - 1;
- QTC_ASSERT(componentAncestors.at(componentHighestAncestorIndex) == includeComponentAncestors.at(includeComponentHighestAncestorIndex), return);
+ QMT_ASSERT(componentAncestors.at(componentHighestAncestorIndex) == includeComponentAncestors.at(includeComponentHighestAncestorIndex), return);
while (componentHighestAncestorIndex > 0 && includeComponentHighestAncestorIndex > 0) {
if (componentAncestors.at(componentHighestAncestorIndex) != includeComponentAncestors.at(includeComponentHighestAncestorIndex))
break;
@@ -211,7 +211,7 @@ void UpdateIncludeDependenciesVisitor::visitMComponent(qmt::MComponent *componen
auto dependency = new qmt::MDependency;
dependency->setFlags(qmt::MElement::ReverseEngineered);
// TODO set stereotype for testing purpose
- dependency->setStereotypes(QStringList() << QStringLiteral("same stereotype"));
+ dependency->setStereotypes(QStringList() << "same stereotype");
dependency->setDirection(qmt::MDependency::AToB);
dependency->setSource(componentAncestors.at(index1)->uid());
dependency->setTarget(includeComponentAncestors.at(index2)->uid());
@@ -232,7 +232,7 @@ void UpdateIncludeDependenciesVisitor::visitMComponent(qmt::MComponent *componen
auto dependency = new qmt::MDependency;
dependency->setFlags(qmt::MElement::ReverseEngineered);
// TODO set stereotype for testing purpose
- dependency->setStereotypes(QStringList() << QStringLiteral("ancestor"));
+ dependency->setStereotypes(QStringList() << "ancestor");
dependency->setDirection(qmt::MDependency::AToB);
dependency->setSource(componentAncestors.at(componentHighestAncestorIndex)->uid());
dependency->setTarget(includeComponentAncestors.at(includeComponentHighestAncestorIndex)->uid());
@@ -247,7 +247,7 @@ void UpdateIncludeDependenciesVisitor::visitMComponent(qmt::MComponent *componen
auto dependency = new qmt::MDependency;
dependency->setFlags(qmt::MElement::ReverseEngineered);
// TODO set stereotype for testing purpose
- dependency->setStereotypes(QStringList() << QStringLiteral("parents"));
+ dependency->setStereotypes(QStringList() << "parents");
dependency->setDirection(qmt::MDependency::AToB);
dependency->setSource(componentAncestors.at(0)->uid());
dependency->setTarget(includeComponentAncestors.at(0)->uid());
@@ -360,8 +360,8 @@ bool UpdateIncludeDependenciesVisitor::haveDependency(const qmt::MObject *source
class ComponentViewController::ComponentViewControllerPrivate {
public:
- PxNodeUtilities *pxnodeUtilities = 0;
- qmt::DiagramSceneController *diagramSceneController = 0;
+ PxNodeUtilities *pxnodeUtilities = nullptr;
+ qmt::DiagramSceneController *diagramSceneController = nullptr;
};
ComponentViewController::ComponentViewController(QObject *parent)
@@ -408,7 +408,7 @@ void ComponentViewController::doCreateComponentModel(const ProjectExplorer::Fold
{
foreach (const ProjectExplorer::FileNode *fileNode, folderNode->fileNodes()) {
QString componentName = qmt::NameController::convertFileNameToElementName(fileNode->filePath().toString());
- qmt::MComponent *component = 0;
+ qmt::MComponent *component = nullptr;
bool isSource = false;
CppTools::ProjectFile::Kind kind = CppTools::ProjectFile::classify(fileNode->filePath().toString());
switch (kind) {
@@ -441,7 +441,7 @@ void ComponentViewController::doCreateComponentModel(const ProjectExplorer::Fold
if (d->pxnodeUtilities->findSameObject(relativeElements, component)) {
delete component;
} else {
- qmt::MPackage *requestedRootPackage = d->diagramSceneController->findSuitableParentPackage(0, diagram);
+ qmt::MPackage *requestedRootPackage = d->diagramSceneController->findSuitableParentPackage(nullptr, diagram);
qmt::MPackage *bestParentPackage = d->pxnodeUtilities->createBestMatchingPackagePath(requestedRootPackage, relativeElements);
d->diagramSceneController->modelController()->addObject(bestParentPackage, component);
}
diff --git a/src/plugins/modeleditor/componentviewcontroller.h b/src/plugins/modeleditor/componentviewcontroller.h
index 321805ab408..a0a70b73b8b 100644
--- a/src/plugins/modeleditor/componentviewcontroller.h
+++ b/src/plugins/modeleditor/componentviewcontroller.h
@@ -47,7 +47,7 @@ class ComponentViewController :
class ComponentViewControllerPrivate;
public:
- explicit ComponentViewController(QObject *parent = 0);
+ explicit ComponentViewController(QObject *parent = nullptr);
~ComponentViewController();
void setPxNodeUtilties(PxNodeUtilities *pxnodeUtilities);
diff --git a/src/plugins/modeleditor/diagramsviewmanager.h b/src/plugins/modeleditor/diagramsviewmanager.h
index 0811d6cd70e..62ecff23cc2 100644
--- a/src/plugins/modeleditor/diagramsviewmanager.h
+++ b/src/plugins/modeleditor/diagramsviewmanager.h
@@ -46,7 +46,7 @@ class DiagramsViewManager :
Q_OBJECT
public:
- explicit DiagramsViewManager(QObject *parent = 0);
+ explicit DiagramsViewManager(QObject *parent = nullptr);
~DiagramsViewManager() = default;
signals:
diff --git a/src/plugins/modeleditor/dragtool.h b/src/plugins/modeleditor/dragtool.h
index 5764f97ec6d..844b8189c2b 100644
--- a/src/plugins/modeleditor/dragtool.h
+++ b/src/plugins/modeleditor/dragtool.h
@@ -39,7 +39,7 @@ class DragTool :
public:
DragTool(const QIcon &icon, const QString &title, const QString &newElementId,
- const QString &stereotype, QWidget *parent = 0);
+ const QString &stereotype, QWidget *parent = nullptr);
~DragTool();
QSize sizeHint() const override;
diff --git a/src/plugins/modeleditor/editordiagramview.cpp b/src/plugins/modeleditor/editordiagramview.cpp
index 09621c2335c..5e2fe5b65e7 100644
--- a/src/plugins/modeleditor/editordiagramview.cpp
+++ b/src/plugins/modeleditor/editordiagramview.cpp
@@ -40,7 +40,7 @@ namespace Internal {
class EditorDiagramView::EditorDiagramViewPrivate {
public:
- PxNodeController *pxNodeController = 0;
+ PxNodeController *pxNodeController = nullptr;
};
EditorDiagramView::EditorDiagramView(QWidget *parent)
@@ -49,7 +49,7 @@ EditorDiagramView::EditorDiagramView(QWidget *parent)
{
auto droputils = new Utils::DropSupport(
this,
- [this](QDropEvent *event, Utils::DropSupport *dropSupport)
+ [](QDropEvent *event, Utils::DropSupport *dropSupport)
-> bool { return dropSupport->isValueDrop(event); });
connect(droputils, &Utils::DropSupport::valuesDropped,
this, &EditorDiagramView::dropProjectExplorerNodes);
diff --git a/src/plugins/modeleditor/editordiagramview.h b/src/plugins/modeleditor/editordiagramview.h
index 0a90af01617..984445d68f0 100644
--- a/src/plugins/modeleditor/editordiagramview.h
+++ b/src/plugins/modeleditor/editordiagramview.h
@@ -39,7 +39,7 @@ class EditorDiagramView :
class EditorDiagramViewPrivate;
public:
- explicit EditorDiagramView(QWidget *parent = 0);
+ explicit EditorDiagramView(QWidget *parent = nullptr);
~EditorDiagramView() override;
signals:
diff --git a/src/plugins/modeleditor/elementtasks.cpp b/src/plugins/modeleditor/elementtasks.cpp
index ed120c3523d..3ace1bec41c 100644
--- a/src/plugins/modeleditor/elementtasks.cpp
+++ b/src/plugins/modeleditor/elementtasks.cpp
@@ -59,8 +59,8 @@ namespace Internal {
class ElementTasks::ElementTasksPrivate {
public:
- qmt::DocumentController *documentController = 0;
- ComponentViewController *componentViewController = 0;
+ qmt::DocumentController *documentController = nullptr;
+ ComponentViewController *componentViewController = nullptr;
};
ElementTasks::ElementTasks(QObject *parent)
@@ -106,7 +106,7 @@ bool ElementTasks::hasClassDefinition(const qmt::MElement *element) const
if (auto klass = dynamic_cast<const qmt::MClass *>(element)) {
QString qualifiedClassName = klass->umlNamespace().isEmpty()
? klass->name()
- : klass->umlNamespace() + QStringLiteral("::") + klass->name();
+ : klass->umlNamespace() + "::" + klass->name();
CppTools::CppClassesFilter *classesFilter = ExtensionSystem::PluginManager::getObject<CppTools::CppClassesFilter>();
if (!classesFilter)
@@ -142,7 +142,7 @@ void ElementTasks::openClassDefinition(const qmt::MElement *element)
if (auto klass = dynamic_cast<const qmt::MClass *>(element)) {
QString qualifiedClassName = klass->umlNamespace().isEmpty()
? klass->name()
- : klass->umlNamespace() + QStringLiteral("::") + klass->name();
+ : klass->umlNamespace() + "::" + klass->name();
CppTools::CppClassesFilter *classesFilter = ExtensionSystem::PluginManager::getObject<CppTools::CppClassesFilter>();
if (!classesFilter)
@@ -274,7 +274,7 @@ bool ElementTasks::hasDiagram(const qmt::MElement *element) const
qmt::FindDiagramVisitor visitor;
element->accept(&visitor);
const qmt::MDiagram *diagram = visitor.diagram();
- return diagram != 0;
+ return diagram != nullptr;
}
bool ElementTasks::hasDiagram(const qmt::DElement *element, const qmt::MDiagram *diagram) const
@@ -373,7 +373,7 @@ void ElementTasks::openParentDiagram(const qmt::DElement *element, const qmt::ME
bool ElementTasks::mayCreateDiagram(const qmt::MElement *element) const
{
- return dynamic_cast<const qmt::MPackage *>(element) != 0;
+ return dynamic_cast<const qmt::MPackage *>(element) != nullptr;
}
bool ElementTasks::mayCreateDiagram(const qmt::DElement *element,
@@ -401,7 +401,7 @@ void ElementTasks::createAndOpenDiagram(const qmt::MElement *element)
auto newDiagram = new qmt::MCanvasDiagram();
newDiagram->setName(package->name());
qmt::MPackage *parentPackage = d->documentController->modelController()->findObject<qmt::MPackage>(package->uid());
- QTC_ASSERT(parentPackage, delete newDiagram; return);
+ QMT_ASSERT(parentPackage, delete newDiagram; return);
d->documentController->modelController()->addObject(parentPackage, newDiagram);
ModelEditorPlugin::modelsManager()->openDiagram(
d->documentController->projectController()->project()->uid(),
@@ -424,7 +424,7 @@ bool ElementTasks::extendContextMenu(const qmt::DElement *delement, const qmt::M
{
bool extended = false;
if (dynamic_cast<const qmt::DPackage *>(delement)) {
- menu->addAction(new qmt::ContextMenuAction(tr("Update Include Dependencies"), QStringLiteral("updateIncludeDependencies"), menu));
+ menu->addAction(new qmt::ContextMenuAction(tr("Update Include Dependencies"), "updateIncludeDependencies", menu));
extended = true;
}
return extended;
diff --git a/src/plugins/modeleditor/elementtasks.h b/src/plugins/modeleditor/elementtasks.h
index fa2fc53cdc6..458c31e54bd 100644
--- a/src/plugins/modeleditor/elementtasks.h
+++ b/src/plugins/modeleditor/elementtasks.h
@@ -43,7 +43,7 @@ class ElementTasks :
class ElementTasksPrivate;
public:
- ElementTasks(QObject *parent = 0);
+ ElementTasks(QObject *parent = nullptr);
~ElementTasks();
void setDocumentController(qmt::DocumentController *documentController);
diff --git a/src/plugins/modeleditor/extdocumentcontroller.cpp b/src/plugins/modeleditor/extdocumentcontroller.cpp
index 72e960461bf..e9c125215d5 100644
--- a/src/plugins/modeleditor/extdocumentcontroller.cpp
+++ b/src/plugins/modeleditor/extdocumentcontroller.cpp
@@ -38,8 +38,8 @@ namespace Internal {
class ExtDocumentController::ExtDocumentControllerPrivate {
public:
- ElementTasks *elementTasks = 0;
- PxNodeController *pxNodeController = 0;
+ ElementTasks *elementTasks = nullptr;
+ PxNodeController *pxNodeController = nullptr;
};
ExtDocumentController::ExtDocumentController(QObject *parent)
diff --git a/src/plugins/modeleditor/extdocumentcontroller.h b/src/plugins/modeleditor/extdocumentcontroller.h
index 667403b82e0..44a3fc716a6 100644
--- a/src/plugins/modeleditor/extdocumentcontroller.h
+++ b/src/plugins/modeleditor/extdocumentcontroller.h
@@ -40,7 +40,7 @@ class ExtDocumentController :
class ExtDocumentControllerPrivate;
public:
- explicit ExtDocumentController(QObject *parent = 0);
+ explicit ExtDocumentController(QObject *parent = nullptr);
~ExtDocumentController();
ElementTasks *elementTasks() const;
diff --git a/src/plugins/modeleditor/extpropertiesmview.cpp b/src/plugins/modeleditor/extpropertiesmview.cpp
index 529f251dca2..a0c19b71418 100644
--- a/src/plugins/modeleditor/extpropertiesmview.cpp
+++ b/src/plugins/modeleditor/extpropertiesmview.cpp
@@ -57,7 +57,7 @@ void ExtPropertiesMView::visitMPackage(const qmt::MPackage *package)
qmt::PropertiesView::MView::visitMPackage(package);
if (m_modelElements.size() == 1 && !package->owner()) {
qmt::Project *project = m_projectController->project();
- if (m_configPath == 0) {
+ if (!m_configPath) {
m_configPath = new Utils::PathChooser(m_topWidget);
m_configPath->setPromptDialogTitle(tr("Select Custom Configuration Folder"));
m_configPath->setExpectedKind(Utils::PathChooser::ExistingDirectory);
@@ -78,7 +78,7 @@ void ExtPropertiesMView::visitMPackage(const qmt::MPackage *package)
m_configPath->setPath(QFileInfo(projectDir, project->configPath()).canonicalFilePath());
}
}
- if (m_configPathInfo == 0) {
+ if (!m_configPathInfo) {
m_configPathInfo = new QLabel(m_topWidget);
addRow(QString(), m_configPathInfo, "configpathinfo");
}
diff --git a/src/plugins/modeleditor/extpropertiesmview.h b/src/plugins/modeleditor/extpropertiesmview.h
index 673fcd9d396..f9f2564ce2e 100644
--- a/src/plugins/modeleditor/extpropertiesmview.h
+++ b/src/plugins/modeleditor/extpropertiesmview.h
@@ -49,9 +49,9 @@ private:
void onConfigPathChanged(const QString &path);
private:
- qmt::ProjectController *m_projectController = 0;
- Utils::PathChooser *m_configPath = 0;
- QLabel *m_configPathInfo = 0;
+ qmt::ProjectController *m_projectController = nullptr;
+ Utils::PathChooser *m_configPath = nullptr;
+ QLabel *m_configPathInfo = nullptr;
};
} // namespace Interal
diff --git a/src/plugins/modeleditor/jsextension.h b/src/plugins/modeleditor/jsextension.h
index be2479fd683..74c7cbc892c 100644
--- a/src/plugins/modeleditor/jsextension.h
+++ b/src/plugins/modeleditor/jsextension.h
@@ -35,7 +35,7 @@ class JsExtension : public QObject
Q_OBJECT
public:
- JsExtension(QObject *parent = 0) : QObject(parent) { }
+ JsExtension(QObject *parent = nullptr) : QObject(parent) { }
Q_INVOKABLE QString fileNameToElementName(const QString &file);
Q_INVOKABLE QString elementNameToFileName(const QString &element);
diff --git a/src/plugins/modeleditor/modeldocument.cpp b/src/plugins/modeleditor/modeldocument.cpp
index e75ff0760e1..eef5ce60dcc 100644
--- a/src/plugins/modeleditor/modeldocument.cpp
+++ b/src/plugins/modeleditor/modeldocument.cpp
@@ -48,7 +48,7 @@ namespace Internal {
class ModelDocument::ModelDocumentPrivate {
public:
- ExtDocumentController *documentController = 0;
+ ExtDocumentController *documentController = nullptr;
};
ModelDocument::ModelDocument(QObject *parent)
diff --git a/src/plugins/modeleditor/modeldocument.h b/src/plugins/modeleditor/modeldocument.h
index f83085866ab..5f7a99cd56c 100644
--- a/src/plugins/modeleditor/modeldocument.h
+++ b/src/plugins/modeleditor/modeldocument.h
@@ -41,7 +41,7 @@ class ModelDocument :
class ModelDocumentPrivate;
public:
- explicit ModelDocument(QObject *parent = 0);
+ explicit ModelDocument(QObject *parent = nullptr);
~ModelDocument();
signals:
diff --git a/src/plugins/modeleditor/modeleditor.cpp b/src/plugins/modeleditor/modeleditor.cpp
index ea30818f5ad..9602c72c153 100644
--- a/src/plugins/modeleditor/modeleditor.cpp
+++ b/src/plugins/modeleditor/modeleditor.cpp
@@ -107,30 +107,30 @@ static const double ZOOM_FACTOR = 1.05;
class ModelEditor::ModelEditorPrivate
{
public:
- UiController *uiController = 0;
- ActionHandler *actionHandler = 0;
- ModelDocument *document = 0;
- qmt::PropertiesView *propertiesView = 0;
- Core::MiniSplitter *rightSplitter = 0;
- QWidget *leftGroup = 0;
- QHBoxLayout *leftGroupLayout = 0;
- QToolBox *leftToolBox = 0;
- QStackedWidget *diagramStack = 0;
- EditorDiagramView *diagramView = 0;
- QLabel *noDiagramLabel = 0;
- DiagramsViewManager *diagramsViewManager = 0;
- Core::MiniSplitter *rightHorizSplitter = 0;
- qmt::ModelTreeView *modelTreeView = 0;
- qmt::TreeModelManager *modelTreeViewServant = 0;
- QScrollArea *propertiesScrollArea = 0;
- QWidget *propertiesGroupWidget = 0;
- QWidget *toolbar = 0;
- QComboBox *diagramSelector = 0;
+ UiController *uiController = nullptr;
+ ActionHandler *actionHandler = nullptr;
+ ModelDocument *document = nullptr;
+ qmt::PropertiesView *propertiesView = nullptr;
+ Core::MiniSplitter *rightSplitter = nullptr;
+ QWidget *leftGroup = nullptr;
+ QHBoxLayout *leftGroupLayout = nullptr;
+ QToolBox *leftToolBox = nullptr;
+ QStackedWidget *diagramStack = nullptr;
+ EditorDiagramView *diagramView = nullptr;
+ QLabel *noDiagramLabel = nullptr;
+ DiagramsViewManager *diagramsViewManager = nullptr;
+ Core::MiniSplitter *rightHorizSplitter = nullptr;
+ qmt::ModelTreeView *modelTreeView = nullptr;
+ qmt::TreeModelManager *modelTreeViewServant = nullptr;
+ QScrollArea *propertiesScrollArea = nullptr;
+ QWidget *propertiesGroupWidget = nullptr;
+ QWidget *toolbar = nullptr;
+ QComboBox *diagramSelector = nullptr;
SelectedArea selectedArea = SelectedArea::Nothing;
QString lastExportDirPath;
- QAction *syncBrowserWithDiagramAction = 0;
- QAction *syncDiagramWithBrowserAction = 0;
- QAction *syncEachOtherAction = 0;
+ QAction *syncBrowserWithDiagramAction = nullptr;
+ QAction *syncDiagramWithBrowserAction = nullptr;
+ QAction *syncEachOtherAction = nullptr;
};
ModelEditor::ModelEditor(UiController *uiController, ActionHandler *actionHandler, QWidget *parent)
@@ -217,7 +217,7 @@ void ModelEditor::init(QWidget *parent)
d->leftToolBox = new QToolBox(d->leftGroup);
// Windows style does not truncate the tab label to a very small width (GTK+ does)
- static QStyle *windowsStyle = QStyleFactory().create(QStringLiteral("Windows"));
+ static QStyle *windowsStyle = QStyleFactory().create("Windows");
if (windowsStyle)
d->leftToolBox->setStyle(windowsStyle);
// TODO improve this (and the diagram colors) for use with dark theme
@@ -321,19 +321,19 @@ void ModelEditor::init(QWidget *parent)
toolbarLayout->addWidget(
createToolbarCommandButton(Constants::ACTION_ADD_PACKAGE, [this]() { onAddPackage(); },
- QIcon(QStringLiteral(":/modelinglib/48x48/package.png")),
+ QIcon(":/modelinglib/48x48/package.png"),
tr("Add Package"), d->toolbar));
toolbarLayout->addWidget(
createToolbarCommandButton(Constants::ACTION_ADD_COMPONENT, [this]() { onAddComponent(); },
- QIcon(QStringLiteral(":/modelinglib/48x48/component.png")),
+ QIcon(":/modelinglib/48x48/component.png"),
tr("Add Component"), d->toolbar));
toolbarLayout->addWidget(
createToolbarCommandButton(Constants::ACTION_ADD_CLASS, [this]() { onAddClass(); },
- QIcon(QStringLiteral(":/modelinglib/48x48/class.png")),
+ QIcon(":/modelinglib/48x48/class.png"),
tr("Add Class"), d->toolbar));
toolbarLayout->addWidget(
createToolbarCommandButton(Constants::ACTION_ADD_CANVAS_DIAGRAM, [this]() { onAddCanvasDiagram(); },
- QIcon(QStringLiteral(":/modelinglib/48x48/canvas-diagram.png")),
+ QIcon(":/modelinglib/48x48/canvas-diagram.png"),
tr("Add Canvas Diagram"), d->toolbar));
toolbarLayout->addSpacing(20);
@@ -341,13 +341,13 @@ void ModelEditor::init(QWidget *parent)
syncToggleButton->setDefaultAction(d->actionHandler->synchronizeBrowserAction());
QMenu *syncMenu = new QMenu(syncToggleButton);
QActionGroup *syncGroup = new QActionGroup(syncMenu);
- d->syncBrowserWithDiagramAction = syncMenu->addAction(QStringLiteral("Synchronize Structure with Diagram"));
+ d->syncBrowserWithDiagramAction = syncMenu->addAction(tr("Synchronize Structure with Diagram"));
d->syncBrowserWithDiagramAction->setCheckable(true);
d->syncBrowserWithDiagramAction->setActionGroup(syncGroup);
- d->syncDiagramWithBrowserAction = syncMenu->addAction(QStringLiteral("Synchronize Diagram with Structure"));
+ d->syncDiagramWithBrowserAction = syncMenu->addAction(tr("Synchronize Diagram with Structure"));
d->syncDiagramWithBrowserAction->setCheckable(true);
d->syncDiagramWithBrowserAction->setActionGroup(syncGroup);
- d->syncEachOtherAction = syncMenu->addAction(QStringLiteral("Keep Synchronized"));
+ d->syncEachOtherAction = syncMenu->addAction(tr("Keep Synchronized"));
d->syncEachOtherAction->setCheckable(true);
d->syncEachOtherAction->setActionGroup(syncGroup);
syncToggleButton->setMenu(syncMenu);
@@ -363,7 +363,7 @@ void ModelEditor::initDocument()
d->diagramView->setPxNodeController(documentController->pxNodeController());
- QTC_CHECK(!d->diagramsViewManager);
+ QMT_CHECK(!d->diagramsViewManager);
d->diagramsViewManager = new DiagramsViewManager(this);
//connect(diagramsViewManager, &DiagramsViewManager::someDiagramOpened,
// documentController->diagramsManager(), &qmt::DiagramsManager::someDiagramOpened);
@@ -578,13 +578,13 @@ void ModelEditor::exportDiagram()
QString suffix = QFileInfo(fileName).suffix().toLower();
// TODO use QFileDialog::selectedNameFilter() as fallback if no suffix is given
if (suffix.isEmpty()) {
- suffix = QStringLiteral("png");
- fileName += QStringLiteral(".png");
+ suffix = "png";
+ fileName += ".png";
}
- if (suffix == QStringLiteral("pdf"))
+ if (suffix == "pdf")
success = sceneModel->exportPdf(fileName);
#ifndef QT_NO_SVG
- else if (suffix == QStringLiteral("svg"))
+ else if (suffix == "svg")
success = sceneModel->exportSvg(fileName);
#endif // QT_NO_SVG
else
@@ -622,7 +622,7 @@ void ModelEditor::resetZoom()
qmt::MPackage *ModelEditor::guessSelectedPackage() const
{
- qmt::MPackage *package = 0;
+ qmt::MPackage *package = nullptr;
switch (d->selectedArea) {
case SelectedArea::Nothing:
package = d->modelTreeViewServant->selectedPackage();
@@ -661,13 +661,13 @@ void ModelEditor::updateSelectedArea(SelectedArea selectedArea)
bool canExportDiagram = false;
QList<qmt::MElement *> propertiesModelElements;
QList<qmt::DElement *> propertiesDiagramElements;
- qmt::MDiagram *propertiesDiagram = 0;
+ qmt::MDiagram *propertiesDiagram = nullptr;
qmt::MDiagram *activeDiagram = currentDiagram();
switch (d->selectedArea) {
case SelectedArea::Nothing:
canSelectAll = activeDiagram && !activeDiagram->diagramElements().isEmpty();
- canExportDiagram = activeDiagram != 0;
+ canExportDiagram = activeDiagram != nullptr;
break;
case SelectedArea::Diagram:
{
@@ -696,7 +696,7 @@ void ModelEditor::updateSelectedArea(SelectedArea selectedArea)
}
case SelectedArea::TreeView:
{
- canExportDiagram = activeDiagram != 0;
+ canExportDiagram = activeDiagram != nullptr;
bool hasSelection = !d->modelTreeViewServant->selectedObjects().isEmpty();
bool hasSingleSelection = d->modelTreeViewServant->selectedObjects().indices().size() == 1;
canCutCopyDelete = hasSelection && !d->modelTreeViewServant->isRootPackageSelected();
@@ -767,9 +767,9 @@ void ModelEditor::clearProperties()
if (d->propertiesGroupWidget) {
QWidget *scrollWidget = d->propertiesScrollArea->takeWidget();
Q_UNUSED(scrollWidget); // avoid warning in release mode
- QTC_CHECK(scrollWidget == d->propertiesGroupWidget);
+ QMT_CHECK(scrollWidget == d->propertiesGroupWidget);
d->propertiesGroupWidget->deleteLater();
- d->propertiesGroupWidget = 0;
+ d->propertiesGroupWidget = nullptr;
}
}
@@ -801,8 +801,8 @@ QToolButton *ModelEditor::createToolbarCommandButton(const Core::Id &id, const s
bool ModelEditor::updateButtonIconByTheme(QAbstractButton *button, const QString &name)
{
- QTC_ASSERT(button, return false);
- QTC_ASSERT(!name.isEmpty(), return false);
+ QMT_ASSERT(button, return false);
+ QMT_ASSERT(!name.isEmpty(), return false);
if (QIcon::hasThemeIcon(name)) {
button->setIcon(QIcon::fromTheme(name));
@@ -1003,7 +1003,7 @@ void ModelEditor::initToolbars()
[=](const qmt::Toolbar &lhs, const qmt::Toolbar &rhs) { return lhs.priority() > rhs.priority(); });
foreach (const qmt::Toolbar &toolbar, toolbars) {
QWidget *toolBar = toolBars.value(toolbar.id());
- QLayout *toolBarLayout = 0;
+ QLayout *toolBarLayout = nullptr;
if (!toolBar) {
toolBar = new QWidget(d->leftToolBox);
toolBar->setProperty(PROPERTYNAME_TOOLBARID, toolbar.id());
@@ -1015,7 +1015,7 @@ void ModelEditor::initToolbars()
toolBars.insert(toolbar.id(), toolBar);
} else {
toolBarLayout = toolBar->layout();
- QTC_ASSERT(toolBarLayout, continue);
+ QMT_ASSERT(toolBarLayout, continue);
}
foreach (const qmt::Toolbar::Tool &tool, toolbar.tools()) {
switch (tool.m_toolType) {
@@ -1025,27 +1025,30 @@ void ModelEditor::initToolbars()
qmt::StereotypeIcon::Element stereotypeIconElement = qmt::StereotypeIcon::ElementAny;
qmt::StyleEngine::ElementType styleEngineElementType = qmt::StyleEngine::TypeOther;
if (tool.m_elementType == QLatin1String(qmt::ELEMENT_TYPE_PACKAGE)) {
- iconPath = QStringLiteral(":/modelinglib/48x48/package.png");
+ iconPath = ":/modelinglib/48x48/package.png";
stereotypeIconElement = qmt::StereotypeIcon::ElementPackage;
styleEngineElementType = qmt::StyleEngine::TypePackage;
} else if (tool.m_elementType == QLatin1String(qmt::ELEMENT_TYPE_COMPONENT)) {
- iconPath = QStringLiteral(":/modelinglib/48x48/component.png");
+ iconPath = ":/modelinglib/48x48/component.png";
stereotypeIconElement = qmt::StereotypeIcon::ElementComponent;
styleEngineElementType = qmt::StyleEngine::TypeComponent;
} else if (tool.m_elementType == QLatin1String(qmt::ELEMENT_TYPE_CLASS)) {
- iconPath = QStringLiteral(":/modelinglib/48x48/class.png");
+ iconPath = ":/modelinglib/48x48/class.png";
stereotypeIconElement = qmt::StereotypeIcon::ElementClass;
styleEngineElementType = qmt::StyleEngine::TypeClass;
} else if (tool.m_elementType == QLatin1String(qmt::ELEMENT_TYPE_ITEM)) {
- iconPath = QStringLiteral(":/modelinglib/48x48/item.png");
+ iconPath = ":/modelinglib/48x48/item.png";
stereotypeIconElement = qmt::StereotypeIcon::ElementItem;
styleEngineElementType = qmt::StyleEngine::TypeItem;
} else if (tool.m_elementType == QLatin1String(qmt::ELEMENT_TYPE_ANNOTATION)) {
- iconPath = QStringLiteral(":/modelinglib/48x48/annotation.png");
+ iconPath = ":/modelinglib/48x48/annotation.png";
styleEngineElementType = qmt::StyleEngine::TypeAnnotation;
} else if (tool.m_elementType == QLatin1String(qmt::ELEMENT_TYPE_BOUNDARY)) {
- iconPath = QStringLiteral(":/modelinglib/48x48/boundary.png");
+ iconPath = ":/modelinglib/48x48/boundary.png";
styleEngineElementType = qmt::StyleEngine::TypeBoundary;
+ } else if (tool.m_elementType == QLatin1String(qmt::ELEMENT_TYPE_SWIMLANE)) {
+ iconPath = ":/modelinglib/48x48/swimlane.png";
+ styleEngineElementType = qmt::StyleEngine::TypeSwimlane;
}
QIcon icon;
if (!tool.m_stereotype.isEmpty() && stereotypeIconElement != qmt::StereotypeIcon::ElementAny) {
@@ -1075,7 +1078,7 @@ void ModelEditor::initToolbars()
// fallback if no toolbar was defined
if (!toolBars.isEmpty()) {
- QString generalId = QStringLiteral("General");
+ QString generalId = "General";
auto toolBar = new QWidget(d->leftToolBox);
toolBar->setProperty(PROPERTYNAME_TOOLBARID, generalId);
auto toolBarLayout = new QVBoxLayout(toolBar);
@@ -1084,40 +1087,44 @@ void ModelEditor::initToolbars()
d->leftToolBox->insertItem(0, toolBar, generalId);
toolBars.insert(generalId, toolBar);
toolBarLayout->addWidget(
- new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/package.png")),
+ new DragTool(QIcon(":/modelinglib/48x48/package.png"),
tr("Package"), QLatin1String(qmt::ELEMENT_TYPE_PACKAGE),
QString(), toolBar));
toolBarLayout->addWidget(
- new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/component.png")),
+ new DragTool(QIcon(":/modelinglib/48x48/component.png"),
tr("Component"), QLatin1String(qmt::ELEMENT_TYPE_COMPONENT),
QString(), toolBar));
toolBarLayout->addWidget(
- new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/class.png")),
+ new DragTool(QIcon(":/modelinglib/48x48/class.png"),
tr("Class"), QLatin1String(qmt::ELEMENT_TYPE_CLASS),
QString(), toolBar));
toolBarLayout->addWidget(
- new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/item.png")),
+ new DragTool(QIcon(":/modelinglib/48x48/item.png"),
tr("Item"), QLatin1String(qmt::ELEMENT_TYPE_ITEM),
QString(), toolBar));
auto horizLine1 = new QFrame(d->leftToolBox);
horizLine1->setFrameShape(QFrame::HLine);
toolBarLayout->addWidget(horizLine1);
toolBarLayout->addWidget(
- new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/annotation.png")),
+ new DragTool(QIcon(":/modelinglib/48x48/annotation.png"),
tr("Annotation"), QLatin1String(qmt::ELEMENT_TYPE_ANNOTATION),
QString(), toolBar));
toolBarLayout->addWidget(
- new DragTool(QIcon(QStringLiteral(":/modelinglib/48x48/boundary.png")),
+ new DragTool(QIcon(":/modelinglib/48x48/boundary.png"),
tr("Boundary"), QLatin1String(qmt::ELEMENT_TYPE_BOUNDARY),
QString(), toolBar));
+ toolBarLayout->addWidget(
+ new DragTool(QIcon(":/modelinglib/48x48/swimlane.png"),
+ tr("Swimlane"), QLatin1String(qmt::ELEMENT_TYPE_SWIMLANE),
+ QString(), toolBar));
}
// add stretch to all layouts and calculate width of tool bar
int maxWidth = 48;
foreach (QWidget *toolBar, toolBars) {
- QTC_ASSERT(toolBar, continue);
+ QMT_ASSERT(toolBar, continue);
auto layout = qobject_cast<QBoxLayout *>(toolBar->layout());
- QTC_ASSERT(layout, continue);
+ QMT_ASSERT(layout, continue);
layout->addStretch(1);
toolBar->adjustSize();
if (maxWidth < toolBar->width())
@@ -1209,7 +1216,7 @@ void ModelEditor::addDiagramToSelector(const qmt::MDiagram *diagram)
int i = d->diagramSelector->findData(diagramUid);
if (i >= 0)
d->diagramSelector->removeItem(i);
- d->diagramSelector->insertItem(0, QIcon(QStringLiteral(":/modelinglib/48x48/canvas-diagram.png")), diagramLabel, diagramUid);
+ d->diagramSelector->insertItem(0, QIcon(":/modelinglib/48x48/canvas-diagram.png"), diagramLabel, diagramUid);
d->diagramSelector->setCurrentIndex(0);
while (d->diagramSelector->count() > 20)
d->diagramSelector->removeItem(d->diagramSelector->count() - 1);
@@ -1257,7 +1264,7 @@ QString ModelEditor::buildDiagramLabel(const qmt::MDiagram *diagram)
owner = owner->owner();
}
if (!path.isEmpty()) {
- label += QStringLiteral(" [");
+ label += " [";
label += path.last();
for (int i = path.count() - 2; i >= 0; --i) {
label += QLatin1Char('.');
diff --git a/src/plugins/modeleditor/modeleditor.h b/src/plugins/modeleditor/modeleditor.h
index 7c51751a90c..2d4aaa26d70 100644
--- a/src/plugins/modeleditor/modeleditor.h
+++ b/src/plugins/modeleditor/modeleditor.h
@@ -65,7 +65,7 @@ class ModelEditor :
public:
explicit ModelEditor(UiController *uiController, ActionHandler *actionHandler,
- QWidget *parent = 0);
+ QWidget *parent = nullptr);
~ModelEditor();
Core::IDocument *document() override;
diff --git a/src/plugins/modeleditor/modeleditor_plugin.cpp b/src/plugins/modeleditor/modeleditor_plugin.cpp
index 756809f9078..acaa8f24dce 100644
--- a/src/plugins/modeleditor/modeleditor_plugin.cpp
+++ b/src/plugins/modeleditor/modeleditor_plugin.cpp
@@ -57,15 +57,15 @@
namespace ModelEditor {
namespace Internal {
-ModelEditorPlugin *pluginInstance = 0;
+ModelEditorPlugin *pluginInstance = nullptr;
class ModelEditorPlugin::ModelEditorPluginPrivate
{
public:
- ModelsManager *modelsManager = 0;
- UiController *uiController = 0;
- ModelEditorFactory *modelFactory = 0;
- SettingsController *settingsController = 0;
+ ModelsManager *modelsManager = nullptr;
+ UiController *uiController = nullptr;
+ ModelEditorFactory *modelFactory = nullptr;
+ SettingsController *settingsController = nullptr;
};
ModelEditorPlugin::ModelEditorPlugin()
diff --git a/src/plugins/modeleditor/modeleditorfactory.cpp b/src/plugins/modeleditor/modeleditorfactory.cpp
index ab6bf6746ea..da20bd8679c 100644
--- a/src/plugins/modeleditor/modeleditorfactory.cpp
+++ b/src/plugins/modeleditor/modeleditorfactory.cpp
@@ -37,8 +37,8 @@ namespace Internal {
class ModelEditorFactory::ModelEditorFactoryPrivate
{
public:
- UiController *uiController = 0;
- ActionHandler *actionHandler = 0;
+ UiController *uiController = nullptr;
+ ActionHandler *actionHandler = nullptr;
};
ModelEditorFactory::ModelEditorFactory(UiController *uiController, QObject *parent)
diff --git a/src/plugins/modeleditor/modeleditorfactory.h b/src/plugins/modeleditor/modeleditorfactory.h
index 972a1ae44e6..ca06f7da408 100644
--- a/src/plugins/modeleditor/modeleditorfactory.h
+++ b/src/plugins/modeleditor/modeleditorfactory.h
@@ -40,7 +40,7 @@ class ModelEditorFactory :
class ModelEditorFactoryPrivate;
public:
- explicit ModelEditorFactory(UiController *uiController, QObject *parent = 0);
+ explicit ModelEditorFactory(UiController *uiController, QObject *parent = nullptr);
~ModelEditorFactory();
Core::IEditor *createEditor() override;
diff --git a/src/plugins/modeleditor/modelindexer.cpp b/src/plugins/modeleditor/modelindexer.cpp
index 062244a1fe2..476edaae262 100644
--- a/src/plugins/modeleditor/modelindexer.cpp
+++ b/src/plugins/modeleditor/modelindexer.cpp
@@ -89,7 +89,7 @@ public:
private:
QString m_file;
- ProjectExplorer::Project *m_project = 0;
+ ProjectExplorer::Project *m_project = nullptr;
QDateTime m_lastModified;
};
@@ -234,12 +234,12 @@ class ModelIndexer::ModelIndexerPrivate
public:
~ModelIndexerPrivate()
{
- QTC_CHECK(filesQueue.isEmpty());
- QTC_CHECK(queuedFilesSet.isEmpty());
- QTC_CHECK(indexedModels.isEmpty());
- QTC_CHECK(indexedModelsByUid.isEmpty());
- QTC_CHECK(indexedDiagramReferences.isEmpty());
- QTC_CHECK(indexedDiagramReferencesByDiagramUid.isEmpty());
+ QMT_CHECK(filesQueue.isEmpty());
+ QMT_CHECK(queuedFilesSet.isEmpty());
+ QMT_CHECK(indexedModels.isEmpty());
+ QMT_CHECK(indexedModelsByUid.isEmpty());
+ QMT_CHECK(indexedDiagramReferences.isEmpty());
+ QMT_CHECK(indexedDiagramReferencesByDiagramUid.isEmpty());
delete indexerThread;
}
@@ -255,7 +255,7 @@ public:
QHash<QString, ModelIndexer::IndexedDiagramReference *> indexedDiagramReferences;
QHash<qmt::Uid, QSet<ModelIndexer::IndexedDiagramReference *> > indexedDiagramReferencesByDiagramUid;
- ModelIndexer::IndexerThread *indexerThread = 0;
+ ModelIndexer::IndexerThread *indexerThread = nullptr;
};
void ModelIndexer::IndexerThread::onQuitIndexerThread()
@@ -350,7 +350,7 @@ QString ModelIndexer::findModel(const qmt::Uid &modelUid)
if (indexedModels.isEmpty())
return QString();
IndexedModel *indexedModel = *indexedModels.cbegin();
- QTC_ASSERT(indexedModel, return QString());
+ QMT_ASSERT(indexedModel, return QString());
return indexedModel->file();
}
@@ -363,8 +363,8 @@ QString ModelIndexer::findDiagram(const qmt::Uid &modelUid, const qmt::Uid &diag
if (indexedDiagramReferences.isEmpty())
return QString();
IndexedDiagramReference *indexedDiagramReference = *indexedDiagramReferences.cbegin();
- QTC_ASSERT(indexedDiagramReference, return QString());
- QTC_ASSERT(indexedDiagramReference->modelUid() == modelUid, return QString());
+ QMT_ASSERT(indexedDiagramReference, return QString());
+ QMT_ASSERT(indexedDiagramReference->modelUid() == modelUid, return QString());
return indexedDiagramReference->file();
}
@@ -377,7 +377,7 @@ void ModelIndexer::onProjectAdded(ProjectExplorer::Project *project)
void ModelIndexer::onAboutToRemoveProject(ProjectExplorer::Project *project)
{
- disconnect(project, &ProjectExplorer::Project::fileListChanged, this, 0);
+ disconnect(project, &ProjectExplorer::Project::fileListChanged, this, nullptr);
forgetProject(project);
}
@@ -440,7 +440,7 @@ void ModelIndexer::scanProject(ProjectExplorer::Project *project)
while (!filesQueue.isEmpty()) {
QueuedFile queuedFile = filesQueue.takeFirst();
if (!d->queuedFilesSet.contains(queuedFile)) {
- QTC_CHECK(!d->filesQueue.contains(queuedFile));
+ QMT_CHECK(!d->filesQueue.contains(queuedFile));
d->filesQueue.append(queuedFile);
d->queuedFilesSet.insert(queuedFile);
filesAreQueued = true;
@@ -481,9 +481,9 @@ void ModelIndexer::forgetProject(ProjectExplorer::Project *project)
// remove file from queue
QueuedFile queuedFile(file, project);
if (d->queuedFilesSet.contains(queuedFile)) {
- QTC_CHECK(d->filesQueue.contains(queuedFile));
+ QMT_CHECK(d->filesQueue.contains(queuedFile));
d->filesQueue.removeOne(queuedFile);
- QTC_CHECK(!d->filesQueue.contains(queuedFile));
+ QMT_CHECK(!d->filesQueue.contains(queuedFile));
d->queuedFilesSet.remove(queuedFile);
}
removeModelFile(file, project);
@@ -503,9 +503,9 @@ void ModelIndexer::removeModelFile(const QString &file, ProjectExplorer::Project
d->indexedModels.remove(file);
// remove indexedModel from set of indexedModelsByUid
- QTC_CHECK(d->indexedModelsByUid.contains(indexedModel->modelUid()));
+ QMT_CHECK(d->indexedModelsByUid.contains(indexedModel->modelUid()));
QSet<IndexedModel *> indexedModels = d->indexedModelsByUid.value(indexedModel->modelUid());
- QTC_CHECK(indexedModels.contains(indexedModel));
+ QMT_CHECK(indexedModels.contains(indexedModel));
indexedModels.remove(indexedModel);
if (indexedModels.isEmpty())
d->indexedModelsByUid.remove(indexedModel->modelUid());
@@ -522,7 +522,7 @@ void ModelIndexer::removeDiagramReferenceFile(const QString &file,
{
IndexedDiagramReference *indexedDiagramReference = d->indexedDiagramReferences.value(file);
if (indexedDiagramReference) {
- QTC_CHECK(indexedDiagramReference->owningProjects().contains(project));
+ QMT_CHECK(indexedDiagramReference->owningProjects().contains(project));
qCDebug(logger) << "remove diagram reference file "
<< file << " from project " << project->displayName();
indexedDiagramReference->removeOwningProject(project);
@@ -531,9 +531,9 @@ void ModelIndexer::removeDiagramReferenceFile(const QString &file,
d->indexedDiagramReferences.remove(file);
// remove indexedDiagramReference from set of indexedDiagramReferecesByDiagramUid
- QTC_CHECK(d->indexedDiagramReferencesByDiagramUid.contains(indexedDiagramReference->diagramUid()));
+ QMT_CHECK(d->indexedDiagramReferencesByDiagramUid.contains(indexedDiagramReference->diagramUid()));
QSet<IndexedDiagramReference *> indexedDiagramReferences = d->indexedDiagramReferencesByDiagramUid.value(indexedDiagramReference->diagramUid());
- QTC_CHECK(indexedDiagramReferences.contains(indexedDiagramReference));
+ QMT_CHECK(indexedDiagramReferences.contains(indexedDiagramReference));
indexedDiagramReferences.remove(indexedDiagramReference);
if (indexedDiagramReferences.isEmpty()) {
d->indexedDiagramReferencesByDiagramUid.remove(
diff --git a/src/plugins/modeleditor/modelindexer.h b/src/plugins/modeleditor/modelindexer.h
index d392f386ea1..da925977b6a 100644
--- a/src/plugins/modeleditor/modelindexer.h
+++ b/src/plugins/modeleditor/modelindexer.h
@@ -53,7 +53,7 @@ class ModelIndexer :
const ModelIndexer::QueuedFile &rhs);
public:
- ModelIndexer(QObject *parent = 0);
+ ModelIndexer(QObject *parent = nullptr);
~ModelIndexer();
signals:
diff --git a/src/plugins/modeleditor/modelsmanager.cpp b/src/plugins/modeleditor/modelsmanager.cpp
index ab51ced73bf..89d691ddc6e 100644
--- a/src/plugins/modeleditor/modelsmanager.cpp
+++ b/src/plugins/modeleditor/modelsmanager.cpp
@@ -69,8 +69,8 @@ public:
ManagedModel() = default;
ManagedModel(ExtDocumentController *m_documentController,ModelDocument *m_modelDocument);
- ExtDocumentController *m_documentController = 0;
- ModelDocument *m_modelDocument = 0;
+ ExtDocumentController *m_documentController = nullptr;
+ ModelDocument *m_modelDocument = nullptr;
};
ModelsManager::ManagedModel::ManagedModel(ExtDocumentController *documentController,
@@ -88,11 +88,11 @@ public:
}
QList<ModelsManager::ManagedModel> managedModels;
- ModelIndexer *modelIndexer = 0;
+ ModelIndexer *modelIndexer = nullptr;
QList<Core::IDocument *> documentsToBeClosed;
- QAction *openDiagramContextMenuItem = 0;
- ProjectExplorer::Node *contextMenuOwnerNode = 0;
+ QAction *openDiagramContextMenuItem = nullptr;
+ ProjectExplorer::Node *contextMenuOwnerNode = nullptr;
};
ModelsManager::ModelsManager(QObject *parent)
@@ -123,7 +123,7 @@ ModelsManager::ModelsManager(QObject *parent)
ModelsManager::~ModelsManager()
{
- QTC_CHECK(d->managedModels.isEmpty());
+ QMT_CHECK(d->managedModels.isEmpty());
delete d->modelIndexer;
delete d;
}
@@ -150,7 +150,7 @@ void ModelsManager::releaseModel(ExtDocumentController *documentController)
return;
}
}
- QTC_CHECK(false);
+ QMT_CHECK(false);
}
void ModelsManager::openDiagram(const qmt::Uid &modelUid, const qmt::Uid &diagramUid)
@@ -158,7 +158,7 @@ void ModelsManager::openDiagram(const qmt::Uid &modelUid, const qmt::Uid &diagra
foreach (const ManagedModel &managedModel, d->managedModels) {
if (managedModel.m_documentController->projectController()->project()->uid() == modelUid) {
qmt::MDiagram *diagram = managedModel.m_documentController->modelController()->findObject<qmt::MDiagram>(diagramUid);
- QTC_ASSERT(diagram, continue);
+ QMT_ASSERT(diagram, continue);
openDiagram(managedModel.m_documentController, diagram);
return;
}
@@ -182,14 +182,14 @@ void ModelsManager::onAboutToShowContextMenu(ProjectExplorer::Project *project,
if (canOpenDiagram)
d->contextMenuOwnerNode = node;
else
- d->contextMenuOwnerNode = 0;
+ d->contextMenuOwnerNode = nullptr;
d->openDiagramContextMenuItem->setVisible(canOpenDiagram);
}
void ModelsManager::onOpenDiagramFromProjectExplorer()
{
- if (ProjectExplorer::ProjectTree::instance()->currentNode() == d->contextMenuOwnerNode) {
- qmt::MDiagram *diagram = 0;
+ if (ProjectExplorer::ProjectTree::findCurrentNode() == d->contextMenuOwnerNode) {
+ qmt::MDiagram *diagram = nullptr;
foreach (const ManagedModel &managedModel, d->managedModels) {
if ((diagram = managedModel.m_documentController->pxNodeController()->findDiagramForExplorerNode(d->contextMenuOwnerNode))) {
openDiagram(managedModel.m_documentController, diagram);
diff --git a/src/plugins/modeleditor/modelsmanager.h b/src/plugins/modeleditor/modelsmanager.h
index 743a0f3a578..09b1e290551 100644
--- a/src/plugins/modeleditor/modelsmanager.h
+++ b/src/plugins/modeleditor/modelsmanager.h
@@ -53,7 +53,7 @@ class ModelsManager :
class ModelsManagerPrivate;
public:
- explicit ModelsManager(QObject *parent = 0);
+ explicit ModelsManager(QObject *parent = nullptr);
~ModelsManager();
ExtDocumentController *createModel(ModelDocument *modelDocument);
diff --git a/src/plugins/modeleditor/openelementvisitor.cpp b/src/plugins/modeleditor/openelementvisitor.cpp
index 05cca71e390..24292975281 100644
--- a/src/plugins/modeleditor/openelementvisitor.cpp
+++ b/src/plugins/modeleditor/openelementvisitor.cpp
@@ -37,6 +37,7 @@
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dinheritance.h"
#include "qmt/diagram/dassociation.h"
+#include "qmt/diagram/dconnection.h"
#include "qmt/model/melement.h"
#include "qmt/model/mpackage.h"
@@ -121,6 +122,11 @@ void OpenDiagramElementVisitor::visitDAssociation(const qmt::DAssociation *assoc
visitDRelation(association);
}
+void OpenDiagramElementVisitor::visitDConnection(const qmt::DConnection *connection)
+{
+ visitDRelation(connection);
+}
+
void OpenDiagramElementVisitor::visitDAnnotation(const qmt::DAnnotation *annotation)
{
Q_UNUSED(annotation);
@@ -131,6 +137,11 @@ void OpenDiagramElementVisitor::visitDBoundary(const qmt::DBoundary *boundary)
Q_UNUSED(boundary);
}
+void OpenDiagramElementVisitor::visitDSwimlane(const qmt::DSwimlane *swimlane)
+{
+ Q_UNUSED(swimlane);
+}
+
void OpenModelElementVisitor::setElementTasks(ElementTasks *elementTasks)
{
m_elementTasks = elementTasks;
@@ -199,5 +210,10 @@ void OpenModelElementVisitor::visitMAssociation(const qmt::MAssociation *associa
Q_UNUSED(association);
}
+void OpenModelElementVisitor::visitMConnection(const qmt::MConnection *connection)
+{
+ Q_UNUSED(connection);
+}
+
} // namespace Internal
} // namespace ModelEditor
diff --git a/src/plugins/modeleditor/openelementvisitor.h b/src/plugins/modeleditor/openelementvisitor.h
index 48e04080768..de13828b890 100644
--- a/src/plugins/modeleditor/openelementvisitor.h
+++ b/src/plugins/modeleditor/openelementvisitor.h
@@ -42,23 +42,25 @@ public:
void setModelController(qmt::ModelController *modelController);
void setElementTasks(ElementTasks *elementTasks);
- void visitDElement(const qmt::DElement *element);
- void visitDObject(const qmt::DObject *object);
- void visitDPackage(const qmt::DPackage *package);
- void visitDClass(const qmt::DClass *klass);
- void visitDComponent(const qmt::DComponent *component);
- void visitDDiagram(const qmt::DDiagram *diagram);
- void visitDItem(const qmt::DItem *item);
- void visitDRelation(const qmt::DRelation *relation);
- void visitDInheritance(const qmt::DInheritance *inheritance);
- void visitDDependency(const qmt::DDependency *dependency);
- void visitDAssociation(const qmt::DAssociation *association);
- void visitDAnnotation(const qmt::DAnnotation *annotation);
- void visitDBoundary(const qmt::DBoundary *boundary);
+ void visitDElement(const qmt::DElement *element) override;
+ void visitDObject(const qmt::DObject *object) override;
+ void visitDPackage(const qmt::DPackage *package) override;
+ void visitDClass(const qmt::DClass *klass) override;
+ void visitDComponent(const qmt::DComponent *component) override;
+ void visitDDiagram(const qmt::DDiagram *diagram) override;
+ void visitDItem(const qmt::DItem *item) override;
+ void visitDRelation(const qmt::DRelation *relation) override;
+ void visitDInheritance(const qmt::DInheritance *inheritance) override;
+ void visitDDependency(const qmt::DDependency *dependency) override;
+ void visitDAssociation(const qmt::DAssociation *association) override;
+ void visitDConnection(const qmt::DConnection *connection) override;
+ void visitDAnnotation(const qmt::DAnnotation *annotation) override;
+ void visitDBoundary(const qmt::DBoundary *boundary) override;
+ void visitDSwimlane(const qmt::DSwimlane *swimlane) override;
private:
- qmt::ModelController *m_modelController = 0;
- ElementTasks *m_elementTasks = 0;
+ qmt::ModelController *m_modelController = nullptr;
+ ElementTasks *m_elementTasks = nullptr;
};
class OpenModelElementVisitor :
@@ -79,9 +81,10 @@ public:
void visitMDependency(const qmt::MDependency *dependency) override;
void visitMInheritance(const qmt::MInheritance *inheritance) override;
void visitMAssociation(const qmt::MAssociation *association) override;
+ void visitMConnection(const qmt::MConnection *connection) override;
private:
- ElementTasks *m_elementTasks = 0;
+ ElementTasks *m_elementTasks = nullptr;
};
} // namespace Internal
diff --git a/src/plugins/modeleditor/pxnodecontroller.cpp b/src/plugins/modeleditor/pxnodecontroller.cpp
index 79ceb8a9140..61e2f36541b 100644
--- a/src/plugins/modeleditor/pxnodecontroller.cpp
+++ b/src/plugins/modeleditor/pxnodecontroller.cpp
@@ -91,10 +91,10 @@ public:
class PxNodeController::PxNodeControllerPrivate
{
public:
- PxNodeUtilities *pxnodeUtilities = 0;
- ComponentViewController *componentViewController = 0;
- ClassViewController *classViewController = 0;
- qmt::DiagramSceneController *diagramSceneController = 0;
+ PxNodeUtilities *pxnodeUtilities = nullptr;
+ ComponentViewController *componentViewController = nullptr;
+ ClassViewController *classViewController = nullptr;
+ qmt::DiagramSceneController *diagramSceneController = nullptr;
QString anchorFolder;
};
@@ -135,8 +135,8 @@ void PxNodeController::addExplorerNode(const ProjectExplorer::Node *node,
qmt::DElement *topMostElementAtPos, const QPointF &pos,
qmt::MDiagram *diagram)
{
- QTC_ASSERT(node, return);
- QTC_ASSERT(diagram, return);
+ QMT_ASSERT(node, return);
+ QMT_ASSERT(diagram, return);
QString elementName = qmt::NameController::convertFileNameToElementName(
node->filePath().toString());
@@ -174,10 +174,10 @@ void PxNodeController::addExplorerNode(const ProjectExplorer::Node *node,
QString stereotype;
switch (node->nodeType()) {
case ProjectExplorer::NodeType::VirtualFolder:
- stereotype = QStringLiteral("virtual folder");
+ stereotype = "virtual folder";
break;
case ProjectExplorer::NodeType::Project:
- stereotype = QStringLiteral("project");
+ stereotype = "project";
break;
default:
break;
@@ -208,7 +208,7 @@ void PxNodeController::addExplorerNode(const ProjectExplorer::Node *node,
bool PxNodeController::hasDiagramForExplorerNode(const ProjectExplorer::Node *node)
{
- return findDiagramForExplorerNode(node) != 0;
+ return findDiagramForExplorerNode(node) != nullptr;
}
qmt::MDiagram *PxNodeController::findDiagramForExplorerNode(const ProjectExplorer::Node *node)
@@ -252,7 +252,7 @@ qmt::MDiagram *PxNodeController::findDiagramForExplorerNode(const ProjectExplore
}
if (found) {
- QTC_ASSERT(relativeIndex >= relativeElements.size(), return 0);
+ QMT_ASSERT(relativeIndex >= relativeElements.size(), return nullptr);
// complete package chain found so check for appropriate diagram within deepest package
qmt::MDiagram *diagram = d->diagramSceneController->findDiagramBySearchId(
package, package->name());
@@ -269,7 +269,7 @@ qmt::MDiagram *PxNodeController::findDiagramForExplorerNode(const ProjectExplore
}
// complete sub-package structure scanned but did not found the desired object
- return 0;
+ return nullptr;
}
void PxNodeController::onMenuActionTriggered(PxNodeController::MenuAction *action,
@@ -277,8 +277,8 @@ void PxNodeController::onMenuActionTriggered(PxNodeController::MenuAction *actio
qmt::DElement *topMostElementAtPos,
const QPointF &pos, qmt::MDiagram *diagram)
{
- qmt::MObject *newObject = 0;
- qmt::MDiagram *newDiagramInObject = 0;
+ qmt::MObject *newObject = nullptr;
+ qmt::MDiagram *newDiagramInObject = nullptr;
switch (action->type) {
case MenuAction::TYPE_ADD_COMPONENT:
@@ -329,7 +329,7 @@ void PxNodeController::onMenuActionTriggered(PxNodeController::MenuAction *actio
if (qmt::MObject *existingObject = d->pxnodeUtilities->findSameObject(relativeElements, package)) {
delete package;
package = dynamic_cast<qmt::MPackage *>(existingObject);
- QTC_ASSERT(package, return);
+ QMT_ASSERT(package, return);
d->diagramSceneController->addExistingModelElement(package->uid(), pos, diagram);
} else {
qmt::MPackage *requestedRootPackage = d->diagramSceneController->findSuitableParentPackage(topMostElementAtPos, diagram);
@@ -348,13 +348,13 @@ void PxNodeController::onMenuActionTriggered(PxNodeController::MenuAction *actio
if (newObject) {
d->diagramSceneController->modelController()->undoController()->beginMergeSequence(tr("Drop Node"));
- qmt::MObject *parentForDiagram = 0;
+ qmt::MObject *parentForDiagram = nullptr;
QStringList relativeElements = qmt::NameController::buildElementsPath(
d->pxnodeUtilities->calcRelativePath(node, d->anchorFolder),
- dynamic_cast<qmt::MPackage *>(newObject) != 0);
+ dynamic_cast<qmt::MPackage *>(newObject) != nullptr);
if (qmt::MObject *existingObject = d->pxnodeUtilities->findSameObject(relativeElements, newObject)) {
delete newObject;
- newObject = 0;
+ newObject = nullptr;
d->diagramSceneController->addExistingModelElement(existingObject->uid(), pos, diagram);
parentForDiagram = existingObject;
} else {
@@ -367,7 +367,7 @@ void PxNodeController::onMenuActionTriggered(PxNodeController::MenuAction *actio
// if requested and not existing then create new diagram in package
if (newDiagramInObject) {
auto package = dynamic_cast<qmt::MPackage *>(parentForDiagram);
- QTC_ASSERT(package, return);
+ QMT_ASSERT(package, return);
if (d->diagramSceneController->findDiagramBySearchId(package, newDiagramInObject->name()))
delete newDiagramInObject;
else
diff --git a/src/plugins/modeleditor/pxnodecontroller.h b/src/plugins/modeleditor/pxnodecontroller.h
index 7eee19e66af..7f5d570a9ba 100644
--- a/src/plugins/modeleditor/pxnodecontroller.h
+++ b/src/plugins/modeleditor/pxnodecontroller.h
@@ -49,7 +49,7 @@ class PxNodeController :
class MenuAction;
public:
- explicit PxNodeController(QObject *parent = 0);
+ explicit PxNodeController(QObject *parent = nullptr);
~PxNodeController();
ComponentViewController *componentViewController() const;
diff --git a/src/plugins/modeleditor/pxnodeutilities.cpp b/src/plugins/modeleditor/pxnodeutilities.cpp
index 31fede39fbd..34f830fb417 100644
--- a/src/plugins/modeleditor/pxnodeutilities.cpp
+++ b/src/plugins/modeleditor/pxnodeutilities.cpp
@@ -44,7 +44,7 @@ namespace Internal {
class PxNodeUtilities::PxNodeUtilitiesPrivate {
public:
- qmt::DiagramSceneController *diagramSceneController = 0;
+ qmt::DiagramSceneController *diagramSceneController = nullptr;
};
PxNodeUtilities::PxNodeUtilities(QObject *parent)
@@ -100,7 +100,7 @@ qmt::MPackage *PxNodeUtilities::createBestMatchingPackagePath(
int maxChainLength = -1;
int minChainDepth = -1;
- qmt::MPackage *bestParentPackage = 0;
+ qmt::MPackage *bestParentPackage = nullptr;
while (!roots.isEmpty()) {
qmt::MPackage *package = roots.first().first;
@@ -144,7 +144,7 @@ qmt::MPackage *PxNodeUtilities::createBestMatchingPackagePath(
if (found)
return package; // complete chain found, innermost package is already the result
- QTC_CHECK(!(relativeIndex == maxChainLength && minChainDepth < 0));
+ QMT_CHECK(!(relativeIndex == maxChainLength && minChainDepth < 0));
if (relativeIndex >= 1
&& (relativeIndex > maxChainLength
|| (relativeIndex == maxChainLength && depth < minChainDepth))) {
@@ -154,14 +154,14 @@ qmt::MPackage *PxNodeUtilities::createBestMatchingPackagePath(
}
}
- QTC_CHECK(maxChainLength < relativeElements.size());
+ QMT_CHECK(maxChainLength < relativeElements.size());
if (!bestParentPackage) {
- QTC_CHECK(maxChainLength == -1);
- QTC_CHECK(minChainDepth == -1);
+ QMT_CHECK(maxChainLength == -1);
+ QMT_CHECK(minChainDepth == -1);
maxChainLength = 0;
bestParentPackage = suggestedParentPackage;
} else {
- QTC_CHECK(maxChainLength >= 1);
+ QMT_CHECK(maxChainLength >= 1);
}
int i = maxChainLength;
@@ -215,7 +215,7 @@ qmt::MObject *PxNodeUtilities::findSameObject(const QStringList &relativeElement
}
if (found) {
- QTC_CHECK(relativeIndex >= relativeElements.size());
+ QMT_CHECK(relativeIndex >= relativeElements.size());
// chain was found so check for given object within deepest package
QString objectSearchId = qmt::NameController::calcElementNameSearchId(object->name());
foreach (const qmt::Handle<qmt::MObject> &handle, package->children()) {
@@ -231,7 +231,7 @@ qmt::MObject *PxNodeUtilities::findSameObject(const QStringList &relativeElement
}
// complete sub-package structure scanned but did not found the desired object
- return 0;
+ return nullptr;
}
} // namespace Internal
diff --git a/src/plugins/modeleditor/pxnodeutilities.h b/src/plugins/modeleditor/pxnodeutilities.h
index 1aea2f1b9ad..fd620de63e9 100644
--- a/src/plugins/modeleditor/pxnodeutilities.h
+++ b/src/plugins/modeleditor/pxnodeutilities.h
@@ -45,7 +45,7 @@ class PxNodeUtilities :
class PxNodeUtilitiesPrivate;
public:
- explicit PxNodeUtilities(QObject *parent = 0);
+ explicit PxNodeUtilities(QObject *parent = nullptr);
~PxNodeUtilities();
void setDiagramSceneController(qmt::DiagramSceneController *diagramSceneController);
diff --git a/src/plugins/modeleditor/settingscontroller.h b/src/plugins/modeleditor/settingscontroller.h
index 9400cd6282d..90371b66a76 100644
--- a/src/plugins/modeleditor/settingscontroller.h
+++ b/src/plugins/modeleditor/settingscontroller.h
@@ -40,7 +40,7 @@ class SettingsController :
Q_OBJECT
public:
- explicit SettingsController(QObject *parent = 0);
+ explicit SettingsController(QObject *parent = nullptr);
signals:
void resetSettings();
diff --git a/src/plugins/modeleditor/uicontroller.h b/src/plugins/modeleditor/uicontroller.h
index c31f630bca7..9dacf6d0690 100644
--- a/src/plugins/modeleditor/uicontroller.h
+++ b/src/plugins/modeleditor/uicontroller.h
@@ -41,7 +41,7 @@ class UiController :
class UiControllerPrivate;
public:
- explicit UiController(QObject *parent = 0);
+ explicit UiController(QObject *parent = nullptr);
~UiController();
signals:
diff --git a/src/plugins/nim/project/nimcompilerbuildstep.cpp b/src/plugins/nim/project/nimcompilerbuildstep.cpp
index 232afc29503..8f366488ffa 100644
--- a/src/plugins/nim/project/nimcompilerbuildstep.cpp
+++ b/src/plugins/nim/project/nimcompilerbuildstep.cpp
@@ -130,7 +130,7 @@ BuildStepConfigWidget *NimCompilerBuildStep::createConfigWidget()
bool NimCompilerBuildStep::fromMap(const QVariantMap &map)
{
AbstractProcessStep::fromMap(map);
- m_userCompilerOptions = map[Constants::C_NIMCOMPILERBUILDSTEP_USERCOMPILEROPTIONS].toString().split(QLatin1Char('|'));
+ m_userCompilerOptions = map[Constants::C_NIMCOMPILERBUILDSTEP_USERCOMPILEROPTIONS].toString().split('|');
m_defaultOptions = static_cast<DefaultBuildOptions>(map[Constants::C_NIMCOMPILERBUILDSTEP_DEFAULTBUILDOPTIONS].toInt());
m_targetNimFile = FileName::fromString(map[Constants::C_NIMCOMPILERBUILDSTEP_TARGETNIMFILE].toString());
updateProcessParameters();
@@ -140,7 +140,7 @@ bool NimCompilerBuildStep::fromMap(const QVariantMap &map)
QVariantMap NimCompilerBuildStep::toMap() const
{
QVariantMap result = AbstractProcessStep::toMap();
- result[Constants::C_NIMCOMPILERBUILDSTEP_USERCOMPILEROPTIONS] = m_userCompilerOptions.join(QLatin1Char('|'));
+ result[Constants::C_NIMCOMPILERBUILDSTEP_USERCOMPILEROPTIONS] = m_userCompilerOptions.join('|');
result[Constants::C_NIMCOMPILERBUILDSTEP_DEFAULTBUILDOPTIONS] = m_defaultOptions;
result[Constants::C_NIMCOMPILERBUILDSTEP_TARGETNIMFILE] = m_targetNimFile.toString();
return result;
diff --git a/src/plugins/nim/project/nimproject.cpp b/src/plugins/nim/project/nimproject.cpp
index 8910bd42af6..c6d28a3974a 100644
--- a/src/plugins/nim/project/nimproject.cpp
+++ b/src/plugins/nim/project/nimproject.cpp
@@ -127,6 +127,7 @@ void NimProject::collectProjectFiles()
void NimProject::updateProject()
{
+ emitParsingStarted();
const QStringList oldFiles = m_files;
m_files.clear();
@@ -152,7 +153,7 @@ void NimProject::updateProject()
newRoot->setDisplayName(displayName());
newRoot->addNestedNodes(fileNodes);
setRootProjectNode(newRoot);
- emit parsingFinished();
+ emitParsingFinished(true);
}
bool NimProject::supportsKit(Kit *k, QString *errorMessage) const
diff --git a/src/plugins/nim/project/nimprojectnode.cpp b/src/plugins/nim/project/nimprojectnode.cpp
index 223c6f950db..7604fb3a6df 100644
--- a/src/plugins/nim/project/nimprojectnode.cpp
+++ b/src/plugins/nim/project/nimprojectnode.cpp
@@ -37,7 +37,7 @@ NimProjectNode::NimProjectNode(NimProject &project,
, m_project(project)
{}
-bool NimProjectNode::supportsAction(ProjectAction action, Node *node) const
+bool NimProjectNode::supportsAction(ProjectAction action, const Node *node) const
{
switch (node->nodeType()) {
case NodeType::File:
diff --git a/src/plugins/nim/project/nimprojectnode.h b/src/plugins/nim/project/nimprojectnode.h
index 05270846f96..317d4be5554 100644
--- a/src/plugins/nim/project/nimprojectnode.h
+++ b/src/plugins/nim/project/nimprojectnode.h
@@ -38,7 +38,7 @@ class NimProjectNode : public ProjectExplorer::ProjectNode
public:
NimProjectNode(NimProject &project, const Utils::FileName &projectFilePath);
- bool supportsAction(ProjectExplorer::ProjectAction action, Node *node) const override;
+ bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
bool addFiles(const QStringList &filePaths, QStringList *) override;
bool removeFiles(const QStringList &filePaths, QStringList *) override;
bool deleteFiles(const QStringList &) override;
diff --git a/src/plugins/nim/project/nimrunconfiguration.cpp b/src/plugins/nim/project/nimrunconfiguration.cpp
index 7b9e43ab47b..cbf31afd1ba 100644
--- a/src/plugins/nim/project/nimrunconfiguration.cpp
+++ b/src/plugins/nim/project/nimrunconfiguration.cpp
@@ -44,9 +44,8 @@ using namespace Utils;
namespace Nim {
-NimRunConfiguration::NimRunConfiguration(Target *parent, Core::Id id)
- : RunConfiguration(parent, id)
- , m_buildConfiguration(nullptr)
+NimRunConfiguration::NimRunConfiguration(Target *target)
+ : RunConfiguration(target)
, m_workingDirectoryAspect(new WorkingDirectoryAspect(this, Nim::Constants::C_NIMRUNCONFIGURATION_WORKINGDIRECTORYASPECT_ID))
, m_argumentAspect(new ArgumentsAspect(this, Nim::Constants::C_NIMRUNCONFIGURATION_ARGUMENTASPECT_ID))
, m_terminalAspect(new TerminalAspect(this, Nim::Constants::C_NIMRUNCONFIGURATION_TERMINALASPECT_ID))
@@ -62,9 +61,8 @@ NimRunConfiguration::NimRunConfiguration(Target *parent, Core::Id id)
setDefaultDisplayName(tr(Constants::C_NIMRUNCONFIGURATION_DEFAULT_DISPLAY));
// Connect target signals
- connect(this->target(), &Target::activeBuildConfigurationChanged,
+ connect(target, &Target::activeBuildConfigurationChanged,
this, &NimRunConfiguration::updateConfiguration);
-
updateConfiguration();
}
diff --git a/src/plugins/nim/project/nimrunconfiguration.h b/src/plugins/nim/project/nimrunconfiguration.h
index 6769b4f307a..5ab1ce6130c 100644
--- a/src/plugins/nim/project/nimrunconfiguration.h
+++ b/src/plugins/nim/project/nimrunconfiguration.h
@@ -43,7 +43,7 @@ class NimRunConfiguration : public ProjectExplorer::RunConfiguration
Q_OBJECT
public:
- NimRunConfiguration(ProjectExplorer::Target *parent, Core::Id id);
+ explicit NimRunConfiguration(ProjectExplorer::Target *target);
QWidget *createConfigurationWidget() override;
ProjectExplorer::Runnable runnable() const override;
@@ -65,7 +65,7 @@ private:
void setActiveBuildConfiguration(NimBuildConfiguration *activeBuildConfiguration);
QString m_executable;
- NimBuildConfiguration *m_buildConfiguration;
+ NimBuildConfiguration *m_buildConfiguration = nullptr;
ProjectExplorer::WorkingDirectoryAspect* m_workingDirectoryAspect;
ProjectExplorer::ArgumentsAspect* m_argumentAspect;
ProjectExplorer::TerminalAspect* m_terminalAspect;
diff --git a/src/plugins/nim/project/nimrunconfigurationfactory.cpp b/src/plugins/nim/project/nimrunconfigurationfactory.cpp
index 7b00593017b..5bce6e297e7 100644
--- a/src/plugins/nim/project/nimrunconfigurationfactory.cpp
+++ b/src/plugins/nim/project/nimrunconfigurationfactory.cpp
@@ -80,7 +80,8 @@ RunConfiguration *NimRunConfigurationFactory::clone(Target *parent, RunConfigura
{
QTC_ASSERT(parent, return nullptr);
QTC_ASSERT(product, return nullptr);
- std::unique_ptr<NimRunConfiguration> result(new NimRunConfiguration(parent, Constants::C_NIMRUNCONFIGURATION_ID));
+ std::unique_ptr<NimRunConfiguration> result(
+ createHelper<NimRunConfiguration>(parent, Constants::C_NIMRUNCONFIGURATION_ID));
return result->fromMap(product->toMap()) ? result.release() : nullptr;
}
@@ -94,14 +95,13 @@ bool NimRunConfigurationFactory::canHandle(Target *parent) const
RunConfiguration *NimRunConfigurationFactory::doCreate(Target *parent, Core::Id id)
{
- Q_UNUSED(id);
- return new NimRunConfiguration(parent, id);
+ return createHelper<NimRunConfiguration>(parent, id);
}
RunConfiguration *NimRunConfigurationFactory::doRestore(Target *parent, const QVariantMap &map)
{
Q_UNUSED(map);
- auto result = new NimRunConfiguration(parent, idFromMap(map));
+ auto result = createHelper<NimRunConfiguration>(parent, idFromMap(map));
result->fromMap(map);
return result;
}
diff --git a/src/plugins/nim/project/nimrunconfigurationwidget.cpp b/src/plugins/nim/project/nimrunconfigurationwidget.cpp
index 74ea801937b..0fc0b671a6e 100644
--- a/src/plugins/nim/project/nimrunconfigurationwidget.cpp
+++ b/src/plugins/nim/project/nimrunconfigurationwidget.cpp
@@ -45,14 +45,6 @@ NimRunConfigurationWidget::NimRunConfigurationWidget(NimRunConfiguration *rc,
fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
rc->extraAspect<ArgumentsAspect>()->addToMainConfigurationWidget(this, fl);
rc->extraAspect<TerminalAspect>()->addToMainConfigurationWidget(this,fl);
- connect(rc, &NimRunConfiguration::enabledChanged, this, &NimRunConfigurationWidget::updateUi);
- updateUi();
}
-
-void NimRunConfigurationWidget::updateUi()
-{
- setEnabled(m_rc->isEnabled());
-}
-
-}
+} // namespace Nim
diff --git a/src/plugins/nim/project/nimrunconfigurationwidget.h b/src/plugins/nim/project/nimrunconfigurationwidget.h
index 9c47bf1d067..7e5e096bf0a 100644
--- a/src/plugins/nim/project/nimrunconfigurationwidget.h
+++ b/src/plugins/nim/project/nimrunconfigurationwidget.h
@@ -39,9 +39,7 @@ public:
explicit NimRunConfigurationWidget(NimRunConfiguration *rc, QWidget *parent = 0);
private:
- void updateUi();
-
NimRunConfiguration* m_rc;
};
-}
+} // namespace Nim
diff --git a/src/plugins/nim/project/nimtoolchain.cpp b/src/plugins/nim/project/nimtoolchain.cpp
index 6c8fd0f32b8..3605b5bcb6b 100644
--- a/src/plugins/nim/project/nimtoolchain.cpp
+++ b/src/plugins/nim/project/nimtoolchain.cpp
@@ -82,9 +82,9 @@ ToolChain::PredefinedMacrosRunner NimToolChain::createPredefinedMacrosRunner() c
return ToolChain::PredefinedMacrosRunner();
}
-QByteArray NimToolChain::predefinedMacros(const QStringList &) const
+Macros NimToolChain::predefinedMacros(const QStringList &) const
{
- return QByteArray();
+ return Macros();
}
ToolChain::CompilerFlags NimToolChain::compilerFlags(const QStringList &) const
diff --git a/src/plugins/nim/project/nimtoolchain.h b/src/plugins/nim/project/nimtoolchain.h
index 7061a9751bc..2da07dd2e23 100644
--- a/src/plugins/nim/project/nimtoolchain.h
+++ b/src/plugins/nim/project/nimtoolchain.h
@@ -41,7 +41,7 @@ public:
bool isValid() const override;
PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
- QByteArray predefinedMacros(const QStringList &flags) const final;
+ ProjectExplorer::Macros predefinedMacros(const QStringList &flags) const final;
CompilerFlags compilerFlags(const QStringList &flags) const final;
ProjectExplorer::WarningFlags warningFlags(const QStringList &flags) const final;
diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp
index ba5ed219c71..0278cd6403c 100644
--- a/src/plugins/perforce/perforceplugin.cpp
+++ b/src/plugins/perforce/perforceplugin.cpp
@@ -183,7 +183,7 @@ bool PerforcePlugin::initialize(const QStringList & /* arguments */, QString *er
Q_UNUSED(errorMessage)
Context context(PERFORCE_CONTEXT);
- initializeVcs(new PerforceVersionControl(this), context);
+ initializeVcs<PerforceVersionControl>(context, this);
m_instance = this;
@@ -556,6 +556,8 @@ void PerforcePlugin::printOpenedFileList()
void PerforcePlugin::startSubmitProject()
{
+ if (!promptBeforeCommit())
+ return;
if (raiseSubmitEditor())
return;
@@ -1225,6 +1227,11 @@ void PerforceDiffConfig::triggerReRun()
emit reRunDiff(effectiveParameters);
}
+QString PerforcePlugin::commitDisplayName() const
+{
+ return tr("submit", "\"commit\" action for perforce");
+}
+
void PerforcePlugin::p4Diff(const QString &workingDir, const QStringList &files)
{
PerforceDiffParameters p;
diff --git a/src/plugins/perforce/perforceplugin.h b/src/plugins/perforce/perforceplugin.h
index ae90276f977..814969537ad 100644
--- a/src/plugins/perforce/perforceplugin.h
+++ b/src/plugins/perforce/perforceplugin.h
@@ -113,6 +113,7 @@ private slots:
#endif
private:
+ QString commitDisplayName() const final;
void p4Diff(const PerforceDiffParameters &p);
void openCurrentFile();
diff --git a/src/plugins/projectexplorer/abi.cpp b/src/plugins/projectexplorer/abi.cpp
index 4a99590d824..90a27134a51 100644
--- a/src/plugins/projectexplorer/abi.cpp
+++ b/src/plugins/projectexplorer/abi.cpp
@@ -322,37 +322,41 @@ Abi::Abi(const Architecture &a, const OS &o,
m_architecture(a), m_os(o), m_osFlavor(of), m_binaryFormat(f), m_wordWidth(w)
{
switch (m_os) {
- case Abi::UnknownOS:
+ case UnknownOS:
m_osFlavor = UnknownFlavor;
break;
- case Abi::LinuxOS:
+ case LinuxOS:
if (m_osFlavor < GenericLinuxFlavor || m_osFlavor > AndroidLinuxFlavor)
m_osFlavor = UnknownFlavor;
break;
- case Abi::BsdOS:
+ case BsdOS:
if (m_osFlavor < FreeBsdFlavor || m_osFlavor > OpenBsdFlavor)
m_osFlavor = UnknownFlavor;
break;
- case Abi::DarwinOS:
+ case DarwinOS:
if (m_osFlavor < GenericDarwinFlavor || m_osFlavor > GenericDarwinFlavor)
m_osFlavor = UnknownFlavor;
break;
- case Abi::UnixOS:
+ case UnixOS:
if (m_osFlavor < GenericUnixFlavor || m_osFlavor > SolarisUnixFlavor)
m_osFlavor = UnknownFlavor;
break;
- case Abi::WindowsOS:
+ case WindowsOS:
if (m_osFlavor < WindowsMsvc2005Flavor || m_osFlavor > WindowsCEFlavor)
m_osFlavor = UnknownFlavor;
break;
- case Abi::VxWorks:
+ case VxWorks:
if (m_osFlavor != VxWorksFlavor)
m_osFlavor = VxWorksFlavor;
break;
- case Abi::QnxOS:
+ case QnxOS:
if (m_osFlavor != GenericQnxFlavor)
m_osFlavor = UnknownFlavor;
break;
+ case BareMetalOS:
+ if (m_osFlavor != GenericBareMetalFlavor)
+ m_osFlavor = GenericBareMetalFlavor;
+ break;
}
}
@@ -360,105 +364,107 @@ Abi::Abi(const QString &abiString) :
m_architecture(UnknownArchitecture), m_os(UnknownOS),
m_osFlavor(UnknownFlavor), m_binaryFormat(UnknownFormat), m_wordWidth(0)
{
- const QVector<QStringRef> abiParts = abiString.splitRef(QLatin1Char('-'));
+ const QVector<QStringRef> abiParts = abiString.splitRef('-');
if (abiParts.count() >= 1) {
- if (abiParts.at(0) == QLatin1String("unknown"))
+ if (abiParts.at(0) == "unknown")
m_architecture = UnknownArchitecture;
- else if (abiParts.at(0) == QLatin1String("arm"))
+ else if (abiParts.at(0) == "arm")
m_architecture = ArmArchitecture;
- else if (abiParts.at(0) == QLatin1String("aarch64"))
+ else if (abiParts.at(0) == "aarch64")
m_architecture = ArmArchitecture;
- else if (abiParts.at(0) == QLatin1String("x86"))
+ else if (abiParts.at(0) == "avr")
+ m_architecture = AvrArchitecture;
+ else if (abiParts.at(0) == "x86")
m_architecture = X86Architecture;
- else if (abiParts.at(0) == QLatin1String("mips"))
+ else if (abiParts.at(0) == "mips")
m_architecture = MipsArchitecture;
- else if (abiParts.at(0) == QLatin1String("ppc"))
+ else if (abiParts.at(0) == "ppc")
m_architecture = PowerPCArchitecture;
- else if (abiParts.at(0) == QLatin1String("itanium"))
+ else if (abiParts.at(0) == "itanium")
m_architecture = ItaniumArchitecture;
- else if (abiParts.at(0) == QLatin1String("sh"))
+ else if (abiParts.at(0) == "sh")
m_architecture = ShArchitecture;
else
return;
}
if (abiParts.count() >= 2) {
- if (abiParts.at(1) == QLatin1String("unknown"))
+ if (abiParts.at(1) == "unknown")
m_os = UnknownOS;
- else if (abiParts.at(1) == QLatin1String("linux"))
+ else if (abiParts.at(1) == "linux")
m_os = LinuxOS;
- else if (abiParts.at(1) == QLatin1String("bsd"))
+ else if (abiParts.at(1) == "bsd")
m_os = BsdOS;
- else if (abiParts.at(1) == QLatin1String("darwin")
- || abiParts.at(1) == QLatin1String("macos"))
+ else if (abiParts.at(1) == "darwin"
+ || abiParts.at(1) == "macos")
m_os = DarwinOS;
- else if (abiParts.at(1) == QLatin1String("unix"))
+ else if (abiParts.at(1) == "unix")
m_os = UnixOS;
- else if (abiParts.at(1) == QLatin1String("windows"))
+ else if (abiParts.at(1) == "windows")
m_os = WindowsOS;
- else if (abiParts.at(1) == QLatin1String("vxworks"))
+ else if (abiParts.at(1) == "vxworks")
m_os = VxWorks;
- else if (abiParts.at(1) == QLatin1String("qnx"))
+ else if (abiParts.at(1) == "qnx")
m_os = QnxOS;
else
return;
}
if (abiParts.count() >= 3) {
- if (abiParts.at(2) == QLatin1String("unknown"))
+ if (abiParts.at(2) == "unknown")
m_osFlavor = UnknownFlavor;
- else if (abiParts.at(2) == QLatin1String("generic") && m_os == LinuxOS)
+ else if (abiParts.at(2) == "generic" && m_os == LinuxOS)
m_osFlavor = GenericLinuxFlavor;
- else if (abiParts.at(2) == QLatin1String("android") && m_os == LinuxOS)
+ else if (abiParts.at(2) == "android" && m_os == LinuxOS)
m_osFlavor = AndroidLinuxFlavor;
- else if (abiParts.at(2) == QLatin1String("generic") && m_os == QnxOS)
+ else if (abiParts.at(2) == "generic" && m_os == QnxOS)
m_osFlavor = GenericQnxFlavor;
- else if (abiParts.at(2) == QLatin1String("freebsd") && m_os == BsdOS)
+ else if (abiParts.at(2) == "freebsd" && m_os == BsdOS)
m_osFlavor = FreeBsdFlavor;
- else if (abiParts.at(2) == QLatin1String("netbsd") && m_os == BsdOS)
+ else if (abiParts.at(2) == "netbsd" && m_os == BsdOS)
m_osFlavor = NetBsdFlavor;
- else if (abiParts.at(2) == QLatin1String("openbsd") && m_os == BsdOS)
+ else if (abiParts.at(2) == "openbsd" && m_os == BsdOS)
m_osFlavor = OpenBsdFlavor;
- else if (abiParts.at(2) == QLatin1String("generic") && m_os == DarwinOS)
+ else if (abiParts.at(2) == "generic" && m_os == DarwinOS)
m_osFlavor = GenericDarwinFlavor;
- else if (abiParts.at(2) == QLatin1String("generic") && m_os == UnixOS)
+ else if (abiParts.at(2) == "generic" && m_os == UnixOS)
m_osFlavor = GenericUnixFlavor;
- else if (abiParts.at(2) == QLatin1String("solaris") && m_os == UnixOS)
+ else if (abiParts.at(2) == "solaris" && m_os == UnixOS)
m_osFlavor = SolarisUnixFlavor;
- else if (abiParts.at(2) == QLatin1String("msvc2005") && m_os == WindowsOS)
+ else if (abiParts.at(2) == "msvc2005" && m_os == WindowsOS)
m_osFlavor = WindowsMsvc2005Flavor;
- else if (abiParts.at(2) == QLatin1String("msvc2008") && m_os == WindowsOS)
+ else if (abiParts.at(2) == "msvc2008" && m_os == WindowsOS)
m_osFlavor = WindowsMsvc2008Flavor;
- else if (abiParts.at(2) == QLatin1String("msvc2010") && m_os == WindowsOS)
+ else if (abiParts.at(2) == "msvc2010" && m_os == WindowsOS)
m_osFlavor = WindowsMsvc2010Flavor;
- else if (abiParts.at(2) == QLatin1String("msvc2012") && m_os == WindowsOS)
+ else if (abiParts.at(2) == "msvc2012" && m_os == WindowsOS)
m_osFlavor = WindowsMsvc2012Flavor;
- else if (abiParts.at(2) == QLatin1String("msvc2013") && m_os == WindowsOS)
+ else if (abiParts.at(2) == "msvc2013" && m_os == WindowsOS)
m_osFlavor = WindowsMsvc2013Flavor;
- else if (abiParts.at(2) == QLatin1String("msvc2015") && m_os == WindowsOS)
+ else if (abiParts.at(2) == "msvc2015" && m_os == WindowsOS)
m_osFlavor = WindowsMsvc2015Flavor;
- else if (abiParts.at(2) == QLatin1String("msvc2017") && m_os == WindowsOS)
+ else if (abiParts.at(2) == "msvc2017" && m_os == WindowsOS)
m_osFlavor = WindowsMsvc2017Flavor;
- else if (abiParts.at(2) == QLatin1String("msys") && m_os == WindowsOS)
+ else if (abiParts.at(2) == "msys" && m_os == WindowsOS)
m_osFlavor = WindowsMSysFlavor;
- else if (abiParts.at(2) == QLatin1String("ce") && m_os == WindowsOS)
+ else if (abiParts.at(2) == "ce" && m_os == WindowsOS)
m_osFlavor = WindowsCEFlavor;
- else if (abiParts.at(2) == QLatin1String("vxworks") && m_os == VxWorks)
+ else if (abiParts.at(2) == "vxworks" && m_os == VxWorks)
m_osFlavor = VxWorksFlavor;
else
return;
}
if (abiParts.count() >= 4) {
- if (abiParts.at(3) == QLatin1String("unknown"))
+ if (abiParts.at(3) == "unknown")
m_binaryFormat = UnknownFormat;
- else if (abiParts.at(3) == QLatin1String("elf"))
+ else if (abiParts.at(3) == "elf")
m_binaryFormat = ElfFormat;
- else if (abiParts.at(3) == QLatin1String("pe"))
+ else if (abiParts.at(3) == "pe")
m_binaryFormat = PEFormat;
- else if (abiParts.at(3) == QLatin1String("mach_o"))
+ else if (abiParts.at(3) == "mach_o")
m_binaryFormat = MachOFormat;
- else if (abiParts.at(3) == QLatin1String("qml_rt"))
+ else if (abiParts.at(3) == "qml_rt")
m_binaryFormat = RuntimeQmlFormat;
else
return;
@@ -466,7 +472,7 @@ Abi::Abi(const QString &abiString) :
if (abiParts.count() >= 5) {
const QStringRef &bits = abiParts.at(4);
- if (!bits.endsWith(QLatin1String("bit")))
+ if (!bits.endsWith("bit"))
return;
bool ok = false;
@@ -487,89 +493,95 @@ Abi Abi::abiFromTargetTriplet(const QString &triple)
if (machine.isEmpty())
return Abi();
- const QVector<QStringRef> parts = machine.splitRef(QRegExp(QLatin1String("[ /-]")));
+ const QVector<QStringRef> parts = machine.splitRef(QRegExp("[ /-]"));
- Abi::Architecture arch = Abi::UnknownArchitecture;
- Abi::OS os = Abi::UnknownOS;
- Abi::OSFlavor flavor = Abi::UnknownFlavor;
- Abi::BinaryFormat format = Abi::UnknownFormat;
+ Architecture arch = UnknownArchitecture;
+ OS os = UnknownOS;
+ OSFlavor flavor = UnknownFlavor;
+ BinaryFormat format = UnknownFormat;
unsigned char width = 0;
int unknownCount = 0;
for (const QStringRef &p : parts) {
- if (p == QLatin1String("unknown") || p == QLatin1String("pc") || p == QLatin1String("none")
- || p == QLatin1String("gnu") || p == QLatin1String("uclibc")
- || p == QLatin1String("86_64") || p == QLatin1String("redhat")
- || p == QLatin1String("gnueabi") || p == QLatin1String("w64")) {
+ if (p == "unknown" || p == "pc" || p == "none"
+ || p == "gnu" || p == "uclibc"
+ || p == "86_64" || p == "redhat"
+ || p == "gnueabi" || p == "w64") {
continue;
- } else if (p == QLatin1String("i386") || p == QLatin1String("i486") || p == QLatin1String("i586")
- || p == QLatin1String("i686") || p == QLatin1String("x86")) {
- arch = Abi::X86Architecture;
+ } else if (p == "i386" || p == "i486" || p == "i586"
+ || p == "i686" || p == "x86") {
+ arch = X86Architecture;
width = 32;
- } else if (p.startsWith(QLatin1String("arm"))) {
- arch = Abi::ArmArchitecture;
- width = p.contains(QLatin1String("64")) ? 64 : 32;
- } else if (p.startsWith(QLatin1String("aarch64"))) {
- arch = Abi::ArmArchitecture;
+ } else if (p.startsWith("arm")) {
+ arch = ArmArchitecture;
+ width = p.contains("64") ? 64 : 32;
+ } else if (p.startsWith("aarch64")) {
+ arch = ArmArchitecture;
width = 64;
- } else if (p.startsWith(QLatin1String("mips"))) {
- arch = Abi::MipsArchitecture;
- width = p.contains(QLatin1String("64")) ? 64 : 32;
- } else if (p == QLatin1String("x86_64") || p == QLatin1String("amd64")) {
- arch = Abi::X86Architecture;
+ } else if (p == "avr") {
+ arch = AvrArchitecture;
+ os = BareMetalOS;
+ flavor = GenericBareMetalFlavor;
+ format = ElfFormat;
+ width = 16;
+ } else if (p.startsWith("mips")) {
+ arch = MipsArchitecture;
+ width = p.contains("64") ? 64 : 32;
+ } else if (p == "x86_64" || p == "amd64") {
+ arch = X86Architecture;
width = 64;
- } else if (p == QLatin1String("powerpc64")) {
- arch = Abi::PowerPCArchitecture;
+ } else if (p == "powerpc64") {
+ arch = PowerPCArchitecture;
width = 64;
- } else if (p == QLatin1String("powerpc")) {
- arch = Abi::PowerPCArchitecture;
+ } else if (p == "powerpc") {
+ arch = PowerPCArchitecture;
width = 32;
- } else if (p == QLatin1String("linux") || p == QLatin1String("linux6e")) {
- os = Abi::LinuxOS;
- if (flavor == Abi::UnknownFlavor)
- flavor = Abi::GenericLinuxFlavor;
- format = Abi::ElfFormat;
- } else if (p == QLatin1String("android")) {
- flavor = Abi::AndroidLinuxFlavor;
- } else if (p == QLatin1String("androideabi")) {
- flavor = Abi::AndroidLinuxFlavor;
- } else if (p.startsWith(QLatin1String("freebsd"))) {
- os = Abi::BsdOS;
- if (flavor == Abi::UnknownFlavor)
- flavor = Abi::FreeBsdFlavor;
- format = Abi::ElfFormat;
- } else if (p.startsWith(QLatin1String("openbsd"))) {
- os = Abi::BsdOS;
- if (flavor == Abi::UnknownFlavor)
- flavor = Abi::OpenBsdFlavor;
- format = Abi::ElfFormat;
- } else if (p == QLatin1String("mingw32") || p == QLatin1String("win32")
- || p == QLatin1String("mingw32msvc") || p == QLatin1String("msys")
- || p == QLatin1String("cygwin") || p == QLatin1String("windows")) {
- arch = Abi::X86Architecture;
- os = Abi::WindowsOS;
- flavor = Abi::WindowsMSysFlavor;
- format = Abi::PEFormat;
- } else if (p == QLatin1String("apple")) {
- os = Abi::DarwinOS;
- flavor = Abi::GenericDarwinFlavor;
- format = Abi::MachOFormat;
- } else if (p == QLatin1String("darwin10")) {
+ } else if (p == "linux" || p == "linux6e") {
+ os = LinuxOS;
+ if (flavor == UnknownFlavor)
+ flavor = GenericLinuxFlavor;
+ format = ElfFormat;
+ } else if (p == "android") {
+ flavor = AndroidLinuxFlavor;
+ } else if (p == "androideabi") {
+ flavor = AndroidLinuxFlavor;
+ } else if (p.startsWith("freebsd")) {
+ os = BsdOS;
+ if (flavor == UnknownFlavor)
+ flavor = FreeBsdFlavor;
+ format = ElfFormat;
+ } else if (p.startsWith("openbsd")) {
+ os = BsdOS;
+ if (flavor == UnknownFlavor)
+ flavor = OpenBsdFlavor;
+ format = ElfFormat;
+ } else if (p == "mingw32" || p == "win32"
+ || p == "mingw32msvc" || p == "msys"
+ || p == "cygwin" || p == "windows") {
+ arch = X86Architecture;
+ os = WindowsOS;
+ flavor = WindowsMSysFlavor;
+ format = PEFormat;
+ } else if (p == "apple") {
+ os = DarwinOS;
+ flavor = GenericDarwinFlavor;
+ format = MachOFormat;
+ } else if (p == "darwin10") {
width = 64;
- } else if (p == QLatin1String("darwin9")) {
+ } else if (p == "darwin9") {
width = 32;
- } else if (p == QLatin1String("gnueabi")) {
- format = Abi::ElfFormat;
- } else if (p == QLatin1String("wrs")) {
+ } else if (p == "gnueabi") {
+ format = ElfFormat;
+ } else if (p == "wrs") {
continue;
- } else if (p == QLatin1String("vxworks")) {
- os = Abi::VxWorks;
- flavor = Abi::VxWorksFlavor;
- format = Abi::ElfFormat;
- } else if (p.startsWith(QLatin1String("qnx"))) {
- os = Abi::QnxOS;
- flavor = Abi::GenericQnxFlavor;
- format = Abi::ElfFormat;
+ } else if (p == "vxworks") {
+ os = VxWorks;
+ flavor = VxWorksFlavor;
+ format = ElfFormat;
+ } else if (p.startsWith("qnx")) {
+ os = QnxOS;
+ flavor = GenericQnxFlavor;
+ format = ElfFormat;
} else {
++unknownCount;
}
@@ -580,14 +592,9 @@ Abi Abi::abiFromTargetTriplet(const QString &triple)
QString Abi::toString() const
{
- QStringList dn;
- dn << toString(m_architecture);
- dn << toString(m_os);
- dn << toString(m_osFlavor);
- dn << toString(m_binaryFormat);
- dn << toString(m_wordWidth);
-
- return dn.join(QLatin1Char('-'));
+ const QStringList dn = {toString(m_architecture), toString(m_os), toString(m_osFlavor),
+ toString(m_binaryFormat), toString(m_wordWidth)};
+ return dn.join('-');
}
bool Abi::operator != (const Abi &other) const
@@ -662,6 +669,8 @@ QString Abi::toString(const Architecture &a)
switch (a) {
case ArmArchitecture:
return QLatin1String("arm");
+ case AvrArchitecture:
+ return QLatin1String("avr");
case X86Architecture:
return QLatin1String("x86");
case MipsArchitecture:
@@ -695,6 +704,8 @@ QString Abi::toString(const OS &o)
return QLatin1String("vxworks");
case QnxOS:
return QLatin1String("qnx");
+ case BareMetalOS:
+ return QLatin1String("baremetal");
case UnknownOS: // fall through!
default:
return QLatin1String("unknown");
@@ -704,45 +715,46 @@ QString Abi::toString(const OS &o)
QString Abi::toString(const OSFlavor &of)
{
switch (of) {
- case Abi::GenericLinuxFlavor:
+ case GenericLinuxFlavor:
return QLatin1String("generic");
- case Abi::AndroidLinuxFlavor:
+ case AndroidLinuxFlavor:
return QLatin1String("android");
- case Abi::FreeBsdFlavor:
+ case FreeBsdFlavor:
return QLatin1String("freebsd");
- case Abi::NetBsdFlavor:
+ case NetBsdFlavor:
return QLatin1String("netbsd");
- case Abi::OpenBsdFlavor:
+ case OpenBsdFlavor:
return QLatin1String("openbsd");
- case Abi::GenericDarwinFlavor:
+ case GenericDarwinFlavor:
return QLatin1String("generic");
- case Abi::GenericUnixFlavor:
+ case GenericUnixFlavor:
return QLatin1String("generic");
- case Abi::SolarisUnixFlavor:
+ case SolarisUnixFlavor:
return QLatin1String("solaris");
- case Abi::WindowsMsvc2005Flavor:
+ case WindowsMsvc2005Flavor:
return QLatin1String("msvc2005");
- case Abi::WindowsMsvc2008Flavor:
+ case WindowsMsvc2008Flavor:
return QLatin1String("msvc2008");
- case Abi::WindowsMsvc2010Flavor:
+ case WindowsMsvc2010Flavor:
return QLatin1String("msvc2010");
- case Abi::WindowsMsvc2012Flavor:
+ case WindowsMsvc2012Flavor:
return QLatin1String("msvc2012");
- case Abi::WindowsMsvc2013Flavor:
+ case WindowsMsvc2013Flavor:
return QLatin1String("msvc2013");
- case Abi::WindowsMsvc2015Flavor:
+ case WindowsMsvc2015Flavor:
return QLatin1String("msvc2015");
- case Abi::WindowsMsvc2017Flavor:
+ case WindowsMsvc2017Flavor:
return QLatin1String("msvc2017");
- case Abi::WindowsMSysFlavor:
+ case WindowsMSysFlavor:
return QLatin1String("msys");
- case Abi::WindowsCEFlavor:
+ case WindowsCEFlavor:
return QLatin1String("ce");
- case Abi::VxWorksFlavor:
+ case VxWorksFlavor:
return QLatin1String("vxworks");
- case Abi::GenericQnxFlavor:
+ case GenericQnxFlavor:
+ case GenericBareMetalFlavor:
return QLatin1String("generic");
- case Abi::UnknownFlavor: // fall through!
+ case UnknownFlavor: // fall through!
default:
return QLatin1String("unknown");
}
@@ -777,24 +789,25 @@ QList<Abi::OSFlavor> Abi::flavorsForOs(const Abi::OS &o)
QList<OSFlavor> result;
switch (o) {
case BsdOS:
- return result << FreeBsdFlavor << OpenBsdFlavor << NetBsdFlavor << UnknownFlavor;
+ return {FreeBsdFlavor, OpenBsdFlavor, NetBsdFlavor, UnknownFlavor};
case LinuxOS:
- return result << GenericLinuxFlavor << AndroidLinuxFlavor << UnknownFlavor;
+ return {GenericLinuxFlavor, AndroidLinuxFlavor, UnknownFlavor};
case DarwinOS:
- return result << GenericDarwinFlavor << UnknownFlavor;
+ return {GenericDarwinFlavor, UnknownFlavor};
case UnixOS:
- return result << GenericUnixFlavor << SolarisUnixFlavor << UnknownFlavor;
+ return {GenericUnixFlavor, SolarisUnixFlavor, UnknownFlavor};
case WindowsOS:
- return result << WindowsMsvc2005Flavor << WindowsMsvc2008Flavor << WindowsMsvc2010Flavor
- << WindowsMsvc2012Flavor << WindowsMsvc2013Flavor << WindowsMsvc2015Flavor
- << WindowsMsvc2017Flavor
- << WindowsMSysFlavor << WindowsCEFlavor << UnknownFlavor;
+ return {WindowsMsvc2005Flavor, WindowsMsvc2008Flavor, WindowsMsvc2010Flavor,
+ WindowsMsvc2012Flavor, WindowsMsvc2013Flavor, WindowsMsvc2015Flavor,
+ WindowsMsvc2017Flavor , WindowsMSysFlavor, WindowsCEFlavor, UnknownFlavor};
case VxWorks:
- return result << VxWorksFlavor << UnknownFlavor;
+ return {VxWorksFlavor, UnknownFlavor};
case QnxOS:
- return result << GenericQnxFlavor << UnknownFlavor;
+ return {GenericQnxFlavor, UnknownFlavor};
+ case BareMetalOS:
+ return {GenericBareMetalFlavor};
case UnknownOS:
- return result << UnknownFlavor;
+ return {UnknownFlavor};
default:
break;
}
@@ -896,7 +909,7 @@ QList<Abi> Abi::abisOfBinary(const Utils::FileName &path)
const QString fileName = QString::fromLocal8Bit(data.mid(0, 16));
quint64 fileNameOffset = 0;
- if (fileName.startsWith(QLatin1String("#1/")))
+ if (fileName.startsWith("#1/"))
fileNameOffset = fileName.midRef(3).toInt();
const QString fileLength = QString::fromLatin1(data.mid(48, 10));
@@ -904,11 +917,10 @@ QList<Abi> Abi::abisOfBinary(const Utils::FileName &path)
offset += fileLength.toInt() + 60 /* header */;
tmp.append(abiOf(data.mid(toSkip)));
- if (tmp.isEmpty() && fileName == QLatin1String("/0 "))
+ if (tmp.isEmpty() && fileName == "/0 ")
tmp = parseCoffHeader(data.mid(toSkip, 20)); // This might be windws...
- if (!tmp.isEmpty()
- && tmp.at(0).binaryFormat() != Abi::MachOFormat)
+ if (!tmp.isEmpty() && tmp.at(0).binaryFormat() != MachOFormat)
break;
offset += (offset % 2); // ar is 2 byte aligned
@@ -955,7 +967,7 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiOfBinary_data()
QString prefix = QString::fromLocal8Bit(qgetenv("QTC_TEST_EXTRADATALOCATION"));
if (prefix.isEmpty())
return;
- prefix += QLatin1String("/projectexplorer/abi");
+ prefix += "/projectexplorer/abi";
QFileInfo fi(prefix);
if (!fi.exists() || !fi.isDir())
@@ -1074,7 +1086,7 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiOfBinary()
QFETCH(QString, file);
QFETCH(QStringList, abis);
- QList<ProjectExplorer::Abi> result = Abi::abisOfBinary(Utils::FileName::fromString(file));
+ QList<Abi> result = Abi::abisOfBinary(Utils::FileName::fromString(file));
QCOMPARE(result.count(), abis.count());
for (int i = 0; i < abis.count(); ++i)
QCOMPARE(result.at(i).toString(), abis.at(i));
@@ -1082,7 +1094,7 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiOfBinary()
void ProjectExplorer::ProjectExplorerPlugin::testFlavorForOs()
{
- QList<QList<ProjectExplorer::Abi::OSFlavor> > flavorLists;
+ QList<QList<Abi::OSFlavor> > flavorLists;
for (int i = 0; i != static_cast<int>(Abi::UnknownOS); ++i)
flavorLists.append(Abi::flavorsForOs(static_cast<Abi::OS>(i)));
@@ -1214,6 +1226,11 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiFromTargetTriplet_data()
QTest::newRow("aarch64-unknown-linux-gnu") << int(Abi::ArmArchitecture)
<< int(Abi::LinuxOS) << int(Abi::GenericLinuxFlavor)
<< int(Abi::ElfFormat) << 64;
+
+ // Yes, that's the entire triplet
+ QTest::newRow("avr") << int(Abi::AvrArchitecture)
+ << int(Abi::BareMetalOS) << int(Abi::GenericBareMetalFlavor)
+ << int(Abi::ElfFormat) << 16;
}
void ProjectExplorer::ProjectExplorerPlugin::testAbiFromTargetTriplet()
@@ -1226,7 +1243,8 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiFromTargetTriplet()
const Abi expectedAbi = Abi(Abi::Architecture(architecture),
Abi::OS(os), Abi::OSFlavor(osFlavor),
- Abi::BinaryFormat(binaryFormat), (unsigned char)wordWidth);
+ Abi::BinaryFormat(binaryFormat),
+ static_cast<unsigned char>(wordWidth));
QCOMPARE(Abi::abiFromTargetTriplet(QLatin1String(QTest::currentDataTag())), expectedAbi);
}
diff --git a/src/plugins/projectexplorer/abi.h b/src/plugins/projectexplorer/abi.h
index 06157aa81b0..3fc3cbe1b1f 100644
--- a/src/plugins/projectexplorer/abi.h
+++ b/src/plugins/projectexplorer/abi.h
@@ -48,6 +48,7 @@ public:
MipsArchitecture,
PowerPCArchitecture,
ShArchitecture,
+ AvrArchitecture,
UnknownArchitecture
};
@@ -59,6 +60,7 @@ public:
WindowsOS,
VxWorks,
QnxOS,
+ BareMetalOS,
UnknownOS
};
@@ -90,10 +92,10 @@ public:
WindowsMSysFlavor,
WindowsCEFlavor,
+ // Embedded
VxWorksFlavor,
-
- // QNX
GenericQnxFlavor,
+ GenericBareMetalFlavor,
UnknownFlavor
};
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
index 121e2b43b4f..44d961ba087 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
@@ -118,7 +118,7 @@ ToolChain::PredefinedMacrosRunner AbstractMsvcToolChain::createPredefinedMacrosR
};
}
-QByteArray AbstractMsvcToolChain::predefinedMacros(const QStringList &cxxflags) const
+ProjectExplorer::Macros AbstractMsvcToolChain::predefinedMacros(const QStringList &cxxflags) const
{
return createPredefinedMacrosRunner()(cxxflags);
}
@@ -277,13 +277,6 @@ bool AbstractMsvcToolChain::canClone() const
return true;
}
-// Function must be thread-safe!
-QByteArray AbstractMsvcToolChain::msvcPredefinedMacros(const QStringList,
- const Utils::Environment&) const
-{
- return QByteArray();
-}
-
bool AbstractMsvcToolChain::generateEnvironmentSettings(const Utils::Environment &env,
const QString &batchFile,
const QString &batchArgs,
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.h b/src/plugins/projectexplorer/abstractmsvctoolchain.h
index 9a96faea0eb..0851e09cc09 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.h
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.h
@@ -53,7 +53,7 @@ public:
QString originalTargetTriple() const override;
PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
- QByteArray predefinedMacros(const QStringList &cxxflags) const override;
+ Macros predefinedMacros(const QStringList &cxxflags) const override;
CompilerFlags compilerFlags(const QStringList &cxxflags) const override;
WarningFlags warningFlags(const QStringList &cflags) const override;
SystemHeaderPathsRunner createSystemHeaderPathsRunner() const override;
@@ -92,13 +92,14 @@ protected:
static void inferWarningsForLevel(int warningLevel, WarningFlags &flags);
virtual Utils::Environment readEnvironmentSetting(const Utils::Environment& env) const = 0;
- virtual QByteArray msvcPredefinedMacros(const QStringList cxxflags,
- const Utils::Environment& env) const;
+ // Function must be thread-safe!
+ virtual Macros msvcPredefinedMacros(const QStringList cxxflags,
+ const Utils::Environment& env) const = 0;
Utils::FileName m_debuggerCommand;
mutable QMutex *m_predefinedMacrosMutex = nullptr;
- mutable QByteArray m_predefinedMacros;
+ mutable Macros m_predefinedMacros;
mutable Utils::Environment m_lastEnvironment; // Last checked 'incoming' environment.
mutable Utils::Environment m_resultEnvironment; // Resulting environment for VC
mutable QMutex *m_headerPathsMutex = nullptr;
diff --git a/src/plugins/projectexplorer/appoutputpane.cpp b/src/plugins/projectexplorer/appoutputpane.cpp
index 09007fe8b22..676b1de19b1 100644
--- a/src/plugins/projectexplorer/appoutputpane.cpp
+++ b/src/plugins/projectexplorer/appoutputpane.cpp
@@ -397,6 +397,8 @@ void AppOutputPane::updateBehaviorSettings()
void AppOutputPane::createNewOutputWindow(RunControl *rc)
{
+ QTC_ASSERT(rc, return);
+
connect(rc, &RunControl::aboutToStart,
this, &AppOutputPane::slotRunControlChanged);
connect(rc, &RunControl::started,
@@ -418,7 +420,7 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
if (tab.runControl)
tab.runControl->initiateFinish();
tab.runControl = rc;
- tab.window->setFormatter(rc ? rc->outputFormatter() : nullptr);
+ tab.window->setFormatter(rc->outputFormatter());
handleOldOutput(tab.window);
@@ -532,9 +534,9 @@ void AppOutputPane::stopRunControl()
if (rc->isRunning() && optionallyPromptToStop(rc))
rc->initiateStop();
- else if (rc->isStarting()) {
+ else {
QTC_CHECK(false);
- rc->initiateStop();
+ rc->forceStop();
}
if (debug)
diff --git a/src/plugins/projectexplorer/baseprojectwizarddialog.cpp b/src/plugins/projectexplorer/baseprojectwizarddialog.cpp
index 2d7a9588f83..61a66a12060 100644
--- a/src/plugins/projectexplorer/baseprojectwizarddialog.cpp
+++ b/src/plugins/projectexplorer/baseprojectwizarddialog.cpp
@@ -26,6 +26,7 @@
#include "baseprojectwizarddialog.h"
#include <coreplugin/documentmanager.h>
+#include <utils/fileutils.h>
#include <utils/projectintropage.h>
#include <QDir>
@@ -144,7 +145,7 @@ void BaseProjectWizardDialog::slotAccepted()
{
if (d->introPage->useAsDefaultPath()) {
// Store the path as default path for new projects if desired.
- Core::DocumentManager::setProjectsDirectory(path());
+ Core::DocumentManager::setProjectsDirectory(Utils::FileName::fromString(path()));
Core::DocumentManager::setUseProjectsDirectory(true);
}
}
diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp
index 3464c033f64..705d9b9b967 100644
--- a/src/plugins/projectexplorer/buildconfiguration.cpp
+++ b/src/plugins/projectexplorer/buildconfiguration.cpp
@@ -52,9 +52,10 @@ static const char BUILDDIRECTORY_KEY[] = "ProjectExplorer.BuildConfiguration.Bui
namespace ProjectExplorer {
BuildConfiguration::BuildConfiguration(Target *target, Core::Id id) :
- ProjectConfiguration(target, id),
+ ProjectConfiguration(target),
m_clearSystemEnvironment(false)
{
+ initialize(id);
Q_ASSERT(target);
auto bsl = new BuildStepList(this, Core::Id(Constants::BUILDSTEPS_BUILD));
//: Display name of the build build step list. Used as part of the labels in the project window.
@@ -76,11 +77,12 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id) :
}
BuildConfiguration::BuildConfiguration(Target *target, BuildConfiguration *source) :
- ProjectConfiguration(target, source),
+ ProjectConfiguration(target),
m_clearSystemEnvironment(source->m_clearSystemEnvironment),
m_userEnvironmentChanges(source->m_userEnvironmentChanges),
m_buildDirectory(source->m_buildDirectory)
{
+ copyFrom(source);
Q_ASSERT(target);
// Do not clone stepLists here, do that in the derived constructor instead
// otherwise BuildStepFactories might reject to set up a BuildStep for us
@@ -226,6 +228,11 @@ Target *BuildConfiguration::target() const
return static_cast<Target *>(parent());
}
+Project *BuildConfiguration::project() const
+{
+ return target()->project();
+}
+
Utils::Environment BuildConfiguration::baseEnvironment() const
{
Utils::Environment result;
@@ -318,6 +325,11 @@ QString BuildConfiguration::buildTypeName(BuildConfiguration::BuildType type)
}
}
+bool BuildConfiguration::isActive() const
+{
+ return target()->isActive() && target()->activeBuildConfiguration() == this;
+}
+
///
// IBuildConfigurationFactory
///
diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h
index 03d42d4dbdc..cc30d2ba44d 100644
--- a/src/plugins/projectexplorer/buildconfiguration.h
+++ b/src/plugins/projectexplorer/buildconfiguration.h
@@ -73,6 +73,7 @@ public:
QVariantMap toMap() const override;
Target *target() const;
+ Project *project() const override;
virtual bool isEnabled() const;
virtual QString disabledReason() const;
@@ -87,6 +88,8 @@ public:
static QString buildTypeName(BuildType type);
+ bool isActive() const override;
+
signals:
void environmentChanged();
void buildDirectoryChanged();
diff --git a/src/plugins/projectexplorer/buildconfigurationmodel.cpp b/src/plugins/projectexplorer/buildconfigurationmodel.cpp
deleted file mode 100644
index b8ef079f383..00000000000
--- a/src/plugins/projectexplorer/buildconfigurationmodel.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "buildconfigurationmodel.h"
-#include "target.h"
-#include "buildconfiguration.h"
-
-#include <utils/algorithm.h>
-
-using namespace ProjectExplorer;
-
-/*!
- \class ProjectExplorer::BuildConfigurationModel
- \brief The BuildConfigurationModel class is a model to represent the build
- configurations of a target.
-
- To be used in the dropdown lists of comboboxes.
- Automatically adjusts itself to added and removed BuildConfigurations.
- Very similar to the Run Configuration Model.
-
- TODO might it possible to share code without making the code a complete mess.
-*/
-
-class BuildConfigurationComparer
-{
-public:
- bool operator()(BuildConfiguration *a, BuildConfiguration *b)
- {
- return a->displayName() < b->displayName();
- }
-};
-
-BuildConfigurationModel::BuildConfigurationModel(Target *target, QObject *parent)
- : QAbstractListModel(parent),
- m_target(target)
-{
- m_buildConfigurations = m_target->buildConfigurations();
- Utils::sort(m_buildConfigurations, BuildConfigurationComparer());
-
- connect(target, &Target::addedBuildConfiguration,
- this, &BuildConfigurationModel::addedBuildConfiguration);
- connect(target, &Target::removedBuildConfiguration,
- this, &BuildConfigurationModel::removedBuildConfiguration);
-
- foreach (BuildConfiguration *bc, m_buildConfigurations)
- connect(bc, &ProjectConfiguration::displayNameChanged,
- this, &BuildConfigurationModel::displayNameChanged);
-}
-
-int BuildConfigurationModel::rowCount(const QModelIndex &parent) const
-{
- return parent.isValid() ? 0 : m_buildConfigurations.size();
-}
-
-int BuildConfigurationModel::columnCount(const QModelIndex &parent) const
-{
- return parent.isValid() ? 0 : 1;
-}
-
-void BuildConfigurationModel::displayNameChanged()
-{
- auto rc = qobject_cast<BuildConfiguration *>(sender());
- if (!rc)
- return;
-
- BuildConfigurationComparer compare;
- // Find the old position
- int oldPos = m_buildConfigurations.indexOf(rc);
-
- if (oldPos >= 1 && compare(m_buildConfigurations.at(oldPos), m_buildConfigurations.at(oldPos - 1))) {
- // We need to move up
- int newPos = oldPos - 1;
- while (newPos >= 0 && compare(m_buildConfigurations.at(oldPos), m_buildConfigurations.at(newPos))) {
- --newPos;
- }
- ++newPos;
-
- beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
- m_buildConfigurations.insert(newPos, rc);
- m_buildConfigurations.removeAt(oldPos + 1);
- endMoveRows();
- // Not only did we move, we also changed...
- emit dataChanged(index(newPos, 0), index(newPos,0));
- } else if (oldPos < m_buildConfigurations.size() - 1
- && compare(m_buildConfigurations.at(oldPos + 1), m_buildConfigurations.at(oldPos))) {
- // We need to move down
- int newPos = oldPos + 1;
- while (newPos < m_buildConfigurations.size()
- && compare(m_buildConfigurations.at(newPos), m_buildConfigurations.at(oldPos))) {
- ++newPos;
- }
- beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
- m_buildConfigurations.insert(newPos, rc);
- m_buildConfigurations.removeAt(oldPos);
- endMoveRows();
-
- // We need to subtract one since removing at the old place moves the newIndex down
- emit dataChanged(index(newPos - 1, 0), index(newPos - 1, 0));
- } else {
- emit dataChanged(index(oldPos, 0), index(oldPos, 0));
- }
-}
-
-QVariant BuildConfigurationModel::data(const QModelIndex &index, int role) const
-{
- if (role == Qt::DisplayRole) {
- const int row = index.row();
- if (row < m_buildConfigurations.size())
- return m_buildConfigurations.at(row)->displayName();
- }
-
- return QVariant();
-}
-
-BuildConfiguration *BuildConfigurationModel::buildConfigurationAt(int i)
-{
- if (i > m_buildConfigurations.size() || i < 0)
- return 0;
- return m_buildConfigurations.at(i);
-}
-
-BuildConfiguration *BuildConfigurationModel::buildConfigurationFor(const QModelIndex &idx)
-{
- if (idx.row() > m_buildConfigurations.size() || idx.row() < 0)
- return 0;
- return m_buildConfigurations.at(idx.row());
-}
-
-QModelIndex BuildConfigurationModel::indexFor(BuildConfiguration *rc)
-{
- int idx = m_buildConfigurations.indexOf(rc);
- if (idx == -1)
- return QModelIndex();
- return index(idx, 0);
-}
-
-void BuildConfigurationModel::addedBuildConfiguration(BuildConfiguration *bc)
-{
- // Find the right place to insert
- BuildConfigurationComparer compare;
- int i = 0;
- for (; i < m_buildConfigurations.size(); ++i) {
- if (compare(bc, m_buildConfigurations.at(i)))
- break;
- }
-
- beginInsertRows(QModelIndex(), i, i);
- m_buildConfigurations.insert(i, bc);
- endInsertRows();
-
-
- connect(bc, &ProjectConfiguration::displayNameChanged,
- this, &BuildConfigurationModel::displayNameChanged);
-}
-
-void BuildConfigurationModel::removedBuildConfiguration(BuildConfiguration *bc)
-{
- int i = m_buildConfigurations.indexOf(bc);
- beginRemoveRows(QModelIndex(), i, i);
- m_buildConfigurations.removeAt(i);
- endRemoveRows();
-}
diff --git a/src/plugins/projectexplorer/buildconfigurationmodel.h b/src/plugins/projectexplorer/buildconfigurationmodel.h
deleted file mode 100644
index b5712f85fc8..00000000000
--- a/src/plugins/projectexplorer/buildconfigurationmodel.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <QAbstractItemModel>
-
-namespace ProjectExplorer {
-class Target;
-class BuildConfiguration;
-
-// Documentation inside.
-class BuildConfigurationModel : public QAbstractListModel
-{
- Q_OBJECT
-public:
- explicit BuildConfigurationModel(Target *target, QObject *parent = nullptr);
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
-
- BuildConfiguration *buildConfigurationAt(int i);
- BuildConfiguration *buildConfigurationFor(const QModelIndex &idx);
- QModelIndex indexFor(BuildConfiguration *rc);
-
-private:
- void addedBuildConfiguration(ProjectExplorer::BuildConfiguration*);
- void removedBuildConfiguration(ProjectExplorer::BuildConfiguration*);
- void displayNameChanged();
-
- Target *m_target;
- QList<BuildConfiguration *> m_buildConfigurations;
-};
-
-} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildenvironmentwidget.cpp b/src/plugins/projectexplorer/buildenvironmentwidget.cpp
index f7f253d94b1..3177f7e6b19 100644
--- a/src/plugins/projectexplorer/buildenvironmentwidget.cpp
+++ b/src/plugins/projectexplorer/buildenvironmentwidget.cpp
@@ -53,7 +53,7 @@ BuildEnvironmentWidget::BuildEnvironmentWidget(BuildConfiguration *bc) :
m_buildConfiguration = bc;
- connect(m_buildConfiguration->target(), &Target::environmentChanged,
+ connect(m_buildConfiguration, &BuildConfiguration::environmentChanged,
this, &BuildEnvironmentWidget::environmentChanged);
m_clearSystemEnvironmentCheckBox->setChecked(!m_buildConfiguration->useSystemEnvironment());
diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
index 6319a59aea2..a144680a74f 100644
--- a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
@@ -29,7 +29,7 @@
#include "project.h"
#include "target.h"
#include "buildconfiguration.h"
-#include "buildconfigurationmodel.h"
+#include "projectconfigurationmodel.h"
#include "session.h"
#include <utils/qtcassert.h>
@@ -218,7 +218,7 @@ void BuildSettingsWidget::updateBuildSettings()
void BuildSettingsWidget::currentIndexChanged(int index)
{
auto model = static_cast<BuildConfigurationModel *>(m_buildConfigurationComboBox->model());
- BuildConfiguration *buildConfiguration = model->buildConfigurationAt(index);
+ auto buildConfiguration = qobject_cast<BuildConfiguration *>(model->projectConfigurationAt(index));
SessionManager::setActiveBuildConfiguration(m_target, buildConfiguration, SetActive::Cascade);
}
diff --git a/src/plugins/projectexplorer/buildstep.cpp b/src/plugins/projectexplorer/buildstep.cpp
index d428b0bef30..40c31f0c9f9 100644
--- a/src/plugins/projectexplorer/buildstep.cpp
+++ b/src/plugins/projectexplorer/buildstep.cpp
@@ -112,15 +112,17 @@ static const char buildStepEnabledKey[] = "ProjectExplorer.BuildStep.Enabled";
using namespace ProjectExplorer;
BuildStep::BuildStep(BuildStepList *bsl, Core::Id id) :
- ProjectConfiguration(bsl, id), m_enabled(true)
+ ProjectConfiguration(bsl), m_enabled(true)
{
+ initialize(id);
Q_ASSERT(bsl);
ctor();
}
BuildStep::BuildStep(BuildStepList *bsl, BuildStep *bs) :
- ProjectConfiguration(bsl, bs), m_enabled(bs->m_enabled)
+ ProjectConfiguration(bsl), m_enabled(bs->m_enabled)
{
+ copyFrom(bs);
Q_ASSERT(bsl);
setDisplayName(bs->displayName());
ctor();
@@ -136,14 +138,14 @@ void BuildStep::ctor()
bool BuildStep::fromMap(const QVariantMap &map)
{
- m_enabled = map.value(QLatin1String(buildStepEnabledKey), true).toBool();
+ m_enabled = map.value(buildStepEnabledKey, true).toBool();
return ProjectConfiguration::fromMap(map);
}
QVariantMap BuildStep::toMap() const
{
QVariantMap map = ProjectConfiguration::toMap();
- map.insert(QLatin1String(buildStepEnabledKey), m_enabled);
+ map.insert(buildStepEnabledKey, m_enabled);
return map;
}
@@ -178,6 +180,11 @@ void BuildStep::reportRunResult(QFutureInterface<bool> &fi, bool success)
fi.reportFinished();
}
+bool BuildStep::isActive() const
+{
+ return projectConfiguration()->isActive();
+}
+
/*!
If this function returns \c true, the user cannot delete this build step for
this target and the user is prevented from changing the order in which
diff --git a/src/plugins/projectexplorer/buildstep.h b/src/plugins/projectexplorer/buildstep.h
index bd907d9ddec..2fe6ee1960d 100644
--- a/src/plugins/projectexplorer/buildstep.h
+++ b/src/plugins/projectexplorer/buildstep.h
@@ -70,7 +70,7 @@ public:
DeployConfiguration *deployConfiguration() const;
ProjectConfiguration *projectConfiguration() const;
Target *target() const;
- Project *project() const;
+ Project *project() const override;
enum class OutputFormat {
Stdout, Stderr, // These are for forwarded output from external tools
@@ -81,6 +81,8 @@ public:
static void reportRunResult(QFutureInterface<bool> &fi, bool success);
+ bool isActive() const override;
+
signals:
/// Adds a \p task to the Issues pane.
/// Do note that for linking compile output with tasks, you should first emit the task
@@ -97,7 +99,7 @@ signals:
private:
void ctor();
- bool m_enabled;
+ bool m_enabled = true;
};
class PROJECTEXPLORER_EXPORT BuildStepInfo
diff --git a/src/plugins/projectexplorer/buildsteplist.cpp b/src/plugins/projectexplorer/buildsteplist.cpp
index 51b25fe2040..0cb7e618a5a 100644
--- a/src/plugins/projectexplorer/buildsteplist.cpp
+++ b/src/plugins/projectexplorer/buildsteplist.cpp
@@ -45,14 +45,16 @@ const char STEPS_PREFIX[] = "ProjectExplorer.BuildStepList.Step.";
} // namespace
BuildStepList::BuildStepList(QObject *parent, Core::Id id) :
- ProjectConfiguration(parent, id)
+ ProjectConfiguration(parent)
{
Q_ASSERT(parent);
+ initialize(id);
}
BuildStepList::BuildStepList(QObject *parent, BuildStepList *source) :
- ProjectConfiguration(parent, source)
+ ProjectConfiguration(parent)
{
+ copyFrom(source);
setDisplayName(source->displayName());
Q_ASSERT(parent);
// do not clone the steps here:
@@ -116,6 +118,11 @@ void BuildStepList::cloneSteps(BuildStepList *source)
}
}
+bool BuildStepList::isActive() const
+{
+ return qobject_cast<ProjectConfiguration *>(parent())->isActive();
+}
+
bool BuildStepList::fromMap(const QVariantMap &map)
{
// We need the ID set before trying to restore the steps!
@@ -198,3 +205,8 @@ Target *BuildStepList::target() const
return dc->target();
return 0;
}
+
+Project *BuildStepList::project() const
+{
+ return target()->project();
+}
diff --git a/src/plugins/projectexplorer/buildsteplist.h b/src/plugins/projectexplorer/buildsteplist.h
index 1ca131e2eb4..8a1c6659bc1 100644
--- a/src/plugins/projectexplorer/buildsteplist.h
+++ b/src/plugins/projectexplorer/buildsteplist.h
@@ -78,11 +78,14 @@ public:
BuildStep *at(int position);
Target *target() const;
+ Project *project() const override;
virtual QVariantMap toMap() const override;
virtual bool fromMap(const QVariantMap &map) override;
void cloneSteps(BuildStepList *source);
+ bool isActive() const override;
+
signals:
void stepInserted(int position);
void aboutToRemoveStep(int position);
diff --git a/src/plugins/projectexplorer/compileoutputwindow.cpp b/src/plugins/projectexplorer/compileoutputwindow.cpp
index fb56d5d2c62..2f1e4f75a0c 100644
--- a/src/plugins/projectexplorer/compileoutputwindow.cpp
+++ b/src/plugins/projectexplorer/compileoutputwindow.cpp
@@ -35,6 +35,7 @@
#include <coreplugin/outputwindow.h>
#include <coreplugin/find/basetextfind.h>
#include <coreplugin/icore.h>
+#include <coreplugin/coreconstants.h>
#include <extensionsystem/pluginmanager.h>
#include <texteditor/texteditorsettings.h>
#include <texteditor/fontsettings.h>
@@ -55,7 +56,6 @@ using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;
namespace {
-const int MAX_LINECOUNT = 100000;
const char SETTINGS_KEY[] = "ProjectExplorer/CompileOutput/Zoom";
const char C_COMPILE_OUTPUT[] = "ProjectExplorer.CompileOutput";
}
@@ -159,7 +159,7 @@ CompileOutputWindow::CompileOutputWindow(QAction *cancelBuildAction) :
m_outputWindow->setWindowIcon(Icons::WINDOW.icon());
m_outputWindow->setReadOnly(true);
m_outputWindow->setUndoRedoEnabled(false);
- m_outputWindow->setMaxLineCount(MAX_LINECOUNT);
+ m_outputWindow->setMaxLineCount(Core::Constants::DEFAULT_MAX_LINE_COUNT);
// Let selected text be colored as if the text edit was editable,
// otherwise the highlight for searching is too light
@@ -199,8 +199,8 @@ CompileOutputWindow::CompileOutputWindow(QAction *cancelBuildAction) :
m_handler = new ShowOutputTaskHandler(this);
ExtensionSystem::PluginManager::addObject(m_handler);
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
- this, &CompileOutputWindow::updateWordWrapMode);
- updateWordWrapMode();
+ this, &CompileOutputWindow::updateFromSettings);
+ updateFromSettings();
}
CompileOutputWindow::~CompileOutputWindow()
@@ -223,9 +223,10 @@ void CompileOutputWindow::updateZoomEnabled()
m_outputWindow->setWheelZoomEnabled(zoomEnabled);
}
-void CompileOutputWindow::updateWordWrapMode()
+void CompileOutputWindow::updateFromSettings()
{
m_outputWindow->setWordWrapEnabled(ProjectExplorerPlugin::projectExplorerSettings().wrapAppOutput);
+ m_outputWindow->setMaxLineCount(ProjectExplorerPlugin::projectExplorerSettings().maxBuildOutputLines);
}
bool CompileOutputWindow::hasFocus() const
@@ -323,7 +324,7 @@ void CompileOutputWindow::registerPositionOf(const Task &task, int linkedOutputL
if (linkedOutputLines <= 0)
return;
int blocknumber = m_outputWindow->document()->blockCount();
- if (blocknumber > MAX_LINECOUNT)
+ if (blocknumber > m_outputWindow->maxLineCount())
return;
const int startLine = blocknumber - linkedOutputLines + 1 - skipLines;
diff --git a/src/plugins/projectexplorer/compileoutputwindow.h b/src/plugins/projectexplorer/compileoutputwindow.h
index 043b07001b1..3e9e3b0b517 100644
--- a/src/plugins/projectexplorer/compileoutputwindow.h
+++ b/src/plugins/projectexplorer/compileoutputwindow.h
@@ -82,7 +82,7 @@ public:
void flush();
private:
- void updateWordWrapMode();
+ void updateFromSettings();
void updateZoomEnabled();
CompileOutputTextEdit *m_outputWindow;
diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
index dc2dbc9603d..c349e850896 100644
--- a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
+++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
@@ -82,32 +82,32 @@ private:
CustomExecutableConfigurationWidget *m_widget;
};
-
-void CustomExecutableRunConfiguration::ctor()
-{
- setDefaultDisplayName(defaultDisplayName());
-}
-
-CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *parent) :
- RunConfiguration(parent, CUSTOM_EXECUTABLE_ID)
+CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *target)
+ : RunConfiguration(target)
{
addExtraAspect(new LocalEnvironmentAspect(this, LocalEnvironmentAspect::BaseEnvironmentModifier()));
addExtraAspect(new ArgumentsAspect(this, "ProjectExplorer.CustomExecutableRunConfiguration.Arguments"));
addExtraAspect(new TerminalAspect(this, "ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal"));
- if (parent->activeBuildConfiguration())
+}
+
+void CustomExecutableRunConfiguration::initialize()
+{
+ RunConfiguration::initialize(CUSTOM_EXECUTABLE_ID);
+ if (target()->activeBuildConfiguration())
m_workingDirectory = Constants::DEFAULT_WORKING_DIR;
else
m_workingDirectory = Constants::DEFAULT_WORKING_DIR_ALTERNATE;
- ctor();
+
+ setDefaultDisplayName(defaultDisplayName());
}
-CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *parent,
- CustomExecutableRunConfiguration *source) :
- RunConfiguration(parent, source),
- m_executable(source->m_executable),
- m_workingDirectory(source->m_workingDirectory)
+void CustomExecutableRunConfiguration::copyFrom(const CustomExecutableRunConfiguration *source)
{
- ctor();
+ RunConfiguration::copyFrom(source);
+ m_executable = source->m_executable;
+ m_workingDirectory = source->m_workingDirectory;
+
+ setDefaultDisplayName(defaultDisplayName());
}
// Note: Qt4Project deletes all empty customexecrunconfigs for which isConfigured() == false.
@@ -336,7 +336,7 @@ RunConfiguration *
CustomExecutableRunConfigurationFactory::doCreate(Target *parent, Core::Id id)
{
Q_UNUSED(id);
- return new CustomExecutableRunConfiguration(parent);
+ return createHelper<CustomExecutableRunConfiguration>(parent);
}
bool CustomExecutableRunConfigurationFactory::canRestore(Target *parent,
@@ -352,7 +352,7 @@ RunConfiguration *
CustomExecutableRunConfigurationFactory::doRestore(Target *parent, const QVariantMap &map)
{
Q_UNUSED(map);
- return new CustomExecutableRunConfiguration(parent);
+ return createHelper<CustomExecutableRunConfiguration>(parent);
}
bool CustomExecutableRunConfigurationFactory::canClone(Target *parent,
@@ -366,7 +366,7 @@ CustomExecutableRunConfigurationFactory::clone(Target *parent, RunConfiguration
{
if (!canClone(parent, source))
return 0;
- return new CustomExecutableRunConfiguration(parent, static_cast<CustomExecutableRunConfiguration*>(source));
+ return cloneHelper<CustomExecutableRunConfiguration>(parent, source);
}
bool CustomExecutableRunConfigurationFactory::canHandle(Target *parent) const
diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.h b/src/plugins/projectexplorer/customexecutablerunconfiguration.h
index 972ec74ea43..65cdec20c44 100644
--- a/src/plugins/projectexplorer/customexecutablerunconfiguration.h
+++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.h
@@ -35,17 +35,15 @@ class CustomExecutableDialog;
namespace Internal { class CustomExecutableConfigurationWidget; }
-class CustomExecutableRunConfigurationFactory;
-
class PROJECTEXPLORER_EXPORT CustomExecutableRunConfiguration : public RunConfiguration
{
Q_OBJECT
// the configuration widget needs to setExecutable setWorkingDirectory and setCommandLineArguments
friend class Internal::CustomExecutableConfigurationWidget;
- friend class CustomExecutableRunConfigurationFactory;
+ friend class ProjectExplorer::IRunConfigurationFactory;
public:
- explicit CustomExecutableRunConfiguration(Target *parent);
+ explicit CustomExecutableRunConfiguration(Target *target);
~CustomExecutableRunConfiguration() override;
/**
@@ -68,8 +66,8 @@ signals:
void changed();
protected:
- CustomExecutableRunConfiguration(Target *parent,
- CustomExecutableRunConfiguration *source);
+ void initialize();
+ void copyFrom(const CustomExecutableRunConfiguration *source);
virtual bool fromMap(const QVariantMap &map) override;
QString defaultDisplayName() const;
diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp
index 06a3b041e89..dc0989eed19 100644
--- a/src/plugins/projectexplorer/customtoolchain.cpp
+++ b/src/plugins/projectexplorer/customtoolchain.cpp
@@ -32,6 +32,7 @@
#include "customparser.h"
#include "customparserconfigdialog.h"
#include "projectexplorerconstants.h"
+#include "projectmacro.h"
#include "toolchainmanager.h"
#include <utils/algorithm.h>
@@ -118,39 +119,24 @@ bool CustomToolChain::isValid() const
ToolChain::PredefinedMacrosRunner CustomToolChain::createPredefinedMacrosRunner() const
{
- const QStringList theMacros = m_predefinedMacros;
+ const Macros theMacros = m_predefinedMacros;
// This runner must be thread-safe!
return [theMacros](const QStringList &cxxflags){
QByteArray result;
- QStringList macros = theMacros;
+ Macros macros = theMacros;
for (const QString &cxxFlag : cxxflags) {
- if (cxxFlag.startsWith(QLatin1String("-D"))) {
- macros << cxxFlag.mid(2).trimmed();
- } else if (cxxFlag.startsWith(QLatin1String("-U"))) {
- const QString &removedName = cxxFlag.mid(2).trimmed();
- for (int i = macros.size() - 1; i >= 0; --i) {
- const QString &m = macros.at(i);
- if (m.left(m.indexOf(QLatin1Char('='))) == removedName)
- macros.removeAt(i);
- }
- }
- }
- for (const QString &str : Utils::asConst(macros)) {
- QByteArray ba = str.toUtf8();
- int equals = ba.indexOf('=');
- if (equals == -1) {
- result += "#define " + ba.trimmed() + '\n';
- } else {
- result += "#define " + ba.left(equals).trimmed() + ' '
- + ba.mid(equals + 1).trimmed() + '\n';
- }
+ if (cxxFlag.startsWith(QLatin1String("-D")))
+ macros.append(Macro::fromKeyValue(cxxFlag.mid(2).trimmed()));
+ else if (cxxFlag.startsWith(QLatin1String("-U")) && !cxxFlag.contains('='))
+ macros.append({cxxFlag.mid(2).trimmed().toUtf8(), MacroType::Undefine});
+
}
- return result;
+ return macros;
};
}
-QByteArray CustomToolChain::predefinedMacros(const QStringList &cxxflags) const
+Macros CustomToolChain::predefinedMacros(const QStringList &cxxflags) const
{
return createPredefinedMacrosRunner()(cxxflags);
}
@@ -169,16 +155,16 @@ WarningFlags CustomToolChain::warningFlags(const QStringList &cxxflags) const
return WarningFlags::Default;
}
-const QStringList &CustomToolChain::rawPredefinedMacros() const
+const Macros &CustomToolChain::rawPredefinedMacros() const
{
return m_predefinedMacros;
}
-void CustomToolChain::setPredefinedMacros(const QStringList &list)
+void CustomToolChain::setPredefinedMacros(const Macros &macros)
{
- if (m_predefinedMacros == list)
+ if (m_predefinedMacros == macros)
return;
- m_predefinedMacros = list;
+ m_predefinedMacros = macros;
toolChainUpdated();
}
@@ -323,7 +309,8 @@ QVariantMap CustomToolChain::toMap() const
data.insert(QLatin1String(compilerCommandKeyC), m_compilerCommand.toString());
data.insert(QLatin1String(makeCommandKeyC), m_makeCommand.toString());
data.insert(QLatin1String(targetAbiKeyC), m_targetAbi.toString());
- data.insert(QLatin1String(predefinedMacrosKeyC), m_predefinedMacros);
+ QStringList macros = Utils::transform<QList>(m_predefinedMacros, [](const Macro &m) { return QString::fromUtf8(m.toByteArray()); });
+ data.insert(QLatin1String(predefinedMacrosKeyC), macros);
data.insert(QLatin1String(headerPathsKeyC), headerPathsList());
data.insert(QLatin1String(cxx11FlagsKeyC), m_cxx11Flags);
data.insert(QLatin1String(mkspecsKeyC), mkspecs());
@@ -352,7 +339,8 @@ bool CustomToolChain::fromMap(const QVariantMap &data)
m_compilerCommand = FileName::fromString(data.value(QLatin1String(compilerCommandKeyC)).toString());
m_makeCommand = FileName::fromString(data.value(QLatin1String(makeCommandKeyC)).toString());
m_targetAbi = Abi(data.value(QLatin1String(targetAbiKeyC)).toString());
- m_predefinedMacros = data.value(QLatin1String(predefinedMacrosKeyC)).toStringList();
+ const QStringList macros = data.value(QLatin1String(predefinedMacrosKeyC)).toStringList();
+ m_predefinedMacros = Macro::toMacros(macros.join('\n').toUtf8());
setHeaderPaths(data.value(QLatin1String(headerPathsKeyC)).toStringList());
m_cxx11Flags = data.value(QLatin1String(cxx11FlagsKeyC)).toStringList();
setMkspecs(data.value(QLatin1String(mkspecsKeyC)).toString());
@@ -526,11 +514,16 @@ public:
return static_cast<QPlainTextEdit *>(widget());
}
- inline QStringList entries() const
+ QStringList entries() const
{
return textEditWidget()->toPlainText().split(QLatin1Char('\n'), QString::SkipEmptyParts);
}
+ QString text() const
+ {
+ return textEditWidget()->toPlainText();
+ }
+
// not accurate, counts empty lines (except last)
int entryCount() const
{
@@ -656,7 +649,7 @@ void CustomToolChainConfigWidget::applyImpl()
tc->setCompilerCommand(m_compilerCommand->fileName());
tc->setMakeCommand(m_makeCommand->fileName());
tc->setTargetAbi(m_abiWidget->currentAbi());
- tc->setPredefinedMacros(m_predefinedDetails->entries());
+ tc->setPredefinedMacros(Macro::toMacros(m_predefinedDetails->text().toUtf8()));
tc->setHeaderPaths(m_headerDetails->entries());
tc->setCxx11Flags(m_cxx11Flags->text().split(QLatin1Char(',')));
tc->setMkspecs(m_mkspecs->text());
@@ -673,8 +666,8 @@ void CustomToolChainConfigWidget::setFromToolchain()
m_compilerCommand->setFileName(tc->compilerCommand());
m_makeCommand->setFileName(FileName::fromString(tc->makeCommand(Environment())));
m_abiWidget->setAbis(QList<Abi>(), tc->targetAbi());
- m_predefinedMacros->setPlainText(tc->rawPredefinedMacros().join(QLatin1Char('\n')));
- m_headerPaths->setPlainText(tc->headerPathsList().join(QLatin1Char('\n')));
+ m_predefinedMacros->setPlainText(QString::fromUtf8(Macro::toByteArray(tc->rawPredefinedMacros())));
+ m_headerPaths->setPlainText(tc->headerPathsList().join('\n'));
m_cxx11Flags->setText(tc->cxx11Flags().join(QLatin1Char(',')));
m_mkspecs->setText(tc->mkspecs());
int index = m_errorParserComboBox->findData(tc->outputParserId().toSetting());
@@ -690,7 +683,7 @@ bool CustomToolChainConfigWidget::isDirtyImpl() const
return m_compilerCommand->fileName() != tc->compilerCommand()
|| m_makeCommand->path() != tc->makeCommand(Environment())
|| m_abiWidget->currentAbi() != tc->targetAbi()
- || m_predefinedDetails->entries() != tc->rawPredefinedMacros()
+ || Macro::toMacros(m_predefinedDetails->text().toUtf8()) != tc->rawPredefinedMacros()
|| m_headerDetails->entries() != tc->headerPathsList()
|| m_cxx11Flags->text().split(QLatin1Char(',')) != tc->cxx11Flags()
|| m_mkspecs->text() != tc->mkspecs()
diff --git a/src/plugins/projectexplorer/customtoolchain.h b/src/plugins/projectexplorer/customtoolchain.h
index fa5ec68ed01..75ba190c66f 100644
--- a/src/plugins/projectexplorer/customtoolchain.h
+++ b/src/plugins/projectexplorer/customtoolchain.h
@@ -72,11 +72,11 @@ public:
bool isValid() const override;
PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
- QByteArray predefinedMacros(const QStringList &cxxflags) const override;
+ Macros predefinedMacros(const QStringList &cxxflags) const override;
CompilerFlags compilerFlags(const QStringList &cxxflags) const override;
WarningFlags warningFlags(const QStringList &cxxflags) const override;
- const QStringList &rawPredefinedMacros() const;
- void setPredefinedMacros(const QStringList &list);
+ const Macros &rawPredefinedMacros() const;
+ void setPredefinedMacros(const Macros &macros);
SystemHeaderPathsRunner createSystemHeaderPathsRunner() const override;
QList<HeaderPath> systemHeaderPaths(const QStringList &cxxFlags,
@@ -124,7 +124,7 @@ private:
Utils::FileName m_makeCommand;
Abi m_targetAbi;
- QStringList m_predefinedMacros;
+ Macros m_predefinedMacros;
QList<HeaderPath> m_systemHeaderPaths;
QStringList m_cxx11Flags;
Utils::FileNameList m_mkspecs;
diff --git a/src/plugins/projectexplorer/deployconfiguration.cpp b/src/plugins/projectexplorer/deployconfiguration.cpp
index 119d9a057c2..6f44d135b12 100644
--- a/src/plugins/projectexplorer/deployconfiguration.cpp
+++ b/src/plugins/projectexplorer/deployconfiguration.cpp
@@ -41,8 +41,9 @@ const char BUILD_STEP_LIST_PREFIX[] = "ProjectExplorer.BuildConfiguration.BuildS
const char DEFAULT_DEPLOYCONFIGURATION_ID[] = "ProjectExplorer.DefaultDeployConfiguration";
DeployConfiguration::DeployConfiguration(Target *target, Core::Id id) :
- ProjectConfiguration(target, id)
+ ProjectConfiguration(target)
{
+ ProjectConfiguration::initialize(id);
Q_ASSERT(target);
m_stepList = new BuildStepList(this, Core::Id(Constants::BUILDSTEPS_DEPLOY));
//: Display name of the deploy build step list. Used as part of the labels in the project window.
@@ -53,8 +54,9 @@ DeployConfiguration::DeployConfiguration(Target *target, Core::Id id) :
}
DeployConfiguration::DeployConfiguration(Target *target, DeployConfiguration *source) :
- ProjectConfiguration(target, source)
+ ProjectConfiguration(target)
{
+ ProjectConfiguration::copyFrom(source);
Q_ASSERT(target);
// Do not clone stepLists here, do that in the derived constructor instead
// otherwise BuildStepFactories might reject to set up a BuildStep for us
@@ -141,6 +143,16 @@ Target *DeployConfiguration::target() const
return static_cast<Target *>(parent());
}
+Project *DeployConfiguration::project() const
+{
+ return target()->project();
+}
+
+bool DeployConfiguration::isActive() const
+{
+ return target()->isActive() && target()->activeDeployConfiguration() == this;
+}
+
void DeployConfiguration::cloneSteps(DeployConfiguration *source)
{
if (source == this)
diff --git a/src/plugins/projectexplorer/deployconfiguration.h b/src/plugins/projectexplorer/deployconfiguration.h
index aec33fd3086..db3b37c5c30 100644
--- a/src/plugins/projectexplorer/deployconfiguration.h
+++ b/src/plugins/projectexplorer/deployconfiguration.h
@@ -59,6 +59,9 @@ public:
virtual QString disabledReason() const;
Target *target() const;
+ Project *project() const override;
+
+ bool isActive() const override;
signals:
void enabledChanged();
diff --git a/src/plugins/projectexplorer/deployconfigurationmodel.cpp b/src/plugins/projectexplorer/deployconfigurationmodel.cpp
deleted file mode 100644
index b0e5dc70eb1..00000000000
--- a/src/plugins/projectexplorer/deployconfigurationmodel.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "deployconfigurationmodel.h"
-#include "target.h"
-#include "deployconfiguration.h"
-
-#include <utils/algorithm.h>
-
-using namespace ProjectExplorer;
-
-/*!
- \class ProjectExplorer::DeployConfigurationModel
-
- \brief The DeployConfigurationModel class provides a model to represent
- the run configurations of a target.
-
- To be used in drop down lists of comboboxes. Automatically adjusts
- itself to added and removed deploy configurations.
-*/
-
-class DeployConfigurationComparer
-{
-public:
- bool operator()(DeployConfiguration *a, DeployConfiguration *b)
- {
- return a->displayName() < b->displayName();
- }
-};
-
-DeployConfigurationModel::DeployConfigurationModel(Target *target, QObject *parent) :
- QAbstractListModel(parent),
- m_target(target)
-{
- m_deployConfigurations = m_target->deployConfigurations();
- Utils::sort(m_deployConfigurations, DeployConfigurationComparer());
-
- connect(target, &Target::addedDeployConfiguration,
- this, &DeployConfigurationModel::addedDeployConfiguration);
- connect(target, &Target::removedDeployConfiguration,
- this, &DeployConfigurationModel::removedDeployConfiguration);
-
- foreach (DeployConfiguration *dc, m_deployConfigurations) {
- connect(dc, &ProjectConfiguration::displayNameChanged,
- this, &DeployConfigurationModel::displayNameChanged);
- }
-}
-
-int DeployConfigurationModel::rowCount(const QModelIndex &parent) const
-{
- return parent.isValid() ? 0 : m_deployConfigurations.size();
-}
-
-int DeployConfigurationModel::columnCount(const QModelIndex &parent) const
-{
- return parent.isValid() ? 0 : 1;
-}
-
-void DeployConfigurationModel::displayNameChanged()
-{
- auto dc = qobject_cast<DeployConfiguration *>(sender());
- if (!dc)
- return;
-
- DeployConfigurationComparer compare;
- // Find the old position
- int oldPos = m_deployConfigurations.indexOf(dc);
-
- if (oldPos >= 1 && compare(m_deployConfigurations.at(oldPos), m_deployConfigurations.at(oldPos - 1))) {
- // We need to move up
- int newPos = oldPos - 1;
- while (newPos >= 0 && compare(m_deployConfigurations.at(oldPos), m_deployConfigurations.at(newPos))) {
- --newPos;
- }
- ++newPos;
-
- beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
- m_deployConfigurations.insert(newPos, dc);
- m_deployConfigurations.removeAt(oldPos + 1);
- endMoveRows();
- // Not only did we move, we also changed...
- emit dataChanged(index(newPos, 0), index(newPos,0));
- } else if (oldPos < m_deployConfigurations.size() - 1
- && compare(m_deployConfigurations.at(oldPos + 1), m_deployConfigurations.at(oldPos))) {
- // We need to move down
- int newPos = oldPos + 1;
- while (newPos < m_deployConfigurations.size()
- && compare(m_deployConfigurations.at(newPos), m_deployConfigurations.at(oldPos))) {
- ++newPos;
- }
- beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
- m_deployConfigurations.insert(newPos, dc);
- m_deployConfigurations.removeAt(oldPos);
- endMoveRows();
-
- // We need to subtract one since removing at the old place moves the newIndex down
- emit dataChanged(index(newPos - 1, 0), index(newPos - 1, 0));
- } else {
- emit dataChanged(index(oldPos, 0), index(oldPos, 0));
- }
-}
-
-QVariant DeployConfigurationModel::data(const QModelIndex &index, int role) const
-{
- if (role == Qt::DisplayRole) {
- const int row = index.row();
- if (row < m_deployConfigurations.size())
- return m_deployConfigurations.at(row)->displayName();
- }
-
- return QVariant();
-}
-
-DeployConfiguration *DeployConfigurationModel::deployConfigurationAt(int i)
-{
- if (i > m_deployConfigurations.size() || i < 0)
- return nullptr;
- return m_deployConfigurations.at(i);
-}
-
-DeployConfiguration *DeployConfigurationModel::deployConfigurationFor(const QModelIndex &idx)
-{
- if (idx.row() > m_deployConfigurations.size() || idx.row() < 0)
- return nullptr;
- return m_deployConfigurations.at(idx.row());
-}
-
-QModelIndex DeployConfigurationModel::indexFor(DeployConfiguration *rc)
-{
- int idx = m_deployConfigurations.indexOf(rc);
- if (idx == -1)
- return QModelIndex();
- return index(idx, 0);
-}
-
-void DeployConfigurationModel::addedDeployConfiguration(DeployConfiguration *dc)
-{
- // Find the right place to insert
- DeployConfigurationComparer compare;
- int i = 0;
- for (; i < m_deployConfigurations.size(); ++i) {
- if (compare(dc, m_deployConfigurations.at(i)))
- break;
- }
-
- beginInsertRows(QModelIndex(), i, i);
- m_deployConfigurations.insert(i, dc);
- endInsertRows();
-
- connect(dc, &ProjectConfiguration::displayNameChanged,
- this, &DeployConfigurationModel::displayNameChanged);
-}
-
-void DeployConfigurationModel::removedDeployConfiguration(DeployConfiguration *dc)
-{
- int i = m_deployConfigurations.indexOf(dc);
- if (i < 0)
- return;
- beginRemoveRows(QModelIndex(), i, i);
- m_deployConfigurations.removeAt(i);
- endRemoveRows();
-}
diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
index 2167f9ddbbe..f7c85ce0c7a 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
+++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
@@ -191,7 +191,7 @@ void PortsGatherer::start()
});
connect(&m_portsGatherer, &DeviceUsedPortsGatherer::portListReady, this, [this] {
m_portList = device()->freePorts();
- appendMessage(tr("Found %1 free ports").arg(m_portList.count()) + '\n', NormalMessageFormat);
+ appendMessage(tr("Found %n free ports.", nullptr, m_portList.count()) + '\n', NormalMessageFormat);
reportStarted();
});
m_portsGatherer.start(device());
diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp
index e784536d3a6..10c452b027d 100644
--- a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp
+++ b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp
@@ -45,8 +45,8 @@ public:
SshDeviceProcessPrivate(SshDeviceProcess *q) : q(q) {}
SshDeviceProcess * const q;
- bool serverSupportsSignals;
- QSsh::SshConnection *connection;
+ bool serverSupportsSignals = false;
+ QSsh::SshConnection *connection = nullptr;
QSsh::SshRemoteProcess::Ptr process;
StandardRunnable runnable;
QString errorMessage;
@@ -55,8 +55,8 @@ public:
QTimer killTimer;
QByteArray stdOut;
QByteArray stdErr;
- int exitCode;
- enum State { Inactive, Connecting, Connected, ProcessRunning } state;
+ int exitCode = -1;
+ enum State { Inactive, Connecting, Connected, ProcessRunning } state = Inactive;
void setState(State newState);
void doSignal(QSsh::SshRemoteProcess::Signal signal);
@@ -65,9 +65,6 @@ public:
SshDeviceProcess::SshDeviceProcess(const IDevice::ConstPtr &device, QObject *parent)
: DeviceProcess(device, parent), d(new SshDeviceProcessPrivate(this))
{
- d->connection = 0;
- d->state = SshDeviceProcessPrivate::Inactive;
- setSshServerSupportsSignals(false);
connect(&d->killTimer, &QTimer::timeout, this, &SshDeviceProcess::handleKillOperationTimeout);
}
diff --git a/src/plugins/projectexplorer/extracompiler.cpp b/src/plugins/projectexplorer/extracompiler.cpp
index 59fd6b96759..ab020004404 100644
--- a/src/plugins/projectexplorer/extracompiler.cpp
+++ b/src/plugins/projectexplorer/extracompiler.cpp
@@ -381,13 +381,13 @@ ProcessExtraCompiler::~ProcessExtraCompiler()
void ProcessExtraCompiler::run(const QByteArray &sourceContents)
{
- ContentProvider contents = [this, sourceContents]() { return sourceContents; };
+ ContentProvider contents = [sourceContents]() { return sourceContents; };
runImpl(contents);
}
void ProcessExtraCompiler::run(const Utils::FileName &fileName)
{
- ContentProvider contents = [this, fileName]() {
+ ContentProvider contents = [fileName]() {
QFile file(fileName.toString());
if (!file.open(QFile::ReadOnly | QFile::Text))
return QByteArray();
diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp
index 8742c885cf2..797c0c2b15b 100644
--- a/src/plugins/projectexplorer/foldernavigationwidget.cpp
+++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp
@@ -26,8 +26,6 @@
#include "foldernavigationwidget.h"
#include "projectexplorer.h"
-#include <extensionsystem/pluginmanager.h>
-
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
@@ -35,62 +33,33 @@
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/fileutils.h>
-#include <coreplugin/find/findplugin.h>
-
-#include <texteditor/findinfiles.h>
+#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
-#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
-#include <utils/elidinglabel.h>
-#include <utils/itemviews.h>
+#include <utils/navigationtreeview.h>
#include <utils/utilsicons.h>
-#include <QDebug>
+#include <QComboBox>
+#include <QHeaderView>
#include <QSize>
+#include <QTimer>
#include <QFileSystemModel>
#include <QVBoxLayout>
#include <QToolButton>
-#include <QSortFilterProxyModel>
#include <QAction>
#include <QMenu>
-#include <QFileDialog>
#include <QContextMenuEvent>
#include <QDir>
#include <QFileInfo>
-enum { debug = 0 };
-
namespace ProjectExplorer {
namespace Internal {
-// Hide the '.' entry.
-class DotRemovalFilter : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- explicit DotRemovalFilter(QObject *parent = nullptr);
-protected:
- virtual bool filterAcceptsRow(int source_row, const QModelIndex &parent) const;
- Qt::DropActions supportedDragActions() const;
-};
-
-DotRemovalFilter::DotRemovalFilter(QObject *parent) : QSortFilterProxyModel(parent)
-{ }
-
-bool DotRemovalFilter::filterAcceptsRow(int source_row, const QModelIndex &parent) const
-{
- const QVariant fileName = sourceModel()->data(parent.child(source_row, 0));
- if (Utils::HostOsInfo::isAnyUnixHost())
- if (sourceModel()->data(parent) == QLatin1String("/") && fileName == QLatin1String(".."))
- return false;
- return fileName != QLatin1String(".");
-}
+static FolderNavigationWidgetFactory *m_instance = nullptr;
-Qt::DropActions DotRemovalFilter::supportedDragActions() const
-{
- return sourceModel()->supportedDragActions();
-}
+QVector<FolderNavigationWidgetFactory::DirectoryEntry>
+ FolderNavigationWidgetFactory::m_rootDirectories;
// FolderNavigationModel: Shows path as tooltip.
class FolderNavigationModel : public QFileSystemModel
@@ -117,42 +86,46 @@ Qt::DropActions FolderNavigationModel::supportedDragActions() const
return Qt::MoveAction;
}
+static void showOnlyFirstColumn(QTreeView *view)
+{
+ const int columnCount = view->header()->count();
+ for (int i = 1; i < columnCount; ++i)
+ view->setColumnHidden(i, true);
+}
+
/*!
- \class FolderNavigationWidget
+ \class FolderNavigationWidget
+
+ Shows a file system tree, with the root directory selectable from a dropdown.
- Shows a file system folder
- */
+ \internal
+*/
FolderNavigationWidget::FolderNavigationWidget(QWidget *parent) : QWidget(parent),
- m_listView(new Utils::ListView(this)),
+ m_listView(new Utils::NavigationTreeView(this)),
m_fileSystemModel(new FolderNavigationModel(this)),
m_filterHiddenFilesAction(new QAction(tr("Show Hidden Files"), this)),
- m_filterModel(new DotRemovalFilter(this)),
- m_title(new Utils::ElidingLabel(this)),
- m_toggleSync(new QToolButton(this))
+ m_toggleSync(new QToolButton(this)),
+ m_rootSelector(new QComboBox)
{
m_fileSystemModel->setResolveSymlinks(false);
m_fileSystemModel->setIconProvider(Core::FileIconProvider::iconProvider());
- QDir::Filters filters = QDir::AllDirs | QDir::Files | QDir::Drives
- | QDir::Readable| QDir::Writable
- | QDir::Executable | QDir::Hidden;
+ QDir::Filters filters = QDir::AllEntries | QDir::NoDotAndDotDot;
if (Utils::HostOsInfo::isWindowsHost()) // Symlinked directories can cause file watcher warnings on Win32.
filters |= QDir::NoSymLinks;
m_fileSystemModel->setFilter(filters);
- m_filterModel->setSourceModel(m_fileSystemModel);
+ m_fileSystemModel->setRootPath(QString());
m_filterHiddenFilesAction->setCheckable(true);
setHiddenFilesFilter(false);
m_listView->setIconSize(QSize(16,16));
- m_listView->setModel(m_filterModel);
- m_listView->setFrameStyle(QFrame::NoFrame);
- m_listView->setAttribute(Qt::WA_MacShowFocusRect, false);
+ m_listView->setModel(m_fileSystemModel);
m_listView->setDragEnabled(true);
m_listView->setDragDropMode(QAbstractItemView::DragOnly);
+ showOnlyFirstColumn(m_listView);
setFocusProxy(m_listView);
auto layout = new QVBoxLayout();
- layout->addWidget(m_title);
+ layout->addWidget(m_rootSelector);
layout->addWidget(m_listView);
- m_title->setMargin(5);
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
setLayout(layout);
@@ -164,13 +137,26 @@ FolderNavigationWidget::FolderNavigationWidget(QWidget *parent) : QWidget(parent
// connections
connect(m_listView, &QAbstractItemView::activated,
- this, &FolderNavigationWidget::slotOpenItem);
+ this, [this](const QModelIndex &index) { openItem(index); });
connect(m_filterHiddenFilesAction, &QAction::toggled,
this, &FolderNavigationWidget::setHiddenFilesFilter);
connect(m_toggleSync, &QAbstractButton::clicked,
this, &FolderNavigationWidget::toggleAutoSynchronization);
- connect(m_filterModel, &QAbstractItemModel::layoutChanged,
- this, &FolderNavigationWidget::ensureCurrentIndex);
+ connect(m_rootSelector,
+ static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ this,
+ [this](int index) {
+ const auto directory = m_rootSelector->itemData(index).value<Utils::FileName>();
+ m_rootSelector->setToolTip(directory.toString());
+ setRootDirectory(directory);
+ });
+ connect(m_rootSelector,
+ static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
+ this,
+ [this] {
+ if (m_autoSync && Core::EditorManager::currentEditor())
+ selectFile(Core::EditorManager::currentEditor()->document()->filePath());
+ });
}
void FolderNavigationWidget::toggleAutoSynchronization()
@@ -178,6 +164,29 @@ void FolderNavigationWidget::toggleAutoSynchronization()
setAutoSynchronization(!m_autoSync);
}
+void FolderNavigationWidget::addRootDirectory(const QString &displayName,
+ const Utils::FileName &directory)
+{
+ m_rootSelector->addItem(displayName, qVariantFromValue(directory));
+ m_rootSelector->setItemData(m_rootSelector->count() - 1,
+ directory.toUserOutput(),
+ Qt::ToolTipRole);
+ if (m_autoSync) // we might find a better root for current selection now
+ setCurrentEditor(Core::EditorManager::currentEditor());
+}
+
+void FolderNavigationWidget::removeRootDirectory(const Utils::FileName &directory)
+{
+ for (int i = 0; i < m_rootSelector->count(); ++i) {
+ if (m_rootSelector->itemData(i).value<Utils::FileName>() == directory) {
+ m_rootSelector->removeItem(i);
+ break;
+ }
+ }
+ if (m_autoSync) // we might need to find a new root for current selection
+ setCurrentEditor(Core::EditorManager::currentEditor());
+}
+
bool FolderNavigationWidget::autoSynchronization() const
{
return m_autoSync;
@@ -193,148 +202,95 @@ void FolderNavigationWidget::setAutoSynchronization(bool sync)
if (m_autoSync) {
connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
- this, &FolderNavigationWidget::setCurrentFile);
- setCurrentFile(Core::EditorManager::currentEditor());
+ this, &FolderNavigationWidget::setCurrentEditor);
+ setCurrentEditor(Core::EditorManager::currentEditor());
} else {
disconnect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
- this, &FolderNavigationWidget::setCurrentFile);
+ this, &FolderNavigationWidget::setCurrentEditor);
}
}
-void FolderNavigationWidget::setCurrentFile(Core::IEditor *editor)
+void FolderNavigationWidget::setCurrentEditor(Core::IEditor *editor)
{
if (!editor)
return;
-
- const QString filePath = editor->document()->filePath().toString();
- // Try to find directory of current file
- bool pathOpened = false;
- if (!filePath.isEmpty()) {
- const QFileInfo fi(filePath);
- if (fi.exists())
- pathOpened = setCurrentDirectory(fi.absolutePath());
- }
- if (!pathOpened) // Default to home.
- setCurrentDirectory(Utils::PathChooser::homePath());
-
- // Select the current file.
- if (pathOpened) {
- const QModelIndex fileIndex = m_fileSystemModel->index(filePath);
- if (fileIndex.isValid()) {
- QItemSelectionModel *selections = m_listView->selectionModel();
- const QModelIndex mainIndex = m_filterModel->mapFromSource(fileIndex);
- selections->setCurrentIndex(mainIndex, QItemSelectionModel::SelectCurrent
- | QItemSelectionModel::Clear);
- m_listView->scrollTo(mainIndex);
- }
- }
+ const Utils::FileName filePath = editor->document()->filePath();
+ // switch to most fitting root
+ const int bestRootIndex = bestRootForFile(filePath);
+ m_rootSelector->setCurrentIndex(bestRootIndex);
+ // select
+ selectFile(filePath);
}
-bool FolderNavigationWidget::setCurrentDirectory(const QString &directory)
+void FolderNavigationWidget::selectFile(const Utils::FileName &filePath)
{
- const QString newDirectory = directory.isEmpty() ? QDir::rootPath() : directory;
- if (debug)
- qDebug() << "setcurdir" << directory << newDirectory;
- // Set the root path on the model instead of changing the top index
- // of the view to cause the model to clean out its file watchers.
- const QModelIndex index = m_fileSystemModel->setRootPath(newDirectory);
- if (!index.isValid()) {
- setCurrentTitle(QString(), QString());
- return false;
+ const QModelIndex fileIndex = m_fileSystemModel->index(filePath.toString());
+ if (fileIndex.isValid()) {
+ // TODO This only scrolls to the right position if all directory contents are loaded.
+ // Unfortunately listening to directoryLoaded was still not enough (there might also
+ // be some delayed sorting involved?).
+ // Use magic timer for scrolling.
+ m_listView->setCurrentIndex(fileIndex);
+ QTimer::singleShot(200, this, [this, filePath] {
+ const QModelIndex fileIndex = m_fileSystemModel->index(filePath.toString());
+ m_listView->scrollTo(fileIndex);
+ });
}
- QModelIndex oldRootIndex = m_listView->rootIndex();
- QModelIndex newRootIndex = m_filterModel->mapFromSource(index);
- m_listView->setRootIndex(newRootIndex);
- const QDir current(QDir::cleanPath(newDirectory));
- setCurrentTitle(current.dirName(),
- QDir::toNativeSeparators(current.absolutePath()));
- if (oldRootIndex.parent() == newRootIndex) { // cdUp, so select the old directory
- m_listView->setCurrentIndex(oldRootIndex);
- m_listView->scrollTo(oldRootIndex, QAbstractItemView::EnsureVisible);
- }
-
- return !directory.isEmpty();
}
-QString FolderNavigationWidget::currentDirectory() const
+void FolderNavigationWidget::setRootDirectory(const Utils::FileName &directory)
{
- return m_fileSystemModel->rootPath();
+ const QModelIndex index = m_fileSystemModel->setRootPath(directory.toString());
+ m_listView->setRootIndex(index);
}
-void FolderNavigationWidget::slotOpenItem(const QModelIndex &viewIndex)
+int FolderNavigationWidget::bestRootForFile(const Utils::FileName &filePath)
{
- if (viewIndex.isValid())
- openItem(m_filterModel->mapToSource(viewIndex));
+ int index = 0; // Computer is default
+ int commonLength = 0;
+ for (int i = 1; i < m_rootSelector->count(); ++i) {
+ const auto root = m_rootSelector->itemData(i).value<Utils::FileName>();
+ if (filePath.isChildOf(root) && root.length() > commonLength) {
+ index = i;
+ commonLength = root.length();
+ }
+ }
+ return index;
}
-void FolderNavigationWidget::openItem(const QModelIndex &srcIndex, bool openDirectoryAsProject)
+void FolderNavigationWidget::openItem(const QModelIndex &index)
{
- const QString fileName = m_fileSystemModel->fileName(srcIndex);
- if (fileName == QLatin1String("."))
- return;
- if (fileName == QLatin1String("..")) {
- // cd up: Special behaviour: The fileInfo of ".." is that of the parent directory.
- const QString parentPath = m_fileSystemModel->fileInfo(srcIndex).absoluteFilePath();
- setCurrentDirectory(parentPath);
+ if (!index.isValid())
return;
- }
- const QString path = m_fileSystemModel->filePath(srcIndex);
- if (m_fileSystemModel->isDir(srcIndex)) {
- const QFileInfo fi = m_fileSystemModel->fileInfo(srcIndex);
+ const QString path = m_fileSystemModel->filePath(index);
+ if (m_fileSystemModel->isDir(index)) {
+ const QFileInfo fi = m_fileSystemModel->fileInfo(index);
if (!fi.isReadable() || !fi.isExecutable())
return;
// Try to find project files in directory and open those.
- if (openDirectoryAsProject) {
- const QStringList projectFiles = FolderNavigationWidget::projectFilesInDirectory(path);
- if (!projectFiles.isEmpty())
- Core::ICore::instance()->openFiles(projectFiles);
- return;
- }
- // Change to directory
- setCurrentDirectory(path);
- return;
+ const QStringList projectFiles = FolderNavigationWidget::projectFilesInDirectory(path);
+ if (!projectFiles.isEmpty())
+ Core::ICore::instance()->openFiles(projectFiles);
+ } else {
+ // Open editor
+ Core::EditorManager::openEditor(path);
}
- // Open file.
- Core::ICore::instance()->openFiles(QStringList(path));
-}
-
-void FolderNavigationWidget::setCurrentTitle(QString dirName, const QString &fullPath)
-{
- if (dirName.isEmpty())
- dirName = fullPath;
- m_title->setText(dirName);
- m_title->setToolTip(fullPath);
-}
-
-QModelIndex FolderNavigationWidget::currentItem() const
-{
- const QModelIndex current = m_listView->currentIndex();
- if (current.isValid())
- return m_filterModel->mapToSource(current);
- return QModelIndex();
-}
-
-// Format the text for the "open" action of the context menu according
-// to the selectect entry
-static inline QString actionOpenText(const QFileSystemModel *model,
- const QModelIndex &index)
-{
- if (!index.isValid())
- return FolderNavigationWidget::tr("Open");
- const QString fileName = model->fileName(index);
- if (fileName == QLatin1String(".."))
- return FolderNavigationWidget::tr("Open Parent Folder");
- return FolderNavigationWidget::tr("Open \"%1\"").arg(fileName);
}
void FolderNavigationWidget::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu menu;
// Open current item
- const QModelIndex current = currentItem();
+ const QModelIndex current = m_listView->currentIndex();
const bool hasCurrentItem = current.isValid();
- QAction *actionOpen = menu.addAction(actionOpenText(m_fileSystemModel, current));
- actionOpen->setEnabled(hasCurrentItem);
+ QAction *actionOpen = nullptr;
+ if (hasCurrentItem) {
+ const QString fileName = m_fileSystemModel->fileName(current);
+ if (m_fileSystemModel->isDir(current))
+ actionOpen = menu.addAction(tr("Open Project in \"%1\"").arg(fileName));
+ else
+ actionOpen = menu.addAction(tr("Open \"%1\"").arg(fileName));
+ }
// we need dummy DocumentModel::Entry with absolute file path in it
// to get EditorManager::addNativeDirAndOpenWithActions() working
@@ -344,17 +300,6 @@ void FolderNavigationWidget::contextMenuEvent(QContextMenuEvent *ev)
fakeEntry.document = &document;
Core::EditorManager::addNativeDirAndOpenWithActions(&menu, &fakeEntry);
- const bool isDirectory = hasCurrentItem && m_fileSystemModel->isDir(current);
- QAction *actionOpenDirectoryAsProject = 0;
- if (isDirectory && m_fileSystemModel->fileName(current) != QLatin1String("..")) {
- actionOpenDirectoryAsProject =
- menu.addAction(tr("Open Project in \"%1\"")
- .arg(m_fileSystemModel->fileName(current)));
- }
-
- // Open file dialog to choose a path starting from current
- QAction *actionChooseFolder = menu.addAction(tr("Choose Folder..."));
-
QAction *action = menu.exec(ev->globalPos());
if (!action)
return;
@@ -362,12 +307,6 @@ void FolderNavigationWidget::contextMenuEvent(QContextMenuEvent *ev)
ev->accept();
if (action == actionOpen) { // Handle open file.
openItem(current);
- } else if (action == actionOpenDirectoryAsProject) {
- openItem(current, true);
- } else if (action == actionChooseFolder) { // Open file dialog
- const QString newPath = QFileDialog::getExistingDirectory(this, tr("Choose Folder"), currentDirectory());
- if (!newPath.isEmpty())
- setCurrentDirectory(newPath);
}
}
@@ -387,17 +326,6 @@ bool FolderNavigationWidget::hiddenFilesFilter() const
return m_filterHiddenFilesAction->isChecked();
}
-void FolderNavigationWidget::ensureCurrentIndex()
-{
- QModelIndex index = m_listView->currentIndex();
- if (!index.isValid()
- || index.parent() != m_listView->rootIndex()) {
- index = m_listView->rootIndex().child(0, 0);
- m_listView->setCurrentIndex(index);
- }
- m_listView->scrollTo(index);
-}
-
QStringList FolderNavigationWidget::projectFilesInDirectory(const QString &path)
{
QDir dir(path);
@@ -410,16 +338,29 @@ QStringList FolderNavigationWidget::projectFilesInDirectory(const QString &path)
// --------------------FolderNavigationWidgetFactory
FolderNavigationWidgetFactory::FolderNavigationWidgetFactory()
{
+ m_instance = this;
setDisplayName(tr("File System"));
setPriority(400);
setId("File System");
setActivationSequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Y") : tr("Alt+Y")));
+ addRootDirectory(FolderNavigationWidget::tr("Computer"), Utils::FileName());
}
Core::NavigationView FolderNavigationWidgetFactory::createWidget()
{
- Core::NavigationView n;
auto fnw = new FolderNavigationWidget;
+ for (const DirectoryEntry &root : m_rootDirectories)
+ fnw->addRootDirectory(root.first, root.second);
+ connect(this,
+ &FolderNavigationWidgetFactory::rootDirectoryAdded,
+ fnw,
+ &FolderNavigationWidget::addRootDirectory);
+ connect(this,
+ &FolderNavigationWidgetFactory::rootDirectoryRemoved,
+ fnw,
+ &FolderNavigationWidget::removeRootDirectory);
+
+ Core::NavigationView n;
n.widget = fnw;
auto filter = new QToolButton;
filter->setIcon(Utils::Icons::FILTER.icon());
@@ -450,7 +391,23 @@ void FolderNavigationWidgetFactory::restoreSettings(QSettings *settings, int pos
fnw->setHiddenFilesFilter(settings->value(baseKey + QLatin1String(".HiddenFilesFilter"), false).toBool());
fnw->setAutoSynchronization(settings->value(baseKey + QLatin1String(".SyncWithEditor"), true).toBool());
}
+
+void FolderNavigationWidgetFactory::addRootDirectory(const QString &displayName,
+ const Utils::FileName &directory)
+{
+ m_rootDirectories.append(DirectoryEntry(displayName, directory));
+ emit m_instance->rootDirectoryAdded(displayName, directory);
+}
+
+void FolderNavigationWidgetFactory::removeRootDirectory(const Utils::FileName &directory)
+{
+ const int index = Utils::indexOf(m_rootDirectories, [directory](const DirectoryEntry &entry) {
+ return entry.second == directory;
+ });
+ QTC_ASSERT(index >= 0, return);
+ m_rootDirectories.removeAt(index);
+ emit m_instance->rootDirectoryRemoved(directory);
+}
+
} // namespace Internal
} // namespace ProjectExplorer
-
-#include "foldernavigationwidget.moc"
diff --git a/src/plugins/projectexplorer/foldernavigationwidget.h b/src/plugins/projectexplorer/foldernavigationwidget.h
index 3b4b37fa2fb..22f88f43485 100644
--- a/src/plugins/projectexplorer/foldernavigationwidget.h
+++ b/src/plugins/projectexplorer/foldernavigationwidget.h
@@ -29,15 +29,18 @@
#include <QWidget>
-namespace Utils { class ListView; }
namespace Core { class IEditor; }
+namespace Utils {
+class FileName;
+class NavigationTreeView;
+}
+
QT_BEGIN_NAMESPACE
-class QLabel;
-class QSortFilterProxyModel;
-class QModelIndex;
-class QFileSystemModel;
class QAction;
+class QComboBox;
+class QFileSystemModel;
+class QModelIndex;
QT_END_NAMESPACE
namespace ProjectExplorer {
@@ -58,29 +61,26 @@ public:
void setAutoSynchronization(bool sync);
void toggleAutoSynchronization();
-private:
- void setCurrentFile(Core::IEditor *editor);
- void slotOpenItem(const QModelIndex &viewIndex);
- void setHiddenFilesFilter(bool filter);
- void ensureCurrentIndex();
+ void addRootDirectory(const QString &displayName, const Utils::FileName &directory);
+ void removeRootDirectory(const Utils::FileName &directory);
protected:
void contextMenuEvent(QContextMenuEvent *ev) override;
private:
- void setCurrentTitle(QString dirName, const QString &fullPath);
- bool setCurrentDirectory(const QString &directory);
- void openItem(const QModelIndex &srcIndex, bool openDirectoryAsProject = false);
- QModelIndex currentItem() const;
- QString currentDirectory() const;
-
- Utils::ListView *m_listView;
- QFileSystemModel *m_fileSystemModel;
- QAction *m_filterHiddenFilesAction;
- QSortFilterProxyModel *m_filterModel;
- QLabel *m_title;
+ void setHiddenFilesFilter(bool filter);
+ void setCurrentEditor(Core::IEditor *editor);
+ void selectFile(const Utils::FileName &filePath);
+ void setRootDirectory(const Utils::FileName &directory);
+ int bestRootForFile(const Utils::FileName &filePath);
+ void openItem(const QModelIndex &index);
+
+ Utils::NavigationTreeView *m_listView = nullptr;
+ QFileSystemModel *m_fileSystemModel = nullptr;
+ QAction *m_filterHiddenFilesAction = nullptr;
bool m_autoSync = false;
- QToolButton *m_toggleSync;
+ QToolButton *m_toggleSync = nullptr;
+ QComboBox *m_rootSelector = nullptr;
// FolderNavigationWidgetFactory needs private members to build a menu
friend class FolderNavigationWidgetFactory;
@@ -96,6 +96,17 @@ public:
Core::NavigationView createWidget() override;
void saveSettings(QSettings *settings, int position, QWidget *widget) override;
void restoreSettings(QSettings *settings, int position, QWidget *widget) override;
+
+ static void addRootDirectory(const QString &displayName, const Utils::FileName &directory);
+ static void removeRootDirectory(const Utils::FileName &directory);
+
+signals:
+ void rootDirectoryAdded(const QString &displayName, const Utils::FileName &directory);
+ void rootDirectoryRemoved(const Utils::FileName &directory);
+
+private:
+ using DirectoryEntry = std::pair<QString, Utils::FileName>;
+ static QVector<DirectoryEntry> m_rootDirectories;
};
} // namespace Internal
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp
index 56a744b01f5..9800908a53d 100644
--- a/src/plugins/projectexplorer/gcctoolchain.cpp
+++ b/src/plugins/projectexplorer/gcctoolchain.cpp
@@ -28,6 +28,7 @@
#include "gcctoolchainfactories.h"
#include "gccparser.h"
#include "linuxiccparser.h"
+#include "projectmacro.h"
#include "projectexplorerconstants.h"
#include "toolchainmanager.h"
@@ -42,11 +43,13 @@
#include <QBuffer>
#include <QCoreApplication>
+#include <QDir>
#include <QFileInfo>
-
-#include <QLineEdit>
#include <QFormLayout>
+#include <QLineEdit>
+#include <QRegularExpression>
+#include <algorithm>
#include <memory>
using namespace Utils;
@@ -65,6 +68,7 @@ static const char compilerPlatformLinkerFlagsKeyC[] = "ProjectExplorer.GccToolCh
static const char targetAbiKeyC[] = "ProjectExplorer.GccToolChain.TargetAbi";
static const char originalTargetTripleKeyC[] = "ProjectExplorer.GccToolChain.OriginalTargetTriple";
static const char supportedAbisKeyC[] = "ProjectExplorer.GccToolChain.SupportedAbis";
+static const char binaryRegexp[] = "(?:^|-|\\b)(?:gcc|g\\+\\+)(?:-([\\d.]+))?$";
static const int CACHE_SIZE = 16;
@@ -117,6 +121,11 @@ HeaderPathsCache::Cache HeaderPathsCache::cache() const
return m_cache;
}
+MacroCache::MacroCache() : m_mutex(QMutex::Recursive)
+{
+ m_cache.reserve(CACHE_SIZE + 1);
+}
+
MacroCache::MacroCache(const MacroCache &other)
: MacroCache()
{
@@ -124,40 +133,21 @@ MacroCache::MacroCache(const MacroCache &other)
m_cache = other.cache();
}
-void MacroCache::insert(const QStringList &compilerCommand, const QByteArray &macros)
+void MacroCache::insert(const QStringList &compilerCommand, const Macros &macros)
{
- if (macros.isNull())
+ QMutexLocker locker(&m_mutex);
+ if (macros.isEmpty() || unlockedCheck(compilerCommand).isEmpty())
return;
- CacheItem runResults;
- QByteArray data = macros;
- runResults.first = compilerCommand;
- if (macros.isNull())
- data = QByteArray("");
- runResults.second = data;
-
- QMutexLocker locker(&m_mutex);
- if (check(compilerCommand).isNull()) {
- m_cache.push_back(runResults);
- if (m_cache.size() > CACHE_SIZE)
- m_cache.pop_front();
- }
+ m_cache.push_back(qMakePair(compilerCommand, macros));
+ if (m_cache.size() > CACHE_SIZE)
+ m_cache.pop_front();
}
-QByteArray MacroCache::check(const QStringList &compilerCommand) const
+Macros MacroCache::check(const QStringList &compilerCommand) const
{
QMutexLocker locker(&m_mutex);
- for (Cache::iterator it = m_cache.begin(); it != m_cache.end(); ++it) {
- if (it->first == compilerCommand) {
- // Increase cached item priority
- CacheItem pair = *it;
- m_cache.erase(it);
- m_cache.push_back(pair);
-
- return pair.second;
- }
- }
- return QByteArray();
+ return unlockedCheck(compilerCommand);
}
MacroCache::Cache MacroCache::cache() const
@@ -166,6 +156,16 @@ MacroCache::Cache MacroCache::cache() const
return m_cache;
}
+Macros MacroCache::unlockedCheck(const QStringList &compilerCommand) const
+{
+ auto it = std::stable_partition(m_cache.begin(), m_cache.end(), [&](const CacheItem &ci) {
+ return ci.first == compilerCommand;
+ });
+ if (it != m_cache.end())
+ return it->second;
+ return {};
+}
+
static QByteArray runGcc(const FileName &gcc, const QStringList &arguments, const QStringList &env)
{
if (gcc.isEmpty() || !gcc.toFileInfo().isExecutable())
@@ -187,30 +187,35 @@ static QByteArray runGcc(const FileName &gcc, const QStringList &arguments, cons
return response.allOutput().toUtf8();
}
-static const QStringList gccPredefinedMacrosOptions()
+static const QStringList gccPredefinedMacrosOptions(Core::Id languageId)
{
- return QStringList({"-xc++", "-E", "-dM"});
+ const QString langOption = languageId == Constants::CXX_LANGUAGE_ID
+ ? QLatin1String("-xc++") : QLatin1String("-xc");
+ return QStringList({langOption, "-E", "-dM"});
}
-static QByteArray gccPredefinedMacros(const FileName &gcc, const QStringList &args, const QStringList &env)
+static ProjectExplorer::Macros gccPredefinedMacros(const FileName &gcc,
+ const QStringList &args,
+ const QStringList &env)
{
QStringList arguments = args;
arguments << "-";
- QByteArray predefinedMacros = runGcc(gcc, arguments, env);
+ ProjectExplorer::Macros predefinedMacros = Macro::toMacros(runGcc(gcc, arguments, env));
// Sanity check in case we get an error message instead of real output:
- QTC_CHECK(predefinedMacros.isNull() || predefinedMacros.startsWith("#define "));
+ QTC_CHECK(predefinedMacros.isEmpty()
+ || predefinedMacros.front().type == ProjectExplorer::MacroType::Define);
if (HostOsInfo::isMacHost()) {
// Turn off flag indicating Apple's blocks support
- const QByteArray blocksDefine("#define __BLOCKS__ 1");
- const QByteArray blocksUndefine("#undef __BLOCKS__");
+ const ProjectExplorer::Macro blocksDefine("__BLOCKS__", "1");
+ const ProjectExplorer::Macro blocksUndefine("__BLOCKS__", ProjectExplorer::MacroType::Undefine);
const int idx = predefinedMacros.indexOf(blocksDefine);
if (idx != -1)
- predefinedMacros.replace(idx, blocksDefine.length(), blocksUndefine);
+ predefinedMacros[idx] = blocksUndefine;
// Define __strong and __weak (used for Apple's GC extension of C) to be empty
- predefinedMacros.append("#define __strong\n");
- predefinedMacros.append("#define __weak\n");
+ predefinedMacros.append({"__strong"});
+ predefinedMacros.append({"__weak"});
}
return predefinedMacros;
}
@@ -257,7 +262,7 @@ QList<HeaderPath> GccToolChain::gccHeaderPaths(const FileName &gcc, const QStrin
return systemHeaderPaths;
}
-static QList<Abi> guessGccAbi(const QString &m, const QByteArray &macros)
+static QList<Abi> guessGccAbi(const QString &m, const ProjectExplorer::Macros &macros)
{
QList<Abi> abiList;
@@ -270,17 +275,13 @@ static QList<Abi> guessGccAbi(const QString &m, const QByteArray &macros)
Abi::OSFlavor flavor = guessed.osFlavor();
Abi::BinaryFormat format = guessed.binaryFormat();
int width = guessed.wordWidth();
- const QByteArray mscVer = "#define _MSC_VER ";
-
- if (macros.contains("#define __SIZEOF_SIZE_T__ 8"))
- width = 64;
- else if (macros.contains("#define __SIZEOF_SIZE_T__ 4"))
- width = 32;
- int mscVerIndex = macros.indexOf(mscVer);
- if (mscVerIndex != -1) {
- mscVerIndex += mscVer.length();
- const int eol = macros.indexOf('\n', mscVerIndex);
- const int msvcVersion = macros.mid(mscVerIndex, eol - mscVerIndex).toInt();
+
+ const Macro sizeOfMacro = Utils::findOrDefault(macros, [](const Macro &m) { return m.key == "__SIZEOF_SIZE_T__"; });
+ if (sizeOfMacro.isValid() && sizeOfMacro.type == MacroType::Define)
+ width = sizeOfMacro.value.toInt() * 8;
+ const Macro &mscVerMacro = Utils::findOrDefault(macros, [](const Macro &m) { return m.key == "_MSC_VER"; });
+ if (mscVerMacro.type == MacroType::Define) {
+ const int msvcVersion = mscVerMacro.value.toInt();
flavor = Abi::flavorForMsvcVersion(msvcVersion);
}
@@ -299,7 +300,7 @@ static QList<Abi> guessGccAbi(const QString &m, const QByteArray &macros)
static GccToolChain::DetectedAbisResult guessGccAbi(const FileName &path, const QStringList &env,
- const QByteArray &macros,
+ const ProjectExplorer::Macros &macros,
const QStringList &extraArgs = QStringList())
{
if (path.isEmpty())
@@ -360,10 +361,15 @@ void GccToolChain::setOriginalTargetTriple(const QString &targetTriple)
QString GccToolChain::defaultDisplayName() const
{
- if (!m_targetAbi.isValid())
- return typeDisplayName();
+ QString type = typeDisplayName();
+ const QRegularExpression regexp(binaryRegexp);
+ const QRegularExpressionMatch match = regexp.match(m_compilerCommand.fileName());
+ if (match.lastCapturedIndex() >= 1)
+ type += ' ' + match.captured(1);
+ if (m_targetAbi.architecture() == Abi::UnknownArchitecture || m_targetAbi.wordWidth() == 0)
+ return type;
return QCoreApplication::translate("ProjectExplorer::GccToolChain",
- "%1 (%2, %3 %4 in %5)").arg(typeDisplayName(),
+ "%1 (%2, %3 %4 in %5)").arg(type,
ToolChainManager::displayNameOfLanguageId(language()),
Abi::toString(m_targetAbi.architecture()),
Abi::toString(m_targetAbi.wordWidth()),
@@ -445,12 +451,13 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter;
QTC_CHECK(reinterpretOptions);
MacroCache *macroCache = &m_predefinedMacrosCache;
+ Core::Id lang = language();
// This runner must be thread-safe!
- return [env, compilerCommand, platformCodeGenFlags, reinterpretOptions, macroCache]
+ return [env, compilerCommand, platformCodeGenFlags, reinterpretOptions, macroCache, lang]
(const QStringList &cxxflags) {
QStringList allCxxflags = platformCodeGenFlags + cxxflags; // add only cxxflags is empty?
- QStringList arguments = gccPredefinedMacrosOptions();
+ QStringList arguments = gccPredefinedMacrosOptions(lang);
for (int iArg = 0; iArg < allCxxflags.length(); ++iArg) {
const QString &a = allCxxflags.at(iArg);
if (a.startsWith("--gcc-toolchain=")) {
@@ -483,8 +490,8 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
}
arguments = reinterpretOptions(arguments);
- QByteArray macros = macroCache->check(arguments);
- if (!macros.isNull())
+ Macros macros = macroCache->check(arguments);
+ if (!macros.isEmpty())
return macros;
macros = gccPredefinedMacros(findLocalCompiler(compilerCommand, env),
@@ -505,7 +512,7 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
* adds _OPENMP macro, for full list of macro search by word "when" on this page:
* http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
*/
-QByteArray GccToolChain::predefinedMacros(const QStringList &cxxflags) const
+ProjectExplorer::Macros GccToolChain::predefinedMacros(const QStringList &cxxflags) const
{
return createPredefinedMacrosRunner()(cxxflags);
}
@@ -689,6 +696,8 @@ void GccToolChain::addCommandPathToEnvironment(const FileName &command, Environm
env.prependOrSetPath(command.parentDir().toString());
}
+GccToolChain::GccToolChain(const GccToolChain &) = default;
+
void GccToolChain::addToEnvironment(Environment &env) const
{
addCommandPathToEnvironment(m_compilerCommand, env);
@@ -886,7 +895,7 @@ GccToolChain::DetectedAbisResult GccToolChain::detectSupportedAbis() const
{
Environment env = Environment::systemEnvironment();
addToEnvironment(env);
- QByteArray macros = predefinedMacros(QStringList());
+ ProjectExplorer::Macros macros = predefinedMacros(QStringList());
return guessGccAbi(findLocalCompiler(m_compilerCommand, env),
env.toStringList(),
macros,
@@ -929,10 +938,37 @@ ToolChain *GccToolChainFactory::create(Core::Id language)
QList<ToolChain *> GccToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
{
QList<ToolChain *> tcs;
+ QList<ToolChain *> known = alreadyKnown;
tcs.append(autoDetectToolchains("g++", Abi::hostAbi(), Constants::CXX_LANGUAGE_ID,
Constants::GCC_TOOLCHAIN_TYPEID, alreadyKnown));
tcs.append(autoDetectToolchains("gcc", Abi::hostAbi(), Constants::C_LANGUAGE_ID,
Constants::GCC_TOOLCHAIN_TYPEID, alreadyKnown));
+ known.append(tcs);
+ if (HostOsInfo::isLinuxHost()) {
+ const QRegularExpression regexp(binaryRegexp);
+ for (const QString &dir : QStringList({ "/usr/bin", "/usr/local/bin" })) {
+ QDir binDir(dir);
+ auto gccProbe = [&](const QString &name, Core::Id language) {
+ for (const QString &entry : binDir.entryList(
+ {"*-" + name, name + "-*", "*-" + name + "-*"},
+ QDir::Files | QDir::Executable)) {
+ const QString fileName = FileName::fromString(entry).fileName();
+ if (fileName == "c89-gcc" || fileName == "c99-gcc")
+ continue;
+ const QRegularExpressionMatch match = regexp.match(fileName);
+ if (!match.hasMatch())
+ continue;
+ const bool isNative = fileName.startsWith(name);
+ const Abi abi = isNative ? Abi::hostAbi() : Abi();
+ tcs.append(autoDetectToolchains(entry, abi, language,
+ Constants::GCC_TOOLCHAIN_TYPEID, known));
+ known.append(tcs);
+ }
+ };
+ gccProbe("g++", Constants::CXX_LANGUAGE_ID);
+ gccProbe("gcc", Constants::C_LANGUAGE_ID);
+ }
+ }
return tcs;
}
@@ -981,11 +1017,11 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &comp
const FileName compilerPath = systemEnvironment.searchInPath(compiler);
if (compilerPath.isEmpty())
return result;
+ const FileName canonicalPath = FileUtils::canonicalPath(compilerPath);
result = Utils::filtered(alreadyKnown, [requiredTypeId, compilerPath](ToolChain *tc) {
- return tc->typeId() == requiredTypeId
- && tc->compilerCommand() == compilerPath;
- });
+ return tc->typeId() == requiredTypeId && tc->compilerCommand() == compilerPath;
+ });
if (!result.isEmpty()) {
for (ToolChain *tc : result) {
if (tc->isAutoDetected())
@@ -996,15 +1032,17 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &comp
result = autoDetectToolChain(compilerPath, language, requiredAbi);
- const Abi alternateAbi = Abi(requiredAbi.architecture(), requiredAbi.os(),
- requiredAbi.osFlavor(), requiredAbi.binaryFormat(), 32);
- ToolChain *abiTc = Utils::findOrDefault(result, [&requiredAbi, &alternateAbi](const ToolChain *tc) {
- return requiredAbi == tc->targetAbi()
- || (requiredAbi.wordWidth() == 64 && tc->targetAbi() == alternateAbi);
- });
- if (!abiTc) {
- qDeleteAll(result);
- result.clear();
+ if (!requiredAbi.isNull()) {
+ const Abi alternateAbi = Abi(requiredAbi.architecture(), requiredAbi.os(),
+ requiredAbi.osFlavor(), requiredAbi.binaryFormat(), 32);
+ ToolChain *abiTc = Utils::findOrDefault(result, [&requiredAbi, &alternateAbi](const ToolChain *tc) {
+ return requiredAbi == tc->targetAbi()
+ || (requiredAbi.wordWidth() == 64 && tc->targetAbi() == alternateAbi);
+ });
+ if (!abiTc) {
+ qDeleteAll(result);
+ result.clear();
+ }
}
return result;
@@ -1019,8 +1057,9 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const FileName &comp
Environment systemEnvironment = Environment::systemEnvironment();
GccToolChain::addCommandPathToEnvironment(compilerPath, systemEnvironment);
const FileName localCompilerPath = findLocalCompiler(compilerPath, systemEnvironment);
- QByteArray macros
- = gccPredefinedMacros(localCompilerPath, gccPredefinedMacrosOptions(), systemEnvironment.toStringList());
+ Macros macros
+ = gccPredefinedMacros(localCompilerPath, gccPredefinedMacrosOptions(language),
+ systemEnvironment.toStringList());
const GccToolChain::DetectedAbisResult detectedAbis = guessGccAbi(localCompilerPath,
systemEnvironment.toStringList(),
macros);
@@ -1171,7 +1210,8 @@ void GccToolChainConfigWidget::handleCompilerCommandChange()
if (haveCompiler) {
Environment env = Environment::systemEnvironment();
GccToolChain::addCommandPathToEnvironment(path, env);
- QStringList args = gccPredefinedMacrosOptions() + splitString(m_platformCodeGenFlagsLineEdit->text());
+ QStringList args = gccPredefinedMacrosOptions(Constants::CXX_LANGUAGE_ID)
+ + splitString(m_platformCodeGenFlagsLineEdit->text());
const FileName localCompilerPath = findLocalCompiler(path, env);
m_macros = gccPredefinedMacros(localCompilerPath, args, env.toStringList());
abiList = guessGccAbi(localCompilerPath, env.toStringList(), m_macros,
@@ -1722,7 +1762,7 @@ void ProjectExplorerPlugin::testGccAbiGuessing()
QFETCH(QByteArray, macros);
QFETCH(QStringList, abiList);
- QList<Abi> al = guessGccAbi(input, macros);
+ QList<Abi> al = guessGccAbi(input, ProjectExplorer::Macro::toMacros(macros));
QCOMPARE(al.count(), abiList.count());
for (int i = 0; i < al.count(); ++i)
QCOMPARE(al.at(i).toString(), abiList.at(i));
diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h
index 0399b1ec145..a3c4b4eacae 100644
--- a/src/plugins/projectexplorer/gcctoolchain.h
+++ b/src/plugins/projectexplorer/gcctoolchain.h
@@ -51,7 +51,7 @@ class LinuxIccToolChainFactory;
// GccToolChain
// --------------------------------------------------------------------------
-class PROJECTEXPLORER_EXPORT HeaderPathsCache
+class HeaderPathsCache
{
public:
HeaderPathsCache() : m_mutex(QMutex::Recursive) {}
@@ -69,20 +69,22 @@ private:
mutable Cache m_cache;
};
-class PROJECTEXPLORER_EXPORT MacroCache
+class MacroCache
{
public:
- MacroCache() : m_mutex(QMutex::Recursive) {}
+ MacroCache();
MacroCache(const MacroCache &other);
- void insert(const QStringList &compilerCommand, const QByteArray &macros);
- QByteArray check(const QStringList &compilerCommand) const;
+ void insert(const QStringList &compilerCommand, const Macros &macros);
+ Macros check(const QStringList &compilerCommand) const;
protected:
- using CacheItem = QPair<QStringList, QByteArray>;
- using Cache = QList<CacheItem>;
+ using CacheItem = QPair<QStringList, Macros>;
+ using Cache = QVector<CacheItem>;
Cache cache() const;
private:
+ // Does not lock!
+ Macros unlockedCheck(const QStringList &compilerCommand) const;
mutable QMutex m_mutex;
mutable Cache m_cache;
};
@@ -104,7 +106,7 @@ public:
WarningFlags warningFlags(const QStringList &cflags) const override;
PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
- QByteArray predefinedMacros(const QStringList &cxxflags) const override;
+ Macros predefinedMacros(const QStringList &cxxflags) const override;
SystemHeaderPathsRunner createSystemHeaderPathsRunner() const override;
QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags,
@@ -147,14 +149,16 @@ public:
};
protected:
- GccToolChain(const GccToolChain &) = default;
+ using CacheItem = QPair<QStringList, Macros>;
+ using GccCache = QVector<CacheItem>;
+
+ GccToolChain(const GccToolChain &);
void setCompilerCommand(const Utils::FileName &path);
void setSupportedAbis(const QList<Abi> &m_abis);
void setOriginalTargetTriple(const QString &targetTriple);
-
- void setMacroCache(const QStringList &allCxxflags, const QByteArray &macros) const;
- QByteArray macroCache(const QStringList &allCxxflags) const;
+ void setMacroCache(const QStringList &allCxxflags, const Macros &macroCache) const;
+ Macros macroCache(const QStringList &allCxxflags) const;
virtual QString defaultDisplayName() const;
virtual CompilerFlags defaultCompilerFlags() const;
diff --git a/src/plugins/projectexplorer/gcctoolchainfactories.h b/src/plugins/projectexplorer/gcctoolchainfactories.h
index 4417fc712fd..e4c0a583e9e 100644
--- a/src/plugins/projectexplorer/gcctoolchainfactories.h
+++ b/src/plugins/projectexplorer/gcctoolchainfactories.h
@@ -99,7 +99,7 @@ private:
AbiWidget *m_abiWidget;
bool m_isReadOnly = false;
- QByteArray m_macros;
+ ProjectExplorer::Macros m_macros;
};
// --------------------------------------------------------------------------
diff --git a/src/plugins/projectexplorer/images/build.png b/src/plugins/projectexplorer/images/build.png
index e4590537ed8..76bdf9a460c 100644
--- a/src/plugins/projectexplorer/images/build.png
+++ b/src/plugins/projectexplorer/images/build.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/build@2x.png b/src/plugins/projectexplorer/images/build@2x.png
index bb2b17ebc42..b3e3c581a34 100644
--- a/src/plugins/projectexplorer/images/build@2x.png
+++ b/src/plugins/projectexplorer/images/build@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/build_hammerhandle_mask.png b/src/plugins/projectexplorer/images/build_hammerhandle_mask.png
index 8759e4204fc..15e318ac4ab 100644
--- a/src/plugins/projectexplorer/images/build_hammerhandle_mask.png
+++ b/src/plugins/projectexplorer/images/build_hammerhandle_mask.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/build_hammerhandle_mask@2x.png b/src/plugins/projectexplorer/images/build_hammerhandle_mask@2x.png
index 04304d35f82..8b2525dbf4e 100644
--- a/src/plugins/projectexplorer/images/build_hammerhandle_mask@2x.png
+++ b/src/plugins/projectexplorer/images/build_hammerhandle_mask@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/build_hammerhead_mask.png b/src/plugins/projectexplorer/images/build_hammerhead_mask.png
index 31a174fd177..98f11810b3c 100644
--- a/src/plugins/projectexplorer/images/build_hammerhead_mask.png
+++ b/src/plugins/projectexplorer/images/build_hammerhead_mask.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/build_hammerhead_mask@2x.png b/src/plugins/projectexplorer/images/build_hammerhead_mask@2x.png
index 4bc0b4b7fc8..ec7ecd42b0f 100644
--- a/src/plugins/projectexplorer/images/build_hammerhead_mask@2x.png
+++ b/src/plugins/projectexplorer/images/build_hammerhead_mask@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/build_small.png b/src/plugins/projectexplorer/images/build_small.png
deleted file mode 100644
index 991f2c0c306..00000000000
--- a/src/plugins/projectexplorer/images/build_small.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/projectexplorer/images/buildhammerhandle.png b/src/plugins/projectexplorer/images/buildhammerhandle.png
new file mode 100644
index 00000000000..6c7c8a00e05
--- /dev/null
+++ b/src/plugins/projectexplorer/images/buildhammerhandle.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/buildhammerhandle@2x.png b/src/plugins/projectexplorer/images/buildhammerhandle@2x.png
new file mode 100644
index 00000000000..5e67dc5ab9a
--- /dev/null
+++ b/src/plugins/projectexplorer/images/buildhammerhandle@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/buildhammerhead.png b/src/plugins/projectexplorer/images/buildhammerhead.png
new file mode 100644
index 00000000000..2f7fd76a1af
--- /dev/null
+++ b/src/plugins/projectexplorer/images/buildhammerhead.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/buildhammerhead@2x.png b/src/plugins/projectexplorer/images/buildhammerhead@2x.png
new file mode 100644
index 00000000000..374166321cf
--- /dev/null
+++ b/src/plugins/projectexplorer/images/buildhammerhead@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/debugger_beetle_mask.png b/src/plugins/projectexplorer/images/debugger_beetle_mask.png
index b041005b3ae..816aacc3398 100644
--- a/src/plugins/projectexplorer/images/debugger_beetle_mask.png
+++ b/src/plugins/projectexplorer/images/debugger_beetle_mask.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/debugger_beetle_mask@2x.png b/src/plugins/projectexplorer/images/debugger_beetle_mask@2x.png
index f4f7098ee39..c240532d29e 100644
--- a/src/plugins/projectexplorer/images/debugger_beetle_mask@2x.png
+++ b/src/plugins/projectexplorer/images/debugger_beetle_mask@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/debugger_start.png b/src/plugins/projectexplorer/images/debugger_start.png
index 973d1fad52b..0e7cd1a6723 100644
--- a/src/plugins/projectexplorer/images/debugger_start.png
+++ b/src/plugins/projectexplorer/images/debugger_start.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/debugger_start@2x.png b/src/plugins/projectexplorer/images/debugger_start@2x.png
index e29d9b603d4..ab7cc15f7ae 100644
--- a/src/plugins/projectexplorer/images/debugger_start@2x.png
+++ b/src/plugins/projectexplorer/images/debugger_start@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/desktopdevice.png b/src/plugins/projectexplorer/images/desktopdevice.png
index 2323f95b6f1..10909fdd1d5 100644
--- a/src/plugins/projectexplorer/images/desktopdevice.png
+++ b/src/plugins/projectexplorer/images/desktopdevice.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/desktopdevice@2x.png b/src/plugins/projectexplorer/images/desktopdevice@2x.png
index 8abf5f330af..4fd9ca8a169 100644
--- a/src/plugins/projectexplorer/images/desktopdevice@2x.png
+++ b/src/plugins/projectexplorer/images/desktopdevice@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/devicestatusindicator.png b/src/plugins/projectexplorer/images/devicestatusindicator.png
index 2b13d25aa26..44e045cfb4d 100644
--- a/src/plugins/projectexplorer/images/devicestatusindicator.png
+++ b/src/plugins/projectexplorer/images/devicestatusindicator.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/devicestatusindicator@2x.png b/src/plugins/projectexplorer/images/devicestatusindicator@2x.png
index 4cb3a5d42da..7f03474cd01 100644
--- a/src/plugins/projectexplorer/images/devicestatusindicator@2x.png
+++ b/src/plugins/projectexplorer/images/devicestatusindicator@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/mode_project.png b/src/plugins/projectexplorer/images/mode_project.png
index 67fc3720463..cb4856b325a 100644
--- a/src/plugins/projectexplorer/images/mode_project.png
+++ b/src/plugins/projectexplorer/images/mode_project.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/mode_project@2x.png b/src/plugins/projectexplorer/images/mode_project@2x.png
index f0b7fdae0ef..264cece448f 100644
--- a/src/plugins/projectexplorer/images/mode_project@2x.png
+++ b/src/plugins/projectexplorer/images/mode_project@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/mode_project_mask.png b/src/plugins/projectexplorer/images/mode_project_mask.png
index beffa6722b8..6e6092b7ad4 100644
--- a/src/plugins/projectexplorer/images/mode_project_mask.png
+++ b/src/plugins/projectexplorer/images/mode_project_mask.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/mode_project_mask@2x.png b/src/plugins/projectexplorer/images/mode_project_mask@2x.png
index bd195752ac7..3538453911b 100644
--- a/src/plugins/projectexplorer/images/mode_project_mask@2x.png
+++ b/src/plugins/projectexplorer/images/mode_project_mask@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/rebuildhammerhandles.png b/src/plugins/projectexplorer/images/rebuildhammerhandles.png
index d0c117da138..181b4f38814 100644
--- a/src/plugins/projectexplorer/images/rebuildhammerhandles.png
+++ b/src/plugins/projectexplorer/images/rebuildhammerhandles.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/rebuildhammerhandles@2x.png b/src/plugins/projectexplorer/images/rebuildhammerhandles@2x.png
index 9ea2b3a8710..a9742c822e3 100644
--- a/src/plugins/projectexplorer/images/rebuildhammerhandles@2x.png
+++ b/src/plugins/projectexplorer/images/rebuildhammerhandles@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/rebuildhammerheads.png b/src/plugins/projectexplorer/images/rebuildhammerheads.png
index 24de5314c9d..b683bd8bd47 100644
--- a/src/plugins/projectexplorer/images/rebuildhammerheads.png
+++ b/src/plugins/projectexplorer/images/rebuildhammerheads.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/rebuildhammerheads@2x.png b/src/plugins/projectexplorer/images/rebuildhammerheads@2x.png
index 50f8757d194..ac71ffc9cc8 100644
--- a/src/plugins/projectexplorer/images/rebuildhammerheads@2x.png
+++ b/src/plugins/projectexplorer/images/rebuildhammerheads@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/run.png b/src/plugins/projectexplorer/images/run.png
index 2df52b8e7f8..7650f122067 100644
--- a/src/plugins/projectexplorer/images/run.png
+++ b/src/plugins/projectexplorer/images/run.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/run@2x.png b/src/plugins/projectexplorer/images/run@2x.png
index 9e6e984d7ca..f55a9bd37c4 100644
--- a/src/plugins/projectexplorer/images/run@2x.png
+++ b/src/plugins/projectexplorer/images/run@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/run_mask.png b/src/plugins/projectexplorer/images/run_mask.png
index aaaf05ce22d..d08de1ad5f0 100644
--- a/src/plugins/projectexplorer/images/run_mask.png
+++ b/src/plugins/projectexplorer/images/run_mask.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/run_mask@2x.png b/src/plugins/projectexplorer/images/run_mask@2x.png
index 38f6445c252..72af48223ed 100644
--- a/src/plugins/projectexplorer/images/run_mask@2x.png
+++ b/src/plugins/projectexplorer/images/run_mask@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp
index d7b284e877c..80e39bec98c 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp
@@ -438,7 +438,8 @@ QWidget *LineEditField::createWidget(const QString &displayName, JsonFieldPage *
void LineEditField::setup(JsonFieldPage *page, const QString &name)
{
- auto w = static_cast<FancyLineEdit *>(widget());
+ auto w = qobject_cast<FancyLineEdit *>(widget());
+ QTC_ASSERT(w, return);
page->registerFieldWithName(name, w);
QObject::connect(w, &FancyLineEdit::textChanged,
page, [this, page]() -> void { m_isModified = true; emit page->completeChanged(); });
@@ -454,7 +455,8 @@ bool LineEditField::validate(MacroExpander *expander, QString *message)
m_isValidating = true;
- auto w = static_cast<FancyLineEdit *>(widget());
+ auto w = qobject_cast<FancyLineEdit *>(widget());
+ QTC_ASSERT(w, return false);
if (w->isEnabled()) {
if (m_isModified) {
@@ -478,9 +480,8 @@ bool LineEditField::validate(MacroExpander *expander, QString *message)
void LineEditField::initializeData(MacroExpander *expander)
{
- QTC_ASSERT(widget(), return);
-
- auto w = static_cast<FancyLineEdit *>(widget());
+ auto w = qobject_cast<FancyLineEdit *>(widget());
+ QTC_ASSERT(w, return);
m_isValidating = true;
w->setText(expander->expand(m_defaultText));
w->setPlaceholderText(m_placeholderText);
@@ -525,7 +526,8 @@ QWidget *TextEditField::createWidget(const QString &displayName, JsonFieldPage *
void TextEditField::setup(JsonFieldPage *page, const QString &name)
{
- auto w = static_cast<QTextEdit *>(widget());
+ auto w = qobject_cast<QTextEdit *>(widget());
+ QTC_ASSERT(w, return);
page->registerFieldWithName(name, w, "plainText", SIGNAL(textChanged()));
QObject::connect(w, &QTextEdit::textChanged, page, &QWizardPage::completeChanged);
}
@@ -535,7 +537,8 @@ bool TextEditField::validate(MacroExpander *expander, QString *message)
if (!JsonFieldPage::Field::validate(expander, message))
return false;
- auto w = static_cast<QTextEdit *>(widget());
+ auto w = qobject_cast<QTextEdit *>(widget());
+ QTC_ASSERT(w, return false);
if (!w->isEnabled() && !m_disabledText.isNull() && m_currentText.isNull()) {
m_currentText = w->toHtml();
@@ -550,7 +553,8 @@ bool TextEditField::validate(MacroExpander *expander, QString *message)
void TextEditField::initializeData(MacroExpander *expander)
{
- auto w = static_cast<QTextEdit *>(widget());
+ auto w = qobject_cast<QTextEdit *>(widget());
+ QTC_ASSERT(w, return);
w->setPlainText(expander->expand(m_defaultText));
}
@@ -614,14 +618,15 @@ QWidget *PathChooserField::createWidget(const QString &displayName, JsonFieldPag
void PathChooserField::setEnabled(bool e)
{
- QTC_ASSERT(widget(), return);
- auto w = static_cast<PathChooser *>(widget());
+ auto w = qobject_cast<PathChooser *>(widget());
+ QTC_ASSERT(w, return);
w->setReadOnly(!e);
}
void PathChooserField::setup(JsonFieldPage *page, const QString &name)
{
- auto w = static_cast<PathChooser *>(widget());
+ auto w = qobject_cast<PathChooser *>(widget());
+ QTC_ASSERT(w, return);
page->registerFieldWithName(name, w, "path", SIGNAL(rawPathChanged(QString)));
QObject::connect(w, &PathChooser::rawPathChanged,
page, [page](QString) { page->completeChanged(); });
@@ -632,14 +637,15 @@ bool PathChooserField::validate(MacroExpander *expander, QString *message)
if (!JsonFieldPage::Field::validate(expander, message))
return false;
- auto w = static_cast<PathChooser *>(widget());
+ auto w = qobject_cast<PathChooser *>(widget());
+ QTC_ASSERT(w, return false);
return w->isValid();
}
void PathChooserField::initializeData(MacroExpander *expander)
{
- QTC_ASSERT(widget(), return);
- auto w = static_cast<PathChooser *>(widget());
+ auto w = qobject_cast<PathChooser *>(widget());
+ QTC_ASSERT(w, return);
w->setBaseDirectory(expander->expand(m_basePath));
w->setExpectedKind(m_kind);
@@ -686,7 +692,8 @@ QWidget *CheckBoxField::createWidget(const QString &displayName, JsonFieldPage *
void CheckBoxField::setup(JsonFieldPage *page, const QString &name)
{
- auto w = static_cast<TextFieldCheckBox *>(widget());
+ auto w = qobject_cast<TextFieldCheckBox *>(widget());
+ QTC_ASSERT(w, return);
QObject::connect(w, &TextFieldCheckBox::clicked,
page, [this, page]() { m_isModified = true; page->completeChanged();});
page->registerFieldWithName(name, w, "compareText", SIGNAL(textChanged(QString)));
@@ -698,7 +705,8 @@ bool CheckBoxField::validate(MacroExpander *expander, QString *message)
return false;
if (!m_isModified) {
- auto w = static_cast<TextFieldCheckBox *>(widget());
+ auto w = qobject_cast<TextFieldCheckBox *>(widget());
+ QTC_ASSERT(w, return false);
w->setChecked(JsonWizard::boolFromVariant(m_checkedExpression, expander));
}
return true;
@@ -706,9 +714,8 @@ bool CheckBoxField::validate(MacroExpander *expander, QString *message)
void CheckBoxField::initializeData(MacroExpander *expander)
{
+ auto w = qobject_cast<TextFieldCheckBox *>(widget());
QTC_ASSERT(widget(), return);
-
- auto w = static_cast<TextFieldCheckBox *>(widget());
w->setTrueText(expander->expand(m_checkedValue));
w->setFalseText(expander->expand(m_uncheckedValue));
@@ -821,7 +828,8 @@ QWidget *ComboBoxField::createWidget(const QString &displayName, JsonFieldPage *
void ComboBoxField::setup(JsonFieldPage *page, const QString &name)
{
- auto w = static_cast<TextFieldComboBox *>(widget());
+ auto w = qobject_cast<TextFieldComboBox *>(widget());
+ QTC_ASSERT(w, return);
page->registerFieldWithName(name, w, "indexText", SIGNAL(text4Changed(QString)));
QObject::connect(w, &TextFieldComboBox::text4Changed,
page, [page](QString) { page->completeChanged(); });
@@ -832,7 +840,8 @@ bool ComboBoxField::validate(MacroExpander *expander, QString *message)
if (!JsonFieldPage::Field::validate(expander, message))
return false;
- auto w = static_cast<TextFieldComboBox *>(widget());
+ auto w = qobject_cast<TextFieldComboBox *>(widget());
+ QTC_ASSERT(w, return false);
if (!w->isEnabled() && m_disabledIndex >= 0 && m_savedIndex < 0) {
m_savedIndex = w->currentIndex();
w->setCurrentIndex(m_disabledIndex);
@@ -846,7 +855,8 @@ bool ComboBoxField::validate(MacroExpander *expander, QString *message)
void ComboBoxField::initializeData(MacroExpander *expander)
{
- auto w = static_cast<TextFieldComboBox *>(widget());
+ auto w = qobject_cast<TextFieldComboBox *>(widget());
+ QTC_ASSERT(widget(), return);
QStringList tmpItems
= Utils::transform(m_itemList,
[expander](const QString &i) { return expander->expand(i); });
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonprojectpage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonprojectpage.cpp
index b23b000d30e..45f332a2def 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonprojectpage.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonprojectpage.cpp
@@ -28,6 +28,7 @@
#include <coreplugin/documentmanager.h>
+#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <QDir>
@@ -51,7 +52,7 @@ bool JsonProjectPage::validatePage()
{
if (isComplete() && useAsDefaultPath()) {
// Store the path as default path for new projects if desired.
- Core::DocumentManager::setProjectsDirectory(path());
+ Core::DocumentManager::setProjectsDirectory(Utils::FileName::fromString(path()));
Core::DocumentManager::setUseProjectsDirectory(true);
}
diff --git a/src/plugins/projectexplorer/kit.cpp b/src/plugins/projectexplorer/kit.cpp
index c6fb97cffed..a4d7b608f66 100644
--- a/src/plugins/projectexplorer/kit.cpp
+++ b/src/plugins/projectexplorer/kit.cpp
@@ -381,7 +381,7 @@ QIcon Kit::icon() const
if (!d->m_cachedIcon.isNull())
return d->m_cachedIcon;
- if (d->m_iconPath.exists()) {
+ if (!d->m_iconPath.isEmpty() && d->m_iconPath.exists()) {
d->m_cachedIcon = QIcon(d->m_iconPath.toString());
return d->m_cachedIcon;
}
diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp
index f340f086dc2..34578f64b82 100644
--- a/src/plugins/projectexplorer/kitinformation.cpp
+++ b/src/plugins/projectexplorer/kitinformation.cpp
@@ -101,7 +101,7 @@ KitInformation::ItemList SysRootKitInformation::toUserOutput(const Kit *k) const
void SysRootKitInformation::addToMacroExpander(Kit *kit, Utils::MacroExpander *expander) const
{
- expander->registerFileVariables("SysRoot", tr("Sys Root"), [this, kit]() -> QString {
+ expander->registerFileVariables("SysRoot", tr("Sys Root"), [kit]() -> QString {
return SysRootKitInformation::sysRoot(kit).toString();
});
}
@@ -190,7 +190,8 @@ QList<Task> ToolChainKitInformation::validate(const Kit *k) const
result << tc->validateKit(k);
}
if (targetAbis.count() != 1) {
- result << Task(Task::Error, tr("Compilers produce code for different ABIs."),
+ result << Task(Task::Error, tr("Compilers produce code for different ABIs: %1")
+ .arg(Utils::transform(targetAbis, &Abi::toString).toList().join(", ")),
Utils::FileName(), -1, Core::Id(Constants::TASK_CATEGORY_BUILDSYSTEM));
}
}
@@ -335,24 +336,24 @@ void ToolChainKitInformation::addToMacroExpander(Kit *kit, Utils::MacroExpander
{
// Compatibility with Qt Creator < 4.2:
expander->registerVariable("Compiler:Name", tr("Compiler"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
const ToolChain *tc = toolChain(kit, Constants::CXX_LANGUAGE_ID);
return tc ? tc->displayName() : tr("None");
});
expander->registerVariable("Compiler:Executable", tr("Path to the compiler executable"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
const ToolChain *tc = toolChain(kit, Constants::CXX_LANGUAGE_ID);
return tc ? tc->compilerCommand().toString() : QString();
});
expander->registerPrefix("Compiler:Name", tr("Compiler for different languages"),
- [this, kit](const QString &ls) -> QString {
+ [kit](const QString &ls) -> QString {
const ToolChain *tc = toolChain(kit, findLanguage(ls));
return tc ? tc->displayName() : tr("None");
});
expander->registerPrefix("Compiler:Executable", tr("Compiler executable for different languages"),
- [this, kit](const QString &ls) -> QString {
+ [kit](const QString &ls) -> QString {
const ToolChain *tc = toolChain(kit, findLanguage(ls));
return tc ? tc->compilerCommand().toString() : QString();
});
@@ -518,7 +519,7 @@ void ToolChainKitInformation::kitsWereLoaded()
void ToolChainKitInformation::toolChainUpdated(ToolChain *tc)
{
- for (Kit *k : KitManager::kits([tc, this](const Kit *k) { return toolChain(k, tc->language()) == tc; }))
+ for (Kit *k : KitManager::kits([tc](const Kit *k) { return toolChain(k, tc->language()) == tc; }))
notifyAboutUpdate(k);
}
@@ -691,27 +692,27 @@ KitInformation::ItemList DeviceKitInformation::toUserOutput(const Kit *k) const
void DeviceKitInformation::addToMacroExpander(Kit *kit, Utils::MacroExpander *expander) const
{
expander->registerVariable("Device:HostAddress", tr("Host address"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
const IDevice::ConstPtr device = DeviceKitInformation::device(kit);
return device ? device->sshParameters().host : QString();
});
expander->registerVariable("Device:SshPort", tr("SSH port"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
const IDevice::ConstPtr device = DeviceKitInformation::device(kit);
return device ? QString::number(device->sshParameters().port) : QString();
});
expander->registerVariable("Device:UserName", tr("User name"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
const IDevice::ConstPtr device = DeviceKitInformation::device(kit);
return device ? device->sshParameters().userName : QString();
});
expander->registerVariable("Device:KeyFile", tr("Private key file"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
const IDevice::ConstPtr device = DeviceKitInformation::device(kit);
return device ? device->sshParameters().privateKeyFile : QString();
});
expander->registerVariable("Device:Name", tr("Device name"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
const IDevice::ConstPtr device = DeviceKitInformation::device(kit);
return device ? device->displayName() : QString();
});
diff --git a/src/plugins/projectexplorer/localenvironmentaspect.cpp b/src/plugins/projectexplorer/localenvironmentaspect.cpp
index edc9e8a761a..9d7cd8dcdc8 100644
--- a/src/plugins/projectexplorer/localenvironmentaspect.cpp
+++ b/src/plugins/projectexplorer/localenvironmentaspect.cpp
@@ -88,7 +88,9 @@ LocalEnvironmentAspect::LocalEnvironmentAspect(RunConfiguration *parent,
const BaseEnvironmentModifier &modifier) :
EnvironmentAspect(parent), m_baseEnvironmentModifier(modifier)
{
- connect(parent->target(), &Target::environmentChanged,
+ parent->target()->subscribeSignal(&BuildConfiguration::environmentChanged,
+ this, &LocalEnvironmentAspect::buildEnvironmentHasChanged);
+ connect(parent->target(), &Target::activeBuildConfigurationChanged,
this, &LocalEnvironmentAspect::buildEnvironmentHasChanged);
}
diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.cpp b/src/plugins/projectexplorer/miniprojecttargetselector.cpp
index d1efd49bb6b..46b63e23934 100644
--- a/src/plugins/projectexplorer/miniprojecttargetselector.cpp
+++ b/src/plugins/projectexplorer/miniprojecttargetselector.cpp
@@ -23,12 +23,20 @@
**
****************************************************************************/
-#include "miniprojecttargetselector.h"
-#include "kit.h"
+#include "buildconfiguration.h"
+#include "deployconfiguration.h"
#include "kitconfigwidget.h"
+#include "kit.h"
#include "kitmanager.h"
-#include "target.h"
+#include "kitmanager.h"
+#include "miniprojecttargetselector.h"
+#include "projectexplorer.h"
#include "projectexplorericons.h"
+#include "project.h"
+#include "projectmodels.h"
+#include "runconfiguration.h"
+#include "session.h"
+#include "target.h"
#include <utils/algorithm.h>
#include <utils/styledbar.h>
@@ -39,23 +47,16 @@
#include <coreplugin/coreconstants.h>
#include <coreplugin/modemanager.h>
-#include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/session.h>
-#include <projectexplorer/project.h>
-#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/deployconfiguration.h>
-#include <projectexplorer/kitmanager.h>
-#include <projectexplorer/projectmodels.h>
-#include <projectexplorer/runconfiguration.h>
-
#include <QGuiApplication>
#include <QTimer>
#include <QLayout>
#include <QLabel>
+#include <QList>
#include <QListWidget>
#include <QStatusBar>
#include <QKeyEvent>
#include <QPainter>
+#include <QPixmap>
#include <QStyleFactory>
#include <QAction>
#include <QItemDelegate>
@@ -64,21 +65,21 @@ static QIcon createCenteredIcon(const QIcon &icon, const QIcon &overlay)
{
QPixmap targetPixmap;
const qreal appDevicePixelRatio = qApp->devicePixelRatio();
- int deviceSpaceIconSize = Core::Constants::TARGET_ICON_SIZE * appDevicePixelRatio;
- targetPixmap = QPixmap(deviceSpaceIconSize, deviceSpaceIconSize);
+ targetPixmap = QPixmap(Core::Constants::MODEBAR_ICON_SIZE * appDevicePixelRatio,
+ Core::Constants::MODEBAR_ICON_SIZE * appDevicePixelRatio);
targetPixmap.setDevicePixelRatio(appDevicePixelRatio);
targetPixmap.fill(Qt::transparent);
QPainter painter(&targetPixmap); // painter in user space
- QPixmap pixmap = icon.pixmap(Core::Constants::TARGET_ICON_SIZE); // already takes app devicePixelRatio into account
+ QPixmap pixmap = icon.pixmap(Core::Constants::MODEBAR_ICON_SIZE); // already takes app devicePixelRatio into account
qreal pixmapDevicePixelRatio = pixmap.devicePixelRatio();
- painter.drawPixmap((Core::Constants::TARGET_ICON_SIZE - pixmap.width() / pixmapDevicePixelRatio) / 2,
- (Core::Constants::TARGET_ICON_SIZE - pixmap.height() / pixmapDevicePixelRatio) / 2, pixmap);
+ painter.drawPixmap((Core::Constants::MODEBAR_ICON_SIZE - pixmap.width() / pixmapDevicePixelRatio) / 2,
+ (Core::Constants::MODEBAR_ICON_SIZE - pixmap.height() / pixmapDevicePixelRatio) / 2, pixmap);
if (!overlay.isNull()) {
- pixmap = overlay.pixmap(Core::Constants::TARGET_ICON_SIZE); // already takes app devicePixelRatio into account
+ pixmap = overlay.pixmap(Core::Constants::MODEBAR_ICON_SIZE); // already takes app devicePixelRatio into account
pixmapDevicePixelRatio = pixmap.devicePixelRatio();
- painter.drawPixmap((Core::Constants::TARGET_ICON_SIZE - pixmap.width() / pixmapDevicePixelRatio) / 2,
- (Core::Constants::TARGET_ICON_SIZE - pixmap.height() / pixmapDevicePixelRatio) / 2, pixmap);
+ painter.drawPixmap((Core::Constants::MODEBAR_ICON_SIZE - pixmap.width() / pixmapDevicePixelRatio) / 2,
+ (Core::Constants::MODEBAR_ICON_SIZE - pixmap.height() / pixmapDevicePixelRatio) / 2, pixmap);
}
return QIcon(targetPixmap);
@@ -719,13 +720,23 @@ MiniProjectTargetSelector::MiniProjectTargetSelector(QAction *targetSelectorActi
this, &MiniProjectTargetSelector::kitChanged);
connect(m_listWidgets[TARGET], &GenericListWidget::changeActiveProjectConfiguration,
- this, &MiniProjectTargetSelector::setActiveTarget);
+ this, [this](ProjectConfiguration *pc) {
+ SessionManager::setActiveTarget(m_project, static_cast<Target *>(pc), SetActive::Cascade);
+ });
connect(m_listWidgets[BUILD], &GenericListWidget::changeActiveProjectConfiguration,
- this, &MiniProjectTargetSelector::setActiveBuildConfiguration);
+ this, [this](ProjectConfiguration *pc) {
+ SessionManager::setActiveBuildConfiguration(m_project->activeTarget(),
+ static_cast<BuildConfiguration *>(pc), SetActive::Cascade);
+ });
connect(m_listWidgets[DEPLOY], &GenericListWidget::changeActiveProjectConfiguration,
- this, &MiniProjectTargetSelector::setActiveDeployConfiguration);
+ this, [this](ProjectConfiguration *pc) {
+ SessionManager::setActiveDeployConfiguration(m_project->activeTarget(),
+ static_cast<DeployConfiguration *>(pc), SetActive::Cascade);
+ });
connect(m_listWidgets[RUN], &GenericListWidget::changeActiveProjectConfiguration,
- this, &MiniProjectTargetSelector::setActiveRunConfiguration);
+ this, [this](ProjectConfiguration *pc) {
+ m_project->activeTarget()->setActiveRunConfiguration(static_cast<RunConfiguration *>(pc));
+ });
}
bool MiniProjectTargetSelector::event(QEvent *event)
@@ -959,34 +970,13 @@ void MiniProjectTargetSelector::doLayout(bool keepSize)
move(moveTo);
}
-void MiniProjectTargetSelector::setActiveTarget(ProjectConfiguration *pc)
-{
- SessionManager::setActiveTarget(m_project, static_cast<Target *>(pc),
- SetActive::Cascade);
-}
-
-void MiniProjectTargetSelector::setActiveBuildConfiguration(ProjectConfiguration *pc)
-{
- SessionManager::setActiveBuildConfiguration(m_target, static_cast<BuildConfiguration *>(pc), SetActive::Cascade);
-}
-
-void MiniProjectTargetSelector::setActiveDeployConfiguration(ProjectConfiguration *pc)
-{
- SessionManager::setActiveDeployConfiguration(m_target, static_cast<DeployConfiguration *>(pc), SetActive::Cascade);
-}
-
-void MiniProjectTargetSelector::setActiveRunConfiguration(ProjectConfiguration *pc)
-{
- m_target->setActiveRunConfiguration(static_cast<RunConfiguration *>(pc));
-}
-
void MiniProjectTargetSelector::projectAdded(Project *project)
{
- connect(project, &Project::addedTarget,
- this, &MiniProjectTargetSelector::slotAddedTarget);
+ connect(project, &Project::addedProjectConfiguration,
+ this, &MiniProjectTargetSelector::handleNewProjectConfiguration);
- connect(project, &Project::removedTarget,
- this, &MiniProjectTargetSelector::slotRemovedTarget);
+ connect(project, &Project::removedProjectConfiguration,
+ this, &MiniProjectTargetSelector::handleRemovalOfProjectConfiguration);
foreach (Target *t, project->targets())
addedTarget(t);
@@ -1000,11 +990,11 @@ void MiniProjectTargetSelector::projectAdded(Project *project)
void MiniProjectTargetSelector::projectRemoved(Project *project)
{
- disconnect(project, &Project::addedTarget,
- this, &MiniProjectTargetSelector::slotAddedTarget);
+ disconnect(project, &Project::addedProjectConfiguration,
+ this, &MiniProjectTargetSelector::handleNewProjectConfiguration);
- disconnect(project, &Project::removedTarget,
- this, &MiniProjectTargetSelector::slotRemovedTarget);
+ disconnect(project, &Project::removedProjectConfiguration,
+ this, &MiniProjectTargetSelector::handleRemovalOfProjectConfiguration);
foreach (Target *t, project->targets())
removedTarget(t);
@@ -1016,23 +1006,63 @@ void MiniProjectTargetSelector::projectRemoved(Project *project)
updateRunListVisible();
}
-void MiniProjectTargetSelector::addedTarget(Target *target)
+void MiniProjectTargetSelector::handleNewProjectConfiguration(ProjectConfiguration *pc)
{
- connect(target, &Target::addedBuildConfiguration,
- this, &MiniProjectTargetSelector::slotAddedBuildConfiguration);
- connect(target, &Target::removedBuildConfiguration,
- this, &MiniProjectTargetSelector::slotRemovedBuildConfiguration);
+ if (auto t = qobject_cast<Target *>(pc)) {
+ addedTarget(t);
+ updateTargetListVisible();
+ updateBuildListVisible();
+ updateDeployListVisible();
+ updateRunListVisible();
+ return;
+ }
+ if (auto bc = qobject_cast<BuildConfiguration *>(pc)) {
+ addedBuildConfiguration(bc);
+ updateBuildListVisible();
+ return;
+ }
+ if (auto dc = qobject_cast<DeployConfiguration *>(pc)) {
+ addedDeployConfiguration(dc);
+ updateDeployListVisible();
+ return;
+ }
+ if (auto rc = qobject_cast<RunConfiguration *>(pc)) {
+ addedRunConfiguration(rc);
+ updateRunListVisible();
+ return;
+ }
+}
- connect(target, &Target::addedDeployConfiguration,
- this, &MiniProjectTargetSelector::slotAddedDeployConfiguration);
- connect(target, &Target::removedDeployConfiguration,
- this, &MiniProjectTargetSelector::slotRemovedDeployConfiguration);
+void MiniProjectTargetSelector::handleRemovalOfProjectConfiguration(ProjectConfiguration *pc)
+{
+ if (auto t = qobject_cast<Target *>(pc)) {
+ removedTarget(t);
- connect(target, &Target::addedRunConfiguration,
- this, &MiniProjectTargetSelector::slotAddedRunConfiguration);
- connect(target, &Target::removedRunConfiguration,
- this, &MiniProjectTargetSelector::slotRemovedRunConfiguration);
+ updateTargetListVisible();
+ updateBuildListVisible();
+ updateDeployListVisible();
+ updateRunListVisible();
+ return;
+ }
+ if (auto bc = qobject_cast<BuildConfiguration *>(pc)) {
+ removedBuildConfiguration(bc);
+ updateBuildListVisible();
+ return;
+ }
+ if (auto dc = qobject_cast<DeployConfiguration *>(pc)) {
+ removedDeployConfiguration(dc);
+ updateDeployListVisible();
+ return;
+ }
+ if (auto rc = qobject_cast<RunConfiguration *>(pc)) {
+ removedRunConfiguration(rc);
+ updateRunListVisible();
+ return;
+ }
+}
+void MiniProjectTargetSelector::addedTarget(Target *target)
+{
if (target->project() == m_project)
m_listWidgets[TARGET]->addProjectConfiguration(target);
@@ -1044,32 +1074,8 @@ void MiniProjectTargetSelector::addedTarget(Target *target)
addedRunConfiguration(rc);
}
-void MiniProjectTargetSelector::slotAddedTarget(Target *target)
-{
- addedTarget(target);
- updateTargetListVisible();
- updateBuildListVisible();
- updateDeployListVisible();
- updateRunListVisible();
-}
-
void MiniProjectTargetSelector::removedTarget(Target *target)
{
- disconnect(target, &Target::addedBuildConfiguration,
- this, &MiniProjectTargetSelector::slotAddedBuildConfiguration);
- disconnect(target, &Target::removedBuildConfiguration,
- this, &MiniProjectTargetSelector::slotRemovedBuildConfiguration);
-
- disconnect(target, &Target::addedDeployConfiguration,
- this, &MiniProjectTargetSelector::slotAddedDeployConfiguration);
- disconnect(target, &Target::removedDeployConfiguration,
- this, &MiniProjectTargetSelector::slotRemovedDeployConfiguration);
-
- disconnect(target, &Target::addedRunConfiguration,
- this, &MiniProjectTargetSelector::slotAddedRunConfiguration);
- disconnect(target, &Target::removedRunConfiguration,
- this, &MiniProjectTargetSelector::slotRemovedRunConfiguration);
-
if (target->project() == m_project)
m_listWidgets[TARGET]->removeProjectConfiguration(target);
@@ -1081,95 +1087,41 @@ void MiniProjectTargetSelector::removedTarget(Target *target)
removedRunConfiguration(rc);
}
-void MiniProjectTargetSelector::slotRemovedTarget(Target *target)
-{
- removedTarget(target);
-
- updateTargetListVisible();
- updateBuildListVisible();
- updateDeployListVisible();
- updateRunListVisible();
-}
-
-
void MiniProjectTargetSelector::addedBuildConfiguration(BuildConfiguration *bc)
{
if (bc->target() == m_target)
m_listWidgets[BUILD]->addProjectConfiguration(bc);
}
-void MiniProjectTargetSelector::slotAddedBuildConfiguration(BuildConfiguration *bc)
-{
- if (bc->target() == m_target)
- m_listWidgets[BUILD]->addProjectConfiguration(bc);
- updateBuildListVisible();
-}
-
void MiniProjectTargetSelector::removedBuildConfiguration(BuildConfiguration *bc)
{
if (bc->target() == m_target)
m_listWidgets[BUILD]->removeProjectConfiguration(bc);
}
-void MiniProjectTargetSelector::slotRemovedBuildConfiguration(BuildConfiguration *bc)
-{
- if (bc->target() == m_target)
- m_listWidgets[BUILD]->removeProjectConfiguration(bc);
- updateBuildListVisible();
-}
-
void MiniProjectTargetSelector::addedDeployConfiguration(DeployConfiguration *dc)
{
if (dc->target() == m_target)
m_listWidgets[DEPLOY]->addProjectConfiguration(dc);
}
-void MiniProjectTargetSelector::slotAddedDeployConfiguration(DeployConfiguration *dc)
-{
- if (dc->target() == m_target)
- m_listWidgets[DEPLOY]->addProjectConfiguration(dc);
- updateDeployListVisible();
-}
-
void MiniProjectTargetSelector::removedDeployConfiguration(DeployConfiguration *dc)
{
if (dc->target() == m_target)
m_listWidgets[DEPLOY]->removeProjectConfiguration(dc);
}
-
-void MiniProjectTargetSelector::slotRemovedDeployConfiguration(DeployConfiguration *dc)
-{
- if (dc->target() == m_target)
- m_listWidgets[DEPLOY]->removeProjectConfiguration(dc);
- updateDeployListVisible();
-}
-
void MiniProjectTargetSelector::addedRunConfiguration(RunConfiguration *rc)
{
if (rc->target() == m_target)
m_listWidgets[RUN]->addProjectConfiguration(rc);
}
-void MiniProjectTargetSelector::slotAddedRunConfiguration(RunConfiguration *rc)
-{
- if (rc->target() == m_target)
- m_listWidgets[RUN]->addProjectConfiguration(rc);
- updateRunListVisible();
-}
-
void MiniProjectTargetSelector::removedRunConfiguration(RunConfiguration *rc)
{
if (rc->target() == m_target)
m_listWidgets[RUN]->removeProjectConfiguration(rc);
}
-void MiniProjectTargetSelector::slotRemovedRunConfiguration(RunConfiguration *rc)
-{
- if (rc->target() == m_target)
- m_listWidgets[RUN]->removeProjectConfiguration(rc);
- updateRunListVisible();
-}
-
void MiniProjectTargetSelector::updateProjectListVisible()
{
int count = SessionManager::projects().size();
diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.h b/src/plugins/projectexplorer/miniprojecttargetselector.h
index 07f8da0906b..0821a2257db 100644
--- a/src/plugins/projectexplorer/miniprojecttargetselector.h
+++ b/src/plugins/projectexplorer/miniprojecttargetselector.h
@@ -148,14 +148,8 @@ public:
private:
void projectAdded(ProjectExplorer::Project *project);
void projectRemoved(ProjectExplorer::Project *project);
- void slotAddedTarget(ProjectExplorer::Target *target);
- void slotRemovedTarget(ProjectExplorer::Target *target);
- void slotAddedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc);
- void slotRemovedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc);
- void slotAddedDeployConfiguration(ProjectExplorer::DeployConfiguration *dc);
- void slotRemovedDeployConfiguration(ProjectExplorer::DeployConfiguration *dc);
- void slotAddedRunConfiguration(ProjectExplorer::RunConfiguration *rc);
- void slotRemovedRunConfiguration(ProjectExplorer::RunConfiguration *rc);
+ void handleNewProjectConfiguration(ProjectConfiguration *pc);
+ void handleRemovalOfProjectConfiguration(ProjectConfiguration *pc);
void changeStartupProject(ProjectExplorer::Project *project);
void activeTargetChanged(ProjectExplorer::Target *target);
@@ -164,11 +158,6 @@ private:
void activeDeployConfigurationChanged(ProjectExplorer::DeployConfiguration *dc);
void activeRunConfigurationChanged(ProjectExplorer::RunConfiguration *rc);
- void setActiveTarget(ProjectExplorer::ProjectConfiguration *pc);
- void setActiveBuildConfiguration(ProjectExplorer::ProjectConfiguration *pc);
- void setActiveDeployConfiguration(ProjectExplorer::ProjectConfiguration *pc);
- void setActiveRunConfiguration(ProjectExplorer::ProjectConfiguration *pc);
-
void delayedHide();
void updateActionAndSummary();
void switchToProjectsMode();
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index 2562b7fcc4b..2ff34dbcb87 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -410,31 +410,18 @@ static QByteArray msvcCompilationFile()
//
// [1] https://msdn.microsoft.com/en-us/library/b0084kay.aspx
// [2] http://stackoverflow.com/questions/3665537/how-to-find-out-cl-exes-built-in-macros
-QByteArray MsvcToolChain::msvcPredefinedMacros(const QStringList cxxflags,
- const Utils::Environment &env) const
+Macros MsvcToolChain::msvcPredefinedMacros(const QStringList cxxflags,
+ const Utils::Environment &env) const
{
- QByteArray predefinedMacros;
+ Macros predefinedMacros;
QStringList toProcess;
- foreach (const QString &arg, cxxflags) {
+ for (const QString &arg : cxxflags) {
if (arg.startsWith(QLatin1String("/D"))) {
- QString define = arg.mid(2);
- int pos = define.indexOf(QLatin1Char('='));
- if (pos < 0) {
- predefinedMacros += "#define ";
- predefinedMacros += define.toLocal8Bit();
- predefinedMacros += '\n';
- } else {
- predefinedMacros += "#define ";
- predefinedMacros += define.left(pos).toLocal8Bit();
- predefinedMacros += ' ';
- predefinedMacros += define.mid(pos + 1).toLocal8Bit();
- predefinedMacros += '\n';
- }
+ const QString define = arg.mid(2);
+ predefinedMacros.append(Macro::fromKeyValue(define));
} else if (arg.startsWith(QLatin1String("/U"))) {
- predefinedMacros += "#undef ";
- predefinedMacros += arg.mid(2).toLocal8Bit();
- predefinedMacros += '\n';
+ predefinedMacros.append({arg.mid(2).toLocal8Bit(), ProjectExplorer::MacroType::Undefine});
} else if (arg.startsWith(QLatin1String("-I"))) {
// Include paths should not have any effect on defines
} else {
@@ -468,18 +455,8 @@ QByteArray MsvcToolChain::msvcPredefinedMacros(const QStringList cxxflags,
const QStringList output = Utils::filtered(response.stdOut().split('\n'),
[](const QString &s) { return s.startsWith('V'); });
- foreach (const QString& line, output) {
- QStringList split = line.split('=');
- const QString key = split.at(0).mid(1);
- QString value = split.at(1);
- predefinedMacros += "#define ";
- predefinedMacros += key.toUtf8();
- predefinedMacros += ' ';
- predefinedMacros += value.toUtf8();
- predefinedMacros += '\n';
- }
- if (debug)
- qDebug() << "msvcPredefinedMacros" << predefinedMacros;
+ for (const QString &line : output)
+ predefinedMacros.append(Macro::fromKeyValue(line.mid(1)));
return predefinedMacros;
}
diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h
index fd341177eb3..3dcb715286a 100644
--- a/src/plugins/projectexplorer/msvctoolchain.h
+++ b/src/plugins/projectexplorer/msvctoolchain.h
@@ -82,8 +82,8 @@ protected:
Utils::Environment readEnvironmentSetting(const Utils::Environment& env) const final;
// Function must be thread-safe!
- QByteArray msvcPredefinedMacros(const QStringList cxxflags,
- const Utils::Environment &env) const override;
+ Macros msvcPredefinedMacros(const QStringList cxxflags,
+ const Utils::Environment &env) const override;
private:
QList<Utils::EnvironmentItem> environmentModifications() const;
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index 09475e24b8f..7215b28eb8a 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -52,6 +52,7 @@
#include <utils/qtcassert.h>
#include <limits>
+#include <memory>
/*!
\class ProjectExplorer::Project
@@ -126,20 +127,27 @@ bool ProjectDocument::reload(QString *errorString, Core::IDocument::ReloadFlag f
class ProjectPrivate
{
public:
- ProjectPrivate(Core::IDocument *document) : m_document(document) { }
+ ProjectPrivate(const QString &mimeType, const Utils::FileName &fileName,
+ const ProjectDocument::ProjectCallback &callback)
+ {
+ m_document = std::make_unique<ProjectDocument>(mimeType, fileName, callback);
+ }
+
~ProjectPrivate();
Core::Id m_id;
- Core::IDocument *m_document = nullptr;
+ bool m_isParsing = false;
+ bool m_hasParsingData = false;
+ std::unique_ptr<Core::IDocument> m_document;
ProjectNode *m_rootProjectNode = nullptr;
- ContainerNode *m_containerNode = nullptr;
+ std::unique_ptr<ContainerNode> m_containerNode;
QList<Target *> m_targets;
Target *m_activeTarget = nullptr;
EditorConfiguration m_editorConfiguration;
Core::Context m_projectContext;
Core::Context m_projectLanguages;
QVariantMap m_pluginSettings;
- Internal::UserFileAccessor *m_accessor = nullptr;
+ std::unique_ptr<Internal::UserFileAccessor> m_accessor;
QString m_displayName;
@@ -151,32 +159,28 @@ public:
ProjectPrivate::~ProjectPrivate()
{
+ qDeleteAll(m_targets);
+
// Make sure our root node is null when deleting
ProjectNode *oldNode = m_rootProjectNode;
m_rootProjectNode = nullptr;
delete oldNode;
-
- delete m_containerNode;
-
- delete m_document;
- delete m_accessor;
}
Project::Project(const QString &mimeType, const Utils::FileName &fileName,
const ProjectDocument::ProjectCallback &callback) :
- d(new ProjectPrivate(new ProjectDocument(mimeType, fileName, callback)))
+ d(new ProjectPrivate(mimeType, fileName, callback))
{
d->m_macroExpander.setDisplayName(tr("Project"));
d->m_macroExpander.registerVariable("Project:Name", tr("Project Name"),
[this] { return displayName(); });
// Only set up containernode after d is set so that it will find the project directory!
- d->m_containerNode = new ContainerNode(this);
+ d->m_containerNode = std::make_unique<ContainerNode>(this);
}
Project::~Project()
{
- qDeleteAll(d->m_targets);
delete d;
}
@@ -194,7 +198,7 @@ Core::Id Project::id() const
Core::IDocument *Project::document() const
{
QTC_CHECK(d->m_document);
- return d->m_document;
+ return d->m_document.get();
}
Utils::FileName Project::projectFilePath() const
@@ -219,20 +223,6 @@ QString Project::makeUnique(const QString &preferredName, const QStringList &use
return tryName;
}
-void Project::changeEnvironment()
-{
- auto t = qobject_cast<Target *>(sender());
- if (t == activeTarget())
- emit environmentChanged();
-}
-
-void Project::changeBuildConfigurationEnabled()
-{
- auto t = qobject_cast<Target *>(sender());
- if (t == activeTarget())
- emit buildConfigurationEnabledChanged();
-}
-
void Project::addTarget(Target *t)
{
QTC_ASSERT(t && !d->m_targets.contains(t), return);
@@ -243,10 +233,11 @@ void Project::addTarget(Target *t)
// add it
d->m_targets.push_back(t);
- connect(t, &Target::environmentChanged, this, &Project::changeEnvironment);
- connect(t, &Target::buildConfigurationEnabledChanged,
- this, &Project::changeBuildConfigurationEnabled);
- connect(t, &Target::buildDirectoryChanged, this, &Project::onBuildDirectoryChanged);
+ connect(t, &Target::addedProjectConfiguration, this, &Project::addedProjectConfiguration);
+ connect(t, &Target::aboutToRemoveProjectConfiguration, this, &Project::aboutToRemoveProjectConfiguration);
+ connect(t, &Target::removedProjectConfiguration, this, &Project::removedProjectConfiguration);
+ connect(t, &Target::activeProjectConfigurationChanged, this, &Project::activeProjectConfigurationChanged);
+ emit addedProjectConfiguration(t);
emit addedTarget(t);
// check activeTarget:
@@ -270,9 +261,11 @@ bool Project::removeTarget(Target *target)
SessionManager::setActiveTarget(this, d->m_targets.at(0), SetActive::Cascade);
}
+ emit aboutToRemoveProjectConfiguration(target);
emit aboutToRemoveTarget(target);
d->m_targets.removeOne(target);
emit removedTarget(target);
+ emit removedProjectConfiguration(target);
delete target;
return true;
@@ -293,9 +286,8 @@ void Project::setActiveTarget(Target *target)
if ((!target && !d->m_targets.isEmpty()) ||
(target && d->m_targets.contains(target) && d->m_activeTarget != target)) {
d->m_activeTarget = target;
+ emit activeProjectConfigurationChanged(d->m_activeTarget);
emit activeTargetChanged(d->m_activeTarget);
- emit environmentChanged();
- emit buildConfigurationEnabledChanged();
}
}
@@ -462,6 +454,24 @@ bool Project::setupTarget(Target *t)
return true;
}
+void Project::emitParsingStarted()
+{
+ QTC_ASSERT(!d->m_isParsing, return);
+
+ d->m_isParsing = true;
+ d->m_hasParsingData = false;
+ emit parsingStarted();
+}
+
+void Project::emitParsingFinished(bool success)
+{
+ QTC_ASSERT(d->m_isParsing, return);
+
+ d->m_isParsing = false;
+ d->m_hasParsingData = success;
+ emit parsingFinished(success);
+}
+
void Project::setDisplayName(const QString &name)
{
if (name == d->m_displayName)
@@ -493,7 +503,7 @@ void Project::setRootProjectNode(ProjectNode *root)
ProjectNode *oldNode = d->m_rootProjectNode;
d->m_rootProjectNode = root;
if (root) {
- root->setParentFolderNode(d->m_containerNode);
+ root->setParentFolderNode(d->m_containerNode.get());
// Only announce non-null root, null is only used when project is destroyed.
// In that case SessionManager::projectRemoved() triggers the update.
ProjectTree::emitSubtreeChanged(root);
@@ -531,7 +541,7 @@ void Project::saveSettings()
{
emit aboutToSaveSettings();
if (!d->m_accessor)
- d->m_accessor = new Internal::UserFileAccessor(this);
+ d->m_accessor = std::make_unique<Internal::UserFileAccessor>(this);
if (!targets().isEmpty())
d->m_accessor->saveSettings(toMap(), Core::ICore::mainWindow());
}
@@ -539,7 +549,7 @@ void Project::saveSettings()
Project::RestoreResult Project::restoreSettings(QString *errorMessage)
{
if (!d->m_accessor)
- d->m_accessor = new Internal::UserFileAccessor(this);
+ d->m_accessor = std::make_unique<Internal::UserFileAccessor>(this);
QVariantMap map(d->m_accessor->restoreSettings(Core::ICore::mainWindow()));
RestoreResult result = fromMap(map, errorMessage);
if (result == RestoreResult::Ok)
@@ -633,7 +643,7 @@ ProjectNode *Project::rootProjectNode() const
ContainerNode *Project::containerNode() const
{
- return d->m_containerNode;
+ return d->m_containerNode.get();
}
Project::RestoreResult Project::fromMap(const QVariantMap &map, QString *errorMessage)
@@ -811,6 +821,16 @@ Utils::MacroExpander *Project::macroExpander() const
return &d->m_macroExpander;
}
+bool Project::isParsing() const
+{
+ return d->m_isParsing;
+}
+
+bool Project::hasParsingData() const
+{
+ return d->m_hasParsingData;
+}
+
ProjectImporter *Project::projectImporter() const
{
return nullptr;
@@ -836,11 +856,4 @@ void Project::setPreferredKitPredicate(const Kit::Predicate &predicate)
d->m_preferredKitPredicate = predicate;
}
-void Project::onBuildDirectoryChanged()
-{
- auto target = qobject_cast<Target *>(sender());
- if (target && target == activeTarget())
- emit buildDirectoryChanged();
-}
-
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index f76a1513dea..aac69ab22c8 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -28,6 +28,7 @@
#include "projectexplorer_export.h"
#include "kit.h"
+#include "subscription.h"
#include <coreplugin/id.h>
#include <coreplugin/idocument.h>
@@ -49,6 +50,7 @@ class ContainerNode;
class EditorConfiguration;
class NamedWidget;
class Node;
+class ProjectConfiguration;
class ProjectImporter;
class ProjectNode;
class ProjectPrivate;
@@ -85,7 +87,8 @@ public:
enum ModelRoles {
// Absolute file path
FilePathRole = QFileSystemModel::FilePathRole,
- EnabledRole
+ EnabledRole,
+ isParsingRole
};
Project(const QString &mimeType, const Utils::FileName &fileName,
@@ -163,6 +166,27 @@ public:
void setup(QList<const BuildInfo *> infoList);
Utils::MacroExpander *macroExpander() const;
+ bool isParsing() const;
+ bool hasParsingData() const;
+
+ template<typename S, typename R, typename T>
+ void subscribeSignal(void (S::*sig)(), R*recv, T (R::*sl)()) {
+ new Internal::ProjectSubscription([sig, recv, sl, this](ProjectConfiguration *pc) {
+ if (S* sender = qobject_cast<S*>(pc))
+ return connect(sender, sig, recv, sl);
+ return QMetaObject::Connection();
+ }, recv, this);
+ }
+
+ template<typename S, typename R, typename T>
+ void subscribeSignal(void (S::*sig)(), R*recv, T sl) {
+ new Internal::ProjectSubscription([sig, recv, sl, this](ProjectConfiguration *pc) {
+ if (S* sender = qobject_cast<S*>(pc))
+ return connect(sender, sig, recv, sl);
+ return QMetaObject::Connection();
+ }, recv, this);
+ }
+
signals:
void displayNameChanged();
void fileListChanged();
@@ -170,27 +194,38 @@ signals:
// Note: activeTarget can be 0 (if no targets are defined).
void activeTargetChanged(ProjectExplorer::Target *target);
+ void aboutToRemoveProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
+ void removedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
+ void addedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
+
+ // *ANY* active project configuration changed somewhere in the tree. This might not be
+ // the one that would get started right now, since some part of the tree in between might
+ // not be active.
+ void activeProjectConfigurationChanged(ProjectExplorer::ProjectConfiguration *pc);
+
void aboutToRemoveTarget(ProjectExplorer::Target *target);
void removedTarget(ProjectExplorer::Target *target);
void addedTarget(ProjectExplorer::Target *target);
- void environmentChanged();
- void buildConfigurationEnabledChanged();
-
- void buildDirectoryChanged();
-
void settingsLoaded();
void aboutToSaveSettings();
void projectContextUpdated();
void projectLanguagesUpdated();
- void parsingFinished();
+ void parsingStarted();
+ void parsingFinished(bool success);
protected:
virtual RestoreResult fromMap(const QVariantMap &map, QString *errorMessage);
virtual bool setupTarget(Target *t);
+ // Helper methods to manage parsing state and signalling
+ // Call in GUI thread before the actual parsing starts
+ void emitParsingStarted();
+ // Call in GUI thread right after the actual parsing is done
+ void emitParsingFinished(bool success);
+
void setDisplayName(const QString &name);
void setRequiredKitPredicate(const Kit::Predicate &predicate);
void setPreferredKitPredicate(const Kit::Predicate &predicate);
@@ -205,10 +240,6 @@ protected:
virtual void projectLoaded(); // Called when the project is fully loaded.
private:
- void changeEnvironment();
- void changeBuildConfigurationEnabled();
- void onBuildDirectoryChanged();
-
void setActiveTarget(Target *target);
ProjectPrivate *d;
diff --git a/src/plugins/projectexplorer/projectconfiguration.cpp b/src/plugins/projectexplorer/projectconfiguration.cpp
index 2958bb12ed6..0362c747c95 100644
--- a/src/plugins/projectexplorer/projectconfiguration.cpp
+++ b/src/plugins/projectexplorer/projectconfiguration.cpp
@@ -31,16 +31,21 @@ const char CONFIGURATION_ID_KEY[] = "ProjectExplorer.ProjectConfiguration.Id";
const char DISPLAY_NAME_KEY[] = "ProjectExplorer.ProjectConfiguration.DisplayName";
const char DEFAULT_DISPLAY_NAME_KEY[] = "ProjectExplorer.ProjectConfiguration.DefaultDisplayName";
-ProjectConfiguration::ProjectConfiguration(QObject *parent, Core::Id id) : QObject(parent),
- m_id(id)
-{ setObjectName(id.toString()); }
+ProjectConfiguration::ProjectConfiguration(QObject *parent)
+ : QObject(parent)
+{}
-ProjectConfiguration::ProjectConfiguration(QObject *parent, const ProjectConfiguration *source) :
- QObject(parent),
- m_id(source->m_id),
- m_defaultDisplayName(source->m_defaultDisplayName)
+void ProjectConfiguration::initialize(Core::Id id)
+{
+ m_id = id;
+ setObjectName(id.toString());
+}
+
+void ProjectConfiguration::copyFrom(const ProjectConfiguration *source)
{
Q_ASSERT(source);
+ m_id = source->m_id;
+ m_defaultDisplayName = source->m_defaultDisplayName;
m_displayName = tr("Clone of %1").arg(source->displayName());
}
@@ -123,3 +128,26 @@ QString ProjectExplorer::displayNameFromMap(const QVariantMap &map)
{
return map.value(QLatin1String(DISPLAY_NAME_KEY), QString()).toString();
}
+
+bool StatefulProjectConfiguration::isEnabled() const
+{
+ return m_isEnabled;
+}
+
+StatefulProjectConfiguration::StatefulProjectConfiguration(QObject *parent) :
+ ProjectConfiguration(parent)
+{ }
+
+void StatefulProjectConfiguration::copyFrom(const StatefulProjectConfiguration *source)
+{
+ ProjectConfiguration::copyFrom(source);
+ m_isEnabled = source->m_isEnabled;
+}
+
+void StatefulProjectConfiguration::setEnabled(bool enabled)
+{
+ if (enabled == m_isEnabled)
+ return;
+ m_isEnabled = enabled;
+ emit enabledChanged();
+}
diff --git a/src/plugins/projectexplorer/projectconfiguration.h b/src/plugins/projectexplorer/projectconfiguration.h
index ad3f2ca7976..38fe375e028 100644
--- a/src/plugins/projectexplorer/projectconfiguration.h
+++ b/src/plugins/projectexplorer/projectconfiguration.h
@@ -65,13 +65,18 @@ public:
Utils::MacroExpander *macroExpander() { return &m_macroExpander; }
const Utils::MacroExpander *macroExpander() const { return &m_macroExpander; }
+ virtual Project *project() const = 0;
+
+ virtual bool isActive() const = 0;
+
signals:
void displayNameChanged();
void toolTipChanged();
protected:
- ProjectConfiguration(QObject *parent, Core::Id id);
- ProjectConfiguration(QObject *parent, const ProjectConfiguration *source);
+ ProjectConfiguration(QObject *parent);
+ void initialize(Core::Id id);
+ void copyFrom(const ProjectConfiguration *source);
private:
Core::Id m_id;
@@ -81,6 +86,30 @@ private:
Utils::MacroExpander m_macroExpander;
};
+class PROJECTEXPLORER_EXPORT StatefulProjectConfiguration : public ProjectConfiguration
+{
+ Q_OBJECT
+
+public:
+ StatefulProjectConfiguration() = default;
+
+ bool isEnabled() const;
+
+ virtual QString disabledReason() const = 0;
+
+signals:
+ void enabledChanged();
+
+protected:
+ StatefulProjectConfiguration(QObject *parent);
+ void copyFrom(const StatefulProjectConfiguration *source);
+
+ void setEnabled(bool enabled);
+
+private:
+ bool m_isEnabled = false;
+};
+
// helper functions:
PROJECTEXPLORER_EXPORT Core::Id idFromMap(const QVariantMap &map);
PROJECTEXPLORER_EXPORT QString displayNameFromMap(const QVariantMap &map);
diff --git a/src/plugins/projectexplorer/projectconfigurationmodel.cpp b/src/plugins/projectexplorer/projectconfigurationmodel.cpp
new file mode 100644
index 00000000000..f27f1bf55b3
--- /dev/null
+++ b/src/plugins/projectexplorer/projectconfigurationmodel.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "projectconfigurationmodel.h"
+
+#include "buildconfiguration.h"
+#include "deployconfiguration.h"
+#include "runconfiguration.h"
+#include "target.h"
+#include "projectconfiguration.h"
+
+#include <utils/algorithm.h>
+
+using namespace ProjectExplorer;
+
+/*!
+ \class ProjectExplorer::BuildConfigurationModel
+ \brief The BuildConfigurationModel class is a model to represent the build
+ configurations of a target.
+
+ To be used in the dropdown lists of comboboxes.
+ Automatically adjusts itself to added and removed BuildConfigurations.
+ Very similar to the Run Configuration Model.
+
+ TODO might it possible to share code without making the code a complete mess.
+*/
+
+namespace {
+
+const auto ComparisonOperator =
+ [](const ProjectConfiguration *a, const ProjectConfiguration *b) {
+ return a->displayName() < b->displayName();
+ };
+
+} // namespace
+
+ProjectConfigurationModel::ProjectConfigurationModel(Target *target, FilterFunction filter,
+ QObject *parent) :
+ QAbstractListModel(parent),
+ m_target(target),
+ m_filter(filter)
+{
+ m_projectConfigurations = Utils::filtered(m_target->projectConfigurations(), m_filter);
+ Utils::sort(m_projectConfigurations, ComparisonOperator);
+
+ connect(target, &Target::addedProjectConfiguration,
+ this, &ProjectConfigurationModel::addedProjectConfiguration);
+ connect(target, &Target::removedProjectConfiguration,
+ this, &ProjectConfigurationModel::removedProjectConfiguration);
+
+ foreach (ProjectConfiguration *pc, m_projectConfigurations)
+ connect(pc, &ProjectConfiguration::displayNameChanged,
+ this, &ProjectConfigurationModel::displayNameChanged);
+}
+
+int ProjectConfigurationModel::rowCount(const QModelIndex &parent) const
+{
+ return parent.isValid() ? 0 : m_projectConfigurations.size();
+}
+
+int ProjectConfigurationModel::columnCount(const QModelIndex &parent) const
+{
+ return parent.isValid() ? 0 : 1;
+}
+
+void ProjectConfigurationModel::displayNameChanged()
+{
+ auto pc = qobject_cast<ProjectConfiguration *>(sender());
+ if (!pc)
+ return;
+
+ // Find the old position
+ int oldPos = m_projectConfigurations.indexOf(pc);
+ if (oldPos < 0)
+ return;
+
+ if (oldPos >= 1 && ComparisonOperator(m_projectConfigurations.at(oldPos), m_projectConfigurations.at(oldPos - 1))) {
+ // We need to move up
+ int newPos = oldPos - 1;
+ while (newPos >= 0 && ComparisonOperator(m_projectConfigurations.at(oldPos), m_projectConfigurations.at(newPos))) {
+ --newPos;
+ }
+ ++newPos;
+
+ beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
+ m_projectConfigurations.insert(newPos, pc);
+ m_projectConfigurations.removeAt(oldPos + 1);
+ endMoveRows();
+ // Not only did we move, we also changed...
+ emit dataChanged(index(newPos, 0), index(newPos,0));
+ } else if (oldPos < m_projectConfigurations.size() - 1
+ && ComparisonOperator(m_projectConfigurations.at(oldPos + 1), m_projectConfigurations.at(oldPos))) {
+ // We need to move down
+ int newPos = oldPos + 1;
+ while (newPos < m_projectConfigurations.size()
+ && ComparisonOperator(m_projectConfigurations.at(newPos), m_projectConfigurations.at(oldPos))) {
+ ++newPos;
+ }
+ beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
+ m_projectConfigurations.insert(newPos, pc);
+ m_projectConfigurations.removeAt(oldPos);
+ endMoveRows();
+
+ // We need to subtract one since removing at the old place moves the newIndex down
+ emit dataChanged(index(newPos - 1, 0), index(newPos - 1, 0));
+ } else {
+ emit dataChanged(index(oldPos, 0), index(oldPos, 0));
+ }
+}
+
+QVariant ProjectConfigurationModel::data(const QModelIndex &index, int role) const
+{
+ if (role == Qt::DisplayRole) {
+ const int row = index.row();
+ if (row < m_projectConfigurations.size())
+ return m_projectConfigurations.at(row)->displayName();
+ }
+
+ return QVariant();
+}
+
+ProjectConfiguration *ProjectConfigurationModel::projectConfigurationAt(int i)
+{
+ if (i > m_projectConfigurations.size() || i < 0)
+ return nullptr;
+ return m_projectConfigurations.at(i);
+}
+
+ProjectConfiguration *ProjectConfigurationModel::projectConfigurationFor(const QModelIndex &idx)
+{
+ if (idx.row() > m_projectConfigurations.size() || idx.row() < 0)
+ return nullptr;
+ return m_projectConfigurations.at(idx.row());
+}
+
+QModelIndex ProjectConfigurationModel::indexFor(ProjectConfiguration *pc)
+{
+ int idx = m_projectConfigurations.indexOf(pc);
+ if (idx == -1)
+ return QModelIndex();
+ return index(idx, 0);
+}
+
+void ProjectConfigurationModel::addedProjectConfiguration(ProjectConfiguration *pc)
+{
+ if (!m_filter(pc))
+ return;
+
+ // Find the right place to insert
+ int i = 0;
+ for (; i < m_projectConfigurations.size(); ++i) {
+ if (ComparisonOperator(pc, m_projectConfigurations.at(i)))
+ break;
+ }
+
+ beginInsertRows(QModelIndex(), i, i);
+ m_projectConfigurations.insert(i, pc);
+ endInsertRows();
+
+ connect(pc, &ProjectConfiguration::displayNameChanged,
+ this, &ProjectConfigurationModel::displayNameChanged);
+}
+
+void ProjectConfigurationModel::removedProjectConfiguration(ProjectConfiguration *pc)
+{
+ int i = m_projectConfigurations.indexOf(pc);
+ if (i < 0)
+ return;
+ beginRemoveRows(QModelIndex(), i, i);
+ m_projectConfigurations.removeAt(i);
+ endRemoveRows();
+}
+
+BuildConfigurationModel::BuildConfigurationModel(Target *t, QObject *parent) :
+ ProjectConfigurationModel(t,
+ [](const ProjectConfiguration *pc) {
+ return qobject_cast<const BuildConfiguration *>(pc) != nullptr;
+ },
+ parent)
+{ }
+
+DeployConfigurationModel::DeployConfigurationModel(Target *t, QObject *parent) :
+ ProjectConfigurationModel(t,
+ [](const ProjectConfiguration *pc) {
+ return qobject_cast<const DeployConfiguration *>(pc) != nullptr;
+ },
+ parent)
+{ }
+
+RunConfigurationModel::RunConfigurationModel(Target *t, QObject *parent) :
+ ProjectConfigurationModel(t,
+ [](const ProjectConfiguration *pc) {
+ return qobject_cast<const RunConfiguration *>(pc) != nullptr;
+ },
+ parent)
+{ }
diff --git a/src/plugins/projectexplorer/runconfigurationmodel.h b/src/plugins/projectexplorer/projectconfigurationmodel.h
index 8af2566b950..adc1a004029 100644
--- a/src/plugins/projectexplorer/runconfigurationmodel.h
+++ b/src/plugins/projectexplorer/projectconfigurationmodel.h
@@ -27,32 +27,56 @@
#include <QAbstractItemModel>
+#include <functional>
+
namespace ProjectExplorer {
class Target;
-class RunConfiguration;
+class ProjectConfiguration;
// Documentation inside.
-class RunConfigurationModel : public QAbstractListModel
+class ProjectConfigurationModel : public QAbstractListModel
{
Q_OBJECT
-
public:
- explicit RunConfigurationModel(Target *target, QObject *parent = nullptr);
+ using FilterFunction = std::function<bool(const ProjectConfiguration *)>;
+
+ explicit ProjectConfigurationModel(Target *target, FilterFunction filter,
+ QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- RunConfiguration *runConfigurationAt(int i);
- RunConfiguration *runConfigurationFor(const QModelIndex &idx);
- QModelIndex indexFor(RunConfiguration *rc);
+ ProjectConfiguration *projectConfigurationAt(int i);
+ ProjectConfiguration *projectConfigurationFor(const QModelIndex &idx);
+ QModelIndex indexFor(ProjectConfiguration *pc);
private:
- void addedRunConfiguration(ProjectExplorer::RunConfiguration*);
- void removedRunConfiguration(ProjectExplorer::RunConfiguration*);
+ void addedProjectConfiguration(ProjectConfiguration *pc);
+ void removedProjectConfiguration(ProjectConfiguration *pc);
void displayNameChanged();
+
Target *m_target;
- QList<RunConfiguration *> m_runConfigurations;
+ FilterFunction m_filter;
+ QList<ProjectConfiguration *> m_projectConfigurations;
+};
+
+class BuildConfigurationModel : public ProjectConfigurationModel
+{
+public:
+ explicit BuildConfigurationModel(Target *t, QObject *parent = nullptr);
+};
+
+class DeployConfigurationModel : public ProjectConfigurationModel
+{
+public:
+ explicit DeployConfigurationModel(Target *t, QObject *parent = nullptr);
+};
+
+class RunConfigurationModel : public ProjectConfigurationModel
+{
+public:
+ explicit RunConfigurationModel(Target *t, QObject *parent = nullptr);
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index acd546e09b9..2b27328ddbf 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -94,6 +94,7 @@
#include "projecttree.h"
#include "projectwelcomepage.h"
+#include <app/app_version.h>
#include <extensionsystem/pluginspec.h>
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
@@ -235,6 +236,9 @@ const char G_BUILD_RUN[] = "ProjectExplorer.Group.Run";
const char G_BUILD_CANCEL[] = "ProjectExplorer.Group.BuildCancel";
const char RUNMENUCONTEXTMENU[] = "Project.RunMenu";
+const char FOLDER_OPEN_LOCATIONS_CONTEXT_MENU[] = "Project.F.OpenLocation.CtxMenu";
+const char PROJECT_OPEN_LOCATIONS_CONTEXT_MENU[] = "Project.P.OpenLocation.CtxMenu";
+const char SUBPROJECT_OPEN_LOCATIONS_CONTEXT_MENU[] = "Project.S.OpenLocation.CtxMenu";
} // namespace Constants
@@ -275,6 +279,7 @@ public:
void deploy(QList<Project *>);
int queue(QList<Project *>, QList<Id> stepIds);
void updateContextMenuActions();
+ void updateLocationSubMenus();
void executeRunConfiguration(RunConfiguration *, Core::Id mode);
QPair<bool, QString> buildSettingsEnabledForSession();
QPair<bool, QString> buildSettingsEnabled(const Project *pro);
@@ -611,7 +616,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
addAutoReleasedObject(new ConfigTaskHandler(Task::compilerMissingTask(),
Constants::KITS_SETTINGS_PAGE_ID));
- ICore::addPreCloseListener([this]() -> bool { return coreAboutToClose(); });
+ ICore::addPreCloseListener([]() -> bool { return coreAboutToClose(); });
dd->m_outputPane = new AppOutputPane;
addAutoReleasedObject(dd->m_outputPane);
@@ -655,7 +660,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
const IDevice::ConstPtr device = runnable.as<StandardRunnable>().device;
if (device && device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
return true;
- Target *target = runConfiguration ? runConfiguration->target() : nullptr;
+ Target *target = runConfiguration->target();
Kit *kit = target ? target->kit() : nullptr;
return DeviceTypeKitInformation::deviceTypeId(kit) == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE;
};
@@ -686,6 +691,22 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
ActionContainer *menubar =
ActionManager::actionContainer(Core::Constants::MENU_BAR);
+ // context menu sub menus:
+ ActionContainer *folderOpenLocationCtxMenu =
+ ActionManager::createMenu(Constants::FOLDER_OPEN_LOCATIONS_CONTEXT_MENU);
+ folderOpenLocationCtxMenu->menu()->setTitle(tr("Open..."));
+ folderOpenLocationCtxMenu->setOnAllDisabledBehavior(ActionContainer::Show);
+
+ ActionContainer *subProjectOpenLocationCtxMenu =
+ ActionManager::createMenu(Constants::SUBPROJECT_OPEN_LOCATIONS_CONTEXT_MENU);
+ subProjectOpenLocationCtxMenu->menu()->setTitle(tr("Open..."));
+ subProjectOpenLocationCtxMenu->setOnAllDisabledBehavior(ActionContainer::Show);
+
+ ActionContainer *projectOpenLocationCtxMenu =
+ ActionManager::createMenu(Constants::PROJECT_OPEN_LOCATIONS_CONTEXT_MENU);
+ projectOpenLocationCtxMenu->menu()->setTitle(tr("Open..."));
+ projectOpenLocationCtxMenu->setOnAllDisabledBehavior(ActionContainer::Show);
+
// build menu
ActionContainer *mbuild =
ActionManager::createMenu(Constants::M_BUILDPROJECT);
@@ -721,6 +742,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
msessionContextMenu->appendGroup(Constants::G_PROJECT_TREE);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_FIRST);
+ mprojectContextMenu->appendGroup(Constants::G_FOLDER_LOCATIONS);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_BUILD);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_RUN);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_REBUILD);
@@ -728,22 +750,33 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
mprojectContextMenu->appendGroup(Constants::G_PROJECT_LAST);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_TREE);
+ mprojectContextMenu->addMenu(projectOpenLocationCtxMenu, Constants::G_FOLDER_LOCATIONS);
+ connect(mprojectContextMenu->menu(), &QMenu::aboutToShow,
+ dd, &ProjectExplorerPluginPrivate::updateLocationSubMenus);
+
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FIRST);
+ msubProjectContextMenu->appendGroup(Constants::G_FOLDER_LOCATIONS);
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_BUILD);
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_RUN);
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FILES);
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_LAST);
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_TREE);
+ msubProjectContextMenu->addMenu(subProjectOpenLocationCtxMenu, Constants::G_FOLDER_LOCATIONS);
+ connect(msubProjectContextMenu->menu(), &QMenu::aboutToShow,
+ dd, &ProjectExplorerPluginPrivate::updateLocationSubMenus);
+
ActionContainer *runMenu = ActionManager::createMenu(Constants::RUNMENUCONTEXTMENU);
runMenu->setOnAllDisabledBehavior(ActionContainer::Hide);
const QIcon runSideBarIcon = Utils::Icon::sideBarIcon(Icons::RUN, Icons::RUN_FLAT);
const QIcon runIcon = Utils::Icon::combinedIcon({Utils::Icons::RUN_SMALL.icon(),
runSideBarIcon});
+
runMenu->menu()->setIcon(runIcon);
runMenu->menu()->setTitle(tr("Run"));
msubProjectContextMenu->addMenu(runMenu, ProjectExplorer::Constants::G_PROJECT_RUN);
+ mfolderContextMenu->appendGroup(Constants::G_FOLDER_LOCATIONS);
mfolderContextMenu->appendGroup(Constants::G_FOLDER_FILES);
mfolderContextMenu->appendGroup(Constants::G_FOLDER_OTHER);
mfolderContextMenu->appendGroup(Constants::G_FOLDER_CONFIG);
@@ -760,6 +793,10 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
dd->m_openWithMenu = openWith->menu();
dd->m_openWithMenu->setTitle(tr("Open With"));
+ mfolderContextMenu->addMenu(folderOpenLocationCtxMenu, Constants::G_FOLDER_LOCATIONS);
+ connect(mfolderContextMenu->menu(), &QMenu::aboutToShow,
+ dd, &ProjectExplorerPluginPrivate::updateLocationSubMenus);
+
//
// Separators
//
@@ -1156,7 +1193,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
connect(ICore::instance(), &ICore::saveSettingsRequested,
dd, &ProjectExplorerPluginPrivate::savePersistentSettings);
- connect(EditorManager::instance(), &EditorManager::autoSaved, this, [this] {
+ connect(EditorManager::instance(), &EditorManager::autoSaved, this, [] {
if (!dd->m_shuttingDown && !SessionManager::loadingSession())
SessionManager::save();
});
@@ -1205,7 +1242,9 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
dd->m_projectExplorerSettings.prompToStopRunControl =
s->value(QLatin1String("ProjectExplorer/Settings/PromptToStopRunControl"), false).toBool();
dd->m_projectExplorerSettings.maxAppOutputLines =
- s->value(QLatin1String("ProjectExplorer/Settings/MaxAppOutputLines"), 100000).toInt();
+ s->value(QLatin1String("ProjectExplorer/Settings/MaxAppOutputLines"), Core::Constants::DEFAULT_MAX_LINE_COUNT).toInt();
+ dd->m_projectExplorerSettings.maxBuildOutputLines =
+ s->value(QLatin1String("ProjectExplorer/Settings/MaxBuildOutputLines"), Core::Constants::DEFAULT_MAX_LINE_COUNT).toInt();
dd->m_projectExplorerSettings.environmentId =
QUuid(s->value(QLatin1String("ProjectExplorer/Settings/EnvironmentId")).toByteArray());
if (dd->m_projectExplorerSettings.environmentId.isNull())
@@ -1228,79 +1267,78 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
dd, &ProjectExplorerPlugin::openNewProjectDialog);
connect(dd->m_loadAction, &QAction::triggered,
dd, &ProjectExplorerPluginPrivate::loadAction);
- connect(dd->m_buildProjectOnlyAction, &QAction::triggered, dd, [this] {
+ connect(dd->m_buildProjectOnlyAction, &QAction::triggered, dd, [] {
dd->queue({ SessionManager::startupProject() }, { Id(Constants::BUILDSTEPS_BUILD) });
});
- connect(dd->m_buildAction, &QAction::triggered,
- dd, [this] {
+ connect(dd->m_buildAction, &QAction::triggered, dd, [] {
dd->queue(SessionManager::projectOrder(SessionManager::startupProject()),
{ Id(Constants::BUILDSTEPS_BUILD) });
});
- connect(dd->m_buildActionContextMenu, &QAction::triggered, dd, [this] {
+ connect(dd->m_buildActionContextMenu, &QAction::triggered, dd, [] {
dd->queue({ ProjectTree::currentProject() }, { Id(Constants::BUILDSTEPS_BUILD) });
});
- connect(dd->m_buildDependenciesActionContextMenu, &QAction::triggered, dd, [this] {
+ connect(dd->m_buildDependenciesActionContextMenu, &QAction::triggered, dd, [] {
dd->queue(SessionManager::projectOrder(ProjectTree::currentProject()),
{ Id(Constants::BUILDSTEPS_BUILD) });
});
- connect(dd->m_buildSessionAction, &QAction::triggered, dd, [this] {
+ connect(dd->m_buildSessionAction, &QAction::triggered, dd, [] {
dd->queue(SessionManager::projectOrder(), { Id(Constants::BUILDSTEPS_BUILD) });
});
- connect(dd->m_rebuildProjectOnlyAction, &QAction::triggered, dd, [this] {
+ connect(dd->m_rebuildProjectOnlyAction, &QAction::triggered, dd, [] {
dd->queue({ SessionManager::startupProject() },
{ Id(Constants::BUILDSTEPS_CLEAN), Id(Constants::BUILDSTEPS_BUILD) });
});
- connect(dd->m_rebuildAction, &QAction::triggered, dd, [this] {
+ connect(dd->m_rebuildAction, &QAction::triggered, dd, [] {
dd->queue(SessionManager::projectOrder(SessionManager::startupProject()),
{ Id(Constants::BUILDSTEPS_CLEAN), Id(Constants::BUILDSTEPS_BUILD) });
});
- connect(dd->m_rebuildActionContextMenu, &QAction::triggered, dd, [this] {
+ connect(dd->m_rebuildActionContextMenu, &QAction::triggered, dd, [] {
dd->queue({ ProjectTree::currentProject() },
{ Id(Constants::BUILDSTEPS_CLEAN), Id(Constants::BUILDSTEPS_BUILD) });
});
- connect(dd->m_rebuildDependenciesActionContextMenu, &QAction::triggered, dd, [this] {
+ connect(dd->m_rebuildDependenciesActionContextMenu, &QAction::triggered, dd, [] {
dd->queue(SessionManager::projectOrder(ProjectTree::currentProject()),
{ Id(Constants::BUILDSTEPS_CLEAN), Id(Constants::BUILDSTEPS_BUILD) });
});
- connect(dd->m_rebuildSessionAction, &QAction::triggered, dd, [this] {
+ connect(dd->m_rebuildSessionAction, &QAction::triggered, dd, [] {
dd->queue(SessionManager::projectOrder(),
{ Id(Constants::BUILDSTEPS_CLEAN), Id(Constants::BUILDSTEPS_BUILD) });
});
- connect(dd->m_deployProjectOnlyAction, &QAction::triggered, dd, [this] {
+ connect(dd->m_deployProjectOnlyAction, &QAction::triggered, dd, [] {
dd->deploy({ SessionManager::startupProject() });
});
- connect(dd->m_deployAction, &QAction::triggered, dd, [this] {
+ connect(dd->m_deployAction, &QAction::triggered, dd, [] {
dd->deploy(SessionManager::projectOrder(SessionManager::startupProject()));
});
- connect(dd->m_deployActionContextMenu, &QAction::triggered, dd, [this] {
+ connect(dd->m_deployActionContextMenu, &QAction::triggered, dd, [] {
dd->deploy({ ProjectTree::currentProject() });
});
- connect(dd->m_deploySessionAction, &QAction::triggered, dd, [this] {
+ connect(dd->m_deploySessionAction, &QAction::triggered, dd, [] {
dd->deploy(SessionManager::projectOrder());
});
- connect(dd->m_cleanProjectOnlyAction, &QAction::triggered, dd, [this] {
+ connect(dd->m_cleanProjectOnlyAction, &QAction::triggered, dd, [] {
dd->queue({ SessionManager::startupProject() }, { Id(Constants::BUILDSTEPS_CLEAN) });
});
- connect(dd->m_cleanAction, &QAction::triggered, dd, [this] {
+ connect(dd->m_cleanAction, &QAction::triggered, dd, [] {
dd->queue(SessionManager::projectOrder(SessionManager::startupProject()),
{ Id(Constants::BUILDSTEPS_CLEAN) });
});
- connect(dd->m_cleanActionContextMenu, &QAction::triggered, dd, [this] {
+ connect(dd->m_cleanActionContextMenu, &QAction::triggered, dd, [] {
dd->queue({ ProjectTree::currentProject() }, { Id(Constants::BUILDSTEPS_CLEAN) });
});
- connect(dd->m_cleanDependenciesActionContextMenu, &QAction::triggered, dd, [this] {
+ connect(dd->m_cleanDependenciesActionContextMenu, &QAction::triggered, dd, [] {
dd->queue(SessionManager::projectOrder(ProjectTree::currentProject()),
{ Id(Constants::BUILDSTEPS_CLEAN) });
});
- connect(dd->m_cleanSessionAction, &QAction::triggered, dd, [this] {
+ connect(dd->m_cleanSessionAction, &QAction::triggered, dd, [] {
dd->queue(SessionManager::projectOrder(), { Id(Constants::BUILDSTEPS_CLEAN) });
});
connect(dd->m_runAction, &QAction::triggered,
- dd, [this]() { m_instance->runStartupProject(Constants::NORMAL_RUN_MODE); });
+ dd, []() { m_instance->runStartupProject(Constants::NORMAL_RUN_MODE); });
connect(dd->m_runActionContextMenu, &QAction::triggered,
dd, &ProjectExplorerPluginPrivate::runProjectContextMenu);
connect(dd->m_runWithoutDeployAction, &QAction::triggered,
- dd, [this]() { m_instance->runStartupProject(Constants::NORMAL_RUN_MODE, true); });
+ dd, []() { m_instance->runStartupProject(Constants::NORMAL_RUN_MODE, true); });
connect(dd->m_cancelBuildAction, &QAction::triggered,
BuildManager::instance(), &BuildManager::cancel);
connect(dd->m_unloadAction, &QAction::triggered,
@@ -1358,7 +1396,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
Utils::MacroExpander *expander = Utils::globalMacroExpander();
expander->registerFileVariables(Constants::VAR_CURRENTPROJECT_PREFIX,
tr("Current project's main file."),
- [this]() -> QString {
+ []() -> QString {
Utils::FileName projectFilePath;
if (Project *project = ProjectTree::currentProject())
projectFilePath = project->projectFilePath();
@@ -1374,7 +1412,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
expander->registerVariable(Constants::VAR_CURRENTPROJECT_NAME,
tr("The name of the current project."),
- [this]() -> QString {
+ []() -> QString {
Project *project = ProjectTree::currentProject();
return project ? project->displayName() : QString();
});
@@ -1443,7 +1481,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
expander->registerVariable(Constants::VAR_CURRENTRUN_NAME,
tr("The currently active run configuration's name."),
- [this]() -> QString {
+ []() -> QString {
if (Target *target = activeTarget()) {
if (RunConfiguration *rc = target->activeRunConfiguration())
return rc->displayName();
@@ -1453,7 +1491,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
expander->registerFileVariables("CurrentRun:Executable",
tr("The currently active run configuration's executable (if applicable)."),
- [this]() -> QString {
+ []() -> QString {
if (Target *target = activeTarget()) {
if (RunConfiguration *rc = target->activeRunConfiguration()) {
if (rc->runnable().is<StandardRunnable>())
@@ -1575,7 +1613,7 @@ void ProjectExplorerPlugin::extensionsInitialized()
QStringList filterStrings;
auto factory = new IDocumentFactory;
- factory->setOpener([this](QString fileName) -> IDocument* {
+ factory->setOpener([](QString fileName) -> IDocument* {
const QFileInfo fi(fileName);
if (fi.isDir())
fileName = FolderNavigationWidget::projectFilesInDirectory(fi.absoluteFilePath()).value(0, fileName);
@@ -1721,6 +1759,7 @@ void ProjectExplorerPluginPrivate::savePersistentSettings()
s->setValue(QLatin1String("ProjectExplorer/Settings/AutoRestoreLastSession"), dd->m_projectExplorerSettings.autorestoreLastSession);
s->setValue(QLatin1String("ProjectExplorer/Settings/PromptToStopRunControl"), dd->m_projectExplorerSettings.prompToStopRunControl);
s->setValue(QLatin1String("ProjectExplorer/Settings/MaxAppOutputLines"), dd->m_projectExplorerSettings.maxAppOutputLines);
+ s->setValue(QLatin1String("ProjectExplorer/Settings/MaxBuildOutputLines"), dd->m_projectExplorerSettings.maxBuildOutputLines);
s->setValue(QLatin1String("ProjectExplorer/Settings/EnvironmentId"), dd->m_projectExplorerSettings.environmentId.toByteArray());
s->setValue(QLatin1String("ProjectExplorer/Settings/StopBeforeBuild"), dd->m_projectExplorerSettings.stopBeforeBuild);
}
@@ -2118,11 +2157,11 @@ QList<QPair<QString, QString> > ProjectExplorerPluginPrivate::recentProjects() c
});
}
-static QString pathOrDirectoryFor(Node *node, bool dir)
+static QString pathOrDirectoryFor(const Node *node, bool dir)
{
Utils::FileName path = node->filePath();
QString location;
- FolderNode *folder = node->asFolderNode();
+ const FolderNode *folder = node->asFolderNode();
if (node->nodeType() == NodeType::VirtualFolder && folder) {
// Virtual Folder case
// If there are files directly below or no subfolders, take the folder path
@@ -2156,12 +2195,12 @@ static QString pathOrDirectoryFor(Node *node, bool dir)
return location;
}
-static QString pathFor(Node *node)
+static QString pathFor(const Node *node)
{
return pathOrDirectoryFor(node, false);
}
-static QString directoryFor(Node *node)
+static QString directoryFor(const Node *node)
{
return pathOrDirectoryFor(node, true);
}
@@ -2412,8 +2451,8 @@ void ProjectExplorerPlugin::buildProject(Project *p)
void ProjectExplorerPluginPrivate::runProjectContextMenu()
{
- Node *node = ProjectTree::currentNode();
- ProjectNode *projectNode = node ? node->asProjectNode() : nullptr;
+ const Node *node = ProjectTree::findCurrentNode();
+ const ProjectNode *projectNode = node ? node->asProjectNode() : nullptr;
if (projectNode == ProjectTree::currentProject()->rootProjectNode() || !projectNode) {
m_instance->runProject(ProjectTree::currentProject(), Constants::NORMAL_RUN_MODE);
} else {
@@ -2506,9 +2545,10 @@ bool ProjectExplorerPlugin::coreAboutToClose()
QPushButton *closeAnyway = box.addButton(tr("Cancel Build && Close"), QMessageBox::AcceptRole);
QPushButton *cancelClose = box.addButton(tr("Do Not Close"), QMessageBox::RejectRole);
box.setDefaultButton(cancelClose);
- box.setWindowTitle(tr("Close Qt Creator?"));
+ box.setWindowTitle(tr("Close %1?").arg(Core::Constants::IDE_DISPLAY_NAME));
box.setText(tr("A project is currently being built."));
- box.setInformativeText(tr("Do you want to cancel the build process and close Qt Creator anyway?"));
+ box.setInformativeText(tr("Do you want to cancel the build process and close %1 anyway?")
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
box.exec();
if (box.clickedButton() != closeAnyway)
return false;
@@ -2588,17 +2628,17 @@ void ProjectExplorerPluginPrivate::projectAdded(Project *pro)
if (m_projectsMode)
m_projectsMode->setEnabled(true);
// more specific action en and disabling ?
- connect(pro, &Project::buildConfigurationEnabledChanged,
- this, &ProjectExplorerPluginPrivate::updateActions);
+ pro->subscribeSignal(&BuildConfiguration::enabledChanged, this, [this]() {
+ if (static_cast<BuildConfiguration *>(sender())->isActive())
+ updateActions();
+ });
}
-void ProjectExplorerPluginPrivate::projectRemoved(Project * pro)
+void ProjectExplorerPluginPrivate::projectRemoved(Project *pro)
{
+ Q_UNUSED(pro);
if (m_projectsMode)
m_projectsMode->setEnabled(SessionManager::hasProjects());
- // more specific action en and disabling ?
- disconnect(pro, &Project::buildConfigurationEnabledChanged,
- this, &ProjectExplorerPluginPrivate::updateActions);
}
void ProjectExplorerPluginPrivate::projectDisplayNameChanged(Project *pro)
@@ -2949,14 +2989,14 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
runMenu->menu()->clear();
runMenu->menu()->menuAction()->setVisible(false);
- Node *currentNode = ProjectTree::currentNode();
+ const Node *currentNode = ProjectTree::findCurrentNode();
if (currentNode && currentNode->managingProject()) {
ProjectNode *pn;
- if (ContainerNode *cn = currentNode->asContainerNode())
+ if (const ContainerNode *cn = currentNode->asContainerNode())
pn = cn->rootProjectNode();
else
- pn = currentNode->asProjectNode();
+ pn = const_cast<ProjectNode*>(currentNode->asProjectNode());
if (pn) {
if (ProjectTree::currentProject() && pn == ProjectTree::currentProject()->rootProjectNode()) {
@@ -3011,7 +3051,7 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
m_removeFileAction->setVisible(!enableDelete || enableRemove);
m_renameFileAction->setEnabled(supports(Rename));
const bool currentNodeIsTextFile = isTextFile(
- ProjectTree::currentNode()->filePath().toString());
+ currentNode->filePath().toString());
m_diffFileAction->setEnabled(isDiffServiceAvailable()
&& currentNodeIsTextFile && TextEditor::TextDocument::currentTextDocument());
@@ -3019,7 +3059,7 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
m_duplicateFileAction->setEnabled(supports(DuplicateFile));
EditorManager::populateOpenWithMenu(m_openWithMenu,
- ProjectTree::currentNode()->filePath().toString());
+ currentNode->filePath().toString());
}
if (supports(HidePathActions)) {
@@ -3043,10 +3083,53 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
}
}
+void ProjectExplorerPluginPrivate::updateLocationSubMenus()
+{
+ static QList<QAction *> actions;
+ qDeleteAll(actions); // This will also remove these actions from the menus!
+ actions.clear();
+
+ ActionContainer *projectMenuContainer
+ = ActionManager::actionContainer(Constants::PROJECT_OPEN_LOCATIONS_CONTEXT_MENU);
+ QMenu *projectMenu = projectMenuContainer->menu();
+ QTC_CHECK(projectMenu->actions().isEmpty());
+
+ ActionContainer *folderMenuContainer
+ = ActionManager::actionContainer(Constants::FOLDER_OPEN_LOCATIONS_CONTEXT_MENU);
+ QMenu *folderMenu = folderMenuContainer->menu();
+ QTC_CHECK(folderMenu->actions().isEmpty());
+
+ const FolderNode *const fn
+ = ProjectTree::findCurrentNode() ? ProjectTree::findCurrentNode()->asFolderNode() : nullptr;
+ const QList<FolderNode::LocationInfo> locations
+ = fn ? fn->locationInfo() : QList<FolderNode::LocationInfo>();
+
+ const bool isVisible = !locations.isEmpty();
+ projectMenu->menuAction()->setVisible(isVisible);
+ folderMenu->menuAction()->setVisible(isVisible);
+
+ if (!isVisible)
+ return;
+
+ for (const FolderNode::LocationInfo &li : locations) {
+ const int line = li.line;
+ const Utils::FileName path = li.path;
+ QAction *action = new QAction(li.displayName, nullptr);
+ connect(action, &QAction::triggered, this, [line, path]() {
+ Core::EditorManager::openEditorAt(path.toString(), line);
+ });
+
+ projectMenu->addAction(action);
+ folderMenu->addAction(action);
+
+ actions.append(action);
+ }
+}
+
void ProjectExplorerPluginPrivate::addNewFile()
{
- QTC_ASSERT(ProjectTree::currentNode(), return);
- Node *currentNode = ProjectTree::currentNode();
+ Node* currentNode = ProjectTree::findCurrentNode();
+ QTC_ASSERT(currentNode, return);
QString location = directoryFor(currentNode);
QVariantMap map;
@@ -3069,8 +3152,8 @@ void ProjectExplorerPluginPrivate::addNewFile()
void ProjectExplorerPluginPrivate::addNewSubproject()
{
- QTC_ASSERT(ProjectTree::currentNode(), return);
- Node *currentNode = ProjectTree::currentNode();
+ Node* currentNode = ProjectTree::findCurrentNode();
+ QTC_ASSERT(currentNode, return);
QString location = directoryFor(currentNode);
if (currentNode->nodeType() == NodeType::Project
@@ -3096,13 +3179,13 @@ void ProjectExplorerPluginPrivate::addNewSubproject()
void ProjectExplorerPluginPrivate::handleAddExistingFiles()
{
- Node *node = ProjectTree::currentNode();
+ Node *node = ProjectTree::findCurrentNode();
FolderNode *folderNode = node ? node->asFolderNode() : nullptr;
QTC_ASSERT(folderNode, return);
QStringList fileNames = QFileDialog::getOpenFileNames(ICore::mainWindow(),
- tr("Add Existing Files"), directoryFor(ProjectTree::currentNode()));
+ tr("Add Existing Files"), directoryFor(node));
if (fileNames.isEmpty())
return;
@@ -3111,12 +3194,12 @@ void ProjectExplorerPluginPrivate::handleAddExistingFiles()
void ProjectExplorerPluginPrivate::addExistingDirectory()
{
- Node *node = ProjectTree::currentNode();
+ Node *node = ProjectTree::findCurrentNode();
FolderNode *folderNode = node ? node->asFolderNode() : nullptr;
QTC_ASSERT(folderNode, return);
- SelectableFilesDialogAddDirectory dialog(Utils::FileName::fromString(directoryFor(ProjectTree::currentNode())),
+ SelectableFilesDialogAddDirectory dialog(Utils::FileName::fromString(directoryFor(node)),
Utils::FileNameList(), ICore::mainWindow());
dialog.setAddFileFilter(folderNode->addFileFilter());
@@ -3152,7 +3235,7 @@ void ProjectExplorerPlugin::addExistingFiles(FolderNode *folderNode, const QStri
void ProjectExplorerPluginPrivate::removeProject()
{
- Node *node = ProjectTree::currentNode();
+ Node *node = ProjectTree::findCurrentNode();
if (!node)
return;
ProjectNode *subProjectNode = node->managingProject();
@@ -3169,31 +3252,35 @@ void ProjectExplorerPluginPrivate::removeProject()
void ProjectExplorerPluginPrivate::openFile()
{
- QTC_ASSERT(ProjectTree::currentNode(), return);
- EditorManager::openEditor(ProjectTree::currentNode()->filePath().toString());
+ const Node *currentNode = ProjectTree::findCurrentNode();
+ QTC_ASSERT(currentNode, return);
+ EditorManager::openEditor(currentNode->filePath().toString());
}
void ProjectExplorerPluginPrivate::searchOnFileSystem()
{
- QTC_ASSERT(ProjectTree::currentNode(), return);
- TextEditor::FindInFiles::findOnFileSystem(pathFor(ProjectTree::currentNode()));
+ const Node *currentNode = ProjectTree::findCurrentNode();
+ QTC_ASSERT(currentNode, return);
+ TextEditor::FindInFiles::findOnFileSystem(pathFor(currentNode));
}
void ProjectExplorerPluginPrivate::showInGraphicalShell()
{
- QTC_ASSERT(ProjectTree::currentNode(), return);
- FileUtils::showInGraphicalShell(ICore::mainWindow(), pathFor(ProjectTree::currentNode()));
+ Node *currentNode = ProjectTree::findCurrentNode();
+ QTC_ASSERT(currentNode, return);
+ FileUtils::showInGraphicalShell(ICore::mainWindow(), pathFor(currentNode));
}
void ProjectExplorerPluginPrivate::openTerminalHere()
{
- QTC_ASSERT(ProjectTree::currentNode(), return);
- FileUtils::openTerminal(directoryFor(ProjectTree::currentNode()));
+ const Node *currentNode = ProjectTree::findCurrentNode();
+ QTC_ASSERT(currentNode, return);
+ FileUtils::openTerminal(directoryFor(currentNode));
}
void ProjectExplorerPluginPrivate::removeFile()
{
- Node *currentNode = ProjectTree::currentNode();
+ const Node *currentNode = ProjectTree::findCurrentNode();
QTC_ASSERT(currentNode && currentNode->nodeType() == NodeType::File, return);
const Utils::FileName filePath = currentNode->filePath();
@@ -3203,7 +3290,7 @@ void ProjectExplorerPluginPrivate::removeFile()
const bool deleteFile = removeFileDialog.isDeleteFileChecked();
// Re-read the current node, in case the project is re-parsed while the dialog is open
- if (currentNode != ProjectTree::currentNode()) {
+ if (currentNode != ProjectTree::findCurrentNode()) {
currentNode = ProjectTreeWidget::nodeForFile(filePath);
QTC_ASSERT(currentNode && currentNode->nodeType() == NodeType::File, return);
}
@@ -3228,7 +3315,7 @@ void ProjectExplorerPluginPrivate::removeFile()
void ProjectExplorerPluginPrivate::duplicateFile()
{
- Node *currentNode = ProjectTree::currentNode();
+ Node *currentNode = ProjectTree::findCurrentNode();
QTC_ASSERT(currentNode && currentNode->nodeType() == NodeType::File, return);
FileNode *fileNode = currentNode->asFileNode();
@@ -3259,7 +3346,7 @@ void ProjectExplorerPluginPrivate::duplicateFile()
void ProjectExplorerPluginPrivate::deleteFile()
{
- Node *currentNode = ProjectTree::currentNode();
+ Node *currentNode = ProjectTree::findCurrentNode();
QTC_ASSERT(currentNode && currentNode->nodeType() == NodeType::File, return);
FileNode *fileNode = currentNode->asFileNode();
@@ -3320,7 +3407,7 @@ void ProjectExplorerPluginPrivate::handleDiffFile()
return;
// current item's file
- Node *currentNode = ProjectTree::currentNode();
+ Node *currentNode = ProjectTree::findCurrentNode();
QTC_ASSERT(currentNode && currentNode->nodeType() == NodeType::File, return);
FileNode *fileNode = currentNode->asFileNode();
@@ -3358,8 +3445,9 @@ void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
.arg(projectFileName)
.arg(QDir::toNativeSeparators(oldFilePath))
.arg(QDir::toNativeSeparators(newFilePath)));
- if (res == QMessageBox::Yes)
- FileUtils::renameFile(oldFilePath, newFilePath);
+ if (res == QMessageBox::Yes) {
+ QTC_CHECK(FileUtils::renameFile(oldFilePath, newFilePath));
+ }
});
return;
@@ -3457,7 +3545,9 @@ QStringList ProjectExplorerPlugin::projectFilePatterns()
void ProjectExplorerPlugin::openOpenProjectDialog()
{
- const QString path = DocumentManager::useProjectsDirectory() ? DocumentManager::projectsDirectory() : QString();
+ const QString path = DocumentManager::useProjectsDirectory()
+ ? DocumentManager::projectsDirectory().toString()
+ : QString();
const QStringList files = DocumentManager::getOpenFileNames(dd->m_projectFilterString, path);
if (!files.isEmpty())
ICore::openFiles(files, ICore::SwitchMode);
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index 21d97fb2c27..979a3e865d8 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -21,6 +21,7 @@ HEADERS += projectexplorer.h \
projectimporter.h \
projectwindow.h \
removetaskhandler.h \
+ subscription.h \
targetsetuppage.h \
targetsetupwidget.h \
kit.h \
@@ -33,11 +34,11 @@ HEADERS += projectexplorer.h \
kitmanagerconfigwidget.h \
kitmodel.h \
kitoptionspage.h \
+ projectconfigurationmodel.h \
buildmanager.h \
buildsteplist.h \
compileoutputwindow.h \
deployconfiguration.h \
- deployconfigurationmodel.h \
namedwidget.h \
target.h \
targetsettingspanel.h \
@@ -94,8 +95,6 @@ HEADERS += projectexplorer.h \
ldparser.h \
linuxiccparser.h \
runconfigurationaspects.h \
- runconfigurationmodel.h \
- buildconfigurationmodel.h \
processparameters.h \
abstractprocessstep.h \
taskhub.h \
@@ -150,7 +149,8 @@ HEADERS += projectexplorer.h \
projectexplorer_global.h \
extracompiler.h \
customexecutableconfigurationwidget.h \
- customexecutablerunconfiguration.h
+ customexecutablerunconfiguration.h \
+ projectmacro.h
SOURCES += projectexplorer.cpp \
abi.cpp \
@@ -163,12 +163,14 @@ SOURCES += projectexplorer.cpp \
environmentaspectwidget.cpp \
gcctoolchain.cpp \
importwidget.cpp \
+ projectconfigurationmodel.cpp \
runnables.cpp \
localenvironmentaspect.cpp \
osparser.cpp \
projectimporter.cpp \
projectwindow.cpp \
removetaskhandler.cpp \
+ subscription.cpp \
targetsetuppage.cpp \
targetsetupwidget.cpp \
kit.cpp \
@@ -184,7 +186,6 @@ SOURCES += projectexplorer.cpp \
buildsteplist.cpp \
compileoutputwindow.cpp \
deployconfiguration.cpp \
- deployconfigurationmodel.cpp \
namedwidget.cpp \
target.cpp \
targetsettingspanel.cpp \
@@ -238,8 +239,6 @@ SOURCES += projectexplorer.cpp \
ldparser.cpp \
linuxiccparser.cpp \
runconfigurationaspects.cpp \
- runconfigurationmodel.cpp \
- buildconfigurationmodel.cpp \
taskhub.cpp \
processparameters.cpp \
appoutputpane.cpp \
@@ -286,7 +285,8 @@ SOURCES += projectexplorer.cpp \
projectexplorericons.cpp \
extracompiler.cpp \
customexecutableconfigurationwidget.cpp \
- customexecutablerunconfiguration.cpp
+ customexecutablerunconfiguration.cpp \
+ projectmacro.cpp
FORMS += processstep.ui \
editorsettingspropertiespage.ui \
diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs
index 47bc9d39478..2b643f69a76 100644
--- a/src/plugins/projectexplorer/projectexplorer.qbs
+++ b/src/plugins/projectexplorer/projectexplorer.qbs
@@ -13,6 +13,7 @@ Project {
Depends { name: "Core" }
Depends { name: "TextEditor" }
+ Depends { name: "app_version_header" }
cpp.defines: base.concat("QTC_CPU=X86Architecture")
@@ -29,7 +30,6 @@ Project {
"appoutputpane.cpp", "appoutputpane.h",
"baseprojectwizarddialog.cpp", "baseprojectwizarddialog.h",
"buildconfiguration.cpp", "buildconfiguration.h",
- "buildconfigurationmodel.cpp", "buildconfigurationmodel.h",
"buildenvironmentwidget.cpp", "buildenvironmentwidget.h",
"buildinfo.cpp", "buildinfo.h",
"buildmanager.cpp", "buildmanager.h",
@@ -54,7 +54,6 @@ Project {
"dependenciespanel.cpp", "dependenciespanel.h",
"deployablefile.cpp", "deployablefile.h",
"deployconfiguration.cpp", "deployconfiguration.h",
- "deployconfigurationmodel.cpp", "deployconfigurationmodel.h",
"deploymentdata.h",
"deploymentdataview.cpp",
"deploymentdataview.h",
@@ -100,6 +99,7 @@ Project {
"processstep.cpp", "processstep.h", "processstep.ui",
"project.cpp", "project.h",
"projectconfiguration.cpp", "projectconfiguration.h",
+ "projectconfigurationmodel.cpp", "projectconfigurationmodel.h",
"projectexplorer.cpp", "projectexplorer.h",
"projectexplorer.qrc",
"projectexplorer_export.h",
@@ -110,6 +110,7 @@ Project {
"projectexplorersettingspage.cpp", "projectexplorersettingspage.h", "projectexplorersettingspage.ui",
"projectfilewizardextension.cpp", "projectfilewizardextension.h",
"projectimporter.cpp", "projectimporter.h",
+ "projectmacro.cpp", "projectmacro.h",
"projectmacroexpander.cpp", "projectmacroexpander.h",
"projectmanager.h",
"projectmodels.cpp", "projectmodels.h",
@@ -124,7 +125,6 @@ Project {
"runnables.cpp", "runnables.h",
"runconfiguration.cpp", "runconfiguration.h",
"runconfigurationaspects.cpp", "runconfigurationaspects.h",
- "runconfigurationmodel.cpp", "runconfigurationmodel.h",
"runsettingspropertiespage.cpp", "runsettingspropertiespage.h",
"selectablefilesmodel.cpp", "selectablefilesmodel.h",
"session.cpp", "session.h",
@@ -134,6 +134,7 @@ Project {
"settingsaccessor.cpp", "settingsaccessor.h",
"showineditortaskhandler.cpp", "showineditortaskhandler.h",
"showoutputtaskhandler.cpp", "showoutputtaskhandler.h",
+ "subscription.cpp", "subscription.h",
"target.cpp", "target.h",
"targetsettingspanel.cpp", "targetsettingspanel.h",
"targetsetuppage.cpp", "targetsetuppage.h",
diff --git a/src/plugins/projectexplorer/projectexplorer.qrc b/src/plugins/projectexplorer/projectexplorer.qrc
index 85e1a5a4add..649c3e658f5 100644
--- a/src/plugins/projectexplorer/projectexplorer.qrc
+++ b/src/plugins/projectexplorer/projectexplorer.qrc
@@ -1,6 +1,5 @@
<RCC>
<qresource prefix="/projectexplorer">
- <file>images/build_small.png</file>
<file>images/category_buildrun.png</file>
<file>images/closetab.png</file>
<file>images/debugger_start.png</file>
@@ -12,6 +11,10 @@
<file>images/mode_project_mask.png</file>
<file>images/mode_project_mask@2x.png</file>
<file>images/projectexplorer.png</file>
+ <file>images/buildhammerhandle.png</file>
+ <file>images/buildhammerhandle@2x.png</file>
+ <file>images/buildhammerhead.png</file>
+ <file>images/buildhammerhead@2x.png</file>
<file>images/rebuildhammerhandles.png</file>
<file>images/rebuildhammerhandles@2x.png</file>
<file>images/rebuildhammerheads.png</file>
diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h
index 13dfe2431a5..f0f4b2762af 100644
--- a/src/plugins/projectexplorer/projectexplorerconstants.h
+++ b/src/plugins/projectexplorer/projectexplorerconstants.h
@@ -73,6 +73,7 @@ const char G_PROJECT_FILES[] = "Project.Group.Files";
const char G_PROJECT_TREE[] = "Project.Group.Tree";
const char G_PROJECT_LAST[] = "Project.Group.Last";
+const char G_FOLDER_LOCATIONS[] = "ProjectFolder.Group.Locations";
const char G_FOLDER_FILES[] = "ProjectFolder.Group.Files";
const char G_FOLDER_OTHER[] = "ProjectFolder.Group.Other";
const char G_FOLDER_CONFIG[] = "ProjectFolder.Group.Config";
diff --git a/src/plugins/projectexplorer/projectexplorericons.cpp b/src/plugins/projectexplorer/projectexplorericons.cpp
index e86fe915bc3..cd1913838da 100644
--- a/src/plugins/projectexplorer/projectexplorericons.cpp
+++ b/src/plugins/projectexplorer/projectexplorericons.cpp
@@ -34,10 +34,14 @@ const Icon BUILD(":/projectexplorer/images/build.png");
const Icon BUILD_FLAT({
{":/projectexplorer/images/build_hammerhandle_mask.png", Theme::IconsBuildHammerHandleColor},
{":/projectexplorer/images/build_hammerhead_mask.png", Theme::IconsBuildHammerHeadColor}});
-const Icon BUILD_SMALL(":/projectexplorer/images/build_small.png");
+const Icon BUILD_SMALL({
+ {":/projectexplorer/images/buildhammerhandle.png", Theme::IconsBuildHammerHandleColor},
+ {":/projectexplorer/images/buildhammerhead.png", Theme::IconsBuildHammerHeadColor}}, Icon::Tint);
const Icon REBUILD({
{":/projectexplorer/images/rebuildhammerhandles.png", Theme::IconsBuildHammerHandleColor},
- {":/projectexplorer/images/rebuildhammerheads.png", Theme::IconsBuildHammerHeadColor}}, Icon::Tint);
+ {":/projectexplorer/images/buildhammerhandle.png", Theme::IconsBuildHammerHandleColor},
+ {":/projectexplorer/images/rebuildhammerheads.png", Theme::IconsBuildHammerHeadColor},
+ {":/projectexplorer/images/buildhammerhead.png", Theme::IconsBuildHammerHeadColor}}, Icon::Tint);
const Icon RUN(":/projectexplorer/images/run.png");
const Icon RUN_FLAT({
{":/projectexplorer/images/run_mask.png", Theme::IconsRunToolBarColor}});
diff --git a/src/plugins/projectexplorer/projectexplorersettings.h b/src/plugins/projectexplorer/projectexplorersettings.h
index a2759d66e3d..e0d4b8088c1 100644
--- a/src/plugins/projectexplorer/projectexplorersettings.h
+++ b/src/plugins/projectexplorer/projectexplorersettings.h
@@ -25,6 +25,8 @@
#pragma once
+#include <coreplugin/coreconstants.h>
+
#include <QUuid>
namespace ProjectExplorer {
@@ -47,7 +49,8 @@ public:
bool useJom = true;
bool autorestoreLastSession = false; // This option is set in the Session Manager!
bool prompToStopRunControl = false;
- int maxAppOutputLines = 100000;
+ int maxAppOutputLines = Core::Constants::DEFAULT_MAX_LINE_COUNT;
+ int maxBuildOutputLines = Core::Constants::DEFAULT_MAX_LINE_COUNT;
StopBeforeBuild stopBeforeBuild = StopBeforeBuild::StopNone;
// Add a UUid which is used to identify the development environment.
@@ -71,6 +74,7 @@ inline bool operator==(const ProjectExplorerSettings &p1, const ProjectExplorerS
&& p1.autorestoreLastSession == p2.autorestoreLastSession
&& p1.prompToStopRunControl == p2.prompToStopRunControl
&& p1.maxAppOutputLines == p2.maxAppOutputLines
+ && p1.maxBuildOutputLines == p2.maxBuildOutputLines
&& p1.environmentId == p2.environmentId
&& p1.stopBeforeBuild == p2.stopBeforeBuild;
}
diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.cpp b/src/plugins/projectexplorer/projectexplorersettingspage.cpp
index 115413b47a5..9d7f8b1c8b1 100644
--- a/src/plugins/projectexplorer/projectexplorersettingspage.cpp
+++ b/src/plugins/projectexplorer/projectexplorersettingspage.cpp
@@ -109,6 +109,7 @@ ProjectExplorerSettings ProjectExplorerSettingsWidget::settings() const
m_settings.useJom = m_ui.jomCheckbox->isChecked();
m_settings.prompToStopRunControl = m_ui.promptToStopRunControlCheckBox->isChecked();
m_settings.maxAppOutputLines = m_ui.maxAppOutputBox->value();
+ m_settings.maxBuildOutputLines = m_ui.maxBuildOutputBox->value();
m_settings.stopBeforeBuild = static_cast<ProjectExplorerSettings::StopBeforeBuild>(m_ui.stopBeforeBuildComboBox->currentIndex());
return m_settings;
}
@@ -128,7 +129,8 @@ void ProjectExplorerSettingsWidget::setSettings(const ProjectExplorerSettings &
m_ui.jomCheckbox->setChecked(m_settings.useJom);
m_ui.promptToStopRunControlCheckBox->setChecked(m_settings.prompToStopRunControl);
m_ui.maxAppOutputBox->setValue(m_settings.maxAppOutputLines);
- m_ui.stopBeforeBuildComboBox->setCurrentIndex(static_cast<int>(pes.stopBeforeBuild));
+ m_ui.maxBuildOutputBox->setValue(m_settings.maxBuildOutputLines);
+ m_ui.stopBeforeBuildComboBox->setCurrentIndex(static_cast<int>(m_settings.stopBeforeBuild));
}
QString ProjectExplorerSettingsWidget::projectsDirectory() const
@@ -196,7 +198,7 @@ QWidget *ProjectExplorerSettingsPage::widget()
if (!m_widget) {
m_widget = new ProjectExplorerSettingsWidget;
m_widget->setSettings(ProjectExplorerPlugin::projectExplorerSettings());
- m_widget->setProjectsDirectory(Core::DocumentManager::projectsDirectory());
+ m_widget->setProjectsDirectory(Core::DocumentManager::projectsDirectory().toString());
m_widget->setUseProjectsDirectory(Core::DocumentManager::useProjectsDirectory());
m_widget->setBuildDirectory(Core::DocumentManager::buildDirectory());
}
@@ -207,7 +209,8 @@ void ProjectExplorerSettingsPage::apply()
{
if (m_widget) {
ProjectExplorerPlugin::setProjectExplorerSettings(m_widget->settings());
- Core::DocumentManager::setProjectsDirectory(m_widget->projectsDirectory());
+ Core::DocumentManager::setProjectsDirectory(
+ Utils::FileName::fromString(m_widget->projectsDirectory()));
Core::DocumentManager::setUseProjectsDirectory(m_widget->useProjectsDirectory());
Core::DocumentManager::setBuildDirectory(m_widget->buildDirectory());
}
diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.ui b/src/plugins/projectexplorer/projectexplorersettingspage.ui
index 7ea652cc174..4a51b8b2742 100644
--- a/src/plugins/projectexplorer/projectexplorersettingspage.ui
+++ b/src/plugins/projectexplorer/projectexplorersettingspage.ui
@@ -120,14 +120,14 @@
<number>0</number>
</property>
<item>
- <widget class="QLabel" name="label">
+ <widget class="QLabel" name="limitBuildOutputLabel">
<property name="text">
- <string>Limit application output to </string>
+ <string>Limit build output to </string>
</property>
</widget>
</item>
<item>
- <widget class="QSpinBox" name="maxAppOutputBox">
+ <widget class="QSpinBox" name="maxBuildOutputBox">
<property name="minimum">
<number>500</number>
</property>
@@ -143,7 +143,7 @@
</widget>
</item>
<item>
- <widget class="QLabel" name="label_2">
+ <widget class="QLabel" name="limitBuildOutputLabel_2">
<property name="text">
<string>lines</string>
</property>
@@ -159,6 +159,54 @@
</property>
</widget>
</item>
+ <item row="4" column="1">
+ <widget class="QWidget" name="widget_1" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Limit application output to</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="maxAppOutputBox">
+ <property name="minimum">
+ <number>500</number>
+ </property>
+ <property name="maximum">
+ <number>1000000</number>
+ </property>
+ <property name="singleStep">
+ <number>500</number>
+ </property>
+ <property name="value">
+ <number>100000</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>lines</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
<item row="5" column="0">
<widget class="QCheckBox" name="showDebugOutputCheckBox">
<property name="text">
diff --git a/src/plugins/projectexplorer/projectexplorerunittestfiles.pri b/src/plugins/projectexplorer/projectexplorerunittestfiles.pri
new file mode 100644
index 00000000000..6b005059e6a
--- /dev/null
+++ b/src/plugins/projectexplorer/projectexplorerunittestfiles.pri
@@ -0,0 +1,12 @@
+shared {
+ DEFINES += PROJECTEXPLORER_LIBRARY
+} else {
+ DEFINES += PROJECTEXPLORER_STATIC_LIBRARY
+}
+
+HEADERS += \
+ $$PWD/projectmacro.h
+
+SOURCES += \
+ $$PWD/projectmacro.cpp
+
diff --git a/src/plugins/projectexplorer/projectmacro.cpp b/src/plugins/projectexplorer/projectmacro.cpp
new file mode 100644
index 00000000000..5d2824f01db
--- /dev/null
+++ b/src/plugins/projectexplorer/projectmacro.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "projectmacro.h"
+
+#include <utils/algorithm.h>
+#include <cctype>
+
+namespace ProjectExplorer {
+
+bool Macro::isValid() const
+{
+ return !key.isEmpty() && type != MacroType::Invalid;
+}
+
+QByteArray Macro::toByteArray() const
+{
+ switch (type) {
+ case MacroType::Define: {
+ if (value.isEmpty())
+ return QByteArray("#define ") + key;
+ return QByteArray("#define ") + key + ' ' + value;
+ }
+ case MacroType::Undefine: return QByteArray("#undef ") + key;
+ case MacroType::Invalid: break;
+ }
+
+ return QByteArray();
+}
+
+QByteArray Macro::toByteArray(const Macros &macros)
+{
+ QByteArray text;
+
+ for (const Macro &macro : macros) {
+ const QByteArray macroText = macro.toByteArray();
+ if (!macroText.isEmpty())
+ text += macroText + '\n';
+ }
+
+ return text;
+}
+
+QByteArray Macro::toByteArray(const QVector<Macros> &macrosVector)
+{
+ QByteArray text;
+
+ for (const Macros &macros : macrosVector)
+ text += toByteArray(macros);
+
+ return text;
+}
+
+Macros Macro::toMacros(const QByteArray &text)
+{
+ return tokensLinesToMacros(tokenizeLines(splitLines(text)));
+}
+
+Macro Macro::fromKeyValue(const QString &utf16text)
+{
+ return fromKeyValue(utf16text.toUtf8());
+}
+
+Macro Macro::fromKeyValue(const QByteArray &text)
+{
+ QByteArray key;
+ QByteArray value;
+ MacroType type = MacroType::Invalid;
+
+ if (!text.isEmpty()) {
+ type = MacroType::Define;
+
+ int index = text.indexOf('=');
+
+ if (index != -1) {
+ key = text.left(index).trimmed();
+ value = text.mid(index + 1).trimmed();
+ } else {
+ key = text.trimmed();
+ value = "1";
+ }
+ }
+
+ return Macro(key, value, type);
+}
+
+QByteArray Macro::toKeyValue(const QByteArray &prefix) const
+{
+ QByteArray keyValue;
+ if (type != MacroType::Invalid)
+ keyValue = prefix;
+
+ if (value.isEmpty())
+ keyValue += key + '=';
+ else if (value == "1")
+ keyValue += key;
+ else
+ keyValue += key + '=' + value;
+
+ return keyValue;
+}
+
+static void removeCarriageReturn(QByteArray &line)
+{
+ if (line.endsWith('\r'))
+ line.truncate(line.size() - 1);
+}
+
+static void removeCarriageReturns(QList<QByteArray> &lines)
+{
+ for (QByteArray &line : lines)
+ removeCarriageReturn(line);
+}
+
+QList<QByteArray> Macro::splitLines(const QByteArray &text)
+{
+ QList<QByteArray> splitLines = text.split('\n');
+
+ splitLines.removeAll("");
+ removeCarriageReturns(splitLines);
+
+ return splitLines;
+}
+
+QByteArray Macro::removeNonsemanticSpaces(QByteArray line)
+{
+ auto begin = line.begin();
+ auto end = line.end();
+ bool notInString = true;
+
+ auto newEnd = std::unique(begin, end, [&] (char first, char second) {
+ notInString = notInString && first != '\"';
+ return notInString && (first == '#' || std::isspace(first)) && std::isspace(second);
+ });
+
+ line.truncate(line.size() - int(std::distance(newEnd, end)));
+
+ return line.trimmed();
+}
+
+QList<QByteArray> Macro::tokenizeLine(const QByteArray &line)
+{
+ const QByteArray normalizedLine = removeNonsemanticSpaces(line);
+
+ const auto begin = normalizedLine.begin();
+ auto first = std::find(normalizedLine.begin(), normalizedLine.end(), ' ');
+ auto second = std::find(std::next(first), normalizedLine.end(), ' ');
+ const auto end = normalizedLine.end();
+
+ QList<QByteArray> tokens;
+
+ if (first != end) {
+ tokens.append(QByteArray(begin, int(std::distance(begin, first))));
+
+ std::advance(first, 1);
+ tokens.append(QByteArray(first, int(std::distance(first, second))));
+
+ if (second != end) {
+ std::advance(second, 1);
+ tokens.append(QByteArray(second, int(std::distance(second, end))));
+ }
+ }
+
+ return tokens;
+}
+
+QList<QList<QByteArray>> Macro::tokenizeLines(const QList<QByteArray> &lines)
+{
+ QList<QList<QByteArray>> tokensLines = Utils::transform(lines, &Macro::tokenizeLine);
+
+ return tokensLines;
+}
+
+Macro Macro::tokensToMacro(const QList<QByteArray> &tokens)
+{
+ Macro macro;
+
+ if (tokens.size() >= 2 && tokens[0] == "#define") {
+ macro.type = MacroType::Define;
+ macro.key = tokens[1];
+
+ if (tokens.size() >= 3)
+ macro.value = tokens[2];
+ }
+
+ return macro;
+}
+
+Macros Macro::tokensLinesToMacros(const QList<QList<QByteArray>> &tokensLines)
+{
+ Macros macros;
+ macros.reserve(tokensLines.size());
+
+ for (const QList<QByteArray> &tokens : tokensLines) {
+ Macro macro = tokensToMacro(tokens);
+
+ if (macro.type != MacroType::Invalid)
+ macros.push_back(std::move(macro));
+ }
+
+ return macros;
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/projectmacro.h b/src/plugins/projectexplorer/projectmacro.h
new file mode 100644
index 00000000000..9489b54d809
--- /dev/null
+++ b/src/plugins/projectexplorer/projectmacro.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "projectexplorer_export.h"
+
+#include <QByteArray>
+#include <QHash>
+#include <QVector>
+
+namespace ProjectExplorer {
+
+enum class MacroType
+{
+ Invalid,
+ Define,
+ Undefine
+};
+
+class Macro;
+
+using Macros = QVector<Macro>;
+
+class PROJECTEXPLORER_EXPORT Macro
+{
+public:
+ Macro() = default;
+
+ Macro(QByteArray key, QByteArray value, MacroType type = MacroType::Define)
+ : key(key), value(value), type(type)
+ {}
+
+ Macro(QByteArray key, MacroType type = MacroType::Define)
+ : key(key), type(type)
+ {}
+
+ bool isValid() const;
+
+ QByteArray toByteArray() const;
+ static QByteArray toByteArray(const Macros &macros);
+ static QByteArray toByteArray(const QVector<Macros> &macross);
+
+ static Macros toMacros(const QByteArray &text);
+
+ // define Foo will be converted to Foo=1
+ static Macro fromKeyValue(const QString &utf16text);
+ static Macro fromKeyValue(const QByteArray &text);
+ QByteArray toKeyValue(const QByteArray &prefix) const;
+
+public:
+ QByteArray key;
+ QByteArray value;
+ MacroType type = MacroType::Invalid;
+
+private:
+ static QList<QByteArray> splitLines(const QByteArray &text);
+ static QByteArray removeNonsemanticSpaces(QByteArray line);
+ static QList<QByteArray> tokenizeLine(const QByteArray &line);
+ static QList<QList<QByteArray>> tokenizeLines(const QList<QByteArray> &lines);
+ static Macro tokensToMacro(const QList<QByteArray> &tokens);
+ static Macros tokensLinesToMacros(const QList<QList<QByteArray>> &tokensLines);
+};
+
+inline
+uint qHash(const Macro &macro)
+{
+ using ::qHash;
+ return qHash(macro.key) ^ qHash(macro.value) ^ qHash(int(macro.type));
+}
+
+inline
+bool operator==(const Macro &first, const Macro &second)
+{
+ return first.type == second.type
+ && first.key == second.key
+ && first.value == second.value;
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp
index 17504821ac3..f22618a3c57 100644
--- a/src/plugins/projectexplorer/projectmodels.cpp
+++ b/src/plugins/projectexplorer/projectmodels.cpp
@@ -32,15 +32,18 @@
#include "session.h"
#include <coreplugin/fileiconprovider.h>
+#include <utils/utilsicons.h>
#include <utils/algorithm.h>
#include <utils/dropsupport.h>
+#include <utils/theme/theme.h>
-#include <QDebug>
#include <QFileInfo>
#include <QFont>
#include <QMimeData>
#include <QLoggingCategory>
+#include <functional>
+
using namespace Utils;
namespace ProjectExplorer {
@@ -106,10 +109,19 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
}
case Qt::DecorationRole: {
if (folderNode) {
- result = folderNode->icon();
+ static QIcon emptyIcon = Utils::Icons::EMPTY16.icon();
if (ContainerNode *containerNode = folderNode->asContainerNode()) {
- if (ProjectNode *projectNode = containerNode->rootProjectNode())
- result = projectNode->icon();
+ WrapperNode *wn = wrapperForNode(node);
+ Project *project = Utils::findOrDefault(SessionManager::projects(), [this, wn](const Project *p) {
+ return nodeForProject(p) == wn;
+ });
+ if (project && project->isParsing())
+ result = emptyIcon;
+ else
+ result = containerNode->rootProjectNode() ? containerNode->rootProjectNode()->icon() :
+ folderNode->icon();
+ } else {
+ result = folderNode->icon();
}
} else {
result = Core::FileIconProvider::icon(node->filePath().toString());
@@ -133,6 +145,17 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
result = node->isEnabled();
break;
}
+ case Project::isParsingRole: {
+ const Project *project = nullptr;
+ if (node->asContainerNode()) {
+ WrapperNode *wn = wrapperForNode(node);
+ project = Utils::findOrDefault(SessionManager::projects(), [this, wn](const Project *p) {
+ return nodeForProject(p) == wn;
+ });
+ }
+ result = project ? project->isParsing() : false;
+ break;
+ }
}
}
@@ -229,6 +252,13 @@ void FlatModel::addOrRebuildProjectModel(Project *project)
emit requestExpansion(container->index());
}
+void FlatModel::parsingStateChanged(Project *project)
+{
+ const WrapperNode *const node = nodeForProject(project);
+ const QModelIndex nodeIdx = indexForNode(node->m_node);
+ emit dataChanged(nodeIdx, nodeIdx);
+}
+
void FlatModel::updateSubtree(FolderNode *node)
{
// FIXME: This is still excessive, should be limited to the affected subtree.
@@ -265,6 +295,12 @@ ExpandData FlatModel::expandDataForNode(const Node *node) const
void FlatModel::handleProjectAdded(Project *project)
{
+ QTC_ASSERT(project, return);
+
+ connect(project, &Project::parsingStarted,
+ this, [this, project]() { parsingStateChanged(project); });
+ connect(project, &Project::parsingFinished,
+ this, [this, project]() { parsingStateChanged(project); });
addOrRebuildProjectModel(project);
}
@@ -273,7 +309,7 @@ void FlatModel::handleProjectRemoved(Project *project)
destroyItem(nodeForProject(project));
}
-WrapperNode *FlatModel::nodeForProject(Project *project)
+WrapperNode *FlatModel::nodeForProject(const Project *project) const
{
QTC_ASSERT(project, return nullptr);
ContainerNode *containerNode = project->containerNode();
@@ -359,7 +395,7 @@ QMimeData *FlatModel::mimeData(const QModelIndexList &indexes) const
WrapperNode *FlatModel::wrapperForNode(const Node *node) const
{
- return findNonRooItem([this, node](WrapperNode *item) {
+ return findNonRootItem([node](WrapperNode *item) {
return item->m_node == node;
});
}
diff --git a/src/plugins/projectexplorer/projectmodels.h b/src/plugins/projectexplorer/projectmodels.h
index a0041a7bcd0..80fdbbc36db 100644
--- a/src/plugins/projectexplorer/projectmodels.h
+++ b/src/plugins/projectexplorer/projectmodels.h
@@ -49,7 +49,7 @@ class WrapperNode : public Utils::TypedTreeItem<WrapperNode>
{
public:
explicit WrapperNode(Node *node) : m_node(node) {}
- QPointer<Node> m_node;
+ Node *m_node = nullptr;
};
class FlatModel : public Utils::TreeModel<WrapperNode, WrapperNode>
@@ -102,9 +102,11 @@ private:
void saveExpandData();
void handleProjectAdded(Project *project);
void handleProjectRemoved(Project *project);
- WrapperNode *nodeForProject(Project *project);
+ WrapperNode *nodeForProject(const Project *project) const;
void addOrRebuildProjectModel(Project *project);
+ void parsingStateChanged(Project *project);
+
QTimer m_timer;
QSet<ExpandData> m_toExpand;
};
diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp
index a3e7203e342..91ff23f5fac 100644
--- a/src/plugins/projectexplorer/projectnodes.cpp
+++ b/src/plugins/projectexplorer/projectnodes.cpp
@@ -253,7 +253,7 @@ bool Node::isGenerated() const
return (m_flags & FlagIsGenerated) == FlagIsGenerated;
}
-bool Node::supportsAction(ProjectAction, Node *) const
+bool Node::supportsAction(ProjectAction, const Node *) const
{
return false;
}
@@ -408,7 +408,7 @@ FileNode::scanForFilesWithVersionControls(const Utils::FileName &directory,
return scanForFilesRecursively(directory, factory, visited, future, 0.0, 1000000.0, versionControls);
}
-bool FileNode::supportsAction(ProjectAction action, Node *node) const
+bool FileNode::supportsAction(ProjectAction action, const Node *node) const
{
if (action == InheritedFromParent)
return true;
@@ -643,13 +643,23 @@ void FolderNode::setIcon(const QIcon &icon)
m_icon = icon;
}
+void FolderNode::setLocationInfo(const QList<FolderNode::LocationInfo> &info)
+{
+ m_locations = info;
+}
+
+const QList<FolderNode::LocationInfo> FolderNode::locationInfo() const
+{
+ return m_locations;
+}
+
QString FolderNode::addFileFilter() const
{
FolderNode *fn = parentFolderNode();
return fn ? fn->addFileFilter() : QString();
}
-bool FolderNode::supportsAction(ProjectAction action, Node *node) const
+bool FolderNode::supportsAction(ProjectAction action, const Node *node) const
{
if (action == InheritedFromParent)
return true;
@@ -832,7 +842,7 @@ bool ProjectNode::renameFile(const QString &filePath, const QString &newFilePath
return false;
}
-bool ProjectNode::supportsAction(ProjectAction, Node *) const
+bool ProjectNode::supportsAction(ProjectAction, const Node *) const
{
return false;
}
@@ -887,9 +897,9 @@ QString ContainerNode::displayName() const
return name;
}
-bool ContainerNode::supportsAction(ProjectAction action, Node *node) const
+bool ContainerNode::supportsAction(ProjectAction action, const Node *node) const
{
- Node *rootNode = m_project->rootProjectNode();
+ const Node *rootNode = m_project->rootProjectNode();
return rootNode && rootNode->supportsAction(action, node);
}
diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h
index 376e50192fe..c0cc25a04de 100644
--- a/src/plugins/projectexplorer/projectnodes.h
+++ b/src/plugins/projectexplorer/projectnodes.h
@@ -29,7 +29,6 @@
#include <QFutureInterface>
#include <QIcon>
-#include <QObject>
#include <QStringList>
#include <utils/fileutils.h>
@@ -98,9 +97,8 @@ class ProjectNode;
class ContainerNode;
// Documentation inside.
-class PROJECTEXPLORER_EXPORT Node : public QObject
+class PROJECTEXPLORER_EXPORT Node
{
- Q_OBJECT
public:
enum PriorityLevel {
DefaultPriority = 0,
@@ -134,7 +132,7 @@ public:
bool listInProject() const;
bool isGenerated() const;
- virtual bool supportsAction(ProjectAction action, Node *node) const;
+ virtual bool supportsAction(ProjectAction action, const Node *node) const;
void setEnabled(bool enabled);
void setAbsoluteFilePathAndLine(const Utils::FileName &filePath, int line);
@@ -203,7 +201,7 @@ public:
const std::function<FileNode *(const Utils::FileName &fileName)> factory,
const QList<Core::IVersionControl *> &versionControls,
QFutureInterface<QList<FileNode *>> *future = nullptr);
- bool supportsAction(ProjectAction action, Node *node) const override;
+ bool supportsAction(ProjectAction action, const Node *node) const override;
private:
FileType m_fileType;
@@ -247,9 +245,21 @@ public:
void setDisplayName(const QString &name);
void setIcon(const QIcon &icon);
+ class LocationInfo {
+ public:
+ LocationInfo(const QString &dn, const Utils::FileName &p, const int l = -1) :
+ path(p), line(l), displayName(dn) { }
+
+ Utils::FileName path;
+ int line = -1;
+ QString displayName;
+ };
+ void setLocationInfo(const QList<LocationInfo> &info);
+ const QList<LocationInfo> locationInfo() const;
+
virtual QString addFileFilter() const;
- bool supportsAction(ProjectAction action, Node *node) const override;
+ bool supportsAction(ProjectAction action, const Node *node) const override;
virtual bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0);
virtual bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = 0);
@@ -285,6 +295,7 @@ public:
protected:
QList<Node *> m_nodes;
+ QList<LocationInfo> m_locations;
private:
QString m_displayName;
@@ -317,7 +328,7 @@ public:
bool deleteFiles(const QStringList &filePaths) override;
bool canRenameFile(const QString &filePath, const QString &newFilePath) override;
bool renameFile(const QString &filePath, const QString &newFilePath) override;
- bool supportsAction(ProjectAction action, Node *node) const override;
+ bool supportsAction(ProjectAction action, const Node *node) const override;
// by default returns false
virtual bool deploysFolder(const QString &folder) const;
@@ -339,7 +350,7 @@ public:
ContainerNode(Project *project);
QString displayName() const final;
- bool supportsAction(ProjectAction action, Node *node) const final;
+ bool supportsAction(ProjectAction action, const Node *node) const final;
ContainerNode *asContainerNode() final { return this; }
const ContainerNode *asContainerNode() const final { return this; }
diff --git a/src/plugins/projectexplorer/projecttree.cpp b/src/plugins/projectexplorer/projecttree.cpp
index 5f4a0b780e8..606ad41f246 100644
--- a/src/plugins/projectexplorer/projecttree.cpp
+++ b/src/plugins/projectexplorer/projecttree.cpp
@@ -65,10 +65,10 @@ ProjectTree::ProjectTree(QObject *parent) : QObject(parent)
s_instance = this;
connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
- this, &ProjectTree::documentManagerCurrentFileChanged);
+ this, &ProjectTree::update);
connect(qApp, &QApplication::focusChanged,
- this, &ProjectTree::focusChanged);
+ this, &ProjectTree::update);
connect(SessionManager::instance(), &SessionManager::projectAdded,
this, &ProjectTree::sessionChanged);
@@ -92,8 +92,8 @@ ProjectTree::~ProjectTree()
void ProjectTree::aboutToShutDown()
{
disconnect(qApp, &QApplication::focusChanged,
- s_instance, &ProjectTree::focusChanged);
- s_instance->update(nullptr, nullptr);
+ s_instance, &ProjectTree::update);
+ s_instance->setCurrent(nullptr, nullptr);
qDeleteAll(s_instance->m_projectTreeWidgets);
QTC_CHECK(s_instance->m_projectTreeWidgets.isEmpty());
}
@@ -108,8 +108,9 @@ Project *ProjectTree::currentProject()
return s_instance->m_currentProject;
}
-Node *ProjectTree::currentNode()
+Node *ProjectTree::findCurrentNode()
{
+ s_instance->update();
return s_instance->m_currentNode;
}
@@ -133,21 +134,21 @@ void ProjectTree::nodeChanged(ProjectTreeWidget *widget)
s_instance->updateFromProjectTreeWidget(widget);
}
-void ProjectTree::focusChanged()
-{
- s_instance->updateFromFocus();
-}
-
-void ProjectTree::updateFromFocus(bool invalidCurrentNode)
+void ProjectTree::update()
{
ProjectTreeWidget *focus = m_focusForContextMenu;
- if (!focus)
+ static QPointer<ProjectTreeWidget> lastFocusedProjectTreeWidget;
+ if (!focus) {
focus = Utils::findOrDefault(m_projectTreeWidgets, &ProjectTree::hasFocus);
+ lastFocusedProjectTreeWidget = focus;
+ }
+ if (!focus)
+ focus = lastFocusedProjectTreeWidget;
if (focus)
updateFromProjectTreeWidget(focus);
else
- updateFromDocumentManager(invalidCurrentNode);
+ updateFromDocumentManager();
}
void ProjectTree::updateFromProjectTreeWidget(ProjectTreeWidget *widget)
@@ -155,26 +156,17 @@ void ProjectTree::updateFromProjectTreeWidget(ProjectTreeWidget *widget)
Node *currentNode = widget->currentNode();
Project *project = SessionManager::projectForNode(currentNode);
- update(currentNode, project);
+ setCurrent(currentNode, project);
}
-void ProjectTree::documentManagerCurrentFileChanged()
+void ProjectTree::updateFromDocumentManager()
{
- updateFromFocus();
-}
-
-void ProjectTree::updateFromDocumentManager(bool invalidCurrentNode)
-{
- Core::IDocument *document = Core::EditorManager::currentDocument();
- const FileName fileName = document ? document->filePath() : FileName();
-
- Node *currentNode = nullptr;
- if (!invalidCurrentNode && m_currentNode && m_currentNode->filePath() == fileName)
- currentNode = m_currentNode;
- else
- currentNode = ProjectTreeWidget::nodeForFile(fileName);
-
- updateFromNode(currentNode);
+ if (Core::IDocument *document = Core::EditorManager::currentDocument()) {
+ const FileName fileName = document->filePath();
+ updateFromNode(ProjectTreeWidget::nodeForFile(fileName));
+ } else {
+ updateFromNode(nullptr);
+ }
}
void ProjectTree::updateFromNode(Node *node)
@@ -185,12 +177,12 @@ void ProjectTree::updateFromNode(Node *node)
else
project = SessionManager::startupProject();
- update(node, project);
+ setCurrent(node, project);
foreach (ProjectTreeWidget *widget, m_projectTreeWidgets)
widget->sync(node);
}
-void ProjectTree::update(Node *node, Project *project)
+void ProjectTree::setCurrent(Node *node, Project *project)
{
const bool changedProject = project != m_currentProject;
if (changedProject) {
@@ -243,7 +235,7 @@ void ProjectTree::sessionChanged()
Core::DocumentManager::setDefaultLocationForNewFiles(SessionManager::startupProject()->projectDirectory().toString());
else
Core::DocumentManager::setDefaultLocationForNewFiles(QString());
- updateFromFocus();
+ update();
}
void ProjectTree::updateContext()
diff --git a/src/plugins/projectexplorer/projecttree.h b/src/plugins/projectexplorer/projecttree.h
index 7f61a2ee78a..3d880d8355b 100644
--- a/src/plugins/projectexplorer/projecttree.h
+++ b/src/plugins/projectexplorer/projecttree.h
@@ -51,7 +51,7 @@ public:
static ProjectTree *instance();
static Project *currentProject();
- static Node *currentNode();
+ static Node *findCurrentNode();
// Integration with ProjectTreeWidget
static void registerWidget(Internal::ProjectTreeWidget *widget);
@@ -90,15 +90,14 @@ signals:
private:
void sessionChanged();
- void focusChanged();
+ void update();
void updateFromProjectTreeWidget(Internal::ProjectTreeWidget *widget);
- void documentManagerCurrentFileChanged();
- void updateFromDocumentManager(bool invalidCurrentNode = false);
+ void updateFromDocumentManager();
void updateFromNode(Node *node);
- void update(Node *node, Project *project);
+ void setCurrent(Node *node, Project *project);
void updateContext();
- void updateFromFocus(bool invalidCurrentNode = false);
+ void updateFromFocus();
void updateExternalFileWarning();
static bool hasFocus(Internal::ProjectTreeWidget *widget);
@@ -108,7 +107,7 @@ private:
static ProjectTree *s_instance;
QList<QPointer<Internal::ProjectTreeWidget>> m_projectTreeWidgets;
QVector<TreeManagerFunction> m_treeManagers;
- QPointer<Node> m_currentNode;
+ Node *m_currentNode = nullptr;
Project *m_currentProject = nullptr;
Internal::ProjectTreeWidget *m_focusForContextMenu = nullptr;
Core::Context m_lastProjectContext;
diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp
index 5b1471504ee..f310cd14680 100644
--- a/src/plugins/projectexplorer/projecttreewidget.cpp
+++ b/src/plugins/projectexplorer/projecttreewidget.cpp
@@ -40,23 +40,28 @@
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/find/itemviewfind.h>
-#include <utils/navigationtreeview.h>
#include <utils/algorithm.h>
+#include <utils/navigationtreeview.h>
+#include <utils/progressindicator.h>
#include <utils/tooltip/tooltip.h>
#include <utils/utilsicons.h>
-#include <QDebug>
+#include <QApplication>
#include <QSettings>
#include <QStyledItemDelegate>
#include <QVBoxLayout>
#include <QToolButton>
+#include <QPainter>
#include <QAction>
#include <QMenu>
+#include <memory>
+
using namespace Core;
using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;
+using namespace Utils;
QList<ProjectTreeWidget *> ProjectTreeWidget::m_projectTreeWidgets;
@@ -65,22 +70,78 @@ namespace {
class ProjectTreeItemDelegate : public QStyledItemDelegate
{
public:
- ProjectTreeItemDelegate(QObject *parent) : QStyledItemDelegate(parent)
- { }
+ ProjectTreeItemDelegate(QTreeView *view) : QStyledItemDelegate(view),
+ m_view(view)
+ {
+ connect(m_view->model(), &QAbstractItemModel::modelReset,
+ this, &ProjectTreeItemDelegate::deleteAllIndicators);
+
+ // Actually this only needs to delete the indicators in the effected rows and *after* it,
+ // but just be lazy and nuke all the indicators.
+ connect(m_view->model(), &QAbstractItemModel::rowsAboutToBeRemoved,
+ this, &ProjectTreeItemDelegate::deleteAllIndicators);
+ connect(m_view->model(), &QAbstractItemModel::rowsAboutToBeInserted,
+ this, &ProjectTreeItemDelegate::deleteAllIndicators);
+ }
+
+ ~ProjectTreeItemDelegate() override
+ {
+ deleteAllIndicators();
+ }
- void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+ void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
QStyleOptionViewItem opt = option;
if (!index.data(Project::EnabledRole).toBool())
opt.state &= ~QStyle::State_Enabled;
QStyledItemDelegate::paint(painter, opt, index);
+
+ if (index.data(Project::isParsingRole).toBool()) {
+ initStyleOption(&opt, index);
+ ProgressIndicatorPainter *indicator = findOrCreateIndicatorPainter(index);
+
+ QStyle *style = option.widget ? option.widget->style() : QApplication::style();
+ const QRect rect = style->subElementRect(QStyle::SE_ItemViewItemDecoration, &opt, opt.widget);
+
+ indicator->paint(*painter, rect);
+ } else {
+ delete m_indicators.value(index);
+ m_indicators.remove(index);
+ }
}
+
+private:
+ ProgressIndicatorPainter *findOrCreateIndicatorPainter(const QModelIndex &index) const
+ {
+ ProgressIndicatorPainter *indicator = m_indicators.value(index);
+ if (!indicator)
+ indicator = createIndicatorPainter(index);
+ return indicator;
+ }
+
+ ProgressIndicatorPainter *createIndicatorPainter(const QModelIndex &index) const
+ {
+ auto indicator = new ProgressIndicatorPainter(ProgressIndicatorSize::Small);
+ indicator->setUpdateCallback([index, this]() { m_view->update(index); });
+ indicator->startAnimation();
+ m_indicators.insert(index, indicator);
+ return indicator;
+ }
+
+ void deleteAllIndicators()
+ {
+ qDeleteAll(m_indicators);
+ m_indicators.clear();
+ }
+
+ mutable QHash<QModelIndex, ProgressIndicatorPainter *> m_indicators;
+ QTreeView *m_view;
};
bool debug = false;
}
-class ProjectTreeView : public Utils::NavigationTreeView
+class ProjectTreeView : public NavigationTreeView
{
public:
ProjectTreeView()
@@ -138,7 +199,7 @@ public:
connect(newModel, &QAbstractItemModel::rowsRemoved,
this, &ProjectTreeView::invalidateSize);
}
- Utils::NavigationTreeView::setModel(newModel);
+ NavigationTreeView::setModel(newModel);
}
~ProjectTreeView()
@@ -150,7 +211,7 @@ public:
int sizeHintForColumn(int column) const override
{
if (m_cachedSize < 0)
- m_cachedSize = Utils::NavigationTreeView::sizeHintForColumn(column);
+ m_cachedSize = NavigationTreeView::sizeHintForColumn(column);
return m_cachedSize;
}
@@ -172,7 +233,7 @@ ProjectTreeWidget::ProjectTreeWidget(QWidget *parent) : QWidget(parent)
m_model = new FlatModel(this);
m_view = new ProjectTreeView;
m_view->setModel(m_model);
- m_view->setItemDelegate(new ProjectTreeItemDelegate(this));
+ m_view->setItemDelegate(new ProjectTreeItemDelegate(m_view));
setFocusProxy(m_view);
m_view->installEventFilter(this);
@@ -217,14 +278,14 @@ ProjectTreeWidget::ProjectTreeWidget(QWidget *parent) : QWidget(parent)
m_model, &FlatModel::onCollapsed);
m_toggleSync = new QToolButton;
- m_toggleSync->setIcon(Utils::Icons::LINK.icon());
+ m_toggleSync->setIcon(Icons::LINK.icon());
m_toggleSync->setCheckable(true);
m_toggleSync->setChecked(autoSynchronization());
m_toggleSync->setToolTip(tr("Synchronize with Editor"));
connect(m_toggleSync, &QAbstractButton::clicked,
this, &ProjectTreeWidget::toggleAutoSynchronization);
- setCurrentItem(ProjectTree::currentNode());
+ setCurrentItem(ProjectTree::findCurrentNode());
setAutoSynchronization(true);
m_projectTreeWidgets << this;
@@ -276,7 +337,7 @@ void ProjectTreeWidget::rowsInserted(const QModelIndex &parent, int start, int e
}
}
-Node *ProjectTreeWidget::nodeForFile(const Utils::FileName &fileName)
+Node *ProjectTreeWidget::nodeForFile(const FileName &fileName)
{
Node *bestNode = nullptr;
int bestNodeExpandCount = INT_MAX;
@@ -334,7 +395,7 @@ void ProjectTreeWidget::setAutoSynchronization(bool sync)
if (m_autoSync) {
// sync from document manager
- Utils::FileName fileName;
+ FileName fileName;
if (IDocument *doc = EditorManager::currentDocument())
fileName = doc->filePath();
if (!currentNode() || currentNode()->filePath() != fileName)
@@ -354,7 +415,7 @@ void ProjectTreeWidget::editCurrentItem()
m_view->edit(m_view->selectionModel()->currentIndex());
}
-void ProjectTreeWidget::renamed(const Utils::FileName &oldPath, const Utils::FileName &newPath)
+void ProjectTreeWidget::renamed(const FileName &oldPath, const FileName &newPath)
{
update();
Q_UNUSED(oldPath);
@@ -406,8 +467,8 @@ void ProjectTreeWidget::showMessage(Node *node, const QString &message)
m_view->scrollTo(idx);
QPoint pos = m_view->mapToGlobal(m_view->visualRect(idx).bottomLeft());
- pos -= Utils::ToolTip::offsetFromPosition();
- Utils::ToolTip::show(pos, message);
+ pos -= ToolTip::offsetFromPosition();
+ ToolTip::show(pos, message);
}
void ProjectTreeWidget::showContextMenu(const QPoint &pos)
@@ -471,7 +532,7 @@ NavigationView ProjectTreeWidgetFactory::createWidget()
n.widget = ptw;
auto filter = new QToolButton;
- filter->setIcon(Utils::Icons::FILTER.icon());
+ filter->setIcon(Icons::FILTER.icon());
filter->setToolTip(tr("Filter Tree"));
filter->setPopupMode(QToolButton::InstantPopup);
filter->setProperty("noArrow", true);
diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp
index e70f93a707e..db50d1cafaf 100644
--- a/src/plugins/projectexplorer/runconfiguration.cpp
+++ b/src/plugins/projectexplorer/runconfiguration.cpp
@@ -173,34 +173,75 @@ void IRunConfigurationAspect::resetProjectToGlobalSettings()
A run configuration specifies how a target should be run, while a runner
does the actual running.
- All RunControls and the target hold a shared pointer to the run
- configuration. That is, the lifetime of the run configuration might exceed
- the life of the target.
- The user might still have a RunControl running (or output tab of that RunControl open)
- and yet unloaded the target.
-
- Also, a run configuration might be already removed from the list of run
- configurations
- for a target, but still be runnable via the output tab.
+ The target owns the RunConfiguraitons and a RunControl will need to copy all
+ necessary data as the RunControl may continue to exist after the RunConfiguration
+ has been destroyed.
+
+ A RunConfiguration disables itself when the project is parsing or has no parsing
+ data available. The disabledReason() method can be used to get a user-facing string
+ describing why the RunConfiguration considers itself unfit for use.
+
+ Override updateEnabledState() to change the enabled state handling. Override
+ disabledReasons() to provide better/more descriptions to the user.
+
+ Connect signals that may change enabled state of your RunConfiguration to updateEnabledState.
*/
static std::vector<RunConfiguration::AspectFactory> theAspectFactories;
-RunConfiguration::RunConfiguration(Target *target, Core::Id id) :
- ProjectConfiguration(target, id)
+RunConfiguration::RunConfiguration(Target *target)
+ : StatefulProjectConfiguration(target)
{
Q_ASSERT(target);
- ctor();
+
+ connect(target->project(), &Project::parsingStarted,
+ this, [this]() { updateEnabledState(); });
+ connect(target->project(), &Project::parsingFinished,
+ this, [this]() { updateEnabledState(); });
+
+ connect(target, &Target::addedRunConfiguration,
+ this, [this](const RunConfiguration *rc) {
+ if (rc == this)
+ updateEnabledState();
+ });
+
+ connect(this, &RunConfiguration::enabledChanged,
+ this, &RunConfiguration::requestRunActionsUpdate);
+
+ Utils::MacroExpander *expander = macroExpander();
+ expander->setDisplayName(tr("Run Settings"));
+ expander->setAccumulating(true);
+ expander->registerSubProvider([target] {
+ BuildConfiguration *bc = target->activeBuildConfiguration();
+ return bc ? bc->macroExpander() : target->macroExpander();
+ });
+ expander->registerPrefix("CurrentRun:Env", tr("Variables in the current run environment"),
+ [this](const QString &var) {
+ const auto envAspect = extraAspect<EnvironmentAspect>();
+ return envAspect ? envAspect->environment().value(var) : QString();
+ });
+ expander->registerVariable(Constants::VAR_CURRENTRUN_NAME,
+ QCoreApplication::translate("ProjectExplorer", "The currently active run configuration's name."),
+ [this] { return displayName(); }, false);
+}
+
+RunConfiguration::~RunConfiguration()
+{
+ qDeleteAll(m_aspects);
+}
+
+void RunConfiguration::initialize(Core::Id id)
+{
+ StatefulProjectConfiguration::initialize(id);
for (const AspectFactory &factory : theAspectFactories)
addExtraAspect(factory(this));
}
-RunConfiguration::RunConfiguration(Target *target, RunConfiguration *source) :
- ProjectConfiguration(target, source)
+void RunConfiguration::copyFrom(const RunConfiguration *source)
{
- Q_ASSERT(target);
- ctor();
+ StatefulProjectConfiguration::copyFrom(source);
+
foreach (IRunConfigurationAspect *aspect, source->m_aspects) {
IRunConfigurationAspect *clone = aspect->clone(this);
if (clone)
@@ -208,9 +249,25 @@ RunConfiguration::RunConfiguration(Target *target, RunConfiguration *source) :
}
}
-RunConfiguration::~RunConfiguration()
+bool RunConfiguration::isActive() const
{
- qDeleteAll(m_aspects);
+ return target()->isActive() && target()->activeRunConfiguration() == this;
+}
+
+QString RunConfiguration::disabledReason() const
+{
+ if (target()->project()->isParsing())
+ return tr("The Project is currently being parsed.");
+ if (!target()->project()->hasParsingData())
+ return tr("The project could not be fully parsed.");
+ return QString();
+}
+
+void RunConfiguration::updateEnabledState()
+{
+ Project *p = target()->project();
+
+ setEnabled(!p->isParsing() && p->hasParsingData());
}
void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory)
@@ -224,28 +281,6 @@ void RunConfiguration::addExtraAspect(IRunConfigurationAspect *aspect)
m_aspects += aspect;
}
-void RunConfiguration::ctor()
-{
- connect(this, &RunConfiguration::enabledChanged,
- this, &RunConfiguration::requestRunActionsUpdate);
-
- Utils::MacroExpander *expander = macroExpander();
- expander->setDisplayName(tr("Run Settings"));
- expander->setAccumulating(true);
- expander->registerSubProvider([this]() -> Utils::MacroExpander * {
- BuildConfiguration *bc = target()->activeBuildConfiguration();
- return bc ? bc->macroExpander() : target()->macroExpander();
- });
- expander->registerPrefix("CurrentRun:Env", tr("Variables in the current run environment"),
- [this](const QString &var) {
- const auto envAspect = extraAspect<EnvironmentAspect>();
- return envAspect ? envAspect->environment().value(var) : QString();
- });
- expander->registerVariable(Constants::VAR_CURRENTRUN_NAME,
- QCoreApplication::translate("ProjectExplorer", "The currently active run configuration's name."),
- [this] { return displayName(); }, false);
-}
-
/*!
* Returns the RunConfiguration of the currently active target
* of the startup project, if such exists, or \c nullptr otherwise.
@@ -260,20 +295,6 @@ RunConfiguration *RunConfiguration::startupRunConfiguration()
return nullptr;
}
-/*!
- Checks whether a run configuration is enabled.
-*/
-
-bool RunConfiguration::isEnabled() const
-{
- return true;
-}
-
-QString RunConfiguration::disabledReason() const
-{
- return QString();
-}
-
bool RunConfiguration::isConfigured() const
{
return true;
@@ -288,7 +309,6 @@ RunConfiguration::ConfigurationState RunConfiguration::ensureConfigured(QString
return UnConfigured;
}
-
BuildConfiguration *RunConfiguration::activeBuildConfiguration() const
{
if (!target())
@@ -301,6 +321,11 @@ Target *RunConfiguration::target() const
return static_cast<Target *>(parent());
}
+Project *RunConfiguration::project() const
+{
+ return target()->project();
+}
+
QVariantMap RunConfiguration::toMap() const
{
QVariantMap map = ProjectConfiguration::toMap();
@@ -615,6 +640,7 @@ public:
void initiateReStart();
void continueStart();
void initiateStop();
+ void forceStop();
void continueStopOrFinish();
void initiateFinish();
@@ -699,6 +725,11 @@ void RunControl::initiateStop()
d->initiateStop();
}
+void RunControl::forceStop()
+{
+ d->forceStop();
+}
+
void RunControl::initiateFinish()
{
QTimer::singleShot(0, d, &RunControlPrivate::initiateFinish);
@@ -896,6 +927,43 @@ void RunControlPrivate::continueStopOrFinish()
}
}
+void RunControlPrivate::forceStop()
+{
+ if (state == RunControlState::Finished) {
+ debugMessage("Was finished, too late to force Stop");
+ return;
+ }
+ for (RunWorker *worker : m_workers) {
+ if (worker) {
+ const QString &workerId = worker->d->id;
+ debugMessage(" Examining worker " + workerId);
+ switch (worker->d->state) {
+ case RunWorkerState::Initialized:
+ debugMessage(" " + workerId + " was Initialized, setting to Done");
+ break;
+ case RunWorkerState::Stopping:
+ debugMessage(" " + workerId + " was already Stopping. Set it forcefully to Done.");
+ break;
+ case RunWorkerState::Starting:
+ debugMessage(" " + workerId + " was Starting. Set it forcefully to Done.");
+ break;
+ case RunWorkerState::Running:
+ debugMessage(" " + workerId + " was Running. Set it forcefully to Done.");
+ break;
+ case RunWorkerState::Done:
+ debugMessage(" " + workerId + " was Done. Good.");
+ break;
+ }
+ worker->d->state = RunWorkerState::Done;
+ } else {
+ debugMessage("Found unknown deleted worker");
+ }
+ }
+
+ setState(RunControlState::Stopped);
+ debugMessage("All Stopped");
+}
+
void RunControlPrivate::initiateFinish()
{
setState(RunControlState::Finishing);
diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h
index 04607352062..51f5c7b2e25 100644
--- a/src/plugins/projectexplorer/runconfiguration.h
+++ b/src/plugins/projectexplorer/runconfiguration.h
@@ -199,15 +199,17 @@ private:
};
// Documentation inside.
-class PROJECTEXPLORER_EXPORT RunConfiguration : public ProjectConfiguration
+class PROJECTEXPLORER_EXPORT RunConfiguration : public StatefulProjectConfiguration
{
Q_OBJECT
public:
~RunConfiguration() override;
- virtual bool isEnabled() const;
- virtual QString disabledReason() const;
+ bool isActive() const override;
+
+ QString disabledReason() const override;
+
virtual QWidget *createConfigurationWidget() = 0;
virtual bool isConfigured() const;
@@ -217,6 +219,7 @@ public:
virtual ConfigurationState ensureConfigured(QString *errorMessage = nullptr);
Target *target() const;
+ Project *project() const override;
virtual Utils::OutputFormatter *createOutputFormatter() const;
@@ -252,20 +255,22 @@ public:
}
signals:
- void enabledChanged();
void requestRunActionsUpdate();
void configurationFinished();
protected:
- RunConfiguration(Target *parent, Core::Id id);
- RunConfiguration(Target *parent, RunConfiguration *source);
+ friend class IRunConfigurationFactory;
+
+ RunConfiguration(Target *target);
+ void initialize(Core::Id id);
+ void copyFrom(const RunConfiguration *source);
/// convenience function to get current build configuration.
BuildConfiguration *activeBuildConfiguration() const;
-private:
- void ctor();
+ virtual void updateEnabledState();
+private:
static void addAspectFactory(const AspectFactory &aspectFactory);
QList<IRunConfigurationAspect *> m_aspects;
@@ -293,6 +298,20 @@ public:
static IRunConfigurationFactory *find(Target *parent, RunConfiguration *rc);
static QList<IRunConfigurationFactory *> find(Target *parent);
+ template <class RunConfig, typename ...Args>
+ static RunConfig *createHelper(Target *target, Args ...args) {
+ auto runConfig = new RunConfig(target);
+ runConfig->initialize(args...);
+ return runConfig;
+ }
+
+ template <class RunConfig>
+ static RunConfig *cloneHelper(Target *target, const RunConfiguration *source) {
+ auto runConfig = new RunConfig(target);
+ runConfig->copyFrom(static_cast<const RunConfig *>(source));
+ return runConfig;
+ }
+
signals:
void availableCreationIdsChanged();
@@ -392,6 +411,7 @@ public:
void initiateStart();
void initiateReStart();
void initiateStop();
+ void forceStop();
void initiateFinish();
bool promptToStop(bool *optionalPrompt = nullptr) const;
diff --git a/src/plugins/projectexplorer/runconfigurationmodel.cpp b/src/plugins/projectexplorer/runconfigurationmodel.cpp
deleted file mode 100644
index 45d7bf06686..00000000000
--- a/src/plugins/projectexplorer/runconfigurationmodel.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "runconfigurationmodel.h"
-#include "target.h"
-#include "runconfiguration.h"
-
-#include <utils/algorithm.h>
-
-using namespace ProjectExplorer;
-
-/*!
- \class ProjectExplorer::RunConfigurationModel
-
- \brief The RunConfigurationModel class provides a model to represent the
- run configurations of a target.
-
- To be used in the dropdown lists of comboboxes.
- Automatically adjusts itself to added and removed run configurations.
-*/
-
-class RunConfigurationComparer
-{
-public:
- bool operator()(RunConfiguration *a, RunConfiguration *b)
- {
- return a->displayName() < b->displayName();
- }
-};
-
-RunConfigurationModel::RunConfigurationModel(Target *target, QObject *parent) :
- QAbstractListModel(parent),
- m_target(target)
-{
- QTC_ASSERT(target, return);
- m_runConfigurations = m_target->runConfigurations();
- Utils::sort(m_runConfigurations, RunConfigurationComparer());
-
- connect(target, &Target::addedRunConfiguration,
- this, &RunConfigurationModel::addedRunConfiguration);
- connect(target, &Target::removedRunConfiguration,
- this, &RunConfigurationModel::removedRunConfiguration);
-
- foreach (RunConfiguration *rc, m_runConfigurations)
- connect(rc, &ProjectConfiguration::displayNameChanged,
- this, &RunConfigurationModel::displayNameChanged);
-}
-
-int RunConfigurationModel::rowCount(const QModelIndex &parent) const
-{
- return parent.isValid() ? 0 : m_runConfigurations.size();
-}
-
-int RunConfigurationModel::columnCount(const QModelIndex &parent) const
-{
- return parent.isValid() ? 0 : 1;
-}
-
-void RunConfigurationModel::displayNameChanged()
-{
- RunConfiguration *rc = qobject_cast<RunConfiguration *>(sender());
- if (!rc)
- return;
-
- RunConfigurationComparer compare;
- // Find the old position
- int oldPos = m_runConfigurations.indexOf(rc);
-
- if (oldPos >= 1 && compare(m_runConfigurations.at(oldPos), m_runConfigurations.at(oldPos - 1))) {
- // We need to move up
- int newPos = oldPos - 1;
- while (newPos >= 0 && compare(m_runConfigurations.at(oldPos), m_runConfigurations.at(newPos))) {
- --newPos;
- }
- ++newPos;
-
- beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
- m_runConfigurations.insert(newPos, rc);
- m_runConfigurations.removeAt(oldPos + 1);
- endMoveRows();
- // Not only did we move, we also changed...
- emit dataChanged(index(newPos, 0), index(newPos,0));
- } else if (oldPos < m_runConfigurations.size() - 1
- && compare(m_runConfigurations.at(oldPos + 1), m_runConfigurations.at(oldPos))) {
- // We need to move down
- int newPos = oldPos + 1;
- while (newPos < m_runConfigurations.size()
- && compare(m_runConfigurations.at(newPos), m_runConfigurations.at(oldPos))) {
- ++newPos;
- }
- beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
- m_runConfigurations.insert(newPos, rc);
- m_runConfigurations.removeAt(oldPos);
- endMoveRows();
-
- // We need to subtract one since removing at the old place moves the newIndex down
- emit dataChanged(index(newPos - 1, 0), index(newPos - 1, 0));
- } else {
- emit dataChanged(index(oldPos, 0), index(oldPos, 0));
- }
-}
-
-QVariant RunConfigurationModel::data(const QModelIndex &index, int role) const
-{
- if (role == Qt::DisplayRole) {
- const int row = index.row();
- if (row < m_runConfigurations.size())
- return m_runConfigurations.at(row)->displayName();
- }
-
- return QVariant();
-}
-
-RunConfiguration *RunConfigurationModel::runConfigurationAt(int i)
-{
- if (i > m_runConfigurations.size() || i < 0)
- return nullptr;
- return m_runConfigurations.at(i);
-}
-
-RunConfiguration *RunConfigurationModel::runConfigurationFor(const QModelIndex &idx)
-{
- if (idx.row() > m_runConfigurations.size() || idx.row() < 0)
- return nullptr;
- return m_runConfigurations.at(idx.row());
-}
-
-QModelIndex RunConfigurationModel::indexFor(RunConfiguration *rc)
-{
- int idx = m_runConfigurations.indexOf(rc);
- if (idx == -1)
- return QModelIndex();
- return index(idx, 0);
-}
-
-void RunConfigurationModel::addedRunConfiguration(RunConfiguration *rc)
-{
- // Find the right place to insert
- RunConfigurationComparer compare;
- int i = 0;
- for (; i < m_runConfigurations.size(); ++i) {
- if (compare(rc, m_runConfigurations.at(i)))
- break;
- }
-
- beginInsertRows(QModelIndex(), i, i);
- m_runConfigurations.insert(i, rc);
- endInsertRows();
-
-
- connect(rc, &ProjectConfiguration::displayNameChanged,
- this, &RunConfigurationModel::displayNameChanged);
-}
-
-void RunConfigurationModel::removedRunConfiguration(RunConfiguration *rc)
-{
- int i = m_runConfigurations.indexOf(rc);
- if (i < 0)
- return;
-
- beginRemoveRows(QModelIndex(), i, i);
- m_runConfigurations.removeAt(i);
- endRemoveRows();
-}
diff --git a/src/plugins/projectexplorer/runnables.cpp b/src/plugins/projectexplorer/runnables.cpp
index 3ac15f53ef7..33d612f0adc 100644
--- a/src/plugins/projectexplorer/runnables.cpp
+++ b/src/plugins/projectexplorer/runnables.cpp
@@ -46,6 +46,7 @@ QUrl urlFromLocalHostAndFreePort()
{
QUrl serverUrl;
QTcpServer server;
+ serverUrl.setScheme(urlTcpScheme());
if (server.listen(QHostAddress::LocalHost) || server.listen(QHostAddress::LocalHostIPv6)) {
serverUrl.setHost(server.serverAddress().toString());
serverUrl.setPort(server.serverPort());
@@ -68,4 +69,9 @@ QString urlSocketScheme()
return QString("socket");
}
+QString urlTcpScheme()
+{
+ return QString("tcp");
+}
+
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/runnables.h b/src/plugins/projectexplorer/runnables.h
index f28aefeda4b..a893545d23a 100644
--- a/src/plugins/projectexplorer/runnables.h
+++ b/src/plugins/projectexplorer/runnables.h
@@ -56,5 +56,6 @@ PROJECTEXPLORER_EXPORT bool operator==(const StandardRunnable &r1, const Standar
PROJECTEXPLORER_EXPORT QUrl urlFromLocalHostAndFreePort();
PROJECTEXPLORER_EXPORT QUrl urlFromLocalSocket();
PROJECTEXPLORER_EXPORT QString urlSocketScheme();
+PROJECTEXPLORER_EXPORT QString urlTcpScheme();
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
index 88fb230f05e..7930a783368 100644
--- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
@@ -27,11 +27,10 @@
#include "buildstepspage.h"
#include "deployconfiguration.h"
-#include "deployconfigurationmodel.h"
-#include "runconfigurationmodel.h"
#include "runconfiguration.h"
#include "target.h"
#include "project.h"
+#include "projectconfigurationmodel.h"
#include "session.h"
#include <extensionsystem/pluginmanager.h>
@@ -39,6 +38,7 @@
#include <projectexplorer/buildmanager.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
+#include <utils/utilsicons.h>
#include <QVariant>
#include <QAction>
@@ -184,6 +184,16 @@ RunSettingsWidget::RunSettingsWidget(Target *target) :
m_runLayout->setMargin(0);
m_runLayout->setSpacing(5);
+ m_disabledIcon = new QLabel;
+ m_disabledIcon->setPixmap(Utils::Icons::WARNING.pixmap());
+ m_disabledText = new QLabel;
+ auto disabledHBox = new QHBoxLayout;
+ disabledHBox->addWidget(m_disabledIcon);
+ disabledHBox->addWidget(m_disabledText);
+ disabledHBox->addStretch(255);
+
+ m_runLayout->addLayout(disabledHBox);
+
m_addRunMenu = new QMenu(m_addRunToolButton);
m_addRunToolButton->setMenu(m_addRunMenu);
RunConfiguration *rc = m_target->activeRunConfiguration();
@@ -303,7 +313,7 @@ void RunSettingsWidget::activeRunConfigurationChanged()
QModelIndex actRc = m_runConfigurationsModel->indexFor(m_target->activeRunConfiguration());
m_ignoreChange = true;
m_runConfigurationCombo->setCurrentIndex(actRc.row());
- setConfigurationWidget(m_runConfigurationsModel->runConfigurationAt(actRc.row()));
+ setConfigurationWidget(qobject_cast<RunConfiguration *>(m_runConfigurationsModel->projectConfigurationAt(actRc.row())));
m_ignoreChange = false;
m_renameRunButton->setEnabled(m_target->activeRunConfiguration());
}
@@ -333,7 +343,7 @@ void RunSettingsWidget::currentRunConfigurationChanged(int index)
RunConfiguration *selectedRunConfiguration = nullptr;
if (index >= 0)
- selectedRunConfiguration = m_runConfigurationsModel->runConfigurationAt(index);
+ selectedRunConfiguration = qobject_cast<RunConfiguration *>(m_runConfigurationsModel->projectConfigurationAt(index));
if (selectedRunConfiguration == m_runConfiguration)
return;
@@ -353,7 +363,8 @@ void RunSettingsWidget::currentDeployConfigurationChanged(int index)
if (index == -1)
SessionManager::setActiveDeployConfiguration(m_target, nullptr, SetActive::Cascade);
else
- SessionManager::setActiveDeployConfiguration(m_target, m_deployConfigurationModel->deployConfigurationAt(index),
+ SessionManager::setActiveDeployConfiguration(m_target,
+ qobject_cast<DeployConfiguration *>(m_deployConfigurationModel->projectConfigurationAt(index)),
SetActive::Cascade);
}
@@ -485,9 +496,12 @@ void RunSettingsWidget::setConfigurationWidget(RunConfiguration *rc)
return;
m_runConfigurationWidget = rc->createConfigurationWidget();
m_runConfiguration = rc;
- if (m_runConfigurationWidget)
+ if (m_runConfigurationWidget) {
m_runLayout->addWidget(m_runConfigurationWidget);
-
+ updateEnabledState();
+ connect(m_runConfiguration, &RunConfiguration::enabledChanged,
+ m_runConfigurationWidget, [this]() { updateEnabledState(); });
+ }
addRunControlWidgets();
}
@@ -561,3 +575,15 @@ void RunSettingsWidget::removeSubWidgets()
}
m_subWidgets.clear();
}
+
+void RunSettingsWidget::updateEnabledState()
+{
+ const bool enable = m_runConfiguration ? m_runConfiguration->isEnabled() : false;
+ const QString reason = m_runConfiguration ? m_runConfiguration->disabledReason() : QString();
+
+ m_runConfigurationWidget->setEnabled(enable);
+
+ m_disabledIcon->setVisible(!enable && !reason.isEmpty());
+ m_disabledText->setVisible(!enable && !reason.isEmpty());
+ m_disabledText->setText(reason);
+}
diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.h b/src/plugins/projectexplorer/runsettingspropertiespage.h
index 839a1e56887..5a551f94213 100644
--- a/src/plugins/projectexplorer/runsettingspropertiespage.h
+++ b/src/plugins/projectexplorer/runsettingspropertiespage.h
@@ -80,6 +80,8 @@ private:
void addSubWidget(RunConfigWidget *subWidget);
void removeSubWidgets();
+ void updateEnabledState();
+
Target *m_target;
RunConfigurationModel *m_runConfigurationsModel;
DeployConfigurationModel *m_deployConfigurationModel;
@@ -105,6 +107,8 @@ private:
QPushButton *m_removeRunToolButton;
QPushButton *m_renameRunButton;
QPushButton *m_renameDeployButton;
+ QLabel *m_disabledIcon;
+ QLabel *m_disabledText;
};
} // namespace Internal
diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp
index 432915f7770..458bc525469 100644
--- a/src/plugins/projectexplorer/session.cpp
+++ b/src/plugins/projectexplorer/session.cpp
@@ -30,6 +30,7 @@
#include "kit.h"
#include "buildconfiguration.h"
#include "deployconfiguration.h"
+#include "foldernavigationwidget.h"
#include "projectexplorer.h"
#include "projectnodes.h"
#include "editorconfiguration.h"
@@ -134,9 +135,9 @@ SessionManager::SessionManager(QObject *parent) : QObject(parent)
connect(this, &SessionManager::projectDisplayNameChanged,
EditorManager::instance(), &EditorManager::updateWindowTitles);
connect(EditorManager::instance(), &EditorManager::editorOpened,
- [this] { markSessionFileDirty(); });
+ this, [] { markSessionFileDirty(); });
connect(EditorManager::instance(), &EditorManager::editorsClosed,
- [this] { markSessionFileDirty(); });
+ this, [] { markSessionFileDirty(); });
EditorManager::setWindowTitleAdditionHandler(&SessionManagerPrivate::windowTitleAddition);
EditorManager::setSessionTitleHandler(&SessionManagerPrivate::sessionTitle);
@@ -385,6 +386,8 @@ void SessionManager::addProject(Project *pro)
m_instance, [pro]() { m_instance->projectDisplayNameChanged(pro); });
emit m_instance->projectAdded(pro);
+ FolderNavigationWidgetFactory::addRootDirectory(pro->displayName(),
+ pro->projectFilePath().parentDir());
configureEditors(pro);
connect(pro, &Project::fileListChanged, [pro](){ configureEditors(pro); });
}
@@ -739,6 +742,7 @@ void SessionManager::removeProjects(QList<Project *> remove)
m_instance, &SessionManager::clearProjectFileCache);
d->m_projectFileCache.remove(pro);
emit m_instance->projectRemoved(pro);
+ FolderNavigationWidgetFactory::removeRootDirectory(pro->projectFilePath().parentDir());
delete pro;
}
@@ -855,7 +859,7 @@ bool SessionManager::cloneSession(const QString &original, const QString &clone)
// If the file does not exist, we can still clone
if (!fi.exists() || fi.copy(sessionNameToFileName(clone).toString())) {
d->m_sessions.insert(1, clone);
- d->m_sessionDateTimes.insert(clone, QFileInfo(sessionNameToFileName(clone).toString()).lastModified());
+ d->m_sessionDateTimes.insert(clone, sessionNameToFileName(clone).toFileInfo().lastModified());
return true;
}
return false;
diff --git a/src/plugins/projectexplorer/sessiondialog.ui b/src/plugins/projectexplorer/sessiondialog.ui
index fd41eeacec1..21f2195a5ce 100644
--- a/src/plugins/projectexplorer/sessiondialog.ui
+++ b/src/plugins/projectexplorer/sessiondialog.ui
@@ -87,9 +87,6 @@
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="autoLoadCheckBox">
- <property name="toolTip">
- <string>Automatically restores the last session when Qt Creator is started.</string>
- </property>
<property name="text">
<string>Restore last session on startup</string>
</property>
diff --git a/src/plugins/projectexplorer/settingsaccessor.cpp b/src/plugins/projectexplorer/settingsaccessor.cpp
index 49b24103f5a..6b413d702c0 100644
--- a/src/plugins/projectexplorer/settingsaccessor.cpp
+++ b/src/plugins/projectexplorer/settingsaccessor.cpp
@@ -35,6 +35,7 @@
#include "kit.h"
#include "kitmanager.h"
+#include <app/app_version.h>
#include <coreplugin/icore.h>
#include <utils/persistentsettings.h>
#include <utils/hostosinfo.h>
@@ -837,11 +838,12 @@ SettingsAccessor::IssueInfo SettingsAccessor::findIssues(const QVariantMap &data
result.message = QApplication::translate("Utils::SettingsAccessor",
"<p>The versioned backup \"%1\" of the settings "
"file is used, because the non-versioned file was "
- "created by an incompatible version of Qt Creator.</p>"
+ "created by an incompatible version of %2.</p>"
"<p>Settings changes made since the last time this "
- "version of Qt Creator was used are ignored, and "
+ "version of %2 was used are ignored, and "
"changes made now will <b>not</b> be propagated to "
- "the newer version.</p>").arg(path.toUserOutput());
+ "the newer version.</p>").arg(path.toUserOutput())
+ .arg(Core::Constants::IDE_DISPLAY_NAME);
result.buttons.insert(QMessageBox::Ok, Continue);
}
@@ -853,10 +855,11 @@ SettingsAccessor::IssueInfo SettingsAccessor::findIssues(const QVariantMap &data
result.title = differentEnvironmentMsg(project()->displayName());
result.message = QApplication::translate("ProjectExplorer::EnvironmentIdAccessor",
"<p>No .user settings file created by this instance "
- "of Qt Creator was found.</p>"
+ "of %1 was found.</p>"
"<p>Did you work with this project on another machine or "
"using a different settings path before?</p>"
- "<p>Do you still want to load the settings file \"%1\"?</p>")
+ "<p>Do you still want to load the settings file \"%2\"?</p>")
+ .arg(Core::Constants::IDE_DISPLAY_NAME)
.arg(path.toUserOutput());
result.defaultButton = QMessageBox::No;
result.escapeButton = QMessageBox::No;
@@ -1093,8 +1096,9 @@ QVariantMap SettingsAccessor::readSharedSettings(QWidget *parent) const
"Unsupported Shared Settings File"),
QApplication::translate("ProjectExplorer::SettingsAccessor",
"The version of your .shared file is not "
- "supported by Qt Creator. "
- "Do you want to try loading it anyway?"),
+ "supported by %1. "
+ "Do you want to try loading it anyway?")
+ .arg(Core::Constants::IDE_DISPLAY_NAME),
QMessageBox::Yes | QMessageBox::No,
parent);
msgBox.setDefaultButton(QMessageBox::No);
diff --git a/src/plugins/projectexplorer/subscription.cpp b/src/plugins/projectexplorer/subscription.cpp
new file mode 100644
index 00000000000..4ee9db21b1b
--- /dev/null
+++ b/src/plugins/projectexplorer/subscription.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "subscription.h"
+
+#include "project.h"
+#include "projectconfiguration.h"
+#include "target.h"
+
+#include <utils/asconst.h>
+
+namespace ProjectExplorer {
+namespace Internal {
+
+Subscription::Subscription(const Subscription::Connector &s, const QObject *receiver, QObject *parent) :
+ QObject(parent), m_subscriber(s)
+{
+ if (receiver != parent)
+ connect(receiver, &QObject::destroyed, this, &QObject::deleteLater);
+}
+
+Subscription::~Subscription()
+{
+ for (const auto &c : Utils::asConst(m_connections))
+ disconnect(c);
+}
+
+void Subscription::subscribe(ProjectConfiguration *pc)
+{
+ if (!m_subscriber)
+ return;
+ QMetaObject::Connection conn = m_subscriber(pc);
+ if (conn)
+ m_connections.insert(pc, conn);
+}
+
+void Subscription::unsubscribe(ProjectConfiguration *pc)
+{
+ auto c = m_connections.value(pc);
+ if (c) {
+ disconnect(c);
+ m_connections.remove(pc);
+ }
+}
+
+ProjectSubscription::ProjectSubscription(const Subscription::Connector &s, const QObject *r,
+ Project *p) :
+ Subscription(s, r, p)
+{
+ if (m_subscriber) {
+ for (const Target *t : p->targets()) {
+ for (ProjectConfiguration *pc : t->projectConfigurations())
+ m_subscriber(pc);
+ }
+ connect(p, &Project::addedProjectConfiguration, this, &ProjectSubscription::subscribe);
+ connect(p, &Project::removedProjectConfiguration, this, &ProjectSubscription::unsubscribe);
+ }
+}
+
+ProjectSubscription::~ProjectSubscription() = default;
+
+TargetSubscription::TargetSubscription(const Subscription::Connector &s, const QObject *r,
+ Target *t) :
+ Subscription(s, r, t)
+{
+ for (ProjectConfiguration *pc : t->projectConfigurations())
+ m_subscriber(pc);
+ connect(t, &Target::addedProjectConfiguration, this, &TargetSubscription::subscribe);
+ connect(t, &Target::removedProjectConfiguration, this, &TargetSubscription::unsubscribe);
+}
+
+TargetSubscription::~TargetSubscription() = default;
+
+} // namespace Internal
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/deployconfigurationmodel.h b/src/plugins/projectexplorer/subscription.h
index 95b6092898d..5c1e0ec1a46 100644
--- a/src/plugins/projectexplorer/deployconfigurationmodel.h
+++ b/src/plugins/projectexplorer/subscription.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,35 +25,51 @@
#pragma once
-#include <QAbstractItemModel>
+#include "projectexplorer_export.h"
+
+#include <QHash>
+#include <QObject>
+
+#include <functional>
namespace ProjectExplorer {
+class Project;
+class ProjectConfiguration;
class Target;
-class DeployConfiguration;
-// Documentation inside.
-class DeployConfigurationModel : public QAbstractListModel
+namespace Internal {
+
+class PROJECTEXPLORER_EXPORT Subscription : public QObject
{
Q_OBJECT
public:
- explicit DeployConfigurationModel(Target *target, QObject *parent = nullptr);
+ using Connector = std::function<QMetaObject::Connection(ProjectConfiguration *)>;
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ Subscription(const Connector &s, const QObject *receiver, QObject *parent);
+ ~Subscription() override;
- DeployConfiguration *deployConfigurationAt(int i);
- DeployConfiguration *deployConfigurationFor(const QModelIndex &idx);
- QModelIndex indexFor(DeployConfiguration *rc);
+protected:
+ void subscribe(ProjectConfiguration *pc);
+ void unsubscribe(ProjectConfiguration *pc);
+
+ Connector m_subscriber;
+ QHash<ProjectConfiguration *, QMetaObject::Connection> m_connections;
+};
-private:
- void addedDeployConfiguration(ProjectExplorer::DeployConfiguration*);
- void removedDeployConfiguration(ProjectExplorer::DeployConfiguration*);
- void displayNameChanged();
+class PROJECTEXPLORER_EXPORT ProjectSubscription : public Subscription
+{
+public:
+ ProjectSubscription(const Connector &s, const QObject *receiver, Project *p);
+ ~ProjectSubscription() final;
+};
- Target *m_target;
- QList<DeployConfiguration *> m_deployConfigurations;
+class PROJECTEXPLORER_EXPORT TargetSubscription : public Subscription
+{
+public:
+ TargetSubscription(const Connector &s, const QObject *receiver, Target *t);
+ ~TargetSubscription() final;
};
+} // namespace Internal
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp
index 3b480e8266e..221a8d55a24 100644
--- a/src/plugins/projectexplorer/target.cpp
+++ b/src/plugins/projectexplorer/target.cpp
@@ -115,9 +115,10 @@ QList<DeployConfigurationFactory *> TargetPrivate::deployFactories() const
}
Target::Target(Project *project, Kit *k) :
- ProjectConfiguration(project, k->id()),
+ ProjectConfiguration(project),
d(new TargetPrivate(k))
{
+ initialize(k->id());
QTC_CHECK(d->m_kit);
connect(DeviceManager::instance(), &DeviceManager::updated, this, &Target::updateDeviceState);
@@ -153,41 +154,6 @@ Target::~Target()
delete d;
}
-void Target::changeEnvironment()
-{
- auto bc = qobject_cast<BuildConfiguration *>(sender());
- if (bc == activeBuildConfiguration())
- emit environmentChanged();
-}
-
-void Target::changeBuildConfigurationEnabled()
-{
- auto bc = qobject_cast<BuildConfiguration *>(sender());
- if (bc == activeBuildConfiguration())
- emit buildConfigurationEnabledChanged();
-}
-
-void Target::changeDeployConfigurationEnabled()
-{
- auto dc = qobject_cast<DeployConfiguration *>(sender());
- if (dc == activeDeployConfiguration())
- emit deployConfigurationEnabledChanged();
-}
-
-void Target::changeRunConfigurationEnabled()
-{
- auto rc = qobject_cast<RunConfiguration *>(sender());
- if (rc == activeRunConfiguration())
- emit runConfigurationEnabledChanged();
-}
-
-void Target::onBuildDirectoryChanged()
-{
- auto bc = qobject_cast<BuildConfiguration *>(sender());
- if (bc && activeBuildConfiguration() == bc)
- emit buildDirectoryChanged();
-}
-
void Target::handleKitUpdates(Kit *k)
{
if (k != d->m_kit)
@@ -209,6 +175,11 @@ void Target::handleKitRemoval(Kit *k)
project()->removeTarget(this);
}
+bool Target::isActive() const
+{
+ return project()->activeTarget() == this;
+}
+
Project *Target::project() const
{
return static_cast<Project *>(parent());
@@ -238,15 +209,9 @@ void Target::addBuildConfiguration(BuildConfiguration *bc)
// add it
d->m_buildConfigurations.push_back(bc);
+ emit addedProjectConfiguration(bc);
emit addedBuildConfiguration(bc);
- connect(bc, &BuildConfiguration::environmentChanged,
- this, &Target::changeEnvironment);
- connect(bc, &BuildConfiguration::enabledChanged,
- this, &Target::changeBuildConfigurationEnabled);
- connect(bc, &BuildConfiguration::buildDirectoryChanged,
- this, &Target::onBuildDirectoryChanged);
-
if (!activeBuildConfiguration())
setActiveBuildConfiguration(bc);
}
@@ -261,8 +226,9 @@ bool Target::removeBuildConfiguration(BuildConfiguration *bc)
return false;
d->m_buildConfigurations.removeOne(bc);
+ emit aboutToRemoveProjectConfiguration(bc);
+ d->m_buildConfigurations.removeOne(bc);
- emit removedBuildConfiguration(bc);
if (activeBuildConfiguration() == bc) {
if (d->m_buildConfigurations.isEmpty())
@@ -271,6 +237,9 @@ bool Target::removeBuildConfiguration(BuildConfiguration *bc)
SessionManager::setActiveBuildConfiguration(this, d->m_buildConfigurations.at(0), SetActive::Cascade);
}
+ emit removedBuildConfiguration(bc);
+ emit removedProjectConfiguration(bc);
+
delete bc;
return true;
}
@@ -285,16 +254,14 @@ BuildConfiguration *Target::activeBuildConfiguration() const
return d->m_activeBuildConfiguration;
}
-void Target::setActiveBuildConfiguration(BuildConfiguration *configuration)
+void Target::setActiveBuildConfiguration(BuildConfiguration *bc)
{
- if ((!configuration && d->m_buildConfigurations.isEmpty()) ||
- (configuration && d->m_buildConfigurations.contains(configuration) &&
- configuration != d->m_activeBuildConfiguration)) {
- d->m_activeBuildConfiguration = configuration;
+ if ((!bc && d->m_buildConfigurations.isEmpty()) ||
+ (bc && d->m_buildConfigurations.contains(bc) &&
+ bc != d->m_activeBuildConfiguration)) {
+ d->m_activeBuildConfiguration = bc;
+ emit activeProjectConfigurationChanged(d->m_activeBuildConfiguration);
emit activeBuildConfigurationChanged(d->m_activeBuildConfiguration);
- emit environmentChanged();
- emit buildConfigurationEnabledChanged();
- emit buildDirectoryChanged();
}
}
@@ -315,9 +282,7 @@ void Target::addDeployConfiguration(DeployConfiguration *dc)
// add it
d->m_deployConfigurations.push_back(dc);
- connect(dc, &DeployConfiguration::enabledChanged,
- this, &Target::changeDeployConfigurationEnabled);
-
+ emit addedProjectConfiguration(dc);
emit addedDeployConfiguration(dc);
if (!d->m_activeDeployConfiguration)
@@ -334,10 +299,9 @@ bool Target::removeDeployConfiguration(DeployConfiguration *dc)
if (BuildManager::isBuilding(dc))
return false;
+ emit aboutToRemoveProjectConfiguration(dc);
d->m_deployConfigurations.removeOne(dc);
- emit removedDeployConfiguration(dc);
-
if (activeDeployConfiguration() == dc) {
if (d->m_deployConfigurations.isEmpty())
SessionManager::setActiveDeployConfiguration(this, nullptr, SetActive::Cascade);
@@ -346,6 +310,9 @@ bool Target::removeDeployConfiguration(DeployConfiguration *dc)
SetActive::Cascade);
}
+ emit removedProjectConfiguration(dc);
+ emit removedDeployConfiguration(dc);
+
delete dc;
return true;
}
@@ -366,8 +333,8 @@ void Target::setActiveDeployConfiguration(DeployConfiguration *dc)
(dc && d->m_deployConfigurations.contains(dc) &&
dc != d->m_activeDeployConfiguration)) {
d->m_activeDeployConfiguration = dc;
+ emit activeProjectConfigurationChanged(d->m_activeDeployConfiguration);
emit activeDeployConfigurationChanged(d->m_activeDeployConfiguration);
- emit deployConfigurationEnabledChanged();
}
updateDeviceState();
}
@@ -398,6 +365,15 @@ BuildTargetInfoList Target::applicationTargets() const
return d->m_appTargets;
}
+QList<ProjectConfiguration *> Target::projectConfigurations() const
+{
+ QList<ProjectConfiguration *> result;
+ result.append(Utils::transform(buildConfigurations(), [](BuildConfiguration *bc) { return qobject_cast<ProjectConfiguration *>(bc); }));
+ result.append(Utils::transform(deployConfigurations(), [](DeployConfiguration *dc) { return qobject_cast<ProjectConfiguration *>(dc); }));
+ result.append(Utils::transform(runConfigurations(), [](RunConfiguration *rc) { return qobject_cast<ProjectConfiguration *>(rc); }));
+ return result;
+}
+
QList<RunConfiguration *> Target::runConfigurations() const
{
return d->m_runConfigurations;
@@ -416,9 +392,7 @@ void Target::addRunConfiguration(RunConfiguration *rc)
d->m_runConfigurations.push_back(rc);
- connect(rc, &RunConfiguration::enabledChanged,
- this, &Target::changeRunConfigurationEnabled);
-
+ emit addedProjectConfiguration(rc);
emit addedRunConfiguration(rc);
if (!activeRunConfiguration())
@@ -429,6 +403,7 @@ void Target::removeRunConfiguration(RunConfiguration *rc)
{
QTC_ASSERT(rc && d->m_runConfigurations.contains(rc), return);
+ emit aboutToRemoveProjectConfiguration(rc);
d->m_runConfigurations.removeOne(rc);
if (activeRunConfiguration() == rc) {
@@ -439,6 +414,8 @@ void Target::removeRunConfiguration(RunConfiguration *rc)
}
emit removedRunConfiguration(rc);
+ emit removedProjectConfiguration(rc);
+
delete rc;
}
@@ -453,8 +430,8 @@ void Target::setActiveRunConfiguration(RunConfiguration *rc)
(rc && d->m_runConfigurations.contains(rc) &&
rc != d->m_activeRunConfiguration)) {
d->m_activeRunConfiguration = rc;
+ emit activeProjectConfigurationChanged(d->m_activeRunConfiguration);
emit activeRunConfigurationChanged(d->m_activeRunConfiguration);
- emit runConfigurationEnabledChanged();
}
updateDeviceState();
}
diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h
index 61f3ed56155..f3ed83ebf3d 100644
--- a/src/plugins/projectexplorer/target.h
+++ b/src/plugins/projectexplorer/target.h
@@ -28,6 +28,8 @@
#include "projectconfiguration.h"
#include "projectexplorer_export.h"
+#include "subscription.h"
+
QT_FORWARD_DECLARE_CLASS(QIcon)
namespace Utils { class Environment; }
@@ -55,14 +57,16 @@ class PROJECTEXPLORER_EXPORT Target : public ProjectConfiguration
public:
~Target() override;
- Project *project() const;
+ Project *project() const override;
+
+ bool isActive() const final;
// Kit:
Kit *kit() const;
// Build configuration
- void addBuildConfiguration(BuildConfiguration *configuration);
- bool removeBuildConfiguration(BuildConfiguration *configuration);
+ void addBuildConfiguration(BuildConfiguration *bc);
+ bool removeBuildConfiguration(BuildConfiguration *bc);
QList<BuildConfiguration *> buildConfigurations() const;
BuildConfiguration *activeBuildConfiguration() const;
@@ -80,13 +84,15 @@ public:
void setApplicationTargets(const BuildTargetInfoList &appTargets);
BuildTargetInfoList applicationTargets() const;
+ QList<ProjectConfiguration *> projectConfigurations() const;
+
// Running
QList<RunConfiguration *> runConfigurations() const;
- void addRunConfiguration(RunConfiguration *runConfiguration);
- void removeRunConfiguration(RunConfiguration *runConfiguration);
+ void addRunConfiguration(RunConfiguration *rc);
+ void removeRunConfiguration(RunConfiguration *rc);
RunConfiguration *activeRunConfiguration() const;
- void setActiveRunConfiguration(RunConfiguration *runConfiguration);
+ void setActiveRunConfiguration(RunConfiguration *rc);
// Returns whether this target is actually available at he time
// of the call. A target may become unavailable e.g. when a Qt version
@@ -108,6 +114,25 @@ public:
QVariant namedSettings(const QString &name) const;
void setNamedSettings(const QString &name, const QVariant &value);
+
+ template<typename S, typename R, typename T>
+ void subscribeSignal(void (S::*sig)(), R*recv, T (R::*sl)()) {
+ new Internal::TargetSubscription([sig, recv, sl, this](ProjectConfiguration *pc) {
+ if (S* sender = qobject_cast<S*>(pc))
+ return connect(sender, sig, recv, sl);
+ return QMetaObject::Connection();
+ }, recv, this);
+ }
+
+ template<typename S, typename R, typename T>
+ void subscribeSignal(void (S::*sig)(), R*recv, T sl) {
+ new Internal::TargetSubscription([sig, recv, sl, this](ProjectConfiguration *pc) {
+ if (S* sender = qobject_cast<S*>(pc))
+ return connect(sender, sig, recv, sl);
+ return QMetaObject::Connection();
+ }, recv, this);
+ }
+
signals:
void targetEnabled(bool);
void iconChanged();
@@ -115,6 +140,12 @@ signals:
void kitChanged();
+ void aboutToRemoveProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
+ void removedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
+ void addedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
+
+ void activeProjectConfigurationChanged(ProjectExplorer::ProjectConfiguration *pc);
+
// TODO clean up signal names
// might be better to also have aboutToRemove signals
void removedRunConfiguration(ProjectExplorer::RunConfiguration *rc);
@@ -129,24 +160,9 @@ signals:
void addedDeployConfiguration(ProjectExplorer::DeployConfiguration *dc);
void activeDeployConfigurationChanged(ProjectExplorer::DeployConfiguration *dc);
- /// convenience signal, emitted if either the active buildconfiguration emits
- /// environmentChanged() or if the active build configuration changes
- void environmentChanged();
-
- /// convenience signal, emitted if either the active configuration emits
- /// enabledChanged() or if the active build configuration changes
- void buildConfigurationEnabledChanged();
- void deployConfigurationEnabledChanged();
- void runConfigurationEnabledChanged();
-
void deploymentDataChanged();
void applicationTargetsChanged();
- // Remove all the signals below, they are stupid
- /// Emitted whenever the current build configuartion changed or the build directory of the current
- /// build configuration was changed.
- void buildDirectoryChanged();
-
private:
Target(Project *parent, Kit *k);
void setEnabled(bool);
@@ -154,10 +170,7 @@ private:
bool fromMap(const QVariantMap &map) override;
void updateDeviceState();
- void onBuildDirectoryChanged();
- void changeEnvironment();
- void changeBuildConfigurationEnabled();
void changeDeployConfigurationEnabled();
void changeRunConfigurationEnabled();
void handleKitUpdates(ProjectExplorer::Kit *k);
diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp
index de40db6c669..955cedc9566 100644
--- a/src/plugins/projectexplorer/targetsettingspanel.cpp
+++ b/src/plugins/projectexplorer/targetsettingspanel.cpp
@@ -41,6 +41,8 @@
#include "target.h"
#include "targetsetuppage.h"
+#include <app/app_version.h>
+
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/modemanager.h>
@@ -171,20 +173,22 @@ void TargetSetupPageWrapper::updateNoteText()
bool showHint = false;
if (!k) {
text = tr("The project <b>%1</b> is not yet configured.<br/>"
- "Qt Creator cannot parse the project, because no kit "
+ "%2 cannot parse the project, because no kit "
"has been set up.")
- .arg(m_project->displayName());
+ .arg(m_project->displayName(), Core::Constants::IDE_DISPLAY_NAME);
showHint = true;
} else if (k->isValid()) {
text = tr("The project <b>%1</b> is not yet configured.<br/>"
- "Qt Creator uses the kit <b>%2</b> to parse the project.")
+ "%2 uses the kit <b>%3</b> to parse the project.")
.arg(m_project->displayName())
+ .arg(Core::Constants::IDE_DISPLAY_NAME)
.arg(k->displayName());
showHint = false;
} else {
text = tr("The project <b>%1</b> is not yet configured.<br/>"
- "Qt Creator uses the <b>invalid</b> kit <b>%2</b> to parse the project.")
+ "%2 uses the <b>invalid</b> kit <b>%3</b> to parse the project.")
.arg(m_project->displayName())
+ .arg(Core::Constants::IDE_DISPLAY_NAME)
.arg(k->displayName());
showHint = true;
}
@@ -419,7 +423,7 @@ public:
QAction *disableAction = menu->addAction(tr("Disable Kit \"%1\" for Project \"%2\"").arg(kitName, projectName));
disableAction->setEnabled(m_kitId.isValid() && isEnabled());
- QObject::connect(disableAction, &QAction::triggered, [this, kit] {
+ QObject::connect(disableAction, &QAction::triggered, m_project, [this] {
Target *t = target();
QTC_ASSERT(t, return);
QString kitName = t->displayName();
@@ -763,7 +767,7 @@ TargetItem *TargetGroupItem::targetItem(Target *target) const
{
if (target) {
Id needle = target->id(); // Unconfigured project have no active target.
- return findFirstLevelChild([this, needle](TargetItem *item) { return item->m_kitId == needle; });
+ return findFirstLevelChild([needle](TargetItem *item) { return item->m_kitId == needle; });
}
return 0;
}
diff --git a/src/plugins/projectexplorer/targetsetuppage.cpp b/src/plugins/projectexplorer/targetsetuppage.cpp
index 0944b8f5b10..c84beaf226d 100644
--- a/src/plugins/projectexplorer/targetsetuppage.cpp
+++ b/src/plugins/projectexplorer/targetsetuppage.cpp
@@ -285,7 +285,7 @@ void TargetSetupPage::setProjectPath(const QString &path)
if (!m_projectPath.isEmpty()) {
QFileInfo fileInfo(QDir::cleanPath(path));
QStringList subDirsList = fileInfo.absolutePath().split('/');
- m_ui->headerLabel->setText(tr("Qt Creator can use the following kits for project <b>%1</b>:",
+ m_ui->headerLabel->setText(tr("The following kits can be used for project <b>%1</b>:",
"%1: Project name").arg(subDirsList.last()));
}
m_ui->headerLabel->setVisible(!m_projectPath.isEmpty());
diff --git a/src/plugins/projectexplorer/task.cpp b/src/plugins/projectexplorer/task.cpp
index 9d6f4a33168..0b34cec14cc 100644
--- a/src/plugins/projectexplorer/task.cpp
+++ b/src/plugins/projectexplorer/task.cpp
@@ -25,6 +25,7 @@
#include "task.h"
+#include <app/app_version.h>
#include <texteditor/textmark.h>
#include <utils/utilsicons.h>
#include <utils/qtcassert.h>
@@ -68,8 +69,9 @@ Task Task::compilerMissingTask()
{
return Task(Task::Error,
QCoreApplication::translate("ProjectExplorer::Task",
- "Qt Creator needs a compiler set up to build. "
- "Configure a compiler in the kit options."),
+ "%1 needs a compiler set up to build. "
+ "Configure a compiler in the kit options.")
+ .arg(Core::Constants::IDE_DISPLAY_NAME),
Utils::FileName(), -1,
Constants::TASK_CATEGORY_BUILDSYSTEM);
}
@@ -78,8 +80,9 @@ Task Task::buildConfigurationMissingTask()
{
return Task(Task::Error,
QCoreApplication::translate("ProjectExplorer::Task",
- "Qt Creator needs a build configuration set up to build. "
- "Configure a build configuration in the project settings."),
+ "%1 needs a build configuration set up to build. "
+ "Configure a build configuration in the project settings.")
+ .arg(Core::Constants::IDE_DISPLAY_NAME),
Utils::FileName(), -1,
Constants::TASK_CATEGORY_BUILDSYSTEM);
}
diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h
index 8c461bd3987..4ee56f05a8f 100644
--- a/src/plugins/projectexplorer/toolchain.h
+++ b/src/plugins/projectexplorer/toolchain.h
@@ -27,6 +27,7 @@
#include "projectexplorer_export.h"
#include "projectexplorer_global.h"
+#include "projectmacro.h"
#include <coreplugin/id.h>
@@ -122,9 +123,9 @@ public:
virtual WarningFlags warningFlags(const QStringList &cflags) const = 0;
// A PredefinedMacrosRunner is created in the ui thread and runs in another thread.
- using PredefinedMacrosRunner = std::function<QByteArray(const QStringList &cxxflags)>;
+ using PredefinedMacrosRunner = std::function<Macros(const QStringList &cxxflags)>;
virtual PredefinedMacrosRunner createPredefinedMacrosRunner() const = 0;
- virtual QByteArray predefinedMacros(const QStringList &cxxflags) const = 0;
+ virtual Macros predefinedMacros(const QStringList &cxxflags) const = 0;
// A SystemHeaderPathsRunner is created in the ui thread and runs in another thread.
using SystemHeaderPathsRunner = std::function<QList<HeaderPath>(const QStringList &cxxflags, const QString &sysRoot)>;
diff --git a/src/plugins/projectexplorer/toolchainmanager.cpp b/src/plugins/projectexplorer/toolchainmanager.cpp
index df7d6888ec1..b6c79b8773c 100644
--- a/src/plugins/projectexplorer/toolchainmanager.cpp
+++ b/src/plugins/projectexplorer/toolchainmanager.cpp
@@ -492,7 +492,7 @@ public:
Abi targetAbi() const override { return Abi::hostAbi(); }
bool isValid() const override { return m_valid; }
PredefinedMacrosRunner createPredefinedMacrosRunner() const override { return PredefinedMacrosRunner(); }
- QByteArray predefinedMacros(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return QByteArray(); }
+ Macros predefinedMacros(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return Macros(); }
CompilerFlags compilerFlags(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return NoFlags; }
WarningFlags warningFlags(const QStringList &cflags) const override { Q_UNUSED(cflags); return WarningFlags::NoWarnings; }
SystemHeaderPathsRunner createSystemHeaderPathsRunner() const override { return SystemHeaderPathsRunner(); }
diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp
index bb907067844..30fb0dcbb2e 100644
--- a/src/plugins/pythoneditor/pythoneditorplugin.cpp
+++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp
@@ -151,13 +151,11 @@ class PythonRunConfiguration : public RunConfiguration
Q_PROPERTY(QString arguments READ arguments)
public:
- PythonRunConfiguration(Target *parent, Core::Id id);
+ explicit PythonRunConfiguration(Target *target);
QWidget *createConfigurationWidget() override;
QVariantMap toMap() const override;
bool fromMap(const QVariantMap &map) override;
- bool isEnabled() const override { return m_enabled; }
- QString disabledReason() const override;
Runnable runnable() const override;
bool supportsDebugger() const { return true; }
@@ -165,42 +163,45 @@ public:
QString arguments() const;
QString interpreter() const { return m_interpreter; }
void setInterpreter(const QString &interpreter) { m_interpreter = interpreter; }
- void setEnabled(bool b);
private:
- friend class PythonRunConfigurationFactory;
- PythonRunConfiguration(Target *parent, PythonRunConfiguration *source);
+ friend class ProjectExplorer::IRunConfigurationFactory;
+ void initialize(Core::Id id);
+ void copyFrom(const PythonRunConfiguration *source);
+
QString defaultDisplayName() const;
QString m_interpreter;
QString m_mainScript;
- bool m_enabled;
};
////////////////////////////////////////////////////////////////
-PythonRunConfiguration::PythonRunConfiguration(Target *parent, Core::Id id) :
- RunConfiguration(parent, id),
- m_mainScript(scriptFromId(id)),
- m_enabled(true)
+PythonRunConfiguration::PythonRunConfiguration(Target *target)
+ : RunConfiguration(target)
{
- Environment sysEnv = Environment::systemEnvironment();
- const QString exec = sysEnv.searchInPath("python").toString();
- m_interpreter = exec.isEmpty() ? "python" : exec;
-
addExtraAspect(new LocalEnvironmentAspect(this, LocalEnvironmentAspect::BaseEnvironmentModifier()));
addExtraAspect(new ArgumentsAspect(this, "PythonEditor.RunConfiguration.Arguments"));
addExtraAspect(new TerminalAspect(this, "PythonEditor.RunConfiguration.UseTerminal"));
setDefaultDisplayName(defaultDisplayName());
}
-PythonRunConfiguration::PythonRunConfiguration(Target *parent, PythonRunConfiguration *source) :
- RunConfiguration(parent, source),
- m_interpreter(source->interpreter()),
- m_mainScript(source->m_mainScript),
- m_enabled(source->m_enabled)
+void PythonRunConfiguration::initialize(Core::Id id)
{
- setDefaultDisplayName(defaultDisplayName());
+ RunConfiguration::initialize(id);
+
+ m_mainScript = scriptFromId(id);
+
+ Environment sysEnv = Environment::systemEnvironment();
+ const QString exec = sysEnv.searchInPath("python").toString();
+ m_interpreter = exec.isEmpty() ? "python" : exec;
+}
+
+void PythonRunConfiguration::copyFrom(const PythonRunConfiguration *source)
+{
+ RunConfiguration::copyFrom(source);
+ m_interpreter = source->interpreter();
+ m_mainScript = source->m_mainScript;
}
QVariantMap PythonRunConfiguration::toMap() const
@@ -220,10 +221,7 @@ bool PythonRunConfiguration::fromMap(const QVariantMap &map)
QString PythonRunConfiguration::defaultDisplayName() const
{
- QString result = tr("Run %1").arg(m_mainScript);
- if (!m_enabled)
- result += ' ' + tr("(disabled)");
- return result;
+ return tr("Run %1").arg(m_mainScript);
}
QWidget *PythonRunConfiguration::createConfigurationWidget()
@@ -231,22 +229,6 @@ QWidget *PythonRunConfiguration::createConfigurationWidget()
return new PythonRunConfigurationWidget(this);
}
-void PythonRunConfiguration::setEnabled(bool b)
-{
- if (m_enabled == b)
- return;
- m_enabled = b;
- emit enabledChanged();
- setDefaultDisplayName(defaultDisplayName());
-}
-
-QString PythonRunConfiguration::disabledReason() const
-{
- if (!m_enabled)
- return tr("The script is currently disabled.");
- return QString();
-}
-
Runnable PythonRunConfiguration::runnable() const
{
StandardRunnable r;
@@ -295,8 +277,6 @@ PythonRunConfigurationWidget::PythonRunConfigurationWidget(PythonRunConfiguratio
auto vbx = new QVBoxLayout(this);
vbx->setMargin(0);
vbx->addWidget(m_detailsContainer);
-
- setEnabled(runConfiguration->isEnabled());
}
class PythonRunConfigurationFactory : public IRunConfigurationFactory
@@ -351,7 +331,7 @@ public:
{
if (!canClone(parent, source))
return 0;
- return new PythonRunConfiguration(parent, static_cast<PythonRunConfiguration*>(source));
+ return cloneHelper<PythonRunConfiguration>(parent, source);
}
private:
@@ -359,13 +339,12 @@ private:
RunConfiguration *doCreate(Target *parent, Core::Id id) override
{
- return new PythonRunConfiguration(parent, id);
+ return createHelper<PythonRunConfiguration>(parent, id);
}
RunConfiguration *doRestore(Target *parent, const QVariantMap &map) override
{
- Core::Id id(idFromMap(map));
- return new PythonRunConfiguration(parent, id);
+ return createHelper<PythonRunConfiguration>(parent, idFromMap(map));
}
};
@@ -507,6 +486,7 @@ private:
void PythonProject::refresh()
{
+ emitParsingStarted();
parseProject();
QDir baseDir(projectDirectory().toString());
@@ -517,7 +497,7 @@ void PythonProject::refresh()
}
setRootProjectNode(newRoot);
- emit parsingFinished();
+ emitParsingFinished(true);
}
/**
@@ -601,7 +581,7 @@ Project::RestoreResult PythonProject::fromMap(const QVariantMap &map, QString *e
}
}
if (!alreadyPresent)
- t->addRunConfiguration(new PythonRunConfiguration(t, id));
+ t->addRunConfiguration(IRunConfigurationFactory::createHelper<PythonRunConfiguration>(t, id));
}
}
}
diff --git a/src/plugins/pythoneditor/pythonhighlighter.cpp b/src/plugins/pythoneditor/pythonhighlighter.cpp
index 389beee4b87..b485c2a450e 100644
--- a/src/plugins/pythoneditor/pythonhighlighter.cpp
+++ b/src/plugins/pythoneditor/pythonhighlighter.cpp
@@ -37,6 +37,7 @@
#include "pythonscanner.h"
#include <texteditor/textdocument.h>
+#include <texteditor/textdocumentlayout.h>
#include <texteditor/texteditorconstants.h>
#include <utils/qtcassert.h>
@@ -116,6 +117,24 @@ static bool isImportKeyword(const QString &keyword)
return keyword == "import" || keyword == "from";
}
+static int indent(const QString &line)
+{
+ for (int i = 0, size = line.size(); i < size; ++i) {
+ if (!line.at(i).isSpace())
+ return i;
+ }
+ return -1;
+}
+
+static void setFoldingIndent(const QTextBlock &block, int indent)
+{
+ if (TextEditor::TextBlockUserData *userData = TextEditor::TextDocumentLayout::userData(block)) {
+ userData->setFoldingIndent(indent);
+ userData->setFoldingStartIncluded(false);
+ userData->setFoldingEndIncluded(false);
+ }
+}
+
/**
* @brief Highlight line of code, returns new block state
* @param text Source code to highlight
@@ -127,6 +146,23 @@ int PythonHighlighter::highlightLine(const QString &text, int initialState)
Scanner scanner(text.constData(), text.size());
scanner.setState(initialState);
+ const int pos = indent(text);
+ if (pos < 0) {
+ // Empty lines do not change folding indent
+ setFoldingIndent(currentBlock(), m_lastIndent);
+ } else {
+ m_lastIndent = pos;
+ if (pos == 0 && text.startsWith('#') && !text.startsWith("#!")) {
+ // A comment block at indentation 0. Fold on first line.
+ setFoldingIndent(currentBlock(), withinLicenseHeader ? 1 : 0);
+ withinLicenseHeader = true;
+ } else {
+ // Normal Python code. Line indentation can be used as folding indent.
+ setFoldingIndent(currentBlock(), m_lastIndent);
+ withinLicenseHeader = false;
+ }
+ }
+
FormatToken tk;
bool hasOnlyWhitespace = true;
while (!(tk = scanner.read()).isEndOfBlock()) {
diff --git a/src/plugins/pythoneditor/pythonhighlighter.h b/src/plugins/pythoneditor/pythonhighlighter.h
index 778d3727b29..63c35dfaf34 100644
--- a/src/plugins/pythoneditor/pythonhighlighter.h
+++ b/src/plugins/pythoneditor/pythonhighlighter.h
@@ -41,6 +41,9 @@ private:
void highlightBlock(const QString &text) override;
int highlightLine(const QString &text, int initialState);
void highlightImport(Internal::Scanner &scanner);
+
+ int m_lastIndent = 0;
+ bool withinLicenseHeader = false;
};
} // namespace Internal
diff --git a/src/plugins/pythoneditor/pythonindenter.cpp b/src/plugins/pythoneditor/pythonindenter.cpp
index 70b431368cd..035f1aef7cd 100644
--- a/src/plugins/pythoneditor/pythonindenter.cpp
+++ b/src/plugins/pythoneditor/pythonindenter.cpp
@@ -28,8 +28,28 @@
#include <texteditor/tabsettings.h>
+#include <algorithm>
+
namespace PythonEditor {
+static bool isEmptyLine(const QString &t)
+{
+ return std::all_of(t.cbegin(), t.cend(), [] (QChar c) { return c.isSpace(); });
+}
+
+static inline bool isEmptyLine(const QTextBlock &block)
+{
+ return isEmptyLine(block.text());
+}
+
+static QTextBlock previousNonEmptyBlock(const QTextBlock &block)
+{
+ QTextBlock result = block;
+ while (result.isValid() && isEmptyLine(result))
+ result = result.previous();
+ return result;
+}
+
/**
* @brief Does given character change indentation level?
* @param ch Any value
@@ -46,6 +66,15 @@ int PythonIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSett
if (!previousBlock.isValid())
return 0;
+ // When pasting in actual code, try to skip back past empty lines to an
+ // actual code line to find a suitable indentation. This prevents code from
+ // not being indented when pasting below an empty line.
+ if (!isEmptyLine(block)) {
+ const QTextBlock previousNonEmpty = previousNonEmptyBlock(previousBlock);
+ if (previousNonEmpty.isValid())
+ previousBlock = previousNonEmpty;
+ }
+
QString previousLine = previousBlock.text();
int indentation = tabSettings.indentationColumn(previousLine);
diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp
index 208ca398fe4..2b11012b28f 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp
+++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp
@@ -69,8 +69,8 @@ QbsBuildConfiguration::QbsBuildConfiguration(Target *target) :
m_isParsing(true),
m_parsingError(false)
{
- connect(project(), &QbsProject::projectParsingStarted, this, &BuildConfiguration::enabledChanged);
- connect(project(), &QbsProject::projectParsingDone, this, &BuildConfiguration::enabledChanged);
+ connect(project(), &Project::parsingStarted, this, &BuildConfiguration::enabledChanged);
+ connect(project(), &Project::parsingFinished, this, &BuildConfiguration::enabledChanged);
BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
connect(bsl, &BuildStepList::stepInserted, this, &QbsBuildConfiguration::buildStepInserted);
@@ -147,7 +147,7 @@ QVariantMap QbsBuildConfiguration::qbsConfiguration() const
Internal::QbsProject *QbsBuildConfiguration::project() const
{
- return qobject_cast<Internal::QbsProject *>(target()->project());
+ return qobject_cast<Internal::QbsProject *>(BuildConfiguration::project());
}
IOutputParser *QbsBuildConfiguration::createOutputParser() const
diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h
index 6df507fde69..1a0248d8f6a 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h
+++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h
@@ -27,6 +27,8 @@
#include "qbsprojectmanager_global.h"
+#include "qbsproject.h"
+
#include <projectexplorer/buildconfiguration.h>
#include <qtsupport/baseqtversion.h>
@@ -56,7 +58,7 @@ public:
QbsBuildStep *qbsStep() const;
QVariantMap qbsConfiguration() const;
- Internal::QbsProject *project() const;
+ Internal::QbsProject *project() const override;
ProjectExplorer::IOutputParser *createOutputParser() const;
diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
index 1a678b89656..063e6bf203b 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
+++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
@@ -346,7 +346,8 @@ void QbsBuildStep::buildingDone(bool success)
void QbsBuildStep::reparsingDone(bool success)
{
- disconnect(qbsProject(), &QbsProject::projectParsingDone, this, &QbsBuildStep::reparsingDone);
+ disconnect(qbsProject(), &ProjectExplorer::Project::parsingFinished,
+ this, &QbsBuildStep::reparsingDone);
m_parsingProject = false;
if (m_job) { // This was a scheduled reparsing after building.
finish();
@@ -485,7 +486,8 @@ void QbsBuildStep::setCleanInstallRoot(bool clean)
void QbsBuildStep::parseProject()
{
m_parsingProject = true;
- connect(qbsProject(), &QbsProject::projectParsingDone, this, &QbsBuildStep::reparsingDone);
+ connect(qbsProject(), &ProjectExplorer::Project::parsingFinished,
+ this, &QbsBuildStep::reparsingDone);
qbsProject()->parseCurrentBuildConfiguration();
}
@@ -551,8 +553,11 @@ QbsBuildStepConfigWidget::QbsBuildStepConfigWidget(QbsBuildStep *step) :
this, &QbsBuildStepConfigWidget::updateState);
connect(&QbsProjectManagerSettings::instance(), &QbsProjectManagerSettings::settingsBaseChanged,
this, &QbsBuildStepConfigWidget::updateState);
- connect(step->buildConfiguration()->target(), &ProjectExplorer::Target::buildDirectoryChanged,
- this, &QbsBuildStepConfigWidget::updateState);
+ step->target()->subscribeSignal(&ProjectExplorer::BuildConfiguration::buildDirectoryChanged,
+ this, [this]() {
+ if (m_step->target()->activeBuildConfiguration() == sender())
+ updateState();
+ });
setContentsMargins(0, 0, 0, 0);
diff --git a/src/plugins/qbsprojectmanager/qbsinstallstep.cpp b/src/plugins/qbsprojectmanager/qbsinstallstep.cpp
index 840cf4eefd5..8a4e9ad7b9d 100644
--- a/src/plugins/qbsprojectmanager/qbsinstallstep.cpp
+++ b/src/plugins/qbsprojectmanager/qbsinstallstep.cpp
@@ -286,7 +286,7 @@ QbsInstallStepConfigWidget::QbsInstallStepConfigWidget(QbsInstallStep *step) :
connect(m_ui->keepGoingCheckBox, &QAbstractButton::toggled,
this, &QbsInstallStepConfigWidget::changeKeepGoing);
- connect(project, &QbsProject::projectParsingDone,
+ connect(project, &ProjectExplorer::Project::parsingFinished,
this, &QbsInstallStepConfigWidget::updateState);
updateState();
diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp
index e3dd87e23ec..37da6326ab9 100644
--- a/src/plugins/qbsprojectmanager/qbsnodes.cpp
+++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp
@@ -43,7 +43,6 @@
#include <QtDebug>
#include <QDir>
#include <QIcon>
-#include <QStyle>
using namespace ProjectExplorer;
@@ -51,36 +50,23 @@ using namespace ProjectExplorer;
// Helpers:
// ----------------------------------------------------------------------
-static QIcon generateIcon(const QString &overlay)
-{
- const QSize desiredSize = QSize(16, 16);
- const QIcon overlayIcon(overlay);
- const QPixmap pixmap
- = Core::FileIconProvider::overlayIcon(QStyle::SP_DirIcon, overlayIcon, desiredSize);
-
- QIcon result;
- result.addPixmap(pixmap);
-
- return result;
-}
-
namespace QbsProjectManager {
namespace Internal {
-static QbsProjectNode *parentQbsProjectNode(ProjectExplorer::Node *node)
+static const QbsProjectNode *parentQbsProjectNode(const ProjectExplorer::Node *node)
{
- for (ProjectExplorer::FolderNode *pn = node->managingProject(); pn; pn = pn->parentProjectNode()) {
- QbsProjectNode *prjNode = dynamic_cast<QbsProjectNode *>(pn);
+ for (const ProjectExplorer::FolderNode *pn = node->managingProject(); pn; pn = pn->parentProjectNode()) {
+ const QbsProjectNode *prjNode = dynamic_cast<const QbsProjectNode *>(pn);
if (prjNode)
return prjNode;
}
return 0;
}
-static QbsProductNode *parentQbsProductNode(ProjectExplorer::Node *node)
+static const QbsProductNode *parentQbsProductNode(const ProjectExplorer::Node *node)
{
for (; node; node = node->parentFolderNode()) {
- QbsProductNode *prdNode = dynamic_cast<QbsProductNode *>(node);
+ const QbsProductNode *prdNode = dynamic_cast<const QbsProductNode *>(node);
if (prdNode)
return prdNode;
}
@@ -225,7 +211,7 @@ public:
};
-static bool supportsNodeAction(ProjectAction action, Node *node)
+static bool supportsNodeAction(ProjectAction action, const Node *node)
{
const QbsProject * const project = parentQbsProjectNode(node)->project();
if (!project->isProjectEditable())
@@ -270,7 +256,7 @@ QbsFolderNode::QbsFolderNode(const Utils::FileName &folderPath, ProjectExplorer:
{
}
-bool QbsFolderNode::supportsAction(ProjectAction action, Node *node) const
+bool QbsFolderNode::supportsAction(ProjectAction action, const Node *node) const
{
return supportsNodeAction(action, node);
}
@@ -302,7 +288,7 @@ QbsGroupNode::QbsGroupNode(const qbs::GroupData &grp, const QString &productPath
m_qbsGroupData = grp;
}
-bool QbsGroupNode::supportsAction(ProjectAction action, Node *node) const
+bool QbsGroupNode::supportsAction(ProjectAction action, const Node *node) const
{
if (action == AddNewFile || action == AddExistingFile)
return true;
@@ -316,13 +302,13 @@ bool QbsGroupNode::addFiles(const QStringList &filePaths, QStringList *notAdded)
if (!notAdded)
notAdded = &notAddedDummy;
- QbsProjectNode *prjNode = parentQbsProjectNode(this);
+ const QbsProjectNode *prjNode = parentQbsProjectNode(this);
if (!prjNode || !prjNode->qbsProject().isValid()) {
*notAdded += filePaths;
return false;
}
- QbsProductNode *prdNode = parentQbsProductNode(this);
+ const QbsProductNode *prdNode = parentQbsProductNode(this);
if (!prdNode || !prdNode->qbsProductData().isValid()) {
*notAdded += filePaths;
return false;
@@ -338,13 +324,13 @@ bool QbsGroupNode::removeFiles(const QStringList &filePaths, QStringList *notRem
if (!notRemoved)
notRemoved = &notRemovedDummy;
- QbsProjectNode *prjNode = parentQbsProjectNode(this);
+ const QbsProjectNode *prjNode = parentQbsProjectNode(this);
if (!prjNode || !prjNode->qbsProject().isValid()) {
*notRemoved += filePaths;
return false;
}
- QbsProductNode *prdNode = parentQbsProductNode(this);
+ const QbsProductNode *prdNode = parentQbsProductNode(this);
if (!prdNode || !prdNode->qbsProductData().isValid()) {
*notRemoved += filePaths;
return false;
@@ -356,10 +342,10 @@ bool QbsGroupNode::removeFiles(const QStringList &filePaths, QStringList *notRem
bool QbsGroupNode::renameFile(const QString &filePath, const QString &newFilePath)
{
- QbsProjectNode * const prjNode = parentQbsProjectNode(this);
+ const QbsProjectNode *prjNode = parentQbsProjectNode(this);
if (!prjNode || !prjNode->qbsProject().isValid())
return false;
- QbsProductNode * const prdNode = parentQbsProductNode(this);
+ const QbsProductNode *prdNode = parentQbsProductNode(this);
if (!prdNode || !prdNode->qbsProductData().isValid())
return false;
@@ -375,7 +361,7 @@ QbsProductNode::QbsProductNode(const qbs::ProductData &prd) :
QbsBaseProjectNode(Utils::FileName::fromString(prd.location().filePath())),
m_qbsProductData(prd)
{
- static QIcon productIcon = generateIcon(QString(Constants::QBS_PRODUCT_OVERLAY_ICON));
+ static QIcon productIcon = Core::FileIconProvider::directoryIcon(Constants::QBS_PRODUCT_OVERLAY_ICON);
setIcon(productIcon);
}
@@ -384,7 +370,7 @@ bool QbsProductNode::showInSimpleTree() const
return true;
}
-bool QbsProductNode::supportsAction(ProjectAction action, Node *node) const
+bool QbsProductNode::supportsAction(ProjectAction action, const Node *node) const
{
if (action == AddNewFile || action == AddExistingFile)
return true;
@@ -398,7 +384,7 @@ bool QbsProductNode::addFiles(const QStringList &filePaths, QStringList *notAdde
if (!notAdded)
notAdded = &notAddedDummy;
- QbsProjectNode *prjNode = parentQbsProjectNode(this);
+ const QbsProjectNode *prjNode = parentQbsProjectNode(this);
if (!prjNode || !prjNode->qbsProject().isValid()) {
*notAdded += filePaths;
return false;
@@ -418,7 +404,7 @@ bool QbsProductNode::removeFiles(const QStringList &filePaths, QStringList *notR
if (!notRemoved)
notRemoved = &notRemovedDummy;
- QbsProjectNode *prjNode = parentQbsProjectNode(this);
+ const QbsProjectNode *prjNode = parentQbsProjectNode(this);
if (!prjNode || !prjNode->qbsProject().isValid()) {
*notRemoved += filePaths;
return false;
@@ -435,7 +421,7 @@ bool QbsProductNode::removeFiles(const QStringList &filePaths, QStringList *notR
bool QbsProductNode::renameFile(const QString &filePath, const QString &newFilePath)
{
- QbsProjectNode * const prjNode = parentQbsProjectNode(this);
+ const QbsProjectNode * prjNode = parentQbsProjectNode(this);
if (!prjNode || !prjNode->qbsProject().isValid())
return false;
const qbs::GroupData grp = findMainQbsGroup(m_qbsProductData);
@@ -468,7 +454,7 @@ QList<ProjectExplorer::RunConfiguration *> QbsProductNode::runConfigurations() c
QbsProjectNode::QbsProjectNode(const Utils::FileName &projectDirectory) :
QbsBaseProjectNode(projectDirectory)
{
- static QIcon projectIcon = generateIcon(QString(ProjectExplorer::Constants::FILEOVERLAY_QT));
+ static QIcon projectIcon = Core::FileIconProvider::directoryIcon(ProjectExplorer::Constants::FILEOVERLAY_QT);
setIcon(projectIcon);
}
diff --git a/src/plugins/qbsprojectmanager/qbsnodes.h b/src/plugins/qbsprojectmanager/qbsnodes.h
index 904851bc810..f6d02f16b57 100644
--- a/src/plugins/qbsprojectmanager/qbsnodes.h
+++ b/src/plugins/qbsprojectmanager/qbsnodes.h
@@ -55,7 +55,7 @@ public:
const QString &displayName);
private:
- bool supportsAction(ProjectExplorer::ProjectAction action, Node *node) const final;
+ bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const final;
};
// ---------------------------------------------------------------------------
@@ -81,7 +81,7 @@ class QbsGroupNode : public QbsBaseProjectNode
public:
QbsGroupNode(const qbs::GroupData &grp, const QString &productPath);
- bool supportsAction(ProjectExplorer::ProjectAction action, Node *node) const final;
+ bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const final;
bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0) override;
bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = 0) override;
bool renameFile(const QString &filePath, const QString &newFilePath) override;
@@ -103,7 +103,7 @@ public:
explicit QbsProductNode(const qbs::ProductData &prd);
bool showInSimpleTree() const override;
- bool supportsAction(ProjectExplorer::ProjectAction action, Node *node) const final;
+ bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const final;
bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0) override;
bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = 0) override;
bool renameFile(const QString &filePath, const QString &newFilePath) override;
diff --git a/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp b/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp
index 8e54900fd64..3e7ac54eb43 100644
--- a/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp
+++ b/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp
@@ -30,6 +30,7 @@
#include "qbsprojectmanagerconstants.h"
#include "qbsprojectmanagersettings.h"
+#include <app/app_version.h>
#include <coreplugin/icore.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/kitmanager.h>
@@ -105,6 +106,8 @@ QbsProfilesSettingsWidget::QbsProfilesSettingsWidget(QWidget *parent)
{
m_model.setEditable(false);
m_ui.setupUi(this);
+ m_ui.settingsDirCheckBox->setText(tr("Store profiles in %1 settings directory")
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
m_ui.settingsDirCheckBox->setChecked(QbsProjectManagerSettings::useCreatorSettingsDirForQbs());
m_ui.versionValueLabel->setText(qbs::LanguageInfo::qbsVersion());
connect(ProjectExplorer::KitManager::instance(), &ProjectExplorer::KitManager::kitsChanged,
diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp
index dbeb13cb608..f9f212fcb08 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.cpp
+++ b/src/plugins/qbsprojectmanager/qbsproject.cpp
@@ -140,7 +140,15 @@ QbsProject::QbsProject(const FileName &fileName) :
connect(this, &Project::activeTargetChanged, this, &QbsProject::changeActiveTarget);
connect(this, &Project::addedTarget, this, &QbsProject::targetWasAdded);
connect(this, &Project::removedTarget, this, &QbsProject::targetWasRemoved);
- connect(this, &Project::environmentChanged, this, &QbsProject::delayParsing);
+ subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
+ if (static_cast<BuildConfiguration *>(sender())->isActive())
+ startParsing();
+ });
+ connect(this, &Project::activeProjectConfigurationChanged,
+ this, [this](ProjectConfiguration *pc) {
+ if (pc && pc->isActive())
+ startParsing();
+ });
connect(&m_parsingDelay, &QTimer::timeout, this, &QbsProject::startParsing);
@@ -503,8 +511,7 @@ void QbsProject::handleQbsParsingDone(bool success)
if (dataChanged)
updateAfterParse();
- emit projectParsingDone(success);
- emit parsingFinished();
+ emitParsingFinished(success);
}
void QbsProject::rebuildProjectTree()
@@ -530,14 +537,17 @@ void QbsProject::handleRuleExecutionDone()
QTC_ASSERT(m_qbsProject.isValid(), return);
m_projectData = m_qbsProject.projectData();
updateAfterParse();
- emit projectParsingDone(true);
+ // finishParsing(true);
}
void QbsProject::targetWasAdded(Target *t)
{
m_qbsProjects.insert(t, qbs::Project());
connect(t, &Target::activeBuildConfigurationChanged, this, &QbsProject::delayParsing);
- connect(t, &Target::buildDirectoryChanged, this, &QbsProject::delayParsing);
+ t->subscribeSignal(&BuildConfiguration::buildDirectoryChanged, this, [this]() {
+ if (static_cast<BuildConfiguration *>(sender())->isActive())
+ delayParsing();
+ });
}
void QbsProject::targetWasRemoved(Target *t)
@@ -724,7 +734,7 @@ void QbsProject::parse(const QVariantMap &config, const Environment &env, const
QbsManager::instance()->updateProfileIfNecessary(activeTarget()->kit());
m_qbsProjectParser->parse(config, env, dir, configName);
- emit projectParsingStarted();
+ emitParsingStarted();
}
void QbsProject::prepareForParsing()
@@ -965,17 +975,7 @@ void QbsProject::updateCppCodeModel()
QStringList list = props.getModulePropertiesAsStringList(
QLatin1String(CONFIG_CPP_MODULE),
QLatin1String(CONFIG_DEFINES));
- QByteArray grpDefines;
- foreach (const QString &def, list) {
- QByteArray data = def.toUtf8();
- int pos = data.indexOf('=');
- if (pos >= 0)
- data[pos] = ' ';
- else
- data.append(" 1"); // cpp.defines: [ "FOO" ] is considered to be "FOO=1"
- grpDefines += (QByteArray("#define ") + data + '\n');
- }
- rpp.setDefines(grpDefines);
+ rpp.setMacros(Utils::transform<QVector>(list, [](const QString &s) { return ProjectExplorer::Macro::fromKeyValue(s); }));
list = props.getModulePropertiesAsStringList(QLatin1String(CONFIG_CPP_MODULE),
QLatin1String(CONFIG_INCLUDEPATHS));
@@ -1004,6 +1004,8 @@ void QbsProject::updateCppCodeModel()
rpp.setProjectFileLocation(grp.location().filePath(),
grp.location().line(), grp.location().column());
rpp.setBuildSystemTarget(prd.name());
+ rpp.setBuildTargetType(prd.isRunnable() ? CppTools::ProjectPart::Executable
+ : CppTools::ProjectPart::Library);
QHash<QString, qbs::ArtifactData> filePathToSourceArtifact;
bool hasCFiles = false;
diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h
index 8d2e0c8cbde..23e0f706b90 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.h
+++ b/src/plugins/qbsprojectmanager/qbsproject.h
@@ -110,14 +110,9 @@ public:
void configureAsExampleProject(const QSet<Core::Id> &platforms) final;
-public:
void invalidate();
void delayParsing();
-signals:
- void projectParsingStarted();
- void projectParsingDone(bool);
-
private:
void handleQbsParsingDone(bool success);
diff --git a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp
index 406039e40f4..8c038f20a9a 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp
+++ b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp
@@ -116,7 +116,7 @@ static QStringList candidatesForDirectory(const QString &dir)
QStringList QbsProjectImporter::importCandidates()
{
- const QString projectDir = QFileInfo(projectFilePath().toString()).absolutePath();
+ const QString projectDir = projectFilePath().toFileInfo().absolutePath();
QStringList candidates = candidatesForDirectory(projectDir);
QSet<QString> seenCandidates;
diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs
index c732facdf4b..bfa79ea5192 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs
+++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs
@@ -43,6 +43,7 @@ QtcPlugin {
Depends { name: "CppTools" }
Depends { name: "QtSupport" }
Depends { name: "QmlJSTools" }
+ Depends { name: "app_version_header" }
cpp.defines: base.concat([
'QML_BUILD_STATIC_LIB',
diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
index 2a34b2f8b1e..a4cd157c71a 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
+++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
@@ -297,23 +297,23 @@ void QbsProjectManagerPlugin::projectWasAdded(Project *project)
if (!qbsProject)
return;
- connect(qbsProject, &QbsProject::projectParsingStarted,
+ connect(qbsProject, &Project::parsingStarted,
this, &QbsProjectManagerPlugin::projectChanged);
- connect(qbsProject, &QbsProject::projectParsingDone,
+ connect(qbsProject, &Project::parsingFinished,
this, &QbsProjectManagerPlugin::projectChanged);
}
void QbsProjectManagerPlugin::updateContextActions()
{
QbsProject *project = qobject_cast<Internal::QbsProject *>(ProjectTree::currentProject());
- Node *node = ProjectTree::currentNode();
+ const Node *node = ProjectTree::findCurrentNode();
bool isEnabled = !BuildManager::isBuilding(project)
&& project && !project->isParsing()
&& node && node->isEnabled();
bool isFile = project && node && (node->nodeType() == NodeType::File);
- bool isProduct = project && node && dynamic_cast<QbsProductNode *>(node);
- QbsProjectNode *subproject = dynamic_cast<QbsProjectNode *>(node);
+ const bool isProduct = project && node && dynamic_cast<const QbsProductNode *>(node);
+ const QbsProjectNode *subproject = dynamic_cast<const QbsProjectNode *>(node);
bool isSubproject = project && subproject && subproject != project->rootProjectNode();
m_reparseQbsCtx->setEnabled(isEnabled);
@@ -409,7 +409,7 @@ void QbsProjectManagerPlugin::projectChanged()
void QbsProjectManagerPlugin::buildFileContextMenu()
{
- Node *node = ProjectTree::currentNode();
+ const Node *node = ProjectTree::findCurrentNode();
QTC_ASSERT(node, return);
QbsProject *project = dynamic_cast<QbsProject *>(ProjectTree::currentProject());
QTC_ASSERT(project, return);
@@ -446,12 +446,12 @@ void QbsProjectManagerPlugin::rebuildProductContextMenu()
void QbsProjectManagerPlugin::runStepsForProductContextMenu(const QList<Core::Id> &stepTypes)
{
- Node *node = ProjectTree::currentNode();
+ const Node *node = ProjectTree::findCurrentNode();
QTC_ASSERT(node, return);
QbsProject *project = dynamic_cast<QbsProject *>(ProjectTree::currentProject());
QTC_ASSERT(project, return);
- const QbsProductNode * const productNode = dynamic_cast<QbsProductNode *>(node);
+ const QbsProductNode * const productNode = dynamic_cast<const QbsProductNode *>(node);
QTC_ASSERT(productNode, return);
runStepsForProducts(project, {QbsProject::uniqueProductName(productNode->qbsProductData())},
@@ -511,12 +511,12 @@ void QbsProjectManagerPlugin::rebuildSubprojectContextMenu()
void QbsProjectManagerPlugin::runStepsForSubprojectContextMenu(const QList<Core::Id> &stepTypes)
{
- Node *node = ProjectTree::currentNode();
+ const Node *node = ProjectTree::findCurrentNode();
QTC_ASSERT(node, return);
QbsProject *project = dynamic_cast<QbsProject *>(ProjectTree::currentProject());
QTC_ASSERT(project, return);
- QbsProjectNode *subProject = dynamic_cast<QbsProjectNode *>(node);
+ const QbsProjectNode *subProject = dynamic_cast<const QbsProjectNode *>(node);
QTC_ASSERT(subProject, return);
QStringList toBuild;
diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp
index e8b90d4377a..5ddee4a3ed9 100644
--- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp
+++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp
@@ -44,11 +44,11 @@
#include <utils/detailswidget.h>
#include <utils/stringutils.h>
#include <utils/persistentsettings.h>
+#include <utils/utilsicons.h>
#include <qtsupport/qtoutputformatter.h>
#include <qtsupport/qtsupportconstants.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/hostosinfo.h>
-#include <utils/utilsicons.h>
#include "api/runenvironment.h"
@@ -107,77 +107,57 @@ const qbs::ProductData findProduct(const qbs::ProjectData &pro, const QString &u
// QbsRunConfiguration:
// --------------------------------------------------------------------
-QbsRunConfiguration::QbsRunConfiguration(Target *parent, Core::Id id) :
- RunConfiguration(parent, id),
- m_uniqueProductName(uniqueProductNameFromId(id)),
- m_currentInstallStep(0),
- m_currentBuildStepList(0)
+QbsRunConfiguration::QbsRunConfiguration(Target *target)
+ : RunConfiguration(target)
{
- auto * const envAspect = new LocalEnvironmentAspect(this,
+ auto envAspect = new LocalEnvironmentAspect(this,
[](RunConfiguration *rc, Environment &env) {
static_cast<QbsRunConfiguration *>(rc)->addToBaseEnvironment(env);
- }
- );
+ });
addExtraAspect(envAspect);
- connect(static_cast<QbsProject *>(parent->project()), &QbsProject::parsingFinished, this,
+ connect(static_cast<QbsProject *>(target->project()), &Project::parsingFinished, this,
[envAspect]() { envAspect->buildEnvironmentHasChanged(); });
- addExtraAspect(new ArgumentsAspect(this, QStringLiteral("Qbs.RunConfiguration.CommandLineArguments")));
- addExtraAspect(new WorkingDirectoryAspect(this, QStringLiteral("Qbs.RunConfiguration.WorkingDirectory")));
+ addExtraAspect(new ArgumentsAspect(this, "Qbs.RunConfiguration.CommandLineArguments"));
+ addExtraAspect(new WorkingDirectoryAspect(this, "Qbs.RunConfiguration.WorkingDirectory"));
- addExtraAspect(new TerminalAspect(this,
- QStringLiteral("Qbs.RunConfiguration.UseTerminal"),
- isConsoleApplication()));
+ addExtraAspect(new TerminalAspect(this, "Qbs.RunConfiguration.UseTerminal", isConsoleApplication()));
- ctor();
-}
+ QbsProject *project = static_cast<QbsProject *>(target->project());
+ connect(project, &Project::parsingFinished, this, [this](bool success) {
+ auto terminalAspect = extraAspect<TerminalAspect>();
+ if (success && !terminalAspect->isUserSet())
+ terminalAspect->setUseTerminal(isConsoleApplication());
+ });
+ connect(BuildManager::instance(), &BuildManager::buildStateChanged, this,
+ [this, project](Project *p) {
+ if (p == project && !BuildManager::isBuilding(p))
+ emit enabledChanged();
+ }
+ );
-QbsRunConfiguration::QbsRunConfiguration(Target *parent, QbsRunConfiguration *source) :
- RunConfiguration(parent, source),
- m_uniqueProductName(source->m_uniqueProductName),
- m_currentInstallStep(0), // no need to copy this, we will get if from the DC anyway.
- m_currentBuildStepList(0) // ditto
-{
- ctor();
+ connect(target, &Target::activeDeployConfigurationChanged,
+ this, &QbsRunConfiguration::installStepChanged);
}
-bool QbsRunConfiguration::isEnabled() const
+void QbsRunConfiguration::initialize(Core::Id id)
{
- QbsProject *project = static_cast<QbsProject *>(target()->project());
- return !project->isParsing() && project->hasParseResult();
+ m_uniqueProductName = uniqueProductNameFromId(id);
+ ctor();
}
-QString QbsRunConfiguration::disabledReason() const
+void QbsRunConfiguration::copyFrom(const QbsRunConfiguration *source)
{
- QbsProject *project = static_cast<QbsProject *>(target()->project());
- if (project->isParsing())
- return tr("The .qbs files are currently being parsed.");
+ RunConfiguration::copyFrom(source);
+ m_uniqueProductName = source->m_uniqueProductName;
+ m_currentInstallStep = nullptr; // no need to copy this, we will get if from the DC anyway.
+ m_currentBuildStepList = nullptr; // ditto
- if (!project->hasParseResult())
- return tr("Parsing of .qbs files has failed.");
- return QString();
+ ctor();
}
void QbsRunConfiguration::ctor()
{
setDefaultDisplayName(defaultDisplayName());
-
- QbsProject *project = static_cast<QbsProject *>(target()->project());
- connect(project, &QbsProject::projectParsingStarted, this, &RunConfiguration::enabledChanged);
- connect(project, &QbsProject::projectParsingDone, this, [this](bool success) {
- auto terminalAspect = extraAspect<TerminalAspect>();
- if (success && !terminalAspect->isUserSet())
- terminalAspect->setUseTerminal(isConsoleApplication());
- emit enabledChanged();
- });
- connect(BuildManager::instance(), &BuildManager::buildStateChanged, this,
- [this, project](Project *p) {
- if (p == project && !BuildManager::isBuilding(p))
- emit enabledChanged();
- }
- );
-
- connect(target(), &Target::activeDeployConfigurationChanged,
- this, &QbsRunConfiguration::installStepChanged);
installStepChanged();
}
@@ -332,17 +312,6 @@ QbsRunConfigurationWidget::QbsRunConfigurationWidget(QbsRunConfiguration *rc)
auto vboxTopLayout = new QVBoxLayout(this);
vboxTopLayout->setMargin(0);
- auto hl = new QHBoxLayout();
- hl->addStretch();
- m_disabledIcon = new QLabel(this);
- m_disabledIcon->setPixmap(Utils::Icons::WARNING.pixmap());
- hl->addWidget(m_disabledIcon);
- m_disabledReason = new QLabel(this);
- m_disabledReason->setVisible(false);
- hl->addWidget(m_disabledReason);
- hl->addStretch();
- vboxTopLayout->addLayout(hl);
-
auto detailsContainer = new Utils::DetailsWidget(this);
detailsContainer->setState(Utils::DetailsWidget::NoSummary);
vboxTopLayout->addWidget(detailsContainer);
@@ -362,23 +331,11 @@ QbsRunConfigurationWidget::QbsRunConfigurationWidget(QbsRunConfiguration *rc)
m_rc->extraAspect<TerminalAspect>()->addToMainConfigurationWidget(this, toplayout);
- runConfigurationEnabledChange();
-
connect(m_rc, &QbsRunConfiguration::targetInformationChanged,
this, &QbsRunConfigurationWidget::targetInformationHasChanged, Qt::QueuedConnection);
connect(m_rc, &RunConfiguration::enabledChanged,
- this, &QbsRunConfigurationWidget::runConfigurationEnabledChange);
-}
-
-void QbsRunConfigurationWidget::runConfigurationEnabledChange()
-{
- bool enabled = m_rc->isEnabled();
- m_disabledIcon->setVisible(!enabled);
- m_disabledReason->setVisible(!enabled);
- m_disabledReason->setText(m_rc->disabledReason());
-
- targetInformationHasChanged();
+ this, &QbsRunConfigurationWidget::targetInformationHasChanged);
}
void QbsRunConfigurationWidget::targetInformationHasChanged()
@@ -419,7 +376,7 @@ bool QbsRunConfigurationFactory::canCreate(Target *parent, Core::Id id) const
RunConfiguration *QbsRunConfigurationFactory::doCreate(Target *parent, Core::Id id)
{
- return new QbsRunConfiguration(parent, id);
+ return createHelper<QbsRunConfiguration>(parent, id);
}
bool QbsRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
@@ -431,7 +388,7 @@ bool QbsRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &m
RunConfiguration *QbsRunConfigurationFactory::doRestore(Target *parent, const QVariantMap &map)
{
- return new QbsRunConfiguration(parent, idFromMap(map));
+ return createHelper<QbsRunConfiguration>(parent, idFromMap(map));
}
bool QbsRunConfigurationFactory::canClone(Target *parent, RunConfiguration *source) const
@@ -443,8 +400,7 @@ RunConfiguration *QbsRunConfigurationFactory::clone(Target *parent, RunConfigura
{
if (!canClone(parent, source))
return 0;
- QbsRunConfiguration *old = static_cast<QbsRunConfiguration *>(source);
- return new QbsRunConfiguration(parent, old);
+ return cloneHelper<QbsRunConfiguration>(parent, source);
}
QList<Core::Id> QbsRunConfigurationFactory::availableCreationIds(Target *parent, CreationMode mode) const
diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h
index bff341af467..5367cd2d90e 100644
--- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h
+++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h
@@ -31,27 +31,14 @@
#include <QLabel>
#include <QWidget>
-QT_BEGIN_NAMESPACE
-class QCheckBox;
-class QLineEdit;
-class QRadioButton;
-class QComboBox;
-QT_END_NAMESPACE
-
namespace qbs { class InstallOptions; }
-namespace Utils { class PathChooser; }
-
namespace ProjectExplorer { class BuildStepList; }
namespace QbsProjectManager {
-
-class QbsProject;
-
namespace Internal {
class QbsInstallStep;
-class QbsRunConfigurationFactory;
class QbsRunConfiguration : public ProjectExplorer::RunConfiguration
{
@@ -59,13 +46,11 @@ class QbsRunConfiguration : public ProjectExplorer::RunConfiguration
// to change the display name and arguments and set the userenvironmentchanges
friend class QbsRunConfigurationWidget;
- friend class QbsRunConfigurationFactory;
+ friend class ProjectExplorer::IRunConfigurationFactory;
public:
- QbsRunConfiguration(ProjectExplorer::Target *parent, Core::Id id);
+ explicit QbsRunConfiguration(ProjectExplorer::Target *target);
- bool isEnabled() const override;
- QString disabledReason() const override;
QWidget *createConfigurationWidget() override;
ProjectExplorer::Runnable runnable() const override;
@@ -83,10 +68,11 @@ signals:
void targetInformationChanged();
void usingDyldImageSuffixChanged(bool);
-protected:
- QbsRunConfiguration(ProjectExplorer::Target *parent, QbsRunConfiguration *source);
private:
+ void initialize(Core::Id id);
+ void copyFrom(const QbsRunConfiguration *source);
+
void installStepChanged();
void installStepToBeRemoved(int pos);
QString baseWorkingDirectory() const;
@@ -98,8 +84,8 @@ private:
QString m_uniqueProductName;
- QbsInstallStep *m_currentInstallStep; // We do not take ownership!
- ProjectExplorer::BuildStepList *m_currentBuildStepList; // We do not take ownership!
+ QbsInstallStep *m_currentInstallStep = nullptr; // We do not take ownership!
+ ProjectExplorer::BuildStepList *m_currentBuildStepList = nullptr; // We do not take ownership!
};
class QbsRunConfigurationWidget : public QWidget
@@ -115,10 +101,8 @@ private:
void setExecutableLineText(const QString &text = QString());
QbsRunConfiguration *m_rc;
- bool m_ignoreChange = false;
- QLabel *m_disabledIcon;
- QLabel *m_disabledReason;
QLabel *m_executableLineLabel;
+ bool m_ignoreChange = false;
bool m_isShown = false;
};
diff --git a/src/plugins/qmakeandroidsupport/androidpackageinstallationstep.cpp b/src/plugins/qmakeandroidsupport/androidpackageinstallationstep.cpp
index d07d766462f..c7d0db210bd 100644
--- a/src/plugins/qmakeandroidsupport/androidpackageinstallationstep.cpp
+++ b/src/plugins/qmakeandroidsupport/androidpackageinstallationstep.cpp
@@ -59,9 +59,9 @@ AndroidPackageInstallationStep::AndroidPackageInstallationStep(ProjectExplorer::
bool AndroidPackageInstallationStep::init(QList<const BuildStep *> &earlierSteps)
{
ProjectExplorer::BuildConfiguration *bc = buildConfiguration();
- QString dirPath = bc->buildDirectory().appendPath(QLatin1String(Android::Constants::ANDROID_BUILDDIRECTORY)).toString();
+ QString dirPath = bc->buildDirectory().appendPath(Android::Constants::ANDROID_BUILDDIRECTORY).toString();
if (Utils::HostOsInfo::isWindowsHost())
- if (bc->environment().searchInPath(QLatin1String("sh.exe")).isEmpty())
+ if (bc->environment().searchInPath("sh.exe").isEmpty())
dirPath = QDir::toNativeSeparators(dirPath);
ProjectExplorer::ToolChain *tc
@@ -88,12 +88,8 @@ bool AndroidPackageInstallationStep::init(QList<const BuildStep *> &earlierSteps
m_androidDirsToClean.clear();
// don't remove gradle's cache, it takes ages to rebuild it.
- if (!QFile::exists(dirPath + QLatin1String("/build.xml")) && Android::AndroidManager::useGradle(target())) {
- m_androidDirsToClean << dirPath + QLatin1String("/assets");
- m_androidDirsToClean << dirPath + QLatin1String("/libs");
- } else {
- m_androidDirsToClean << dirPath;
- }
+ m_androidDirsToClean << dirPath + "/assets";
+ m_androidDirsToClean << dirPath + "/libs";
return AbstractProcessStep::init(earlierSteps);
}
diff --git a/src/plugins/qmakeandroidsupport/qmakeandroidbuildapkstep.cpp b/src/plugins/qmakeandroidsupport/qmakeandroidbuildapkstep.cpp
index 4ca9ef9653a..68e3e1d632f 100644
--- a/src/plugins/qmakeandroidsupport/qmakeandroidbuildapkstep.cpp
+++ b/src/plugins/qmakeandroidsupport/qmakeandroidbuildapkstep.cpp
@@ -129,22 +129,20 @@ bool QmakeAndroidBuildApkStep::init(QList<const BuildStep *> &earlierSteps)
return false;
QString command = version->qmakeProperty("QT_HOST_BINS");
- if (!command.endsWith(QLatin1Char('/')))
- command += QLatin1Char('/');
- command += QLatin1String("androiddeployqt");
+ if (!command.endsWith('/'))
+ command += '/';
+ command += "androiddeployqt";
if (Utils::HostOsInfo::isWindowsHost())
- command += QLatin1String(".exe");
+ command += ".exe";
QString deploymentMethod;
if (m_deployAction == MinistroDeployment)
- deploymentMethod = QLatin1String("ministro");
- else if (m_deployAction == DebugDeployment)
- deploymentMethod = QLatin1String("debug");
+ deploymentMethod = "ministro";
else if (m_deployAction == BundleLibrariesDeployment)
- deploymentMethod = QLatin1String("bundled");
+ deploymentMethod = "bundled";
ProjectExplorer::BuildConfiguration *bc = buildConfiguration();
- QString outputDir = bc->buildDirectory().appendPath(QLatin1String(Constants::ANDROID_BUILDDIRECTORY)).toString();
+ QString outputDir = bc->buildDirectory().appendPath(Constants::ANDROID_BUILDDIRECTORY).toString();
const auto *pro = static_cast<QmakeProjectManager::QmakeProject *>(project());
const QmakeProjectManager::QmakeProFileNode *node = pro->rootProjectNode()->findProFileFor(proFilePathForInputFile());
@@ -165,43 +163,27 @@ bool QmakeAndroidBuildApkStep::init(QList<const BuildStep *> &earlierSteps)
return false;
}
- QStringList arguments;
- arguments << QLatin1String("--input")
- << inputFile
- << QLatin1String("--output")
- << outputDir
- << QLatin1String("--deployment")
- << deploymentMethod
- << QLatin1String("--android-platform")
- << AndroidManager::buildTargetSDK(target())
- << QLatin1String("--jdk")
- << AndroidConfigurations::currentConfig().openJDKLocation().toString();
+ QStringList arguments = {"--input", inputFile,
+ "--output", outputDir,
+ "--deployment", deploymentMethod,
+ "--android-platform", AndroidManager::buildTargetSDK(target()),
+ "--jdk", AndroidConfigurations::currentConfig().openJDKLocation().toString()};
if (m_verbose)
- arguments << QLatin1String("--verbose");
-
- if (m_useGradle)
- arguments << QLatin1String("--gradle");
- else
- arguments << QLatin1String("--ant")
- << AndroidConfigurations::currentConfig().antToolPath().toString();
+ arguments << "--verbose";
+ arguments << "--gradle";
QStringList argumentsPasswordConcealed = arguments;
if (m_signPackage) {
- arguments << QLatin1String("--sign")
- << m_keystorePath.toString()
- << m_certificateAlias
- << QLatin1String("--storepass")
- << m_keystorePasswd;
- argumentsPasswordConcealed << QLatin1String("--sign") << QLatin1String("******")
- << QLatin1String("--storepass") << QLatin1String("******");
+ arguments << "--sign" << m_keystorePath.toString() << m_certificateAlias
+ << "--storepass" << m_keystorePasswd;
+ argumentsPasswordConcealed << "--sign" << "******"
+ << "--storepass" << "******";
if (!m_certificatePasswd.isEmpty()) {
- arguments << QLatin1String("--keypass")
- << m_certificatePasswd;
- argumentsPasswordConcealed << QLatin1String("--keypass")
- << QLatin1String("******");
+ arguments << "--keypass" << m_certificatePasswd;
+ argumentsPasswordConcealed << "--keypass" << "******";
}
}
@@ -210,9 +192,9 @@ bool QmakeAndroidBuildApkStep::init(QList<const BuildStep *> &earlierSteps)
// params (e.g. --sign) to choose not to add gdbserver
if (version->qtVersion() >= QtSupport::QtVersionNumber(5, 6, 0)) {
if (m_addDebugger || bc->buildType() == ProjectExplorer::BuildConfiguration::Debug)
- arguments << QLatin1String("--gdbserver");
+ arguments << "--gdbserver";
else
- arguments << QLatin1String("--no-gdbserver");
+ arguments << "--no-gdbserver";
}
ProjectExplorer::ProcessParameters *pp = processParameters();
diff --git a/src/plugins/qmakeandroidsupport/qmakeandroidrunconfiguration.cpp b/src/plugins/qmakeandroidsupport/qmakeandroidrunconfiguration.cpp
index 6cb626ee7ef..deb380e49ce 100644
--- a/src/plugins/qmakeandroidsupport/qmakeandroidrunconfiguration.cpp
+++ b/src/plugins/qmakeandroidsupport/qmakeandroidrunconfiguration.cpp
@@ -49,35 +49,35 @@ namespace Internal {
static const char ANDROID_RC_ID_PREFIX[] = "Qt4ProjectManager.AndroidRunConfiguration:";
-static QString pathFromId(const Core::Id id)
+static Utils::FileName pathFromId(const Core::Id id)
{
- return id.suffixAfter(ANDROID_RC_ID_PREFIX);
+ return Utils::FileName::fromString(id.suffixAfter(ANDROID_RC_ID_PREFIX));
}
-QmakeAndroidRunConfiguration::QmakeAndroidRunConfiguration(Target *parent, Core::Id id, const Utils::FileName &path)
- : AndroidRunConfiguration(parent, id)
- , m_proFilePath(path)
+QmakeAndroidRunConfiguration::QmakeAndroidRunConfiguration(Target *target)
+ : AndroidRunConfiguration(target)
+{}
+
+void QmakeAndroidRunConfiguration::initialize(Core::Id id)
{
- QmakeProject *project = static_cast<QmakeProject *>(parent->project());
- m_parseSuccess = project->validParse(m_proFilePath);
- m_parseInProgress = project->parseInProgress(m_proFilePath);
- init();
+ AndroidRunConfiguration::initialize(id);
+ m_proFilePath = pathFromId(id);
+
+ ctor();
}
-QmakeAndroidRunConfiguration::QmakeAndroidRunConfiguration(Target *parent, QmakeAndroidRunConfiguration *source)
- : AndroidRunConfiguration(parent, source)
- , m_proFilePath(source->m_proFilePath)
- , m_parseSuccess(source->m_parseSuccess)
- , m_parseInProgress(source->m_parseInProgress)
+void QmakeAndroidRunConfiguration::copyFrom(const QmakeAndroidRunConfiguration *source)
{
- init();
+ AndroidRunConfiguration::copyFrom(source);
+ m_proFilePath = source->m_proFilePath;
+
+ ctor();
}
-void QmakeAndroidRunConfiguration::init()
+void QmakeAndroidRunConfiguration::ctor()
{
setDefaultDisplayName(defaultDisplayName());
- connect(qmakeProject(), &QmakeProject::proFileUpdated,
- this, &QmakeAndroidRunConfiguration::proFileUpdated);
+ QTC_CHECK(!m_proFilePath.isEmpty());
}
bool QmakeAndroidRunConfiguration::fromMap(const QVariantMap &map)
@@ -86,24 +86,17 @@ bool QmakeAndroidRunConfiguration::fromMap(const QVariantMap &map)
QTC_ASSERT(project, return false);
const QDir projectDir = QDir(project->projectDirectory().toString());
m_proFilePath = Utils::FileName::fromUserInput(projectDir.filePath(map.value(PRO_FILE_KEY).toString()));
- m_parseSuccess = project->validParse(m_proFilePath);
- m_parseInProgress = project->parseInProgress(m_proFilePath);
return AndroidRunConfiguration::fromMap(map);
}
QVariantMap QmakeAndroidRunConfiguration::toMap() const
{
- QmakeProject *project = qmakeProject();
- if (m_proFilePath.isEmpty()) {
- if (!project->rootProjectNode())
- return QVariantMap();
- m_proFilePath = project->rootProjectNode()->filePath();
- }
-
- const QDir projectDir = QDir(project->projectDirectory().toString());
QVariantMap map(AndroidRunConfiguration::toMap());
+
+ const QDir projectDir = QDir(target()->project()->projectDirectory().toString());
map.insert(PRO_FILE_KEY, projectDir.relativeFilePath(m_proFilePath.toString()));
+
return map;
}
@@ -117,21 +110,16 @@ QString QmakeAndroidRunConfiguration::defaultDisplayName()
return node->displayName();
}
- return QFileInfo(pathFromId(id())).completeBaseName();
-}
-
-bool QmakeAndroidRunConfiguration::isEnabled() const
-{
- return m_parseSuccess && !m_parseInProgress;
+ return displayNameForId(id());
}
QString QmakeAndroidRunConfiguration::disabledReason() const
{
- if (m_parseInProgress)
+ if (qmakeProject()->isParsing())
return tr("The .pro file \"%1\" is currently being parsed.")
.arg(m_proFilePath.fileName());
- if (!m_parseSuccess)
+ if (!qmakeProject()->hasParsingData())
return qmakeProject()->disabledReasonForRunConfiguration(m_proFilePath);
return QString();
}
@@ -141,25 +129,9 @@ QString QmakeAndroidRunConfiguration::buildSystemTarget() const
return qmakeProject()->mapProFilePathToTarget(m_proFilePath);
}
-void QmakeAndroidRunConfiguration::proFileUpdated(QmakeProjectManager::QmakeProFile *pro,
- bool success, bool parseInProgress)
+QString QmakeAndroidRunConfiguration::displayNameForId(Core::Id id)
{
- QmakeProject *project = qmakeProject();
- if (m_proFilePath.isEmpty() && project->rootProjectNode())
- m_proFilePath = project->rootProjectNode()->filePath();
-
- if (m_proFilePath != pro->filePath())
- return;
-
- bool enabled = isEnabled();
- QString reason = disabledReason();
- m_parseSuccess = success;
- m_parseInProgress = parseInProgress;
- if (enabled != isEnabled() || reason != disabledReason())
- emit enabledChanged();
-
- if (!parseInProgress)
- setDefaultDisplayName(defaultDisplayName());
+ return pathFromId(id).toFileInfo().completeBaseName();
}
QmakeProject *QmakeAndroidRunConfiguration::qmakeProject() const
diff --git a/src/plugins/qmakeandroidsupport/qmakeandroidrunconfiguration.h b/src/plugins/qmakeandroidsupport/qmakeandroidrunconfiguration.h
index f7ff72987cb..c0265b9abbc 100644
--- a/src/plugins/qmakeandroidsupport/qmakeandroidrunconfiguration.h
+++ b/src/plugins/qmakeandroidsupport/qmakeandroidrunconfiguration.h
@@ -40,34 +40,31 @@ namespace Internal {
class QmakeAndroidRunConfiguration : public Android::AndroidRunConfiguration
{
Q_OBJECT
- friend class QmakeAndroidRunConfigurationFactory;
public:
- QmakeAndroidRunConfiguration(ProjectExplorer::Target *parent, Core::Id id,
- const Utils::FileName &path = Utils::FileName());
+ explicit QmakeAndroidRunConfiguration(ProjectExplorer::Target *target);
Utils::FileName proFilePath() const;
- bool isEnabled() const override;
QString disabledReason() const override;
QString buildSystemTarget() const final;
-protected:
- QmakeAndroidRunConfiguration(ProjectExplorer::Target *parent, QmakeAndroidRunConfiguration *source);
+ static QString displayNameForId(Core::Id id);
+
+private:
+ friend class ProjectExplorer::IRunConfigurationFactory;
+ void initialize(Core::Id id);
+ void copyFrom(const QmakeAndroidRunConfiguration *source);
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
QString defaultDisplayName();
-private:
- void proFileUpdated(QmakeProjectManager::QmakeProFile *pro, bool success, bool parseInProgress);
QmakeProjectManager::QmakeProject *qmakeProject() const;
- void init();
+ void ctor();
mutable Utils::FileName m_proFilePath;
- bool m_parseSuccess;
- bool m_parseInProgress;
};
} // namespace Internal
diff --git a/src/plugins/qmakeandroidsupport/qmakeandroidrunfactories.cpp b/src/plugins/qmakeandroidsupport/qmakeandroidrunfactories.cpp
index 2f93281adad..4fd903972ce 100644
--- a/src/plugins/qmakeandroidsupport/qmakeandroidrunfactories.cpp
+++ b/src/plugins/qmakeandroidsupport/qmakeandroidrunfactories.cpp
@@ -46,11 +46,6 @@ namespace Internal {
static const char ANDROID_RC_ID_PREFIX[] = "Qt4ProjectManager.AndroidRunConfiguration:";
-static Utils::FileName pathFromId(const Core::Id id)
-{
- return Utils::FileName::fromString(id.suffixAfter(ANDROID_RC_ID_PREFIX));
-}
-
QmakeAndroidRunConfigurationFactory::QmakeAndroidRunConfigurationFactory(QObject *parent)
: IRunConfigurationFactory(parent)
{
@@ -58,7 +53,7 @@ QmakeAndroidRunConfigurationFactory::QmakeAndroidRunConfigurationFactory(QObject
QString QmakeAndroidRunConfigurationFactory::displayNameForId(Core::Id id) const
{
- return pathFromId(id).toFileInfo().completeBaseName();
+ return QmakeAndroidRunConfiguration::displayNameForId(id);
}
bool QmakeAndroidRunConfigurationFactory::canCreate(Target *parent, Core::Id id) const
@@ -92,27 +87,21 @@ QList<Core::Id> QmakeAndroidRunConfigurationFactory::availableCreationIds(Target
RunConfiguration *QmakeAndroidRunConfigurationFactory::doCreate(Target *parent, Core::Id id)
{
- if (parent->project()->rootProjectNode())
- return new QmakeAndroidRunConfiguration(parent, id, pathFromId(id));
- return new QmakeAndroidRunConfiguration(parent, id);
+ return createHelper<QmakeAndroidRunConfiguration>(parent, id);
}
RunConfiguration *QmakeAndroidRunConfigurationFactory::doRestore(Target *parent,
const QVariantMap &map)
{
Core::Id id = ProjectExplorer::idFromMap(map);
- if (parent->project()->rootProjectNode())
- return new QmakeAndroidRunConfiguration(parent, id);
- return new QmakeAndroidRunConfiguration(parent, id);
+ return createHelper<QmakeAndroidRunConfiguration>(parent, id);
}
RunConfiguration *QmakeAndroidRunConfigurationFactory::clone(Target *parent, RunConfiguration *source)
{
if (!canClone(parent, source))
return 0;
-
- QmakeAndroidRunConfiguration *old = static_cast<QmakeAndroidRunConfiguration *>(source);
- return new QmakeAndroidRunConfiguration(parent, old);
+ return cloneHelper<QmakeAndroidRunConfiguration>(parent, source);
}
bool QmakeAndroidRunConfigurationFactory::canHandle(Target *t) const
diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp
index a4a1302769e..60ba1523590 100644
--- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp
+++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp
@@ -76,64 +76,33 @@ static Utils::FileName pathFromId(Core::Id id)
// QmakeRunConfiguration
//
-DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *parent, Core::Id id) :
- RunConfiguration(parent, id),
- m_proFilePath(pathFromId(id))
+DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *target)
+ : RunConfiguration(target)
{
addExtraAspect(new LocalEnvironmentAspect(this, [](RunConfiguration *rc, Environment &env) {
static_cast<DesktopQmakeRunConfiguration *>(rc)->addToBaseEnvironment(env);
}));
- addExtraAspect(new ArgumentsAspect(this, QStringLiteral("Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments")));
- addExtraAspect(new TerminalAspect(this, QStringLiteral("Qt4ProjectManager.Qt4RunConfiguration.UseTerminal")));
- addExtraAspect(new WorkingDirectoryAspect(this,
- QStringLiteral("Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory")));
- QmakeProject *project = qmakeProject();
- m_parseSuccess = project->validParse(m_proFilePath);
- m_parseInProgress = project->parseInProgress(m_proFilePath);
-
- ctor();
-}
-
-DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *parent, DesktopQmakeRunConfiguration *source) :
- RunConfiguration(parent, source),
- m_proFilePath(source->m_proFilePath),
- m_isUsingDyldImageSuffix(source->m_isUsingDyldImageSuffix),
- m_isUsingLibrarySearchPath(source->m_isUsingLibrarySearchPath),
- m_parseSuccess(source->m_parseSuccess),
- m_parseInProgress(source->m_parseInProgress)
-{
- ctor();
-}
-
-bool DesktopQmakeRunConfiguration::isEnabled() const
-{
- return m_parseSuccess && !m_parseInProgress;
+ addExtraAspect(new ArgumentsAspect(this, "Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"));
+ addExtraAspect(new TerminalAspect(this, "Qt4ProjectManager.Qt4RunConfiguration.UseTerminal"));
+ addExtraAspect(new WorkingDirectoryAspect(this, "Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"));
}
-QString DesktopQmakeRunConfiguration::disabledReason() const
+void DesktopQmakeRunConfiguration::initialize(Core::Id id)
{
- if (m_parseInProgress)
- return tr("The .pro file \"%1\" is currently being parsed.")
- .arg(m_proFilePath.fileName());
+ RunConfiguration::initialize(id);
+ m_proFilePath = pathFromId(id);
- if (!m_parseSuccess)
- return qmakeProject()->disabledReasonForRunConfiguration(m_proFilePath);
- return QString();
+ ctor();
}
-void DesktopQmakeRunConfiguration::proFileUpdated(QmakeProFile *pro, bool success, bool parseInProgress)
+void DesktopQmakeRunConfiguration::copyFrom(const DesktopQmakeRunConfiguration *source)
{
- if (m_proFilePath != pro->filePath())
- return;
- const bool enabled = isEnabled();
- const QString reason = disabledReason();
- m_parseSuccess = success;
- m_parseInProgress = parseInProgress;
- if (enabled != isEnabled() || reason != disabledReason())
- emit enabledChanged();
+ RunConfiguration::copyFrom(source);
+ m_proFilePath = source->m_proFilePath;
+ m_isUsingDyldImageSuffix = source->m_isUsingDyldImageSuffix;
+ m_isUsingLibrarySearchPath = source->m_isUsingLibrarySearchPath;
- if (!parseInProgress)
- updateTargetInformation();
+ ctor();
}
void DesktopQmakeRunConfiguration::proFileEvaluated()
@@ -165,8 +134,8 @@ void DesktopQmakeRunConfiguration::ctor()
setDefaultDisplayName(defaultDisplayName());
QmakeProject *project = qmakeProject();
- connect(project, &QmakeProject::proFileUpdated,
- this, &DesktopQmakeRunConfiguration::proFileUpdated);
+ connect(project, &Project::parsingFinished,
+ this, &DesktopQmakeRunConfiguration::updateTargetInformation);
connect(project, &QmakeProject::proFilesEvaluated,
this, &DesktopQmakeRunConfiguration::proFileEvaluated);
@@ -183,17 +152,6 @@ DesktopQmakeRunConfigurationWidget::DesktopQmakeRunConfigurationWidget(DesktopQm
auto vboxTopLayout = new QVBoxLayout(this);
vboxTopLayout->setMargin(0);
- auto hl = new QHBoxLayout();
- hl->addStretch();
- m_disabledIcon = new QLabel(this);
- m_disabledIcon->setPixmap(Utils::Icons::WARNING.pixmap());
- hl->addWidget(m_disabledIcon);
- m_disabledReason = new QLabel(this);
- m_disabledReason->setVisible(false);
- hl->addWidget(m_disabledReason);
- hl->addStretch();
- vboxTopLayout->addLayout(hl);
-
auto detailsContainer = new DetailsWidget(this);
detailsContainer->setState(DetailsWidget::NoSummary);
vboxTopLayout->addWidget(detailsContainer);
@@ -249,8 +207,6 @@ DesktopQmakeRunConfigurationWidget::DesktopQmakeRunConfigurationWidget(DesktopQm
this, &DesktopQmakeRunConfigurationWidget::usingLibrarySearchPathToggled);
}
- runConfigurationEnabledChange();
-
connect(qmakeRunConfiguration, &DesktopQmakeRunConfiguration::usingDyldImageSuffixChanged,
this, &DesktopQmakeRunConfigurationWidget::usingDyldImageSuffixChanged);
connect(qmakeRunConfiguration, &DesktopQmakeRunConfiguration::usingLibrarySearchPathChanged,
@@ -258,21 +214,10 @@ DesktopQmakeRunConfigurationWidget::DesktopQmakeRunConfigurationWidget(DesktopQm
connect(qmakeRunConfiguration, &DesktopQmakeRunConfiguration::effectiveTargetInformationChanged,
this, &DesktopQmakeRunConfigurationWidget::effectiveTargetInformationChanged, Qt::QueuedConnection);
- connect(qmakeRunConfiguration, &RunConfiguration::enabledChanged,
- this, &DesktopQmakeRunConfigurationWidget::runConfigurationEnabledChange);
-
Core::VariableChooser::addSupportForChildWidgets(this, m_qmakeRunConfiguration->macroExpander());
effectiveTargetInformationChanged();
}
-void DesktopQmakeRunConfigurationWidget::runConfigurationEnabledChange()
-{
- bool enabled = m_qmakeRunConfiguration->isEnabled();
- m_disabledIcon->setVisible(!enabled);
- m_disabledReason->setVisible(!enabled);
- m_disabledReason->setText(m_qmakeRunConfiguration->disabledReason());
-}
-
void DesktopQmakeRunConfigurationWidget::usingDyldImageSuffixToggled(bool state)
{
m_ignoreChange = true;
@@ -337,9 +282,6 @@ bool DesktopQmakeRunConfiguration::fromMap(const QVariantMap &map)
m_isUsingDyldImageSuffix = map.value(QLatin1String(USE_DYLD_IMAGE_SUFFIX_KEY), false).toBool();
m_isUsingLibrarySearchPath = map.value(QLatin1String(USE_LIBRARY_SEARCH_PATH), true).toBool();
- m_parseSuccess = qmakeProject()->validParse(m_proFilePath);
- m_parseInProgress = qmakeProject()->parseInProgress(m_proFilePath);
-
return RunConfiguration::fromMap(map);
}
@@ -527,7 +469,7 @@ bool DesktopQmakeRunConfigurationFactory::canCreate(Target *parent, Core::Id id)
RunConfiguration *DesktopQmakeRunConfigurationFactory::doCreate(Target *parent, Core::Id id)
{
- return new DesktopQmakeRunConfiguration(parent, id);
+ return createHelper<DesktopQmakeRunConfiguration>(parent, id);
}
bool DesktopQmakeRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
@@ -539,7 +481,7 @@ bool DesktopQmakeRunConfigurationFactory::canRestore(Target *parent, const QVari
RunConfiguration *DesktopQmakeRunConfigurationFactory::doRestore(Target *parent, const QVariantMap &map)
{
- return new DesktopQmakeRunConfiguration(parent, idFromMap(map));
+ return createHelper<DesktopQmakeRunConfiguration>(parent, idFromMap(map));
}
bool DesktopQmakeRunConfigurationFactory::canClone(Target *parent, RunConfiguration *source) const
@@ -551,8 +493,7 @@ RunConfiguration *DesktopQmakeRunConfigurationFactory::clone(Target *parent, Run
{
if (!canClone(parent, source))
return 0;
- DesktopQmakeRunConfiguration *old = static_cast<DesktopQmakeRunConfiguration *>(source);
- return new DesktopQmakeRunConfiguration(parent, old);
+ return cloneHelper<DesktopQmakeRunConfiguration>(parent, source);
}
QList<Core::Id> DesktopQmakeRunConfigurationFactory::availableCreationIds(Target *parent, CreationMode mode) const
diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h
index ff7c86b5fc7..706758038f4 100644
--- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h
+++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h
@@ -53,13 +53,11 @@ class DesktopQmakeRunConfiguration : public ProjectExplorer::RunConfiguration
Q_OBJECT
// to change the display name and arguments and set the userenvironmentchanges
friend class DesktopQmakeRunConfigurationWidget;
- friend class DesktopQmakeRunConfigurationFactory;
+ friend class ProjectExplorer::IRunConfigurationFactory;
public:
- DesktopQmakeRunConfiguration(ProjectExplorer::Target *parent, Core::Id id);
+ explicit DesktopQmakeRunConfiguration(ProjectExplorer::Target *target);
- bool isEnabled() const override;
- QString disabledReason() const override;
QWidget *createConfigurationWidget() override;
ProjectExplorer::Runnable runnable() const override;
@@ -90,11 +88,12 @@ signals:
void effectiveTargetInformationChanged();
protected:
- DesktopQmakeRunConfiguration(ProjectExplorer::Target *parent, DesktopQmakeRunConfiguration *source);
+ void initialize(Core::Id id);
+ void copyFrom(const DesktopQmakeRunConfiguration *source);
+
bool fromMap(const QVariantMap &map) override;
private:
- void proFileUpdated(QmakeProjectManager::QmakeProFile *pro, bool success, bool parseInProgress);
void proFileEvaluated();
void updateTargetInformation();
@@ -113,8 +112,6 @@ private:
// Cached startup sub project information
bool m_isUsingDyldImageSuffix = false;
bool m_isUsingLibrarySearchPath = true;
- bool m_parseSuccess = false;
- bool m_parseInProgress = false;
};
class DesktopQmakeRunConfigurationWidget : public QWidget
@@ -125,7 +122,6 @@ public:
explicit DesktopQmakeRunConfigurationWidget(DesktopQmakeRunConfiguration *qmakeRunConfiguration);
private:
- void runConfigurationEnabledChange();
void effectiveTargetInformationChanged();
void usingDyldImageSuffixToggled(bool);
void usingDyldImageSuffixChanged(bool);
@@ -135,8 +131,6 @@ private:
private:
DesktopQmakeRunConfiguration *m_qmakeRunConfiguration = nullptr;
bool m_ignoreChange = false;
- QLabel *m_disabledIcon = nullptr;
- QLabel *m_disabledReason = nullptr;
QLabel *m_executableLineLabel = nullptr;
QCheckBox *m_useQvfbCheck = nullptr;
QCheckBox *m_usingDyldImageSuffix = nullptr;
diff --git a/src/plugins/qmakeprojectmanager/makestep.cpp b/src/plugins/qmakeprojectmanager/makestep.cpp
index de4666461ba..24c480ffc90 100644
--- a/src/plugins/qmakeprojectmanager/makestep.cpp
+++ b/src/plugins/qmakeprojectmanager/makestep.cpp
@@ -127,10 +127,10 @@ QString MakeStep::effectiveMakeCommand() const
QVariantMap MakeStep::toMap() const
{
QVariantMap map(AbstractProcessStep::toMap());
- map.insert(QLatin1String(MAKE_ARGUMENTS_KEY), m_userArgs);
- map.insert(QLatin1String(MAKE_COMMAND_KEY), m_makeCmd);
- map.insert(QLatin1String(CLEAN_KEY), m_clean);
- map.insert(QLatin1String(AUTOMATICLY_ADDED_MAKE_ARGUMENTS_KEY), automaticallyAddedArguments());
+ map.insert(MAKE_ARGUMENTS_KEY, m_userArgs);
+ map.insert(MAKE_COMMAND_KEY, m_makeCmd);
+ map.insert(CLEAN_KEY, m_clean);
+ map.insert(AUTOMATICLY_ADDED_MAKE_ARGUMENTS_KEY, automaticallyAddedArguments());
return map;
}
@@ -139,20 +139,20 @@ QStringList MakeStep::automaticallyAddedArguments() const
ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID);
if (!tc || tc->targetAbi().binaryFormat() == Abi::PEFormat)
return QStringList();
- return QStringList() << QLatin1String("-w") << QLatin1String("-r");
+ return QStringList() << "-w" << "-r";
}
bool MakeStep::fromMap(const QVariantMap &map)
{
- m_makeCmd = map.value(QLatin1String(MAKE_COMMAND_KEY)).toString();
- m_userArgs = map.value(QLatin1String(MAKE_ARGUMENTS_KEY)).toString();
- m_clean = map.value(QLatin1String(CLEAN_KEY)).toBool();
+ m_makeCmd = map.value(MAKE_COMMAND_KEY).toString();
+ m_userArgs = map.value(MAKE_ARGUMENTS_KEY).toString();
+ m_clean = map.value(CLEAN_KEY).toBool();
QStringList oldAddedArgs
- = map.value(QLatin1String(AUTOMATICLY_ADDED_MAKE_ARGUMENTS_KEY)).toStringList();
+ = map.value(AUTOMATICLY_ADDED_MAKE_ARGUMENTS_KEY).toStringList();
foreach (const QString &newArg, automaticallyAddedArguments()) {
if (oldAddedArgs.contains(newArg))
continue;
- m_userArgs.prepend(newArg + QLatin1Char(' '));
+ m_userArgs.prepend(newArg + ' ');
}
return AbstractProcessStep::fromMap(map);
@@ -199,28 +199,28 @@ bool MakeStep::init(QList<const BuildStep *> &earlierSteps)
if (subProFile) {
QString makefile = subProFile->makefile();
if (makefile.isEmpty())
- makefile = QLatin1String("Makefile");
+ makefile = "Makefile";
// Use Makefile.Debug and Makefile.Release
// for file builds, since the rules for that are
// only in those files.
if (subProFile->isDebugAndRelease() && bc->fileNodeBuild()) {
if (bc->buildType() == QmakeBuildConfiguration::Debug)
- makefile += QLatin1String(".Debug");
+ makefile += ".Debug";
else
- makefile += QLatin1String(".Release");
+ makefile += ".Release";
}
- if (makefile != QLatin1String("Makefile")) {
- Utils::QtcProcess::addArg(&args, QLatin1String("-f"));
+ if (makefile != "Makefile") {
+ Utils::QtcProcess::addArg(&args, "-f");
Utils::QtcProcess::addArg(&args, makefile);
}
m_makeFileToCheck = QDir(workingDirectory).filePath(makefile);
} else {
if (!bc->makefile().isEmpty()) {
- Utils::QtcProcess::addArg(&args, QLatin1String("-f"));
+ Utils::QtcProcess::addArg(&args, "-f");
Utils::QtcProcess::addArg(&args, bc->makefile());
m_makeFileToCheck = QDir(workingDirectory).filePath(bc->makefile());
} else {
- m_makeFileToCheck = QDir(workingDirectory).filePath(QLatin1String("Makefile"));
+ m_makeFileToCheck = QDir(workingDirectory).filePath("Makefile");
}
}
@@ -231,16 +231,16 @@ bool MakeStep::init(QList<const BuildStep *> &earlierSteps)
objectsDir = subProFile->buildDir(bc).toString();
if (subProFile->isDebugAndRelease()) {
if (bc->buildType() == QmakeBuildConfiguration::Debug)
- objectsDir += QLatin1String("/debug");
+ objectsDir += "/debug";
else
- objectsDir += QLatin1String("/release");
+ objectsDir += "/release";
}
}
QString relObjectsDir = QDir(pp->workingDirectory()).relativeFilePath(objectsDir);
- if (relObjectsDir == QLatin1String("."))
+ if (relObjectsDir == ".")
relObjectsDir.clear();
if (!relObjectsDir.isEmpty())
- relObjectsDir += QLatin1Char('/');
+ relObjectsDir += '/';
QString objectFile = relObjectsDir +
bc->fileNodeBuild()->filePath().toFileInfo().baseName() +
subProFile->objectExtension();
@@ -252,8 +252,8 @@ bool MakeStep::init(QList<const BuildStep *> &earlierSteps)
if (tc && makeCommand().isEmpty()) {
if (tc->targetAbi().os() == Abi::WindowsOS
&& tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor) {
- const QString makeFlags = QLatin1String("MAKEFLAGS");
- env.set(makeFlags, QLatin1Char('L') + env.value(makeFlags));
+ const QString makeFlags = "MAKEFLAGS";
+ env.set(makeFlags, 'L' + env.value(makeFlags));
}
}
@@ -322,7 +322,7 @@ MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep)
m_ui->makePathChooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
m_ui->makePathChooser->setBaseDirectory(Utils::PathChooser::homePath());
- m_ui->makePathChooser->setHistoryCompleter(QLatin1String("PE.MakeCommand.History"));
+ m_ui->makePathChooser->setHistoryCompleter("PE.MakeCommand.History");
const QString &makeCmd = m_makeStep->makeCommand();
m_ui->makePathChooser->setPath(makeCmd);
@@ -434,8 +434,8 @@ void MakeStepConfigWidget::updateDetails()
if (tc && m_makeStep->makeCommand().isEmpty()) {
if (tc->targetAbi().os() == Abi::WindowsOS
&& tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor) {
- const QString makeFlags = QLatin1String("MAKEFLAGS");
- env.set(makeFlags, QLatin1Char('L') + env.value(makeFlags));
+ const QString makeFlags = "MAKEFLAGS";
+ env.set(makeFlags, 'L' + env.value(makeFlags));
}
}
param.setArguments(args);
@@ -502,7 +502,7 @@ BuildStep *MakeStepFactory::create(BuildStepList *parent, Core::Id id)
MakeStep *step = new MakeStep(parent);
if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
step->setClean(true);
- step->setUserArguments(QLatin1String("clean"));
+ step->setUserArguments("clean");
}
return step;
}
diff --git a/src/plugins/qmakeprojectmanager/profileeditor.cpp b/src/plugins/qmakeprojectmanager/profileeditor.cpp
index 97c119c456e..637cb1b239c 100644
--- a/src/plugins/qmakeprojectmanager/profileeditor.cpp
+++ b/src/plugins/qmakeprojectmanager/profileeditor.cpp
@@ -46,6 +46,8 @@
#include <QDir>
#include <QTextBlock>
+#include <algorithm>
+
using namespace TextEditor;
using namespace Utils;
@@ -89,7 +91,40 @@ ProFileEditorWidget::Link ProFileEditorWidget::findLinkAt(const QTextCursor &cur
// find the beginning of a filename
QString buffer;
int beginPos = positionInBlock - 1;
- while (beginPos >= 0) {
+ int endPos = positionInBlock;
+
+ // Check is cursor is somewhere on $${PWD}:
+ const int chunkStart = std::max(0, positionInBlock - 7);
+ const int chunkLength = 14 + std::min(0, positionInBlock - 7);
+ QString chunk = block.mid(chunkStart, chunkLength);
+
+ const QString curlyPwd = "$${PWD}";
+ const QString pwd = "$$PWD";
+ const int posCurlyPwd = chunk.indexOf(curlyPwd);
+ const int posPwd = chunk.indexOf(pwd);
+ bool doBackwardScan = true;
+
+ if (posCurlyPwd >= 0) {
+ const int end = chunkStart + posCurlyPwd + curlyPwd.count();
+ const int start = chunkStart + posCurlyPwd;
+ if (start <= positionInBlock && end >= positionInBlock) {
+ buffer = pwd;
+ beginPos = chunkStart + posCurlyPwd - 1;
+ endPos = end;
+ doBackwardScan = false;
+ }
+ } else if (posPwd >= 0) {
+ const int end = chunkStart + posPwd + pwd.count();
+ const int start = chunkStart + posPwd;
+ if (start <= positionInBlock && end >= positionInBlock) {
+ buffer = pwd;
+ beginPos = start - 1;
+ endPos = end;
+ doBackwardScan = false;
+ }
+ }
+
+ while (doBackwardScan && beginPos >= 0) {
QChar c = block.at(beginPos);
if (isValidFileNameChar(c)) {
buffer.prepend(c);
@@ -99,8 +134,20 @@ ProFileEditorWidget::Link ProFileEditorWidget::findLinkAt(const QTextCursor &cur
}
}
+ if (doBackwardScan
+ && beginPos > 0
+ && block.mid(beginPos - 1, pwd.count()) == pwd
+ && (block.at(beginPos + pwd.count() - 1) == '/' || block.at(beginPos + pwd.count() - 1) == '\\')) {
+ buffer.prepend("$$");
+ beginPos -= 2;
+ } else if (doBackwardScan
+ && beginPos >= curlyPwd.count() - 1
+ && block.mid(beginPos - curlyPwd.count() + 1, curlyPwd.count()) == curlyPwd) {
+ buffer.prepend(pwd);
+ beginPos -= curlyPwd.count();
+ }
+
// find the end of a filename
- int endPos = positionInBlock;
while (endPos < block.count()) {
QChar c = block.at(endPos);
if (isValidFileNameChar(c)) {
@@ -121,13 +168,8 @@ ProFileEditorWidget::Link ProFileEditorWidget::findLinkAt(const QTextCursor &cur
}
// if the buffer starts with $$PWD accept it
- if (buffer.startsWith(QLatin1String("PWD/")) ||
- buffer.startsWith(QLatin1String("PWD\\"))) {
- if (beginPos > 0 && block.mid(beginPos - 1, 2) == QLatin1String("$$")) {
- beginPos -=2;
- buffer = buffer.mid(4);
- }
- }
+ if (buffer.startsWith("$$PWD/") || buffer.startsWith("$$PWD\\"))
+ buffer = buffer.mid(6);
QDir dir(textDocument()->filePath().toFileInfo().absolutePath());
QString fileName = dir.filePath(buffer);
diff --git a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp
index 268b01dbc20..57550e2e52f 100644
--- a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp
@@ -85,7 +85,8 @@ void QmakeKitInformation::setup(Kit *k)
ToolChain *tc = ToolChainKitInformation::toolChain(k, Constants::CXX_LANGUAGE_ID);
if (!tc || (!tc->suggestedMkspecList().empty() && !tc->suggestedMkspecList().contains(spec))) {
- const QList<ToolChain *> possibleTcs = ToolChainManager::toolChains([version, &spec](const ToolChain *t) {
+ const QList<ToolChain *> possibleTcs = ToolChainManager::toolChains(
+ [version](const ToolChain *t) {
return t->isValid()
&& t->language() == Core::Id(Constants::CXX_LANGUAGE_ID)
&& version->qtAbis().contains(t->targetAbi());
@@ -113,7 +114,7 @@ KitInformation::ItemList QmakeKitInformation::toUserOutput(const Kit *k) const
void QmakeKitInformation::addToMacroExpander(Kit *kit, MacroExpander *expander) const
{
expander->registerVariable("Qmake:mkspec", tr("Mkspec configured for qmake by the Kit."),
- [this, kit]() -> QString {
+ [kit]() -> QString {
return QmakeKitInformation::mkspec(kit).toUserOutput();
});
}
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
index 007e47b0180..f19723df952 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
@@ -74,12 +74,12 @@ QmakeProFileNode *QmakePriFileNode::proFileNode() const
return m_qmakeProFileNode;
}
-bool QmakePriFileNode::supportsAction(ProjectAction action, Node *node) const
+bool QmakePriFileNode::supportsAction(ProjectAction action, const Node *node) const
{
if (action == Rename || action == DuplicateFile) {
- FileNode *fileNode = node->asFileNode();
+ const FileNode *fileNode = node->asFileNode();
return (fileNode && fileNode->fileType() != FileType::Project)
- || dynamic_cast<ResourceEditor::ResourceTopLevelNode *>(node);
+ || dynamic_cast<const ResourceEditor::ResourceTopLevelNode *>(node);
}
const FolderNode *folderNode = this;
@@ -109,7 +109,7 @@ bool QmakePriFileNode::supportsAction(ProjectAction action, Node *node) const
bool addExistingFiles = true;
if (node->nodeType() == NodeType::VirtualFolder) {
// A virtual folder, we do what the projectexplorer does
- FolderNode *folder = node->asFolderNode();
+ const FolderNode *folder = node->asFolderNode();
if (folder) {
QStringList list;
foreach (FolderNode *f, folder->folderNodes())
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h
index 719e42a05a1..aca17e18a29 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.h
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.h
@@ -47,7 +47,7 @@ public:
QmakePriFile *priFile() const;
// ProjectNode interface
- bool supportsAction(ProjectExplorer::ProjectAction action, Node *node) const override;
+ bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
bool showInSimpleTree() const override { return false; }
diff --git a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
index fea0898dde7..a65b9cd44b4 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
@@ -37,9 +37,6 @@
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
-#include <QApplication>
-#include <QStyle>
-
using namespace Core;
using namespace ProjectExplorer;
using namespace QtSupport;
@@ -106,23 +103,15 @@ QmakeStaticData::QmakeStaticData()
const unsigned count = sizeof(fileTypeDataStorage)/sizeof(FileTypeDataStorage);
fileTypeData.reserve(count);
- // Overlay the SP_DirIcon with the custom icons
- const QSize desiredSize = QSize(16, 16);
-
- const QPixmap dirPixmap = QApplication::style()->standardIcon(QStyle::SP_DirIcon).pixmap(desiredSize);
for (unsigned i = 0 ; i < count; ++i) {
- const QIcon overlayIcon(QLatin1String(fileTypeDataStorage[i].icon));
- QIcon folderIcon;
- folderIcon.addPixmap(FileIconProvider::overlayIcon(dirPixmap, overlayIcon));
const QString desc = QCoreApplication::translate("QmakeProjectManager::QmakePriFile", fileTypeDataStorage[i].typeName);
const QString filter = QString::fromUtf8(fileTypeDataStorage[i].addFileFilter);
fileTypeData.push_back(QmakeStaticData::FileTypeData(fileTypeDataStorage[i].type,
- desc, filter, folderIcon));
+ desc, filter,
+ Core::FileIconProvider::directoryIcon(QLatin1String(fileTypeDataStorage[i].icon))));
}
// Project icon
- const QIcon projectBaseIcon(ProjectExplorer::Constants::FILEOVERLAY_QT);
- const QPixmap projectPixmap = FileIconProvider::overlayIcon(dirPixmap, projectBaseIcon);
- projectIcon.addPixmap(projectPixmap);
+ projectIcon = Core::FileIconProvider::directoryIcon(ProjectExplorer::Constants::FILEOVERLAY_QT);
qAddPostRoutine(clearQmakeStaticData);
}
diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
index 1611156d6b5..38e25554cfb 100644
--- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
@@ -1184,9 +1184,9 @@ void QmakeProFile::asyncUpdate()
m_parseFutureWatcher.waitForFinished();
QmakeEvalInput input = evalInput();
QFuture<QmakeEvalResult *> future = Utils::runAsync(ProjectExplorerPlugin::sharedThreadPool(),
- QThread::LowestPriority,
- &QmakeProFile::asyncEvaluate,
- this, input);
+ QThread::LowestPriority,
+ &QmakeProFile::asyncEvaluate,
+ this, input);
m_parseFutureWatcher.setFuture(future);
}
@@ -1473,7 +1473,7 @@ void QmakeProFile::asyncEvaluate(QFutureInterface<QmakeEvalResult *> &fi, QmakeE
void QmakeProFile::applyAsyncEvaluate()
{
applyEvaluate(m_parseFutureWatcher.result());
- m_project->decrementPendingEvaluateFutures();
+ m_project->decrementPendingEvaluateFutures(validParse());
}
bool sortByParserNodes(Node *a, Node *b)
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
index cca96c070ef..c3b847447aa 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
@@ -290,9 +290,13 @@ void QmakeProject::updateCppCodeModel()
rpp.setDisplayName(pro->displayName());
rpp.setProjectFileLocation(pro->filePath().toString());
rpp.setBuildSystemTarget(pro->targetInformation().target);
+ const bool isExecutable = pro->projectType() == ProjectType::ApplicationTemplate;
+ rpp.setBuildTargetType(isExecutable ? CppTools::ProjectPart::Executable
+ : CppTools::ProjectPart::Library);
+
// TODO: Handle QMAKE_CFLAGS
rpp.setFlagsForCxx({cxxToolChain, pro->variableValue(Variable::CppFlags)});
- rpp.setDefines(pro->cxxDefines());
+ rpp.setMacros(ProjectExplorer::Macro::toMacros(pro->cxxDefines()));
rpp.setPreCompiledHeaders(pro->variableValue(Variable::PrecompiledHeader));
rpp.setSelectedForBuilding(pro->includedInExactParse());
@@ -410,6 +414,7 @@ void QmakeProject::scheduleAsyncUpdate(QmakeProFile *file, QmakeProFile::AsyncUp
return;
}
+ emitParsingStarted();
file->setParseInProgressRecursive(true);
setAllBuildConfigurationsEnabled(false);
@@ -466,6 +471,7 @@ void QmakeProject::scheduleAsyncUpdate(QmakeProFile::AsyncUpdateDelay delay)
return;
}
+ emitParsingStarted();
rootProFile()->setParseInProgressRecursive(true);
setAllBuildConfigurationsEnabled(false);
@@ -494,19 +500,26 @@ void QmakeProject::startAsyncTimer(QmakeProFile::AsyncUpdateDelay delay)
void QmakeProject::incrementPendingEvaluateFutures()
{
++m_pendingEvaluateFuturesCount;
+ if (m_pendingEvaluateFuturesCount == 1)
+ m_totalEvaluationSuccess = true;
m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(),
- m_asyncUpdateFutureInterface->progressMaximum() + 1);
+ m_asyncUpdateFutureInterface->progressMaximum() + 1);
}
-void QmakeProject::decrementPendingEvaluateFutures()
+void QmakeProject::decrementPendingEvaluateFutures(bool success)
{
--m_pendingEvaluateFuturesCount;
+ m_totalEvaluationSuccess = m_totalEvaluationSuccess && success;
+
m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue() + 1);
if (m_pendingEvaluateFuturesCount == 0) {
// We are done!
setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this));
+ if (!m_totalEvaluationSuccess)
+ m_asyncUpdateFutureInterface->reportCanceled();
+
m_asyncUpdateFutureInterface->reportFinished();
delete m_asyncUpdateFutureInterface;
m_asyncUpdateFutureInterface = nullptr;
@@ -514,6 +527,7 @@ void QmakeProject::decrementPendingEvaluateFutures()
// TODO clear the profile cache ?
if (m_asyncUpdateState == AsyncFullUpdatePending || m_asyncUpdateState == AsyncPartialUpdatePending) {
+ // Already parsing!
rootProFile()->setParseInProgressRecursive(true);
setAllBuildConfigurationsEnabled(false);
startAsyncTimer(QmakeProFile::ParseLater);
@@ -528,7 +542,7 @@ void QmakeProject::decrementPendingEvaluateFutures()
activeTarget()->updateDefaultDeployConfigurations();
updateRunConfigurations();
emit proFilesEvaluated();
- emit parsingFinished();
+ emitParsingFinished(true); // Qmake always returns (some) data, even when it failed:-)
}
}
}
@@ -725,22 +739,6 @@ QmakeProFileNode *QmakeProject::rootProjectNode() const
return static_cast<QmakeProFileNode *>(Project::rootProjectNode());
}
-bool QmakeProject::validParse(const FileName &proFilePath) const
-{
- if (!rootProFile())
- return false;
- const QmakeProFile *pro = rootProFile()->findProFile(proFilePath);
- return pro && pro->validParse();
-}
-
-bool QmakeProject::parseInProgress(const FileName &proFilePath) const
-{
- if (!rootProFile())
- return false;
- const QmakeProFile *pro = rootProFile()->findProFile(proFilePath);
- return pro && pro->parseInProgress();
-}
-
QList<QmakeProFile *>
QmakeProject::collectAllProFiles(QmakeProFile *file, Parsing parse,
const QList<ProjectType> &projectTypes)
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h
index 590fe4f46ee..b8d3192f098 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.h
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.h
@@ -68,8 +68,6 @@ public:
bool supportsKit(ProjectExplorer::Kit *k, QString *errorMesage) const final;
QmakeProFileNode *rootProjectNode() const final;
- bool validParse(const Utils::FileName &proFilePath) const;
- bool parseInProgress(const Utils::FileName &proFilePath) const;
virtual QStringList filesGeneratedFrom(const QString &file) const final;
@@ -102,7 +100,7 @@ public:
/// \internal
void incrementPendingEvaluateFutures();
/// \internal
- void decrementPendingEvaluateFutures();
+ void decrementPendingEvaluateFutures(bool success);
/// \internal
bool wasEvaluateCanceled();
@@ -188,6 +186,7 @@ private:
// cached data during project rescan
QMakeGlobals *m_qmakeGlobals = nullptr;
int m_qmakeGlobalsRefCnt = 0;
+ bool m_totalEvaluationSuccess = false;
QString m_qmakeSysroot;
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
index 8a71762ef3a..4d62b470754 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
@@ -98,8 +98,15 @@ QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc)
this, &QmakeProjectConfigWidget::shadowBuildEdited);
QmakeProject *project = static_cast<QmakeProject *>(bc->target()->project());
- connect(project, &QmakeProject::environmentChanged,
- this, &QmakeProjectConfigWidget::environmentChanged);
+ project->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
+ if (static_cast<BuildConfiguration *>(sender())->isActive())
+ environmentChanged();
+ });
+ connect(project, &Project::activeProjectConfigurationChanged,
+ this, [this](ProjectConfiguration *pc) {
+ if (pc && pc->isActive())
+ environmentChanged();
+ });
connect(project, &QmakeProject::buildDirectoryInitialized,
this, &QmakeProjectConfigWidget::updateProblemLabel);
connect(project, &QmakeProject::proFilesEvaluated,
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp
index 666ec0ce51a..bfcc2f3d50c 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp
@@ -55,7 +55,7 @@ namespace QmakeProjectManager {
Node *QmakeManager::contextNode()
{
- return ProjectTree::currentNode();
+ return ProjectTree::findCurrentNode();
}
Project *QmakeManager::contextProject()
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs
index 3e6bff6572e..027173ce519 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs
@@ -16,6 +16,7 @@ Project {
Depends { name: "CppTools" }
Depends { name: "TextEditor" }
Depends { name: "ResourceEditor" }
+ Depends { name: "app_version_header" }
pluginRecommends: [
"Designer"
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
index 817676bfeea..ee18fd8e9f9 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
@@ -279,8 +279,8 @@ void QmakeProjectManagerPlugin::projectChanged()
if (m_previousStartupProject) {
connect(m_previousStartupProject, &Project::activeTargetChanged,
- this, &QmakeProjectManagerPlugin::activeTargetChanged);
- connect(m_previousStartupProject, &QmakeProject::parsingFinished,
+ this, &QmakeProjectManagerPlugin::activeTargetChanged);
+ connect(m_previousStartupProject, &Project::parsingFinished,
this, &QmakeProjectManagerPlugin::updateActions);
}
@@ -326,22 +326,22 @@ void QmakeProjectManagerPlugin::updateRunQMakeAction()
void QmakeProjectManagerPlugin::updateContextActions()
{
- Node *node = ProjectTree::currentNode();
+ const Node *node = ProjectTree::findCurrentNode();
Project *project = ProjectTree::currentProject();
- ContainerNode *containerNode = node ? node->asContainerNode() : nullptr;
- QmakeProFileNode *proFileNode = dynamic_cast<QmakeProFileNode *>(containerNode ? containerNode->rootProjectNode() : node);
+ const ContainerNode *containerNode = node ? node->asContainerNode() : nullptr;
+ const QmakeProFileNode *proFileNode = dynamic_cast<const QmakeProFileNode *>(containerNode ? containerNode->rootProjectNode() : node);
m_addLibraryActionContextMenu->setEnabled(proFileNode);
QmakeProject *qmakeProject = qobject_cast<QmakeProject *>(QmakeManager::contextProject());
QmakeProFileNode *subProjectNode = nullptr;
if (node) {
- auto subPriFileNode = dynamic_cast<QmakePriFileNode *>(node);
+ auto subPriFileNode = dynamic_cast<const QmakePriFileNode *>(node);
if (!subPriFileNode)
subPriFileNode = dynamic_cast<QmakePriFileNode *>(node->parentProjectNode());
subProjectNode = subPriFileNode ? subPriFileNode->proFileNode() : nullptr;
}
- FileNode *fileNode = node ? node->asFileNode() : nullptr;
+ const FileNode *fileNode = node ? node->asFileNode() : nullptr;
bool buildFilePossible = subProjectNode && fileNode && (fileNode->fileType() == FileType::Source);
bool subProjectActionsVisible = false;
diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp
index 54c8d0989df..dd5fa509794 100644
--- a/src/plugins/qmakeprojectmanager/qmakestep.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp
@@ -134,10 +134,10 @@ QString QMakeStep::allArguments(const BaseQtVersion *v, bool shorted) const
arguments << project()->projectFilePath().toUserOutput();
if (v->qtVersion() < QtVersionNumber(5, 0, 0))
- arguments << QLatin1String("-r");
+ arguments << "-r";
bool userProvidedMkspec = false;
for (QtcProcess::ConstArgIterator ait(m_userArgs); ait.next(); ) {
- if (ait.value() == QLatin1String("-spec")) {
+ if (ait.value() == "-spec") {
if (ait.next()) {
userProvidedMkspec = true;
break;
@@ -146,7 +146,7 @@ QString QMakeStep::allArguments(const BaseQtVersion *v, bool shorted) const
}
FileName specArg = mkspec();
if (!userProvidedMkspec && !specArg.isEmpty())
- arguments << QLatin1String("-spec") << specArg.toUserOutput();
+ arguments << "-spec" << specArg.toUserOutput();
// Find out what flags we pass on to qmake
arguments << bc->configCommandLineArguments();
@@ -538,7 +538,7 @@ FileName QMakeStep::mkspec() const
QString additionalArguments = m_userArgs;
QtcProcess::addArgs(&additionalArguments, m_extraArgs);
for (QtcProcess::ArgIterator ait(&additionalArguments); ait.next(); ) {
- if (ait.value() == QLatin1String("-spec")) {
+ if (ait.value() == "-spec") {
if (ait.next())
return FileName::fromUserInput(ait.value());
}
@@ -550,31 +550,31 @@ FileName QMakeStep::mkspec() const
QVariantMap QMakeStep::toMap() const
{
QVariantMap map(AbstractProcessStep::toMap());
- map.insert(QLatin1String(QMAKE_ARGUMENTS_KEY), m_userArgs);
- map.insert(QLatin1String(QMAKE_QMLDEBUGLIB_KEY), m_linkQmlDebuggingLibrary);
- map.insert(QLatin1String(QMAKE_FORCED_KEY), m_forced);
- map.insert(QLatin1String(QMAKE_USE_QTQUICKCOMPILER), m_useQtQuickCompiler);
- map.insert(QLatin1String(QMAKE_SEPARATEDEBUGINFO_KEY), m_separateDebugInfo);
+ map.insert(QMAKE_ARGUMENTS_KEY, m_userArgs);
+ map.insert(QMAKE_QMLDEBUGLIB_KEY, m_linkQmlDebuggingLibrary);
+ map.insert(QMAKE_FORCED_KEY, m_forced);
+ map.insert(QMAKE_USE_QTQUICKCOMPILER, m_useQtQuickCompiler);
+ map.insert(QMAKE_SEPARATEDEBUGINFO_KEY, m_separateDebugInfo);
return map;
}
bool QMakeStep::fromMap(const QVariantMap &map)
{
- m_userArgs = map.value(QLatin1String(QMAKE_ARGUMENTS_KEY)).toString();
- m_forced = map.value(QLatin1String(QMAKE_FORCED_KEY), false).toBool();
- m_useQtQuickCompiler = map.value(QLatin1String(QMAKE_USE_QTQUICKCOMPILER), false).toBool();
+ m_userArgs = map.value(QMAKE_ARGUMENTS_KEY).toString();
+ m_forced = map.value(QMAKE_FORCED_KEY, false).toBool();
+ m_useQtQuickCompiler = map.value(QMAKE_USE_QTQUICKCOMPILER, false).toBool();
// QMAKE_QMLDEBUGLIBAUTO_KEY was used in versions 2.3 to 3.5 (both included) to automatically
// change the qml_debug CONFIG flag based no the qmake build configuration.
- if (map.value(QLatin1String(QMAKE_QMLDEBUGLIBAUTO_KEY), false).toBool()) {
+ if (map.value(QMAKE_QMLDEBUGLIBAUTO_KEY, false).toBool()) {
m_linkQmlDebuggingLibrary =
project()->projectLanguages().contains(
ProjectExplorer::Constants::QMLJS_LANGUAGE_ID) &&
(qmakeBuildConfiguration()->qmakeBuildConfiguration() & BaseQtVersion::DebugBuild);
} else {
- m_linkQmlDebuggingLibrary = map.value(QLatin1String(QMAKE_QMLDEBUGLIB_KEY), false).toBool();
+ m_linkQmlDebuggingLibrary = map.value(QMAKE_QMLDEBUGLIB_KEY, false).toBool();
}
- m_separateDebugInfo = map.value(QLatin1String(QMAKE_SEPARATEDEBUGINFO_KEY), false).toBool();
+ m_separateDebugInfo = map.value(QMAKE_SEPARATEDEBUGINFO_KEY, false).toBool();
return BuildStep::fromMap(map);
}
@@ -910,7 +910,7 @@ ProjectExplorer::BuildStep *QMakeStepFactory::clone(BuildStepList *parent, Proje
QMakeStepConfig::TargetArchConfig QMakeStepConfig::targetArchFor(const Abi &targetAbi, const BaseQtVersion *version)
{
QMakeStepConfig::TargetArchConfig arch = QMakeStepConfig::NoArch;
- if (!version || version->type() != QLatin1String(QtSupport::Constants::DESKTOPQT))
+ if (!version || version->type() != QtSupport::Constants::DESKTOPQT)
return arch;
if ((targetAbi.os() == ProjectExplorer::Abi::DarwinOS)
&& (targetAbi.binaryFormat() == ProjectExplorer::Abi::MachOFormat)) {
@@ -933,7 +933,7 @@ QMakeStepConfig::OsType QMakeStepConfig::osTypeFor(const ProjectExplorer::Abi &t
{
QMakeStepConfig::OsType os = QMakeStepConfig::NoOsType;
const char IOSQT[] = "Qt4ProjectManager.QtVersion.Ios";
- if (!version || version->type() != QLatin1String(IOSQT))
+ if (!version || version->type() != IOSQT)
return os;
if ((targetAbi.os() == ProjectExplorer::Abi::DarwinOS)
&& (targetAbi.binaryFormat() == ProjectExplorer::Abi::MachOFormat)) {
@@ -950,29 +950,28 @@ QStringList QMakeStepConfig::toArguments() const
{
QStringList arguments;
if (archConfig == X86)
- arguments << QLatin1String("CONFIG+=x86");
+ arguments << "CONFIG+=x86";
else if (archConfig == X86_64)
- arguments << QLatin1String("CONFIG+=x86_64");
+ arguments << "CONFIG+=x86_64";
else if (archConfig == PowerPC)
- arguments << QLatin1String("CONFIG+=ppc");
+ arguments << "CONFIG+=ppc";
else if (archConfig == PowerPC64)
- arguments << QLatin1String("CONFIG+=ppc64");
+ arguments << "CONFIG+=ppc64";
// TODO: make that depend on the actual Qt version that is used
if (osType == IphoneSimulator)
- arguments << QLatin1String("CONFIG+=iphonesimulator") << QLatin1String("CONFIG+=simulator") /*since Qt 5.7*/;
+ arguments << "CONFIG+=iphonesimulator" << "CONFIG+=simulator" /*since Qt 5.7*/;
else if (osType == IphoneOS)
- arguments << QLatin1String("CONFIG+=iphoneos") << QLatin1String("CONFIG+=device") /*since Qt 5.7*/;
+ arguments << "CONFIG+=iphoneos" << "CONFIG+=device" /*since Qt 5.7*/;
if (linkQmlDebuggingQQ2)
- arguments << QLatin1String("CONFIG+=qml_debug");
+ arguments << "CONFIG+=qml_debug";
if (useQtQuickCompiler)
- arguments << QLatin1String("CONFIG+=qtquickcompiler");
+ arguments << "CONFIG+=qtquickcompiler";
if (separateDebugInfo)
- arguments << QLatin1String("CONFIG+=force_debug_info")
- << QLatin1String("CONFIG+=separate_debug_info");
+ arguments << "CONFIG+=force_debug_info" << "CONFIG+=separate_debug_info";
return arguments;
}
diff --git a/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp
index 04e76561730..d6bfb86551f 100644
--- a/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp
+++ b/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp
@@ -27,6 +27,8 @@
#include <qmakeprojectmanager/qmakeprojectmanagerconstants.h>
+#include <app/app_version.h>
+
#include <coreplugin/basefilewizard.h>
#include <coreplugin/icore.h>
@@ -134,9 +136,10 @@ SimpleProjectWizard::SimpleProjectWizard()
setDisplayName(tr("Import as qmake Project (Limited Functionality)"));
setId("Z.DummyProFile");
setDescription(tr("Imports existing projects that do not use qmake, CMake or Autotools.<p>"
- "This creates a qmake .pro file that allows you to use Qt Creator as a code editor "
+ "This creates a qmake .pro file that allows you to use %1 as a code editor "
"and as a launcher for debugging and analyzing tools. "
- "If you want to build the project, you might need to edit the generated .pro file."));
+ "If you want to build the project, you might need to edit the generated .pro file.")
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
setCategory(ProjectExplorer::Constants::IMPORT_WIZARD_CATEGORY);
setDisplayCategory(ProjectExplorer::Constants::IMPORT_WIZARD_CATEGORY_DISPLAY);
setFlags(IWizardFactory::PlatformIndependent);
@@ -200,7 +203,8 @@ GeneratedFiles SimpleProjectWizard::generateFiles(const QWizard *w,
GeneratedFile generatedProFile(proFileName);
generatedProFile.setAttributes(Core::GeneratedFile::OpenProjectAttribute);
generatedProFile.setContents(
- "# Created by and for Qt Creator. This file was created for editing the project sources only.\n"
+ "# Created by and for " + QLatin1String(Core::Constants::IDE_DISPLAY_NAME)
+ + " This file was created for editing the project sources only.\n"
"# You may attempt to use it for building too, by modifying this file here.\n\n"
"#TARGET = " + projectName + "\n\n"
+ proHeaders + "\n\n"
diff --git a/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp b/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp
index 812f49f9f52..e3659185866 100644
--- a/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp
@@ -92,7 +92,7 @@ QWidget *ChangeStyleWidgetAction::createWidget(QWidget *parent)
connect(comboBox,
static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated),
this,
- [comboBox, this](const QString &style) {
+ [this](const QString &style) {
if (style.isEmpty())
return;
diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h
index 6b0015f0823..1ef51816dc3 100644
--- a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h
+++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h
@@ -80,10 +80,6 @@ const char positionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContext
const char layoutCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout");
const char stackedContainerCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Stacked Container");
-const char selectParentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select Parent: %1");
-const char selectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1");
-const char deSelectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Deselect: ");
-
const char cutSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Cut");
const char copySelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Copy");
const char pasteSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Paste");
diff --git a/src/plugins/qmldesigner/components/componentcore/findimplementation.cpp b/src/plugins/qmldesigner/components/componentcore/findimplementation.cpp
index 24bffa14d0b..1d88bf56a00 100644
--- a/src/plugins/qmldesigner/components/componentcore/findimplementation.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/findimplementation.cpp
@@ -231,7 +231,7 @@ private:
QString m_typeName;
QString m_itemId;
- const ObjectValue *m_typeValue;
+ const ObjectValue *m_typeValue = nullptr;
bool m_insideObject = false;
};
diff --git a/src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp b/src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp
index c3cf12d3cc5..298eb855c38 100644
--- a/src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp
@@ -30,15 +30,10 @@
namespace QmlDesigner {
-SelectionContext::SelectionContext() :
- m_toggled(false)
-{
-
-}
+SelectionContext::SelectionContext() = default;
SelectionContext::SelectionContext(AbstractView *view) :
- m_view(view),
- m_toggled(false)
+ m_view(view)
{
}
diff --git a/src/plugins/qmldesigner/components/componentcore/selectioncontext.h b/src/plugins/qmldesigner/components/componentcore/selectioncontext.h
index 17e5981e6d4..594fc2f6e5c 100644
--- a/src/plugins/qmldesigner/components/componentcore/selectioncontext.h
+++ b/src/plugins/qmldesigner/components/componentcore/selectioncontext.h
@@ -65,9 +65,9 @@ public:
private:
QPointer<AbstractView> m_view;
ModelNode m_targetNode;
- bool m_showSelectionTools;
QPointF m_scenePosition;
- bool m_toggled;
+ bool m_showSelectionTools = false;
+ bool m_toggled = false;
};
} //QmlDesigner
diff --git a/src/plugins/qmldesigner/components/formeditor/anchorindicatorgraphicsitem.h b/src/plugins/qmldesigner/components/formeditor/anchorindicatorgraphicsitem.h
index a6cc8a8f17f..16946b392f2 100644
--- a/src/plugins/qmldesigner/components/formeditor/anchorindicatorgraphicsitem.h
+++ b/src/plugins/qmldesigner/components/formeditor/anchorindicatorgraphicsitem.h
@@ -57,8 +57,8 @@ private:
QPointF m_sourceAnchorLineSecondPoint;
QPointF m_targetAnchorLineFirstPoint;
QPointF m_targetAnchorLineSecondPoint;
- AnchorLineType m_sourceAnchorLineType;
- AnchorLineType m_targetAnchorLineType;
+ AnchorLineType m_sourceAnchorLineType = AnchorLineInvalid;
+ AnchorLineType m_targetAnchorLineType = AnchorLineInvalid;
QRectF m_boundingRect;
};
diff --git a/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp
index d0c7b9e5bc9..a6e53143435 100644
--- a/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp
+++ b/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.cpp
@@ -33,6 +33,9 @@
#include "qproxystyle.h"
#include "metainfo.h"
+
+#include <utils/qtcassert.h>
+
#include <QLineEdit>
#include <QPen>
#include <QPixmapCache>
@@ -42,11 +45,11 @@
namespace QmlDesigner {
IconCheckboxItemDelegate::IconCheckboxItemDelegate(QObject *parent,
- const QPixmap &checkedPixmap,
- const QPixmap &uncheckedPixmap)
+ const QIcon &checkedIcon,
+ const QIcon &uncheckedIcon)
: QStyledItemDelegate(parent),
- m_checkedPixmap(checkedPixmap),
- m_uncheckedPixmap(uncheckedPixmap)
+ m_checkedIcon(checkedIcon),
+ m_uncheckedIcon(uncheckedIcon)
{}
QSize IconCheckboxItemDelegate::sizeHint(const QStyleOptionViewItem & /*option*/,
@@ -82,25 +85,28 @@ void IconCheckboxItemDelegate::paint(QPainter *painter,
if (rowIsPropertyRole(modelIndex.model(), modelIndex))
return; //Do not paint icons for property rows
- const int yOffset = (styleOption.rect.height()
- - (m_checkedPixmap.height() / painter->device()->devicePixelRatio())) / 2;
- const int xOffset = 2;
-
- painter->save();
if (styleOption.state & QStyle::State_Selected)
NavigatorTreeView::drawSelectionBackground(painter, styleOption);
if (!getModelNode(modelIndex).isRootNode()) {
+ QWindow *window = dynamic_cast<QWidget*>(painter->device())->window()->windowHandle();
+ QTC_ASSERT(window, return);
- if (!isVisible(modelIndex))
+ const QRect iconRect(styleOption.rect.left() + 2, styleOption.rect.top() + 2, 16, 16);
+ const QIcon &icon = isChecked(modelIndex) ? m_checkedIcon : m_uncheckedIcon;
+ const QPixmap iconPixmap = icon.pixmap(window, iconRect.size());
+ const bool visible = isVisible(modelIndex);
+
+ if (!visible) {
+ painter->save();
painter->setOpacity(0.5);
+ }
- const bool checked = isChecked(modelIndex);
- painter->drawPixmap(styleOption.rect.x() + xOffset, styleOption.rect.y() + yOffset,
- checked ? m_checkedPixmap : m_uncheckedPixmap);
- }
+ painter->drawPixmap(iconRect.topLeft(), iconPixmap);
- painter->restore();
+ if (!visible)
+ painter->restore();
+ }
}
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.h b/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.h
index a21f3338095..17f9a3537ea 100644
--- a/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.h
+++ b/src/plugins/qmldesigner/components/navigator/iconcheckboxitemdelegate.h
@@ -35,8 +35,8 @@ class IconCheckboxItemDelegate : public QStyledItemDelegate
{
public:
explicit IconCheckboxItemDelegate(QObject *parent,
- const QPixmap &checkedPixmap,
- const QPixmap &uncheckedPixmap);
+ const QIcon &checkedIcon,
+ const QIcon &uncheckedIcon);
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const;
@@ -46,7 +46,7 @@ public:
const QModelIndex &index) const;
private:
- const QPixmap m_checkedPixmap;
- const QPixmap m_uncheckedPixmap;
+ const QIcon m_checkedIcon;
+ const QIcon m_uncheckedIcon;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/navigator/navigator.qrc b/src/plugins/qmldesigner/components/navigator/navigator.qrc
index 41599b77be1..aa28a4aaeec 100644
--- a/src/plugins/qmldesigner/components/navigator/navigator.qrc
+++ b/src/plugins/qmldesigner/components/navigator/navigator.qrc
@@ -12,6 +12,5 @@
<file>export_checked@2x.png</file>
<file>export_unchecked.png</file>
<file>export_unchecked@2x.png</file>
- <file>warning.png</file>
</qresource>
</RCC>
diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp
index 3db86f70091..4bf00a00e7b 100644
--- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp
+++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp
@@ -93,17 +93,19 @@ NavigatorView::NavigatorView(QObject* parent) :
NameItemDelegate *idDelegate = new NameItemDelegate(this);
IconCheckboxItemDelegate *showDelegate =
new IconCheckboxItemDelegate(this,
- Utils::Icons::EYE_OPEN_TOOLBAR.pixmap(),
- Utils::Icons::EYE_CLOSED_TOOLBAR.pixmap());
+ Utils::Icons::EYE_OPEN_TOOLBAR.icon(),
+ Utils::Icons::EYE_CLOSED_TOOLBAR.icon());
IconCheckboxItemDelegate *exportDelegate =
new IconCheckboxItemDelegate(this,
- Icons::EXPORT_CHECKED.pixmap(),
- Icons::EXPORT_UNCHECKED.pixmap());
+ Icons::EXPORT_CHECKED.icon(),
+ Icons::EXPORT_UNCHECKED.icon());
#ifdef _LOCK_ITEMS_
- IconCheckboxItemDelegate *lockDelegate = new IconCheckboxItemDelegate(this,":/qmldesigner/images/lock.png",
- ":/qmldesigner/images/hole.png",m_treeModel.data());
+ IconCheckboxItemDelegate *lockDelegate =
+ new IconCheckboxItemDelegate(this,
+ Utils::Icons::LOCKED_TOOLBAR.icon(),
+ Utils::Icons::UNLOCKED_TOOLBAR.icon());
#endif
diff --git a/src/plugins/qmldesigner/components/navigator/warning.png b/src/plugins/qmldesigner/components/navigator/warning.png
deleted file mode 100644
index 38a80acc1ec..00000000000
--- a/src/plugins/qmldesigner/components/navigator/warning.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp
index 4e8a390bfd7..d44bcfc3d3d 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp
@@ -123,7 +123,7 @@ void FileResourcesModel::openFileDialog()
//If that one is not valid we try the path for the current file
if (path.isEmpty() && !m_fileName.isEmpty())
- path = QFileInfo(modelPath + QStringLiteral("/") + m_fileName.toString()).absoluteDir().absolutePath();
+ path = QFileInfo(modelPath + '/' + m_fileName.toString()).absolutePath();
//Next we try to fall back to the path any file browser was opened with
diff --git a/src/plugins/qmldesigner/components/propertyeditor/images/button2_hovered.png b/src/plugins/qmldesigner/components/propertyeditor/images/button2_hovered.png
deleted file mode 100644
index b82f1fd0060..00000000000
--- a/src/plugins/qmldesigner/components/propertyeditor/images/button2_hovered.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmldesigner/components/propertyeditor/images/button2_normal.png b/src/plugins/qmldesigner/components/propertyeditor/images/button2_normal.png
deleted file mode 100644
index 4fef115d3ef..00000000000
--- a/src/plugins/qmldesigner/components/propertyeditor/images/button2_normal.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmldesigner/components/propertyeditor/images/button2_pressed.png b/src/plugins/qmldesigner/components/propertyeditor/images/button2_pressed.png
deleted file mode 100644
index 305530afaf6..00000000000
--- a/src/plugins/qmldesigner/components/propertyeditor/images/button2_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmldesigner/components/propertyeditor/images/button_hovered.png b/src/plugins/qmldesigner/components/propertyeditor/images/button_hovered.png
deleted file mode 100644
index 2dc66ec3e39..00000000000
--- a/src/plugins/qmldesigner/components/propertyeditor/images/button_hovered.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmldesigner/components/propertyeditor/images/button_normal.png b/src/plugins/qmldesigner/components/propertyeditor/images/button_normal.png
deleted file mode 100644
index ca297723196..00000000000
--- a/src/plugins/qmldesigner/components/propertyeditor/images/button_normal.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmldesigner/components/propertyeditor/images/button_pressed.png b/src/plugins/qmldesigner/components/propertyeditor/images/button_pressed.png
deleted file mode 100644
index 7cf55d718d7..00000000000
--- a/src/plugins/qmldesigner/components/propertyeditor/images/button_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmldesigner/components/propertyeditor/images/frame.png b/src/plugins/qmldesigner/components/propertyeditor/images/frame.png
deleted file mode 100644
index a9516090188..00000000000
--- a/src/plugins/qmldesigner/components/propertyeditor/images/frame.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmldesigner/components/propertyeditor/images/gradient.png b/src/plugins/qmldesigner/components/propertyeditor/images/gradient.png
deleted file mode 100644
index ae48afbd7aa..00000000000
--- a/src/plugins/qmldesigner/components/propertyeditor/images/gradient.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri
index 5336225b118..d822fbb70d2 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri
@@ -27,5 +27,3 @@ HEADERS += propertyeditorview.h \
qmlmodelnodeproxy.h
QT += qml quick
-
-RESOURCES += propertyeditor.qrc
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.qrc b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.qrc
deleted file mode 100644
index 61d22611ba8..00000000000
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.qrc
+++ /dev/null
@@ -1,12 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>images/button_hovered.png</file>
- <file>images/button_normal.png</file>
- <file>images/button_pressed.png</file>
- <file>images/button2_hovered.png</file>
- <file>images/button2_normal.png</file>
- <file>images/button2_pressed.png</file>
- <file>images/frame.png</file>
- <file>images/gradient.png</file>
- </qresource>
-</RCC>
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
index 80b3dc29249..4fa195b3c57 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
@@ -94,8 +94,6 @@ PropertyEditorQmlBackend::PropertyEditorQmlBackend(PropertyEditorView *propertyE
m_view(new Quick2PropertyEditorView), m_propertyEditorTransaction(new PropertyEditorTransaction(propertyEditor)), m_dummyPropertyEditorValue(new PropertyEditorValue()),
m_contextObject(new PropertyEditorContextObject())
{
- Q_ASSERT(QFileInfo(QLatin1String(":/images/button_normal.png")).exists());
-
m_view->engine()->setOutputWarningsToStandardError(QmlDesignerPlugin::instance()
->settings().value(DesignerSettingsKey::SHOW_PROPERTYEDITOR_WARNINGS).toBool());
diff --git a/src/plugins/qmldesigner/components/resources/resources.qrc b/src/plugins/qmldesigner/components/resources/resources.qrc
index 5b75f585a28..4100b9da6bc 100644
--- a/src/plugins/qmldesigner/components/resources/resources.qrc
+++ b/src/plugins/qmldesigner/components/resources/resources.qrc
@@ -1,6 +1,5 @@
<RCC>
<qresource prefix="/qmldesigner">
- <file>templates/Standard/Form.xml</file>
<file>stylesheet.css</file>
<file>scrollbar.css</file>
<file>formeditorstylesheet.css</file>
diff --git a/src/plugins/qmldesigner/components/resources/templates/Standard/Form.xml b/src/plugins/qmldesigner/components/resources/templates/Standard/Form.xml
deleted file mode 100644
index 4a9aa660d51..00000000000
--- a/src/plugins/qmldesigner/components/resources/templates/Standard/Form.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<QWidget objectName="Form" width="186" height="141">
- <windowTitle><?i18n?>Form</windowTitle>
- <QVBoxLayout objectName="verticalLayout">
- <!--Start of QLayoutItem 1--><QLabel objectName="label">
- <text><?i18n?>Hello world</text>
- </QLabel>
- <!--End of QLayoutItem 1--><!--Start of QLayoutItem 1--><QPlainTextEdit objectName="plainTextEdit"/>
- <!--End of QLayoutItem 1--></QVBoxLayout>
-</QWidget>
diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp
index 5877424a142..698ce6afc06 100644
--- a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp
+++ b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp
@@ -173,9 +173,9 @@ void TextEditorView::selectedNodesChanged(const QList<ModelNode> &/*selectedNode
void TextEditorView::customNotification(const AbstractView * /*view*/, const QString &identifier, const QList<ModelNode> &/*nodeList*/, const QList<QVariant> &/*data*/)
{
if (identifier == StartRewriterApply)
- m_widget->setBlockCurserSelectionSyncronisation(true);
+ m_widget->setBlockCursorSelectionSynchronisation(true);
else if (identifier == EndRewriterApply)
- m_widget->setBlockCurserSelectionSyncronisation(false);
+ m_widget->setBlockCursorSelectionSynchronisation(false);
}
void TextEditorView::documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &)
diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp
index 591164138f3..1062aa4a961 100644
--- a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp
+++ b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp
@@ -80,7 +80,7 @@ void TextEditorWidget::setTextEditor(TextEditor::BaseTextEditor *textEditor)
connect(textEditor->editorWidget(), &QPlainTextEdit::cursorPositionChanged,
this, [this]() {
/* Cursor position is changed by rewriter */
- if (!m_blockCurserSelectionSyncronisation)
+ if (!m_blockCursorSelectionSynchronisation)
m_updateSelectionTimer.start();
});
@@ -168,9 +168,9 @@ int TextEditorWidget::currentLine() const
return -1;
}
-void TextEditorWidget::setBlockCurserSelectionSyncronisation(bool b)
+void TextEditorWidget::setBlockCursorSelectionSynchronisation(bool b)
{
- m_blockCurserSelectionSyncronisation = b;
+ m_blockCursorSelectionSynchronisation = b;
}
bool TextEditorWidget::eventFilter( QObject *, QEvent *event)
diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.h b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.h
index 267f93a1837..7ab245adbbf 100644
--- a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.h
+++ b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.h
@@ -59,7 +59,7 @@ public:
int currentLine() const;
- void setBlockCurserSelectionSyncronisation(bool b);
+ void setBlockCursorSelectionSynchronisation(bool b);
protected:
bool eventFilter(QObject *object, QEvent *event) override;
@@ -71,7 +71,7 @@ private:
QPointer<TextEditorView> m_textEditorView;
QTimer m_updateSelectionTimer;
TextEditorStatusBar *m_statusBar;
- bool m_blockCurserSelectionSyncronisation = false;
+ bool m_blockCursorSelectionSynchronisation = false;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.h b/src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.h
index a1dfb7b71a0..159b65bdd21 100644
--- a/src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.h
+++ b/src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.h
@@ -45,7 +45,7 @@ protected:
private:
QmlJS::Document::MutablePtr m_document;
- quint32 m_location;
+ quint32 m_location = 0;
QString m_text;
};
diff --git a/src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.h b/src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.h
index 9aca188a607..fb306f8bc46 100644
--- a/src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.h
+++ b/src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.h
@@ -48,7 +48,7 @@ protected:
private:
QmlJS::Document::MutablePtr m_doc;
quint32 m_offset;
- QmlJS::AST::UiObjectDefinition *m_firstObjectDefinition;
+ QmlJS::AST::UiObjectDefinition *m_firstObjectDefinition = nullptr;
};
diff --git a/src/plugins/qmldesigner/designercore/filemanager/moveobjectbeforeobjectvisitor.h b/src/plugins/qmldesigner/designercore/filemanager/moveobjectbeforeobjectvisitor.h
index 909c77ef702..7b5f39d1751 100644
--- a/src/plugins/qmldesigner/designercore/filemanager/moveobjectbeforeobjectvisitor.h
+++ b/src/plugins/qmldesigner/designercore/filemanager/moveobjectbeforeobjectvisitor.h
@@ -67,8 +67,8 @@ private:
bool toEnd;
quint32 beforeObjectLocation;
- QmlJS::AST::UiObjectDefinition *movingObject;
- QmlJS::AST::UiObjectDefinition *beforeObject;
+ QmlJS::AST::UiObjectDefinition *movingObject = nullptr;
+ QmlJS::AST::UiObjectDefinition *beforeObject = nullptr;
ASTPath movingObjectParents;
};
diff --git a/src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.h b/src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.h
index e869bb98b45..1ff31837a1a 100644
--- a/src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.h
+++ b/src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.h
@@ -45,8 +45,8 @@ protected:
private:
QmlJS::Document::MutablePtr m_doc;
- quint32 m_offset;
- quint32 m_length;
+ quint32 m_offset = 0;
+ quint32 m_length = 0;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
index 800ef1baadd..ebaaf93b3de 100644
--- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
+++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
@@ -193,7 +193,6 @@ private: //variables
QHash<ModelNode, NodeInstance> m_nodeInstanceHash;
QHash<ModelNode, QImage> m_statePreviewImage;
- uint m_blockUpdates;
QPointer<NodeInstanceServerInterface> m_nodeInstanceServer;
QImage m_baseStatePreviewImage;
QTime m_lastCrashTime;
diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp
index e8fbe3a71cf..eebf3c0f8d1 100644
--- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp
+++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp
@@ -107,15 +107,7 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV
: NodeInstanceServerInterface(nodeInstanceView),
m_localServer(new QLocalServer(this)),
m_nodeInstanceView(nodeInstanceView),
- m_firstBlockSize(0),
- m_secondBlockSize(0),
- m_thirdBlockSize(0),
- m_writeCommandCounter(0),
- m_firstLastReadCommandCounter(0),
- m_secondLastReadCommandCounter(0),
- m_thirdLastReadCommandCounter(0),
- m_runModus(runModus),
- m_synchronizeId(-1)
+ m_runModus(runModus)
{
if (instanceViewBenchmark().isInfoEnabled())
m_benchmarkTimer.start();
diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h
index 9ab15b15c7c..4cf8f1241e3 100644
--- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h
+++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h
@@ -118,15 +118,15 @@ private:
QPointer<QProcess> m_qmlPuppetEditorProcess;
QPointer<QProcess> m_qmlPuppetPreviewProcess;
QPointer<QProcess> m_qmlPuppetRenderProcess;
- quint32 m_firstBlockSize;
- quint32 m_secondBlockSize;
- quint32 m_thirdBlockSize;
- quint32 m_writeCommandCounter;
- quint32 m_firstLastReadCommandCounter;
- quint32 m_secondLastReadCommandCounter;
- quint32 m_thirdLastReadCommandCounter;
+ quint32 m_firstBlockSize = 0;
+ quint32 m_secondBlockSize = 0;
+ quint32 m_thirdBlockSize = 0;
+ quint32 m_writeCommandCounter = 0;
+ quint32 m_firstLastReadCommandCounter = 0;
+ quint32 m_secondLastReadCommandCounter = 0;
+ quint32 m_thirdLastReadCommandCounter = 0;
RunModus m_runModus;
- int m_synchronizeId;
+ int m_synchronizeId = -1;
QTime m_benchmarkTimer;
};
diff --git a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp
index 90f72c5d737..c5bb6e9d126 100644
--- a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp
+++ b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp
@@ -549,7 +549,8 @@ bool PuppetCreator::startBuildProcess(const QString &buildDirectoryPath,
process.setProcessEnvironment(processEnvironment());
process.setWorkingDirectory(buildDirectoryPath);
process.start(command, processArguments);
- process.waitForStarted();
+ if (!process.waitForStarted())
+ return false;
while (process.waitForReadyRead(100) || process.state() == QProcess::Running) {
if (progressDialog->useFallbackPuppet())
return false;
@@ -565,8 +566,8 @@ bool PuppetCreator::startBuildProcess(const QString &buildDirectoryPath,
process.waitForFinished();
- qCInfo(puppetBuild) << Q_FUNC_INFO;
- qCInfo(puppetBuild) << m_compileLog;
+ qCInfo(puppetBuild) << Q_FUNC_INFO;
+ qCInfo(puppetBuild) << m_compileLog;
if (process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0)
return true;
diff --git a/src/plugins/qmldesigner/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/designercore/model/internalnode_p.h
index c19fca55a85..9f70fe1e94f 100644
--- a/src/plugins/qmldesigner/designercore/model/internalnode_p.h
+++ b/src/plugins/qmldesigner/designercore/model/internalnode_p.h
@@ -150,7 +150,7 @@ private:
QStringList m_scriptFunctionList;
QString m_nodeSource;
- int m_nodeSourceType;
+ int m_nodeSourceType = 0;
};
uint qHash(const InternalNodePointer& node);
diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp
index ce532708143..d73f96df940 100644
--- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp
+++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp
@@ -749,10 +749,6 @@ bool operator <(const ModelNode &firstNode, const ModelNode &secondNode)
Internal::InternalNodePointer ModelNode::internalNode() const
{
- if (!isValid()) {
- Q_ASSERT_X(isValid(), Q_FUNC_INFO, "model node is invalid");
- throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
- }
return m_internalNode;
}
diff --git a/src/plugins/qmldesigner/designercore/model/textmodifier.cpp b/src/plugins/qmldesigner/designercore/model/textmodifier.cpp
index 8b5ea35ff1c..9016619f6db 100644
--- a/src/plugins/qmldesigner/designercore/model/textmodifier.cpp
+++ b/src/plugins/qmldesigner/designercore/model/textmodifier.cpp
@@ -26,7 +26,8 @@
#include "textmodifier.h"
#include <qmljs/qmljsmodelmanagerinterface.h>
-#include <texteditor/convenience.h>
+
+#include <utils/textutils.h>
using namespace QmlDesigner;
@@ -38,7 +39,7 @@ int TextModifier::getLineInDocument(QTextDocument *document, int offset)
{
int line = -1;
int column = -1;
- TextEditor::Convenience::convertPosition(document, offset, &line, &column);
+ Utils::Text::convertPosition(document, offset, &line, &column);
return line;
}
diff --git a/src/plugins/qmldesigner/designercore/rewritertransaction.h b/src/plugins/qmldesigner/designercore/rewritertransaction.h
index 87e50c53fe4..9a91f0d23f7 100644
--- a/src/plugins/qmldesigner/designercore/rewritertransaction.h
+++ b/src/plugins/qmldesigner/designercore/rewritertransaction.h
@@ -54,7 +54,7 @@ private:
QPointer<AbstractView> m_view;
QByteArray m_identifier;
mutable bool m_valid;
- int m_identifierNumber;
+ int m_identifierNumber = 0;
static QList<QByteArray> m_identifierList;
static bool m_activeIdentifier;
bool m_ignoreSemanticChecks = false;
diff --git a/src/plugins/qmldesigner/openuiqmlfiledialog.cpp b/src/plugins/qmldesigner/openuiqmlfiledialog.cpp
index 75837654dce..545719623fe 100644
--- a/src/plugins/qmldesigner/openuiqmlfiledialog.cpp
+++ b/src/plugins/qmldesigner/openuiqmlfiledialog.cpp
@@ -55,7 +55,7 @@ OpenUiQmlFileDialog::OpenUiQmlFileDialog(QWidget *parent) :
}
close();
});
- connect(ui->checkBox, &QCheckBox::toggled, [this](bool b){
+ connect(ui->checkBox, &QCheckBox::toggled, this, [](bool b){
DesignerSettings settings = QmlDesignerPlugin::instance()->settings();
settings.insert(DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES, !b);
QmlDesignerPlugin::instance()->setSettings(settings);
diff --git a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionviewwidget.cpp b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionviewwidget.cpp
index 7bd706f834d..2ad6d34d3d1 100644
--- a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionviewwidget.cpp
+++ b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionviewwidget.cpp
@@ -69,17 +69,13 @@ ConnectionViewWidget::ConnectionViewWidget(QWidget *parent) :
ui->tabBar->addTab(tr("Backends", "Title of dynamic properties view"));
ui->tabBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
- ui->connectionView->setStyleSheet(Theme::replaceCssColors(
- QLatin1String(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/scrollbar.css")))));
+ const QString themedScrollBarCss = Theme::replaceCssColors(
+ QLatin1String(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/scrollbar.css"))));
- ui->bindingView->setStyleSheet(Theme::replaceCssColors(
- QLatin1String(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/scrollbar.css")))));
-
- ui->dynamicPropertiesView->setStyleSheet(Theme::replaceCssColors(
- QLatin1String(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/scrollbar.css")))));
-
- ui->backendView->setStyleSheet(Theme::replaceCssColors(
- QLatin1String(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/scrollbar.css")))));
+ ui->connectionView->setStyleSheet(themedScrollBarCss);
+ ui->bindingView->setStyleSheet(themedScrollBarCss);
+ ui->dynamicPropertiesView->setStyleSheet(themedScrollBarCss);
+ ui->backendView->setStyleSheet(themedScrollBarCss);
connect(ui->tabBar, &QTabBar::currentChanged,
ui->stackedWidget, &QStackedWidget::setCurrentIndex);
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs
index 9f040daf760..6e88e6f101e 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.qbs
+++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs
@@ -25,6 +25,7 @@ Project {
Depends { name: "ProjectExplorer" }
Depends { name: "LanguageUtils" }
Depends { name: "QtSupport" }
+ Depends { name: "app_version_header" }
cpp.defines: base.concat("DESIGNER_CORE_LIBRARY")
cpp.enableExceptions: true
@@ -550,7 +551,6 @@ Project {
"propertyeditor/fileresourcesmodel.h",
"propertyeditor/gradientmodel.cpp",
"propertyeditor/gradientmodel.h",
- "propertyeditor/propertyeditor.qrc",
"propertyeditor/propertyeditorcontextobject.cpp",
"propertyeditor/propertyeditorcontextobject.h",
"propertyeditor/propertyeditortransaction.cpp",
diff --git a/src/plugins/qmldesigner/settingspage.cpp b/src/plugins/qmldesigner/settingspage.cpp
index cc0136dc4c5..0a32af56eac 100644
--- a/src/plugins/qmldesigner/settingspage.cpp
+++ b/src/plugins/qmldesigner/settingspage.cpp
@@ -29,6 +29,8 @@
#include "designersettings.h"
#include "puppetcreator.h"
+#include <app/app_version.h>
+
#include <coreplugin/icore.h>
#include <qmljseditor/qmljseditorconstants.h>
@@ -251,7 +253,8 @@ void SettingsPage::apply()
if (currentSettings.value(key) != newSettings.value(key)) {
QMessageBox::information(Core::ICore::mainWindow(), tr("Restart Required"),
tr("The made changes will take effect after a "
- "restart of the QML Emulation layer or Qt Creator."));
+ "restart of the QML Emulation layer or %1.")
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
break;
}
}
diff --git a/src/plugins/qmldesigner/settingspage.ui b/src/plugins/qmldesigner/settingspage.ui
index 9fed112a68f..ca00b6fc411 100644
--- a/src/plugins/qmldesigner/settingspage.ui
+++ b/src/plugins/qmldesigner/settingspage.ui
@@ -252,14 +252,14 @@
<bool>true</bool>
</property>
<property name="toolTip">
- <string>Path where Qt Creator can find the QML emulation layer executable (qmlpuppet).</string>
+ <string>Path to the QML emulation layer executable (qmlpuppet).</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="resetFallbackPuppetPathButton">
<property name="toolTip">
- <string>Resets the path to the QML emulation layer that comes with Qt Creator.</string>
+ <string>Resets the path to the built-in QML emulation layer.</string>
</property>
<property name="text">
<string>Reset Path</string>
diff --git a/src/plugins/qmldesigner/shortcutmanager.cpp b/src/plugins/qmldesigner/shortcutmanager.cpp
index 864d4046f4d..8b45efc8535 100644
--- a/src/plugins/qmldesigner/shortcutmanager.cpp
+++ b/src/plugins/qmldesigner/shortcutmanager.cpp
@@ -175,7 +175,7 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex
//Close All Others Action
Core::ActionManager::registerAction(&m_closeOtherEditorsAction, Core::Constants::CLOSEOTHERS, qmlDesignerMainContext);
- connect(&m_closeOtherEditorsAction, &QAction::triggered, em, [em] {
+ connect(&m_closeOtherEditorsAction, &QAction::triggered, em, [] {
Core::EditorManager::closeOtherDocuments();
});
diff --git a/src/plugins/qmljseditor/qmljseditorplugin.cpp b/src/plugins/qmljseditor/qmljseditorplugin.cpp
index 3b9a50866f5..34f2fa818a1 100644
--- a/src/plugins/qmljseditor/qmljseditorplugin.cpp
+++ b/src/plugins/qmljseditor/qmljseditorplugin.cpp
@@ -54,6 +54,7 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <texteditor/snippets/snippetprovider.h>
#include <texteditor/texteditorconstants.h>
+#include <texteditor/tabsettings.h>
#include <utils/qtcassert.h>
#include <utils/json.h>
@@ -258,8 +259,10 @@ void QmlJSEditorPlugin::reformatFile()
if (!document->isParsedCorrectly())
return;
-
- const QString &newText = QmlJS::reformat(document);
+ TextEditor::TabSettings tabSettings = m_currentDocument->tabSettings();
+ const QString &newText = QmlJS::reformat(document,
+ tabSettings.m_indentSize,
+ tabSettings.m_tabSize);
QmlJSEditorWidget *widget = EditorManager::currentEditor()
? qobject_cast<QmlJSEditorWidget*>(EditorManager::currentEditor()->widget())
: nullptr;
diff --git a/src/plugins/qmljstools/qmljsfunctionfilter.cpp b/src/plugins/qmljstools/qmljsfunctionfilter.cpp
index 7c00e6c9f02..02081f7e906 100644
--- a/src/plugins/qmljstools/qmljsfunctionfilter.cpp
+++ b/src/plugins/qmljstools/qmljsfunctionfilter.cpp
@@ -28,9 +28,9 @@
#include <coreplugin/editormanager/editormanager.h>
#include <utils/algorithm.h>
+#include <utils/camelhumpmatcher.h>
-#include <QRegExp>
-#include <QStringMatcher>
+#include <QRegularExpression>
using namespace QmlJSTools::Internal;
@@ -59,12 +59,13 @@ QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor(
{
QList<Core::LocatorFilterEntry> goodEntries;
QList<Core::LocatorFilterEntry> betterEntries;
- const Qt::CaseSensitivity cs = caseSensitivity(entry);
- QStringMatcher matcher(entry, cs);
- QRegExp regexp(entry, cs, QRegExp::Wildcard);
+ QList<Core::LocatorFilterEntry> bestEntries;
+ const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
+ const QRegularExpression regexp = containsWildcard(entry)
+ ? createWildcardRegExp(entry) : CamelHumpMatcher::createCamelHumpRegExp(entry);
+
if (!regexp.isValid())
return goodEntries;
- bool hasWildcard = containsWildcard(entry);
QHashIterator<QString, QList<LocatorData::Entry> > it(m_data->entries());
while (it.hasNext()) {
@@ -78,16 +79,19 @@ QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor(
if (info.type != LocatorData::Function)
continue;
- const int index = hasWildcard ? regexp.indexIn(info.symbolName)
- : matcher.indexIn(info.symbolName);
- if (index >= 0) {
+ const QRegularExpressionMatch match = regexp.match(info.symbolName);
+ if (match.hasMatch()) {
QVariant id = qVariantFromValue(info);
Core::LocatorFilterEntry filterEntry(this, info.displayName, id/*, info.icon*/);
+ const CamelHumpMatcher::HighlightingPositions positions =
+ CamelHumpMatcher::highlightingPositions(match);
filterEntry.extraInfo = info.extraInfo;
- const int length = hasWildcard ? regexp.matchedLength() : entry.length();
- filterEntry.highlightInfo = {index, length};
+ filterEntry.highlightInfo.starts = positions.starts;
+ filterEntry.highlightInfo.lengths = positions.lengths;
- if (index == 0)
+ if (filterEntry.displayName.startsWith(entry, caseSensitivityForPrefix))
+ bestEntries.append(filterEntry);
+ else if (filterEntry.displayName.contains(entry, caseSensitivityForPrefix))
betterEntries.append(filterEntry);
else
goodEntries.append(filterEntry);
@@ -99,9 +103,12 @@ QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor(
Utils::sort(goodEntries, Core::LocatorFilterEntry::compareLexigraphically);
if (betterEntries.size() < 1000)
Utils::sort(betterEntries, Core::LocatorFilterEntry::compareLexigraphically);
+ if (bestEntries.size() < 1000)
+ Utils::sort(bestEntries, Core::LocatorFilterEntry::compareLexigraphically);
- betterEntries += goodEntries;
- return betterEntries;
+ bestEntries += betterEntries;
+ bestEntries += goodEntries;
+ return bestEntries;
}
void FunctionFilter::accept(Core::LocatorFilterEntry selection,
diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp
index d28cc3ab87e..9f05506ee07 100644
--- a/src/plugins/qmljstools/qmljsmodelmanager.cpp
+++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp
@@ -163,8 +163,7 @@ void setupProjectInfoQmlBundles(ModelManagerInterface::ProjectInfo &projectInfo)
if (projectInfo.project) {
QSet<Kit *> currentKits;
foreach (const Target *t, projectInfo.project->targets())
- if (t->kit())
- currentKits.insert(t->kit());
+ currentKits.insert(t->kit());
currentKits.remove(activeKit);
foreach (Kit *kit, currentKits) {
foreach (IBundleProvider *bp, bundleProviders)
diff --git a/src/plugins/qmlprofiler/flamegraphmodel.h b/src/plugins/qmlprofiler/flamegraphmodel.h
index 587de41cf75..cc8150fb29c 100644
--- a/src/plugins/qmlprofiler/flamegraphmodel.h
+++ b/src/plugins/qmlprofiler/flamegraphmodel.h
@@ -87,7 +87,6 @@ public:
QHash<int, QByteArray> roleNames() const override;
QmlProfilerModelManager *modelManager() const;
-public slots:
void loadEvent(const QmlEvent &event, const QmlEventType &type);
void finalize();
void onModelManagerStateChanged();
@@ -95,6 +94,10 @@ public slots:
void loadNotes(int typeId, bool emitSignal);
void clear();
+signals:
+ void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber);
+ void typeSelected(int typeIndex);
+
private:
QVariant lookup(const FlameGraphData &data, int role) const;
FlameGraphData *pushChild(FlameGraphData *parent, const QmlEvent &data);
diff --git a/src/plugins/qmlprofiler/flamegraphview.cpp b/src/plugins/qmlprofiler/flamegraphview.cpp
index d26d4747a31..4de7fd1601e 100644
--- a/src/plugins/qmlprofiler/flamegraphview.cpp
+++ b/src/plugins/qmlprofiler/flamegraphview.cpp
@@ -67,10 +67,9 @@ FlameGraphView::FlameGraphView(QmlProfilerModelManager *manager, QWidget *parent
layout->addWidget(m_content);
setLayout(layout);
- connect(m_content->rootObject(), SIGNAL(typeSelected(int)),
- this, SIGNAL(typeSelected(int)));
- connect(m_content->rootObject(), SIGNAL(gotoSourceLocation(QString,int,int)),
- this, SIGNAL(gotoSourceLocation(QString,int,int)));
+ connect(m_model, &FlameGraphModel::typeSelected, this, &FlameGraphView::typeSelected);
+ connect(m_model, &FlameGraphModel::gotoSourceLocation,
+ this, &FlameGraphView::gotoSourceLocation);
}
void FlameGraphView::selectByTypeId(int typeIndex)
diff --git a/src/plugins/qmlprofiler/flamegraphview.h b/src/plugins/qmlprofiler/flamegraphview.h
index 60c817584ea..ed4c23a1363 100644
--- a/src/plugins/qmlprofiler/flamegraphview.h
+++ b/src/plugins/qmlprofiler/flamegraphview.h
@@ -40,7 +40,6 @@ class FlameGraphView : public QmlProfilerEventsView
public:
FlameGraphView(QmlProfilerModelManager *manager, QWidget *parent = nullptr);
-public slots:
void selectByTypeId(int typeIndex) override;
void onVisibleFeaturesChanged(quint64 features) override;
diff --git a/src/plugins/qmlprofiler/inputeventsmodel.cpp b/src/plugins/qmlprofiler/inputeventsmodel.cpp
index 0c7e9b50fc8..2c8be86fe43 100644
--- a/src/plugins/qmlprofiler/inputeventsmodel.cpp
+++ b/src/plugins/qmlprofiler/inputeventsmodel.cpp
@@ -126,7 +126,7 @@ QVariantMap InputEventsModel::details(int index) const
type = tr("Mouse Event");
break;
default:
- Q_UNREACHABLE();
+ type = tr("Unknown");
break;
}
diff --git a/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml b/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml
index 34bca26cfa3..b49c16f562e 100644
--- a/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml
+++ b/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml
@@ -32,8 +32,6 @@ import "../flamegraph/"
ScrollView {
id: root
- signal typeSelected(int typeIndex)
- signal gotoSourceLocation(string filename, int line, int column)
property int selectedTypeId: -1
property int sizeRole: QmlProfilerFlameGraphModel.DurationRole
@@ -157,9 +155,9 @@ ScrollView {
onClicked: {
if (flamegraphItem.FlameGraph.dataValid) {
tooltip.selectedNode = flamegraphItem;
- root.typeSelected(flamegraphItem.FlameGraph.data(
+ flameGraphModel.typeSelected(flamegraphItem.FlameGraph.data(
QmlProfilerFlameGraphModel.TypeIdRole));
- root.gotoSourceLocation(
+ flameGraphModel.gotoSourceLocation(
flamegraphItem.FlameGraph.data(
QmlProfilerFlameGraphModel.FilenameRole),
flamegraphItem.FlameGraph.data(
@@ -269,7 +267,7 @@ ScrollView {
onClearSelection: {
selectedTypeId = -1;
selectedNode = null;
- root.typeSelected(-1);
+ flameGraphModel.typeSelected(-1);
}
dialogTitle: {
diff --git a/src/plugins/qmlprofiler/qmlprofiler.qbs b/src/plugins/qmlprofiler/qmlprofiler.qbs
index 02a08fb6566..629641c4151 100644
--- a/src/plugins/qmlprofiler/qmlprofiler.qbs
+++ b/src/plugins/qmlprofiler/qmlprofiler.qbs
@@ -16,6 +16,7 @@ QtcPlugin {
Depends { name: "ProjectExplorer" }
Depends { name: "QtSupport" }
Depends { name: "TextEditor" }
+ Depends { name: "app_version_header" }
Group {
name: "General"
@@ -92,7 +93,10 @@ QtcPlugin {
"qmlprofilerbindingloopsrenderpass_test.h",
"qmlprofilerclientmanager_test.cpp", "qmlprofilerclientmanager_test.h",
"qmlprofilerconfigwidget_test.cpp", "qmlprofilerconfigwidget_test.h",
+ "qmlprofilerdetailsrewriter_test.cpp", "qmlprofilerdetailsrewriter_test.h",
"qmlprofilertraceview_test.cpp", "qmlprofilertraceview_test.h",
+
+ "tests.qrc"
]
}
}
diff --git a/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp b/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp
index 0dca25645da..1c00071ad3e 100644
--- a/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp
+++ b/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp
@@ -85,7 +85,6 @@ void QmlProfilerAnimationsModel::loadEvent(const QmlEvent &event, const QmlEvent
lastEvent.typeId = event.typeIndex();
lastEvent.framerate = event.number<qint32>(0);
lastEvent.animationcount = event.number<qint32>(1);
- QTC_ASSERT(lastEvent.animationcount > 0, return);
m_data.insert(insert(realStartTime, realEndTime - realStartTime, lastThread), lastEvent);
diff --git a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp
index 2b919e7f429..0152d994e4a 100644
--- a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp
@@ -29,6 +29,7 @@
#include "qmlprofilerstatemanager.h"
#include <utils/qtcassert.h>
+#include <projectexplorer/runnables.h>
namespace QmlProfiler {
namespace Internal {
@@ -65,13 +66,19 @@ void QmlProfilerClientManager::setRetryParams(int interval, int maxAttempts)
m_maximumRetries = maxAttempts;
}
-void QmlProfilerClientManager::setServerUrl(const QUrl &server)
+void QmlProfilerClientManager::connectToServer(const QUrl &server)
{
if (m_server != server) {
m_server = server;
disconnectClient();
stopConnectionTimer();
}
+ if (server.scheme() == ProjectExplorer::urlTcpScheme())
+ connectToTcpServer();
+ else if (server.scheme() == ProjectExplorer::urlSocketScheme())
+ startLocalServer();
+ else
+ QTC_ASSERT(false, emit connectionFailed());
}
void QmlProfilerClientManager::clearConnection()
@@ -166,9 +173,9 @@ void QmlProfilerClientManager::stopRecording()
void QmlProfilerClientManager::retryConnect()
{
- if (m_server.scheme() == "socket") {
+ if (m_server.scheme() == ProjectExplorer::urlSocketScheme()) {
startLocalServer();
- } else if (!m_server.host().isEmpty() && m_server.port() > 0) {
+ } else if (m_server.scheme() == ProjectExplorer::urlTcpScheme()) {
disconnectClient();
connectToTcpServer();
} else {
diff --git a/src/plugins/qmlprofiler/qmlprofilerclientmanager.h b/src/plugins/qmlprofiler/qmlprofilerclientmanager.h
index 61a9d178004..c64429abc70 100644
--- a/src/plugins/qmlprofiler/qmlprofilerclientmanager.h
+++ b/src/plugins/qmlprofiler/qmlprofilerclientmanager.h
@@ -47,7 +47,7 @@ public:
~QmlProfilerClientManager();
void setProfilerStateManager(QmlProfilerStateManager *profilerState);
- void setServerUrl(const QUrl &server);
+ void connectToServer(const QUrl &server);
void clearConnection();
void clearBufferedData();
@@ -58,8 +58,6 @@ public:
void setRetryParams(int interval, int maxAttempts);
void retryConnect();
- void connectToTcpServer();
- void startLocalServer();
void stopRecording();
@@ -69,6 +67,9 @@ signals:
void connectionClosed();
private:
+ void connectToTcpServer();
+ void startLocalServer();
+
QPointer<QmlProfilerStateManager> m_profilerState;
QPointer<QmlProfilerModelManager> m_modelManager;
QScopedPointer<QmlDebug::QmlDebugConnection> m_connection;
diff --git a/src/plugins/qmlprofiler/qmlprofilerconfigwidget.h b/src/plugins/qmlprofiler/qmlprofilerconfigwidget.h
index 2f3b0022b78..0daf884b78c 100644
--- a/src/plugins/qmlprofiler/qmlprofilerconfigwidget.h
+++ b/src/plugins/qmlprofiler/qmlprofilerconfigwidget.h
@@ -44,10 +44,9 @@ public:
explicit QmlProfilerConfigWidget(QmlProfilerSettings *settings, QWidget *parent = 0);
~QmlProfilerConfigWidget();
-private slots:
+private:
void updateUi();
-private:
Ui::QmlProfilerConfigWidget *m_ui;
QmlProfilerSettings *m_settings;
};
diff --git a/src/plugins/qmlprofiler/qmlprofilerconfigwidget.ui b/src/plugins/qmlprofiler/qmlprofilerconfigwidget.ui
index 9c7bdb50dcd..df66e67b80a 100644
--- a/src/plugins/qmlprofiler/qmlprofilerconfigwidget.ui
+++ b/src/plugins/qmlprofiler/qmlprofilerconfigwidget.ui
@@ -21,7 +21,7 @@
<item row="0" column="1">
<widget class="QCheckBox" name="flushEnabled">
<property name="toolTip">
- <string>Periodically flush pending data to Qt Creator. This reduces the delay when loading the
+ <string>Periodically flush pending data to the profiler. This reduces the delay when loading the
data and the memory usage in the application. It distorts the profile as the flushing
itself takes time.</string>
</property>
diff --git a/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp b/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp
index a5199491f61..59d236cc1ab 100644
--- a/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.cpp
@@ -42,53 +42,53 @@ namespace Internal {
class PropertyVisitor: protected QmlJS::AST::Visitor
{
- QmlJS::AST::Node * _lastValidNode;
- unsigned _line;
- unsigned _col;
public:
- QmlJS::AST::Node * operator()(QmlJS::AST::Node *node, unsigned line, unsigned col)
+ QmlJS::AST::Node *operator()(QmlJS::AST::Node *node, int line, int column)
{
- _line = line;
- _col = col;
- _lastValidNode = 0;
- accept(node);
- return _lastValidNode;
+ QTC_ASSERT(line >= 0, return nullptr);
+ QTC_ASSERT(column >= 0, return nullptr);
+ QTC_ASSERT(node, return nullptr);
+ m_line = line;
+ m_column = column;
+ m_lastValidNode = nullptr;
+ node->accept(this);
+ return m_lastValidNode;
}
protected:
using QmlJS::AST::Visitor::visit;
- void accept(QmlJS::AST::Node *node)
- {
- if (node)
- node->accept(this);
- }
-
- bool containsLocation(QmlJS::AST::SourceLocation start, QmlJS::AST::SourceLocation end)
- {
- return (_line > start.startLine || (_line == start.startLine && _col >= start.startColumn))
- && (_line < end.startLine || (_line == end.startLine && _col <= end.startColumn));
- }
-
-
- virtual bool preVisit(QmlJS::AST::Node *node)
+ bool preVisit(QmlJS::AST::Node *node) override
{
if (QmlJS::AST::cast<QmlJS::AST::UiQualifiedId *>(node))
return false;
return containsLocation(node->firstSourceLocation(), node->lastSourceLocation());
}
- virtual bool visit(QmlJS::AST::UiScriptBinding *ast)
+ bool visit(QmlJS::AST::UiScriptBinding *ast) override
{
- _lastValidNode = ast;
+ m_lastValidNode = ast;
return true;
}
- virtual bool visit(QmlJS::AST::UiPublicMember *ast)
+ bool visit(QmlJS::AST::UiPublicMember *ast) override
{
- _lastValidNode = ast;
+ m_lastValidNode = ast;
return true;
}
+
+private:
+ QmlJS::AST::Node *m_lastValidNode = nullptr;
+ quint32 m_line = 0;
+ quint32 m_column = 0;
+
+ bool containsLocation(QmlJS::AST::SourceLocation start, QmlJS::AST::SourceLocation end)
+ {
+ return (m_line > start.startLine
+ || (m_line == start.startLine && m_column >= start.startColumn))
+ && (m_line < end.startLine
+ || (m_line == end.startLine && m_column <= end.startColumn));
+ }
};
QmlProfilerDetailsRewriter::QmlProfilerDetailsRewriter(QObject *parent)
@@ -148,7 +148,6 @@ void QmlProfilerDetailsRewriter::rewriteDetailsForLocation(
{
PropertyVisitor propertyVisitor;
QmlJS::AST::Node *node = propertyVisitor(doc->ast(), location.line(), location.column());
-
if (!node)
return;
@@ -174,7 +173,7 @@ void QmlProfilerDetailsRewriter::disconnectQmlModel()
}
}
-void QmlProfilerDetailsRewriter::clearRequests()
+void QmlProfilerDetailsRewriter::clear()
{
m_filesCache.clear();
m_pendingEvents.clear();
@@ -257,6 +256,7 @@ void QmlProfilerDetailsRewriter::populateFileFinder(
m_projectFinder.setProjectDirectory(projectDirectory);
m_projectFinder.setProjectFiles(sourceFiles);
m_projectFinder.setSysroot(activeSysroot);
+ m_filesCache.clear();
}
} // namespace Internal
diff --git a/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.h b/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.h
index d5dcf6e773c..ae0b55cde7c 100644
--- a/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.h
+++ b/src/plugins/qmlprofiler/qmlprofilerdetailsrewriter.h
@@ -42,23 +42,22 @@ class QmlProfilerDetailsRewriter : public QObject
public:
explicit QmlProfilerDetailsRewriter(QObject *parent = nullptr);
- void clearRequests();
+ void clear();
void requestDetailsForLocation(int typeId, const QmlEventLocation &location);
QString getLocalFile(const QString &remoteFile);
void reloadDocuments();
- void documentReady(QmlJS::Document::Ptr doc);
void populateFileFinder(const ProjectExplorer::RunConfiguration *runConfiguration);
- struct PendingEvent {
- QmlEventLocation location;
- int typeId;
- };
-
signals:
void rewriteDetailsString(int typeId, const QString &details);
void eventDetailsChanged();
private:
+ struct PendingEvent {
+ QmlEventLocation location;
+ int typeId;
+ };
+
QMultiHash<QString, PendingEvent> m_pendingEvents;
Utils::FileInProjectFinder m_projectFinder;
QHash<QString, QString> m_filesCache;
@@ -67,6 +66,9 @@ private:
const QmlEventLocation &location);
void connectQmlModel();
void disconnectQmlModel();
+ void documentReady(QmlJS::Document::Ptr doc);
+
+ friend class QTypeInfo<PendingEvent>;
};
} // namespace Internal
diff --git a/src/plugins/qmlprofiler/qmlprofilereventsview.h b/src/plugins/qmlprofiler/qmlprofilereventsview.h
index e48f64ab953..85cfe31e5ca 100644
--- a/src/plugins/qmlprofiler/qmlprofilereventsview.h
+++ b/src/plugins/qmlprofiler/qmlprofilereventsview.h
@@ -40,14 +40,13 @@ public:
QmlProfilerEventsView(QWidget *parent = 0) : QWidget(parent) {}
virtual void clear() {}
+ virtual void selectByTypeId(int typeIndex) = 0;
+ virtual void onVisibleFeaturesChanged(quint64 features) = 0;
+
signals:
void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber);
void typeSelected(int typeIndex);
void showFullRange();
-
-public slots:
- virtual void selectByTypeId(int typeIndex) = 0;
- virtual void onVisibleFeaturesChanged(quint64 features) = 0;
};
} // namespace QmlProfiler
diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
index 3902167af26..7c85817841e 100644
--- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
@@ -92,18 +92,23 @@ bool QmlProfilerTraceTime::isRestrictedToRange() const
void QmlProfilerTraceTime::clear()
{
restrictToRange(-1, -1);
- setTime(-1, -1);
+ m_startTime = -1;
+ m_endTime = -1;
}
-void QmlProfilerTraceTime::setTime(qint64 startTime, qint64 endTime)
+void QmlProfilerTraceTime::update(qint64 time)
{
- QTC_ASSERT(startTime <= endTime, endTime = startTime);
- m_startTime = startTime;
- m_endTime = endTime;
+ QTC_ASSERT(time >= 0, return);
+ if (m_startTime > time || m_startTime == -1)
+ m_startTime = time;
+ if (m_endTime < time || m_endTime == -1)
+ m_endTime = time;
+ QTC_ASSERT(m_endTime >= m_startTime, m_startTime = m_endTime);
}
void QmlProfilerTraceTime::decreaseStartTime(qint64 time)
{
+ QTC_ASSERT(time >= 0, return);
if (m_startTime > time || m_startTime == -1) {
m_startTime = time;
if (m_endTime == -1)
@@ -115,6 +120,7 @@ void QmlProfilerTraceTime::decreaseStartTime(qint64 time)
void QmlProfilerTraceTime::increaseEndTime(qint64 time)
{
+ QTC_ASSERT(time >= 0, return);
if (m_endTime < time || m_endTime == -1) {
m_endTime = time;
if (m_startTime == -1)
@@ -244,6 +250,7 @@ void QmlProfilerModelManager::addEvents(const QVector<QmlEvent> &events)
{
for (const QmlEvent &event : events) {
d->eventStream << event;
+ d->traceTime->update(event.timestamp());
d->dispatch(event, d->eventTypes[event.typeIndex()]);
}
}
@@ -251,6 +258,7 @@ void QmlProfilerModelManager::addEvents(const QVector<QmlEvent> &events)
void QmlProfilerModelManager::addEvent(const QmlEvent &event)
{
d->eventStream << event;
+ d->traceTime->update(event.timestamp());
QTC_ASSERT(event.typeIndex() < d->eventTypes.size(),
d->eventTypes.resize(event.typeIndex() + 1));
d->dispatch(event, d->eventTypes.at(event.typeIndex()));
@@ -554,12 +562,12 @@ void QmlProfilerModelManager::save(const QString &filename)
emit error(message);
}, Qt::QueuedConnection);
- connect(writer, &QmlProfilerFileWriter::success, this, [this, file]() {
+ connect(writer, &QmlProfilerFileWriter::success, this, [file]() {
file->close();
delete file;
}, Qt::QueuedConnection);
- connect(writer, &QmlProfilerFileWriter::canceled, this, [this, file]() {
+ connect(writer, &QmlProfilerFileWriter::canceled, this, [file]() {
file->close();
file->remove();
delete file;
@@ -606,7 +614,10 @@ void QmlProfilerModelManager::load(const QString &filename)
this, &QmlProfilerModelManager::addEvents);
connect(reader, &QmlProfilerFileReader::success, this, [this, reader]() {
- d->traceTime->setTime(reader->traceStart(), reader->traceEnd());
+ if (reader->traceStart() >= 0)
+ d->traceTime->decreaseStartTime(reader->traceStart());
+ if (reader->traceEnd() >= 0)
+ d->traceTime->increaseEndTime(reader->traceEnd());
setRecordedFeatures(reader->loadedFeatures());
delete reader;
acquiringDone();
@@ -692,7 +703,7 @@ void QmlProfilerModelManager::clear()
else
emit error(tr("Cannot open temporary trace file to store events."));
d->eventTypes.clear();
- d->detailsRewriter->clearRequests();
+ d->detailsRewriter->clear();
d->traceTime->clear();
d->notesModel->clear();
setVisibleFeatures(0);
diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h
index 8cce222c513..f09537667e5 100644
--- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h
+++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h
@@ -56,10 +56,9 @@ public:
qint64 duration() const;
bool isRestrictedToRange() const;
-public slots:
void clear();
- void setTime(qint64 startTime, qint64 endTime);
+ void update(qint64 time);
void decreaseStartTime(qint64 time);
void increaseEndTime(qint64 time);
void restrictToRange(qint64 startTime, qint64 endTime);
@@ -135,6 +134,15 @@ public:
static const char *featureName(ProfileFeature feature);
+ void clear();
+ void restrictToRange(qint64 startTime, qint64 endTime);
+ bool isRestrictedToRange() const;
+
+ void startAcquiring();
+
+ void save(const QString &filename);
+ void load(const QString &filename);
+
signals:
void error(const QString &error);
void stateChanged();
@@ -145,21 +153,10 @@ signals:
void visibleFeaturesChanged(quint64 features);
void recordedFeaturesChanged(quint64 features);
-public slots:
- void clear();
- void restrictToRange(qint64 startTime, qint64 endTime);
- bool isRestrictedToRange() const;
-
- void startAcquiring();
-
- void save(const QString &filename);
- void load(const QString &filename);
-
private:
void setState(State state);
void detailsChanged(int typeId, const QString &newString);
-private:
class QmlProfilerModelManagerPrivate;
QmlProfilerModelManagerPrivate *d;
};
diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
index 273666e35b1..d18514eb880 100644
--- a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
@@ -48,6 +48,7 @@
#include "tests/qmlprofilerbindingloopsrenderpass_test.h"
#include "tests/qmlprofilerclientmanager_test.h"
#include "tests/qmlprofilerconfigwidget_test.h"
+#include "tests/qmlprofilerdetailsrewriter_test.h"
#include "tests/qmlprofilertraceview_test.h"
// Force QML Debugging to be enabled, so that we can selftest the profiler
@@ -103,7 +104,7 @@ void QmlProfilerPlugin::extensionsInitialized()
};
RunControl::registerWorkerCreator(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE,
- [this](RunControl *runControl) { return new QmlProfilerRunner(runControl); });
+ [](RunControl *runControl) { return new QmlProfilerRunner(runControl); });
RunControl::registerWorker<LocalQmlProfilerSupport>
(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, constraint);
@@ -145,6 +146,7 @@ QList<QObject *> QmlProfiler::Internal::QmlProfilerPlugin::createTestObjects() c
tests << new QmlProfilerBindingLoopsRenderPassTest;
tests << new QmlProfilerClientManagerTest;
tests << new QmlProfilerConfigWidgetTest;
+ tests << new QmlProfilerDetailsRewriterTest;
tests << new QmlProfilerTraceViewTest;
tests << new QQmlEngine; // Trigger debug connector to be started
diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
index 949eab3176a..7a24026e93e 100644
--- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
@@ -28,6 +28,8 @@
#include "qmlprofilerclientmanager.h"
#include "qmlprofilertool.h"
+#include <app/app_version.h>
+
#include <coreplugin/icore.h>
#include <coreplugin/helpmanager.h>
@@ -100,7 +102,7 @@ void QmlProfilerRunner::start()
this, [this, clientManager] {
QMessageBox *infoBox = new QMessageBox(ICore::mainWindow());
infoBox->setIcon(QMessageBox::Critical);
- infoBox->setWindowTitle(QmlProfilerTool::tr("Qt Creator"));
+ infoBox->setWindowTitle(Core::Constants::IDE_DISPLAY_NAME);
infoBox->setText(QmlProfilerTool::tr("Could not connect to the in-process QML profiler.\n"
"Do you want to retry?"));
infoBox->setStandardButtons(QMessageBox::Retry | QMessageBox::Cancel | QMessageBox::Help);
@@ -125,17 +127,10 @@ void QmlProfilerRunner::start()
});
infoBox->show();
- });
-
- clientManager->setServerUrl(serverUrl);
- if (serverUrl.port() != -1) {
- clientManager->connectToTcpServer();
- } else {
- clientManager->startLocalServer();
- }
+ }, Qt::QueuedConnection); // Queue any connection failures after reportStarted()
+ clientManager->connectToServer(serverUrl);
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning);
-
reportStarted();
}
@@ -281,7 +276,17 @@ LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl, const Q
addStartDependency(m_profiler);
StandardRunnable debuggee = runnable().as<StandardRunnable>();
- QString arguments = QmlDebug::qmlDebugArguments(QmlDebug::QmlProfilerServices, serverUrl);
+
+ QString code;
+ if (serverUrl.scheme() == urlSocketScheme())
+ code = QString("file:%1").arg(serverUrl.path());
+ else if (serverUrl.scheme() == urlTcpScheme())
+ code = QString("port:%1").arg(serverUrl.port());
+ else
+ QTC_CHECK(false);
+
+ QString arguments = QmlDebug::qmlDebugCommandLineArguments(QmlDebug::QmlProfilerServices,
+ code, true);
if (!debuggee.commandLineArguments.isEmpty())
arguments += ' ' + debuggee.commandLineArguments;
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatemanager.h b/src/plugins/qmlprofiler/qmlprofilerstatemanager.h
index 35b9bca98a6..e04870ab1c3 100644
--- a/src/plugins/qmlprofiler/qmlprofilerstatemanager.h
+++ b/src/plugins/qmlprofiler/qmlprofilerstatemanager.h
@@ -51,6 +51,12 @@ public:
QString currentStateAsString();
+ void setCurrentState(QmlProfilerState newState);
+ void setClientRecording(bool recording);
+ void setServerRecording(bool recording);
+ void setRequestedFeatures(quint64 features);
+ void setRecordedFeatures(quint64 features);
+
signals:
void stateChanged();
void clientRecordingChanged(bool);
@@ -58,13 +64,6 @@ signals:
void requestedFeaturesChanged(quint64);
void recordedFeaturesChanged(quint64);
-public slots:
- void setCurrentState(QmlProfilerState newState);
- void setClientRecording(bool recording);
- void setServerRecording(bool recording);
- void setRequestedFeatures(quint64 features);
- void setRecordedFeatures(quint64 features);
-
private:
class QmlProfilerStateManagerPrivate;
QmlProfilerStateManagerPrivate *d;
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatewidget.h b/src/plugins/qmlprofiler/qmlprofilerstatewidget.h
index 68322b2a712..bce98d9ce8e 100644
--- a/src/plugins/qmlprofiler/qmlprofilerstatewidget.h
+++ b/src/plugins/qmlprofiler/qmlprofilerstatewidget.h
@@ -41,13 +41,12 @@ public:
QmlProfilerModelManager *modelManager, QWidget *parent = 0);
~QmlProfilerStateWidget();
-private slots:
+private:
void showText(const QString &text);
void updateDisplay();
void update();
void reposition();
-private:
class QmlProfilerStateWidgetPrivate;
QmlProfilerStateWidgetPrivate *d;
};
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h
index cab4e5f5458..f83ef3c26e6 100644
--- a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h
+++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h
@@ -87,11 +87,9 @@ private:
void loadEvent(const QmlEvent &event, const QmlEventType &type);
void finalize();
-private slots:
void dataChanged();
void notesChanged(int typeIndex);
-private:
class QmlProfilerStatisticsModelPrivate;
QmlProfilerStatisticsModelPrivate *d;
};
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h
index a23b8711762..651bc97a19e 100644
--- a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h
+++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h
@@ -82,7 +82,6 @@ public:
QString summary(const QVector<int> &typeIds) const;
QStringList details(int typeId) const;
-public slots:
void selectByTypeId(int typeIndex) override;
void onVisibleFeaturesChanged(quint64 features) override;
@@ -121,27 +120,24 @@ public:
void setShowExtendedStatistics(bool);
bool showExtendedStatistics() const;
-signals:
- void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber);
- void typeSelected(int typeIndex);
-
-public slots:
void clear();
void jumpToItem(const QModelIndex &index);
void selectType(int typeIndex);
void buildModel();
void updateNotes(int typeIndex);
+signals:
+ void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber);
+ void typeSelected(int typeIndex);
+
private:
void selectItem(const QStandardItem *item);
void setHeaderLabels();
void parseModel();
QStandardItem *itemFromIndex(const QModelIndex &index) const;
-private:
class QmlProfilerStatisticsMainViewPrivate;
QmlProfilerStatisticsMainViewPrivate *d;
-
};
class QmlProfilerStatisticsRelativesView : public Utils::TreeView
@@ -152,15 +148,14 @@ public:
QWidget *parent);
~QmlProfilerStatisticsRelativesView();
-signals:
- void typeClicked(int typeIndex);
- void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber);
-
-public slots:
void displayType(int typeIndex);
void jumpToItem(const QModelIndex &);
void clear();
+signals:
+ void typeClicked(int typeIndex);
+ void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber);
+
private:
void rebuildTree(const QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesMap &map);
void updateHeader();
diff --git a/src/plugins/qmlprofiler/qmlprofilertextmark.cpp b/src/plugins/qmlprofiler/qmlprofilertextmark.cpp
index bbc0bf3fc0b..4a7bf4ae389 100644
--- a/src/plugins/qmlprofiler/qmlprofilertextmark.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertextmark.cpp
@@ -22,8 +22,12 @@
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
+
#include "qmlprofilertextmark.h"
+
#include "qmlprofilerconstants.h"
+#include "qmlprofilerviewmanager.h"
+#include "qmlprofilerstatisticsview.h"
#include <QLabel>
#include <QLayout>
@@ -32,9 +36,9 @@
namespace QmlProfiler {
namespace Internal {
-QmlProfilerTextMark::QmlProfilerTextMark(QmlProfilerTool *tool, int typeId, const QString &fileName,
- int lineNumber) :
- TextMark(fileName, lineNumber, Constants::TEXT_MARK_CATEGORY, 3.5), m_tool(tool),
+QmlProfilerTextMark::QmlProfilerTextMark(QmlProfilerViewManager *viewManager, int typeId,
+ const QString &fileName, int lineNumber) :
+ TextMark(fileName, lineNumber, Constants::TEXT_MARK_CATEGORY, 3.5), m_viewManager(viewManager),
m_typeIds(1, typeId)
{
}
@@ -50,7 +54,8 @@ void QmlProfilerTextMark::paintIcon(QPainter *painter, const QRect &paintRect) c
painter->setPen(Qt::black);
painter->fillRect(paintRect, Qt::white);
painter->drawRect(paintRect);
- painter->drawText(paintRect, m_tool->summary(m_typeIds), Qt::AlignRight | Qt::AlignVCenter);
+ painter->drawText(paintRect, m_viewManager->statisticsView()->summary(m_typeIds),
+ Qt::AlignRight | Qt::AlignVCenter);
painter->restore();
}
@@ -58,7 +63,7 @@ void QmlProfilerTextMark::clicked()
{
int typeId = m_typeIds.takeFirst();
m_typeIds.append(typeId);
- m_tool->selectType(typeId);
+ m_viewManager->typeSelected(typeId);
}
QmlProfilerTextMarkModel::QmlProfilerTextMarkModel(QObject *parent) : QObject(parent)
@@ -82,7 +87,8 @@ void QmlProfilerTextMarkModel::addTextMarkId(int typeId, const QmlEventLocation
m_ids.insert(location.filename(), {typeId, location.line(), location.column()});
}
-void QmlProfilerTextMarkModel::createMarks(QmlProfilerTool *tool, const QString &fileName)
+void QmlProfilerTextMarkModel::createMarks(QmlProfilerViewManager *viewManager,
+ const QString &fileName)
{
auto first = m_ids.find(fileName);
QVarLengthArray<TextMarkId> ids;
@@ -103,7 +109,7 @@ void QmlProfilerTextMarkModel::createMarks(QmlProfilerTool *tool, const QString
m_marks.last()->addTypeId(it->typeId);
} else {
lineNumber = it->lineNumber;
- m_marks.append(new QmlProfilerTextMark(tool, it->typeId, fileName, it->lineNumber));
+ m_marks << new QmlProfilerTextMark(viewManager, it->typeId, fileName, it->lineNumber);
}
}
}
@@ -113,7 +119,7 @@ bool QmlProfilerTextMark::addToolTipContent(QLayout *target) const
QGridLayout *layout = new QGridLayout;
layout->setHorizontalSpacing(10);
for (int row = 0, rowEnd = m_typeIds.length(); row != rowEnd; ++row) {
- const QStringList typeDetails = m_tool->details(m_typeIds[row]);
+ const QStringList typeDetails = m_viewManager->statisticsView()->details(m_typeIds[row]);
for (int column = 0, columnEnd = typeDetails.length(); column != columnEnd; ++column) {
QLabel *label = new QLabel;
label->setAlignment(column == columnEnd - 1 ? Qt::AlignRight : Qt::AlignLeft);
diff --git a/src/plugins/qmlprofiler/qmlprofilertextmark.h b/src/plugins/qmlprofiler/qmlprofilertextmark.h
index 894e5fc5178..19d13dcf79b 100644
--- a/src/plugins/qmlprofiler/qmlprofilertextmark.h
+++ b/src/plugins/qmlprofiler/qmlprofilertextmark.h
@@ -25,16 +25,18 @@
#pragma once
#include "qmleventlocation.h"
-#include "qmlprofilertool.h"
#include <texteditor/textmark.h>
namespace QmlProfiler {
namespace Internal {
+class QmlProfilerViewManager;
+
class QmlProfilerTextMark : public TextEditor::TextMark
{
public:
- QmlProfilerTextMark(QmlProfilerTool *tool, int typeId, const QString &fileName, int lineNumber);
+ QmlProfilerTextMark(QmlProfilerViewManager *viewManager, int typeId,
+ const QString &fileName, int lineNumber);
void addTypeId(int typeId);
void paintIcon(QPainter *painter, const QRect &rect) const override;
@@ -43,7 +45,7 @@ public:
bool addToolTipContent(QLayout *target) const override;
private:
- QmlProfilerTool *m_tool;
+ QmlProfilerViewManager *m_viewManager;
QVector<int> m_typeIds;
};
@@ -55,7 +57,7 @@ public:
void clear();
void addTextMarkId(int typeId, const QmlEventLocation &location);
- void createMarks(QmlProfilerTool *tool, const QString &fileName);
+ void createMarks(QmlProfilerViewManager *viewManager, const QString &fileName);
private:
struct TextMarkId {
diff --git a/src/plugins/qmlprofiler/qmlprofilertimelinemodel.h b/src/plugins/qmlprofiler/qmlprofilertimelinemodel.h
index bfb4e267853..742bec73b4b 100644
--- a/src/plugins/qmlprofiler/qmlprofilertimelinemodel.h
+++ b/src/plugins/qmlprofiler/qmlprofilertimelinemodel.h
@@ -55,14 +55,13 @@ public:
virtual void loadEvent(const QmlEvent &event, const QmlEventType &type) = 0;
virtual void finalize() = 0;
-private slots:
- void dataChanged();
- void onVisibleFeaturesChanged(quint64 features);
-
protected:
void announceFeatures(quint64 features);
private:
+ void dataChanged();
+ void onVisibleFeaturesChanged(quint64 features);
+
const Message m_message;
const RangeType m_rangeType;
const ProfileFeature m_mainFeature;
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp
index 423b8c655ad..3488c93f14d 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp
@@ -290,7 +290,7 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
connect(editorManager, &EditorManager::editorCreated,
model, [this, model](Core::IEditor *editor, const QString &fileName) {
Q_UNUSED(editor);
- model->createMarks(this, fileName);
+ model->createMarks(d->m_viewContainer, fileName);
});
}
@@ -393,9 +393,7 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker)
// Initialize m_projectFinder
//
- if (runConfiguration) {
- d->m_profilerModelManager->populateFileFinder(runConfiguration);
- }
+ d->m_profilerModelManager->populateFileFinder(runConfiguration);
}
void QmlProfilerTool::recordingButtonChanged(bool recording)
@@ -439,11 +437,6 @@ void QmlProfilerTool::gotoSourceLocation(const QString &fileUrl, int lineNumber,
EditorManager::DoNotSwitchToDesignMode | EditorManager::DoNotSwitchToEditMode);
}
-void QmlProfilerTool::selectType(int typeId)
-{
- d->m_viewContainer->typeSelected(typeId);
-}
-
void QmlProfilerTool::updateTimeDisplay()
{
double seconds = 0;
@@ -502,7 +495,7 @@ void QmlProfilerTool::createTextMarks()
{
QmlProfilerTextMarkModel *model = d->m_profilerModelManager->textMarkModel();
foreach (IDocument *document, DocumentModel::openedDocuments())
- model->createMarks(this, document->filePath().toString());
+ model->createMarks(d->m_viewContainer, document->filePath().toString());
}
void QmlProfilerTool::clearTextMarks()
@@ -571,16 +564,6 @@ void QmlProfilerTool::attachToWaitingApplication()
ProjectExplorerPlugin::startRunControl(runControl);
}
-QString QmlProfilerTool::summary(const QVector<int> &typeIds) const
-{
- return d->m_viewContainer->statisticsView()->summary(typeIds);
-}
-
-QStringList QmlProfilerTool::details(int typeId) const
-{
- return d->m_viewContainer->statisticsView()->details(typeId);
-}
-
void QmlProfilerTool::logState(const QString &msg)
{
MessageManager::write(msg, MessageManager::Flash);
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h
index c50747e85b1..4b784dfe8e1 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.h
+++ b/src/plugins/qmlprofiler/qmlprofilertool.h
@@ -55,9 +55,6 @@ public:
bool prepareTool();
void attachToWaitingApplication();
- QString summary(const QVector<int> &typeIds) const;
- QStringList details(int typeId) const;
-
static QList <QAction *> profilerContextMenuActions();
// display dialogs / log output
@@ -67,7 +64,6 @@ public:
static QmlProfilerClientManager *clientManager();
-public slots:
void profilerStateChanged();
void serverRecordingChanged();
void clientsDisconnected();
@@ -76,9 +72,8 @@ public slots:
void recordingButtonChanged(bool recording);
void gotoSourceLocation(const QString &fileUrl, int lineNumber, int columnNumber);
- void selectType(int typeId);
-private slots:
+private:
void clearData();
void showErrorDialog(const QString &error);
void profilerDataModelStateChanged();
@@ -94,7 +89,6 @@ private slots:
void toggleRequestedFeature(QAction *action);
void toggleVisibleFeature(QAction *action);
-private:
void updateRunActions();
void clearDisplay();
template<ProfileFeature feature>
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
index 76dbf370097..39cdb96ede0 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
@@ -138,7 +138,8 @@ void QmlProfilerTraceClientPrivate::processCurrentEvent()
break;
case RangeEnd: {
int typeIndex = resolveStackTop();
- QTC_ASSERT(typeIndex != -1, break);
+ if (typeIndex == -1)
+ break;
currentEvent.event.setTypeIndex(typeIndex);
while (!pendingMessages.isEmpty())
modelManager->addEvent(pendingMessages.dequeue());
@@ -147,10 +148,12 @@ void QmlProfilerTraceClientPrivate::processCurrentEvent()
break;
}
case RangeData:
- rangesInProgress.top().type.setData(currentEvent.type.data());
+ if (!rangesInProgress.isEmpty())
+ rangesInProgress.top().type.setData(currentEvent.type.data());
break;
case RangeLocation:
- rangesInProgress.top().type.setLocation(currentEvent.type.location());
+ if (!rangesInProgress.isEmpty())
+ rangesInProgress.top().type.setLocation(currentEvent.type.location());
break;
default: {
int typeIndex = resolveType(currentEvent);
@@ -166,7 +169,7 @@ void QmlProfilerTraceClientPrivate::processCurrentEvent()
void QmlProfilerTraceClientPrivate::sendRecordingStatus(int engineId)
{
- QmlDebug::QPacket stream(q->connection()->currentDataStreamVersion());
+ QmlDebug::QPacket stream(q->dataStreamVersion());
stream << recording << engineId; // engineId -1 is OK. It means "all of them"
if (recording) {
stream << requestedFeatures << flushInterval;
@@ -244,7 +247,7 @@ void QmlProfilerTraceClient::setRequestedFeatures(quint64 features)
const QmlDebug::QDebugContextInfo &context)
{
d->updateFeatures(ProfileDebugMessages);
- d->currentEvent.event.setTimestamp(context.timestamp);
+ d->currentEvent.event.setTimestamp(context.timestamp > 0 ? context.timestamp : 0);
d->currentEvent.event.setTypeIndex(-1);
d->currentEvent.event.setString(text);
d->currentEvent.type = QmlEventType(DebugMessage, MaximumRangeType, type,
@@ -282,7 +285,7 @@ void QmlProfilerTraceClient::stateChanged(State status)
void QmlProfilerTraceClient::messageReceived(const QByteArray &data)
{
- QmlDebug::QPacket stream(connection()->currentDataStreamVersion(), data);
+ QmlDebug::QPacket stream(dataStreamVersion(), data);
stream >> d->currentEvent;
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceclient.h b/src/plugins/qmlprofiler/qmlprofilertraceclient.h
index 237fdc002a4..b0f17c97893 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceclient.h
+++ b/src/plugins/qmlprofiler/qmlprofilertraceclient.h
@@ -52,8 +52,9 @@ public:
bool isRecording() const;
void setRecording(bool);
quint64 recordedFeatures() const;
+ virtual void messageReceived(const QByteArray &) override;
+ virtual void stateChanged(State status) override;
-public slots:
void clearData();
void sendRecordingStatus(int engineId = -1);
void setRequestedFeatures(quint64 features);
@@ -69,10 +70,6 @@ signals:
void cleared();
-protected:
- virtual void stateChanged(State status);
- virtual void messageReceived(const QByteArray &);
-
private:
class QmlProfilerTraceClientPrivate *d;
};
diff --git a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
index b84de415ae7..87f6e89e441 100644
--- a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
@@ -108,7 +108,7 @@ static QString qmlTypeAsString(Message message, RangeType rangeType)
{
if (rangeType < MaximumRangeType)
return _(RANGE_TYPE_STRINGS[rangeType]);
- else if (message != MaximumMessage)
+ else if (message < MaximumMessage)
return _(MESSAGE_STRINGS[message]);
else
return QString::number((int)rangeType);
@@ -257,6 +257,8 @@ void QmlProfilerFileReader::loadQzt(QIODevice *device)
return;
}
m_loadedFeatures |= (1ULL << m_eventTypes[event.typeIndex()].feature());
+ if (event.timestamp() < 0)
+ event.setTimestamp(0);
} else if (bufferStream.status() == QDataStream::ReadPastEnd) {
break; // Apparently EOF is a character so we end up here after the last event.
} else if (bufferStream.status() == QDataStream::ReadCorruptData) {
@@ -506,15 +508,16 @@ void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
continue;
}
- event.setTimestamp(attributes.value(_("startTime")).toLongLong());
+ const qint64 timestamp = attributes.value(_("startTime")).toLongLong();
+ event.setTimestamp(timestamp > 0 ? timestamp : 0);
event.setTypeIndex(attributes.value(_("eventIndex")).toInt());
if (attributes.hasAttribute(_("duration"))) {
event.setRangeStage(RangeStart);
QmlEvent rangeEnd(event);
rangeEnd.setRangeStage(RangeEnd);
- rangeEnd.setTimestamp(event.timestamp()
- + attributes.value(_("duration")).toLongLong());
+ const qint64 duration = attributes.value(_("duration")).toLongLong();
+ rangeEnd.setTimestamp(event.timestamp() + (duration > 0 ? duration : 0));
events.addRange(event, rangeEnd);
} else {
// attributes for special events
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
index a7bf3fe4682..7efdefa93a5 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
@@ -183,8 +183,8 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerViewManag
d->m_zoomControl);
d->m_mainView->setSource(QUrl(QLatin1String("qrc:/timeline/MainView.qml")));
- QQuickItem *rootObject = d->m_mainView->rootObject();
- connect(rootObject, SIGNAL(updateCursorPosition()), this, SLOT(updateCursorPosition()));
+ connect(d->m_modelProxy, &Timeline::TimelineModelAggregator::updateCursorPosition,
+ this, &QmlProfilerTraceView::updateCursorPosition);
}
QmlProfilerTraceView::~QmlProfilerTraceView()
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.h b/src/plugins/qmlprofiler/qmlprofilertraceview.h
index 79063ac2610..0c5fc2efed4 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceview.h
+++ b/src/plugins/qmlprofiler/qmlprofilertraceview.h
@@ -55,7 +55,6 @@ public:
bool isUsable() const;
bool isSuspended() const;
-public slots:
void clear();
void selectByTypeId(int typeId);
void selectByEventIndex(int modelId, int eventIndex);
diff --git a/src/plugins/qmlprofiler/qmltypedevent.cpp b/src/plugins/qmlprofiler/qmltypedevent.cpp
index e5007345b5f..30bfeb9b705 100644
--- a/src/plugins/qmlprofiler/qmltypedevent.cpp
+++ b/src/plugins/qmlprofiler/qmltypedevent.cpp
@@ -36,15 +36,20 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
stream >> time >> messageType;
+ if (messageType < 0 || messageType > MaximumMessage)
+ messageType = MaximumMessage;
+
RangeType rangeType = MaximumRangeType;
if (!stream.atEnd()) {
stream >> subtype;
rangeType = static_cast<RangeType>(subtype);
+ if (rangeType < 0 || rangeType > MaximumRangeType)
+ rangeType = MaximumRangeType;
} else {
subtype = -1;
}
- event.event.setTimestamp(time);
+ event.event.setTimestamp(time > 0 ? time : 0);
event.event.setTypeIndex(-1);
event.serverTypeId = 0;
@@ -180,6 +185,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
break;
}
default:
+ event.event.setNumbers<char>({});
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
break;
}
diff --git a/src/plugins/qmlprofiler/tests/Test.qml b/src/plugins/qmlprofiler/tests/Test.qml
new file mode 100644
index 00000000000..e0fc79d1da5
--- /dev/null
+++ b/src/plugins/qmlprofiler/tests/Test.qml
@@ -0,0 +1,7 @@
+import QtQml 2.0
+
+QtObject {
+ property int dings: 12 + 12 + 12
+ property string no: "nonono"
+ objectName: { return no + Math.random(); }
+}
diff --git a/src/plugins/qmlprofiler/tests/inputeventsmodel_test.cpp b/src/plugins/qmlprofiler/tests/inputeventsmodel_test.cpp
index 781a14d4e9b..0d24d359ace 100644
--- a/src/plugins/qmlprofiler/tests/inputeventsmodel_test.cpp
+++ b/src/plugins/qmlprofiler/tests/inputeventsmodel_test.cpp
@@ -32,6 +32,11 @@
namespace QmlProfiler {
namespace Internal {
+static InputEventType inputType(int i)
+{
+ return static_cast<InputEventType>(i % (MaximumInputEventType + 1));
+}
+
InputEventsModelTest::InputEventsModelTest(QObject *parent) :
QObject(parent), manager(nullptr), model(&manager)
{
@@ -48,13 +53,14 @@ void InputEventsModelTest::initTestCase()
for (int i = 0; i < 10; ++i) {
event.setTimestamp(i);
- InputEventType type = static_cast<InputEventType>(i % MaximumInputEventType);
+ InputEventType type = inputType(i);
event.setTypeIndex(type <= InputKeyUnknown ? keyTypeId : mouseTypeId);
event.setNumbers({static_cast<qint32>(type),
(i * 32) % 256,
static_cast<qint32>((i * 0x02000000) & Qt::KeyboardModifierMask)});
manager.addEvent(event);
}
+
manager.acquiringDone();
QCOMPARE(manager.state(), QmlProfilerModelManager::Done);
}
@@ -71,7 +77,7 @@ void InputEventsModelTest::testAccepted()
void InputEventsModelTest::testTypeId()
{
for (int i = 0; i < 10; ++i) {
- InputEventType type = static_cast<InputEventType>(i % MaximumInputEventType);
+ InputEventType type = inputType(i);
QCOMPARE(model.typeId(i), type <= InputKeyUnknown ? keyTypeId : mouseTypeId);
}
}
@@ -81,7 +87,7 @@ void InputEventsModelTest::testColor()
QRgb keyColor = 0;
QRgb mouseColor = 0;
for (int i = 0; i < 10; ++i) {
- InputEventType type = static_cast<InputEventType>(i % MaximumInputEventType);
+ InputEventType type = inputType(i);
int selectionId = (type <= InputKeyUnknown ? Key : Mouse);
QCOMPARE(selectionId, model.selectionId(i));
@@ -112,7 +118,7 @@ void InputEventsModelTest::testDetails()
QCOMPARE(details[model.tr("Timestamp")].toString(), Timeline::formatTime(i));
QString displayName = details[QString("displayName")].toString();
QVERIFY(!displayName.isEmpty());
- switch (static_cast<InputEventType>(i % MaximumInputEventType)) {
+ switch (inputType(i)) {
case InputKeyPress:
QCOMPARE(displayName, model.tr("Key Press"));
if (i == 0) {
@@ -177,7 +183,7 @@ void InputEventsModelTest::testDetails()
QVERIFY(!details.contains(model.tr("Result")));
break;
default:
- Q_UNREACHABLE();
+ QCOMPARE(displayName, model.tr("Unknown"));
break;
}
}
@@ -186,7 +192,7 @@ void InputEventsModelTest::testDetails()
void InputEventsModelTest::testExpandedRow()
{
for (int i = 0; i < 10; ++i) {
- InputEventType type = static_cast<InputEventType>(i % MaximumInputEventType);
+ InputEventType type = inputType(i);
QCOMPARE(model.expandedRow(i), (type <= InputKeyUnknown ? 2 : 1));
}
}
diff --git a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
index 53489eaee8b..754455c86b4 100644
--- a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
+++ b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
@@ -56,6 +56,7 @@ void LocalQmlProfilerRunnerTest::testRunner()
debuggee.environment = Utils::Environment::systemEnvironment();
// should not be used anywhere but cannot be empty
+ serverUrl.setScheme(ProjectExplorer::urlSocketScheme());
serverUrl.setPath("invalid");
runControl = new ProjectExplorer::RunControl(nullptr,
diff --git a/src/plugins/qmlprofiler/tests/pixmapcachemodel_test.cpp b/src/plugins/qmlprofiler/tests/pixmapcachemodel_test.cpp
index 0b4d39fdc61..903e2b13320 100644
--- a/src/plugins/qmlprofiler/tests/pixmapcachemodel_test.cpp
+++ b/src/plugins/qmlprofiler/tests/pixmapcachemodel_test.cpp
@@ -38,7 +38,8 @@ PixmapCacheModelTest::PixmapCacheModelTest(QObject *parent) : QObject(parent),
void PixmapCacheModelTest::initTestCase()
{
manager.startAcquiring();
- manager.traceTime()->setTime(1, 300);
+ manager.traceTime()->decreaseStartTime(1);
+ manager.traceTime()->increaseEndTime(300);
for (int i = 0; i < MaximumPixmapEventType; ++i) {
eventTypeIndices[i] = manager.numLoadedEventTypes();
diff --git a/src/plugins/qmlprofiler/tests/qmlprofileranimationsmodel_test.cpp b/src/plugins/qmlprofiler/tests/qmlprofileranimationsmodel_test.cpp
index 846ff731d68..d5723dd731a 100644
--- a/src/plugins/qmlprofiler/tests/qmlprofileranimationsmodel_test.cpp
+++ b/src/plugins/qmlprofiler/tests/qmlprofileranimationsmodel_test.cpp
@@ -51,7 +51,7 @@ void QmlProfilerAnimationsModelTest::initTestCase()
for (int i = 0; i < 10; ++i) {
event.setTimestamp(i);
- event.setNumbers<int>({frameRate(i), 20 - i, (i % 2) ? RenderThread : GuiThread});
+ event.setNumbers<int>({frameRate(i), 9 - i, (i % 2) ? RenderThread : GuiThread});
manager.addEvent(event);
}
manager.acquiringDone();
@@ -69,8 +69,8 @@ void QmlProfilerAnimationsModelTest::testAccepted()
void QmlProfilerAnimationsModelTest::testRowMaxValue()
{
QCOMPARE(model.rowMaxValue(0), 0);
- QCOMPARE(model.rowMaxValue(1), 20);
- QCOMPARE(model.rowMaxValue(2), 19);
+ QCOMPARE(model.rowMaxValue(1), 9);
+ QCOMPARE(model.rowMaxValue(2), 8);
}
void QmlProfilerAnimationsModelTest::testRowNumbers()
@@ -133,7 +133,7 @@ void QmlProfilerAnimationsModelTest::testDetails()
QCOMPARE(details[QmlProfilerAnimationsModel::tr("Framerate")].toString(),
QString::fromLatin1("%1 FPS").arg(frameRate(i)));
QCOMPARE(details[QmlProfilerAnimationsModel::tr("Animations")].toString(),
- QString::number(20 - i));
+ QString::number(9 - i));
QCOMPARE(details[QmlProfilerAnimationsModel::tr("Context")].toString(), i % 2 ?
QmlProfilerAnimationsModel::tr("Render Thread") :
QmlProfilerAnimationsModel::tr("GUI Thread"));
diff --git a/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp b/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp
index d2347d42640..0318a6b6185 100644
--- a/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp
+++ b/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp
@@ -73,38 +73,32 @@ void QmlProfilerClientManagerTest::testConnectionFailure_data()
QUrl localUrl = urlFromLocalHostAndFreePort();
QTest::addColumn<QUrl>("serverUrl");
- QVarLengthArray<QString> hosts({"", "/-/|\\-\\|/-", localUrl.host()});
- QVarLengthArray<int> ports({-1, 5, localUrl.port()});
- QVarLengthArray<QString> sockets({"", "/-/|\\-\\|/-", urlFromLocalSocket().path()});
-
- foreach (QmlProfilerModelManager *modelManager, modelManagers) {
- foreach (QmlProfilerStateManager *stateManager, stateManagers) {
- foreach (QString host, hosts) {
- foreach (int port, ports) {
- QString tag = QString::fromLatin1("%1, %2, %3, %4, %5")
- .arg(QLatin1String(modelManager ? "modelManager" : "<null>"))
- .arg(QLatin1String(stateManager ? "stateManager" : "<null>"))
- .arg(host.isEmpty() ? "<empty>" : host)
- .arg(Utils::Port(port).isValid() ? port : 0)
- .arg("<empty>");
- QUrl url;
- url.setHost(host);
- url.setPort(port);
- QTest::newRow(tag.toLatin1().constData()) << modelManager << stateManager << url;
+ const QVarLengthArray<QString> hosts({"", "/-/|\\-\\|/-", localUrl.host()});
+ const QVarLengthArray<int> ports({-1, 5, localUrl.port()});
+ const QVarLengthArray<QString> sockets({"", "/-/|\\-\\|/-", urlFromLocalSocket().path()});
+ const QVarLengthArray<QString> schemes({"", urlSocketScheme(), urlTcpScheme()});
+
+ for (QmlProfilerModelManager *modelManager : modelManagers) {
+ for (QmlProfilerStateManager *stateManager : stateManagers) {
+ for (const QString &host : hosts) {
+ for (int port : ports) {
+ for (const QString &socket : sockets) {
+ for (const QString &scheme : schemes ) {
+ QUrl url;
+ url.setScheme(scheme);
+ url.setHost(host);
+ url.setPort(port);
+ url.setPath(socket);
+ QString tag = QString::fromLatin1("%1, %2, %3")
+ .arg(QLatin1String(modelManager ? "modelManager" : "<null>"))
+ .arg(QLatin1String(stateManager ? "stateManager" : "<null>"))
+ .arg(url.toString());
+ QTest::newRow(tag.toLatin1().constData()) << modelManager
+ << stateManager << url;
+ }
+ }
}
}
- foreach (QString socket, sockets) {
- QString tag = QString::fromLatin1("%1, %2, %3, %4, %5")
- .arg(QLatin1String(modelManager ? "modelManager" : "<null>"))
- .arg(QLatin1String(stateManager ? "stateManager" : "<null>"))
- .arg("<empty>")
- .arg(0)
- .arg(socket);
- QUrl url;
- url.setScheme(urlSocketScheme());
- url.setPath(socket);
- QTest::newRow(tag.toLatin1().constData()) << modelManager << stateManager << url;
- }
}
}
}
@@ -137,24 +131,17 @@ void QmlProfilerClientManagerTest::testConnectionFailure()
clientManager.setModelManager(modelManager);
clientManager.setProfilerStateManager(stateManager);
- clientManager.setServerUrl(serverUrl);
QVERIFY(!clientManager.isConnected());
- clientManager.connectToTcpServer();
+ clientManager.connectToServer(serverUrl);
QTRY_COMPARE(failedSpy.count(), 1);
QCOMPARE(closedSpy.count(), 0);
QCOMPARE(openedSpy.count(), 0);
QVERIFY(!clientManager.isConnected());
- clientManager.startLocalServer();
- QTRY_COMPARE(failedSpy.count(), 2);
- QCOMPARE(closedSpy.count(), 0);
- QCOMPARE(openedSpy.count(), 0);
- QVERIFY(!clientManager.isConnected());
-
clientManager.retryConnect();
- QTRY_COMPARE(failedSpy.count(), 3);
+ QTRY_COMPARE(failedSpy.count(), 2);
QCOMPARE(closedSpy.count(), 0);
QCOMPARE(openedSpy.count(), 0);
QVERIFY(!clientManager.isConnected());
@@ -181,8 +168,7 @@ void QmlProfilerClientManagerTest::testUnresponsiveTcp()
server.listen(QHostAddress(serverUrl.host()), serverUrl.port());
QSignalSpy connectionSpy(&server, SIGNAL(newConnection()));
- clientManager.setServerUrl(serverUrl);
- clientManager.connectToTcpServer();
+ clientManager.connectToServer(serverUrl);
QTRY_VERIFY(connectionSpy.count() > 0);
QTRY_COMPARE(failedSpy.count(), 1);
@@ -208,8 +194,7 @@ void QmlProfilerClientManagerTest::testUnresponsiveLocal()
QLocalSocket socket;
QSignalSpy connectionSpy(&socket, SIGNAL(connected()));
- clientManager.setServerUrl(socketUrl);
- clientManager.startLocalServer();
+ clientManager.connectToServer(socketUrl);
socket.connectToServer(socketUrl.path());
QTRY_COMPARE(connectionSpy.count(), 1);
@@ -280,8 +265,7 @@ void QmlProfilerClientManagerTest::testResponsiveTcp()
connect(&clientManager, &QmlProfilerClientManager::connectionFailed,
&clientManager, &QmlProfilerClientManager::retryConnect);
- clientManager.setServerUrl(serverUrl);
- clientManager.connectToTcpServer();
+ clientManager.connectToServer(serverUrl);
QTRY_COMPARE(openedSpy.count(), 1);
QCOMPARE(closedSpy.count(), 0);
@@ -329,8 +313,7 @@ void QmlProfilerClientManagerTest::testResponsiveLocal()
connect(&clientManager, &QmlProfilerClientManager::connectionFailed,
&clientManager, &QmlProfilerClientManager::retryConnect);
- clientManager.setServerUrl(socketUrl);
- clientManager.startLocalServer();
+ clientManager.connectToServer(socketUrl);
{
QScopedPointer<QLocalSocket> socket(new QLocalSocket(this));
@@ -397,8 +380,7 @@ void QmlProfilerClientManagerTest::testInvalidData()
server.listen(QHostAddress(serverUrl.host()), serverUrl.port());
- clientManager.setServerUrl(serverUrl);
- clientManager.connectToTcpServer();
+ clientManager.connectToServer(serverUrl);
QTRY_VERIFY(dataSent);
QTRY_COMPARE(failedSpy.count(), 1);
@@ -427,8 +409,7 @@ void QmlProfilerClientManagerTest::testStopRecording()
connect(&clientManager, &QmlProfilerClientManager::connectionFailed,
&clientManager, &QmlProfilerClientManager::retryConnect);
- clientManager.setServerUrl(socketUrl);
- clientManager.startLocalServer();
+ clientManager.connectToServer(socketUrl);
QScopedPointer<QLocalSocket> socket(new QLocalSocket(this));
socket->connectToServer(socketUrl.path());
diff --git a/src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.cpp b/src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.cpp
new file mode 100644
index 00000000000..3363619d782
--- /dev/null
+++ b/src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qmlprofilerdetailsrewriter_test.h"
+
+#include <projectexplorer/customexecutablerunconfiguration.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/target.h>
+#include <projectexplorer/kitmanager.h>
+#include <projectexplorer/projectnodes.h>
+#include <projectexplorer/session.h>
+#include <projectexplorer/kitinformation.h>
+
+#include <QLibraryInfo>
+#include <QTest>
+
+namespace QmlProfiler {
+namespace Internal {
+
+class DummyProjectNode : public ProjectExplorer::ProjectNode
+{
+public:
+ DummyProjectNode(const Utils::FileName &file) : ProjectExplorer::ProjectNode(file)
+ {}
+};
+
+class DummyProject : public ProjectExplorer::Project
+{
+ Q_OBJECT
+public:
+ DummyProject(const Utils::FileName &file) :
+ ProjectExplorer::Project(QString(), file, {})
+ {
+ ProjectExplorer::FileNode *fileNode
+ = new ProjectExplorer::FileNode(file, ProjectExplorer::FileType::Source, false);
+ DummyProjectNode *root = new DummyProjectNode(file);
+ root->addNode(fileNode);
+ fileNode = new ProjectExplorer::FileNode(
+ Utils::FileName::fromLatin1(
+ ":/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.cpp"),
+ ProjectExplorer::FileType::Source, false);
+ root->addNode(fileNode);
+ setRootProjectNode(root);
+ }
+};
+
+QmlProfilerDetailsRewriterTest::QmlProfilerDetailsRewriterTest(QObject *parent) : QObject(parent)
+{
+ connect(&m_rewriter, &QmlProfilerDetailsRewriter::eventDetailsChanged,
+ this, [this]() {
+ m_rewriterDone = true;
+ });
+}
+
+void QmlProfilerDetailsRewriterTest::testMissingModelManager()
+{
+ seedRewriter();
+ delete m_modelManager;
+ m_modelManager = nullptr;
+
+ // Verify it doesn't crash if model manager is missing.
+ QVERIFY(!m_rewriterDone);
+ auto rewriteConnection = connect(&m_rewriter, &QmlProfilerDetailsRewriter::rewriteDetailsString,
+ this, [&](int typeId, const QString &string) {
+ Q_UNUSED(typeId);
+ Q_UNUSED(string);
+ QFAIL("found nonexisting file in nonexisting model manager");
+ });
+ m_rewriter.requestDetailsForLocation(44, QmlEventLocation("Test.qml", 12, 12));
+ m_rewriter.reloadDocuments();
+ QVERIFY(m_rewriterDone);
+ m_rewriterDone = false;
+ disconnect(rewriteConnection);
+}
+
+void QmlProfilerDetailsRewriterTest::testRequestDetailsForLocation()
+{
+ seedRewriter();
+ QVERIFY(!m_rewriterDone);
+ bool found1 = false;
+ bool found2 = false;
+ auto rewriteConnection = connect(&m_rewriter, &QmlProfilerDetailsRewriter::rewriteDetailsString,
+ this, [&](int typeId, const QString &string) {
+ if (typeId == 1) {
+ QCOMPARE(string, QString::fromLatin1("property int dings: 12 + 12 + 12"));
+ found1 = true;
+ } else if (typeId == 2) {
+ QCOMPARE(string, QString::fromLatin1("objectName: { return no + Math.random(); }"));
+ found2 = true;
+ } else {
+ QFAIL("invalid typeId");
+ }
+ });
+
+ m_rewriter.requestDetailsForLocation(12, QmlEventLocation("Test.qml", 5, 25));
+ // simulate unrelated document update: Shouldn't send any events our way.
+ emit m_modelManager->documentUpdated(QmlJS::Document::create("gibtsnich.qml",
+ QmlJS::Dialect::Qml));
+ m_rewriter.clear();
+ QVERIFY(!found1);
+ QVERIFY(!found2);
+ QVERIFY(!m_rewriterDone);
+
+ m_rewriter.requestDetailsForLocation(1, QmlEventLocation("Test.qml", 4, 25));
+ m_rewriter.requestDetailsForLocation(2, QmlEventLocation("Test.qml", 6, 17));
+ m_rewriter.requestDetailsForLocation(42, QmlEventLocation("gibtsnich.qml", 6, 17));
+ m_rewriter.requestDetailsForLocation(14, QmlEventLocation("Test.qml", 55, 4));
+ m_rewriter.reloadDocuments();
+
+ QTRY_VERIFY(found1);
+ QTRY_VERIFY(found2);
+ QTRY_VERIFY(m_rewriterDone);
+
+ found1 = found2 = m_rewriterDone = false;
+ m_rewriter.reloadDocuments();
+ QVERIFY(!found1);
+ QVERIFY(!found2);
+ QVERIFY(m_rewriterDone);
+ m_rewriterDone = false;
+
+ disconnect(rewriteConnection);
+}
+
+void QmlProfilerDetailsRewriterTest::testGetLocalFile()
+{
+ seedRewriter();
+ QCOMPARE(m_rewriter.getLocalFile("notthere.qml"), QString());
+ QCOMPARE(m_rewriter.getLocalFile("Test.qml"),
+ QString::fromLatin1(":/qmlprofiler/tests/Test.qml"));
+ QCOMPARE(m_rewriter.getLocalFile("qmlprofilerdetailsrewriter_test.cpp"), QString());
+}
+
+void QmlProfilerDetailsRewriterTest::testPopulateFileFinder()
+{
+ m_rewriter.populateFileFinder(nullptr);
+ QCOMPARE(m_rewriter.getLocalFile("Test.qml"), QString());
+
+ // Test that the rewriter will populate from available projects if given nullptr as parameter.
+ DummyProject *project1 = new DummyProject(Utils::FileName::fromString(":/nix.nix"));
+ ProjectExplorer::SessionManager::addProject(project1);
+ DummyProject *project2 = new DummyProject(
+ Utils::FileName::fromString(":/qmlprofiler/tests/Test.qml"));
+ ProjectExplorer::SessionManager::addProject(project2);
+ m_rewriter.populateFileFinder(nullptr);
+ QCOMPARE(m_rewriter.getLocalFile("Test.qml"),
+ QString::fromLatin1(":/qmlprofiler/tests/Test.qml"));
+
+ ProjectExplorer::SessionManager::removeProject(project1);
+ ProjectExplorer::SessionManager::removeProject(project2);
+}
+
+void QmlProfilerDetailsRewriterTest::seedRewriter()
+{
+ delete m_modelManager;
+ m_modelManager = new QmlJS::ModelManagerInterface(this);
+ QString filename = ":/qmlprofiler/tests/Test.qml";
+
+ QFutureInterface<void> result;
+ QmlJS::PathsAndLanguages lPaths;
+ for (auto p : QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath))
+ lPaths.maybeInsert(Utils::FileName::fromString(p), QmlJS::Dialect::Qml);
+ QmlJS::ModelManagerInterface::importScan(result, QmlJS::ModelManagerInterface::workingCopy(),
+ lPaths, m_modelManager, false);
+
+ QFile file(filename);
+ file.open(QFile::ReadOnly | QFile::Text);
+ const QString content = QString::fromUtf8(file.readAll());
+ file.close();
+
+ QmlJS::Document::MutablePtr doc = QmlJS::Document::create(filename, QmlJS::Dialect::Qml);
+ doc->setSource(content);
+ doc->parse();
+ QVERIFY(!doc->source().isEmpty());
+
+ ProjectExplorer::Kit *kit = new ProjectExplorer::Kit;
+ ProjectExplorer::SysRootKitInformation::setSysRoot(
+ kit, Utils::FileName::fromLatin1("/nowhere"));
+
+ DummyProject *project = new DummyProject(Utils::FileName::fromString(filename));
+ ProjectExplorer::SessionManager::addProject(project);
+ ProjectExplorer::Target *target = project->createTarget(kit);
+
+ ProjectExplorer::CustomExecutableRunConfiguration *rc
+ = new ProjectExplorer::CustomExecutableRunConfiguration(target);
+ m_rewriter.populateFileFinder(rc);
+ ProjectExplorer::SessionManager::removeProject(project);
+ ProjectExplorer::KitManager::deleteKit(kit);
+}
+
+} // namespace Internal
+} // namespace QmlProfiler
+
+#include "qmlprofilerdetailsrewriter_test.moc"
diff --git a/src/plugins/debugger/gdb/attachgdbadapter.h b/src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.h
index cabf4688061..35142952c28 100644
--- a/src/plugins/debugger/gdb/attachgdbadapter.h
+++ b/src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.h
@@ -25,33 +25,31 @@
#pragma once
-#include "gdbengine.h"
+#include <qmljs/qmljsmodelmanagerinterface.h>
+#include <qmlprofiler/qmlprofilerdetailsrewriter.h>
-namespace Debugger {
+namespace QmlProfiler {
namespace Internal {
-///////////////////////////////////////////////////////////////////////
-//
-// AttachGdbAdapter
-//
-///////////////////////////////////////////////////////////////////////
-
-class GdbAttachEngine : public GdbEngine
+class QmlProfilerDetailsRewriterTest : public QObject
{
Q_OBJECT
-
public:
- explicit GdbAttachEngine(bool useTerminal);
+ explicit QmlProfilerDetailsRewriterTest(QObject *parent = nullptr);
+
+private slots:
+ void testMissingModelManager();
+ void testRequestDetailsForLocation();
+ void testGetLocalFile();
+ void testPopulateFileFinder();
private:
- void setupEngine() override;
- void setupInferior() override;
- void runEngine() override;
- void interruptInferior2() override;
- void shutdownEngine() override;
+ QmlJS::ModelManagerInterface *m_modelManager = nullptr;
+ QmlProfilerDetailsRewriter m_rewriter;
+ bool m_rewriterDone = false;
- void handleAttach(const DebuggerResponse &response);
+ void seedRewriter();
};
} // namespace Internal
-} // namespace Debugger
+} // namespace QmlProfiler
diff --git a/src/plugins/qmlprofiler/tests/tests.pri b/src/plugins/qmlprofiler/tests/tests.pri
index feeda0cc407..c4560100433 100644
--- a/src/plugins/qmlprofiler/tests/tests.pri
+++ b/src/plugins/qmlprofiler/tests/tests.pri
@@ -15,6 +15,7 @@ SOURCES += \
$$PWD/qmlprofilerbindingloopsrenderpass_test.cpp \
$$PWD/qmlprofilerclientmanager_test.cpp \
$$PWD/qmlprofilerconfigwidget_test.cpp \
+ $$PWD/qmlprofilerdetailsrewriter_test.cpp \
$$PWD/qmlprofilertraceview_test.cpp
HEADERS += \
@@ -34,4 +35,8 @@ HEADERS += \
$$PWD/qmlprofilerbindingloopsrenderpass_test.h \
$$PWD/qmlprofilerclientmanager_test.h \
$$PWD/qmlprofilerconfigwidget_test.h \
+ $$PWD/qmlprofilerdetailsrewriter_test.h \
$$PWD/qmlprofilertraceview_test.h
+
+RESOURCES += \
+ $$PWD/tests.qrc
diff --git a/src/plugins/qmlprofiler/tests/tests.qrc b/src/plugins/qmlprofiler/tests/tests.qrc
new file mode 100644
index 00000000000..323fb37b144
--- /dev/null
+++ b/src/plugins/qmlprofiler/tests/tests.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/qmlprofiler/tests">
+ <file>Test.qml</file>
+ <file>qmlprofilerdetailsrewriter_test.cpp</file>
+ </qresource>
+</RCC>
diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp
index 49de48f7621..4e2ca8c2591 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ b/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -101,7 +101,7 @@ void QmlProject::addedRunConfiguration(RunConfiguration *rc)
// they have been added to a project
QmlProjectRunConfiguration *qmlrc = qobject_cast<QmlProjectRunConfiguration *>(rc);
if (qmlrc)
- qmlrc->updateEnabled();
+ qmlrc->updateEnabledState();
}
QDir QmlProject::projectDir() const
@@ -170,6 +170,7 @@ void QmlProject::parseProject(RefreshOptions options)
void QmlProject::refresh(RefreshOptions options)
{
+ emitParsingStarted();
parseProject(options);
if (options & Files)
@@ -187,7 +188,7 @@ void QmlProject::refresh(RefreshOptions options)
modelManager->updateProjectInfo(projectInfo, this);
- emit parsingFinished();
+ emitParsingFinished(true);
}
QString QmlProject::mainFile() const
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
index ecf191a02f4..10d804dfa8e 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
@@ -32,8 +32,6 @@
#include <utils/algorithm.h>
-#include <QStyle>
-
using namespace ProjectExplorer;
namespace QmlProjectManager {
@@ -43,13 +41,9 @@ QmlProjectNode::QmlProjectNode(QmlProject *project) : ProjectNode(project->proje
m_project(project)
{
setDisplayName(project->projectFilePath().toFileInfo().completeBaseName());
- // make overlay
- const QSize desiredSize = QSize(16, 16);
- const QIcon projectBaseIcon(QLatin1String(":/qmlproject/images/qmlfolder.png"));
- const QPixmap projectPixmap = Core::FileIconProvider::overlayIcon(QStyle::SP_DirIcon,
- projectBaseIcon,
- desiredSize);
- setIcon(QIcon(projectPixmap));
+
+ static QIcon qmlProjectIcon = Core::FileIconProvider::directoryIcon(QLatin1String(":/qmlproject/images/qmlfolder.png"));
+ setIcon(qmlProjectIcon);
}
bool QmlProjectNode::showInSimpleTree() const
@@ -57,13 +51,15 @@ bool QmlProjectNode::showInSimpleTree() const
return true;
}
-bool QmlProjectNode::supportsAction(ProjectAction action, Node *node) const
+bool QmlProjectNode::supportsAction(ProjectAction action, const Node *node) const
{
if (action == AddNewFile || action == EraseFile)
return true;
+ QTC_ASSERT(node, return false);
if (action == Rename && node->nodeType() == NodeType::File) {
- FileNode *fileNode = static_cast<FileNode *>(node);
+ const FileNode *fileNode = node->asFileNode();
+ QTC_ASSERT(fileNode, return false);
return fileNode->fileType() != FileType::Project;
}
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.h b/src/plugins/qmlprojectmanager/qmlprojectnodes.h
index bc715d86f6d..35ebf428f83 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectnodes.h
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.h
@@ -39,7 +39,7 @@ public:
QmlProjectNode(QmlProject *project);
bool showInSimpleTree() const override;
- bool supportsAction(ProjectExplorer::ProjectAction action, Node *node) const override;
+ bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0) override;
bool deleteFiles(const QStringList &filePaths) override;
bool renameFile(const QString &filePath, const QString &newFilePath) override;
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
index 1c2e77fb04c..f1ee22c7e62 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
@@ -51,14 +51,43 @@ namespace QmlProjectManager {
const char M_CURRENT_FILE[] = "CurrentFile";
-QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *parent, Id id) :
- RunConfiguration(parent, id),
- m_scriptFile(QLatin1String(M_CURRENT_FILE)),
- m_isEnabled(false)
+QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target)
+ : RunConfiguration(target)
{
addExtraAspect(new QmlProjectEnvironmentAspect(this));
- ctor();
+ // reset default settings in constructor
+ connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
+ this, &QmlProjectRunConfiguration::changeCurrentFile);
+ connect(EditorManager::instance(), &EditorManager::currentDocumentStateChanged,
+ this, [this] { changeCurrentFile(); });
+
+ connect(target, &Target::kitChanged,
+ this, &QmlProjectRunConfiguration::updateEnabledState);
+}
+
+void QmlProjectRunConfiguration::initialize(Id id)
+{
+ RunConfiguration::initialize(id);
+ m_scriptFile = M_CURRENT_FILE;
+
+ if (id == Constants::QML_SCENE_RC_ID)
+ setDisplayName(tr("QML Scene", "QMLRunConfiguration display name."));
+ else
+ setDisplayName(tr("QML Viewer", "QMLRunConfiguration display name."));
+
+ updateEnabledState();
+}
+
+void QmlProjectRunConfiguration::copyFrom(const QmlProjectRunConfiguration *source)
+{
+ RunConfiguration::copyFrom(source);
+ m_currentFileFilename = source->m_currentFileFilename;
+ m_mainScriptFilename = source->m_mainScriptFilename;
+ m_scriptFile = source->m_scriptFile;
+ m_qmlViewerArgs = source->m_qmlViewerArgs;
+
+ updateEnabledState();
}
Runnable QmlProjectRunConfiguration::runnable() const
@@ -73,46 +102,13 @@ Runnable QmlProjectRunConfiguration::runnable() const
return r;
}
-QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *parent,
- QmlProjectRunConfiguration *source) :
- RunConfiguration(parent, source),
- m_currentFileFilename(source->m_currentFileFilename),
- m_mainScriptFilename(source->m_mainScriptFilename),
- m_scriptFile(source->m_scriptFile),
- m_qmlViewerArgs(source->m_qmlViewerArgs),
- m_isEnabled(source->m_isEnabled)
-{
- ctor();
-}
-
-bool QmlProjectRunConfiguration::isEnabled() const
-{
- return m_isEnabled;
-}
-
QString QmlProjectRunConfiguration::disabledReason() const
{
- if (!m_isEnabled)
+ if (mainScript().isEmpty())
+ return tr("No script file to execute.");
+ if (!QFileInfo(executable()).exists())
return tr("No qmlviewer or qmlscene found.");
- return QString();
-}
-
-void QmlProjectRunConfiguration::ctor()
-{
- // reset default settings in constructor
- connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
- this, &QmlProjectRunConfiguration::changeCurrentFile);
- connect(EditorManager::instance(), &EditorManager::currentDocumentStateChanged,
- this, [this] { changeCurrentFile(); });
-
- connect(target(), &Target::kitChanged,
- this, &QmlProjectRunConfiguration::updateEnabled);
-
- if (id() == Constants::QML_SCENE_RC_ID)
- setDisplayName(tr("QML Scene", "QMLRunConfiguration display name."));
- else
- setDisplayName(tr("QML Viewer", "QMLRunConfiguration display name."));
- updateEnabled();
+ return RunConfiguration::disabledReason();
}
QString QmlProjectRunConfiguration::executable() const
@@ -215,7 +211,7 @@ void QmlProjectRunConfiguration::setScriptSource(MainScriptSource source,
m_mainScriptFilename
= target()->project()->projectDirectory().toString() + QLatin1Char('/') + m_scriptFile;
}
- updateEnabled();
+ updateEnabledState();
emit scriptSourceChanged();
}
@@ -258,10 +254,10 @@ void QmlProjectRunConfiguration::changeCurrentFile(IEditor *editor)
if (editor)
m_currentFileFilename = editor->document()->filePath().toString();
- updateEnabled();
+ updateEnabledState();
}
-void QmlProjectRunConfiguration::updateEnabled()
+void QmlProjectRunConfiguration::updateEnabledState()
{
bool qmlFileFound = false;
if (mainScriptSource() == FileInEditor) {
@@ -293,11 +289,10 @@ void QmlProjectRunConfiguration::updateEnabled()
qmlFileFound = !mainScript().isEmpty();
}
- bool newValue = QFileInfo::exists(executable()) && qmlFileFound;
- m_isEnabled = newValue;
-
- // Always emit change signal to force reevaluation of run/debug buttons
- emit enabledChanged();
+ if (QFileInfo::exists(executable()) && qmlFileFound)
+ RunConfiguration::updateEnabledState();
+ else
+ setEnabled(false);
}
bool QmlProjectRunConfiguration::isValidVersion(QtSupport::BaseQtVersion *version)
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
index cfab4cfd5f0..0dcdf19a59a 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
@@ -40,20 +40,17 @@ namespace QtSupport { class BaseQtVersion; }
namespace QmlProjectManager {
class QmlProject;
-namespace Internal {
- class QmlProjectRunConfigurationFactory;
- class QmlProjectRunConfigurationWidget;
-}
+namespace Internal { class QmlProjectRunConfigurationWidget; }
class QMLPROJECTMANAGER_EXPORT QmlProjectRunConfiguration : public ProjectExplorer::RunConfiguration
{
Q_OBJECT
- friend class Internal::QmlProjectRunConfigurationFactory;
+ friend class ProjectExplorer::IRunConfigurationFactory;
friend class Internal::QmlProjectRunConfigurationWidget;
friend class QmlProject; // to call updateEnabled()
public:
- QmlProjectRunConfiguration(ProjectExplorer::Target *parent, Core::Id id);
+ explicit QmlProjectRunConfiguration(ProjectExplorer::Target *target);
ProjectExplorer::Runnable runnable() const override;
@@ -70,7 +67,6 @@ public:
QString mainScript() const;
// RunConfiguration
- bool isEnabled() const override;
QString disabledReason() const override;
virtual QWidget *createConfigurationWidget() override;
Utils::OutputFormatter *createOutputFormatter() const override;
@@ -80,17 +76,13 @@ public:
signals:
void scriptSourceChanged();
-protected:
- QmlProjectRunConfiguration(ProjectExplorer::Target *parent,
- QmlProjectRunConfiguration *source);
- virtual bool fromMap(const QVariantMap &map) override;
- void setEnabled(bool value);
-
private:
- void ctor();
+ void initialize(Core::Id id);
+ void copyFrom(const QmlProjectRunConfiguration *source);
+ virtual bool fromMap(const QVariantMap &map) override;
void changeCurrentFile(Core::IEditor* = 0);
- void updateEnabled();
+ void updateEnabledState() final;
QString executable() const;
QString commandLineArguments() const;
@@ -106,8 +98,6 @@ private:
QString m_scriptFile;
QString m_qmlViewerArgs;
-
- bool m_isEnabled;
};
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationfactory.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationfactory.cpp
index 7cf17cb7bbf..98d3c53c549 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationfactory.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationfactory.cpp
@@ -104,7 +104,7 @@ bool QmlProjectRunConfigurationFactory::canCreate(ProjectExplorer::Target *paren
ProjectExplorer::RunConfiguration *QmlProjectRunConfigurationFactory::doCreate(ProjectExplorer::Target *parent, Core::Id id)
{
- return new QmlProjectRunConfiguration(parent, id);
+ return createHelper<QmlProjectRunConfiguration>(parent, id);
}
bool QmlProjectRunConfigurationFactory::canRestore(ProjectExplorer::Target *parent, const QVariantMap &map) const
@@ -115,7 +115,7 @@ bool QmlProjectRunConfigurationFactory::canRestore(ProjectExplorer::Target *pare
ProjectExplorer::RunConfiguration *QmlProjectRunConfigurationFactory::doRestore(ProjectExplorer::Target *parent,
const QVariantMap &map)
{
- return new QmlProjectRunConfiguration(parent, ProjectExplorer::idFromMap(map));
+ return createHelper<QmlProjectRunConfiguration>(parent, ProjectExplorer::idFromMap(map));
}
bool QmlProjectRunConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::RunConfiguration *source) const
@@ -128,7 +128,7 @@ ProjectExplorer::RunConfiguration *QmlProjectRunConfigurationFactory::clone(Proj
{
if (!canClone(parent, source))
return 0;
- return new QmlProjectRunConfiguration(parent, qobject_cast<QmlProjectRunConfiguration *>(source));
+ return cloneHelper<QmlProjectRunConfiguration>(parent, source);
}
bool QmlProjectRunConfigurationFactory::canHandle(ProjectExplorer::Target *parent) const
diff --git a/src/plugins/qnx/qnx.pro b/src/plugins/qnx/qnx.pro
index bcfad2f36e1..30708de7643 100644
--- a/src/plugins/qnx/qnx.pro
+++ b/src/plugins/qnx/qnx.pro
@@ -23,8 +23,6 @@ SOURCES += qnxplugin.cpp \
qnxdeviceprocesslist.cpp \
qnxtoolchain.cpp \
slog2inforunner.cpp \
- qnxattachdebugsupport.cpp \
- qnxattachdebugdialog.cpp \
qnxconfiguration.cpp \
qnxsettingswidget.cpp \
qnxconfigurationmanager.cpp \
@@ -55,8 +53,6 @@ HEADERS += qnxplugin.h\
qnxdeviceprocesslist.h \
qnxtoolchain.h \
slog2inforunner.h \
- qnxattachdebugsupport.h \
- qnxattachdebugdialog.h \
qnxconfiguration.h \
qnxsettingswidget.h \
qnxconfigurationmanager.h \
diff --git a/src/plugins/qnx/qnx.qbs b/src/plugins/qnx/qnx.qbs
index b617fc1b6a9..0ffc887fdf4 100644
--- a/src/plugins/qnx/qnx.qbs
+++ b/src/plugins/qnx/qnx.qbs
@@ -24,10 +24,6 @@ QtcPlugin {
"qnxtoolchain.cpp",
"qnxtoolchain.h",
"qnx.qrc",
- "qnxattachdebugsupport.cpp",
- "qnxattachdebugsupport.h",
- "qnxattachdebugdialog.cpp",
- "qnxattachdebugdialog.h",
"qnxbaseqtconfigwidget.cpp",
"qnxbaseqtconfigwidget.h",
"qnxconstants.h",
diff --git a/src/plugins/qnx/qnxattachdebugdialog.cpp b/src/plugins/qnx/qnxattachdebugdialog.cpp
deleted file mode 100644
index 6c780bad153..00000000000
--- a/src/plugins/qnx/qnxattachdebugdialog.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
-** Contact: info@kdab.com
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "qnxattachdebugdialog.h"
-
-#include <utils/pathchooser.h>
-#include <utils/qtcassert.h>
-
-#include <QFormLayout>
-#include <QLabel>
-#include <QVBoxLayout>
-
-using namespace Qnx;
-using namespace Qnx::Internal;
-
-QnxAttachDebugDialog::QnxAttachDebugDialog(ProjectExplorer::KitChooser *kitChooser, QWidget *parent)
- : ProjectExplorer::DeviceProcessesDialog(kitChooser, parent)
-{
- auto sourceLabel = new QLabel(tr("Project source directory:"), this);
- m_projectSource = new Utils::PathChooser(this);
- m_projectSource->setExpectedKind(Utils::PathChooser::ExistingDirectory);
-
- auto binaryLabel = new QLabel(tr("Local executable:"), this);
- m_localExecutable = new Utils::PathChooser(this);
- m_localExecutable->setExpectedKind(Utils::PathChooser::File);
-
- auto formLayout = new QFormLayout;
- formLayout->addRow(sourceLabel, m_projectSource);
- formLayout->addRow(binaryLabel, m_localExecutable);
-
- auto mainLayout = dynamic_cast<QVBoxLayout*>(layout());
- QTC_ASSERT(mainLayout, return);
- mainLayout->insertLayout(mainLayout->count() - 2, formLayout);
-}
-
-QString QnxAttachDebugDialog::projectSource() const
-{
- return m_projectSource->path();
-}
-
-QString QnxAttachDebugDialog::localExecutable() const
-{
- return m_localExecutable->path();
-}
diff --git a/src/plugins/qnx/qnxattachdebugdialog.h b/src/plugins/qnx/qnxattachdebugdialog.h
deleted file mode 100644
index ef124555ffc..00000000000
--- a/src/plugins/qnx/qnxattachdebugdialog.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
-** Contact: info@kdab.com
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
-
-namespace Utils { class PathChooser; }
-
-namespace Qnx {
-namespace Internal {
-
-class QnxAttachDebugDialog : public ProjectExplorer::DeviceProcessesDialog
-{
- Q_OBJECT
-
-public:
- explicit QnxAttachDebugDialog(ProjectExplorer::KitChooser *kitChooser, QWidget *parent = 0);
-
- QString projectSource() const;
- QString localExecutable() const;
-
-private:
- Utils::PathChooser *m_projectSource;
- Utils::PathChooser *m_localExecutable;
-};
-
-} // namespace Internal
-} // namespace Qnx
diff --git a/src/plugins/qnx/qnxattachdebugsupport.cpp b/src/plugins/qnx/qnxattachdebugsupport.cpp
deleted file mode 100644
index 43714da762c..00000000000
--- a/src/plugins/qnx/qnxattachdebugsupport.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
-** Contact: info@kdab.com
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "qnxattachdebugsupport.h"
-
-#include "qnxattachdebugdialog.h"
-#include "qnxconstants.h"
-#include "qnxqtversion.h"
-#include "qnxutils.h"
-
-#include <debugger/debuggerkitinformation.h>
-#include <debugger/debuggerruncontrol.h>
-#include <debugger/debuggerstartparameters.h>
-#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
-#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
-#include <projectexplorer/devicesupport/deviceprocesslist.h>
-#include <projectexplorer/kit.h>
-#include <projectexplorer/kitchooser.h>
-#include <projectexplorer/kitinformation.h>
-#include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/runnables.h>
-#include <projectexplorer/toolchain.h>
-#include <qtsupport/qtkitinformation.h>
-#include <utils/portlist.h>
-#include <utils/qtcassert.h>
-
-using namespace ProjectExplorer;
-
-namespace Qnx {
-namespace Internal {
-
-QnxAttachDebugSupport::QnxAttachDebugSupport(QObject *parent)
- : QObject(parent)
-{
- m_launcher = new ApplicationLauncher(this);
- m_portsGatherer = new DeviceUsedPortsGatherer(this);
-
- connect(m_portsGatherer, &DeviceUsedPortsGatherer::portListReady,
- this, &QnxAttachDebugSupport::launchPDebug);
- connect(m_portsGatherer, &DeviceUsedPortsGatherer::error,
- this, &QnxAttachDebugSupport::handleError);
- connect(m_launcher, &ApplicationLauncher::remoteProcessStarted,
- this, &QnxAttachDebugSupport::attachToProcess);
- connect(m_launcher, &ApplicationLauncher::reportError,
- this, &QnxAttachDebugSupport::handleError);
- connect(m_launcher, &ApplicationLauncher::reportProgress,
- this, &QnxAttachDebugSupport::handleProgressReport);
- connect(m_launcher, &ApplicationLauncher::remoteStdout,
- this, &QnxAttachDebugSupport::handleRemoteOutput);
- connect(m_launcher, &ApplicationLauncher::remoteStderr,
- this, &QnxAttachDebugSupport::handleRemoteOutput);
-}
-
-void QnxAttachDebugSupport::showProcessesDialog()
-{
- auto kitChooser = new KitChooser;
- kitChooser->setKitPredicate([](const Kit *k){
- return k->isValid() && DeviceTypeKitInformation::deviceTypeId(k) == Core::Id(Constants::QNX_QNX_OS_TYPE);
- });
-
- QnxAttachDebugDialog dlg(kitChooser, 0);
- dlg.addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
- dlg.showAllDevices();
- if (dlg.exec() == QDialog::Rejected)
- return;
-
- m_kit = kitChooser->currentKit();
- if (!m_kit)
- return;
-
- m_device = DeviceKitInformation::device(m_kit);
- QTC_ASSERT(m_device, return);
- m_process = dlg.currentProcess();
-
- m_projectSourceDirectory = dlg.projectSource();
- m_localExecutablePath = dlg.localExecutable();
-
- m_portsGatherer->start(m_device);
-}
-
-void QnxAttachDebugSupport::launchPDebug()
-{
- Utils::PortList portList = m_device->freePorts();
- m_pdebugPort = m_portsGatherer->getNextFreePort(&portList);
- if (!m_pdebugPort.isValid()) {
- handleError(tr("No free ports for debugging."));
- return;
- }
-
- StandardRunnable r;
- r.executable = QLatin1String("pdebug");
- r.commandLineArguments = QString::number(m_pdebugPort.number());
- m_launcher->start(r, m_device);
-}
-
-void QnxAttachDebugSupport::attachToProcess()
-{
- Debugger::DebuggerStartParameters sp;
- sp.attachPID = Utils::ProcessHandle(m_process.pid);
- sp.startMode = Debugger::AttachToRemoteServer;
- sp.closeMode = Debugger::DetachAtClose;
- sp.remoteChannel = QString("%1:%2").arg(m_device->sshParameters().host).arg(m_pdebugPort.number());
- sp.displayName = tr("Remote: \"%1\" - Process %2").arg(sp.remoteChannel).arg(m_process.pid);
- sp.inferior.executable = m_localExecutablePath;
- sp.useCtrlCStub = true;
-
- QnxQtVersion *qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(m_kit));
- if (qtVersion)
- sp.solibSearchPath = QnxUtils::searchPaths(qtVersion);
-
- auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE);
- (void) new Debugger::DebuggerRunTool(runControl, sp);
-// connect(qobject_cast<Debugger::DebuggerRunTool *>(runControl->toolRunner()),
-// &Debugger::DebuggerRunTool::stateChanged,
-// this, &QnxAttachDebugSupport::handleDebuggerStateChanged);
- ProjectExplorerPlugin::startRunControl(runControl);
-}
-
-void QnxAttachDebugSupport::handleDebuggerStateChanged(Debugger::DebuggerState state)
-{
- if (state == Debugger::DebuggerFinished)
- stopPDebug();
-}
-
-void QnxAttachDebugSupport::handleError(const QString &message)
-{
- if (m_runTool)
- m_runTool->showMessage(message, Debugger::AppError);
-}
-
-void QnxAttachDebugSupport::handleProgressReport(const QString &message)
-{
- if (m_runTool)
- m_runTool->showMessage(message + QLatin1Char('\n'), Debugger::AppStuff);
-}
-
-void QnxAttachDebugSupport::handleRemoteOutput(const QString &output)
-{
- if (m_runTool)
- m_runTool->showMessage(output, Debugger::AppOutput);
-}
-
-void QnxAttachDebugSupport::stopPDebug()
-{
- m_launcher->stop();
-}
-
-} // namespace Internal
-} // namespace Qnx
diff --git a/src/plugins/qnx/qnxattachdebugsupport.h b/src/plugins/qnx/qnxattachdebugsupport.h
deleted file mode 100644
index 1bb00a42f46..00000000000
--- a/src/plugins/qnx/qnxattachdebugsupport.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
-** Contact: info@kdab.com
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <debugger/debuggerconstants.h>
-#include <projectexplorer/devicesupport/deviceprocesslist.h>
-#include <projectexplorer/devicesupport/idevice.h>
-#include <utils/port.h>
-
-#include <QObject>
-
-namespace Debugger { class DebuggerRunTool; }
-
-namespace ProjectExplorer {
-class ApplicationLauncher;
-class DeviceUsedPortsGatherer;
-class Kit;
-}
-
-namespace Qnx {
-namespace Internal {
-
-class QnxAttachDebugSupport : public QObject
-{
- Q_OBJECT
-public:
- explicit QnxAttachDebugSupport(QObject *parent = 0);
-
-public slots:
- void showProcessesDialog();
-
-private slots:
- void launchPDebug();
- void attachToProcess();
-
- void handleDebuggerStateChanged(Debugger::DebuggerState state);
- void handleError(const QString &message);
- void handleProgressReport(const QString &message);
- void handleRemoteOutput(const QString &output);
-
-private:
- void stopPDebug();
-
- ProjectExplorer::Kit *m_kit = 0;
- ProjectExplorer::IDevice::ConstPtr m_device;
- ProjectExplorer::DeviceProcessItem m_process;
-
- ProjectExplorer::ApplicationLauncher *m_launcher;
- ProjectExplorer::DeviceUsedPortsGatherer *m_portsGatherer;
- Debugger::DebuggerRunTool *m_runTool = 0;
-
- Utils::Port m_pdebugPort;
- QString m_projectSourceDirectory;
- QString m_localExecutablePath;
-};
-
-} // namespace Internal
-} // namespace Qnx
diff --git a/src/plugins/qnx/qnxconstants.h b/src/plugins/qnx/qnxconstants.h
index 13656eccf7b..979aa1e94e8 100644
--- a/src/plugins/qnx/qnxconstants.h
+++ b/src/plugins/qnx/qnxconstants.h
@@ -28,7 +28,6 @@
#include <QtGlobal>
namespace Qnx {
-
namespace Constants {
const char QNX_TARGET_KEY[] = "QNX_TARGET";
diff --git a/src/plugins/qnx/qnxdebugsupport.cpp b/src/plugins/qnx/qnxdebugsupport.cpp
index 0f3d527a15d..cb506420b75 100644
--- a/src/plugins/qnx/qnxdebugsupport.cpp
+++ b/src/plugins/qnx/qnxdebugsupport.cpp
@@ -24,6 +24,7 @@
****************************************************************************/
#include "qnxdebugsupport.h"
+
#include "qnxconstants.h"
#include "qnxdevice.h"
#include "qnxrunconfiguration.h"
@@ -31,26 +32,64 @@
#include "qnxqtversion.h"
#include "qnxutils.h"
+#include <coreplugin/icore.h>
+
+#include <debugger/debuggerkitinformation.h>
#include <debugger/debuggerruncontrol.h>
#include <projectexplorer/applicationlauncher.h>
+#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
+#include <projectexplorer/devicesupport/deviceprocesslist.h>
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
+#include <projectexplorer/kit.h>
+#include <projectexplorer/kitchooser.h>
#include <projectexplorer/kitinformation.h>
+#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/target.h>
+#include <projectexplorer/toolchain.h>
#include <qmldebug/qmldebugcommandlinearguments.h>
+
#include <qtsupport/qtkitinformation.h>
+#include <utils/pathchooser.h>
+#include <utils/portlist.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
+#include <QFormLayout>
+#include <QLabel>
+#include <QVBoxLayout>
+
using namespace Debugger;
using namespace ProjectExplorer;
+using namespace Utils;
namespace Qnx {
namespace Internal {
+static QStringList searchPaths(Kit *kit)
+{
+ auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(kit));
+ if (!qtVersion)
+ return {};
+
+ const QDir pluginDir(qtVersion->qmakeProperty("QT_INSTALL_PLUGINS"));
+ const QStringList pluginSubDirs = pluginDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+
+ QStringList searchPaths;
+
+ for (const QString &dir : pluginSubDirs)
+ searchPaths << qtVersion->qmakeProperty("QT_INSTALL_PLUGINS") + '/' + dir;
+
+ searchPaths << qtVersion->qmakeProperty("QT_INSTALL_LIBS");
+ searchPaths << qtVersion->qnxTarget() + '/' + qtVersion->cpuDir() + "/lib";
+ searchPaths << qtVersion->qnxTarget() + '/' + qtVersion->cpuDir() + "/usr/lib";
+
+ return searchPaths;
+}
+
// QnxDebuggeeRunner
class QnxDebuggeeRunner : public ProjectExplorer::SimpleTargetRunner
@@ -63,12 +102,12 @@ public:
}
private:
- void start() override
+ void start() final
{
StandardRunnable r = runnable().as<StandardRunnable>();
QStringList arguments;
if (m_portsGatherer->useGdbServer()) {
- Utils::Port pdebugPort = m_portsGatherer->gdbServerPort();
+ Port pdebugPort = m_portsGatherer->gdbServerPort();
r.executable = Constants::QNX_DEBUG_EXECUTABLE;
arguments.append(pdebugPort.toString());
}
@@ -76,8 +115,8 @@ private:
arguments.append(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
m_portsGatherer->qmlServerPort()));
}
- arguments.append(Utils::QtcProcess::splitArgs(r.commandLineArguments));
- r.commandLineArguments = Utils::QtcProcess::joinArgs(arguments);
+ arguments.append(QtcProcess::splitArgs(r.commandLineArguments));
+ r.commandLineArguments = QtcProcess::joinArgs(arguments);
setRunnable(r);
@@ -94,7 +133,7 @@ QnxDebugSupport::QnxDebugSupport(RunControl *runControl)
: DebuggerRunTool(runControl)
{
setDisplayName("QnxDebugSupport");
- appendMessage(tr("Preparing remote side..."), Utils::LogMessageFormat);
+ appendMessage(tr("Preparing remote side..."), LogMessageFormat);
m_portsGatherer = new GdbServerPortsGatherer(runControl);
m_portsGatherer->setUseGdbServer(isCppDebugging());
@@ -111,36 +150,156 @@ QnxDebugSupport::QnxDebugSupport(RunControl *runControl)
void QnxDebugSupport::start()
{
- Utils::Port pdebugPort = m_portsGatherer->gdbServerPort();
-
auto runConfig = qobject_cast<QnxRunConfiguration *>(runControl()->runConfiguration());
QTC_ASSERT(runConfig, return);
Target *target = runConfig->target();
Kit *k = target->kit();
- DebuggerStartParameters params;
- params.startMode = AttachToRemoteServer;
- params.useCtrlCStub = true;
- params.inferior.executable = runConfig->remoteExecutableFilePath();
- params.symbolFile = runConfig->localExecutableFilePath();
- params.remoteChannel = QString("%1:%2").arg(device()->sshParameters().host).arg(pdebugPort.number());
- params.closeMode = KillAtClose;
- params.inferior.commandLineArguments = runConfig->arguments();
-
- if (isQmlDebugging()) {
- params.qmlServer.host = device()->sshParameters().host;
- params.qmlServer.port = m_portsGatherer->qmlServerPort();
- params.inferior.commandLineArguments.replace("%qml_port%", params.qmlServer.port.toString());
+ setStartMode(AttachToRemoteServer);
+ setCloseMode(KillAtClose);
+ setUseCtrlCStub(true);
+ setRemoteChannel(m_portsGatherer->gdbServerChannel());
+ setQmlServer(m_portsGatherer->qmlServer());
+ setSolibSearchPath(searchPaths(k));
+ setSymbolFile(runConfig->localExecutableFilePath());
+
+ DebuggerRunTool::start();
+}
+
+
+// QnxAttachDebugDialog
+
+class QnxAttachDebugDialog : public DeviceProcessesDialog
+{
+public:
+ QnxAttachDebugDialog(KitChooser *kitChooser)
+ : DeviceProcessesDialog(kitChooser, Core::ICore::dialogParent())
+ {
+ auto sourceLabel = new QLabel(QnxDebugSupport::tr("Project source directory:"), this);
+ m_projectSource = new PathChooser(this);
+ m_projectSource->setExpectedKind(PathChooser::ExistingDirectory);
+
+ auto binaryLabel = new QLabel(QnxDebugSupport::tr("Local executable:"), this);
+ m_localExecutable = new PathChooser(this);
+ m_localExecutable->setExpectedKind(PathChooser::File);
+
+ auto formLayout = new QFormLayout;
+ formLayout->addRow(sourceLabel, m_projectSource);
+ formLayout->addRow(binaryLabel, m_localExecutable);
+
+ auto mainLayout = dynamic_cast<QVBoxLayout*>(layout());
+ QTC_ASSERT(mainLayout, return);
+ mainLayout->insertLayout(mainLayout->count() - 2, formLayout);
}
- auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(k));
- if (qtVersion)
- params.solibSearchPath = QnxUtils::searchPaths(qtVersion);
+ QString projectSource() const { return m_projectSource->path(); }
+ QString localExecutable() const { return m_localExecutable->path(); }
+
+private:
+ PathChooser *m_projectSource;
+ PathChooser *m_localExecutable;
+};
- setStartParameters(params);
+
+// QnxAttachDebugSupport
+
+class PDebugRunner : public ProjectExplorer::SimpleTargetRunner
+{
+public:
+ PDebugRunner(RunControl *runControl, GdbServerPortsGatherer *portsGatherer)
+ : SimpleTargetRunner(runControl), m_portsGatherer(portsGatherer)
+ {
+ setDisplayName("PDebugRunner");
+ }
+
+private:
+ void start() final
+ {
+ Port pdebugPort = m_portsGatherer->gdbServerPort();
+
+ StandardRunnable r;
+ r.executable = Constants::QNX_DEBUG_EXECUTABLE;
+ r.commandLineArguments = pdebugPort.toString();
+ setRunnable(r);
+
+ SimpleTargetRunner::start();
+ }
+
+ GdbServerPortsGatherer *m_portsGatherer;
+};
+
+QnxAttachDebugSupport::QnxAttachDebugSupport(RunControl *runControl)
+ : DebuggerRunTool(runControl)
+{
+ setDisplayName("QnxAttachDebugSupport");
+
+ m_portsGatherer = new GdbServerPortsGatherer(runControl);
+ m_portsGatherer->setUseGdbServer(isCppDebugging());
+ m_portsGatherer->setUseQmlServer(isQmlDebugging());
+
+ if (isCppDebugging()) {
+ m_pdebugRunner = new PDebugRunner(runControl, m_portsGatherer);
+ m_pdebugRunner->addStartDependency(m_portsGatherer);
+ addStartDependency(m_pdebugRunner);
+ } else {
+ // No pdebug needed for Qml-only debugging.
+ addStartDependency(m_portsGatherer);
+ }
+}
+
+void QnxAttachDebugSupport::start()
+{
+ setRemoteChannel(m_portsGatherer->gdbServerChannel());
+ setQmlServer(m_portsGatherer->qmlServer());
DebuggerRunTool::start();
}
+void QnxAttachDebugSupport::showProcessesDialog()
+{
+ auto kitChooser = new KitChooser;
+ kitChooser->setKitPredicate([](const Kit *k) {
+ return k->isValid() && DeviceTypeKitInformation::deviceTypeId(k) == Constants::QNX_QNX_OS_TYPE;
+ });
+
+ QnxAttachDebugDialog dlg(kitChooser);
+ dlg.addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
+ dlg.showAllDevices();
+ if (dlg.exec() == QDialog::Rejected)
+ return;
+
+ Kit *kit = kitChooser->currentKit();
+ if (!kit)
+ return;
+
+ // FIXME: That should be somehow related to the selected kit.
+ auto startRunConfig = RunConfiguration::startupRunConfiguration();
+ auto runConfig = qobject_cast<QnxRunConfiguration *>(startRunConfig);
+ if (!runConfig)
+ return;
+
+ DeviceProcessItem process = dlg.currentProcess();
+ const int pid = process.pid;
+// QString projectSourceDirectory = dlg.projectSource();
+ QString localExecutable = dlg.localExecutable();
+ if (localExecutable.isEmpty())
+ localExecutable = runConfig->localExecutableFilePath();
+
+ auto runControl = new RunControl(runConfig, ProjectExplorer::Constants::DEBUG_RUN_MODE);
+ auto debugger = new QnxAttachDebugSupport(runControl);
+ debugger->setStartMode(AttachToRemoteServer);
+ debugger->setCloseMode(DetachAtClose);
+ debugger->setNeedFixup(false);
+ debugger->setSymbolFile(localExecutable);
+ debugger->setUseCtrlCStub(true);
+ debugger->setAttachPid(pid);
+// setRunControlName(tr("Remote: \"%1\" - Process %2").arg(remoteChannel).arg(m_process.pid));
+ debugger->setRunControlName(tr("Remote QNX process %1").arg(pid));
+ debugger->setSolibSearchPath(searchPaths(kit));
+ debugger->setUseContinueInsteadOfRun(true);
+
+ ProjectExplorerPlugin::startRunControl(runControl);
+}
+
} // namespace Internal
} // namespace Qnx
diff --git a/src/plugins/qnx/qnxdebugsupport.h b/src/plugins/qnx/qnxdebugsupport.h
index 4bc75283c44..bfce06231f3 100644
--- a/src/plugins/qnx/qnxdebugsupport.h
+++ b/src/plugins/qnx/qnxdebugsupport.h
@@ -43,5 +43,21 @@ private:
Debugger::GdbServerPortsGatherer *m_portsGatherer;
};
+class QnxAttachDebugSupport : public Debugger::DebuggerRunTool
+{
+ Q_OBJECT
+
+public:
+ explicit QnxAttachDebugSupport(ProjectExplorer::RunControl *runControl);
+
+ static void showProcessesDialog();
+
+private:
+ void start() final;
+
+ Debugger::GdbServerPortsGatherer *m_portsGatherer;
+ ProjectExplorer::SimpleTargetRunner *m_pdebugRunner;
+};
+
} // namespace Internal
} // namespace Qnx
diff --git a/src/plugins/qnx/qnxplugin.cpp b/src/plugins/qnx/qnxplugin.cpp
index a1f1cffc9c1..07306e81e30 100644
--- a/src/plugins/qnx/qnxplugin.cpp
+++ b/src/plugins/qnx/qnxplugin.cpp
@@ -26,7 +26,6 @@
#include "qnxplugin.h"
#include "qnxanalyzesupport.h"
-#include "qnxattachdebugsupport.h"
#include "qnxconfigurationmanager.h"
#include "qnxconstants.h"
#include "qnxdebugsupport.h"
@@ -108,12 +107,10 @@ bool QnxPlugin::initialize(const QStringList &arguments, QString *errorString)
void QnxPlugin::extensionsInitialized()
{
- // Debug support
- QnxAttachDebugSupport *debugSupport = new QnxAttachDebugSupport(this);
-
+ // Attach support
m_attachToQnxApplication = new QAction(this);
m_attachToQnxApplication->setText(tr("Attach to remote QNX application..."));
- connect(m_attachToQnxApplication, &QAction::triggered, debugSupport, &QnxAttachDebugSupport::showProcessesDialog);
+ connect(m_attachToQnxApplication, &QAction::triggered, this, [] { QnxAttachDebugSupport::showProcessesDialog(); });
Core::ActionContainer *mstart = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_DEBUG_STARTDEBUGGING);
mstart->appendGroup(Constants::QNX_DEBUGGING_GROUP);
@@ -142,8 +139,8 @@ void QnxPlugin::updateDebuggerActions()
}
}
- m_attachToQnxApplication->setVisible(false && hasValidQnxKit); // FIXME
- m_debugSeparator->setVisible(false && hasValidQnxKit); // FIXME QTCREATORBUG-16608
+ m_attachToQnxApplication->setVisible(hasValidQnxKit);
+ m_debugSeparator->setVisible(hasValidQnxKit);
}
} // Internal
diff --git a/src/plugins/qnx/qnxrunconfiguration.cpp b/src/plugins/qnx/qnxrunconfiguration.cpp
index 2ccedf4df8a..c7b4b80559b 100644
--- a/src/plugins/qnx/qnxrunconfiguration.cpp
+++ b/src/plugins/qnx/qnxrunconfiguration.cpp
@@ -41,14 +41,19 @@ namespace Internal {
const char QtLibPathKey[] = "Qt4ProjectManager.QnxRunConfiguration.QtLibPath";
-QnxRunConfiguration::QnxRunConfiguration(Target *parent, Core::Id id, const QString &targetName)
- : RemoteLinuxRunConfiguration(parent, id, targetName)
+QnxRunConfiguration::QnxRunConfiguration(Target *target)
+ : RemoteLinuxRunConfiguration(target)
+{}
+
+void QnxRunConfiguration::initialize(Core::Id id, const QString &targetName)
{
+ RemoteLinuxRunConfiguration::initialize(id, targetName);
}
-QnxRunConfiguration::QnxRunConfiguration(Target *parent, QnxRunConfiguration *source)
- : RemoteLinuxRunConfiguration(parent, source), m_qtLibPath(source->m_qtLibPath)
+void QnxRunConfiguration::copyFrom(const QnxRunConfiguration *source)
{
+ RemoteLinuxRunConfiguration::copyFrom(source);
+ m_qtLibPath = source->m_qtLibPath;
}
Runnable QnxRunConfiguration::runnable() const
diff --git a/src/plugins/qnx/qnxrunconfiguration.h b/src/plugins/qnx/qnxrunconfiguration.h
index f897aefa2a6..7ce0ec9114a 100644
--- a/src/plugins/qnx/qnxrunconfiguration.h
+++ b/src/plugins/qnx/qnxrunconfiguration.h
@@ -35,8 +35,7 @@ class QnxRunConfiguration : public RemoteLinux::RemoteLinuxRunConfiguration
Q_OBJECT
public:
- QnxRunConfiguration(ProjectExplorer::Target *parent, Core::Id id,
- const QString &targetName);
+ explicit QnxRunConfiguration(ProjectExplorer::Target *target);
ProjectExplorer::Runnable runnable() const override;
@@ -44,9 +43,11 @@ public:
QVariantMap toMap() const override;
private:
- friend class QnxRunConfigurationFactory;
+ friend class ProjectExplorer::IRunConfigurationFactory;
+
+ void copyFrom(const QnxRunConfiguration *source);
+ void initialize(Core::Id id, const QString &targetName);
- QnxRunConfiguration(ProjectExplorer::Target *parent, QnxRunConfiguration *source);
bool fromMap(const QVariantMap &map) override;
QString m_qtLibPath;
diff --git a/src/plugins/qnx/qnxrunconfigurationfactory.cpp b/src/plugins/qnx/qnxrunconfigurationfactory.cpp
index 6cfab76b2dd..af474f3a294 100644
--- a/src/plugins/qnx/qnxrunconfigurationfactory.cpp
+++ b/src/plugins/qnx/qnxrunconfigurationfactory.cpp
@@ -91,7 +91,7 @@ ProjectExplorer::RunConfiguration *QnxRunConfigurationFactory::doCreate(ProjectE
QTC_ASSERT(project, return nullptr);
for (const QmakeProjectManager::QmakeProFile *file : project->applicationProFiles()) {
if (file->filePath() == projectFilePath)
- return new QnxRunConfiguration(parent, id, file->targetInformation().target);
+ return createHelper<QnxRunConfiguration>(parent, id, file->targetInformation().target);
}
QTC_CHECK(false);
return nullptr;
@@ -107,7 +107,7 @@ ProjectExplorer::RunConfiguration *QnxRunConfigurationFactory::doRestore(Project
const QVariantMap &map)
{
Q_UNUSED(map);
- return new QnxRunConfiguration(parent, Core::Id(Constants::QNX_QNX_RUNCONFIGURATION_PREFIX), QString());
+ return createHelper<QnxRunConfiguration>(parent, Constants::QNX_QNX_RUNCONFIGURATION_PREFIX, QString());
}
bool QnxRunConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::RunConfiguration *source) const
@@ -120,8 +120,7 @@ ProjectExplorer::RunConfiguration *QnxRunConfigurationFactory::clone(ProjectExpl
if (!canClone(parent, source))
return 0;
- QnxRunConfiguration *old = static_cast<QnxRunConfiguration *>(source);
- return new QnxRunConfiguration(parent, old);
+ return cloneHelper<QnxRunConfiguration>(parent, source);
}
bool QnxRunConfigurationFactory::canHandle(ProjectExplorer::Target *t) const
diff --git a/src/plugins/qnx/qnxutils.cpp b/src/plugins/qnx/qnxutils.cpp
index 2206e67a92a..37351cd92dd 100644
--- a/src/plugins/qnx/qnxutils.cpp
+++ b/src/plugins/qnx/qnxutils.cpp
@@ -73,27 +73,6 @@ QString QnxUtils::cpuDirShortDescription(const QString &cpuDir)
return cpuDir;
}
-QStringList QnxUtils::searchPaths(QnxQtVersion *qtVersion)
-{
- const QDir pluginDir(qtVersion->qmakeProperty("QT_INSTALL_PLUGINS"));
- const QStringList pluginSubDirs = pluginDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
-
- QStringList searchPaths;
-
- Q_FOREACH (const QString &dir, pluginSubDirs) {
- searchPaths << qtVersion->qmakeProperty("QT_INSTALL_PLUGINS")
- + QLatin1Char('/') + dir;
- }
-
- searchPaths << qtVersion->qmakeProperty("QT_INSTALL_LIBS");
- searchPaths << qtVersion->qnxTarget() + QLatin1Char('/') + qtVersion->cpuDir()
- + QLatin1String("/lib");
- searchPaths << qtVersion->qnxTarget() + QLatin1Char('/') + qtVersion->cpuDir()
- + QLatin1String("/usr/lib");
-
- return searchPaths;
-}
-
QList<Utils::EnvironmentItem> QnxUtils::qnxEnvironmentFromEnvFile(const QString &fileName)
{
QList <Utils::EnvironmentItem> items;
diff --git a/src/plugins/qnx/qnxutils.h b/src/plugins/qnx/qnxutils.h
index af0ed5823fc..505a1a5bff8 100644
--- a/src/plugins/qnx/qnxutils.h
+++ b/src/plugins/qnx/qnxutils.h
@@ -70,7 +70,6 @@ class QnxUtils
public:
static QString addQuotes(const QString &string);
static QString cpuDirShortDescription(const QString &cpuDir);
- static QStringList searchPaths(Qnx::Internal::QnxQtVersion *qtVersion);
static QList<Utils::EnvironmentItem> qnxEnvironmentFromEnvFile(const QString &fileName);
static QString envFilePath(const QString &sdpPath);
static QString defaultTargetVersion(const QString &sdpPath);
diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
index c5ca314c05a..a5f40194753 100644
--- a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
+++ b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
@@ -124,7 +124,7 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI
chooser->setHistoryCompleter(QLatin1String("Qt.WritableExamplesDir.History"));
QSettings *settings = ICore::settings();
chooser->setPath(settings->value(QString::fromLatin1(C_FALLBACK_ROOT),
- DocumentManager::projectsDirectory()).toString());
+ DocumentManager::projectsDirectory().toString()).toString());
lay->addWidget(txt, 1, 0);
lay->addWidget(chooser, 1, 1);
enum { Copy = QDialog::Accepted + 1, Keep = QDialog::Accepted + 2 };
diff --git a/src/plugins/qtsupport/qtkitinformation.cpp b/src/plugins/qtsupport/qtkitinformation.cpp
index 93997c901e9..972df564a87 100644
--- a/src/plugins/qtsupport/qtkitinformation.cpp
+++ b/src/plugins/qtsupport/qtkitinformation.cpp
@@ -126,18 +126,18 @@ ProjectExplorer::IOutputParser *QtKitInformation::createOutputParser(const Proje
void QtKitInformation::addToMacroExpander(Kit *kit, MacroExpander *expander) const
{
expander->registerSubProvider(
- [this, kit]() -> MacroExpander * {
+ [kit]() -> MacroExpander * {
BaseQtVersion *version = qtVersion(kit);
return version ? version->macroExpander() : 0;
});
expander->registerVariable("Qt:Name", tr("Name of Qt Version"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
BaseQtVersion *version = qtVersion(kit);
return version ? version->displayName() : tr("unknown");
});
expander->registerVariable("Qt:qmakeExecutable", tr("Path to the qmake executable"),
- [this, kit]() -> QString {
+ [kit]() -> QString {
BaseQtVersion *version = qtVersion(kit);
return version ? version->qmakeCommand().toString() : QString();
});
diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp
index 23e10b9a17a..bdd358c1991 100644
--- a/src/plugins/qtsupport/qtoptionspage.cpp
+++ b/src/plugins/qtsupport/qtoptionspage.cpp
@@ -337,7 +337,7 @@ void QtOptionsPageWidget::toolChainsUpdated()
void QtOptionsPageWidget::qtVersionsDumpUpdated(const FileName &qmakeCommand)
{
- m_model->forItemsAtLevel<2>([this, qmakeCommand](QtVersionItem *item) {
+ m_model->forItemsAtLevel<2>([qmakeCommand](QtVersionItem *item) {
if (item->version()->qmakeCommand() == qmakeCommand)
item->version()->recheckDumper();
});
@@ -769,7 +769,7 @@ void QtOptionsPageWidget::apply()
QList<BaseQtVersion *> versions;
- m_model->forItemsAtLevel<2>([this, &versions](QtVersionItem *item) {
+ m_model->forItemsAtLevel<2>([&versions](QtVersionItem *item) {
item->setChanged(false);
versions.append(item->version()->clone());
});
diff --git a/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp b/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp
deleted file mode 100644
index 48aac088138..00000000000
--- a/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "abstractremotelinuxrunsupport.h"
-
-#include <projectexplorer/kitinformation.h>
-#include <projectexplorer/runnables.h>
-#include <projectexplorer/target.h>
-
-#include <utils/environment.h>
-#include <utils/portlist.h>
-#include <utils/qtcprocess.h>
-
-#include <qmldebug/qmldebugcommandlinearguments.h>
-
-using namespace ProjectExplorer;
-using namespace Utils;
-
-namespace RemoteLinux {
-
-// FifoGatherer
-
-FifoGatherer::FifoGatherer(RunControl *runControl)
- : RunWorker(runControl)
-{
- setDisplayName("FifoGatherer");
-}
-
-FifoGatherer::~FifoGatherer()
-{
-}
-
-void FifoGatherer::start()
-{
- appendMessage(tr("Creating remote socket...") + '\n', NormalMessageFormat);
-
- StandardRunnable r;
- r.executable = QLatin1String("/bin/sh");
- r.commandLineArguments = "-c 'd=`mktemp -d` && mkfifo $d/fifo && echo -n $d/fifo'";
- r.workingDirectory = QLatin1String("/tmp");
- r.runMode = ApplicationLauncher::Console;
-
- QSharedPointer<QString> output(new QString);
- QSharedPointer<QString> errors(new QString);
-
- connect(&m_fifoCreator, &ApplicationLauncher::finished,
- this, [this, output, errors](bool success) {
- if (!success) {
- reportFailure(QString("Failed to create fifo: %1").arg(*errors));
- } else {
- m_fifo = *output;
- appendMessage(tr("Created fifo: %1").arg(m_fifo), NormalMessageFormat);
- reportStarted();
- }
- });
-
- connect(&m_fifoCreator, &ApplicationLauncher::remoteStdout,
- this, [output](const QString &data) {
- output->append(data);
- });
-
- connect(&m_fifoCreator, &ApplicationLauncher::remoteStderr,
- this, [this, errors](const QString &) {
- reportFailure();
-// errors->append(data);
- });
-
- m_fifoCreator.start(r, device());
-}
-
-void FifoGatherer::stop()
-{
- m_fifoCreator.stop();
- reportStopped();
-}
-
-} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/abstractremotelinuxrunsupport.h b/src/plugins/remotelinux/abstractremotelinuxrunsupport.h
deleted file mode 100644
index 4f6589ab1f2..00000000000
--- a/src/plugins/remotelinux/abstractremotelinuxrunsupport.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "remotelinux_export.h"
-
-#include <projectexplorer/runconfiguration.h>
-
-namespace RemoteLinux {
-
-class REMOTELINUX_EXPORT FifoGatherer : public ProjectExplorer::RunWorker
-{
- Q_OBJECT
-
-public:
- explicit FifoGatherer(ProjectExplorer::RunControl *runControl);
- ~FifoGatherer();
-
- QString fifo() const { return m_fifo; }
-
-private:
- void start() override;
- void stop() override;
-
- void createRemoteFifo();
-
- ProjectExplorer::ApplicationLauncher m_fifoCreator;
- QString m_fifo;
-};
-
-} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinux.pro b/src/plugins/remotelinux/remotelinux.pro
index 5167f61acee..b667c040abb 100644
--- a/src/plugins/remotelinux/remotelinux.pro
+++ b/src/plugins/remotelinux/remotelinux.pro
@@ -43,7 +43,6 @@ HEADERS += \
remotelinuxcheckforfreediskspaceservice.h \
remotelinuxcheckforfreediskspacestep.h \
remotelinuxanalyzesupport.h \
- abstractremotelinuxrunsupport.h \
linuxdeviceprocess.h \
remotelinuxcustomrunconfiguration.h \
remotelinuxsignaloperation.h \
@@ -88,7 +87,6 @@ SOURCES += \
remotelinuxcheckforfreediskspaceservice.cpp \
remotelinuxcheckforfreediskspacestep.cpp \
remotelinuxanalyzesupport.cpp \
- abstractremotelinuxrunsupport.cpp \
linuxdeviceprocess.cpp \
remotelinuxcustomrunconfiguration.cpp \
remotelinuxsignaloperation.cpp \
diff --git a/src/plugins/remotelinux/remotelinux.qbs b/src/plugins/remotelinux/remotelinux.qbs
index 3855efc24bb..5ad7f7abe44 100644
--- a/src/plugins/remotelinux/remotelinux.qbs
+++ b/src/plugins/remotelinux/remotelinux.qbs
@@ -23,8 +23,6 @@ Project {
"abstractremotelinuxdeployservice.h",
"abstractremotelinuxdeploystep.cpp",
"abstractremotelinuxdeploystep.h",
- "abstractremotelinuxrunsupport.cpp",
- "abstractremotelinuxrunsupport.h",
"abstractuploadandinstallpackageservice.cpp",
"abstractuploadandinstallpackageservice.h",
"deploymenttimeinfo.cpp",
diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
index de1a9efde1c..aaf384cf679 100644
--- a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
+++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
@@ -25,30 +25,17 @@
#include "remotelinuxanalyzesupport.h"
-#include "remotelinuxrunconfiguration.h"
-
-#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/project.h>
-#include <projectexplorer/target.h>
-#include <projectexplorer/toolchain.h>
-#include <projectexplorer/kitinformation.h>
#include <projectexplorer/runnables.h>
-#include <utils/qtcassert.h>
-#include <utils/qtcprocess.h>
-
#include <ssh/sshconnection.h>
-#include <qmldebug/qmloutputparser.h>
#include <qmldebug/qmldebugcommandlinearguments.h>
-#include <QPointer>
-
-using namespace QSsh;
using namespace ProjectExplorer;
using namespace Utils;
namespace RemoteLinux {
+namespace Internal {
// RemoteLinuxQmlProfilerSupport
@@ -89,62 +76,5 @@ void RemoteLinuxQmlProfilerSupport::start()
SimpleTargetRunner::start();
}
-
-// RemoteLinuxPerfSupport
-
-RemoteLinuxPerfSupport::RemoteLinuxPerfSupport(RunControl *runControl)
- : RunWorker(runControl)
-{
- setDisplayName("RemoteLinuxPerfSupport");
-
- RunConfiguration *runConfiguration = runControl->runConfiguration();
- QTC_ASSERT(runConfiguration, return);
- IRunConfigurationAspect *perfAspect =
- runConfiguration->extraAspect("Analyzer.Perf.Settings");
- QTC_ASSERT(perfAspect, return);
- m_perfRecordArguments =
- perfAspect->currentSettings()->property("perfRecordArguments").toStringList()
- .join(' ');
-
- auto toolRunner = runControl->createWorker(runControl->runMode());
- toolRunner->addStartDependency(this);
-// connect(&m_outputGatherer, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
-// this, &RemoteLinuxPerfSupport::remoteIsRunning);
-
-// addDependency(FifoCreatorWorkerId);
-}
-
-void RemoteLinuxPerfSupport::start()
-{
-// m_remoteFifo = targetRunner()->fifo();
- if (m_remoteFifo.isEmpty()) {
- reportFailure(tr("FIFO for profiling data could not be created."));
- return;
- }
-
-// ApplicationLauncher *runner = targetRunner()->applicationLauncher();
-
- auto r = runnable().as<StandardRunnable>();
-
- r.commandLineArguments = "-c 'perf record -o - " + m_perfRecordArguments
- + " -- " + r.executable + " "
- + r.commandLineArguments + " > " + m_remoteFifo
- + "'";
- r.executable = "sh";
-
- connect(&m_outputGatherer, SIGNAL(remoteStdout(QByteArray)),
- runControl(), SIGNAL(analyzePerfOutput(QByteArray)));
- connect(&m_outputGatherer, SIGNAL(finished(bool)),
- runControl(), SIGNAL(perfFinished()));
-
- StandardRunnable outputRunner;
- outputRunner.executable = "sh";
- outputRunner.commandLineArguments = QString("-c 'cat %1 && rm -r `dirname %1`'").arg(m_remoteFifo);
- m_outputGatherer.start(outputRunner, device());
-// remoteIsRunning();
-// runControl()->notifyRemoteSetupDone(d->qmlPort);
-
-// runner->start(r, device());
-}
-
+} // namespace Internal
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.h b/src/plugins/remotelinux/remotelinuxanalyzesupport.h
index 66847533337..6b444fc97c3 100644
--- a/src/plugins/remotelinux/remotelinuxanalyzesupport.h
+++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.h
@@ -25,48 +25,23 @@
#pragma once
-#include "abstractremotelinuxrunsupport.h"
-
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
#include <projectexplorer/runconfiguration.h>
-#include <utils/outputformat.h>
-
-#include <qmldebug/qmloutputparser.h>
-
namespace RemoteLinux {
+namespace Internal {
-class REMOTELINUX_EXPORT RemoteLinuxQmlProfilerSupport
- : public ProjectExplorer::SimpleTargetRunner
+class RemoteLinuxQmlProfilerSupport : public ProjectExplorer::SimpleTargetRunner
{
- Q_OBJECT
-
public:
RemoteLinuxQmlProfilerSupport(ProjectExplorer::RunControl *runControl);
private:
void start() override;
- QmlDebug::QmlOutputParser m_outputParser;
ProjectExplorer::PortsGatherer *m_portsGatherer;
ProjectExplorer::RunWorker *m_profiler;
};
-
-class REMOTELINUX_EXPORT RemoteLinuxPerfSupport : public ProjectExplorer::RunWorker
-{
- Q_OBJECT
-
-public:
- RemoteLinuxPerfSupport(ProjectExplorer::RunControl *runControl);
-
-private:
- void start() override;
-
- QString m_remoteFifo;
- QString m_perfRecordArguments;
-
- ProjectExplorer::ApplicationLauncher m_outputGatherer;
-};
-
+} // namespace Internal
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp
index 1f0b9fc2102..7ae8d9b9fad 100644
--- a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp
+++ b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp
@@ -96,21 +96,29 @@ private:
Ui::RemoteLinuxCustomRunConfigurationWidget m_ui;
};
-RemoteLinuxCustomRunConfiguration::RemoteLinuxCustomRunConfiguration(ProjectExplorer::Target *parent)
- : RunConfiguration(parent, runConfigId())
+RemoteLinuxCustomRunConfiguration::RemoteLinuxCustomRunConfiguration(Target *target)
+ : RunConfiguration(target)
{
- init();
+ addExtraAspect(new RemoteLinuxEnvironmentAspect(this));
}
-RemoteLinuxCustomRunConfiguration::RemoteLinuxCustomRunConfiguration(ProjectExplorer::Target *parent,
- RemoteLinuxCustomRunConfiguration *source)
- : RunConfiguration(parent, source)
- , m_localExecutable(source->m_localExecutable)
- , m_remoteExecutable(source->m_remoteExecutable)
- , m_arguments(source->m_arguments)
- , m_workingDirectory(source->m_workingDirectory)
+void RemoteLinuxCustomRunConfiguration::initialize()
{
- init();
+ RunConfiguration::initialize(runConfigId());
+
+ setDefaultDisplayName(runConfigDefaultDisplayName());
+}
+
+void RemoteLinuxCustomRunConfiguration::copyFrom(const RemoteLinuxCustomRunConfiguration *source)
+{
+ RunConfiguration::copyFrom(source);
+
+ m_localExecutable = source->m_localExecutable;
+ m_remoteExecutable = source->m_remoteExecutable;
+ m_arguments = source->m_arguments;
+ m_workingDirectory = source->m_workingDirectory;
+
+ setDefaultDisplayName(runConfigDefaultDisplayName());
}
bool RemoteLinuxCustomRunConfiguration::isConfigured() const
@@ -167,12 +175,6 @@ QString RemoteLinuxCustomRunConfiguration::runConfigDefaultDisplayName()
return tr("Custom Executable (on Remote Generic Linux Host)");
}
-void RemoteLinuxCustomRunConfiguration::init()
-{
- setDefaultDisplayName(runConfigDefaultDisplayName());
- addExtraAspect(new RemoteLinuxEnvironmentAspect(this));
-}
-
static QString localExeKey()
{
return QLatin1String("RemoteLinux.CustomRunConfig.LocalExecutable");
diff --git a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.h b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.h
index be97dad96c0..06d29cf48c9 100644
--- a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.h
+++ b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.h
@@ -34,14 +34,14 @@ class RemoteLinuxCustomRunConfiguration : public ProjectExplorer::RunConfigurati
{
Q_OBJECT
public:
- RemoteLinuxCustomRunConfiguration(ProjectExplorer::Target *parent);
- RemoteLinuxCustomRunConfiguration(ProjectExplorer::Target *parent,
- RemoteLinuxCustomRunConfiguration *source);
+ explicit RemoteLinuxCustomRunConfiguration(ProjectExplorer::Target *target);
+
+ void initialize();
+ void copyFrom(const RemoteLinuxCustomRunConfiguration *source);
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
- bool isEnabled() const override { return true; }
bool isConfigured() const override;
ConfigurationState ensureConfigured(QString *errorMessage) override;
QWidget *createConfigurationWidget() override;
@@ -58,8 +58,6 @@ public:
static QString runConfigDefaultDisplayName();
private:
- void init();
-
QString m_localExecutable;
QString m_remoteExecutable;
QString m_arguments;
diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
index 4ce28bbc165..1687eb1808e 100644
--- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
+++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
@@ -28,24 +28,11 @@
#include "remotelinuxcustomrunconfiguration.h"
#include "remotelinuxrunconfiguration.h"
-#include <debugger/debuggerruncontrol.h>
-
-#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/project.h>
-#include <projectexplorer/runnables.h>
-#include <projectexplorer/target.h>
-#include <projectexplorer/toolchain.h>
-
-#include <qmldebug/qmldebugcommandlinearguments.h>
-
-#include <utils/qtcassert.h>
-#include <utils/qtcprocess.h>
-
using namespace Debugger;
using namespace ProjectExplorer;
-using namespace Utils;
namespace RemoteLinux {
+namespace Internal {
LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl)
: DebuggerRunTool(runControl)
@@ -61,54 +48,25 @@ LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl)
addStartDependency(gdbServer);
+ setStartMode(AttachToRemoteServer);
+ setCloseMode(KillAndExitMonitorAtClose);
+ setUseExtendedRemote(true);
+
RunConfiguration *runConfig = runControl->runConfiguration();
if (auto rlrc = qobject_cast<RemoteLinuxRunConfiguration *>(runConfig))
- m_symbolFile = rlrc->localExecutableFilePath();
+ setSymbolFile(rlrc->localExecutableFilePath());
else if (auto rlrc = qobject_cast<Internal::RemoteLinuxCustomRunConfiguration *>(runConfig))
- m_symbolFile = rlrc->localExecutableFilePath();
+ setSymbolFile(rlrc->localExecutableFilePath());
}
void LinuxDeviceDebugSupport::start()
{
- if (m_symbolFile.isEmpty()) {
- reportFailure(tr("Cannot debug: Local executable is not set."));
- return;
- }
-
- const QString host = device()->sshParameters().host;
- const Port gdbServerPort = m_portsGatherer->gdbServerPort();
- const Port qmlServerPort = m_portsGatherer->qmlServerPort();
-
- DebuggerStartParameters params;
- params.startMode = AttachToRemoteServer;
- params.closeMode = KillAndExitMonitorAtClose;
-
- if (isQmlDebugging()) {
- params.qmlServer.host = host;
- params.qmlServer.port = qmlServerPort;
- params.inferior.commandLineArguments.replace("%qml_port%",
- QString::number(qmlServerPort.number()));
- }
- if (isCppDebugging()) {
- Runnable r = runnable();
- QTC_ASSERT(r.is<StandardRunnable>(), return);
- auto stdRunnable = r.as<StandardRunnable>();
- params.useExtendedRemote = true;
- params.inferior.executable = stdRunnable.executable;
- params.inferior.commandLineArguments = stdRunnable.commandLineArguments;
- if (isQmlDebugging()) {
- params.inferior.commandLineArguments.prepend(' ');
- params.inferior.commandLineArguments.prepend(
- QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices));
- }
-
- params.remoteChannel = QString("%1:%2").arg(host).arg(gdbServerPort.number());
- params.symbolFile = m_symbolFile;
- }
-
- setStartParameters(params);
+ setRemoteChannel(m_portsGatherer->gdbServerChannel());
+ setQmlServer(m_portsGatherer->qmlServer());
+ addQmlServerInferiorCommandLineArgumentIfNeeded();
DebuggerRunTool::start();
}
+} // namespace Internal
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.h b/src/plugins/remotelinux/remotelinuxdebugsupport.h
index 81ecb85c357..1b7a0ee3ac2 100644
--- a/src/plugins/remotelinux/remotelinuxdebugsupport.h
+++ b/src/plugins/remotelinux/remotelinuxdebugsupport.h
@@ -25,25 +25,21 @@
#pragma once
-#include "abstractremotelinuxrunsupport.h"
-
#include <debugger/debuggerruncontrol.h>
namespace RemoteLinux {
+namespace Internal {
-class REMOTELINUX_EXPORT LinuxDeviceDebugSupport : public Debugger::DebuggerRunTool
+class LinuxDeviceDebugSupport : public Debugger::DebuggerRunTool
{
- Q_OBJECT
-
public:
LinuxDeviceDebugSupport(ProjectExplorer::RunControl *runControl);
private:
void start() override;
-protected:
- QString m_symbolFile;
Debugger::GdbServerPortsGatherer *m_portsGatherer = nullptr;
};
+} // namespace Internal
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxplugin.cpp b/src/plugins/remotelinux/remotelinuxplugin.cpp
index 78b82378df1..cc18906fbee 100644
--- a/src/plugins/remotelinux/remotelinuxplugin.cpp
+++ b/src/plugins/remotelinux/remotelinuxplugin.cpp
@@ -63,7 +63,6 @@ bool RemoteLinuxPlugin::initialize(const QStringList &arguments,
RunControl::registerWorker<SimpleTargetRunner>(NORMAL_RUN_MODE, constraint);
RunControl::registerWorker<LinuxDeviceDebugSupport>(DEBUG_RUN_MODE, constraint);
RunControl::registerWorker<RemoteLinuxQmlProfilerSupport>(QML_PROFILER_RUN_MODE, constraint);
- //RunControl::registerWorker<RemoteLinuxPerfSupport>(PERFPROFILER_RUN_MODE, constraint);
addAutoReleasedObject(new GenericLinuxDeviceConfigurationFactory);
addAutoReleasedObject(new RemoteLinuxRunConfigurationFactory);
diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
index 4dcca9c9cc8..ea8b4f65058 100644
--- a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
+++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
@@ -51,26 +51,12 @@ const char WorkingDirectoryKey[] = "RemoteLinux.RunConfig.WorkingDirectory";
} // anonymous namespace
-class RemoteLinuxRunConfigurationPrivate {
+class RemoteLinuxRunConfigurationPrivate
+{
public:
- RemoteLinuxRunConfigurationPrivate(const QString &targetName)
- : targetName(targetName),
- useAlternateRemoteExecutable(false)
- {
- }
-
- RemoteLinuxRunConfigurationPrivate(const RemoteLinuxRunConfigurationPrivate *other)
- : targetName(other->targetName),
- arguments(other->arguments),
- useAlternateRemoteExecutable(other->useAlternateRemoteExecutable),
- alternateRemoteExecutable(other->alternateRemoteExecutable),
- workingDirectory(other->workingDirectory)
- {
- }
-
QString targetName;
QString arguments;
- bool useAlternateRemoteExecutable;
+ bool useAlternateRemoteExecutable = false;
QString alternateRemoteExecutable;
QString workingDirectory;
};
@@ -79,45 +65,40 @@ public:
using namespace Internal;
-RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *parent, Core::Id id,
- const QString &targetName)
- : RunConfiguration(parent, id),
- d(new RemoteLinuxRunConfigurationPrivate(targetName))
+RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target)
+ : RunConfiguration(target), d(new RemoteLinuxRunConfigurationPrivate)
{
- init();
-}
+ addExtraAspect(new RemoteLinuxEnvironmentAspect(this));
-RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *parent,
- RemoteLinuxRunConfiguration *source)
- : RunConfiguration(parent, source),
- d(new RemoteLinuxRunConfigurationPrivate(source->d))
-{
- init();
+ connect(target, &Target::deploymentDataChanged,
+ this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated);
+ connect(target, &Target::applicationTargetsChanged,
+ this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated);
+ // Handles device changes, etc.
+ connect(target, &Target::kitChanged,
+ this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated);
}
-RemoteLinuxRunConfiguration::~RemoteLinuxRunConfiguration()
+void RemoteLinuxRunConfiguration::initialize(Core::Id id, const QString &targetName)
{
- delete d;
-}
+ RunConfiguration::initialize(id);
+
+ d->targetName = targetName;
-void RemoteLinuxRunConfiguration::init()
-{
setDefaultDisplayName(defaultDisplayName());
+}
- addExtraAspect(new RemoteLinuxEnvironmentAspect(this));
+void RemoteLinuxRunConfiguration::copyFrom(const RemoteLinuxRunConfiguration *source)
+{
+ RunConfiguration::copyFrom(source);
+ *d = *source->d;
- connect(target(), &Target::deploymentDataChanged,
- this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated);
- connect(target(), &Target::applicationTargetsChanged,
- this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated);
- // Handles device changes, etc.
- connect(target(), &Target::kitChanged,
- this, &RemoteLinuxRunConfiguration::handleBuildSystemDataUpdated);
+ setDefaultDisplayName(defaultDisplayName());
}
-bool RemoteLinuxRunConfiguration::isEnabled() const
+RemoteLinuxRunConfiguration::~RemoteLinuxRunConfiguration()
{
- return true;
+ delete d;
}
QWidget *RemoteLinuxRunConfiguration::createConfigurationWidget()
diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.h b/src/plugins/remotelinux/remotelinuxrunconfiguration.h
index a1926c4cd53..b4ef39a7370 100644
--- a/src/plugins/remotelinux/remotelinuxrunconfiguration.h
+++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.h
@@ -34,24 +34,18 @@
namespace RemoteLinux {
class RemoteLinuxRunConfigurationWidget;
-namespace Internal {
-class RemoteLinuxRunConfigurationPrivate;
-class RemoteLinuxRunConfigurationFactory;
-} // namespace Internal
+namespace Internal { class RemoteLinuxRunConfigurationPrivate; }
class REMOTELINUX_EXPORT RemoteLinuxRunConfiguration : public ProjectExplorer::RunConfiguration
{
Q_OBJECT
- Q_DISABLE_COPY(RemoteLinuxRunConfiguration)
- friend class Internal::RemoteLinuxRunConfigurationFactory;
friend class RemoteLinuxRunConfigurationWidget;
+ friend class ProjectExplorer::IRunConfigurationFactory;
public:
- RemoteLinuxRunConfiguration(ProjectExplorer::Target *parent, Core::Id id,
- const QString &targetName);
+ explicit RemoteLinuxRunConfiguration(ProjectExplorer::Target *target);
~RemoteLinuxRunConfiguration() override;
- bool isEnabled() const override;
QWidget *createConfigurationWidget() override;
Utils::OutputFormatter *createOutputFormatter() const override;
@@ -80,14 +74,14 @@ signals:
void targetInformationChanged() const;
protected:
- RemoteLinuxRunConfiguration(ProjectExplorer::Target *parent,
- RemoteLinuxRunConfiguration *source);
+ void initialize(Core::Id id, const QString &targetName);
+ void copyFrom(const RemoteLinuxRunConfiguration *source);
+
bool fromMap(const QVariantMap &map) override;
QString defaultDisplayName();
private:
void handleBuildSystemDataUpdated();
- void init();
Internal::RemoteLinuxRunConfigurationPrivate * const d;
};
diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp
index 8745163fcae..53363b19c4b 100644
--- a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp
+++ b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp
@@ -107,27 +107,25 @@ QString RemoteLinuxRunConfigurationFactory::displayNameForId(Core::Id id) const
RunConfiguration *RemoteLinuxRunConfigurationFactory::doCreate(Target *parent, Core::Id id)
{
if (id == RemoteLinuxCustomRunConfiguration::runConfigId())
- return new RemoteLinuxCustomRunConfiguration(parent);
- return new RemoteLinuxRunConfiguration(parent, id, stringFromId(id));
+ return createHelper<RemoteLinuxCustomRunConfiguration>(parent);
+ return createHelper<RemoteLinuxRunConfiguration>(parent, id, stringFromId(id));
}
RunConfiguration *RemoteLinuxRunConfigurationFactory::doRestore(Target *parent,
const QVariantMap &map)
{
if (idFromMap(map) == RemoteLinuxCustomRunConfiguration::runConfigId())
- return new RemoteLinuxCustomRunConfiguration(parent);
- return new RemoteLinuxRunConfiguration(parent,
- Core::Id(RemoteLinuxRunConfiguration::IdPrefix), QString());
+ return createHelper<RemoteLinuxCustomRunConfiguration>(parent);
+ return createHelper<RemoteLinuxRunConfiguration>(parent, RemoteLinuxRunConfiguration::IdPrefix, QString());
}
RunConfiguration *RemoteLinuxRunConfigurationFactory::clone(Target *parent,
RunConfiguration *source)
{
QTC_ASSERT(canClone(parent, source), return 0);
- if (RemoteLinuxCustomRunConfiguration *old = qobject_cast<RemoteLinuxCustomRunConfiguration *>(source))
- return new RemoteLinuxCustomRunConfiguration(parent, old);
- RemoteLinuxRunConfiguration *old = static_cast<RemoteLinuxRunConfiguration *>(source);
- return new RemoteLinuxRunConfiguration(parent, old);
+ if (qobject_cast<RemoteLinuxCustomRunConfiguration *>(source))
+ return cloneHelper<RemoteLinuxCustomRunConfiguration>(parent, source);
+ return cloneHelper<RemoteLinuxRunConfiguration>(parent, source);
}
bool RemoteLinuxRunConfigurationFactory::canHandle(const Target *target) const
diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp
index 8e3442efaf8..1f898bfdc63 100644
--- a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp
+++ b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp
@@ -58,9 +58,6 @@ public:
RemoteLinuxRunConfiguration * const runConfiguration;
bool ignoreChange;
- QWidget topWidget;
- QLabel disabledIcon;
- QLabel disabledReason;
QLineEdit argsLineEdit;
QLineEdit workingDirLineEdit;
QLabel localExecutableLabel;
@@ -79,17 +76,9 @@ RemoteLinuxRunConfigurationWidget::RemoteLinuxRunConfigurationWidget(RemoteLinux
QWidget *parent)
: QWidget(parent), d(new RemoteLinuxRunConfigurationWidgetPrivate(runConfiguration))
{
- QVBoxLayout *topLayout = new QVBoxLayout(this);
- topLayout->setMargin(0);
- addDisabledLabel(topLayout);
- topLayout->addWidget(&d->topWidget);
- QVBoxLayout *mainLayout = new QVBoxLayout(&d->topWidget);
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setMargin(0);
addGenericWidgets(mainLayout);
-
- connect(d->runConfiguration, &RemoteLinuxRunConfiguration::enabledChanged,
- this, &RemoteLinuxRunConfigurationWidget::runConfigurationEnabledChange);
- runConfigurationEnabledChange();
}
RemoteLinuxRunConfigurationWidget::~RemoteLinuxRunConfigurationWidget()
@@ -102,27 +91,6 @@ void RemoteLinuxRunConfigurationWidget::addFormLayoutRow(QWidget *label, QWidget
d->genericWidgetsLayout.addRow(label, field);
}
-void RemoteLinuxRunConfigurationWidget::addDisabledLabel(QVBoxLayout *topLayout)
-{
- QHBoxLayout * const hl = new QHBoxLayout;
- hl->addStretch();
- d->disabledIcon.setPixmap(Utils::Icons::WARNING.pixmap());
- hl->addWidget(&d->disabledIcon);
- d->disabledReason.setVisible(false);
- hl->addWidget(&d->disabledReason);
- hl->addStretch();
- topLayout->addLayout(hl);
-}
-
-void RemoteLinuxRunConfigurationWidget::runConfigurationEnabledChange()
-{
- bool enabled = d->runConfiguration->isEnabled();
- d->topWidget.setEnabled(enabled);
- d->disabledIcon.setVisible(!enabled);
- d->disabledReason.setVisible(!enabled);
- d->disabledReason.setText(d->runConfiguration->disabledReason());
-}
-
void RemoteLinuxRunConfigurationWidget::addGenericWidgets(QVBoxLayout *mainLayout)
{
Utils::DetailsWidget *detailsContainer = new Utils::DetailsWidget(this);
diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h
index a25d74220af..0ac60985c6b 100644
--- a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h
+++ b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.h
@@ -49,9 +49,6 @@ public:
void addFormLayoutRow(QWidget *label, QWidget *field);
- void addDisabledLabel(QVBoxLayout *topLayout);
- void runConfigurationEnabledChange();
-
private:
void argumentsEdited(const QString &args);
void updateTargetInformation();
diff --git a/src/plugins/resourceeditor/qrceditor/resourcefile.cpp b/src/plugins/resourceeditor/qrceditor/resourcefile.cpp
index b139e7fda42..5e17105cfa6 100644
--- a/src/plugins/resourceeditor/qrceditor/resourcefile.cpp
+++ b/src/plugins/resourceeditor/qrceditor/resourcefile.cpp
@@ -564,8 +564,8 @@ void ResourceFile::clearPrefixList()
ResourceModel::ResourceModel(QObject *parent)
: QAbstractItemModel(parent), m_dirty(false)
{
- m_prefixIcon = Core::FileIconProvider::overlayIcon(QStyle::SP_DirIcon,
- QIcon(QLatin1String(ProjectExplorer::Constants::FILEOVERLAY_QRC)), QSize(16, 16));
+ static QIcon resourceFolderIcon = Core::FileIconProvider::directoryIcon(QLatin1String(ProjectExplorer::Constants::FILEOVERLAY_QRC));
+ m_prefixIcon = resourceFolderIcon;
}
void ResourceModel::setDirty(bool b)
diff --git a/src/plugins/resourceeditor/resourceeditorplugin.cpp b/src/plugins/resourceeditor/resourceeditorplugin.cpp
index 75cce175429..bc28f947475 100644
--- a/src/plugins/resourceeditor/resourceeditorplugin.cpp
+++ b/src/plugins/resourceeditor/resourceeditorplugin.cpp
@@ -245,7 +245,7 @@ void ResourceEditorPlugin::onRefresh()
void ResourceEditorPlugin::addPrefixContextMenu()
{
- auto topLevel = dynamic_cast<ResourceTopLevelNode *>(ProjectTree::currentNode());
+ auto topLevel = dynamic_cast<ResourceTopLevelNode *>(ProjectTree::findCurrentNode());
QTC_ASSERT(topLevel, return);
PrefixLangDialog dialog(tr("Add Prefix"), QString(), QString(), Core::ICore::mainWindow());
if (dialog.exec() != QDialog::Accepted)
@@ -258,7 +258,7 @@ void ResourceEditorPlugin::addPrefixContextMenu()
void ResourceEditorPlugin::removePrefixContextMenu()
{
- auto rfn = dynamic_cast<ResourceFolderNode *>(ProjectTree::currentNode());
+ auto rfn = dynamic_cast<ResourceFolderNode *>(ProjectTree::findCurrentNode());
QTC_ASSERT(rfn, return);
if (QMessageBox::question(Core::ICore::mainWindow(),
tr("Remove Prefix"),
@@ -271,7 +271,7 @@ void ResourceEditorPlugin::removePrefixContextMenu()
void ResourceEditorPlugin::removeNonExisting()
{
- auto topLevel = dynamic_cast<ResourceTopLevelNode *>(ProjectTree::currentNode());
+ auto topLevel = dynamic_cast<ResourceTopLevelNode *>(ProjectTree::findCurrentNode());
QTC_ASSERT(topLevel, return);
topLevel->removeNonExistingFiles();
}
@@ -283,7 +283,7 @@ void ResourceEditorPlugin::renameFileContextMenu()
void ResourceEditorPlugin::removeFileContextMenu()
{
- auto rfn = dynamic_cast<ResourceFolderNode *>(ProjectTree::currentNode());
+ auto rfn = dynamic_cast<ResourceTopLevelNode *>(ProjectTree::findCurrentNode());
QTC_ASSERT(rfn, return);
QString path = rfn->filePath().toString();
FolderNode *parent = rfn->parentFolderNode();
@@ -296,26 +296,26 @@ void ResourceEditorPlugin::removeFileContextMenu()
void ResourceEditorPlugin::openEditorContextMenu()
{
- Core::EditorManager::openEditor(ProjectTree::currentNode()->filePath().toString());
+ Core::EditorManager::openEditor(ProjectTree::findCurrentNode()->filePath().toString());
}
void ResourceEditorPlugin::copyPathContextMenu()
{
- auto node = dynamic_cast<ResourceFileNode *>(ProjectTree::currentNode());
+ auto node = dynamic_cast<ResourceFileNode *>(ProjectTree::findCurrentNode());
QTC_ASSERT(node, return);
QApplication::clipboard()->setText(QLatin1String(resourcePrefix) + node->qrcPath());
}
void ResourceEditorPlugin::copyUrlContextMenu()
{
- auto node = dynamic_cast<ResourceFileNode *>(ProjectTree::currentNode());
+ auto node = dynamic_cast<ResourceFileNode *>(ProjectTree::findCurrentNode());
QTC_ASSERT(node, return);
QApplication::clipboard()->setText(QLatin1String(urlPrefix) + node->qrcPath());
}
void ResourceEditorPlugin::renamePrefixContextMenu()
{
- auto node = dynamic_cast<ResourceFolderNode *>(ProjectTree::currentNode());
+ auto node = dynamic_cast<ResourceFolderNode *>(ProjectTree::findCurrentNode());
QTC_ASSERT(node, return);
PrefixLangDialog dialog(tr("Rename Prefix"), node->prefix(), node->lang(), Core::ICore::mainWindow());
@@ -330,8 +330,8 @@ void ResourceEditorPlugin::renamePrefixContextMenu()
void ResourceEditorPlugin::updateContextActions()
{
- Node *node = ProjectTree::currentNode();
- bool isResourceNode = dynamic_cast<ResourceTopLevelNode *>(node);
+ const Node *node = ProjectTree::findCurrentNode();
+ const bool isResourceNode = dynamic_cast<const ResourceTopLevelNode *>(node);
m_addPrefix->setEnabled(isResourceNode);
m_addPrefix->setVisible(isResourceNode);
@@ -352,7 +352,7 @@ void ResourceEditorPlugin::updateContextActions()
m_openInEditor->setEnabled(isResourceNode);
m_openInEditor->setVisible(isResourceNode);
- bool isResourceFolder = dynamic_cast<ResourceFolderNode *>(node);
+ const bool isResourceFolder = dynamic_cast<const ResourceFolderNode *>(node);
m_removePrefix->setEnabled(isResourceFolder);
m_removePrefix->setVisible(isResourceFolder);
@@ -368,13 +368,13 @@ void ResourceEditorPlugin::updateContextActions()
m_openWithMenu->clear();
m_openWithMenu->menuAction()->setVisible(!m_openWithMenu->actions().isEmpty());
- bool isResourceFile = dynamic_cast<ResourceFileNode *>(node);
+ const bool isResourceFile = dynamic_cast<const ResourceFileNode *>(node);
m_copyPath->setEnabled(isResourceFile);
m_copyPath->setVisible(isResourceFile);
m_copyUrl->setEnabled(isResourceFile);
m_copyUrl->setVisible(isResourceFile);
if (isResourceFile) {
- auto fileNode = dynamic_cast<ResourceFileNode *>(node);
+ auto fileNode = dynamic_cast<const ResourceFileNode *>(node);
QTC_ASSERT(fileNode, return);
QString qrcPath = fileNode->qrcPath();
m_copyPath->setParameter(QLatin1String(resourcePrefix) + qrcPath);
diff --git a/src/plugins/resourceeditor/resourcenode.cpp b/src/plugins/resourceeditor/resourcenode.cpp
index 45c57c91260..0ca93ea5b5a 100644
--- a/src/plugins/resourceeditor/resourcenode.cpp
+++ b/src/plugins/resourceeditor/resourcenode.cpp
@@ -160,7 +160,7 @@ public:
ResourceTopLevelNode *topLevel, ResourceFolderNode *prefixNode);
QString displayName() const final;
- bool supportsAction(ProjectAction, Node *node) const final;
+ bool supportsAction(ProjectAction, const Node *node) const final;
bool addFiles(const QStringList &filePaths, QStringList *notAdded) final;
bool removeFiles(const QStringList &filePaths, QStringList *notRemoved) final;
bool renameFile(const QString &filePath, const QString &newFilePath) final;
@@ -199,7 +199,7 @@ SimpleResourceFolderNode::SimpleResourceFolderNode(const QString &afolderName, c
}
-bool SimpleResourceFolderNode::supportsAction(ProjectAction action, Node *) const
+bool SimpleResourceFolderNode::supportsAction(ProjectAction action, const Node *) const
{
return action == AddNewFile
|| action == AddExistingFile
@@ -390,7 +390,7 @@ QString ResourceTopLevelNode::addFileFilter() const
return QLatin1String("*.png; *.jpg; *.gif; *.svg; *.ico; *.qml; *.qml.ui");
}
-bool ResourceTopLevelNode::supportsAction(ProjectAction action, Node *node) const
+bool ResourceTopLevelNode::supportsAction(ProjectAction action, const Node *node) const
{
if (node != this)
return false;
@@ -513,7 +513,7 @@ ResourceFolderNode::~ResourceFolderNode()
}
-bool ResourceFolderNode::supportsAction(ProjectAction action, Node *node) const
+bool ResourceFolderNode::supportsAction(ProjectAction action, const Node *node) const
{
Q_UNUSED(node)
@@ -678,7 +678,7 @@ QString ResourceFileNode::qrcPath() const
return m_qrcPath;
}
-bool ResourceFileNode::supportsAction(ProjectAction action, Node *node) const
+bool ResourceFileNode::supportsAction(ProjectAction action, const Node *node) const
{
if (action == HidePathActions)
return false;
diff --git a/src/plugins/resourceeditor/resourcenode.h b/src/plugins/resourceeditor/resourcenode.h
index f9b9e65c37f..6752eb68559 100644
--- a/src/plugins/resourceeditor/resourcenode.h
+++ b/src/plugins/resourceeditor/resourcenode.h
@@ -42,7 +42,7 @@ public:
QString addFileFilter() const override;
- bool supportsAction(ProjectExplorer::ProjectAction action, Node *node) const override;
+ bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
bool addFiles(const QStringList &filePaths, QStringList *notAdded) override;
bool removeFiles(const QStringList &filePaths, QStringList *notRemoved) override;
@@ -69,7 +69,7 @@ public:
ResourceFolderNode(const QString &prefix, const QString &lang, ResourceTopLevelNode *parent);
~ResourceFolderNode() override;
- bool supportsAction(ProjectExplorer::ProjectAction action, Node *node) const override;
+ bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
QString displayName() const override;
@@ -99,7 +99,7 @@ public:
QString displayName() const override;
QString qrcPath() const;
- bool supportsAction(ProjectExplorer::ProjectAction action, Node *node) const override;
+ bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
private:
QString m_qrcPath;
diff --git a/src/plugins/scxmleditor/common/stateproperties.cpp b/src/plugins/scxmleditor/common/stateproperties.cpp
index 32272833b2d..568336295f9 100644
--- a/src/plugins/scxmleditor/common/stateproperties.cpp
+++ b/src/plugins/scxmleditor/common/stateproperties.cpp
@@ -30,6 +30,7 @@
#include "scxmluifactory.h"
#include <coreplugin/minisplitter.h>
+#include <utils/qtcfallthrough.h>
#include <QHeaderView>
#include <QLabel>
@@ -84,6 +85,7 @@ void StateProperties::tagChange(ScxmlDocument::TagChange change, ScxmlTag *tag,
case ScxmlDocument::TagContentChanged:
if (tag != m_tag)
return;
+ Q_FALLTHROUGH();
case ScxmlDocument::TagCurrentChanged:
setTag(tag);
break;
diff --git a/src/plugins/scxmleditor/outputpane/warningmodel.cpp b/src/plugins/scxmleditor/outputpane/warningmodel.cpp
index 23a406a3230..6b4bb0ea033 100644
--- a/src/plugins/scxmleditor/outputpane/warningmodel.cpp
+++ b/src/plugins/scxmleditor/outputpane/warningmodel.cpp
@@ -237,14 +237,15 @@ Warning *WarningModel::getWarning(const QModelIndex &ind)
return nullptr;
}
-void WarningModel::warningDestroyed(QObject *ww)
+void WarningModel::warningDestroyed(QObject *w)
{
- auto w = static_cast<Warning*>(ww);
- if (m_warnings.contains(w)) {
- int ind = m_warnings.indexOf(w);
+ // Intentional static_cast.
+ // The Warning is being destroyed, so qobject_cast doesn't work anymore.
+ const int ind = m_warnings.indexOf(static_cast<Warning *>(w));
+ if (ind >= 0) {
beginRemoveRows(QModelIndex(), ind, ind);
m_warnings.removeAt(ind);
- endResetModel();
+ endRemoveRows();
}
m_countChecker->start();
diff --git a/src/plugins/scxmleditor/plugin_interface/connectableitem.cpp b/src/plugins/scxmleditor/plugin_interface/connectableitem.cpp
index 82200f2a57d..130c86bf5c4 100644
--- a/src/plugins/scxmleditor/plugin_interface/connectableitem.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/connectableitem.cpp
@@ -33,6 +33,8 @@
#include "serializer.h"
#include "stateitem.h"
+#include <utils/qtcfallthrough.h>
+
#include <QDebug>
#include <QPainter>
#include <QPen>
@@ -491,7 +493,7 @@ QVariant ConnectableItem::itemChange(GraphicsItemChange change, const QVariant &
case ItemParentHasChanged:
updateTransitions(true);
updateTransitionAttributes(true);
- // FIXME: intended fallthrough?
+ Q_FALLTHROUGH();
case ItemPositionHasChanged:
if (!m_releasedFromParent && !blockUpdates())
checkParentBoundingRect();
diff --git a/src/plugins/scxmleditor/plugin_interface/graphicsscene.cpp b/src/plugins/scxmleditor/plugin_interface/graphicsscene.cpp
index e5681fbc6e6..b1347007bea 100644
--- a/src/plugins/scxmleditor/plugin_interface/graphicsscene.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/graphicsscene.cpp
@@ -541,7 +541,7 @@ void GraphicsScene::endTagChange(ScxmlDocument::TagChange change, ScxmlTag *tag,
item->finalizeCreation();
}
}
- // FIXME: intended fallthrough?
+ break;
case ScxmlDocument::TagAddChild: {
ScxmlTag *childTag = tag->child(value.toInt());
if (childTag) {
diff --git a/src/plugins/scxmleditor/plugin_interface/scattributeitemmodel.cpp b/src/plugins/scxmleditor/plugin_interface/scattributeitemmodel.cpp
index 38fe97e6675..7ea007bdff4 100644
--- a/src/plugins/scxmleditor/plugin_interface/scattributeitemmodel.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/scattributeitemmodel.cpp
@@ -26,6 +26,8 @@
#include "scattributeitemmodel.h"
#include "mytypes.h"
+#include <utils/qtcfallthrough.h>
+
#include <QBrush>
using namespace ScxmlEditor::PluginInterface;
@@ -91,6 +93,7 @@ QVariant SCAttributeItemModel::data(const QModelIndex &index, int role) const
case Qt::DisplayRole:
if (bExtraRow)
return index.column() == 0 ? tr("- name -") : tr(" - value -");
+ Q_FALLTHROUGH();
case Qt::EditRole: {
if (index.column() == 0) {
if (bEditable) {
diff --git a/src/plugins/scxmleditor/plugin_interface/transitionitem.cpp b/src/plugins/scxmleditor/plugin_interface/transitionitem.cpp
index 154324fd98d..acf0116ac6c 100644
--- a/src/plugins/scxmleditor/plugin_interface/transitionitem.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/transitionitem.cpp
@@ -244,7 +244,7 @@ void TransitionItem::snapToAnyPoint(int id, const QPointF &newPoint, int diff)
void TransitionItem::snapPointToPoint(int idSnap, const QPointF &p, int diff)
{
- if (idSnap >= 0 && idSnap < m_cornerPoints.count()) {
+ if (idSnap >= 0 && static_cast<uint>(idSnap) < static_cast<uint>(m_cornerPoints.count())) {
if (qAbs(p.x() - m_cornerPoints[idSnap].x()) < diff)
m_cornerPoints[idSnap].setX(p.x());
if (qAbs(p.y() - m_cornerPoints[idSnap].y()) < diff)
diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp
index aaf43d91953..d35d027b57e 100644
--- a/src/plugins/subversion/subversionplugin.cpp
+++ b/src/plugins/subversion/subversionplugin.cpp
@@ -210,7 +210,7 @@ bool SubversionPlugin::initialize(const QStringList & /*arguments */, QString *e
Context context(SUBVERSION_CONTEXT);
- initializeVcs(new SubversionControl(this), context);
+ initializeVcs<SubversionControl>(context, this);
m_subversionPluginInstance = this;
@@ -642,6 +642,9 @@ void SubversionPlugin::startCommitProject()
* commit will start. */
void SubversionPlugin::startCommit(const QString &workingDir, const QStringList &files)
{
+ if (!promptBeforeCommit())
+ return;
+
if (raiseSubmitEditor())
return;
if (isCommitEditorOpen()) {
diff --git a/src/plugins/subversion/subversionsettings.cpp b/src/plugins/subversion/subversionsettings.cpp
index 5870f2f423b..78a0f4728ac 100644
--- a/src/plugins/subversion/subversionsettings.cpp
+++ b/src/plugins/subversion/subversionsettings.cpp
@@ -46,8 +46,8 @@ SubversionSettings::SubversionSettings()
declareKey(binaryPathKey, QLatin1String("svn" QTC_HOST_EXE_SUFFIX));
declareKey(logCountKey, 1000);
declareKey(useAuthenticationKey, false);
- declareKey(userKey, QLatin1String(""));
- declareKey(passwordKey, QLatin1String(""));
+ declareKey(userKey, QString());
+ declareKey(passwordKey, QString());
declareKey(spaceIgnorantAnnotationKey, true);
declareKey(diffIgnoreWhiteSpaceKey, false);
declareKey(logVerboseKey, false);
diff --git a/src/plugins/texteditor/behaviorsettingspage.cpp b/src/plugins/texteditor/behaviorsettingspage.cpp
index 22b04439324..1c26e30a543 100644
--- a/src/plugins/texteditor/behaviorsettingspage.cpp
+++ b/src/plugins/texteditor/behaviorsettingspage.cpp
@@ -57,13 +57,13 @@ struct BehaviorSettingsPage::BehaviorSettingsPagePrivate
const BehaviorSettingsPageParameters m_parameters;
QPointer<QWidget> m_widget;
- Internal::Ui::BehaviorSettingsPage *m_page;
+ Internal::Ui::BehaviorSettingsPage *m_page = nullptr;
void init();
- CodeStylePool *m_defaultCodeStylePool;
- SimpleCodeStylePreferences *m_codeStyle;
- SimpleCodeStylePreferences *m_pageCodeStyle;
+ CodeStylePool *m_defaultCodeStylePool = nullptr;
+ SimpleCodeStylePreferences *m_codeStyle = nullptr;
+ SimpleCodeStylePreferences *m_pageCodeStyle = nullptr;
TypingSettings m_typingSettings;
StorageSettings m_storageSettings;
BehaviorSettings m_behaviorSettings;
@@ -72,7 +72,7 @@ struct BehaviorSettingsPage::BehaviorSettingsPagePrivate
BehaviorSettingsPage::BehaviorSettingsPagePrivate::BehaviorSettingsPagePrivate
(const BehaviorSettingsPageParameters &p)
- : m_parameters(p), m_page(0), m_pageCodeStyle(0)
+ : m_parameters(p)
{
}
diff --git a/src/plugins/texteditor/behaviorsettingswidget.ui b/src/plugins/texteditor/behaviorsettingswidget.ui
index bc3d4e5b767..a342858801b 100644
--- a/src/plugins/texteditor/behaviorsettingswidget.ui
+++ b/src/plugins/texteditor/behaviorsettingswidget.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>801</width>
- <height>459</height>
+ <height>480</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
@@ -290,7 +290,7 @@ Specifies how backspace interacts with indentation.
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;
&lt;p&gt;How text editors should deal with UTF-8 Byte Order Marks. The options are:&lt;/p&gt;
-&lt;ul &gt;&lt;li&gt;&lt;i&gt;Add If Encoding Is UTF-8:&lt;/i&gt; always add a BOM when saving a file in UTF-8 encoding. Note that this will not work if the encoding is &lt;i&gt;System&lt;/i&gt;, as Qt Creator does not know what it actually is.&lt;/li&gt;
+&lt;ul &gt;&lt;li&gt;&lt;i&gt;Add If Encoding Is UTF-8:&lt;/i&gt; always add a BOM when saving a file in UTF-8 encoding. Note that this will not work if the encoding is &lt;i&gt;System&lt;/i&gt;, as the text editor does not know what it actually is.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Keep If Already Present: &lt;/i&gt;save the file with a BOM if it already had one when it was loaded.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Always Delete:&lt;/i&gt; never write an UTF-8 BOM, possibly deleting a pre-existing one.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Note that UTF-8 BOMs are uncommon and treated incorrectly by some editors, so it usually makes little sense to add any.&lt;/p&gt;
diff --git a/src/plugins/texteditor/codeassist/assistinterface.cpp b/src/plugins/texteditor/codeassist/assistinterface.cpp
index 42670678895..3577718dfb4 100644
--- a/src/plugins/texteditor/codeassist/assistinterface.cpp
+++ b/src/plugins/texteditor/codeassist/assistinterface.cpp
@@ -91,7 +91,7 @@ using namespace TextEditor;
#include "assistinterface.h"
-#include <texteditor/convenience.h>
+#include <utils/textutils.h>
#include <QTextBlock>
#include <QTextDocument>
@@ -125,7 +125,7 @@ QChar AssistInterface::characterAt(int position) const
QString AssistInterface::textAt(int pos, int length) const
{
- return Convenience::textAt(QTextCursor(m_textDocument), pos, length);
+ return Utils::Text::textAt(QTextCursor(m_textDocument), pos, length);
}
void AssistInterface::prepareForAsyncUse()
diff --git a/src/plugins/texteditor/codeassist/codeassistant.cpp b/src/plugins/texteditor/codeassist/codeassistant.cpp
index 0622f29f10d..5de47c3b092 100644
--- a/src/plugins/texteditor/codeassist/codeassistant.cpp
+++ b/src/plugins/texteditor/codeassist/codeassistant.cpp
@@ -74,6 +74,9 @@ public:
bool hasContext() const;
void destroyContext();
+ QVariant userData() const;
+ void setUserData(const QVariant &data);
+
CompletionAssistProvider *identifyActivationSequence();
void stopAutomaticProposalTimer();
@@ -105,6 +108,7 @@ private:
CompletionSettings m_settings;
int m_abortedBasePosition;
static const QChar m_null;
+ QVariant m_userData;
};
// --------------------
@@ -248,7 +252,7 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason,
}
case IAssistProvider::Asynchronous: {
processor->setAsyncCompletionAvailableHandler(
- [this, processor, reason](IAssistProposal *newProposal){
+ [this, reason](IAssistProposal *newProposal){
QTC_CHECK(newProposal);
invalidateCurrentRequestData();
displayProposal(newProposal, reason);
@@ -340,6 +344,7 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
m_proposalWidget->setAssistant(q);
m_proposalWidget->setReason(reason);
m_proposalWidget->setKind(m_assistKind);
+ m_proposalWidget->setBasePosition(basePosition);
m_proposalWidget->setUnderlyingWidget(m_editorWidget);
m_proposalWidget->setModel(proposalCandidateModel.take());
m_proposalWidget->setDisplayRect(m_editorWidget->cursorRect(basePosition));
@@ -441,8 +446,6 @@ void CodeAssistantPrivate::notifyChange()
m_proposalWidget->updateProposal(
m_editorWidget->textAt(m_proposal->basePosition(),
m_editorWidget->position() - m_proposal->basePosition()));
- if (m_proposal->isFragile())
- startAutomaticProposalTimer();
}
}
}
@@ -467,6 +470,16 @@ void CodeAssistantPrivate::destroyContext()
}
}
+QVariant CodeAssistantPrivate::userData() const
+{
+ return m_userData;
+}
+
+void CodeAssistantPrivate::setUserData(const QVariant &data)
+{
+ m_userData = data;
+}
+
void CodeAssistantPrivate::startAutomaticProposalTimer()
{
if (m_settings.m_completionTrigger == AutomaticCompletion)
@@ -574,6 +587,16 @@ void CodeAssistant::destroyContext()
d->destroyContext();
}
+QVariant CodeAssistant::userData() const
+{
+ return d->userData();
+}
+
+void CodeAssistant::setUserData(const QVariant &data)
+{
+ d->setUserData(data);
+}
+
void CodeAssistant::invoke(AssistKind kind, IAssistProvider *provider)
{
d->invoke(kind, provider);
diff --git a/src/plugins/texteditor/codeassist/codeassistant.h b/src/plugins/texteditor/codeassist/codeassistant.h
index dca761f4ac8..64e507f49b8 100644
--- a/src/plugins/texteditor/codeassist/codeassistant.h
+++ b/src/plugins/texteditor/codeassist/codeassistant.h
@@ -53,6 +53,9 @@ public:
bool hasContext() const;
void destroyContext();
+ QVariant userData() const;
+ void setUserData(const QVariant &data);
+
void invoke(AssistKind assistKind, IAssistProvider *provider = 0);
signals:
diff --git a/src/plugins/texteditor/codeassist/functionhintproposal.cpp b/src/plugins/texteditor/codeassist/functionhintproposal.cpp
index 5a2bb07cfd6..048ce8da569 100644
--- a/src/plugins/texteditor/codeassist/functionhintproposal.cpp
+++ b/src/plugins/texteditor/codeassist/functionhintproposal.cpp
@@ -32,16 +32,13 @@ using namespace TextEditor;
FunctionHintProposal::FunctionHintProposal(int cursorPos, IFunctionHintProposalModel *model)
: IAssistProposal(cursorPos)
, m_model(model)
-{}
+{
+ setFragile(true);
+}
FunctionHintProposal::~FunctionHintProposal()
{}
-bool FunctionHintProposal::isFragile() const
-{
- return true;
-}
-
IAssistProposalModel *FunctionHintProposal::model() const
{
return m_model;
diff --git a/src/plugins/texteditor/codeassist/functionhintproposal.h b/src/plugins/texteditor/codeassist/functionhintproposal.h
index fd73886b056..53746534541 100644
--- a/src/plugins/texteditor/codeassist/functionhintproposal.h
+++ b/src/plugins/texteditor/codeassist/functionhintproposal.h
@@ -38,7 +38,6 @@ public:
FunctionHintProposal(int cursorPos, IFunctionHintProposalModel *model);
~FunctionHintProposal();
- bool isFragile() const override;
IAssistProposalModel *model() const override;
IAssistProposalWidget *createWidget() const override;
diff --git a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp
index 4ad414d44ec..dc952e19946 100644
--- a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp
+++ b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp
@@ -27,6 +27,7 @@
#include "ifunctionhintproposalmodel.h"
#include "codeassistant.h"
+#include <utils/algorithm.h>
#include <utils/faketooltip.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
@@ -42,6 +43,56 @@
namespace TextEditor {
+static const int maxSelectedFunctionHints = 20;
+
+class SelectedFunctionHints
+{
+public:
+ void insert(int basePosition, const QString &hintId)
+ {
+ if (basePosition < 0 || hintId.isEmpty())
+ return;
+
+ const int index = indexOf(basePosition);
+
+ // Add new item
+ if (index == -1) {
+ if (m_items.size() + 1 > maxSelectedFunctionHints)
+ m_items.removeLast();
+ m_items.prepend(FunctionHintItem(basePosition, hintId));
+ return;
+ }
+
+ // Update existing item
+ m_items[index].hintId = hintId;
+ }
+
+ QString hintId(int basePosition) const
+ {
+ const int index = indexOf(basePosition);
+ return index == -1 ? QString() : m_items.at(index).hintId;
+ }
+
+private:
+ int indexOf(int basePosition) const
+ {
+ return Utils::indexOf(m_items, [&](const FunctionHintItem &item) {
+ return item.basePosition == basePosition;
+ });
+ }
+
+private:
+ struct FunctionHintItem {
+ FunctionHintItem(int basePosition, const QString &hintId)
+ : basePosition(basePosition), hintId(hintId) {}
+
+ int basePosition = -1;
+ QString hintId;
+ };
+
+ QList<FunctionHintItem> m_items;
+};
+
// -------------------------
// HintProposalWidgetPrivate
// -------------------------
@@ -158,7 +209,7 @@ void FunctionHintProposalWidget::showProposal(const QString &prefix)
QTC_ASSERT(d->m_totalHints != 0, abort(); return; );
d->m_pager->setVisible(d->m_totalHints > 1);
- d->m_currentHint = 0;
+ d->m_currentHint = loadSelectedHint();
if (!updateAndCheck(prefix))
return;
@@ -184,6 +235,32 @@ void FunctionHintProposalWidget::abort()
deleteLater();
}
+static SelectedFunctionHints selectedFunctionHints(CodeAssistant &codeAssistant)
+{
+ const QVariant variant = codeAssistant.userData();
+ return variant.value<SelectedFunctionHints>();
+}
+
+int FunctionHintProposalWidget::loadSelectedHint() const
+{
+ const QString hintId = selectedFunctionHints(*d->m_assistant).hintId(basePosition());
+
+ for (int i = 0; i < d->m_model->size(); ++i) {
+ if (d->m_model->id(i) == hintId)
+ return i;
+ }
+
+ return 0;
+}
+
+void FunctionHintProposalWidget::storeSelectedHint()
+{
+ SelectedFunctionHints table = selectedFunctionHints(*d->m_assistant);
+ table.insert(basePosition(), d->m_model->id(d->m_currentHint));
+
+ d->m_assistant->setUserData(QVariant::fromValue(table));
+}
+
bool FunctionHintProposalWidget::eventFilter(QObject *obj, QEvent *e)
{
switch (e->type()) {
@@ -257,6 +334,8 @@ bool FunctionHintProposalWidget::eventFilter(QObject *obj, QEvent *e)
void FunctionHintProposalWidget::nextPage()
{
d->m_currentHint = (d->m_currentHint + 1) % d->m_totalHints;
+
+ storeSelectedHint();
updateContent();
}
@@ -266,6 +345,8 @@ void FunctionHintProposalWidget::previousPage()
d->m_currentHint = d->m_totalHints - 1;
else
--d->m_currentHint;
+
+ storeSelectedHint();
updateContent();
}
@@ -322,3 +403,5 @@ void FunctionHintProposalWidget::updatePosition()
}
} // TextEditor
+
+Q_DECLARE_METATYPE(TextEditor::SelectedFunctionHints)
diff --git a/src/plugins/texteditor/codeassist/functionhintproposalwidget.h b/src/plugins/texteditor/codeassist/functionhintproposalwidget.h
index d42d1e3e692..21a85395dce 100644
--- a/src/plugins/texteditor/codeassist/functionhintproposalwidget.h
+++ b/src/plugins/texteditor/codeassist/functionhintproposalwidget.h
@@ -63,6 +63,9 @@ private:
void updatePosition();
void abort();
+ int loadSelectedHint() const;
+ void storeSelectedHint();
+
private:
FunctionHintProposalWidgetPrivate *d;
};
diff --git a/src/plugins/texteditor/codeassist/genericproposal.cpp b/src/plugins/texteditor/codeassist/genericproposal.cpp
index 5feac5810b8..33fb0c547f3 100644
--- a/src/plugins/texteditor/codeassist/genericproposal.cpp
+++ b/src/plugins/texteditor/codeassist/genericproposal.cpp
@@ -44,11 +44,6 @@ GenericProposal::GenericProposal(int cursorPos, const QList<AssistProposalItemIn
GenericProposal::~GenericProposal()
{}
-bool GenericProposal::isFragile() const
-{
- return false;
-}
-
bool GenericProposal::hasItemsToPropose(const QString &prefix, AssistReason reason) const
{
if (!prefix.isEmpty()) {
diff --git a/src/plugins/texteditor/codeassist/genericproposal.h b/src/plugins/texteditor/codeassist/genericproposal.h
index 385f9978df7..1155ab52ad4 100644
--- a/src/plugins/texteditor/codeassist/genericproposal.h
+++ b/src/plugins/texteditor/codeassist/genericproposal.h
@@ -40,7 +40,6 @@ public:
GenericProposal(int cursorPos, const QList<AssistProposalItemInterface *> &items);
~GenericProposal();
- bool isFragile() const override;
bool hasItemsToPropose(const QString &prefix, AssistReason reason) const override;
IAssistProposalModel *model() const override;
IAssistProposalWidget *createWidget() const override;
diff --git a/src/plugins/texteditor/codeassist/genericproposalmodel.cpp b/src/plugins/texteditor/codeassist/genericproposalmodel.cpp
index 34a51a4ba13..0357bb80341 100644
--- a/src/plugins/texteditor/codeassist/genericproposalmodel.cpp
+++ b/src/plugins/texteditor/codeassist/genericproposalmodel.cpp
@@ -30,7 +30,7 @@
#include <texteditor/completionsettings.h>
#include <QDebug>
-#include <QRegExp>
+#include <QRegularExpression>
#include <QtAlgorithms>
#include <QHash>
@@ -255,64 +255,15 @@ void GenericProposalModel::filter(const QString &prefix)
if (prefix.isEmpty())
return;
- /*
- * This code builds a regular expression in order to more intelligently match
- * camel-case and underscore names.
- *
- * For any but the first letter, the following replacements are made:
- * A => [a-z0-9_]*A
- * a => (?:[a-zA-Z0-9]*_)?a
- *
- * That means any sequence of lower-case or underscore characters can preceed an
- * upper-case character. And any sequence of lower-case or upper case characters -
- * followed by an underscore can preceed a lower-case character.
- *
- * Examples: (case sensitive mode)
- * gAC matches getActionController
- * gac matches get_action_controller
- *
- * It also implements the fully and first-letter-only case sensitivity.
- */
- const CaseSensitivity caseSensitivity =
- TextEditorSettings::completionSettings().m_caseSensitivity;
-
- QString keyRegExp;
- keyRegExp += QLatin1Char('^');
- bool first = true;
- const QLatin1String uppercaseWordContinuation("[a-z0-9_]*");
- const QLatin1String lowercaseWordContinuation("(?:[a-zA-Z0-9]*_)?");
- foreach (const QChar &c, prefix) {
- if (caseSensitivity == CaseInsensitive ||
- (caseSensitivity == FirstLetterCaseSensitive && !first)) {
-
- keyRegExp += QLatin1String("(?:");
- if (!first)
- keyRegExp += uppercaseWordContinuation;
- keyRegExp += QRegExp::escape(c.toUpper());
- keyRegExp += QLatin1Char('|');
- if (!first)
- keyRegExp += lowercaseWordContinuation;
- keyRegExp += QRegExp::escape(c.toLower());
- keyRegExp += QLatin1Char(')');
- } else {
- if (!first) {
- if (c.isUpper())
- keyRegExp += uppercaseWordContinuation;
- else
- keyRegExp += lowercaseWordContinuation;
- }
- keyRegExp += QRegExp::escape(c);
- }
-
- first = false;
- }
- QRegExp regExp(keyRegExp);
+ const CamelHumpMatcher::CaseSensitivity caseSensitivity =
+ convertCaseSensitivity(TextEditorSettings::completionSettings().m_caseSensitivity);
+ const QRegularExpression regExp = CamelHumpMatcher::createCamelHumpRegExp(prefix, caseSensitivity);
m_currentItems.clear();
const QString lowerPrefix = prefix.toLower();
foreach (const auto &item, m_originalItems) {
const QString &text = item->text();
- if (regExp.indexIn(text) == 0) {
+ if (regExp.match(text).hasMatch()) {
m_currentItems.append(item);
if (text.startsWith(prefix)) {
// Direct match
@@ -328,6 +279,19 @@ void GenericProposalModel::filter(const QString &prefix)
}
}
+CamelHumpMatcher::CaseSensitivity
+ GenericProposalModel::convertCaseSensitivity(TextEditor::CaseSensitivity textEditorCaseSensitivity)
+{
+ switch (textEditorCaseSensitivity) {
+ case TextEditor::CaseSensitive:
+ return CamelHumpMatcher::CaseSensitivity::CaseSensitive;
+ case TextEditor::FirstLetterCaseSensitive:
+ return CamelHumpMatcher::CaseSensitivity::FirstLetterCaseSensitive;
+ default:
+ return CamelHumpMatcher::CaseSensitivity::CaseInsensitive;
+ }
+}
+
bool GenericProposalModel::isSortable(const QString &prefix) const
{
Q_UNUSED(prefix);
diff --git a/src/plugins/texteditor/codeassist/genericproposalmodel.h b/src/plugins/texteditor/codeassist/genericproposalmodel.h
index 32cfd008a80..1a9fd7df572 100644
--- a/src/plugins/texteditor/codeassist/genericproposalmodel.h
+++ b/src/plugins/texteditor/codeassist/genericproposalmodel.h
@@ -28,8 +28,9 @@
#include "iassistproposalmodel.h"
#include "assistenums.h"
+#include <texteditor/completionsettings.h>
#include <texteditor/texteditor_global.h>
-
+#include <utils/camelhumpmatcher.h>
#include <QHash>
#include <QList>
@@ -71,6 +72,8 @@ public:
bool isPrefiltered(const QString &prefix) const;
void setPrefilterPrefix(const QString &prefix);
+ CamelHumpMatcher::CaseSensitivity convertCaseSensitivity(TextEditor::CaseSensitivity textEditorCaseSensitivity);
+
protected:
QList<AssistProposalItemInterface *> m_currentItems;
diff --git a/src/plugins/texteditor/codeassist/iassistproposal.cpp b/src/plugins/texteditor/codeassist/iassistproposal.cpp
index 2880235ac2a..fcbe2e83862 100644
--- a/src/plugins/texteditor/codeassist/iassistproposal.cpp
+++ b/src/plugins/texteditor/codeassist/iassistproposal.cpp
@@ -85,6 +85,11 @@ int IAssistProposal::basePosition() const
return m_basePosition;
}
+bool IAssistProposal::isFragile() const
+{
+ return m_isFragile;
+}
+
/*!
\fn bool TextEditor::IAssistProposal::isCorrective() const
@@ -110,6 +115,11 @@ void IAssistProposal::makeCorrection(TextEditorWidget *editorWidget)
Q_UNUSED(editorWidget);
}
+void IAssistProposal::setFragile(bool fragile)
+{
+ m_isFragile = fragile;
+}
+
/*!
\fn IAssistModel *TextEditor::IAssistProposal::model() const
diff --git a/src/plugins/texteditor/codeassist/iassistproposal.h b/src/plugins/texteditor/codeassist/iassistproposal.h
index 732fe9a4689..4e93993dc26 100644
--- a/src/plugins/texteditor/codeassist/iassistproposal.h
+++ b/src/plugins/texteditor/codeassist/iassistproposal.h
@@ -42,15 +42,17 @@ public:
virtual ~IAssistProposal();
int basePosition() const;
+ bool isFragile() const;
virtual bool hasItemsToPropose(const QString &, AssistReason) const { return true; }
- virtual bool isFragile() const = 0;
virtual bool isCorrective(TextEditorWidget *editorWidget) const;
virtual void makeCorrection(TextEditorWidget *editorWidget);
virtual IAssistProposalModel *model() const = 0;
virtual IAssistProposalWidget *createWidget() const = 0;
+ void setFragile(bool fragile);
protected:
int m_basePosition;
+ bool m_isFragile = false;
};
} // TextEditor
diff --git a/src/plugins/texteditor/codeassist/iassistproposalwidget.cpp b/src/plugins/texteditor/codeassist/iassistproposalwidget.cpp
index 6e3d7d34e05..4be7453bd0a 100644
--- a/src/plugins/texteditor/codeassist/iassistproposalwidget.cpp
+++ b/src/plugins/texteditor/codeassist/iassistproposalwidget.cpp
@@ -55,6 +55,16 @@ IAssistProposalWidget::IAssistProposalWidget()
IAssistProposalWidget::~IAssistProposalWidget()
{}
+int IAssistProposalWidget::basePosition() const
+{
+ return m_basePosition;
+}
+
+void IAssistProposalWidget::setBasePosition(int basePosition)
+{
+ m_basePosition = basePosition;
+}
+
/*!
\fn void TextEditor::IAssistProposalWidget::setAssistant(CodeAssistant *assistant)
diff --git a/src/plugins/texteditor/codeassist/iassistproposalwidget.h b/src/plugins/texteditor/codeassist/iassistproposalwidget.h
index 2f2f6e8bf6c..fd86bb5722b 100644
--- a/src/plugins/texteditor/codeassist/iassistproposalwidget.h
+++ b/src/plugins/texteditor/codeassist/iassistproposalwidget.h
@@ -57,10 +57,16 @@ public:
virtual void updateProposal(const QString &prefix) = 0;
virtual void closeProposal() = 0;
+ int basePosition() const;
+ void setBasePosition(int basePosition);
+
signals:
void prefixExpanded(const QString &newPrefix);
void proposalItemActivated(AssistProposalItemInterface *proposalItem);
void explicitlyAborted();
+
+protected:
+ int m_basePosition = -1;
};
} // TextEditor
diff --git a/src/plugins/texteditor/codeassist/ifunctionhintproposalmodel.cpp b/src/plugins/texteditor/codeassist/ifunctionhintproposalmodel.cpp
index 2a28dfc5a1d..f1685c58d6a 100644
--- a/src/plugins/texteditor/codeassist/ifunctionhintproposalmodel.cpp
+++ b/src/plugins/texteditor/codeassist/ifunctionhintproposalmodel.cpp
@@ -25,6 +25,8 @@
#include "ifunctionhintproposalmodel.h"
+#include <QString>
+
using namespace TextEditor;
IFunctionHintProposalModel::IFunctionHintProposalModel()
@@ -32,3 +34,8 @@ IFunctionHintProposalModel::IFunctionHintProposalModel()
IFunctionHintProposalModel::~IFunctionHintProposalModel()
{}
+
+QString IFunctionHintProposalModel::id(int /*index*/) const
+{
+ return QString();
+}
diff --git a/src/plugins/texteditor/codeassist/ifunctionhintproposalmodel.h b/src/plugins/texteditor/codeassist/ifunctionhintproposalmodel.h
index 1af6bf12196..fe329e7c822 100644
--- a/src/plugins/texteditor/codeassist/ifunctionhintproposalmodel.h
+++ b/src/plugins/texteditor/codeassist/ifunctionhintproposalmodel.h
@@ -29,6 +29,8 @@
#include <texteditor/texteditor_global.h>
+QT_FORWARD_DECLARE_CLASS(QString);
+
namespace TextEditor {
class TEXTEDITOR_EXPORT IFunctionHintProposalModel : public IAssistProposalModel
@@ -38,6 +40,7 @@ public:
~IFunctionHintProposalModel();
virtual int activeArgument(const QString &prefix) const = 0;
+ virtual QString id(int index) const;
};
} // TextEditor
diff --git a/src/plugins/texteditor/codeassist/runner.cpp b/src/plugins/texteditor/codeassist/runner.cpp
index d801a593418..2306ecd328d 100644
--- a/src/plugins/texteditor/codeassist/runner.cpp
+++ b/src/plugins/texteditor/codeassist/runner.cpp
@@ -33,10 +33,6 @@ using namespace TextEditor;
using namespace Internal;
ProcessorRunner::ProcessorRunner()
- : m_processor(0)
- , m_interface(0)
- , m_discardProposal(false)
- , m_proposal(0)
{}
ProcessorRunner::~ProcessorRunner()
diff --git a/src/plugins/texteditor/codeassist/runner.h b/src/plugins/texteditor/codeassist/runner.h
index 6dcdf5e0e40..48ede437533 100644
--- a/src/plugins/texteditor/codeassist/runner.h
+++ b/src/plugins/texteditor/codeassist/runner.h
@@ -54,11 +54,11 @@ public:
IAssistProposal *proposal() const;
private:
- IAssistProcessor *m_processor;
- AssistInterface *m_interface;
- bool m_discardProposal;
- IAssistProposal *m_proposal;
- AssistReason m_reason;
+ IAssistProcessor *m_processor = nullptr;
+ AssistInterface *m_interface = nullptr;
+ bool m_discardProposal = false;
+ IAssistProposal *m_proposal = nullptr;
+ AssistReason m_reason = IdleEditor;
};
} // Internal
diff --git a/src/plugins/texteditor/fontsettingspage.cpp b/src/plugins/texteditor/fontsettingspage.cpp
index 18d324a7e8c..64d1209a7c9 100644
--- a/src/plugins/texteditor/fontsettingspage.cpp
+++ b/src/plugins/texteditor/fontsettingspage.cpp
@@ -349,7 +349,7 @@ QWidget *FontSettingsPage::widget()
d_ptr->m_ui = new Ui::FontSettingsPage;
d_ptr->m_ui->setupUi(d_ptr->m_widget);
d_ptr->m_ui->colorSchemeGroupBox->setTitle(
- tr("Color Scheme for Qt Creator Theme \"%1\"")
+ tr("Color Scheme for Theme \"%1\"")
.arg(Utils::creatorTheme()->displayName()));
d_ptr->m_ui->schemeComboBox->setModel(d_ptr->m_schemeListModel);
diff --git a/src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.cpp b/src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.cpp
index 00652390326..c9d83b6893a 100644
--- a/src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.cpp
+++ b/src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.cpp
@@ -352,7 +352,8 @@ void HighlightDefinitionHandler::keywordStarted(const QXmlAttributes &atts)
// Handle broken files. makefile.xml references an invalid list.
Core::MessageManager::write(
QCoreApplication::translate("GenericHighlighter",
- "Generic highlighter warning: ") + e.message());
+ "Generic highlighter warning: %1")
+ .arg(e.message()));
}
rule->setInsensitive(atts.value(kInsensitive));
ruleElementStarted(atts, QSharedPointer<Rule>(rule));
diff --git a/src/plugins/texteditor/generichighlighter/highlighter.cpp b/src/plugins/texteditor/generichighlighter/highlighter.cpp
index b2a12fb02fd..2902f09a635 100644
--- a/src/plugins/texteditor/generichighlighter/highlighter.cpp
+++ b/src/plugins/texteditor/generichighlighter/highlighter.cpp
@@ -253,8 +253,9 @@ void Highlighter::highlightBlock(const QString &text)
} catch (const HighlighterException &e) {
Core::MessageManager::write(
QCoreApplication::translate("GenericHighlighter",
- "Generic highlighter error: ") + e.message(),
- Core::MessageManager::WithFocus);
+ "Generic highlighter error: %1")
+ .arg(e.message()),
+ Core::MessageManager::WithFocus);
m_isBroken = true;
}
}
diff --git a/src/plugins/texteditor/generichighlighter/specificrules.h b/src/plugins/texteditor/generichighlighter/specificrules.h
index 674c3fbd7b9..051ab81d26e 100644
--- a/src/plugins/texteditor/generichighlighter/specificrules.h
+++ b/src/plugins/texteditor/generichighlighter/specificrules.h
@@ -107,14 +107,13 @@ private:
virtual void doReplaceExpressions(const QStringList &captures);
QString m_string;
- int m_length;
- Qt::CaseSensitivity m_caseSensitivity;
+ int m_length = 0;
+ Qt::CaseSensitivity m_caseSensitivity = Qt::CaseSensitive;
};
class RegExprRule : public DynamicRule
{
public:
- RegExprRule() : m_onlyBegin(false), m_isCached(false) {}
virtual ~RegExprRule() {}
void setPattern(const QString &pattern);
@@ -131,10 +130,10 @@ private:
bool isExactMatch(ProgressData *progress);
- bool m_onlyBegin;
- bool m_isCached;
- int m_offset;
- int m_length;
+ bool m_onlyBegin = false;
+ bool m_isCached = false;
+ int m_offset = 0;
+ int m_length = 0;
QStringList m_captures;
QRegExp m_expression;
};
diff --git a/src/plugins/texteditor/helpitem.h b/src/plugins/texteditor/helpitem.h
index f7ea8ee4f3a..2618f7f5e47 100644
--- a/src/plugins/texteditor/helpitem.h
+++ b/src/plugins/texteditor/helpitem.h
@@ -75,7 +75,7 @@ private:
private:
QString m_helpId;
QString m_docMark;
- Category m_category;
+ Category m_category = Unknown;
mutable QMap<QString, QUrl> m_helpLinks; // cached help links
};
diff --git a/src/plugins/texteditor/linenumberfilter.h b/src/plugins/texteditor/linenumberfilter.h
index de35e95696c..6643e218f01 100644
--- a/src/plugins/texteditor/linenumberfilter.h
+++ b/src/plugins/texteditor/linenumberfilter.h
@@ -51,7 +51,7 @@ public:
void refresh(QFutureInterface<void> &) override {}
private:
- bool m_hasCurrentEditor;
+ bool m_hasCurrentEditor = false;
};
} // namespace Internal
diff --git a/src/plugins/texteditor/outlinefactory.cpp b/src/plugins/texteditor/outlinefactory.cpp
index 31eeabde175..0b047890992 100644
--- a/src/plugins/texteditor/outlinefactory.cpp
+++ b/src/plugins/texteditor/outlinefactory.cpp
@@ -62,7 +62,11 @@ OutlineWidgetStack::OutlineWidgetStack(OutlineFactory *factory) :
connect(m_toggleSync, &QAbstractButton::clicked,
this, &OutlineWidgetStack::toggleCursorSynchronization);
- m_filterButton = new QToolButton;
+ m_filterButton = new QToolButton(this);
+ // The ToolButton needs a parent because updateFilterMenu() sets
+ // it visible. That would open a top-level window if the button
+ // did not have a parent in that moment.
+
m_filterButton->setIcon(Utils::Icons::FILTER.icon());
m_filterButton->setToolTip(tr("Filter tree"));
m_filterButton->setPopupMode(QToolButton::InstantPopup);
diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp
index 7c53c812962..1bb79b9e83a 100644
--- a/src/plugins/texteditor/textdocument.cpp
+++ b/src/plugins/texteditor/textdocument.cpp
@@ -25,7 +25,6 @@
#include "textdocument.h"
-#include "convenience.h"
#include "extraencodingsettings.h"
#include "fontsettings.h"
#include "indenter.h"
@@ -39,6 +38,7 @@
#include <texteditor/generichighlighter/highlighter.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/documentmodel.h>
+#include <utils/textutils.h>
#include <utils/guard.h>
#include <utils/mimetypes/mimedatabase.h>
@@ -303,7 +303,7 @@ QString TextDocument::plainText() const
QString TextDocument::textAt(int pos, int length) const
{
- return Convenience::textAt(QTextCursor(document()), pos, length);
+ return Utils::Text::textAt(QTextCursor(document()), pos, length);
}
QChar TextDocument::characterAt(int pos) const
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index f237c0f7ed8..80365d7449c 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -37,7 +37,6 @@
#include "circularclipboardassist.h"
#include "codecselector.h"
#include "completionsettings.h"
-#include "convenience.h"
#include "highlighterutils.h"
#include "icodestylepreferences.h"
#include "indenter.h"
@@ -77,6 +76,7 @@
#include <coreplugin/find/highlightscrollbar.h>
#include <utils/algorithm.h>
#include <utils/asconst.h>
+#include <utils/textutils.h>
#include <utils/linecolumnlabel.h>
#include <utils/fileutils.h>
#include <utils/dropsupport.h>
@@ -154,6 +154,7 @@ namespace Internal {
enum { NExtraSelectionKinds = 12 };
typedef QString (TransformationMethod)(const QString &);
+typedef void (ListTransformationMethod)(QStringList &);
static QString QString_toUpper(const QString &str)
{
@@ -247,7 +248,7 @@ class BaseTextEditorPrivate
public:
BaseTextEditorPrivate() {}
- TextEditorFactoryPrivate *m_origin;
+ TextEditorFactoryPrivate *m_origin = nullptr;
};
class HoverHandlerRunner
@@ -266,7 +267,7 @@ public:
// Does the last handler still applies?
const int documentRevision = textCursor.document()->revision();
- const int position = Convenience::wordStartCursor(textCursor).position();
+ const int position = Text::wordStartCursor(textCursor).position();
if (m_lastHandlerInfo.applies(documentRevision, position)) {
m_lastHandlerInfo.handler->showToolTip(m_widget, point, /*decorate=*/ false);
return;
@@ -419,6 +420,8 @@ public:
void transformSelection(TransformationMethod method);
void transformBlockSelection(TransformationMethod method);
+ void transformSelectedLines(ListTransformationMethod method);
+
void slotUpdateExtraAreaWidth();
void slotUpdateRequest(const QRect &r, int dy);
void slotUpdateBlockNotify(const QTextBlock &);
@@ -565,7 +568,7 @@ public:
void disableBlockSelection(BlockSelectionUpdateKind kind);
void resetCursorFlashTimer();
QBasicTimer m_cursorFlashTimer;
- bool m_cursorVisible;
+ bool m_cursorVisible = true;
bool m_moveLineUndoHack = false;
QTextCursor m_findScopeStart;
@@ -1159,19 +1162,37 @@ void TextEditorWidgetPrivate::updateCannotDecodeInfo()
}
}
+// Skip over shebang to license header (Python, Perl, sh)
+// '#!/bin/sh'
+// ''
+// '###############'
+
+static QTextBlock skipShebang(const QTextBlock &block)
+{
+ if (!block.isValid() || !block.text().startsWith("#!"))
+ return block;
+ const QTextBlock nextBlock1 = block.next();
+ if (!nextBlock1.isValid() || !nextBlock1.text().isEmpty())
+ return block;
+ const QTextBlock nextBlock2 = nextBlock1.next();
+ return nextBlock2.isValid() && nextBlock2.text().startsWith('#') ? nextBlock2 : block;
+}
+
/*
- Collapses the first comment in a file, if there is only whitespace above
+ Collapses the first comment in a file, if there is only whitespace/shebang line
+ above
*/
void TextEditorWidgetPrivate::foldLicenseHeader()
{
QTextDocument *doc = q->document();
TextDocumentLayout *documentLayout = qobject_cast<TextDocumentLayout*>(doc->documentLayout());
QTC_ASSERT(documentLayout, return);
- QTextBlock block = doc->firstBlock();
+ QTextBlock block = skipShebang(doc->firstBlock());
while (block.isValid() && block.isVisible()) {
QString text = block.text();
if (TextDocumentLayout::canFold(block) && block.next().isVisible()) {
- if (text.trimmed().startsWith(QLatin1String("/*"))) {
+ const QString trimmedText = text.trimmed();
+ if (trimmedText.startsWith("/*") || trimmedText.startsWith('#')) {
TextDocumentLayout::doFoldOrUnfold(block, false);
moveCursorVisible();
documentLayout->requestUpdate();
@@ -1427,7 +1448,7 @@ bool TextEditorWidget::selectBlockUp()
if (!TextBlockUserData::findNextClosingParenthesis(&cursor, true))
return false;
- setTextCursor(Convenience::flippedCursor(cursor));
+ setTextCursor(Text::flippedCursor(cursor));
d->_q_matchParentheses();
return true;
}
@@ -1452,7 +1473,7 @@ bool TextEditorWidget::selectBlockDown()
if ( cursor != d->m_selectBlockAnchor)
TextBlockUserData::findNextClosingParenthesis(&cursor, true);
- setTextCursor(Convenience::flippedCursor(cursor));
+ setTextCursor(Text::flippedCursor(cursor));
d->_q_matchParentheses();
return true;
}
@@ -1616,6 +1637,11 @@ void TextEditorWidget::lowercaseSelection()
d->transformSelection(&QString_toLower);
}
+void TextEditorWidget::sortSelectedLines()
+{
+ d->transformSelectedLines([](QStringList &list) { list.sort(); });
+}
+
void TextEditorWidget::indent()
{
int offset = 0;
@@ -2776,7 +2802,7 @@ QRect TextEditorWidget::cursorRect(int pos) const
void TextEditorWidget::convertPosition(int pos, int *line, int *column) const
{
- Convenience::convertPosition(document(), pos, line, column);
+ Text::convertPosition(document(), pos, line, column);
}
bool TextEditorWidget::event(QEvent *e)
@@ -7892,6 +7918,41 @@ void TextEditorWidgetPrivate::transformBlockSelection(TransformationMethod metho
enableBlockSelection(positionBlock, anchorColumn, anchorBlock, positionColumn);
}
+void TextEditorWidgetPrivate::transformSelectedLines(ListTransformationMethod method)
+{
+ if (!method || q->hasBlockSelection())
+ return;
+
+ QTextCursor cursor = q->textCursor();
+ if (!cursor.hasSelection())
+ return;
+
+ const bool downwardDirection = cursor.anchor() < cursor.position();
+ int startPosition = cursor.selectionStart();
+ int endPosition = cursor.selectionEnd();
+
+ cursor.setPosition(startPosition);
+ cursor.movePosition(QTextCursor::StartOfBlock);
+ startPosition = cursor.position();
+
+ cursor.setPosition(endPosition, QTextCursor::KeepAnchor);
+ if (cursor.positionInBlock() == 0)
+ cursor.movePosition(QTextCursor::PreviousBlock, QTextCursor::KeepAnchor);
+ cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ endPosition = qMax(cursor.position(), endPosition);
+
+ const QString text = cursor.selectedText();
+ QStringList lines = text.split(QChar::ParagraphSeparator);
+ method(lines);
+ cursor.insertText(lines.join(QChar::ParagraphSeparator));
+
+ // (re)select the changed lines
+ // Note: this assumes the transformation did not change the length
+ cursor.setPosition(downwardDirection ? startPosition : endPosition);
+ cursor.setPosition(downwardDirection ? endPosition : startPosition, QTextCursor::KeepAnchor);
+ q->setTextCursor(cursor);
+}
+
void TextEditorWidget::inSnippetMode(bool *active)
{
*active = d->m_snippetOverlay->isVisible();
diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h
index f6fb8644045..b5365ad3279 100644
--- a/src/plugins/texteditor/texteditor.h
+++ b/src/plugins/texteditor/texteditor.h
@@ -423,6 +423,8 @@ public:
void uppercaseSelection();
void lowercaseSelection();
+ void sortSelectedLines();
+
void cleanWhitespace();
void indent();
diff --git a/src/plugins/texteditor/texteditor.pro b/src/plugins/texteditor/texteditor.pro
index 1ef00e05174..d83d1654432 100644
--- a/src/plugins/texteditor/texteditor.pro
+++ b/src/plugins/texteditor/texteditor.pro
@@ -77,7 +77,6 @@ SOURCES += texteditorplugin.cpp \
snippets/snippetassistcollector.cpp \
codeassist/assistinterface.cpp \
codeassist/assistproposalitem.cpp \
- convenience.cpp \
codeassist/runner.cpp \
codeassist/completionassistprovider.cpp \
codeassist/genericproposalmodel.cpp \
@@ -187,7 +186,6 @@ HEADERS += texteditorplugin.h \
snippets/snippetassistcollector.h \
codeassist/assistinterface.h \
codeassist/assistproposalitem.h \
- convenience.h \
codeassist/assistenums.h \
codeassist/runner.h \
codeassist/assistproposaliteminterface.h \
diff --git a/src/plugins/texteditor/texteditor.qbs b/src/plugins/texteditor/texteditor.qbs
index 2b5f43e2478..1dfbde68a85 100644
--- a/src/plugins/texteditor/texteditor.qbs
+++ b/src/plugins/texteditor/texteditor.qbs
@@ -58,8 +58,6 @@ Project {
"completionsettingspage.cpp",
"completionsettingspage.h",
"completionsettingspage.ui",
- "convenience.cpp",
- "convenience.h",
"displaysettings.cpp",
"displaysettings.h",
"displaysettingspage.cpp",
diff --git a/src/plugins/texteditor/texteditor_test.cpp b/src/plugins/texteditor/texteditor_test.cpp
index c5e81ec3af4..78b8564e439 100644
--- a/src/plugins/texteditor/texteditor_test.cpp
+++ b/src/plugins/texteditor/texteditor_test.cpp
@@ -44,10 +44,10 @@ enum TransFormationType { Uppercase, Lowercase };
struct TestBlockSelection
{
- int positionBlock;
- int positionColumn;
- int anchorBlock;
- int anchorColumn;
+ int positionBlock = 0;
+ int positionColumn = 0;
+ int anchorBlock = 0;
+ int anchorColumn = 0;
TestBlockSelection(int positionBlock, int positionColumn, int anchorBlock, int anchorColumn)
: positionBlock(positionBlock), positionColumn(positionColumn)
, anchorBlock(anchorBlock), anchorColumn(anchorColumn) {}
diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp
index cb2515acec8..be12984f67a 100644
--- a/src/plugins/texteditor/texteditoractionhandler.cpp
+++ b/src/plugins/texteditor/texteditoractionhandler.cpp
@@ -176,6 +176,7 @@ public:
QAction *m_insertLineBelowAction = nullptr;
QAction *m_upperCaseSelectionAction = nullptr;
QAction *m_lowerCaseSelectionAction = nullptr;
+ QAction *m_sortSelectedLinesAction = nullptr;
QAction *m_indentAction = nullptr;
QAction *m_unindentAction = nullptr;
QAction *m_followSymbolAction = nullptr;
@@ -214,18 +215,18 @@ void TextEditorActionHandlerPrivate::createActions()
using namespace TextEditor::Constants;
m_undoAction = registerAction(UNDO,
- [this] (TextEditorWidget *w) { w->undo(); }, true, tr("&Undo"));
+ [] (TextEditorWidget *w) { w->undo(); }, true, tr("&Undo"));
m_redoAction = registerAction(REDO,
- [this] (TextEditorWidget *w) { w->redo(); }, true, tr("&Redo"));
+ [] (TextEditorWidget *w) { w->redo(); }, true, tr("&Redo"));
m_copyAction = registerAction(COPY,
- [this] (TextEditorWidget *w) { w->copy(); }, true);
+ [] (TextEditorWidget *w) { w->copy(); }, true);
m_cutAction = registerAction(CUT,
- [this] (TextEditorWidget *w) { w->cut(); }, true);
+ [] (TextEditorWidget *w) { w->cut(); }, true);
m_pasteAction = registerAction(PASTE,
- [this] (TextEditorWidget *w) { w->paste(); }, true);
+ [] (TextEditorWidget *w) { w->paste(); }, true);
m_selectAllAction = registerAction(SELECTALL,
- [this] (TextEditorWidget *w) { w->selectAll(); }, true);
- m_gotoAction = registerAction(GOTO, [this] (TextEditorWidget *) {
+ [] (TextEditorWidget *w) { w->selectAll(); }, true);
+ m_gotoAction = registerAction(GOTO, [] (TextEditorWidget *) {
QString locatorString = TextEditorPlugin::lineNumberFilter()->shortcutString();
locatorString += QLatin1Char(' ');
const int selectionStart = locatorString.size();
@@ -233,101 +234,101 @@ void TextEditorActionHandlerPrivate::createActions()
Core::LocatorManager::show(locatorString, selectionStart, locatorString.size() - selectionStart);
});
m_printAction = registerAction(PRINT,
- [this] (TextEditorWidget *widget) { widget->print(Core::ICore::printer()); });
+ [] (TextEditorWidget *widget) { widget->print(Core::ICore::printer()); });
m_deleteLineAction = registerAction(DELETE_LINE,
- [this] (TextEditorWidget *w) { w->deleteLine(); }, true, tr("Delete &Line"));
+ [] (TextEditorWidget *w) { w->deleteLine(); }, true, tr("Delete &Line"));
m_deleteEndOfLineAction = registerAction(DELETE_END_OF_LINE,
- [this] (TextEditorWidget *w) { w->deleteEndOfLine(); }, true, tr("Delete Line from Cursor On"));
+ [] (TextEditorWidget *w) { w->deleteEndOfLine(); }, true, tr("Delete Line from Cursor On"));
m_deleteEndOfWordAction = registerAction(DELETE_END_OF_WORD,
- [this] (TextEditorWidget *w) { w->deleteEndOfWord(); }, true, tr("Delete Word from Cursor On"));
+ [] (TextEditorWidget *w) { w->deleteEndOfWord(); }, true, tr("Delete Word from Cursor On"));
m_deleteEndOfWordCamelCaseAction = registerAction(DELETE_END_OF_WORD_CAMEL_CASE,
- [this] (TextEditorWidget *w) { w->deleteEndOfWordCamelCase(); }, true, tr("Delete Word Camel Case from Cursor On"));
+ [] (TextEditorWidget *w) { w->deleteEndOfWordCamelCase(); }, true, tr("Delete Word Camel Case from Cursor On"));
m_deleteStartOfLineAction = registerAction(DELETE_START_OF_LINE,
- [this] (TextEditorWidget *w) { w->deleteStartOfLine(); }, true, tr("Delete Line up to Cursor"));
+ [] (TextEditorWidget *w) { w->deleteStartOfLine(); }, true, tr("Delete Line up to Cursor"));
m_deleteStartOfWordAction = registerAction(DELETE_START_OF_WORD,
- [this] (TextEditorWidget *w) { w->deleteStartOfWord(); }, true, tr("Delete Word up to Cursor"));
+ [] (TextEditorWidget *w) { w->deleteStartOfWord(); }, true, tr("Delete Word up to Cursor"));
m_deleteStartOfWordCamelCaseAction = registerAction(DELETE_START_OF_WORD_CAMEL_CASE,
- [this] (TextEditorWidget *w) { w->deleteStartOfWordCamelCase(); }, true, tr("Delete Word Camel Case up to Cursor"));
+ [] (TextEditorWidget *w) { w->deleteStartOfWordCamelCase(); }, true, tr("Delete Word Camel Case up to Cursor"));
m_gotoBlockStartWithSelectionAction = registerAction(GOTO_BLOCK_START_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoBlockStartWithSelection(); }, true, tr("Go to Block Start with Selection"),
+ [] (TextEditorWidget *w) { w->gotoBlockStartWithSelection(); }, true, tr("Go to Block Start with Selection"),
QKeySequence(tr("Ctrl+{")));
m_gotoBlockEndWithSelectionAction = registerAction(GOTO_BLOCK_END_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoBlockEndWithSelection(); }, true, tr("Go to Block End with Selection"),
+ [] (TextEditorWidget *w) { w->gotoBlockEndWithSelection(); }, true, tr("Go to Block End with Selection"),
QKeySequence(tr("Ctrl+}")));
m_moveLineUpAction = registerAction(MOVE_LINE_UP,
- [this] (TextEditorWidget *w) { w->moveLineUp(); }, true, tr("Move Line Up"),
+ [] (TextEditorWidget *w) { w->moveLineUp(); }, true, tr("Move Line Up"),
QKeySequence(tr("Ctrl+Shift+Up")));
m_moveLineDownAction = registerAction(MOVE_LINE_DOWN,
- [this] (TextEditorWidget *w) { w->moveLineDown(); }, true, tr("Move Line Down"),
+ [] (TextEditorWidget *w) { w->moveLineDown(); }, true, tr("Move Line Down"),
QKeySequence(tr("Ctrl+Shift+Down")));
m_copyLineUpAction = registerAction(COPY_LINE_UP,
- [this] (TextEditorWidget *w) { w->copyLineUp(); }, true, tr("Copy Line Up"),
+ [] (TextEditorWidget *w) { w->copyLineUp(); }, true, tr("Copy Line Up"),
QKeySequence(tr("Ctrl+Alt+Up")));
m_copyLineDownAction = registerAction(COPY_LINE_DOWN,
- [this] (TextEditorWidget *w) { w->copyLineDown(); }, true, tr("Copy Line Down"),
+ [] (TextEditorWidget *w) { w->copyLineDown(); }, true, tr("Copy Line Down"),
QKeySequence(tr("Ctrl+Alt+Down")));
m_joinLinesAction = registerAction(JOIN_LINES,
- [this] (TextEditorWidget *w) { w->joinLines(); }, true, tr("Join Lines"),
+ [] (TextEditorWidget *w) { w->joinLines(); }, true, tr("Join Lines"),
QKeySequence(tr("Ctrl+J")));
m_insertLineAboveAction = registerAction(INSERT_LINE_ABOVE,
- [this] (TextEditorWidget *w) { w->insertLineAbove(); }, true, tr("Insert Line Above Current Line"),
+ [] (TextEditorWidget *w) { w->insertLineAbove(); }, true, tr("Insert Line Above Current Line"),
QKeySequence(tr("Ctrl+Shift+Return")));
m_insertLineBelowAction = registerAction(INSERT_LINE_BELOW,
- [this] (TextEditorWidget *w) { w->insertLineBelow(); }, true, tr("Insert Line Below Current Line"),
+ [] (TextEditorWidget *w) { w->insertLineBelow(); }, true, tr("Insert Line Below Current Line"),
QKeySequence(tr("Ctrl+Return")));
m_switchUtf8bomAction = registerAction(SWITCH_UTF8BOM,
- [this] (TextEditorWidget *w) { w->switchUtf8bom(); }, true, tr("Toggle UTF-8 BOM"));
+ [] (TextEditorWidget *w) { w->switchUtf8bom(); }, true, tr("Toggle UTF-8 BOM"));
m_indentAction = registerAction(INDENT,
- [this] (TextEditorWidget *w) { w->indent(); }, true, tr("Indent"));
+ [] (TextEditorWidget *w) { w->indent(); }, true, tr("Indent"));
m_unindentAction = registerAction(UNINDENT,
- [this] (TextEditorWidget *w) { w->unindent(); }, true, tr("Unindent"));
+ [] (TextEditorWidget *w) { w->unindent(); }, true, tr("Unindent"));
m_followSymbolAction = registerAction(FOLLOW_SYMBOL_UNDER_CURSOR,
- [this] (TextEditorWidget *w) { w->openLinkUnderCursor(); }, true, tr("Follow Symbol Under Cursor"),
+ [] (TextEditorWidget *w) { w->openLinkUnderCursor(); }, true, tr("Follow Symbol Under Cursor"),
QKeySequence(Qt::Key_F2));
m_followSymbolInNextSplitAction = registerAction(FOLLOW_SYMBOL_UNDER_CURSOR_IN_NEXT_SPLIT,
- [this] (TextEditorWidget *w) { w->openLinkUnderCursorInNextSplit(); }, true, tr("Follow Symbol Under Cursor in Next Split"),
+ [] (TextEditorWidget *w) { w->openLinkUnderCursorInNextSplit(); }, true, tr("Follow Symbol Under Cursor in Next Split"),
QKeySequence(Utils::HostOsInfo::isMacHost() ? tr("Meta+E, F2") : tr("Ctrl+E, F2")));
m_jumpToFileAction = registerAction(JUMP_TO_FILE_UNDER_CURSOR,
- [this] (TextEditorWidget *w) { w->openLinkUnderCursor(); }, true, tr("Jump to File Under Cursor"),
+ [] (TextEditorWidget *w) { w->openLinkUnderCursor(); }, true, tr("Jump to File Under Cursor"),
QKeySequence(Qt::Key_F2));
m_jumpToFileInNextSplitAction = registerAction(JUMP_TO_FILE_UNDER_CURSOR_IN_NEXT_SPLIT,
- [this] (TextEditorWidget *w) { w->openLinkUnderCursorInNextSplit(); }, true, tr("Jump to File Under Cursor in Next Split"),
+ [] (TextEditorWidget *w) { w->openLinkUnderCursorInNextSplit(); }, true, tr("Jump to File Under Cursor in Next Split"),
QKeySequence(Utils::HostOsInfo::isMacHost() ? tr("Meta+E, F2") : tr("Ctrl+E, F2")).toString());
m_viewPageUpAction = registerAction(VIEW_PAGE_UP,
- [this] (TextEditorWidget *w) { w->viewPageUp(); }, true, tr("Move the View a Page Up and Keep the Cursor Position"),
+ [] (TextEditorWidget *w) { w->viewPageUp(); }, true, tr("Move the View a Page Up and Keep the Cursor Position"),
QKeySequence(tr("Ctrl+PgUp")));
m_viewPageDownAction = registerAction(VIEW_PAGE_DOWN,
- [this] (TextEditorWidget *w) { w->viewPageDown(); }, true, tr("Move the View a Page Down and Keep the Cursor Position"),
+ [] (TextEditorWidget *w) { w->viewPageDown(); }, true, tr("Move the View a Page Down and Keep the Cursor Position"),
QKeySequence(tr("Ctrl+PgDown")));
m_viewLineUpAction = registerAction(VIEW_LINE_UP,
- [this] (TextEditorWidget *w) { w->viewLineUp(); }, true, tr("Move the View a Line Up and Keep the Cursor Position"),
+ [] (TextEditorWidget *w) { w->viewLineUp(); }, true, tr("Move the View a Line Up and Keep the Cursor Position"),
QKeySequence(tr("Ctrl+Up")));
m_viewLineDownAction = registerAction(VIEW_LINE_DOWN,
- [this] (TextEditorWidget *w) { w->viewLineDown(); }, true, tr("Move the View a Line Down and Keep the Cursor Position"),
+ [] (TextEditorWidget *w) { w->viewLineDown(); }, true, tr("Move the View a Line Down and Keep the Cursor Position"),
QKeySequence(tr("Ctrl+Down")));
// register "Edit" Menu Actions
Core::ActionContainer *editMenu = Core::ActionManager::actionContainer(M_EDIT);
m_selectEncodingAction = registerAction(SELECT_ENCODING,
- [this] (TextEditorWidget *w) { w->selectEncoding(); }, false, tr("Select Encoding..."),
+ [] (TextEditorWidget *w) { w->selectEncoding(); }, false, tr("Select Encoding..."),
QKeySequence(), G_EDIT_OTHER, editMenu);
m_circularPasteAction = registerAction(CIRCULAR_PASTE,
- [this] (TextEditorWidget *w) { w->circularPaste(); }, false, tr("Paste from Clipboard History"),
+ [] (TextEditorWidget *w) { w->circularPaste(); }, false, tr("Paste from Clipboard History"),
QKeySequence(tr("Ctrl+Shift+V")), G_EDIT_COPYPASTE, editMenu);
// register "Edit -> Advanced" Menu Actions
Core::ActionContainer *advancedEditMenu = Core::ActionManager::actionContainer(M_EDIT_ADVANCED);
m_formatAction = registerAction(AUTO_INDENT_SELECTION,
- [this] (TextEditorWidget *w) { w->format(); }, true, tr("Auto-&indent Selection"),
+ [] (TextEditorWidget *w) { w->format(); }, true, tr("Auto-&indent Selection"),
QKeySequence(tr("Ctrl+I")),
G_EDIT_FORMAT, advancedEditMenu);
m_rewrapParagraphAction = registerAction(REWRAP_PARAGRAPH,
- [this] (TextEditorWidget *w) { w->rewrapParagraph(); }, true, tr("&Rewrap Paragraph"),
+ [] (TextEditorWidget *w) { w->rewrapParagraph(); }, true, tr("&Rewrap Paragraph"),
QKeySequence(Core::UseMacShortcuts ? tr("Meta+E, R") : tr("Ctrl+E, R")),
G_EDIT_FORMAT, advancedEditMenu);
m_visualizeWhitespaceAction = registerBoolAction(VISUALIZE_WHITESPACE,
- [this] (TextEditorWidget *widget, bool checked) {
+ [] (TextEditorWidget *widget, bool checked) {
if (widget) {
DisplaySettings ds = widget->displaySettings();
ds.m_visualizeWhitespace = checked;
@@ -339,11 +340,11 @@ void TextEditorActionHandlerPrivate::createActions()
G_EDIT_FORMAT, advancedEditMenu);
m_visualizeWhitespaceAction->setCheckable(true);
m_cleanWhitespaceAction = registerAction(CLEAN_WHITESPACE,
- [this] (TextEditorWidget *w) { w->cleanWhitespace(); }, true, tr("Clean Whitespace"),
+ [] (TextEditorWidget *w) { w->cleanWhitespace(); }, true, tr("Clean Whitespace"),
QKeySequence(),
G_EDIT_FORMAT, advancedEditMenu);
m_textWrappingAction = registerBoolAction(TEXT_WRAPPING,
- [this] (TextEditorWidget *widget, bool checked) {
+ [] (TextEditorWidget *widget, bool checked) {
if (widget) {
DisplaySettings ds = widget->displaySettings();
ds.m_textWrapping = checked;
@@ -355,120 +356,124 @@ void TextEditorActionHandlerPrivate::createActions()
G_EDIT_FORMAT, advancedEditMenu);
m_textWrappingAction->setCheckable(true);
m_unCommentSelectionAction = registerAction(UN_COMMENT_SELECTION,
- [this] (TextEditorWidget *w) { w->unCommentSelection(); }, true, tr("Toggle Comment &Selection"),
+ [] (TextEditorWidget *w) { w->unCommentSelection(); }, true, tr("Toggle Comment &Selection"),
QKeySequence(tr("Ctrl+/")),
G_EDIT_FORMAT, advancedEditMenu);
m_cutLineAction = registerAction(CUT_LINE,
- [this] (TextEditorWidget *w) { w->cutLine(); }, true, tr("Cut &Line"),
+ [] (TextEditorWidget *w) { w->cutLine(); }, true, tr("Cut &Line"),
QKeySequence(tr("Shift+Del")),
G_EDIT_TEXT, advancedEditMenu);
m_copyLineAction = registerAction(COPY_LINE,
- [this] (TextEditorWidget *w) { w->copyLine(); }, false, tr("Copy &Line"),
+ [] (TextEditorWidget *w) { w->copyLine(); }, false, tr("Copy &Line"),
QKeySequence(tr("Ctrl+Ins")),
G_EDIT_TEXT, advancedEditMenu);
m_duplicateSelectionAction = registerAction(DUPLICATE_SELECTION,
- [this] (TextEditorWidget *w) { w->duplicateSelection(); }, false, tr("&Duplicate Selection"),
+ [] (TextEditorWidget *w) { w->duplicateSelection(); }, false, tr("&Duplicate Selection"),
QKeySequence(),
G_EDIT_TEXT, advancedEditMenu);
m_duplicateSelectionAndCommentAction = registerAction(DUPLICATE_SELECTION_AND_COMMENT,
- [this] (TextEditorWidget *w) { w->duplicateSelectionAndComment(); }, false, tr("&Duplicate Selection and Comment"),
+ [] (TextEditorWidget *w) { w->duplicateSelectionAndComment(); }, false, tr("&Duplicate Selection and Comment"),
QKeySequence(),
G_EDIT_TEXT, advancedEditMenu);
m_upperCaseSelectionAction = registerAction(UPPERCASE_SELECTION,
- [this] (TextEditorWidget *w) { w->uppercaseSelection(); }, true, tr("Uppercase Selection"),
+ [] (TextEditorWidget *w) { w->uppercaseSelection(); }, true, tr("Uppercase Selection"),
QKeySequence(Core::UseMacShortcuts ? tr("Meta+Shift+U") : tr("Alt+Shift+U")),
G_EDIT_TEXT, advancedEditMenu);
m_lowerCaseSelectionAction = registerAction(LOWERCASE_SELECTION,
- [this] (TextEditorWidget *w) { w->lowercaseSelection(); }, true, tr("Lowercase Selection"),
+ [] (TextEditorWidget *w) { w->lowercaseSelection(); }, true, tr("Lowercase Selection"),
QKeySequence(Core::UseMacShortcuts ? tr("Meta+U") : tr("Alt+U")),
G_EDIT_TEXT, advancedEditMenu);
+ m_sortSelectedLinesAction = registerAction(SORT_SELECTED_LINES,
+ [] (TextEditorWidget *w) { w->sortSelectedLines(); }, false, tr("&Sort Selected Lines"),
+ QKeySequence(Core::UseMacShortcuts ? tr("Meta+Shift+S") : tr("Alt+Shift+S")),
+ G_EDIT_TEXT, advancedEditMenu);
m_foldAction = registerAction(FOLD,
- [this] (TextEditorWidget *w) { w->fold(); }, true, tr("Fold"),
+ [] (TextEditorWidget *w) { w->fold(); }, true, tr("Fold"),
QKeySequence(tr("Ctrl+<")),
G_EDIT_COLLAPSING, advancedEditMenu);
m_unfoldAction = registerAction(UNFOLD,
- [this] (TextEditorWidget *w) { w->unfold(); }, true, tr("Unfold"),
+ [] (TextEditorWidget *w) { w->unfold(); }, true, tr("Unfold"),
QKeySequence(tr("Ctrl+>")),
G_EDIT_COLLAPSING, advancedEditMenu);
m_unfoldAllAction = registerAction(UNFOLD_ALL,
- [this] (TextEditorWidget *w) { w->unfoldAll(); }, true, tr("Toggle &Fold All"),
+ [] (TextEditorWidget *w) { w->unfoldAll(); }, true, tr("Toggle &Fold All"),
QKeySequence(),
G_EDIT_COLLAPSING, advancedEditMenu);
m_increaseFontSizeAction = registerAction(INCREASE_FONT_SIZE,
- [this] (TextEditorWidget *w) { w->zoomF(1.f); }, false, tr("Increase Font Size"),
+ [] (TextEditorWidget *w) { w->zoomF(1.f); }, false, tr("Increase Font Size"),
QKeySequence(tr("Ctrl++")),
G_EDIT_FONT, advancedEditMenu);
m_decreaseFontSizeAction = registerAction(DECREASE_FONT_SIZE,
- [this] (TextEditorWidget *w) { w->zoomF(-1.f); }, false, tr("Decrease Font Size"),
+ [] (TextEditorWidget *w) { w->zoomF(-1.f); }, false, tr("Decrease Font Size"),
QKeySequence(tr("Ctrl+-")),
G_EDIT_FONT, advancedEditMenu);
m_resetFontSizeAction = registerAction(RESET_FONT_SIZE,
- [this] (TextEditorWidget *w) { w->zoomReset(); }, false, tr("Reset Font Size"),
+ [] (TextEditorWidget *w) { w->zoomReset(); }, false, tr("Reset Font Size"),
QKeySequence(Core::UseMacShortcuts ? tr("Meta+0") : tr("Ctrl+0")),
G_EDIT_FONT, advancedEditMenu);
m_gotoBlockStartAction = registerAction(GOTO_BLOCK_START,
- [this] (TextEditorWidget *w) { w->gotoBlockStart(); }, true, tr("Go to Block Start"),
+ [] (TextEditorWidget *w) { w->gotoBlockStart(); }, true, tr("Go to Block Start"),
QKeySequence(tr("Ctrl+[")),
G_EDIT_BLOCKS, advancedEditMenu);
m_gotoBlockEndAction = registerAction(GOTO_BLOCK_END,
- [this] (TextEditorWidget *w) { w->gotoBlockEnd(); }, true, tr("Go to Block End"),
+ [] (TextEditorWidget *w) { w->gotoBlockEnd(); }, true, tr("Go to Block End"),
QKeySequence(tr("Ctrl+]")),
G_EDIT_BLOCKS, advancedEditMenu);
m_selectBlockUpAction = registerAction(SELECT_BLOCK_UP,
- [this] (TextEditorWidget *w) { w->selectBlockUp(); }, true, tr("Select Block Up"),
+ [] (TextEditorWidget *w) { w->selectBlockUp(); }, true, tr("Select Block Up"),
QKeySequence(tr("Ctrl+U")),
G_EDIT_BLOCKS, advancedEditMenu);
m_selectBlockDownAction = registerAction(SELECT_BLOCK_DOWN,
- [this] (TextEditorWidget *w) { w->selectBlockDown(); }, true, tr("Select Block Down"),
+ [] (TextEditorWidget *w) { w->selectBlockDown(); }, true, tr("Select Block Down"),
QKeySequence(tr("Ctrl+Shift+Alt+U")),
G_EDIT_BLOCKS, advancedEditMenu);
registerAction(SELECT_WORD_UNDER_CURSOR,
- [this] (TextEditorWidget *w) { w->selectWordUnderCursor(); }, true,
+ [] (TextEditorWidget *w) { w->selectWordUnderCursor(); }, true,
tr("Select Word Under Cursor"));
// register GOTO Actions
registerAction(GOTO_LINE_START,
- [this] (TextEditorWidget *w) { w->gotoLineStart(); }, true, tr("Go to Line Start"));
+ [] (TextEditorWidget *w) { w->gotoLineStart(); }, true, tr("Go to Line Start"));
registerAction(GOTO_LINE_END,
- [this] (TextEditorWidget *w) { w->gotoLineEnd(); }, true, tr("Go to Line End"));
+ [] (TextEditorWidget *w) { w->gotoLineEnd(); }, true, tr("Go to Line End"));
registerAction(GOTO_NEXT_LINE,
- [this] (TextEditorWidget *w) { w->gotoNextLine(); }, true, tr("Go to Next Line"));
+ [] (TextEditorWidget *w) { w->gotoNextLine(); }, true, tr("Go to Next Line"));
registerAction(GOTO_PREVIOUS_LINE,
- [this] (TextEditorWidget *w) { w->gotoPreviousLine(); }, true, tr("Go to Previous Line"));
+ [] (TextEditorWidget *w) { w->gotoPreviousLine(); }, true, tr("Go to Previous Line"));
registerAction(GOTO_PREVIOUS_CHARACTER,
- [this] (TextEditorWidget *w) { w->gotoPreviousCharacter(); }, true, tr("Go to Previous Character"));
+ [] (TextEditorWidget *w) { w->gotoPreviousCharacter(); }, true, tr("Go to Previous Character"));
registerAction(GOTO_NEXT_CHARACTER,
- [this] (TextEditorWidget *w) { w->gotoNextCharacter(); }, true, tr("Go to Next Character"));
+ [] (TextEditorWidget *w) { w->gotoNextCharacter(); }, true, tr("Go to Next Character"));
registerAction(GOTO_PREVIOUS_WORD,
- [this] (TextEditorWidget *w) { w->gotoPreviousWord(); }, true, tr("Go to Previous Word"));
+ [] (TextEditorWidget *w) { w->gotoPreviousWord(); }, true, tr("Go to Previous Word"));
registerAction(GOTO_NEXT_WORD,
- [this] (TextEditorWidget *w) { w->gotoNextWord(); }, true, tr("Go to Next Word"));
+ [] (TextEditorWidget *w) { w->gotoNextWord(); }, true, tr("Go to Next Word"));
registerAction(GOTO_PREVIOUS_WORD_CAMEL_CASE,
- [this] (TextEditorWidget *w) { w->gotoPreviousWordCamelCase(); }, false, tr("Go to Previous Word Camel Case"));
+ [] (TextEditorWidget *w) { w->gotoPreviousWordCamelCase(); }, false, tr("Go to Previous Word Camel Case"));
registerAction(GOTO_NEXT_WORD_CAMEL_CASE,
- [this] (TextEditorWidget *w) { w->gotoNextWordCamelCase(); }, false, tr("Go to Next Word Camel Case"));
+ [] (TextEditorWidget *w) { w->gotoNextWordCamelCase(); }, false, tr("Go to Next Word Camel Case"));
// register GOTO actions with selection
registerAction(GOTO_LINE_START_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoLineStartWithSelection(); }, true, tr("Go to Line Start with Selection"));
+ [] (TextEditorWidget *w) { w->gotoLineStartWithSelection(); }, true, tr("Go to Line Start with Selection"));
registerAction(GOTO_LINE_END_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoLineEndWithSelection(); }, true, tr("Go to Line End with Selection"));
+ [] (TextEditorWidget *w) { w->gotoLineEndWithSelection(); }, true, tr("Go to Line End with Selection"));
registerAction(GOTO_NEXT_LINE_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoNextLineWithSelection(); }, true, tr("Go to Next Line with Selection"));
+ [] (TextEditorWidget *w) { w->gotoNextLineWithSelection(); }, true, tr("Go to Next Line with Selection"));
registerAction(GOTO_PREVIOUS_LINE_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoPreviousLineWithSelection(); }, true, tr("Go to Previous Line with Selection"));
+ [] (TextEditorWidget *w) { w->gotoPreviousLineWithSelection(); }, true, tr("Go to Previous Line with Selection"));
registerAction(GOTO_PREVIOUS_CHARACTER_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoPreviousCharacterWithSelection(); }, true, tr("Go to Previous Character with Selection"));
+ [] (TextEditorWidget *w) { w->gotoPreviousCharacterWithSelection(); }, true, tr("Go to Previous Character with Selection"));
registerAction(GOTO_NEXT_CHARACTER_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoNextCharacterWithSelection(); }, true, tr("Go to Next Character with Selection"));
+ [] (TextEditorWidget *w) { w->gotoNextCharacterWithSelection(); }, true, tr("Go to Next Character with Selection"));
registerAction(GOTO_PREVIOUS_WORD_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoPreviousWordWithSelection(); }, true, tr("Go to Previous Word with Selection"));
+ [] (TextEditorWidget *w) { w->gotoPreviousWordWithSelection(); }, true, tr("Go to Previous Word with Selection"));
registerAction(GOTO_NEXT_WORD_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoNextWordWithSelection(); }, true, tr("Go to Next Word with Selection"));
+ [] (TextEditorWidget *w) { w->gotoNextWordWithSelection(); }, true, tr("Go to Next Word with Selection"));
registerAction(GOTO_PREVIOUS_WORD_CAMEL_CASE_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoPreviousWordCamelCaseWithSelection(); }, false, tr("Go to Previous Word Camel Case with Selection"));
+ [] (TextEditorWidget *w) { w->gotoPreviousWordCamelCaseWithSelection(); }, false, tr("Go to Previous Word Camel Case with Selection"));
registerAction(GOTO_NEXT_WORD_CAMEL_CASE_WITH_SELECTION,
- [this] (TextEditorWidget *w) { w->gotoNextWordCamelCaseWithSelection(); }, false, tr("Go to Next Word Camel Case with Selection"));
+ [] (TextEditorWidget *w) { w->gotoNextWordCamelCaseWithSelection(); }, false, tr("Go to Next Word Camel Case with Selection"));
// Collect all modifying actions so we can check for them inside a readonly file
// and disable them
@@ -500,6 +505,7 @@ void TextEditorActionHandlerPrivate::createActions()
m_modifyingActions << m_unCommentSelectionAction;
m_modifyingActions << m_unindentAction;
m_modifyingActions << m_upperCaseSelectionAction;
+ m_modifyingActions << m_sortSelectedLinesAction;
// set enabled state of optional actions
m_followSymbolAction->setEnabled(m_optionalActions & TextEditorActionHandler::FollowSymbolUnderCursor);
diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h
index af565243620..8cf692d022a 100644
--- a/src/plugins/texteditor/texteditorconstants.h
+++ b/src/plugins/texteditor/texteditorconstants.h
@@ -143,6 +143,7 @@ const char INSERT_LINE_ABOVE[] = "TextEditor.InsertLineAboveCurrentLine";
const char INSERT_LINE_BELOW[] = "TextEditor.InsertLineBelowCurrentLine";
const char UPPERCASE_SELECTION[] = "TextEditor.UppercaseSelection";
const char LOWERCASE_SELECTION[] = "TextEditor.LowercaseSelection";
+const char SORT_SELECTED_LINES[] = "TextEditor.SortSelectedLines";
const char CUT_LINE[] = "TextEditor.CutLine";
const char COPY_LINE[] = "TextEditor.CopyLine";
const char DUPLICATE_SELECTION[] = "TextEditor.DuplicateSelection";
diff --git a/src/plugins/texteditor/textmark.cpp b/src/plugins/texteditor/textmark.cpp
index 1e3c7bd4b50..d4f9db7c509 100644
--- a/src/plugins/texteditor/textmark.cpp
+++ b/src/plugins/texteditor/textmark.cpp
@@ -92,7 +92,7 @@ TextMark::~TextMark()
TextMarkRegistry::remove(this);
if (m_baseTextDocument)
m_baseTextDocument->removeMark(this);
- m_baseTextDocument = 0;
+ m_baseTextDocument = nullptr;
}
QString TextMark::fileName() const
diff --git a/src/plugins/texteditor/textmark.h b/src/plugins/texteditor/textmark.h
index f744da7dc9b..f8cd36b1317 100644
--- a/src/plugins/texteditor/textmark.h
+++ b/src/plugins/texteditor/textmark.h
@@ -125,9 +125,9 @@ private:
QString m_fileName;
int m_lineNumber = 0;
Priority m_priority = LowPriority;
- bool m_visible = false;
QIcon m_icon;
- Utils::Theme::Color m_color;
+ Utils::Theme::Color m_color = Utils::Theme::TextColorNormal;
+ bool m_visible = false;
bool m_hasColor = false;
Core::Id m_category;
double m_widthFactor = 1.0;
diff --git a/src/plugins/todo/todoitemsprovider.cpp b/src/plugins/todo/todoitemsprovider.cpp
index d7a584179fe..54a525cf7df 100644
--- a/src/plugins/todo/todoitemsprovider.cpp
+++ b/src/plugins/todo/todoitemsprovider.cpp
@@ -145,7 +145,7 @@ void TodoItemsProvider::setItemsListWithinStartupProject()
void TodoItemsProvider::setItemsListWithinSubproject()
{
// TODO prefer current editor as source of sub-project
- Node *node = ProjectTree::currentNode();
+ const Node *node = ProjectTree::findCurrentNode();
if (node) {
ProjectNode *projectNode = node->parentProjectNode();
if (projectNode) {
diff --git a/src/plugins/todo/todoplugin.cpp b/src/plugins/todo/todoplugin.cpp
index b99ec94bd17..5b2fef62cde 100644
--- a/src/plugins/todo/todoplugin.cpp
+++ b/src/plugins/todo/todoplugin.cpp
@@ -71,7 +71,7 @@ bool TodoPlugin::initialize(const QStringList& args, QString *errMsg)
auto panelFactory = new ProjectExplorer::ProjectPanelFactory;
panelFactory->setPriority(100);
panelFactory->setDisplayName(TodoProjectSettingsWidget::tr("To-Do"));
- panelFactory->setCreateWidgetFunction([this, panelFactory](ProjectExplorer::Project *project) {
+ panelFactory->setCreateWidgetFunction([this](ProjectExplorer::Project *project) {
auto widget = new TodoProjectSettingsWidget(project);
connect(widget, &TodoProjectSettingsWidget::projectSettingsChanged,
m_todoItemsProvider, [this, project] { m_todoItemsProvider->projectSettingsChanged(project); });
diff --git a/src/plugins/updateinfo/settingspage.cpp b/src/plugins/updateinfo/settingspage.cpp
index e8e07a7d9d7..03a1045a325 100644
--- a/src/plugins/updateinfo/settingspage.cpp
+++ b/src/plugins/updateinfo/settingspage.cpp
@@ -116,7 +116,7 @@ void SettingsPage::checkRunningChanged(bool running)
if (running) {
if (!m_progressIndicator) {
- m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicator::Large);
+ m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Large);
m_progressIndicator->attachToWidget(m_widget);
}
m_progressIndicator->show();
diff --git a/src/plugins/updateinfo/settingspage.ui b/src/plugins/updateinfo/settingspage.ui
index 7e16862038a..de6357b9568 100644
--- a/src/plugins/updateinfo/settingspage.ui
+++ b/src/plugins/updateinfo/settingspage.ui
@@ -42,7 +42,7 @@
</sizepolicy>
</property>
<property name="text">
- <string>Qt Creator automatically runs a scheduled check for updates on a time interval basis. If Qt Creator is not in use on the scheduled date, the automatic check for updates will be performed next time Qt Creator starts.</string>
+ <string>Automatically runs a scheduled check for updates on a time interval basis. The automatic check for updates will be performed at the scheduled date, or the next startup following it.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
diff --git a/src/plugins/valgrind/memcheckengine.cpp b/src/plugins/valgrind/memcheckengine.cpp
deleted file mode 100644
index 8e80ef1165e..00000000000
--- a/src/plugins/valgrind/memcheckengine.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Author: Nicolas Arnaud-Cormos, KDAB (nicolas.arnaud-cormos@kdab.com)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "memcheckengine.h"
-#include "memchecktool.h"
-#include "valgrindsettings.h"
-#include "xmlprotocol/error.h"
-#include "xmlprotocol/status.h"
-
-#include <debugger/debuggerkitinformation.h>
-#include <debugger/debuggerstartparameters.h>
-#include <debugger/debuggerruncontrol.h>
-
-#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/kitinformation.h>
-#include <projectexplorer/project.h>
-#include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/target.h>
-#include <projectexplorer/toolchain.h>
-
-#include <utils/qtcassert.h>
-
-using namespace Debugger;
-using namespace ProjectExplorer;
-using namespace Valgrind::XmlProtocol;
-
-namespace Valgrind {
-namespace Internal {
-
-class LocalAddressFinder : public RunWorker
-{
-public:
- LocalAddressFinder(RunControl *runControl, QHostAddress *localServerAddress)
- : RunWorker(runControl), connection(device()->sshParameters())
- {
- connect(&connection, &QSsh::SshConnection::connected, this, [this, localServerAddress] {
- *localServerAddress = connection.connectionInfo().localAddress;
- reportStarted();
- });
- connect(&connection, &QSsh::SshConnection::error, this, [this] {
- reportFailure();
- });
- }
-
- void start() override
- {
- connection.connectToHost();
- }
-
- QSsh::SshConnection connection;
-};
-
-MemcheckToolRunner::MemcheckToolRunner(RunControl *runControl, bool withGdb)
- : ValgrindToolRunner(runControl),
- m_withGdb(withGdb),
- m_localServerAddress(QHostAddress::LocalHost)
-{
- setDisplayName("MemcheckToolRunner");
- connect(m_runner.parser(), &XmlProtocol::ThreadedParser::error,
- this, &MemcheckToolRunner::parserError);
- connect(m_runner.parser(), &XmlProtocol::ThreadedParser::suppressionCount,
- this, &MemcheckToolRunner::suppressionCount);
-
- if (withGdb) {
- connect(&m_runner, &ValgrindRunner::valgrindStarted,
- this, &MemcheckToolRunner::startDebugger);
- connect(&m_runner, &ValgrindRunner::logMessageReceived,
- this, &MemcheckToolRunner::appendLog);
-// m_runner.disableXml();
- } else {
- connect(m_runner.parser(), &XmlProtocol::ThreadedParser::internalError,
- this, &MemcheckToolRunner::internalParserError);
- }
-
- // We need a real address to connect to from the outside.
- if (device()->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
- addStartDependency(new LocalAddressFinder(runControl, &m_localServerAddress));
-}
-
-QString MemcheckToolRunner::progressTitle() const
-{
- return tr("Analyzing Memory");
-}
-
-void MemcheckToolRunner::start()
-{
- m_runner.setLocalServerAddress(m_localServerAddress);
- ValgrindToolRunner::start();
-}
-
-void MemcheckToolRunner::stop()
-{
- disconnect(m_runner.parser(), &ThreadedParser::internalError,
- this, &MemcheckToolRunner::internalParserError);
- ValgrindToolRunner::stop();
-}
-
-QStringList MemcheckToolRunner::toolArguments() const
-{
- QStringList arguments = {"--tool=memcheck", "--gen-suppressions=all"};
-
- QTC_ASSERT(m_settings, return arguments);
-
- if (m_settings->trackOrigins())
- arguments << "--track-origins=yes";
-
- if (m_settings->showReachable())
- arguments << "--show-reachable=yes";
-
- QString leakCheckValue;
- switch (m_settings->leakCheckOnFinish()) {
- case ValgrindBaseSettings::LeakCheckOnFinishNo:
- leakCheckValue = "no";
- break;
- case ValgrindBaseSettings::LeakCheckOnFinishYes:
- leakCheckValue = "full";
- break;
- case ValgrindBaseSettings::LeakCheckOnFinishSummaryOnly:
- default:
- leakCheckValue = "summary";
- break;
- }
- arguments << "--leak-check=" + leakCheckValue;
-
- foreach (const QString &file, m_settings->suppressionFiles())
- arguments << QString("--suppressions=%1").arg(file);
-
- arguments << QString("--num-callers=%1").arg(m_settings->numCallers());
-
- if (m_withGdb)
- arguments << "--vgdb=yes" << "--vgdb-error=0";
-
- return arguments;
-}
-
-QStringList MemcheckToolRunner::suppressionFiles() const
-{
- return m_settings->suppressionFiles();
-}
-
-void MemcheckToolRunner::startDebugger(qint64 valgrindPid)
-{
- Debugger::DebuggerStartParameters sp;
- sp.inferior = runnable().as<StandardRunnable>();
- sp.startMode = Debugger::AttachToRemoteServer;
- sp.displayName = QString("VGdb %1").arg(valgrindPid);
- sp.remoteChannel = QString("| vgdb --pid=%1").arg(valgrindPid);
- sp.useContinueInsteadOfRun = true;
- sp.expectedSignals.append("SIGTRAP");
-
- auto gdbWorker = new Debugger::DebuggerRunTool(runControl());
- gdbWorker->setStartParameters(sp);
- gdbWorker->initiateStart();
- connect(runControl(), &RunControl::stopped, gdbWorker, &RunControl::deleteLater);
-}
-
-void MemcheckToolRunner::appendLog(const QByteArray &data)
-{
- appendMessage(QString::fromUtf8(data), Utils::StdOutFormat);
-}
-
-} // namespace Internal
-} // namespace Valgrind
diff --git a/src/plugins/valgrind/memcheckengine.h b/src/plugins/valgrind/memcheckengine.h
deleted file mode 100644
index 6113390e91c..00000000000
--- a/src/plugins/valgrind/memcheckengine.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Author: Nicolas Arnaud-Cormos, KDAB (nicolas.arnaud-cormos@kdab.com)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "valgrindengine.h"
-
-#include "valgrindrunner.h"
-#include "xmlprotocol/threadedparser.h"
-
-#include <QHostAddress>
-
-namespace Valgrind {
-namespace Internal {
-
-class MemcheckToolRunner : public ValgrindToolRunner
-{
- Q_OBJECT
-
-public:
- explicit MemcheckToolRunner(ProjectExplorer::RunControl *runControl,
- bool withGdb = false);
-
- void start() override;
- void stop() override;
-
- QStringList suppressionFiles() const;
-
-signals:
- void internalParserError(const QString &errorString);
- void parserError(const Valgrind::XmlProtocol::Error &error);
- void suppressionCount(const QString &name, qint64 count);
-
-private:
- QString progressTitle() const override;
- QStringList toolArguments() const override;
-
- void startDebugger(qint64 valgrindPid);
- void appendLog(const QByteArray &data);
-
- const bool m_withGdb;
- QHostAddress m_localServerAddress;
-};
-
-} // namespace Internal
-} // namespace Valgrind
diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp
index cab6dea44c9..f668ee3a5fb 100644
--- a/src/plugins/valgrind/memchecktool.cpp
+++ b/src/plugins/valgrind/memchecktool.cpp
@@ -25,37 +25,44 @@
****************************************************************************/
#include "memchecktool.h"
-#include "memcheckengine.h"
+
#include "memcheckerrorview.h"
#include "valgrindsettings.h"
#include "valgrindplugin.h"
-
+#include "valgrindengine.h"
+#include "valgrindsettings.h"
+#include "valgrindrunner.h"
+
+#include "xmlprotocol/error.h"
+#include "xmlprotocol/error.h"
+#include "xmlprotocol/errorlistmodel.h"
+#include "xmlprotocol/frame.h"
+#include "xmlprotocol/stack.h"
+#include "xmlprotocol/stackmodel.h"
+#include "xmlprotocol/status.h"
+#include "xmlprotocol/suppression.h"
+#include "xmlprotocol/threadedparser.h"
+
+#include <debugger/debuggerkitinformation.h>
+#include <debugger/debuggerruncontrol.h>
#include <debugger/analyzer/analyzerconstants.h>
#include <debugger/analyzer/analyzermanager.h>
-#include <debugger/analyzer/analyzerutils.h>
#include <debugger/analyzer/startremotedialog.h>
-#include <valgrind/valgrindsettings.h>
-#include <valgrind/xmlprotocol/errorlistmodel.h>
-#include <valgrind/xmlprotocol/stackmodel.h>
-#include <valgrind/xmlprotocol/error.h>
-#include <valgrind/xmlprotocol/frame.h>
-#include <valgrind/xmlprotocol/stack.h>
-#include <valgrind/xmlprotocol/suppression.h>
-
-#include <extensionsystem/iplugin.h>
-#include <extensionsystem/pluginmanager.h>
-
+#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/deploymentdata.h>
-#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/kitinformation.h>
#include <projectexplorer/project.h>
+#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/runconfiguration.h>
+#include <projectexplorer/session.h>
#include <projectexplorer/target.h>
#include <projectexplorer/taskhub.h>
-#include <projectexplorer/session.h>
-#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/toolchain.h>
+
+#include <extensionsystem/iplugin.h>
+#include <extensionsystem/pluginmanager.h>
-#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
@@ -65,32 +72,23 @@
#include <utils/fancymainwindow.h>
#include <utils/qtcassert.h>
-#include <utils/styledbar.h>
-#include <utils/stylehelper.h>
#include <utils/utilsicons.h>
#include <QAction>
-#include <QCheckBox>
-#include <QComboBox>
-#include <QDir>
-#include <QDockWidget>
#include <QFile>
#include <QFileDialog>
#include <QFileInfo>
-#include <QHBoxLayout>
#include <QLabel>
-#include <QLatin1String>
#include <QMenu>
-#include <QSortFilterProxyModel>
-#include <QSpinBox>
-#include <QString>
#include <QToolButton>
+#include <QSortFilterProxyModel>
using namespace Core;
using namespace Debugger;
using namespace ProjectExplorer;
using namespace Utils;
using namespace Valgrind::XmlProtocol;
+
using namespace std::placeholders;
namespace Valgrind {
@@ -102,6 +100,167 @@ const char MEMCHECK_WITH_GDB_RUN_MODE[] = "MemcheckTool.MemcheckWithGdbRunMode";
const char MemcheckPerspectiveId[] = "Memcheck.Perspective";
const char MemcheckErrorDockId[] = "Memcheck.Dock.Error";
+
+class MemcheckToolRunner : public ValgrindToolRunner
+{
+ Q_OBJECT
+
+public:
+ explicit MemcheckToolRunner(ProjectExplorer::RunControl *runControl,
+ bool withGdb = false);
+
+ void start() override;
+ void stop() override;
+
+ QStringList suppressionFiles() const;
+
+signals:
+ void internalParserError(const QString &errorString);
+ void parserError(const Valgrind::XmlProtocol::Error &error);
+ void suppressionCount(const QString &name, qint64 count);
+
+private:
+ QString progressTitle() const override;
+ QStringList toolArguments() const override;
+
+ void startDebugger(qint64 valgrindPid);
+ void appendLog(const QByteArray &data);
+
+ const bool m_withGdb;
+ QHostAddress m_localServerAddress;
+};
+
+class LocalAddressFinder : public RunWorker
+{
+public:
+ LocalAddressFinder(RunControl *runControl, QHostAddress *localServerAddress)
+ : RunWorker(runControl), connection(device()->sshParameters())
+ {
+ connect(&connection, &QSsh::SshConnection::connected, this, [this, localServerAddress] {
+ *localServerAddress = connection.connectionInfo().localAddress;
+ reportStarted();
+ });
+ connect(&connection, &QSsh::SshConnection::error, this, [this] {
+ reportFailure();
+ });
+ }
+
+ void start() override
+ {
+ connection.connectToHost();
+ }
+
+ QSsh::SshConnection connection;
+};
+
+MemcheckToolRunner::MemcheckToolRunner(RunControl *runControl, bool withGdb)
+ : ValgrindToolRunner(runControl),
+ m_withGdb(withGdb),
+ m_localServerAddress(QHostAddress::LocalHost)
+{
+ setDisplayName("MemcheckToolRunner");
+ connect(m_runner.parser(), &XmlProtocol::ThreadedParser::error,
+ this, &MemcheckToolRunner::parserError);
+ connect(m_runner.parser(), &XmlProtocol::ThreadedParser::suppressionCount,
+ this, &MemcheckToolRunner::suppressionCount);
+
+ if (withGdb) {
+ connect(&m_runner, &ValgrindRunner::valgrindStarted,
+ this, &MemcheckToolRunner::startDebugger);
+ connect(&m_runner, &ValgrindRunner::logMessageReceived,
+ this, &MemcheckToolRunner::appendLog);
+// m_runner.disableXml();
+ } else {
+ connect(m_runner.parser(), &XmlProtocol::ThreadedParser::internalError,
+ this, &MemcheckToolRunner::internalParserError);
+ }
+
+ // We need a real address to connect to from the outside.
+ if (device()->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
+ addStartDependency(new LocalAddressFinder(runControl, &m_localServerAddress));
+}
+
+QString MemcheckToolRunner::progressTitle() const
+{
+ return tr("Analyzing Memory");
+}
+
+void MemcheckToolRunner::start()
+{
+ m_runner.setLocalServerAddress(m_localServerAddress);
+ ValgrindToolRunner::start();
+}
+
+void MemcheckToolRunner::stop()
+{
+ disconnect(m_runner.parser(), &ThreadedParser::internalError,
+ this, &MemcheckToolRunner::internalParserError);
+ ValgrindToolRunner::stop();
+}
+
+QStringList MemcheckToolRunner::toolArguments() const
+{
+ QStringList arguments = {"--tool=memcheck", "--gen-suppressions=all"};
+
+ QTC_ASSERT(m_settings, return arguments);
+
+ if (m_settings->trackOrigins())
+ arguments << "--track-origins=yes";
+
+ if (m_settings->showReachable())
+ arguments << "--show-reachable=yes";
+
+ QString leakCheckValue;
+ switch (m_settings->leakCheckOnFinish()) {
+ case ValgrindBaseSettings::LeakCheckOnFinishNo:
+ leakCheckValue = "no";
+ break;
+ case ValgrindBaseSettings::LeakCheckOnFinishYes:
+ leakCheckValue = "full";
+ break;
+ case ValgrindBaseSettings::LeakCheckOnFinishSummaryOnly:
+ default:
+ leakCheckValue = "summary";
+ break;
+ }
+ arguments << "--leak-check=" + leakCheckValue;
+
+ foreach (const QString &file, m_settings->suppressionFiles())
+ arguments << QString("--suppressions=%1").arg(file);
+
+ arguments << QString("--num-callers=%1").arg(m_settings->numCallers());
+
+ if (m_withGdb)
+ arguments << "--vgdb=yes" << "--vgdb-error=0";
+
+ return arguments;
+}
+
+QStringList MemcheckToolRunner::suppressionFiles() const
+{
+ return m_settings->suppressionFiles();
+}
+
+void MemcheckToolRunner::startDebugger(qint64 valgrindPid)
+{
+ auto debugger = new Debugger::DebuggerRunTool(runControl());
+ debugger->setStartMode(Debugger::AttachToRemoteServer);
+ debugger->setRunControlName(QString("VGdb %1").arg(valgrindPid));
+ debugger->setRemoteChannel(QString("| vgdb --pid=%1").arg(valgrindPid));
+ debugger->setUseContinueInsteadOfRun(true);
+ debugger->addExpectedSignal("SIGTRAP");
+
+ connect(runControl(), &RunControl::stopped, debugger, &RunControl::deleteLater);
+
+ debugger->initiateStart();
+}
+
+void MemcheckToolRunner::appendLog(const QByteArray &data)
+{
+ appendMessage(QString::fromUtf8(data), Utils::StdOutFormat);
+}
+
+
static ErrorListModel::RelevantFrameFinder makeFrameFinder(const QStringList &projectFiles)
{
return [projectFiles](const Error &error) {
@@ -352,7 +511,7 @@ MemcheckTool::MemcheckTool()
// Load external XML log file
auto action = new QAction(this);
- action->setIcon(Utils::Icons::OPENFILE.icon());
+ action->setIcon(Icons::OPENFILE.icon());
action->setToolTip(tr("Load External XML Log File"));
connect(action, &QAction::triggered, this, &MemcheckTool::loadExternalXmlLogFile);
m_loadExternalLogFile = action;
@@ -360,7 +519,7 @@ MemcheckTool::MemcheckTool()
// Go to previous leak.
action = new QAction(this);
action->setDisabled(true);
- action->setIcon(Utils::Icons::PREV_TOOLBAR.icon());
+ action->setIcon(Icons::PREV_TOOLBAR.icon());
action->setToolTip(tr("Go to previous leak."));
connect(action, &QAction::triggered, m_errorView, &MemcheckErrorView::goBack);
m_goBack = action;
@@ -368,13 +527,13 @@ MemcheckTool::MemcheckTool()
// Go to next leak.
action = new QAction(this);
action->setDisabled(true);
- action->setIcon(Utils::Icons::NEXT_TOOLBAR.icon());
+ action->setIcon(Icons::NEXT_TOOLBAR.icon());
action->setToolTip(tr("Go to next leak."));
connect(action, &QAction::triggered, m_errorView, &MemcheckErrorView::goNext);
m_goNext = action;
auto filterButton = new QToolButton;
- filterButton->setIcon(Utils::Icons::FILTER.icon());
+ filterButton->setIcon(Icons::FILTER.icon());
filterButton->setText(tr("Error Filter"));
filterButton->setPopupMode(QToolButton::InstantPopup);
filterButton->setProperty("noArrow", true);
@@ -391,7 +550,7 @@ MemcheckTool::MemcheckTool()
ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);
QString toolTip = tr("Valgrind Analyze Memory uses the Memcheck tool to find memory leaks.");
- if (!Utils::HostOsInfo::isWindowsHost()) {
+ if (!HostOsInfo::isWindowsHost()) {
action = new QAction(this);
action->setText(tr("Valgrind Memory Analyzer"));
action->setToolTip(toolTip);
@@ -434,7 +593,7 @@ MemcheckTool::MemcheckTool()
action->setToolTip(toolTip);
menu->addAction(ActionManager::registerAction(action, "Memcheck.Remote"),
Debugger::Constants::G_ANALYZER_REMOTE_TOOLS);
- QObject::connect(action, &QAction::triggered, this, [this, action] {
+ QObject::connect(action, &QAction::triggered, this, [action] {
auto runConfig = RunConfiguration::startupRunConfiguration();
if (!runConfig) {
showCannotStartDialog(action->text());
@@ -552,9 +711,7 @@ void MemcheckTool::maybeActiveRunConfigurationChanged()
RunWorker *MemcheckTool::createRunWorker(RunControl *runControl)
{
- RunConfiguration *runConfig = runControl->runConfiguration();
- m_errorModel.setRelevantFrameFinder(makeFrameFinder(runConfig
- ? runConfig->target()->project()->files(Project::AllFiles) : QStringList()));
+ m_errorModel.setRelevantFrameFinder(makeFrameFinder(runControl->project()->files(Project::AllFiles)));
auto runTool = new MemcheckToolRunner(runControl, runControl->runMode() == MEMCHECK_WITH_GDB_RUN_MODE);
@@ -572,19 +729,16 @@ RunWorker *MemcheckTool::createRunWorker(RunControl *runControl)
clearErrorView();
m_loadExternalLogFile->setDisabled(true);
- QString dir;
- if (RunConfiguration *rc = runTool->runControl()->runConfiguration())
- dir = rc->target()->project()->projectDirectory().toString() + QLatin1Char('/');
+ QString dir = runControl->project()->projectDirectory().toString() + '/';
+ const QString name = FileName::fromString(runTool->executable()).fileName();
- const QString name = Utils::FileName::fromString(runTool->executable()).fileName();
-
- m_errorView->setDefaultSuppressionFile(dir + name + QLatin1String(".supp"));
+ m_errorView->setDefaultSuppressionFile(dir + name + ".supp");
foreach (const QString &file, runTool->suppressionFiles()) {
- QAction *action = m_filterMenu->addAction(Utils::FileName::fromString(file).fileName());
+ QAction *action = m_filterMenu->addAction(FileName::fromString(file).fileName());
action->setToolTip(file);
- connect(action, &QAction::triggered, this, [this, file]() {
- Core::EditorManager::openEditorAt(file, 0);
+ connect(action, &QAction::triggered, this, [file] {
+ EditorManager::openEditorAt(file, 0);
});
m_suppressionActions.append(action);
}
@@ -595,7 +749,7 @@ RunWorker *MemcheckTool::createRunWorker(RunControl *runControl)
void MemcheckTool::loadExternalXmlLogFile()
{
const QString filePath = QFileDialog::getOpenFileName(
- Core::ICore::mainWindow(),
+ ICore::mainWindow(),
tr("Open Memcheck XML Log File"),
QString(),
tr("XML Files (*.xml);;All Files (*)"));
@@ -726,3 +880,5 @@ void destroyMemcheckTool()
} // namespace Internal
} // namespace Valgrind
+
+#include "memchecktool.moc"
diff --git a/src/plugins/valgrind/valgrind.pro b/src/plugins/valgrind/valgrind.pro
index 4bbd41fc5c7..216e3568173 100644
--- a/src/plugins/valgrind/valgrind.pro
+++ b/src/plugins/valgrind/valgrind.pro
@@ -21,7 +21,6 @@ HEADERS += \
workarounds.h \
callgrindtextmark.h \
memchecktool.h \
- memcheckengine.h \
memcheckerrorview.h \
suppressiondialog.h
@@ -41,7 +40,6 @@ SOURCES += \
workarounds.cpp \
callgrindtextmark.cpp \
memchecktool.cpp \
- memcheckengine.cpp \
memcheckerrorview.cpp \
suppressiondialog.cpp
diff --git a/src/plugins/valgrind/valgrind.qbs b/src/plugins/valgrind/valgrind.qbs
index c7e992921ec..5b7fb8f040c 100644
--- a/src/plugins/valgrind/valgrind.qbs
+++ b/src/plugins/valgrind/valgrind.qbs
@@ -27,10 +27,10 @@ QtcPlugin {
"callgrindtextmark.cpp", "callgrindtextmark.h",
"callgrindtool.cpp", "callgrindtool.h",
"callgrindvisualisation.cpp", "callgrindvisualisation.h",
- "memcheckengine.cpp", "memcheckengine.h",
"memcheckerrorview.cpp", "memcheckerrorview.h",
"memchecktool.cpp", "memchecktool.h",
"suppressiondialog.cpp", "suppressiondialog.h",
+ "valgrind.qrc",
"valgrindconfigwidget.cpp", "valgrindconfigwidget.h", "valgrindconfigwidget.ui",
"valgrindengine.cpp", "valgrindengine.h",
"valgrindplugin.cpp", "valgrindplugin.h",
diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp
index 13beca1fa06..cfe6648b012 100644
--- a/src/plugins/valgrind/valgrindengine.cpp
+++ b/src/plugins/valgrind/valgrindengine.cpp
@@ -177,7 +177,7 @@ void ValgrindToolRunner::receiveProcessError(const QString &message, QProcess::P
} else if (m_isStopping && error == QProcess::Crashed) { // process gets killed on stop
appendMessage(tr("Process terminated."), ErrorMessageFormat);
} else {
- appendMessage(QString("** %1 **\n").arg(message), ErrorMessageFormat);
+ appendMessage(tr("Process exited with return value %1\n").arg(message), NormalMessageFormat);
}
if (m_isStopping)
diff --git a/src/plugins/vcsbase/basevcseditorfactory.cpp b/src/plugins/vcsbase/basevcseditorfactory.cpp
index 8b183e5c01e..2e26d4026e4 100644
--- a/src/plugins/vcsbase/basevcseditorfactory.cpp
+++ b/src/plugins/vcsbase/basevcseditorfactory.cpp
@@ -63,7 +63,7 @@ VcsEditorFactory::VcsEditorFactory(const VcsBaseEditorParameters *parameters,
setEditorActionHandlers(TextEditorActionHandler::None);
setDuplicatedSupported(false);
- setDocumentCreator([this, parameters]() -> TextDocument* {
+ setDocumentCreator([parameters]() -> TextDocument* {
auto document = new TextDocument(parameters->id);
// if (QLatin1String(parameters->mimeType) != QLatin1String(DiffEditor::Constants::DIFF_EDITOR_MIMETYPE))
document->setMimeType(QLatin1String(parameters->mimeType));
@@ -71,7 +71,7 @@ VcsEditorFactory::VcsEditorFactory(const VcsBaseEditorParameters *parameters,
return document;
});
- setEditorWidgetCreator([this, parameters, editorWidgetCreator, describeFunc]() -> TextEditorWidget * {
+ setEditorWidgetCreator([parameters, editorWidgetCreator, describeFunc]() -> TextEditorWidget * {
auto widget = qobject_cast<VcsBaseEditorWidget *>(editorWidgetCreator());
widget->setDescribeFunc(describeFunc);
widget->setParameters(parameters);
diff --git a/src/plugins/vcsbase/commonsettingspage.cpp b/src/plugins/vcsbase/commonsettingspage.cpp
index 735defb4ae7..12f374bcbba 100644
--- a/src/plugins/vcsbase/commonsettingspage.cpp
+++ b/src/plugins/vcsbase/commonsettingspage.cpp
@@ -61,7 +61,7 @@ CommonSettingsWidget::CommonSettingsWidget(QWidget *parent) :
connect(Core::VcsManager::instance(), &Core::VcsManager::configurationChanged,
this, &CommonSettingsWidget::updatePath);
connect(m_ui->cacheResetButton, &QPushButton::clicked,
- this, [] { Core::VcsManager::clearVersionControlCache(); });
+ Core::VcsManager::instance(), &Core::VcsManager::clearVersionControlCache);
}
CommonSettingsWidget::~CommonSettingsWidget()
diff --git a/src/plugins/vcsbase/vcsbaseclientsettings.cpp b/src/plugins/vcsbase/vcsbaseclientsettings.cpp
index ab67910c2f5..f87daf18017 100644
--- a/src/plugins/vcsbase/vcsbaseclientsettings.cpp
+++ b/src/plugins/vcsbase/vcsbaseclientsettings.cpp
@@ -201,9 +201,9 @@ const QLatin1String VcsBaseClientSettings::pathKey("Path");
VcsBaseClientSettings::VcsBaseClientSettings() :
d(new Internal::VcsBaseClientSettingsPrivate)
{
- declareKey(binaryPathKey, QLatin1String(""));
- declareKey(userNameKey, QLatin1String(""));
- declareKey(userEmailKey, QLatin1String(""));
+ declareKey(binaryPathKey, QString());
+ declareKey(userNameKey, QString());
+ declareKey(userEmailKey, QString());
declareKey(logCountKey, 100);
declareKey(promptOnSubmitKey, true);
declareKey(timeoutKey, 30);
diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp
index 063d2695d7b..2d17bb36928 100644
--- a/src/plugins/vcsbase/vcsbaseeditor.cpp
+++ b/src/plugins/vcsbase/vcsbaseeditor.cpp
@@ -1398,7 +1398,7 @@ void VcsBaseEditorWidget::setCommand(VcsCommand *command)
}
d->m_command = command;
if (command) {
- d->m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicator::Large);
+ d->m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Large);
d->m_progressIndicator->attachToWidget(this);
connect(command, &VcsCommand::finished, this, &VcsBaseEditorWidget::reportCommandFinished);
QTimer::singleShot(100, this, &VcsBaseEditorWidget::showProgressIndicator);
diff --git a/src/plugins/vcsbase/vcsbaseplugin.cpp b/src/plugins/vcsbase/vcsbaseplugin.cpp
index 0a62647a053..92b2fb44a38 100644
--- a/src/plugins/vcsbase/vcsbaseplugin.cpp
+++ b/src/plugins/vcsbase/vcsbaseplugin.cpp
@@ -34,9 +34,7 @@
#include <coreplugin/icore.h>
#include <coreplugin/id.h>
#include <coreplugin/idocument.h>
-#include <coreplugin/iversioncontrol.h>
#include <coreplugin/editormanager/editormanager.h>
-#include <coreplugin/vcsmanager.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
@@ -552,9 +550,10 @@ VcsBasePlugin::~VcsBasePlugin()
void VcsBasePlugin::initializeVcs(IVersionControl *vc, const Context &context)
{
+ QTC_ASSERT(vc, return);
+
d->m_versionControl = vc;
d->m_context = context;
- addAutoReleasedObject(vc);
Internal::VcsPlugin *plugin = Internal::VcsPlugin::instance();
connect(plugin, &Internal::VcsPlugin::submitEditorAboutToClose,
@@ -642,6 +641,16 @@ bool VcsBasePlugin::enableMenuAction(ActionState as, QAction *menuAction) const
return true;
}
+QString VcsBasePlugin::commitDisplayName() const
+{
+ return tr("commit", "name of \"commit\" action of the VCS.");
+}
+
+bool VcsBasePlugin::promptBeforeCommit()
+{
+ return DocumentManager::saveAllModifiedDocuments(tr("Save before %1?").arg(commitDisplayName()));
+}
+
void VcsBasePlugin::promptToDeleteCurrentFile()
{
const VcsBasePluginState state = currentState();
diff --git a/src/plugins/vcsbase/vcsbaseplugin.h b/src/plugins/vcsbase/vcsbaseplugin.h
index dc719111b22..72b2c5a46eb 100644
--- a/src/plugins/vcsbase/vcsbaseplugin.h
+++ b/src/plugins/vcsbase/vcsbaseplugin.h
@@ -27,6 +27,8 @@
#include "vcsbase_global.h"
+#include <coreplugin/iversioncontrol.h>
+#include <coreplugin/vcsmanager.h>
#include <extensionsystem/iplugin.h>
#include <QList>
@@ -128,7 +130,14 @@ class VCSBASE_EXPORT VcsBasePlugin : public ExtensionSystem::IPlugin
protected:
explicit VcsBasePlugin();
- void initializeVcs(Core::IVersionControl *vc, const Core::Context &context);
+ template<class T, typename... Args>
+ T *initializeVcs(const Core::Context &context, Args&&... args)
+ {
+ T *vc = Core::VcsManager::registerVersionControl<T>(std::forward<Args>(args)...);
+ initializeVcs(vc, context);
+ return vc;
+ }
+
void extensionsInitialized() override;
public:
@@ -169,6 +178,11 @@ public:
const QProcessEnvironment &env = QProcessEnvironment());
protected:
+ // Display name of the commit action:
+ virtual QString commitDisplayName() const;
+ // Prompt to save all files before commit:
+ bool promptBeforeCommit();
+
// Convenience slot for "Delete current file" action. Prompts to
// delete the file via VcsManager.
void promptToDeleteCurrentFile();
@@ -204,6 +218,8 @@ private:
void slotSubmitEditorAboutToClose(VcsBaseSubmitEditor *submitEditor, bool *result);
void slotStateChanged(const VcsBase::Internal::State &s, Core::IVersionControl *vc);
+ void initializeVcs(Core::IVersionControl *vc, const Core::Context &context);
+
VcsBasePluginPrivate *d;
};
diff --git a/src/plugins/vcsbase/vcsprojectcache.cpp b/src/plugins/vcsbase/vcsprojectcache.cpp
index 6540daf2a78..a2ca3987a6a 100644
--- a/src/plugins/vcsbase/vcsprojectcache.cpp
+++ b/src/plugins/vcsbase/vcsprojectcache.cpp
@@ -74,9 +74,9 @@ VcsProjectCache::VcsProjectCache()
m_instance = this;
connect(ProjectExplorer::SessionManager::instance(), &ProjectExplorer::SessionManager::projectAdded,
- this, [this]() { VcsProjectCache::invalidate(); });
+ this, []() { VcsProjectCache::invalidate(); });
connect(ProjectExplorer::SessionManager::instance(), &ProjectExplorer::SessionManager::projectRemoved,
- this, [this]() { VcsProjectCache::invalidate(); });
+ this, []() { VcsProjectCache::invalidate(); });
}
VcsProjectCache::~VcsProjectCache()
diff --git a/src/plugins/welcome/images/mode_edit_mask.png b/src/plugins/welcome/images/mode_edit_mask.png
deleted file mode 100644
index 221f4915193..00000000000
--- a/src/plugins/welcome/images/mode_edit_mask.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/welcome/images/mode_welcome.png b/src/plugins/welcome/images/mode_welcome.png
index 24cfcd8cc8e..186b85f1918 100644
--- a/src/plugins/welcome/images/mode_welcome.png
+++ b/src/plugins/welcome/images/mode_welcome.png
Binary files differ
diff --git a/src/plugins/welcome/images/mode_welcome@2x.png b/src/plugins/welcome/images/mode_welcome@2x.png
index f1e91895231..f911a462542 100644
--- a/src/plugins/welcome/images/mode_welcome@2x.png
+++ b/src/plugins/welcome/images/mode_welcome@2x.png
Binary files differ
diff --git a/src/plugins/welcome/images/mode_welcome_mask.png b/src/plugins/welcome/images/mode_welcome_mask.png
index 86912bb0695..696af0c5499 100644
--- a/src/plugins/welcome/images/mode_welcome_mask.png
+++ b/src/plugins/welcome/images/mode_welcome_mask.png
Binary files differ
diff --git a/src/plugins/welcome/images/mode_welcome_mask@2x.png b/src/plugins/welcome/images/mode_welcome_mask@2x.png
index daee953529c..060ada0cf54 100644
--- a/src/plugins/welcome/images/mode_welcome_mask@2x.png
+++ b/src/plugins/welcome/images/mode_welcome_mask@2x.png
Binary files differ
diff --git a/src/plugins/welcome/welcome.qbs b/src/plugins/welcome/welcome.qbs
index d7febc088ce..4209a041168 100644
--- a/src/plugins/welcome/welcome.qbs
+++ b/src/plugins/welcome/welcome.qbs
@@ -7,6 +7,7 @@ QtcPlugin {
Depends { name: "Utils" }
Depends { name: "Core" }
+ Depends { name: "app_version_header" }
files: [
"welcome.qrc",
diff --git a/src/plugins/welcome/welcome.qrc b/src/plugins/welcome/welcome.qrc
index 5321c6ebd46..28e8d22d1c8 100644
--- a/src/plugins/welcome/welcome.qrc
+++ b/src/plugins/welcome/welcome.qrc
@@ -8,7 +8,6 @@
<file>images/blogs@2x.png</file>
<file>images/community.png</file>
<file>images/community@2x.png</file>
- <file>images/mode_edit_mask.png</file>
<file>images/open.png</file>
<file>images/open@2x.png</file>
<file>images/project.png</file>
diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp
index d0bde8e9946..848e0e64499 100644
--- a/src/plugins/welcome/welcomeplugin.cpp
+++ b/src/plugins/welcome/welcomeplugin.cpp
@@ -26,6 +26,8 @@
#include <extensionsystem/iplugin.h>
#include <extensionsystem/pluginmanager.h>
+#include <app/app_version.h>
+
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h>
@@ -228,7 +230,8 @@ public:
l->addWidget(newLabel);
auto learnLabel = new QLabel(tr("Learn how to develop your own applications "
- "and explore Qt Creator."), this);
+ "and explore %1.")
+ .arg(Core::Constants::IDE_DISPLAY_NAME), this);
learnLabel->setMaximumWidth(200);
learnLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
learnLabel->setWordWrap(true);
@@ -398,7 +401,7 @@ void WelcomeMode::addPage(IWelcomePage *page)
stackPage->setAutoFillBackground(true);
m_pageStack->insertWidget(idx, stackPage);
- auto onClicked = [this, page, pageId, stackPage] {
+ auto onClicked = [this, pageId, stackPage] {
m_activePage = pageId;
m_pageStack->setCurrentWidget(stackPage);
for (WelcomePageButton *pageButton : m_pageButtons)
diff --git a/src/plugins/winrt/images/winrtdevice.png b/src/plugins/winrt/images/winrtdevice.png
index d8f5bb71211..2b45adb69a1 100644
--- a/src/plugins/winrt/images/winrtdevice.png
+++ b/src/plugins/winrt/images/winrtdevice.png
Binary files differ
diff --git a/src/plugins/winrt/images/winrtdevice@2x.png b/src/plugins/winrt/images/winrtdevice@2x.png
index 305c2e9376d..a57f2b49783 100644
--- a/src/plugins/winrt/images/winrtdevice@2x.png
+++ b/src/plugins/winrt/images/winrtdevice@2x.png
Binary files differ
diff --git a/src/plugins/winrt/winrt.qbs b/src/plugins/winrt/winrt.qbs
index ea9c8f9746d..96ccca36903 100644
--- a/src/plugins/winrt/winrt.qbs
+++ b/src/plugins/winrt/winrt.qbs
@@ -9,6 +9,7 @@ QtcPlugin {
Depends { name: "QtSupport" }
Depends { name: "QmakeProjectManager" }
Depends { name: "Qt.gui" }
+ Depends { name: "app_version_header" }
files: [
"winrtconstants.h",
diff --git a/src/plugins/winrt/winrtdebugsupport.cpp b/src/plugins/winrt/winrtdebugsupport.cpp
index 7499200df17..03945602a08 100644
--- a/src/plugins/winrt/winrtdebugsupport.cpp
+++ b/src/plugins/winrt/winrtdebugsupport.cpp
@@ -27,6 +27,8 @@
#include "winrtrunconfiguration.h"
#include "winrtrunnerhelper.h"
+#include <app/app_version.h>
+
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
@@ -49,26 +51,27 @@ WinRtDebugSupport::WinRtDebugSupport(RunControl *runControl)
: DebuggerRunTool(runControl)
{
// FIXME: This is just working for local debugging;
- DebuggerStartParameters params;
- params.startMode = AttachExternal;
+ setStartMode(AttachExternal);
// The first Thread needs to be resumed manually.
- params.commandsAfterConnect = "~0 m";
+ setCommandsAfterConnect("~0 m");
QFileInfo debuggerHelper(QCoreApplication::applicationDirPath()
+ QLatin1String("/winrtdebughelper.exe"));
if (!debuggerHelper.isExecutable()) {
- reportFailure(tr("The WinRT debugging helper is missing from your Qt Creator "
- "installation. It was assumed to be located at %1").arg(
- debuggerHelper.absoluteFilePath()));
+ reportFailure(tr("The WinRT debugging helper is missing from your %1 "
+ "installation. It was assumed to be located at %2")
+ .arg(Core::Constants::IDE_DISPLAY_NAME)
+ .arg(debuggerHelper.absoluteFilePath()));
return;
}
if (isQmlDebugging()) {
- Utils::Port qmlDebugPort;
- if (!getFreePort(qmlDebugPort))
+ QUrl qmlServer = ProjectExplorer::urlFromLocalHostAndFreePort();
+ if (qmlServer.port() <= 0) {
+ reportFailure(tr("Not enough free ports for QML debugging."));
return;
- params.qmlServer.host = QHostAddress(QHostAddress::LocalHost).toString();
- params.qmlServer.port = qmlDebugPort;
+ }
+ setQmlServer(qmlServer);
}
QString errorMessage;
@@ -99,14 +102,14 @@ WinRtDebugSupport::WinRtDebugSupport(RunControl *runControl)
QList<QByteArray> arg = output.split(':');
if (arg.first() == "PID") {
bool ok =false;
- params.attachPID = Utils::ProcessHandle(arg.last().toInt(&ok));
+ int pid = arg.last().toInt(&ok);
if (!ok) {
reportFailure(tr("Cannot extract the PID from the WinRT debugging helper. "
"(output: %1)").arg(QString::fromLocal8Bit(output)));
return;
}
+ setAttachPid(Utils::ProcessHandle(pid));
server.close();
- setStartParameters(params);
return;
}
}
@@ -118,18 +121,6 @@ WinRtDebugSupport::WinRtDebugSupport(RunControl *runControl)
"the current run configuration."));
}
-bool WinRtDebugSupport::getFreePort(Utils::Port &qmlDebuggerPort)
-{
- QTcpServer server;
- if (!server.listen(QHostAddress::LocalHost,
- qmlDebuggerPort.isValid() ? qmlDebuggerPort.number() : 0)) {
- reportFailure(tr("Not enough free ports for QML debugging."));
- return false;
- }
- qmlDebuggerPort = Utils::Port(server.serverPort());
- return true;
-}
-
WinRtDebugSupport::~WinRtDebugSupport()
{
delete m_runner;
diff --git a/src/plugins/winrt/winrtdebugsupport.h b/src/plugins/winrt/winrtdebugsupport.h
index 0a8ed4e31ab..b8e3c6846ac 100644
--- a/src/plugins/winrt/winrtdebugsupport.h
+++ b/src/plugins/winrt/winrtdebugsupport.h
@@ -42,8 +42,6 @@ public:
~WinRtDebugSupport();
private:
- bool getFreePort(Utils::Port &qmlDebuggerPort);
-
WinRtRunnerHelper *m_runner = nullptr;
};
diff --git a/src/plugins/winrt/winrtrunconfiguration.cpp b/src/plugins/winrt/winrtrunconfiguration.cpp
index 4a29b722e84..6e83042dc98 100644
--- a/src/plugins/winrt/winrtrunconfiguration.cpp
+++ b/src/plugins/winrt/winrtrunconfiguration.cpp
@@ -44,14 +44,16 @@ static QString pathFromId(Core::Id id)
return id.suffixAfter(Constants::WINRT_RC_PREFIX);
}
-WinRtRunConfiguration::WinRtRunConfiguration(ProjectExplorer::Target *parent, Core::Id id)
- : RunConfiguration(parent, id)
- , m_proFilePath(pathFromId(id))
- , m_uninstallAfterStop(false)
+WinRtRunConfiguration::WinRtRunConfiguration(ProjectExplorer::Target *target)
+ : RunConfiguration(target)
{
setDisplayName(tr("Run App Package"));
- addExtraAspect(new ProjectExplorer::ArgumentsAspect(this,
- QLatin1String("WinRtRunConfigurationArgumentsId")));
+ addExtraAspect(new ProjectExplorer::ArgumentsAspect(this, "WinRtRunConfigurationArgumentsId"));
+}
+
+void WinRtRunConfiguration::initialize(Core::Id id)
+{
+ m_proFilePath = pathFromId(id);
}
QWidget *WinRtRunConfiguration::createConfigurationWidget()
diff --git a/src/plugins/winrt/winrtrunconfiguration.h b/src/plugins/winrt/winrtrunconfiguration.h
index 36bcf1ad438..9e3c13878c7 100644
--- a/src/plugins/winrt/winrtrunconfiguration.h
+++ b/src/plugins/winrt/winrtrunconfiguration.h
@@ -35,10 +35,9 @@ class WinRtRunConfiguration : public ProjectExplorer::RunConfiguration
Q_OBJECT
public:
- explicit WinRtRunConfiguration(ProjectExplorer::Target *parent, Core::Id id);
+ explicit WinRtRunConfiguration(ProjectExplorer::Target *target);
QWidget *createConfigurationWidget() override;
- bool isEnabled() const override { return true; } // Always enabled like DLL run control
QVariantMap toMap() const override;
bool fromMap(const QVariantMap &map) override;
@@ -54,8 +53,11 @@ signals:
void uninstallAfterStopChanged(bool);
private:
+ friend class ProjectExplorer::IRunConfigurationFactory;
+ void initialize(Core::Id id);
+
QString m_proFilePath;
- bool m_uninstallAfterStop;
+ bool m_uninstallAfterStop = false;
};
} // namespace Internal
diff --git a/src/plugins/winrt/winrtrunfactories.cpp b/src/plugins/winrt/winrtrunfactories.cpp
index 4adde539749..0c004f0c446 100644
--- a/src/plugins/winrt/winrtrunfactories.cpp
+++ b/src/plugins/winrt/winrtrunfactories.cpp
@@ -81,7 +81,7 @@ bool WinRtRunConfigurationFactory::canCreate(Target *parent, Core::Id id) const
RunConfiguration *WinRtRunConfigurationFactory::doCreate(Target *parent, Core::Id id)
{
- return new WinRtRunConfiguration(parent, id);
+ return createHelper<WinRtRunConfiguration>(parent, id);
}
bool WinRtRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
@@ -94,9 +94,7 @@ bool WinRtRunConfigurationFactory::canRestore(Target *parent, const QVariantMap
RunConfiguration *WinRtRunConfigurationFactory::doRestore(Target *parent, const QVariantMap &map)
{
- RunConfiguration *config = new WinRtRunConfiguration(parent, idFromMap(map));
- config->fromMap(map);
- return config;
+ return createHelper<WinRtRunConfiguration>(parent, idFromMap(map));
}
bool WinRtRunConfigurationFactory::canClone(Target *parent, RunConfiguration *product) const
diff --git a/src/shared/clang/clang_installation.pri b/src/shared/clang/clang_installation.pri
index 517ded4e4b4..f7428c0be3c 100644
--- a/src/shared/clang/clang_installation.pri
+++ b/src/shared/clang/clang_installation.pri
@@ -3,10 +3,10 @@ LLVM_INSTALL_DIR = $$clean_path($$LLVM_INSTALL_DIR)
isEmpty(LLVM_INSTALL_DIR): error("No LLVM_INSTALL_DIR provided")
!exists($$LLVM_INSTALL_DIR): error("LLVM_INSTALL_DIR does not exist: $$LLVM_INSTALL_DIR")
-defineReplace(extractVersion) { return($$replace(1, ^(\\d+\\.\\d+\\.\\d+)$, \\1)) }
-defineReplace(extractMajorVersion) { return($$replace(1, ^(\\d+)\\.\\d+\\.\\d+$, \\1)) }
-defineReplace(extractMinorVersion) { return($$replace(1, ^\\d+\\.(\\d+)\\.\\d+$, \\1)) }
-defineReplace(extractPatchVersion) { return($$replace(1, ^\\d+\\.\\d+\\.(\\d+)$, \\1)) }
+defineReplace(extractVersion) { return($$replace(1, ^(\\d+\\.\\d+\\.\\d+)\\w*$, \\1)) }
+defineReplace(extractMajorVersion) { return($$replace(1, ^(\\d+)\\.\\d+\\.\\d+\\w*$, \\1)) }
+defineReplace(extractMinorVersion) { return($$replace(1, ^\\d+\\.(\\d+)\\.\\d+\\w*$, \\1)) }
+defineReplace(extractPatchVersion) { return($$replace(1, ^\\d+\\.\\d+\\.(\\d+)\\w*$, \\1)) }
defineTest(versionIsAtLeast) {
actual_major_version = $$extractMajorVersion($$1)
diff --git a/src/shared/help/bookmarkmanager.cpp b/src/shared/help/bookmarkmanager.cpp
index 7b6015811b8..979ca7c5bf2 100644
--- a/src/shared/help/bookmarkmanager.cpp
+++ b/src/shared/help/bookmarkmanager.cpp
@@ -217,7 +217,7 @@ void BookmarkDialog::customContextMenuRequested(const QPoint &point)
if (!index.isValid())
return;
- QMenu menu(QLatin1String(""), this);
+ QMenu menu(this);
QAction *removeItem = menu.addAction(tr("Delete Folder"));
QAction *renameItem = menu.addAction(tr("Rename Folder"));
@@ -322,7 +322,7 @@ void BookmarkWidget::filterChanged()
regExp.setPattern(searchField->text());
filterBookmarkModel->setSourceModel(bookmarkManager->listBookmarkModel());
} else {
- regExp.setPattern(QLatin1String(""));
+ regExp.setPattern(QString());
filterBookmarkModel->setSourceModel(bookmarkManager->treeBookmarkModel());
}
@@ -366,7 +366,7 @@ void BookmarkWidget::customContextMenuRequested(const QPoint &point)
QAction *renameItem = 0;
QAction *showItemNewTab = 0;
- QMenu menu(QLatin1String(""), this);
+ QMenu menu(this);
QString data = index.data(Qt::UserRole + 10).toString();
if (data == QLatin1String("Folder")) {
removeItem = menu.addAction(tr("Delete Folder"));
diff --git a/src/tools/clangbackend/clangbackend.pro b/src/tools/clangbackend/clangbackend.pro
index f75775c8e78..b17d923a3b5 100644
--- a/src/tools/clangbackend/clangbackend.pro
+++ b/src/tools/clangbackend/clangbackend.pro
@@ -1,6 +1,6 @@
QTC_LIB_DEPENDS += \
sqlite \
- clangbackendipc
+ clangsupport
include(../../qtcreatortool.pri)
include(../../shared/clang/clang_installation.pri)
diff --git a/src/tools/clangbackend/clangbackend.qbs b/src/tools/clangbackend/clangbackend.qbs
index 457c218501a..4a1ca115792 100644
--- a/src/tools/clangbackend/clangbackend.qbs
+++ b/src/tools/clangbackend/clangbackend.qbs
@@ -3,7 +3,7 @@ import qbs 1.0
QtcTool {
name: "clangbackend"
- Depends { name: "ClangBackEndIpc" }
+ Depends { name: "ClangSupport" }
Depends { name: "libclang"; required: false }
Group {
diff --git a/src/tools/clangbackend/ipcsource/clangasyncjob.h b/src/tools/clangbackend/ipcsource/clangasyncjob.h
index c8a7b799473..58b6a1f8455 100644
--- a/src/tools/clangbackend/ipcsource/clangasyncjob.h
+++ b/src/tools/clangbackend/ipcsource/clangasyncjob.h
@@ -47,7 +47,7 @@ public:
Result asyncResult() const { return m_futureWatcher.future().result(); }
- QFuture<void> runAsync() override
+ QFuture<void> runAsync() final
{
const auto onFinished = [this]() {
finalizeAsyncRun();
@@ -64,7 +64,7 @@ public:
return future;
}
- void preventFinalization() override
+ void preventFinalization() final
{
m_futureWatcher.disconnect();
}
diff --git a/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri b/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri
index 877d63ca9cc..6919db68399 100644
--- a/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri
+++ b/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri
@@ -9,6 +9,7 @@ HEADERS += \
$$PWD/clangcompletecodejob.h \
$$PWD/clangcreateinitialdocumentpreamblejob.h \
$$PWD/clangdocument.h \
+ $$PWD/clangdocumentjob.h \
$$PWD/clangdocumentprocessor.h \
$$PWD/clangdocumentprocessors.h \
$$PWD/clangdocuments.h \
@@ -16,6 +17,8 @@ HEADERS += \
$$PWD/clangexceptions.h \
$$PWD/clangfilepath.h \
$$PWD/clangfilesystemwatcher.h \
+ $$PWD/clangfollowsymboljob.h \
+ $$PWD/clangfollowsymbol.h \
$$PWD/clangiasyncjob.h \
$$PWD/clangjobcontext.h \
$$PWD/clangjobqueue.h \
@@ -55,7 +58,7 @@ HEADERS += \
$$PWD/sourcerange.h \
$$PWD/unsavedfile.h \
$$PWD/unsavedfiles.h \
- $$PWD/utf8positionfromlinecolumn.h \
+ $$PWD/utf8positionfromlinecolumn.h
SOURCES += \
$$PWD/clangcodecompleteresults.cpp \
@@ -70,6 +73,8 @@ SOURCES += \
$$PWD/clangexceptions.cpp \
$$PWD/clangfilepath.cpp \
$$PWD/clangfilesystemwatcher.cpp \
+ $$PWD/clangfollowsymboljob.cpp \
+ $$PWD/clangfollowsymbol.cpp \
$$PWD/clangiasyncjob.cpp \
$$PWD/clangjobcontext.cpp \
$$PWD/clangjobqueue.cpp \
@@ -106,4 +111,4 @@ SOURCES += \
$$PWD/sourcerange.cpp \
$$PWD/unsavedfile.cpp \
$$PWD/unsavedfiles.cpp \
- $$PWD/utf8positionfromlinecolumn.cpp \
+ $$PWD/utf8positionfromlinecolumn.cpp
diff --git a/src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp b/src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp
index 6dae8b266f4..9def46b2dba 100644
--- a/src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp
+++ b/src/tools/clangbackend/ipcsource/clangcodemodelserver.cpp
@@ -35,8 +35,8 @@
#include "clangexceptions.h"
#include "skippedsourceranges.h"
-#include <clangbackendipc/clangbackendipcdebugutils.h>
-#include <clangbackendipc/clangcodemodelservermessages.h>
+#include <clangsupport/clangsupportdebugutils.h>
+#include <clangsupport/clangcodemodelservermessages.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -212,6 +212,8 @@ void ClangCodeModelServer::completeCode(const ClangBackEnd::CompleteCodeMessage
JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::CompleteCode);
jobRequest.line = message.line();
jobRequest.column = message.column();
+ jobRequest.funcNameStartLine = message.funcNameStartLine();
+ jobRequest.funcNameStartColumn = message.funcNameStartColumn();
jobRequest.ticketNumber = message.ticketNumber();
processor.addJob(jobRequest);
@@ -237,6 +239,17 @@ void ClangCodeModelServer::requestDocumentAnnotations(const RequestDocumentAnnot
}
}
+template <class MessageType>
+static void fillJobRequest(JobRequest &jobRequest, const MessageType &message)
+{
+ jobRequest.line = message.line();
+ jobRequest.column = message.column();
+ jobRequest.ticketNumber = message.ticketNumber();
+ // The unsaved files might get updater later, so take the current
+ // revision for the request.
+ jobRequest.documentRevision = message.fileContainer().documentRevision();
+}
+
void ClangCodeModelServer::requestReferences(const RequestReferencesMessage &message)
{
TIME_SCOPE_DURATION("ClangCodeModelServer::requestReferences");
@@ -247,13 +260,7 @@ void ClangCodeModelServer::requestReferences(const RequestReferencesMessage &mes
DocumentProcessor processor = documentProcessors().processor(document);
JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::RequestReferences);
- jobRequest.line = message.line();
- jobRequest.column = message.column();
- jobRequest.ticketNumber = message.ticketNumber();
- // The unsaved files might get updater later, so take the current
- // revision for the request.
- jobRequest.documentRevision = message.fileContainer().documentRevision();
-
+ fillJobRequest(jobRequest, message);
processor.addJob(jobRequest);
processor.process();
} catch (const std::exception &exception) {
@@ -261,6 +268,26 @@ void ClangCodeModelServer::requestReferences(const RequestReferencesMessage &mes
}
}
+void ClangCodeModelServer::requestFollowSymbol(const RequestFollowSymbolMessage &message)
+{
+ TIME_SCOPE_DURATION("ClangCodeModelServer::requestFollowSymbol");
+
+ try {
+ auto projectPartId = message.fileContainer().projectPartId();
+ Document document = documents.document(message.fileContainer().filePath(),
+ projectPartId);
+ DocumentProcessor processor = documentProcessors().processor(document);
+
+ JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::FollowSymbol);
+ fillJobRequest(jobRequest, message);
+ jobRequest.dependentFiles = message.dependentFiles();
+ processor.addJob(jobRequest);
+ processor.process();
+ } catch (const std::exception &exception) {
+ qWarning() << "Error in ClangCodeModelServer::requestFollowSymbol:" << exception.what();
+ }
+}
+
void ClangCodeModelServer::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
{
TIME_SCOPE_DURATION("ClangCodeModelServer::updateVisibleTranslationUnits");
diff --git a/src/tools/clangbackend/ipcsource/clangcodemodelserver.h b/src/tools/clangbackend/ipcsource/clangcodemodelserver.h
index d5fc33250b3..5e9e2934a69 100644
--- a/src/tools/clangbackend/ipcsource/clangcodemodelserver.h
+++ b/src/tools/clangbackend/ipcsource/clangcodemodelserver.h
@@ -25,8 +25,6 @@
#pragma once
-#include "clangcodemodelserverinterface.h"
-
#include "projectpart.h"
#include "projects.h"
#include "clangdocument.h"
@@ -35,6 +33,8 @@
#include "clangjobrequest.h"
#include "unsavedfiles.h"
+#include <clangcodemodelserverinterface.h>
+#include <ipcclientprovider.h>
#include <utf8string.h>
#include <QScopedPointer>
@@ -42,7 +42,8 @@
namespace ClangBackEnd {
-class ClangCodeModelServer : public ClangCodeModelServerInterface
+class ClangCodeModelServer : public ClangCodeModelServerInterface,
+ public IpcClientProvider<ClangCodeModelClientInterface>
{
public:
ClangCodeModelServer();
@@ -59,6 +60,7 @@ public:
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
void requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &message) override;
void requestReferences(const RequestReferencesMessage &message) override;
+ void requestFollowSymbol(const RequestFollowSymbolMessage &message) override;
public: // for tests
const Documents &documentsForTestOnly() const;
diff --git a/src/tools/clangbackend/ipcsource/clangcompletecodejob.cpp b/src/tools/clangbackend/ipcsource/clangcompletecodejob.cpp
index d45f53fdda0..9970d59269b 100644
--- a/src/tools/clangbackend/ipcsource/clangcompletecodejob.cpp
+++ b/src/tools/clangbackend/ipcsource/clangcompletecodejob.cpp
@@ -25,53 +25,43 @@
#include "clangcompletecodejob.h"
-#include <clangbackendipc/clangbackendipcdebugutils.h>
-#include <clangbackendipc/clangcodemodelclientinterface.h>
-#include <clangbackendipc/cmbcodecompletedmessage.h>
+#include <clangsupport/clangsupportdebugutils.h>
+#include <clangsupport/clangcodemodelclientinterface.h>
+#include <clangsupport/cmbcodecompletedmessage.h>
#include <utils/qtcassert.h>
namespace ClangBackEnd {
-static CompleteCodeJob::AsyncResult runAsyncHelper(const TranslationUnit &translationUnit,
- UnsavedFiles unsavedFiles,
- quint32 line,
- quint32 column)
-{
- TIME_SCOPE_DURATION("CompleteCodeJobRunner");
-
- const TranslationUnit::CodeCompletionResult results
- = translationUnit.complete(unsavedFiles, line, column);
-
- CompleteCodeJob::AsyncResult asyncResult;
- asyncResult.completions = results.completions;
- asyncResult.correction = results.correction;
-
- return asyncResult;
-}
-
IAsyncJob::AsyncPrepareResult CompleteCodeJob::prepareAsyncRun()
{
const JobRequest jobRequest = context().jobRequest;
QTC_ASSERT(jobRequest.type == JobRequest::Type::CompleteCode, return AsyncPrepareResult());
+ QTC_ASSERT(acquireDocument(), return AsyncPrepareResult());
- try {
- m_pinnedDocument = context().documentForJobRequest();
+ const TranslationUnit translationUnit = *m_translationUnit;
+ const UnsavedFiles unsavedFiles = *context().unsavedFiles;
+ const quint32 line = jobRequest.line;
+ const quint32 column = jobRequest.column;
+ const qint32 funcNameStartLine = jobRequest.funcNameStartLine;
+ const qint32 funcNameStartColumn = jobRequest.funcNameStartColumn;
+ setRunner([translationUnit, unsavedFiles, line, column,
+ funcNameStartLine, funcNameStartColumn]() {
+ TIME_SCOPE_DURATION("CompleteCodeJobRunner");
- const TranslationUnit translationUnit
- = m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
- const UnsavedFiles unsavedFiles = *context().unsavedFiles;
- const quint32 line = jobRequest.line;
- const quint32 column = jobRequest.column;
- setRunner([translationUnit, unsavedFiles, line, column]() {
- return runAsyncHelper(translationUnit, unsavedFiles, line, column);
- });
- return AsyncPrepareResult{translationUnit.id()};
+ UnsavedFiles theUnsavedFiles = unsavedFiles;
+ const TranslationUnit::CodeCompletionResult results
+ = translationUnit.complete(theUnsavedFiles, line, column,
+ funcNameStartLine, funcNameStartColumn);
- } catch (const std::exception &exception) {
- qWarning() << "Error in CompleteCodeJob::prepareAsyncRun:" << exception.what();
- return AsyncPrepareResult();
- }
+ CompleteCodeJob::AsyncResult asyncResult;
+ asyncResult.completions = results.completions;
+ asyncResult.correction = results.correction;
+
+ return asyncResult;
+ });
+
+ return AsyncPrepareResult{translationUnit.id()};
}
void CompleteCodeJob::finalizeAsyncRun()
diff --git a/src/tools/clangbackend/ipcsource/clangcompletecodejob.h b/src/tools/clangbackend/ipcsource/clangcompletecodejob.h
index 142988d7403..4e9c274faf9 100644
--- a/src/tools/clangbackend/ipcsource/clangcompletecodejob.h
+++ b/src/tools/clangbackend/ipcsource/clangcompletecodejob.h
@@ -25,10 +25,9 @@
#pragma once
-#include "clangasyncjob.h"
-#include "clangdocument.h"
+#include "clangdocumentjob.h"
-#include <clangbackendipc/codecompletion.h>
+#include <clangsupport/codecompletion.h>
namespace ClangBackEnd {
@@ -38,16 +37,13 @@ struct CompleteCodeJobResult
CompletionCorrection correction = CompletionCorrection::NoCorrection;
};
-class CompleteCodeJob : public AsyncJob<CompleteCodeJobResult>
+class CompleteCodeJob : public DocumentJob<CompleteCodeJobResult>
{
public:
using AsyncResult = CompleteCodeJobResult;
AsyncPrepareResult prepareAsyncRun() override;
void finalizeAsyncRun() override;
-
-private:
- Document m_pinnedDocument;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.cpp b/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.cpp
index a9bf6698661..b60a5ca613f 100644
--- a/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.cpp
+++ b/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.cpp
@@ -25,42 +25,26 @@
#include "clangcreateinitialdocumentpreamblejob.h"
-#include <clangbackendipc/clangbackendipcdebugutils.h>
+#include <clangsupport/clangsupportdebugutils.h>
#include <utils/qtcassert.h>
namespace ClangBackEnd {
-static void runAsyncHelper(const TranslationUnit &translationUnit,
- const TranslationUnitUpdateInput &translationUnitUpdateInput)
-{
- TIME_SCOPE_DURATION("CreateInitialDocumentPreambleJobRunner");
-
- translationUnit.reparse(translationUnitUpdateInput);
-}
-
IAsyncJob::AsyncPrepareResult CreateInitialDocumentPreambleJob::prepareAsyncRun()
{
const JobRequest jobRequest = context().jobRequest;
QTC_ASSERT(jobRequest.type == JobRequest::Type::CreateInitialDocumentPreamble, return AsyncPrepareResult());
+ QTC_ASSERT(acquireDocument(), return AsyncPrepareResult());
- try {
- m_pinnedDocument = context().documentForJobRequest();
- m_pinnedFileContainer = m_pinnedDocument.fileContainer();
-
- const TranslationUnit translationUnit
- = m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
- const TranslationUnitUpdateInput updateInput = m_pinnedDocument.createUpdateInput();
- setRunner([translationUnit, updateInput]() {
- return runAsyncHelper(translationUnit, updateInput);
- });
- return AsyncPrepareResult{translationUnit.id()};
+ const TranslationUnit translationUnit = *m_translationUnit;
+ const TranslationUnitUpdateInput updateInput = m_pinnedDocument.createUpdateInput();
+ setRunner([translationUnit, updateInput]() {
+ TIME_SCOPE_DURATION("CreateInitialDocumentPreambleJobRunner");
+ return translationUnit.reparse(updateInput);
+ });
- } catch (const std::exception &exception) {
- qWarning() << "Error in CreateInitialDocumentPreambleJob::prepareAsyncRun:"
- << exception.what();
- return AsyncPrepareResult();
- }
+ return AsyncPrepareResult{translationUnit.id()};
}
void CreateInitialDocumentPreambleJob::finalizeAsyncRun()
diff --git a/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.h b/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.h
index 570b746460e..f8b790ea36d 100644
--- a/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.h
+++ b/src/tools/clangbackend/ipcsource/clangcreateinitialdocumentpreamblejob.h
@@ -25,20 +25,15 @@
#pragma once
-#include "clangasyncjob.h"
-#include "clangdocument.h"
+#include "clangdocumentjob.h"
namespace ClangBackEnd {
-class CreateInitialDocumentPreambleJob : public AsyncJob<void>
+class CreateInitialDocumentPreambleJob : public DocumentJob<void>
{
public:
AsyncPrepareResult prepareAsyncRun() override;
void finalizeAsyncRun() override;
-
-private:
- Document m_pinnedDocument;
- FileContainer m_pinnedFileContainer;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangdocumentjob.h b/src/tools/clangbackend/ipcsource/clangdocumentjob.h
new file mode 100644
index 00000000000..7808286ce0b
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/clangdocumentjob.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "clangasyncjob.h"
+#include "clangdocument.h"
+
+#include <clangsupport/filecontainer.h>
+
+#include <memory>
+
+namespace ClangBackEnd {
+
+template<class Result>
+class DocumentJob : public AsyncJob<Result>
+{
+protected:
+ bool acquireDocument()
+ {
+ try {
+ m_pinnedDocument = IAsyncJob::context().documentForJobRequest();
+ m_pinnedFileContainer = m_pinnedDocument.fileContainer();
+
+ const PreferredTranslationUnit preferredTranslationUnit
+ = IAsyncJob::context().jobRequest.preferredTranslationUnit;
+ m_translationUnit.reset(
+ new TranslationUnit(m_pinnedDocument.translationUnit(preferredTranslationUnit)));
+ return true;
+ } catch (const std::exception &) {
+ return false;
+ }
+ }
+
+protected:
+ Document m_pinnedDocument;
+ FileContainer m_pinnedFileContainer;
+
+ std::unique_ptr<TranslationUnit> m_translationUnit;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.cpp b/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.cpp
index bae98893187..cd0e29b5d05 100644
--- a/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.cpp
+++ b/src/tools/clangbackend/ipcsource/clangdocumentsuspenderresumer.cpp
@@ -25,7 +25,7 @@
#include "clangdocumentsuspenderresumer.h"
-#include "clangbackendipc_global.h"
+#include "clangsupport_global.h"
#include "clangdocumentprocessors.h"
#include "clangdocuments.h"
diff --git a/src/tools/clangbackend/ipcsource/clangfollowsymbol.cpp b/src/tools/clangbackend/ipcsource/clangfollowsymbol.cpp
new file mode 100644
index 00000000000..bc151bc93c4
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/clangfollowsymbol.cpp
@@ -0,0 +1,337 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "clangfollowsymbol.h"
+#include "clangfollowsymboljob.h"
+#include "commandlinearguments.h"
+#include "cursor.h"
+#include "clangstring.h"
+#include "sourcerange.h"
+#include "clangsupportdebugutils.h"
+
+#include <utils/qtcassert.h>
+
+#include <future>
+
+namespace ClangBackEnd {
+
+namespace {
+
+struct Tokens
+{
+ Tokens(const Tokens &) = delete;
+ Tokens(const Cursor &cursor) {
+ tu = cursor.cxTranslationUnit();
+ clang_tokenize(tu, cursor.cxSourceRange(), &data, &tokenCount);
+ }
+ Tokens(const CXTranslationUnit &tu) {
+ const CXSourceRange range
+ = clang_getCursorExtent(clang_getTranslationUnitCursor(tu));
+ clang_tokenize(tu, range, &data, &tokenCount);
+ }
+ ~Tokens() {
+ clang_disposeTokens(tu, data, tokenCount);
+ }
+
+ CXToken *data = nullptr;
+ uint tokenCount = 0;
+private:
+ CXTranslationUnit tu;
+};
+
+class FollowSymbolData {
+public:
+ FollowSymbolData() = delete;
+ FollowSymbolData(const Utf8String &usr, const Utf8String &tokenSpelling, bool isFunctionLike,
+ std::atomic<bool> &ready)
+ : m_usr(usr)
+ , m_spelling(tokenSpelling)
+ , m_isFunctionLike(isFunctionLike)
+ , m_ready(ready)
+ {}
+ FollowSymbolData(const FollowSymbolData &other)
+ : m_usr(other.m_usr)
+ , m_spelling(other.m_spelling)
+ , m_isFunctionLike(other.m_isFunctionLike)
+ , m_ready(other.m_ready)
+ {}
+
+ const Utf8String &usr() const { return m_usr; }
+ const Utf8String &spelling() const { return m_spelling; }
+ bool isFunctionLike() const { return m_isFunctionLike; }
+ bool ready() const { return m_ready; }
+ const SourceRangeContainer &result() const { return m_result; }
+
+ void setReady(bool ready = true) { m_ready = ready; }
+ void setResult(const SourceRangeContainer &result) { m_result = result; }
+private:
+ const Utf8String &m_usr;
+ const Utf8String &m_spelling;
+ SourceRangeContainer m_result;
+ bool m_isFunctionLike;
+ std::atomic<bool> &m_ready;
+};
+
+} // anonymous namespace
+
+static SourceRange getOperatorRange(const CXTranslationUnit tu,
+ const Tokens &tokens,
+ uint operatorIndex)
+{
+ const CXSourceLocation start = clang_getTokenLocation(tu, tokens.data[operatorIndex]);
+ operatorIndex += 2;
+ while (operatorIndex < tokens.tokenCount
+ && !(ClangString(clang_getTokenSpelling(tu, tokens.data[operatorIndex])) == "(")) {
+ ++operatorIndex;
+ }
+ const CXSourceLocation end = clang_getTokenLocation(tu, tokens.data[operatorIndex]);
+ return SourceRange(clang_getRange(start, end));
+}
+
+static SourceRangeContainer extractMatchingTokenRange(const Cursor &cursor,
+ const Utf8String &tokenStr)
+{
+ Tokens tokens(cursor);
+ const CXTranslationUnit tu = cursor.cxTranslationUnit();
+ for (uint i = 0; i < tokens.tokenCount; ++i) {
+ if (!(tokenStr == ClangString(clang_getTokenSpelling(tu, tokens.data[i]))))
+ continue;
+
+ if (cursor.isFunctionLike() || cursor.isConstructorOrDestructor()) {
+ if (tokenStr == "operator")
+ return getOperatorRange(tu, tokens, i);
+
+ if (i+1 > tokens.tokenCount
+ || !(ClangString(clang_getTokenSpelling(tu, tokens.data[i+1])) == "(")) {
+ continue;
+ }
+ }
+ return SourceRange(clang_getTokenExtent(tu, tokens.data[i]));
+ }
+ return SourceRangeContainer();
+}
+
+static void handleDeclaration(CXClientData client_data, const CXIdxDeclInfo *declInfo)
+{
+ if (!declInfo || !declInfo->isDefinition)
+ return;
+
+ const Cursor currentCursor(declInfo->cursor);
+ auto* data = reinterpret_cast<FollowSymbolData*>(client_data);
+ if (data->ready())
+ return;
+
+ if (data->usr() != currentCursor.canonical().unifiedSymbolResolution())
+ return;
+
+ QString str = Utf8String(currentCursor.displayName());
+ if (currentCursor.isFunctionLike() || currentCursor.isConstructorOrDestructor()) {
+ if (!data->isFunctionLike())
+ return;
+ str = str.mid(0, str.indexOf('('));
+ } else if (data->isFunctionLike()) {
+ return;
+ }
+ if (!str.endsWith(data->spelling()))
+ return;
+ const CXTranslationUnit tu = clang_Cursor_getTranslationUnit(declInfo->cursor);
+ Tokens tokens(currentCursor);
+
+ for (uint i = 0; i < tokens.tokenCount; ++i) {
+ Utf8String curSpelling = ClangString(clang_getTokenSpelling(tu, tokens.data[i]));
+ if (data->spelling() == curSpelling) {
+ if (data->isFunctionLike()
+ && (i+1 >= tokens.tokenCount
+ || !(ClangString(clang_getTokenSpelling(tu, tokens.data[i+1])) == "("))) {
+ continue;
+ }
+ data->setResult(SourceRange(clang_getTokenExtent(tu, tokens.data[i])));
+ data->setReady();
+ return;
+ }
+ }
+}
+
+static int getTokenIndex(CXTranslationUnit tu, const Tokens &tokens, uint line, uint column)
+{
+ int tokenIndex = -1;
+ for (int i = static_cast<int>(tokens.tokenCount - 1); i >= 0; --i) {
+ const SourceRange range = clang_getTokenExtent(tu, tokens.data[i]);
+ if (range.contains(line, column)) {
+ tokenIndex = i;
+ break;
+ }
+ }
+ return tokenIndex;
+}
+
+static IndexerCallbacks createIndexerCallbacks()
+{
+ return {
+ [](CXClientData client_data, void *) {
+ auto* data = reinterpret_cast<FollowSymbolData*>(client_data);
+ return data->ready() ? 1 : 0;
+ },
+ [](CXClientData, CXDiagnosticSet, void *) {},
+ [](CXClientData, CXFile, void *) { return CXIdxClientFile(); },
+ [](CXClientData, const CXIdxIncludedFileInfo *) { return CXIdxClientFile(); },
+ [](CXClientData, const CXIdxImportedASTFileInfo *) { return CXIdxClientASTFile(); },
+ [](CXClientData, void *) { return CXIdxClientContainer(); },
+ handleDeclaration,
+ [](CXClientData, const CXIdxEntityRefInfo *) {}
+ };
+}
+
+static SourceRangeContainer followSymbolInDependentFiles(CXIndex index,
+ const Cursor &cursor,
+ const Utf8String &tokenSpelling,
+ const QVector<Utf8String> &dependentFiles,
+ const CommandLineArguments &currentArgs)
+{
+ int argsCount = 0;
+ if (currentArgs.data())
+ argsCount = currentArgs.count() - 1;
+
+ const Utf8String usr = cursor.canonical().unifiedSymbolResolution();
+
+ // ready is shared for all data in vector
+ std::atomic<bool> ready {false};
+ std::vector<FollowSymbolData> dataVector(
+ dependentFiles.size(),
+ FollowSymbolData(usr, tokenSpelling,
+ cursor.isFunctionLike() || cursor.isConstructorOrDestructor(),
+ ready));
+
+ std::vector<std::future<void>> indexFutures;
+
+ for (int i = 0; i < dependentFiles.size(); ++i) {
+ if (i > 0 && ready)
+ break;
+ indexFutures.emplace_back(std::async([&, i]() {
+ TIME_SCOPE_DURATION("Dependent file " + dependentFiles.at(i) + " indexer runner");
+
+ const CXIndexAction indexAction = clang_IndexAction_create(index);
+ IndexerCallbacks callbacks = createIndexerCallbacks();
+ clang_indexSourceFile(indexAction,
+ &dataVector[i],
+ &callbacks,
+ sizeof(callbacks),
+ CXIndexOpt_SkipParsedBodiesInSession
+ | CXIndexOpt_SuppressRedundantRefs
+ | CXIndexOpt_SuppressWarnings,
+ dependentFiles.at(i).constData(),
+ currentArgs.data(),
+ argsCount,
+ nullptr,
+ 0,
+ nullptr,
+ CXTranslationUnit_SkipFunctionBodies
+ | CXTranslationUnit_KeepGoing);
+ clang_IndexAction_dispose(indexAction);
+ }));
+ }
+
+ for (const std::future<void> &future: indexFutures)
+ future.wait();
+
+ for (const FollowSymbolData &data: dataVector) {
+ if (!data.result().start().filePath().isEmpty()) {
+ return data.result();
+ }
+ }
+ return SourceRangeContainer();
+}
+
+SourceRangeContainer FollowSymbol::followSymbol(CXTranslationUnit tu,
+ CXIndex index,
+ const Cursor &fullCursor,
+ uint line,
+ uint column,
+ const QVector<Utf8String> &dependentFiles,
+ const CommandLineArguments &currentArgs)
+{
+ std::unique_ptr<Tokens> tokens(new Tokens(fullCursor));
+
+ if (!tokens->tokenCount)
+ tokens.reset(new Tokens(tu));
+
+ if (!tokens->tokenCount)
+ return SourceRangeContainer();
+
+ QVector<CXCursor> cursors(static_cast<int>(tokens->tokenCount));
+ clang_annotateTokens(tu, tokens->data, tokens->tokenCount, cursors.data());
+ int tokenIndex = getTokenIndex(tu, *tokens, line, column);
+ QTC_ASSERT(tokenIndex >= 0, return SourceRangeContainer());
+
+ const Utf8String tokenSpelling = ClangString(
+ clang_getTokenSpelling(tu, tokens->data[tokenIndex]));
+ if (tokenSpelling.isEmpty())
+ return SourceRangeContainer();
+
+ Cursor cursor{cursors[tokenIndex]};
+
+ if (cursor.kind() == CXCursor_InclusionDirective) {
+ CXFile file = clang_getIncludedFile(cursors[tokenIndex]);
+ const ClangString filename(clang_getFileName(file));
+ const SourceLocation loc(tu, filename, 1, 1);
+ return SourceRange(loc, loc);
+ }
+
+ // For definitions we can always find a declaration in current TU
+ if (cursor.isDefinition())
+ return extractMatchingTokenRange(cursor.canonical(), tokenSpelling);
+
+ SourceRangeContainer result;
+ if (!cursor.isDeclaration()) {
+ // This is the symbol usage
+ // We want to return definition or at least declaration of this symbol
+ const Cursor referencedCursor = cursor.referenced();
+ if (referencedCursor.isNull() || referencedCursor == cursor)
+ return SourceRangeContainer();
+ result = extractMatchingTokenRange(referencedCursor, tokenSpelling);
+
+ // We've already found what we need
+ if (referencedCursor.isDefinition())
+ return result;
+ cursor = referencedCursor;
+ }
+
+ const Cursor definitionCursor = cursor.definition();
+ if (!definitionCursor.isNull() && definitionCursor != cursor) {
+ // If we are able to find a definition in current TU
+ return extractMatchingTokenRange(definitionCursor, tokenSpelling);
+ }
+
+ // Search for the definition in the dependent files
+ SourceRangeContainer dependentFilesResult = followSymbolInDependentFiles(index,
+ cursor,
+ tokenSpelling,
+ dependentFiles,
+ currentArgs);
+ return dependentFilesResult.start().filePath().isEmpty() ?
+ result : dependentFilesResult;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangfollowsymbol.h b/src/tools/clangbackend/ipcsource/clangfollowsymbol.h
new file mode 100644
index 00000000000..a881bd9631d
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/clangfollowsymbol.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QVector>
+
+#include <clang-c/Index.h>
+
+class Utf8String;
+
+namespace ClangBackEnd {
+
+class Cursor;
+class SourceRangeContainer;
+class CommandLineArguments;
+
+class FollowSymbol
+{
+public:
+ static SourceRangeContainer followSymbol(CXTranslationUnit tu,
+ CXIndex index,
+ const Cursor &fullCursor,
+ uint line,
+ uint column,
+ const QVector<Utf8String> &dependentFiles,
+ const CommandLineArguments &currentArgs);
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangfollowsymboljob.cpp b/src/tools/clangbackend/ipcsource/clangfollowsymboljob.cpp
new file mode 100644
index 00000000000..7136db34326
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/clangfollowsymboljob.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "clangfollowsymboljob.h"
+
+#include <clangsupport/clangsupportdebugutils.h>
+#include <clangsupport/followsymbolmessage.h>
+#include <clangsupport/clangcodemodelclientinterface.h>
+
+#include <utils/qtcassert.h>
+
+namespace ClangBackEnd {
+
+IAsyncJob::AsyncPrepareResult FollowSymbolJob::prepareAsyncRun()
+{
+ const JobRequest jobRequest = context().jobRequest;
+ QTC_ASSERT(jobRequest.type == JobRequest::Type::FollowSymbol,
+ return AsyncPrepareResult());
+ QTC_ASSERT(acquireDocument(), return AsyncPrepareResult());
+
+ const TranslationUnit translationUnit = *m_translationUnit;
+ const TranslationUnitUpdateInput updateInput = m_pinnedDocument.createUpdateInput();
+ const CommandLineArguments currentArgs(updateInput.filePath.constData(),
+ updateInput.projectArguments,
+ updateInput.fileArguments,
+ false);
+
+ const quint32 line = jobRequest.line;
+ const quint32 column = jobRequest.column;
+ const QVector<Utf8String> &dependentFiles = jobRequest.dependentFiles;
+ setRunner([translationUnit, line, column, dependentFiles, currentArgs]() {
+ TIME_SCOPE_DURATION("FollowSymbolJobRunner");
+ return translationUnit.followSymbol(line, column, dependentFiles, currentArgs);
+ });
+
+ return AsyncPrepareResult{translationUnit.id()};
+}
+
+void FollowSymbolJob::finalizeAsyncRun()
+{
+ if (!context().isOutdated()) {
+ const AsyncResult result = asyncResult();
+
+ const FollowSymbolMessage message(m_pinnedFileContainer,
+ result,
+ context().jobRequest.ticketNumber);
+ context().client->followSymbol(message);
+ }
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangfollowsymboljob.h b/src/tools/clangbackend/ipcsource/clangfollowsymboljob.h
new file mode 100644
index 00000000000..3a8741db1c6
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/clangfollowsymboljob.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "clangdocumentjob.h"
+
+#include <clangsupport/sourcerangecontainer.h>
+
+namespace ClangBackEnd {
+
+class FollowSymbolJob : public DocumentJob<SourceRangeContainer>
+{
+public:
+ using AsyncResult = SourceRangeContainer;
+
+ AsyncPrepareResult prepareAsyncRun() override;
+ void finalizeAsyncRun() override;
+};
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangiasyncjob.cpp b/src/tools/clangbackend/ipcsource/clangiasyncjob.cpp
index db3aebfe8e4..c325c494c9b 100644
--- a/src/tools/clangbackend/ipcsource/clangiasyncjob.cpp
+++ b/src/tools/clangbackend/ipcsource/clangiasyncjob.cpp
@@ -25,46 +25,10 @@
#include "clangiasyncjob.h"
-#include "clangcompletecodejob.h"
-#include "clangcreateinitialdocumentpreamblejob.h"
-#include "clangparsesupportivetranslationunitjob.h"
-#include "clangreparsesupportivetranslationunitjob.h"
-#include "clangrequestdocumentannotationsjob.h"
-#include "clangrequestreferencesjob.h"
-#include "clangresumedocumentjob.h"
-#include "clangsuspenddocumentjob.h"
-#include "clangupdatedocumentannotationsjob.h"
-
Q_LOGGING_CATEGORY(jobsLog, "qtc.clangbackend.jobs");
namespace ClangBackEnd {
-IAsyncJob *IAsyncJob::create(JobRequest::Type type)
-{
- switch (type) {
- case JobRequest::Type::UpdateDocumentAnnotations:
- return new UpdateDocumentAnnotationsJob();
- case JobRequest::Type::ParseSupportiveTranslationUnit:
- return new ParseSupportiveTranslationUnitJob();
- case JobRequest::Type::ReparseSupportiveTranslationUnit:
- return new ReparseSupportiveTranslationUnitJob();
- case JobRequest::Type::CreateInitialDocumentPreamble:
- return new CreateInitialDocumentPreambleJob();
- case JobRequest::Type::CompleteCode:
- return new CompleteCodeJob();
- case JobRequest::Type::RequestDocumentAnnotations:
- return new RequestDocumentAnnotationsJob();
- case JobRequest::Type::RequestReferences:
- return new RequestReferencesJob();
- case JobRequest::Type::SuspendDocument:
- return new SuspendDocumentJob();
- case JobRequest::Type::ResumeDocument:
- return new ResumeDocumentJob();
- }
-
- return nullptr;
-}
-
IAsyncJob::IAsyncJob()
: m_context(JobContext())
{
diff --git a/src/tools/clangbackend/ipcsource/clangiasyncjob.h b/src/tools/clangbackend/ipcsource/clangiasyncjob.h
index 98f61e857ab..e4481fcbf5d 100644
--- a/src/tools/clangbackend/ipcsource/clangiasyncjob.h
+++ b/src/tools/clangbackend/ipcsource/clangiasyncjob.h
@@ -39,8 +39,6 @@ namespace ClangBackEnd {
class IAsyncJob
{
public:
- static IAsyncJob *create(JobRequest::Type type);
-
struct AsyncPrepareResult {
operator bool() const { return !translationUnitId.isEmpty(); }
Utf8String translationUnitId;
diff --git a/src/tools/clangbackend/ipcsource/clangjobqueue.cpp b/src/tools/clangbackend/ipcsource/clangjobqueue.cpp
index 383c2ecaa45..4ea098db3ac 100644
--- a/src/tools/clangbackend/ipcsource/clangjobqueue.cpp
+++ b/src/tools/clangbackend/ipcsource/clangjobqueue.cpp
@@ -105,11 +105,11 @@ void JobQueue::removeExpiredRequests()
bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest)
{
- const JobRequest::ExpirationReasons expirationReasons = jobRequest.expirationReasons;
+ const JobRequest::ExpirationConditions conditions = jobRequest.expirationConditions;
const UnsavedFiles unsavedFiles = m_documents.unsavedFiles();
- using ExpirationReason = JobRequest::ExpirationReason;
+ using Condition = JobRequest::ExpirationCondition;
- if (expirationReasons.testFlag(ExpirationReason::UnsavedFilesChanged)) {
+ if (conditions.testFlag(Condition::UnsavedFilesChanged)) {
if (jobRequest.unsavedFilesChangeTimePoint != unsavedFiles.lastChangeTimePoint()) {
qCDebug(jobsLog) << "Removing due to outdated unsaved files:" << jobRequest;
return true;
@@ -118,7 +118,7 @@ bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest)
bool projectCheckedAndItExists = false;
- if (expirationReasons.testFlag(ExpirationReason::DocumentClosed)) {
+ if (conditions.testFlag(Condition::DocumentClosed)) {
if (!m_documents.hasDocument(jobRequest.filePath, jobRequest.projectPartId)) {
qCDebug(jobsLog) << "Removing due to already closed document:" << jobRequest;
return true;
@@ -138,7 +138,7 @@ bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest)
return true;
}
- if (expirationReasons.testFlag(ExpirationReason::DocumentRevisionChanged)) {
+ if (conditions.testFlag(Condition::DocumentRevisionChanged)) {
if (document.documentRevision() > jobRequest.documentRevision) {
qCDebug(jobsLog) << "Removing due to changed document revision:" << jobRequest;
return true;
@@ -146,7 +146,7 @@ bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest)
}
}
- if (expirationReasons.testFlag(ExpirationReason::ProjectChanged)) {
+ if (conditions.testFlag(Condition::ProjectChanged)) {
if (!projectCheckedAndItExists && !m_projectParts.hasProjectPart(jobRequest.projectPartId)) {
qCDebug(jobsLog) << "Removing due to already closed project:" << jobRequest;
return true;
@@ -194,10 +194,10 @@ void JobQueue::cancelJobRequest(const JobRequest &jobRequest)
m_cancelJobRequest(jobRequest);
}
-static bool passesPreconditions(const JobRequest &request, const Document &document)
+static bool areRunConditionsMet(const JobRequest &request, const Document &document)
{
- using Condition = JobRequest::Condition;
- const JobRequest::Conditions conditions = request.conditions;
+ using Condition = JobRequest::RunCondition;
+ const JobRequest::RunConditions conditions = request.runConditions;
if (conditions.testFlag(Condition::DocumentSuspended) && !document.isSuspended()) {
qCDebug(jobsLog) << "Not choosing due to unsuspended document:" << request;
@@ -250,7 +250,7 @@ JobRequests JobQueue::takeJobRequestsToRunNow()
const Document &document = m_documents.document(request.filePath,
request.projectPartId);
- if (!passesPreconditions(request, document))
+ if (!areRunConditionsMet(request, document))
continue;
const Utf8String id = document.translationUnit(request.preferredTranslationUnit).id();
diff --git a/src/tools/clangbackend/ipcsource/clangjobrequest.cpp b/src/tools/clangbackend/ipcsource/clangjobrequest.cpp
index 7dc16812ce0..9f8eb55f77f 100644
--- a/src/tools/clangbackend/ipcsource/clangjobrequest.cpp
+++ b/src/tools/clangbackend/ipcsource/clangjobrequest.cpp
@@ -25,6 +25,24 @@
#include "clangjobrequest.h"
+#include "clangcompletecodejob.h"
+#include "clangcreateinitialdocumentpreamblejob.h"
+#include "clangfollowsymboljob.h"
+#include "clangparsesupportivetranslationunitjob.h"
+#include "clangreparsesupportivetranslationunitjob.h"
+#include "clangrequestdocumentannotationsjob.h"
+#include "clangrequestreferencesjob.h"
+#include "clangresumedocumentjob.h"
+#include "clangsuspenddocumentjob.h"
+#include "clangupdatedocumentannotationsjob.h"
+
+#include <clangsupport/clangcodemodelclientinterface.h>
+#include <clangsupport/cmbcodecompletedmessage.h>
+#include <clangsupport/followsymbolmessage.h>
+#include <clangsupport/referencesmessage.h>
+
+#include <utils/qtcassert.h>
+
#include <QFileInfo>
#include <ostream>
@@ -35,6 +53,7 @@ namespace ClangBackEnd {
static const char *JobRequestTypeToText(JobRequest::Type type)
{
switch (type) {
+ RETURN_TEXT_FOR_CASE(Invalid);
RETURN_TEXT_FOR_CASE(UpdateDocumentAnnotations);
RETURN_TEXT_FOR_CASE(ParseSupportiveTranslationUnit);
RETURN_TEXT_FOR_CASE(ReparseSupportiveTranslationUnit);
@@ -42,6 +61,7 @@ static const char *JobRequestTypeToText(JobRequest::Type type)
RETURN_TEXT_FOR_CASE(CompleteCode);
RETURN_TEXT_FOR_CASE(RequestDocumentAnnotations);
RETURN_TEXT_FOR_CASE(RequestReferences);
+ RETURN_TEXT_FOR_CASE(FollowSymbol);
RETURN_TEXT_FOR_CASE(SuspendDocument);
RETURN_TEXT_FOR_CASE(ResumeDocument);
}
@@ -95,46 +115,31 @@ QDebug operator<<(QDebug debug, const JobRequest &jobRequest)
return debug.space();
}
-JobRequest::JobRequest()
+static JobRequest::ExpirationConditions expirationConditionsForType(JobRequest::Type type)
{
- static quint64 idCounter = 0;
- id = ++idCounter;
-}
-
-bool JobRequest::operator==(const JobRequest &other) const
-{
- return type == other.type
- && expirationReasons == other.expirationReasons
- && conditions == other.conditions
-
- && filePath == other.filePath
- && projectPartId == other.projectPartId
- && unsavedFilesChangeTimePoint == other.unsavedFilesChangeTimePoint
- && projectChangeTimePoint == other.projectChangeTimePoint
- && documentRevision == other.documentRevision
- && preferredTranslationUnit == other.preferredTranslationUnit
-
- && line == other.line
- && column == other.column
- && ticketNumber == other.ticketNumber;
-}
+ using Type = JobRequest::Type;
+ using Condition = JobRequest::ExpirationCondition;
+ using Conditions = JobRequest::ExpirationConditions;
-JobRequest::ExpirationReasons JobRequest::expirationReasonsForType(Type type)
-{
switch (type) {
case Type::UpdateDocumentAnnotations:
- return ExpirationReasons(ExpirationReason::AnythingChanged);
+ return Conditions(Condition::AnythingChanged);
case Type::RequestReferences:
case Type::RequestDocumentAnnotations:
- return ExpirationReasons(ExpirationReason::DocumentClosed)
- | ExpirationReasons(ExpirationReason::DocumentRevisionChanged);
+ case Type::FollowSymbol:
+ return Conditions(Condition::DocumentClosed)
+ | Conditions(Condition::DocumentRevisionChanged);
default:
- return ExpirationReason::DocumentClosed;
+ return Condition::DocumentClosed;
}
}
-JobRequest::Conditions JobRequest::conditionsForType(JobRequest::Type type)
+static JobRequest::RunConditions conditionsForType(JobRequest::Type type)
{
+ using Type = JobRequest::Type;
+ using Condition = JobRequest::RunCondition;
+ using Conditions = JobRequest::RunConditions;
+
if (type == Type::SuspendDocument) {
return Conditions(Condition::DocumentUnsuspended)
| Conditions(Condition::DocumentNotVisible);
@@ -154,4 +159,100 @@ JobRequest::Conditions JobRequest::conditionsForType(JobRequest::Type type)
return conditions;
}
+JobRequest::JobRequest(Type type)
+{
+ static quint64 idCounter = 0;
+
+ id = ++idCounter;
+ this->type = type;
+ runConditions = conditionsForType(type);
+ expirationConditions = expirationConditionsForType(type);
+}
+
+IAsyncJob *JobRequest::createJob() const
+{
+ switch (type) {
+ case JobRequest::Type::Invalid:
+ QTC_CHECK(false && "Cannot create job for invalid job request.");
+ break;
+ case JobRequest::Type::UpdateDocumentAnnotations:
+ return new UpdateDocumentAnnotationsJob();
+ case JobRequest::Type::ParseSupportiveTranslationUnit:
+ return new ParseSupportiveTranslationUnitJob();
+ case JobRequest::Type::ReparseSupportiveTranslationUnit:
+ return new ReparseSupportiveTranslationUnitJob();
+ case JobRequest::Type::CreateInitialDocumentPreamble:
+ return new CreateInitialDocumentPreambleJob();
+ case JobRequest::Type::CompleteCode:
+ return new CompleteCodeJob();
+ case JobRequest::Type::RequestDocumentAnnotations:
+ return new RequestDocumentAnnotationsJob();
+ case JobRequest::Type::RequestReferences:
+ return new RequestReferencesJob();
+ case JobRequest::Type::FollowSymbol:
+ return new FollowSymbolJob();
+ case JobRequest::Type::SuspendDocument:
+ return new SuspendDocumentJob();
+ case JobRequest::Type::ResumeDocument:
+ return new ResumeDocumentJob();
+ }
+
+ return nullptr;
+}
+
+void JobRequest::cancelJob(ClangCodeModelClientInterface &client) const
+{
+ // If a job request with a ticket number is cancelled, the plugin side
+ // must get back some results in order to clean up the state there.
+
+ switch (type) {
+ case JobRequest::Type::Invalid:
+ case JobRequest::Type::UpdateDocumentAnnotations:
+ case JobRequest::Type::ParseSupportiveTranslationUnit:
+ case JobRequest::Type::ReparseSupportiveTranslationUnit:
+ case JobRequest::Type::CreateInitialDocumentPreamble:
+ case JobRequest::Type::RequestDocumentAnnotations:
+ case JobRequest::Type::SuspendDocument:
+ case JobRequest::Type::ResumeDocument:
+ break;
+ case JobRequest::Type::RequestReferences:
+ client.references(ReferencesMessage(FileContainer(),
+ QVector<SourceRangeContainer>(),
+ false,
+ ticketNumber));
+ break;
+ case JobRequest::Type::CompleteCode:
+ client.codeCompleted(CodeCompletedMessage(CodeCompletions(),
+ CompletionCorrection::NoCorrection,
+ ticketNumber));
+ break;
+ case JobRequest::Type::FollowSymbol:
+ client.followSymbol(FollowSymbolMessage(FileContainer(),
+ SourceRangeContainer(),
+ ticketNumber));
+ break;
+ }
+}
+
+bool JobRequest::operator==(const JobRequest &other) const
+{
+ return type == other.type
+ && expirationConditions == other.expirationConditions
+ && runConditions == other.runConditions
+
+ && filePath == other.filePath
+ && projectPartId == other.projectPartId
+ && unsavedFilesChangeTimePoint == other.unsavedFilesChangeTimePoint
+ && projectChangeTimePoint == other.projectChangeTimePoint
+ && documentRevision == other.documentRevision
+ && preferredTranslationUnit == other.preferredTranslationUnit
+
+ && line == other.line
+ && column == other.column
+ && ticketNumber == other.ticketNumber;
+
+ // Additional members that are not compared here explicitly are
+ // supposed to depend on the already compared ones.
+}
+
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangjobrequest.h b/src/tools/clangbackend/ipcsource/clangjobrequest.h
index 33b68cb60f3..78aaed6618a 100644
--- a/src/tools/clangbackend/ipcsource/clangjobrequest.h
+++ b/src/tools/clangbackend/ipcsource/clangjobrequest.h
@@ -29,6 +29,7 @@
#include "clangclock.h"
#include <utf8string.h>
+#include <utf8stringvector.h>
#include <QFlags>
#include <QDebug>
@@ -38,12 +39,16 @@
namespace ClangBackEnd {
+class ClangCodeModelClientInterface;
class Document;
+class IAsyncJob;
class JobRequest
{
public:
enum class Type {
+ Invalid,
+
UpdateDocumentAnnotations,
CreateInitialDocumentPreamble,
@@ -53,12 +58,13 @@ public:
CompleteCode,
RequestDocumentAnnotations,
RequestReferences,
+ FollowSymbol,
SuspendDocument,
ResumeDocument,
};
- enum class Condition {
+ enum class RunCondition {
NoCondition = 1 << 0,
DocumentVisible = 1 << 1,
DocumentNotVisible = 1 << 2,
@@ -66,9 +72,9 @@ public:
DocumentUnsuspended = 1 << 4,
CurrentDocumentRevision = 1 << 5,
};
- Q_DECLARE_FLAGS(Conditions, Condition)
+ Q_DECLARE_FLAGS(RunConditions, RunCondition)
- enum class ExpirationReason {
+ enum class ExpirationCondition {
Never = 1 << 0,
DocumentClosed = 1 << 1,
@@ -81,21 +87,21 @@ public:
| UnsavedFilesChanged
| ProjectChanged,
};
- Q_DECLARE_FLAGS(ExpirationReasons, ExpirationReason)
+ Q_DECLARE_FLAGS(ExpirationConditions, ExpirationCondition)
public:
- static ExpirationReasons expirationReasonsForType(Type type);
- static Conditions conditionsForType(Type type);
+ JobRequest(Type type = Type::Invalid);
- JobRequest();
+ IAsyncJob *createJob() const;
+ void cancelJob(ClangCodeModelClientInterface &client) const;
bool operator==(const JobRequest &other) const;
public:
quint64 id = 0;
Type type;
- ExpirationReasons expirationReasons;
- Conditions conditions;
+ ExpirationConditions expirationConditions;
+ RunConditions runConditions;
// General
Utf8String filePath;
@@ -108,7 +114,10 @@ public:
// Specific to some jobs
quint32 line = 0;
quint32 column = 0;
+ qint32 funcNameStartLine = -1;
+ qint32 funcNameStartColumn = -1;
quint64 ticketNumber = 0;
+ Utf8StringVector dependentFiles;
};
using JobRequests = QVector<JobRequest>;
diff --git a/src/tools/clangbackend/ipcsource/clangjobs.cpp b/src/tools/clangbackend/ipcsource/clangjobs.cpp
index f168387505f..033dc4ef1a4 100644
--- a/src/tools/clangbackend/ipcsource/clangjobs.cpp
+++ b/src/tools/clangbackend/ipcsource/clangjobs.cpp
@@ -29,9 +29,6 @@
#include "clangiasyncjob.h"
#include "projects.h"
-#include <clangbackendipc/cmbcodecompletedmessage.h>
-#include <clangbackendipc/referencesmessage.h>
-
#include <QDebug>
#include <QFutureSynchronizer>
#include <QLoggingCategory>
@@ -58,7 +55,7 @@ Jobs::Jobs(Documents &documents,
return isJobRunningForJobRequest(jobRequest);
});
m_queue.setCancelJobRequest([this](const JobRequest &jobRequest) {
- return cancelJobRequest(jobRequest);
+ jobRequest.cancelJob(m_client);
});
}
@@ -79,10 +76,7 @@ JobRequest Jobs::createJobRequest(const Document &document,
JobRequest::Type type,
PreferredTranslationUnit preferredTranslationUnit) const
{
- JobRequest jobRequest;
- jobRequest.type = type;
- jobRequest.expirationReasons = JobRequest::expirationReasonsForType(type);
- jobRequest.conditions = JobRequest::conditionsForType(type);
+ JobRequest jobRequest(type);
jobRequest.filePath = document.filePath();
jobRequest.projectPartId = document.projectPart().id();
jobRequest.unsavedFilesChangeTimePoint = m_unsavedFiles.lastChangeTimePoint();
@@ -131,7 +125,7 @@ JobRequests Jobs::runJobs(const JobRequests &jobsRequests)
bool Jobs::runJob(const JobRequest &jobRequest)
{
- IAsyncJob *asyncJob = IAsyncJob::create(jobRequest.type);
+ IAsyncJob *asyncJob = jobRequest.createJob();
QTC_ASSERT(asyncJob, return false);
JobContext context(jobRequest, &m_documents, &m_unsavedFiles, &m_client);
@@ -203,29 +197,4 @@ bool Jobs::isJobRunningForJobRequest(const JobRequest &jobRequest) const
return Utils::anyOf(m_running.values(), hasJobRequest);
}
-void Jobs::cancelJobRequest(const JobRequest &jobRequest)
-{
- // TODO: Consider to refactor this. Jobs should not know anything about
- // concrete messages. On the other hand, having this here avoids
- // duplication in multiple job classes.
-
- // If a job request with a ticket number is cancelled, the plugin side
- // must get back some results in order to clean up the state there.
- switch (jobRequest.type) {
- case JobRequest::Type::RequestReferences:
- m_client.references(ReferencesMessage(FileContainer(),
- QVector<SourceRangeContainer>(),
- false,
- jobRequest.ticketNumber));
- break;
- case JobRequest::Type::CompleteCode:
- m_client.codeCompleted(CodeCompletedMessage(CodeCompletions(),
- CompletionCorrection::NoCorrection,
- jobRequest.ticketNumber));
- break;
- default:
- break;
- }
-}
-
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangjobs.h b/src/tools/clangbackend/ipcsource/clangjobs.h
index 711f15e67a5..d154d401e88 100644
--- a/src/tools/clangbackend/ipcsource/clangjobs.h
+++ b/src/tools/clangbackend/ipcsource/clangjobs.h
@@ -27,7 +27,7 @@
#include "clangjobqueue.h"
-#include <clangbackendipc/clangcodemodelclientinterface.h>
+#include <clangsupport/clangcodemodelclientinterface.h>
#include <QFuture>
@@ -80,7 +80,6 @@ public /*for tests*/:
bool isJobRunningForJobRequest(const JobRequest &jobRequest) const;
private:
- void cancelJobRequest(const JobRequest &jobRequest);
JobRequests runJobs(const JobRequests &jobRequest);
bool runJob(const JobRequest &jobRequest);
void onJobFinished(IAsyncJob *asyncJob);
diff --git a/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.cpp b/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.cpp
index fa8937c1951..017426ab021 100644
--- a/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.cpp
+++ b/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.cpp
@@ -25,49 +25,30 @@
#include "clangparsesupportivetranslationunitjob.h"
-#include <clangbackendipc/clangbackendipcdebugutils.h>
+#include <clangsupport/clangsupportdebugutils.h>
#include <utils/qtcassert.h>
namespace ClangBackEnd {
-static ParseSupportiveTranslationUnitJob::AsyncResult runAsyncHelper(
- const TranslationUnit &translationUnit,
- const TranslationUnitUpdateInput &translationUnitUpdateInput)
-{
- TIME_SCOPE_DURATION("ParseSupportiveTranslationUnitJob");
-
- TranslationUnitUpdateInput updateInput = translationUnitUpdateInput;
- updateInput.parseNeeded = true;
-
- ParseSupportiveTranslationUnitJob::AsyncResult asyncResult;
- asyncResult.updateResult = translationUnit.update(updateInput);
-
- return asyncResult;
-}
-
IAsyncJob::AsyncPrepareResult ParseSupportiveTranslationUnitJob::prepareAsyncRun()
{
const JobRequest jobRequest = context().jobRequest;
QTC_ASSERT(jobRequest.type == JobRequest::Type::ParseSupportiveTranslationUnit, return AsyncPrepareResult());
+ QTC_ASSERT(acquireDocument(), return AsyncPrepareResult());
+
+ const TranslationUnit translationUnit = *m_translationUnit;
+ const TranslationUnitUpdateInput updateInput = m_pinnedDocument.createUpdateInput();
+ setRunner([translationUnit, updateInput]() {
+ TIME_SCOPE_DURATION("ParseSupportiveTranslationUnitJob");
- try {
- m_pinnedDocument = context().documentForJobRequest();
- m_pinnedFileContainer = m_pinnedDocument.fileContainer();
+ TranslationUnitUpdateInput theUpdateInput = updateInput;
+ theUpdateInput.parseNeeded = true;
- const TranslationUnit translationUnit
- = m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
- const TranslationUnitUpdateInput updateInput = m_pinnedDocument.createUpdateInput();
- setRunner([translationUnit, updateInput]() {
- return runAsyncHelper(translationUnit, updateInput);
- });
- return AsyncPrepareResult{translationUnit.id()};
+ return translationUnit.update(updateInput);
+ });
- } catch (const std::exception &exception) {
- qWarning() << "Error in ParseForSupportiveTranslationUnitJob::prepareAsyncRun:"
- << exception.what();
- return AsyncPrepareResult();
- }
+ return AsyncPrepareResult{translationUnit.id()};
}
void ParseSupportiveTranslationUnitJob::finalizeAsyncRun()
diff --git a/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.h b/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.h
index 6d4d01131e2..5a0cfec1837 100644
--- a/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.h
+++ b/src/tools/clangbackend/ipcsource/clangparsesupportivetranslationunitjob.h
@@ -25,27 +25,18 @@
#pragma once
-#include "clangasyncjob.h"
-#include "clangdocument.h"
+#include "clangdocumentjob.h"
+#include "clangtranslationunitupdater.h"
namespace ClangBackEnd {
-struct ParseSupportiveTranslationUnitJobResult
-{
- TranslationUnitUpdateResult updateResult;
-};
-
-class ParseSupportiveTranslationUnitJob : public AsyncJob<ParseSupportiveTranslationUnitJobResult>
+class ParseSupportiveTranslationUnitJob : public DocumentJob<TranslationUnitUpdateResult>
{
public:
- using AsyncResult = ParseSupportiveTranslationUnitJobResult;
+ using AsyncResult = TranslationUnitUpdateResult;
AsyncPrepareResult prepareAsyncRun() override;
void finalizeAsyncRun() override;
-
-private:
- Document m_pinnedDocument;
- FileContainer m_pinnedFileContainer;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangreferencescollector.cpp b/src/tools/clangbackend/ipcsource/clangreferencescollector.cpp
index df9d937de05..d2b7bf5431d 100644
--- a/src/tools/clangbackend/ipcsource/clangreferencescollector.cpp
+++ b/src/tools/clangbackend/ipcsource/clangreferencescollector.cpp
@@ -29,7 +29,7 @@
#include "cursor.h"
#include "sourcerange.h"
-#include <clangbackendipc/sourcerangecontainer.h>
+#include <clangsupport/sourcerangecontainer.h>
#include <utils/qtcassert.h>
#include <utf8string.h>
diff --git a/src/tools/clangbackend/ipcsource/clangreferencescollector.h b/src/tools/clangbackend/ipcsource/clangreferencescollector.h
index 6feee77c79b..263ba07fd9e 100644
--- a/src/tools/clangbackend/ipcsource/clangreferencescollector.h
+++ b/src/tools/clangbackend/ipcsource/clangreferencescollector.h
@@ -25,7 +25,7 @@
#pragma once
-#include <clangbackendipc/sourcerangecontainer.h>
+#include <clangsupport/sourcerangecontainer.h>
#include <QVector>
diff --git a/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.cpp b/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.cpp
index da922db8e9d..a02821fff48 100644
--- a/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.cpp
+++ b/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.cpp
@@ -25,49 +25,33 @@
#include "clangreparsesupportivetranslationunitjob.h"
-#include <clangbackendipc/clangbackendipcdebugutils.h>
+#include <clangsupport/clangsupportdebugutils.h>
#include <utils/qtcassert.h>
namespace ClangBackEnd {
-static ReparseSupportiveTranslationUnitJob::AsyncResult runAsyncHelper(
- const TranslationUnit &translationUnit,
- const TranslationUnitUpdateInput &translationUnitUpdateInput)
-{
- TIME_SCOPE_DURATION("ReparseSupportiveTranslationUnitJob");
-
- TranslationUnitUpdateInput updateInput = translationUnitUpdateInput;
- updateInput.reparseNeeded = true;
-
- ReparseSupportiveTranslationUnitJob::AsyncResult asyncResult;
- asyncResult.updateResult = translationUnit.reparse(updateInput);
-
- return asyncResult;
-}
-
IAsyncJob::AsyncPrepareResult ReparseSupportiveTranslationUnitJob::prepareAsyncRun()
{
const JobRequest jobRequest = context().jobRequest;
QTC_ASSERT(jobRequest.type == JobRequest::Type::ReparseSupportiveTranslationUnit, return AsyncPrepareResult());
+ QTC_ASSERT(acquireDocument(), return AsyncPrepareResult());
- try {
- m_pinnedDocument = context().documentForJobRequest();
- m_pinnedFileContainer = m_pinnedDocument.fileContainer();
+ const TranslationUnit translationUnit = *m_translationUnit;
+ const TranslationUnitUpdateInput updateInput = m_pinnedDocument.createUpdateInput();
+ setRunner([translationUnit, updateInput]() {
+ TIME_SCOPE_DURATION("ReparseSupportiveTranslationUnitJob");
- const TranslationUnit translationUnit
- = m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
- const TranslationUnitUpdateInput updateInput = m_pinnedDocument.createUpdateInput();
- setRunner([translationUnit, updateInput]() {
- return runAsyncHelper(translationUnit, updateInput);
- });
- return AsyncPrepareResult{translationUnit.id()};
+ TranslationUnitUpdateInput theUpdateInput = updateInput;
+ theUpdateInput.reparseNeeded = true;
- } catch (const std::exception &exception) {
- qWarning() << "Error in ReparseSupportiveTranslationUnitJob::prepareAsyncRun:"
- << exception.what();
- return AsyncPrepareResult();
- }
+ ReparseSupportiveTranslationUnitJob::AsyncResult asyncResult;
+ asyncResult.updateResult = translationUnit.reparse(theUpdateInput);
+
+ return asyncResult;
+ });
+
+ return AsyncPrepareResult{translationUnit.id()};
}
void ReparseSupportiveTranslationUnitJob::finalizeAsyncRun()
diff --git a/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.h b/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.h
index 1b352c2c361..cb146299c72 100644
--- a/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.h
+++ b/src/tools/clangbackend/ipcsource/clangreparsesupportivetranslationunitjob.h
@@ -25,8 +25,7 @@
#pragma once
-#include "clangasyncjob.h"
-#include "clangdocument.h"
+#include "clangdocumentjob.h"
namespace ClangBackEnd {
@@ -35,17 +34,13 @@ struct ReparseSupportiveTranslationUnitJobResult
TranslationUnitUpdateResult updateResult;
};
-class ReparseSupportiveTranslationUnitJob : public AsyncJob<ReparseSupportiveTranslationUnitJobResult>
+class ReparseSupportiveTranslationUnitJob : public DocumentJob<ReparseSupportiveTranslationUnitJobResult>
{
public:
using AsyncResult = ReparseSupportiveTranslationUnitJobResult;
AsyncPrepareResult prepareAsyncRun() override;
void finalizeAsyncRun() override;
-
-private:
- Document m_pinnedDocument;
- FileContainer m_pinnedFileContainer;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.cpp b/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.cpp
index 45b06c02037..99ac98eec2a 100644
--- a/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.cpp
+++ b/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.cpp
@@ -25,70 +25,47 @@
#include "clangrequestdocumentannotationsjob.h"
-#include <clangbackendipc/clangbackendipcdebugutils.h>
-#include <clangbackendipc/documentannotationschangedmessage.h>
-#include <clangbackendipc/clangcodemodelclientinterface.h>
+#include <clangsupport/clangsupportdebugutils.h>
+#include <clangsupport/documentannotationschangedmessage.h>
+#include <clangsupport/clangcodemodelclientinterface.h>
#include <utils/qtcassert.h>
namespace ClangBackEnd {
-static RequestDocumentAnnotationsJob::AsyncResult runAsyncHelper(
- const TranslationUnit &translationUnit)
-{
- TIME_SCOPE_DURATION("RequestDocumentAnnotationsJobRunner");
-
- RequestDocumentAnnotationsJob::AsyncResult asyncResult;
-
- translationUnit.extractDocumentAnnotations(asyncResult.firstHeaderErrorDiagnostic,
- asyncResult.diagnostics,
- asyncResult.highlightingMarks,
- asyncResult.skippedSourceRanges);
-
- return asyncResult;
-}
-
IAsyncJob::AsyncPrepareResult RequestDocumentAnnotationsJob::prepareAsyncRun()
{
const JobRequest jobRequest = context().jobRequest;
QTC_ASSERT(jobRequest.type == JobRequest::Type::RequestDocumentAnnotations,
return AsyncPrepareResult());
+ QTC_ASSERT(acquireDocument(), return AsyncPrepareResult());
- try {
- m_pinnedDocument = context().documentForJobRequest();
- m_pinnedFileContainer = m_pinnedDocument.fileContainer();
+ const TranslationUnit translationUnit = *m_translationUnit;
+ setRunner([translationUnit]() {
+ TIME_SCOPE_DURATION("RequestDocumentAnnotationsJobRunner");
- const TranslationUnit translationUnit
- = m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
- setRunner([translationUnit]() {
- return runAsyncHelper(translationUnit);
- });
- return AsyncPrepareResult{translationUnit.id()};
+ RequestDocumentAnnotationsJob::AsyncResult asyncResult;
+ translationUnit.extractDocumentAnnotations(asyncResult.firstHeaderErrorDiagnostic,
+ asyncResult.diagnostics,
+ asyncResult.highlightingMarks,
+ asyncResult.skippedSourceRanges);
+ return asyncResult;
+ });
- } catch (const std::exception &exception) {
- qWarning() << "Error in RequestDocumentAnnotationsJob::prepareAsyncRun:" << exception.what();
- return AsyncPrepareResult();
- }
+ return AsyncPrepareResult{translationUnit.id()};
}
void RequestDocumentAnnotationsJob::finalizeAsyncRun()
{
if (context().isDocumentOpen()) {
const AsyncResult result = asyncResult();
- sendAnnotations(result);
+ context().client->documentAnnotationsChanged(
+ DocumentAnnotationsChangedMessage(m_pinnedFileContainer,
+ result.diagnostics,
+ result.firstHeaderErrorDiagnostic,
+ result.highlightingMarks,
+ result.skippedSourceRanges));
}
}
-void RequestDocumentAnnotationsJob::sendAnnotations(
- const RequestDocumentAnnotationsJob::AsyncResult &result)
-{
- const DocumentAnnotationsChangedMessage message(m_pinnedFileContainer,
- result.diagnostics,
- result.firstHeaderErrorDiagnostic,
- result.highlightingMarks,
- result.skippedSourceRanges);
-
- context().client->documentAnnotationsChanged(message);
-}
-
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.h b/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.h
index e6bb4f9edca..1c78621119e 100644
--- a/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.h
+++ b/src/tools/clangbackend/ipcsource/clangrequestdocumentannotationsjob.h
@@ -25,12 +25,11 @@
#pragma once
-#include "clangasyncjob.h"
-#include "clangdocument.h"
+#include "clangdocumentjob.h"
-#include <clangbackendipc/diagnosticcontainer.h>
-#include <clangbackendipc/highlightingmarkcontainer.h>
-#include <clangbackendipc/sourcerangecontainer.h>
+#include <clangsupport/diagnosticcontainer.h>
+#include <clangsupport/highlightingmarkcontainer.h>
+#include <clangsupport/sourcerangecontainer.h>
namespace ClangBackEnd {
@@ -42,20 +41,13 @@ struct RequestDocumentAnnotationsJobResult
QVector<SourceRangeContainer> skippedSourceRanges;
};
-class RequestDocumentAnnotationsJob : public AsyncJob<RequestDocumentAnnotationsJobResult>
+class RequestDocumentAnnotationsJob : public DocumentJob<RequestDocumentAnnotationsJobResult>
{
public:
using AsyncResult = RequestDocumentAnnotationsJobResult;
AsyncPrepareResult prepareAsyncRun() override;
void finalizeAsyncRun() override;
-
-private:
- void sendAnnotations(const AsyncResult &result);
-
-private:
- Document m_pinnedDocument;
- FileContainer m_pinnedFileContainer;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.cpp b/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.cpp
index f80072c0ed4..39b3319488e 100644
--- a/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.cpp
+++ b/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.cpp
@@ -25,46 +25,30 @@
#include "clangrequestreferencesjob.h"
-#include <clangbackendipc/clangbackendipcdebugutils.h>
-#include <clangbackendipc/referencesmessage.h>
-#include <clangbackendipc/clangcodemodelclientinterface.h>
+#include <clangsupport/clangsupportdebugutils.h>
+#include <clangsupport/referencesmessage.h>
+#include <clangsupport/clangcodemodelclientinterface.h>
#include <utils/qtcassert.h>
namespace ClangBackEnd {
-static RequestReferencesJob::AsyncResult runAsyncHelper(const TranslationUnit &translationUnit,
- quint32 line,
- quint32 column)
-{
- TIME_SCOPE_DURATION("RequestReferencesJobRunner");
-
- return translationUnit.references(line, column);
-}
-
IAsyncJob::AsyncPrepareResult RequestReferencesJob::prepareAsyncRun()
{
const JobRequest jobRequest = context().jobRequest;
QTC_ASSERT(jobRequest.type == JobRequest::Type::RequestReferences,
return AsyncPrepareResult());
+ QTC_ASSERT(acquireDocument(), return AsyncPrepareResult());
- try {
- m_pinnedDocument = context().documentForJobRequest();
- m_pinnedFileContainer = m_pinnedDocument.fileContainer();
-
- const TranslationUnit translationUnit
- = m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
- const quint32 line = jobRequest.line;
- const quint32 column = jobRequest.column;
- setRunner([translationUnit, line, column]() {
- return runAsyncHelper(translationUnit, line, column);
- });
- return AsyncPrepareResult{translationUnit.id()};
+ const TranslationUnit translationUnit = *m_translationUnit;
+ const quint32 line = jobRequest.line;
+ const quint32 column = jobRequest.column;
+ setRunner([translationUnit, line, column]() {
+ TIME_SCOPE_DURATION("RequestReferencesJobRunner");
+ return translationUnit.references(line, column);
+ });
- } catch (const std::exception &exception) {
- qWarning() << "Error in RequestReferencesJob::prepareAsyncRun:" << exception.what();
- return AsyncPrepareResult();
- }
+ return AsyncPrepareResult{translationUnit.id()};
}
void RequestReferencesJob::finalizeAsyncRun()
diff --git a/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.h b/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.h
index 179f8b845b8..d92d869a9bb 100644
--- a/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.h
+++ b/src/tools/clangbackend/ipcsource/clangrequestreferencesjob.h
@@ -25,25 +25,18 @@
#pragma once
-#include "clangasyncjob.h"
+#include "clangdocumentjob.h"
#include "clangreferencescollector.h"
-#include "clangdocument.h"
-
-#include <clangbackendipc/sourcerangecontainer.h>
namespace ClangBackEnd {
-class RequestReferencesJob : public AsyncJob<ReferencesResult>
+class RequestReferencesJob : public DocumentJob<ReferencesResult>
{
public:
using AsyncResult = ReferencesResult;
AsyncPrepareResult prepareAsyncRun() override;
void finalizeAsyncRun() override;
-
-private:
- Document m_pinnedDocument;
- FileContainer m_pinnedFileContainer;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.cpp b/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.cpp
index e3406fcf327..87fe54bfae9 100644
--- a/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.cpp
+++ b/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.cpp
@@ -25,39 +25,25 @@
#include "clangsuspenddocumentjob.h"
-#include <clangbackendipc/clangbackendipcdebugutils.h>
+#include <clangsupport/clangsupportdebugutils.h>
#include <utils/qtcassert.h>
namespace ClangBackEnd {
-static bool runAsyncHelper(const TranslationUnit &translationUnit)
-{
- TIME_SCOPE_DURATION("SuspendDocumentJobRunner");
-
- return translationUnit.suspend();
-}
-
IAsyncJob::AsyncPrepareResult SuspendDocumentJob::prepareAsyncRun()
{
const JobRequest jobRequest = context().jobRequest;
QTC_ASSERT(jobRequest.type == JobRequest::Type::SuspendDocument, return AsyncPrepareResult());
+ QTC_ASSERT(acquireDocument(), return AsyncPrepareResult());
- try {
- m_pinnedDocument = context().documentForJobRequest();
- m_pinnedFileContainer = m_pinnedDocument.fileContainer();
-
- TranslationUnit translationUnit
- = m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
- setRunner([translationUnit]() {
- return runAsyncHelper(translationUnit);
- });
- return AsyncPrepareResult{translationUnit.id()};
+ TranslationUnit translationUnit = *m_translationUnit;
+ setRunner([translationUnit]() {
+ TIME_SCOPE_DURATION("SuspendDocumentJobRunner");
+ return translationUnit.suspend();
+ });
- } catch (const std::exception &exception) {
- qWarning() << "Error in SuspendDocumentJob::prepareAsyncRun:" << exception.what();
- return AsyncPrepareResult();
- }
+ return AsyncPrepareResult{translationUnit.id()};
}
void SuspendDocumentJob::finalizeAsyncRun()
diff --git a/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.h b/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.h
index 16d5b52a1ea..5948f8226f1 100644
--- a/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.h
+++ b/src/tools/clangbackend/ipcsource/clangsuspenddocumentjob.h
@@ -25,20 +25,15 @@
#pragma once
-#include "clangasyncjob.h"
-#include "clangdocument.h"
+#include "clangdocumentjob.h"
namespace ClangBackEnd {
-class SuspendDocumentJob : public AsyncJob<bool>
+class SuspendDocumentJob : public DocumentJob<bool>
{
public:
AsyncPrepareResult prepareAsyncRun() override;
void finalizeAsyncRun() override;
-
-private:
- Document m_pinnedDocument;
- FileContainer m_pinnedFileContainer;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp b/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp
index 0bc0509a5ee..720bfb92555 100644
--- a/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp
+++ b/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp
@@ -28,6 +28,8 @@
#include "clangbackend_global.h"
#include "clangreferencescollector.h"
#include "clangtranslationunitupdater.h"
+#include "clangfollowsymbol.h"
+#include "clangfollowsymboljob.h"
#include <codecompleter.h>
#include <cursor.h>
@@ -38,6 +40,7 @@
#include <skippedsourceranges.h>
#include <sourcelocation.h>
#include <sourcerange.h>
+#include <commandlinearguments.h>
#include <utils/qtcassert.h>
@@ -116,11 +119,15 @@ bool TranslationUnit::suspend() const
TranslationUnit::CodeCompletionResult TranslationUnit::complete(
UnsavedFiles &unsavedFiles,
uint line,
- uint column) const
+ uint column,
+ int funcNameStartLine,
+ int funcNameStartColumn) const
{
CodeCompleter codeCompleter(*this, unsavedFiles);
- const CodeCompletions completions = codeCompleter.complete(line, column);
+ const CodeCompletions completions = codeCompleter.complete(line, column,
+ funcNameStartLine,
+ funcNameStartColumn);
const CompletionCorrection correction = codeCompleter.neededCorrection();
return CodeCompletionResult{completions, correction};
@@ -236,4 +243,13 @@ void TranslationUnit::extractDiagnostics(DiagnosticContainer &firstHeaderErrorDi
}
}
+SourceRangeContainer TranslationUnit::followSymbol(uint line,
+ uint column,
+ const QVector<Utf8String> &dependentFiles,
+ const CommandLineArguments &currentArgs) const
+{
+ return FollowSymbol::followSymbol(m_cxTranslationUnit, m_cxIndex, cursorAt(line, column), line,
+ column, dependentFiles, currentArgs);
+}
+
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunit.h b/src/tools/clangbackend/ipcsource/clangtranslationunit.h
index cc398e9a728..9634c8cb510 100644
--- a/src/tools/clangbackend/ipcsource/clangtranslationunit.h
+++ b/src/tools/clangbackend/ipcsource/clangtranslationunit.h
@@ -25,14 +25,10 @@
#pragma once
-#include <clangbackendipc/codecompletion.h>
-
-#include <utf8string.h>
+#include <clangsupport/codecompletion.h>
#include <clang-c/Index.h>
-class Utf8String;
-
namespace ClangBackEnd {
class Cursor;
@@ -48,6 +44,7 @@ class SourceRangeContainer;
class TranslationUnitUpdateInput;
class TranslationUnitUpdateResult;
class UnsavedFiles;
+class CommandLineArguments;
class TranslationUnit
{
@@ -77,7 +74,8 @@ public:
TranslationUnitUpdateResult parse(const TranslationUnitUpdateInput &parseInput) const;
TranslationUnitUpdateResult reparse(const TranslationUnitUpdateInput &parseInput) const;
- CodeCompletionResult complete(UnsavedFiles &unsavedFiles, uint line, uint column) const;
+ CodeCompletionResult complete(UnsavedFiles &unsavedFiles, uint line, uint column,
+ int funcNameStartLine, int funcNameStartColumn) const;
void extractDiagnostics(DiagnosticContainer &firstHeaderErrorDiagnostic,
QVector<DiagnosticContainer> &mainFileDiagnostics) const;
@@ -102,6 +100,10 @@ public:
HighlightingMarks highlightingMarksInRange(const SourceRange &range) const;
SkippedSourceRanges skippedSourceRanges() const;
+ SourceRangeContainer followSymbol(uint line,
+ uint column,
+ const QVector<Utf8String> &dependentFiles,
+ const CommandLineArguments &currentArgs) const;
private:
const Utf8String m_id;
diff --git a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp b/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp
index b4b56fe5341..7333ca68787 100644
--- a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp
+++ b/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.cpp
@@ -25,55 +25,39 @@
#include "clangupdatedocumentannotationsjob.h"
-#include <clangbackendipc/clangbackendipcdebugutils.h>
-#include <clangbackendipc/clangcodemodelclientinterface.h>
-#include <clangbackendipc/documentannotationschangedmessage.h>
+#include <clangsupport/clangsupportdebugutils.h>
+#include <clangsupport/clangcodemodelclientinterface.h>
+#include <clangsupport/documentannotationschangedmessage.h>
#include <utils/qtcassert.h>
namespace ClangBackEnd {
-static UpdateDocumentAnnotationsJob::AsyncResult runAsyncHelper(
- const TranslationUnit &translationUnit,
- const TranslationUnitUpdateInput &translationUnitUpdatInput)
+IAsyncJob::AsyncPrepareResult UpdateDocumentAnnotationsJob::prepareAsyncRun()
{
- TIME_SCOPE_DURATION("UpdateDocumentAnnotationsJobRunner");
-
- UpdateDocumentAnnotationsJob::AsyncResult asyncResult;
+ const JobRequest jobRequest = context().jobRequest;
+ QTC_ASSERT(isExpectedJobRequestType(jobRequest), return AsyncPrepareResult());
+ QTC_ASSERT(acquireDocument(), return AsyncPrepareResult());
- // Update
- asyncResult.updateResult = translationUnit.update(translationUnitUpdatInput);
+ const TranslationUnit translationUnit = *m_translationUnit;
+ const TranslationUnitUpdateInput updateInput = createUpdateInput(m_pinnedDocument);
+ setRunner([translationUnit, updateInput]() {
+ TIME_SCOPE_DURATION("UpdateDocumentAnnotationsJobRunner");
- // Collect
- translationUnit.extractDocumentAnnotations(asyncResult.firstHeaderErrorDiagnostic,
- asyncResult.diagnostics,
- asyncResult.highlightingMarks,
- asyncResult.skippedSourceRanges);
+ // Update
+ UpdateDocumentAnnotationsJob::AsyncResult asyncResult;
+ asyncResult.updateResult = translationUnit.update(updateInput);
- return asyncResult;
-}
+ // Collect
+ translationUnit.extractDocumentAnnotations(asyncResult.firstHeaderErrorDiagnostic,
+ asyncResult.diagnostics,
+ asyncResult.highlightingMarks,
+ asyncResult.skippedSourceRanges);
-IAsyncJob::AsyncPrepareResult UpdateDocumentAnnotationsJob::prepareAsyncRun()
-{
- const JobRequest jobRequest = context().jobRequest;
- QTC_ASSERT(isExpectedJobRequestType(jobRequest), return AsyncPrepareResult());
+ return asyncResult;
+ });
- try {
- m_pinnedDocument = context().documentForJobRequest();
- m_pinnedFileContainer = m_pinnedDocument.fileContainer();
-
- const TranslationUnit translationUnit
- = m_pinnedDocument.translationUnit(jobRequest.preferredTranslationUnit);
- const TranslationUnitUpdateInput updateInput = createUpdateInput(m_pinnedDocument);
- setRunner([translationUnit, updateInput]() {
- return runAsyncHelper(translationUnit, updateInput);
- });
- return AsyncPrepareResult{translationUnit.id()};
-
- } catch (const std::exception &exception) {
- qWarning() << "Error in UpdateDocumentAnnotationsJob::prepareAsyncRun:" << exception.what();
- return AsyncPrepareResult();
- }
+ return AsyncPrepareResult{translationUnit.id()};
}
void UpdateDocumentAnnotationsJob::finalizeAsyncRun()
@@ -81,8 +65,13 @@ void UpdateDocumentAnnotationsJob::finalizeAsyncRun()
if (!context().isOutdated()) {
const AsyncResult result = asyncResult();
- incorporateUpdaterResult(result);
- sendAnnotations(result);
+ m_pinnedDocument.incorporateUpdaterResult(result.updateResult);
+ context().client->documentAnnotationsChanged(
+ DocumentAnnotationsChangedMessage(m_pinnedFileContainer,
+ result.diagnostics,
+ result.firstHeaderErrorDiagnostic,
+ result.highlightingMarks,
+ result.skippedSourceRanges));
}
}
@@ -97,21 +86,5 @@ UpdateDocumentAnnotationsJob::createUpdateInput(const Document &document) const
return document.createUpdateInput();
}
-void UpdateDocumentAnnotationsJob::incorporateUpdaterResult(const AsyncResult &result)
-{
- m_pinnedDocument.incorporateUpdaterResult(result.updateResult);
-}
-
-void UpdateDocumentAnnotationsJob::sendAnnotations(const AsyncResult &result)
-{
- const DocumentAnnotationsChangedMessage message(m_pinnedFileContainer,
- result.diagnostics,
- result.firstHeaderErrorDiagnostic,
- result.highlightingMarks,
- result.skippedSourceRanges);
-
- context().client->documentAnnotationsChanged(message);
-}
-
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h b/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h
index fdbe9068a6d..141b3535a09 100644
--- a/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h
+++ b/src/tools/clangbackend/ipcsource/clangupdatedocumentannotationsjob.h
@@ -25,13 +25,11 @@
#pragma once
-#include "clangasyncjob.h"
-#include "clangdocument.h"
-#include "clangtranslationunitupdater.h"
+#include "clangdocumentjob.h"
-#include <clangbackendipc/diagnosticcontainer.h>
-#include <clangbackendipc/highlightingmarkcontainer.h>
-#include <clangbackendipc/sourcerangecontainer.h>
+#include <clangsupport/diagnosticcontainer.h>
+#include <clangsupport/highlightingmarkcontainer.h>
+#include <clangsupport/sourcerangecontainer.h>
namespace ClangBackEnd {
@@ -45,7 +43,7 @@ struct UpdateDocumentAnnotationsJobResult
QVector<SourceRangeContainer> skippedSourceRanges;
};
-class UpdateDocumentAnnotationsJob : public AsyncJob<UpdateDocumentAnnotationsJobResult>
+class UpdateDocumentAnnotationsJob : public DocumentJob<UpdateDocumentAnnotationsJobResult>
{
public:
using AsyncResult = UpdateDocumentAnnotationsJobResult;
@@ -56,16 +54,6 @@ public:
protected:
virtual bool isExpectedJobRequestType(const JobRequest &jobRequest) const;
virtual TranslationUnitUpdateInput createUpdateInput(const Document &document) const;
-
-private:
- void incorporateUpdaterResult(const AsyncResult &result);
- void sendAnnotations(const AsyncResult &result);
-
-protected:
- Document m_pinnedDocument;
-
-private:
- FileContainer m_pinnedFileContainer;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/codecompleter.cpp b/src/tools/clangbackend/ipcsource/codecompleter.cpp
index fe746c8cfd8..8fa5c9cce23 100644
--- a/src/tools/clangbackend/ipcsource/codecompleter.cpp
+++ b/src/tools/clangbackend/ipcsource/codecompleter.cpp
@@ -81,11 +81,22 @@ CodeCompleter::CodeCompleter(const TranslationUnit &translationUnit,
{
}
-CodeCompletions CodeCompleter::complete(uint line, uint column)
+CodeCompletions CodeCompleter::complete(uint line, uint column,
+ int funcNameStartLine,
+ int funcNameStartColumn)
{
neededCorrection_ = CompletionCorrection::NoCorrection;
- ClangCodeCompleteResults results = completeHelper(line, column);
+ // Check if we have a smart pointer completion and get proper constructor signatures in results.
+ // Results are empty when it's not a smart pointer or this completion failed.
+ ClangCodeCompleteResults results = completeSmartPointerCreation(line,
+ column,
+ funcNameStartLine,
+ funcNameStartColumn);
+
+ if (results.isNull() || results.isEmpty())
+ results = completeHelper(line, column);
+
filterUnknownContextResults(results, unsavedFile(), line, column);
tryDotArrowCorrectionIfNoResults(results, line, column);
@@ -97,6 +108,62 @@ CompletionCorrection CodeCompleter::neededCorrection() const
return neededCorrection_;
}
+// For given "make_unique<T>" / "make_shared<T>" / "QSharedPointer<T>::create" return "new T("
+// Otherwize return empty QString
+static QString tweakName(const QString &oldName)
+{
+ QString fullName = oldName.trimmed();
+ if (!fullName.contains('>'))
+ return QString();
+
+ if (!fullName.endsWith('>')) {
+ // This is the class<type>::method case - remove ::method part
+ if (!fullName.endsWith("create") || !fullName.contains("QSharedPointer"))
+ return QString();
+ fullName = fullName.mid(0, fullName.lastIndexOf(':') - 1);
+ } else if (!fullName.contains("make_unique") && !fullName.contains("make_shared")) {
+ return QString();
+ }
+ int templateStart = fullName.indexOf('<');
+ QString name = fullName.mid(0, templateStart);
+ QString templatePart = fullName.mid(templateStart + 1,
+ fullName.length() - templateStart - 2);
+ return "new " + templatePart + "(";
+}
+
+ClangCodeCompleteResults CodeCompleter::completeSmartPointerCreation(uint line,
+ uint column,
+ int funcNameStartLine,
+ int funcNameStartColumn)
+{
+ if (column <= 1 || funcNameStartLine == -1)
+ return ClangCodeCompleteResults();
+
+ UnsavedFile &file = unsavedFiles.unsavedFile(translationUnit.filePath());
+ if (!file.hasCharacterAt(line, column - 1, '('))
+ return ClangCodeCompleteResults();
+
+ bool ok;
+ const uint startPos = file.toUtf8Position(funcNameStartLine, funcNameStartColumn, &ok);
+ const uint endPos = file.toUtf8Position(line, column - 1, &ok);
+
+ Utf8String content = file.fileContent();
+ const QString oldName = content.mid(startPos, endPos - startPos);
+ const QString updatedName = tweakName(oldName);
+ if (updatedName.isEmpty())
+ return ClangCodeCompleteResults();
+
+ column += updatedName.length();
+ file.replaceAt(endPos + 1, 0, updatedName);
+
+ ClangCodeCompleteResults results = completeHelper(line, column);
+ if (results.isEmpty()) {
+ column -= updatedName.length();
+ file.replaceAt(endPos + 1, updatedName.length(), QString());
+ }
+ return results;
+}
+
ClangCodeCompleteResults CodeCompleter::completeHelper(uint line, uint column)
{
const Utf8String nativeFilePath = FilePath::toNativeSeparators(translationUnit.filePath());
diff --git a/src/tools/clangbackend/ipcsource/codecompleter.h b/src/tools/clangbackend/ipcsource/codecompleter.h
index 1b2dc4bb37b..2026e9ba2c0 100644
--- a/src/tools/clangbackend/ipcsource/codecompleter.h
+++ b/src/tools/clangbackend/ipcsource/codecompleter.h
@@ -43,7 +43,9 @@ public:
CodeCompleter(const TranslationUnit &translationUnit,
const UnsavedFiles &unsavedFiles);
- CodeCompletions complete(uint line, uint column);
+ CodeCompletions complete(uint line, uint column,
+ int funcNameStartLine = -1,
+ int funcNameStartColumn = -1);
CompletionCorrection neededCorrection() const;
@@ -56,6 +58,10 @@ private:
uint column);
ClangCodeCompleteResults completeHelper(uint line, uint column);
+ ClangCodeCompleteResults completeSmartPointerCreation(uint line,
+ uint column,
+ int funcNameStartLine,
+ int funcNameStartColumn);
ClangCodeCompleteResults completeWithArrowInsteadOfDot(uint line,
uint column,
uint dotPosition);
diff --git a/src/tools/clangbackend/ipcsource/codecompletionsextractor.cpp b/src/tools/clangbackend/ipcsource/codecompletionsextractor.cpp
index 1c810e50698..89dec4b1bf0 100644
--- a/src/tools/clangbackend/ipcsource/codecompletionsextractor.cpp
+++ b/src/tools/clangbackend/ipcsource/codecompletionsextractor.cpp
@@ -42,8 +42,6 @@ bool CodeCompletionsExtractor::next()
{
const uint cxCodeCompleteResultCount = cxCodeCompleteResults->NumResults;
- ++cxCodeCompleteResultIndex;
-
if (cxCodeCompleteResultIndex < cxCodeCompleteResultCount) {
currentCxCodeCompleteResult = cxCodeCompleteResults->Results[cxCodeCompleteResultIndex];
@@ -58,6 +56,8 @@ bool CodeCompletionsExtractor::next()
extractCompletionChunks();
adaptPriority();
+ ++cxCodeCompleteResultIndex;
+
return true;
}
@@ -68,7 +68,7 @@ bool CodeCompletionsExtractor::peek(const Utf8String &name)
{
const uint cxCodeCompleteResultCount = cxCodeCompleteResults->NumResults;
- uint peekCxCodeCompleteResultIndex = cxCodeCompleteResultIndex + 1;
+ uint peekCxCodeCompleteResultIndex = cxCodeCompleteResultIndex;
while (peekCxCodeCompleteResultIndex < cxCodeCompleteResultCount) {
if (hasText(name, cxCodeCompleteResults->Results[peekCxCodeCompleteResultIndex].CompletionString))
diff --git a/src/tools/clangbackend/ipcsource/codecompletionsextractor.h b/src/tools/clangbackend/ipcsource/codecompletionsextractor.h
index 57e9bd5afcf..bbb3611bf65 100644
--- a/src/tools/clangbackend/ipcsource/codecompletionsextractor.h
+++ b/src/tools/clangbackend/ipcsource/codecompletionsextractor.h
@@ -77,7 +77,7 @@ private:
CodeCompletion currentCodeCompletion_;
CXCompletionResult currentCxCodeCompleteResult;
CXCodeCompleteResults *cxCodeCompleteResults;
- uint cxCodeCompleteResultIndex = -1;
+ uint cxCodeCompleteResultIndex = 0;
};
std::ostream &operator<<(std::ostream &os, const CodeCompletionsExtractor &extractor);
diff --git a/src/tools/clangbackend/ipcsource/cursor.cpp b/src/tools/clangbackend/ipcsource/cursor.cpp
index 518fd013d24..6ad50307cdd 100644
--- a/src/tools/clangbackend/ipcsource/cursor.cpp
+++ b/src/tools/clangbackend/ipcsource/cursor.cpp
@@ -273,6 +273,11 @@ CXSourceRange Cursor::cxSourceRange() const
return clang_getCursorExtent(cxCursor);
}
+CXTranslationUnit Cursor::cxTranslationUnit() const
+{
+ return clang_Cursor_getTranslationUnit(cxCursor);
+}
+
SourceRange Cursor::commentRange() const
{
return clang_Cursor_getCommentRange(cxCursor);
diff --git a/src/tools/clangbackend/ipcsource/cursor.h b/src/tools/clangbackend/ipcsource/cursor.h
index 0187d8448b1..6520366b36d 100644
--- a/src/tools/clangbackend/ipcsource/cursor.h
+++ b/src/tools/clangbackend/ipcsource/cursor.h
@@ -86,6 +86,7 @@ public:
CXSourceLocation cxSourceLocation() const;
SourceRange sourceRange() const;
CXSourceRange cxSourceRange() const;
+ CXTranslationUnit cxTranslationUnit() const;
SourceRange commentRange() const;
bool hasSameSourceLocationAs(const Cursor &other) const;
diff --git a/src/tools/clangbackend/ipcsource/diagnostic.h b/src/tools/clangbackend/ipcsource/diagnostic.h
index 64d4eff9b77..140322931fb 100644
--- a/src/tools/clangbackend/ipcsource/diagnostic.h
+++ b/src/tools/clangbackend/ipcsource/diagnostic.h
@@ -25,7 +25,7 @@
#pragma once
-#include <clangbackendipc_global.h>
+#include <clangsupport_global.h>
#include <clang-c/Index.h>
diff --git a/src/tools/clangbackend/ipcsource/highlightingmark.cpp b/src/tools/clangbackend/ipcsource/highlightingmark.cpp
index 510192b6e70..9339d4ba9e7 100644
--- a/src/tools/clangbackend/ipcsource/highlightingmark.cpp
+++ b/src/tools/clangbackend/ipcsource/highlightingmark.cpp
@@ -105,7 +105,8 @@ bool HighlightingMark::hasFunctionArguments() const
HighlightingMark::operator HighlightingMarkContainer() const
{
- return HighlightingMarkContainer(m_line, m_column, m_length, m_types);
+ return HighlightingMarkContainer(m_line, m_column, m_length, m_types, m_isIdentifier,
+ m_isInclusion);
}
namespace {
@@ -288,6 +289,8 @@ void HighlightingMark::functionKind(const Cursor &cursor, Recursion recursion)
void HighlightingMark::identifierKind(const Cursor &cursor, Recursion recursion)
{
+ m_isIdentifier = (cursor.kind() != CXCursor_PreprocessingDirective);
+
switch (cursor.kind()) {
case CXCursor_Destructor:
case CXCursor_Constructor:
@@ -352,6 +355,7 @@ HighlightingType literalKind(const Cursor &cursor)
switch (cursor.kind()) {
case CXCursor_CharacterLiteral:
case CXCursor_StringLiteral:
+ case CXCursor_InclusionDirective:
case CXCursor_ObjCStringLiteral: return HighlightingType::StringLiteral;
case CXCursor_IntegerLiteral:
case CXCursor_ImaginaryLiteral:
@@ -438,6 +442,8 @@ void HighlightingMark::collectKinds(CXTranslationUnit cxTranslationUnit,
case CXToken_Comment: m_types.mainHighlightingType = HighlightingType::Comment; break;
case CXToken_Literal: m_types.mainHighlightingType = literalKind(cursor); break;
}
+
+ m_isInclusion = (cursor.kind() == CXCursor_InclusionDirective);
}
std::ostream &operator<<(std::ostream &os, const HighlightingMark& highlightingMark)
diff --git a/src/tools/clangbackend/ipcsource/highlightingmark.h b/src/tools/clangbackend/ipcsource/highlightingmark.h
index a749a5c9223..b322391c49d 100644
--- a/src/tools/clangbackend/ipcsource/highlightingmark.h
+++ b/src/tools/clangbackend/ipcsource/highlightingmark.h
@@ -25,7 +25,7 @@
#pragma once
-#include <clangbackendipc_global.h>
+#include <clangsupport_global.h>
#include <highlightingmarkcontainer.h>
#include "cursor.h"
@@ -87,6 +87,8 @@ private:
uint m_length;
uint m_offset = 0;
HighlightingTypes m_types;
+ bool m_isIdentifier = false;
+ bool m_isInclusion = false;
};
diff --git a/src/tools/clangbackend/ipcsource/highlightingmarks.cpp b/src/tools/clangbackend/ipcsource/highlightingmarks.cpp
index 2e157ff835e..ed8ddfdd656 100644
--- a/src/tools/clangbackend/ipcsource/highlightingmarks.cpp
+++ b/src/tools/clangbackend/ipcsource/highlightingmarks.cpp
@@ -68,15 +68,12 @@ QVector<HighlightingMarkContainer> HighlightingMarks::toHighlightingMarksContain
const auto isValidHighlightMark = [] (const HighlightingMark &highlightMark) {
return !highlightMark.hasInvalidMainType()
- && !highlightMark.hasMainType(HighlightingType::StringLiteral)
- && !highlightMark.hasMainType(HighlightingType::NumberLiteral)
- && !highlightMark.hasMainType(HighlightingType::Comment);
+ && !highlightMark.hasMainType(HighlightingType::NumberLiteral)
+ && !highlightMark.hasMainType(HighlightingType::Comment);
};
-
- for (const HighlightingMark &highlightMark : *this) {
+ for (const HighlightingMark &highlightMark : *this)
if (isValidHighlightMark(highlightMark))
containers.push_back(highlightMark);
- }
return containers;
}
diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro b/src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro
index b115782dfe7..8dab349dd34 100644
--- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro
+++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro
@@ -1,5 +1,5 @@
QTC_LIB_DEPENDS += \
- clangbackendipc
+ clangsupport
include(../../qtcreatortool.pri)
include(../../shared/clang/clang_installation.pri)
diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
index a8eb4ce09a1..5622179272b 100644
--- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
+++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
@@ -50,7 +50,7 @@ using ClangBackEnd::PchGenerator;
using ClangBackEnd::PchManagerClientProxy;
using ClangBackEnd::PchManagerServer;
using ClangBackEnd::ProjectParts;
-using ClangBackEnd::StringCache;
+using ClangBackEnd::FilePathCache;
class ApplicationEnvironment : public ClangBackEnd::Environment
{
@@ -103,7 +103,7 @@ int main(int argc, char *argv[])
const QString connection = processArguments(application);
- StringCache<Utils::PathString> filePathCache;
+ FilePathCache<> filePathCache;
ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher(filePathCache);
ApplicationEnvironment environment;
PchGenerator<QProcess> pchGenerator(environment);
diff --git a/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h b/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h
index ba990c6cf9d..85ad8bbd63e 100644
--- a/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h
+++ b/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h
@@ -37,8 +37,8 @@ namespace ClangBackEnd {
class WatcherEntry
{
public:
- uint id;
- uint path;
+ FilePathIndex id;
+ FilePathIndex path;
friend bool operator==(const WatcherEntry &first, const WatcherEntry &second)
{
@@ -50,12 +50,12 @@ public:
return std::tie(first.path, first.id) < std::tie(second.path, second.id);
}
- friend bool operator<(const WatcherEntry &entry, uint path)
+ friend bool operator<(const WatcherEntry &entry, FilePathIndex path)
{
return entry.path < path;
}
- friend bool operator<(uint path, const WatcherEntry &entry)
+ friend bool operator<(FilePathIndex path, const WatcherEntry &entry)
{
return path < entry.path;
}
@@ -63,12 +63,18 @@ public:
using WatcherEntries = std::vector<WatcherEntry>;
+using IdCache = StringCache<Utils::SmallString,
+ FilePathIndex,
+ NonLockingMutex,
+ decltype(&Utils::compare),
+ Utils::compare>;
+
template <typename FileSystemWatcher,
typename Timer>
class ClangPathWatcher : public ClangPathWatcherInterface
{
public:
- ClangPathWatcher(StringCache<Utils::PathString> &pathCache,
+ ClangPathWatcher(FilePathCache<> &pathCache,
ClangPathWatcherNotifier *notifier=nullptr)
: m_pathCache(pathCache),
m_notifier(notifier)
@@ -130,9 +136,9 @@ unittest_public:
return ids;
}
- std::vector<uint> convertToIdNumbers(const Utils::SmallStringVector &ids)
+ std::vector<FilePathIndex> convertToIdNumbers(const Utils::SmallStringVector &ids)
{
- std::vector<uint> idNumbers = m_idCache.stringIds(ids);
+ std::vector<FilePathIndex> idNumbers = m_idCache.stringIds(ids);
std::sort(idNumbers.begin(), idNumbers.end());
@@ -149,19 +155,19 @@ unittest_public:
}
- std::pair<WatcherEntries,std::vector<uint>>
+ std::pair<WatcherEntries,std::vector<FilePathIndex>>
convertIdPathsToWatcherEntriesAndIds(const std::vector<IdPaths> &idPaths)
{
WatcherEntries entries;
entries.reserve(sizeOfIdPaths(idPaths));
- std::vector<uint> ids;
+ std::vector<FilePathIndex> ids;
ids.reserve(ids.size());
auto outputIterator = std::back_inserter(entries);
for (const IdPaths &idPath : idPaths)
{
- uint id = m_idCache.stringId(idPath.id);
+ FilePathIndex id = m_idCache.stringId(idPath.id);
ids.push_back(id);
@@ -190,7 +196,7 @@ unittest_public:
}
void removeUnusedEntries(const WatcherEntries &entries,
- const std::vector<uint> &ids)
+ const std::vector<FilePathIndex> &ids)
{
auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, ids);
@@ -216,7 +222,7 @@ unittest_public:
std::transform(watcherEntries.begin(),
watcherEntries.end(),
std::back_inserter(paths),
- [&] (const WatcherEntry &entry) { return m_pathCache.string(entry.path); });
+ [&] (const WatcherEntry &entry) { return QString(m_pathCache.string(entry.path)); });
return paths;
}
@@ -272,7 +278,7 @@ unittest_public:
WatcherEntries notAnymoreWatchedEntriesWithIds(
const WatcherEntries &newEntries,
- const std::vector<uint> &ids) const
+ const std::vector<FilePathIndex> &ids) const
{
auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less<WatcherEntry>());
@@ -328,7 +334,7 @@ unittest_public:
return m_watchedEntries;
}
- WatcherEntries removeIdsFromWatchedEntries(const std::vector<uint> &ids)
+ WatcherEntries removeIdsFromWatchedEntries(const std::vector<FilePathIndex> &ids)
{
auto keep = [&] (const WatcherEntry &entry) {
@@ -368,7 +374,7 @@ unittest_public:
WatcherEntries watchedEntriesForPaths(Utils::PathStringVector &&filePaths)
{
- std::vector<uint> pathIds = m_pathCache.stringIds(filePaths);
+ std::vector<FilePathIndex> pathIds = m_pathCache.stringIds(filePaths);
WatcherEntries foundEntries;
@@ -388,7 +394,7 @@ unittest_public:
foundEntries.end(),
std::back_inserter(ids),
[&] (const WatcherEntry &entry) {
- return m_idCache.string(entry.id);
+ return Utils::SmallString(m_idCache.string(entry.id));
});
return ids;
@@ -414,22 +420,22 @@ unittest_public:
}
}
- StringCache<Utils::PathString> &pathCache()
+ FilePathCache<> &pathCache()
{
return m_pathCache;
}
- StringCache<Utils::SmallString> &idCache()
+ IdCache &idCache()
{
return m_idCache;
}
private:
- StringCache<Utils::SmallString> m_idCache;
+ IdCache m_idCache;
WatcherEntries m_watchedEntries;
ChangedFilePathCompressor<Timer> m_changedFilePathCompressor;
FileSystemWatcher m_fileSystemWatcher;
- StringCache<Utils::PathString> &m_pathCache;
+ FilePathCache<> &m_pathCache;
ClangPathWatcherNotifier *m_notifier;
};
diff --git a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h b/src/tools/clangpchmanagerbackend/source/collectincludesaction.h
index 5b8b8ad5e6b..339d491848d 100644
--- a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h
+++ b/src/tools/clangpchmanagerbackend/source/collectincludesaction.h
@@ -38,10 +38,10 @@ namespace ClangBackEnd {
class CollectIncludesAction final : public clang::PreprocessOnlyAction
{
public:
- CollectIncludesAction(std::vector<uint> &includeIds,
- StringCache<Utils::PathString> &filePathCache,
- std::vector<uint> &excludedIncludeUID,
- std::vector<uint> &alreadyIncludedFileUIDs)
+ CollectIncludesAction(FilePathIndices &includeIds,
+ FilePathCache<> &filePathCache,
+ FilePathIndices &excludedIncludeUID,
+ FilePathIndices &alreadyIncludedFileUIDs)
: m_includeIds(includeIds),
m_filePathCache(filePathCache),
m_excludedIncludeUID(excludedIncludeUID),
@@ -78,10 +78,10 @@ public:
}
private:
- std::vector<uint> &m_includeIds;
- StringCache<Utils::PathString> &m_filePathCache;
- std::vector<uint> &m_excludedIncludeUID;
- std::vector<uint> &m_alreadyIncludedFileUIDs;
+ FilePathIndices &m_includeIds;
+ FilePathCache<> &m_filePathCache;
+ FilePathIndices &m_excludedIncludeUID;
+ FilePathIndices &m_alreadyIncludedFileUIDs;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h
index ba86822fce3..a57d72adfcb 100644
--- a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h
+++ b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h
@@ -47,10 +47,10 @@ class CollectIncludesPreprocessorCallbacks final : public clang::PPCallbacks
{
public:
CollectIncludesPreprocessorCallbacks(clang::HeaderSearch &headerSearch,
- std::vector<uint> &includeIds,
- StringCache<Utils::PathString> &filePathCache,
- const std::vector<uint> &excludedIncludeUID,
- std::vector<uint> &alreadyIncludedFileUIDs)
+ std::vector<FilePathIndex> &includeIds,
+ FilePathCache<> &filePathCache,
+ const std::vector<FilePathIndex> &excludedIncludeUID,
+ std::vector<FilePathIndex> &alreadyIncludedFileUIDs)
: m_headerSearch(headerSearch),
m_includeIds(includeIds),
m_filePathCache(filePathCache),
@@ -78,7 +78,7 @@ public:
m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID);
Utils::PathString filePath = filePathFromFile(file);
if (!filePath.isEmpty()) {
- uint includeId = m_filePathCache.stringId(filePath);
+ FilePathIndex includeId = m_filePathCache.stringId(filePath);
m_includeIds.emplace_back(includeId);
}
}
@@ -132,7 +132,7 @@ public:
uid);
}
- std::pair<bool, std::vector<uint>::iterator> isNotAlreadyIncluded(uint uid) const
+ std::pair<bool, std::vector<FilePathIndex>::iterator> isNotAlreadyIncluded(FilePathIndex uid) const
{
auto range = std::equal_range(m_alreadyIncludedFileUIDs.begin(),
m_alreadyIncludedFileUIDs.end(),
@@ -174,10 +174,10 @@ public:
private:
clang::HeaderSearch &m_headerSearch;
- std::vector<uint> &m_includeIds;
- StringCache<Utils::PathString> &m_filePathCache;
- const std::vector<uint> &m_excludedIncludeUID;
- std::vector<uint> &m_alreadyIncludedFileUIDs;
+ std::vector<FilePathIndex> &m_includeIds;
+ FilePathCache<> &m_filePathCache;
+ const std::vector<FilePathIndex> &m_excludedIncludeUID;
+ std::vector<FilePathIndex> &m_alreadyIncludedFileUIDs;
bool m_skipInclude = false;
};
diff --git a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h b/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h
index 87e92c1df3e..42b8a62cea7 100644
--- a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h
+++ b/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h
@@ -36,8 +36,8 @@ namespace ClangBackEnd {
class CollectIncludesToolAction final : public clang::tooling::FrontendActionFactory
{
public:
- CollectIncludesToolAction(std::vector<uint> &includeIds,
- StringCache<Utils::PathString> &filePathCache,
+ CollectIncludesToolAction(std::vector<FilePathIndex> &includeIds,
+ FilePathCache<> &filePathCache,
const Utils::PathStringVector &excludedIncludes)
: m_includeIds(includeIds),
m_filePathCache(filePathCache),
@@ -72,9 +72,9 @@ public:
m_alreadyIncludedFileUIDs);
}
- std::vector<uint> generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const
+ std::vector<FilePathIndex> generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const
{
- std::vector<uint> fileUIDs;
+ std::vector<FilePathIndex> fileUIDs;
fileUIDs.reserve(m_excludedIncludes.size());
for (const Utils::PathString &filePath : m_excludedIncludes) {
@@ -90,10 +90,10 @@ public:
}
private:
- std::vector<uint> m_alreadyIncludedFileUIDs;
- std::vector<uint> m_excludedIncludeUIDs;
- std::vector<uint> &m_includeIds;
- StringCache<Utils::PathString> &m_filePathCache;
+ std::vector<FilePathIndex> m_alreadyIncludedFileUIDs;
+ std::vector<FilePathIndex> m_excludedIncludeUIDs;
+ std::vector<FilePathIndex> &m_includeIds;
+ FilePathCache<> &m_filePathCache;
const Utils::PathStringVector &m_excludedIncludes;
};
diff --git a/src/tools/clangpchmanagerbackend/source/idpaths.h b/src/tools/clangpchmanagerbackend/source/idpaths.h
index f6f312f05fd..a407e24530f 100644
--- a/src/tools/clangpchmanagerbackend/source/idpaths.h
+++ b/src/tools/clangpchmanagerbackend/source/idpaths.h
@@ -29,13 +29,15 @@
#include <iosfwd>
+#include <stringcachefwd.h>
+
namespace ClangBackEnd {
class IdPaths
{
public:
Utils::SmallString id;
- std::vector<uint> paths;
+ std::vector<FilePathIndex> paths;
friend bool operator==(const IdPaths &first, const IdPaths &second)
{
diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.cpp b/src/tools/clangpchmanagerbackend/source/includecollector.cpp
index b380fa2b8b6..421123b3a7c 100644
--- a/src/tools/clangpchmanagerbackend/source/includecollector.cpp
+++ b/src/tools/clangpchmanagerbackend/source/includecollector.cpp
@@ -33,7 +33,7 @@
namespace ClangBackEnd {
-IncludeCollector::IncludeCollector(StringCache<Utils::PathString> &filePathCache)
+IncludeCollector::IncludeCollector(FilePathCache<> &filePathCache)
: m_filePathCache(filePathCache)
{
}
@@ -69,7 +69,7 @@ void IncludeCollector::setExcludedIncludes(Utils::PathStringVector &&excludedInc
#endif
}
-std::vector<uint> IncludeCollector::takeIncludeIds()
+std::vector<FilePathIndex> IncludeCollector::takeIncludeIds()
{
std::sort(m_includeIds.begin(), m_includeIds.end());
diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.h b/src/tools/clangpchmanagerbackend/source/includecollector.h
index ba485ea33d7..73f9b948afa 100644
--- a/src/tools/clangpchmanagerbackend/source/includecollector.h
+++ b/src/tools/clangpchmanagerbackend/source/includecollector.h
@@ -34,19 +34,19 @@ namespace ClangBackEnd {
class IncludeCollector : public ClangTool
{
public:
- IncludeCollector(StringCache<Utils::PathString> &filePathCache);
+ IncludeCollector(FilePathCache<> &filePathCache);
void collectIncludes();
void setExcludedIncludes(Utils::PathStringVector &&excludedIncludes);
- std::vector<uint> takeIncludeIds();
+ std::vector<FilePathIndex> takeIncludeIds();
private:
Utils::PathStringVector m_excludedIncludes;
- std::vector<uint> m_includeIds;
+ std::vector<FilePathIndex> m_includeIds;
Utils::SmallStringVector m_directories;
- StringCache<Utils::PathString> &m_filePathCache;
+ FilePathCache<> &m_filePathCache;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
index 31485b8ed17..fd6da580129 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
@@ -37,7 +37,7 @@
namespace ClangBackEnd {
-PchCreator::PchCreator(Environment &environment, StringCache<Utils::PathString> &filePathCache)
+PchCreator::PchCreator(Environment &environment, FilePathCache<> &filePathCache)
: m_environment(environment),
m_filePathCache(filePathCache)
{
@@ -45,7 +45,7 @@ PchCreator::PchCreator(Environment &environment, StringCache<Utils::PathString>
PchCreator::PchCreator(V2::ProjectPartContainers &&projectsParts,
Environment &environment,
- StringCache<Utils::PathString> &filePathCache,
+ FilePathCache<> &filePathCache,
PchGeneratorInterface *pchGenerator,
V2::FileContainers &&generatedFiles)
: m_projectParts(std::move(projectsParts)),
@@ -66,24 +66,24 @@ template <typename Source,
typename Target>
void append(Target &target, const Source &source)
{
+ using ValueType = typename Target::value_type;
Source clonedSource = source.clone();
target.reserve(target.size() + source.size());
- std::move(clonedSource.begin(),
- clonedSource.end(),
- std::back_inserter(target));
+ for (auto &&entry : clonedSource)
+ target.push_back(ValueType(std::move(entry)));
}
template <typename Source,
typename Target>
void append(Target &target, Source &source)
{
+ using ValueType = typename Target::value_type;
target.reserve(target.size() + source.size());
- std::move(source.begin(),
- source.end(),
- std::back_inserter(target));
+ for (auto &&entry : source)
+ target.push_back(ValueType(entry));
}
template <typename GetterFunction>
@@ -239,7 +239,7 @@ Utils::SmallStringVector PchCreator::generateGlobalClangCompilerArguments() cons
return compilerArguments;
}
-std::vector<uint> PchCreator::generateGlobalPchIncludeIds() const
+std::vector<FilePathIndex> PchCreator::generateGlobalPchIncludeIds() const
{
IncludeCollector collector(m_filePathCache);
@@ -267,7 +267,7 @@ std::size_t contentSize(const std::vector<Utils::PathString> &includes)
}
Utils::SmallString PchCreator::generatePchIncludeFileContent(
- const std::vector<uint> &includeIds) const
+ const std::vector<FilePathIndex> &includeIds) const
{
Utils::SmallString fileContent;
const std::size_t lineTemplateSize = 12;
@@ -461,7 +461,7 @@ Utils::PathStringVector PchCreator::generateProjectPartHeaderAndSourcePaths(
return includeAndSources;
}
-std::vector<uint> PchCreator::generateProjectPartPchIncludes(
+std::vector<FilePathIndex> PchCreator::generateProjectPartPchIncludes(
const V2::ProjectPartContainer &projectPart) const
{
Utils::SmallString jointedFileContent = generateProjectPartHeaderAndSourcesContent(projectPart);
@@ -469,14 +469,14 @@ std::vector<uint> PchCreator::generateProjectPartPchIncludes(
auto jointFile = generateFileWithContent(jointedFilePath, jointedFileContent);
Utils::SmallStringVector arguments = generateProjectPartCommandLine(projectPart);
arguments.push_back(jointedFilePath);
- FilePath filePath(jointedFilePath.clone());
+ FilePath filePath{Utils::PathString(jointedFilePath)};
IncludeCollector collector(m_filePathCache);
collector.setExcludedIncludes(generateProjectPartHeaderAndSourcePaths(projectPart));
- collector.addFile(filePath.directory(),
- filePath.name(),
+ collector.addFile(std::string(filePath.directory()),
+ std::string(filePath.name()),
{},
arguments);
@@ -581,11 +581,11 @@ std::unique_ptr<QFile> PchCreator::generateFileWithContent(
const Utils::SmallString &filePath,
const Utils::SmallString &content)
{
- std::unique_ptr<QFile> precompiledIncludeFile(new QFile(filePath));
+ std::unique_ptr<QFile> precompiledIncludeFile(new QFile(QString(filePath)));
precompiledIncludeFile->open(QIODevice::WriteOnly);
- precompiledIncludeFile->write(content.data(), content.size());
+ precompiledIncludeFile->write(content.data(), qint64(content.size()));
precompiledIncludeFile->close();
return precompiledIncludeFile;
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h
index 1b418ad3db2..5548ec7acd2 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreator.h
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h
@@ -48,10 +48,10 @@ class PchCreator final : public PchCreatorInterface
{
public:
PchCreator(Environment &environment,
- StringCache<Utils::PathString> &filePathCache);
+ FilePathCache<> &filePathCache);
PchCreator(V2::ProjectPartContainers &&projectsParts,
Environment &environment,
- StringCache<Utils::PathString> &filePathCache,
+ FilePathCache<> &filePathCache,
PchGeneratorInterface *pchGenerator,
V2::FileContainers &&generatedFiles);
@@ -70,9 +70,9 @@ unittest_public:
Utils::SmallStringVector generateGlobalPchCompilerArguments() const;
Utils::SmallStringVector generateGlobalClangCompilerArguments() const;
- std::vector<uint> generateGlobalPchIncludeIds() const;
+ std::vector<FilePathIndex> generateGlobalPchIncludeIds() const;
- Utils::SmallString generatePchIncludeFileContent(const std::vector<uint> &includeIds) const;
+ Utils::SmallString generatePchIncludeFileContent(const std::vector<FilePathIndex> &includeIds) const;
Utils::SmallString generateGlobalPchHeaderFileContent() const;
std::unique_ptr<QFile> generateGlobalPchHeaderFile();
void generatePch(Utils::SmallStringVector &&commandLineArguments,
@@ -97,7 +97,7 @@ unittest_public:
const V2::ProjectPartContainer &projectPart);
static Utils::PathStringVector generateProjectPartHeaderAndSourcePaths(
const V2::ProjectPartContainer &projectPart);
- std::vector<uint> generateProjectPartPchIncludes(
+ std::vector<FilePathIndex> generateProjectPartPchIncludes(
const V2::ProjectPartContainer &projectPart) const;
Utils::SmallString generateProjectPathPchHeaderFilePath(
const V2::ProjectPartContainer &projectPart) const;
@@ -127,7 +127,7 @@ private:
std::vector<ProjectPartPch> m_projectPartPchs;
std::vector<IdPaths> m_projectsIncludeIds;
Environment &m_environment;
- StringCache<Utils::PathString> &m_filePathCache;
+ FilePathCache<> &m_filePathCache;
PchGeneratorInterface *m_pchGenerator = nullptr;
};
diff --git a/src/tools/clangpchmanagerbackend/source/pchgenerator.h b/src/tools/clangpchmanagerbackend/source/pchgenerator.h
index ca8438506fd..144f21bffa8 100644
--- a/src/tools/clangpchmanagerbackend/source/pchgenerator.h
+++ b/src/tools/clangpchmanagerbackend/source/pchgenerator.h
@@ -70,8 +70,8 @@ unittest_public:
Process *processPointer = process.get();
process->setProcessChannelMode(QProcess::ForwardedChannels);
- process->setArguments(compilerArguments);
- process->setProgram(m_environment.clangCompilerPath());
+ process->setArguments(QStringList(compilerArguments));
+ process->setProgram(QString(m_environment.clangCompilerPath()));
connectProcess(processPointer, std::move(projectPartPch));
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
index f22458c8b3d..03261ae164c 100644
--- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
@@ -36,7 +36,7 @@
namespace ClangBackEnd {
-PchManagerServer::PchManagerServer(StringCache<Utils::PathString> &filePathCache,
+PchManagerServer::PchManagerServer(FilePathCache<> &filePathCache,
ClangPathWatcherInterface &fileSystemWatcher,
PchCreatorInterface &pchCreator,
ProjectPartsInterface &projectParts)
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
index e28a3658e27..7be9c759669 100644
--- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
@@ -33,16 +33,20 @@
#include "projectpartsinterface.h"
#include "stringcache.h"
+#include <ipcclientprovider.h>
+
namespace ClangBackEnd {
class SourceRangesAndDiagnosticsForQueryMessage;
class PchManagerServer : public PchManagerServerInterface,
public ClangPathWatcherNotifier,
- public PchGeneratorNotifierInterface
+ public PchGeneratorNotifierInterface,
+ public IpcClientProvider<PchManagerClientInterface>
+
{
public:
- PchManagerServer(StringCache<Utils::PathString> &filePathCache,
+ PchManagerServer(FilePathCache<> &filePathCache,
ClangPathWatcherInterface &fileSystemWatcher,
PchCreatorInterface &pchCreator,
ProjectPartsInterface &projectParts);
@@ -56,7 +60,7 @@ public:
void taskFinished(TaskFinishStatus status, const ProjectPartPch &projectPartPch) override;
private:
- StringCache<Utils::PathString> &m_filePathCache;
+ FilePathCache<> &m_filePathCache;
ClangPathWatcherInterface &m_fileSystemWatcher;
PchCreatorInterface &m_pchCreator;
ProjectPartsInterface &m_projectParts;
diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro b/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro
index 705198f216e..3b94d003c06 100644
--- a/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro
+++ b/src/tools/clangrefactoringbackend/clangrefactoringbackend.pro
@@ -1,5 +1,5 @@
QTC_LIB_DEPENDS += \
- clangbackendipc
+ clangsupport
include(../../qtcreatortool.pri)
include(../../shared/clang/clang_installation.pri)
diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
index fca9a0c9fcf..8c5fe3f751f 100644
--- a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
+++ b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
@@ -26,14 +26,19 @@
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QLoggingCategory>
+#include <QDir>
#include <connectionserver.h>
+#include <stringcache.h>
#include <refactoringserver.h>
#include <refactoringclientproxy.h>
+#include <symbolindexing.h>
+using ClangBackEnd::FilePathCache;
using ClangBackEnd::RefactoringClientProxy;
using ClangBackEnd::RefactoringServer;
using ClangBackEnd::ConnectionServer;
+using ClangBackEnd::SymbolIndexing;
QString processArguments(QCoreApplication &application)
{
@@ -52,7 +57,7 @@ QString processArguments(QCoreApplication &application)
}
int main(int argc, char *argv[])
-{
+try {
//QLoggingCategory::setFilterRules(QStringLiteral("*.debug=false"));
QCoreApplication::setOrganizationName(QStringLiteral("QtProject"));
@@ -64,13 +69,17 @@ int main(int argc, char *argv[])
const QString connection = processArguments(application);
- RefactoringServer clangCodeModelServer;
+ FilePathCache<std::mutex> filePathCache;
+ SymbolIndexing symbolIndexing{filePathCache, Utils::PathString{QDir::tempPath() + "/symbol.db"}};
+ RefactoringServer clangCodeModelServer{symbolIndexing, filePathCache};
ConnectionServer<RefactoringServer, RefactoringClientProxy> connectionServer(connection);
connectionServer.start();
connectionServer.setServer(&clangCodeModelServer);
return application.exec();
+} catch (const Sqlite::Exception &exception) {
+ exception.printWarning();
}
diff --git a/src/tools/clangrefactoringbackend/source/clangquery.cpp b/src/tools/clangrefactoringbackend/source/clangquery.cpp
index b625e9e197f..620a7ebaab0 100644
--- a/src/tools/clangrefactoringbackend/source/clangquery.cpp
+++ b/src/tools/clangrefactoringbackend/source/clangquery.cpp
@@ -54,7 +54,7 @@ struct CollectBoundNodes : MatchFinder::MatchCallback {
}
};
-ClangQuery::ClangQuery(StringCache<Utils::PathString, std::mutex> &filePathCache,
+ClangQuery::ClangQuery(FilePathCache<std::mutex> &filePathCache,
Utils::SmallString &&query)
: query(std::move(query)),
filePathCache(filePathCache)
diff --git a/src/tools/clangrefactoringbackend/source/clangquery.h b/src/tools/clangrefactoringbackend/source/clangquery.h
index faa5821ca3b..7d99766008d 100644
--- a/src/tools/clangrefactoringbackend/source/clangquery.h
+++ b/src/tools/clangrefactoringbackend/source/clangquery.h
@@ -51,7 +51,7 @@ namespace ClangBackEnd {
class ClangQuery : public ClangTool
{
public:
- ClangQuery(StringCache<Utils::PathString, std::mutex> &filePathCache, Utils::SmallString &&query={});
+ ClangQuery(FilePathCache<std::mutex> &filePathCache, Utils::SmallString &&query={});
void setQuery(Utils::SmallString &&query);
@@ -69,7 +69,7 @@ private:
SourceRangesContainer sourceRangesContainer;
Utils::SmallString query;
std::vector<DynamicASTMatcherDiagnosticContainer> diagnosticContainers_;
- StringCache<Utils::PathString, std::mutex> &filePathCache;
+ FilePathCache<std::mutex> &filePathCache;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp
index 319cfaa47d1..692065a9e79 100644
--- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp
+++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp
@@ -29,7 +29,7 @@
namespace ClangBackEnd {
-ClangQueryGatherer::ClangQueryGatherer(StringCache<Utils::PathString, std::mutex> *filePathCache,
+ClangQueryGatherer::ClangQueryGatherer(FilePathCache<std::mutex> *filePathCache,
std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved,
Utils::SmallString &&query)
@@ -43,17 +43,17 @@ ClangQueryGatherer::ClangQueryGatherer(StringCache<Utils::PathString, std::mutex
SourceRangesForQueryMessage
ClangQueryGatherer::createSourceRangesForSource(
- StringCache<Utils::PathString, std::mutex> *filePathCache,
+ FilePathCache<std::mutex> *filePathCache,
V2::FileContainer &&source,
const std::vector<V2::FileContainer> &unsaved,
Utils::SmallString &&query)
{
ClangQuery clangQuery(*filePathCache, std::move(query));
- clangQuery.addFile(source.filePath().directory(),
- source.filePath().name(),
- source.takeUnsavedFileContent(),
- source.takeCommandLineArguments());
+ clangQuery.addFile(std::string(source.filePath().directory()),
+ std::string(source.filePath().name()),
+ std::string(source.takeUnsavedFileContent()),
+ std::vector<std::string>(source.takeCommandLineArguments()));
clangQuery.addUnsavedFiles(unsaved);
diff --git a/src/tools/clangrefactoringbackend/source/clangquerygatherer.h b/src/tools/clangrefactoringbackend/source/clangquerygatherer.h
index 7d93560eecf..c1fd6341fab 100644
--- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.h
+++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.h
@@ -41,13 +41,13 @@ public:
using Future = std::future<SourceRangesForQueryMessage>;
ClangQueryGatherer() = default;
- ClangQueryGatherer(StringCache<Utils::PathString, std::mutex> *filePathCache,
+ ClangQueryGatherer(FilePathCache<std::mutex> *filePathCache,
std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved,
Utils::SmallString &&query);
static SourceRangesForQueryMessage createSourceRangesForSource(
- StringCache<Utils::PathString, std::mutex> *filePathCache,
+ FilePathCache<std::mutex> *filePathCache,
V2::FileContainer &&source,
const std::vector<V2::FileContainer> &unsaved,
Utils::SmallString &&query);
@@ -69,7 +69,7 @@ protected:
std::vector<Future> finishedFutures();
private:
- StringCache<Utils::PathString, std::mutex> *m_filePathCache = nullptr;
+ FilePathCache<std::mutex> *m_filePathCache = nullptr;
SourceRangeFilter m_sourceRangeFilter;
std::vector<V2::FileContainer> m_sources;
std::vector<V2::FileContainer> m_unsaved;
diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
index 8af6b89974c..50041e596a2 100644
--- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
+++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
@@ -2,7 +2,16 @@ INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/clangrefactoringbackend_global.h \
- $$PWD/sourcerangefilter.h
+ $$PWD/sourcerangefilter.h \
+ $$PWD/symbolindexer.h \
+ $$PWD/symbolentry.h \
+ $$PWD/sourcelocationentry.h \
+ $$PWD/symbolscollectorinterface.h \
+ $$PWD/symbolstorageinterface.h \
+ $$PWD/symbolstorage.h \
+ $$PWD/storagesqlitestatementfactory.h \
+ $$PWD/symbolindexing.h \
+ $$PWD/symbolindexinginterface.h
!isEmpty(LIBTOOLING_LIBS) {
SOURCES += \
@@ -16,7 +25,12 @@ SOURCES += \
$$PWD/clangtool.cpp \
$$PWD/sourcerangeextractor.cpp \
$$PWD/locationsourcefilecallbacks.cpp \
- $$PWD/clangquerygatherer.cpp
+ $$PWD/collectsymbolsaction.cpp \
+ $$PWD/collectmacrossourcefilecallbacks.cpp \
+ $$PWD/symbolscollector.cpp \
+ $$PWD/clangquerygatherer.cpp \
+ $$PWD/symbolstorage.cpp \
+ $$PWD/symbolindexing.cpp
HEADERS += \
$$PWD/refactoringcompilationdatabase.h \
@@ -32,8 +46,16 @@ HEADERS += \
$$PWD/clangtool.h \
$$PWD/sourcerangeextractor.h \
$$PWD/locationsourcefilecallbacks.h \
+ $$PWD/collectsymbolsconsumer.h \
+ $$PWD/collectsymbolsaction.h \
+ $$PWD/collectsymbolsastvisitor.h \
+ $$PWD/collectmacrossourcefilecallbacks.h \
+ $$PWD/symbolscollector.h \
$$PWD/clangquerygatherer.h
}
SOURCES += \
- $$PWD/sourcerangefilter.cpp
+ $$PWD/sourcerangefilter.cpp \
+ $$PWD/symbolindexer.cpp \
+ $$PWD/symbolentry.cpp \
+ $$PWD/sourcelocationentry.cpp
diff --git a/src/tools/clangrefactoringbackend/source/clangtool.cpp b/src/tools/clangrefactoringbackend/source/clangtool.cpp
index 2ffad739655..61d3f968406 100644
--- a/src/tools/clangrefactoringbackend/source/clangtool.cpp
+++ b/src/tools/clangrefactoringbackend/source/clangtool.cpp
@@ -43,19 +43,19 @@ String toNativePath(String &&path)
}
void ClangTool::addFile(std::string &&directory,
- std::string &&fileName,
- std::string &&content,
- std::vector<std::string> &&commandLine)
+ std::string &&fileName,
+ std::string &&content,
+ std::vector<std::string> &&commandLine)
{
- fileContents.emplace_back(toNativePath(std::move(directory)),
+ m_fileContents.emplace_back(toNativePath(std::move(directory)),
std::move(fileName),
std::move(content),
std::move(commandLine));
- const auto &fileContent = fileContents.back();
+ const auto &fileContent = m_fileContents.back();
- compilationDatabase.addFile(fileContent.directory, fileContent.fileName, fileContent.commandLine);
- sourceFilePaths.push_back(fileContent.filePath);
+ m_compilationDatabase.addFile(fileContent.directory, fileContent.fileName, fileContent.commandLine);
+ m_sourceFilePaths.push_back(fileContent.filePath);
}
template <typename Container>
@@ -68,7 +68,7 @@ void ClangTool::addFiles(const Container &filePaths,
auto fileNameBegin = found.base();
std::vector<std::string> commandLine(arguments.begin(), arguments.end());
- commandLine.push_back(filePath);
+ commandLine.push_back(std::string(filePath));
addFile({filePath.begin(), std::prev(fileNameBegin)},
{fileNameBegin, filePath.end()},
@@ -86,7 +86,7 @@ void ClangTool::addFiles<Utils::PathStringVector>(const Utils::PathStringVector
void ClangTool::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
{
- unsavedFileContents.reserve(unsavedFileContents.size() + unsavedFiles.size());
+ m_unsavedFileContents.reserve(m_unsavedFileContents.size() + unsavedFiles.size());
auto convertToUnsavedFileContent = [] (const V2::FileContainer &unsavedFile) {
return UnsavedFileContent{toNativePath(unsavedFile.filePath().path().clone()),
@@ -95,7 +95,7 @@ void ClangTool::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
std::transform(unsavedFiles.begin(),
unsavedFiles.end(),
- std::back_inserter(unsavedFileContents),
+ std::back_inserter(m_unsavedFileContents),
convertToUnsavedFileContent);
}
@@ -109,14 +109,14 @@ llvm::StringRef toStringRef(const String &string)
clang::tooling::ClangTool ClangTool::createTool() const
{
- clang::tooling::ClangTool tool(compilationDatabase, sourceFilePaths);
+ clang::tooling::ClangTool tool(m_compilationDatabase, m_sourceFilePaths);
- for (const auto &fileContent : fileContents) {
+ for (const auto &fileContent : m_fileContents) {
if (!fileContent.content.empty())
tool.mapVirtualFile(fileContent.filePath, fileContent.content);
}
- for (const auto &unsavedFileContent : unsavedFileContents)
+ for (const auto &unsavedFileContent : m_unsavedFileContents)
tool.mapVirtualFile(toStringRef(unsavedFileContent.filePath),
toStringRef(unsavedFileContent.content));
diff --git a/src/tools/clangrefactoringbackend/source/clangtool.h b/src/tools/clangrefactoringbackend/source/clangtool.h
index c6439209143..0f436a0e37d 100644
--- a/src/tools/clangrefactoringbackend/source/clangtool.h
+++ b/src/tools/clangrefactoringbackend/source/clangtool.h
@@ -104,10 +104,17 @@ public:
clang::tooling::ClangTool createTool() const;
private:
- RefactoringCompilationDatabase compilationDatabase;
- std::vector<FileContent> fileContents;
- std::vector<std::string> sourceFilePaths;
- std::vector<UnsavedFileContent> unsavedFileContents;
+ RefactoringCompilationDatabase m_compilationDatabase;
+ std::vector<FileContent> m_fileContents;
+ std::vector<std::string> m_sourceFilePaths;
+ std::vector<UnsavedFileContent> m_unsavedFileContents;
};
+extern template
+void ClangTool::addFiles<Utils::SmallStringVector>(const Utils::SmallStringVector &filePaths,
+ const Utils::SmallStringVector &arguments);
+extern template
+void ClangTool::addFiles<Utils::PathStringVector>(const Utils::PathStringVector &filePaths,
+ const Utils::SmallStringVector &arguments);
+
} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp
new file mode 100644
index 00000000000..ade4904e46e
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp
@@ -0,0 +1,35 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "collectmacrossourcefilecallbacks.h"
+
+namespace ClangBackEnd {
+
+CollectMacrosSourceFileCallbacks::CollectMacrosSourceFileCallbacks()
+{
+
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h
new file mode 100644
index 00000000000..2c28f19f7b5
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <clang/Tooling/Tooling.h>
+
+namespace ClangBackEnd {
+
+class CollectMacrosSourceFileCallbacks : public clang::tooling::SourceFileCallbacks
+{
+public:
+ CollectMacrosSourceFileCallbacks();
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp
new file mode 100644
index 00000000000..011477e4bad
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "collectsymbolsaction.h"
+
+#include "collectsymbolsconsumer.h"
+
+namespace ClangBackEnd {
+
+std::unique_ptr<clang::ASTConsumer> CollectSymbolsAction::newASTConsumer()
+{
+ return std::make_unique<CollectSymbolsConsumer>(m_symbolEntries,
+ m_sourceLocationEntries,
+ m_filePathCache);
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h
new file mode 100644
index 00000000000..1ddd34b595f
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "clangrefactoringbackend_global.h"
+#include "sourcelocationentry.h"
+#include "symbolentry.h"
+
+#include <utils/smallstring.h>
+
+#include <stringcachefwd.h>
+
+#include <clang/Frontend/FrontendAction.h>
+
+#include <mutex>
+
+namespace ClangBackEnd {
+
+class CollectSymbolsAction
+{
+public:
+ CollectSymbolsAction(FilePathCache<std::mutex> &filePathCache)
+ : m_filePathCache(filePathCache)
+ {}
+
+ std::unique_ptr<clang::ASTConsumer> newASTConsumer();
+
+ SymbolEntries takeSymbols()
+ {
+ return std::move(m_symbolEntries);
+ }
+
+ const SymbolEntries &symbols() const
+ {
+ return m_symbolEntries;
+ }
+
+ const SourceLocationEntries &sourceLocations() const
+ {
+ return m_sourceLocationEntries;
+ }
+
+private:
+ SymbolEntries m_symbolEntries;
+ SourceLocationEntries m_sourceLocationEntries;
+ FilePathCache<std::mutex> &m_filePathCache;
+
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h
new file mode 100644
index 00000000000..fcedd6a6d04
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "symbolentry.h"
+#include "sourcelocationentry.h"
+
+#include <stringcache.h>
+
+#include <clang/AST/AST.h>
+#include <clang/AST/ASTContext.h>
+#include <clang/AST/RecursiveASTVisitor.h>
+#include <clang/Index/USRGeneration.h>
+#include <llvm/ADT/SmallVector.h>
+
+#include <vector>
+
+namespace ClangBackEnd {
+
+Utils::SmallStringView toStringView(clang::StringRef stringReference)
+{
+ return Utils::SmallStringView(stringReference.data(), stringReference.size());
+}
+
+class CollectSymbolsASTVisitor : public clang::RecursiveASTVisitor<CollectSymbolsASTVisitor>
+{
+public:
+ CollectSymbolsASTVisitor(SymbolEntries &symbolEntries,
+ SourceLocationEntries &sourceLocationEntries,
+ FilePathCache<std::mutex> &filePathCache,
+ const clang::SourceManager &sourceManager)
+ : m_symbolEntries(symbolEntries),
+ m_sourceLocationEntries(sourceLocationEntries),
+ m_filePathCache(filePathCache),
+ m_sourceManager(sourceManager)
+ {}
+
+ bool shouldVisitTemplateInstantiations() const
+ {
+ return true;
+ }
+
+ bool VisitNamedDecl(const clang::NamedDecl *declaration)
+ {
+ if (!declaration->getIdentifier())
+ return true;
+
+ SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl());
+ auto sourceLocation = declaration->getLocation();
+
+ auto found = m_symbolEntries.find(globalId);
+ if (found == m_symbolEntries.end()) {
+ m_symbolEntries.emplace(std::piecewise_construct,
+ std::forward_as_tuple(globalId),
+ std::forward_as_tuple(generateUSR(declaration), symbolName(declaration)));
+ }
+
+ m_sourceLocationEntries.emplace_back(globalId,
+ filePathId(sourceLocation),
+ lineColum(sourceLocation),
+ SymbolType::Declaration);
+
+ return true;
+ }
+
+ bool VisitDeclRefExpr(const clang::DeclRefExpr *expression)
+ {
+ auto declaration = expression->getFoundDecl();
+ SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl());
+ auto sourceLocation = expression->getLocation();
+
+ m_sourceLocationEntries.emplace_back(globalId,
+ filePathId(sourceLocation),
+ lineColum(sourceLocation),
+ SymbolType::DeclarationReference);
+
+ return true;
+ }
+
+ FilePathIndex filePathId(clang::SourceLocation sourceLocation)
+ {
+ uint clangFileId = m_sourceManager.getFileID(sourceLocation).getHashValue();
+
+ auto found = m_filePathIndices.find(clangFileId);
+
+ if (found != m_filePathIndices.end())
+ return found->second;
+
+ auto filePath = m_sourceManager.getFilename(sourceLocation);
+
+ FilePathIndex index = m_filePathCache.stringId(toStringView(filePath));
+
+ m_filePathIndices.emplace(clangFileId, index);
+
+ return index;
+ }
+
+ LineColumn lineColum(clang::SourceLocation sourceLocation)
+ {
+ return {m_sourceManager.getSpellingLineNumber(sourceLocation),
+ m_sourceManager.getSpellingColumnNumber(sourceLocation)};
+ }
+
+ Utils::PathString generateUSR(const clang::Decl *declaration)
+ {
+ llvm::SmallVector<char, 128> usr;
+
+ clang::index::generateUSRForDecl(declaration, usr);
+
+ return {usr.data(), usr.size()};
+ }
+
+ Utils::SmallString symbolName(const clang::NamedDecl *declaration)
+ {
+ const llvm::StringRef symbolName{declaration->getName()};
+
+ return {symbolName.data(), symbolName.size()};
+ }
+
+ static SymbolIndex toSymbolIndex(const void *pointer)
+ {
+ return SymbolIndex(reinterpret_cast<std::uintptr_t>(pointer));
+ }
+
+private:
+ SymbolEntries &m_symbolEntries;
+ std::unordered_map<uint, FilePathIndex> m_filePathIndices;
+ SourceLocationEntries &m_sourceLocationEntries;
+ FilePathCache<std::mutex> &m_filePathCache;
+ const clang::SourceManager &m_sourceManager;
+};
+
+
+} // namespace ClangBackend
+
diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h b/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h
new file mode 100644
index 00000000000..0eeb7a73f24
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "collectsymbolsastvisitor.h"
+
+#include <clang/AST/AST.h>
+#include <clang/AST/ASTConsumer.h>
+#include <clang/AST/ASTContext.h>
+
+#include <stringcachefwd.h>
+
+namespace ClangBackEnd {
+
+class CollectSymbolsConsumer : public clang::ASTConsumer
+{
+public:
+ CollectSymbolsConsumer(SymbolEntries &symbolEntries,
+ SourceLocationEntries &sourceLocationEntries,
+ FilePathCache<std::mutex> &filePathCache)
+ : m_symbolEntries(symbolEntries),
+ m_sourceLocationEntries(sourceLocationEntries),
+ m_filePathCache(filePathCache)
+ {}
+
+ void HandleTranslationUnit(clang::ASTContext &astContext) override
+ {
+ CollectSymbolsASTVisitor visitor{m_symbolEntries,
+ m_sourceLocationEntries,
+ m_filePathCache,
+ astContext.getSourceManager()};
+ visitor.TraverseDecl(astContext.getTranslationUnitDecl());
+ }
+
+ bool shouldSkipFunctionBody(clang::Decl *declation) override
+ {
+ const clang::SourceManager &sourceManager = declation->getASTContext().getSourceManager();
+ const clang::SourceLocation location = declation->getLocation();
+
+ if (sourceManager.isInSystemHeader(location))
+ return true;
+
+ return false;
+ }
+
+private:
+ SymbolEntries &m_symbolEntries;
+ SourceLocationEntries &m_sourceLocationEntries;
+ FilePathCache<std::mutex> &m_filePathCache;
+};
+}
diff --git a/src/tools/clangrefactoringbackend/source/findcursorusr.h b/src/tools/clangrefactoringbackend/source/findcursorusr.h
index 0c228c67e86..549086cd3aa 100644
--- a/src/tools/clangrefactoringbackend/source/findcursorusr.h
+++ b/src/tools/clangrefactoringbackend/source/findcursorusr.h
@@ -25,26 +25,12 @@
#pragma once
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-parameter"
-#elif defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning( disable : 4100 )
-#endif
-
#include <clang/AST/AST.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Index/USRGeneration.h>
#include <llvm/ADT/SmallVector.h>
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#elif defined(_MSC_VER)
-# pragma warning(pop)
-#endif
-
#include <vector>
namespace ClangBackEnd {
@@ -54,8 +40,8 @@ class FindNamedDeclarationASTVisitor : public clang::RecursiveASTVisitor<FindNam
public:
explicit FindNamedDeclarationASTVisitor(const clang::SourceManager &sourceManager,
const clang::SourceLocation cursorSourceLocation)
- : sourceManager(sourceManager),
- cursorSourceLocation(cursorSourceLocation)
+ : m_sourceManager(sourceManager),
+ m_cursorSourceLocation(cursorSourceLocation)
{
}
@@ -96,7 +82,7 @@ public:
std::vector<const clang::NamedDecl*> takeNamedDecl()
{
- return std::move(namedDeclarations);
+ return std::move(m_namedDeclarations);
}
private:
@@ -138,7 +124,7 @@ private:
bool isValid = isValidLocationWithCursorInside(startLocation, endLocation);
if (isValid)
- namedDeclarations.push_back(declaration);
+ m_namedDeclarations.push_back(declaration);
return !isValid;
}
@@ -153,20 +139,20 @@ private:
bool isCursorLocationBetween(const clang::SourceLocation startLocation,
const clang::SourceLocation endLocation)
{
- return cursorSourceLocation == startLocation
- || cursorSourceLocation == endLocation
- || (sourceManager.isBeforeInTranslationUnit(startLocation, cursorSourceLocation)
- && sourceManager.isBeforeInTranslationUnit(cursorSourceLocation, endLocation));
+ return m_cursorSourceLocation == startLocation
+ || m_cursorSourceLocation == endLocation
+ || (m_sourceManager.isBeforeInTranslationUnit(startLocation, m_cursorSourceLocation)
+ && m_sourceManager.isBeforeInTranslationUnit(m_cursorSourceLocation, endLocation));
}
- std::vector<const clang::NamedDecl*> namedDeclarations;
- const clang::SourceManager &sourceManager;
- const clang::SourceLocation cursorSourceLocation;
+ std::vector<const clang::NamedDecl*> m_namedDeclarations;
+ const clang::SourceManager &m_sourceManager;
+ const clang::SourceLocation m_cursorSourceLocation;
};
inline
std::vector<const clang::NamedDecl *> namedDeclarationsAt(const clang::ASTContext &Context,
- const clang::SourceLocation cursorSourceLocation)
+ const clang::SourceLocation cursorSourceLocation)
{
const auto &sourceManager = Context.getSourceManager();
const auto currentFile = sourceManager.getFilename(cursorSourceLocation);
diff --git a/src/tools/clangrefactoringbackend/source/findusrforcursoraction.cpp b/src/tools/clangrefactoringbackend/source/findusrforcursoraction.cpp
index 50f7230586c..6fa964f5318 100644
--- a/src/tools/clangrefactoringbackend/source/findusrforcursoraction.cpp
+++ b/src/tools/clangrefactoringbackend/source/findusrforcursoraction.cpp
@@ -27,24 +27,10 @@
#include "findcursorusr.h"
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-parameter"
-#elif defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning( disable : 4100 )
-#endif
-
#include <clang/AST/AST.h>
#include <clang/AST/ASTConsumer.h>
#include <clang/AST/ASTContext.h>
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#elif defined(_MSC_VER)
-# pragma warning(pop)
-#endif
-
#include <algorithm>
#include <vector>
@@ -54,16 +40,16 @@ namespace {
std::vector<USRName> collectConstructorUnifiedSymbolResolutions(const clang::CXXRecordDecl *declarations)
{
- std::vector<USRName> unifiedSymbolResolutions;
+ std::vector<USRName> unifiedSymbolResolutions;
- const auto constructorDeclarations = declarations->getDefinition()->ctors();
+ const auto constructorDeclarations = declarations->getDefinition()->ctors();
- std::transform(constructorDeclarations.begin(),
- constructorDeclarations.end(),
- std::back_inserter(unifiedSymbolResolutions),
- USROfDeclaration);
+ std::transform(constructorDeclarations.begin(),
+ constructorDeclarations.end(),
+ std::back_inserter(unifiedSymbolResolutions),
+ USROfDeclaration);
- return unifiedSymbolResolutions;
+ return unifiedSymbolResolutions;
}
void addUnifiedSymbolResolutionsForDeclaration(const std::vector<const clang::NamedDecl *> &declarations,
@@ -87,18 +73,18 @@ public:
std::vector<USRName> &unifiedSymbolResolutions,
uint line,
uint column)
- : symbolName(symbolName),
- unifiedSymbolResolutions(unifiedSymbolResolutions),
- line(line),
- column(column)
+ : m_symbolName(symbolName),
+ m_unifiedSymbolResolutions(unifiedSymbolResolutions),
+ m_line(line),
+ m_column(column)
{
}
void HandleTranslationUnit(clang::ASTContext &astContext) override {
const auto &sourceManager = astContext.getSourceManager();
const auto cursorSourceLocation = sourceManager.translateLineCol(sourceManager.getMainFileID(),
- line,
- column);
+ m_line,
+ m_column);
if (cursorSourceLocation.isValid())
collectUnifiedSymbolResoltions(astContext, cursorSourceLocation);
@@ -114,32 +100,29 @@ public:
if (const auto *constructorDecl = clang::dyn_cast<clang::CXXConstructorDecl>(firstFoundDeclaration)) {
const clang::CXXRecordDecl *foundDeclarationParent = constructorDecl->getParent();
- unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent);
+ m_unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent);
} else if (const auto *destructorDecl = clang::dyn_cast<clang::CXXDestructorDecl>(firstFoundDeclaration)) {
const clang::CXXRecordDecl *foundDeclarationParent = destructorDecl->getParent();
- unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent);
+ m_unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent);
} else if (const auto *recordDeclaration = clang::dyn_cast<clang::CXXRecordDecl>(firstFoundDeclaration)) {
- unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(recordDeclaration);
+ m_unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(recordDeclaration);
}
- addUnifiedSymbolResolutionsForDeclaration(foundDeclarations, unifiedSymbolResolutions);
- symbolName = firstFoundDeclaration->getNameAsString();
+ addUnifiedSymbolResolutionsForDeclaration(foundDeclarations, m_unifiedSymbolResolutions);
+ m_symbolName = firstFoundDeclaration->getNameAsString();
}
}
private:
- Utils::SmallString &symbolName;
- std::vector<USRName> &unifiedSymbolResolutions;
- uint line;
- uint column;
+ Utils::SmallString &m_symbolName;
+ std::vector<USRName> &m_unifiedSymbolResolutions;
+ uint m_line;
+ uint m_column;
};
std::unique_ptr<clang::ASTConsumer>
USRFindingAction::newASTConsumer() {
- std::unique_ptr<FindDeclarationsConsumer> Consumer(
- new FindDeclarationsConsumer(symbolName, unifiedSymbolResolutions_, line, column));
-
- return std::move(Consumer);
+ return std::make_unique<FindDeclarationsConsumer>(m_symbolName, m_unifiedSymbolResolutions, m_line, m_column);
}
} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/findusrforcursoraction.h b/src/tools/clangrefactoringbackend/source/findusrforcursoraction.h
index 65ec394e7d0..bfa4a373a4a 100644
--- a/src/tools/clangrefactoringbackend/source/findusrforcursoraction.h
+++ b/src/tools/clangrefactoringbackend/source/findusrforcursoraction.h
@@ -29,21 +29,7 @@
#include <utils/smallstring.h>
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-parameter"
-#elif defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning( disable : 4100 )
-#endif
-
-#include "clang/Frontend/FrontendAction.h"
-
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#elif defined(_MSC_VER)
-# pragma warning(pop)
-#endif
+#include <clang/Frontend/FrontendAction.h>
namespace clang {
class ASTConsumer;
@@ -57,8 +43,8 @@ class USRFindingAction
{
public:
USRFindingAction(uint line, uint column)
- : line(line),
- column(column)
+ : m_line(line),
+ m_column(column)
{
}
@@ -66,19 +52,19 @@ public:
std::string takeSymbolName()
{
- return std::move(symbolName);
+ return std::string(m_symbolName);
}
std::vector<USRName> takeUnifiedSymbolResolutions()
{
- return std::move(unifiedSymbolResolutions_);
+ return std::move(m_unifiedSymbolResolutions);
}
private:
- Utils::SmallString symbolName;
- std::vector<USRName> unifiedSymbolResolutions_;
- uint line;
- uint column;
+ Utils::SmallString m_symbolName;
+ std::vector<USRName> m_unifiedSymbolResolutions;
+ uint m_line;
+ uint m_column;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h b/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h
index fe23e3e5a5a..cb9560ae7d8 100644
--- a/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h
+++ b/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h
@@ -27,22 +27,8 @@
#include <sourcelocationscontainer.h>
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-parameter"
-#elif defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning( disable : 4100 )
-#endif
-
#include <clang/Tooling/Tooling.h>
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#elif defined(_MSC_VER)
-# pragma warning(pop)
-#endif
-
namespace llvm {
class StringRef;
}
diff --git a/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.h b/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.h
index bac6465c8e4..d25407438b7 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.h
+++ b/src/tools/clangrefactoringbackend/source/refactoringcompilationdatabase.h
@@ -54,8 +54,8 @@ public:
std::vector<clang::tooling::CompileCommand> getAllCompileCommands() const override;
void addFile(const std::string &directory,
- const std::string &fileName,
- const std::vector<std::string> &commandLine);
+ const std::string &fileName,
+ const std::vector<std::string> &commandLine);
private:
std::vector<clang::tooling::CompileCommand> compileCommands;
diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
index ff4f06babe5..84b588118e6 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
+++ b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
@@ -27,6 +27,7 @@
#include "symbolfinder.h"
#include "clangquery.h"
+#include "symbolindexing.h"
#include <refactoringclientinterface.h>
#include <clangrefactoringmessages.h>
@@ -38,7 +39,10 @@
namespace ClangBackEnd {
-RefactoringServer::RefactoringServer()
+RefactoringServer::RefactoringServer(SymbolIndexingInterface &symbolIndexing,
+ FilePathCache<std::mutex> &filePathCache)
+ : m_symbolIndexing(symbolIndexing),
+ m_filePathCache(filePathCache)
{
m_pollTimer.setInterval(100);
@@ -56,10 +60,10 @@ void RefactoringServer::requestSourceLocationsForRenamingMessage(RequestSourceLo
{
SymbolFinder symbolFinder(message.line(), message.column());
- symbolFinder.addFile(message.filePath().directory(),
- message.filePath().name(),
- message.unsavedContent(),
- message.commandLine());
+ symbolFinder.addFile(std::string(message.filePath().directory()),
+ std::string(message.filePath().name()),
+ std::string(message.unsavedContent()),
+ std::vector<std::string>(message.commandLine()));
symbolFinder.findSymbol();
@@ -73,10 +77,10 @@ void RefactoringServer::requestSourceRangesAndDiagnosticsForQueryMessage(
{
ClangQuery clangQuery(m_filePathCache, message.takeQuery());
- clangQuery.addFile(message.source().filePath().directory(),
- message.source().filePath().name(),
- message.source().unsavedFileContent(),
- message.source().commandLineArguments());
+ clangQuery.addFile(std::string(message.source().filePath().directory()),
+ std::string(message.source().filePath().name()),
+ std::string(message.source().unsavedFileContent()),
+ std::vector<std::string>(message.source().commandLineArguments()));
clangQuery.findLocations();
@@ -88,7 +92,17 @@ void RefactoringServer::requestSourceRangesForQueryMessage(RequestSourceRangesFo
{
gatherSourceRangesForQueryMessages(message.takeSources(),
message.takeUnsavedContent(),
- message.takeQuery());
+ message.takeQuery());
+}
+
+void RefactoringServer::updatePchProjectParts(UpdatePchProjectPartsMessage &&message)
+{
+ m_symbolIndexing.updateProjectParts(message.takeProjectsParts(), message.takeGeneratedFiles());
+}
+
+void RefactoringServer::removePchProjectParts(RemovePchProjectPartsMessage &&)
+{
+
}
void RefactoringServer::cancel()
diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.h b/src/tools/clangrefactoringbackend/source/refactoringserver.h
index 94eeb3dcc6c..b11cf3fc215 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringserver.h
+++ b/src/tools/clangrefactoringbackend/source/refactoringserver.h
@@ -30,6 +30,7 @@
#include <refactoringserverinterface.h>
#include <QTimer>
+#include <ipcclientprovider.h>
#include <stringcache.h>
#include <utils/smallstring.h>
@@ -41,21 +42,26 @@
namespace ClangBackEnd {
class SourceRangesForQueryMessage;
+class SymbolIndexingInterface;
namespace V2 {
class FileContainer;
}
-class RefactoringServer : public RefactoringServerInterface
+class RefactoringServer : public RefactoringServerInterface,
+ public IpcClientProvider<RefactoringClientInterface>
{
using Future = std::future<SourceRangesForQueryMessage>;
public:
- RefactoringServer();
+ RefactoringServer(SymbolIndexingInterface &symbolIndexing,
+ FilePathCache<std::mutex> &filePathCache);
void end() override;
void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override;
void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override;
void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override;
+ void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) override;
+ void removePchProjectParts(RemovePchProjectPartsMessage &&message) override;
void cancel() override;
bool isCancelingJobs() const;
@@ -73,9 +79,10 @@ private:
Utils::SmallString &&query);
private:
- StringCache<Utils::PathString, std::mutex> m_filePathCache;
ClangQueryGatherer m_gatherer;
QTimer m_pollTimer;
+ SymbolIndexingInterface &m_symbolIndexing;
+ FilePathCache<std::mutex> &m_filePathCache;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/sourcelocationentry.cpp b/src/tools/clangrefactoringbackend/source/sourcelocationentry.cpp
new file mode 100644
index 00000000000..9cea242fa87
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/sourcelocationentry.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "sourcelocationentry.h"
+
+#include <utils/smallstringio.h>
+
+namespace ClangBackEnd {
+
+std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry)
+{
+ out << "("
+ << entry.fileId << ", "
+ << entry.line << ", "
+ << entry.column << ")";
+
+ return out;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/sourcelocationentry.h b/src/tools/clangrefactoringbackend/source/sourcelocationentry.h
new file mode 100644
index 00000000000..dbe70123883
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/sourcelocationentry.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <stringcachefwd.h>
+
+#include <limits>
+#include <vector>
+#include <iosfwd>
+
+using uint = unsigned int;
+
+namespace ClangBackEnd {
+
+enum class SymbolType
+{
+ Declaration,
+ DeclarationReference
+};
+
+class LineColumn
+{
+public:
+ LineColumn(uint line, uint column)
+ : line(line),
+ column(column)
+ {}
+
+ uint line = 0;
+ uint column = 0;
+};
+
+using SymbolIndex = long long;
+
+class SourceLocationEntry
+{
+public:
+ SourceLocationEntry(SymbolIndex symbolId,
+ FilePathIndex fileId,
+ LineColumn lineColumn,
+ SymbolType symbolType)
+ : symbolId(symbolId),
+ fileId(fileId),
+ line(lineColumn.line),
+ column(lineColumn.column),
+ symbolType(symbolType)
+ {}
+
+ SymbolIndex symbolId = 0;
+ FilePathIndex fileId = std::numeric_limits<uint>::max();
+ uint line = 0;
+ uint column = 0;
+ SymbolType symbolType;
+
+ friend bool operator==(const SourceLocationEntry &first, const SourceLocationEntry &second)
+ {
+ return first.symbolId == second.symbolId
+ && first.fileId == second.fileId
+ && first.line == second.line
+ && first.column == second.column
+ && first.symbolType == second.symbolType;
+ }
+};
+
+using SourceLocationEntries = std::vector<SourceLocationEntry>;
+
+std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry);
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp
index 9788d656830..399a7353f3e 100644
--- a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp
+++ b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp
@@ -54,7 +54,7 @@ namespace ClangBackEnd {
SourceRangeExtractor::SourceRangeExtractor(
const clang::SourceManager &sourceManager,
const clang::LangOptions &languageOptions,
- ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache,
+ ClangBackEnd::FilePathCache<std::mutex> &filePathCache,
SourceRangesContainer &sourceRangesContainer)
: sourceManager(sourceManager),
languageOptions(languageOptions),
@@ -146,7 +146,7 @@ void SourceRangeExtractor::insertSourceRange(uint fileId,
std::move(lineSnippet));
}
-uint SourceRangeExtractor::findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const
+FilePathIndex SourceRangeExtractor::findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const
{
auto found = m_fileIdMapping.find(fileId.getHashValue());
if (found != m_fileIdMapping.end()) {
diff --git a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h
index 7a07e5c3f87..30646429747 100644
--- a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h
+++ b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h
@@ -59,7 +59,7 @@ class SourceRangeExtractor
public:
SourceRangeExtractor(const clang::SourceManager &sourceManager,
const clang::LangOptions &languageOptions,
- ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache,
+ ClangBackEnd::FilePathCache<std::mutex> &filePathCache,
SourceRangesContainer &sourceRangesContainer);
void addSourceRange(const clang::SourceRange &sourceRange);
@@ -82,13 +82,13 @@ private:
uint endOffset,
Utils::SmallString &&lineSnippet);
- uint findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const;
+ FilePathIndex findFileId(clang::FileID fileId, const clang::FileEntry *fileEntry) const;
private:
mutable std::unordered_map<uint, uint> m_fileIdMapping;
const clang::SourceManager &sourceManager;
const clang::LangOptions &languageOptions;
- ClangBackEnd::StringCache<Utils::PathString, std::mutex> &filePathCache;
+ ClangBackEnd::FilePathCache<std::mutex> &filePathCache;
SourceRangesContainer &sourceRangesContainer;
};
diff --git a/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h b/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h
new file mode 100644
index 00000000000..c144c7a9c51
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <createtablesqlstatementbuilder.h>
+
+#include <sqlitetransaction.h>
+#include <sqlitetable.h>
+
+namespace ClangBackEnd {
+
+template<typename Database,
+ typename ReadStatement,
+ typename WriteStatement>
+class StorageSqliteStatementFactory
+{
+public:
+ using DatabaseType = Database;
+ using ReadStatementType = ReadStatement;
+ using WriteStatementType = WriteStatement;
+
+ StorageSqliteStatementFactory(Database &database)
+ : database(database)
+ {
+ }
+
+ Sqlite::Table createNewSymbolsTable() const
+ {
+ Sqlite::Table table;
+ table.setName("newSymbols");
+ table.setUseTemporaryTable(true);
+ table.addColumn("temporarySymbolId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
+ const Sqlite::Column &symbolIdColumn = table.addColumn("symbolId", Sqlite::ColumnType::Integer);
+ const Sqlite::Column &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
+ const Sqlite::Column &symbolNameColumn = table.addColumn("symbolName", Sqlite::ColumnType::Text);
+ table.addIndex({usrColumn, symbolNameColumn});
+ table.addIndex({symbolIdColumn});
+
+ Sqlite::ImmediateTransaction<DatabaseType> transaction(database);
+ table.initialize(database);
+ transaction.commit();
+
+ return table;
+ }
+
+ Sqlite::Table createNewLocationsTable() const
+ {
+ Sqlite::Table table;
+ table.setName("newLocations");
+ table.setUseTemporaryTable(true);
+ table.addColumn("temporarySymbolId", Sqlite::ColumnType::Integer);
+ table.addColumn("symbolId", Sqlite::ColumnType::Integer);
+ table.addColumn("line", Sqlite::ColumnType::Integer);
+ table.addColumn("column", Sqlite::ColumnType::Integer);
+ const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
+ table.addIndex({sourceIdColumn});
+
+ Sqlite::ImmediateTransaction<DatabaseType> transaction(database);
+ table.initialize(database);
+ transaction.commit();
+
+ return table;
+ }
+
+public:
+ Database &database;
+ Sqlite::Table newSymbolsTablet{createNewSymbolsTable()};
+ Sqlite::Table newLocationsTable{createNewLocationsTable()};
+ WriteStatement insertSymbolsToNewSymbolsStatement{
+ "INSERT INTO newSymbols(temporarySymbolId, usr, symbolName) VALUES(?,?,?)",
+ database};
+ WriteStatement insertLocationsToNewLocationsStatement{
+ "INSERT INTO newLocations(temporarySymbolId, line, column, sourceId) VALUES(?,?,?,?)",
+ database
+ };
+// WriteStatement syncNewLocationsToLocationsStatement{
+// "INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations",
+// database};
+ ReadStatement selectNewSourceIdsStatement{
+ "SELECT DISTINCT sourceId FROM newLocations WHERE NOT EXISTS (SELECT sourceId FROM sources WHERE newLocations.sourceId == sources.sourceId)",
+ database
+ };
+ WriteStatement addNewSymbolsToSymbolsStatement{
+ "INSERT INTO symbols(usr, symbolName) "
+ "SELECT usr, symbolName FROM newSymbols WHERE NOT EXISTS "
+ "(SELECT usr FROM symbols WHERE symbols.usr == newSymbols.usr)",
+ database
+ };
+ WriteStatement insertSourcesStatement{
+ "INSERT INTO sources(sourceId, sourcePath) VALUES(?,?)",
+ database
+ };
+ WriteStatement syncNewSymbolsFromSymbolsStatement{
+ "UPDATE newSymbols SET symbolId = (SELECT symbolId FROM symbols WHERE newSymbols.usr = symbols.usr)",
+ database
+ };
+ WriteStatement syncSymbolsIntoNewLocationsStatement{
+ "UPDATE newLocations SET symbolId = (SELECT symbolId FROM newSymbols WHERE newSymbols.temporarySymbolId = newLocations.temporarySymbolId)",
+ database
+ };
+ WriteStatement deleteAllLocationsFromUpdatedFilesStatement{
+ "DELETE FROM locations WHERE sourceId IN (SELECT DISTINCT sourceId FROM newLocations)",
+ database
+ };
+ WriteStatement insertNewLocationsInLocationsStatement{
+ "INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations",
+ database
+ };
+ WriteStatement deleteNewSymbolsTableStatement{
+ "DELETE FROM newSymbols",
+ database
+ };
+ WriteStatement deleteNewLocationsTableStatement{
+ "DELETE FROM newLocations",
+ database
+ };
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolentry.cpp b/src/tools/clangrefactoringbackend/source/symbolentry.cpp
new file mode 100644
index 00000000000..ee606cf9ab8
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolentry.cpp
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "symbolentry.h"
+
+#include <utils/smallstringio.h>
+
+namespace ClangBackEnd {
+
+std::ostream &operator<<(std::ostream &out, const SymbolEntry &entry)
+{
+ out << "("
+ << entry.symbolName << ", "
+ << entry.usr <<")";
+
+ return out;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolentry.h b/src/tools/clangrefactoringbackend/source/symbolentry.h
new file mode 100644
index 00000000000..7312f45bd68
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolentry.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <stringcachefwd.h>
+
+#include <utils/smallstring.h>
+
+#include <limits>
+#include <unordered_map>
+#include <iosfwd>
+
+namespace ClangBackEnd {
+
+using SymbolIndex = long long;
+
+class SymbolEntry
+{
+public:
+ SymbolEntry(Utils::PathString &&usr,
+ Utils::SmallString &&symbolName)
+ : usr(std::move(usr)),
+ symbolName(std::move(symbolName))
+ {}
+
+ Utils::PathString usr;
+ Utils::SmallString symbolName;
+
+ friend bool operator==(const SymbolEntry &first, const SymbolEntry &second)
+ {
+ return first.usr == second.usr && first.symbolName == second.symbolName;
+ }
+};
+
+using SymbolEntries = std::unordered_map<SymbolIndex, SymbolEntry>;
+
+std::ostream &operator<<(std::ostream &out, const SymbolEntry &entry);
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolfinder.h b/src/tools/clangrefactoringbackend/source/symbolfinder.h
index 42c7098f1e2..a76639aa26a 100644
--- a/src/tools/clangrefactoringbackend/source/symbolfinder.h
+++ b/src/tools/clangrefactoringbackend/source/symbolfinder.h
@@ -32,22 +32,6 @@
#include <sourcelocationscontainer.h>
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-parameter"
-#elif defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning( disable : 4100 )
-#endif
-
-#include "clang/Tooling/Refactoring.h"
-
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#elif defined(_MSC_VER)
-# pragma warning(pop)
-#endif
-
namespace ClangBackEnd {
class SymbolFinder : public ClangTool
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
new file mode 100644
index 00000000000..ed48d920a6f
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "symbolindexer.h"
+
+namespace ClangBackEnd {
+
+SymbolIndexer::SymbolIndexer(SymbolsCollectorInterface &symbolsCollector, SymbolStorageInterface &symbolStorage)
+ : m_symbolsCollector(symbolsCollector),
+ m_symbolStorage(symbolStorage)
+{
+}
+
+void SymbolIndexer::updateProjectParts(V2::ProjectPartContainers &&projectParts,
+ V2::FileContainers &&generatedFiles)
+{
+ for (const V2::ProjectPartContainer &projectPart : projectParts)
+ m_symbolsCollector.addFiles(projectPart.sourcePaths(), projectPart.arguments());
+
+ m_symbolsCollector.addUnsavedFiles(generatedFiles);
+
+ m_symbolsCollector.collectSymbols();
+
+ m_symbolStorage.addSymbolsAndSourceLocations(m_symbolsCollector.symbols(),
+ m_symbolsCollector.sourceLocations());
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.h b/src/tools/clangrefactoringbackend/source/symbolindexer.h
new file mode 100644
index 00000000000..283e761da58
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "symbolscollectorinterface.h"
+#include "symbolstorageinterface.h"
+
+#include <projectpartcontainerv2.h>
+#include <filecontainerv2.h>
+
+namespace ClangBackEnd {
+
+class SymbolIndexer
+{
+public:
+ SymbolIndexer(SymbolsCollectorInterface &symbolsCollector,
+ SymbolStorageInterface &symbolStorage);
+
+ void updateProjectParts(V2::ProjectPartContainers &&projectParts,
+ V2::FileContainers &&generatedFiles);
+
+private:
+ SymbolsCollectorInterface &m_symbolsCollector;
+ SymbolStorageInterface &m_symbolStorage;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.cpp b/src/tools/clangrefactoringbackend/source/symbolindexing.cpp
new file mode 100644
index 00000000000..11e34e449fe
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolindexing.cpp
@@ -0,0 +1,30 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "symbolindexing.h"
+
+namespace ClangBackEnd {
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h
new file mode 100644
index 00000000000..4dd173e1bfb
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "symbolindexinginterface.h"
+
+#include "storagesqlitestatementfactory.h"
+#include "symbolindexer.h"
+#include "symbolscollector.h"
+#include "symbolstorage.h"
+
+#include <refactoringdatabaseinitializer.h>
+#include <stringcache.h>
+
+#include <sqlitedatabase.h>
+#include <sqlitereadstatement.h>
+#include <sqlitewritestatement.h>
+
+namespace ClangBackEnd {
+
+class SymbolIndexing final : public SymbolIndexingInterface
+{
+public:
+ using StatementFactory = ClangBackEnd::StorageSqliteStatementFactory<Sqlite::Database,
+ Sqlite::ReadStatement,
+ Sqlite::WriteStatement>;
+ using Storage = ClangBackEnd::SymbolStorage<StatementFactory>;
+ using DatabaseInitializer = RefactoringDatabaseInitializer<Sqlite::Database>;
+
+ SymbolIndexing(FilePathCache<std::mutex> &filePathCache,
+ Utils::PathString &&databaseFilePath)
+ : m_filePathCache(filePathCache),
+ m_database(std::move(databaseFilePath)),
+ m_databaseInitializer(m_database)
+ {
+ }
+
+ SymbolIndexer &indexer()
+ {
+ return m_indexer;
+ }
+
+ Sqlite::Database &database()
+ {
+ return m_database;
+ }
+
+ void updateProjectParts(V2::ProjectPartContainers &&projectParts,
+ V2::FileContainers &&generatedFiles)
+ {
+ m_indexer.updateProjectParts(std::move(projectParts), std::move(generatedFiles));
+ }
+
+private:
+ FilePathCache<std::mutex> &m_filePathCache;
+ Sqlite::Database m_database;
+ DatabaseInitializer m_databaseInitializer;
+ SymbolsCollector m_collector{m_filePathCache};
+ StatementFactory m_statementFactory{m_database};
+ Storage m_symbolStorage{m_statementFactory, m_filePathCache};
+ SymbolIndexer m_indexer{m_collector, m_symbolStorage};
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h b/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h
new file mode 100644
index 00000000000..8c331aadce7
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectpartcontainerv2.h>
+#include <filecontainerv2.h>
+
+namespace ClangBackEnd {
+
+class SymbolIndexingInterface
+{
+public:
+ virtual void updateProjectParts(V2::ProjectPartContainers &&projectParts,
+ V2::FileContainers &&generatedFiles) = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp b/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp
index c5aba6ca905..2b07e893f58 100644
--- a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.cpp
@@ -39,7 +39,7 @@ class FindingSymbolsASTConsumer : public clang::ASTConsumer
{
public:
FindingSymbolsASTConsumer(std::vector<USRName> &unifiedSymbolResolutions)
- : unifiedSymbolResolutions(unifiedSymbolResolutions)
+ : m_unifiedSymbolResolutions(unifiedSymbolResolutions)
{
}
@@ -48,7 +48,7 @@ public:
std::vector<clang::SourceLocation> sourceLocations;
- auto &&sourceLocationsOfUsr = takeLocationsOfUSRs(unifiedSymbolResolutions, context.getTranslationUnitDecl());
+ auto &&sourceLocationsOfUsr = takeLocationsOfUSRs(m_unifiedSymbolResolutions, context.getTranslationUnitDecl());
sourceLocations.insert(sourceLocations.end(),
sourceLocationsOfUsr.begin(),
sourceLocationsOfUsr.end());
@@ -65,24 +65,24 @@ public:
void updateSourceLocations(const std::vector<clang::SourceLocation> &sourceLocations,
const clang::SourceManager &sourceManager)
{
- appendSourceLocationsToSourceLocationsContainer(*sourceLocationsContainer, sourceLocations, sourceManager);
+ appendSourceLocationsToSourceLocationsContainer(*m_sourceLocationsContainer, sourceLocations, sourceManager);
}
void setSourceLocations(ClangBackEnd::SourceLocationsContainer *sourceLocations)
{
- sourceLocationsContainer = sourceLocations;
+ m_sourceLocationsContainer = sourceLocations;
}
private:
- ClangBackEnd::SourceLocationsContainer *sourceLocationsContainer = nullptr;
- std::vector<USRName> &unifiedSymbolResolutions;
+ ClangBackEnd::SourceLocationsContainer *m_sourceLocationsContainer = nullptr;
+ std::vector<USRName> &m_unifiedSymbolResolutions;
};
std::unique_ptr<clang::ASTConsumer> SymbolLocationFinderAction::newASTConsumer()
{
- auto consumer = std::unique_ptr<FindingSymbolsASTConsumer>(new FindingSymbolsASTConsumer(unifiedSymbolResolutions_));
+ auto consumer = std::unique_ptr<FindingSymbolsASTConsumer>(new FindingSymbolsASTConsumer(m_unifiedSymbolResolutions_));
- consumer->setSourceLocations(&sourceLocations);
+ consumer->setSourceLocations(&m_sourceLocations);
return std::move(consumer);
}
diff --git a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h b/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h
index 7bee18f94bb..ae601d8219e 100644
--- a/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h
+++ b/src/tools/clangrefactoringbackend/source/symbollocationfinderaction.h
@@ -29,22 +29,8 @@
#include <sourcelocationscontainer.h>
-#if defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-parameter"
-#elif defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning( disable : 4100 )
-#endif
-
#include <clang/Tooling/Refactoring.h>
-#if defined(__GNUC__)
-# pragma GCC diagnostic pop
-#elif defined(_MSC_VER)
-# pragma warning(pop)
-#endif
-
namespace clang {
class ASTConsumer;
}
@@ -59,22 +45,22 @@ public:
SourceLocationsContainer takeSourceLocations()
{
- return std::move(sourceLocations);
+ return std::move(m_sourceLocations);
}
void setUnifiedSymbolResolutions(std::vector<USRName> &&unifiedSymbolResolutions)
{
- unifiedSymbolResolutions_ = std::move(unifiedSymbolResolutions);
+ m_unifiedSymbolResolutions_ = std::move(unifiedSymbolResolutions);
}
const std::vector<USRName> &unifiedSymbolResolutions() const
{
- return unifiedSymbolResolutions_;
+ return m_unifiedSymbolResolutions_;
}
private:
- ClangBackEnd::SourceLocationsContainer sourceLocations;
- std::vector<USRName> unifiedSymbolResolutions_;
+ ClangBackEnd::SourceLocationsContainer m_sourceLocations;
+ std::vector<USRName> m_unifiedSymbolResolutions_;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
new file mode 100644
index 00000000000..c759232a04b
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "symbolscollector.h"
+
+namespace ClangBackEnd {
+
+SymbolsCollector::SymbolsCollector(FilePathCache<std::mutex> &filePathCache)
+ : m_collectSymbolsAction(filePathCache)
+{
+}
+
+void SymbolsCollector::addFiles(const Utils::PathStringVector &filePaths, const Utils::SmallStringVector &arguments)
+{
+ ClangTool::addFiles(filePaths, arguments);
+}
+
+void SymbolsCollector::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
+{
+ ClangTool::addUnsavedFiles(unsavedFiles);
+}
+
+void SymbolsCollector::collectSymbols()
+{
+ auto tool = createTool();
+
+ tool.run(clang::tooling::newFrontendActionFactory(&m_collectSymbolsAction,
+ &m_collectMacrosSourceFileCallbacks).get());
+}
+
+const SymbolEntries &SymbolsCollector::symbols() const
+{
+ return m_collectSymbolsAction.symbols();
+}
+
+const SourceLocationEntries &SymbolsCollector::sourceLocations() const
+{
+ return m_collectSymbolsAction.sourceLocations();
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.h b/src/tools/clangrefactoringbackend/source/symbolscollector.h
new file mode 100644
index 00000000000..6bbdfbcf9e5
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "clangtool.h"
+#include "collectmacrossourcefilecallbacks.h"
+#include "collectsymbolsaction.h"
+#include "symbolscollectorinterface.h"
+#include "symbolentry.h"
+#include "stringcache.h"
+
+namespace ClangBackEnd {
+
+class SymbolsCollector : public ClangTool, public SymbolsCollectorInterface
+{
+public:
+ SymbolsCollector(FilePathCache<std::mutex> &filePathCache);
+
+ void addFiles(const Utils::PathStringVector &filePaths,
+ const Utils::SmallStringVector &arguments) override;
+
+ void addUnsavedFiles(const V2::FileContainers &unsavedFiles) override;
+
+ void collectSymbols() override;
+
+ const SymbolEntries &symbols() const override;
+ const SourceLocationEntries &sourceLocations() const override;
+
+private:
+ CollectSymbolsAction m_collectSymbolsAction;
+ CollectMacrosSourceFileCallbacks m_collectMacrosSourceFileCallbacks;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
new file mode 100644
index 00000000000..fcb909bdc8f
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "symbolentry.h"
+#include "sourcelocationentry.h"
+
+#include <filecontainerv2.h>
+
+#include <utils/smallstringvector.h>
+
+#include <string>
+#include <vector>
+
+namespace ClangBackEnd {
+
+class SymbolsCollectorInterface
+{
+public:
+ virtual void addFiles(const Utils::PathStringVector &filePaths,
+ const Utils::SmallStringVector &arguments) = 0;
+
+ virtual void addUnsavedFiles(const V2::FileContainers &unsavedFiles) = 0;
+
+ virtual void collectSymbols() = 0;
+
+ virtual const SymbolEntries &symbols() const = 0;
+ virtual const SourceLocationEntries &sourceLocations() const = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.cpp b/src/tools/clangrefactoringbackend/source/symbolstorage.cpp
new file mode 100644
index 00000000000..793f06f882b
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolstorage.cpp
@@ -0,0 +1,30 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "symbolstorage.h"
+
+namespace ClangBackEnd {
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.h b/src/tools/clangrefactoringbackend/source/symbolstorage.h
new file mode 100644
index 00000000000..835f7dec923
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolstorage.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "symbolstorageinterface.h"
+
+#include <sqliteexception.h>
+#include <sqlitetransaction.h>
+#include <stringcache.h>
+
+#include <mutex>
+
+namespace ClangBackEnd {
+
+template <typename StatementFactory>
+class SymbolStorage : public SymbolStorageInterface
+{
+ using Transaction = Sqlite::ImmediateTransaction<typename StatementFactory::DatabaseType>;
+ using ReadStatement = typename StatementFactory::ReadStatementType;
+ using WriteStatement = typename StatementFactory::WriteStatementType;
+ using Database = typename StatementFactory::DatabaseType;
+
+public:
+ SymbolStorage(StatementFactory &statementFactory,
+ FilePathCache<std::mutex> &filePathCache)
+ : m_statementFactory(statementFactory),
+ m_filePathCache(filePathCache)
+ {
+ }
+
+ void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries,
+ const SourceLocationEntries &sourceLocations) override
+ {
+ Transaction transaction{m_statementFactory.database};
+
+ fillTemporarySymbolsTable(symbolEntries);
+ fillTemporaryLocationsTable(sourceLocations);
+ addNewSymbolsToSymbols();
+ syncNewSymbolsFromSymbols();
+ syncSymbolsIntoNewLocations();
+ insertNewSources();
+ deleteAllLocationsFromUpdatedFiles();
+ insertNewLocationsInLocations();
+ deleteNewSymbolsTable();
+ deleteNewLocationsTable();
+
+ transaction.commit();
+ }
+
+ void fillTemporarySymbolsTable(const SymbolEntries &symbolEntries)
+ {
+ WriteStatement &statement = m_statementFactory.insertSymbolsToNewSymbolsStatement;
+
+ for (const auto &symbolEntry : symbolEntries) {
+ statement.write(symbolEntry.first,
+ symbolEntry.second.usr,
+ symbolEntry.second.symbolName);
+ }
+ }
+
+ void fillTemporaryLocationsTable(const SourceLocationEntries &sourceLocations)
+ {
+ WriteStatement &statement = m_statementFactory.insertLocationsToNewLocationsStatement;
+
+ for (const auto &locationsEntry : sourceLocations) {
+ statement.write(locationsEntry.symbolId,
+ locationsEntry.line,
+ locationsEntry.column,
+ locationsEntry.fileId);
+ }
+ }
+
+ void addNewSymbolsToSymbols()
+ {
+ m_statementFactory.addNewSymbolsToSymbolsStatement.execute();
+ }
+
+ void syncNewSymbolsFromSymbols()
+ {
+ m_statementFactory.syncNewSymbolsFromSymbolsStatement.execute();
+ }
+
+ void syncSymbolsIntoNewLocations()
+ {
+ m_statementFactory.syncSymbolsIntoNewLocationsStatement.execute();
+ }
+
+ void deleteAllLocationsFromUpdatedFiles()
+ {
+ m_statementFactory.deleteAllLocationsFromUpdatedFilesStatement.execute();
+ }
+
+ void insertNewLocationsInLocations()
+ {
+ m_statementFactory.insertNewLocationsInLocationsStatement.execute();
+ }
+
+ FilePathIndices selectNewSourceIds() const
+ {
+ ReadStatement &statement = m_statementFactory.selectNewSourceIdsStatement;
+
+ return statement.template values<FilePathIndex>(16);
+ }
+
+ void insertNewSources()
+ {
+ WriteStatement &statement = m_statementFactory.insertSourcesStatement;
+
+ FilePathIndices newSourceIds = selectNewSourceIds();
+
+ for (FilePathIndex sourceId : newSourceIds)
+ statement.write(sourceId, m_filePathCache.string(sourceId));
+ }
+
+ void deleteNewSymbolsTable()
+ {
+ m_statementFactory.deleteNewSymbolsTableStatement.execute();
+ }
+
+ void deleteNewLocationsTable()
+ {
+ m_statementFactory.deleteNewLocationsTableStatement.execute();
+ }
+
+ SourceLocationEntries sourceLocations() const
+ {
+ return SourceLocationEntries();
+ }
+
+private:
+ StatementFactory &m_statementFactory;
+ FilePathCache<std::mutex> &m_filePathCache;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h
new file mode 100644
index 00000000000..05d449748c2
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "sourcelocationentry.h"
+#include "symbolentry.h"
+
+namespace ClangBackEnd {
+
+class SymbolStorageInterface
+{
+public:
+ virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries,
+ const SourceLocationEntries &sourceLocations) = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg
index 4e1fbadcd25..d82f71ae752 100644
--- a/src/tools/icons/qtcreatoricons.svg
+++ b/src/tools/icons/qtcreatoricons.svg
@@ -18,6 +18,18 @@
sodipodi:docname="qtcreatoricons.svg">
<defs
id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient9821">
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0"
+ id="stop9817" />
+ <stop
+ style="stop-color:#fffff1;stop-opacity:1"
+ offset="1"
+ id="stop9819" />
+ </linearGradient>
<inkscape:path-effect
effect="clone_original"
linkedpath="#path2727"
@@ -457,26 +469,13 @@
</clipPath>
<linearGradient
inkscape:collect="always"
- xlink:href="#linearGradient5340"
- id="linearGradient5346"
- x1="515.5"
- y1="439"
- x2="515.5"
- y2="442"
+ xlink:href="#linearGradient9821"
+ id="linearGradient9824"
gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-5.25,-362.50001)" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient5340">
- <stop
- style="stop-color:#000000;stop-opacity:1"
- offset="0"
- id="stop5342" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1"
- offset="1"
- id="stop5344" />
- </linearGradient>
+ x1="510.75"
+ y1="73.5"
+ x2="510.75"
+ y2="75.5" />
</defs>
<sodipodi:namedview
id="base"
@@ -591,6 +590,13 @@
style="fill:#00ff00;fill-opacity:1;stroke:none" />
</g>
<rect
+ y="436"
+ x="-16"
+ height="16"
+ width="16"
+ id="backgroundRect"
+ style="display:inline;fill:#ffffff" />
+ <rect
y="452"
x="-16"
height="16"
@@ -2208,7 +2214,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="share/qtcreator/templates/wizards/projects/qtquickapplication/icon-empty"
+ id="share/qtcreator/templates/wizards/projects/qtquickapplication/empty/icon"
transform="translate(-23,-82)">
<use
style="display:inline"
@@ -2242,7 +2248,7 @@
</g>
</g>
<g
- id="share/qtcreator/templates/wizards/projects/qtquickapplication/icon-swipe"
+ id="share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/icon"
transform="translate(-57,-82)">
<use
style="display:inline"
@@ -2311,7 +2317,7 @@
x="0" />
</g>
<g
- id="share/qtcreator/templates/wizards/projects/qtquickapplication/icon-stack"
+ id="share/qtcreator/templates/wizards/projects/qtquickapplication/stack/icon"
transform="translate(-91,-82)">
<use
style="display:inline"
@@ -2379,7 +2385,7 @@
transform="matrix(0,1,1,0,-78,95)" />
</g>
<g
- id="share/qtcreator/templates/wizards/projects/qtquickapplication/icon-scroll"
+ id="share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/icon"
transform="translate(-125,-83)">
<use
style="display:inline"
@@ -2501,7 +2507,7 @@
height="100%" />
</g>
<g
- id="share/qtcreator/templates/wizards/projects/qtcanvas3dapplication/3dapplication"
+ id="share/qtcreator/templates/wizards/projects/qtquickapplication/canvas3d/icon"
transform="translate(-159,-83)">
<use
style="display:inline"
@@ -4423,7 +4429,7 @@
y="0"
x="0"
style="display:inline"
- transform="translate(387,509)" />
+ transform="translate(388,513)" />
</g>
<g
transform="translate(32,0)"
@@ -5283,6 +5289,71 @@
width="100%"
height="100%"
transform="matrix(-1,0,0,1,2293,0)" />
+ <g
+ id="src/plugins/autotest/images/benchmark">
+ <rect
+ style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none"
+ x="1676"
+ y="568"
+ width="16"
+ height="16"
+ id="rect4959-4-5-4-4-9-6" />
+ <circle
+ cy="576"
+ cx="1684"
+ id="path5907"
+ style="fill:#e6e6e6;stroke:#000000;stroke-width:1;stroke-opacity:1"
+ r="5.5" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path5911"
+ d="m 1683.5,576.5 3.8812,-3.88134"
+ style="stroke:#000000;stroke-width:0.60000002" />
+ <path
+ style="fill:#000000;stroke-width:1"
+ d="m 1682.5,569 v 1 h 3 v -1 z"
+ id="rect5909"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+ <g
+ id="src/plugins/autotest/images/text">
+ <rect
+ id="rect4959-4-5-4-4-9-6-3"
+ height="16"
+ width="16"
+ y="568"
+ x="1692"
+ style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none" />
+ <path
+ id="path9930"
+ style="fill:none;stroke:#000000"
+ d="m 1700,581.5 h 7 m -12.5,-11 5.5,5.5 -5.5,5.5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+ <g
+ id="src/plugins/autotest/images/visual">
+ <rect
+ style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none"
+ x="1708"
+ y="568"
+ width="16"
+ height="16"
+ id="rect4959-4-5-4-4-9-6-3-6" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0"
+ d="m 1714.5,577.5 h 3.5 m -3.5,-4 v 4.5 m -4,-4.5 h 4.5 m -4.5,-2.5 v 11 m 3.5,-0.5 h -3.5"
+ style="stroke:#666666"
+ id="path9999" />
+ <path
+ id="rect9970-2-1"
+ d="m 1714,581 h 5 v 2 h -5 z m -4,-12 h 5 v 2 h -5 z m 4,4 h 5 v 2 h -5 z m 4,4 h 5 v 2 h -5 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccccccccc" />
+ </g>
</g>
<g
inkscape:groupmode="layer"
@@ -5365,68 +5436,6 @@
style="fill:none;stroke:#000000;stroke-width:1.42;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1.0;stroke-dasharray:none" />
</g>
<g
- style="display:inline"
- id="src/plugins/projectexplorer/images/rebuildhammerhandles"
- transform="translate(-1266.5,289)">
- <rect
- y="263"
- x="1339.5"
- height="16"
- width="16"
- id="rect6249-7"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="smallhammerhandle"
- d="m 1343,269 9,9 1.5,-1.5 -9,-9 z" />
- <use
- height="100%"
- width="100%"
- transform="matrix(-1,0,0,1,2695,0)"
- id="use6253-7"
- xlink:href="#smallhammerhandle"
- y="0"
- x="0" />
- <path
- style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 1347.675,273.675 1.5,-1.5"
- id="path6284"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- style="display:inline;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50006026;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 1345.8268,271.82353 1.5,-1.50041"
- id="path6284-5"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- </g>
- <g
- style="display:inline"
- id="src/plugins/projectexplorer/images/rebuildhammerheads"
- transform="translate(-1250.5,289)">
- <rect
- y="263"
- x="1339.5"
- height="16"
- width="16"
- id="rect6249"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="smallhammerhead"
- d="m 1339.5,268.5 2,2.5 6,-6 -4.5,0 z" />
- <use
- height="100%"
- width="100%"
- transform="matrix(-1,0,0,1,2695,0)"
- id="use6253"
- xlink:href="#smallhammerhead"
- y="0"
- x="0" />
- </g>
- <g
transform="translate(-34,374)"
id="src/plugins/welcome/images/new">
<rect
@@ -6223,6 +6232,77 @@
cy="564"
r="3.5" />
</g>
+ <g
+ style="display:inline"
+ id="src/plugins/projectexplorer/images/buildhammerhandle"
+ transform="translate(-802.5,289)">
+ <rect
+ y="263"
+ x="1339.5"
+ height="16"
+ width="16"
+ id="rect6249-7-2"
+ style="fill:#ffffff" />
+ <path
+ d="m 1352,269 -9,9 -1.5,-1.5 9,-9 z"
+ id="use6253-7-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+ <g
+ style="display:inline"
+ id="src/plugins/projectexplorer/images/buildhammerhead"
+ transform="translate(-786.5,289)">
+ <rect
+ y="263"
+ x="1339.5"
+ height="16"
+ width="16"
+ id="rect6249-2"
+ style="fill:#ffffff" />
+ <path
+ d="m 1355.5,268.5 -2,2.5 -6,-6 h 4.5 z"
+ id="use6253-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+ <g
+ style="display:inline"
+ id="src/plugins/projectexplorer/images/rebuildhammerhandles"
+ transform="translate(-770.5,289)">
+ <rect
+ y="263"
+ x="1339.5"
+ height="16"
+ width="16"
+ id="rect6249-7"
+ style="fill:#ffffff" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="smallhammerhandle"
+ d="m 1343,269 9,9 1.5,-1.5 -9,-9 z" />
+ <path
+ style="stroke:#ffffff;stroke-width:0.5"
+ d="m 1347.675,273.675 1.5,-1.5"
+ id="path6284"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="stroke:#ffffff;stroke-width:0.5"
+ d="m 1345.8268,271.82353 1.5,-1.5"
+ id="path6284-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ <use
+ x="0"
+ y="0"
+ xlink:href="#src/plugins/projectexplorer/images/buildhammerhead"
+ id="src/plugins/projectexplorer/images/rebuildhammerheads"
+ transform="matrix(-1,0,0,1,1154,0)"
+ width="100%"
+ height="100%" />
</g>
<g
inkscape:groupmode="layer"
@@ -6672,38 +6752,28 @@
</g>
</g>
<g
- style="display:inline"
- id="src/libs/utils/images/magnifier"
- transform="translate(37,-80)">
+ id="src/libs/utils/images/magnifier">
<rect
style="fill:#ffffff;fill-opacity:1"
id="rect3817-2-9-1-9-6-0"
- width="17"
- height="11"
- x="171"
- y="589" />
- <g
- transform="translate(-231.13585,386.05488)"
- id="magnifying_lense-1"
- style="display:inline;fill:#000000;fill-opacity:1">
- <path
- id="path4719-8-0"
- d="m 402.25285,212.41599 c -0.156,0.155 -0.156,0.41 0,0.565 l 0.84663,0.84863 c 0.156,0.154 0.41,0.154 0.566,0 L 407.231,210.24 c 0.156,-0.154 0.156,-0.41 0.001,-0.565 l -0.84763,-0.84763 c -0.156,-0.156 -0.41,-0.156 -0.566,0 z"
- inkscape:connector-curvature="0"
- style="fill-opacity:1"
- sodipodi:nodetypes="cccccsscc" />
- <circle
- style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.17697227;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path5669-9"
- cx="409"
- cy="206.94511"
- r="3.4115138" />
- </g>
+ width="16"
+ height="16"
+ x="208"
+ y="504" />
+ <use
+ transform="translate(-193,303)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#magnifying_lense"
+ id="use5882"
+ width="100%"
+ height="100%" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path4784-5"
- d="m 186,597 -2.5,2.5 -2.5,-2.5 z"
+ d="m 224,516 -2.5,2.5 -2.5,-2.5 z"
style="display:inline;fill:#000000;fill-opacity:1;stroke:none" />
</g>
<g
@@ -6920,147 +6990,164 @@
id="g4718"
inkscape:label="Side Bar Icons">
<g
- transform="translate(-34,308)"
+ transform="translate(-41,264)"
style="display:inline"
id="src/plugins/welcome/images/mode_welcome_mask">
- <rect
- style="fill:#ffffff;fill-opacity:1"
- x="34"
- y="42"
- width="48"
- height="32"
- id="rect5694-0" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect"
+ id="backgroundRect_32_28"
+ transform="matrix(2.125,0,0,2.125,75,-888.5)"
+ width="100%"
+ height="100%"
+ style="stroke-width:0.88038999" />
<path
inkscape:connector-curvature="0"
- d="m 62,62 5,0 0,5 -5,0 z m -7,0 5,0 0,5 -5,0 z m -7,0 5,0 0,5 -5,0 z m 14,-7 5,0 0,5 -5,0 z m -7,0 5,0 0,5 -5,0 z m -7,0 5,0 0,5 -5,0 z m 14,-7 5,0 0,5 -5,0 z m -7,0 5,0 0,5 -5,0 z m -7,0 5,0 0,5 -5,0 z"
+ d="m 62,59 h 5 v 5 h -5 z m -7,0 h 5 v 5 h -5 z m -7,0 h 5 v 5 h -5 z m 14,-7 h 5 v 5 h -5 z m -7,0 h 5 v 5 h -5 z m -7,0 h 5 v 5 h -5 z m 14,-7 h 5 v 5 h -5 z m -7,0 h 5 v 5 h -5 z m -7,0 h 5 v 5 h -5 z"
id="rect5371-8" />
</g>
<g
- transform="translate(-36,308)"
+ transform="translate(-55,264)"
style="display:inline;fill:#000000"
id="src/plugins/coreplugin/images/mode_edit_mask">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="84"
- y="42"
- width="48"
- height="32"
- id="rect5706-3-8" />
+ <use
+ transform="translate(50)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913"
+ width="100%"
+ height="100%" />
<path
id="path5381-3"
- d="m 98,48 0,19 19,0 0,-19 z m 4,9 9,0 0,1 -9,0 z m 9,5 -9,0 0,-1 9,0 z m 2,-2 -11,0 0,-1 11,0 z m 0,-4 -11,0 0,-1 11,0 z m 0,-2 -11,0 0,-1 11,0 z"
+ d="m 98,45 v 19 h 19 V 45 Z m 4,9 h 9 v 1 h -9 z m 9,5 h -9 v -1 h 9 z m 2,-2 h -11 v -1 h 11 z m 0,-4 h -11 v -1 h 11 z m 0,-2 h -11 v -1 h 11 z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
</g>
<g
- transform="translate(-38,308)"
+ transform="translate(-69,264)"
style="display:inline"
id="src/plugins/coreplugin/images/mode_design_mask">
- <rect
- style="fill:#ffffff;fill-opacity:1"
- x="134"
- y="42"
- width="48"
- height="32"
- id="rect5706-2" />
+ <use
+ transform="translate(100)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0"
+ width="100%"
+ height="100%" />
<g
- transform="translate(-5,-4)"
+ transform="translate(-5,-6)"
id="g5387-8">
<path
id="polygon5391-6"
- d="m 167.909,59.778 -3.535,-3.536 -10.96,10.96 -1.414,4.95 4.949,-1.414 z m -2.4715,-4.589696 3.18214,-3.180343 3.5338,3.535793 -3.18215,3.180343 z"
+ d="m 167.909,58.778 -3.535,-3.536 -10.96,10.96 -1.414,4.95 4.949,-1.414 z m -2.4715,-4.589696 3.18214,-3.180343 3.5338,3.535793 -3.18215,3.180343 z"
inkscape:connector-curvature="0" />
</g>
</g>
<g
- transform="translate(-40,308)"
+ transform="translate(-83,264)"
style="display:inline"
id="src/plugins/debugger/images/mode_debug_mask">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none"
- x="184"
- y="42"
- width="48"
- height="32"
- id="rect5706-4-6" />
+ <use
+ transform="translate(150)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8"
+ width="100%"
+ height="100%" />
<g
- transform="translate(-4.5,-5)"
+ transform="translate(-4.5,-7)"
id="g5397-4">
<path
- d="M 167.5 356 C 166.225 356 164.19123 357.17695 163.61523 358.75195 L 167.5 360.9375 L 171.38477 358.75195 C 170.80877 357.17595 168.775 356 167.5 356 z M 162.82422 359.68359 L 160.83789 361.44922 L 159.44141 360.05469 C 159.24741 359.86069 158.92837 359.86069 158.73438 360.05469 C 158.54038 360.24869 158.54038 360.56772 158.73438 360.76172 L 160.42188 362.44922 L 159.53516 366 L 158 366 C 157.725 366 157.5 366.225 157.5 366.5 C 157.5 366.775 157.725 367 158 367 L 159.48828 367 L 160.67969 370.8125 L 159.05273 372.43945 C 158.85873 372.63345 158.85873 372.95248 159.05273 373.14648 C 159.24673 373.34048 159.56577 373.34048 159.75977 373.14648 L 161.13477 371.77148 L 164.6875 374.13867 L 167 374.72461 L 167 362 L 162.82422 359.68359 z M 172.17578 359.68359 L 168 362 L 168 374.72461 L 170.3125 374.13867 L 173.86328 371.77148 L 175.23828 373.14648 C 175.43228 373.34048 175.75131 373.34048 175.94531 373.14648 C 176.13931 372.95248 176.13931 372.63345 175.94531 372.43945 L 174.32031 370.81445 L 175.51172 367 L 177 367 C 177.275 367 177.5 366.775 177.5 366.5 C 177.5 366.225 177.275 366 177 366 L 175.46484 366 L 174.57812 362.44922 L 176.26562 360.76172 C 176.45963 360.56772 176.45962 360.24869 176.26562 360.05469 C 176.07163 359.86069 175.75259 359.86069 175.55859 360.05469 L 174.16211 361.44922 L 172.17578 359.68359 z "
- transform="translate(44.5,-303)"
- id="path5403-3" />
+ d="m 212,52 c -1.275,0 -3.30877,1.17695 -3.88477,2.75195 L 212,56.9375 215.88477,54.75195 C 215.30877,53.17595 213.275,52 212,52 Z m -4.67578,3.68359 -1.98633,1.76563 -1.39648,-1.39453 c -0.194,-0.194 -0.51304,-0.194 -0.70703,0 -0.194,0.194 -0.194,0.51303 0,0.70703 l 1.6875,1.6875 L 204.03516,62 H 202.5 c -0.275,0 -0.5,0.225 -0.5,0.5 0,0.275 0.225,0.5 0.5,0.5 h 1.48828 l 1.19141,3.8125 -1.62696,1.62695 c -0.194,0.194 -0.194,0.51303 0,0.70703 0.194,0.194 0.51304,0.194 0.70704,0 l 1.375,-1.375 3.55273,2.36719 2.3125,0.58594 V 58 Z m 9.35156,0 L 212.5,58 v 12.72461 l 2.3125,-0.58594 3.55078,-2.36719 1.375,1.375 c 0.194,0.194 0.51303,0.194 0.70703,0 0.194,-0.194 0.194,-0.51303 0,-0.70703 l -1.625,-1.625 L 220.01172,63 H 221.5 c 0.275,0 0.5,-0.225 0.5,-0.5 0,-0.275 -0.225,-0.5 -0.5,-0.5 h -1.53516 l -0.88672,-3.55078 1.6875,-1.6875 c 0.19401,-0.194 0.194,-0.51303 0,-0.70703 -0.19399,-0.194 -0.51303,-0.194 -0.70703,0 l -1.39648,1.39453 z"
+ id="path5403-3"
+ inkscape:connector-curvature="0" />
</g>
</g>
<g
- transform="translate(-42,308)"
+ transform="translate(-97,264)"
style="display:inline"
id="src/plugins/projectexplorer/images/mode_project_mask">
- <rect
- style="fill:#ffffff;fill-opacity:1"
- x="234"
- y="42"
- width="48"
- height="32"
- id="rect5722-4" />
+ <use
+ transform="translate(200)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-3"
+ width="100%"
+ height="100%" />
<path
id="path5439-0"
- d="m 265.554,57.885 c 1.51,-1.511 1.955,-3.68 1.34,-5.583 l -2.754,2.754 c -0.584,0.583 -1.538,0.583 -2.121,0 l -1.414,-1.415 c -0.584,-0.583 -0.584,-1.538 0,-2.121 l 2.754,-2.754 c -1.903,-0.614 -4.073,-0.17 -5.583,1.34 -1.647,1.647 -2.025,4.081 -1.145,6.095 l -8.048,8.047 c -0.777,0.778 -0.777,2.051 0,2.829 0.777,0.777 2.051,0.777 2.828,0 l 8.048,-8.048 c 2.015,0.882 4.447,0.503 6.095,-1.144 z"
+ d="m 265.554,54.885 c 1.51,-1.511 1.955,-3.68 1.34,-5.583 l -2.754,2.754 c -0.584,0.583 -1.538,0.583 -2.121,0 l -1.414,-1.415 c -0.584,-0.583 -0.584,-1.538 0,-2.121 l 2.754,-2.754 c -1.903,-0.614 -4.073,-0.17 -5.583,1.34 -1.647,1.647 -2.025,4.081 -1.145,6.095 l -8.048,8.047 c -0.777,0.778 -0.777,2.051 0,2.829 0.777,0.777 2.051,0.777 2.828,0 l 8.048,-8.048 c 2.015,0.882 4.447,0.503 6.095,-1.144 z"
inkscape:connector-curvature="0" />
</g>
<g
- transform="translate(-46,308)"
+ transform="translate(-162,264)"
style="display:inline"
id="src/plugins/help/images/mode_help_mask">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="334"
- y="42"
- width="48"
- height="32"
- id="rect5706-9-7" />
+ <use
+ transform="translate(301)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-7"
+ width="100%"
+ height="100%" />
<path
id="path5457-0"
- d="m 358,48 c -5.522,0 -10,4.478 -10,10 0,5.522 4.478,10 10,10 5.522,0 10,-4.478 10,-10 0,-5.522 -4.478,-10 -10,-10 z m 1.136,16.182 c -0.274,0.269 -0.604,0.402 -0.989,0.402 -0.187,0 -0.364,-0.035 -0.533,-0.105 -0.169,-0.07 -0.318,-0.163 -0.446,-0.28 -0.129,-0.117 -0.23,-0.257 -0.307,-0.42 -0.076,-0.163 -0.113,-0.338 -0.113,-0.525 0,-0.373 0.137,-0.694 0.411,-0.962 0.273,-0.268 0.603,-0.402 0.988,-0.402 0.374,0 0.7,0.128 0.98,0.385 0.28,0.257 0.42,0.572 0.42,0.945 0,0.372 -0.138,0.693 -0.411,0.962 z m 2.738,-7.98 c -0.104,0.292 -0.245,0.56 -0.42,0.805 -0.175,0.245 -0.376,0.479 -0.604,0.7 -0.228,0.222 -0.47,0.455 -0.727,0.7 -0.163,0.151 -0.303,0.286 -0.42,0.402 -0.116,0.117 -0.213,0.236 -0.288,0.359 -0.076,0.122 -0.132,0.262 -0.167,0.42 -0.034,0.157 -0.052,0.347 -0.052,0.569 l 0,0.665 -2.101,0 0,-0.962 c 0,-0.256 0.015,-0.475 0.044,-0.656 0.029,-0.181 0.081,-0.344 0.157,-0.49 0.076,-0.146 0.175,-0.286 0.298,-0.42 0.122,-0.134 0.271,-0.295 0.446,-0.481 l 1.348,-1.365 c 0.291,-0.292 0.438,-0.67 0.438,-1.137 0,-0.455 -0.149,-0.825 -0.446,-1.111 -0.298,-0.286 -0.674,-0.429 -1.129,-0.429 -0.49,0 -0.893,0.166 -1.208,0.499 -0.314,0.333 -0.495,0.738 -0.542,1.216 l -2.24,-0.175 c 0.07,-0.56 0.216,-1.059 0.438,-1.496 0.222,-0.438 0.511,-0.808 0.866,-1.111 0.355,-0.303 0.768,-0.534 1.234,-0.691 0.466,-0.158 0.979,-0.236 1.54,-0.236 0.524,0 1.012,0.076 1.461,0.228 0.449,0.152 0.84,0.371 1.172,0.656 0.333,0.286 0.593,0.642 0.779,1.067 0.186,0.426 0.28,0.913 0.28,1.461 10e-4,0.382 -0.052,0.721 -0.157,1.013 z"
+ d="m 359,45 c -5.522,0 -10,4.478 -10,10 0,5.522 4.478,10 10,10 5.522,0 10,-4.478 10,-10 0,-5.522 -4.478,-10 -10,-10 z m 1.136,16.182 c -0.274,0.269 -0.604,0.402 -0.989,0.402 -0.187,0 -0.364,-0.035 -0.533,-0.105 -0.169,-0.07 -0.318,-0.163 -0.446,-0.28 -0.129,-0.117 -0.23,-0.257 -0.307,-0.42 -0.076,-0.163 -0.113,-0.338 -0.113,-0.525 0,-0.373 0.137,-0.694 0.411,-0.962 0.273,-0.268 0.603,-0.402 0.988,-0.402 0.374,0 0.7,0.128 0.98,0.385 0.28,0.257 0.42,0.572 0.42,0.945 0,0.372 -0.138,0.693 -0.411,0.962 z m 2.738,-7.98 c -0.104,0.292 -0.245,0.56 -0.42,0.805 -0.175,0.245 -0.376,0.479 -0.604,0.7 -0.228,0.222 -0.47,0.455 -0.727,0.7 -0.163,0.151 -0.303,0.286 -0.42,0.402 -0.116,0.117 -0.213,0.236 -0.288,0.359 -0.076,0.122 -0.132,0.262 -0.167,0.42 -0.034,0.157 -0.052,0.347 -0.052,0.569 v 0.665 h -2.101 V 56.86 c 0,-0.256 0.015,-0.475 0.044,-0.656 0.029,-0.181 0.081,-0.344 0.157,-0.49 0.076,-0.146 0.175,-0.286 0.298,-0.42 0.122,-0.134 0.271,-0.295 0.446,-0.481 l 1.348,-1.365 c 0.291,-0.292 0.438,-0.67 0.438,-1.137 0,-0.455 -0.149,-0.825 -0.446,-1.111 -0.298,-0.286 -0.674,-0.429 -1.129,-0.429 -0.49,0 -0.893,0.166 -1.208,0.499 -0.314,0.333 -0.495,0.738 -0.542,1.216 l -2.24,-0.175 c 0.07,-0.56 0.216,-1.059 0.438,-1.496 0.222,-0.438 0.511,-0.808 0.866,-1.111 0.355,-0.303 0.768,-0.534 1.234,-0.691 0.466,-0.158 0.979,-0.236 1.54,-0.236 0.524,0 1.012,0.076 1.461,0.228 0.449,0.152 0.84,0.371 1.172,0.656 0.333,0.286 0.593,0.642 0.779,1.067 0.186,0.426 0.28,0.913 0.28,1.461 10e-4,0.382 -0.052,0.721 -0.157,1.013 z"
inkscape:connector-curvature="0" />
</g>
<g
- transform="translate(-262,305)"
+ transform="translate(-595,297)"
style="display:inline"
id="src/plugins/projectexplorer/images/run_mask">
- <rect
- style="fill:#ffffff;fill-opacity:1"
- x="600"
- y="50"
- width="24"
- height="24"
- id="rect5751-4" />
+ <use
+ transform="translate(554,3)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1"
+ width="100%"
+ height="100%" />
<polygon
style="fill:#000000"
- points="621,61 603,72 603,50 "
- id="polygon5749-6" />
+ points="603,50 621,61 603,72 "
+ id="polygon5749-6"
+ transform="translate(0,-4)" />
</g>
<g
- transform="translate(-388,305)"
+ transform="translate(-708,297)"
style="display:inline"
id="src/plugins/projectexplorer/images/debugger_beetle_mask">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="750"
- y="50"
- width="24"
- height="24"
- id="rect5759-4-1" />
+ <use
+ transform="translate(703,3)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-3"
+ width="100%"
+ height="100%" />
<g
id="big_bug"
- transform="translate(-4,2.999762)">
+ transform="translate(-5,-1.000238)">
<path
d="m 769.50001,58.836563 c -0.65839,0 -1.70859,0.724548 -2.00602,1.694142 l 2.00602,1.345458 2.006,-1.345458 c -0.29742,-0.97021 -1.34763,-1.694142 -2.006,-1.694142 z"
id="path4874"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cccccccccccccccc"
- d="m 767.12627,61.068318 c -0.25633,0.152637 -0.64848,0.411162 -1.25704,1.062795 l -1.53472,-1.238122 -0.75352,0.91144 1.76081,1.340958 C 765.1929,63.665163 764.94085,64.148012 764.875,65 l -1.875,0 0,1 1.875,0 c 0.13153,0.564121 0.25703,1.128242 0.58926,1.692363 l -1.66595,1.498516 0.73938,0.89637 1.61151,-1.446886 c 1.00647,0.777187 1.78541,1.06964 2.8508,1.139875 l 0,-7.354264 z"
+ d="m 767.12627,61.068318 c -0.25633,0.152637 -0.64848,0.411162 -1.25704,1.062795 l -1.53472,-1.238122 -0.75352,0.91144 1.76081,1.340958 C 765.1929,63.665163 764.94085,64.148012 764.875,65 H 763 v 1 h 1.875 c 0.13153,0.564121 0.25703,1.128242 0.58926,1.692363 l -1.66595,1.498516 0.73938,0.89637 1.61151,-1.446886 c 1.00647,0.777187 1.78541,1.06964 2.8508,1.139875 v -7.354264 z"
id="path4872"
inkscape:connector-curvature="0" />
<use
@@ -7075,142 +7162,176 @@
</g>
<g
id="src/plugins/debugger/images/debugger_interrupt_mask"
- transform="translate(-364,305)"
+ transform="translate(-673,297)"
style="display:inline">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="750"
- y="50"
- width="24"
- height="24"
- id="rect4791" />
+ <use
+ transform="translate(704,3)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-7"
+ width="100%"
+ height="100%" />
<rect
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4608-0"
width="7"
height="18"
x="753"
- y="52" />
+ y="48" />
<rect
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4610-6"
width="7"
height="18"
x="763"
- y="52" />
+ y="48" />
</g>
<g
id="src/plugins/debugger/images/debugger_continue_1_mask"
- transform="translate(-340,305)"
+ transform="translate(-636,297)"
style="display:inline">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="750"
- y="50"
- width="24"
- height="24"
- id="rect4791-9" />
+ <use
+ transform="translate(703,3)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-30"
+ width="100%"
+ height="100%" />
<rect
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4608-0-4"
width="7"
height="18"
- x="753"
- y="52" />
+ x="752"
+ y="48" />
</g>
<g
id="src/plugins/debugger/images/debugger_continue_2_mask"
- transform="translate(-316,305)"
+ transform="translate(-602,297)"
style="display:inline">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="750"
- y="50"
- width="24"
- height="24"
- id="rect4791-9-8" />
+ <use
+ transform="translate(705,3)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-8"
+ width="100%"
+ height="100%" />
<path
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 763,52 9,9 -9,9 z"
+ d="m 764,48 9,9 -9,9 z"
id="rect4610-6-2-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</g>
<g
- transform="translate(-392,305)"
+ transform="translate(-664,297)"
style="display:inline"
id="src/plugins/projectexplorer/images/build_hammerhandle_mask">
- <rect
- style="fill:#ffffff;fill-opacity:1"
- x="850"
- y="50"
- width="24"
- height="24"
- id="rect5759-5" />
+ <use
+ transform="translate(803,3)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-89"
+ width="100%"
+ height="100%" />
<g
style="fill:#030303;fill-opacity:1"
- id="build-5">
+ id="build-5"
+ transform="translate(-1,-3)">
<rect
- style="fill:#030303;fill-opacity:1"
- x="856.98199"
- y="53.081001"
- transform="matrix(0.7071,0.7071,-0.7071,0.7071,296.0486,-588.562)"
- width="3"
- height="20"
+ style="fill:#030303;fill-opacity:1;stroke-width:0.9999904"
+ x="649.42847"
+ y="-573.14081"
+ transform="rotate(45)"
+ width="2.9999712"
+ height="19.999807"
id="rect5755-4" />
</g>
</g>
<g
- transform="translate(-368,305)"
+ transform="translate(-628,297)"
style="display:inline"
id="src/plugins/projectexplorer/images/build_hammerhead_mask">
- <rect
- style="fill:#ffffff;fill-opacity:1"
- x="850"
- y="50"
- width="24"
- height="24"
- id="rect5759-5-9" />
+ <use
+ transform="translate(803,3)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-5"
+ width="100%"
+ height="100%" />
<g
style="fill:#030303;fill-opacity:1"
- id="build-5-2">
+ id="build-5-2"
+ transform="translate(-1,-3)">
<polygon
style="fill:#030303;fill-opacity:1"
- points="866.613,50 873.684,57.071 870.148,60.606 859.542,50 "
- id="polygon5757-3-4" />
+ points="873.684,57.071 870.148,60.606 859.542,50 866.613,50 "
+ id="polygon5757-3-4"
+ transform="translate(0,-1)" />
</g>
</g>
<g
- transform="translate(6.5,297)"
+ transform="translate(-247.5,256)"
id="src/plugins/projectexplorer/images/desktopdevice">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="499.5"
- y="50"
- width="32"
- height="32"
- id="rect5759-5-9-0" />
- <path
- d="m 525.5,54 -20,0 c -1.1,0 -2,0.9 -2,2 l 0,14 c 0,1.1 0.9,2 2,2 l 20,0 c 1.1,0 2,-0.9 2,-2 l 0,-14 c 0,-1.1 -0.9,-2 -2,-2 l 0,0 z"
- id="path5514" />
- <path
- d="m 521,78 -3.5,-7 -4,0 -3.5,7 z"
- id="polygon5516"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- d="m 525.5,56 0,14 -20,0 0,-14 20,0"
- id="path4825"
- style="fill:#b3b3b3" />
+ <use
+ transform="translate(458.5,7)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-5-6"
+ width="100%"
+ height="100%" />
+ <g
+ id="desktopDevice"
+ transform="translate(1,-4)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path5514"
+ d="m 525.5,54 h -20 c -1.1,0 -2,0.9 -2,2 v 14 c 0,1.1 0.9,2 2,2 h 20 c 1.1,0 2,-0.9 2,-2 V 56 c 0,-1.1 -0.9,-2 -2,-2 z" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="polygon5516"
+ d="m 521,78 -3.5,-7 h -4 l -3.5,7 z" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#b3b3b3"
+ id="path4825"
+ d="m 525.5,56 v 14 h -20 V 56 h 20" />
+ </g>
</g>
- <use
- x="0"
- y="0"
- xlink:href="#src/plugins/projectexplorer/images/desktopdevice"
+ <g
id="src/libs/utils/images/desktopdevicesmall"
- transform="matrix(0.5,0,0,0.5,285,189.5)"
- width="100%"
- height="100%" />
+ transform="translate(-190,-45)">
+ <use
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect"
+ id="use6054"
+ width="100%"
+ height="100%"
+ transform="translate(458,-54)" />
+ <use
+ transform="matrix(0.5,0,0,0.5,191.75,359)"
+ x="0"
+ y="0"
+ xlink:href="#desktopDevice"
+ id="use8907"
+ width="100%"
+ height="100%"
+ style="stroke-width:2" />
+ </g>
<g
id="src/plugins/projectexplorer/images/fileoverlay_qt">
<rect
@@ -7667,36 +7788,40 @@
sodipodi:nodetypes="ccccc" />
</g>
<g
- id="src/plugins/ios/images/iosdevice">
- <rect
- style="fill:#ffffff"
- x="554"
- y="347"
- width="32"
- height="32"
- id="rect5230" />
+ id="src/plugins/ios/images/iosdevice"
+ transform="translate(-266,-42)">
+ <use
+ transform="translate(513,305)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-5-6-8"
+ width="100%"
+ height="100%" />
<g
- id="phone_body_big">
+ id="phone_body_big"
+ transform="translate(1,-3)">
<path
sodipodi:nodetypes="csssssssc"
id="path5232"
- d="m 578,374 0,-22 c 0,-1.1 -1,-2 -2,-2 l -12,0 c -1.1,0 -2,1 -2,2 l 0,22 c 0,1.1 1,2 2,2 l 12,0 c 1.1,0 2,-1 2,-2 z"
+ d="m 578,374 v -22 c 0,-1.1 -1,-2 -2,-2 h -12 c -1.1,0 -2,1 -2,2 v 22 c 0,1.1 1,2 2,2 h 12 c 1.1,0 2,-1 2,-2 z"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccc"
style="fill:#b3b3b3"
id="path5234"
- d="m 564,371 0,-19 12,0 0,19 z"
+ d="m 564,371 v -19 h 12 v 19 z"
inkscape:connector-curvature="0" />
</g>
<circle
style="fill:#b3b3b3"
id="circle5236"
- cx="570"
- cy="373.5"
+ cx="571"
+ cy="370.5"
r="1.5" />
<use
- transform="matrix(1.7179779,0,0,1.7179779,-422.96128,-273.18602)"
+ transform="matrix(1.7179779,0,0,1.7179779,-421.96128,-276.18602)"
x="0"
y="0"
xlink:href="#ioslogo"
@@ -7706,24 +7831,25 @@
</g>
<g
id="src/plugins/ios/images/iosdevicesmall"
- transform="translate(16,0)">
- <rect
- id="rect5759-5-9-0-8"
- height="16"
- width="16"
- y="363"
- x="570"
- style="fill:#ffffff" />
+ transform="translate(-282,-26)">
+ <use
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect"
+ id="use6054-9"
+ width="100%"
+ height="100%"
+ transform="translate(586,-73)" />
<g
id="phone_body_small">
<path
inkscape:connector-curvature="0"
- d="m 582,377 0,-12 c 0,-0.55 -0.5,-1 -1,-1 l -6,0 c -0.55,0 -1,0.5 -1,1 l 0,12 c 0,0.55 0.5,1 1,1 l 6,0 c 0.55,0 1,-0.5 1,-1 z"
+ d="m 582,377 v -12 c 0,-0.55 -0.5,-1 -1,-1 h -6 c -0.55,0 -1,0.5 -1,1 v 12 c 0,0.55 0.5,1 1,1 h 6 c 0.55,0 1,-0.5 1,-1 z"
id="path5514-4"
sodipodi:nodetypes="csssssssc" />
<path
inkscape:connector-curvature="0"
- d="m 575,375 0,-10 6,0 0,10 z"
+ d="m 575,375 v -10 h 6 v 10 z"
id="path4825-5"
style="fill:#b3b3b3"
sodipodi:nodetypes="ccccc" />
@@ -7736,20 +7862,22 @@
style="fill:#b3b3b3" />
<path
id="ioslogo"
- style="fill:#000000;fill-opacity:1.0"
+ style="fill:#000000;fill-opacity:1"
d="m 578.70257,367.62846 c 0.17676,-0.2141 0.29609,-0.51179 0.26322,-0.80851 -0.25463,0.0103 -0.56283,0.16975 -0.74567,0.38384 -0.16367,0.18922 -0.30725,0.49232 -0.26834,0.783 0.28398,0.022 0.574,-0.14455 0.75079,-0.35833 m 0.6373,1.88113 c -0.006,-0.64069 0.52327,-0.94828 0.5472,-0.96327 -0.29769,-0.43553 -0.76098,-0.4952 -0.92626,-0.50222 -0.39405,-0.0399 -0.76928,0.23197 -0.96901,0.23197 -0.19974,0 -0.5086,-0.22622 -0.83533,-0.21984 -0.4301,0.006 -0.82607,0.24984 -1.0475,0.63463 -0.44638,0.77438 -0.11391,1.92207 0.32066,2.55064 0.21282,0.30726 0.46616,0.65345 0.79927,0.64069 0.32098,-0.0128 0.44223,-0.2074 0.82958,-0.2074 0.38735,0 0.49647,0.2074 0.83565,0.20134 0.34491,-0.007 0.56379,-0.31397 0.77501,-0.62219 0.24377,-0.35672 0.3446,-0.70195 0.35034,-0.72014 -0.008,-0.003 -0.67259,-0.25813 -0.67961,-1.02421"
inkscape:connector-curvature="0" />
</g>
<g
- transform="translate(48,0)"
+ transform="translate(-230,-42)"
id="src/plugins/android/images/androiddevice">
- <rect
- style="fill:#ffffff"
- x="554"
- y="347"
- width="32"
- height="32"
- id="rect5230-4" />
+ <use
+ transform="translate(513,305)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-5-6-8-7"
+ width="100%"
+ height="100%" />
<use
x="0"
y="0"
@@ -7762,23 +7890,23 @@
id="rect4318"
width="4"
height="2"
- x="568"
- y="373" />
+ x="569"
+ y="370" />
<g
- transform="translate(-48,0)"
+ transform="translate(-47,-3)"
id="g5128"
- style="fill:#000000;fill-opacity:1.0">
+ style="fill:#000000;fill-opacity:1">
<path
sodipodi:nodetypes="ccccccccccccc"
inkscape:connector-curvature="0"
id="path4309"
- d="m 620.5,360 0,5 -0.5,0 0,2 -1,0 0,-2 -2,0 0,2 -1,0 0,-2 -0.5,0 0,-5 z"
+ d="m 620.5,360 v 5 H 620 v 2 h -1 v -2 h -2 v 2 h -1 v -2 h -0.5 v -5 z"
style="fill-opacity:1" />
<path
sodipodi:nodetypes="cccccccccc"
inkscape:connector-curvature="0"
id="path4311"
- d="m 616.29102,356.80664 -0.58204,0.38672 1,1.5 0.58204,-0.38672 z M 614,360 l 0,4 1,0 0,-4 z"
+ d="m 616.29102,356.80664 -0.58204,0.38672 1,1.5 0.58204,-0.38672 z M 614,360 v 4 h 1 v -4 z"
style="fill-opacity:1" />
<use
height="100%"
@@ -7793,20 +7921,21 @@
sodipodi:nodetypes="cczc"
inkscape:connector-curvature="0"
id="path4315"
- d="m 615.5,359.5 5,0 c 0,0 -0.5,-2 -2.5,-2 -2,0 -2.5,2 -2.5,2 z"
+ d="m 615.5,359.5 h 5 c 0,0 -0.5,-2 -2.5,-2 -2,0 -2.5,2 -2.5,2 z"
style="fill-opacity:1" />
</g>
</g>
<g
id="src/plugins/android/images/androiddevicesmall"
- transform="translate(64,0)">
- <rect
- id="rect5759-5-9-0-8-6"
- height="16"
- width="16"
- y="363"
- x="570"
- style="fill:#ffffff" />
+ transform="translate(-246,-26)">
+ <use
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect"
+ id="use6054-0"
+ width="100%"
+ height="100%"
+ transform="translate(586,-73)" />
<use
x="0"
y="0"
@@ -7822,27 +7951,29 @@
x="577"
y="376" />
<path
- style="fill:#000000;fill-opacity:1.0"
- d="m 642,367.5 c -1,0 -1,1.25 -1,1.25 l 2,0 c 0,0 0,-1.25 -1,-1.25 z m -2,1.5 0,2 0.75,0 0,-2 -0.75,0 z m 1,0 0,2 2,0 0,-2 -2,0 z m 2.25,0 0,2 0.75,0 0,-2 -0.75,0 z m -2.25,2.25 0,1.75 2,0 0,-1.75 -2,0 z"
- transform="translate(-64,0)"
+ style="fill:#000000;fill-opacity:1"
+ d="m 642,367.5 c -1,0 -1,1.25 -1,1.25 h 2 c 0,0 0,-1.25 -1,-1.25 z m -2,1.5 v 2 h 0.75 v -2 z m 1,0 v 2 h 2 v -2 z m 2.25,0 v 2 H 644 v -2 z M 641,371.25 V 373 h 2 v -1.75 z"
+ transform="translate(-64)"
id="path5131"
inkscape:connector-curvature="0" />
</g>
<g
- transform="translate(-286,-205)"
+ transform="translate(-503,-249)"
style="display:inline"
id="src/plugins/projectexplorer/images/devicestatusindicator">
- <rect
- id="rect6782-96-9-2"
- height="32"
- width="32"
- y="552"
- x="936"
- style="fill:#ffffff" />
+ <use
+ transform="translate(894,512)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-5-6-8-11-2"
+ width="100%"
+ height="100%" />
<circle
style="fill:#000000"
id="path4864-5"
- cx="961.5"
+ cx="962.5"
cy="577.5"
r="5.5" />
</g>
@@ -8029,34 +8160,36 @@
style="fill:#0dbf0d;fill-opacity:1" />
</g>
<g
- transform="translate(-48,32)"
+ transform="translate(-194,-42)"
id="src/plugins/baremetal/images/baremetaldevice">
- <rect
- style="fill:#ffffff"
- x="554"
- y="347"
- width="32"
- height="32"
- id="rect5230-4-4" />
+ <use
+ transform="translate(513,305)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-5-6-8-1"
+ width="100%"
+ height="100%" />
<path
style="fill:#808080;fill-opacity:1;stroke:#000000;stroke-opacity:1"
- d="m 563.5,354.5 13,0 2,2 0,13 -2,2 -13,0 -2,-2 0,-13 z"
+ d="m 564.5,351.5 h 13 l 2,2 v 13 l -2,2 h -13 l -2,-2 v -13 z"
id="rect5155"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccc" />
<circle
style="fill:#000000"
id="path5159"
- cx="565"
- cy="368"
+ cx="566"
+ cy="365"
r="1.5" />
<g
id="g5189"
- transform="translate(-0.5,-1)">
+ transform="translate(0.5,-4)">
<path
id="path5432-0"
style="color:#000000"
- d="m 565.5,352 1,0 0,3 -1,0 z m 3,0 1,0 0,3 -1,0 z m 3,0 1,0 0,3 -1,0 z m 3,0 1,0 0,3 -1,0 z"
+ d="m 565.5,352 h 1 v 3 h -1 z m 3,0 h 1 v 3 h -1 z m 3,0 h 1 v 3 h -1 z m 3,0 h 1 v 3 h -1 z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccccc" />
</g>
@@ -8065,7 +8198,7 @@
y="0"
xlink:href="#g5189"
id="use5200"
- transform="matrix(1,0,0,-1,0,726)"
+ transform="matrix(1,0,0,-1,0,720)"
width="100%"
height="100%" />
<use
@@ -8073,7 +8206,7 @@
y="0"
xlink:href="#g5189"
id="use5202"
- transform="matrix(0,1,-1,0,933,-207)"
+ transform="rotate(90,571,360)"
width="100%"
height="100%" />
<use
@@ -8081,36 +8214,37 @@
y="0"
xlink:href="#g5189"
id="use5204"
- transform="matrix(0,-1,1,0,207,933)"
+ transform="rotate(-90,571,360)"
width="100%"
height="100%" />
<path
id="rect5208-6-6"
style="fill:#000000"
- d="m 565,363 7,0 0,1 -7,0 z m 0,-2 6,0 0,1 -6,0 z m 0,-3 10,0 0,2 -10,0 z"
+ d="m 566,360 h 7 v 1 h -7 z m 0,-2 h 6 v 1 h -6 z m 0,-3 h 10 v 2 h -10 z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccccc" />
</g>
<g
id="src/plugins/baremetal/images/baremetaldevicesmall"
- transform="translate(-32,32)">
- <rect
- id="rect5759-5-9-0-8-6-4"
- height="16"
- width="16"
- y="363"
- x="570"
- style="fill:#ffffff" />
+ transform="translate(-210,-26)">
+ <use
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect"
+ id="use6054-7"
+ width="100%"
+ height="100%"
+ transform="translate(586,-73)" />
<path
style="fill:#999999;fill-opacity:1;stroke:#000000;stroke-width:0.5"
- d="m 575.5,367.25 6,0 1.25,1.25 0,6 -1.25,1.25 -6,0 -1.25,-1.25 0,-6 z"
+ d="m 575.5,367.25 h 6 l 1.25,1.25 v 6 l -1.25,1.25 h -6 l -1.25,-1.25 v -6 z"
id="rect5492"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccc" />
<path
id="rect5494-5"
style="fill:#4d4d4d"
- d="m 580,365 1,0 0,2 -1,0 z m -2,0 1,0 0,2 -1,0 z m -2,0 1,0 0,2 -1,0 z"
+ d="m 580,365 h 1 v 2 h -1 z m -2,0 h 1 v 2 h -1 z m -2,0 h 1 v 2 h -1 z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccscc" />
<use
@@ -8118,7 +8252,7 @@
y="0"
xlink:href="#rect5494-5"
id="use5529"
- transform="matrix(0,1,-1,0,950,-207)"
+ transform="rotate(90,578.5,371.5)"
width="100%"
height="100%" />
<use
@@ -8134,7 +8268,7 @@
y="0"
xlink:href="#rect5494-5"
id="use5533"
- transform="matrix(0,-1,1,0,207,950)"
+ transform="rotate(-90,578.5,371.5)"
width="100%"
height="100%" />
<circle
@@ -8146,66 +8280,69 @@
<path
id="rect5535-8"
style="fill:#000000;fill-opacity:1"
- d="m 576,371 4,0 0,0.5 -4,0 z m 0,-2 5,0 0,0.5 -5,0 z"
+ d="m 576,371 h 4 v 0.5 h -4 z m 0,-2 h 5 v 0.5 h -5 z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" />
</g>
<g
- transform="translate(6.25,362.5)"
+ transform="translate(-247.75,309.5)"
id="src/boot2qtdevice">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="499.75"
- y="48.5"
- width="32"
- height="32"
- id="rect5759-5-9-0-5" />
+ <use
+ transform="translate(458.75,6.5)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-5-6-8-74"
+ width="100%"
+ height="100%" />
<rect
style="fill:#555555"
id="rect6230"
width="30"
height="20"
- x="500.75"
- y="53.5" />
+ x="501.75"
+ y="50.5" />
<path
id="path7535"
style="fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 522.75,58.5 3,0 0,3 -3,0 z m 0,5 3,0 0,1 -3,0 z m 0,2 3,0 0,1 -3,0 z m 4,-2 3,0 0,1 -3,0 z m 0,2 3,0 0,1 -3,0 z m -1,4.5 c 0,0.828427 -0.67157,1.5 -1.5,1.5 -0.82843,0 -1.5,-0.671573 -1.5,-1.5 0,-0.828427 0.67157,-1.5 1.5,-1.5 0.82843,0 1.5,0.671573 1.5,1.5 z m -17,-0.5 3,0 0,3.5 -3,0 z m 4,1 3,0 0,2.5 -3,0 z m 17.5,-12 0,3 -3.5,0 0,-3 z"
+ d="m 523.75,55.5 h 3 v 3 h -3 z m 0,5 h 3 v 1 h -3 z m 0,2 h 3 v 1 h -3 z m 4,-2 h 3 v 1 h -3 z m 0,2 h 3 v 1 h -3 z m -1,4.5 c 0,0.828427 -0.67157,1.5 -1.5,1.5 -0.82843,0 -1.5,-0.671573 -1.5,-1.5 0,-0.828427 0.67157,-1.5 1.5,-1.5 0.82843,0 1.5,0.671573 1.5,1.5 z m -17,-0.5 h 3 V 70 h -3 z m 4,1 h 3 V 70 h -3 z m 17.5,-12 v 3 h -3.5 v -3 z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccccccccccsssssccccccccccccccc" />
<path
inkscape:connector-curvature="0"
style="fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 520.75,68.5 -18,0 0,-12 18,0 z"
+ d="m 521.75,65.5 h -18 v -12 h 18 z"
id="rect5261-2-0"
sodipodi:nodetypes="ccccc" />
<g
id="boottoqtscreen"
- bottoqtscreen="">
+ bottoqtscreen=""
+ transform="translate(1,-3)">
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="use7459-1-0-9-4"
- d="m 505.75,67.5 10,0 2,-2 0,-8 -10,0 -2,2 z"
+ d="m 505.75,67.5 h 10 l 2,-2 v -8 h -10 l -2,2 z"
style="fill:#000000;fill-opacity:1" />
<path
id="path4482-08"
style="fill:#ffffff;fill-opacity:1"
- d="m 514.75034,61.49797 0,2.06092 c 0,0.3626 0.0286,0.6013 0.0811,0.7205 0.0525,0.1193 0.14667,0.1766 0.3614,0.1766 l 0.72529,-0.029 0.0429,0.773 c -0.39605,0.076 -0.69666,0.1145 -0.90661,0.1145 -0.50103,0 -0.84458,-0.1145 -1.03068,-0.3435 -0.18609,-0.2291 -0.28153,-0.6633 -0.28153,-1.3027 l 0,-2.16592 -0.99227,0 0,-1.00235 0.99705,0 0.003,-1.00002 1,0 3.4e-4,1.00002 0.99967,-2e-5 0,0.99765 z m -4.99647,3.84385 c -0.74662,0 -1.26886,-0.2316 -1.56286,-0.69479 C 507.897,64.18374 507.75,63.44871 507.75,62.45099 c 0,-1.00219 0.15087,-1.74609 0.44874,-2.23159 0.29788,-0.48551 0.82012,-0.73046 1.55513,-0.73046 0.73888,0 1.25725,0.24047 1.55126,0.72597 0.29787,0.48112 0.44487,1.22502 0.44487,2.2317 0,0.66361 -0.0619,1.19813 -0.18182,1.60345 -0.12379,0.4099 -0.32108,0.72168 -0.59961,0.93545 l 0.69187,1.26167 -0.73888,0.39645 -0.72669,-1.35082 c -0.0928,0.0364 -0.23984,0.0495 -0.441,0.0495 z m -0.9323,-1.28728 c 0.16247,0.32066 0.47582,0.48551 0.93617,0.48551 0.46035,0 0.76982,-0.16028 0.9323,-0.47655 0.15861,-0.31626 0.15145,-0.85526 0.15145,-1.60803 0,-0.75724 0.007,-1.30511 -0.15919,-1.64807 -0.16634,-0.34306 -0.47195,-0.42391 -0.92456,-0.42391 -0.44875,0 -0.75822,0.0808 -0.92844,0.42391 -0.16634,0.34296 -0.16306,0.88644 -0.16306,1.63921 0,0.74828 -0.007,1.28728 0.15533,1.60793 z"
+ d="m 514.75034,61.49797 v 2.06092 c 0,0.3626 0.0286,0.6013 0.0811,0.7205 0.0525,0.1193 0.14667,0.1766 0.3614,0.1766 l 0.72529,-0.029 0.0429,0.773 c -0.39605,0.076 -0.69666,0.1145 -0.90661,0.1145 -0.50103,0 -0.84458,-0.1145 -1.03068,-0.3435 -0.18609,-0.2291 -0.28153,-0.6633 -0.28153,-1.3027 v -2.16592 h -0.99227 v -1.00235 h 0.99705 l 0.003,-1.00002 h 1 l 3.4e-4,1.00002 0.99967,-2e-5 v 0.99765 z m -4.99647,3.84385 c -0.74662,0 -1.26886,-0.2316 -1.56286,-0.69479 C 507.897,64.18374 507.75,63.44871 507.75,62.45099 c 0,-1.00219 0.15087,-1.74609 0.44874,-2.23159 0.29788,-0.48551 0.82012,-0.73046 1.55513,-0.73046 0.73888,0 1.25725,0.24047 1.55126,0.72597 0.29787,0.48112 0.44487,1.22502 0.44487,2.2317 0,0.66361 -0.0619,1.19813 -0.18182,1.60345 -0.12379,0.4099 -0.32108,0.72168 -0.59961,0.93545 l 0.69187,1.26167 -0.73888,0.39645 -0.72669,-1.35082 c -0.0928,0.0364 -0.23984,0.0495 -0.441,0.0495 z m -0.9323,-1.28728 c 0.16247,0.32066 0.47582,0.48551 0.93617,0.48551 0.46035,0 0.76982,-0.16028 0.9323,-0.47655 0.15861,-0.31626 0.15145,-0.85526 0.15145,-1.60803 0,-0.75724 0.007,-1.30511 -0.15919,-1.64807 -0.16634,-0.34306 -0.47195,-0.42391 -0.92456,-0.42391 -0.44875,0 -0.75822,0.0808 -0.92844,0.42391 -0.16634,0.34296 -0.16306,0.88644 -0.16306,1.63921 0,0.74828 -0.007,1.28728 0.15533,1.60793 z"
inkscape:connector-curvature="0" />
</g>
<circle
style="fill:#ffffff"
id="path6232"
- cx="502.25"
- cy="55"
+ cx="503.25"
+ cy="52"
r="0.75" />
<use
x="0"
y="0"
xlink:href="#path6232"
id="use6261"
- transform="translate(27,0)"
+ transform="translate(27)"
width="100%"
height="100%" />
<use
@@ -8225,38 +8362,40 @@
width="100%"
height="100%" />
<path
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="m 508.75,73.5 1,1.5 0,1.5 1,0 0,-1.5 1,-1.5 z"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 509.75,70.5 1,1.5 v 1.5 h 1 V 72 l 1,-1.5 z"
id="path5336"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<rect
- style="fill:url(#linearGradient5346);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ style="fill:url(#linearGradient9824);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="devicecable"
width="1"
- height="3"
- x="509.75"
- y="76.5"
+ height="2"
+ x="510.75"
+ y="73.5"
inkscape:label="#rect5338" />
</g>
<g
id="src/boot2qtdevicesmall"
- transform="translate(-32,64)">
- <rect
- id="rect5759-5-9-0-8-6-4-8"
- height="16"
- width="16"
- y="363"
- x="570"
- style="fill:#ffffff" />
+ transform="translate(-318,27)">
+ <use
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect"
+ id="use6054-39"
+ width="100%"
+ height="100%"
+ transform="translate(586,-73)" />
<use
- transform="translate(64.25,299)"
+ transform="matrix(1,0,0,1.25,63.25,283.625)"
x="0"
y="0"
xlink:href="#devicecable"
id="use5375"
width="100%"
- height="100%" />
+ height="100%"
+ style="stroke-width:0.89442718" />
<rect
style="fill:#333333"
id="rect5347"
@@ -8267,7 +8406,7 @@
<path
id="rect5404-4-2-3"
style="fill:#b3b3b3"
- d="m 584,373 0,2 -1,0 0,-2 z m 0,-2 0,0.5 -1,0 0,-0.5 z m 0,-1 0,0.5 -1,0 0,-0.5 z m 0,-1 0,0.5 -1,0 0,-0.5 z m 0,-3 0,2 -1,0 0,-2 z m -6,9 3,0 0,0.5 -3,0 z m -5,0 3,0 0,0.5 -3,0 z m -1,-9 10,0 0,8 -10,0 z"
+ d="m 584,373 v 2 h -1 v -2 z m 0,-2 v 0.5 h -1 V 371 Z m 0,-1 v 0.5 h -1 V 370 Z m 0,-1 v 0.5 h -1 V 369 Z m 0,-3 v 2 h -1 v -2 z m -6,9 h 3 v 0.5 h -3 z m -5,0 h 3 v 0.5 h -3 z m -1,-9 h 10 v 8 h -10 z"
inkscape:connector-curvature="0" />
<g
id="boottoqtscreensmall">
@@ -8275,11 +8414,11 @@
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path5089-53"
- d="m 581,371.5 -1.5,1.5 -6.5,0 0,-4.5 1.5,-1.5 6.5,0 z"
+ d="m 581,371.5 -1.5,1.5 H 573 v -4.5 l 1.5,-1.5 h 6.5 z"
style="fill:#000000;fill-opacity:1" />
<path
id="path4957-9"
- d="m 577.5,369.5 2.5,0 m -1.48438,-1.54688 -0.0227,2.94133 c 0.002,0.96521 0.83838,0.77673 1.50706,0.60555 m -3.69064,0 1.19887,1.38951 M 575.5,368.5 c 1,0 1,0.28518 1,1.5 0,1.21481 0,1.5 -1,1.5 -1,0 -1,-0.30273 -1,-1.5 0,-1.19726 0,-1.5 1,-1.5 z"
+ d="m 577.5,369.5 h 2.5 m -1.48438,-1.54688 -0.0227,2.94133 c 0.002,0.96521 0.83838,0.77673 1.50706,0.60555 m -3.69064,0 1.19887,1.38951 M 575.5,368.5 c 1,0 1,0.28518 1,1.5 0,1.21481 0,1.5 -1,1.5 -1,0 -1,-0.30273 -1,-1.5 0,-1.19726 0,-1.5 1,-1.5 z"
inkscape:connector-curvature="0"
style="fill:none;stroke:#ffffff;stroke-width:0.89999998" />
</g>
@@ -8295,7 +8434,7 @@
y="0"
xlink:href="#rect5349"
id="use5495"
- transform="translate(12.5,0)"
+ transform="translate(12.5)"
width="100%"
height="100%" />
<use
@@ -8316,26 +8455,28 @@
height="100%" />
</g>
<g
- transform="translate(6.25,394.5)"
+ transform="translate(-211.75,309.5)"
id="src/boot2qtemulator">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="499.75"
- y="48.5"
- width="32"
- height="32"
- id="rect5759-5-9-0-5-2" />
+ <use
+ transform="translate(458.75,6.5)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-5-6-8-74-0"
+ width="100%"
+ height="100%" />
<rect
style="fill:#000000;fill-opacity:1"
id="rect7751"
width="16"
height="16"
- x="500.75"
- y="56.5" />
+ x="501.75"
+ y="53.5" />
<path
id="rect7756"
style="fill:#b3b3b3"
- d="m 514.75,57.5 1,0 0,1 -1,0 z m -4,0 1,0 0,1 -1,0 z m 2,0 1,0 0,1 -1,0 z m -11,2 14,0 0,12 -14,0 z"
+ d="m 515.75,54.5 h 1 v 1 h -1 z m -4,0 h 1 v 1 h -1 z m 2,0 h 1 v 1 h -1 z m -11,2 h 14 v 12 h -14 z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccscc" />
<use
@@ -8348,7 +8489,7 @@
height="100%" />
<g
id="g7856"
- transform="translate(1,0)">
+ transform="translate(2,-3)">
<rect
y="54.5"
x="516.75"
@@ -8359,7 +8500,7 @@
<path
id="rect5261-2-0-1-9-5"
style="fill:#b3b3b3"
- d="m 528.75,74.5 -11,0 0,-6.5 11,0 z m 0,-7 -11,0 0,-6.5 11,0 z m 0,-7 -11,0 0,-3 11,0 z m -5,-5 1,0 0,1 -1,0 z m 2,0 1,0 0,1 -1,0 z m 2,0 1,0 0,1 -1,0 z"
+ d="m 528.75,74.5 h -11 V 68 h 11 z m 0,-7 h -11 V 61 h 11 z m 0,-7 h -11 v -3 h 11 z m -5,-5 h 1 v 1 h -1 z m 2,0 h 1 v 1 h -1 z m 2,0 h 1 v 1 h -1 z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
</g>
@@ -8367,19 +8508,20 @@
inkscape:connector-curvature="0"
id="rect7899-2-7-1-7"
style="fill:#333333"
- d="m 524.75,71.5 4,0 0,1 -4,0 z m -5,0 4,0 0,1 -4,0 z m 5,-2 4,0 0,1 -4,0 z m -3,0 2,0 0,1 -2,0 z m 3,-5 4,0 0,1 -4,0 z m -3,0 2,0 0,1 -2,0 z m 3,-2 4,0 0,1 -4,0 z m -5,0 4,0 0,1 -4,0 z m 5,-4 4,0 0,1 -4,0 z m -4,0 3,0 0,1 -3,0 z"
+ d="m 525.75,68.5 h 4 v 1 h -4 z m -5,0 h 4 v 1 h -4 z m 5,-2 h 4 v 1 h -4 z m -3,0 h 2 v 1 h -2 z m 3,-5 h 4 v 1 h -4 z m -3,0 h 2 v 1 h -2 z m 3,-2 h 4 v 1 h -4 z m -5,0 h 4 v 1 h -4 z m 5,-4 h 4 v 1 h -4 z m -4,0 h 3 v 1 h -3 z"
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccc" />
</g>
<g
id="src/boot2qtemulatorsmall"
- transform="translate(-32,96)">
- <rect
- id="rect5759-5-9-0-8-6-4-8-7"
- height="16"
- width="16"
- y="363"
- x="570"
- style="fill:#ffffff" />
+ transform="translate(-282,27)">
+ <use
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect"
+ id="use6054-6"
+ width="100%"
+ height="100%"
+ transform="translate(586,-73)" />
<rect
style="fill:#000000;fill-opacity:1"
id="rect7751-2"
@@ -8390,7 +8532,7 @@
<path
id="rect7756-5"
style="fill:#b3b3b3"
- d="m 582,366 1,0 0,1 -1,0 z m -4,0 1,0 0,1 -1,0 z m 2,0 1,0 0,1 -1,0 z m -7,2 10,0 0,8 -10,0 z"
+ d="m 582,366 h 1 v 1 h -1 z m -4,0 h 1 v 1 h -1 z m 2,0 h 1 v 1 h -1 z m -7,2 h 10 v 8 h -10 z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccscc" />
<use
@@ -8403,15 +8545,17 @@
height="100%" />
</g>
<g
- transform="translate(-25.75,394.5)"
+ transform="translate(-175.75,309.5)"
id="src/boot2qtstartvm">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="499.75"
- y="48.5"
- width="32"
- height="32"
- id="rect5759-5-9-0-5-2-7" />
+ <use
+ transform="translate(458.75,6.5)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-5-6-8-74-6"
+ width="100%"
+ height="100%" />
<use
x="0"
y="0"
@@ -8425,17 +8569,19 @@
id="rect8268-8"
width="21"
height="17"
- x="507.25"
- y="58"
- rx="2" />
+ x="508.25"
+ y="55"
+ rx="2"
+ ry="2" />
<rect
style="fill:#b3b3b3;fill-opacity:1;stroke:#000000"
id="rect8268"
width="21"
height="17"
- x="507.25"
- y="58"
- rx="2" />
+ x="508.25"
+ y="55"
+ rx="2"
+ ry="2" />
<use
transform="translate(6,4)"
x="0"
@@ -8446,34 +8592,37 @@
height="100%" />
</g>
<g
- transform="translate(54.25,362.5)"
+ transform="translate(-139.75,310.5)"
id="src/vxworksqtdevice">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="499.75"
- y="48.5"
- width="32"
- height="32"
- id="rect5759-5-9-0-5-9" />
+ <use
+ transform="translate(458.75,5.5)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-5-6-8-74-5"
+ width="100%"
+ height="100%" />
<path
style="fill:#000000"
- d="M 521.18792,71.036287 523.69993,75.5 518.68,75.5 Z M 502.39828,53.5 l 8.75116,0 8.36478,14.341164 -4.39783,7.401968 z m 14.5378,4.930014 2.79243,-4.930014 8.49821,0 -7.09801,12.136563 z"
+ d="M 522.18792,67.036287 524.69993,71.5 H 519.68 Z M 503.39828,49.5 h 8.75116 l 8.36478,14.341164 -4.39783,7.401968 z m 14.5378,4.930014 L 520.72851,49.5 h 8.49821 l -7.09801,12.136563 z"
id="vxworxkslogo"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccc" />
</g>
<g
id="src/vxworksdevicesmall"
- transform="translate(16,64)">
- <rect
- id="rect5759-5-9-0-8-6-4-8-8"
- height="16"
- width="16"
- y="363"
- x="570"
- style="fill:#ffffff;fill-opacity:1" />
+ transform="translate(-210,27)">
+ <use
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect"
+ id="use6054-1"
+ width="100%"
+ height="100%"
+ transform="translate(586,-73)" />
<use
- transform="matrix(0.54545415,0,0,0.54545415,297.22355,335.8182)"
+ transform="matrix(0.54545415,0,0,0.54545415,296.67809,338.00004)"
x="0"
y="0"
xlink:href="#vxworxkslogo"
@@ -8482,35 +8631,40 @@
height="100%" />
</g>
<g
- id="src/plugins/winrt/images/winrtdevice">
- <rect
- style="display:inline;fill:#ffffff;fill-opacity:1"
- x="602"
- y="379"
- width="32"
- height="32"
- id="rect5759-5-9-0-5-9-1" />
+ id="src/plugins/winrt/images/winrtdevice"
+ transform="translate(-206,-74)">
+ <use
+ transform="translate(561,337)"
+ style="display:inline"
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect_32_28"
+ id="use5913-0-8-1-5-6-8-11"
+ width="100%"
+ height="100%" />
<path
sodipodi:nodetypes="cccccccccccccccccccc"
style="fill:#000000;fill-opacity:1"
inkscape:connector-curvature="0"
- d="m 606,394 10,0 0,-10.16502 -10,1.1313 z m 12,-10.3911 0,10.3911 12,0 0,-11.74108 z m 0,22.75938 12,1.34794 0,-11.71622 -12,0 z m -12,-1.35943 10,1.12952 0,-10.13837 -10,0 z"
+ d="m 607,391 h 10 v -10.16502 l -10,1.1313 z m 12,-10.3911 V 391 h 12 v -11.74108 z m 0,22.75938 12,1.34794 V 393 h -12 z m -12,-1.35943 10,1.12952 V 393 h -10 z"
id="path5333-0" />
</g>
<g
- id="src/plugins/winrt/images/winrtdevicesmall">
- <rect
- id="rect5759-5-9-0-8-6-4-8-8-5"
- height="16"
- width="16"
- y="395"
- x="634"
- style="fill:#ffffff;fill-opacity:1" />
+ id="src/plugins/winrt/images/winrtdevicesmall"
+ transform="translate(-238,-58)">
+ <use
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect"
+ id="use6054-3"
+ width="100%"
+ height="100%"
+ transform="translate(650,-41)" />
<path
sodipodi:nodetypes="cccccccccccccccccccc"
style="fill:#000000;fill-opacity:1"
inkscape:connector-curvature="0"
- d="m 636.00003,403 4.99997,0 0,-4.67861 -4.99997,0.67433 z M 642,398.18129 642,403 l 6.00003,0 0,-5.6287 z m 0,10.72061 6.00003,0.81345 0,-5.71535 L 642,404 Z M 636.00003,408.09093 641,408.7667 641,404 l -4.99997,0 z"
+ d="M 636.00003,403 H 641 v -4.67861 l -4.99997,0.67433 z M 642,398.18129 V 403 h 6.00003 v -5.6287 z m 0,10.72061 6.00003,0.81345 V 404 H 642 Z M 636.00003,408.09093 641,408.7667 V 404 h -4.99997 z"
id="path5333" />
</g>
<g
diff --git a/src/tools/qml2puppet/qml2puppet/qml2puppet.pro b/src/tools/qml2puppet/qml2puppet/qml2puppet.pro
index 9644cf4bca4..af8591e8ec6 100644
--- a/src/tools/qml2puppet/qml2puppet/qml2puppet.pro
+++ b/src/tools/qml2puppet/qml2puppet/qml2puppet.pro
@@ -1,7 +1,7 @@
TARGET = qml2puppet
TEMPLATE = app
-
+QTC_LIB_DEPENDS += utils
include(../../../../qtcreator.pri)
osx: DESTDIR = $$IDE_LIBEXEC_PATH/qmldesigner
@@ -9,6 +9,7 @@ else: DESTDIR = $$IDE_LIBEXEC_PATH
include(../../../rpath.pri)
+include(../../../libs/qt-breakpad/qtbreakpad.pri)
include(../../../../share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pri)
isEmpty(PRECOMPILED_HEADER):PRECOMPILED_HEADER = $$PWD/../../../shared/qtcreator_pch.h
diff --git a/src/tools/qtcrashhandler/qtcrashhandler.pro b/src/tools/qtcrashhandler/qtcrashhandler.pro
index f6ba7590aeb..f2a75957d5f 100644
--- a/src/tools/qtcrashhandler/qtcrashhandler.pro
+++ b/src/tools/qtcrashhandler/qtcrashhandler.pro
@@ -1,9 +1,6 @@
TARGET = qtcrashhandler
TEMPLATE = app
-QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
-include($${QT_BREAKPAD_ROOT_PATH}/qtcrashhandler.pri)
-include(../../../qtcreator.pri)
-DESTDIR = $$IDE_BIN_PATH
-include(../../rpath.pri)
+include(../../qtcreatortool.pri)
+include(../../libs/qt-breakpad/qtcrashhandler.pri)
diff --git a/src/tools/sdktool/addcmakeoperation.cpp b/src/tools/sdktool/addcmakeoperation.cpp
index d6e6146d750..bddf275c51f 100644
--- a/src/tools/sdktool/addcmakeoperation.cpp
+++ b/src/tools/sdktool/addcmakeoperation.cpp
@@ -55,7 +55,7 @@ QString AddCMakeOperation::name() const
QString AddCMakeOperation::helpText() const
{
- return QString("add a cmake tool to Qt Creator");
+ return QString("add a cmake tool");
}
QString AddCMakeOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/adddebuggeroperation.cpp b/src/tools/sdktool/adddebuggeroperation.cpp
index a39af5a71d7..6ec0716491a 100644
--- a/src/tools/sdktool/adddebuggeroperation.cpp
+++ b/src/tools/sdktool/adddebuggeroperation.cpp
@@ -56,7 +56,7 @@ QString AddDebuggerOperation::name() const
QString AddDebuggerOperation::helpText() const
{
- return QLatin1String("add a debugger to Qt Creator");
+ return QLatin1String("add a debugger");
}
QString AddDebuggerOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/adddeviceoperation.cpp b/src/tools/sdktool/adddeviceoperation.cpp
index 34d0d26455c..91eff774cfe 100644
--- a/src/tools/sdktool/adddeviceoperation.cpp
+++ b/src/tools/sdktool/adddeviceoperation.cpp
@@ -50,7 +50,7 @@ QString AddDeviceOperation::name() const
QString AddDeviceOperation::helpText() const
{
- return QLatin1String("add a Device to Qt Creator");
+ return QLatin1String("add a Device");
}
QString AddDeviceOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/addkeysoperation.cpp b/src/tools/sdktool/addkeysoperation.cpp
index 8fa6f465560..b7abd5aacae 100644
--- a/src/tools/sdktool/addkeysoperation.cpp
+++ b/src/tools/sdktool/addkeysoperation.cpp
@@ -34,7 +34,7 @@ QString AddKeysOperation::name() const
QString AddKeysOperation::helpText() const
{
- return QLatin1String("add settings to Qt Creator configuration");
+ return QLatin1String("add arbitrary settings to configuration");
}
QString AddKeysOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/addkitoperation.cpp b/src/tools/sdktool/addkitoperation.cpp
index e46945e1a59..e5767be7e86 100644
--- a/src/tools/sdktool/addkitoperation.cpp
+++ b/src/tools/sdktool/addkitoperation.cpp
@@ -78,7 +78,7 @@ QString AddKitOperation::name() const
QString AddKitOperation::helpText() const
{
- return QString("add a Kit to Qt Creator");
+ return QString("add a Kit");
}
QString AddKitOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/addqtoperation.cpp b/src/tools/sdktool/addqtoperation.cpp
index 0039e4217c6..59a0b1b5550 100644
--- a/src/tools/sdktool/addqtoperation.cpp
+++ b/src/tools/sdktool/addqtoperation.cpp
@@ -63,7 +63,7 @@ QString AddQtOperation::name() const
QString AddQtOperation::helpText() const
{
- return QLatin1String("add a Qt version to Qt Creator");
+ return QLatin1String("add a Qt version");
}
QString AddQtOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/addtoolchainoperation.cpp b/src/tools/sdktool/addtoolchainoperation.cpp
index 60aba4558d3..51f98fe555b 100644
--- a/src/tools/sdktool/addtoolchainoperation.cpp
+++ b/src/tools/sdktool/addtoolchainoperation.cpp
@@ -61,7 +61,7 @@ QString AddToolChainOperation::name() const
QString AddToolChainOperation::helpText() const
{
- return QString("add a tool chain to Qt Creator");
+ return QString("add a tool chain");
}
QString AddToolChainOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/findkeyoperation.cpp b/src/tools/sdktool/findkeyoperation.cpp
index 1085b20f343..58d3b31ed24 100644
--- a/src/tools/sdktool/findkeyoperation.cpp
+++ b/src/tools/sdktool/findkeyoperation.cpp
@@ -34,7 +34,7 @@ QString FindKeyOperation::name() const
QString FindKeyOperation::helpText() const
{
- return QLatin1String("find a key in the settings of Qt Creator");
+ return QLatin1String("find a key in the settings");
}
QString FindKeyOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/findvalueoperation.cpp b/src/tools/sdktool/findvalueoperation.cpp
index e7d31892f73..e59a0fa115e 100644
--- a/src/tools/sdktool/findvalueoperation.cpp
+++ b/src/tools/sdktool/findvalueoperation.cpp
@@ -34,7 +34,7 @@ QString FindValueOperation::name() const
QString FindValueOperation::helpText() const
{
- return QLatin1String("find a value in the settings of Qt Creator");
+ return QLatin1String("find a value in the settings");
}
QString FindValueOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/getoperation.cpp b/src/tools/sdktool/getoperation.cpp
index b43346dd6f4..fb15d42142e 100644
--- a/src/tools/sdktool/getoperation.cpp
+++ b/src/tools/sdktool/getoperation.cpp
@@ -34,7 +34,7 @@ QString GetOperation::name() const
QString GetOperation::helpText() const
{
- return QLatin1String("get settings from Qt Creator configuration");
+ return QLatin1String("get settings from configuration");
}
QString GetOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/main.cpp b/src/tools/sdktool/main.cpp
index 0e5b4320fa6..f480543fbb6 100644
--- a/src/tools/sdktool/main.cpp
+++ b/src/tools/sdktool/main.cpp
@@ -45,6 +45,8 @@
#include "rmqtoperation.h"
#include "rmtoolchainoperation.h"
+#include <app/app_version.h>
+
#include <iostream>
#include <QCoreApplication>
@@ -52,7 +54,7 @@
void printHelp(const Operation *op)
{
- std::cout << "Qt Creator SDK setup tool." << std::endl;
+ std::cout << Core::Constants::IDE_DISPLAY_NAME << " SDK setup tool." << std::endl;
std::cout << "Help for operation " << qPrintable(op->name()) << std::endl;
std::cout << std::endl;
@@ -68,7 +70,7 @@ const QString tabular(const Operation *o)
void printHelp(const QList<Operation *> &operations)
{
- std::cout << "Qt Creator SDK setup tool." << std::endl;
+ std::cout << Core::Constants::IDE_DISPLAY_NAME << "SDK setup tool." << std::endl;
std::cout << " Usage: " << qPrintable(QCoreApplication::arguments().at(0))
<< " <ARGS> <OPERATION> <OPERATION_ARGS>" << std::endl << std::endl;
std::cout << "ARGS:" << std::endl;
diff --git a/src/tools/sdktool/rmcmakeoperation.cpp b/src/tools/sdktool/rmcmakeoperation.cpp
index dc41b748c36..2eaf84b9d03 100644
--- a/src/tools/sdktool/rmcmakeoperation.cpp
+++ b/src/tools/sdktool/rmcmakeoperation.cpp
@@ -48,7 +48,7 @@ QString RmCMakeOperation::name() const
QString RmCMakeOperation::helpText() const
{
- return QString("remove a cmake tool from Qt Creator");
+ return QString("remove a cmake tool");
}
QString RmCMakeOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/rmdebuggeroperation.cpp b/src/tools/sdktool/rmdebuggeroperation.cpp
index 129947271a5..8c2a6bea0d9 100644
--- a/src/tools/sdktool/rmdebuggeroperation.cpp
+++ b/src/tools/sdktool/rmdebuggeroperation.cpp
@@ -53,7 +53,7 @@ QString RmDebuggerOperation::name() const
QString RmDebuggerOperation::helpText() const
{
- return QLatin1String("remove a debugger from Qt Creator");
+ return QLatin1String("remove a debugger");
}
QString RmDebuggerOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/rmdeviceoperation.cpp b/src/tools/sdktool/rmdeviceoperation.cpp
index b678bb07fce..4558352ab33 100644
--- a/src/tools/sdktool/rmdeviceoperation.cpp
+++ b/src/tools/sdktool/rmdeviceoperation.cpp
@@ -39,7 +39,7 @@ QString RmDeviceOperation::name() const
QString RmDeviceOperation::helpText() const
{
- return QLatin1String("remove a Device from Qt Creator");
+ return QLatin1String("remove a Device");
}
QString RmDeviceOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/rmkeysoperation.cpp b/src/tools/sdktool/rmkeysoperation.cpp
index 138506bbb84..ff1f7f8baf9 100644
--- a/src/tools/sdktool/rmkeysoperation.cpp
+++ b/src/tools/sdktool/rmkeysoperation.cpp
@@ -34,7 +34,7 @@ QString RmKeysOperation::name() const
QString RmKeysOperation::helpText() const
{
- return QLatin1String("remove settings from Qt Creator configuration");
+ return QLatin1String("remove settings from configuration");
}
QString RmKeysOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/rmkitoperation.cpp b/src/tools/sdktool/rmkitoperation.cpp
index caa4c2f0e05..5abfe9ecdd0 100644
--- a/src/tools/sdktool/rmkitoperation.cpp
+++ b/src/tools/sdktool/rmkitoperation.cpp
@@ -57,7 +57,7 @@ QString RmKitOperation::name() const
QString RmKitOperation::helpText() const
{
- return QString("remove a Kit from Qt Creator");
+ return QString("remove a Kit");
}
QString RmKitOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/rmqtoperation.cpp b/src/tools/sdktool/rmqtoperation.cpp
index 50e6e66bfe8..292b8fdb3fe 100644
--- a/src/tools/sdktool/rmqtoperation.cpp
+++ b/src/tools/sdktool/rmqtoperation.cpp
@@ -47,7 +47,7 @@ QString RmQtOperation::name() const
QString RmQtOperation::helpText() const
{
- return QLatin1String("remove a Qt version from Qt Creator");
+ return QLatin1String("remove a Qt version");
}
QString RmQtOperation::argumentsHelpText() const
diff --git a/src/tools/sdktool/rmtoolchainoperation.cpp b/src/tools/sdktool/rmtoolchainoperation.cpp
index bb1e8d17281..1cefe020609 100644
--- a/src/tools/sdktool/rmtoolchainoperation.cpp
+++ b/src/tools/sdktool/rmtoolchainoperation.cpp
@@ -48,7 +48,7 @@ QString RmToolChainOperation::name() const
QString RmToolChainOperation::helpText() const
{
- return QString("remove a tool chain from Qt Creator");
+ return QString("remove a tool chain");
}
QString RmToolChainOperation::argumentsHelpText() const
diff --git a/src/tools/tools.pro b/src/tools/tools.pro
index cfe34abaa0a..23268020b79 100644
--- a/src/tools/tools.pro
+++ b/src/tools/tools.pro
@@ -41,8 +41,7 @@ isEmpty(BUILD_CPLUSPLUS_TOOLS):BUILD_CPLUSPLUS_TOOLS=$$(BUILD_CPLUSPLUS_TOOLS)
cplusplus-update-frontend
}
-QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
-!isEmpty(QT_BREAKPAD_ROOT_PATH) {
+!isEmpty(BREAKPAD_SOURCE_DIR) {
SUBDIRS += qtcrashhandler
} else {
linux-* {