diff options
author | Eike Ziller <eike.ziller@qt.io> | 2017-03-22 10:26:01 +0100 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2017-03-22 10:26:01 +0100 |
commit | edee1e805c13310525a0c01ed4db58f7d16eee5b (patch) | |
tree | 82b55fa6d3c1b6113dce9e41b6592e2b5b422a9e | |
parent | 4d3c297d024a86201d70d478beffa61176ac1e82 (diff) | |
parent | 26e76d3387c4053a334a08d2b0ca22b9e4b18f6c (diff) |
Merge remote-tracking branch 'origin/4.3'
Change-Id: I266a41de38789922363d1d88e73726cdca608920
67 files changed, 560 insertions, 703 deletions
diff --git a/doc/images/qtcreator-search-allprojects.png b/doc/images/qtcreator-search-allprojects.png Binary files differindex f78038af4b..c48cd50b47 100644 --- a/doc/images/qtcreator-search-allprojects.png +++ b/doc/images/qtcreator-search-allprojects.png diff --git a/doc/images/qtcreator-search-filesystem.png b/doc/images/qtcreator-search-filesystem.png Binary files differindex e51d0287af..b8a886c9c9 100644 --- a/doc/images/qtcreator-search-filesystem.png +++ b/doc/images/qtcreator-search-filesystem.png diff --git a/doc/images/qtcreator-searchresults.png b/doc/images/qtcreator-searchresults.png Binary files differindex 02835cbb4b..8a663c0e17 100644 --- a/doc/images/qtcreator-searchresults.png +++ b/doc/images/qtcreator-searchresults.png diff --git a/doc/src/editors/creator-editors.qdoc b/doc/src/editors/creator-editors.qdoc index 86e809b66f..34ff10542b 100644 --- a/doc/src/editors/creator-editors.qdoc +++ b/doc/src/editors/creator-editors.qdoc @@ -1570,36 +1570,54 @@ \list - \li \uicontrol {All Projects} searches files matching the - defined file pattern in all currently open projects. - - For example, to search for a string only in \c {.cpp} - and \c {.h} files, enter in \uicontrol {File pattern} - \c {*.cpp,*.h}. + \li \uicontrol {All Projects} searches from all currently open + projects. \image qtcreator-search-allprojects.png - \li \uicontrol {Current Project} searches files matching the - defined file pattern only in the project you are currently - editing. + \li \uicontrol {Current Project} searches from the project you + are currently editing. - \li \uicontrol {Files in File System} recursively searches files - matching the defined file pattern in the selected directory. + \li \uicontrol {Files in File System} recursively searches from + the selected directory. \image qtcreator-search-filesystem.png - Select the \uicontrol {Use Git Grep} check box to use Git to - only search tracked files in the Git work tree. To restrict - the search to the HEAD, a tag, a local or remote branch, or - a commit hash, enter a reference in the field. Leave the - field empty to search through the file system. + In the \uicontrol {Search engine} field, select the search + engine to use: + + \list + \li Select \uicontrol Internal to use the \QC search + engine. + + \li Select \uicontrol {Git Grep} to use Git to only + search tracked files in the Git work tree. To + restrict the search to the HEAD, a tag, a local or + remote branch, or a commit hash, enter a reference. + Leave the field empty to search through the file + system. + + \li Select \uicontrol {Silver Searcher} to use the + experimental Silver Searcher plugin. For more + information, see \l{Enabling Silver Searcher}. + + \endlist - \li \uicontrol {Current File} searches only the current file. + \li \uicontrol {Current File} searches only from the current + file. - \li \uicontrol {Open Documents} searches all open files. + \li \uicontrol {Open Documents} searches from all open files. \endlist + \li In the \uicontrol {File pattern} field, specify file patterns to + restrict the search to files that match the pattern. For example, to + search for a string only in \c {.cpp} and \c {.h} files, enter + \c {*.cpp,*.h}. + + \li In the \uicontrol {Exclusion pattern} field, specify file patterns + to omit files from the search. + \li Enter the text you are looking for and click \uicontrol Search. \image qtcreator-searchresults.png @@ -1628,6 +1646,32 @@ \note You can use \uicontrol {Advanced Find} also to search for symbols. For more information, see \l{Finding Symbols}. + \section1 Enabling Silver Searcher + + You can use Silver Searcher as a search engine in \QC if you install + Silver Searcher on the development PC and enable the experimental plugin. + + To use Silver Searcher: + + \list 1 + + \li Download and install Silver Searcher from + \l {https://geoff.greer.fm/ag/}{The Silver Searcher} or + \l {https://github.com/ggreer/the_silver_searcher}{GitHub}. + + You might have to build Silver Searcher from sources for some + platforms. + + \li Select \uicontrol Help > \uicontrol {About Plugins} > + \uicontrol {Utilities} > \uicontrol {SilverSearcher} to enable the + plugin. + + \li Restart \QC to be able to use the plugin. + + \li When searching, select \uicontrol {Silver Searcher} in the + \uicontrol {Search engine} field. + + \endlist */ diff --git a/doc/src/howto/creator-autotest.qdoc b/doc/src/howto/creator-autotest.qdoc index 22335df271..b4cebaaac2 100644 --- a/doc/src/howto/creator-autotest.qdoc +++ b/doc/src/howto/creator-autotest.qdoc @@ -85,10 +85,9 @@ \endlist - \QC creates the test in the \c{tests\auto} directory in the project - directory. Edit the .cpp file to add private slots for each test - function in your test. For more information about creating Qt tests, see - \l{Creating a Test}. + \QC creates the test in the specified project directory. Edit the .cpp file + to add private slots for each test function in your test. For more information + about creating Qt tests, see \l{Creating a Test}. \section2 Creating Google Tests @@ -133,8 +132,7 @@ \endlist - \QC creates the test in the \c{tests\auto} directory in the project - directory. + \QC creates the test in the specified project directory. \section1 Setting Up the Google C++ Testing Framework diff --git a/share/qtcreator/debugger/cdbbridge.py b/share/qtcreator/debugger/cdbbridge.py index 55a531e63a..0849b532c2 100644 --- a/share/qtcreator/debugger/cdbbridge.py +++ b/share/qtcreator/debugger/cdbbridge.py @@ -318,28 +318,6 @@ class Dumper(DumperBase): % (self.qtCoreModuleName(), namespace)) return namespace - def couldBeQObjectVTable(self, vtablePtr): - try: - customEventFunc = self.extractPointer(vtablePtr + 8 * self.ptrSize()) - except: - self.bump('nostruct-3') - return False - - if customEventFunc in (self.qtCustomEventFunc, self.qtCustomEventPltFunc): - return True - try: - delta = int.from_bytes(self.readRawMemory(customEventFunc + 1, 4), byteorder='little') - if (customEventFunc + 5 + delta) in (self.qtCustomEventFunc, self.qtCustomEventPltFunc): - return True - except: - pass - - try: - return 'QObject::customEvent' in cdbext.getNameByAddress(customEventFunc) - except: - return False - - def qtVersion(self): qtVersion = self.findValueByExpression('((void**)&%s)[2]' % self.qtHookDataSymbolName()) if qtVersion is None and self.qtCoreModuleName() is not None: diff --git a/share/qtcreator/debugger/creatortypes.py b/share/qtcreator/debugger/creatortypes.py index 652c30bc0a..8b7d5d67e1 100644 --- a/share/qtcreator/debugger/creatortypes.py +++ b/share/qtcreator/debugger/creatortypes.py @@ -37,7 +37,7 @@ def extractPointerType(d, value): postfix = "" while stripTypeName(value) == "CPlusPlus::PointerType": postfix += "*" - value = d.downcast(value["_elementType"]["_type"]) + value = value["_elementType"]["_type"] try: return readLiteral(d, value["_name"]) + postfix except: @@ -60,7 +60,7 @@ def readTemplateName(d, value): for i in range(int(size)): if i > 0: name += ", " - name += extractPointerType(d, d.downcast(start[i]["_type"])) + name += extractPointerType(d, start[i]["_type"]) except: return "<not accessible>" name += ">" @@ -69,7 +69,6 @@ def readTemplateName(d, value): def readLiteral(d, value): if d.isNull(value): return "<null>" - value = d.downcast(value) type = value.type.unqualified() try: type = type.target() @@ -147,7 +146,7 @@ def qdump__CPlusPlus__IntegerType(d, value): d.putPlainChildren(value) def qdump__CPlusPlus__FullySpecifiedType(d, value): - type = d.downcast(value["_type"]) + type = value["_type"] typeName = stripTypeName(type) if typeName == "CPlusPlus::NamedType": dumpLiteral(d, type["_name"]) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 8392aceb96..aaad6180b0 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -1494,12 +1494,49 @@ class DumperBase: return self.couldBeQObjectVTable(vtablePtr) def couldBeQObjectVTable(self, vtablePtr): + def getJumpAddress_x86(dumper, address): + relativeJumpCode = 0xe9 + jumpCode = 0xff + data = dumper.readRawMemory(address, 6) + primaryOpcode = data[0] + if primaryOpcode == relativeJumpCode: + # relative jump on 32 and 64 bit with a 32bit offset + offset = int.from_bytes(data[1:5], byteorder='little') + return address + 5 + offset + if primaryOpcode == jumpCode: + if data[1] != 0x25: # check for known extended opcode + return 0 + # 0xff25 is a relative jump on 64bit and an absolute jump on 32 bit + if self.ptrSize() == 8: + offset = int.from_bytes(data[2:6], byteorder='little') + return address + 6 + offset + else: + return int.from_bytes(data[2:6], byteorder='little') + return 0 + + # Do not try to extract a function pointer if there are no values to compare with + if self.qtCustomEventFunc == 0 and self.qtCustomEventPltFunc == 0: + return False + try: - customEventFunc = self.extractPointer(vtablePtr + 9 * self.ptrSize()) + customEventOffset = 8 if self.isMsvcTarget() else 9 + customEventFunc = self.extractPointer(vtablePtr + customEventOffset * self.ptrSize()) except: self.bump('nostruct-3') return False + if self.isWindowsTarget(): + if customEventFunc in (self.qtCustomEventFunc, self.qtCustomEventPltFunc): + return True + # The vtable may point to a function that is just calling the customEvent function + customEventFunc = getJumpAddress_x86(self, customEventFunc) + if customEventFunc in (self.qtCustomEventFunc, self.qtCustomEventPltFunc): + return True + customEventFunc = self.extractPointer(customEventFunc) + if customEventFunc in (self.qtCustomEventFunc, self.qtCustomEventPltFunc): + return True + # If the object is defined in another module there may be another level of indirection + customEventFunc = getJumpAddress_x86(self, customEventFunc) return customEventFunc in (self.qtCustomEventFunc, self.qtCustomEventPltFunc) # def extractQObjectProperty(objectPtr): @@ -3121,10 +3158,6 @@ class DumperBase: val.type = self.dumper.createType(typish) return val - def downcast(self): - self.check() - return self - def address(self): self.check() return self.laddress diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 0877634a3c..69443b6cdc 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -487,12 +487,20 @@ def qdump__QFile(d, value): # 9fc0965 and a373ffcd change the layout of the private structure qtVersion = d.qtVersion() is32bit = d.ptrSize() == 4 - if qtVersion >= 0x050600: + if qtVersion >= 0x050700: if d.isWindowsTarget(): if d.isMsvcTarget(): offset = 184 if is32bit else 248 else: - offset = 164 if is32bit else 248 + offset = 172 if is32bit else 248 + else: + offset = 168 if is32bit else 248 + elif qtVersion >= 0x050600: + if d.isWindowsTarget(): + if d.isMsvcTarget(): + offset = 184 if is32bit else 248 + else: + offset = 180 if is32bit else 248 else: offset = 168 if is32bit else 248 elif qtVersion >= 0x050500: diff --git a/share/qtcreator/templates/wizards/autotest/files/auto.pro b/share/qtcreator/templates/wizards/autotest/files/auto.pro deleted file mode 100644 index 510a371006..0000000000 --- a/share/qtcreator/templates/wizards/autotest/files/auto.pro +++ /dev/null @@ -1,3 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += %{JS: '%{TestCaseName}'.toLowerCase()} diff --git a/share/qtcreator/templates/wizards/autotest/files/auto.qbs b/share/qtcreator/templates/wizards/autotest/files/auto.qbs deleted file mode 100644 index 319bfbd1d4..0000000000 --- a/share/qtcreator/templates/wizards/autotest/files/auto.qbs +++ /dev/null @@ -1,26 +0,0 @@ -import qbs -@if "%{TestFrameWork}" == "GTest" -import qbs.Environment -@endif - -Project { - name: "auto tests" - -@if "%{TestFrameWork}" == "GTest" - property string googletestDir: { - if (typeof Environment.getEnv("GOOGLETEST_DIR") === 'undefined') { - console.warn("Using googletest src dir specified at Qt Creator wizard") - console.log("set GOOGLETEST_DIR as environment variable or Qbs property to get rid of this message") - return "%{GTestRepository}" - } else { - return Environment.getEnv("GOOGLETEST_DIR") - } - } -@endif -@if "%{BuildAutoTests}" == "debug" - condition: qbs.buildVariant === "debug" -@endif - references: [ - "%{JS: '%{TestCaseName}'.toLowerCase()}/%{JS: '%{TestCaseName}'.toLowerCase()}.qbs" - ] -} diff --git a/share/qtcreator/templates/wizards/autotest/files/main.cpp b/share/qtcreator/templates/wizards/autotest/files/main.cpp deleted file mode 100644 index 8a4a5671fc..0000000000 --- a/share/qtcreator/templates/wizards/autotest/files/main.cpp +++ /dev/null @@ -1,31 +0,0 @@ -%{Cpp:LicenseTemplate}\ -@if "%{TestFrameWork}" == "QtTest" -@if "%{RequireGUI}" == "true" -%{JS: QtSupport.qtIncludes([ 'QtGui/QApplication' ], - [ 'QtWidgets/QApplication' ]) }\ -@else -%{JS: QtSupport.qtIncludes([ 'QtCore/QCoreApplication' ], - [ 'QtCore/QCoreApplication' ]) }\ -@endif -// add necessary includes here - -int main(int argc, char *argv[]) -{ -@if "%{RequireGUI}" == "true" - QApplication a(argc, argv); -@else - QCoreApplication a(argc, argv); -@endif - - return a.exec(); -} -@else -#include <iostream> - -int main(int , char **) -{ - std::cout << "Hello World!\\n"; - - return 0; -} -@endif diff --git a/share/qtcreator/templates/wizards/autotest/files/src.pro b/share/qtcreator/templates/wizards/autotest/files/src.pro deleted file mode 100644 index 8d66476066..0000000000 --- a/share/qtcreator/templates/wizards/autotest/files/src.pro +++ /dev/null @@ -1,18 +0,0 @@ -@if "%{TestFrameWork}" == "QtTest" -@if "%{RequireGUI}" == "true" -QT += core gui -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -@else -QT -= gui -@endif -@else -CONFIG -= qt -@endif -CONFIG += console c++11 -CONFIG -= app_bundle - -TEMPLATE = app - -TARGET = %{ProjectName} - -SOURCES += %{MainCppName} diff --git a/share/qtcreator/templates/wizards/autotest/files/src.qbs b/share/qtcreator/templates/wizards/autotest/files/src.qbs deleted file mode 100644 index 36e44e774b..0000000000 --- a/share/qtcreator/templates/wizards/autotest/files/src.qbs +++ /dev/null @@ -1,27 +0,0 @@ -import qbs - -CppApplication { - type: "application" - consoleApplication: true - name: "%{ProjectName}" -@if "%{TestFrameWork}" == "QtTest" -@if "%{RequireGUI}" == "true" - - Depends { name: "Qt.core" } - Depends { name: "Qt.gui" } - Depends { - name: "Qt.widgets" - condition: Qt.core.versionMajor > 4 - } -@else - - Depends { name: "Qt.core" } -@endif -@endif - - cpp.cxxLanguageVersion: "c++11" - - files: [ - "%{MainCppName}" - ] -} diff --git a/share/qtcreator/templates/wizards/autotest/files/tests.pro b/share/qtcreator/templates/wizards/autotest/files/tests.pro deleted file mode 100644 index f927700008..0000000000 --- a/share/qtcreator/templates/wizards/autotest/files/tests.pro +++ /dev/null @@ -1,3 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += auto diff --git a/share/qtcreator/templates/wizards/autotest/files/tests.qbs b/share/qtcreator/templates/wizards/autotest/files/tests.qbs deleted file mode 100644 index 6a83cf65ef..0000000000 --- a/share/qtcreator/templates/wizards/autotest/files/tests.qbs +++ /dev/null @@ -1,8 +0,0 @@ -import qbs - -Project { - name: "%{ProjectName} tests" - references: [ - "auto/auto.qbs" - ] -} diff --git a/share/qtcreator/templates/wizards/autotest/files/tmp.pro b/share/qtcreator/templates/wizards/autotest/files/tmp.pro deleted file mode 100644 index 4832797c02..0000000000 --- a/share/qtcreator/templates/wizards/autotest/files/tmp.pro +++ /dev/null @@ -1,12 +0,0 @@ -TEMPLATE = subdirs - -@if "%{BuildAutoTests}" == "always" -SUBDIRS += src \ - tests -@else -SUBDIRS += src - -CONFIG(debug, debug|release) { - SUBDIRS += tests -} -@endif diff --git a/share/qtcreator/templates/wizards/autotest/files/tmp.qbs b/share/qtcreator/templates/wizards/autotest/files/tmp.qbs deleted file mode 100644 index dfc99c15df..0000000000 --- a/share/qtcreator/templates/wizards/autotest/files/tmp.qbs +++ /dev/null @@ -1,8 +0,0 @@ -import qbs - -Project { - references: [ - "src/src.qbs", - "tests/tests.qbs" - ] -} diff --git a/share/qtcreator/templates/wizards/autotest/files/tst.pro b/share/qtcreator/templates/wizards/autotest/files/tst.pro index 5f0f7455f4..695f0f7ffd 100644 --- a/share/qtcreator/templates/wizards/autotest/files/tst.pro +++ b/share/qtcreator/templates/wizards/autotest/files/tst.pro @@ -14,7 +14,7 @@ TEMPLATE = app SOURCES += %{TestCaseFileWithCppSuffix} @else -include(../gtest_dependency.pri) +include(gtest_dependency.pri) TEMPLATE = app @if "%{GTestCXX11}" == "true" diff --git a/share/qtcreator/templates/wizards/autotest/files/tst.qbs b/share/qtcreator/templates/wizards/autotest/files/tst.qbs index 1000451bc6..58a647df86 100644 --- a/share/qtcreator/templates/wizards/autotest/files/tst.qbs +++ b/share/qtcreator/templates/wizards/autotest/files/tst.qbs @@ -1,6 +1,7 @@ import qbs @if "%{TestFrameWork}" == "GTest" -import "../googlecommon.js" as googleCommon +import qbs.Environment +import "googlecommon.js" as googleCommon @endif CppApplication { @@ -16,6 +17,19 @@ CppApplication { ] @else consoleApplication: true + +@if "%{TestFrameWork}" == "GTest" + property string googletestDir: { + if (typeof Environment.getEnv("GOOGLETEST_DIR") === 'undefined') { + console.warn("Using googletest src dir specified at Qt Creator wizard") + console.log("set GOOGLETEST_DIR as environment variable or Qbs property to get rid of this message") + return "%{GTestRepository}" + } else { + return Environment.getEnv("GOOGLETEST_DIR") + } + } +@endif + @if "%{GTestCXX11}" == "true" cpp.cxxLanguageVersion: "c++11" cpp.defines: [ "GTEST_LANG_CXX11" ] @@ -23,13 +37,13 @@ CppApplication { cpp.dynamicLibraries: [ "pthread" ] - cpp.includePaths: [].concat(googleCommon.getGTestIncludes(project.googletestDir)) - .concat(googleCommon.getGMockIncludes(project.googletestDir)) + cpp.includePaths: [].concat(googleCommon.getGTestIncludes(googletestDir)) + .concat(googleCommon.getGMockIncludes(googletestDir)) files: [ "%{MainCppName}", "%{TestCaseFileWithHeaderSuffix}", - ].concat(googleCommon.getGTestAll(project.googletestDir)) - .concat(googleCommon.getGMockAll(project.googletestDir)) + ].concat(googleCommon.getGTestAll(googletestDir)) + .concat(googleCommon.getGMockAll(googletestDir)) @endif } diff --git a/share/qtcreator/templates/wizards/autotest/files/tst.txt b/share/qtcreator/templates/wizards/autotest/files/tst.txt new file mode 100644 index 0000000000..8c13344d41 --- /dev/null +++ b/share/qtcreator/templates/wizards/autotest/files/tst.txt @@ -0,0 +1,57 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.1) + +PROJECT(%{TestCaseName} + LANGUAGES CXX) + +@if "%{TestFrameWork}" == "QtTest" + +find_package(Qt5Test REQUIRED) +@if "%{RequireGUI}" == "true" +find_package(Qt5Gui REQUIRED) +@endif + +SET(CMAKE_AUTOMOC ON) +SET(CMAKE_INCLUDE_CURRENT_DIR ON) +SET(CMAKE_CXX_STANDARD 11) +ENABLE_TESTING() + +add_executable(${PROJECT_NAME} %{TestCaseFileWithCppSuffix}) +add_test(${PROJECT_NAME} COMMAND ${PROJECT_NAME}) + +@if "%{RequireGUI}" == "true" +target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Gui Qt5::Test) +@else +target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Test) +@endif + +@else + +@if "%{GTestCXX11}" == "true" +add_definitions(-DGTEST_LANGUAGE_CXX11) +@endif + +find_package(Threads REQUIRED) + +if ($ENV{GOOGLETEST_DIR}) + SET(GOOGLETEST_DIR $ENV{GOOGLETEST_DIR}) +else () + message(WARNING "Using googletest src dir specified at Qt Creator wizard") + SET(GOOGLETEST_DIR "%{GTestRepository}") +endif () +if (EXISTS ${GOOGLETEST_DIR}) + SET(GTestSrc ${GOOGLETEST_DIR}/googletest) + SET(GMockSrc ${GOOGLETEST_DIR}/googlemock) +else () + message( FATAL_ERROR "No googletest src dir found - set GOOGLETEST_DIR to enable!") +endif () + + +include_directories(${GTestSrc} ${GTestSrc}/include ${GMockSrc} ${GMockSrc}/include) + +add_executable(${PROJECT_NAME} %{MainCppName} %{TestCaseFileWithHeaderSuffix} + ${GTestSrc}/src/gtest-all.cc + ${GMockSrc}/src/gmock-all.cc) +add_test(${PROJECT_NAME} COMMAND ${PROJECT_NAME}) +target_link_libraries(${PROJECT_NAME} PRIVATE Threads::Threads) + +@endif diff --git a/share/qtcreator/templates/wizards/autotest/wizard.json b/share/qtcreator/templates/wizards/autotest/wizard.json index 1f0d9cf5b5..8e593342d1 100644 --- a/share/qtcreator/templates/wizards/autotest/wizard.json +++ b/share/qtcreator/templates/wizards/autotest/wizard.json @@ -3,7 +3,7 @@ "supportedProjectTypes": [ "Qt4ProjectManager.Qt4Project" ], "id": "R.AutoTest", "category": "H.Project", - "trDescription": "Creates a new project including an auto test skeleton.", + "trDescription": "Creates a new unit test project. Unit tests allow you to verify that the code is fit for use and that there are no regressions.", "trDisplayName": "Auto Test Project", "trDisplayCategory": "Other Project", "icon": "autotest_24.png", @@ -13,7 +13,7 @@ "options": [ { "key": "ProjectFilePath", - "value": "%{JS: '%{BuildSystem}' == 'qmake' ? '%{ProFileName}' : '%{QbsFileName}' }" + "value": "%{JS: '%{BuildSystem}' == 'qmake' ? '%{ProFileName}' : ('%{BuildSystem}' == 'qbs' ? '%{QbsFileName}' : '%{CMakeFileName}') }" }, { "key": "ProFileName", "value": "%{JS: Util.fileName('%{ProjectDirectory}/%{ProjectName}', 'pro')}" @@ -22,6 +22,10 @@ "key": "QbsFileName", "value": "%{JS: Util.fileName('%{ProjectDirectory}/%{ProjectName}', 'qbs')}" }, + { + "key": "CMakeFileName", + "value": "%{ProjectDirectory}/CMakeLists.txt" + }, { "key": "IsTopLevelProject", "value": "%{JS: !'%{Exists:ProjectExplorer.Profile.Ids}' }" }, @@ -46,7 +50,7 @@ "typeId": "Project", "data": { - "trDescription": "This wizard creates a simple project with an additional auto test skeleton." + "trDescription": "This wizard creates a simple unit test project." } }, { @@ -134,26 +138,6 @@ } }, { - "name": "BuildAutoTests", - "trDisplayName": "Build auto tests", - "type": "ComboBox", - "data": - { - "index": 0, - "items": - [ - { - "trKey": "always", - "value": "always" - }, - { - "trKey": "debug only", - "value": "debug" - } - ] - } - }, - { "name": "GTestRepository", "trDisplayName": "Googletest repository:", "visible": "%{JS: '%{TestFrameWork}' === 'GTest'}", @@ -179,6 +163,11 @@ "trKey": "Qbs", "value": "qbs", "condition": "%{JS: [ %{Plugins} ].indexOf('QbsProjectManager') >= 0}" + }, + { + "trKey": "CMake", + "value": "cmake", + "condition": "%{JS: [ %{Plugins} ].indexOf('CMakeProjectManager') >= 0}" } ] } @@ -191,7 +180,8 @@ "typeId": "Kits", "enabled": "%{IsTopLevelProject}", "data": { - "projectFilePath": "%{ProjectFilePath}" + "projectFilePath": "%{ProjectFilePath}", + "requiredFeatures": [ "%{JS: ('%{BuildSystem}' == 'cmake' && '%{TestFrameWork}' == 'QtTest') ? 'QtSupport.Wizards.FeatureQt.5' : 'QtSupport.Wizards.FeatureQt' }" ] } }, { @@ -207,97 +197,53 @@ "data": [ { - "source": "files/tmp.pro", - "target": "%{ProFileName}", - "condition": "%{JS: '%{BuildSystem}' == 'qmake'}", - "openAsProject": true - }, - { - "source": "files/tmp.qbs", - "target": "%{QbsFileName}", - "condition": "%{JS: '%{BuildSystem}' == 'qbs'}", - "openAsProject": true - }, - { - "source": "files/src.pro", - "target": "src/src.pro", - "condition": "%{JS: '%{BuildSystem}' == 'qmake'}", - "openInEditor": false - }, - { - "source": "files/src.qbs", - "target": "src/src.qbs", - "condition": "%{JS: '%{BuildSystem}' == 'qbs'}", - "openInEditor": false - }, - { - "source": "files/main.cpp", - "target": "src/%{MainCppName}", - "openInEditor": true - }, - { - "source": "files/tests.pro", - "target": "tests/tests.pro", - "condition": "%{JS: '%{BuildSystem}' == 'qmake'}", - "openInEditor": false - }, - { - "source": "files/tests.qbs", - "target": "tests/tests.qbs", - "condition": "%{JS: '%{BuildSystem}' == 'qbs'}", - "openInEditor": false - }, - { - "source": "files/auto.pro", - "target": "tests/auto/auto.pro", - "condition": "%{JS: '%{BuildSystem}' == 'qmake'}", - "openInEditor": false - }, - { - "source": "files/auto.qbs", - "target": "tests/auto/auto.qbs", - "condition": "%{JS: '%{BuildSystem}' == 'qbs'}", - "openInEditor": false - }, - { "source": "files/gtest_dependency.pri", - "target": "tests/auto/gtest_dependency.pri", + "target": "gtest_dependency.pri", "condition": "%{JS: '%{TestFrameWork}' == 'GTest' && '%{BuildSystem}' == 'qmake'}", "openInEditor": false }, { "source": "files/googlecommon.js", - "target": "tests/auto/googlecommon.js", + "target": "googlecommon.js", "condition": "%{JS: '%{TestFrameWork}' == 'GTest' && '%{BuildSystem}' == 'qbs'}", "openInEditor": false }, { "source": "files/tst.pro", - "target": "%{JS: 'tests/auto/' + '%{TestCaseName}/%{TestCaseName}'.toLowerCase() + '.pro' }", + "target": "%{ProjectFilePath}", "condition": "%{JS: '%{BuildSystem}' == 'qmake'}", - "openInEditor": false + "openInEditor": false, + "openAsProject": true }, { "source": "files/tst.qbs", - "target": "%{JS: 'tests/auto/' + '%{TestCaseName}/%{TestCaseName}'.toLowerCase() + '.qbs' }", + "target": "%{ProjectFilePath}", "condition": "%{JS: '%{BuildSystem}' == 'qbs'}", - "openInEditor": false + "openInEditor": false, + "openAsProject": true + }, + { + "source": "files/tst.txt", + "target": "CMakeLists.txt", + "condition": "%{JS: '%{BuildSystem}' == 'cmake'}", + "openInEditor": false, + "openAsProject": true }, { "source": "files/tst_src.h", - "target": "%{JS: 'tests/auto/' + '%{TestCaseName}/'.toLowerCase() + '%{TestCaseFileWithHeaderSuffix}' }", + "target": "%{TestCaseFileWithHeaderSuffix}", "condition": "%{JS: '%{TestFrameWork}' == 'GTest'}", "openInEditor": true }, { "source": "files/tst_src.cpp", - "target": "%{JS: 'tests/auto/' + '%{TestCaseName}/'.toLowerCase() + '%{TestCaseFileWithCppSuffix}' }", + "target": "%{TestCaseFileWithCppSuffix}", "condition": "%{JS: '%{TestFrameWork}' == 'QtTest'}", "openInEditor": true }, { "source": "files/tst_main.cpp", - "target": "%{JS: 'tests/auto/' + '%{TestCaseName}'.toLowerCase() + '/%{MainCppName}' }", + "target": "%{MainCppName}", "condition": "%{JS: '%{TestFrameWork}' == 'GTest'}", "openInEditor": true }, diff --git a/src/libs/modelinglib/qmt/controller/namecontroller.cpp b/src/libs/modelinglib/qmt/controller/namecontroller.cpp index 6871bc035a..2285fb3971 100644 --- a/src/libs/modelinglib/qmt/controller/namecontroller.cpp +++ b/src/libs/modelinglib/qmt/controller/namecontroller.cpp @@ -62,10 +62,7 @@ QString NameController::convertFileNameToElementName(const QString &fileName) elementName += baseName.at(i).toTitleCase(); makeTitlecase = false; } else { - if (insertSpace) { - elementName += QLatin1Char(' '); - insertSpace = false; - } + // insertSpace must be false here elementName += baseName.at(i); } } diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp index 8f6c935417..f94666c6a9 100644 --- a/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp +++ b/src/libs/modelinglib/qmt/diagram_scene/items/classitem.cpp @@ -589,7 +589,7 @@ void ClassItem::updateMembers(const Style *style) bool addSpace = false; if (currentVisibility) *currentVisibility = member.visibility(); - if (member.group() != currentGroup) { + if (currentGroup && member.group() != *currentGroup) { *text += QString(QStringLiteral("[%1]")).arg(member.group()); addNewline = true; *currentGroup = member.group(); diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp index a3bc33f0c1..abe01ada6e 100644 --- a/src/libs/utils/basetreeview.cpp +++ b/src/libs/utils/basetreeview.cpp @@ -26,6 +26,7 @@ #include "basetreeview.h" #include "progressindicator.h" +#include "treemodel.h" #include <utils/qtcassert.h> @@ -271,35 +272,14 @@ BaseTreeView::~BaseTreeView() void BaseTreeView::setModel(QAbstractItemModel *m) { - struct ExtraConnection { - const char *signature; - const char *qsignal; - QObject *receiver; - const char *qslot; - }; -#define DESC(sign, receiver, slot) { #sign, SIGNAL(sign), receiver, SLOT(slot) } - const ExtraConnection c[] = { - DESC(requestExpansion(QModelIndex), this, expand(QModelIndex)) - }; -#undef DESC - - QAbstractItemModel *oldModel = model(); - if (oldModel) { - for (unsigned i = 0; i < sizeof(c) / sizeof(c[0]); ++i) { - int index = model()->metaObject()->indexOfSignal(c[i].signature); - if (index != -1) - disconnect(model(), c[i].qsignal, c[i].receiver, c[i].qslot); - } - } + if (BaseTreeModel *oldModel = qobject_cast<BaseTreeModel *>(model())) + disconnect(oldModel, &BaseTreeModel::requestExpansion, this, &BaseTreeView::expand); TreeView::setModel(m); if (m) { - for (unsigned i = 0; i < sizeof(c) / sizeof(c[0]); ++i) { - int index = m->metaObject()->indexOfSignal(c[i].signature); - if (index != -1) - connect(model(), c[i].qsignal, c[i].receiver, c[i].qslot); - } + if (BaseTreeModel *newModel = qobject_cast<BaseTreeModel *>(m)) + connect(newModel, &BaseTreeModel::requestExpansion, this, &BaseTreeView::expand); d->restoreState(); QVariant delegateBlob = m->data(QModelIndex(), ItemDelegateRole); diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp index 3b2de69ec7..85813004de 100644 --- a/src/libs/utils/stringutils.cpp +++ b/src/libs/utils/stringutils.cpp @@ -183,7 +183,7 @@ bool AbstractMacroExpander::expandNestedMacros(const QString &str, int *pos, QSt if (!expandNestedMacros(str, &i, ret)) return false; varName.chop(1); - varName += ret; + varName += *ret; } else if (currArg == &varName && c == '-' && prev == ':' && validateVarName(varName)) { varName.chop(1); currArg = &defaultValue; diff --git a/src/plugins/autotest/quick/quicktestparser.cpp b/src/plugins/autotest/quick/quicktestparser.cpp index c3440ce15d..cb7e5a0464 100644 --- a/src/plugins/autotest/quick/quicktestparser.cpp +++ b/src/plugins/autotest/quick/quicktestparser.cpp @@ -37,13 +37,9 @@ #include <utils/hostosinfo.h> #include <utils/qtcassert.h> -#include <QFileSystemWatcher> - namespace Autotest { namespace Internal { -static QFileSystemWatcher s_directoryWatcher; - TestTreeItem *QuickTestParseResult::createTestTreeItem() const { if (itemType == TestTreeItem::Root || itemType == TestTreeItem::TestDataTag) @@ -126,7 +122,7 @@ static QString quickTestName(const CPlusPlus::Document::Ptr &doc) return QString(); } -static QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const QString &srcDir) +QList<QmlJS::Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const QString &srcDir) const { QStringList dirs(srcDir); QmlJS::ModelManagerInterface *qmlJsMM = QmlJSTools::Internal::ModelManager::instance(); @@ -142,9 +138,9 @@ static QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const QStri while (it.hasNext()) { it.next(); QFileInfo fi(it.fileInfo().canonicalFilePath()); - dirs << fi.filePath(); + dirs.append(fi.filePath()); } - s_directoryWatcher.addPaths(dirs); + emit updateWatchPaths(dirs); QList<QmlJS::Document::Ptr> foundDocs; @@ -211,9 +207,9 @@ static bool checkQmlDocumentForQuickTestCode(QFutureInterface<TestParseResultPtr return true; } -static bool handleQtQuickTest(QFutureInterface<TestParseResultPtr> futureInterface, - CPlusPlus::Document::Ptr document, - const Core::Id &id) +bool QuickTestParser::handleQtQuickTest(QFutureInterface<TestParseResultPtr> futureInterface, + CPlusPlus::Document::Ptr document, + const Core::Id &id) const { const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance(); if (quickTestName(document).isEmpty()) @@ -229,32 +225,35 @@ static bool handleQtQuickTest(QFutureInterface<TestParseResultPtr> futureInterfa if (srcDir.isEmpty()) return false; + if (futureInterface.isCanceled()) + return false; const QList<QmlJS::Document::Ptr> qmlDocs = scanDirectoryForQuickTestQmlFiles(srcDir); bool result = false; - for (const QmlJS::Document::Ptr &qmlJSDoc : qmlDocs) + for (const QmlJS::Document::Ptr &qmlJSDoc : qmlDocs) { + if (futureInterface.isCanceled()) + break; result |= checkQmlDocumentForQuickTestCode(futureInterface, qmlJSDoc, id, proFile); + } return result; } QuickTestParser::QuickTestParser() : CppParser() { - QObject::connect(ProjectExplorer::SessionManager::instance(), - &ProjectExplorer::SessionManager::startupProjectChanged, [] { - const QStringList &dirs = s_directoryWatcher.directories(); + connect(ProjectExplorer::SessionManager::instance(), + &ProjectExplorer::SessionManager::startupProjectChanged, [this] { + const QStringList &dirs = m_directoryWatcher.directories(); if (!dirs.isEmpty()) - s_directoryWatcher.removePaths(dirs); + m_directoryWatcher.removePaths(dirs); }); - QObject::connect(&s_directoryWatcher, &QFileSystemWatcher::directoryChanged, + connect(&m_directoryWatcher, &QFileSystemWatcher::directoryChanged, [this] { TestTreeModel::instance()->parser()->emitUpdateTestTree(this); }); + connect(this, &QuickTestParser::updateWatchPaths, + &m_directoryWatcher, &QFileSystemWatcher::addPaths, Qt::QueuedConnection); } QuickTestParser::~QuickTestParser() { - QObject::disconnect(&s_directoryWatcher, 0, 0, 0); - const QStringList &dirs = s_directoryWatcher.directories(); - if (!dirs.isEmpty()) - s_directoryWatcher.removePaths(dirs); } void QuickTestParser::init(const QStringList &filesToParse) diff --git a/src/plugins/autotest/quick/quicktestparser.h b/src/plugins/autotest/quick/quicktestparser.h index 9258599e71..26ba514f2f 100644 --- a/src/plugins/autotest/quick/quicktestparser.h +++ b/src/plugins/autotest/quick/quicktestparser.h @@ -29,6 +29,8 @@ #include <qmljs/qmljsdocument.h> +#include <QFileSystemWatcher> + namespace Autotest { namespace Internal { @@ -39,8 +41,9 @@ public: TestTreeItem *createTestTreeItem() const override; }; -class QuickTestParser : public CppParser +class QuickTestParser : public QObject, public CppParser { + Q_OBJECT public: QuickTestParser(); virtual ~QuickTestParser(); @@ -48,9 +51,15 @@ public: void release() override; bool processDocument(QFutureInterface<TestParseResultPtr> futureInterface, const QString &fileName) override; +signals: + void updateWatchPaths(const QStringList &directories) const; private: + bool handleQtQuickTest(QFutureInterface<TestParseResultPtr> futureInterface, + CPlusPlus::Document::Ptr document, const Core::Id &id) const; + QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const QString &srcDir) const; QmlJS::Snapshot m_qmlSnapshot; QHash<QString, QString> m_proFilesForQmlFiles; + QFileSystemWatcher m_directoryWatcher; }; } // namespace Internal diff --git a/src/plugins/bineditor/bineditorwidget.cpp b/src/plugins/bineditor/bineditorwidget.cpp index 1814614296..e647432723 100644 --- a/src/plugins/bineditor/bineditorwidget.cpp +++ b/src/plugins/bineditor/bineditorwidget.cpp @@ -645,7 +645,7 @@ int BinEditorWidget::dataLastIndexOf(const QByteArray &pattern, qint64 from, boo int block = from / m_blockSize; const int lowerBound = qMax(qint64(0), from - SearchStride); while (from > lowerBound) { - if (!requestDataAt(block * m_blockSize)) + if (!requestDataAt(qint64(block) * m_blockSize)) return -1; QByteArray data = blockData(block); ::memcpy(b + m_blockSize, b, trailing); @@ -658,7 +658,7 @@ int BinEditorWidget::dataLastIndexOf(const QByteArray &pattern, qint64 from, boo if (pos >= 0) return pos + block * m_blockSize; --block; - from = block * m_blockSize + (m_blockSize-1) + trailing; + from = qint64(block) * m_blockSize + (m_blockSize-1) + trailing; } return lowerBound == 0 ? -1 : -2; } diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 7310697596..c04d237f38 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -313,9 +313,9 @@ QStringList CMakeProject::files(FilesMode fileMode) const if (ProjectNode *rpn = rootProjectNode()) { rpn->forEachNode([&](const FileNode *fn) { const bool isGenerated = fn->isGenerated(); - if (fileMode == Project::SourceFiles && !isGenerated) + if ((fileMode & Project::SourceFiles) && !isGenerated) result.append(fn->filePath().toString()); - if (fileMode == Project::GeneratedFiles && isGenerated) + if ((fileMode & Project::GeneratedFiles) && isGenerated) result.append(fn->filePath().toString()); }); } diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 53fd3ec9dc..0683a66ef4 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -1033,6 +1033,12 @@ void EditorManagerPrivate::readSettings() d->m_autoSaveEnabled = qs->value(autoSaveEnabledKey).toBool(); d->m_autoSaveInterval = qs->value(autoSaveIntervalKey).toInt(); } + + if (qs->contains(autoSuspendEnabledKey)) { + d->m_autoSuspendEnabled = qs->value(autoSuspendEnabledKey).toBool(); + d->m_autoSuspendMinDocumentCount = qs->value(autoSuspendMinDocumentCountKey).toInt(); + } + updateAutoSave(); } diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index 2b95e64cb7..dea2dc1a43 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -1696,10 +1696,16 @@ QmlV8ObjectData QmlEnginePrivate::extractData(const QVariant &data) const if (dataMap.contains("value")) { QVariant value = dataMap.value("value"); - if (value.isNull()) + // The QVariant representation of null has changed across various Qt versions + // 5.6, 5.7: QVariant::Invalid + // 5.8: isValid(), !isNull(), type() == 51; only typeName() is unique: "std::nullptr_t" + // 5.9: isValid(), isNull(); We can then use isNull() + if (!value.isValid() || value.isNull() + || strcmp(value.typeName(), "std::nullptr_t") == 0) { objectData.value = "null"; // Yes, null is an object. - else if (value.isValid()) + } else if (value.isValid()) { objectData.expectedProperties = value.toInt(); + } } if (dataMap.contains("properties")) diff --git a/src/plugins/git/gerrit/gerritmodel.cpp b/src/plugins/git/gerrit/gerritmodel.cpp index 1cc7a63f90..aed258fb74 100644 --- a/src/plugins/git/gerrit/gerritmodel.cpp +++ b/src/plugins/git/gerrit/gerritmodel.cpp @@ -737,10 +737,15 @@ static GerritChangePtr parseSshOutput(const QJsonObject &object) } */ +static int restNumberValue(const QJsonObject &object) +{ + return object.value("_number").toInt(); +} + static GerritChangePtr parseRestOutput(const QJsonObject &object, const GerritServer &server) { GerritChangePtr change(new GerritChange); - change->number = object.value("_number").toInt(); + change->number = restNumberValue(object); change->url = QString("%1/%2").arg(server.url()).arg(change->number); change->title = object.value("subject").toString(); change->owner = parseGerritUser(object.value("owner").toObject()); @@ -751,10 +756,11 @@ static GerritChangePtr parseRestOutput(const QJsonObject &object, const GerritSe Qt::DateFormat::ISODate).toLocalTime(); // Read current patch set. const QJsonObject patchSet = object.value("revisions").toObject().begin().value().toObject(); - change->currentPatchSet.patchSetNumber = qMax(1, patchSet.value("number").toString().toInt()); - change->currentPatchSet.ref = patchSet.value("ref").toString(); + change->currentPatchSet.patchSetNumber = qMax(1, restNumberValue(patchSet)); + const QJsonObject fetchInfo = patchSet.value("fetch").toObject().value("http").toObject(); + change->currentPatchSet.ref = fetchInfo.value("ref").toString(); // Replace * in ssh://*:29418/qt-creator/qt-creator with the hostname - change->currentPatchSet.url = patchSet.value("url").toString().replace('*', server.host); + change->currentPatchSet.url = fetchInfo.value("url").toString().replace('*', server.host); const QJsonObject labels = object.value("labels").toObject(); for (auto it = labels.constBegin(), end = labels.constEnd(); it != end; ++it) { const QJsonArray all = it.value().toObject().value("all").toArray(); diff --git a/src/plugins/macros/findmacrohandler.cpp b/src/plugins/macros/findmacrohandler.cpp index ee2709a9be..ee5cc6ade5 100644 --- a/src/plugins/macros/findmacrohandler.cpp +++ b/src/plugins/macros/findmacrohandler.cpp @@ -91,6 +91,7 @@ bool FindMacroHandler::executeEvent(const MacroEvent ¯oEvent) currentFind->replace(macroEvent.value(BEFORE).toString(), macroEvent.value(AFTER).toString(), (Core::FindFlags)macroEvent.value(FLAGS).toInt()); + break; case REPLACESTEP: currentFind->replaceStep(macroEvent.value(BEFORE).toString(), macroEvent.value(AFTER).toString(), diff --git a/src/plugins/modeleditor/pxnodecontroller.cpp b/src/plugins/modeleditor/pxnodecontroller.cpp index dfd0393203..e272c67f6f 100644 --- a/src/plugins/modeleditor/pxnodecontroller.cpp +++ b/src/plugins/modeleditor/pxnodecontroller.cpp @@ -198,8 +198,6 @@ void PxNodeController::addExplorerNode(const ProjectExplorer::Node *node, menu->popup(QCursor::pos()); break; } - case ProjectExplorer::NodeType::Session: - break; } } diff --git a/src/plugins/modeleditor/pxnodeutilities.cpp b/src/plugins/modeleditor/pxnodeutilities.cpp index 6df0e93a97..31fede39fb 100644 --- a/src/plugins/modeleditor/pxnodeutilities.cpp +++ b/src/plugins/modeleditor/pxnodeutilities.cpp @@ -80,9 +80,6 @@ QString PxNodeUtilities::calcRelativePath(const ProjectExplorer::Node *node, case ProjectExplorer::NodeType::Project: nodePath = node->filePath().toString(); break; - case ProjectExplorer::NodeType::Session: - QTC_ASSERT(false, return QString()); - break; } return qmt::NameController::calcRelativePath(nodePath, anchorFolder); diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 7d283d3901..e8b68a4560 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -39,6 +39,9 @@ #include <coreplugin/idocument.h> #include <coreplugin/icontext.h> #include <coreplugin/icore.h> +#include <coreplugin/iversioncontrol.h> +#include <coreplugin/vcsmanager.h> + #include <projectexplorer/buildmanager.h> #include <projectexplorer/kitmanager.h> #include <projectexplorer/projecttree.h> @@ -80,18 +83,52 @@ const char PLUGIN_SETTINGS_KEY[] = "ProjectExplorer.Project.PluginSettings"; } // namespace namespace ProjectExplorer { + +class ContainerNode : public ProjectNode +{ +public: + ContainerNode(Project *project) + : ProjectNode(Utils::FileName()), + m_project(project) + {} + + QString displayName() const final + { + QString name = m_project->displayName(); + + const QFileInfo fi = m_project->projectFilePath().toFileInfo(); + const QString dir = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath(); + if (Core::IVersionControl *vc = Core::VcsManager::findVersionControlForDirectory(dir)) { + QString vcsTopic = vc->vcsTopic(dir); + if (!vcsTopic.isEmpty()) + name += " [" + vcsTopic + ']'; + } + + return name; + } + + QList<ProjectAction> supportedActions(Node *) const final + { + return {}; + } + +private: + Project *m_project; +}; + // ------------------------------------------------------------------------- // Project // ------------------------------------------------------------------------- - class ProjectPrivate { public: + ProjectPrivate(Project *owner) : m_containerNode(owner) {} ~ProjectPrivate(); Core::Id m_id; Core::IDocument *m_document = nullptr; ProjectNode *m_rootProjectNode = nullptr; + ContainerNode m_containerNode; QList<Target *> m_targets; Target *m_activeTarget = nullptr; EditorConfiguration m_editorConfiguration; @@ -117,7 +154,7 @@ ProjectPrivate::~ProjectPrivate() delete m_accessor; } -Project::Project() : d(new ProjectPrivate) +Project::Project() : d(new ProjectPrivate(this)) { d->m_macroExpander.setDisplayName(tr("Project")); d->m_macroExpander.registerVariable("Project:Name", tr("Project Name"), @@ -426,9 +463,13 @@ void Project::setRootProjectNode(ProjectNode *root) ProjectTree::applyTreeManager(root); + ProjectNode *oldNode = d->m_rootProjectNode; d->m_rootProjectNode = root; - emit projectTreeChanged(this, QPrivateSignal()); - // Do not delete oldNode! The ProjectTree owns that! + if (root) + root->setParentFolderNode(&d->m_containerNode); + ProjectTree::emitSubtreeChanged(root); + + delete oldNode; } Target *Project::restoreTarget(const QVariantMap &data) @@ -532,6 +573,11 @@ ProjectNode *Project::rootProjectNode() const return d->m_rootProjectNode; } +ProjectNode *Project::containerNode() const +{ + return &d->m_containerNode; +} + Project::RestoreResult Project::fromMap(const QVariantMap &map, QString *errorMessage) { Q_UNUSED(errorMessage); diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index 3ca35707fc..8de6d9ec21 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -81,6 +81,7 @@ public: static Utils::FileName projectDirectory(const Utils::FileName &top); virtual ProjectNode *rootProjectNode() const; + ProjectNode *containerNode() const; bool hasActiveBuildSettings() const; @@ -142,7 +143,6 @@ public: Utils::MacroExpander *macroExpander() const; signals: - void projectTreeChanged(Project *project, QPrivateSignal); void displayNameChanged(); void fileListChanged(); diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index 1a362da0c5..53be442b19 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -71,7 +71,7 @@ static bool sortWrapperNodes(const WrapperNode *w1, const WrapperNode *w2) } FlatModel::FlatModel(QObject *parent) - : TreeModel<WrapperNode, WrapperNode>(new WrapperNode(SessionManager::sessionNode()), parent) + : TreeModel<WrapperNode, WrapperNode>(new WrapperNode(nullptr), parent) { ProjectTree *tree = ProjectTree::instance(); connect(tree, &ProjectTree::subtreeChanged, this, &FlatModel::update); @@ -93,17 +93,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const FolderNode *folderNode = node->asFolderNode(); switch (role) { case Qt::DisplayRole: { - QString name = node->displayName(); - if (node->nodeType() == NodeType::Project - && node->parentFolderNode() - && node->parentFolderNode()->nodeType() == NodeType::Session) { - const QString vcsTopic = static_cast<ProjectNode *>(node)->vcsTopic(); - - if (!vcsTopic.isEmpty()) - name += QLatin1String(" [") + vcsTopic + QLatin1Char(']'); - } - - result = name; + result = node->displayName(); break; } case Qt::EditRole: { @@ -124,7 +114,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const case Qt::FontRole: { QFont font; if (Project *project = SessionManager::startupProject()) { - if (node == SessionManager::nodeForProject(project)) + if (node == project->containerNode()) font.setBold(true); } result = font; @@ -187,23 +177,44 @@ void FlatModel::update() void FlatModel::rebuildModel() { + QList<Project *> projects = SessionManager::projects(); + + Utils::sort(projects, [](Project *p1, Project *p2) { + const int displayNameResult = caseFriendlyCompare(p1->displayName(), p2->displayName()); + if (displayNameResult != 0) + return displayNameResult < 0; + return p1 < p2; // sort by pointer value + }); + QSet<Node *> seen; rootItem()->removeChildren(); - for (Node *node : SessionManager::sessionNode()->nodes()) { - if (ProjectNode *projectNode = node->asProjectNode()) { - if (!seen.contains(projectNode)) - addProjectNode(rootItem(), projectNode, &seen); + for (Project *project : projects) { + WrapperNode *container = new WrapperNode(project->containerNode()); + + ProjectNode *projectNode = project->rootProjectNode(); + if (projectNode) { + addFolderNode(container, projectNode, &seen); + } else { + FileNode *projectFileNode = new FileNode(project->projectFilePath(), FileType::Project, false); + seen.insert(projectFileNode); + container->appendChild(new WrapperNode(projectFileNode)); } + + container->sortChildren(&sortWrapperNodes); + rootItem()->appendChild(container); } - rootItem()->sortChildren(&sortWrapperNodes); forAllItems([this](WrapperNode *node) { - const QString path = node->m_node->filePath().toString(); - const QString displayName = node->m_node->displayName(); - ExpandData ed(path, displayName); - if (m_toExpand.contains(ed)) + if (node->m_node) { + const QString path = node->m_node->filePath().toString(); + const QString displayName = node->m_node->displayName(); + ExpandData ed(path, displayName); + if (m_toExpand.contains(ed)) + emit requestExpansion(node->index()); + } else { emit requestExpansion(node->index()); + } }); } @@ -227,7 +238,7 @@ ExpandData FlatModel::expandDataForNode(const Node *node) const void FlatModel::handleProjectAdded(Project *project) { - Node *node = SessionManager::nodeForProject(project); + Node *node = project->rootProjectNode(); m_toExpand.insert(expandDataForNode(node)); if (WrapperNode *wrapper = wrapperForNode(node)) { wrapper->forFirstLevelChildren([this](WrapperNode *child) { @@ -251,21 +262,6 @@ void FlatModel::saveExpandData() SessionManager::setValue(QLatin1String("ProjectTree.ExpandData"), data); } -void FlatModel::addProjectNode(WrapperNode *parent, ProjectNode *projectNode, QSet<Node *> *seen) -{ - seen->insert(projectNode); - auto node = new WrapperNode(projectNode); - parent->appendChild(node); - addFolderNode(node, projectNode, seen); - for (Node *subNode : projectNode->nodes()) { - if (ProjectNode *subProjectNode = subNode->asProjectNode()) { - if (!seen->contains(subProjectNode)) - addProjectNode(node, subProjectNode, seen); - } - } - node->sortChildren(&sortWrapperNodes); -} - void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen) { const QList<FolderNode *> subFolderNodes = folderNode->folderNodes(); @@ -374,16 +370,6 @@ const QLoggingCategory &FlatModel::logger() return logger; } -bool isSorted(const QList<Node *> &nodes) -{ - int size = nodes.size(); - for (int i = 0; i < size -1; ++i) { - if (!sortNodes(nodes.at(i), nodes.at(i+1))) - return false; - } - return true; -} - namespace Internal { int caseFriendlyCompare(const QString &a, const QString &b) diff --git a/src/plugins/projectexplorer/projectmodels.h b/src/plugins/projectexplorer/projectmodels.h index 25a808ce35..8d177c8b0c 100644 --- a/src/plugins/projectexplorer/projectmodels.h +++ b/src/plugins/projectexplorer/projectmodels.h @@ -94,7 +94,6 @@ private: void update(); void rebuildModel(); - void addProjectNode(WrapperNode *parent, ProjectNode *projectNode, QSet<Node *> *seen); void addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen); ExpandData expandDataForNode(const Node *node) const; diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 8557b99003..0d3b102522 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -214,9 +214,12 @@ bool Node::isEnabled() const QList<ProjectAction> Node::supportedActions(Node *node) const { - QList<ProjectAction> list = parentFolderNode()->supportedActions(node); - list.append(InheritedFromParent); - return list; + if (FolderNode *folder = parentFolderNode()) { + QList<ProjectAction> list = folder->supportedActions(node); + list.append(InheritedFromParent); + return list; + } + return {}; } void Node::setEnabled(bool enabled) @@ -702,18 +705,6 @@ ProjectNode::ProjectNode(const Utils::FileName &projectFilePath) : setDisplayName(projectFilePath.fileName()); } -QString ProjectNode::vcsTopic() const -{ - const QFileInfo fi = filePath().toFileInfo(); - const QString dir = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath(); - - if (Core::IVersionControl *const vc = - Core::VcsManager::findVersionControlForDirectory(dir)) - return vc->vcsTopic(dir); - - return QString(); -} - bool ProjectNode::canAddSubProject(const QString &proFilePath) const { Q_UNUSED(proFilePath) @@ -797,28 +788,4 @@ bool FolderNode::isEmpty() const return m_nodes.isEmpty(); } -/*! - \class ProjectExplorer::SessionNode -*/ - -SessionNode::SessionNode() : - FolderNode(Utils::FileName::fromString("session"), NodeType::Session) -{ } - -QList<ProjectAction> SessionNode::supportedActions(Node *node) const -{ - Q_UNUSED(node) - return QList<ProjectAction>(); -} - -bool SessionNode::showInSimpleTree() const -{ - return true; -} - -QString SessionNode::addFileFilter() const -{ - return QString::fromLatin1("*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++; *.h; *.hh; *.hpp; *.hxx;"); -} - } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index fb17b4806e..757529da8b 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -40,14 +40,12 @@ namespace Utils { class MimeType; } namespace ProjectExplorer { class RunConfiguration; -class SessionManager; enum class NodeType : quint16 { File = 1, Folder, VirtualFolder, - Project, - Session + Project }; // File types common for qt projects @@ -275,8 +273,6 @@ private: class PROJECTEXPLORER_EXPORT ProjectNode : public FolderNode { public: - QString vcsTopic() const; - virtual bool canAddSubProject(const QString &proFilePath) const; virtual bool addSubProject(const QString &proFile); virtual bool removeSubProject(const QString &proFilePath); @@ -298,24 +294,7 @@ public: const ProjectNode *asProjectNode() const final { return this; } protected: - // this is just the in-memory representation, a subclass - // will add the persistent stuff explicit ProjectNode(const Utils::FileName &projectFilePath); - - friend class SessionManager; -}; - -// Documentation inside. -class PROJECTEXPLORER_EXPORT SessionNode : public FolderNode -{ -public: - SessionNode(); - -private: - QList<ProjectAction> supportedActions(Node *node) const final; - QString addFileFilter() const final; - - bool showInSimpleTree() const final; }; } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projecttree.cpp b/src/plugins/projectexplorer/projecttree.cpp index 86d8ef1d26..6d32406015 100644 --- a/src/plugins/projectexplorer/projecttree.cpp +++ b/src/plugins/projectexplorer/projecttree.cpp @@ -261,9 +261,6 @@ void ProjectTree::updateContext() void ProjectTree::emitSubtreeChanged(FolderNode *node) { - if (!SessionManager::sessionNode()->isAncesterOf(node)) - return; - emit s_instance->subtreeChanged(node); } @@ -318,16 +315,15 @@ bool ProjectTree::hasFocus(ProjectTreeWidget *widget) void ProjectTree::showContextMenu(ProjectTreeWidget *focus, const QPoint &globalPos, Node *node) { QMenu *contextMenu = nullptr; + Project *project = SessionManager::projectForNode(node); + emit s_instance->aboutToShowContextMenu(project, node); - if (!node) - node = SessionManager::sessionNode(); - if (node->nodeType() != NodeType::Session) { - Project *project = SessionManager::projectForNode(node); - - emit s_instance->aboutToShowContextMenu(project, node); + if (!node) { + contextMenu = Core::ActionManager::actionContainer(Constants::M_SESSIONCONTEXT)->menu(); + } else { switch (node->nodeType()) { case NodeType::Project: - if (node->parentFolderNode() == SessionManager::sessionNode()) + if (node->parentFolderNode()) contextMenu = Core::ActionManager::actionContainer(Constants::M_PROJECTCONTEXT)->menu(); else contextMenu = Core::ActionManager::actionContainer(Constants::M_SUBPROJECTCONTEXT)->menu(); @@ -342,10 +338,6 @@ void ProjectTree::showContextMenu(ProjectTreeWidget *focus, const QPoint &global default: qWarning("ProjectExplorerPlugin::showContextMenu - Missing handler for node type"); } - } else { // session item - emit s_instance->aboutToShowContextMenu(nullptr, node); - - contextMenu = Core::ActionManager::actionContainer(Constants::M_SESSIONCONTEXT)->menu(); } if (contextMenu && contextMenu->actions().count() > 0) { diff --git a/src/plugins/projectexplorer/projecttree.h b/src/plugins/projectexplorer/projecttree.h index 74f0c53a2c..eb84adf58b 100644 --- a/src/plugins/projectexplorer/projecttree.h +++ b/src/plugins/projectexplorer/projecttree.h @@ -70,6 +70,9 @@ public: void collapseAll(); + // for nodes to emit signals, do not call unless you are a node + static void emitSubtreeChanged(FolderNode *node); + signals: void currentProjectChanged(ProjectExplorer::Project *project); void currentNodeChanged(); @@ -80,9 +83,6 @@ signals: void aboutToShowContextMenu(ProjectExplorer::Project *project, ProjectExplorer::Node *node); -public: // for nodes to emit signals, do not call unless you are a node - static void emitSubtreeChanged(FolderNode *node); - private: void sessionChanged(); void focusChanged(); diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp index 67bbf07405..372dbdb757 100644 --- a/src/plugins/projectexplorer/projecttreewidget.cpp +++ b/src/plugins/projectexplorer/projecttreewidget.cpp @@ -275,23 +275,27 @@ Node *ProjectTreeWidget::nodeForFile(const Utils::FileName &fileName) Node *bestNode = nullptr; int bestNodeExpandCount = INT_MAX; - SessionManager::sessionNode()->forEachGenericNode([&](Node *node) { - if (node->filePath() == fileName) { - if (!bestNode) { - bestNode = node; - bestNodeExpandCount = ProjectTreeWidget::expandedCount(node); - } else if (node->nodeType() < bestNode->nodeType()) { - bestNode = node; - bestNodeExpandCount = ProjectTreeWidget::expandedCount(node); - } else if (node->nodeType() == bestNode->nodeType()) { - int nodeExpandCount = ProjectTreeWidget::expandedCount(node); - if (nodeExpandCount < bestNodeExpandCount) { - bestNode = node; - bestNodeExpandCount = ProjectTreeWidget::expandedCount(node); + for (Project *project : SessionManager::projects()) { + if (ProjectNode *projectNode = project->rootProjectNode()) { + projectNode->forEachGenericNode([&](Node *node) { + if (node->filePath() == fileName) { + if (!bestNode) { + bestNode = node; + bestNodeExpandCount = ProjectTreeWidget::expandedCount(node); + } else if (node->nodeType() < bestNode->nodeType()) { + bestNode = node; + bestNodeExpandCount = ProjectTreeWidget::expandedCount(node); + } else if (node->nodeType() == bestNode->nodeType()) { + int nodeExpandCount = ProjectTreeWidget::expandedCount(node); + if (nodeExpandCount < bestNodeExpandCount) { + bestNode = node; + bestNodeExpandCount = ProjectTreeWidget::expandedCount(node); + } + } } - } + }); } - }); + } return bestNode; } diff --git a/src/plugins/projectexplorer/projectwelcomepage.cpp b/src/plugins/projectexplorer/projectwelcomepage.cpp index ebd52104ba..8f9029028e 100644 --- a/src/plugins/projectexplorer/projectwelcomepage.cpp +++ b/src/plugins/projectexplorer/projectwelcomepage.cpp @@ -55,6 +55,8 @@ using namespace Core; using namespace Utils; +const int LINK_HEIGHT = 35; + namespace ProjectExplorer { namespace Internal { @@ -154,13 +156,18 @@ class BaseDelegate : public QAbstractItemDelegate { protected: virtual QString entryType() = 0; + virtual QRect toolTipArea(const QRect &itemRect, const QModelIndex &) const + { + return itemRect; + } bool helpEvent(QHelpEvent *ev, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &idx) final { - const int y = ev->pos().y(); - if (y > option.rect.bottom() - 20) + if (!toolTipArea(option.rect, idx).contains(ev->pos())) { + QToolTip::hideText(); return false; + } QString shortcut; if (idx.row() < m_shortcuts.size()) @@ -188,6 +195,13 @@ class SessionDelegate : public BaseDelegate { protected: QString entryType() override { return tr("session", "Appears in \"Open session <name>\""); } + QRect toolTipArea(const QRect &itemRect, const QModelIndex &idx) const override + { + // in expanded state bottom contains 'Clone', 'Rename', etc links, where the tool tip + // would be confusing + const bool expanded = m_expandedSessions.contains(idx.data(Qt::DisplayRole).toString()); + return expanded ? itemRect.adjusted(0, 0, 0, -LINK_HEIGHT) : itemRect; + } public: SessionDelegate() { @@ -312,7 +326,7 @@ public: QString sessionName = idx.data(Qt::DisplayRole).toString(); if (m_expandedSessions.contains(sessionName)) { QStringList projects = SessionManager::projectsForSessionName(sessionName); - h += projects.size() * 40 + 35; + h += projects.size() * 40 + LINK_HEIGHT; } return QSize(380, h); } @@ -408,7 +422,7 @@ public: painter->drawPixmap(x + 11, y + 3, pixmap("project", Theme::Welcome_ForegroundSecondaryColor)); QString projectName = idx.data(Qt::DisplayRole).toString(); - QString projectPath = idx.data(Qt::UserRole + 1).toString(); + QString projectPath = idx.data(ProjectModel::FilePathRole).toString(); painter->setPen(themeColor(Theme::Welcome_ForegroundSecondaryColor)); painter->setFont(sizedFont(10, option.widget)); @@ -429,7 +443,7 @@ public: QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &idx) const final { QString projectName = idx.data(Qt::DisplayRole).toString(); - QString projectPath = idx.data(Qt::UserRole + 1).toString(); + QString projectPath = idx.data(ProjectModel::FilePathRole).toString(); QFontMetrics fm(sizedFont(13, option.widget)); int width = std::max(fm.width(projectName), fm.width(projectPath)) + 36; return QSize(width, 48); @@ -439,7 +453,7 @@ public: const QStyleOptionViewItem &, const QModelIndex &idx) final { if (ev->type() == QEvent::MouseButtonRelease) { - QString projectFile = idx.data(Qt::UserRole + 1).toString(); + QString projectFile = idx.data(ProjectModel::FilePathRole).toString(); ProjectExplorerPlugin::openProjectWelcomePage(projectFile); return true; } diff --git a/src/plugins/projectexplorer/projectwizardpage.cpp b/src/plugins/projectexplorer/projectwizardpage.cpp index 6a5c2bd261..88756a3599 100644 --- a/src/plugins/projectexplorer/projectwizardpage.cpp +++ b/src/plugins/projectexplorer/projectwizardpage.cpp @@ -26,6 +26,7 @@ #include "projectwizardpage.h" #include "ui_projectwizardpage.h" +#include "project.h" #include "projectexplorer.h" #include "session.h" @@ -300,18 +301,14 @@ ProjectWizardPage::~ProjectWizardPage() { disconnect(m_ui->projectComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ProjectWizardPage::projectChanged); - delete m_model; delete m_ui; } void ProjectWizardPage::setModel(Utils::TreeModel<> *model) { - delete m_model; - m_model = model; - // TODO see OverViewCombo and OverView for click event filter m_ui->projectComboBox->setModel(model); - bool enabled = m_model->rowCount(QModelIndex()) > 1; + bool enabled = m_model.rowCount(QModelIndex()) > 1; m_ui->projectComboBox->setEnabled(enabled); expandTree(QModelIndex()); @@ -324,9 +321,9 @@ bool ProjectWizardPage::expandTree(const QModelIndex &root) expand = true; // Check children - int count = m_model->rowCount(root); + int count = m_model.rowCount(root); for (int i = 0; i < count; ++i) { - if (expandTree(m_model->index(i, 0, root))) + if (expandTree(m_model.index(i, 0, root))) expand = true; } @@ -346,7 +343,7 @@ bool ProjectWizardPage::expandTree(const QModelIndex &root) void ProjectWizardPage::setBestNode(AddNewTree *tree) { - QModelIndex index = tree ? m_model->indexForItem(tree) : QModelIndex(); + QModelIndex index = tree ? m_model.indexForItem(tree) : QModelIndex(); m_ui->projectComboBox->setCurrentIndex(index); while (index.isValid()) { @@ -454,28 +451,22 @@ void ProjectWizardPage::initializeProjectTree(Node *context, const QStringList & { BestNodeSelector selector(m_commonDirectory, paths); - AddNewTree *tree; - SessionNode *root = SessionManager::sessionNode(); - QList<AddNewTree *> children; - - for (Node *node : root->nodes()) { - if (ProjectNode *pn = node->asProjectNode()) { + TreeItem *root = m_model.rootItem(); + root->removeChildren(); + for (Project *project : SessionManager::projects()) { + if (ProjectNode *pn = project->rootProjectNode()) { if (kind == IWizardFactory::ProjectWizard) { if (AddNewTree *child = buildAddProjectTree(pn, paths.first(), context, &selector)) - children.append(child); + root->appendChild(child); } else { if (AddNewTree *child = buildAddFilesTree(pn, paths, context, &selector)) - children.append(child); + root->appendChild(child); } } } - - children.prepend(createNoneNode(&selector)); - tree = new AddNewTree(root, children, root->displayName()); + root->prependChild(createNoneNode(&selector)); setAdditionalInfo(selector.deployingProjects()); - - setModel(new TreeModel<>(tree)); setBestNode(selector.bestChoice()); setAddingSubProject(action == AddSubProject); } diff --git a/src/plugins/projectexplorer/projectwizardpage.h b/src/plugins/projectexplorer/projectwizardpage.h index ce4f77d625..1516a87cfe 100644 --- a/src/plugins/projectexplorer/projectwizardpage.h +++ b/src/plugins/projectexplorer/projectwizardpage.h @@ -95,7 +95,7 @@ private: Ui::WizardPage *m_ui; QStringList m_projectToolTips; - Utils::TreeModel<> *m_model = nullptr; + Utils::TreeModel<> m_model; QList<Core::IVersionControl*> m_activeVersionControls; QString m_commonDirectory; diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index 2e87aef4ff..9286155bfb 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -92,13 +92,7 @@ public: static QString sessionTitle(const QString &filePath); bool hasProjects() const { return !m_projects.isEmpty(); } - bool hasProject(Project *p) const - { - return Utils::contains(m_projects, - [p](const QPair<Project *, ProjectNode *> &pair) { return pair.first == p; }); - } - SessionNode m_sessionNode; QString m_sessionName = QLatin1String("default"); bool m_virginSession = true; bool m_loadingSession = false; @@ -110,7 +104,7 @@ public: mutable QHash<Project *, QStringList> m_projectFileCache; Project *m_startupProject = nullptr; - QList<QPair<Project *,ProjectNode*>> m_projects; + QList<Project *> m_projects; QStringList m_failedProjects; QMap<QString, QStringList> m_depMap; QMap<QString, QVariant> m_values; @@ -188,36 +182,6 @@ void SessionManager::clearProjectFileCache() d->m_projectFileCache.clear(); } -void SessionManager::updateProjectTree(Project *pro) -{ - if (!pro) - return; - - QPair<Project *, ProjectNode *> *currentPair = nullptr; - for (QPair<Project *, ProjectNode *> &pair : d->m_projects) { - if (pair.first == pro) { - currentPair = &pair; - break; - } - } - - if (!currentPair) - return; // Project was already de-registered and is shutting down - - ProjectNode *const oldNode = currentPair->second; - ProjectNode *newNode = pro->rootProjectNode(); - - if (!newNode) { - // Set up generic project structure if the project does not provide any! - newNode = new ProjectNode(pro->projectDirectory()); - newNode->setDisplayName(pro->displayName()); - newNode->addNode(new FileNode(pro->projectFilePath(), FileType::Project, false)); - } - - d->m_sessionNode.replaceSubtree(oldNode, newNode); - currentPair->second = newNode; -} - bool SessionManagerPrivate::recursiveDependencyCheck(const QString &newDep, const QString &checkDep) const { if (newDep == checkDep) @@ -393,8 +357,8 @@ void SessionManager::setActiveDeployConfiguration(Target *target, DeployConfigur void SessionManager::setStartupProject(Project *startupProject) { - QTC_ASSERT((!startupProject) - || (startupProject && hasProject(startupProject)), return); + QTC_ASSERT(!startupProject + || (startupProject && d->m_projects.contains(startupProject)), return); if (d->m_startupProject == startupProject) return; @@ -413,13 +377,11 @@ void SessionManager::addProject(Project *pro) QTC_ASSERT(pro, return); d->m_virginSession = false; - QTC_ASSERT(!hasProject(pro), return); + QTC_ASSERT(!d->m_projects.contains(pro), return); - d->m_projects.append(qMakePair(pro, nullptr)); - m_instance->updateProjectTree(pro); + d->m_projects.append(pro); connect(pro, &Project::fileListChanged, m_instance, &SessionManager::clearProjectFileCache); - connect(pro, &Project::projectTreeChanged, m_instance, &SessionManager::updateProjectTree); emit m_instance->projectAdded(pro); configureEditors(pro); @@ -522,8 +484,7 @@ void SessionManager::closeAllProjects() const QList<Project *> SessionManager::projects() { - return Utils::transform(d->m_projects, - [](const QPair<Project *, ProjectNode *> &pair) { return pair.first; }); + return d->m_projects; } bool SessionManager::hasProjects() @@ -533,7 +494,7 @@ bool SessionManager::hasProjects() bool SessionManager::hasProject(Project *p) { - return d->hasProject(p); + return d->m_projects.contains(p); } QStringList SessionManagerPrivate::dependencies(const QString &proName) const @@ -604,8 +565,8 @@ QStringList SessionManagerPrivate::dependenciesOrder() const QStringList ordered; // copy the map to a temporary list - for (const QPair<Project *, ProjectNode *> &pro : m_projects) { - const QString proName = pro.first->projectFilePath().toString(); + for (const Project *pro : m_projects) { + const QString proName = pro->projectFilePath().toString(); unordered << QPair<QString, QStringList>(proName, m_depMap.value(proName)); } @@ -658,13 +619,17 @@ QList<Project *> SessionManager::projectOrder(const Project *project) Node *SessionManager::nodeForFile(const Utils::FileName &fileName) { Node *node = nullptr; - sessionNode()->forEachGenericNode([&](Node *n) { - if (n->filePath() == fileName) { - // prefer file nodes - if (!node || (node->nodeType() != NodeType::File && n->nodeType() == NodeType::File)) - node = n; + for (Project *project : d->m_projects) { + if (ProjectNode *projectNode = project->rootProjectNode()) { + projectNode->forEachGenericNode([&](Node *n) { + if (n->filePath() == fileName) { + // prefer file nodes + if (!node || (node->nodeType() != NodeType::File && n->nodeType() == NodeType::File)) + node = n; + } + }); } - }); + } return node; } @@ -673,25 +638,16 @@ Project *SessionManager::projectForNode(Node *node) if (!node) return nullptr; - FolderNode *rootProjectNode = node->asFolderNode(); - if (!rootProjectNode) - rootProjectNode = node->parentFolderNode(); + FolderNode *folder = node->asFolderNode(); + if (!folder) + folder = node->parentFolderNode(); - while (rootProjectNode && rootProjectNode->parentFolderNode() != &d->m_sessionNode) - rootProjectNode = rootProjectNode->parentFolderNode(); - - for (const QPair<Project *, ProjectNode *> &pair : d->m_projects) { - if (pair.second == rootProjectNode) - return pair.first; - } - return nullptr; -} + while (folder && folder->parentFolderNode()) + folder = folder->parentFolderNode(); -Node *SessionManager::nodeForProject(Project *project) -{ - for (const QPair<Project *,ProjectNode*> &pair : d->m_projects) { - if (pair.first == project) - return pair.second; + for (Project *pro : d->m_projects) { + if (pro->containerNode() == folder) + return pro; } return nullptr; } @@ -771,17 +727,9 @@ void SessionManager::removeProjects(QList<Project *> remove) // Delete projects foreach (Project *pro, remove) { pro->saveSettings(); - pro->setRootProjectNode(nullptr); // Deregister project with sessionnode! // Remove the project node: - Node *projectNode = nodeForProject(pro); - d->m_sessionNode.removeNode(projectNode); - - d->m_projects - = Utils::filtered(d->m_projects, [pro](const QPair<Project *, ProjectNode *> &pair) - { - return pair.first != pro; - }); + d->m_projects.removeOne(pro); if (pro == d->m_startupProject) setStartupProject(nullptr); @@ -965,9 +913,9 @@ void SessionManagerPrivate::restoreStartupProject(const PersistentSettingsReader { const QString startupProject = reader.restoreValue(QLatin1String("StartupProject")).toString(); if (!startupProject.isEmpty()) { - for (const QPair<Project *, ProjectNode *> &pro : m_projects) { - if (pro.first->projectFilePath().toString() == startupProject) { - m_instance->setStartupProject(pro.first); + for (Project *pro : m_projects) { + if (pro->projectFilePath().toString() == startupProject) { + m_instance->setStartupProject(pro); break; } } @@ -976,7 +924,7 @@ void SessionManagerPrivate::restoreStartupProject(const PersistentSettingsReader if (!startupProject.isEmpty()) qWarning() << "Could not find startup project" << startupProject; if (hasProjects()) - m_instance->setStartupProject(m_projects.first().first); + m_instance->setStartupProject(m_projects.first()); } } @@ -1140,11 +1088,6 @@ QString SessionManager::lastSession() return ICore::settings()->value(QLatin1String("ProjectExplorer/StartupSession")).toString(); } -SessionNode *SessionManager::sessionNode() -{ - return &d->m_sessionNode; -} - void SessionManager::reportProjectLoadingProgress() { d->sessionLoadingProgress(); diff --git a/src/plugins/projectexplorer/session.h b/src/plugins/projectexplorer/session.h index c654efc615..8d6987363a 100644 --- a/src/plugins/projectexplorer/session.h +++ b/src/plugins/projectexplorer/session.h @@ -44,7 +44,6 @@ class Target; class BuildConfiguration; class DeployConfiguration; class Node; -class SessionNode; enum class SetActive { Cascade, NoCascade }; @@ -113,10 +112,7 @@ public: // NBS rewrite projectOrder (dependency management) static QList<Project *> projectOrder(const Project *project = 0); - static SessionNode *sessionNode(); - static Project *projectForNode(Node *node); - static Node *nodeForProject(Project *project); static Node *nodeForFile(const Utils::FileName &fileName); static Project *projectForFile(const Utils::FileName &fileName); @@ -126,8 +122,7 @@ public: static bool loadingSession(); signals: - void projectAdded(ProjectExplorer::Project *project); - void aboutToRemoveProject(ProjectExplorer::Project *project); + void projectAdded(ProjectExplorer::Project *project); void aboutToRemoveProject(ProjectExplorer::Project *project); void projectDisplayNameChanged(ProjectExplorer::Project *project); void projectRemoved(ProjectExplorer::Project *project); @@ -145,7 +140,6 @@ signals: // for tests only private: static void saveActiveMode(Core::Id mode); void clearProjectFileCache(); - void updateProjectTree(Project *pro); static void configureEditor(Core::IEditor *editor, const QString &fileName); static void markSessionFileDirty(bool makeDefaultVirginDirty = true); static void configureEditors(Project *project); diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp index b942a1be22..730c63ef7f 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.cpp +++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp @@ -42,6 +42,7 @@ #include <QtDebug> #include <QDir> +#include <QIcon> #include <QStyle> // ---------------------------------------------------------------------- @@ -64,10 +65,6 @@ static QIcon generateIcon(const QString &overlay) namespace QbsProjectManager { namespace Internal { -QIcon QbsGroupNode::m_groupIcon; -QIcon QbsProjectNode::m_projectIcon; -QIcon QbsProductNode::m_productIcon; - static QbsProjectNode *parentQbsProjectNode(ProjectExplorer::Node *node) { for (ProjectExplorer::FolderNode *pn = node->managingProject(); pn; pn = pn->parentProjectNode()) { @@ -263,9 +260,8 @@ QString QbsFileNode::displayName() const QbsFolderNode::QbsFolderNode(const Utils::FileName &folderPath, ProjectExplorer::NodeType nodeType, - const QString &displayName, bool isGeneratedFilesFolder) - : ProjectExplorer::FolderNode(folderPath, nodeType, displayName), - m_isGeneratedFilesFolder(isGeneratedFilesFolder) + const QString &displayName) + : ProjectExplorer::FolderNode(folderPath, nodeType, displayName) { } @@ -300,10 +296,8 @@ QList<ProjectExplorer::ProjectAction> QbsBaseProjectNode::supportedActions(Proje QbsGroupNode::QbsGroupNode(const qbs::GroupData &grp, const QString &productPath) : QbsBaseProjectNode(Utils::FileName()) { - if (m_groupIcon.isNull()) - m_groupIcon = QIcon(QString::fromLatin1(Constants::QBS_GROUP_ICON)); - - setIcon(m_groupIcon); + static QIcon groupIcon = QIcon(QString(Constants::QBS_GROUP_ICON)); + setIcon(groupIcon); m_productPath = productPath; m_qbsGroupData = grp; @@ -379,10 +373,8 @@ QbsProductNode::QbsProductNode(const qbs::ProductData &prd) : QbsBaseProjectNode(Utils::FileName::fromString(prd.location().filePath())), m_qbsProductData(prd) { - if (m_productIcon.isNull()) - m_productIcon = generateIcon(QString::fromLatin1(Constants::QBS_PRODUCT_OVERLAY_ICON)); - - setIcon(m_productIcon); + static QIcon productIcon = generateIcon(QString(Constants::QBS_PRODUCT_OVERLAY_ICON)); + setIcon(productIcon); } bool QbsProductNode::showInSimpleTree() const @@ -464,16 +456,6 @@ QList<ProjectExplorer::RunConfiguration *> QbsProductNode::runConfigurations() c return result; } -QbsGroupNode *QbsProductNode::findGroupNode(const QString &name) -{ - for (ProjectExplorer::Node *n : nodes()) { - if (QbsGroupNode *qn = dynamic_cast<QbsGroupNode *>(n)) - if (qn->qbsGroupData().name() == name) - return qn; - } - return 0; -} - // -------------------------------------------------------------------- // QbsProjectNode: // -------------------------------------------------------------------- @@ -481,15 +463,8 @@ QbsGroupNode *QbsProductNode::findGroupNode(const QString &name) QbsProjectNode::QbsProjectNode(const Utils::FileName &projectDirectory) : QbsBaseProjectNode(projectDirectory) { - if (m_projectIcon.isNull()) - m_projectIcon = generateIcon(QString::fromLatin1(ProjectExplorer::Constants::FILEOVERLAY_QT)); - - setIcon(m_projectIcon); -} - -QbsProjectNode::~QbsProjectNode() -{ - // do not delete m_project + static QIcon projectIcon = generateIcon(QString(ProjectExplorer::Constants::FILEOVERLAY_QT)); + setIcon(projectIcon); } QbsProject *QbsProjectNode::project() const diff --git a/src/plugins/qbsprojectmanager/qbsnodes.h b/src/plugins/qbsprojectmanager/qbsnodes.h index 0627083c83..313fa2a6ff 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.h +++ b/src/plugins/qbsprojectmanager/qbsnodes.h @@ -29,15 +29,11 @@ #include <qbs.h> -#include <QIcon> - namespace QbsProjectManager { namespace Internal { -class FileTreeNode; class QbsNodeTreeBuilder; class QbsProject; -class QbsProjectFile; // ---------------------------------------------------------------------- // QbsFileNode: @@ -56,14 +52,10 @@ class QbsFolderNode : public ProjectExplorer::FolderNode { public: QbsFolderNode(const Utils::FileName &folderPath, ProjectExplorer::NodeType nodeType, - const QString &displayName, bool isGeneratedFilesFolder); - - bool isGeneratedFilesFolder() const { return m_isGeneratedFilesFolder; } + const QString &displayName); private: QList<ProjectExplorer::ProjectAction> supportedActions(ProjectExplorer::Node *node) const override; - - const bool m_isGeneratedFilesFolder; }; // --------------------------------------------------------------------------- @@ -100,13 +92,9 @@ public: qbs::GroupData qbsGroupData() const { return m_qbsGroupData; } - QString productPath() const; - private: qbs::GroupData m_qbsGroupData; QString m_productPath; - - static QIcon m_groupIcon; }; // -------------------------------------------------------------------- @@ -129,10 +117,7 @@ public: QList<ProjectExplorer::RunConfiguration *> runConfigurations() const override; private: - QbsGroupNode *findGroupNode(const QString &name); - const qbs::ProductData m_qbsProductData; - static QIcon m_productIcon; }; // --------------------------------------------------------------------------- @@ -143,18 +128,15 @@ class QbsProjectNode : public QbsBaseProjectNode { public: explicit QbsProjectNode(const Utils::FileName &projectDirectory); - ~QbsProjectNode() override; virtual QbsProject *project() const; const qbs::Project qbsProject() const; const qbs::ProjectData qbsProjectData() const { return m_projectData; } bool showInSimpleTree() const override; - - void setProjectData(const qbs::ProjectData &data); + void setProjectData(const qbs::ProjectData &data); // FIXME: Needed? private: - static QIcon m_projectIcon; qbs::ProjectData m_projectData; friend class QbsNodeTreeBuilder; diff --git a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp index 8030825107..1f2d1dc445 100644 --- a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp +++ b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp @@ -148,6 +148,8 @@ void setupProjectNode(QbsProjectManager::Internal::QbsProjectNode *node, const q node->setDisplayName(prjData.name()); else node->setDisplayName(node->project()->displayName()); + + node->setProjectData(prjData); } QSet<QString> referencedBuildSystemFiles(const qbs::ProjectData &data) diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index 0568ec509e..9375f40503 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -325,8 +325,9 @@ void resetSize(const SelectionContext &selectionState) try { RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|resetSize")); foreach (ModelNode node, selectionState.selectedModelNodes()) { - node.removeProperty("width"); - node.removeProperty("height"); + QmlItemNode itemNode(node); + itemNode.removeProperty("width"); + itemNode.removeProperty("height"); } } catch (const RewritingException &e) { //better save then sorry e.showException(); @@ -341,8 +342,9 @@ void resetPosition(const SelectionContext &selectionState) try { RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|resetPosition")); foreach (ModelNode node, selectionState.selectedModelNodes()) { - node.removeProperty("x"); - node.removeProperty("y"); + QmlItemNode itemNode(node); + itemNode.removeProperty("x"); + itemNode.removeProperty("y"); } transaction.commit(); } catch (const RewritingException &e) { //better save then sorry @@ -366,7 +368,8 @@ void resetZ(const SelectionContext &selectionState) RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|resetZ")); foreach (ModelNode node, selectionState.selectedModelNodes()) { - node.removeProperty("z"); + QmlItemNode itemNode(node); + itemNode.removeProperty("z"); } } diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index af1ffeebd3..e4ee007bf7 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -301,15 +301,12 @@ void FormEditorView::selectedNodesChanged(const QList<ModelNode> &selectedNodeLi m_scene->update(); } -void FormEditorView::documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings) +void FormEditorView::documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &) { if (!errors.isEmpty()) formEditorWidget()->showErrorMessageBox(errors); else formEditorWidget()->hideErrorMessageBox(); - - if (!warnings.isEmpty()) - formEditorWidget()->showWarningMessageBox(warnings); } void FormEditorView::customNotification(const AbstractView * /*view*/, const QString &identifier, const QList<ModelNode> &/*nodeList*/, const QList<QVariant> &/*data*/) diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index 12bb8245e4..3c2b516746 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -286,8 +286,6 @@ void FormEditorWidget::showWarningMessageBox(const QList<DocumentMessage> &warni errorWidget()->setWarnings(warnings); errorWidget()->setVisible(true); - m_graphicsView->setDisabled(true); - m_toolBox->setDisabled(true); } ZoomAction *FormEditorWidget::zoomAction() const diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index 7d24c842d1..946dfc9b7d 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -82,10 +82,10 @@ public: void setResourcePath(const QString &resourcePath); - void startDragAndDrop(QVariant itemLibId); - void setModel(Model *model); + Q_INVOKABLE void startDragAndDrop(QVariant itemLibId); + protected: void removeImport(const QString &name); void addImport(const QString &name, const QString &version); diff --git a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp index 84b4cef69c..b21e45ef79 100644 --- a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp +++ b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp @@ -66,6 +66,25 @@ static Q_LOGGING_CATEGORY(puppetBuild, "qtc.puppet.build") namespace QmlDesigner { +class EventFilter : public QObject { + +public: + EventFilter() + {} + + bool eventFilter(QObject *o, QEvent *event) + { + if (event->type() == QEvent::MouseButtonPress + || event->type() == QEvent::MouseButtonRelease + || event->type() == QEvent::KeyPress + || event->type() == QEvent::KeyRelease) { + return true; + } + + return QObject::eventFilter(o, event); + } +}; + QHash<Core::Id, PuppetCreator::PuppetType> PuppetCreator::m_qml2PuppetForKitPuppetHash; QByteArray PuppetCreator::qtHash() const @@ -241,6 +260,7 @@ static QString idealProcessCount() bool PuppetCreator::build(const QString &qmlPuppetProjectFilePath) const { PuppetBuildProgressDialog progressDialog; + progressDialog.setParent(Core::ICore::mainWindow()); m_compileLog.clear(); @@ -248,6 +268,16 @@ bool PuppetCreator::build(const QString &qmlPuppetProjectFilePath) const bool buildSucceeded = false; + + /* Ensure the model dialog is shown and no events are delivered to the rest of Qt Creator. */ + EventFilter eventFilter; + QCoreApplication::instance()->installEventFilter(&eventFilter); + progressDialog.show(); + QCoreApplication::processEvents(); + QCoreApplication::instance()->removeEventFilter(&eventFilter); + /* Now the modal dialog will block input to the rest of Qt Creator. + We can call process events without risking a mode change. */ + if (qtIsSupported()) { if (buildDirectory.isValid()) { QStringList qmakeArguments; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index c1a48b95ad..366e69bd64 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -188,7 +188,6 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e bool QmlDesignerPlugin::delayedInitialize() { - integrateIntoQtCreator(d->mainWidget); // adding default path to item library plugins const QString pluginPath = Utils::HostOsInfo::isMacHost() ? QString(QCoreApplication::applicationDirPath() + "/../PlugIns/QmlDesigner") @@ -210,6 +209,7 @@ bool QmlDesignerPlugin::delayedInitialize() void QmlDesignerPlugin::extensionsInitialized() { + integrateIntoQtCreator(d->mainWidget); } static QStringList allUiQmlFilesforCurrentProject(const Utils::FileName &fileName) diff --git a/src/plugins/qmlprofiler/inputeventsmodel.cpp b/src/plugins/qmlprofiler/inputeventsmodel.cpp index 0d1f91d2b8..0c7e9b50fc 100644 --- a/src/plugins/qmlprofiler/inputeventsmodel.cpp +++ b/src/plugins/qmlprofiler/inputeventsmodel.cpp @@ -84,6 +84,7 @@ QVariantMap InputEventsModel::details(int index) const switch (event.type) { case InputKeyPress: type = tr("Key Press"); + // fallthrough case InputKeyRelease: if (type.isEmpty()) type = tr("Key Release"); @@ -97,9 +98,11 @@ QVariantMap InputEventsModel::details(int index) const break; case InputMouseDoubleClick: type = tr("Double Click"); + // fallthrough case InputMousePress: if (type.isEmpty()) type = tr("Mouse Press"); + // fallthrough case InputMouseRelease: if (type.isEmpty()) type = tr("Mouse Release"); diff --git a/src/plugins/qmlprofiler/pixmapcachemodel.cpp b/src/plugins/qmlprofiler/pixmapcachemodel.cpp index 6ea4d5db2b..5af3a12402 100644 --- a/src/plugins/qmlprofiler/pixmapcachemodel.cpp +++ b/src/plugins/qmlprofiler/pixmapcachemodel.cpp @@ -208,9 +208,10 @@ void PixmapCacheModel::loadEvent(const QmlEvent &event, const QmlEventType &type PixmapState &state = pixmap.sizes[newEvent.sizeIndex]; if (state.cacheState == ToBeCached) { - m_lastCacheSizeEvent = updateCacheCount(m_lastCacheSizeEvent, pixmapStartTime, - state.size.width() * state.size.height(), newEvent, - event.typeIndex()); + m_lastCacheSizeEvent = updateCacheCount( + m_lastCacheSizeEvent, pixmapStartTime, + (qint64) state.size.width() * (qint64) state.size.height(), + newEvent, event.typeIndex()); state.cacheState = Cached; } break; @@ -230,7 +231,7 @@ void PixmapCacheModel::loadEvent(const QmlEvent &event, const QmlEventType &type } else if (!uncache && i->cacheState == Uncached) { newEvent.sizeIndex = i - pixmap.sizes.begin(); if (i->size.isValid()) { - pixSize = i->size.width() * i->size.height(); + pixSize = (qint64) i->size.width() * i->size.height(); i->cacheState = Cached; } else { i->cacheState = ToBeCached; @@ -247,7 +248,7 @@ void PixmapCacheModel::loadEvent(const QmlEvent &event, const QmlEventType &type if (uncache && (i->cacheState == Cached || i->cacheState == ToBeCached)) { newEvent.sizeIndex = i - pixmap.sizes.begin(); if (i->size.isValid()) - pixSize = -i->size.width() * i->size.height(); + pixSize = (qint64) -i->size.width() * i->size.height(); i->cacheState = Uncached; break; } else if (!uncache && i->cacheState == Uncacheable) { diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp index ab3e36c539..428b98b2d2 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp @@ -638,7 +638,7 @@ void QmlProfilerStatisticsMainView::parseModel() newRow << new StatisticsViewItem(QString::number(stats.calls), stats.calls); if (d->m_fieldShown[TimePerCall]) { - const qint64 timePerCall = stats.duration / stats.calls; + const qint64 timePerCall = stats.calls > 0 ? stats.duration / stats.calls : 0; newRow << new StatisticsViewItem(Timeline::formatTime(timePerCall), timePerCall); } diff --git a/src/plugins/qtsupport/qtprojectimporter.cpp b/src/plugins/qtsupport/qtprojectimporter.cpp index f2901f02c7..cee4b38057 100644 --- a/src/plugins/qtsupport/qtprojectimporter.cpp +++ b/src/plugins/qtsupport/qtprojectimporter.cpp @@ -243,6 +243,7 @@ Kit *TestQtProjectImporter::createKit(void *directoryData) const QList<BuildInfo *> TestQtProjectImporter::buildInfoListForKit(const Kit *k, void *directoryData) const { + Q_UNUSED(directoryData); assert(m_testData.contains(directoryData)); assert(!m_deletedTestData.contains(directoryData)); assert(static_cast<const DirectoryData *>(directoryData)->importPath == m_path); diff --git a/src/plugins/silversearcher/findinfilessilversearcher.cpp b/src/plugins/silversearcher/findinfilessilversearcher.cpp index 3d40de9349..613066de36 100644 --- a/src/plugins/silversearcher/findinfilessilversearcher.cpp +++ b/src/plugins/silversearcher/findinfilessilversearcher.cpp @@ -192,7 +192,7 @@ IEditor *FindInFilesSilverSearcher::openEditor(const SearchResultItem & /*item*/ return 0; } -void FindInFilesSilverSearcher::readSettings(QSettings */*settings*/) +void FindInFilesSilverSearcher::readSettings(QSettings * /*settings*/) { } diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index eb3fa0dd5f..5fd4e09ab0 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -2724,7 +2724,8 @@ void tst_Dumpers::dumper_data() + Check("ob", "\"An Object\"", "@QWidget") + Check("ob1", "\"Another Object\"", "@QObject") + Check("ob2", "\"A Subobject\"", "@QObject") - + Check("ob.[extra].[connections].0.0.receiver", "\"Another Object\"", "@QObject"); + + Check("ob.[extra].[connections].0.0.receiver", "\"Another Object\"", + "@QObject") % NoCdbEngine; QString senderData = diff --git a/tests/auto/debugger/tst_offsets.cpp b/tests/auto/debugger/tst_offsets.cpp index ee39d08a76..11009cd802 100644 --- a/tests/auto/debugger/tst_offsets.cpp +++ b/tests/auto/debugger/tst_offsets.cpp @@ -146,12 +146,22 @@ void tst_offsets::offsets_data() const int qtVersion = QT_VERSION; - if (qtVersion >= 0x50600) + if (qtVersion >= 0x50700) #ifdef Q_OS_WIN # ifdef Q_CC_MSVC OFFSET_TEST(QFilePrivate, fileName) << 184 << 248; # else // MinGW - OFFSET_TEST(QFilePrivate, fileName) << 164 << 248; + OFFSET_TEST(QFilePrivate, fileName) << 172 << 248; +# endif +#else + OFFSET_TEST(QFilePrivate, fileName) << 168 << 248; +#endif + else if (qtVersion >= 0x50600) +#ifdef Q_OS_WIN +# ifdef Q_CC_MSVC + OFFSET_TEST(QFilePrivate, fileName) << 184 << 248; +# else // MinGW + OFFSET_TEST(QFilePrivate, fileName) << 180 << 248; # endif #else OFFSET_TEST(QFilePrivate, fileName) << 168 << 248; diff --git a/tests/system/shared/debugger.py b/tests/system/shared/debugger.py index 13f22f4a22..74ea190a30 100644 --- a/tests/system/shared/debugger.py +++ b/tests/system/shared/debugger.py @@ -128,8 +128,7 @@ def doSimpleDebugging(kitCount, currentKit, currentConfigName, pressContinueCoun expectedLabelTexts = ['Stopped\.', 'Stopped at breakpoint \d+ \(\d+\) in thread \d+\.'] if len(expectedBPOrder) == 0: expectedLabelTexts.append("Running\.") - if JIRA.isBugStillOpen(17492): - expectedLabelTexts.append("QML Debugger: Error: Unknown socket error 0") + expectedLabelTexts.append("QML Debugger: Error: Unknown socket error 0") switchViewTo(ViewConstants.PROJECTS) switchToBuildOrRunSettingsFor(kitCount, currentKit, ProjectSettings.RUN) ensureChecked(waitForObject("{container=':Qt Creator.scrollArea_QScrollArea' text='Enable QML' " |