From b0320387817ab0b4f8c4edfa258414b72bfdb105 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 21 Jun 2016 15:43:08 +0200 Subject: [PATCH 01/69] Clang: Tests: Use test data working with clang 3.6 *and* clang 3.8 The test data produces different results when it is run with libclang 3.6 and libclang 3.8. (lib)clang 3.8 will generate an error instead of a warning and suppress further diagnostics. See below. Use simpler test data that is agnostic to the different clang versions. $ cat input.cpp class X { X(X&&) noexcept; }; X::X(X&&) = default; int function() { } $ clang++-3.6 -fsyntax-only -std=c++11 input.cpp input.cpp:5:4: warning: 'X' is missing exception specification 'noexcept' X::X(X&&) = default; ^ noexcept input.cpp:2:5: note: previous declaration is here X(X&&) noexcept; ^ input.cpp:9:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ 2 warnings generated. $ clang++-3.8 -fsyntax-only -std=c++11 input.cpp input.cpp:5:4: error: 'X' is missing exception specification 'noexcept' X::X(X&&) = default; ^ noexcept input.cpp:2:5: note: previous declaration is here X(X&&) noexcept; ^ 1 error generated. Change-Id: I6d786a8b87eb4438fa8db36540db9358181b9a5b Reviewed-by: David Schulz --- .../unittest/data/diagnostic_diagnostic.cpp | 12 +++++------ tests/unit/unittest/diagnostictest.cpp | 20 +++++++++---------- 2 files changed, 15 insertions(+), 17 deletions(-) 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 From 5a11d5cd5ba46c7b077e470fa0be07ed1adc758a Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Mon, 20 Jun 2016 14:36:52 +0200 Subject: [PATCH 02/69] QmlDesigner: use initializer lists Change-Id: Ie93861c7d8a5b2863ec8b111afceacc2c163715b Reviewed-by: Thomas Hartmann --- .../instances/behaviornodeinstance.cpp | 2 +- .../instances/layoutnodeinstance.cpp | 3 ++- .../instances/positionernodeinstance.cpp | 6 +++--- .../instances/qmltransitionnodeinstance.cpp | 3 ++- .../instances/quickitemnodeinstance.cpp | 18 +++++++++--------- .../components/formeditor/formeditorview.cpp | 2 +- .../instances/nodeinstanceview.cpp | 4 ++-- .../designercore/metainfo/nodemetainfo.cpp | 8 ++++---- .../qmldesigner/designercore/model/model.cpp | 4 ++-- .../designercore/model/qmlanchors.cpp | 12 ++++++------ 10 files changed, 32 insertions(+), 30 deletions(-) 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/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/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(); From 18e5dabd72b4cf1f250c13f4c3ad2d2a1a0d5ec4 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Tue, 21 Jun 2016 10:04:50 +0200 Subject: [PATCH 03/69] QmlDesigner: add workaround for broken tooltip calls Change-Id: I2315ad0ebdaca5399e6080a12852f7118399654e Reviewed-by: Thomas Hartmann --- .../propertyEditorQmlSources/HelperWidgets/Label.qml | 2 ++ 1 file changed, 2 insertions(+) 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" From d21c90983bd5f70eb5ed0d4d3f221a77d3034f58 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Tue, 21 Jun 2016 11:17:31 +0200 Subject: [PATCH 04/69] QmlDesinger: remove QtQuick 1 items Change-Id: I439e3bacbe8bde7a82194e247bcb47dff926bcc2 Reviewed-by: Thomas Hartmann --- .../qmldesigner/qtquickplugin/quick.metainfo | 197 ------------------ 1 file changed, 197 deletions(-) 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" From 9271770c645203bdcfac006fc6e82dd4bffc71a0 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Tue, 21 Jun 2016 11:18:10 +0200 Subject: [PATCH 05/69] QmlDesigner: show output for valid items Change-Id: I1de98626ff9f2b3cac594bf9a0f802623c16ce90 Reviewed-by: Thomas Hartmann --- .../qmldesigner/components/itemlibrary/itemlibrarymodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); From 5dd8e7214a5bd486f5fbe087da6726058eaeb60c Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Tue, 21 Jun 2016 13:34:32 +0200 Subject: [PATCH 06/69] QmlDesigner: fix url Problem was that a file added to resource it wasn't shown in the canvas. Change-Id: I57610db8a55791c409bd249d698bf757cde153b9 Reviewed-by: Thomas Hartmann --- share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.cpp | 2 +- .../qml/qmlpuppet/qmlprivategate/qmlprivategate_56.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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); } } } From 4cc69911e930ff9006b55aff580991fffa08ada3 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Tue, 21 Jun 2016 13:35:17 +0200 Subject: [PATCH 07/69] QmlDesigner: refactor populateQrcMapping no behavior change Change-Id: If932cb51b4179a1f79824f9b6660bf45db1e8aee Reviewed-by: Thomas Hartmann --- .../designercore/model/texttomodelmerger.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 4dabb596c13..f4f19553698 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -1943,20 +1943,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)); } } From 5838874b1d1f10fb027d8f923e84b24675918a37 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 22 Jun 2016 13:03:00 +0200 Subject: [PATCH 08/69] Plugin Tests: Make 'all' override previous args, and give sensible order If you write "all" it should mean "all", and "load" order makes more sense than "alphabetic". Change-Id: If90b665d714efaf0919ad418fbbe02c50a0fced2 Reviewed-by: Christian Stenger Reviewed-by: Nikolai Kosjar --- src/libs/extensionsystem/optionsparser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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(); From adae324abaa55b0434f9e5a2fb70771b7dbc0190 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 21 Jun 2016 18:01:42 +0200 Subject: [PATCH 09/69] QmlDesigner: Adding tooltip for canvas color Task-number: QTCREATORBUG-14819 Change-Id: I0929f899e84e6bc5415d8c699fc4df53a2fe561b Reviewed-by: Leena Miettinen --- .../qmldesigner/components/formeditor/backgroundaction.cpp | 1 + 1 file changed, 1 insertion(+) 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; } From d04f1036025a9f5d35d5a49bbc5c82114b2331c3 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 22 Jun 2016 12:24:03 +0200 Subject: [PATCH 10/69] QtQuickDesigner: QML Design Mode > Design Mode Change-Id: I1756704b4121fb8d60b9e895413ce4f7b0069551 Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/qmldesignerplugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 5140bd31ff0..a656f85a7c1 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -99,7 +99,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); } From add38283897f598478fb750d026bb90bb58f74b1 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 21 Jun 2016 18:33:15 +0200 Subject: [PATCH 11/69] QmlJSEditor: Do not allow child items for states Task-number: QTCREATORBUG-13003 Change-Id: I30bcee12803d2b3af804625ffdf417316e3d6c32 Reviewed-by: Tim Jenssen --- src/libs/qmljs/qmljscheck.cpp | 3 +++ src/libs/qmljs/qmljsstaticanalysismessage.cpp | 2 ++ src/libs/qmljs/qmljsstaticanalysismessage.h | 1 + 3 files changed, 6 insertions(+) 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/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, From 8eeb657e75f1ed5ccbe0862fe935c9a4a9bffd90 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 21 Jun 2016 18:15:58 +0200 Subject: [PATCH 12/69] QmlDesigner: Adding tool tips for anchoring Task-number: QTCREATORBUG-13503 Change-Id: I2c65e47797ba77d3cc2e5b2c6723b1c010982d8f Reviewed-by: Tim Jenssen Reviewed-by: Leena Miettinen --- .../HelperWidgets/AnchorButtons.qml | 7 +++++++ .../propertyEditorQmlSources/QtQuick/AnchorRow.qml | 3 +++ 2 files changed, 10 insertions(+) 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/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(); From 3fb0dc379a005ee8b046d295adb6457e591cc7d1 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 21 Jun 2016 18:01:26 +0200 Subject: [PATCH 13/69] QmlDesigner: Use correct overload of QGraphicsScene:items QGraphicsScene:items() is deprecated and returns incorrect results if the scene contains items that ignore transformations. We have to use the overload that takes a QTransform instead and define itemsAt for convenience. Task-number: QTBUG-49627 Change-Id: I388c62dd23a61c569ec6b99d756f4fbe1024e5db Reviewed-by: Tim Jenssen --- .../components/formeditor/formeditorscene.cpp | 31 +++++++++++++------ .../components/formeditor/formeditorscene.h | 1 + 2 files changed, 23 insertions(+), 9 deletions(-) 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*); From e31a389b0f1918424403abc8340d7dd7e1b215dd Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 21 Jun 2016 16:10:32 +0200 Subject: [PATCH 14/69] QmlDesigner: Ignore semantic checks in form editor Those checks are slow and not required for moving and resizing. Change-Id: If9ad047cf2401d39f729134beb813e095ef96abd Reviewed-by: Tim Jenssen --- .../qmldesigner/components/formeditor/movemanipulator.cpp | 3 ++- .../qmldesigner/components/formeditor/resizemanipulator.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) 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()); From 9410a812b9ae045c69d9d015e814f43f8d12da02 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 21 Jun 2016 16:09:59 +0200 Subject: [PATCH 15/69] QmlDesigner: Allow to disable semantic checks in transaction The semantic checks are slow and sometimes we knoe that they are not required. Change-Id: I43cae131e4c5f47d2a61d34975913dd8cb6370fc Reviewed-by: Tim Jenssen --- .../qmldesigner/designercore/rewritertransaction.cpp | 11 +++++++++++ .../qmldesigner/designercore/rewritertransaction.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/src/plugins/qmldesigner/designercore/rewritertransaction.cpp b/src/plugins/qmldesigner/designercore/rewritertransaction.cpp index bb1429eaec2..ff3a07223dc 100644 --- a/src/plugins/qmldesigner/designercore/rewritertransaction.cpp +++ b/src/plugins/qmldesigner/designercore/rewritertransaction.cpp @@ -72,12 +72,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 From a073cbe214477b9c784818308aef770bd94a49ca Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 21 Jun 2016 16:09:10 +0200 Subject: [PATCH 16/69] QmlDesigner: Adding logging category to TextToModelMerger This allows some easy benchmarking. Change-Id: Ib9e16542870d0fc47fc2a0441311020730b79203 Reviewed-by: Tim Jenssen --- .../designercore/model/texttomodelmerger.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index f4f19553698..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) { From 438bd85b849fcf97e005e72bf21ada09c6f204d8 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 6 Jun 2016 12:32:45 +0200 Subject: [PATCH 17/69] Clang: Fix updating revision number for all translation units Change-Id: I1ad305ed081aecadde968e041f7b99a24a1c4784 Reviewed-by: Marco Bubke Reviewed-by: David Schulz Reviewed-by: Nikolai Kosjar --- .../ipcsource/translationunits.cpp | 19 +++++++++++++------ .../clangbackend/ipcsource/translationunits.h | 2 +- tests/unit/unittest/translationunitstest.cpp | 19 ++++++++++++++++++- 3 files changed, 32 insertions(+), 8 deletions(-) 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/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(); From 73dbcb49fdefd14c68ec8933805f167fd3f36491 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 23 Jun 2016 09:08:23 +0200 Subject: [PATCH 18/69] QmlDesigner: Fix build (missing include) rewritertransaction.cpp:84:56: error: invalid use of incomplete type 'class QmlDesigner::RewriterView' Change-Id: Ibbd757ef99a75633337722caa54630baba929cc6 Reviewed-by: Orgad Shaneh --- src/plugins/qmldesigner/designercore/rewritertransaction.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/qmldesigner/designercore/rewritertransaction.cpp b/src/plugins/qmldesigner/designercore/rewritertransaction.cpp index ff3a07223dc..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 From b9bd611e25d5761a476c39a79e008119ce0f54a1 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 22 Jun 2016 13:44:19 +0200 Subject: [PATCH 19/69] PluginView: Functional style dependency list creation Change-Id: I08c6aeb8be55e73a9d8e55e264046afc19c9e4b9 Reviewed-by: Tobias Hunger --- .../extensionsystem/plugindetailsview.cpp | 21 +++---------------- src/libs/extensionsystem/pluginspec.cpp | 17 +++++++++++++++ src/libs/extensionsystem/pluginspec.h | 1 + 3 files changed, 21 insertions(+), 18 deletions(-) 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/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index b7cd3d9777f..782d3e31150 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -146,6 +146,23 @@ 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::Required: + return QString(); + case PluginDependency::Optional: + return ", optional"; + case PluginDependency::Test: + return ", test"; + } +} + +QString PluginDependency::toString() const +{ + return name + " (" + version + typeString(type) + ")"; +} + /*! \internal */ diff --git a/src/libs/extensionsystem/pluginspec.h b/src/libs/extensionsystem/pluginspec.h index 7d41c911583..bc0fc43a4d1 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); From eeb1a8fe58cef1995b7293e39baf8a6c30e08b24 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 21 Jun 2016 16:15:25 +0200 Subject: [PATCH 20/69] AutoTest: Use json based wizard Change-Id: I75693037542ef64bcc094e092086dea65d77872c Reviewed-by: Tobias Hunger --- .../templates/wizards/autotest/auto.pro | 2 +- .../templates/wizards/autotest/main.cpp | 11 +- .../templates/wizards/autotest/src.pro | 6 +- .../templates/wizards/autotest/tmp.pro | 2 +- .../templates/wizards/autotest/tst.pro | 4 +- .../templates/wizards/autotest/tst_src.cpp | 34 ++-- .../templates/wizards/autotest/wizard.json | 168 ++++++++++++++++++ .../templates/wizards/autotest/wizard.xml | 83 --------- 8 files changed, 200 insertions(+), 110 deletions(-) create mode 100644 share/qtcreator/templates/wizards/autotest/wizard.json delete mode 100644 share/qtcreator/templates/wizards/autotest/wizard.xml diff --git a/share/qtcreator/templates/wizards/autotest/auto.pro b/share/qtcreator/templates/wizards/autotest/auto.pro index b39fef654c3..510a3710068 100644 --- a/share/qtcreator/templates/wizards/autotest/auto.pro +++ b/share/qtcreator/templates/wizards/autotest/auto.pro @@ -1,3 +1,3 @@ TEMPLATE = subdirs -SUBDIRS += %TestCaseName:l% +SUBDIRS += %{JS: '%{TestCaseName}'.toLowerCase()} diff --git a/share/qtcreator/templates/wizards/autotest/main.cpp b/share/qtcreator/templates/wizards/autotest/main.cpp index 3ff500decd6..2eb09afb0dc 100644 --- a/share/qtcreator/templates/wizards/autotest/main.cpp +++ b/share/qtcreator/templates/wizards/autotest/main.cpp @@ -1,14 +1,17 @@ -@if "%RequireGUI%" == "true" -#include +%{Cpp:LicenseTemplate}\ +@if "%{RequireGUI}" == "true" +%{JS: QtSupport.qtIncludes([ 'QtGui/QApplication' ], + [ 'QtWidgets/QApplication' ]) }\ @else -#include +%{JS: QtSupport.qtIncludes([ 'QtCore/QCoreApplication' ], + [ 'QtCore/QCoreApplication' ]) }\ @endif // add necessary includes here int main(int argc, char *argv[]) { -@if "%RequireGUI%" == "true" +@if "%{RequireGUI}" == "true" QApplication a(argc, argv); @else QCoreApplication a(argc, argv); diff --git a/share/qtcreator/templates/wizards/autotest/src.pro b/share/qtcreator/templates/wizards/autotest/src.pro index 61fbe2a5bcf..3cbad0593f8 100644 --- a/share/qtcreator/templates/wizards/autotest/src.pro +++ b/share/qtcreator/templates/wizards/autotest/src.pro @@ -1,4 +1,4 @@ -@if "%RequireGUI%" == "true" +@if "%{RequireGUI}" == "true" QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @else @@ -8,6 +8,6 @@ CONFIG -= app_bundle @endif TEMPLATE = app -TARGET = %ProjectName% +TARGET = %{ProjectName} -SOURCES += main.%CppSourceSuffix% +SOURCES += %{MainCppName} diff --git a/share/qtcreator/templates/wizards/autotest/tmp.pro b/share/qtcreator/templates/wizards/autotest/tmp.pro index 1569bd45cb7..c64e8c288c8 100644 --- a/share/qtcreator/templates/wizards/autotest/tmp.pro +++ b/share/qtcreator/templates/wizards/autotest/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/tst.pro b/share/qtcreator/templates/wizards/autotest/tst.pro index 8aa61b767e7..f58c30fd8ea 100644 --- a/share/qtcreator/templates/wizards/autotest/tst.pro +++ b/share/qtcreator/templates/wizards/autotest/tst.pro @@ -1,5 +1,5 @@ QT += testlib -@if "%RequireGUI%" == "false" +@if "%{RequireGUI}" == "false" QT -= gui CONFIG += qt console warn_on depend_includepath testcase @@ -11,4 +11,4 @@ CONFIG += qt warn_on depend_includepath testcase TEMPLATE = app -SOURCES += tst_%TestCaseName:l%.%CppSourceSuffix% +SOURCES += %{TestCaseFileWithCppSuffix} diff --git a/share/qtcreator/templates/wizards/autotest/tst_src.cpp b/share/qtcreator/templates/wizards/autotest/tst_src.cpp index 65d49e9c18a..54a68264d2d 100644 --- a/share/qtcreator/templates/wizards/autotest/tst_src.cpp +++ b/share/qtcreator/templates/wizards/autotest/tst_src.cpp @@ -1,20 +1,22 @@ +%{Cpp:LicenseTemplate}\ #include -@if "%RequireApplication%" == "true" -#include +@if "%{RequireApplication}" == "true" +%{JS: QtSupport.qtIncludes([ 'QtCore/QCoreApplication' ], + [ 'QtCore/QCoreApplication' ]) }\ @endif // add necessary includes here -class %TestCaseName% : public QObject +class %{TestCaseName} : public QObject { Q_OBJECT public: - %TestCaseName%(); - ~%TestCaseName%(); + %{TestCaseName}(); + ~%{TestCaseName}(); private slots: -@if "%GenerateInitAndCleanup%" == "true" +@if "%{GenerateInitAndCleanup}" == "true" void initTestCase(); void cleanupTestCase(); @endif @@ -22,37 +24,37 @@ private slots: }; -%TestCaseName%::%TestCaseName%() +%{TestCaseName}::%{TestCaseName}() { } -%TestCaseName%::~%TestCaseName%() +%{TestCaseName}::~%{TestCaseName}() { } -@if "%GenerateInitAndCleanup%" == "true" -void %TestCaseName%::initTestCase() +@if "%{GenerateInitAndCleanup}" == "true" +void %{TestCaseName}::initTestCase() { } -void %TestCaseName%::cleanupTestCase() +void %{TestCaseName}::cleanupTestCase() { } @endif -void %TestCaseName%::test_case1() +void %{TestCaseName}::test_case1() { } -@if "%RequireApplication%" == "true" -QTEST_MAIN(%TestCaseName%) +@if "%{RequireApplication}" == "true" +QTEST_MAIN(%{TestCaseName}) @else -QTEST_APPLESS_MAIN(%TestCaseName%) +QTEST_APPLESS_MAIN(%{TestCaseName}) @endif -#include "tst_%TestCaseName:l%.moc" +#include "%{JS: 'tst_%{TestCaseName}.moc'.toLowerCase() }" diff --git a/share/qtcreator/templates/wizards/autotest/wizard.json b/share/qtcreator/templates/wizards/autotest/wizard.json new file mode 100644 index 00000000000..16f318aa574 --- /dev/null +++ b/share/qtcreator/templates/wizards/autotest/wizard.json @@ -0,0 +1,168 @@ +{ + "version": 1, + "supportedProjectTypes": [ "Qt4ProjectManager.Qt4Project" ], + "id": "R.AutoTest2", + "category": "H.Project", + "trDescription": "Creates a new project including auto test skeleton.", + "trDisplayName": "Qt 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": "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 Qt project with additional auto test skeleton." + } + }, + { + "trDisplayName": "Project and Test Information", + "trShortTitle": "Details", + "typeId": "Fields", + "data": + [ + { + "name": "RequireGUI", + "trDisplayName": "GUI Application", + "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", + "type": "CheckBox", + "data": { + "checked": false, + "checkedValue": "true", + "uncheckedValue": "false" + } + }, + { + "name": "GenerateInitAndCleanup", + "trDisplayName": "Generate initialization and cleanup code", + "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" + } + ] + } + } + ] + }, + { + "trDisplayName": "Kit Selection", + "trShortTitle": "Kits", + "typeId": "Kits", + "enabled": "%{IsTopLevelProject}", + "data": { "projectFilePath": "%{ProFileName}" } + }, + { + "trDisplayName": "Project Management", + "trShortTitle": "Summary", + "typeId": "Summary" + } + ], + "generators": + [ + { + "typeId": "File", + "data": + [ + { + "source": "tmp.pro", + "target": "%{ProFileName}", + "openAsProject": true + }, + { + "source": "src.pro", + "target": "src/src.pro", + "openInEditor": false + }, + { + "source": "main.cpp", + "target": "src/%{MainCppName}", + "openInEditor": true + }, + { + "source": "tests.pro", + "target": "tests/tests.pro", + "openInEditor": false + }, + { + "source": "auto.pro", + "target": "tests/auto/auto.pro", + "openInEditor": false + }, + { + "source": "tst.pro", + "target": "%{JS: 'tests/auto/' + '%{TestCaseName}/%{TestCaseName}'.toLowerCase() + '.pro' }", + "openInEditor": false + }, + { + "source": "tst_src.cpp", + "target": "%{JS: 'tests/auto/' + '%{TestCaseName}/'.toLowerCase() + '%{TestCaseFileWithCppSuffix}' }", + "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 - - - From e54b53cdaa1db79558e2e4b676cfc697c0375298 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 23 Jun 2016 11:00:52 +0200 Subject: [PATCH 21/69] qbs build: Use precompiled headers. It was an oversight that we haven't done this before. Change-Id: Ic338503f6c1ca5e6c52c9af3bdbdb92b7776cac1 Reviewed-by: Joerg Bornemann Reviewed-by: Tim Jenssen --- qbs/imports/QtcLibrary.qbs | 1 + qbs/imports/QtcPlugin.qbs | 1 + qbs/imports/QtcProduct.qbs | 22 ++++++++++++++++++++++ qbs/imports/QtcTool.qbs | 1 + qbs/imports/src | 0 qbs/modules/qtc/qtc.qbs | 1 + src/shared/pch_files.qbs | 16 ++++++++++++++++ src/src.qbs | 1 + 8 files changed, 43 insertions(+) create mode 100644 qbs/imports/src create mode 100644 src/shared/pch_files.qbs 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/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") From cc804d542d93719ad67f817fb4bba70e5deb7246 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 8 Jun 2016 11:29:58 +0200 Subject: [PATCH 22/69] UnitTests: Disable small string test Change-Id: I508e43923efc065fce9a79edebeff79606069abd (cherry picked from commit 505c9be9af58ad35c62f8fbbce3b7a77017204b3) Reviewed-by: Orgad Shaneh --- tests/unit/unittest/unittest.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index dab05e794fd..0f9a0391464 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -67,7 +67,7 @@ SOURCES += \ chunksreportedmonitor.cpp \ unsavedfiletest.cpp \ clangisdiagnosticrelatedtolocationtest.cpp \ - smallstringtest.cpp \ +# smallstringtest.cpp \ sizedarraytest.cpp \ utf8positionfromlinecolumntest.cpp From 78be4281c179052f1bb4a767ad5999e898b9b569 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 23 Jun 2016 14:38:39 +0200 Subject: [PATCH 23/69] QmlDesigner: Fixing DocumentWarningWidget * Connect was missing * The check box contains the opposite truth value of the setting. Change-Id: If6ef86e0e1107ce537ee05ddf983131f65ee9e20 Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/documentwarningwidget.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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); } From bd63402fb8d123aa4472375486985ddbc9ad915d Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Thu, 23 Jun 2016 14:59:46 +0200 Subject: [PATCH 24/69] Fix warnings about missing overrides Change-Id: I655a0678ae55cf47c6014c52e0f62f7a85cf2dc7 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/runconfiguration.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 520d0284f39..4f258e6d239 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -179,7 +179,7 @@ class PROJECTEXPLORER_EXPORT Runnable return m_data == that->m_data; } - void *typeId() const { return T::staticTypeId; } + void *typeId() const override { return T::staticTypeId; } T m_data; }; @@ -220,7 +220,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; }; From 3d63136836a7b0a0dd033397ef3c1a15d7fba9ff Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 23 Jun 2016 15:46:18 +0300 Subject: [PATCH 25/69] Git: Show date and time for newly created branches Task-number: QTCREATORBUG-16484 Change-Id: I18b262d2d03f6a793123cc655f415a1d46d1a4e3 Reviewed-by: Tobias Hunger --- src/plugins/git/branchmodel.cpp | 23 +++++++++++++++++++++-- src/plugins/git/branchmodel.h | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) 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; From 53c4b36e4a5ef9abf000a294bf8c6f6d807e27c8 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 23 Jun 2016 15:55:36 +0300 Subject: [PATCH 26/69] Git: Resize columns in branches dialog when data is changed When setting a tracking branch, creating or deleting a branch. Change-Id: I58dd06912fbf23900674a8714224ee414f1da4b7 Reviewed-by: Tobias Hunger --- src/plugins/git/branchdialog.cpp | 12 ++++++++++-- src/plugins/git/branchdialog.h | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) 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(); From 573958e79f1033f502690c5ca2821c8c95f8414b Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 23 Jun 2016 21:52:00 +0300 Subject: [PATCH 27/69] Git: Prompt for unchanged file after custom mergetool fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To reproduce, create a conflict and configure a custom mergetool that does nothing: git config mergetool.my.cmd true git config merge.tool my Then execute merge tool from Qt Creator. The merge tool process hangs while asking how to handle the unchanged file, and can only be killed externally. Change-Id: I4d2a91061bd7549e308f6a25f106e6a7afc5cadb Reviewed-by: André Hartmann --- src/plugins/git/mergetool.cpp | 24 +++++++++++++++--------- src/plugins/git/mergetool.h | 1 + 2 files changed, 16 insertions(+), 9 deletions(-) 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(); From 075a6f68054149b568700cf972b45807d99730b9 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 23 Jun 2016 12:17:22 +0200 Subject: [PATCH 28/69] Extensionsystem: Fix compile for gcc 4.7.3/Qt5.5... ...and avoid warning. Change-Id: I1291c02b6c4a707f43235582db211933da0072a4 Reviewed-by: Orgad Shaneh --- src/libs/extensionsystem/pluginspec.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index 782d3e31150..dfe673217e8 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -149,12 +149,13 @@ bool PluginDependency::operator==(const PluginDependency &other) const static QString typeString(PluginDependency::Type type) { switch (type) { - case PluginDependency::Required: - return QString(); case PluginDependency::Optional: - return ", optional"; + return QString(", optional"); case PluginDependency::Test: - return ", test"; + return QString(", test"); + case PluginDependency::Required: + default: + return QString(); } } From a1749f9a14f8d19f9d1c95c499cd242b3c6bd806 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 23 Jun 2016 12:20:28 +0200 Subject: [PATCH 29/69] Clang: Fix dot-arrow-correction for zero results If there are no completion items, do not add snippets since these will otherwise pop-up at undesired positions, e.g. when: 1) Typing float/doubles: 0. 2) Typing file suffix in include directives: #include "stdio. Task-number: QTCREATORBUG-16188 Change-Id: Ie1c29826dc62dc447b2ff57b0c5537eb9d9511ef Reviewed-by: David Schulz --- .../clangcompletionassistprocessor.cpp | 2 +- .../test/clangcodecompletion_test.cpp | 20 ++++++++++++++----- .../test/clangcodecompletion_test.h | 1 + .../test/data/clangtestdata.qrc | 1 + .../data/noDotToArrowCorrectionForFloats.cpp | 4 ++++ 5 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 src/plugins/clangcodemodel/test/data/noDotToArrowCorrectionForFloats.cpp 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 54dba98c4ec..f2d12234bea 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.h +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.h @@ -49,6 +49,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 */ +} From 2536c2bfc719b9d08f18220f4393b542d9199fe7 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Jun 2016 16:17:10 +0200 Subject: [PATCH 30/69] TreeModel: Re-order template arguments for tree levels More natural and easier to extend to use parameter packs later. Adjust users. Change-Id: Ic167196cc969d18bb1615084397e884f769d1e85 Reviewed-by: Eike Ziller --- src/libs/utils/treemodel.h | 6 +++--- src/plugins/cmakeprojectmanager/cmakesettingspage.cpp | 2 +- src/plugins/debugger/breakhandler.h | 2 +- src/plugins/debugger/debuggeroptionspage.cpp | 2 +- src/plugins/debugger/threadshandler.h | 2 +- src/plugins/projectexplorer/kitmodel.cpp | 2 +- src/plugins/projectexplorer/kitmodel.h | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h index 815a3cb695b..ed2515dee33 100644 --- a/src/libs/utils/treemodel.h +++ b/src/libs/utils/treemodel.h @@ -241,9 +241,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/cmakeprojectmanager/cmakesettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp index adeae906a55..23ff123df2c 100644 --- a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp +++ b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp @@ -56,7 +56,7 @@ class CMakeToolTreeItem; // CMakeToolItemModel // -------------------------------------------------------------------------- -class CMakeToolItemModel : public LeveledTreeModel +class CMakeToolItemModel : public LeveledTreeModel { Q_DECLARE_TR_FUNCTIONS(CMakeProjectManager::CMakeSettingsPage) 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/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/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/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 From d5dc6f7f70378105a20c754a96e84da4c6291e33 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Thu, 23 Jun 2016 15:22:11 +0200 Subject: [PATCH 31/69] Utils: Use runBlocking in shellcommand This is run in a background thread, so there is no need to keep the UI alive. Change-Id: I81267b918ef2350a180b0a8ee55244feca2406b4 Reviewed-by: Tim Jenssen --- src/libs/utils/shellcommand.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) { From 82a5320a429e4d7b4f37480faa4918fac927a397 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Thu, 23 Jun 2016 15:31:58 +0200 Subject: [PATCH 32/69] Core: Stop crash in systemsettings Do not crash when updating the Git path settings. Task-number: QTCREATORBUG-16305 Change-Id: Ia6b7f529aa243b5e0b2778aeaddbbd86da9e265a Reviewed-by: Tim Jenssen --- src/plugins/coreplugin/systemsettings.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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())); From 05c1efd8ef359a8c6b45d24abf6f2eb780fe73db Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 23 Jun 2016 16:34:03 +0200 Subject: [PATCH 33/69] Clang: Fix dot-arrow-correction for not-yet-parsed unsaved content The issue was re-producible with e.g.: void g() { // Type 'foo.' as fast as possible in the next line } This led to "foo->" with completion results as if there was no "foo." at all in that line. We relied on a correct position for translationUnit.sourceLocationAtWithoutReparsing(), but the just typed characters were not yet reparsed. And we do not want to reparse at that point since takes too long. We already determine the utf8 position for the dot character, so simply use that instead. This completes commit 17c1325cc45eb563333d28725a51c04e33cd01f2. Change-Id: I669888b5c17ee63b2aec7b16c9921f9d79e281f9 Reviewed-by: David Schulz --- .../clangbackend/ipcsource/codecompleter.cpp | 31 ++++++----- .../clangbackend/ipcsource/codecompleter.h | 12 ++-- .../clangbackend/ipcsource/unsavedfile.cpp | 17 ++++-- .../clangbackend/ipcsource/unsavedfile.h | 1 + tests/unit/unittest/codecompletiontest.cpp | 55 +++++++++++-------- ...tArrowCorrectionForPointer_afterTyping.cpp | 6 ++ ...ArrowCorrectionForPointer_beforeTyping.cpp | 6 ++ tests/unit/unittest/unsavedfiletest.cpp | 39 +++++++++++++ 8 files changed, 121 insertions(+), 46 deletions(-) create mode 100644 tests/unit/unittest/data/complete_withDotArrowCorrectionForPointer_afterTyping.cpp create mode 100644 tests/unit/unittest/data/complete_withDotArrowCorrectionForPointer_beforeTyping.cpp 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 260ac4d581c..c785ae5939d 100644 --- a/src/tools/clangbackend/ipcsource/codecompleter.h +++ b/src/tools/clangbackend/ipcsource/codecompleter.h @@ -46,18 +46,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/unsavedfile.cpp b/src/tools/clangbackend/ipcsource/unsavedfile.cpp index a4d6f0fb82d..dffbdfd1ff0 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 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/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/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); From 1a68968c22076312cfedee77c964b4262df70178 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 21 Jun 2016 10:21:28 +0200 Subject: [PATCH 34/69] ClangBackEnd: Fix unsaved file printer for default constructed object. Change-Id: Ifcc8c2b60521e1f48ca2921d568b4e18d9d0a4eb Reviewed-by: Nikolai Kosjar --- src/tools/clangbackend/ipcsource/unsavedfile.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tools/clangbackend/ipcsource/unsavedfile.cpp b/src/tools/clangbackend/ipcsource/unsavedfile.cpp index a4d6f0fb82d..cc6e0296025 100644 --- a/src/tools/clangbackend/ipcsource/unsavedfile.cpp +++ b/src/tools/clangbackend/ipcsource/unsavedfile.cpp @@ -118,11 +118,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 << ")"; } From b06cc736f4cb9a47746cc5a03cfd5f244e45948a Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 24 Jun 2016 10:23:24 +0200 Subject: [PATCH 35/69] Fix compilation with QT_NO_ACCESSIBILITY Task-number: QTCREATORBUG-16446 Change-Id: If75122c23a697f26ccf56391fe2e8d316aad6367 Reviewed-by: hjk --- src/libs/utils/fancymainwindow.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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); From 438697219ff8ae4ad78ed5cd176abcce10bc7348 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Jun 2016 12:09:37 +0200 Subject: [PATCH 36/69] ProjectExplorer: Fix comparison with default-constructed Runnables Regression was introduced with 3f11ef92167. The original check asserting 'that != 0' is still needed without dynamic_cast, as d-pointer of 'other' can be statically 0 for default-constructed Runnable objects. Change-Id: Ibee898ffc61fb2f4a6a6276390fdf6d517fde546 Reviewed-by: Eike Ziller Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/runconfiguration.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 01fe5b9af4b..225c04bf437 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -173,6 +173,8 @@ public: bool equals(const std::unique_ptr &other) const override { + if (!other.get()) + return false; if (other->typeId() != typeId()) return false; auto that = static_cast *>(other.get()); From 34f75be3227ab2fdf12ed106bfa45aa9ddd9d9a4 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 24 Jun 2016 11:00:59 +0200 Subject: [PATCH 37/69] Git: Add a do not ask again checkbox to the pre checkout message box. Makes it possible to not query the user on every checkout if he wants to create a local branch. Change-Id: I22d8ef03fb98648cafb3f11a008bb24c291cb807 Reviewed-by: Tobias Hunger --- src/plugins/git/gitclient.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) 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; } From 61e770e5a75b6b0d1824f191c6feda442068c56a Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Jun 2016 12:41:58 +0200 Subject: [PATCH 38/69] Tests: Treemodel compile fix Change-Id: I28132baeb4b5b538f5d8c94c6182b3afe3ac2c78 Reviewed-by: Nikolai Kosjar --- tests/auto/utils/treemodel/tst_treemodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); From 667518ad23bb8e13f436e4ed735c19764ea83238 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 24 Jun 2016 13:27:04 +0200 Subject: [PATCH 39/69] Convert some c-style casts Change-Id: I0d7566d14941a17c3f171b32c9902c22558005bd Reviewed-by: Tobias Hunger --- .../pluginmanager/tst_pluginmanager.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp b/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp index 7281f7e06a8..a437e938763 100644 --- a/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp +++ b/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp @@ -139,14 +139,14 @@ 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->getObject(), static_cast(0)); QCOMPARE(m_pm->getObject(), 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 +203,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)); } } } From 5fcf0c438fd5a131dad3fc47cb8974858c9f13f4 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 22 Jun 2016 16:41:55 +0200 Subject: [PATCH 40/69] PluginManager: Code clean up Mostly refactor some explicit loops, and nicer reverse looping. Change-Id: I102b86da597b37cd496762bd776af73ec407d838 Reviewed-by: Tobias Hunger --- src/libs/extensionsystem/pluginmanager.cpp | 149 +++++++----------- src/libs/extensionsystem/pluginmanager_p.h | 1 - src/libs/extensionsystem/pluginspec.cpp | 21 ++- src/libs/extensionsystem/pluginspec.h | 1 + src/libs/utils/algorithm.h | 11 ++ .../pluginmanager/tst_pluginmanager.cpp | 2 + 6 files changed, 85 insertions(+), 100 deletions(-) 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 dfe673217e8..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 @@ -464,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 { @@ -895,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 bc0fc43a4d1..68c6fdd3154 100644 --- a/src/libs/extensionsystem/pluginspec.h +++ b/src/libs/extensionsystem/pluginspec.h @@ -119,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/utils/algorithm.h b/src/libs/utils/algorithm.h index 0867bfc2b41..e08b9ad099c 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -418,4 +418,15 @@ 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) +{ + auto rend = c.rend(); + for (auto it = c.rbegin(); it != rend; ++it) + operation(*it); +} + } diff --git a/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp b/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp index a437e938763..01b92352a71 100644 --- a/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp +++ b/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp @@ -140,8 +140,10 @@ void tst_PluginManager::getObject() object2b->setObjectName(objectName); m_pm->addObject(object2); 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)); From 6d6f30285ab7beefcc436f8c33b53af87af70c03 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 26 Jun 2016 22:09:29 +0300 Subject: [PATCH 41/69] BinEditor: Rename bineditor files to bineditorwidget Change-Id: Iaa94238cd6a53db1da8dd28c4bc4b6552a7b493f Reviewed-by: hjk --- src/plugins/bineditor/bineditor.pro | 4 ++-- src/plugins/bineditor/bineditor.qbs | 4 ++-- src/plugins/bineditor/bineditorplugin.cpp | 2 +- src/plugins/bineditor/{bineditor.cpp => bineditorwidget.cpp} | 2 +- src/plugins/bineditor/{bineditor.h => bineditorwidget.h} | 0 5 files changed, 6 insertions(+), 6 deletions(-) rename src/plugins/bineditor/{bineditor.cpp => bineditorwidget.cpp} (99%) rename src/plugins/bineditor/{bineditor.h => bineditorwidget.h} (100%) diff --git a/src/plugins/bineditor/bineditor.pro b/src/plugins/bineditor/bineditor.pro index 89a91bd621d..a75804a4bb3 100644 --- a/src/plugins/bineditor/bineditor.pro +++ b/src/plugins/bineditor/bineditor.pro @@ -1,10 +1,10 @@ include(../../qtcreatorplugin.pri) HEADERS += bineditorplugin.h \ - bineditor.h \ + bineditorwidget.h \ bineditorconstants.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..3367f873fc9 100644 --- a/src/plugins/bineditor/bineditor.qbs +++ b/src/plugins/bineditor/bineditor.qbs @@ -11,8 +11,8 @@ QtcPlugin { Depends { name: "TextEditor" } files: [ - "bineditor.cpp", - "bineditor.h", + "bineditorwidget.cpp", + "bineditorwidget.h", "bineditorconstants.h", "bineditorplugin.cpp", "bineditorplugin.h", 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 100% rename from src/plugins/bineditor/bineditor.h rename to src/plugins/bineditor/bineditorwidget.h From 9d74b995fb421ef9e5bc90f8ae087e651fc02a5a Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 26 Jun 2016 22:10:29 +0300 Subject: [PATCH 42/69] BinEditor: Export BinEditorWidget Change-Id: I62bfaccc15447118591697fc67d85963388e3978 Reviewed-by: hjk --- src/plugins/bineditor/bineditor.pro | 3 +++ src/plugins/bineditor/bineditor.qbs | 1 + src/plugins/bineditor/bineditor_global.h | 34 ++++++++++++++++++++++++ src/plugins/bineditor/bineditorwidget.h | 3 ++- 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/plugins/bineditor/bineditor_global.h diff --git a/src/plugins/bineditor/bineditor.pro b/src/plugins/bineditor/bineditor.pro index a75804a4bb3..3dde3eaf67d 100644 --- a/src/plugins/bineditor/bineditor.pro +++ b/src/plugins/bineditor/bineditor.pro @@ -1,8 +1,11 @@ include(../../qtcreatorplugin.pri) +DEFINES += BINEDITOR_LIBRARY + HEADERS += bineditorplugin.h \ bineditorwidget.h \ bineditorconstants.h \ + bineditor_global.h \ markup.h SOURCES += bineditorplugin.cpp \ diff --git a/src/plugins/bineditor/bineditor.qbs b/src/plugins/bineditor/bineditor.qbs index 3367f873fc9..8d2138598d4 100644 --- a/src/plugins/bineditor/bineditor.qbs +++ b/src/plugins/bineditor/bineditor.qbs @@ -14,6 +14,7 @@ QtcPlugin { "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/bineditorwidget.h b/src/plugins/bineditor/bineditorwidget.h index 45bfb3bac32..dd54b53c7fb 100644 --- a/src/plugins/bineditor/bineditorwidget.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) From 94e08b9adcc04d1d768bb5ba760546f810be97f6 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sat, 25 Jun 2016 22:27:05 +0300 Subject: [PATCH 43/69] Utils: Fix runBlocking * result is initialized to StartFailed, so after executing, we should always set the result, unless previously set to Hang. If the process really fails to start, we return earlier. * Setting m_maxHangTimerCount to INT_MAX is bad, since it is later multiplied by 1000 (the original value is in seconds), but still remains an int, so we get -1000... Change-Id: Ie990105894fe223a93ece29df4574592a122f94b Reviewed-by: Tobias Hunger --- src/libs/utils/synchronousprocess.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 From 8e2045415882b8116abe8110e8ba650b48f6033b Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 24 Jun 2016 11:44:13 +0200 Subject: [PATCH 44/69] RunConfigurationAspect: Remove needless initialization Change-Id: I31be0f58eb376b6ef6085995b11bb513897023c4 Reviewed-by: hjk --- src/plugins/projectexplorer/runconfigurationaspects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 1f063d02afc..1479bd18cc1 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -132,7 +132,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"); From 21ef857c7abf1a93c44dd42885658941aa9a5e33 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 24 Jun 2016 12:57:13 +0200 Subject: [PATCH 45/69] WorkingDirectoryAspect: Do not reset directory when setting default Do not reset the working directory when setting the default working directory. That update was triggered by setting the PathChooser filename. Task-number: QTCREATORBUG-16330 Change-Id: I5db846c8cf2a6cadad812e775a8424645b15c7c5 Reviewed-by: hjk --- .../projectexplorer/runconfigurationaspects.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 1479bd18cc1..5492b2fa2b2 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -244,13 +244,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 From 1b5c46660cfe8d5d8c48472d49e85db681fcd10b Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 24 Jun 2016 13:44:19 +0200 Subject: [PATCH 46/69] PathChooser: Handle things like %{buildDir}/../something Do not call cleanPath on rawFileName as that sanitizes %{buildDir}/.. to '.', which is not what is expected for a rawFileName. Change-Id: I4bb95b33f4c12c79ed0029d5fbf539e113a3774c Reviewed-by: hjk --- src/libs/utils/pathchooser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp index e14b67d68c9..fc0fa389b29 100644 --- a/src/libs/utils/pathchooser.cpp +++ b/src/libs/utils/pathchooser.cpp @@ -318,7 +318,7 @@ QString PathChooser::rawPath() const FileName PathChooser::rawFileName() const { - return FileName::fromUserInput(d->m_lineEdit->text()); + return FileName::fromString(QDir::fromNativeSeparators(d->m_lineEdit->text())); } FileName PathChooser::fileName() const From 0cfd569038b9da6bdcd2112ee1e50e8420d5cd50 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Jun 2016 08:36:13 +0200 Subject: [PATCH 47/69] TreeModel: Add an optional ParentType parameter for TypedTreeItem ... and use it to add a ParentType *parent() function. Also, de-virtualize the TreeModel::parent(), this flexibility has not been needed so far. Change-Id: I0bcf930a0d6b05d5621753a5a8a1f8c3e5017386 Reviewed-by: Christian Stenger Reviewed-by: Eike Ziller --- src/libs/utils/treemodel.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h index ed2515dee33..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 From 0ec8fdda5c6372f1a979fa09f1ad0d5de3e137a2 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Jun 2016 08:38:42 +0200 Subject: [PATCH 48/69] Debugger: Use TypedTreeItems in RegisterHandler Saves a couple of static_casts on the user side. Change-Id: Ib8f70046ae40539813c01e3ff7d790bf7a170bee Reviewed-by: Christian Stenger --- src/plugins/debugger/registerhandler.cpp | 28 +++++++++++------------- 1 file changed, 13 insertions(+), 15 deletions(-) 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; From 891899dcd48d9151305ea0ffd5eb20993ef0f0e4 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 27 Jun 2016 07:15:08 +0200 Subject: [PATCH 49/69] Utils: Fix compile for Qt5.5 Change-Id: I4294fb7dd448e74236e085f7a1884ecedd5a5b90 Reviewed-by: Eike Ziller --- src/libs/utils/algorithm.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index e08b9ad099c..b1044d26e20 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -424,9 +424,18 @@ inline void sort(Container &c, Predicate p) 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 } } From ff66f5c62f20e55375852c353bdf21509377a9cf Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 24 Jun 2016 13:45:51 +0200 Subject: [PATCH 50/69] PathChooser: Make path/rawPath and fileName/rawFileName more consistent This moves the fromUserInput that used to be in rawFileName to fileName, so that fileName produces the same output it used to produce. Change-Id: Ifb209af3f60d959c3f7119ebfa20f999c5d5f0ca Reviewed-by: hjk --- src/libs/utils/pathchooser.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp index fc0fa389b29..edf0384f2db 100644 --- a/src/libs/utils/pathchooser.cpp +++ b/src/libs/utils/pathchooser.cpp @@ -306,16 +306,16 @@ 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::fromString(QDir::fromNativeSeparators(d->m_lineEdit->text())); @@ -323,7 +323,7 @@ FileName PathChooser::rawFileName() const FileName PathChooser::fileName() const { - return FileName::fromString(path()); + return FileName::fromUserInput(d->expandedPath(rawFileName().toString())); } // FIXME: try to remove again From 9db6897e55970eb44732bec320191beea0e130a0 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 24 Jun 2016 11:44:34 +0200 Subject: [PATCH 51/69] RunConfigurationAspect: Re-enable macro substitution Re-enable macro substitution in work directory of run configurations. This makes it possible to do %{sourceDir} or %{buildDir} again. Task-number: QTCREATORBUG-16338 Change-Id: Ifff7831bf3aa0078d13185da5f5e7c6a3be2f852 Reviewed-by: hjk --- .../projectexplorer/runconfigurationaspects.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 5492b2fa2b2..7e935be8c2d 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -215,16 +215,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( + 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()))); - } + PathChooser::expandedDirectory(m_workingDirectory.toString(), env, QString()))); } FileName WorkingDirectoryAspect::defaultWorkingDirectory() const From 8501ffbb36525fb9d62ff9589781065d017cf956 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 24 Jun 2016 13:47:39 +0200 Subject: [PATCH 52/69] WorkingDirectoryAspect: Expand macros first, then expand variables Expanding variables includes calling cleanPath on the input. At that point macros like %{buildDir} need to be expanded already or working directories like "%{buildDir}/../test" will get turned into "test", which is not what a user expects to happen. Change-Id: I61e6604a621f632ddee87766d38ab3c863bdb9dc Reviewed-by: hjk --- src/plugins/projectexplorer/runconfigurationaspects.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 7e935be8c2d..11e6c10c8b8 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -218,9 +218,9 @@ FileName WorkingDirectoryAspect::workingDirectory() const 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()))); + const QString macroExpanded + = runConfiguration()->macroExpander()->expandProcessArgs(m_workingDirectory.toUserOutput()); + return FileName::fromString(PathChooser::expandedDirectory(macroExpanded, env, QString())); } FileName WorkingDirectoryAspect::defaultWorkingDirectory() const From 8ea167892f229e22d70c8cb0810914c579eeba3c Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 27 Jun 2016 11:55:53 +0200 Subject: [PATCH 53/69] RunConfigurationAspects: Clean up includes Change-Id: Ic838f141956f3aa1f32d90e977dd1e59d22df016 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/runconfigurationaspects.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 11e6c10c8b8..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; From 63e158b4d4de1b958fd6589058955b1a4da3e058 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 22 Jun 2016 16:01:34 +0200 Subject: [PATCH 54/69] AutoTest: Enhance wizard to support GTest Initially this adds basic gtest testing - to be improved later on. Change-Id: I2121cd24493a8d65c5acd0be5c9dd5858702645d Reviewed-by: Tobias Hunger --- .../wizards/autotest/{ => files}/auto.pro | 0 .../autotest/files/gtest_dependency.pri | 31 +++++++ .../wizards/autotest/{ => files}/main.cpp | 12 ++- .../wizards/autotest/{ => files}/src.pro | 7 +- .../wizards/autotest/{ => files}/tests.pro | 0 .../wizards/autotest/{ => files}/tmp.pro | 0 .../templates/wizards/autotest/files/tst.pro | 34 +++++++ .../wizards/autotest/files/tst_main.cpp | 10 ++ .../wizards/autotest/{ => files}/tst_src.cpp | 0 .../wizards/autotest/files/tst_src.h | 11 +++ .../templates/wizards/autotest/tst.pro | 14 --- .../templates/wizards/autotest/wizard.json | 93 +++++++++++++++++-- 12 files changed, 186 insertions(+), 26 deletions(-) rename share/qtcreator/templates/wizards/autotest/{ => files}/auto.pro (100%) create mode 100644 share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri rename share/qtcreator/templates/wizards/autotest/{ => files}/main.cpp (77%) rename share/qtcreator/templates/wizards/autotest/{ => files}/src.pro (78%) rename share/qtcreator/templates/wizards/autotest/{ => files}/tests.pro (100%) rename share/qtcreator/templates/wizards/autotest/{ => files}/tmp.pro (100%) create mode 100644 share/qtcreator/templates/wizards/autotest/files/tst.pro create mode 100644 share/qtcreator/templates/wizards/autotest/files/tst_main.cpp rename share/qtcreator/templates/wizards/autotest/{ => files}/tst_src.cpp (100%) create mode 100644 share/qtcreator/templates/wizards/autotest/files/tst_src.h delete mode 100644 share/qtcreator/templates/wizards/autotest/tst.pro diff --git a/share/qtcreator/templates/wizards/autotest/auto.pro b/share/qtcreator/templates/wizards/autotest/files/auto.pro similarity index 100% rename from share/qtcreator/templates/wizards/autotest/auto.pro rename to share/qtcreator/templates/wizards/autotest/files/auto.pro 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/main.cpp b/share/qtcreator/templates/wizards/autotest/files/main.cpp similarity index 77% rename from share/qtcreator/templates/wizards/autotest/main.cpp rename to share/qtcreator/templates/wizards/autotest/files/main.cpp index 2eb09afb0dc..8a4a5671fc3 100644 --- a/share/qtcreator/templates/wizards/autotest/main.cpp +++ b/share/qtcreator/templates/wizards/autotest/files/main.cpp @@ -1,4 +1,5 @@ %{Cpp:LicenseTemplate}\ +@if "%{TestFrameWork}" == "QtTest" @if "%{RequireGUI}" == "true" %{JS: QtSupport.qtIncludes([ 'QtGui/QApplication' ], [ 'QtWidgets/QApplication' ]) }\ @@ -6,7 +7,6 @@ %{JS: QtSupport.qtIncludes([ 'QtCore/QCoreApplication' ], [ 'QtCore/QCoreApplication' ]) }\ @endif - // add necessary includes here int main(int argc, char *argv[]) @@ -19,3 +19,13 @@ int main(int argc, char *argv[]) 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 78% rename from share/qtcreator/templates/wizards/autotest/src.pro rename to share/qtcreator/templates/wizards/autotest/files/src.pro index 3cbad0593f8..8d49098b6be 100644 --- a/share/qtcreator/templates/wizards/autotest/src.pro +++ b/share/qtcreator/templates/wizards/autotest/files/src.pro @@ -1,13 +1,18 @@ +@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 += %{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 100% rename from share/qtcreator/templates/wizards/autotest/tmp.pro rename to share/qtcreator/templates/wizards/autotest/files/tmp.pro 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/tst_src.cpp b/share/qtcreator/templates/wizards/autotest/files/tst_src.cpp similarity index 100% rename from share/qtcreator/templates/wizards/autotest/tst_src.cpp rename to share/qtcreator/templates/wizards/autotest/files/tst_src.cpp 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/tst.pro b/share/qtcreator/templates/wizards/autotest/tst.pro deleted file mode 100644 index f58c30fd8ea..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 += %{TestCaseFileWithCppSuffix} diff --git a/share/qtcreator/templates/wizards/autotest/wizard.json b/share/qtcreator/templates/wizards/autotest/wizard.json index 16f318aa574..0a7b6e29aee 100644 --- a/share/qtcreator/templates/wizards/autotest/wizard.json +++ b/share/qtcreator/templates/wizards/autotest/wizard.json @@ -1,10 +1,10 @@ { "version": 1, "supportedProjectTypes": [ "Qt4ProjectManager.Qt4Project" ], - "id": "R.AutoTest2", + "id": "R.AutoTest", "category": "H.Project", "trDescription": "Creates a new project including auto test skeleton.", - "trDisplayName": "Qt Test project", + "trDisplayName": "Auto Test Project", "trDisplayCategory": "Other Project", "icon": "autotest_24.png", "featuresRequired": [ "QtSupport.Wizards.FeatureQt", "QtSupport.Wizards.FeatureDesktop" ], @@ -21,6 +21,10 @@ { "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') }" @@ -35,7 +39,7 @@ "typeId": "Project", "data": { - "trDescription": "This wizard creates a simple Qmake based Qt project with additional auto test skeleton." + "trDescription": "This wizard creates a simple Qmake based project with additional auto test skeleton." } }, { @@ -44,9 +48,30 @@ "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, @@ -64,6 +89,7 @@ { "name": "RequireApplication", "trDisplayName": "Requires QApplication", + "visible": "%{JS: '%{TestFrameWork}' === 'QtTest'}", "type": "CheckBox", "data": { "checked": false, @@ -74,6 +100,25 @@ { "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, @@ -100,6 +145,15 @@ } ] } + }, + { + "name": "GTestRepository", + "trDisplayName": "Googletest repository:", + "visible": "%{JS: '%{TestFrameWork}' === 'GTest'}", + "type": "PathChooser", + "data": { + "kind": "existingDirectory" + } } ] }, @@ -123,38 +177,57 @@ "data": [ { - "source": "tmp.pro", + "source": "files/tmp.pro", "target": "%{ProFileName}", "openAsProject": true }, { - "source": "src.pro", + "source": "files/src.pro", "target": "src/src.pro", "openInEditor": false }, { - "source": "main.cpp", + "source": "files/main.cpp", "target": "src/%{MainCppName}", "openInEditor": true }, { - "source": "tests.pro", + "source": "files/tests.pro", "target": "tests/tests.pro", "openInEditor": false }, { - "source": "auto.pro", + "source": "files/auto.pro", "target": "tests/auto/auto.pro", "openInEditor": false }, { - "source": "tst.pro", + "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": "tst_src.cpp", + "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 }, { From 953ec9867fd2437447161c6ebec62738450f7e9e Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 24 Jun 2016 15:49:26 +0200 Subject: [PATCH 55/69] QmlDesigner: Improve performance of item library If there are manu components (e.g. 200) in the same directory, the model was updated for each component. This patch compresses the signal and therefore reduced the updates. Change-Id: I80b38df59952dda7e67e258ecd6e5f29d6a036e6 Reviewed-by: Tim Jenssen --- .../components/itemlibrary/itemlibrarywidget.cpp | 13 +++++++++++-- .../components/itemlibrary/itemlibrarywidget.h | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) 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; From e12949a38a6bdb124b27d14876bf3f19d0ef29ca Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Thu, 23 Jun 2016 17:02:36 +0200 Subject: [PATCH 56/69] QmlDesigner: adding openuiqmlfiledialog files to qbs file Change-Id: Ie652f1bc8b04163befc012e4abd7432d71f4d92c Reviewed-by: Jake Petroules --- src/plugins/qmldesigner/qmldesignerplugin.qbs | 3 +++ 1 file changed, 3 insertions(+) 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", From e1f5fd202aa421c8b510d902a68a03a5345f3ec4 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 23 Jun 2016 15:09:32 +0200 Subject: [PATCH 57/69] QmlDesigner: Propose to open a .ui.qml file instead of .qml If the project contains .ui.qml files the designer proposes to open .ui.qml files instead of opening a .qml file. This encourages to not open the .qml files in the designer. This feature can be disabled. Change-Id: I47a877ea72fafb07ebee485b8f22509f6162993c Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/designersettings.cpp | 1 + src/plugins/qmldesigner/designersettings.h | 1 + .../qmldesigner/openuiqmlfiledialog.cpp | 92 +++++++++++++++++++ src/plugins/qmldesigner/openuiqmlfiledialog.h | 54 +++++++++++ .../qmldesigner/openuiqmlfiledialog.ui | 58 ++++++++++++ src/plugins/qmldesigner/qmldesignerplugin.cpp | 53 ++++++++++- src/plugins/qmldesigner/qmldesignerplugin.pri | 9 +- src/plugins/qmldesigner/settingspage.cpp | 7 +- src/plugins/qmldesigner/settingspage.ui | 18 +++- 9 files changed, 284 insertions(+), 9 deletions(-) create mode 100644 src/plugins/qmldesigner/openuiqmlfiledialog.cpp create mode 100644 src/plugins/qmldesigner/openuiqmlfiledialog.h create mode 100644 src/plugins/qmldesigner/openuiqmlfiledialog.ui 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/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 a656f85a7c1..0ef7f450b7d 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 @@ -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,34 @@ void QmlDesignerPlugin::createDesignModeWidget() }); } +static bool warningsForQmlFilesInsteadOfUiQmlEnabled() +{ + DesignerSettings settings = QmlDesignerPlugin::instance()->settings(); + return settings.value(DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES).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(); 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/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 From b9f699f9576875b4f760fbb70cb198e06add168f Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Thu, 23 Jun 2016 17:03:40 +0200 Subject: [PATCH 58/69] QmlDesigner: take the setting into account This was a regression after the merge of error/warning dialog. Change-Id: I6bd9d2e81d118018a40745a98e67b1bff8f84d4f Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/qmldesignerplugin.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 0ef7f450b7d..60fd2b77ff7 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -307,6 +307,12 @@ static bool warningsForQmlFilesInsteadOfUiQmlEnabled() 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); @@ -425,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(); From fccd50d32b37b3276af03f28dd3af463cab1dec6 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Thu, 23 Jun 2016 17:03:57 +0200 Subject: [PATCH 59/69] QmlDesigner: small code cleanup Change-Id: I4cbfa65c5b8481c859081f43893431c0b93b3cd7 Reviewed-by: Tim Jenssen --- .../qmldesigner/components/integration/designdocument.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 From 0d4150bda95a3fcd8986f5e3e06975301f41e5b5 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 24 Jun 2016 10:35:23 +0200 Subject: [PATCH 60/69] Qmake: Do not turn a CONFIG variable with spaces into several When e.g. examining 'CONFIG+=foo bar' Creator would turn that into CONFIG+=foo and 'CONFIG+=foo bar', which seems wrong to me. Task-number: QTCREATORBUG-16492 Change-Id: I37b83f1e8415d421abb2df7a9466651bff502d17 Reviewed-by: Oswald Buddenhagen --- src/plugins/qmakeprojectmanager/makefileparse.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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); From cd7886a7b3fb71483cee9f57bbf3d3eaf37c4e32 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 27 Jun 2016 16:46:40 +0200 Subject: [PATCH 61/69] Debugger: Remove string freeze workaround Change-Id: Ifd9f89c0d3b5c060af28bdb29e93a5b95f6dc9cd Reviewed-by: Orgad Shaneh --- src/plugins/debugger/watchhandler.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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"); From fc59423f2f1424a3933b4897140a5152b0d76c8d Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Mon, 27 Jun 2016 22:56:03 +0300 Subject: [PATCH 62/69] Debugger: Mark handleResponse as Q_INVOKABLE It is used in invokeMethod Change-Id: Ic4c1d69efefc41069f36be4cf94b06efdc265b11 Reviewed-by: hjk --- src/plugins/debugger/gdb/gdbengine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index c3789f7306c..e718771e8f4 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -204,7 +204,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); From 7d31cb0e18d9cf64748c8dfe98ef1d140d5d2626 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 26 Jun 2016 22:25:34 +0300 Subject: [PATCH 63/69] Debugger: De-slot Most Qt4 connects are gone. Change-Id: Ie74cfb11fc4b4c531f9e22c95a4d18336e1c29e8 Reviewed-by: hjk --- .../analyzer/analyzerrunconfigwidget.h | 3 +- src/plugins/debugger/breakwindow.cpp | 1 - src/plugins/debugger/cdb/cdbengine.h | 3 +- .../debugger/console/consoleitemdelegate.h | 2 - .../debugger/console/consoleitemmodel.h | 1 - .../debugger/console/consoleproxymodel.h | 1 - src/plugins/debugger/console/consoleview.h | 1 - src/plugins/debugger/debuggerplugin.cpp | 4 +- .../debuggersourcepathmappingwidget.h | 3 +- src/plugins/debugger/gdb/gdbengine.h | 3 +- .../debugger/gdb/startgdbserverdialog.h | 3 +- src/plugins/debugger/logwindow.cpp | 1 - src/plugins/debugger/logwindow.h | 1 - src/plugins/debugger/qml/qmlengine.h | 3 +- src/plugins/debugger/registerwindow.h | 1 - src/shared/modeltest/modeltest.cpp | 70 +++++++++---------- 16 files changed, 42 insertions(+), 59 deletions(-) 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/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/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 e718771e8f4..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; 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/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/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(); } From d63e27d877771a42464b53b53780e91dbb5f6ec7 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 22 Jun 2016 11:15:19 +0200 Subject: [PATCH 64/69] CppTools/Clang: Announce only removed project parts ...and not all projects parts of a project if it is closed. Re-produce with: open a project A with subdirs (e.g. qtcreator.pro) open a subdir project from project A (e.g. cppeditor.pro) close project A --> The project part representing the subdir is announced as removed although it is still open. The clang code model was the only affected user - affected translation units were not parsed/updated anymore ("ERROR: ProjectPartDoesNotExistMessage"). Change-Id: Ia79341ce201e3b4aefff9f597920dbc6f7d67634 Reviewed-by: David Schulz --- src/plugins/cpptools/cppmodelmanager.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) 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(); } From 090c1069297883fd4073152d0c62fd4c8e08afb3 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 24 Jun 2016 13:54:33 +0200 Subject: [PATCH 65/69] Fix Ctrl+M (bookmark) in editor when help mode is visible For external windows we need to separate the contexts in which help mode's "add bookmark" and editor's "toggle bookmark" are present. Task-number: QTCREATORBUG-16286 Change-Id: I2a7a28c75dc53e1dd0b21c0a8833bd4594d5afad Reviewed-by: David Schulz --- src/plugins/bookmarks/bookmarksplugin.cpp | 12 +++++++----- src/plugins/help/helpplugin.cpp | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) 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/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, From 7609e56ee365520011920eee07e7e7c876eb5683 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Mon, 27 Jun 2016 22:25:11 +0300 Subject: [PATCH 66/69] QmlJS[|Editor|Tools]: Use Qt5-style connects The heavy lifting was done by clazy. Change-Id: I56550546b341d486d321329e9a90b9369d56af40 Reviewed-by: Marco Benelli --- src/libs/qmljs/qmljsmodelmanagerinterface.cpp | 5 ++- src/libs/qmljs/qmljsmodelmanagerinterface.h | 13 ++++--- src/libs/qmljs/qmljsplugindumper.cpp | 10 +++-- src/libs/qmljs/qmljsplugindumper.h | 14 +++---- .../qmljseditor/qmljscomponentnamedialog.cpp | 16 ++------ .../qmljseditor/qmljscomponentnamedialog.h | 2 - src/plugins/qmljseditor/qmljseditor.cpp | 38 ++++++++----------- src/plugins/qmljseditor/qmljseditor.h | 6 +-- .../qmljseditor/qmljseditordocument.cpp | 28 ++++++++------ .../qmljseditor/qmljseditordocument_p.h | 1 - src/plugins/qmljseditor/qmljseditorplugin.cpp | 37 +++++++++--------- src/plugins/qmljseditor/qmljseditorplugin.h | 4 +- .../qmljseditor/qmljsfindreferences.cpp | 18 ++++----- src/plugins/qmljseditor/qmljsfindreferences.h | 5 +-- src/plugins/qmljseditor/qmljsoutline.cpp | 18 ++++----- src/plugins/qmljseditor/qmljsoutline.h | 4 +- .../qmljseditor/qmljsoutlinetreeview.cpp | 4 +- .../qmljseditor/qmljsoutlinetreeview.h | 2 +- .../qmljseditor/qmljssemantichighlighter.cpp | 8 ++-- .../qmljseditor/qmljssemantichighlighter.h | 4 +- .../qmljseditor/qmljssemanticinfoupdater.h | 2 +- src/plugins/qmljseditor/qmltaskmanager.cpp | 11 +++--- src/plugins/qmljseditor/qmltaskmanager.h | 4 +- src/plugins/qmljseditor/quicktoolbar.cpp | 17 ++++++--- src/plugins/qmljseditor/quicktoolbar.h | 1 - .../qmljstools/qmljscodestylesettingspage.cpp | 4 +- .../qmljstools/qmljscodestylesettingspage.h | 3 +- src/plugins/qmljstools/qmljslocatordata.h | 3 +- src/plugins/qmljstools/qmljsmodelmanager.cpp | 4 +- src/plugins/qmljstools/qmljsmodelmanager.h | 3 +- src/plugins/qmljstools/qmljstoolsplugin.cpp | 8 ++-- src/plugins/qmljstools/qmljstoolsplugin.h | 12 +++--- 32 files changed, 143 insertions(+), 166 deletions(-) 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/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 From d8ed91c44f039ac9a8ef7a84c5dfbcafd4cada0f Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 27 Jun 2016 13:09:14 +0200 Subject: [PATCH 67/69] CMake: Add per-cmake option to not automatically run cmake Task-number: QTCREATORBUG-15934 Change-Id: I54fdb505a451fb269c3747a370c8dfd7043c6c9d Reviewed-by: Tim Jenssen --- .../cmakeprojectmanager/builddirmanager.cpp | 10 +++- .../cmakeprojectmanager/cmakesettingspage.cpp | 47 +++++++++++++------ src/plugins/cmakeprojectmanager/cmaketool.cpp | 17 +++++++ src/plugins/cmakeprojectmanager/cmaketool.h | 4 ++ 4 files changed, 62 insertions(+), 16 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index 38954807835..0a30e0d72e2 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -108,8 +108,14 @@ BuildDirManager::BuildDirManager(CMakeBuildConfiguration *bc) : connect(&m_reparseTimer, &QTimer::timeout, this, &BuildDirManager::parse); connect(m_watcher, &QFileSystemWatcher::fileChanged, this, [this]() { - if (!isParsing()) - m_reparseTimer.start(); + if (isParsing()) + return; + + const CMakeTool *tool = CMakeKitInformation::cmakeTool(m_buildConfiguration->target()->kit()); + if (!tool->isAutoRun()) + return; + + m_reparseTimer.start(); }); } diff --git a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp index 23ff123df2c..ca133101140 100644 --- a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp +++ b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -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; From 703c410085b71217a7f242e7251d900185307366 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 27 Jun 2016 14:49:35 +0200 Subject: [PATCH 68/69] CMake: Only start parsing when creator gets focus again Rip out QFileSystemWatcher and use Qt Creators IDocument for file watching instead. The latter properly delays any action till creator gets focus again. Task-number: QTCREATORBUG-16354 Change-Id: Ibb71963416b09712a80ee95347425550453b7fd4 Reviewed-by: Tim Jenssen --- .../cmakeprojectmanager/builddirmanager.cpp | 67 ++++++++----------- .../cmakeprojectmanager/builddirmanager.h | 7 +- .../cmakebuildconfiguration.cpp | 5 ++ .../cmakebuildconfiguration.h | 2 + src/plugins/cmakeprojectmanager/cmakefile.cpp | 14 +++- src/plugins/cmakeprojectmanager/cmakefile.h | 6 +- .../cmakeprojectmanager/cmakeproject.cpp | 37 +++++++++- .../cmakeprojectmanager/cmakeproject.h | 5 ++ 8 files changed, 99 insertions(+), 44 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index 0a30e0d72e2..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,26 +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()) - return; - - const CMakeTool *tool = CMakeKitInformation::cmakeTool(m_buildConfiguration->target()->kit()); - if (!tool->isAutoRun()) - return; - - m_reparseTimer.start(); - }); } BuildDirManager::~BuildDirManager() @@ -163,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) @@ -186,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() @@ -229,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) { @@ -257,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; @@ -277,6 +266,11 @@ QList BuildDirManager::files() return m_files; } +QSet BuildDirManager::cmakeFiles() +{ + return m_cmakeFiles; +} + void BuildDirManager::clearFiles() { m_files.clear(); @@ -361,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; @@ -380,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 From 8777f4b9b9278c50eda47e142a805902ee2272ec Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 27 Jun 2016 15:53:47 +0200 Subject: [PATCH 69/69] Qmake: Add a macro expander to get the currently configured mkspec of a kit Change-Id: I97cd6f47c20867277ed7612a0cf5a179dedd7501 Reviewed-by: Tim Jenssen Reviewed-by: Oswald Buddenhagen --- src/plugins/qmakeprojectmanager/qmakekitinformation.cpp | 8 ++++++++ src/plugins/qmakeprojectmanager/qmakekitinformation.h | 2 ++ 2 files changed, 10 insertions(+) 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);