diff --git a/qbs/imports/QtcLibrary.qbs b/qbs/imports/QtcLibrary.qbs index 684a18cb12f..e4dd782b116 100644 --- a/qbs/imports/QtcLibrary.qbs +++ b/qbs/imports/QtcLibrary.qbs @@ -5,6 +5,7 @@ QtcProduct { type: ["dynamiclibrary", "dynamiclibrary_symlink", "qtc.dev-module"] installDir: qtc.ide_library_path installTags: ["dynamiclibrary", "dynamiclibrary_symlink"] + useNonGuiPchFile: true Depends { condition: qtc.testsEnabled name: "Qt.test" diff --git a/qbs/imports/QtcPlugin.qbs b/qbs/imports/QtcPlugin.qbs index 88ec4dff16a..ed6d2b6760e 100644 --- a/qbs/imports/QtcPlugin.qbs +++ b/qbs/imports/QtcPlugin.qbs @@ -6,6 +6,7 @@ QtcProduct { type: ["dynamiclibrary", "pluginSpec", "qtc.dev-module"] installDir: qtc.ide_plugin_path installTags: ["dynamiclibrary"] + useGuiPchFile: true property var pluginJsonReplacements property var pluginRecommends: [] diff --git a/qbs/imports/QtcProduct.qbs b/qbs/imports/QtcProduct.qbs index 3c789ed3de5..fee3782c8c6 100644 --- a/qbs/imports/QtcProduct.qbs +++ b/qbs/imports/QtcProduct.qbs @@ -9,6 +9,11 @@ Product { property string installDir property stringList installTags: type property string fileName: FileInfo.fileName(sourceDirectory) + ".qbs" + property bool useNonGuiPchFile: false + property bool useGuiPchFile: false + property string pathToSharedSources: FileInfo.joinPaths(path, + FileInfo.relativePath(FileInfo.joinPaths('/', qtc.ide_qbs_imports_path), + FileInfo.joinPaths('/', qtc.ide_shared_sources_path))) Depends { name: "cpp" } Depends { name: "qtc" } @@ -24,6 +29,7 @@ Product { } cpp.minimumOsxVersion: "10.7" cpp.minimumWindowsVersion: qbs.architecture === "x86" ? "5.1" : "5.2" + cpp.useCxxPrecompiledHeader: useNonGuiPchFile || useGuiPchFile cpp.visibility: "minimal" Depends { name: "Qt.core" } @@ -39,4 +45,20 @@ Product { qbs.install: true qbs.installDir: qtc.ide_qbs_modules_path + '/' + product.name } + + Group { + name: "standard pch file (non-gui)" + condition: useNonGuiPchFile + prefix: pathToSharedSources + '/' + files: ["qtcreator_pch.h"] + fileTags: ["cpp_pch_src"] + } + + Group { + name: "standard pch file (gui)" + condition: useGuiPchFile + prefix: pathToSharedSources + '/' + files: ["qtcreator_gui_pch.h"] + fileTags: ["cpp_pch_src"] + } } diff --git a/qbs/imports/QtcTool.qbs b/qbs/imports/QtcTool.qbs index 7d75ba5ae77..e8dd54efaa1 100644 --- a/qbs/imports/QtcTool.qbs +++ b/qbs/imports/QtcTool.qbs @@ -5,6 +5,7 @@ QtcProduct { type: ["application"] consoleApplication: true installDir: qtc.ide_libexec_path + useNonGuiPchFile: true cpp.rpaths: { var relativePathToLibs = FileInfo.relativePath('/' + qtc.ide_libexec_path, diff --git a/qbs/imports/src b/qbs/imports/src new file mode 100644 index 00000000000..e69de29bb2d diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs index 2b17ae13798..5f7e7de1b3f 100644 --- a/qbs/modules/qtc/qtc.qbs +++ b/qbs/modules/qtc/qtc.qbs @@ -51,6 +51,7 @@ Module { property string ide_qbs_resources_path: "qbs-resources" property string ide_qbs_modules_path: ide_qbs_resources_path + "/modules" property string ide_qbs_imports_path: ide_qbs_resources_path + "/imports" + property string ide_shared_sources_path: "src/shared" property bool make_dev_package: false diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/behaviornodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/behaviornodeinstance.cpp index 5630327eb9d..0e360cb028c 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/behaviornodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/behaviornodeinstance.cpp @@ -65,7 +65,7 @@ void BehaviorNodeInstance::resetProperty(const PropertyName &name) PropertyNameList BehaviorNodeInstance::ignoredProperties() const { - return PropertyNameList() << "enabled"; + return PropertyNameList({"enabled"}); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/layoutnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/layoutnodeinstance.cpp index 40bea716ea4..e92b6a9a51b 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/layoutnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/layoutnodeinstance.cpp @@ -70,7 +70,8 @@ void LayoutNodeInstance::refreshLayoutable() PropertyNameList LayoutNodeInstance::ignoredProperties() const { - return PropertyNameList() << "move" << "add" << "populate"; + static const PropertyNameList properties({"move", "add", "populate"}); + return properties; } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/positionernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/positionernodeinstance.cpp index 4e222bcd14d..1e58cdf55ba 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/positionernodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/positionernodeinstance.cpp @@ -76,8 +76,8 @@ void PositionerNodeInstance::refreshLayoutable() PropertyNameList PositionerNodeInstance::ignoredProperties() const { - return PropertyNameList() << "move" << "add" << "populate"; -} - + static const PropertyNameList properties({"move", "add", "populate"}); + return properties; } +} // namespace Internal } // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmltransitionnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmltransitionnodeinstance.cpp index 12e6d5070ac..ff94549b066 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmltransitionnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmltransitionnodeinstance.cpp @@ -52,7 +52,8 @@ bool QmlTransitionNodeInstance::isTransition() const PropertyNameList QmlTransitionNodeInstance::ignoredProperties() const { - return PropertyNameList() << "from" << "to"; + static const PropertyNameList properties({"from", "to"}); + return properties; } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp index 8fb7cc3347d..c84dcc468e1 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -734,15 +734,15 @@ bool QuickItemNodeInstance::hasAnchor(const PropertyName &name) const static bool isValidAnchorName(const PropertyName &name) { - static PropertyNameList anchorNameList(PropertyNameList() << "anchors.top" - << "anchors.left" - << "anchors.right" - << "anchors.bottom" - << "anchors.verticalCenter" - << "anchors.horizontalCenter" - << "anchors.fill" - << "anchors.centerIn" - << "anchors.baseline"); + static PropertyNameList anchorNameList({"anchors.top", + "anchors.left", + "anchors.right", + "anchors.bottom", + "anchors.verticalCenter", + "anchors.horizontalCenter", + "anchors.fill", + "anchors.centerIn", + "anchors.baseline"}); return anchorNameList.contains(name); } diff --git a/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.cpp b/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.cpp index 2af7f6cd871..b55374220dc 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.cpp @@ -392,7 +392,7 @@ QVariant fixResourcePaths(const QVariant &value) if (QFileInfo(fixedPath).exists()) { fixedPath.replace(QLatin1String("//"), QLatin1String("/")); fixedPath.replace(QLatin1Char('\\'), QLatin1Char('/')); - return QUrl(fixedPath); + return QUrl::fromLocalFile(fixedPath); } } } diff --git a/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate_56.cpp b/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate_56.cpp index 3daafd5af10..0fe7f5d2288 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate_56.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate_56.cpp @@ -105,7 +105,7 @@ QVariant fixResourcePaths(const QVariant &value) if (QFileInfo(fixedPath).exists()) { fixedPath.replace(QLatin1String("//"), QLatin1String("/")); fixedPath.replace(QLatin1Char('\\'), QLatin1Char('/')); - return QUrl(fixedPath); + return QUrl::fromLocalFile(fixedPath); } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/AnchorButtons.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/AnchorButtons.qml index cd89a3f06f5..58e8df834db 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/AnchorButtons.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/AnchorButtons.qml @@ -34,6 +34,7 @@ ButtonRow { ButtonRowButton { iconSource: "images/anchor-top.png" + tooltip: qsTr("Anchor item to the top.") property bool topAnchored: anchorBackend.topAnchored onTopAnchoredChanged: { @@ -53,6 +54,7 @@ ButtonRow { ButtonRowButton { iconSource: "images/anchor-bottom.png" + tooltip: qsTr("Anchor item to the bottom.") property bool bottomAnchored: anchorBackend.bottomAnchored onBottomAnchoredChanged: { @@ -73,6 +75,7 @@ ButtonRow { ButtonRowButton { iconSource: "images/anchor-left.png" + tooltip: qsTr("Anchor item to the left.") property bool leftAnchored: anchorBackend.leftAnchored onLeftAnchoredChanged: { @@ -92,6 +95,7 @@ ButtonRow { ButtonRowButton { iconSource: "images/anchor-right.png" + tooltip: qsTr("Anchor item to the right.") property bool rightAnchored: anchorBackend.rightAnchored onRightAnchoredChanged: { @@ -116,6 +120,7 @@ ButtonRow { ButtonRowButton { iconSource: "images/anchor-fill.png" + tooltip: qsTr("Fill parent item.") property bool isFilled: anchorBackend.isFilled onIsFilledChanged: { @@ -137,6 +142,7 @@ ButtonRow { ButtonRowButton { iconSource: "images/anchor-vertical.png" + tooltip: qsTr("Anchor item vertically.") property bool verticalCentered: anchorBackend.verticalCentered; onVerticalCenteredChanged: { @@ -158,6 +164,7 @@ ButtonRow { ButtonRowButton { iconSource: "images/anchor-horizontal.png" + tooltip: qsTr("Anchor item horizontally.") property bool horizontalCentered: anchorBackend.horizontalCentered; onHorizontalCenteredChanged: { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Label.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Label.qml index 5173469e880..09dd75d7b79 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Label.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Label.qml @@ -32,6 +32,8 @@ Controls.Label { id: label property alias tooltip: toolTipArea.tooltip + // workaround because PictureSpecifics.qml still use this + property alias toolTip: toolTipArea.tooltip width: Math.max(Math.min(240, parent.width - 220), 80) color: "#eee" diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnchorRow.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnchorRow.qml index 288592235ce..6602bf5ab08 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnchorRow.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnchorRow.qml @@ -126,6 +126,7 @@ RowLayout { exclusive: true ButtonRowButton { iconSource: verticalAnchor ? "../HelperWidgets/images/anchor-top.png" : "../HelperWidgets/images/anchor-left.png" + tooltip: verticalAnchor ? qsTr("Anchor to the top of the target.") : qsTr("Anchor to the left of the target.") onClicked: { if (!invertRelativeTargets) sameEdgeButtonClicked(); @@ -136,12 +137,14 @@ RowLayout { ButtonRowButton { iconSource: verticalAnchor ? "../HelperWidgets/images/anchor-vertical.png" : "../HelperWidgets/images/anchor-horizontal.png" + tooltip: verticalAnchor ? qsTr("Anchor to the vertical center of the target.") : qsTr("Anchor to the horizontal center of the target.") onClicked: centerButtonClicked(); } ButtonRowButton { iconSource: verticalAnchor ? "../HelperWidgets/images/anchor-bottom.png" : "../HelperWidgets/images/anchor-right.png" + tooltip: verticalAnchor ? qsTr("Anchor to the bottom of the target.") : qsTr("Anchor to the right of the target.") onClicked: { if (!invertRelativeTargets) oppositeEdgeButtonClicked(); diff --git a/share/qtcreator/templates/wizards/autotest/auto.pro b/share/qtcreator/templates/wizards/autotest/auto.pro deleted file mode 100644 index b39fef654c3..00000000000 --- a/share/qtcreator/templates/wizards/autotest/auto.pro +++ /dev/null @@ -1,3 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += %TestCaseName:l% diff --git a/share/qtcreator/templates/wizards/autotest/files/auto.pro b/share/qtcreator/templates/wizards/autotest/files/auto.pro new file mode 100644 index 00000000000..510a3710068 --- /dev/null +++ b/share/qtcreator/templates/wizards/autotest/files/auto.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs + +SUBDIRS += %{JS: '%{TestCaseName}'.toLowerCase()} diff --git a/share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri b/share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri new file mode 100644 index 00000000000..c01bab677c1 --- /dev/null +++ b/share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri @@ -0,0 +1,31 @@ +isEmpty(GOOGLETEST_DIR):GOOGLETEST_DIR=$$(GOOGLETEST_DIR) + +isEmpty(GOOGLETEST_DIR) { + warning("Using googletest src dir specified at Qt Creator wizard") + message("set GOOGLETEST_DIR as environment variable or qmake variable to get rid of this message") + GOOGLETEST_DIR = %{GTestRepository} +} + +!isEmpty(GOOGLETEST_DIR): { + GTEST_SRCDIR = $$GOOGLETEST_DIR/googletest + GMOCK_SRCDIR = $$GOOGLETEST_DIR/googlemock +} + +requires(exists($$GTEST_SRCDIR):exists($$GMOCK_SRCDIR)) + +!exists($$GOOGLETEST_DIR):message("No googletest src dir found - set GOOGLETEST_DIR to enable.") + +@if "%{GTestCXX11}" == "true" +DEFINES += \\ + GTEST_LANG_CXX11 +@endif + +INCLUDEPATH *= \\ + $$GTEST_SRCDIR \\ + $$GTEST_SRCDIR/include \\ + $$GMOCK_SRCDIR \\ + $$GMOCK_SRCDIR/include + +SOURCES += \\ + $$GTEST_SRCDIR/src/gtest-all.cc \\ + $$GMOCK_SRCDIR/src/gmock-all.cc diff --git a/share/qtcreator/templates/wizards/autotest/files/main.cpp b/share/qtcreator/templates/wizards/autotest/files/main.cpp new file mode 100644 index 00000000000..8a4a5671fc3 --- /dev/null +++ b/share/qtcreator/templates/wizards/autotest/files/main.cpp @@ -0,0 +1,31 @@ +%{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 + +int main(int , char **) +{ + std::cout << "Hello World!\\n"; + + return 0; +} +@endif diff --git a/share/qtcreator/templates/wizards/autotest/src.pro b/share/qtcreator/templates/wizards/autotest/files/src.pro similarity index 50% rename from share/qtcreator/templates/wizards/autotest/src.pro rename to share/qtcreator/templates/wizards/autotest/files/src.pro index 61fbe2a5bcf..8d49098b6be 100644 --- a/share/qtcreator/templates/wizards/autotest/src.pro +++ b/share/qtcreator/templates/wizards/autotest/files/src.pro @@ -1,13 +1,18 @@ -@if "%RequireGUI%" == "true" +@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 CONFIG -= app_bundle -@endif TEMPLATE = app -TARGET = %ProjectName% -SOURCES += main.%CppSourceSuffix% +TARGET = %{ProjectName} + +SOURCES += %{MainCppName} diff --git a/share/qtcreator/templates/wizards/autotest/tests.pro b/share/qtcreator/templates/wizards/autotest/files/tests.pro similarity index 100% rename from share/qtcreator/templates/wizards/autotest/tests.pro rename to share/qtcreator/templates/wizards/autotest/files/tests.pro diff --git a/share/qtcreator/templates/wizards/autotest/tmp.pro b/share/qtcreator/templates/wizards/autotest/files/tmp.pro similarity index 81% rename from share/qtcreator/templates/wizards/autotest/tmp.pro rename to share/qtcreator/templates/wizards/autotest/files/tmp.pro index 1569bd45cb7..c64e8c288c8 100644 --- a/share/qtcreator/templates/wizards/autotest/tmp.pro +++ b/share/qtcreator/templates/wizards/autotest/files/tmp.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -@if "%BuildTests%" == "always" +@if "%{BuildTests}" == "always" SUBDIRS += src \ tests @else diff --git a/share/qtcreator/templates/wizards/autotest/files/tst.pro b/share/qtcreator/templates/wizards/autotest/files/tst.pro new file mode 100644 index 00000000000..5f0f7455f47 --- /dev/null +++ b/share/qtcreator/templates/wizards/autotest/files/tst.pro @@ -0,0 +1,34 @@ +@if "%{TestFrameWork}" == "QtTest" +QT += testlib +@if "%{RequireGUI}" == "false" +QT -= gui + +CONFIG += qt console warn_on depend_includepath testcase +CONFIG -= app_bundle +@else +QT += gui +CONFIG += qt warn_on depend_includepath testcase +@endif + +TEMPLATE = app + +SOURCES += %{TestCaseFileWithCppSuffix} +@else +include(../gtest_dependency.pri) + +TEMPLATE = app +@if "%{GTestCXX11}" == "true" +CONFIG += console c++11 +@else +CONFIG += console +@endif +CONFIG -= app_bundle +CONFIG += thread +CONFIG -= qt + +HEADERS += \ + %{TestCaseFileWithHeaderSuffix} + +SOURCES += \ + %{MainCppName} +@endif diff --git a/share/qtcreator/templates/wizards/autotest/files/tst_main.cpp b/share/qtcreator/templates/wizards/autotest/files/tst_main.cpp new file mode 100644 index 00000000000..2e25da44ead --- /dev/null +++ b/share/qtcreator/templates/wizards/autotest/files/tst_main.cpp @@ -0,0 +1,10 @@ +%{Cpp:LicenseTemplate}\ +#include "%{TestCaseFileWithHeaderSuffix}" + +#include + +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/share/qtcreator/templates/wizards/autotest/files/tst_src.cpp b/share/qtcreator/templates/wizards/autotest/files/tst_src.cpp new file mode 100644 index 00000000000..54a68264d2d --- /dev/null +++ b/share/qtcreator/templates/wizards/autotest/files/tst_src.cpp @@ -0,0 +1,60 @@ +%{Cpp:LicenseTemplate}\ +#include +@if "%{RequireApplication}" == "true" +%{JS: QtSupport.qtIncludes([ 'QtCore/QCoreApplication' ], + [ 'QtCore/QCoreApplication' ]) }\ +@endif + +// add necessary includes here + +class %{TestCaseName} : public QObject +{ + Q_OBJECT + +public: + %{TestCaseName}(); + ~%{TestCaseName}(); + +private slots: +@if "%{GenerateInitAndCleanup}" == "true" + void initTestCase(); + void cleanupTestCase(); +@endif + void test_case1(); + +}; + +%{TestCaseName}::%{TestCaseName}() +{ + +} + +%{TestCaseName}::~%{TestCaseName}() +{ + +} + +@if "%{GenerateInitAndCleanup}" == "true" +void %{TestCaseName}::initTestCase() +{ + +} + +void %{TestCaseName}::cleanupTestCase() +{ + +} + +@endif +void %{TestCaseName}::test_case1() +{ + +} + +@if "%{RequireApplication}" == "true" +QTEST_MAIN(%{TestCaseName}) +@else +QTEST_APPLESS_MAIN(%{TestCaseName}) +@endif + +#include "%{JS: 'tst_%{TestCaseName}.moc'.toLowerCase() }" diff --git a/share/qtcreator/templates/wizards/autotest/files/tst_src.h b/share/qtcreator/templates/wizards/autotest/files/tst_src.h new file mode 100644 index 00000000000..9731d06cf58 --- /dev/null +++ b/share/qtcreator/templates/wizards/autotest/files/tst_src.h @@ -0,0 +1,11 @@ +%{Cpp:LicenseTemplate}\ +#include +#include + +using namespace testing; + +TEST(%{TestCaseName}, %{TestSetName}) +{ + EXPECT_EQ(1, 1); + ASSERT_THAT(0, Eq(0)); +} diff --git a/share/qtcreator/templates/wizards/autotest/main.cpp b/share/qtcreator/templates/wizards/autotest/main.cpp deleted file mode 100644 index 3ff500decd6..00000000000 --- a/share/qtcreator/templates/wizards/autotest/main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -@if "%RequireGUI%" == "true" -#include -@else -#include -@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(); -} diff --git a/share/qtcreator/templates/wizards/autotest/tst.pro b/share/qtcreator/templates/wizards/autotest/tst.pro deleted file mode 100644 index 8aa61b767e7..00000000000 --- a/share/qtcreator/templates/wizards/autotest/tst.pro +++ /dev/null @@ -1,14 +0,0 @@ -QT += testlib -@if "%RequireGUI%" == "false" -QT -= gui - -CONFIG += qt console warn_on depend_includepath testcase -CONFIG -= app_bundle -@else -QT += gui -CONFIG += qt warn_on depend_includepath testcase -@endif - -TEMPLATE = app - -SOURCES += tst_%TestCaseName:l%.%CppSourceSuffix% diff --git a/share/qtcreator/templates/wizards/autotest/tst_src.cpp b/share/qtcreator/templates/wizards/autotest/tst_src.cpp deleted file mode 100644 index 65d49e9c18a..00000000000 --- a/share/qtcreator/templates/wizards/autotest/tst_src.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include -@if "%RequireApplication%" == "true" -#include -@endif - -// add necessary includes here - -class %TestCaseName% : public QObject -{ - Q_OBJECT - -public: - %TestCaseName%(); - ~%TestCaseName%(); - -private slots: -@if "%GenerateInitAndCleanup%" == "true" - void initTestCase(); - void cleanupTestCase(); -@endif - void test_case1(); - -}; - -%TestCaseName%::%TestCaseName%() -{ - -} - -%TestCaseName%::~%TestCaseName%() -{ - -} - -@if "%GenerateInitAndCleanup%" == "true" -void %TestCaseName%::initTestCase() -{ - -} - -void %TestCaseName%::cleanupTestCase() -{ - -} - -@endif -void %TestCaseName%::test_case1() -{ - -} - -@if "%RequireApplication%" == "true" -QTEST_MAIN(%TestCaseName%) -@else -QTEST_APPLESS_MAIN(%TestCaseName%) -@endif - -#include "tst_%TestCaseName:l%.moc" diff --git a/share/qtcreator/templates/wizards/autotest/wizard.json b/share/qtcreator/templates/wizards/autotest/wizard.json new file mode 100644 index 00000000000..0a7b6e29aee --- /dev/null +++ b/share/qtcreator/templates/wizards/autotest/wizard.json @@ -0,0 +1,241 @@ +{ + "version": 1, + "supportedProjectTypes": [ "Qt4ProjectManager.Qt4Project" ], + "id": "R.AutoTest", + "category": "H.Project", + "trDescription": "Creates a new project including auto test skeleton.", + "trDisplayName": "Auto Test Project", + "trDisplayCategory": "Other Project", + "icon": "autotest_24.png", + "featuresRequired": [ "QtSupport.Wizards.FeatureQt", "QtSupport.Wizards.FeatureDesktop" ], + "enabled": "%{JS: [ %{Plugins} ].indexOf('AutoTest') >= 0}", + + "options": + [ + { "key": "ProFileName", + "value": "%{JS: Util.fileName('%{ProjectDirectory}/%{ProjectName}', 'pro')}" + }, + { "key": "IsTopLevelProject", + "value": "%{JS: !'%{Exists:ProjectExplorer.Profile.Ids}' }" + }, + { "key": "MainCppName", + "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src') }" + }, + { + "key": "TestCaseFileWithHeaderSuffix", + "value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++hdr') }" + }, + { + "key": "TestCaseFileWithCppSuffix", + "value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++src') }" + } + ], + + "pages": + [ + { + "trDisplayName": "Project Location", + "trShortTitle": "Location", + "typeId": "Project", + "data": + { + "trDescription": "This wizard creates a simple Qmake based project with additional auto test skeleton." + } + }, + { + "trDisplayName": "Project and Test Information", + "trShortTitle": "Details", + "typeId": "Fields", + "data": + [ + { + "name": "TestFrameWork", + "trDisplayName": "Test Framework:", + "type": "ComboBox", + "data": + { + "index": 0, + "items": + [ + { + "trKey": "Qt Test", + "value": "QtTest" + }, + { + "trKey": "Googletest", + "value": "GTest" + } + ] + } + }, + { + "name": "RequireGUI", + "trDisplayName": "GUI Application", + "visible": "%{JS: '%{TestFrameWork}' === 'QtTest'}", + "type": "CheckBox", + "data": { + "checked": false, + "checkedValue": "true", + "uncheckedValue": "false" + } + }, + { + "name": "TestCaseName", + "trDisplayName": "Test Case Name:", + "mandatory": true, + "type": "LineEdit", + "data": { "validator": "^[a-zA-Z_0-9]+$" } + }, + { + "name": "RequireApplication", + "trDisplayName": "Requires QApplication", + "visible": "%{JS: '%{TestFrameWork}' === 'QtTest'}", + "type": "CheckBox", + "data": { + "checked": false, + "checkedValue": "true", + "uncheckedValue": "false" + } + }, + { + "name": "GenerateInitAndCleanup", + "trDisplayName": "Generate initialization and cleanup code", + "visible": "%{JS: '%{TestFrameWork}' === 'QtTest'}", + "type": "CheckBox", + "data": { + "checked": false, + "checkedValue": "true", + "uncheckedValue": "false" + } + }, + { + "name": "TestSetName", + "trDisplayName": "Test Set Name:", + "visible": "%{JS: '%{TestFrameWork}' === 'GTest'}", + "type": "LineEdit", + "data": { "validator": "^[a-zA-Z0-9]+$" } + }, + { + "name": "GTestCXX11", + "trDisplayName": "Enable C++11", + "visible": "%{JS: '%{TestFrameWork}' === 'GTest'}", + "type": "CheckBox", + "data": { + "checked": false, + "checkedValue": "true", + "uncheckedValue": "false" + } + }, + { + "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'}", + "type": "PathChooser", + "data": { + "kind": "existingDirectory" + } + } + ] + }, + { + "trDisplayName": "Kit Selection", + "trShortTitle": "Kits", + "typeId": "Kits", + "enabled": "%{IsTopLevelProject}", + "data": { "projectFilePath": "%{ProFileName}" } + }, + { + "trDisplayName": "Project Management", + "trShortTitle": "Summary", + "typeId": "Summary" + } + ], + "generators": + [ + { + "typeId": "File", + "data": + [ + { + "source": "files/tmp.pro", + "target": "%{ProFileName}", + "openAsProject": true + }, + { + "source": "files/src.pro", + "target": "src/src.pro", + "openInEditor": false + }, + { + "source": "files/main.cpp", + "target": "src/%{MainCppName}", + "openInEditor": true + }, + { + "source": "files/tests.pro", + "target": "tests/tests.pro", + "openInEditor": false + }, + { + "source": "files/auto.pro", + "target": "tests/auto/auto.pro", + "openInEditor": false + }, + { + "source": "files/gtest_dependency.pri", + "target": "tests/auto/gtest_dependency.pri", + "condition": "%{JS: '%{TestFrameWork}' == 'GTest'}", + "openInEditor": false + }, + { + "source": "files/tst.pro", + "target": "%{JS: 'tests/auto/' + '%{TestCaseName}/%{TestCaseName}'.toLowerCase() + '.pro' }", + "openInEditor": false + }, + { + "source": "files/tst_src.h", + "target": "%{JS: 'tests/auto/' + '%{TestCaseName}/'.toLowerCase() + '%{TestCaseFileWithHeaderSuffix}' }", + "condition": "%{JS: '%{TestFrameWork}' == 'GTest'}", + "openInEditor": true + }, + { + "source": "files/tst_src.cpp", + "target": "%{JS: 'tests/auto/' + '%{TestCaseName}/'.toLowerCase() + '%{TestCaseFileWithCppSuffix}' }", + "condition": "%{JS: '%{TestFrameWork}' == 'QtTest'}", + "openInEditor": true + }, + { + "source": "files/tst_main.cpp", + "target": "%{JS: 'tests/auto/' + '%{TestCaseName}'.toLowerCase() + '/%{MainCppName}' }", + "condition": "%{JS: '%{TestFrameWork}' == 'GTest'}", + "openInEditor": true + }, + { + "source": "../projects/git.ignore", + "target": ".gitignore", + "condition": "%{JS: ( %{IsTopLevelProject} && '%{VersionControl}' === 'G.Git' )}" + } + ] + } + ] +} diff --git a/share/qtcreator/templates/wizards/autotest/wizard.xml b/share/qtcreator/templates/wizards/autotest/wizard.xml deleted file mode 100644 index 12f0c1e0075..00000000000 --- a/share/qtcreator/templates/wizards/autotest/wizard.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - - autotest_24.png - Creates a new project including auto test skeleton. - Auto Test; - Other Project - - - - - - - - - - - Project and Test Information - - - - GUI Application - - - - Test Case Name: - - - - Requires QApplication - - - - Generate initialization and cleanup code - - - - - - always - - - debug only - - - - Build auto tests - - - diff --git a/src/libs/extensionsystem/optionsparser.cpp b/src/libs/extensionsystem/optionsparser.cpp index a7b91de70be..852df2863d8 100644 --- a/src/libs/extensionsystem/optionsparser.cpp +++ b/src/libs/extensionsystem/optionsparser.cpp @@ -112,10 +112,10 @@ bool OptionsParser::checkForTestOptions() if (m_currentArg == QLatin1String(TEST_OPTION)) { if (nextToken(RequiredToken)) { if (m_currentArg == QLatin1String("all")) { - foreach (PluginSpec *spec, m_pmPrivate->pluginSpecs) { - if (spec && !m_pmPrivate->containsTestSpec(spec)) - m_pmPrivate->testSpecs.append(PluginManagerPrivate::TestSpec(spec)); - } + m_pmPrivate->testSpecs = + Utils::transform(m_pmPrivate->loadQueue(), [](PluginSpec *spec) { + return PluginManagerPrivate::TestSpec(spec); + }); } else { QStringList args = m_currentArg.split(QLatin1Char(',')); const QString pluginName = args.takeFirst(); diff --git a/src/libs/extensionsystem/plugindetailsview.cpp b/src/libs/extensionsystem/plugindetailsview.cpp index 224a6805b3a..5d51a1e31d7 100644 --- a/src/libs/extensionsystem/plugindetailsview.cpp +++ b/src/libs/extensionsystem/plugindetailsview.cpp @@ -29,6 +29,8 @@ #include "pluginmanager.h" #include "pluginspec.h" +#include + #include #include @@ -88,23 +90,6 @@ void PluginDetailsView::update(PluginSpec *spec) const QString platformString = tr("%1 (current: \"%2\")").arg(pluginPlatformString, PluginManager::platformName()); m_ui->platforms->setText(platformString); - QStringList depStrings; - foreach (const PluginDependency &dep, spec->dependencies()) { - QString depString = dep.name; - depString += QLatin1String(" ("); - depString += dep.version; - switch (dep.type) { - case PluginDependency::Required: - break; - case PluginDependency::Optional: - depString += QLatin1String(", optional"); - break; - case PluginDependency::Test: - depString += QLatin1String(", test"); - break; - } - depString += QLatin1Char(')'); - depStrings.append(depString); - } + const QStringList depStrings = Utils::transform(spec->dependencies(), &PluginDependency::toString); m_ui->dependencies->addItems(depStrings); } diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index cf9e6d30e2e..e26863265e1 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -369,12 +369,10 @@ void PluginManager::loadPlugins() */ bool PluginManager::hasError() { - foreach (PluginSpec *spec, plugins()) { + return Utils::anyOf(plugins(), [](PluginSpec *spec) { // only show errors on startup if plugin is enabled. - if (spec->hasError() && spec->isEffectivelyEnabled()) - return true; - } - return false; + return spec->hasError() && spec->isEffectivelyEnabled(); + }); } /*! @@ -382,19 +380,11 @@ bool PluginManager::hasError() */ QSet PluginManager::pluginsRequiringPlugin(PluginSpec *spec) { - QSet dependingPlugins; - dependingPlugins.insert(spec); - foreach (PluginSpec *checkSpec, d->loadQueue()) { - QHashIterator depIt(checkSpec->dependencySpecs()); - while (depIt.hasNext()) { - depIt.next(); - if (depIt.key().type != PluginDependency::Required) - continue; - if (dependingPlugins.contains(depIt.value())) { - dependingPlugins.insert(checkSpec); - break; // no use to check other dependencies, continue with load queue - } - } + QSet dependingPlugins({spec}); + // recursively add plugins that depend on plugins that.... that depend on spec + foreach (PluginSpec *spec, d->loadQueue()) { + if (spec->requiresAny(dependingPlugins)) + dependingPlugins.insert(spec); } dependingPlugins.remove(spec); return dependingPlugins; @@ -665,9 +655,7 @@ bool PluginManager::parseOptions(const QStringList &args, static inline void indent(QTextStream &str, int indent) { - const QChar blank = QLatin1Char(' '); - for (int i = 0 ; i < indent; i++) - str << blank; + str << QString(indent, ' '); } static inline void formatOption(QTextStream &str, @@ -927,12 +915,9 @@ void PluginManagerPrivate::stopAll() */ void PluginManagerPrivate::deleteAll() { - QList queue = loadQueue(); - QListIterator it(queue); - it.toBack(); - while (it.hasPrevious()) { - loadPlugin(it.previous(), PluginSpec::Deleted); - } + Utils::reverseForeach(loadQueue(), [this](PluginSpec *spec) { + loadPlugin(spec, PluginSpec::Deleted); + }); } #ifdef WITH_TESTS @@ -1225,10 +1210,7 @@ void PluginManagerPrivate::loadPlugins() foreach (PluginSpec *spec, queue) { loadPlugin(spec, PluginSpec::Initialized); } - QListIterator it(queue); - it.toBack(); - while (it.hasPrevious()) { - PluginSpec *spec = it.previous(); + Utils::reverseForeach(queue, [this](PluginSpec *spec) { loadPlugin(spec, PluginSpec::Running); if (spec->state() == PluginSpec::Running) { delayedInitializeQueue.append(spec); @@ -1236,7 +1218,7 @@ void PluginManagerPrivate::loadPlugins() // Plugin initialization failed, so cleanup after it spec->d->kill(); } - } + }); emit q->pluginsChanged(); delayedInitializeTimer = new QTimer; @@ -1420,6 +1402,21 @@ void PluginManagerPrivate::setPluginPaths(const QStringList &paths) readPluginPaths(); } +static QStringList pluginFiles(const QStringList &pluginPaths) +{ + QStringList pluginFiles; + QStringList searchPaths = pluginPaths; + while (!searchPaths.isEmpty()) { + const QDir dir(searchPaths.takeFirst()); + const QFileInfoList files = dir.entryInfoList(QDir::Files | QDir::NoSymLinks); + const QStringList absoluteFilePaths = Utils::transform(files, &QFileInfo::absoluteFilePath); + pluginFiles += Utils::filtered(absoluteFilePaths, [](const QString &path) { return QLibrary::isLibrary(path); }); + const QFileInfoList dirs = dir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot); + searchPaths += Utils::transform(dirs, &QFileInfo::absoluteFilePath); + } + return pluginFiles; +} + /*! \internal */ @@ -1430,24 +1427,10 @@ void PluginManagerPrivate::readPluginPaths() pluginSpecs.clear(); pluginCategories.clear(); - QStringList pluginFiles; - QStringList searchPaths = pluginPaths; - while (!searchPaths.isEmpty()) { - const QDir dir(searchPaths.takeFirst()); - const QFileInfoList files = dir.entryInfoList(QDir::Files | QDir::NoSymLinks); - foreach (const QFileInfo &file, files) { - const QString filePath = file.absoluteFilePath(); - if (QLibrary::isLibrary(filePath)) - pluginFiles.append(filePath); - } - const QFileInfoList dirs = dir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot); - foreach (const QFileInfo &subdir, dirs) - searchPaths << subdir.absoluteFilePath(); - } - defaultCollection = new PluginCollection(QString()); + auto defaultCollection = new PluginCollection(QString()); pluginCategories.insert(QString(), defaultCollection); - foreach (const QString &pluginFile, pluginFiles) { + foreach (const QString &pluginFile, pluginFiles(pluginPaths)) { PluginSpec *spec = new PluginSpec; if (!spec->d->read(pluginFile)) { // not a Qt Creator plugin delete spec; @@ -1492,12 +1475,9 @@ void PluginManagerPrivate::resolveDependencies() spec->d->resolveDependencies(pluginSpecs); } - QListIterator it(loadQueue()); - it.toBack(); - while (it.hasPrevious()) { - PluginSpec *spec = it.previous(); + Utils::reverseForeach(loadQueue(), [](PluginSpec *spec) { spec->d->enableDependenciesIndirectly(); - } + }); } void PluginManagerPrivate::enableOnlyTestedSpecs() @@ -1529,20 +1509,19 @@ void PluginManagerPrivate::enableOnlyTestedSpecs() } } - // Look in argument descriptions of the specs for the option. +// Look in argument descriptions of the specs for the option. PluginSpec *PluginManagerPrivate::pluginForOption(const QString &option, bool *requiresArgument) const { // Look in the plugins for an option *requiresArgument = false; - foreach (PluginSpec *ps, pluginSpecs) { - const PluginSpec::PluginArgumentDescriptions pargs = ps->argumentDescriptions(); - if (!pargs.empty()) { - foreach (PluginArgumentDescription pad, pargs) { - if (pad.name == option) { - *requiresArgument = !pad.parameter.isEmpty(); - return ps; - } - } + foreach (PluginSpec *spec, pluginSpecs) { + PluginArgumentDescription match = Utils::findOrDefault(spec->argumentDescriptions(), + [option](PluginArgumentDescription pad) { + return pad.name == option; + }); + if (!match.name.isEmpty()) { + *requiresArgument = !match.parameter.isEmpty(); + return spec; } } return 0; @@ -1550,10 +1529,7 @@ PluginSpec *PluginManagerPrivate::pluginForOption(const QString &option, bool *r PluginSpec *PluginManagerPrivate::pluginByName(const QString &name) const { - foreach (PluginSpec *spec, pluginSpecs) - if (spec->name() == name) - return spec; - return 0; + return Utils::findOrDefault(pluginSpecs, [name](PluginSpec *spec) { return spec->name() == name; }); } void PluginManagerPrivate::initProfiling() @@ -1586,22 +1562,19 @@ void PluginManagerPrivate::profilingReport(const char *what, const PluginSpec *s void PluginManagerPrivate::profilingSummary() const { if (!m_profileTimer.isNull()) { - typedef QMultiMap Sorter; - Sorter sorter; + QMultiMap sorter; int total = 0; - QHash::ConstIterator it1 = m_profileTotal.constBegin(); - QHash::ConstIterator et1 = m_profileTotal.constEnd(); - for (; it1 != et1; ++it1) { - sorter.insert(it1.value(), it1.key()); - total += it1.value(); + auto totalEnd = m_profileTotal.constEnd(); + for (auto it = m_profileTotal.constBegin(); it != totalEnd; ++it) { + sorter.insert(it.value(), it.key()); + total += it.value(); } - Sorter::ConstIterator it2 = sorter.constBegin(); - Sorter::ConstIterator et2 = sorter.constEnd(); - for (; it2 != et2; ++it2) - qDebug("%-22s %8dms ( %5.2f%% )", qPrintable(it2.value()->name()), - it2.key(), 100.0 * it2.key() / total); + auto sorterEnd = sorter.constEnd(); + for (auto it = sorter.constBegin(); it != sorterEnd; ++it) + qDebug("%-22s %8dms ( %5.2f%% )", qPrintable(it.value()->name()), + it.key(), 100.0 * it.key() / total); qDebug("Total: %8dms", total); } } @@ -1693,12 +1666,9 @@ bool PluginManager::isInitializationDone() QObject *PluginManager::getObjectByName(const QString &name) { QReadLocker lock(&d->m_lock); - QList all = allObjects(); - foreach (QObject *obj, all) { - if (obj->objectName() == name) - return obj; - } - return 0; + return Utils::findOrDefault(allObjects(), [&name](const QObject *obj) { + return obj->objectName() == name; + }); } /*! @@ -1711,10 +1681,7 @@ QObject *PluginManager::getObjectByClassName(const QString &className) { const QByteArray ba = className.toUtf8(); QReadLocker lock(&d->m_lock); - QList all = allObjects(); - foreach (QObject *obj, all) { - if (obj->inherits(ba.constData())) - return obj; - } - return 0; + return Utils::findOrDefault(allObjects(), [&ba](const QObject *obj) { + return obj->inherits(ba.constData()); + }); } diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h index f92af3bdbb9..ec1f04e1286 100644 --- a/src/libs/extensionsystem/pluginmanager_p.h +++ b/src/libs/extensionsystem/pluginmanager_p.h @@ -134,7 +134,6 @@ public: bool m_isInitializationDone = false; private: - PluginCollection *defaultCollection; PluginManager *q; void nextDelayedInitialize(); diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index b7cd3d9777f..ef83caa66d2 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -30,6 +30,8 @@ #include "iplugin_p.h" #include "pluginmanager.h" +#include + #include #include #include @@ -146,6 +148,24 @@ bool PluginDependency::operator==(const PluginDependency &other) const return name == other.name && version == other.version && type == other.type; } +static QString typeString(PluginDependency::Type type) +{ + switch (type) { + case PluginDependency::Optional: + return QString(", optional"); + case PluginDependency::Test: + return QString(", test"); + case PluginDependency::Required: + default: + return QString(); + } +} + +QString PluginDependency::toString() const +{ + return name + " (" + version + typeString(type) + ")"; +} + /*! \internal */ @@ -446,6 +466,14 @@ QHash PluginSpec::dependencySpecs() const return d->dependencySpecs; } +bool PluginSpec::requiresAny(const QSet &plugins) const +{ + return Utils::anyOf(d->dependencySpecs.keys(), [this, &plugins](const PluginDependency &dep) { + return dep.type == PluginDependency::Required + && plugins.contains(d->dependencySpecs.value(dep)); + }); +} + //==========PluginSpecPrivate================== namespace { @@ -877,14 +905,9 @@ bool PluginSpecPrivate::resolveDependencies(const QList &specs) } QHash resolvedDependencies; foreach (const PluginDependency &dependency, dependencies) { - PluginSpec *found = 0; - - foreach (PluginSpec *spec, specs) { - if (spec->provides(dependency.name, dependency.version)) { - found = spec; - break; - } - } + PluginSpec * const found = Utils::findOrDefault(specs, [&dependency](PluginSpec *spec) { + return spec->provides(dependency.name, dependency.version); + }); if (!found) { if (dependency.type == PluginDependency::Required) { hasError = true; diff --git a/src/libs/extensionsystem/pluginspec.h b/src/libs/extensionsystem/pluginspec.h index 7d41c911583..68c6fdd3154 100644 --- a/src/libs/extensionsystem/pluginspec.h +++ b/src/libs/extensionsystem/pluginspec.h @@ -63,6 +63,7 @@ struct EXTENSIONSYSTEM_EXPORT PluginDependency QString version; Type type; bool operator==(const PluginDependency &other) const; + QString toString() const; }; uint qHash(const ExtensionSystem::PluginDependency &value); @@ -118,6 +119,7 @@ public: // dependency specs, valid after 'Resolved' state is reached QHash dependencySpecs() const; + bool requiresAny(const QSet &plugins) const; // linked plugin instance, valid after 'Loaded' state is reached IPlugin *plugin() const; diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index e5fd12d6b97..6756e7b2ed3 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -820,6 +820,9 @@ void Check::visitQmlObject(Node *ast, UiQualifiedId *typeId, const QString typeName = getRightMostIdentifier(typeId)->name.toString(); + if (!m_typeStack.isEmpty() && m_typeStack.last() == QLatin1String("State")) + addMessage(StateCannotHaveChildItem, typeErrorLocation, typeName); + if (checkTypeForDesignerSupport(typeId)) addMessage(WarnUnsupportedTypeInVisualDesigner, typeErrorLocation, typeName); diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp index aa388312f4f..f739668f9f7 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp @@ -104,12 +104,13 @@ ModelManagerInterface::ModelManagerInterface(QObject *parent) m_updateCppQmlTypesTimer = new QTimer(this); m_updateCppQmlTypesTimer->setInterval(1000); m_updateCppQmlTypesTimer->setSingleShot(true); - connect(m_updateCppQmlTypesTimer, SIGNAL(timeout()), SLOT(startCppQmlTypeUpdate())); + connect(m_updateCppQmlTypesTimer, &QTimer::timeout, + this, &ModelManagerInterface::startCppQmlTypeUpdate); m_asyncResetTimer = new QTimer(this); m_asyncResetTimer->setInterval(15000); m_asyncResetTimer->setSingleShot(true); - connect(m_asyncResetTimer, SIGNAL(timeout()), SLOT(resetCodeModel())); + connect(m_asyncResetTimer, &QTimer::timeout, this, &ModelManagerInterface::resetCodeModel); qRegisterMetaType("QmlJS::Document::Ptr"); qRegisterMetaType("QmlJS::LibraryInfo"); diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.h b/src/libs/qmljs/qmljsmodelmanagerinterface.h index 142fc54c175..568fb63593c 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.h +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.h @@ -205,9 +205,11 @@ public: PathsAndLanguages paths, ModelManagerInterface *modelManager, bool emitDocChangedOnDisk, bool libOnly = true); -public slots: + virtual void resetCodeModel(); void removeProjectInfo(ProjectExplorer::Project *project); + void maybeQueueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc); + signals: void documentUpdated(QmlJS::Document::Ptr doc); void documentChangedOnDisk(QmlJS::Document::Ptr doc); @@ -215,12 +217,11 @@ signals: void libraryInfoUpdated(const QString &path, const QmlJS::LibraryInfo &info); void projectInfoUpdated(const ProjectInfo &pinfo); void projectPathChanged(const QString &projectPath); -protected slots: - void maybeQueueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc); - void queueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc, bool scan); - void asyncReset(); - virtual void startCppQmlTypeUpdate(); + protected: + Q_INVOKABLE void queueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc, bool scan); + Q_INVOKABLE void asyncReset(); + virtual void startCppQmlTypeUpdate(); QMutex *mutex() const; virtual QHash languageForSuffix() const; virtual void writeMessageInternal(const QString &msg) const; diff --git a/src/libs/qmljs/qmljsplugindumper.cpp b/src/libs/qmljs/qmljsplugindumper.cpp index f8f726f2cf4..7d13482272b 100644 --- a/src/libs/qmljs/qmljsplugindumper.cpp +++ b/src/libs/qmljs/qmljsplugindumper.cpp @@ -51,8 +51,8 @@ Utils::FileSystemWatcher *PluginDumper::pluginWatcher() if (!m_pluginWatcher) { m_pluginWatcher = new Utils::FileSystemWatcher(this); m_pluginWatcher->setObjectName(QLatin1String("PluginDumperWatcher")); - connect(m_pluginWatcher, SIGNAL(fileChanged(QString)), - this, SLOT(pluginChanged(QString))); + connect(m_pluginWatcher, &Utils::FileSystemWatcher::fileChanged, + this, &PluginDumper::pluginChanged); } return m_pluginWatcher; } @@ -509,8 +509,10 @@ void PluginDumper::runQmlDump(const QmlJS::ModelManagerInterface::ProjectInfo &i { QProcess *process = new QProcess(this); process->setEnvironment(info.qmlDumpEnvironment.toStringList()); - connect(process, SIGNAL(finished(int)), SLOT(qmlPluginTypeDumpDone(int))); - connect(process, SIGNAL(error(QProcess::ProcessError)), SLOT(qmlPluginTypeDumpError(QProcess::ProcessError))); + connect(process, static_cast(&QProcess::finished), + this, &PluginDumper::qmlPluginTypeDumpDone); + connect(process, static_cast(&QProcess::error), + this, &PluginDumper::qmlPluginTypeDumpError); process->start(info.qmlDumpPath, arguments); m_runningQmldumps.insert(process, importPath); } diff --git a/src/libs/qmljs/qmljsplugindumper.h b/src/libs/qmljs/qmljsplugindumper.h index 31c9b5e0194..7d29e6ef3db 100644 --- a/src/libs/qmljs/qmljsplugindumper.h +++ b/src/libs/qmljs/qmljsplugindumper.h @@ -52,13 +52,13 @@ public: void scheduleRedumpPlugins(); void scheduleMaybeRedumpBuiltins(const QmlJS::ModelManagerInterface::ProjectInfo &info); -private slots: - void onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectInfo &info, - bool force = false); - void onLoadPluginTypes(const QString &libraryPath, const QString &importPath, - const QString &importUri, const QString &importVersion); - void dumpBuiltins(const QmlJS::ModelManagerInterface::ProjectInfo &info); - void dumpAllPlugins(); +private: + Q_INVOKABLE void onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectInfo &info, + bool force = false); + Q_INVOKABLE void onLoadPluginTypes(const QString &libraryPath, const QString &importPath, + const QString &importUri, const QString &importVersion); + Q_INVOKABLE void dumpBuiltins(const QmlJS::ModelManagerInterface::ProjectInfo &info); + Q_INVOKABLE void dumpAllPlugins(); void qmlPluginTypeDumpDone(int exitCode); void qmlPluginTypeDumpError(QProcess::ProcessError error); void pluginChanged(const QString &pluginLibrary); diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.cpp b/src/libs/qmljs/qmljsstaticanalysismessage.cpp index 618b26ff481..331fe6079ed 100644 --- a/src/libs/qmljs/qmljsstaticanalysismessage.cpp +++ b/src/libs/qmljs/qmljsstaticanalysismessage.cpp @@ -235,6 +235,8 @@ StaticAnalysisMessages::StaticAnalysisMessages() tr("States are only supported in the root item in a Qt Quick UI form.")); newMsg(ErrReferenceToParentItemNotSupportedInQmlUi, Error, tr("Referencing the parent of the root item is not supported in a Qt Quick UI form.")); + newMsg(StateCannotHaveChildItem, Error, + tr("A State cannot have a child item (%1)."), 1); } } // anonymous namespace diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.h b/src/libs/qmljs/qmljsstaticanalysismessage.h index e5b8f8d8824..ced78ee686a 100644 --- a/src/libs/qmljs/qmljsstaticanalysismessage.h +++ b/src/libs/qmljs/qmljsstaticanalysismessage.h @@ -88,6 +88,7 @@ enum Type HintExtraParentheses = 123, MaybeWarnEqualityTypeCoercion = 126, WarnConfusingExpressionStatement = 127, + StateCannotHaveChildItem = 128, HintDeclarationsShouldBeAtStartOfFunction = 201, HintOneStatementPerLine = 202, WarnImperativeCodeNotEditableInVisualDesigner = 203, diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index 0867bfc2b41..b1044d26e20 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -418,4 +418,24 @@ inline void sort(Container &c, Predicate p) std::sort(c.begin(), c.end(), p); } +////////////////// +// reverseForeach +///////////////// +template +inline void reverseForeach(const Container &c, const Op &operation) +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) + auto rend = c.begin(); + auto it = c.end(); + while (it != rend) { + --it; + operation(*it); + } +#else + auto rend = c.rend(); + for (auto it = c.rbegin(); it != rend; ++it) + operation(*it); +#endif +} + } diff --git a/src/libs/utils/fancymainwindow.cpp b/src/libs/utils/fancymainwindow.cpp index 4fc91537da7..fd315a8e117 100644 --- a/src/libs/utils/fancymainwindow.cpp +++ b/src/libs/utils/fancymainwindow.cpp @@ -153,13 +153,16 @@ public: m_floatButton = new DockWidgetTitleButton(this); m_floatButton->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q)); - m_floatButton->setAccessibleName(QDockWidget::tr("Float")); - m_floatButton->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget")); m_closeButton = new DockWidgetTitleButton(this); m_closeButton->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q)); + +#ifndef QT_NO_ACCESSIBILITY + m_floatButton->setAccessibleName(QDockWidget::tr("Float")); + m_floatButton->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget")); m_closeButton->setAccessibleName(QDockWidget::tr("Close")); m_closeButton->setAccessibleDescription(QDockWidget::tr("Closes the dock widget")); +#endif setActive(false); diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp index e14b67d68c9..edf0384f2db 100644 --- a/src/libs/utils/pathchooser.cpp +++ b/src/libs/utils/pathchooser.cpp @@ -306,24 +306,24 @@ void PathChooser::setEnvironment(const Environment &env) } } -QString PathChooser::path() const -{ - return d->expandedPath(rawPath()); -} - QString PathChooser::rawPath() const { return rawFileName().toString(); } +QString PathChooser::path() const +{ + return fileName().toString(); +} + FileName PathChooser::rawFileName() const { - return FileName::fromUserInput(d->m_lineEdit->text()); + return FileName::fromString(QDir::fromNativeSeparators(d->m_lineEdit->text())); } FileName PathChooser::fileName() const { - return FileName::fromString(path()); + return FileName::fromUserInput(d->expandedPath(rawFileName().toString())); } // FIXME: try to remove again diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp index 7ec77b49a4c..335142c0ef6 100644 --- a/src/libs/utils/shellcommand.cpp +++ b/src/libs/utils/shellcommand.cpp @@ -377,7 +377,7 @@ Utils::SynchronousProcessResponse ShellCommand::runCommand(const Utils::FileName process.setTimeOutMessageBoxEnabled(true); // Run! - response = process.run(binary.toString(), arguments); + response = process.runBlocking(binary.toString(), arguments); } if (!d->m_aborted) { diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp index 32aea54818c..9f6210869db 100644 --- a/src/libs/utils/synchronousprocess.cpp +++ b/src/libs/utils/synchronousprocess.cpp @@ -297,12 +297,12 @@ void SynchronousProcess::setTimeoutS(int timeoutS) if (timeoutS > 0) d->m_maxHangTimerCount = qMax(2, timeoutS); else - d->m_maxHangTimerCount = INT_MAX; + d->m_maxHangTimerCount = INT_MAX / 1000; } int SynchronousProcess::timeoutS() const { - return d->m_maxHangTimerCount == INT_MAX ? -1 : d->m_maxHangTimerCount; + return d->m_maxHangTimerCount == (INT_MAX / 1000) ? -1 : d->m_maxHangTimerCount; } void SynchronousProcess::setCodec(QTextCodec *c) @@ -476,7 +476,7 @@ SynchronousProcessResponse SynchronousProcess::runBlocking(const QString &binary QTC_ASSERT(d->m_process.state() == QProcess::NotRunning, return d->m_result); d->m_result.exitCode = d->m_process.exitCode(); - if (d->m_result.result != SynchronousProcessResponse::StartFailed) { + if (d->m_result.result == SynchronousProcessResponse::StartFailed) { if (d->m_process.exitStatus() != QProcess::NormalExit) d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally; else diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h index 815a3cb695b..eb56729431c 100644 --- a/src/libs/utils/treemodel.h +++ b/src/libs/utils/treemodel.h @@ -41,7 +41,7 @@ public: TreeItem(); virtual ~TreeItem(); - virtual TreeItem *parent() const { return m_parent; } + TreeItem *parent() const { return m_parent; } virtual TreeItem *child(int pos) const; virtual int rowCount() const; @@ -148,7 +148,7 @@ private: }; // A TreeItem with children all of the same type. -template +template class TypedTreeItem : public TreeItem { public: @@ -175,6 +175,10 @@ public: ChildType *findFirstLevelChild(Predicate pred) const { return TreeItem::findFirstLevelChild(pred); } + + ParentType *parent() const { + return static_cast(TreeItem::parent()); + } }; class QTCREATOR_UTILS_EXPORT StaticTreeItem : public TreeItem @@ -241,9 +245,9 @@ protected: // A multi-level model with uniform types per level. // All items below second level have to have identitical types. -template +template class LeveledTreeModel : public TreeModel { public: diff --git a/src/plugins/bineditor/bineditor.pro b/src/plugins/bineditor/bineditor.pro index 89a91bd621d..3dde3eaf67d 100644 --- a/src/plugins/bineditor/bineditor.pro +++ b/src/plugins/bineditor/bineditor.pro @@ -1,10 +1,13 @@ include(../../qtcreatorplugin.pri) +DEFINES += BINEDITOR_LIBRARY + HEADERS += bineditorplugin.h \ - bineditor.h \ + bineditorwidget.h \ bineditorconstants.h \ + bineditor_global.h \ markup.h SOURCES += bineditorplugin.cpp \ - bineditor.cpp \ + bineditorwidget.cpp \ markup.cpp diff --git a/src/plugins/bineditor/bineditor.qbs b/src/plugins/bineditor/bineditor.qbs index 38d8ba5d30c..8d2138598d4 100644 --- a/src/plugins/bineditor/bineditor.qbs +++ b/src/plugins/bineditor/bineditor.qbs @@ -11,9 +11,10 @@ QtcPlugin { Depends { name: "TextEditor" } files: [ - "bineditor.cpp", - "bineditor.h", + "bineditorwidget.cpp", + "bineditorwidget.h", "bineditorconstants.h", + "bineditor_global.h", "bineditorplugin.cpp", "bineditorplugin.h", "markup.cpp", diff --git a/src/plugins/bineditor/bineditor_global.h b/src/plugins/bineditor/bineditor_global.h new file mode 100644 index 00000000000..cfd032e3f03 --- /dev/null +++ b/src/plugins/bineditor/bineditor_global.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +#if defined(BINEDITOR_LIBRARY) +# define BINEDITOR_EXPORT Q_DECL_EXPORT +#else +# define BINEDITOR_EXPORT Q_DECL_IMPORT +#endif diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp index f3592851f37..6f5f75dfc25 100644 --- a/src/plugins/bineditor/bineditorplugin.cpp +++ b/src/plugins/bineditor/bineditorplugin.cpp @@ -24,7 +24,7 @@ ****************************************************************************/ #include "bineditorplugin.h" -#include "bineditor.h" +#include "bineditorwidget.h" #include "bineditorconstants.h" #include diff --git a/src/plugins/bineditor/bineditor.cpp b/src/plugins/bineditor/bineditorwidget.cpp similarity index 99% rename from src/plugins/bineditor/bineditor.cpp rename to src/plugins/bineditor/bineditorwidget.cpp index 1f287ff0458..44e9ccb6940 100644 --- a/src/plugins/bineditor/bineditor.cpp +++ b/src/plugins/bineditor/bineditorwidget.cpp @@ -23,7 +23,7 @@ ** ****************************************************************************/ -#include "bineditor.h" +#include "bineditorwidget.h" #include #include diff --git a/src/plugins/bineditor/bineditor.h b/src/plugins/bineditor/bineditorwidget.h similarity index 98% rename from src/plugins/bineditor/bineditor.h rename to src/plugins/bineditor/bineditorwidget.h index 45bfb3bac32..dd54b53c7fb 100644 --- a/src/plugins/bineditor/bineditor.h +++ b/src/plugins/bineditor/bineditorwidget.h @@ -25,6 +25,7 @@ #pragma once +#include "bineditor_global.h" #include "markup.h" #include @@ -46,7 +47,7 @@ namespace TextEditor { class FontSettings; } namespace BinEditor { -class BinEditorWidget : public QAbstractScrollArea +class BINEDITOR_EXPORT BinEditorWidget : public QAbstractScrollArea { Q_OBJECT Q_PROPERTY(bool modified READ isModified WRITE setModified DESIGNABLE false) diff --git a/src/plugins/bookmarks/bookmarksplugin.cpp b/src/plugins/bookmarks/bookmarksplugin.cpp index 8e5e75d4c33..89119bb830b 100644 --- a/src/plugins/bookmarks/bookmarksplugin.cpp +++ b/src/plugins/bookmarks/bookmarksplugin.cpp @@ -71,9 +71,11 @@ bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *) mbm->menu()->setTitle(tr("&Bookmarks")); mtools->addMenu(mbm); + const Context editorManagerContext(Core::Constants::C_EDITORMANAGER); + //Toggle m_toggleAction = new QAction(tr("Toggle Bookmark"), this); - Command *cmd = ActionManager::registerAction(m_toggleAction, BOOKMARKS_TOGGLE_ACTION); + Command *cmd = ActionManager::registerAction(m_toggleAction, BOOKMARKS_TOGGLE_ACTION, editorManagerContext); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+M") : tr("Ctrl+M"))); mbm->addAction(cmd); @@ -81,13 +83,13 @@ bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *) //Previous m_prevAction = new QAction(tr("Previous Bookmark"), this); - cmd = ActionManager::registerAction(m_prevAction, BOOKMARKS_PREV_ACTION); + cmd = ActionManager::registerAction(m_prevAction, BOOKMARKS_PREV_ACTION, editorManagerContext); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+,") : tr("Ctrl+,"))); mbm->addAction(cmd); //Next m_nextAction = new QAction(tr("Next Bookmark"), this); - cmd = ActionManager::registerAction(m_nextAction, BOOKMARKS_NEXT_ACTION); + cmd = ActionManager::registerAction(m_nextAction, BOOKMARKS_NEXT_ACTION, editorManagerContext); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+.") : tr("Ctrl+."))); mbm->addAction(cmd); @@ -95,12 +97,12 @@ bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *) //Previous Doc m_docPrevAction = new QAction(tr("Previous Bookmark in Document"), this); - cmd = ActionManager::registerAction(m_docPrevAction, BOOKMARKS_PREVDOC_ACTION); + cmd = ActionManager::registerAction(m_docPrevAction, BOOKMARKS_PREVDOC_ACTION, editorManagerContext); mbm->addAction(cmd); //Next Doc m_docNextAction = new QAction(tr("Next Bookmark in Document"), this); - cmd = ActionManager::registerAction(m_docNextAction, BOOKMARKS_NEXTDOC_ACTION); + cmd = ActionManager::registerAction(m_docNextAction, BOOKMARKS_NEXTDOC_ACTION, editorManagerContext); mbm->addAction(cmd); m_editBookmarkAction = new QAction(tr("Edit Bookmark"), this); diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index d19c12035df..5955d351f0e 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -613,7 +613,7 @@ void ClangCompletionAssistProcessor::handleAvailableCompletions( QTC_CHECK(m_completions.isEmpty()); m_completions = toAssistProposalItems(completions); - if (m_addSnippets) + if (m_addSnippets && !m_completions.isEmpty()) addSnippets(); setAsyncProposalAvailable(createProposal(neededCorrection)); diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index 54f35b9dca4..2714c254b91 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -932,18 +932,28 @@ void ClangCodeCompletionTest::testCompleteConstructorAndFallbackToGlobalCompleti QVERIFY(!hasSnippet(t.proposal, "class")); } +// Explicitly Inserting The Dot +// ---------------------------- +// Inserting the dot for is important since it will send the editor +// content to the backend and thus generate an unsaved file on the backend +// side. The unsaved file enables us to do the dot to arrow correction. + void ClangCodeCompletionTest::testCompleteWithDotToArrowCorrection() { - // Inserting the dot for this test is important since it will send the editor - // content to the backend and thus generate an unsaved file on the backend - // side. The unsaved file enables us to do the dot to arrow correction. - ProjectLessCompletionTest t("dotToArrowCorrection.cpp", - QStringLiteral(".")); + QStringLiteral(".")); // See above "Explicitly Inserting The Dot" QVERIFY(hasItem(t.proposal, "member")); } +void ClangCodeCompletionTest::testDontCompleteWithDotToArrowCorrectionForFloats() +{ + ProjectLessCompletionTest t("noDotToArrowCorrectionForFloats.cpp", + QStringLiteral(".")); // See above "Explicitly Inserting The Dot" + + QCOMPARE(t.proposal->size(), 0); +} + void ClangCodeCompletionTest::testCompleteProjectDependingCode() { const TestDocument testDocument("completionWithProject.cpp"); diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.h b/src/plugins/clangcodemodel/test/clangcodecompletion_test.h index bd9151bcac4..3f163c62663 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.h +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.h @@ -48,6 +48,7 @@ private slots: void testCompleteConstructorAndFallbackToGlobalCompletion(); void testCompleteWithDotToArrowCorrection(); + void testDontCompleteWithDotToArrowCorrectionForFloats(); void testCompleteProjectDependingCode(); void testCompleteProjectDependingCodeAfterChangingProject(); diff --git a/src/plugins/clangcodemodel/test/data/clangtestdata.qrc b/src/plugins/clangcodemodel/test/data/clangtestdata.qrc index c013ccd7f40..ad5ccb47681 100644 --- a/src/plugins/clangcodemodel/test/data/clangtestdata.qrc +++ b/src/plugins/clangcodemodel/test/data/clangtestdata.qrc @@ -22,5 +22,6 @@ objc_messages_3.mm preprocessorKeywordsCompletion.cpp dotToArrowCorrection.cpp + noDotToArrowCorrectionForFloats.cpp diff --git a/src/plugins/clangcodemodel/test/data/noDotToArrowCorrectionForFloats.cpp b/src/plugins/clangcodemodel/test/data/noDotToArrowCorrectionForFloats.cpp new file mode 100644 index 00000000000..7b29c3e171d --- /dev/null +++ b/src/plugins/clangcodemodel/test/data/noDotToArrowCorrectionForFloats.cpp @@ -0,0 +1,4 @@ +void f() +{ + 0 /* COMPLETE HERE */ +} diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index 38954807835..1064d308243 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -97,20 +96,14 @@ static QStringList toArguments(const CMakeConfig &config, const ProjectExplorer: // -------------------------------------------------------------------- BuildDirManager::BuildDirManager(CMakeBuildConfiguration *bc) : - m_buildConfiguration(bc), - m_watcher(new QFileSystemWatcher(this)) + m_buildConfiguration(bc) { QTC_ASSERT(bc, return); m_projectName = sourceDirectory().fileName(); m_reparseTimer.setSingleShot(true); - m_reparseTimer.setInterval(5000); + m_reparseTimer.setInterval(2000); connect(&m_reparseTimer, &QTimer::timeout, this, &BuildDirManager::parse); - - connect(m_watcher, &QFileSystemWatcher::fileChanged, this, [this]() { - if (!isParsing()) - m_reparseTimer.start(); - }); } BuildDirManager::~BuildDirManager() @@ -157,6 +150,18 @@ bool BuildDirManager::isParsing() const return false; } +void BuildDirManager::cmakeFilesChanged() +{ + if (isParsing()) + return; + + const CMakeTool *tool = CMakeKitInformation::cmakeTool(m_buildConfiguration->target()->kit()); + if (!tool->isAutoRun()) + return; + + m_reparseTimer.start(); +} + void BuildDirManager::forceReparse() { if (m_buildConfiguration->target()->activeBuildConfiguration() != m_buildConfiguration) @@ -180,13 +185,8 @@ void BuildDirManager::resetData() m_cmakeCache.clear(); m_projectName.clear(); m_buildTargets.clear(); - m_watchedFiles.clear(); qDeleteAll(m_files); m_files.clear(); - - const QStringList watchedFiles = m_watcher->files(); - if (!watchedFiles.isEmpty()) - m_watcher->removePaths(watchedFiles); } bool BuildDirManager::persistCMakeState() @@ -223,8 +223,8 @@ void BuildDirManager::parse() return; } - const bool mustUpdate = m_watchedFiles.isEmpty() - || Utils::anyOf(m_watchedFiles, [&cbpFileFi](const Utils::FileName &f) { + const bool mustUpdate = m_cmakeFiles.isEmpty() + || Utils::anyOf(m_cmakeFiles, [&cbpFileFi](const Utils::FileName &f) { return f.toFileInfo().lastModified() > cbpFileFi.lastModified(); }); if (mustUpdate) { @@ -251,11 +251,6 @@ void BuildDirManager::clearCache() forceReparse(); } -bool BuildDirManager::isProjectFile(const Utils::FileName &fileName) const -{ - return m_watchedFiles.contains(fileName); -} - QString BuildDirManager::projectName() const { return m_projectName; @@ -271,6 +266,11 @@ QList BuildDirManager::files() return m_files; } +QSet BuildDirManager::cmakeFiles() +{ + return m_cmakeFiles; +} + void BuildDirManager::clearFiles() { m_files.clear(); @@ -355,15 +355,19 @@ void BuildDirManager::extractData() m_projectName = sourceDirectory().fileName(); m_files.append(new ProjectExplorer::FileNode(topCMake, ProjectExplorer::ProjectFileType, false)); - m_watchedFiles.insert(topCMake); + // Do not insert topCMake into m_cmakeFiles: The project already watches that! // Find cbp file QString cbpFile = CMakeManager::findCbpFile(workDirectory().toString()); if (cbpFile.isEmpty()) return; + m_cmakeFiles.insert(Utils::FileName::fromString(cbpFile)); - m_watcher->addPath(cbpFile); - m_watcher->addPath(workDirectory().toString() + QLatin1String("/CMakeCache.txt")); + // Add CMakeCache.txt file: + Utils::FileName cacheFile = workDirectory(); + cacheFile.appendPath(QLatin1String("CMakeCache.txt")); + if (cacheFile.toFileInfo().exists()) + m_cmakeFiles.insert(cacheFile); // setFolderName CMakeCbpParser cbpparser; @@ -374,21 +378,14 @@ void BuildDirManager::extractData() m_projectName = cbpparser.projectName(); m_files = cbpparser.fileList(); - QSet projectFiles; if (cbpparser.hasCMakeFiles()) { m_files.append(cbpparser.cmakeFileList()); foreach (const ProjectExplorer::FileNode *node, cbpparser.cmakeFileList()) - projectFiles.insert(node->filePath()); + m_cmakeFiles.insert(node->filePath()); } else { m_files.append(new ProjectExplorer::FileNode(topCMake, ProjectExplorer::ProjectFileType, false)); - projectFiles.insert(topCMake); } - m_watchedFiles = projectFiles; - const QStringList toWatch - = Utils::transform(m_watchedFiles.toList(), [](const Utils::FileName &fn) { return fn.toString(); }); - m_watcher->addPaths(toWatch); - m_buildTargets = cbpparser.buildTargets(); } diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h index 419a87c3d15..d830e8a8595 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.h +++ b/src/plugins/cmakeprojectmanager/builddirmanager.h @@ -73,6 +73,8 @@ public: const CMakeConfig intendedConfiguration() const; bool isParsing() const; + void cmakeFilesChanged(); + void parse(); void clearCache(); void forceReparse(); @@ -80,10 +82,10 @@ public: void resetData(); bool persistCMakeState(); - bool isProjectFile(const Utils::FileName &fileName) const; QString projectName() const; QList buildTargets() const; QList files(); + QSet cmakeFiles(); void clearFiles(); CMakeConfig parsedConfiguration() const; @@ -115,10 +117,9 @@ private: QTemporaryDir *m_tempDir = nullptr; mutable CMakeConfig m_cmakeCache; - QSet m_watchedFiles; + QSet m_cmakeFiles; QString m_projectName; QList m_buildTargets; - QFileSystemWatcher *m_watcher; QList m_files; // For error reporting: diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 8d9d46e4ba0..a013083c572 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -71,6 +71,11 @@ CMakeBuildConfiguration::~CMakeBuildConfiguration() m_buildDirManager->deleteLater(); // Do not block while waiting for cmake... } +void CMakeBuildConfiguration::cmakeFilesChanged() +{ + m_buildDirManager->cmakeFilesChanged(); +} + bool CMakeBuildConfiguration::isEnabled() const { return m_error.isEmpty(); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index 37ec1aa4275..d56965ffb6c 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -52,6 +52,8 @@ public: CMakeBuildConfiguration(ProjectExplorer::Target *parent); ~CMakeBuildConfiguration(); + void cmakeFilesChanged(); + bool isEnabled() const override; QString disabledReason() const override; diff --git a/src/plugins/cmakeprojectmanager/cmakefile.cpp b/src/plugins/cmakeprojectmanager/cmakefile.cpp index 0d338840166..30a1db0e153 100644 --- a/src/plugins/cmakeprojectmanager/cmakefile.cpp +++ b/src/plugins/cmakeprojectmanager/cmakefile.cpp @@ -27,6 +27,8 @@ #include "cmakeproject.h" #include "cmakeprojectconstants.h" +#include + #include using namespace Utils; @@ -34,7 +36,7 @@ using namespace Utils; namespace CMakeProjectManager { namespace Internal { -CMakeFile::CMakeFile(const FileName &fileName) +CMakeFile::CMakeFile(CMakeProject *project, const FileName &fileName) : m_project(project) { setId("Cmake.ProjectFile"); setMimeType(QLatin1String(Constants::CMAKEPROJECTMIMETYPE)); @@ -48,5 +50,15 @@ Core::IDocument::ReloadBehavior CMakeFile::reloadBehavior(ChangeTrigger state, C return BehaviorSilent; } +bool CMakeFile::reload(QString *errorString, Core::IDocument::ReloadFlag flag, Core::IDocument::ChangeType type) +{ + Q_UNUSED(errorString); + Q_UNUSED(flag); + + if (type != TypePermissions) + m_project->handleCmakeFileChanged(); + return true; +} + } // namespace Internal } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakefile.h b/src/plugins/cmakeprojectmanager/cmakefile.h index e5018ce7315..606012ea244 100644 --- a/src/plugins/cmakeprojectmanager/cmakefile.h +++ b/src/plugins/cmakeprojectmanager/cmakefile.h @@ -35,9 +35,13 @@ namespace Internal { class CMakeFile : public Core::IDocument { public: - CMakeFile(const Utils::FileName &fileName); + CMakeFile(CMakeProject *project, const Utils::FileName &fileName); ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override; + bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override; + +private: + CMakeProject *m_project; }; } // namespace Internal diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index e7c78ab01df..bb09ec627a5 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -36,6 +36,7 @@ #include "cmakeprojectmanager.h" #include +#include #include #include #include @@ -88,11 +89,13 @@ CMakeProject::CMakeProject(CMakeManager *manager, const FileName &fileName) { setId(Constants::CMAKEPROJECT_ID); setProjectManager(manager); - setDocument(new CMakeFile(fileName)); + setDocument(new Internal::CMakeFile(this, fileName)); + setRootProjectNode(new CMakeProjectNode(fileName)); setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX)); + Core::DocumentManager::addDocument(document()); rootProjectNode()->setDisplayName(fileName.parentDir().fileName()); connect(this, &CMakeProject::activeTargetChanged, this, &CMakeProject::handleActiveTargetChanged); @@ -217,6 +220,29 @@ void CMakeProject::parseCMakeOutput() rootProjectNode()->setDisplayName(bdm->projectName()); + // Delete no longer necessary file watcher: + const QSet currentWatched + = Utils::transform(m_watchedFiles, [](CMakeFile *cmf) { return cmf->filePath(); }); + const QSet toWatch = bdm->cmakeFiles(); + QSet toDelete = currentWatched; + toDelete.subtract(toWatch); + m_watchedFiles = Utils::filtered(m_watchedFiles, [&toDelete](Internal::CMakeFile *cmf) { + if (toDelete.contains(cmf->filePath())) { + delete cmf; + return false; + } + return true; + }); + + // Add new file watchers: + QSet toAdd = toWatch; + toAdd.subtract(currentWatched); + foreach (const Utils::FileName &fn, toAdd) { + CMakeFile *cm = new CMakeFile(this, fn); + Core::DocumentManager::addDocument(cm); + m_watchedFiles.insert(cm); + } + buildTree(static_cast(rootProjectNode()), bdm->files()); bdm->clearFiles(); // Some of the FileNodes in files() were deleted! @@ -512,6 +538,15 @@ bool CMakeProject::setupTarget(Target *t) return true; } +void CMakeProject::handleCmakeFileChanged() +{ + if (Target *t = activeTarget()) { + if (auto bc = qobject_cast(t->activeBuildConfiguration())) { + bc->cmakeFilesChanged(); + } + } +} + void CMakeProject::handleActiveTargetChanged() { if (m_connectedTarget) { diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index 38126f5f9aa..27e07d8f073 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -120,6 +120,8 @@ protected: bool setupTarget(ProjectExplorer::Target *t) override; private: + void handleCmakeFileChanged(); + void handleActiveTargetChanged(); void handleActiveBuildConfigurationChanged(); void handleParsingStarted(); @@ -144,7 +146,10 @@ private: QFuture m_codeModelFuture; QList m_extraCompilers; + QSet m_watchedFiles; + friend class Internal::CMakeBuildConfiguration; + friend class Internal::CMakeFile; }; } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp index adeae906a55..ca133101140 100644 --- a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp +++ b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -56,7 +57,7 @@ class CMakeToolTreeItem; // CMakeToolItemModel // -------------------------------------------------------------------------- -class CMakeToolItemModel : public LeveledTreeModel +class CMakeToolItemModel : public LeveledTreeModel { Q_DECLARE_TR_FUNCTIONS(CMakeProjectManager::CMakeSettingsPage) @@ -65,12 +66,13 @@ public: CMakeToolTreeItem *cmakeToolItem(const Core::Id &id) const; CMakeToolTreeItem *cmakeToolItem(const QModelIndex &index) const; - QModelIndex addCMakeTool(const QString &name, const FileName &executable, const bool isAutoDetected); + QModelIndex addCMakeTool(const QString &name, const FileName &executable, const bool autoRun, const bool isAutoDetected); void addCMakeTool(const CMakeTool *item, bool changed); TreeItem *autoGroupItem() const; TreeItem *manualGroupItem() const; void reevaluateChangedFlag(CMakeToolTreeItem *item) const; - void updateCMakeTool(const Core::Id &id, const QString &displayName, const FileName &executable); + void updateCMakeTool(const Core::Id &id, const QString &displayName, const FileName &executable, + bool autoRun); void removeCMakeTool(const Core::Id &id); void apply(); @@ -92,19 +94,22 @@ public: m_id(item->id()), m_name(item->displayName()), m_executable(item->cmakeExecutable()), + m_isAutoRun(item->isAutoRun()), m_autodetected(item->isAutoDetected()), m_changed(changed) {} - CMakeToolTreeItem(const QString &name, const Utils::FileName &executable, bool autodetected) : + CMakeToolTreeItem(const QString &name, const Utils::FileName &executable, + bool autoRun, bool autodetected) : m_id(Core::Id::fromString(QUuid::createUuid().toString())), m_name(name), m_executable(executable), + m_isAutoRun(autoRun), m_autodetected(autodetected), m_changed(true) {} - CMakeToolTreeItem() : m_autodetected(false), m_changed(true) {} + CMakeToolTreeItem() = default; CMakeToolItemModel *model() const { return static_cast(TreeItem::model()); } @@ -135,8 +140,9 @@ public: Core::Id m_id; QString m_name; FileName m_executable; - bool m_autodetected; - bool m_changed; + bool m_isAutoRun = true; + bool m_autodetected = false; + bool m_changed = true; }; CMakeToolItemModel::CMakeToolItemModel() @@ -157,9 +163,10 @@ CMakeToolItemModel::CMakeToolItemModel() } -QModelIndex CMakeToolItemModel::addCMakeTool(const QString &name, const FileName &executable, const bool isAutoDetected) +QModelIndex CMakeToolItemModel::addCMakeTool(const QString &name, const FileName &executable, + const bool autoRun, const bool isAutoDetected) { - CMakeToolTreeItem *item = new CMakeToolTreeItem(name, executable, isAutoDetected); + CMakeToolTreeItem *item = new CMakeToolTreeItem(name, executable, autoRun, isAutoDetected); if (isAutoDetected) autoGroupItem()->appendChild(item); else @@ -208,13 +215,14 @@ void CMakeToolItemModel::reevaluateChangedFlag(CMakeToolTreeItem *item) const } void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &displayName, - const FileName &executable) + const FileName &executable, bool autoRun) { CMakeToolTreeItem *treeItem = cmakeToolItem(id); QTC_ASSERT(treeItem, return); treeItem->m_name = displayName; treeItem->m_executable = executable; + treeItem->m_isAutoRun = autoRun; reevaluateChangedFlag(treeItem); } @@ -249,6 +257,7 @@ void CMakeToolItemModel::apply() if (CMakeTool *cmake = CMakeToolManager::findById(item->m_id)) { cmake->setDisplayName(item->m_name); cmake->setCMakeExecutable(item->m_executable); + cmake->setAutorun(item->m_isAutoRun); } else { toRegister.append(item); } @@ -315,6 +324,7 @@ public: private: CMakeToolItemModel *m_model; QLineEdit *m_displayNameLineEdit; + QCheckBox *m_autoRunCheckBox; PathChooser *m_binaryChooser; Core::Id m_id; bool m_loadingItem; @@ -330,21 +340,28 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model) m_binaryChooser->setMinimumWidth(400); m_binaryChooser->setHistoryCompleter(QLatin1String("Cmake.Command.History")); + m_autoRunCheckBox = new QCheckBox; + m_autoRunCheckBox->setText("Autorun CMake"); + QFormLayout *formLayout = new QFormLayout(this); formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit); formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser); + formLayout->addRow(m_autoRunCheckBox); connect(m_binaryChooser, &PathChooser::rawPathChanged, this, &CMakeToolItemConfigWidget::store); connect(m_displayNameLineEdit, &QLineEdit::textChanged, this, &CMakeToolItemConfigWidget::store); + connect(m_autoRunCheckBox, &QCheckBox::toggled, + this, &CMakeToolItemConfigWidget::store); } void CMakeToolItemConfigWidget::store() const { if (!m_loadingItem && m_id.isValid()) - m_model->updateCMakeTool(m_id, m_displayNameLineEdit->text(), m_binaryChooser->fileName()); + m_model->updateCMakeTool(m_id, m_displayNameLineEdit->text(), m_binaryChooser->fileName(), + m_autoRunCheckBox->checkState() == Qt::Checked); } void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item) @@ -363,6 +380,8 @@ void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item) m_binaryChooser->setReadOnly(item->m_autodetected); m_binaryChooser->setFileName(item->m_executable); + m_autoRunCheckBox->setChecked(item->m_isAutoRun); + m_id = item->m_id; m_loadingItem = false; } @@ -375,7 +394,7 @@ class CMakeToolConfigWidget : public QWidget { Q_OBJECT public: - CMakeToolConfigWidget() : m_currentItem(0) + CMakeToolConfigWidget() { m_addButton = new QPushButton(tr("Add"), this); @@ -452,7 +471,7 @@ public: QPushButton *m_makeDefButton; DetailsWidget *m_container; CMakeToolItemConfigWidget *m_itemConfigWidget; - CMakeToolTreeItem *m_currentItem; + CMakeToolTreeItem *m_currentItem = nullptr; }; void CMakeToolConfigWidget::apply() @@ -467,7 +486,7 @@ void CMakeToolConfigWidget::cloneCMakeTool() QModelIndex newItem = m_model.addCMakeTool(tr("Clone of %1").arg(m_currentItem->m_name), m_currentItem->m_executable, - false); + m_currentItem->m_isAutoRun, false); m_cmakeToolsView->setCurrentIndex(newItem); } @@ -475,7 +494,7 @@ void CMakeToolConfigWidget::cloneCMakeTool() void CMakeToolConfigWidget::addCMakeTool() { QModelIndex newItem = m_model.addCMakeTool(m_model.uniqueDisplayName(tr("New CMake")), - FileName(), false); + FileName(), true, false); m_cmakeToolsView->setCurrentIndex(newItem); } diff --git a/src/plugins/cmakeprojectmanager/cmaketool.cpp b/src/plugins/cmakeprojectmanager/cmaketool.cpp index 70b362fe349..55685b08895 100644 --- a/src/plugins/cmakeprojectmanager/cmaketool.cpp +++ b/src/plugins/cmakeprojectmanager/cmaketool.cpp @@ -42,6 +42,7 @@ namespace CMakeProjectManager { const char CMAKE_INFORMATION_ID[] = "Id"; const char CMAKE_INFORMATION_COMMAND[] = "Binary"; const char CMAKE_INFORMATION_DISPLAYNAME[] = "DisplayName"; +const char CMAKE_INFORMATION_AUTORUN[] = "AutoRun"; const char CMAKE_INFORMATION_AUTODETECTED[] = "AutoDetected"; /////////////////////////// @@ -57,6 +58,7 @@ CMakeTool::CMakeTool(const QVariantMap &map, bool fromSdk) : m_isAutoDetected(fr { m_id = Core::Id::fromSetting(map.value(QLatin1String(CMAKE_INFORMATION_ID))); m_displayName = map.value(QLatin1String(CMAKE_INFORMATION_DISPLAYNAME)).toString(); + m_isAutoRun = map.value(QLatin1String(CMAKE_INFORMATION_AUTORUN), true).toBool(); //loading a CMakeTool from SDK is always autodetection if (!fromSdk) @@ -82,6 +84,15 @@ void CMakeTool::setCMakeExecutable(const Utils::FileName &executable) CMakeToolManager::notifyAboutUpdate(this); } +void CMakeTool::setAutorun(bool autoRun) +{ + if (m_isAutoRun == autoRun) + return; + + m_isAutoRun = autoRun; + CMakeToolManager::notifyAboutUpdate(this); +} + bool CMakeTool::isValid() const { if (!m_id.isValid()) @@ -121,6 +132,7 @@ QVariantMap CMakeTool::toMap() const data.insert(QLatin1String(CMAKE_INFORMATION_DISPLAYNAME), m_displayName); data.insert(QLatin1String(CMAKE_INFORMATION_ID), m_id.toSetting()); data.insert(QLatin1String(CMAKE_INFORMATION_COMMAND), m_executable.toString()); + data.insert(QLatin1String(CMAKE_INFORMATION_AUTORUN), m_isAutoRun); data.insert(QLatin1String(CMAKE_INFORMATION_AUTODETECTED), m_isAutoDetected); return data; } @@ -130,6 +142,11 @@ Utils::FileName CMakeTool::cmakeExecutable() const return m_executable; } +bool CMakeTool::isAutoRun() const +{ + return m_isAutoRun; +} + QStringList CMakeTool::supportedGenerators() const { if (m_generators.isEmpty()) { diff --git a/src/plugins/cmakeprojectmanager/cmaketool.h b/src/plugins/cmakeprojectmanager/cmaketool.h index 964d6f71f1a..eda2fe83ca2 100644 --- a/src/plugins/cmakeprojectmanager/cmaketool.h +++ b/src/plugins/cmakeprojectmanager/cmaketool.h @@ -66,8 +66,10 @@ public: QVariantMap toMap () const; void setCMakeExecutable(const Utils::FileName &executable); + void setAutorun(bool autoRun); Utils::FileName cmakeExecutable() const; + bool isAutoRun() const; QStringList supportedGenerators() const; TextEditor::Keywords keywords(); @@ -87,6 +89,8 @@ private: QString m_displayName; Utils::FileName m_executable; + bool m_isAutoRun; + bool m_isAutoDetected; mutable bool m_didAttemptToRun; diff --git a/src/plugins/coreplugin/systemsettings.cpp b/src/plugins/coreplugin/systemsettings.cpp index c5fc7deff2e..7ceb9de6f9b 100644 --- a/src/plugins/coreplugin/systemsettings.cpp +++ b/src/plugins/coreplugin/systemsettings.cpp @@ -56,6 +56,9 @@ SystemSettings::SystemSettings() setCategory(Constants::SETTINGS_CATEGORY_CORE); setDisplayCategory(QCoreApplication::translate("Core", Constants::SETTINGS_TR_CATEGORY_CORE)); setCategoryIcon(QLatin1String(Constants::SETTINGS_CATEGORY_CORE_ICON)); + + connect(VcsManager::instance(), &VcsManager::configurationChanged, + this, &SystemSettings::updatePath); } QWidget *SystemSettings::widget() @@ -138,9 +141,6 @@ QWidget *SystemSettings::widget() } updatePath(); - - connect(VcsManager::instance(), &VcsManager::configurationChanged, - this, &SystemSettings::updatePath); } return m_widget; } @@ -200,6 +200,9 @@ void SystemSettings::resetFileBrowser() void SystemSettings::updatePath() { + if (!m_page) + return; + Environment env = Environment::systemEnvironment(); QStringList toAdd = VcsManager::additionalToolsPath(); env.appendOrSetPath(toAdd.join(HostOsInfo::pathListSeparator())); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index b27e86fe0af..71703246bcb 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -996,34 +996,34 @@ void CppModelManager::delayedGC() d->m_delayedGcTimer.start(500); } -static QStringList idsOfAllProjectParts(const ProjectInfo &projectInfo) +static QStringList removedProjectParts(const QStringList &before, const QStringList &after) { - QStringList projectPaths; - foreach (const ProjectPart::Ptr &part, projectInfo.projectParts()) - projectPaths << part->id(); - return projectPaths; + QSet b = before.toSet(); + b.subtract(after.toSet()); + + return b.toList(); } void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) { - QStringList projectPartIds; + QStringList idsOfRemovedProjectParts; d->m_projectToIndexerCanceled.remove(project); { QMutexLocker locker(&d->m_projectMutex); d->m_dirty = true; - - // Save paths - const ProjectInfo projectInfo = d->m_projectToProjectsInfo.value(project, ProjectInfo()); - projectPartIds = idsOfAllProjectParts(projectInfo); + const QStringList projectPartsIdsBefore = d->m_projectPartIdToProjectProjectPart.keys(); d->m_projectToProjectsInfo.remove(project); recalculateProjectPartMappings(); + + const QStringList projectPartsIdsAfter = d->m_projectPartIdToProjectProjectPart.keys(); + idsOfRemovedProjectParts = removedProjectParts(projectPartsIdsBefore, projectPartsIdsAfter); } - if (!projectPartIds.isEmpty()) - emit projectPartsRemoved(projectPartIds); + if (!idsOfRemovedProjectParts.isEmpty()) + emit projectPartsRemoved(idsOfRemovedProjectParts); delayedGC(); } diff --git a/src/plugins/debugger/analyzer/analyzerrunconfigwidget.h b/src/plugins/debugger/analyzer/analyzerrunconfigwidget.h index 23d028ff95e..df13971da6c 100644 --- a/src/plugins/debugger/analyzer/analyzerrunconfigwidget.h +++ b/src/plugins/debugger/analyzer/analyzerrunconfigwidget.h @@ -48,11 +48,10 @@ public: QString displayName() const; -private slots: +private: void chooseSettings(int setting); void restoreGlobal(); -private: QWidget *m_configWidget; ProjectExplorer::IRunConfigurationAspect *m_aspect; ProjectExplorer::ISettingsAspect *m_config; diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h index ba1d3e844fe..7fda24c4c1c 100644 --- a/src/plugins/debugger/breakhandler.h +++ b/src/plugins/debugger/breakhandler.h @@ -157,7 +157,7 @@ inline uint qHash(const Debugger::Internal::Breakpoint &b) { return b.hash(); } typedef QList Breakpoints; -class BreakHandler : public Utils::LeveledTreeModel +class BreakHandler : public Utils::LeveledTreeModel { Q_OBJECT diff --git a/src/plugins/debugger/breakwindow.cpp b/src/plugins/debugger/breakwindow.cpp index 54e20e72f65..6fdffcea4ad 100644 --- a/src/plugins/debugger/breakwindow.cpp +++ b/src/plugins/debugger/breakwindow.cpp @@ -96,7 +96,6 @@ public: void setParameters(const BreakpointParameters &data); BreakpointParameters parameters() const; -public slots: void typeChanged(int index); private: diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 9214cef1f21..264bf9ec25b 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -116,7 +116,7 @@ public: static QString extensionLibraryName(bool is64Bit); -private slots: +private: void readyReadStandardOut(); void readyReadStandardError(); void processError(); @@ -132,7 +132,6 @@ private slots: void handleDoInterruptInferior(const QString &errorMessage); -private: typedef QHash PendingBreakPointMap; typedef QPair SourcePathMapping; struct NormalizedSourceFileName // Struct for caching mapped/normalized source files. diff --git a/src/plugins/debugger/console/consoleitemdelegate.h b/src/plugins/debugger/console/consoleitemdelegate.h index f846bfbe327..0cf6889bfee 100644 --- a/src/plugins/debugger/console/consoleitemdelegate.h +++ b/src/plugins/debugger/console/consoleitemdelegate.h @@ -44,8 +44,6 @@ public: void emitSizeHintChanged(const QModelIndex &index); QColor drawBackground(QPainter *painter, const QRect &rect, const QModelIndex &index, bool selected) const; - -public slots: void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); protected: diff --git a/src/plugins/debugger/console/consoleitemmodel.h b/src/plugins/debugger/console/consoleitemmodel.h index c0c7c8485b0..03f0203f014 100644 --- a/src/plugins/debugger/console/consoleitemmodel.h +++ b/src/plugins/debugger/console/consoleitemmodel.h @@ -51,7 +51,6 @@ public: int sizeOfFile(const QFont &font); int sizeOfLineNumber(const QFont &font); -public slots: void clear(); signals: diff --git a/src/plugins/debugger/console/consoleproxymodel.h b/src/plugins/debugger/console/consoleproxymodel.h index f02346f66cf..d75114d3e62 100644 --- a/src/plugins/debugger/console/consoleproxymodel.h +++ b/src/plugins/debugger/console/consoleproxymodel.h @@ -39,7 +39,6 @@ class ConsoleProxyModel : public QSortFilterProxyModel public: explicit ConsoleProxyModel(QObject *parent); -public slots: void setShowLogs(bool show); void setShowWarnings(bool show); void setShowErrors(bool show); diff --git a/src/plugins/debugger/console/consoleview.h b/src/plugins/debugger/console/consoleview.h index 3aedd125e19..89a59439180 100644 --- a/src/plugins/debugger/console/consoleview.h +++ b/src/plugins/debugger/console/consoleview.h @@ -39,7 +39,6 @@ class ConsoleView : public Utils::TreeView public: ConsoleView(ConsoleItemModel *model, QWidget *parent); -public slots: void onScrollToBottom(); protected: diff --git a/src/plugins/debugger/debuggeroptionspage.cpp b/src/plugins/debugger/debuggeroptionspage.cpp index e9a06c03eb8..6026e444f5d 100644 --- a/src/plugins/debugger/debuggeroptionspage.cpp +++ b/src/plugins/debugger/debuggeroptionspage.cpp @@ -99,7 +99,7 @@ public: // DebuggerItemModel // -------------------------------------------------------------------------- -class DebuggerItemModel : public LeveledTreeModel +class DebuggerItemModel : public LeveledTreeModel { Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerOptionsPage) diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 2d41ec65dd4..c8213bed9fd 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -3076,9 +3076,7 @@ void showModuleSections(const QString &moduleName, const Sections §ions) void DebuggerPluginPrivate::aboutToShutdown() { - disconnect(SessionManager::instance(), - SIGNAL(startupProjectChanged(ProjectExplorer::Project*)), - this, 0); + disconnect(SessionManager::instance(), &SessionManager::startupProjectChanged, this, nullptr); m_mainWindow->saveCurrentPerspective(); delete m_mainWindow; diff --git a/src/plugins/debugger/debuggersourcepathmappingwidget.h b/src/plugins/debugger/debuggersourcepathmappingwidget.h index 0ae147b15bb..ec587a2007a 100644 --- a/src/plugins/debugger/debuggersourcepathmappingwidget.h +++ b/src/plugins/debugger/debuggersourcepathmappingwidget.h @@ -62,7 +62,7 @@ public: static SourcePathMap mergePlatformQtPath(const DebuggerRunParameters &sp, const SourcePathMap &in); -private slots: +private: void slotAdd(); void slotAddQt(); void slotRemove(); @@ -70,7 +70,6 @@ private slots: void slotEditSourceFieldChanged(); void slotEditTargetFieldChanged(); -private: void resizeColumns(); void updateEnabled(); QString editSourceField() const; diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index c3789f7306c..25184fd12c3 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -122,7 +122,7 @@ protected: ////////// Gdb Process Management ////////// // Make sure to clean up everything before emitting this signal. void handleAdapterCrashed(const QString &msg); -private slots: +private: friend class GdbPlainEngine; friend class GdbCoreEngine; void handleInterruptDeviceInferior(const QString &error); @@ -132,7 +132,6 @@ private slots: void readGdbStandardError(); void readDebuggeeOutput(const QByteArray &ba); -private: QTextCodec *m_gdbOutputCodec; QTextCodec::ConverterState m_gdbOutputCodecState; QTextCodec *m_inferiorOutputCodec; @@ -204,7 +203,7 @@ private: private: ////////// Gdb Output, State & Capability Handling ////////// protected: - void handleResponse(const QString &buff); + Q_INVOKABLE void handleResponse(const QString &buff); void handleAsyncOutput(const QString &asyncClass, const GdbMi &result); void handleStopResponse(const GdbMi &data); void handleResultRecord(DebuggerResponse *response); diff --git a/src/plugins/debugger/gdb/startgdbserverdialog.h b/src/plugins/debugger/gdb/startgdbserverdialog.h index df2630e4bc3..c90cefe7abc 100644 --- a/src/plugins/debugger/gdb/startgdbserverdialog.h +++ b/src/plugins/debugger/gdb/startgdbserverdialog.h @@ -45,7 +45,7 @@ public: void run(); -private slots: +private: void handleRemoteError(const QString &errorMessage); void portGathererError(const QString &errorMessage); void portListReady(); @@ -56,7 +56,6 @@ private slots: void handleProcessStarted(); void handleConnectionError(); -private: void attach(int port); void logMessage(const QString &line); StartGdbServerDialogPrivate *d; diff --git a/src/plugins/debugger/logwindow.cpp b/src/plugins/debugger/logwindow.cpp index e30d05c2ca0..9bbd5033ac7 100644 --- a/src/plugins/debugger/logwindow.cpp +++ b/src/plugins/debugger/logwindow.cpp @@ -310,7 +310,6 @@ public: (void) new OutputHighlighter(this); } -public slots: void gotoResult(int i) { QString needle = QString::number(i) + QLatin1Char('^'); diff --git a/src/plugins/debugger/logwindow.h b/src/plugins/debugger/logwindow.h index 71bfedccd31..adced53832f 100644 --- a/src/plugins/debugger/logwindow.h +++ b/src/plugins/debugger/logwindow.h @@ -64,7 +64,6 @@ public: static QChar charForChannel(int channel); static LogChannel channelForChar(QChar c); -public slots: void clearContents(); void sendCommand(); void executeLine(); diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index cf65daecf2e..ab469638fa2 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -55,7 +55,7 @@ public: void expressionEvaluated(quint32 queryId, const QVariant &result); -private slots: +private: void disconnected(); void errorMessageBoxFinished(int result); void updateCurrentContext(); @@ -67,7 +67,6 @@ private slots: void appStartupFailed(const QString &errorMessage); void appendMessage(const QString &msg, Utils::OutputFormat); -private: void notifyEngineRemoteServerRunning(const QString &, int pid) override; void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result) override; diff --git a/src/plugins/debugger/registerhandler.cpp b/src/plugins/debugger/registerhandler.cpp index 921da6304f9..6d3749b45f9 100644 --- a/src/plugins/debugger/registerhandler.cpp +++ b/src/plugins/debugger/registerhandler.cpp @@ -30,6 +30,8 @@ #include +using namespace Utils; + namespace Debugger { namespace Internal { @@ -286,9 +288,10 @@ void RegisterValue::shiftOneDigit(uint digit, RegisterFormat format) // ////////////////////////////////////////////////////////////////// +class RegisterItem; class RegisterSubItem; -class RegisterEditItem : public Utils::TreeItem +class RegisterEditItem : public TypedTreeItem { public: RegisterEditItem(int pos, RegisterKind subKind, int subSize, RegisterFormat format) @@ -306,7 +309,7 @@ public: }; -class RegisterSubItem : public Utils::TreeItem +class RegisterSubItem : public TypedTreeItem { public: RegisterSubItem(RegisterKind subKind, int subSize, int count, RegisterFormat format) @@ -333,7 +336,7 @@ public: bool m_changed; }; -class RegisterItem : public Utils::TreeItem +class RegisterItem : public TypedTreeItem { public: explicit RegisterItem(const Register ®); @@ -460,10 +463,8 @@ QVariant RegisterSubItem::data(int column, int role) const case RegisterChangedRole: return m_changed; - case RegisterFormatRole: { - RegisterItem *registerItem = static_cast(parent()); - return int(registerItem->m_format); - } + case RegisterFormatRole: + return int(parent()->m_format); case RegisterAsAddressRole: return 0; @@ -474,8 +475,7 @@ QVariant RegisterSubItem::data(int column, int role) const return subTypeName(m_subKind, m_subSize, m_subFormat); case RegisterValueColumn: { QTC_ASSERT(parent(), return QVariant()); - RegisterItem *registerItem = static_cast(parent()); - RegisterValue value = registerItem->m_reg.value; + RegisterValue value = parent()->m_reg.value; QString ba; for (int i = 0; i != m_count; ++i) { int tab = 5 * (i + 1) * m_subSize; @@ -582,14 +582,13 @@ QVariant RegisterEditItem::data(int column, int role) const return QString("[%1]").arg(m_index); } case RegisterValueColumn: { - RegisterItem *registerItem = static_cast(parent()->parent()); - RegisterValue value = registerItem->m_reg.value; + RegisterValue value = parent()->parent()->m_reg.value; return value.subValue(m_subSize, m_index) .toString(m_subKind, m_subSize, m_subFormat, role == Qt::EditRole); } } case Qt::ToolTipRole: { - RegisterItem *registerItem = static_cast(parent()->parent()); + RegisterItem *registerItem = parent()->parent(); return RegisterHandler::tr("Edit bits %1...%2 of register %3") .arg(m_index * 8).arg(m_index * 8 + 7).arg(registerItem->m_reg.name); } @@ -604,7 +603,7 @@ bool RegisterEditItem::setData(int column, const QVariant &value, int role) if (column == RegisterValueColumn && role == Qt::EditRole) { QTC_ASSERT(parent(), return false); QTC_ASSERT(parent()->parent(), return false); - RegisterItem *registerItem = static_cast(parent()->parent()); + RegisterItem *registerItem = parent()->parent(); Register ® = registerItem->m_reg; RegisterValue vv; vv.fromString(value.toString(), m_subFormat); @@ -618,8 +617,7 @@ bool RegisterEditItem::setData(int column, const QVariant &value, int role) Qt::ItemFlags RegisterEditItem::flags(int column) const { QTC_ASSERT(parent(), return Qt::ItemFlags()); - RegisterSubItem *registerSubItem = static_cast(parent()); - Qt::ItemFlags f = registerSubItem->flags(column); + Qt::ItemFlags f = parent()->flags(column); if (column == RegisterValueColumn) f |= Qt::ItemIsEditable; return f; diff --git a/src/plugins/debugger/registerwindow.h b/src/plugins/debugger/registerwindow.h index 13a6f91c02d..160890ad34e 100644 --- a/src/plugins/debugger/registerwindow.h +++ b/src/plugins/debugger/registerwindow.h @@ -37,7 +37,6 @@ class RegisterTreeView : public Utils::BaseTreeView public: RegisterTreeView(); -public slots: void reloadRegisters(); private: diff --git a/src/plugins/debugger/threadshandler.h b/src/plugins/debugger/threadshandler.h index 83f20ccd9d2..9a29b5314e7 100644 --- a/src/plugins/debugger/threadshandler.h +++ b/src/plugins/debugger/threadshandler.h @@ -41,7 +41,7 @@ namespace Internal { class GdbMi; class ThreadItem; -class ThreadsHandler : public Utils::LeveledTreeModel +class ThreadsHandler : public Utils::LeveledTreeModel { Q_OBJECT diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index d19b2142cfb..d52d4e6ed02 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -36,7 +36,6 @@ #include "simplifytype.h" #include "imageviewer.h" #include "watchutils.h" -#include "cdb/cdbengine.h" // Remove after string freeze #include @@ -1185,9 +1184,9 @@ QString WatchModel::nameForFormat(int format) case AutomaticFormat: return tr("Automatic"); case RawFormat: return tr("Raw Data"); - case SimpleFormat: return CdbEngine::tr("Normal"); // FIXME: String + case SimpleFormat: return tr("Normal"); case EnhancedFormat: return tr("Enhanced"); - case SeparateFormat: return CdbEngine::tr("Separate Window"); // FIXME: String + case SeparateFormat: return tr("Separate Window"); case Latin1StringFormat: return tr("Latin1 String"); case SeparateLatin1StringFormat: return tr("Latin1 String in Separate Window"); diff --git a/src/plugins/git/branchdialog.cpp b/src/plugins/git/branchdialog.cpp index f26dda60fd1..502d3afc4e7 100644 --- a/src/plugins/git/branchdialog.cpp +++ b/src/plugins/git/branchdialog.cpp @@ -88,6 +88,9 @@ BranchDialog::BranchDialog(QWidget *parent) : connect(m_ui->branchView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &BranchDialog::enableButtons); + connect(m_model, &QAbstractItemModel::dataChanged, this, &BranchDialog::resizeColumns); + connect(m_model, &QAbstractItemModel::rowsInserted, this, &BranchDialog::resizeColumns); + connect(m_model, &QAbstractItemModel::rowsRemoved, this, &BranchDialog::resizeColumns); enableButtons(); } @@ -109,8 +112,7 @@ void BranchDialog::refresh(const QString &repository, bool force) VcsOutputWindow::appendError(errorMessage); m_ui->branchView->expandAll(); - m_ui->branchView->resizeColumnToContents(0); - m_ui->branchView->resizeColumnToContents(1); + resizeColumns(); } void BranchDialog::refreshIfSame(const QString &repository) @@ -119,6 +121,12 @@ void BranchDialog::refreshIfSame(const QString &repository) refreshCurrentRepository(); } +void BranchDialog::resizeColumns() +{ + m_ui->branchView->resizeColumnToContents(0); + m_ui->branchView->resizeColumnToContents(1); +} + void BranchDialog::enableButtons() { QModelIndex idx = selectedIndex(); diff --git a/src/plugins/git/branchdialog.h b/src/plugins/git/branchdialog.h index 0bb45a221a7..db0318b5570 100644 --- a/src/plugins/git/branchdialog.h +++ b/src/plugins/git/branchdialog.h @@ -52,11 +52,11 @@ public: explicit BranchDialog(QWidget *parent = 0); ~BranchDialog() override; -public slots: void refresh(const QString &repository, bool force); void refreshIfSame(const QString &repository); private: + void resizeColumns(); void enableButtons(); void refreshCurrentRepository(); void add(); diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index a7de19be346..e1e41d50433 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -470,6 +470,14 @@ QString BranchModel::sha(const QModelIndex &idx) const return node->sha; } +QDateTime BranchModel::dateTime(const QModelIndex &idx) const +{ + if (!idx.isValid()) + return QDateTime(); + BranchNode *node = indexToNode(idx); + return node->dateTime; +} + bool BranchModel::hasTags() const { return m_rootNode->children.count() > Tags; @@ -590,6 +598,7 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel QString startSha; QString output; QString errorMessage; + QDateTime branchDateTime; QStringList args; args << (track ? QLatin1String("--track") : QLatin1String("--no-track")); @@ -597,8 +606,17 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel if (!fullTrackedBranch.isEmpty()) { args << fullTrackedBranch; startSha = sha(startPoint); + branchDateTime = dateTime(startPoint); } else { - startSha = m_client->synchronousTopRevision(m_workingDirectory); + QString output; + QString errorMessage; + const QStringList arguments({"-n1", "--format=%H %ct"}); + if (m_client->synchronousLog(m_workingDirectory, arguments, &output, &errorMessage, + VcsCommand::SuppressCommandLogging)) { + const QStringList values = output.split(' '); + startSha = values[0]; + branchDateTime = QDateTime::fromTime_t(values[1].toInt()); + } } if (!m_client->synchronousBranchCmd(m_workingDirectory, args, &output, &errorMessage)) { @@ -624,7 +642,8 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel local = child; } int pos = positionForName(local, leafName); - auto newNode = new BranchNode(leafName, startSha, track ? trackedBranch : QString()); + auto newNode = new BranchNode(leafName, startSha, track ? trackedBranch : QString(), + branchDateTime); if (!added) beginInsertRows(nodeToIndex(local, 0), pos, pos); newNode->parent = local; diff --git a/src/plugins/git/branchmodel.h b/src/plugins/git/branchmodel.h index a72365a6209..63302aa182f 100644 --- a/src/plugins/git/branchmodel.h +++ b/src/plugins/git/branchmodel.h @@ -68,6 +68,7 @@ public: QString fullName(const QModelIndex &idx, bool includePrefix = false) const; QStringList localBranchNames() const; QString sha(const QModelIndex &idx) const; + QDateTime dateTime(const QModelIndex &idx) const; bool hasTags() const; bool isLocal(const QModelIndex &idx) const; bool isLeaf(const QModelIndex &idx) const; diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 56da73f67f2..6722d74a57f 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -987,9 +988,14 @@ QStringList GitClient::setupCheckoutArguments(const QString &workingDirectory, if (localBranches.contains(ref)) return arguments; - if (QMessageBox::question(ICore::mainWindow(), tr("Create Local Branch"), - tr("Would you like to create a local branch?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { + if (Utils::CheckableMessageBox::doNotAskAgainQuestion( + ICore::mainWindow() /*parent*/, + tr("Create Local Branch") /*title*/, + tr("Would you like to create a local branch?") /*message*/, + ICore::settings(), "Git.CreateLocalBranchOnCheckout" /*setting*/, + QDialogButtonBox::Yes | QDialogButtonBox::No /*buttons*/, + QDialogButtonBox::No /*default button*/, + QDialogButtonBox::No /*button to save*/) == QMessageBox::No) { return arguments; } diff --git a/src/plugins/git/mergetool.cpp b/src/plugins/git/mergetool.cpp index a0a8de0fed1..d62aabfd92c 100644 --- a/src/plugins/git/mergetool.cpp +++ b/src/plugins/git/mergetool.cpp @@ -218,6 +218,18 @@ void MergeTool::addButton(QMessageBox *msgBox, const QString &text, char key) msgBox->addButton(text, QMessageBox::AcceptRole)->setProperty("key", key); } +void MergeTool::prompt(const QString &title, const QString &question) +{ + if (QMessageBox::question(Core::ICore::dialogParent(), title, question, + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No) == QMessageBox::Yes) { + m_process->write("y\n"); + } else { + m_process->write("n\n"); + } + m_process->waitForBytesWritten(); +} + void MergeTool::readData() { while (m_process->bytesAvailable()) { @@ -231,16 +243,10 @@ void MergeTool::readData() m_localState = waitAndReadStatus(m_localInfo); m_remoteState = waitAndReadStatus(m_remoteInfo); chooseAction(); + } else if (line.startsWith("Was the merge successful")) { + prompt(tr("Unchanged File"), tr("Was the merge successful?")); } else if (line.startsWith("Continue merging")) { - if (QMessageBox::question(Core::ICore::dialogParent(), tr("Continue Merging"), - tr("Continue merging other unresolved paths?"), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No) == QMessageBox::Yes) { - m_process->write("y\n"); - } else { - m_process->write("n\n"); - } - m_process->waitForBytesWritten(); + prompt(tr("Continue Merging"), tr("Continue merging other unresolved paths?")); } } } diff --git a/src/plugins/git/mergetool.h b/src/plugins/git/mergetool.h index cb776e7627e..3acdd83adbc 100644 --- a/src/plugins/git/mergetool.h +++ b/src/plugins/git/mergetool.h @@ -64,6 +64,7 @@ public: }; private: + void prompt(const QString &title, const QString &question); void readData(); void done(); diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp index 4bcf9fbab13..243399489ad 100644 --- a/src/plugins/help/helpplugin.cpp +++ b/src/plugins/help/helpplugin.cpp @@ -150,7 +150,7 @@ bool HelpPlugin::initialize(const QStringList &arguments, QString *error) addAutoReleasedObject(new GeneralSettingsPage()); addAutoReleasedObject(m_searchTaskHandler = new SearchTaskHandler); - m_centralWidget = new CentralWidget(modecontext); + m_centralWidget = new CentralWidget(Context("Help.CentralHelpWidget")); connect(m_centralWidget, SIGNAL(sourceChanged(QUrl)), this, SLOT(updateSideBarSource(QUrl))); connect(m_centralWidget, &CentralWidget::closeButtonClicked, diff --git a/src/plugins/projectexplorer/kitmodel.cpp b/src/plugins/projectexplorer/kitmodel.cpp index da5d8472b2f..2a63f20c681 100644 --- a/src/plugins/projectexplorer/kitmodel.cpp +++ b/src/plugins/projectexplorer/kitmodel.cpp @@ -103,7 +103,7 @@ public: // -------------------------------------------------------------------------- KitModel::KitModel(QBoxLayout *parentLayout, QObject *parent) - : LeveledTreeModel(parent), + : LeveledTreeModel(parent), m_parentLayout(parentLayout) { setHeader(QStringList(tr("Name"))); diff --git a/src/plugins/projectexplorer/kitmodel.h b/src/plugins/projectexplorer/kitmodel.h index 0e06908d879..299f8f67b51 100644 --- a/src/plugins/projectexplorer/kitmodel.h +++ b/src/plugins/projectexplorer/kitmodel.h @@ -48,7 +48,7 @@ class KitNode; // KitModel: // -------------------------------------------------------------------------- -class KitModel : public Utils::LeveledTreeModel +class KitModel : public Utils::LeveledTreeModel { Q_OBJECT diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 520d0284f39..53337230d8f 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -173,13 +173,15 @@ class PROJECTEXPLORER_EXPORT Runnable bool canReUseOutputPane(const std::unique_ptr &other) const override { + if (!other.get()) + return false; if (other->typeId() != typeId()) return false; auto that = static_cast *>(other.get()); return m_data == that->m_data; } - void *typeId() const { return T::staticTypeId; } + void *typeId() const override { return T::staticTypeId; } T m_data; }; @@ -220,7 +222,7 @@ class PROJECTEXPLORER_EXPORT Connection { Model(const T &data) : m_data(data) { } Concept *clone() const override { return new Model(*this); } - void *typeId() const { return T::staticTypeId; } + void *typeId() const override { return T::staticTypeId; } T m_data; }; diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 1f063d02afc..75280682647 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -36,9 +36,7 @@ #include #include -#include #include -#include #include using namespace Utils; @@ -132,7 +130,7 @@ void TerminalAspect::setRunMode(ApplicationLauncher::Mode runMode) */ WorkingDirectoryAspect::WorkingDirectoryAspect(RunConfiguration *runConfig, const QString &key) - : IRunConfigurationAspect(runConfig), m_chooser(0), m_key(key) + : IRunConfigurationAspect(runConfig), m_key(key) { setDisplayName(tr("Working Directory")); setId("WorkingDirectoryAspect"); @@ -215,16 +213,12 @@ void WorkingDirectoryAspect::toMap(QVariantMap &data) const FileName WorkingDirectoryAspect::workingDirectory() const { - if (m_chooser) { - return m_chooser->fileName(); - } else { - auto envAspect = runConfiguration()->extraAspect(); - const Utils::Environment env = envAspect ? envAspect->environment() - : Utils::Environment::systemEnvironment(); - return FileName::fromString( - runConfiguration()->macroExpander()->expandProcessArgs( - PathChooser::expandedDirectory(m_workingDirectory.toString(), env, QString()))); - } + auto envAspect = runConfiguration()->extraAspect(); + const Utils::Environment env = envAspect ? envAspect->environment() + : Utils::Environment::systemEnvironment(); + const QString macroExpanded + = runConfiguration()->macroExpander()->expandProcessArgs(m_workingDirectory.toUserOutput()); + return FileName::fromString(PathChooser::expandedDirectory(macroExpanded, env, QString())); } FileName WorkingDirectoryAspect::defaultWorkingDirectory() const @@ -244,13 +238,14 @@ void WorkingDirectoryAspect::setDefaultWorkingDirectory(const FileName &defaultW Utils::FileName oldDefaultDir = m_defaultWorkingDirectory; m_defaultWorkingDirectory = defaultWorkingDir; - if (m_chooser) { - if (m_chooser->fileName() == oldDefaultDir) - m_chooser->setFileName(m_defaultWorkingDirectory); + if (m_chooser) m_chooser->setBaseFileName(m_defaultWorkingDirectory); - } - if (m_workingDirectory.isEmpty() || m_workingDirectory == oldDefaultDir) + + if (m_workingDirectory.isEmpty() || m_workingDirectory == oldDefaultDir) { + if (m_chooser) + m_chooser->setFileName(m_defaultWorkingDirectory); m_workingDirectory = defaultWorkingDir; + } } PathChooser *WorkingDirectoryAspect::pathChooser() const diff --git a/src/plugins/qmakeprojectmanager/makefileparse.cpp b/src/plugins/qmakeprojectmanager/makefileparse.cpp index 8b63e87f47c..2b284d9808c 100644 --- a/src/plugins/qmakeprojectmanager/makefileparse.cpp +++ b/src/plugins/qmakeprojectmanager/makefileparse.cpp @@ -208,10 +208,11 @@ void MakeFileParse::parseAssignments(QList *assignments) } else { newValues.append(value); } + } + if (!newValues.isEmpty()) { QMakeAssignment newQA = qa; newQA.value = newValues.join(QLatin1Char(' ')); - if (!newValues.isEmpty()) - assignments->append(newQA); + assignments->append(newQA); } } else { assignments->append(qa); diff --git a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp index 0974c96a225..d241c255140 100644 --- a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp +++ b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp @@ -101,6 +101,14 @@ KitInformation::ItemList QmakeKitInformation::toUserOutput(const Kit *k) const return ItemList() << qMakePair(tr("mkspec"), mkspec(k).toUserOutput()); } +void QmakeKitInformation::addToMacroExpander(Kit *kit, MacroExpander *expander) const +{ + expander->registerVariable("Qmake:mkspec", tr("Mkspec configured for qmake by the Kit."), + [this, kit]() -> QString { + return QmakeKitInformation::mkspec(kit).toUserOutput(); + }); +} + Core::Id QmakeKitInformation::id() { return "QtPM4.mkSpecInformation"; diff --git a/src/plugins/qmakeprojectmanager/qmakekitinformation.h b/src/plugins/qmakeprojectmanager/qmakekitinformation.h index 0e77153d55f..686ece12467 100644 --- a/src/plugins/qmakeprojectmanager/qmakekitinformation.h +++ b/src/plugins/qmakeprojectmanager/qmakekitinformation.h @@ -47,6 +47,8 @@ public: ItemList toUserOutput(const ProjectExplorer::Kit *k) const override; + void addToMacroExpander(ProjectExplorer::Kit *kit, Utils::MacroExpander *expander) const override; + static Core::Id id(); static void setMkspec(ProjectExplorer::Kit *k, const Utils::FileName &fn); static Utils::FileName mkspec(const ProjectExplorer::Kit *k); diff --git a/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp b/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp index dc21cdcfbeb..45d93e67dfe 100644 --- a/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp +++ b/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp @@ -67,6 +67,7 @@ QWidget *BackgroundAction::createWidget(QWidget *parent) connect(comboBox, SIGNAL(currentIndexChanged(int)), SLOT(emitBackgroundChanged(int))); comboBox->setProperty("hideborder", true); + comboBox->setToolTip(tr("Set the color of the canvas.")); return comboBox; } diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp index 0f958a0f968..7a4ad4f9cb1 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp @@ -221,7 +221,7 @@ FormEditorItem *FormEditorScene::addFormEditorItem(const QmlItemNode &qmlItemNod void FormEditorScene::dropEvent(QGraphicsSceneDragDropEvent * event) { - currentTool()->dropEvent(removeLayerItems(items(event->scenePos())), event); + currentTool()->dropEvent(removeLayerItems(itemsAt(event->scenePos())), event); if (views().first()) views().first()->setFocus(); @@ -229,19 +229,19 @@ void FormEditorScene::dropEvent(QGraphicsSceneDragDropEvent * event) void FormEditorScene::dragEnterEvent(QGraphicsSceneDragDropEvent * event) { - currentTool()->dragEnterEvent(removeLayerItems(items(event->scenePos())), event); + currentTool()->dragEnterEvent(removeLayerItems(itemsAt(event->scenePos())), event); } void FormEditorScene::dragLeaveEvent(QGraphicsSceneDragDropEvent * event) { - currentTool()->dragLeaveEvent(removeLayerItems(items(event->scenePos())), event); + currentTool()->dragLeaveEvent(removeLayerItems(itemsAt(event->scenePos())), event); return; } void FormEditorScene::dragMoveEvent(QGraphicsSceneDragDropEvent * event) { - currentTool()->dragMoveEvent(removeLayerItems(items(event->scenePos())), event); + currentTool()->dragMoveEvent(removeLayerItems(itemsAt(event->scenePos())), event); } QList FormEditorScene::removeLayerItems(const QList &itemList) @@ -255,10 +255,23 @@ QList FormEditorScene::removeLayerItems(const QList FormEditorScene::itemsAt(const QPointF &pos) +{ + QTransform transform; + + if (!views().isEmpty()) + transform = views().first()->transform(); + + return items(pos, + Qt::IntersectsItemShape, + Qt::DescendingOrder, + transform); +} + void FormEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (editorView() && editorView()->model()) - currentTool()->mousePressEvent(removeLayerItems(items(event->scenePos())), event); + currentTool()->mousePressEvent(removeLayerItems(itemsAt(event->scenePos())), event); } static QTime staticTimer() @@ -275,9 +288,9 @@ void FormEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) if (time.elapsed() > 30) { time.restart(); if (event->buttons()) - currentTool()->mouseMoveEvent(removeLayerItems(items(event->scenePos())), event); + currentTool()->mouseMoveEvent(removeLayerItems(itemsAt(event->scenePos())), event); else - currentTool()->hoverMoveEvent(removeLayerItems(items(event->scenePos())), event); + currentTool()->hoverMoveEvent(removeLayerItems(itemsAt(event->scenePos())), event); event->accept(); } @@ -286,7 +299,7 @@ void FormEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void FormEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (editorView() && editorView()->model()) { - currentTool()->mouseReleaseEvent(removeLayerItems(items(event->scenePos())), event); + currentTool()->mouseReleaseEvent(removeLayerItems(itemsAt(event->scenePos())), event); event->accept(); } @@ -295,7 +308,7 @@ void FormEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) void FormEditorScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { if (editorView() && editorView()->model()) { - currentTool()->mouseDoubleClickEvent(removeLayerItems(items(event->scenePos())), event); + currentTool()->mouseDoubleClickEvent(removeLayerItems(itemsAt(event->scenePos())), event); event->accept(); } diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorscene.h b/src/plugins/qmldesigner/components/formeditor/formeditorscene.h index a16b45dab28..ee8340ec149 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorscene.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorscene.h @@ -111,6 +111,7 @@ protected: private: QList removeLayerItems(const QList &itemList); + QList itemsAt(const QPointF &pos); AbstractFormEditorTool* currentTool() const; void removeItemFromHash(FormEditorItem*); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index 664be17399d..1e3f09fac2a 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -527,7 +527,7 @@ void FormEditorView::instancePropertyChange(const QListhasItemForQmlItemNode(itemNode)) { - static PropertyNameList skipList = PropertyNameList() << "x" << "y" << "width" << "height"; + static const PropertyNameList skipList({"x", "y", "width", "height"}); if (!skipList.contains(propertyName)) { m_scene->synchronizeOtherProperty(itemNode, propertyName); m_currentTool->formEditorItemsChanged(QList() << m_scene->itemForQmlItemNode(itemNode)); diff --git a/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp b/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp index 4242e829853..ea78035612e 100644 --- a/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp +++ b/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp @@ -162,7 +162,7 @@ void MoveManipulator::begin(const QPointF &beginPoint) setDirectUpdateInNodeInstances(true); - m_rewriterTransaction = m_view->beginRewriterTransaction(QByteArrayLiteral("MoveManipulator::begin")); + beginRewriterTransaction(); } @@ -426,6 +426,7 @@ void MoveManipulator::moveBy(double deltaX, double deltaY) void MoveManipulator::beginRewriterTransaction() { m_rewriterTransaction = m_view->beginRewriterTransaction(QByteArrayLiteral("MoveManipulator::beginRewriterTransaction")); + m_rewriterTransaction.ignoreSemanticChecks(); } void MoveManipulator::endRewriterTransaction() diff --git a/src/plugins/qmldesigner/components/formeditor/resizemanipulator.cpp b/src/plugins/qmldesigner/components/formeditor/resizemanipulator.cpp index 2e8f5f1a88f..d5f197997f3 100644 --- a/src/plugins/qmldesigner/components/formeditor/resizemanipulator.cpp +++ b/src/plugins/qmldesigner/components/formeditor/resizemanipulator.cpp @@ -78,6 +78,7 @@ void ResizeManipulator::begin(const QPointF &/*beginPoint*/) m_beginFromItemToSceneTransform = m_resizeController.formEditorItem()->qmlItemNode().instanceSceneTransform(); m_beginToParentTransform = m_resizeController.formEditorItem()->qmlItemNode().instanceTransform(); m_rewriterTransaction = m_view->beginRewriterTransaction(QByteArrayLiteral("ResizeManipulator::begin")); + m_rewriterTransaction.ignoreSemanticChecks(); m_snapper.updateSnappingLines(m_resizeController.formEditorItem()); m_beginBottomRightPoint = m_beginToParentTransform.map(m_resizeController.formEditorItem()->qmlItemNode().instanceBoundingRect().bottomRight()); diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index ff78a696f0e..e2ac7235f13 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -170,7 +170,7 @@ QList DesignDocument::qmlParseWarnings() const bool DesignDocument::hasQmlParseWarnings() const { - return currentModel()->rewriterView() && !currentModel()->rewriterView()->warnings().isEmpty(); + return m_rewriterView->warnings().isEmpty(); } QList DesignDocument::qmlParseErrors() const @@ -180,7 +180,7 @@ QList DesignDocument::qmlParseErrors() const bool DesignDocument::hasQmlParseErrors() const { - return currentModel()->rewriterView() && !currentModel()->rewriterView()->errors().isEmpty(); + return m_rewriterView->errors().isEmpty(); } QString DesignDocument::displayName() const diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index c86e15a7d0c..f68f520e20f 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -156,7 +156,7 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model) bool valid = metaInfo.isValid() && metaInfo.majorVersion() == entry.majorVersion(); bool isItem = valid && metaInfo.isSubclassOf("QtQuick.Item"); - if (!isItem) { + if (!isItem && valid) { qDebug() << Q_FUNC_INFO; qDebug() << metaInfo.typeName() << "is not a QtQuick.Item"; qDebug() << Utils::transform(metaInfo.superClasses(), &NodeMetaInfo::typeName); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index cb023421f95..2a292bf4c2b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -66,6 +66,8 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : m_resourcesView(new ItemLibraryTreeView(this)), m_filterFlag(QtBasic) { + m_compressionTimer.setInterval(200); + m_compressionTimer.setSingleShot(true); ItemLibraryModel::registerQmlTypes(); setWindowTitle(tr("Library", "Title of library view")); @@ -145,6 +147,8 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : m_qmlSourceUpdateShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F5), this); connect(m_qmlSourceUpdateShortcut, SIGNAL(activated()), this, SLOT(reloadQmlSource())); + connect(&m_compressionTimer, SIGNAL(timeout()), this, SLOT(updateModel())); + // init the first load of the QML UI elements reloadQmlSource(); } @@ -156,11 +160,11 @@ void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo) if (m_itemLibraryInfo) disconnect(m_itemLibraryInfo.data(), SIGNAL(entriesChanged()), - this, SLOT(updateModel())); + this, SLOT(delayedUpdateModel())); m_itemLibraryInfo = itemLibraryInfo; if (itemLibraryInfo) connect(m_itemLibraryInfo.data(), SIGNAL(entriesChanged()), - this, SLOT(updateModel())); + this, SLOT(delayedUpdateModel())); updateModel(); } @@ -209,6 +213,11 @@ void ItemLibraryWidget::setSearchFilter(const QString &searchFilter) } } +void ItemLibraryWidget::delayedUpdateModel() +{ + m_compressionTimer.start(); +} + void ItemLibraryWidget::setModel(Model *model) { m_model = model; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index 3d4bc503e25..df0a1e9b909 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -34,6 +34,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE class QFileSystemModel; @@ -86,6 +87,7 @@ public: static QString qmlSourcesPath(); public slots: void setSearchFilter(const QString &searchFilter); + void delayedUpdateModel(); void updateModel(); void updateSearch(); @@ -107,6 +109,7 @@ private slots: void reloadQmlSource(); private: + QTimer m_compressionTimer; QSize m_itemIconSize; QSize m_resIconSize; ItemLibraryFileIconProvider m_iconProvider; diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index d5bcfaff6b2..1f5de334005 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -124,7 +124,7 @@ NodeInstanceView::~NodeInstanceView() bool isSkippedRootNode(const ModelNode &node) { - static PropertyNameList skipList = PropertyNameList() << "Qt.ListModel" << "QtQuick.ListModel" << "Qt.ListModel" << "QtQuick.ListModel"; + static const PropertyNameList skipList({"Qt.ListModel", "QtQuick.ListModel", "Qt.ListModel", "QtQuick.ListModel"}); if (skipList.contains(node.type())) return true; @@ -135,7 +135,7 @@ bool isSkippedRootNode(const ModelNode &node) bool isSkippedNode(const ModelNode &node) { - static PropertyNameList skipList = PropertyNameList() << "QtQuick.XmlRole" << "Qt.XmlRole" << "QtQuick.ListElement" << "Qt.ListElement"; + static const PropertyNameList skipList({"QtQuick.XmlRole", "Qt.XmlRole", "QtQuick.ListElement", "Qt.ListElement"}); if (skipList.contains(node.type())) return true; diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 66270c0dfe2..67a6840d13e 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -332,15 +332,15 @@ private: static inline bool isValueType(const TypeName &type) { - static PropertyTypeList objectValuesList(PropertyTypeList() - << "QFont" << "QPoint" << "QPointF" << "QSize" << "QSizeF" << "QVector3D" << "QVector2D"); + static const PropertyTypeList objectValuesList({"QFont", "QPoint", "QPointF", + "QSize", "QSizeF", "QVector3D", "QVector2D"}); return objectValuesList.contains(type); } static inline bool isValueType(const QString &type) { - static QStringList objectValuesList(QStringList() - << "QFont" << "QPoint" << "QPointF" << "QSize" << "QSizeF" << "QVector3D" << "QVector2D"); + static const QStringList objectValuesList({"QFont", "QPoint", "QPointF", + "QSize", "QSizeF", "QVector3D", "QVector2D"}); return objectValuesList.contains(type); } diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 7c65ccc67ff..5470260c2d2 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -1488,7 +1488,7 @@ void ModelPrivate::setVariantProperty(const InternalNode::Pointer &internalNodeP internalNodePointer->variantProperty(name)->setValue(value); internalNodePointer->variantProperty(name)->resetDynamicTypeName(); - notifyVariantPropertiesChanged(internalNodePointer, PropertyNameList() << name, propertyChange); + notifyVariantPropertiesChanged(internalNodePointer, PropertyNameList({name}), propertyChange); } void ModelPrivate::setDynamicVariantProperty(const InternalNodePointer &internalNodePointer, @@ -1503,7 +1503,7 @@ void ModelPrivate::setDynamicVariantProperty(const InternalNodePointer &internal } internalNodePointer->variantProperty(name)->setDynamicValue(dynamicPropertyType, value); - notifyVariantPropertiesChanged(internalNodePointer, PropertyNameList() << name, propertyChange); + notifyVariantPropertiesChanged(internalNodePointer, PropertyNameList({name}), propertyChange); } void ModelPrivate::setDynamicBindingProperty(const InternalNodePointer &internalNodePointer, diff --git a/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp b/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp index 4aad77f709a..263cfb63a71 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp @@ -187,8 +187,8 @@ bool detectHorizontalCycle(const ModelNode &node, QList knownNodeList knownNodeList.append(node); - static PropertyNameList validAnchorLines(PropertyNameList() << "right" << "left" << "horizontalCenter"); - static PropertyNameList anchorNames(PropertyNameList() << "anchors.right" << "anchors.left" << "anchors.horizontalCenter"); + static const PropertyNameList validAnchorLines({"right", "left", "horizontalCenter"}); + static const PropertyNameList anchorNames({"anchors.right", "anchors.left", "anchors.horizontalCenter"}); foreach (const PropertyName &anchorName, anchorNames) { if (node.hasBindingProperty(anchorName)) { @@ -204,7 +204,7 @@ bool detectHorizontalCycle(const ModelNode &node, QList knownNodeList } - static PropertyNameList anchorShortcutNames(PropertyNameList() << "anchors.fill" << "anchors.centerIn"); + static const PropertyNameList anchorShortcutNames({"anchors.fill", "anchors.centerIn"}); foreach (const PropertyName &anchorName, anchorShortcutNames) { if (node.hasBindingProperty(anchorName)) { ModelNode targetNode = node.bindingProperty(anchorName).resolveToModelNode(); @@ -227,8 +227,8 @@ bool detectVerticalCycle(const ModelNode &node, QList knownNodeList) knownNodeList.append(node); - static PropertyNameList validAnchorLines(PropertyNameList() << "top" << "bottom" << "verticalCenter" << "baseline"); - static PropertyNameList anchorNames(PropertyNameList() << "anchors.top" << "anchors.bottom" << "anchors.verticalCenter" << "anchors.baseline"); + static const PropertyNameList validAnchorLines({"top", "bottom", "verticalCenter", "baseline"}); + static const PropertyNameList anchorNames({"anchors.top", "anchors.bottom", "anchors.verticalCenter", "anchors.baseline"}); foreach (const PropertyName &anchorName, anchorNames) { if (node.hasBindingProperty(anchorName)) { @@ -244,7 +244,7 @@ bool detectVerticalCycle(const ModelNode &node, QList knownNodeList) } - static PropertyNameList anchorShortcutNames(PropertyNameList() << "anchors.fill" << "anchors.centerIn"); + static const PropertyNameList anchorShortcutNames({"anchors.fill", "anchors.centerIn"}); foreach (const PropertyName &anchorName, anchorShortcutNames) { if (node.hasBindingProperty(anchorName)) { ModelNode targetNode = node.bindingProperty(anchorName).resolveToModelNode(); diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 4dabb596c13..a4914e17993 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -54,10 +54,13 @@ #include #include +#include using namespace LanguageUtils; using namespace QmlJS; +static Q_LOGGING_CATEGORY(rewriterBenchmark, "rewriter.load") + namespace { static inline bool isSupportedAttachedProperties(const QString &propertyName) @@ -866,6 +869,12 @@ void TextToModelMerger::setupUsedImports() bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceHandler) { + qCInfo(rewriterBenchmark) << Q_FUNC_INFO; + + QTime time; + if (rewriterBenchmark().isInfoEnabled()) + time.start(); + // maybe the project environment (kit, ...) changed, so we need to clean old caches NodeMetaInfo::clearCache(); @@ -889,6 +898,8 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH doc->setSource(data); doc->parseQml(); + qCInfo(rewriterBenchmark) << "parsed correctly: " << doc->isParsedCorrectly() << time.elapsed(); + if (!doc->isParsedCorrectly()) { QList errors; foreach (const QmlJS::DiagnosticMessage &message, doc->diagnosticMessages()) @@ -904,6 +915,8 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH new ScopeChain(ctxt.scopeChain())); m_document = doc; + qCInfo(rewriterBenchmark) << "linked:" << time.elapsed(); + QList errors; QList warnings; @@ -916,6 +929,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH if (view()->checkSemanticErrors()) { + collectSemanticErrorsAndWarnings(&errors, &warnings); if (!errors.isEmpty()) { @@ -924,6 +938,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH return false; } m_rewriterView->setWarnings(warnings); + qCInfo(rewriterBenchmark) << "checked semantic errors:" << time.elapsed(); } setupUsedImports(); @@ -935,6 +950,8 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH syncNode(modelRootNode, astRootNode, &ctxt, differenceHandler); m_rewriterView->positionStorage()->cleanupInvalidOffsets(); + qCInfo(rewriterBenchmark) << "synced nodes:" << time.elapsed(); + setActive(false); return true; } catch (Exception &e) { @@ -1943,20 +1960,20 @@ void TextToModelMerger::collectSemanticErrorsAndWarnings(QList *e void TextToModelMerger::populateQrcMapping(const QString &filePath) { + if (!filePath.startsWith(QLatin1String("qrc:"))) + return; + QString path = removeFileFromQrcPath(filePath); - QString fileName = fileForFullQrcPath(filePath); - if (path.contains(QLatin1String("qrc:"))) { - path.remove(QLatin1String("qrc:")); - QMap map = ModelManagerInterface::instance()->filesInQrcPath(path); - if (map.contains(fileName)) { - if (!map.value(fileName).isEmpty()) { - QString fileSystemPath = map.value(fileName).first(); - fileSystemPath.remove(fileName); - if (path.isEmpty()) - path.prepend(QLatin1String("/")); - m_qrcMapping.insert(qMakePair(path, fileSystemPath)); - } - } + const QString fileName = fileForFullQrcPath(filePath); + path.remove(QLatin1String("qrc:")); + QMap map = ModelManagerInterface::instance()->filesInQrcPath(path); + const QStringList qrcFilePathes = map.value(fileName, QStringList()); + if (!qrcFilePathes.isEmpty()) { + QString fileSystemPath = qrcFilePathes.first(); + fileSystemPath.remove(fileName); + if (path.isEmpty()) + path.prepend(QLatin1String("/")); + m_qrcMapping.insert(qMakePair(path, fileSystemPath)); } } diff --git a/src/plugins/qmldesigner/designercore/rewritertransaction.cpp b/src/plugins/qmldesigner/designercore/rewritertransaction.cpp index bb1429eaec2..7dbc5463772 100644 --- a/src/plugins/qmldesigner/designercore/rewritertransaction.cpp +++ b/src/plugins/qmldesigner/designercore/rewritertransaction.cpp @@ -25,6 +25,7 @@ #include "rewritertransaction.h" #include +#include #ifndef QMLDESIGNER_TEST #include @@ -72,12 +73,23 @@ bool RewriterTransaction::isValid() const return m_valid; } +void RewriterTransaction::ignoreSemanticChecks() +{ + m_ignoreSemanticChecks = true; +} + void RewriterTransaction::commit() { if (m_valid) { m_valid = false; + bool oldSemanticChecks = view()->rewriterView()->checkSemanticErrors(); + if (m_ignoreSemanticChecks) + view()->rewriterView()->setCheckSemanticErrors(false); + view()->emitRewriterEndTransaction(); + view()->rewriterView()->setCheckSemanticErrors(oldSemanticChecks); + if (m_activeIdentifier) { qDebug() << "Commit RewriterTransaction:" << m_identifier << m_identifierNumber; bool success = m_identifierList.removeOne(m_identifier + QByteArrayLiteral("-") + QByteArray::number(m_identifierNumber)); diff --git a/src/plugins/qmldesigner/designercore/rewritertransaction.h b/src/plugins/qmldesigner/designercore/rewritertransaction.h index 213b9e56180..87e50c53fe4 100644 --- a/src/plugins/qmldesigner/designercore/rewritertransaction.h +++ b/src/plugins/qmldesigner/designercore/rewritertransaction.h @@ -46,6 +46,8 @@ public: bool isValid() const; + void ignoreSemanticChecks(); + protected: AbstractView *view(); private: @@ -55,6 +57,7 @@ private: int m_identifierNumber; static QList m_identifierList; static bool m_activeIdentifier; + bool m_ignoreSemanticChecks = false; }; } //QmlDesigner diff --git a/src/plugins/qmldesigner/designersettings.cpp b/src/plugins/qmldesigner/designersettings.cpp index b931ab99839..6a371a50b49 100644 --- a/src/plugins/qmldesigner/designersettings.cpp +++ b/src/plugins/qmldesigner/designersettings.cpp @@ -53,6 +53,7 @@ void DesignerSettings::fromSettings(QSettings *settings) restoreValue(settings, DesignerSettingsKey::CANVASWIDTH, 10000); restoreValue(settings, DesignerSettingsKey::CANVASHEIGHT, 10000); restoreValue(settings, DesignerSettingsKey::WARNING_FOR_FEATURES_IN_DESIGNER, true); + restoreValue(settings, DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES, true); restoreValue(settings, DesignerSettingsKey::WARNING_FOR_DESIGNER_FEATURES_IN_EDITOR, false); restoreValue(settings, DesignerSettingsKey::SHOW_DEBUGVIEW, false); restoreValue(settings, DesignerSettingsKey::ENABLE_DEBUGVIEW, false); diff --git a/src/plugins/qmldesigner/designersettings.h b/src/plugins/qmldesigner/designersettings.h index b5e0b2fd297..2159230cbfd 100644 --- a/src/plugins/qmldesigner/designersettings.h +++ b/src/plugins/qmldesigner/designersettings.h @@ -42,6 +42,7 @@ const char CONTAINERPADDING[] = "ContainerPadding"; const char CANVASWIDTH[] = "CanvasWidth"; const char CANVASHEIGHT[] = "CanvasHeight"; const char WARNING_FOR_FEATURES_IN_DESIGNER[] = "WarnAboutQtQuickFeaturesInDesigner"; +const char WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES[] = "WarnAboutQmlFilesInsteadOfUiQmlFiles"; const char WARNING_FOR_DESIGNER_FEATURES_IN_EDITOR[] = "WarnAboutQtQuickDesignerFeaturesInCodeEditor"; const char SHOW_DEBUGVIEW[] = "ShowQtQuickDesignerDebugView"; const char ENABLE_DEBUGVIEW[] = "EnableQtQuickDesignerDebugView"; diff --git a/src/plugins/qmldesigner/documentwarningwidget.cpp b/src/plugins/qmldesigner/documentwarningwidget.cpp index 438de04c2a1..1567bb5c141 100644 --- a/src/plugins/qmldesigner/documentwarningwidget.cpp +++ b/src/plugins/qmldesigner/documentwarningwidget.cpp @@ -86,6 +86,8 @@ DocumentWarningWidget::DocumentWarningWidget(QWidget *parent) } }); + connect(m_ignoreWarningsCheckBox, &QCheckBox::toggled, this, &DocumentWarningWidget::ignoreCheckBoxToggled); + QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(m_headerLabel); QVBoxLayout *messageLayout = new QVBoxLayout; @@ -117,7 +119,9 @@ void DocumentWarningWidget::refreshContent() m_continueButton->setText(tr("OK")); } else { m_headerLabel->setText(tr("This QML file contains features which are not supported by Qt Quick Designer at:")); + bool block = m_ignoreWarningsCheckBox->blockSignals(true); m_ignoreWarningsCheckBox->setChecked(!warningsEnabled()); + m_ignoreWarningsCheckBox->blockSignals(block); m_ignoreWarningsCheckBox->show(); m_continueButton->setText(tr("Ignore")); } @@ -184,7 +188,7 @@ bool DocumentWarningWidget::warningsEnabled() const void DocumentWarningWidget::ignoreCheckBoxToggled(bool b) { DesignerSettings settings = QmlDesignerPlugin::instance()->settings(); - settings.insert(DesignerSettingsKey::WARNING_FOR_FEATURES_IN_DESIGNER, b); + settings.insert(DesignerSettingsKey::WARNING_FOR_FEATURES_IN_DESIGNER, !b); QmlDesignerPlugin::instance()->setSettings(settings); } diff --git a/src/plugins/qmldesigner/openuiqmlfiledialog.cpp b/src/plugins/qmldesigner/openuiqmlfiledialog.cpp new file mode 100644 index 00000000000..75837654dce --- /dev/null +++ b/src/plugins/qmldesigner/openuiqmlfiledialog.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "openuiqmlfiledialog.h" +#include "ui_openuiqmlfiledialog.h" + +#include + +#include + +namespace QmlDesigner { + +OpenUiQmlFileDialog::OpenUiQmlFileDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::OpenUiQmlFileDialog) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + ui->setupUi(this); + + connect(ui->cancelButton, &QPushButton::clicked, this, &QDialog::close); + connect(ui->openButton, &QPushButton::clicked, [this] { + QListWidgetItem *item = ui->listWidget->currentItem(); + if (item) { + m_uiFileOpened = true; + m_uiQmlFile = item->data(Qt::UserRole).toString(); + } + close(); + }); + connect(ui->listWidget, &QListWidget::itemDoubleClicked, [this](QListWidgetItem *item) { + if (item) { + m_uiFileOpened = true; + m_uiQmlFile = item->data(Qt::UserRole).toString(); + } + close(); + }); + connect(ui->checkBox, &QCheckBox::toggled, [this](bool b){ + DesignerSettings settings = QmlDesignerPlugin::instance()->settings(); + settings.insert(DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES, !b); + QmlDesignerPlugin::instance()->setSettings(settings); + }); +} + +OpenUiQmlFileDialog::~OpenUiQmlFileDialog() +{ + delete ui; +} + +bool OpenUiQmlFileDialog::uiFileOpened() const +{ + return m_uiFileOpened; +} + +void OpenUiQmlFileDialog::setUiQmlFiles(const QString &projectPath, const QStringList &stringList) +{ + QDir projectDir(projectPath); + + foreach (const QString &fileName, stringList) { + QListWidgetItem *item = new QListWidgetItem(projectDir.relativeFilePath(fileName), ui->listWidget); + item->setData(Qt::UserRole, fileName); + ui->listWidget->addItem(item); + } + ui->listWidget->setCurrentItem(ui->listWidget->item(0)); +} + +QString OpenUiQmlFileDialog::uiQmlFile() const +{ + return m_uiQmlFile; +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/openuiqmlfiledialog.h b/src/plugins/qmldesigner/openuiqmlfiledialog.h new file mode 100644 index 00000000000..8f9dac0531e --- /dev/null +++ b/src/plugins/qmldesigner/openuiqmlfiledialog.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +namespace QmlDesigner { + +namespace Ui { +class OpenUiQmlFileDialog; +} + +class OpenUiQmlFileDialog : public QDialog +{ + Q_OBJECT + +public: + explicit OpenUiQmlFileDialog(QWidget *parent = 0); + ~OpenUiQmlFileDialog(); + bool uiFileOpened() const; + void setUiQmlFiles(const QString &projectPath, const QStringList &stringList); + QString uiQmlFile() const; + +private: + Ui::OpenUiQmlFileDialog *ui; + bool m_uiFileOpened = false; + QString m_uiQmlFile; +}; + + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/openuiqmlfiledialog.ui b/src/plugins/qmldesigner/openuiqmlfiledialog.ui new file mode 100644 index 00000000000..a2fab6e786a --- /dev/null +++ b/src/plugins/qmldesigner/openuiqmlfiledialog.ui @@ -0,0 +1,58 @@ + + + QmlDesigner::OpenUiQmlFileDialog + + + + 0 + 0 + 600 + 300 + + + + Open ui.qml file + + + true + + + + + + You are opening a .qml file in the designer. Do you want to open a .ui.qml file instead? + + + + + + + Do not show this dialog again + + + + + + + Open ui.qml file + + + + + + + Cancel + + + true + + + + + + + + + + + diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 5140bd31ff0..60fd2b77ff7 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -29,6 +29,7 @@ #include "designmodewidget.h" #include "settingspage.h" #include "designmodecontext.h" +#include "openuiqmlfiledialog.h" #include #include @@ -53,6 +54,9 @@ #include #include #include +#include +#include +#include #include #include @@ -99,7 +103,7 @@ static bool checkIfEditorIsQtQuick(Core::IEditor *editor) || document->language() == QmlJS::Dialect::Qml; if (Core::ModeManager::currentMode() == Core::Constants::MODE_DESIGN) { - Core::AsynchronousMessageBox::warning(QmlDesignerPlugin::tr("Cannot open QML Design Mode"), + Core::AsynchronousMessageBox::warning(QmlDesignerPlugin::tr("Cannot Open Design Mode"), QmlDesignerPlugin::tr("The QML file is not currently opened in a QML Editor.")); Core::ModeManager::activateMode(Core::Constants::MODE_EDIT); } @@ -220,6 +224,32 @@ void QmlDesignerPlugin::extensionsInitialized() &d->shortCutManager, &ShortCutManager::updateActions); } +static QStringList allUiQmlFilesforCurrentProject(const Utils::FileName &fileName) +{ + QStringList list; + ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile(fileName); + + if (currentProject) { + foreach (const QString &fileName, currentProject->files(ProjectExplorer::Project::SourceFiles)) { + if (fileName.endsWith(".ui.qml")) + list.append(fileName); + } + } + + return list; +} + +static QString projectPath(const Utils::FileName &fileName) +{ + QString path; + ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile(fileName); + + if (currentProject) + path = currentProject->projectDirectory().toString(); + + return path; +} + void QmlDesignerPlugin::createDesignModeWidget() { d->mainWidget = new Internal::DesignModeWidget; @@ -256,6 +286,7 @@ void QmlDesignerPlugin::createDesignModeWidget() connect(Core::ModeManager::instance(), &Core::ModeManager::currentModeChanged, [=] (Core::Id newMode, Core::Id oldMode) { + if (d && Core::EditorManager::currentEditor() && checkIfEditorIsQtQuick (Core::EditorManager::currentEditor()) && !documentIsAlreadyOpen( currentDesignDocument(), Core::EditorManager::currentEditor(), newMode)) { @@ -270,14 +301,40 @@ void QmlDesignerPlugin::createDesignModeWidget() }); } +static bool warningsForQmlFilesInsteadOfUiQmlEnabled() +{ + DesignerSettings settings = QmlDesignerPlugin::instance()->settings(); + return settings.value(DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES).toBool(); +} + +static bool showWarningsForFeaturesInDesigner() +{ + DesignerSettings settings = QmlDesignerPlugin::instance()->settings(); + return settings.value(DesignerSettingsKey::WARNING_FOR_FEATURES_IN_DESIGNER).toBool(); +} + void QmlDesignerPlugin::showDesigner() { QTC_ASSERT(!d->documentManager.hasCurrentDesignDocument(), return); + d->mainWidget->initialize(); + + const Utils::FileName fileName = Core::EditorManager::currentEditor()->document()->filePath(); + const QStringList allUiQmlFiles = allUiQmlFilesforCurrentProject(fileName); + if (warningsForQmlFilesInsteadOfUiQmlEnabled() && !fileName.endsWith(".ui.qml") && !allUiQmlFiles.isEmpty()) { + OpenUiQmlFileDialog dialog(d->mainWidget); + dialog.setUiQmlFiles(projectPath(fileName), allUiQmlFiles); + dialog.exec(); + if (dialog.uiFileOpened()) { + Core::ModeManager::activateMode(Core::Constants::MODE_EDIT); + Core::EditorManager::openEditorAt(dialog.uiQmlFile(), 0, 0); + return; + } + } + d->shortCutManager.disconnectUndoActions(currentDesignDocument()); d->documentManager.setCurrentDesignDocument(Core::EditorManager::currentEditor()); d->shortCutManager.connectUndoActions(currentDesignDocument()); - d->mainWidget->initialize(); if (d->documentManager.hasCurrentDesignDocument()) { activateAutoSynchronization(); @@ -374,7 +431,7 @@ void QmlDesignerPlugin::activateAutoSynchronization() selectModelNodeUnderTextCursor(); d->mainWidget->enableWidgets(); d->mainWidget->setupNavigatorHistory(currentDesignDocument()->textEditor()); - if (currentDesignDocument()->hasQmlParseWarnings()) + if (showWarningsForFeaturesInDesigner() && currentDesignDocument()->hasQmlParseWarnings()) d->mainWidget->showWarningMessageBox(currentDesignDocument()->qmlParseWarnings()); } else { d->mainWidget->disableWidgets(); diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pri b/src/plugins/qmldesigner/qmldesignerplugin.pri index 8afc86cf9df..b9be0d0a558 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.pri +++ b/src/plugins/qmldesigner/qmldesignerplugin.pri @@ -8,7 +8,8 @@ HEADERS += $$PWD/qmldesignerconstants.h \ $$PWD/documentmanager.h \ $$PWD/documentwarningwidget.h \ $$PWD/styledoutputpaneplaceholder.h \ - $$PWD/qmldesignericons.h + $$PWD/qmldesignericons.h \ + $$PWD/openuiqmlfiledialog.h SOURCES += $$PWD/qmldesignerplugin.cpp \ $$PWD/shortcutmanager.cpp \ @@ -18,6 +19,8 @@ SOURCES += $$PWD/qmldesignerplugin.cpp \ $$PWD/designmodecontext.cpp \ $$PWD/documentmanager.cpp \ $$PWD/documentwarningwidget.cpp \ - $$PWD/styledoutputpaneplaceholder.cpp + $$PWD/styledoutputpaneplaceholder.cpp \ + $$PWD/openuiqmlfiledialog.cpp -FORMS += $$PWD/settingspage.ui +FORMS += $$PWD/settingspage.ui \ + $$PWD/openuiqmlfiledialog.ui diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index 99f8b0d7b8b..d6c0ddb9035 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -624,6 +624,9 @@ Project { "documentmanager.h", "documentwarningwidget.cpp", "documentwarningwidget.h", + "openuiqmlfiledialog.cpp", + "openuiqmlfiledialog.h", + "openuiqmlfiledialog.ui", "qmldesignerconstants.h", "qmldesignericons.h", "qmldesignerplugin.cpp", diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo index 6aeb725db7e..9c99274cca0 100644 --- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo +++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo @@ -4,16 +4,6 @@ MetaInfo { name: "QtQuick.Item" icon: ":/qtquickplugin/images/item-icon16.png" - ItemLibraryEntry { - name: "Item" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/images/item-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 200; } - Property { name: "height"; type: "int"; value: 200; } - } - ItemLibraryEntry { name: "Item" category: "Qt Quick - Basic" @@ -29,18 +19,6 @@ MetaInfo { name: "QtQuick.Rectangle" icon: ":/qtquickplugin/images/rect-icon16.png" - ItemLibraryEntry { - name: "Rectangle" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/images/rect-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 200; } - Property { name: "height"; type: "int"; value: 200; } - Property { name: "color"; type: "QColor"; value: "#ffffff"; } - - } - ItemLibraryEntry { name: "Rectangle" category: "Qt Quick - Basic" @@ -57,16 +35,6 @@ MetaInfo { name: "QtQuick.Text" icon: ":/qtquickplugin/images/text-icon16.png" - ItemLibraryEntry { - name: "Text" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/images/text-icon.png" - version: "1.0" - - Property { name: "font.pixelSize"; type: "int"; value: 12; } - Property { name: "text"; type: "binding"; value: "qsTr(\"Text\")"; } - } - ItemLibraryEntry { name: "Text" category: "Qt Quick - Basic" @@ -82,19 +50,6 @@ MetaInfo { name: "QtQuick.TextEdit" icon: ":/qtquickplugin/images/text-edit-icon16.png" - ItemLibraryEntry { - name: "Text Edit" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/images/text-edit-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 80; } - Property { name: "height"; type: "int"; value: 20; } - Property { name: "font.pixelSize"; type: "int"; value: 12; } - Property { name: "text"; type: "binding"; value: "qsTr(\"Text Edit\")"; } - - } - ItemLibraryEntry { name: "Text Edit" category: "Qt Quick - Basic" @@ -112,18 +67,6 @@ MetaInfo { name: "QtQuick.TextInput" icon: ":/qtquickplugin/images/text-input-icon16.png" - ItemLibraryEntry { - name: "Text Input" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/images/text-edit-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 80; } - Property { name: "height"; type: "int"; value: 20; } - Property { name: "font.pixelSize"; type: "int"; value: 12; } - Property { name: "text"; type: "binding"; value: "qsTr(\"Text Input\")"; } - } - ItemLibraryEntry { name: "Text Input" category: "Qt Quick - Basic" @@ -141,17 +84,6 @@ MetaInfo { name: "QtQuick.MouseArea" icon: ":/qtquickplugin/images/mouse-area-icon16.png" - ItemLibraryEntry { - name: "MouseArea" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/images/mouse-area-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 100; } - Property { name: "height"; type: "int"; value: 100; } - - } - ItemLibraryEntry { name: "MouseArea" category: "Qt Quick - Basic" @@ -167,17 +99,6 @@ MetaInfo { name: "QtQuick.Image" icon: ":/qtquickplugin/images/image-icon16.png" - ItemLibraryEntry { - name: "Image" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/images/image-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 100; } - Property { name: "height"; type: "int"; value: 100; } - Property { name: "source"; type: "QUrl"; value:"qrc:/qtquickplugin/images/template_image.png"; } - } - ItemLibraryEntry { name: "Image" category: "Qt Quick - Basic" @@ -194,17 +115,6 @@ MetaInfo { name: "QtQuick.BorderImage" icon: ":/qtquickplugin/images/border-image-icon16.png" - ItemLibraryEntry { - name: "Border Image" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/images/border-image-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 100; } - Property { name: "height"; type: "int"; value: 100; } - Property { name: "source"; type: "QUrl"; value:"qrc:/qtquickplugin/images/template_image.png"; } - } - ItemLibraryEntry { name: "Border Image" category: "Qt Quick - Basic" @@ -221,16 +131,6 @@ MetaInfo { name: "QtQuick.Flickable" icon: ":/qtquickplugin/images/flickable-icon16.png" - ItemLibraryEntry { - name: "Flickable" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/images/flickable-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 300; } - Property { name: "height"; type: "int"; value: 300; } - } - ItemLibraryEntry { name: "Flickable" category: "Qt Quick - Basic" @@ -246,15 +146,6 @@ MetaInfo { name: "QtQuick.GridView" icon: ":/qtquickplugin/images/gridview-icon16.png" - ItemLibraryEntry { - name: "Grid View" - category: "Qt Quick - Views" - libraryIcon: ":/qtquickplugin/images/gridview-icon.png" - version: "1.0" - - QmlSource { source: ":/qtquickplugin/source/gridview.qml" } - } - ItemLibraryEntry { name: "Grid View" category: "Qt Quick - Views" @@ -292,15 +183,6 @@ MetaInfo { name: "QtQuick.PathView" icon: ":/qtquickplugin/images/pathview-icon16.png" - ItemLibraryEntry { - name: "Path View" - category: "Qt Quick - Views" - libraryIcon: ":/qtquickplugin/images/pathview-icon.png" - version: "1.0" - - QmlSource { source: ":/qtquickplugin/source/pathview.qml" } - } - ItemLibraryEntry { name: "Path View" category: "Qt Quick - Views" @@ -315,16 +197,6 @@ MetaInfo { name: "QtQuick.FocusScope" icon: ":/qtquickplugin/images/focusscope-icon16.png" - ItemLibraryEntry { - name: "Focus Scope" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/images/focusscope-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 100; } - Property { name: "height"; type: "int"; value: 100; } - } - ItemLibraryEntry { name: "Focus Scope" category: "Qt Quick - Basic" @@ -336,49 +208,10 @@ MetaInfo { } } - Type { - name: "QtWebKit.WebView" - icon: ":/qtquickplugin/images/webview-icon16.png" - - ItemLibraryEntry { - name: "Web View" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/webview-icon.png" - version: "1.0" - requiredImport: "QtWebKit" - - Property { name: "width"; type: "int"; value: 300; } - Property { name: "height"; type: "int"; value: 300; } - Property { name: "url"; type: "QString"; value: "qrc:/qtquickplugin/html/welcome.html" } - } - - ItemLibraryEntry { - name: "Web View" - category: "Qt Quick - Basic" - libraryIcon: ":/qtquickplugin/images/webview-icon.png" - version: "2.0" - requiredImport: "QtWebKit" - - Property { name: "width"; type: "int"; value: 300; } - Property { name: "height"; type: "int"; value: 300; } - Property { name: "url"; type: "QString"; value: "qrc:/qtquickplugin/html/welcome.html" } - } - } - Type { name: "QtQuick.Column" icon: ":/qtquickplugin/images/item-icon16.png" - ItemLibraryEntry { - name: "Column" - category: "Qt Quick - Positioner" - libraryIcon: ":/qtquickplugin/images/item-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 200; } - Property { name: "height"; type: "int"; value: 400; } - } - ItemLibraryEntry { name: "Column" category: "Qt Quick - Positioner" @@ -394,16 +227,6 @@ MetaInfo { name: "QtQuick.Row" icon: ":/qtquickplugin/images/item-icon16.png" - ItemLibraryEntry { - name: "Row" - category: "Qt Quick - Positioner" - libraryIcon: ":/qtquickplugin/images/item-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 200; } - Property { name: "height"; type: "int"; value: 400; } - } - ItemLibraryEntry { name: "Row" category: "Qt Quick - Positioner" @@ -419,16 +242,6 @@ MetaInfo { name: "QtQuick.Grid" icon: ":/qtquickplugin/images/item-icon16.png" - ItemLibraryEntry { - name: "Grid" - category: "Qt Quick - Positioner" - libraryIcon: ":/qtquickplugin/images/item-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 400; } - Property { name: "height"; type: "int"; value: 400; } - } - ItemLibraryEntry { name: "Grid" category: "Qt Quick - Positioner" @@ -444,16 +257,6 @@ MetaInfo { name: "QtQuick.Flow" icon: ":/qtquickplugin/images/item-icon16.png" - ItemLibraryEntry { - name: "Flow" - category: "Qt Quick - Positioner" - libraryIcon: ":/qtquickplugin/images/item-icon.png" - version: "1.0" - - Property { name: "width"; type: "int"; value: 400; } - Property { name: "height"; type: "int"; value: 400; } - } - ItemLibraryEntry { name: "Flow" category: "Qt Quick - Positioner" diff --git a/src/plugins/qmldesigner/settingspage.cpp b/src/plugins/qmldesigner/settingspage.cpp index 9c5ac641490..3e236631e13 100644 --- a/src/plugins/qmldesigner/settingspage.cpp +++ b/src/plugins/qmldesigner/settingspage.cpp @@ -94,7 +94,10 @@ DesignerSettings SettingsPageWidget::settings() const settings.insert(DesignerSettingsKey::CANVASWIDTH, m_ui.spinCanvasWidth->value()); settings.insert(DesignerSettingsKey::CANVASHEIGHT, m_ui.spinCanvasHeight->value()); settings.insert(DesignerSettingsKey::WARNING_FOR_FEATURES_IN_DESIGNER, - m_ui.designerWarningsCheckBox->isChecked()); + m_ui.designerWarningsCheckBox->isChecked()); + settings.insert(DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES, + m_ui.designerWarningsUiQmlfiles->isChecked()); + settings.insert(DesignerSettingsKey::WARNING_FOR_DESIGNER_FEATURES_IN_EDITOR, m_ui.designerWarningsInEditorCheckBox->isChecked()); settings.insert(DesignerSettingsKey::SHOW_DEBUGVIEW, @@ -144,6 +147,8 @@ void SettingsPageWidget::setSettings(const DesignerSettings &settings) DesignerSettingsKey::CANVASHEIGHT).toInt()); m_ui.designerWarningsCheckBox->setChecked(settings.value( DesignerSettingsKey::WARNING_FOR_FEATURES_IN_DESIGNER).toBool()); + m_ui.designerWarningsUiQmlfiles->setChecked(settings.value( + DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES).toBool()); m_ui.designerWarningsInEditorCheckBox->setChecked(settings.value( DesignerSettingsKey::WARNING_FOR_DESIGNER_FEATURES_IN_EDITOR).toBool()); m_ui.designerShowDebuggerCheckBox->setChecked(settings.value( diff --git a/src/plugins/qmldesigner/settingspage.ui b/src/plugins/qmldesigner/settingspage.ui index 2623092d6e9..72a828bffb8 100644 --- a/src/plugins/qmldesigner/settingspage.ui +++ b/src/plugins/qmldesigner/settingspage.ui @@ -293,6 +293,16 @@ Warnings + + + + Also warns in the code editor about QML features that are not properly supported by the Qt Quick Designer. + + + Warn about unsupported features of Qt Quick Designer in the code editor + + + @@ -303,13 +313,13 @@ - - + + - Also warns in the code editor about QML features that are not properly supported by the Qt Quick Designer. + Qt Quick Designer will propose to open .ui.qml files instead of opening a .qml file. - Warn about unsupported features of Qt Quick Designer in the code editor + Warn about using .qml files instead of .ui.qml files diff --git a/src/plugins/qmljseditor/qmljscomponentnamedialog.cpp b/src/plugins/qmljseditor/qmljscomponentnamedialog.cpp index 3f9ce30019a..6c53cfe62ad 100644 --- a/src/plugins/qmljseditor/qmljscomponentnamedialog.cpp +++ b/src/plugins/qmljseditor/qmljscomponentnamedialog.cpp @@ -38,10 +38,10 @@ ComponentNameDialog::ComponentNameDialog(QWidget *parent) : { ui->setupUi(this); - connect(ui->pathEdit, SIGNAL(rawPathChanged(QString)), - this, SLOT(validate())); - connect(ui->componentNameEdit, SIGNAL(textChanged(QString)), - this, SLOT(validate())); + connect(ui->pathEdit, &Utils::PathChooser::rawPathChanged, + this, &ComponentNameDialog::validate); + connect(ui->componentNameEdit, &QLineEdit::textChanged, + this, &ComponentNameDialog::validate); } ComponentNameDialog::~ComponentNameDialog() @@ -139,14 +139,6 @@ void ComponentNameDialog::generateCodePreview() ui->plainTextEdit->appendPlainText(QLatin1String("}")); } -void ComponentNameDialog::choosePath() -{ - QString dir = QFileDialog::getExistingDirectory(this, tr("Choose a path"), - ui->pathEdit->path()); - if (!dir.isEmpty()) - ui->pathEdit->setPath(dir); -} - void ComponentNameDialog::validate() { const QString message = isValid(); diff --git a/src/plugins/qmljseditor/qmljscomponentnamedialog.h b/src/plugins/qmljseditor/qmljscomponentnamedialog.h index 45309142361..dc3f3674c95 100644 --- a/src/plugins/qmljseditor/qmljscomponentnamedialog.h +++ b/src/plugins/qmljseditor/qmljscomponentnamedialog.h @@ -51,8 +51,6 @@ public: void generateCodePreview(); -public slots: - void choosePath(); void validate(); protected: diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index b3ae499c2e0..232bbd2b25a 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -78,6 +78,7 @@ #include #include #include +#include #include #include #include @@ -147,11 +148,11 @@ void QmlJSEditorWidget::finalizeInitialization() connect(this->document(), &QTextDocument::modificationChanged, this, &QmlJSEditorWidget::modificationChanged); - connect(m_qmlJsEditorDocument, SIGNAL(updateCodeWarnings(QmlJS::Document::Ptr)), - this, SLOT(updateCodeWarnings(QmlJS::Document::Ptr))); + connect(m_qmlJsEditorDocument, &QmlJSEditorDocument::updateCodeWarnings, + this, &QmlJSEditorWidget::updateCodeWarnings); - connect(m_qmlJsEditorDocument, SIGNAL(semanticInfoUpdated(QmlJSTools::SemanticInfo)), - this, SLOT(semanticInfoUpdated(QmlJSTools::SemanticInfo))); + connect(m_qmlJsEditorDocument, &QmlJSEditorDocument::semanticInfoUpdated, + this, &QmlJSEditorWidget::semanticInfoUpdated); setRequestMarkEnabled(true); createToolBar(); @@ -445,7 +446,9 @@ protected: void QmlJSEditorWidget::setSelectedElements() { - if (!receivers(SIGNAL(selectedElementsChanged(QList,QString)))) + static const QMetaMethod selectedChangedSignal = + QMetaMethod::fromSignal(&QmlJSEditorWidget::selectedElementsChanged); + if (!isSignalConnected(selectedChangedSignal)) return; QTextCursor tc = textCursor(); @@ -540,11 +543,12 @@ void QmlJSEditorWidget::createToolBar() policy.setHorizontalPolicy(QSizePolicy::Expanding); m_outlineCombo->setSizePolicy(policy); - connect(m_outlineCombo, SIGNAL(activated(int)), this, SLOT(jumpToOutlineElement(int))); - connect(m_qmlJsEditorDocument->outlineModel(), SIGNAL(updated()), - m_outlineCombo->view()/*QTreeView*/, SLOT(expandAll())); - connect(m_qmlJsEditorDocument->outlineModel(), SIGNAL(updated()), - this, SLOT(updateOutlineIndexNow())); + connect(m_outlineCombo, static_cast(&QComboBox::activated), + this, &QmlJSEditorWidget::jumpToOutlineElement); + connect(m_qmlJsEditorDocument->outlineModel(), &QmlOutlineModel::updated, + static_cast(m_outlineCombo->view()), &QTreeView::expandAll); + connect(m_qmlJsEditorDocument->outlineModel(), &QmlOutlineModel::updated, + this, &QmlJSEditorWidget::updateOutlineIndexNow); connect(this, &QmlJSEditorWidget::cursorPositionChanged, &m_updateOutlineIndexTimer, static_cast(&QTimer::start)); @@ -819,19 +823,12 @@ void QmlJSEditorWidget::showContextPane() } } -void QmlJSEditorWidget::performQuickFix(int index) -{ - m_quickFixes.at(index)->perform(); -} - void QmlJSEditorWidget::contextMenuEvent(QContextMenuEvent *e) { QPointer menu(new QMenu(this)); QMenu *refactoringMenu = new QMenu(tr("Refactoring"), menu); - QSignalMapper mapper; - connect(&mapper, SIGNAL(mapped(int)), this, SLOT(performQuickFix(int))); if (!m_qmlJsEditorDocument->isSemanticInfoOutdated()) { AssistInterface *interface = createAssistInterface(QuickFix, ExplicitlyInvoked); if (interface) { @@ -843,10 +840,8 @@ void QmlJSEditorWidget::contextMenuEvent(QContextMenuEvent *e) for (int index = 0; index < model->size(); ++index) { AssistProposalItem *item = static_cast(model->proposalItem(index)); QuickFixOperation::Ptr op = item->data().value(); - m_quickFixes.append(op); QAction *action = refactoringMenu->addAction(op->description()); - mapper.setMapping(action, index); - connect(action, SIGNAL(triggered()), &mapper, SLOT(map())); + connect(action, &QAction::triggered, this, [op]() { op->perform(); }); } delete model; } @@ -873,9 +868,6 @@ void QmlJSEditorWidget::contextMenuEvent(QContextMenuEvent *e) appendStandardContextMenuActions(menu); menu->exec(e->globalPos()); - if (!menu) - return; - m_quickFixes.clear(); delete menu; } diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h index 79d86dbb5a0..9a086e65c08 100644 --- a/src/plugins/qmljseditor/qmljseditor.h +++ b/src/plugins/qmljseditor/qmljseditor.h @@ -72,7 +72,6 @@ public: void inspectElementUnderCursor() const; -public slots: void findUsages(); void renameUsages(); void showContextPane(); @@ -81,7 +80,7 @@ signals: void outlineModelIndexChanged(const QModelIndex &index); void selectedElementsChanged(QList offsets, const QString &wordAtCursor); -private slots: +private: void modificationChanged(bool); void jumpToOutlineElement(int index); @@ -93,7 +92,6 @@ private slots: void semanticInfoUpdated(const QmlJSTools::SemanticInfo &semanticInfo); - void performQuickFix(int index); void updateCodeWarnings(QmlJS::Document::Ptr doc); protected: @@ -127,8 +125,6 @@ private: QModelIndex m_outlineModelIndex; QmlJS::ModelManagerInterface *m_modelManager; - TextEditor::QuickFixOperations m_quickFixes; - QmlJS::IContextPane *m_contextPane; int m_oldCursorPosition; diff --git a/src/plugins/qmljseditor/qmljseditordocument.cpp b/src/plugins/qmljseditor/qmljseditordocument.cpp index 45a01ee5d3c..6ef9f3bdee8 100644 --- a/src/plugins/qmljseditor/qmljseditordocument.cpp +++ b/src/plugins/qmljseditor/qmljseditordocument.cpp @@ -467,28 +467,32 @@ QmlJSEditorDocumentPrivate::QmlJSEditorDocumentPrivate(QmlJSEditorDocument *pare // code model m_updateDocumentTimer.setInterval(UPDATE_DOCUMENT_DEFAULT_INTERVAL); m_updateDocumentTimer.setSingleShot(true); - connect(q->document(), SIGNAL(contentsChanged()), &m_updateDocumentTimer, SLOT(start())); - connect(&m_updateDocumentTimer, SIGNAL(timeout()), this, SLOT(reparseDocument())); - connect(modelManager, SIGNAL(documentUpdated(QmlJS::Document::Ptr)), - this, SLOT(onDocumentUpdated(QmlJS::Document::Ptr))); + connect(q->document(), &QTextDocument::contentsChanged, + &m_updateDocumentTimer, static_cast(&QTimer::start)); + connect(&m_updateDocumentTimer, &QTimer::timeout, + this, &QmlJSEditorDocumentPrivate::reparseDocument); + connect(modelManager, &ModelManagerInterface::documentUpdated, + this, &QmlJSEditorDocumentPrivate::onDocumentUpdated); // semantic info m_semanticInfoUpdater = new SemanticInfoUpdater(this); - connect(m_semanticInfoUpdater, SIGNAL(updated(QmlJSTools::SemanticInfo)), - this, SLOT(acceptNewSemanticInfo(QmlJSTools::SemanticInfo))); + connect(m_semanticInfoUpdater, &SemanticInfoUpdater::updated, + this, &QmlJSEditorDocumentPrivate::acceptNewSemanticInfo); m_semanticInfoUpdater->start(); // library info changes m_reupdateSemanticInfoTimer.setInterval(UPDATE_DOCUMENT_DEFAULT_INTERVAL); m_reupdateSemanticInfoTimer.setSingleShot(true); - connect(&m_reupdateSemanticInfoTimer, SIGNAL(timeout()), this, SLOT(reupdateSemanticInfo())); - connect(modelManager, SIGNAL(libraryInfoUpdated(QString,QmlJS::LibraryInfo)), - &m_reupdateSemanticInfoTimer, SLOT(start())); + connect(&m_reupdateSemanticInfoTimer, &QTimer::timeout, + this, &QmlJSEditorDocumentPrivate::reupdateSemanticInfo); + connect(modelManager, &ModelManagerInterface::libraryInfoUpdated, + &m_reupdateSemanticInfoTimer, static_cast(&QTimer::start)); // outline model m_updateOutlineModelTimer.setInterval(UPDATE_OUTLINE_INTERVAL); m_updateOutlineModelTimer.setSingleShot(true); - connect(&m_updateOutlineModelTimer, SIGNAL(timeout()), this, SLOT(updateOutlineModel())); + connect(&m_updateOutlineModelTimer, &QTimer::timeout, + this, &QmlJSEditorDocumentPrivate::updateOutlineModel); modelManager->updateSourceFiles(QStringList(parent->filePath().toString()), false); } @@ -589,8 +593,8 @@ QmlJSEditorDocument::QmlJSEditorDocument() : d(new Internal::QmlJSEditorDocumentPrivate(this)) { setId(Constants::C_QMLJSEDITOR_ID); - connect(this, SIGNAL(tabSettingsChanged()), - d, SLOT(invalidateFormatterCache())); + connect(this, &TextEditor::TextDocument::tabSettingsChanged, + d, &Internal::QmlJSEditorDocumentPrivate::invalidateFormatterCache); setSyntaxHighlighter(new QmlJSHighlighter(document())); setIndenter(new Internal::Indenter); } diff --git a/src/plugins/qmljseditor/qmljseditordocument_p.h b/src/plugins/qmljseditor/qmljseditordocument_p.h index 46a6a36c654..f2cee06d762 100644 --- a/src/plugins/qmljseditor/qmljseditordocument_p.h +++ b/src/plugins/qmljseditor/qmljseditordocument_p.h @@ -50,7 +50,6 @@ public: QmlJSEditorDocumentPrivate(QmlJSEditorDocument *parent); ~QmlJSEditorDocumentPrivate(); -public slots: void invalidateFormatterCache(); void reparseDocument(); void onDocumentUpdated(QmlJS::Document::Ptr doc); diff --git a/src/plugins/qmljseditor/qmljseditorplugin.cpp b/src/plugins/qmljseditor/qmljseditorplugin.cpp index 794bd99416b..6bd676e7b82 100644 --- a/src/plugins/qmljseditor/qmljseditorplugin.cpp +++ b/src/plugins/qmljseditor/qmljseditorplugin.cpp @@ -104,16 +104,16 @@ bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *e // QML task updating manager m_qmlTaskManager = new QmlTaskManager; addAutoReleasedObject(m_qmlTaskManager); - connect(m_modelManager, SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)), - m_qmlTaskManager, SLOT(updateMessages())); + connect(m_modelManager, &QmlJS::ModelManagerInterface::documentChangedOnDisk, + m_qmlTaskManager, &QmlTaskManager::updateMessages); // recompute messages when information about libraries changes - connect(m_modelManager, SIGNAL(libraryInfoUpdated(QString,QmlJS::LibraryInfo)), - m_qmlTaskManager, SLOT(updateMessages())); + connect(m_modelManager, &QmlJS::ModelManagerInterface::libraryInfoUpdated, + m_qmlTaskManager, &QmlTaskManager::updateMessages); // recompute messages when project data changes (files added or removed) - connect(m_modelManager, SIGNAL(projectInfoUpdated(ProjectInfo)), - m_qmlTaskManager, SLOT(updateMessages())); - connect(m_modelManager, SIGNAL(aboutToRemoveFiles(QStringList)), - m_qmlTaskManager, SLOT(documentsRemoved(QStringList))); + connect(m_modelManager, &QmlJS::ModelManagerInterface::projectInfoUpdated, + m_qmlTaskManager, &QmlTaskManager::updateMessages); + connect(m_modelManager, &QmlJS::ModelManagerInterface::aboutToRemoveFiles, + m_qmlTaskManager, &QmlTaskManager::documentsRemoved); Context context(Constants::C_QMLJSEDITOR_ID); @@ -132,26 +132,26 @@ bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *e QAction *findUsagesAction = new QAction(tr("Find Usages"), this); cmd = ActionManager::registerAction(findUsagesAction, Constants::FIND_USAGES, context); cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+U"))); - connect(findUsagesAction, SIGNAL(triggered()), this, SLOT(findUsages())); + connect(findUsagesAction, &QAction::triggered, this, &QmlJSEditorPlugin::findUsages); contextMenu->addAction(cmd); qmlToolsMenu->addAction(cmd); QAction *renameUsagesAction = new QAction(tr("Rename Symbol Under Cursor"), this); cmd = ActionManager::registerAction(renameUsagesAction, Constants::RENAME_USAGES, context); cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+R"))); - connect(renameUsagesAction, SIGNAL(triggered()), this, SLOT(renameUsages())); + connect(renameUsagesAction, &QAction::triggered, this, &QmlJSEditorPlugin::renameUsages); contextMenu->addAction(cmd); qmlToolsMenu->addAction(cmd); QAction *semanticScan = new QAction(tr("Run Checks"), this); cmd = ActionManager::registerAction(semanticScan, Id(Constants::RUN_SEMANTIC_SCAN)); cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+C"))); - connect(semanticScan, SIGNAL(triggered()), this, SLOT(runSemanticScan())); + connect(semanticScan, &QAction::triggered, this, &QmlJSEditorPlugin::runSemanticScan); qmlToolsMenu->addAction(cmd); m_reformatFileAction = new QAction(tr("Reformat File"), this); cmd = ActionManager::registerAction(m_reformatFileAction, Id(Constants::REFORMAT_FILE), context); - connect(m_reformatFileAction, SIGNAL(triggered()), this, SLOT(reformatFile())); + connect(m_reformatFileAction, &QAction::triggered, this, &QmlJSEditorPlugin::reformatFile); qmlToolsMenu->addAction(cmd); QAction *inspectElementAction = new QAction(tr("Inspect API for Element Under Cursor"), this); @@ -167,7 +167,7 @@ bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *e cmd = ActionManager::registerAction(showQuickToolbar, Constants::SHOW_QT_QUICK_HELPER, context); cmd->setDefaultKeySequence(UseMacShortcuts ? QKeySequence(Qt::META + Qt::ALT + Qt::Key_Space) : QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Space)); - connect(showQuickToolbar, SIGNAL(triggered()), this, SLOT(showContextPane())); + connect(showQuickToolbar, &QAction::triggered, this, &QmlJSEditorPlugin::showContextPane); contextMenu->addAction(cmd); qmlToolsMenu->addAction(cmd); @@ -195,7 +195,8 @@ bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *e addAutoReleasedObject(new QuickToolBar); addAutoReleasedObject(new QuickToolBarSettingsPage); - connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)), SLOT(currentEditorChanged(Core::IEditor*))); + connect(EditorManager::instance(), &EditorManager::currentEditorChanged, + this, &QmlJSEditorPlugin::currentEditorChanged); return true; } @@ -275,10 +276,10 @@ void QmlJSEditorPlugin::currentEditorChanged(IEditor *editor) m_currentDocument->disconnect(this); m_currentDocument = document; if (document) { - connect(document->document(), SIGNAL(contentsChanged()), - this, SLOT(checkCurrentEditorSemanticInfoUpToDate())); - connect(document, SIGNAL(semanticInfoUpdated(QmlJSTools::SemanticInfo)), - this, SLOT(checkCurrentEditorSemanticInfoUpToDate())); + connect(document->document(), &QTextDocument::contentsChanged, + this, &QmlJSEditorPlugin::checkCurrentEditorSemanticInfoUpToDate); + connect(document, &QmlJSEditorDocument::semanticInfoUpdated, + this, &QmlJSEditorPlugin::checkCurrentEditorSemanticInfoUpToDate); } } diff --git a/src/plugins/qmljseditor/qmljseditorplugin.h b/src/plugins/qmljseditor/qmljseditorplugin.h index e96e59163b2..a85f16b3894 100644 --- a/src/plugins/qmljseditor/qmljseditorplugin.h +++ b/src/plugins/qmljseditor/qmljseditorplugin.h @@ -73,18 +73,16 @@ public: Utils::JsonSchemaManager *jsonManager() const; -public Q_SLOTS: void findUsages(); void renameUsages(); void reformatFile(); void showContextPane(); -private Q_SLOTS: +private: void currentEditorChanged(Core::IEditor *editor); void runSemanticScan(); void checkCurrentEditorSemanticInfoUpToDate(); -private: Core::Command *addToolAction(QAction *a, Core::Context &context, Core::Id id, Core::ActionContainer *c1, const QString &keySequence); diff --git a/src/plugins/qmljseditor/qmljsfindreferences.cpp b/src/plugins/qmljseditor/qmljsfindreferences.cpp index 6c7ff6eb13f..8927407c875 100644 --- a/src/plugins/qmljseditor/qmljsfindreferences.cpp +++ b/src/plugins/qmljseditor/qmljsfindreferences.cpp @@ -782,8 +782,8 @@ FindReferences::FindReferences(QObject *parent) : QObject(parent) { m_watcher.setPendingResultsLimit(1); - connect(&m_watcher, SIGNAL(resultsReadyAt(int,int)), this, SLOT(displayResults(int,int))); - connect(&m_watcher, SIGNAL(finished()), this, SLOT(searchFinished())); + connect(&m_watcher, &QFutureWatcherBase::resultsReadyAt, this, &FindReferences::displayResults); + connect(&m_watcher, &QFutureWatcherBase::finished, this, &FindReferences::searchFinished); } FindReferences::~FindReferences() @@ -955,19 +955,19 @@ void FindReferences::displayResults(int first, int last) label, QString(), symbolName, SearchResultWindow::SearchAndReplace, SearchResultWindow::PreserveCaseDisabled); m_currentSearch->setTextToReplace(replacement); - connect(m_currentSearch, SIGNAL(replaceButtonClicked(QString,QList,bool)), - SLOT(onReplaceButtonClicked(QString,QList,bool))); + connect(m_currentSearch.data(), &SearchResult::replaceButtonClicked, + this, &FindReferences::onReplaceButtonClicked); } - connect(m_currentSearch, SIGNAL(activated(Core::SearchResultItem)), - this, SLOT(openEditor(Core::SearchResultItem))); - connect(m_currentSearch, SIGNAL(cancelled()), this, SLOT(cancel())); - connect(m_currentSearch, SIGNAL(paused(bool)), this, SLOT(setPaused(bool))); + connect(m_currentSearch.data(), &SearchResult::activated, + this, &FindReferences::openEditor); + connect(m_currentSearch.data(), &SearchResult::cancelled, this, &FindReferences::cancel); + connect(m_currentSearch.data(), &SearchResult::paused, this, &FindReferences::setPaused); SearchResultWindow::instance()->popup(IOutputPane::Flags(IOutputPane::ModeSwitch | IOutputPane::WithFocus)); FutureProgress *progress = ProgressManager::addTask( m_watcher.future(), tr("Searching for Usages"), QmlJSEditor::Constants::TASK_SEARCH); - connect(progress, SIGNAL(clicked()), m_currentSearch, SLOT(popup())); + connect(progress, &FutureProgress::clicked, m_currentSearch.data(), &SearchResult::popup); ++first; } diff --git a/src/plugins/qmljseditor/qmljsfindreferences.h b/src/plugins/qmljseditor/qmljsfindreferences.h index 2d8cb9aaebe..e7075b47993 100644 --- a/src/plugins/qmljseditor/qmljsfindreferences.h +++ b/src/plugins/qmljseditor/qmljsfindreferences.h @@ -67,7 +67,7 @@ public: FindReferences(QObject *parent = 0); virtual ~FindReferences(); -Q_SIGNALS: +signals: void changed(); public: @@ -77,7 +77,7 @@ public: static QList findUsageOfType(const QString &fileName, const QString typeName); -private Q_SLOTS: +private: void displayResults(int first, int last); void searchFinished(); void cancel(); @@ -85,7 +85,6 @@ private Q_SLOTS: void openEditor(const Core::SearchResultItem &item); void onReplaceButtonClicked(const QString &text, const QList &items, bool preserveCase); -private: QPointer m_currentSearch; QFutureWatcher m_watcher; }; diff --git a/src/plugins/qmljseditor/qmljsoutline.cpp b/src/plugins/qmljseditor/qmljsoutline.cpp index 5018befbc8c..bf37940983a 100644 --- a/src/plugins/qmljseditor/qmljsoutline.cpp +++ b/src/plugins/qmljseditor/qmljsoutline.cpp @@ -117,7 +117,7 @@ QmlJSOutlineWidget::QmlJSOutlineWidget(QWidget *parent) : m_showBindingsAction->setText(tr("Show All Bindings")); m_showBindingsAction->setCheckable(true); m_showBindingsAction->setChecked(true); - connect(m_showBindingsAction, SIGNAL(toggled(bool)), this, SLOT(setShowBindings(bool))); + connect(m_showBindingsAction, &QAction::toggled, this, &QmlJSOutlineWidget::setShowBindings); setLayout(layout); } @@ -129,16 +129,16 @@ void QmlJSOutlineWidget::setEditor(QmlJSEditorWidget *editor) m_filterModel->setSourceModel(m_editor->qmlJsEditorDocument()->outlineModel()); modelUpdated(); - connect(m_treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - this, SLOT(updateSelectionInText(QItemSelection))); + connect(m_treeView->selectionModel(), &QItemSelectionModel::selectionChanged, + this, &QmlJSOutlineWidget::updateSelectionInText); - connect(m_treeView, SIGNAL(activated(QModelIndex)), - this, SLOT(focusEditor())); + connect(m_treeView, &QAbstractItemView::activated, + this, &QmlJSOutlineWidget::focusEditor); - connect(m_editor, SIGNAL(outlineModelIndexChanged(QModelIndex)), - this, SLOT(updateSelectionInTree(QModelIndex))); - connect(m_editor->qmlJsEditorDocument()->outlineModel(), SIGNAL(updated()), - this, SLOT(modelUpdated())); + connect(m_editor, &QmlJSEditorWidget::outlineModelIndexChanged, + this, &QmlJSOutlineWidget::updateSelectionInTree); + connect(m_editor->qmlJsEditorDocument()->outlineModel(), &QmlOutlineModel::updated, + this, &QmlJSOutlineWidget::modelUpdated); } QList QmlJSOutlineWidget::filterMenuActions() const diff --git a/src/plugins/qmljseditor/qmljsoutline.h b/src/plugins/qmljseditor/qmljsoutline.h index fc475ed6894..799aaf812ad 100644 --- a/src/plugins/qmljseditor/qmljsoutline.h +++ b/src/plugins/qmljseditor/qmljsoutline.h @@ -71,15 +71,13 @@ public: virtual void restoreSettings(const QVariantMap &map); virtual QVariantMap settings() const; -private slots: +private: void modelUpdated(); void updateSelectionInTree(const QModelIndex &index); void updateSelectionInText(const QItemSelection &selection); void updateTextCursor(const QModelIndex &index); void focusEditor(); void setShowBindings(bool showBindings); - -private: bool syncCursor(); private: diff --git a/src/plugins/qmljseditor/qmljsoutlinetreeview.cpp b/src/plugins/qmljseditor/qmljsoutlinetreeview.cpp index a63c6431a85..f20715ad506 100644 --- a/src/plugins/qmljseditor/qmljsoutlinetreeview.cpp +++ b/src/plugins/qmljseditor/qmljsoutlinetreeview.cpp @@ -57,8 +57,8 @@ void QmlJSOutlineTreeView::contextMenuEvent(QContextMenuEvent *event) QMenu contextMenu; - contextMenu.addAction(tr("Expand All"), this, SLOT(expandAll())); - contextMenu.addAction(tr("Collapse All"), this, SLOT(collapseAllExceptRoot())); + contextMenu.addAction(tr("Expand All"), this, [this] { expandAll(); }); + contextMenu.addAction(tr("Collapse All"), this, [this] { collapseAllExceptRoot(); }); contextMenu.exec(event->globalPos()); diff --git a/src/plugins/qmljseditor/qmljsoutlinetreeview.h b/src/plugins/qmljseditor/qmljsoutlinetreeview.h index 7b651f4c243..53e919b484b 100644 --- a/src/plugins/qmljseditor/qmljsoutlinetreeview.h +++ b/src/plugins/qmljseditor/qmljsoutlinetreeview.h @@ -38,7 +38,7 @@ public: void contextMenuEvent(QContextMenuEvent *event); -private slots: +private: void collapseAllExceptRoot(); }; diff --git a/src/plugins/qmljseditor/qmljssemantichighlighter.cpp b/src/plugins/qmljseditor/qmljssemantichighlighter.cpp index 0f2dea0442d..d21ddb387ad 100644 --- a/src/plugins/qmljseditor/qmljssemantichighlighter.cpp +++ b/src/plugins/qmljseditor/qmljssemantichighlighter.cpp @@ -534,10 +534,10 @@ SemanticHighlighter::SemanticHighlighter(QmlJSEditorDocument *document) , m_document(document) , m_startRevision(0) { - connect(&m_watcher, SIGNAL(resultsReadyAt(int,int)), - this, SLOT(applyResults(int,int))); - connect(&m_watcher, SIGNAL(finished()), - this, SLOT(finished())); + connect(&m_watcher, &QFutureWatcherBase::resultsReadyAt, + this, &SemanticHighlighter::applyResults); + connect(&m_watcher, &QFutureWatcherBase::finished, + this, &SemanticHighlighter::finished); } void SemanticHighlighter::rerun(const QmlJSTools::SemanticInfo &semanticInfo) diff --git a/src/plugins/qmljseditor/qmljssemantichighlighter.h b/src/plugins/qmljseditor/qmljssemantichighlighter.h index 7491e71eede..c32a69df89c 100644 --- a/src/plugins/qmljseditor/qmljssemantichighlighter.h +++ b/src/plugins/qmljseditor/qmljssemantichighlighter.h @@ -80,11 +80,9 @@ public: void reportMessagesInfo(const QVector &diagnosticMessages, const QHash &formats); -private slots: +private: void applyResults(int from, int to); void finished(); - -private: void run(QFutureInterface &futureInterface, const QmlJSTools::SemanticInfo &semanticInfo); QFutureWatcher m_watcher; diff --git a/src/plugins/qmljseditor/qmljssemanticinfoupdater.h b/src/plugins/qmljseditor/qmljssemanticinfoupdater.h index 3d7696f4665..0bc3533a422 100644 --- a/src/plugins/qmljseditor/qmljssemanticinfoupdater.h +++ b/src/plugins/qmljseditor/qmljssemanticinfoupdater.h @@ -47,7 +47,7 @@ public: void update(const QmlJS::Document::Ptr &doc, const QmlJS::Snapshot &snapshot); void reupdate(const QmlJS::Snapshot &snapshot); -Q_SIGNALS: +signals: void updated(const QmlJSTools::SemanticInfo &semanticInfo); protected: diff --git a/src/plugins/qmljseditor/qmltaskmanager.cpp b/src/plugins/qmljseditor/qmltaskmanager.cpp index f0e28ad6d3a..8977d453592 100644 --- a/src/plugins/qmljseditor/qmltaskmanager.cpp +++ b/src/plugins/qmljseditor/qmltaskmanager.cpp @@ -52,15 +52,14 @@ QmlTaskManager::QmlTaskManager(QObject *parent) : m_updatingSemantic(false) { // displaying results incrementally leads to flickering -// connect(&m_messageCollector, SIGNAL(resultsReadyAt(int,int)), -// SLOT(displayResults(int,int))); - connect(&m_messageCollector, SIGNAL(finished()), - SLOT(displayAllResults())); +// connect(&m_messageCollector, &QFutureWatcherBase::resultsReadyAt, +// this, &QmlTaskManager::displayResults); + connect(&m_messageCollector, &QFutureWatcherBase::finished, + this, &QmlTaskManager::displayAllResults); m_updateDelay.setInterval(500); m_updateDelay.setSingleShot(true); - connect(&m_updateDelay, SIGNAL(timeout()), - SLOT(updateMessagesNow())); + connect(&m_updateDelay, &QTimer::timeout, this, [this] { updateMessagesNow(); }); } static QList convertToTasks(const QList &messages, const FileName &fileName, Core::Id category) diff --git a/src/plugins/qmljseditor/qmltaskmanager.h b/src/plugins/qmljseditor/qmltaskmanager.h index 9c56e7a93b4..415dcde393e 100644 --- a/src/plugins/qmljseditor/qmltaskmanager.h +++ b/src/plugins/qmljseditor/qmltaskmanager.h @@ -47,17 +47,15 @@ public: void extensionsInitialized(); -public slots: void updateMessages(); void updateSemanticMessagesNow(); void documentsRemoved(const QStringList &path); -private slots: +private: void displayResults(int begin, int end); void displayAllResults(); void updateMessagesNow(bool updateSemantic = false); -private: void insertTask(const ProjectExplorer::Task &task); void removeTasksForFile(const QString &fileName); void removeAllTasks(bool clearSemantic); diff --git a/src/plugins/qmljseditor/quicktoolbar.cpp b/src/plugins/qmljseditor/quicktoolbar.cpp index 6a9c50a4454..863b778c178 100644 --- a/src/plugins/qmljseditor/quicktoolbar.cpp +++ b/src/plugins/qmljseditor/quicktoolbar.cpp @@ -436,12 +436,17 @@ ContextPaneWidget* QuickToolBar::contextWidget() { if (m_widget.isNull()) { //lazily recreate widget m_widget = new ContextPaneWidget; - connect(m_widget.data(), SIGNAL(propertyChanged(QString,QVariant)), this, SLOT(onPropertyChanged(QString,QVariant))); - connect(m_widget.data(), SIGNAL(removeProperty(QString)), this, SLOT(onPropertyRemoved(QString))); - connect(m_widget.data(), SIGNAL(removeAndChangeProperty(QString,QString,QVariant,bool)), this, SLOT(onPropertyRemovedAndChange(QString,QString,QVariant,bool))); - connect(m_widget.data(), SIGNAL(enabledChanged(bool)), this, SLOT(onEnabledChanged(bool))); - connect(m_widget.data(), SIGNAL(pinnedChanged(bool)), this, SLOT(onPinnedChanged(bool))); - connect(m_widget.data(), SIGNAL(closed()), this, SIGNAL(closed())); + connect(m_widget.data(), &ContextPaneWidget::propertyChanged, + this, &QuickToolBar::onPropertyChanged); + connect(m_widget.data(), &ContextPaneWidget::removeProperty, + this, &QuickToolBar::onPropertyRemoved); + connect(m_widget.data(), &ContextPaneWidget::removeAndChangeProperty, + this, &QuickToolBar::onPropertyRemovedAndChange); + connect(m_widget.data(), &ContextPaneWidget::enabledChanged, + this, &QuickToolBar::onEnabledChanged); + connect(m_widget.data(), &ContextPaneWidget::pinnedChanged, + this, &QuickToolBar::onPinnedChanged); + connect(m_widget.data(), &ContextPaneWidget::closed, this, &IContextPane::closed); } return m_widget.data(); } diff --git a/src/plugins/qmljseditor/quicktoolbar.h b/src/plugins/qmljseditor/quicktoolbar.h index df7a5e65149..6d75bb7bed2 100644 --- a/src/plugins/qmljseditor/quicktoolbar.h +++ b/src/plugins/qmljseditor/quicktoolbar.h @@ -47,7 +47,6 @@ public: void setEnabled(bool); QWidget* widget(); -public slots: void onPropertyChanged(const QString &, const QVariant &); void onPropertyRemoved(const QString &); void onPropertyRemovedAndChange(const QString &, const QString &, const QVariant &, bool removeFirst = true); diff --git a/src/plugins/qmljstools/qmljscodestylesettingspage.cpp b/src/plugins/qmljstools/qmljscodestylesettingspage.cpp index 909de2f1a6c..a41d6854510 100644 --- a/src/plugins/qmljstools/qmljscodestylesettingspage.cpp +++ b/src/plugins/qmljstools/qmljscodestylesettingspage.cpp @@ -65,8 +65,8 @@ QmlJSCodeStylePreferencesWidget::QmlJSCodeStylePreferencesWidget(QWidget *parent provider->decorateEditor(m_ui->previewTextEdit); decorateEditor(TextEditorSettings::fontSettings()); - connect(TextEditorSettings::instance(), SIGNAL(fontSettingsChanged(TextEditor::FontSettings)), - this, SLOT(decorateEditor(TextEditor::FontSettings))); + connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged, + this, &QmlJSCodeStylePreferencesWidget::decorateEditor); setVisualizeWhitespace(true); diff --git a/src/plugins/qmljstools/qmljscodestylesettingspage.h b/src/plugins/qmljstools/qmljscodestylesettingspage.h index cae3a9c2b4a..96d377fc8c5 100644 --- a/src/plugins/qmljstools/qmljscodestylesettingspage.h +++ b/src/plugins/qmljstools/qmljscodestylesettingspage.h @@ -55,13 +55,12 @@ public: void setPreferences(TextEditor::ICodeStylePreferences *preferences); -private slots: +private: void decorateEditor(const TextEditor::FontSettings &fontSettings); void setVisualizeWhitespace(bool on); void slotSettingsChanged(); void updatePreview(); -private: TextEditor::ICodeStylePreferences *m_preferences; Ui::QmlJSCodeStyleSettingsPage *m_ui; }; diff --git a/src/plugins/qmljstools/qmljslocatordata.h b/src/plugins/qmljstools/qmljslocatordata.h index 39b728d6f13..238b4f059dc 100644 --- a/src/plugins/qmljstools/qmljslocatordata.h +++ b/src/plugins/qmljstools/qmljslocatordata.h @@ -60,11 +60,10 @@ public: QHash > entries() const; -private slots: +private: void onDocumentUpdated(const QmlJS::Document::Ptr &doc); void onAboutToRemoveFiles(const QStringList &files); -private: mutable QMutex m_mutex; QHash > m_entries; }; diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp index a1c153438a1..1fdf60b8087 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.cpp +++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp @@ -219,8 +219,8 @@ void ModelManager::delayedInitialization() CppTools::CppModelManager *cppModelManager = CppTools::CppModelManager::instance(); // It's important to have a direct connection here so we can prevent // the source and AST of the cpp document being cleaned away. - connect(cppModelManager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)), - this, SLOT(maybeQueueCppQmlTypeUpdate(CPlusPlus::Document::Ptr)), Qt::DirectConnection); + connect(cppModelManager, &CppTools::CppModelManager::documentUpdated, + this, &ModelManagerInterface::maybeQueueCppQmlTypeUpdate, Qt::DirectConnection); connect(SessionManager::instance(), &SessionManager::projectRemoved, this, &ModelManager::removeProjectInfo); diff --git a/src/plugins/qmljstools/qmljsmodelmanager.h b/src/plugins/qmljstools/qmljsmodelmanager.h index c2ab6c4eacb..4a02117c874 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.h +++ b/src/plugins/qmljstools/qmljsmodelmanager.h @@ -56,9 +56,8 @@ protected: WorkingCopy workingCopyInternal() const override; void addTaskInternal(QFuture result, const QString &msg, const char *taskId) const override; ProjectInfo defaultProjectInfoForProject(ProjectExplorer::Project *project) const override; -private slots: - void updateDefaultProjectInfo(); private: + void updateDefaultProjectInfo(); void loadDefaultQmlTypeDescriptions(); QHash initLanguageForSuffix() const; }; diff --git a/src/plugins/qmljstools/qmljstoolsplugin.cpp b/src/plugins/qmljstools/qmljstoolsplugin.cpp index 1e173109e45..356ea6252e8 100644 --- a/src/plugins/qmljstools/qmljstoolsplugin.cpp +++ b/src/plugins/qmljstools/qmljstoolsplugin.cpp @@ -105,10 +105,10 @@ bool QmlJSToolsPlugin::initialize(const QStringList &arguments, QString *error) mqmljstools->addAction(cmd); // watch task progress - connect(ProgressManager::instance(), SIGNAL(taskStarted(Core::Id)), - this, SLOT(onTaskStarted(Core::Id))); - connect(ProgressManager::instance(), SIGNAL(allTasksFinished(Core::Id)), - this, SLOT(onAllTasksFinished(Core::Id))); + connect(ProgressManager::instance(), &ProgressManager::taskStarted, + this, &QmlJSToolsPlugin::onTaskStarted); + connect(ProgressManager::instance(), &ProgressManager::allTasksFinished, + this, &QmlJSToolsPlugin::onAllTasksFinished); return true; } diff --git a/src/plugins/qmljstools/qmljstoolsplugin.h b/src/plugins/qmljstools/qmljstoolsplugin.h index 02faedb5053..c032978de51 100644 --- a/src/plugins/qmljstools/qmljstoolsplugin.h +++ b/src/plugins/qmljstools/qmljstoolsplugin.h @@ -58,20 +58,20 @@ public: ShutdownFlag aboutToShutdown(); ModelManager *modelManager() { return m_modelManager; } -private slots: +private: void onTaskStarted(Core::Id type); void onAllTasksFinished(Core::Id type); -#ifdef WITH_TESTS - void test_basic(); -#endif - -private: ModelManager *m_modelManager; QmlJSToolsSettings *m_settings; QAction *m_resetCodeModelAction; static QmlJSToolsPlugin *m_instance; + +#ifdef WITH_TESTS +private slots: + void test_basic(); +#endif }; } // namespace Internal diff --git a/src/shared/modeltest/modeltest.cpp b/src/shared/modeltest/modeltest.cpp index 3e3f5bf7237..bb4089278e6 100644 --- a/src/shared/modeltest/modeltest.cpp +++ b/src/shared/modeltest/modeltest.cpp @@ -37,44 +37,44 @@ ModelTest::ModelTest(QAbstractItemModel *_model, QObject *parent) : QObject(pare { Q_ASSERT(model); - connect(model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(runAllTests())); - connect(model, SIGNAL(layoutChanged()), this, SLOT(runAllTests())); - connect(model, SIGNAL(modelReset()), this, SLOT(runAllTests())); - connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), - this, SLOT(runAllTests())); + connect(model, &QAbstractItemModel::columnsAboutToBeInserted, + this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::columnsAboutToBeRemoved, + this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::columnsInserted, + this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::columnsRemoved, + this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::dataChanged, + this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::headerDataChanged, + this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::layoutAboutToBeChanged, this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::layoutChanged, this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::modelReset, this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::rowsAboutToBeInserted, + this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, + this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::rowsInserted, + this, &ModelTest::runAllTests); + connect(model, &QAbstractItemModel::rowsRemoved, + this, &ModelTest::runAllTests); // Special checks for inserting/removing - connect(model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(layoutAboutToBeChanged())); - connect(model, SIGNAL(layoutChanged()), - this, SLOT(layoutChanged())); + connect(model, &QAbstractItemModel::layoutAboutToBeChanged, + this, &ModelTest::layoutAboutToBeChanged); + connect(model, &QAbstractItemModel::layoutChanged, + this, &ModelTest::layoutChanged); - connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(rowsAboutToBeInserted(QModelIndex,int,int))); - connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); - connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(rowsInserted(QModelIndex,int,int))); - connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), - this, SLOT(rowsRemoved(QModelIndex,int,int))); + connect(model, &QAbstractItemModel::rowsAboutToBeInserted, + this, &ModelTest::rowsAboutToBeInserted); + connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, + this, &ModelTest::rowsAboutToBeRemoved); + connect(model, &QAbstractItemModel::rowsInserted, + this, &ModelTest::rowsInserted); + connect(model, &QAbstractItemModel::rowsRemoved, + this, &ModelTest::rowsRemoved); runAllTests(); } diff --git a/src/shared/pch_files.qbs b/src/shared/pch_files.qbs new file mode 100644 index 00000000000..237f8456db8 --- /dev/null +++ b/src/shared/pch_files.qbs @@ -0,0 +1,16 @@ +import qbs +import qbs.FileInfo + +Product { + name: "precompiled headers" + condition: qtc.make_dev_package + Depends { name: "qtc" } + Group { + files: [ + "qtcreator_pch.h", + "qtcreator_gui_pch.h", + ] + qbs.install: true + qbs.installDir: qtc.ide_shared_sources_path + } +} diff --git a/src/src.qbs b/src/src.qbs index 885bb6dd1a0..adc7055d216 100644 --- a/src/src.qbs +++ b/src/src.qbs @@ -13,6 +13,7 @@ Project { "tools/tools.qbs", project.sharedSourcesDir + "/json", project.sharedSourcesDir + "/proparser", + project.sharedSourcesDir + "/pch_files.qbs", ] property bool qbsSubModuleExists: File.exists(qbsProject.qbsBaseDir + "/qbs.qbs") diff --git a/src/tools/clangbackend/ipcsource/codecompleter.cpp b/src/tools/clangbackend/ipcsource/codecompleter.cpp index 436c6680524..4344a22aa93 100644 --- a/src/tools/clangbackend/ipcsource/codecompleter.cpp +++ b/src/tools/clangbackend/ipcsource/codecompleter.cpp @@ -68,8 +68,7 @@ CodeCompletions CodeCompleter::complete(uint line, uint column) translationUnit.cxUnsavedFiles(), translationUnit.unsavedFilesCount()); - if (results.hasNoResultsForDotCompletion() && hasDotAt(line, column - 1)) - results = completeWithArrowInsteadOfDot(line, column); + tryDotArrowCorrectionIfNoResults(results, line, column); return toCodeCompletions(results); } @@ -93,13 +92,6 @@ ClangCodeCompleteResults CodeCompleter::complete(uint line, defaultOptions()); } -bool CodeCompleter::hasDotAt(uint line, uint column) const -{ - const UnsavedFile &unsavedFile = translationUnit.unsavedFile(); - - return unsavedFile.hasCharacterAt(line, column, '.'); -} - uint CodeCompleter::defaultOptions() const { uint options = CXCodeComplete_IncludeMacros @@ -111,12 +103,25 @@ uint CodeCompleter::defaultOptions() const return options; } -ClangCodeCompleteResults CodeCompleter::completeWithArrowInsteadOfDot(uint line, uint column) +void CodeCompleter::tryDotArrowCorrectionIfNoResults(ClangCodeCompleteResults &results, + uint line, + uint column) +{ + if (results.hasNoResultsForDotCompletion()) { + const UnsavedFile &unsavedFile = translationUnit.unsavedFile(); + bool positionIsOk = false; + const uint dotPosition = unsavedFile.toUtf8Position(line, column - 1, &positionIsOk); + if (positionIsOk && unsavedFile.hasCharacterAt(dotPosition, '.')) + results = completeWithArrowInsteadOfDot(line, column, dotPosition); + } +} + +ClangCodeCompleteResults CodeCompleter::completeWithArrowInsteadOfDot(uint line, + uint column, + uint dotPosition) { ClangCodeCompleteResults results; - - const SourceLocation location = translationUnit.sourceLocationAtWithoutReparsing(line, column - 1); - const bool replaced = translationUnit.unsavedFile().replaceAt(location.offset(), + const bool replaced = translationUnit.unsavedFile().replaceAt(dotPosition, 1, Utf8StringLiteral("->")); diff --git a/src/tools/clangbackend/ipcsource/codecompleter.h b/src/tools/clangbackend/ipcsource/codecompleter.h index 313323a9d93..c859b2d02e2 100644 --- a/src/tools/clangbackend/ipcsource/codecompleter.h +++ b/src/tools/clangbackend/ipcsource/codecompleter.h @@ -45,18 +45,20 @@ public: CompletionCorrection neededCorrection() const; -public: // for tests - bool hasDotAt(uint line, uint column) const; - private: uint defaultOptions() const; + void tryDotArrowCorrectionIfNoResults(ClangCodeCompleteResults &results, + uint line, + uint column); + ClangCodeCompleteResults complete(uint line, uint column, CXUnsavedFile *unsavedFiles, unsigned unsavedFileCount); - - ClangCodeCompleteResults completeWithArrowInsteadOfDot(uint line, uint column); + ClangCodeCompleteResults completeWithArrowInsteadOfDot(uint line, + uint column, + uint dotPosition); Utf8String filePath() const; static void checkCodeCompleteResult(CXCodeCompleteResults *completeResults); diff --git a/src/tools/clangbackend/ipcsource/translationunits.cpp b/src/tools/clangbackend/ipcsource/translationunits.cpp index 5ec8be8810c..713c4e59755 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.cpp +++ b/src/tools/clangbackend/ipcsource/translationunits.cpp @@ -282,9 +282,10 @@ TranslationUnit TranslationUnits::createTranslationUnit(const FileContainer &fil void TranslationUnits::updateTranslationUnit(const FileContainer &fileContainer) { - auto findIterator = findAllTranslationUnitWithFilePath(fileContainer.filePath()); - if (findIterator != translationUnits_.end()) - findIterator->setDocumentRevision(fileContainer.documentRevision()); + const auto translationUnits = findAllTranslationUnitWithFilePath(fileContainer.filePath()); + + for (auto translationUnit : translationUnits) + translationUnit.setDocumentRevision(fileContainer.documentRevision()); } std::vector::iterator TranslationUnits::findTranslationUnit(const FileContainer &fileContainer) @@ -292,13 +293,19 @@ std::vector::iterator TranslationUnits::findTranslationUnit(con return std::find(translationUnits_.begin(), translationUnits_.end(), fileContainer); } -std::vector::iterator TranslationUnits::findAllTranslationUnitWithFilePath(const Utf8String &filePath) +std::vector TranslationUnits::findAllTranslationUnitWithFilePath(const Utf8String &filePath) { - auto filePathCompare = [&filePath] (const TranslationUnit &translationUnit) { + const auto filePathCompare = [&filePath] (const TranslationUnit &translationUnit) { return translationUnit.filePath() == filePath; }; - return std::find_if(translationUnits_.begin(), translationUnits_.end(), filePathCompare); + std::vector translationUnits; + std::copy_if(translationUnits_.begin(), + translationUnits_.end(), + std::back_inserter(translationUnits), + filePathCompare); + + return translationUnits; } std::vector::const_iterator TranslationUnits::findTranslationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const diff --git a/src/tools/clangbackend/ipcsource/translationunits.h b/src/tools/clangbackend/ipcsource/translationunits.h index d30ca982504..e8fea785bd8 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.h +++ b/src/tools/clangbackend/ipcsource/translationunits.h @@ -94,7 +94,7 @@ private: TranslationUnit createTranslationUnit(const FileContainer &fileContainer); void updateTranslationUnit(const FileContainer &fileContainer); std::vector::iterator findTranslationUnit(const FileContainer &fileContainer); - std::vector::iterator findAllTranslationUnitWithFilePath(const Utf8String &filePath); + std::vector findAllTranslationUnitWithFilePath(const Utf8String &filePath); std::vector::const_iterator findTranslationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const; bool hasTranslationUnit(const FileContainer &fileContainer) const; bool hasTranslationUnitWithFilePath(const Utf8String &filePath) const; diff --git a/src/tools/clangbackend/ipcsource/unsavedfile.cpp b/src/tools/clangbackend/ipcsource/unsavedfile.cpp index a4d6f0fb82d..16d6638e8a5 100644 --- a/src/tools/clangbackend/ipcsource/unsavedfile.cpp +++ b/src/tools/clangbackend/ipcsource/unsavedfile.cpp @@ -71,15 +71,24 @@ const char *UnsavedFile::filePath() const return cxUnsavedFile.Filename; } -bool UnsavedFile::hasCharacterAt(uint line, uint column, char character) const +uint UnsavedFile::toUtf8Position(uint line, uint column, bool *ok) const { Utf8PositionFromLineColumn converter(cxUnsavedFile.Contents); if (converter.find(line, column)) { - const uint utf8Position = converter.position(); - return hasCharacterAt(utf8Position, character); + *ok = true; + return converter.position(); } - return false; + *ok = false; + return 0; +} + +bool UnsavedFile::hasCharacterAt(uint line, uint column, char character) const +{ + bool positionIsOk = false; + const uint utf8Position = toUtf8Position(line, column, &positionIsOk); + + return positionIsOk && hasCharacterAt(utf8Position, character); } bool UnsavedFile::hasCharacterAt(uint position, char character) const @@ -118,11 +127,16 @@ UnsavedFile::~UnsavedFile() cxUnsavedFile.Length = 0; } +static const char *printCString(const char *str) +{ + return str ? str : "nullptr"; +} + void PrintTo(const UnsavedFile &unsavedFile, std::ostream *os) { *os << "UnsavedFile(" - << unsavedFile.cxUnsavedFile.Filename << ", " - << unsavedFile.cxUnsavedFile.Contents << ", " + << printCString(unsavedFile.cxUnsavedFile.Filename) << ", " + << printCString(unsavedFile.cxUnsavedFile.Contents) << ", " << unsavedFile.cxUnsavedFile.Length << ")"; } diff --git a/src/tools/clangbackend/ipcsource/unsavedfile.h b/src/tools/clangbackend/ipcsource/unsavedfile.h index 3433093ae15..dcd4fd026b1 100644 --- a/src/tools/clangbackend/ipcsource/unsavedfile.h +++ b/src/tools/clangbackend/ipcsource/unsavedfile.h @@ -55,6 +55,7 @@ public: const char *filePath() const; // 1-based line and column + uint toUtf8Position(uint line, uint column, bool *ok) const; bool hasCharacterAt(uint line, uint column, char character) const; bool hasCharacterAt(uint position, char character) const; bool replaceAt(uint position, uint length, const Utf8String &replacement); diff --git a/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp b/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp index 7281f7e06a8..01b92352a71 100644 --- a/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp +++ b/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp @@ -139,14 +139,16 @@ void tst_PluginManager::getObject() const QString objectName = QLatin1String("OBJECTNAME"); object2b->setObjectName(objectName); m_pm->addObject(object2); - QCOMPARE(m_pm->getObject(), (MyClass11*)0); - QCOMPARE(m_pm->getObject(), (MyClass1*)0); + QCOMPARE(m_pm->getObject(), static_cast(0)); + QCOMPARE(m_pm->getObjectByClassName("MyClass11"), static_cast(0)); + QCOMPARE(m_pm->getObject(), static_cast(0)); QCOMPARE(m_pm->getObject(), object2); + QCOMPARE(m_pm->getObjectByClassName("MyClass2"), object2); m_pm->addObject(object11); QCOMPARE(m_pm->getObject(), object11); - QCOMPARE(m_pm->getObject(), qobject_cast(object11)); + QCOMPARE(m_pm->getObject(), qobject_cast(object11)); QCOMPARE(m_pm->getObject(), object2); - QCOMPARE(m_pm->getObjectByName(objectName), (QObject*)0); + QCOMPARE(m_pm->getObjectByName(objectName), static_cast(0)); m_pm->addObject(object2b); QCOMPARE(m_pm->getObjectByName(objectName), object2b); QCOMPARE(m_pm->getObject( @@ -203,14 +205,14 @@ void tst_PluginManager::circularPlugins() if (spec->name() == "plugin1") { QVERIFY(spec->hasError()); QCOMPARE(spec->state(), PluginSpec::Resolved); - QCOMPARE(spec->plugin(), (IPlugin*)0); + QCOMPARE(spec->plugin(), static_cast(0)); } else if (spec->name() == "plugin2") { QVERIFY2(!spec->hasError(), qPrintable(spec->errorString())); QCOMPARE(spec->state(), PluginSpec::Running); } else if (spec->name() == "plugin3") { QVERIFY(spec->hasError()); QCOMPARE(spec->state(), PluginSpec::Resolved); - QCOMPARE(spec->plugin(), (IPlugin*)0); + QCOMPARE(spec->plugin(), static_cast(0)); } } } diff --git a/tests/auto/utils/treemodel/tst_treemodel.cpp b/tests/auto/utils/treemodel/tst_treemodel.cpp index 15dbc257038..974294d8e11 100644 --- a/tests/auto/utils/treemodel/tst_treemodel.cpp +++ b/tests/auto/utils/treemodel/tst_treemodel.cpp @@ -95,7 +95,7 @@ struct ItemB : public TreeItem {}; void tst_TreeModel::testMixed() { - LeveledTreeModel m; + LeveledTreeModel m; TreeItem *r = m.rootItem(); TreeItem *ra; r->appendChild(new ItemA); diff --git a/tests/unit/unittest/codecompletiontest.cpp b/tests/unit/unittest/codecompletiontest.cpp index a370f935867..c25b03a492a 100644 --- a/tests/unit/unittest/codecompletiontest.cpp +++ b/tests/unit/unittest/codecompletiontest.cpp @@ -112,6 +112,19 @@ protected: readFileContent(QStringLiteral("/complete_withDotArrowCorrectionForPointer.cpp")), true }; + ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerBeforeTyping{ + Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), + projectPart.projectPartId(), + readFileContent(QStringLiteral("/complete_withDotArrowCorrectionForPointer_beforeTyping.cpp")), + true + }; + ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerAfterTyping{ + Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), + projectPart.projectPartId(), + readFileContent(QStringLiteral("/complete_withDotArrowCorrectionForPointer_afterTyping.cpp")), + true + }; + ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerInitial{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), projectPart.projectPartId(), @@ -313,30 +326,6 @@ TEST_F(CodeCompleter, ArrowCompletion) ClangBackEnd::CompletionCorrection::NoCorrection); } -TEST_F(CodeCompleter, HasDotAt) -{ - auto myCompleter = setupCompleter(dotArrowCorrectionForPointerFileContainer); - - ASSERT_TRUE(myCompleter.hasDotAt(5, 8)); -} - -TEST_F(CodeCompleter, HasDotAtWithUpdatedUnsavedFile) -{ - auto myCompleter = setupCompleter(dotArrowCorrectionForPointerFileContainerInitial); - unsavedFiles.createOrUpdate({dotArrowCorrectionForPointerFileContainerUpdated}); - - ASSERT_TRUE(myCompleter.hasDotAt(5, 8)); -} - -TEST_F(CodeCompleter, HasNoDotAtDueToMissingUnsavedFile) -{ - const ClangBackEnd::FileContainer fileContainer = dotArrowCorrectionForPointerFileContainer; - translationUnits.create({fileContainer}); - ClangBackEnd::CodeCompleter myCompleter(translationUnits.translationUnit(fileContainer)); - - ASSERT_FALSE(myCompleter.hasDotAt(5, 8)); -} - TEST_F(CodeCompleter, DotToArrowCompletionForPointer) { auto myCompleter = setupCompleter(dotArrowCorrectionForPointerFileContainer); @@ -350,6 +339,24 @@ TEST_F(CodeCompleter, DotToArrowCompletionForPointer) ClangBackEnd::CompletionCorrection::DotToArrowCorrection); } +TEST_F(CodeCompleter, DotToArrowCompletionForPointerInOutdatedTranslationUnit) +{ + auto fileContainerBeforeTyping = dotArrowCorrectionForPointerFileContainerBeforeTyping; + auto myCompleter = setupCompleter(fileContainerBeforeTyping); + auto translationUnit = translationUnits.translationUnit(fileContainerBeforeTyping.filePath(), + fileContainerBeforeTyping.projectPartId()); + translationUnit.cxTranslationUnit(); // Parse + unsavedFiles.createOrUpdate({dotArrowCorrectionForPointerFileContainerAfterTyping}); + + const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 9); + + ASSERT_THAT(completions, + Contains(IsCodeCompletion(Utf8StringLiteral("member"), + CodeCompletion::VariableCompletionKind))); + ASSERT_THAT(myCompleter.neededCorrection(), + ClangBackEnd::CompletionCorrection::DotToArrowCorrection); +} + TEST_F(CodeCompleter, NoDotToArrowCompletionForObject) { auto myCompleter = setupCompleter(noDotArrowCorrectionForObjectFileContainer); diff --git a/tests/unit/unittest/data/complete_withDotArrowCorrectionForPointer_afterTyping.cpp b/tests/unit/unittest/data/complete_withDotArrowCorrectionForPointer_afterTyping.cpp new file mode 100644 index 00000000000..9f8d3645b2e --- /dev/null +++ b/tests/unit/unittest/data/complete_withDotArrowCorrectionForPointer_afterTyping.cpp @@ -0,0 +1,6 @@ +struct Foo { int member; }; + +void g(Foo *foo) +{ + foo. +} diff --git a/tests/unit/unittest/data/complete_withDotArrowCorrectionForPointer_beforeTyping.cpp b/tests/unit/unittest/data/complete_withDotArrowCorrectionForPointer_beforeTyping.cpp new file mode 100644 index 00000000000..0472cfacaa4 --- /dev/null +++ b/tests/unit/unittest/data/complete_withDotArrowCorrectionForPointer_beforeTyping.cpp @@ -0,0 +1,6 @@ +struct Foo { int member; }; + +void g(Foo *foo) +{ + +} diff --git a/tests/unit/unittest/data/diagnostic_diagnostic.cpp b/tests/unit/unittest/data/diagnostic_diagnostic.cpp index a1525b85d51..51423c20b51 100644 --- a/tests/unit/unittest/data/diagnostic_diagnostic.cpp +++ b/tests/unit/unittest/data/diagnostic_diagnostic.cpp @@ -1,10 +1,8 @@ -class X { - X(X&&) noexcept; -}; - -X::X(X&&) = default; - -int function() +int noReturnValue() { } +void f(int) +{ + f(); +} diff --git a/tests/unit/unittest/diagnostictest.cpp b/tests/unit/unittest/diagnostictest.cpp index 822b473859f..314c76c9336 100644 --- a/tests/unit/unittest/diagnostictest.cpp +++ b/tests/unit/unittest/diagnostictest.cpp @@ -91,7 +91,7 @@ protected: Utf8StringVector(), translationUnits}; DiagnosticSet diagnosticSet{translationUnit.diagnostics()}; - ::Diagnostic diagnostic{diagnosticSet.back()}; + ::Diagnostic diagnostic{diagnosticSet.front()}; protected: enum ChildMode { WithChild, WithoutChild }; @@ -149,23 +149,23 @@ TEST_F(Diagnostic, Severity) TEST_F(Diagnostic, ChildDiagnosticsSize) { - auto diagnostic = diagnosticSet.front(); + auto diagnostic = diagnosticSet.back(); ASSERT_THAT(diagnostic.childDiagnostics().size(), 1); } TEST_F(Diagnostic, ChildDiagnosticsText) { - auto childDiagnostic = diagnosticSet.front().childDiagnostics().front(); + auto childDiagnostic = diagnosticSet.back().childDiagnostics().front(); - ASSERT_THAT(childDiagnostic.text(), Utf8StringLiteral("note: previous declaration is here")); + ASSERT_THAT(childDiagnostic.text(), Utf8StringLiteral("note: candidate function not viable: requires 1 argument, but 0 were provided")); } TEST_F(Diagnostic, toDiagnosticContainerLetChildrenThroughByDefault) { const auto diagnosticWithChild = expectedDiagnostic(WithChild); - const auto diagnostic = diagnosticSet.front().toDiagnosticContainer(); + const auto diagnostic = diagnosticSet.back().toDiagnosticContainer(); ASSERT_THAT(diagnostic, IsDiagnosticContainer(diagnosticWithChild)); } @@ -175,11 +175,11 @@ DiagnosticContainer Diagnostic::expectedDiagnostic(Diagnostic::ChildMode childMo QVector children; if (childMode == WithChild) { const auto child = DiagnosticContainer( - Utf8StringLiteral("note: previous declaration is here"), + Utf8StringLiteral("note: candidate function not viable: requires 1 argument, but 0 were provided"), Utf8StringLiteral("Semantic Issue"), {Utf8String(), Utf8String()}, ClangBackEnd::DiagnosticSeverity::Note, - SourceLocationContainer(translationUnit.filePath(), 2, 5), + SourceLocationContainer(translationUnit.filePath(), 5, 6), {}, {}, {} @@ -189,11 +189,11 @@ DiagnosticContainer Diagnostic::expectedDiagnostic(Diagnostic::ChildMode childMo return DiagnosticContainer( - Utf8StringLiteral("warning: 'X' is missing exception specification 'noexcept'"), + Utf8StringLiteral("error: no matching function for call to 'f'"), Utf8StringLiteral("Semantic Issue"), {Utf8String(), Utf8String()}, - ClangBackEnd::DiagnosticSeverity::Warning, - SourceLocationContainer(translationUnit.filePath(), 5, 4), + ClangBackEnd::DiagnosticSeverity::Error, + SourceLocationContainer(translationUnit.filePath(), 7, 5), {}, {}, children diff --git a/tests/unit/unittest/translationunitstest.cpp b/tests/unit/unittest/translationunitstest.cpp index 94599b0a222..220cb81a178 100644 --- a/tests/unit/unittest/translationunitstest.cpp +++ b/tests/unit/unittest/translationunitstest.cpp @@ -99,6 +99,7 @@ protected: const Utf8String headerPath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.h"); const Utf8String nonExistingFilePath = Utf8StringLiteral("foo.cpp"); const Utf8String projectPartId = Utf8StringLiteral("projectPartId"); + const Utf8String otherProjectPartId = Utf8StringLiteral("otherProjectPartId"); const Utf8String nonExistingProjectPartId = Utf8StringLiteral("nonExistingProjectPartId"); const ClangBackEnd::FileContainer fileContainer{filePath, projectPartId}; const ClangBackEnd::FileContainer headerContainer{headerPath, projectPartId}; @@ -178,7 +179,7 @@ TEST_F(TranslationUnits, ThrowForUpdatingANonExistingTranslationUnit) ClangBackEnd::TranslationUnitDoesNotExistException); } -TEST_F(TranslationUnits, Update) +TEST_F(TranslationUnits, UpdateSingle) { ClangBackEnd::FileContainer createFileContainer(filePath, projectPartId, Utf8StringVector(), 74u); ClangBackEnd::FileContainer updateFileContainer(filePath, Utf8String(), Utf8StringVector(), 75u); @@ -190,6 +191,21 @@ TEST_F(TranslationUnits, Update) IsTranslationUnit(filePath, projectPartId, 75u)); } +TEST_F(TranslationUnits, UpdateMultiple) +{ + ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer fileContainerWithOtherProject(filePath, otherProjectPartId, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer updatedFileContainer(filePath, Utf8String(), Utf8StringVector(), 75u); + translationUnits.create({fileContainer, fileContainerWithOtherProject}); + + translationUnits.update({updatedFileContainer}); + + ASSERT_THAT(translationUnits.translationUnit(filePath, projectPartId), + IsTranslationUnit(filePath, projectPartId, 75u)); + ASSERT_THAT(translationUnits.translationUnit(filePath, otherProjectPartId), + IsTranslationUnit(filePath, otherProjectPartId, 75u)); +} + TEST_F(TranslationUnits, UpdateUnsavedFileAndCheckForReparse) { ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, Utf8StringVector(), 74u); @@ -509,6 +525,7 @@ TEST_F(TranslationUnits, SendDocumentAnnotationsAfterProjectPartChange) void TranslationUnits::SetUp() { projects.createOrUpdate({ProjectPartContainer(projectPartId)}); + projects.createOrUpdate({ProjectPartContainer(otherProjectPartId)}); auto callback = [&] (const DiagnosticsChangedMessage &, const HighlightingChangedMessage &) { mockSendDocumentAnnotationsCallback.sendDocumentAnnotations(); diff --git a/tests/unit/unittest/unsavedfiletest.cpp b/tests/unit/unittest/unsavedfiletest.cpp index 3f0ae6d90b1..463c29be8b3 100644 --- a/tests/unit/unittest/unsavedfiletest.cpp +++ b/tests/unit/unittest/unsavedfiletest.cpp @@ -34,6 +34,7 @@ using ClangBackEnd::UnsavedFile; using ClangBackEnd::UnsavedFiles; +using ::testing::Eq; using ::testing::PrintToString; namespace { @@ -150,6 +151,44 @@ TEST_F(UnsavedFile, Replace) ASSERT_THAT(unsavedFile, IsUnsavedFile(filePath, expectedContent, expectedContent.byteSize())); } +TEST_F(UnsavedFile, ToUtf8PositionForValidLineColumn) +{ + ::UnsavedFile unsavedFile(filePath, fileContent); + bool ok = false; + + const uint position = unsavedFile.toUtf8Position(1, 1, &ok); + + ASSERT_TRUE(ok); + ASSERT_THAT(position, Eq(0)); +} + +TEST_F(UnsavedFile, ToUtf8PositionForInValidLineColumn) +{ + ::UnsavedFile unsavedFile(filePath, fileContent); + bool ok = false; + + unsavedFile.toUtf8Position(2, 1, &ok); + + ASSERT_FALSE(ok); +} + +TEST_F(UnsavedFile, ToUtf8PositionForDefaultConstructedUnsavedFile) +{ + ::UnsavedFile unsavedFile; + bool ok = false; + + unsavedFile.toUtf8Position(1, 1, &ok); + + ASSERT_FALSE(ok); +} + +TEST_F(UnsavedFile, HasNoCharacterForDefaultConstructedUnsavedFile) +{ + ::UnsavedFile unsavedFile; + + ASSERT_FALSE(unsavedFile.hasCharacterAt(0, 'x')); +} + TEST_F(UnsavedFile, HasNoCharacterForTooBigOffset) { ::UnsavedFile unsavedFile(filePath, fileContent);