Merge remote-tracking branch 'origin/4.1'

Change-Id: Ic8d82172a97bdf1dbf3d047157cc2c8d853f35cc
This commit is contained in:
Eike Ziller
2016-06-28 12:13:33 +02:00
186 changed files with 1784 additions and 1045 deletions

View File

@@ -5,6 +5,7 @@ QtcProduct {
type: ["dynamiclibrary", "dynamiclibrary_symlink", "qtc.dev-module"] type: ["dynamiclibrary", "dynamiclibrary_symlink", "qtc.dev-module"]
installDir: qtc.ide_library_path installDir: qtc.ide_library_path
installTags: ["dynamiclibrary", "dynamiclibrary_symlink"] installTags: ["dynamiclibrary", "dynamiclibrary_symlink"]
useNonGuiPchFile: true
Depends { Depends {
condition: qtc.testsEnabled condition: qtc.testsEnabled
name: "Qt.test" name: "Qt.test"

View File

@@ -6,6 +6,7 @@ QtcProduct {
type: ["dynamiclibrary", "pluginSpec", "qtc.dev-module"] type: ["dynamiclibrary", "pluginSpec", "qtc.dev-module"]
installDir: qtc.ide_plugin_path installDir: qtc.ide_plugin_path
installTags: ["dynamiclibrary"] installTags: ["dynamiclibrary"]
useGuiPchFile: true
property var pluginJsonReplacements property var pluginJsonReplacements
property var pluginRecommends: [] property var pluginRecommends: []

View File

@@ -9,6 +9,11 @@ Product {
property string installDir property string installDir
property stringList installTags: type property stringList installTags: type
property string fileName: FileInfo.fileName(sourceDirectory) + ".qbs" 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: "cpp" }
Depends { name: "qtc" } Depends { name: "qtc" }
@@ -24,6 +29,7 @@ Product {
} }
cpp.minimumOsxVersion: "10.7" cpp.minimumOsxVersion: "10.7"
cpp.minimumWindowsVersion: qbs.architecture === "x86" ? "5.1" : "5.2" cpp.minimumWindowsVersion: qbs.architecture === "x86" ? "5.1" : "5.2"
cpp.useCxxPrecompiledHeader: useNonGuiPchFile || useGuiPchFile
cpp.visibility: "minimal" cpp.visibility: "minimal"
Depends { name: "Qt.core" } Depends { name: "Qt.core" }
@@ -39,4 +45,20 @@ Product {
qbs.install: true qbs.install: true
qbs.installDir: qtc.ide_qbs_modules_path + '/' + product.name 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"]
}
} }

View File

@@ -5,6 +5,7 @@ QtcProduct {
type: ["application"] type: ["application"]
consoleApplication: true consoleApplication: true
installDir: qtc.ide_libexec_path installDir: qtc.ide_libexec_path
useNonGuiPchFile: true
cpp.rpaths: { cpp.rpaths: {
var relativePathToLibs = FileInfo.relativePath('/' + qtc.ide_libexec_path, var relativePathToLibs = FileInfo.relativePath('/' + qtc.ide_libexec_path,

0
qbs/imports/src Normal file
View File

View File

@@ -51,6 +51,7 @@ Module {
property string ide_qbs_resources_path: "qbs-resources" property string ide_qbs_resources_path: "qbs-resources"
property string ide_qbs_modules_path: ide_qbs_resources_path + "/modules" 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_qbs_imports_path: ide_qbs_resources_path + "/imports"
property string ide_shared_sources_path: "src/shared"
property bool make_dev_package: false property bool make_dev_package: false

View File

@@ -65,7 +65,7 @@ void BehaviorNodeInstance::resetProperty(const PropertyName &name)
PropertyNameList BehaviorNodeInstance::ignoredProperties() const PropertyNameList BehaviorNodeInstance::ignoredProperties() const
{ {
return PropertyNameList() << "enabled"; return PropertyNameList({"enabled"});
} }

View File

@@ -70,7 +70,8 @@ void LayoutNodeInstance::refreshLayoutable()
PropertyNameList LayoutNodeInstance::ignoredProperties() const PropertyNameList LayoutNodeInstance::ignoredProperties() const
{ {
return PropertyNameList() << "move" << "add" << "populate"; static const PropertyNameList properties({"move", "add", "populate"});
return properties;
} }
} }

View File

@@ -76,8 +76,8 @@ void PositionerNodeInstance::refreshLayoutable()
PropertyNameList PositionerNodeInstance::ignoredProperties() const PropertyNameList PositionerNodeInstance::ignoredProperties() const
{ {
return PropertyNameList() << "move" << "add" << "populate"; static const PropertyNameList properties({"move", "add", "populate"});
} return properties;
} }
} // namespace Internal
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -52,7 +52,8 @@ bool QmlTransitionNodeInstance::isTransition() const
PropertyNameList QmlTransitionNodeInstance::ignoredProperties() const PropertyNameList QmlTransitionNodeInstance::ignoredProperties() const
{ {
return PropertyNameList() << "from" << "to"; static const PropertyNameList properties({"from", "to"});
return properties;
} }
} }

View File

@@ -734,15 +734,15 @@ bool QuickItemNodeInstance::hasAnchor(const PropertyName &name) const
static bool isValidAnchorName(const PropertyName &name) static bool isValidAnchorName(const PropertyName &name)
{ {
static PropertyNameList anchorNameList(PropertyNameList() << "anchors.top" static PropertyNameList anchorNameList({"anchors.top",
<< "anchors.left" "anchors.left",
<< "anchors.right" "anchors.right",
<< "anchors.bottom" "anchors.bottom",
<< "anchors.verticalCenter" "anchors.verticalCenter",
<< "anchors.horizontalCenter" "anchors.horizontalCenter",
<< "anchors.fill" "anchors.fill",
<< "anchors.centerIn" "anchors.centerIn",
<< "anchors.baseline"); "anchors.baseline"});
return anchorNameList.contains(name); return anchorNameList.contains(name);
} }

View File

@@ -392,7 +392,7 @@ QVariant fixResourcePaths(const QVariant &value)
if (QFileInfo(fixedPath).exists()) { if (QFileInfo(fixedPath).exists()) {
fixedPath.replace(QLatin1String("//"), QLatin1String("/")); fixedPath.replace(QLatin1String("//"), QLatin1String("/"));
fixedPath.replace(QLatin1Char('\\'), QLatin1Char('/')); fixedPath.replace(QLatin1Char('\\'), QLatin1Char('/'));
return QUrl(fixedPath); return QUrl::fromLocalFile(fixedPath);
} }
} }
} }

View File

@@ -105,7 +105,7 @@ QVariant fixResourcePaths(const QVariant &value)
if (QFileInfo(fixedPath).exists()) { if (QFileInfo(fixedPath).exists()) {
fixedPath.replace(QLatin1String("//"), QLatin1String("/")); fixedPath.replace(QLatin1String("//"), QLatin1String("/"));
fixedPath.replace(QLatin1Char('\\'), QLatin1Char('/')); fixedPath.replace(QLatin1Char('\\'), QLatin1Char('/'));
return QUrl(fixedPath); return QUrl::fromLocalFile(fixedPath);
} }
} }
} }

View File

@@ -34,6 +34,7 @@ ButtonRow {
ButtonRowButton { ButtonRowButton {
iconSource: "images/anchor-top.png" iconSource: "images/anchor-top.png"
tooltip: qsTr("Anchor item to the top.")
property bool topAnchored: anchorBackend.topAnchored property bool topAnchored: anchorBackend.topAnchored
onTopAnchoredChanged: { onTopAnchoredChanged: {
@@ -53,6 +54,7 @@ ButtonRow {
ButtonRowButton { ButtonRowButton {
iconSource: "images/anchor-bottom.png" iconSource: "images/anchor-bottom.png"
tooltip: qsTr("Anchor item to the bottom.")
property bool bottomAnchored: anchorBackend.bottomAnchored property bool bottomAnchored: anchorBackend.bottomAnchored
onBottomAnchoredChanged: { onBottomAnchoredChanged: {
@@ -73,6 +75,7 @@ ButtonRow {
ButtonRowButton { ButtonRowButton {
iconSource: "images/anchor-left.png" iconSource: "images/anchor-left.png"
tooltip: qsTr("Anchor item to the left.")
property bool leftAnchored: anchorBackend.leftAnchored property bool leftAnchored: anchorBackend.leftAnchored
onLeftAnchoredChanged: { onLeftAnchoredChanged: {
@@ -92,6 +95,7 @@ ButtonRow {
ButtonRowButton { ButtonRowButton {
iconSource: "images/anchor-right.png" iconSource: "images/anchor-right.png"
tooltip: qsTr("Anchor item to the right.")
property bool rightAnchored: anchorBackend.rightAnchored property bool rightAnchored: anchorBackend.rightAnchored
onRightAnchoredChanged: { onRightAnchoredChanged: {
@@ -116,6 +120,7 @@ ButtonRow {
ButtonRowButton { ButtonRowButton {
iconSource: "images/anchor-fill.png" iconSource: "images/anchor-fill.png"
tooltip: qsTr("Fill parent item.")
property bool isFilled: anchorBackend.isFilled property bool isFilled: anchorBackend.isFilled
onIsFilledChanged: { onIsFilledChanged: {
@@ -137,6 +142,7 @@ ButtonRow {
ButtonRowButton { ButtonRowButton {
iconSource: "images/anchor-vertical.png" iconSource: "images/anchor-vertical.png"
tooltip: qsTr("Anchor item vertically.")
property bool verticalCentered: anchorBackend.verticalCentered; property bool verticalCentered: anchorBackend.verticalCentered;
onVerticalCenteredChanged: { onVerticalCenteredChanged: {
@@ -158,6 +164,7 @@ ButtonRow {
ButtonRowButton { ButtonRowButton {
iconSource: "images/anchor-horizontal.png" iconSource: "images/anchor-horizontal.png"
tooltip: qsTr("Anchor item horizontally.")
property bool horizontalCentered: anchorBackend.horizontalCentered; property bool horizontalCentered: anchorBackend.horizontalCentered;
onHorizontalCenteredChanged: { onHorizontalCenteredChanged: {

View File

@@ -32,6 +32,8 @@ Controls.Label {
id: label id: label
property alias tooltip: toolTipArea.tooltip 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) width: Math.max(Math.min(240, parent.width - 220), 80)
color: "#eee" color: "#eee"

View File

@@ -126,6 +126,7 @@ RowLayout {
exclusive: true exclusive: true
ButtonRowButton { ButtonRowButton {
iconSource: verticalAnchor ? "../HelperWidgets/images/anchor-top.png" : "../HelperWidgets/images/anchor-left.png" 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: { onClicked: {
if (!invertRelativeTargets) if (!invertRelativeTargets)
sameEdgeButtonClicked(); sameEdgeButtonClicked();
@@ -136,12 +137,14 @@ RowLayout {
ButtonRowButton { ButtonRowButton {
iconSource: verticalAnchor ? "../HelperWidgets/images/anchor-vertical.png" : "../HelperWidgets/images/anchor-horizontal.png" 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(); onClicked: centerButtonClicked();
} }
ButtonRowButton { ButtonRowButton {
iconSource: verticalAnchor ? "../HelperWidgets/images/anchor-bottom.png" : "../HelperWidgets/images/anchor-right.png" 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: { onClicked: {
if (!invertRelativeTargets) if (!invertRelativeTargets)
oppositeEdgeButtonClicked(); oppositeEdgeButtonClicked();

View File

@@ -1,3 +0,0 @@
TEMPLATE = subdirs
SUBDIRS += %TestCaseName:l%

View File

@@ -0,0 +1,3 @@
TEMPLATE = subdirs
SUBDIRS += %{JS: '%{TestCaseName}'.toLowerCase()}

View File

@@ -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

View File

@@ -0,0 +1,31 @@
%{Cpp:LicenseTemplate}\
@if "%{TestFrameWork}" == "QtTest"
@if "%{RequireGUI}" == "true"
%{JS: QtSupport.qtIncludes([ 'QtGui/QApplication' ],
[ 'QtWidgets/QApplication' ]) }\
@else
%{JS: QtSupport.qtIncludes([ 'QtCore/QCoreApplication' ],
[ 'QtCore/QCoreApplication' ]) }\
@endif
// add necessary includes here
int main(int argc, char *argv[])
{
@if "%{RequireGUI}" == "true"
QApplication a(argc, argv);
@else
QCoreApplication a(argc, argv);
@endif
return a.exec();
}
@else
#include <iostream>
int main(int , char **)
{
std::cout << "Hello World!\\n";
return 0;
}
@endif

View File

@@ -1,13 +1,18 @@
@if "%RequireGUI%" == "true" @if "%{TestFrameWork}" == "QtTest"
@if "%{RequireGUI}" == "true"
QT += core gui QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
@else @else
QT -= gui QT -= gui
@endif
@else
CONFIG -= qt
@endif
CONFIG += console CONFIG += console
CONFIG -= app_bundle CONFIG -= app_bundle
@endif
TEMPLATE = app TEMPLATE = app
TARGET = %ProjectName%
SOURCES += main.%CppSourceSuffix% TARGET = %{ProjectName}
SOURCES += %{MainCppName}

View File

@@ -1,6 +1,6 @@
TEMPLATE = subdirs TEMPLATE = subdirs
@if "%BuildTests%" == "always" @if "%{BuildTests}" == "always"
SUBDIRS += src \ SUBDIRS += src \
tests tests
@else @else

View File

@@ -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

View File

@@ -0,0 +1,10 @@
%{Cpp:LicenseTemplate}\
#include "%{TestCaseFileWithHeaderSuffix}"
#include <gtest/gtest.h>
int main(int argc, char *argv[])
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,60 @@
%{Cpp:LicenseTemplate}\
#include <QtTest>
@if "%{RequireApplication}" == "true"
%{JS: QtSupport.qtIncludes([ 'QtCore/QCoreApplication' ],
[ 'QtCore/QCoreApplication' ]) }\
@endif
// add necessary includes here
class %{TestCaseName} : public QObject
{
Q_OBJECT
public:
%{TestCaseName}();
~%{TestCaseName}();
private slots:
@if "%{GenerateInitAndCleanup}" == "true"
void initTestCase();
void cleanupTestCase();
@endif
void test_case1();
};
%{TestCaseName}::%{TestCaseName}()
{
}
%{TestCaseName}::~%{TestCaseName}()
{
}
@if "%{GenerateInitAndCleanup}" == "true"
void %{TestCaseName}::initTestCase()
{
}
void %{TestCaseName}::cleanupTestCase()
{
}
@endif
void %{TestCaseName}::test_case1()
{
}
@if "%{RequireApplication}" == "true"
QTEST_MAIN(%{TestCaseName})
@else
QTEST_APPLESS_MAIN(%{TestCaseName})
@endif
#include "%{JS: 'tst_%{TestCaseName}.moc'.toLowerCase() }"

View File

@@ -0,0 +1,11 @@
%{Cpp:LicenseTemplate}\
#include <gtest/gtest.h>
#include <gmock/gmock-matchers.h>
using namespace testing;
TEST(%{TestCaseName}, %{TestSetName})
{
EXPECT_EQ(1, 1);
ASSERT_THAT(0, Eq(0));
}

View File

@@ -1,18 +0,0 @@
@if "%RequireGUI%" == "true"
#include <QApplication>
@else
#include <QCoreApplication>
@endif
// add necessary includes here
int main(int argc, char *argv[])
{
@if "%RequireGUI%" == "true"
QApplication a(argc, argv);
@else
QCoreApplication a(argc, argv);
@endif
return a.exec();
}

View File

@@ -1,14 +0,0 @@
QT += testlib
@if "%RequireGUI%" == "false"
QT -= gui
CONFIG += qt console warn_on depend_includepath testcase
CONFIG -= app_bundle
@else
QT += gui
CONFIG += qt warn_on depend_includepath testcase
@endif
TEMPLATE = app
SOURCES += tst_%TestCaseName:l%.%CppSourceSuffix%

View File

@@ -1,58 +0,0 @@
#include <QtTest>
@if "%RequireApplication%" == "true"
#include <QCoreApplication>
@endif
// add necessary includes here
class %TestCaseName% : public QObject
{
Q_OBJECT
public:
%TestCaseName%();
~%TestCaseName%();
private slots:
@if "%GenerateInitAndCleanup%" == "true"
void initTestCase();
void cleanupTestCase();
@endif
void test_case1();
};
%TestCaseName%::%TestCaseName%()
{
}
%TestCaseName%::~%TestCaseName%()
{
}
@if "%GenerateInitAndCleanup%" == "true"
void %TestCaseName%::initTestCase()
{
}
void %TestCaseName%::cleanupTestCase()
{
}
@endif
void %TestCaseName%::test_case1()
{
}
@if "%RequireApplication%" == "true"
QTEST_MAIN(%TestCaseName%)
@else
QTEST_APPLESS_MAIN(%TestCaseName%)
@endif
#include "tst_%TestCaseName:l%.moc"

View File

@@ -0,0 +1,241 @@
{
"version": 1,
"supportedProjectTypes": [ "Qt4ProjectManager.Qt4Project" ],
"id": "R.AutoTest",
"category": "H.Project",
"trDescription": "Creates a new project including auto test skeleton.",
"trDisplayName": "Auto Test Project",
"trDisplayCategory": "Other Project",
"icon": "autotest_24.png",
"featuresRequired": [ "QtSupport.Wizards.FeatureQt", "QtSupport.Wizards.FeatureDesktop" ],
"enabled": "%{JS: [ %{Plugins} ].indexOf('AutoTest') >= 0}",
"options":
[
{ "key": "ProFileName",
"value": "%{JS: Util.fileName('%{ProjectDirectory}/%{ProjectName}', 'pro')}"
},
{ "key": "IsTopLevelProject",
"value": "%{JS: !'%{Exists:ProjectExplorer.Profile.Ids}' }"
},
{ "key": "MainCppName",
"value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src') }"
},
{
"key": "TestCaseFileWithHeaderSuffix",
"value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++hdr') }"
},
{
"key": "TestCaseFileWithCppSuffix",
"value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++src') }"
}
],
"pages":
[
{
"trDisplayName": "Project Location",
"trShortTitle": "Location",
"typeId": "Project",
"data":
{
"trDescription": "This wizard creates a simple Qmake based project with additional auto test skeleton."
}
},
{
"trDisplayName": "Project and Test Information",
"trShortTitle": "Details",
"typeId": "Fields",
"data":
[
{
"name": "TestFrameWork",
"trDisplayName": "Test Framework:",
"type": "ComboBox",
"data":
{
"index": 0,
"items":
[
{
"trKey": "Qt Test",
"value": "QtTest"
},
{
"trKey": "Googletest",
"value": "GTest"
}
]
}
},
{
"name": "RequireGUI",
"trDisplayName": "GUI Application",
"visible": "%{JS: '%{TestFrameWork}' === 'QtTest'}",
"type": "CheckBox",
"data": {
"checked": false,
"checkedValue": "true",
"uncheckedValue": "false"
}
},
{
"name": "TestCaseName",
"trDisplayName": "Test Case Name:",
"mandatory": true,
"type": "LineEdit",
"data": { "validator": "^[a-zA-Z_0-9]+$" }
},
{
"name": "RequireApplication",
"trDisplayName": "Requires QApplication",
"visible": "%{JS: '%{TestFrameWork}' === 'QtTest'}",
"type": "CheckBox",
"data": {
"checked": false,
"checkedValue": "true",
"uncheckedValue": "false"
}
},
{
"name": "GenerateInitAndCleanup",
"trDisplayName": "Generate initialization and cleanup code",
"visible": "%{JS: '%{TestFrameWork}' === 'QtTest'}",
"type": "CheckBox",
"data": {
"checked": false,
"checkedValue": "true",
"uncheckedValue": "false"
}
},
{
"name": "TestSetName",
"trDisplayName": "Test Set Name:",
"visible": "%{JS: '%{TestFrameWork}' === 'GTest'}",
"type": "LineEdit",
"data": { "validator": "^[a-zA-Z0-9]+$" }
},
{
"name": "GTestCXX11",
"trDisplayName": "Enable C++11",
"visible": "%{JS: '%{TestFrameWork}' === 'GTest'}",
"type": "CheckBox",
"data": {
"checked": false,
"checkedValue": "true",
"uncheckedValue": "false"
}
},
{
"name": "BuildAutoTests",
"trDisplayName": "Build auto tests",
"type": "ComboBox",
"data":
{
"index": 0,
"items":
[
{
"trKey": "always",
"value": "always"
},
{
"trKey": "debug only",
"value": "debug"
}
]
}
},
{
"name": "GTestRepository",
"trDisplayName": "Googletest repository:",
"visible": "%{JS: '%{TestFrameWork}' === 'GTest'}",
"type": "PathChooser",
"data": {
"kind": "existingDirectory"
}
}
]
},
{
"trDisplayName": "Kit Selection",
"trShortTitle": "Kits",
"typeId": "Kits",
"enabled": "%{IsTopLevelProject}",
"data": { "projectFilePath": "%{ProFileName}" }
},
{
"trDisplayName": "Project Management",
"trShortTitle": "Summary",
"typeId": "Summary"
}
],
"generators":
[
{
"typeId": "File",
"data":
[
{
"source": "files/tmp.pro",
"target": "%{ProFileName}",
"openAsProject": true
},
{
"source": "files/src.pro",
"target": "src/src.pro",
"openInEditor": false
},
{
"source": "files/main.cpp",
"target": "src/%{MainCppName}",
"openInEditor": true
},
{
"source": "files/tests.pro",
"target": "tests/tests.pro",
"openInEditor": false
},
{
"source": "files/auto.pro",
"target": "tests/auto/auto.pro",
"openInEditor": false
},
{
"source": "files/gtest_dependency.pri",
"target": "tests/auto/gtest_dependency.pri",
"condition": "%{JS: '%{TestFrameWork}' == 'GTest'}",
"openInEditor": false
},
{
"source": "files/tst.pro",
"target": "%{JS: 'tests/auto/' + '%{TestCaseName}/%{TestCaseName}'.toLowerCase() + '.pro' }",
"openInEditor": false
},
{
"source": "files/tst_src.h",
"target": "%{JS: 'tests/auto/' + '%{TestCaseName}/'.toLowerCase() + '%{TestCaseFileWithHeaderSuffix}' }",
"condition": "%{JS: '%{TestFrameWork}' == 'GTest'}",
"openInEditor": true
},
{
"source": "files/tst_src.cpp",
"target": "%{JS: 'tests/auto/' + '%{TestCaseName}/'.toLowerCase() + '%{TestCaseFileWithCppSuffix}' }",
"condition": "%{JS: '%{TestFrameWork}' == 'QtTest'}",
"openInEditor": true
},
{
"source": "files/tst_main.cpp",
"target": "%{JS: 'tests/auto/' + '%{TestCaseName}'.toLowerCase() + '/%{MainCppName}' }",
"condition": "%{JS: '%{TestFrameWork}' == 'GTest'}",
"openInEditor": true
},
{
"source": "../projects/git.ignore",
"target": ".gitignore",
"condition": "%{JS: ( %{IsTopLevelProject} && '%{VersionControl}' === 'G.Git' )}"
}
]
}
]
}

View File

@@ -1,83 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
** 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.
**
****************************************************************************/
-->
<wizard version="1" kind="project"
class="qmakeproject" firstpage="10"
id="R.AutoTest" category="H.Project"
featuresRequired="QtSupport.Wizards.FeatureQt,QtSupport.Wizards.FeatureDesktop">
<!-- "Plugin.AutotestGenerator" as required feature would disable the template if the
plugin is disabled, but it fails on the kit selection page for having no valid kit -->
<icon>autotest_24.png</icon>
<description>Creates a new project including auto test skeleton.</description>
<displayname>Auto Test</displayname>;
<displaycategory>Other Project</displaycategory>
<files>
<file source="src.pro" target="src/src.pro" />
<file source="tests.pro" target="tests/tests.pro" />
<file source="auto.pro" target="tests/auto/auto.pro"/>
<file source="tst.pro" target="tests/auto/%TestCaseName:l%/%TestCaseName:l%.pro" />
<file source="tst_src.cpp"
target="tests/auto/%TestCaseName:l%/tst_%TestCaseName:l%.%CppSourceSuffix%"
openeditor="true"/>
<file source="main.cpp" target="src/main.%CppSourceSuffix%" openeditor="true" />
<file source="tmp.pro" target="%ProjectName:l%.pro" openproject="true" />
</files>
<!-- Create a 2nd wizard page with parameters -->
<fieldpagetitle>Project and Test Information</fieldpagetitle>
<fields>
<field name="RequireGUI">
<fieldcontrol class="QCheckBox" />
<fielddescription>GUI Application</fielddescription>
</field>
<field mandatory="true" name="TestCaseName">
<fieldcontrol class="QLineEdit" validator="^[a-zA-Z_0-9]+$"
/><!-- defaulttext="" /> -->
<fielddescription>Test Case Name:</fielddescription>
</field>
<field name="RequireApplication">
<fieldcontrol class="QCheckBox" />
<fielddescription>Requires QApplication</fielddescription>
</field>
<field name="GenerateInitAndCleanup">
<fieldcontrol class="QCheckBox" />
<fielddescription>Generate initialization and cleanup code</fielddescription>
</field>
<field name="BuildAutoTests">
<fieldcontrol class="QComboBox" defaultindex="0" >
<comboentries>
<comboentry value="always" >
<comboentrytext>always</comboentrytext>
</comboentry>
<comboentry value="debug" >
<comboentrytext>debug only</comboentrytext>
</comboentry>
</comboentries>
</fieldcontrol>
<fielddescription>Build auto tests</fielddescription>
</field>
</fields>
</wizard>

View File

@@ -112,10 +112,10 @@ bool OptionsParser::checkForTestOptions()
if (m_currentArg == QLatin1String(TEST_OPTION)) { if (m_currentArg == QLatin1String(TEST_OPTION)) {
if (nextToken(RequiredToken)) { if (nextToken(RequiredToken)) {
if (m_currentArg == QLatin1String("all")) { if (m_currentArg == QLatin1String("all")) {
foreach (PluginSpec *spec, m_pmPrivate->pluginSpecs) { m_pmPrivate->testSpecs =
if (spec && !m_pmPrivate->containsTestSpec(spec)) Utils::transform(m_pmPrivate->loadQueue(), [](PluginSpec *spec) {
m_pmPrivate->testSpecs.append(PluginManagerPrivate::TestSpec(spec)); return PluginManagerPrivate::TestSpec(spec);
} });
} else { } else {
QStringList args = m_currentArg.split(QLatin1Char(',')); QStringList args = m_currentArg.split(QLatin1Char(','));
const QString pluginName = args.takeFirst(); const QString pluginName = args.takeFirst();

View File

@@ -29,6 +29,8 @@
#include "pluginmanager.h" #include "pluginmanager.h"
#include "pluginspec.h" #include "pluginspec.h"
#include <utils/algorithm.h>
#include <QDir> #include <QDir>
#include <QRegExp> #include <QRegExp>
@@ -88,23 +90,6 @@ void PluginDetailsView::update(PluginSpec *spec)
const QString platformString = tr("%1 (current: \"%2\")").arg(pluginPlatformString, const QString platformString = tr("%1 (current: \"%2\")").arg(pluginPlatformString,
PluginManager::platformName()); PluginManager::platformName());
m_ui->platforms->setText(platformString); m_ui->platforms->setText(platformString);
QStringList depStrings; const QStringList depStrings = Utils::transform<QList>(spec->dependencies(), &PluginDependency::toString);
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);
}
m_ui->dependencies->addItems(depStrings); m_ui->dependencies->addItems(depStrings);
} }

View File

@@ -369,12 +369,10 @@ void PluginManager::loadPlugins()
*/ */
bool PluginManager::hasError() bool PluginManager::hasError()
{ {
foreach (PluginSpec *spec, plugins()) { return Utils::anyOf(plugins(), [](PluginSpec *spec) {
// only show errors on startup if plugin is enabled. // only show errors on startup if plugin is enabled.
if (spec->hasError() && spec->isEffectivelyEnabled()) return spec->hasError() && spec->isEffectivelyEnabled();
return true; });
}
return false;
} }
/*! /*!
@@ -382,19 +380,11 @@ bool PluginManager::hasError()
*/ */
QSet<PluginSpec *> PluginManager::pluginsRequiringPlugin(PluginSpec *spec) QSet<PluginSpec *> PluginManager::pluginsRequiringPlugin(PluginSpec *spec)
{ {
QSet<PluginSpec *> dependingPlugins; QSet<PluginSpec *> 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.insert(spec);
foreach (PluginSpec *checkSpec, d->loadQueue()) {
QHashIterator<PluginDependency, PluginSpec *> 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
}
}
} }
dependingPlugins.remove(spec); dependingPlugins.remove(spec);
return dependingPlugins; return dependingPlugins;
@@ -665,9 +655,7 @@ bool PluginManager::parseOptions(const QStringList &args,
static inline void indent(QTextStream &str, int indent) static inline void indent(QTextStream &str, int indent)
{ {
const QChar blank = QLatin1Char(' '); str << QString(indent, ' ');
for (int i = 0 ; i < indent; i++)
str << blank;
} }
static inline void formatOption(QTextStream &str, static inline void formatOption(QTextStream &str,
@@ -927,12 +915,9 @@ void PluginManagerPrivate::stopAll()
*/ */
void PluginManagerPrivate::deleteAll() void PluginManagerPrivate::deleteAll()
{ {
QList<PluginSpec *> queue = loadQueue(); Utils::reverseForeach(loadQueue(), [this](PluginSpec *spec) {
QListIterator<PluginSpec *> it(queue); loadPlugin(spec, PluginSpec::Deleted);
it.toBack(); });
while (it.hasPrevious()) {
loadPlugin(it.previous(), PluginSpec::Deleted);
}
} }
#ifdef WITH_TESTS #ifdef WITH_TESTS
@@ -1225,10 +1210,7 @@ void PluginManagerPrivate::loadPlugins()
foreach (PluginSpec *spec, queue) { foreach (PluginSpec *spec, queue) {
loadPlugin(spec, PluginSpec::Initialized); loadPlugin(spec, PluginSpec::Initialized);
} }
QListIterator<PluginSpec *> it(queue); Utils::reverseForeach(queue, [this](PluginSpec *spec) {
it.toBack();
while (it.hasPrevious()) {
PluginSpec *spec = it.previous();
loadPlugin(spec, PluginSpec::Running); loadPlugin(spec, PluginSpec::Running);
if (spec->state() == PluginSpec::Running) { if (spec->state() == PluginSpec::Running) {
delayedInitializeQueue.append(spec); delayedInitializeQueue.append(spec);
@@ -1236,7 +1218,7 @@ void PluginManagerPrivate::loadPlugins()
// Plugin initialization failed, so cleanup after it // Plugin initialization failed, so cleanup after it
spec->d->kill(); spec->d->kill();
} }
} });
emit q->pluginsChanged(); emit q->pluginsChanged();
delayedInitializeTimer = new QTimer; delayedInitializeTimer = new QTimer;
@@ -1420,6 +1402,21 @@ void PluginManagerPrivate::setPluginPaths(const QStringList &paths)
readPluginPaths(); 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 \internal
*/ */
@@ -1430,24 +1427,10 @@ void PluginManagerPrivate::readPluginPaths()
pluginSpecs.clear(); pluginSpecs.clear();
pluginCategories.clear(); pluginCategories.clear();
QStringList pluginFiles; auto defaultCollection = new PluginCollection(QString());
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());
pluginCategories.insert(QString(), defaultCollection); pluginCategories.insert(QString(), defaultCollection);
foreach (const QString &pluginFile, pluginFiles) { foreach (const QString &pluginFile, pluginFiles(pluginPaths)) {
PluginSpec *spec = new PluginSpec; PluginSpec *spec = new PluginSpec;
if (!spec->d->read(pluginFile)) { // not a Qt Creator plugin if (!spec->d->read(pluginFile)) { // not a Qt Creator plugin
delete spec; delete spec;
@@ -1492,12 +1475,9 @@ void PluginManagerPrivate::resolveDependencies()
spec->d->resolveDependencies(pluginSpecs); spec->d->resolveDependencies(pluginSpecs);
} }
QListIterator<PluginSpec *> it(loadQueue()); Utils::reverseForeach(loadQueue(), [](PluginSpec *spec) {
it.toBack();
while (it.hasPrevious()) {
PluginSpec *spec = it.previous();
spec->d->enableDependenciesIndirectly(); spec->d->enableDependenciesIndirectly();
} });
} }
void PluginManagerPrivate::enableOnlyTestedSpecs() 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 PluginSpec *PluginManagerPrivate::pluginForOption(const QString &option, bool *requiresArgument) const
{ {
// Look in the plugins for an option // Look in the plugins for an option
*requiresArgument = false; *requiresArgument = false;
foreach (PluginSpec *ps, pluginSpecs) { foreach (PluginSpec *spec, pluginSpecs) {
const PluginSpec::PluginArgumentDescriptions pargs = ps->argumentDescriptions(); PluginArgumentDescription match = Utils::findOrDefault(spec->argumentDescriptions(),
if (!pargs.empty()) { [option](PluginArgumentDescription pad) {
foreach (PluginArgumentDescription pad, pargs) { return pad.name == option;
if (pad.name == option) { });
*requiresArgument = !pad.parameter.isEmpty(); if (!match.name.isEmpty()) {
return ps; *requiresArgument = !match.parameter.isEmpty();
} return spec;
}
} }
} }
return 0; return 0;
@@ -1550,10 +1529,7 @@ PluginSpec *PluginManagerPrivate::pluginForOption(const QString &option, bool *r
PluginSpec *PluginManagerPrivate::pluginByName(const QString &name) const PluginSpec *PluginManagerPrivate::pluginByName(const QString &name) const
{ {
foreach (PluginSpec *spec, pluginSpecs) return Utils::findOrDefault(pluginSpecs, [name](PluginSpec *spec) { return spec->name() == name; });
if (spec->name() == name)
return spec;
return 0;
} }
void PluginManagerPrivate::initProfiling() void PluginManagerPrivate::initProfiling()
@@ -1586,22 +1562,19 @@ void PluginManagerPrivate::profilingReport(const char *what, const PluginSpec *s
void PluginManagerPrivate::profilingSummary() const void PluginManagerPrivate::profilingSummary() const
{ {
if (!m_profileTimer.isNull()) { if (!m_profileTimer.isNull()) {
typedef QMultiMap<int, const PluginSpec *> Sorter; QMultiMap<int, const PluginSpec *> sorter;
Sorter sorter;
int total = 0; int total = 0;
QHash<const PluginSpec *, int>::ConstIterator it1 = m_profileTotal.constBegin(); auto totalEnd = m_profileTotal.constEnd();
QHash<const PluginSpec *, int>::ConstIterator et1 = m_profileTotal.constEnd(); for (auto it = m_profileTotal.constBegin(); it != totalEnd; ++it) {
for (; it1 != et1; ++it1) { sorter.insert(it.value(), it.key());
sorter.insert(it1.value(), it1.key()); total += it.value();
total += it1.value();
} }
Sorter::ConstIterator it2 = sorter.constBegin(); auto sorterEnd = sorter.constEnd();
Sorter::ConstIterator et2 = sorter.constEnd(); for (auto it = sorter.constBegin(); it != sorterEnd; ++it)
for (; it2 != et2; ++it2) qDebug("%-22s %8dms ( %5.2f%% )", qPrintable(it.value()->name()),
qDebug("%-22s %8dms ( %5.2f%% )", qPrintable(it2.value()->name()), it.key(), 100.0 * it.key() / total);
it2.key(), 100.0 * it2.key() / total);
qDebug("Total: %8dms", total); qDebug("Total: %8dms", total);
} }
} }
@@ -1693,12 +1666,9 @@ bool PluginManager::isInitializationDone()
QObject *PluginManager::getObjectByName(const QString &name) QObject *PluginManager::getObjectByName(const QString &name)
{ {
QReadLocker lock(&d->m_lock); QReadLocker lock(&d->m_lock);
QList<QObject *> all = allObjects(); return Utils::findOrDefault(allObjects(), [&name](const QObject *obj) {
foreach (QObject *obj, all) { return obj->objectName() == name;
if (obj->objectName() == name) });
return obj;
}
return 0;
} }
/*! /*!
@@ -1711,10 +1681,7 @@ QObject *PluginManager::getObjectByClassName(const QString &className)
{ {
const QByteArray ba = className.toUtf8(); const QByteArray ba = className.toUtf8();
QReadLocker lock(&d->m_lock); QReadLocker lock(&d->m_lock);
QList<QObject *> all = allObjects(); return Utils::findOrDefault(allObjects(), [&ba](const QObject *obj) {
foreach (QObject *obj, all) { return obj->inherits(ba.constData());
if (obj->inherits(ba.constData())) });
return obj;
}
return 0;
} }

View File

@@ -134,7 +134,6 @@ public:
bool m_isInitializationDone = false; bool m_isInitializationDone = false;
private: private:
PluginCollection *defaultCollection;
PluginManager *q; PluginManager *q;
void nextDelayedInitialize(); void nextDelayedInitialize();

View File

@@ -30,6 +30,8 @@
#include "iplugin_p.h" #include "iplugin_p.h"
#include "pluginmanager.h" #include "pluginmanager.h"
#include <utils/algorithm.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
@@ -146,6 +148,24 @@ bool PluginDependency::operator==(const PluginDependency &other) const
return name == other.name && version == other.version && type == other.type; return name == other.name && version == other.version && type == other.type;
} }
static QString typeString(PluginDependency::Type type)
{
switch (type) {
case PluginDependency::Optional:
return QString(", optional");
case PluginDependency::Test:
return QString(", test");
case PluginDependency::Required:
default:
return QString();
}
}
QString PluginDependency::toString() const
{
return name + " (" + version + typeString(type) + ")";
}
/*! /*!
\internal \internal
*/ */
@@ -446,6 +466,14 @@ QHash<PluginDependency, PluginSpec *> PluginSpec::dependencySpecs() const
return d->dependencySpecs; return d->dependencySpecs;
} }
bool PluginSpec::requiresAny(const QSet<PluginSpec *> &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================== //==========PluginSpecPrivate==================
namespace { namespace {
@@ -877,14 +905,9 @@ bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs)
} }
QHash<PluginDependency, PluginSpec *> resolvedDependencies; QHash<PluginDependency, PluginSpec *> resolvedDependencies;
foreach (const PluginDependency &dependency, dependencies) { foreach (const PluginDependency &dependency, dependencies) {
PluginSpec *found = 0; PluginSpec * const found = Utils::findOrDefault(specs, [&dependency](PluginSpec *spec) {
return spec->provides(dependency.name, dependency.version);
foreach (PluginSpec *spec, specs) { });
if (spec->provides(dependency.name, dependency.version)) {
found = spec;
break;
}
}
if (!found) { if (!found) {
if (dependency.type == PluginDependency::Required) { if (dependency.type == PluginDependency::Required) {
hasError = true; hasError = true;

View File

@@ -63,6 +63,7 @@ struct EXTENSIONSYSTEM_EXPORT PluginDependency
QString version; QString version;
Type type; Type type;
bool operator==(const PluginDependency &other) const; bool operator==(const PluginDependency &other) const;
QString toString() const;
}; };
uint qHash(const ExtensionSystem::PluginDependency &value); uint qHash(const ExtensionSystem::PluginDependency &value);
@@ -118,6 +119,7 @@ public:
// dependency specs, valid after 'Resolved' state is reached // dependency specs, valid after 'Resolved' state is reached
QHash<PluginDependency, PluginSpec *> dependencySpecs() const; QHash<PluginDependency, PluginSpec *> dependencySpecs() const;
bool requiresAny(const QSet<PluginSpec *> &plugins) const;
// linked plugin instance, valid after 'Loaded' state is reached // linked plugin instance, valid after 'Loaded' state is reached
IPlugin *plugin() const; IPlugin *plugin() const;

View File

@@ -820,6 +820,9 @@ void Check::visitQmlObject(Node *ast, UiQualifiedId *typeId,
const QString typeName = getRightMostIdentifier(typeId)->name.toString(); const QString typeName = getRightMostIdentifier(typeId)->name.toString();
if (!m_typeStack.isEmpty() && m_typeStack.last() == QLatin1String("State"))
addMessage(StateCannotHaveChildItem, typeErrorLocation, typeName);
if (checkTypeForDesignerSupport(typeId)) if (checkTypeForDesignerSupport(typeId))
addMessage(WarnUnsupportedTypeInVisualDesigner, typeErrorLocation, typeName); addMessage(WarnUnsupportedTypeInVisualDesigner, typeErrorLocation, typeName);

View File

@@ -104,12 +104,13 @@ ModelManagerInterface::ModelManagerInterface(QObject *parent)
m_updateCppQmlTypesTimer = new QTimer(this); m_updateCppQmlTypesTimer = new QTimer(this);
m_updateCppQmlTypesTimer->setInterval(1000); m_updateCppQmlTypesTimer->setInterval(1000);
m_updateCppQmlTypesTimer->setSingleShot(true); 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 = new QTimer(this);
m_asyncResetTimer->setInterval(15000); m_asyncResetTimer->setInterval(15000);
m_asyncResetTimer->setSingleShot(true); m_asyncResetTimer->setSingleShot(true);
connect(m_asyncResetTimer, SIGNAL(timeout()), SLOT(resetCodeModel())); connect(m_asyncResetTimer, &QTimer::timeout, this, &ModelManagerInterface::resetCodeModel);
qRegisterMetaType<QmlJS::Document::Ptr>("QmlJS::Document::Ptr"); qRegisterMetaType<QmlJS::Document::Ptr>("QmlJS::Document::Ptr");
qRegisterMetaType<QmlJS::LibraryInfo>("QmlJS::LibraryInfo"); qRegisterMetaType<QmlJS::LibraryInfo>("QmlJS::LibraryInfo");

View File

@@ -205,9 +205,11 @@ public:
PathsAndLanguages paths, PathsAndLanguages paths,
ModelManagerInterface *modelManager, ModelManagerInterface *modelManager,
bool emitDocChangedOnDisk, bool libOnly = true); bool emitDocChangedOnDisk, bool libOnly = true);
public slots:
virtual void resetCodeModel(); virtual void resetCodeModel();
void removeProjectInfo(ProjectExplorer::Project *project); void removeProjectInfo(ProjectExplorer::Project *project);
void maybeQueueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc);
signals: signals:
void documentUpdated(QmlJS::Document::Ptr doc); void documentUpdated(QmlJS::Document::Ptr doc);
void documentChangedOnDisk(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 libraryInfoUpdated(const QString &path, const QmlJS::LibraryInfo &info);
void projectInfoUpdated(const ProjectInfo &pinfo); void projectInfoUpdated(const ProjectInfo &pinfo);
void projectPathChanged(const QString &projectPath); 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: protected:
Q_INVOKABLE void queueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc, bool scan);
Q_INVOKABLE void asyncReset();
virtual void startCppQmlTypeUpdate();
QMutex *mutex() const; QMutex *mutex() const;
virtual QHash<QString,Dialect> languageForSuffix() const; virtual QHash<QString,Dialect> languageForSuffix() const;
virtual void writeMessageInternal(const QString &msg) const; virtual void writeMessageInternal(const QString &msg) const;

View File

@@ -51,8 +51,8 @@ Utils::FileSystemWatcher *PluginDumper::pluginWatcher()
if (!m_pluginWatcher) { if (!m_pluginWatcher) {
m_pluginWatcher = new Utils::FileSystemWatcher(this); m_pluginWatcher = new Utils::FileSystemWatcher(this);
m_pluginWatcher->setObjectName(QLatin1String("PluginDumperWatcher")); m_pluginWatcher->setObjectName(QLatin1String("PluginDumperWatcher"));
connect(m_pluginWatcher, SIGNAL(fileChanged(QString)), connect(m_pluginWatcher, &Utils::FileSystemWatcher::fileChanged,
this, SLOT(pluginChanged(QString))); this, &PluginDumper::pluginChanged);
} }
return m_pluginWatcher; return m_pluginWatcher;
} }
@@ -509,8 +509,10 @@ void PluginDumper::runQmlDump(const QmlJS::ModelManagerInterface::ProjectInfo &i
{ {
QProcess *process = new QProcess(this); QProcess *process = new QProcess(this);
process->setEnvironment(info.qmlDumpEnvironment.toStringList()); process->setEnvironment(info.qmlDumpEnvironment.toStringList());
connect(process, SIGNAL(finished(int)), SLOT(qmlPluginTypeDumpDone(int))); connect(process, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
connect(process, SIGNAL(error(QProcess::ProcessError)), SLOT(qmlPluginTypeDumpError(QProcess::ProcessError))); this, &PluginDumper::qmlPluginTypeDumpDone);
connect(process, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error),
this, &PluginDumper::qmlPluginTypeDumpError);
process->start(info.qmlDumpPath, arguments); process->start(info.qmlDumpPath, arguments);
m_runningQmldumps.insert(process, importPath); m_runningQmldumps.insert(process, importPath);
} }

View File

@@ -52,13 +52,13 @@ public:
void scheduleRedumpPlugins(); void scheduleRedumpPlugins();
void scheduleMaybeRedumpBuiltins(const QmlJS::ModelManagerInterface::ProjectInfo &info); void scheduleMaybeRedumpBuiltins(const QmlJS::ModelManagerInterface::ProjectInfo &info);
private slots: private:
void onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectInfo &info, Q_INVOKABLE void onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectInfo &info,
bool force = false); bool force = false);
void onLoadPluginTypes(const QString &libraryPath, const QString &importPath, Q_INVOKABLE void onLoadPluginTypes(const QString &libraryPath, const QString &importPath,
const QString &importUri, const QString &importVersion); const QString &importUri, const QString &importVersion);
void dumpBuiltins(const QmlJS::ModelManagerInterface::ProjectInfo &info); Q_INVOKABLE void dumpBuiltins(const QmlJS::ModelManagerInterface::ProjectInfo &info);
void dumpAllPlugins(); Q_INVOKABLE void dumpAllPlugins();
void qmlPluginTypeDumpDone(int exitCode); void qmlPluginTypeDumpDone(int exitCode);
void qmlPluginTypeDumpError(QProcess::ProcessError error); void qmlPluginTypeDumpError(QProcess::ProcessError error);
void pluginChanged(const QString &pluginLibrary); void pluginChanged(const QString &pluginLibrary);

View File

@@ -235,6 +235,8 @@ StaticAnalysisMessages::StaticAnalysisMessages()
tr("States are only supported in the root item in a Qt Quick UI form.")); tr("States are only supported in the root item in a Qt Quick UI form."));
newMsg(ErrReferenceToParentItemNotSupportedInQmlUi, Error, newMsg(ErrReferenceToParentItemNotSupportedInQmlUi, Error,
tr("Referencing the parent of the root item is not supported in a Qt Quick UI form.")); 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 } // anonymous namespace

View File

@@ -88,6 +88,7 @@ enum Type
HintExtraParentheses = 123, HintExtraParentheses = 123,
MaybeWarnEqualityTypeCoercion = 126, MaybeWarnEqualityTypeCoercion = 126,
WarnConfusingExpressionStatement = 127, WarnConfusingExpressionStatement = 127,
StateCannotHaveChildItem = 128,
HintDeclarationsShouldBeAtStartOfFunction = 201, HintDeclarationsShouldBeAtStartOfFunction = 201,
HintOneStatementPerLine = 202, HintOneStatementPerLine = 202,
WarnImperativeCodeNotEditableInVisualDesigner = 203, WarnImperativeCodeNotEditableInVisualDesigner = 203,

View File

@@ -418,4 +418,24 @@ inline void sort(Container &c, Predicate p)
std::sort(c.begin(), c.end(), p); std::sort(c.begin(), c.end(), p);
} }
//////////////////
// reverseForeach
/////////////////
template <typename Container, typename Op>
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
}
} }

View File

@@ -153,13 +153,16 @@ public:
m_floatButton = new DockWidgetTitleButton(this); m_floatButton = new DockWidgetTitleButton(this);
m_floatButton->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q)); 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 = new DockWidgetTitleButton(this);
m_closeButton->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q)); 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->setAccessibleName(QDockWidget::tr("Close"));
m_closeButton->setAccessibleDescription(QDockWidget::tr("Closes the dock widget")); m_closeButton->setAccessibleDescription(QDockWidget::tr("Closes the dock widget"));
#endif
setActive(false); setActive(false);

View File

@@ -306,24 +306,24 @@ void PathChooser::setEnvironment(const Environment &env)
} }
} }
QString PathChooser::path() const
{
return d->expandedPath(rawPath());
}
QString PathChooser::rawPath() const QString PathChooser::rawPath() const
{ {
return rawFileName().toString(); return rawFileName().toString();
} }
QString PathChooser::path() const
{
return fileName().toString();
}
FileName PathChooser::rawFileName() 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 FileName PathChooser::fileName() const
{ {
return FileName::fromString(path()); return FileName::fromUserInput(d->expandedPath(rawFileName().toString()));
} }
// FIXME: try to remove again // FIXME: try to remove again

View File

@@ -377,7 +377,7 @@ Utils::SynchronousProcessResponse ShellCommand::runCommand(const Utils::FileName
process.setTimeOutMessageBoxEnabled(true); process.setTimeOutMessageBoxEnabled(true);
// Run! // Run!
response = process.run(binary.toString(), arguments); response = process.runBlocking(binary.toString(), arguments);
} }
if (!d->m_aborted) { if (!d->m_aborted) {

View File

@@ -297,12 +297,12 @@ void SynchronousProcess::setTimeoutS(int timeoutS)
if (timeoutS > 0) if (timeoutS > 0)
d->m_maxHangTimerCount = qMax(2, timeoutS); d->m_maxHangTimerCount = qMax(2, timeoutS);
else else
d->m_maxHangTimerCount = INT_MAX; d->m_maxHangTimerCount = INT_MAX / 1000;
} }
int SynchronousProcess::timeoutS() const 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) 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); QTC_ASSERT(d->m_process.state() == QProcess::NotRunning, return d->m_result);
d->m_result.exitCode = d->m_process.exitCode(); 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) if (d->m_process.exitStatus() != QProcess::NormalExit)
d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally; d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally;
else else

View File

@@ -41,7 +41,7 @@ public:
TreeItem(); TreeItem();
virtual ~TreeItem(); virtual ~TreeItem();
virtual TreeItem *parent() const { return m_parent; } TreeItem *parent() const { return m_parent; }
virtual TreeItem *child(int pos) const; virtual TreeItem *child(int pos) const;
virtual int rowCount() const; virtual int rowCount() const;
@@ -148,7 +148,7 @@ private:
}; };
// A TreeItem with children all of the same type. // A TreeItem with children all of the same type.
template <class ChildType> template <class ChildType, class ParentType = TreeItem>
class TypedTreeItem : public TreeItem class TypedTreeItem : public TreeItem
{ {
public: public:
@@ -175,6 +175,10 @@ public:
ChildType *findFirstLevelChild(Predicate pred) const { ChildType *findFirstLevelChild(Predicate pred) const {
return TreeItem::findFirstLevelChild<ChildType *, Predicate>(pred); return TreeItem::findFirstLevelChild<ChildType *, Predicate>(pred);
} }
ParentType *parent() const {
return static_cast<ParentType *>(TreeItem::parent());
}
}; };
class QTCREATOR_UTILS_EXPORT StaticTreeItem : public TreeItem class QTCREATOR_UTILS_EXPORT StaticTreeItem : public TreeItem
@@ -241,9 +245,9 @@ protected:
// A multi-level model with uniform types per level. // A multi-level model with uniform types per level.
// All items below second level have to have identitical types. // All items below second level have to have identitical types.
template <class FirstLevelItem, template <class RootItem,
class SecondLevelItem = FirstLevelItem, class FirstLevelItem,
class RootItem = TreeItem> class SecondLevelItem = FirstLevelItem>
class LeveledTreeModel : public TreeModel class LeveledTreeModel : public TreeModel
{ {
public: public:

View File

@@ -1,10 +1,13 @@
include(../../qtcreatorplugin.pri) include(../../qtcreatorplugin.pri)
DEFINES += BINEDITOR_LIBRARY
HEADERS += bineditorplugin.h \ HEADERS += bineditorplugin.h \
bineditor.h \ bineditorwidget.h \
bineditorconstants.h \ bineditorconstants.h \
bineditor_global.h \
markup.h markup.h
SOURCES += bineditorplugin.cpp \ SOURCES += bineditorplugin.cpp \
bineditor.cpp \ bineditorwidget.cpp \
markup.cpp markup.cpp

View File

@@ -11,9 +11,10 @@ QtcPlugin {
Depends { name: "TextEditor" } Depends { name: "TextEditor" }
files: [ files: [
"bineditor.cpp", "bineditorwidget.cpp",
"bineditor.h", "bineditorwidget.h",
"bineditorconstants.h", "bineditorconstants.h",
"bineditor_global.h",
"bineditorplugin.cpp", "bineditorplugin.cpp",
"bineditorplugin.h", "bineditorplugin.h",
"markup.cpp", "markup.cpp",

View File

@@ -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 <QtGlobal>
#if defined(BINEDITOR_LIBRARY)
# define BINEDITOR_EXPORT Q_DECL_EXPORT
#else
# define BINEDITOR_EXPORT Q_DECL_IMPORT
#endif

View File

@@ -24,7 +24,7 @@
****************************************************************************/ ****************************************************************************/
#include "bineditorplugin.h" #include "bineditorplugin.h"
#include "bineditor.h" #include "bineditorwidget.h"
#include "bineditorconstants.h" #include "bineditorconstants.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>

View File

@@ -23,7 +23,7 @@
** **
****************************************************************************/ ****************************************************************************/
#include "bineditor.h" #include "bineditorwidget.h"
#include <texteditor/fontsettings.h> #include <texteditor/fontsettings.h>
#include <texteditor/texteditorconstants.h> #include <texteditor/texteditorconstants.h>

View File

@@ -25,6 +25,7 @@
#pragma once #pragma once
#include "bineditor_global.h"
#include "markup.h" #include "markup.h"
#include <QBasicTimer> #include <QBasicTimer>
@@ -46,7 +47,7 @@ namespace TextEditor { class FontSettings; }
namespace BinEditor { namespace BinEditor {
class BinEditorWidget : public QAbstractScrollArea class BINEDITOR_EXPORT BinEditorWidget : public QAbstractScrollArea
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool modified READ isModified WRITE setModified DESIGNABLE false) Q_PROPERTY(bool modified READ isModified WRITE setModified DESIGNABLE false)

View File

@@ -71,9 +71,11 @@ bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *)
mbm->menu()->setTitle(tr("&Bookmarks")); mbm->menu()->setTitle(tr("&Bookmarks"));
mtools->addMenu(mbm); mtools->addMenu(mbm);
const Context editorManagerContext(Core::Constants::C_EDITORMANAGER);
//Toggle //Toggle
m_toggleAction = new QAction(tr("Toggle Bookmark"), this); 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"))); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+M") : tr("Ctrl+M")));
mbm->addAction(cmd); mbm->addAction(cmd);
@@ -81,13 +83,13 @@ bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *)
//Previous //Previous
m_prevAction = new QAction(tr("Previous Bookmark"), this); 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+,"))); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+,") : tr("Ctrl+,")));
mbm->addAction(cmd); mbm->addAction(cmd);
//Next //Next
m_nextAction = new QAction(tr("Next Bookmark"), this); 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+."))); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+.") : tr("Ctrl+.")));
mbm->addAction(cmd); mbm->addAction(cmd);
@@ -95,12 +97,12 @@ bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *)
//Previous Doc //Previous Doc
m_docPrevAction = new QAction(tr("Previous Bookmark in Document"), this); 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); mbm->addAction(cmd);
//Next Doc //Next Doc
m_docNextAction = new QAction(tr("Next Bookmark in Document"), this); 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); mbm->addAction(cmd);
m_editBookmarkAction = new QAction(tr("Edit Bookmark"), this); m_editBookmarkAction = new QAction(tr("Edit Bookmark"), this);

View File

@@ -613,7 +613,7 @@ void ClangCompletionAssistProcessor::handleAvailableCompletions(
QTC_CHECK(m_completions.isEmpty()); QTC_CHECK(m_completions.isEmpty());
m_completions = toAssistProposalItems(completions); m_completions = toAssistProposalItems(completions);
if (m_addSnippets) if (m_addSnippets && !m_completions.isEmpty())
addSnippets(); addSnippets();
setAsyncProposalAvailable(createProposal(neededCorrection)); setAsyncProposalAvailable(createProposal(neededCorrection));

View File

@@ -932,18 +932,28 @@ void ClangCodeCompletionTest::testCompleteConstructorAndFallbackToGlobalCompleti
QVERIFY(!hasSnippet(t.proposal, "class")); 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() 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", ProjectLessCompletionTest t("dotToArrowCorrection.cpp",
QStringLiteral(".")); QStringLiteral(".")); // See above "Explicitly Inserting The Dot"
QVERIFY(hasItem(t.proposal, "member")); 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() void ClangCodeCompletionTest::testCompleteProjectDependingCode()
{ {
const TestDocument testDocument("completionWithProject.cpp"); const TestDocument testDocument("completionWithProject.cpp");

View File

@@ -48,6 +48,7 @@ private slots:
void testCompleteConstructorAndFallbackToGlobalCompletion(); void testCompleteConstructorAndFallbackToGlobalCompletion();
void testCompleteWithDotToArrowCorrection(); void testCompleteWithDotToArrowCorrection();
void testDontCompleteWithDotToArrowCorrectionForFloats();
void testCompleteProjectDependingCode(); void testCompleteProjectDependingCode();
void testCompleteProjectDependingCodeAfterChangingProject(); void testCompleteProjectDependingCodeAfterChangingProject();

View File

@@ -22,5 +22,6 @@
<file>objc_messages_3.mm</file> <file>objc_messages_3.mm</file>
<file>preprocessorKeywordsCompletion.cpp</file> <file>preprocessorKeywordsCompletion.cpp</file>
<file>dotToArrowCorrection.cpp</file> <file>dotToArrowCorrection.cpp</file>
<file>noDotToArrowCorrectionForFloats.cpp</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -0,0 +1,4 @@
void f()
{
0 /* COMPLETE HERE */
}

View File

@@ -49,7 +49,6 @@
#include <QDateTime> #include <QDateTime>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QFileSystemWatcher>
#include <QMessageBox> #include <QMessageBox>
#include <QRegularExpression> #include <QRegularExpression>
#include <QSet> #include <QSet>
@@ -97,20 +96,14 @@ static QStringList toArguments(const CMakeConfig &config, const ProjectExplorer:
// -------------------------------------------------------------------- // --------------------------------------------------------------------
BuildDirManager::BuildDirManager(CMakeBuildConfiguration *bc) : BuildDirManager::BuildDirManager(CMakeBuildConfiguration *bc) :
m_buildConfiguration(bc), m_buildConfiguration(bc)
m_watcher(new QFileSystemWatcher(this))
{ {
QTC_ASSERT(bc, return); QTC_ASSERT(bc, return);
m_projectName = sourceDirectory().fileName(); m_projectName = sourceDirectory().fileName();
m_reparseTimer.setSingleShot(true); m_reparseTimer.setSingleShot(true);
m_reparseTimer.setInterval(5000); m_reparseTimer.setInterval(2000);
connect(&m_reparseTimer, &QTimer::timeout, this, &BuildDirManager::parse); connect(&m_reparseTimer, &QTimer::timeout, this, &BuildDirManager::parse);
connect(m_watcher, &QFileSystemWatcher::fileChanged, this, [this]() {
if (!isParsing())
m_reparseTimer.start();
});
} }
BuildDirManager::~BuildDirManager() BuildDirManager::~BuildDirManager()
@@ -157,6 +150,18 @@ bool BuildDirManager::isParsing() const
return false; 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() void BuildDirManager::forceReparse()
{ {
if (m_buildConfiguration->target()->activeBuildConfiguration() != m_buildConfiguration) if (m_buildConfiguration->target()->activeBuildConfiguration() != m_buildConfiguration)
@@ -180,13 +185,8 @@ void BuildDirManager::resetData()
m_cmakeCache.clear(); m_cmakeCache.clear();
m_projectName.clear(); m_projectName.clear();
m_buildTargets.clear(); m_buildTargets.clear();
m_watchedFiles.clear();
qDeleteAll(m_files); qDeleteAll(m_files);
m_files.clear(); m_files.clear();
const QStringList watchedFiles = m_watcher->files();
if (!watchedFiles.isEmpty())
m_watcher->removePaths(watchedFiles);
} }
bool BuildDirManager::persistCMakeState() bool BuildDirManager::persistCMakeState()
@@ -223,8 +223,8 @@ void BuildDirManager::parse()
return; return;
} }
const bool mustUpdate = m_watchedFiles.isEmpty() const bool mustUpdate = m_cmakeFiles.isEmpty()
|| Utils::anyOf(m_watchedFiles, [&cbpFileFi](const Utils::FileName &f) { || Utils::anyOf(m_cmakeFiles, [&cbpFileFi](const Utils::FileName &f) {
return f.toFileInfo().lastModified() > cbpFileFi.lastModified(); return f.toFileInfo().lastModified() > cbpFileFi.lastModified();
}); });
if (mustUpdate) { if (mustUpdate) {
@@ -251,11 +251,6 @@ void BuildDirManager::clearCache()
forceReparse(); forceReparse();
} }
bool BuildDirManager::isProjectFile(const Utils::FileName &fileName) const
{
return m_watchedFiles.contains(fileName);
}
QString BuildDirManager::projectName() const QString BuildDirManager::projectName() const
{ {
return m_projectName; return m_projectName;
@@ -271,6 +266,11 @@ QList<ProjectExplorer::FileNode *> BuildDirManager::files()
return m_files; return m_files;
} }
QSet<Utils::FileName> BuildDirManager::cmakeFiles()
{
return m_cmakeFiles;
}
void BuildDirManager::clearFiles() void BuildDirManager::clearFiles()
{ {
m_files.clear(); m_files.clear();
@@ -355,15 +355,19 @@ void BuildDirManager::extractData()
m_projectName = sourceDirectory().fileName(); m_projectName = sourceDirectory().fileName();
m_files.append(new ProjectExplorer::FileNode(topCMake, ProjectExplorer::ProjectFileType, false)); 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 // Find cbp file
QString cbpFile = CMakeManager::findCbpFile(workDirectory().toString()); QString cbpFile = CMakeManager::findCbpFile(workDirectory().toString());
if (cbpFile.isEmpty()) if (cbpFile.isEmpty())
return; return;
m_cmakeFiles.insert(Utils::FileName::fromString(cbpFile));
m_watcher->addPath(cbpFile); // Add CMakeCache.txt file:
m_watcher->addPath(workDirectory().toString() + QLatin1String("/CMakeCache.txt")); Utils::FileName cacheFile = workDirectory();
cacheFile.appendPath(QLatin1String("CMakeCache.txt"));
if (cacheFile.toFileInfo().exists())
m_cmakeFiles.insert(cacheFile);
// setFolderName // setFolderName
CMakeCbpParser cbpparser; CMakeCbpParser cbpparser;
@@ -374,21 +378,14 @@ void BuildDirManager::extractData()
m_projectName = cbpparser.projectName(); m_projectName = cbpparser.projectName();
m_files = cbpparser.fileList(); m_files = cbpparser.fileList();
QSet<Utils::FileName> projectFiles;
if (cbpparser.hasCMakeFiles()) { if (cbpparser.hasCMakeFiles()) {
m_files.append(cbpparser.cmakeFileList()); m_files.append(cbpparser.cmakeFileList());
foreach (const ProjectExplorer::FileNode *node, cbpparser.cmakeFileList()) foreach (const ProjectExplorer::FileNode *node, cbpparser.cmakeFileList())
projectFiles.insert(node->filePath()); m_cmakeFiles.insert(node->filePath());
} else { } else {
m_files.append(new ProjectExplorer::FileNode(topCMake, ProjectExplorer::ProjectFileType, false)); 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(); m_buildTargets = cbpparser.buildTargets();
} }

View File

@@ -73,6 +73,8 @@ public:
const CMakeConfig intendedConfiguration() const; const CMakeConfig intendedConfiguration() const;
bool isParsing() const; bool isParsing() const;
void cmakeFilesChanged();
void parse(); void parse();
void clearCache(); void clearCache();
void forceReparse(); void forceReparse();
@@ -80,10 +82,10 @@ public:
void resetData(); void resetData();
bool persistCMakeState(); bool persistCMakeState();
bool isProjectFile(const Utils::FileName &fileName) const;
QString projectName() const; QString projectName() const;
QList<CMakeBuildTarget> buildTargets() const; QList<CMakeBuildTarget> buildTargets() const;
QList<ProjectExplorer::FileNode *> files(); QList<ProjectExplorer::FileNode *> files();
QSet<Utils::FileName> cmakeFiles();
void clearFiles(); void clearFiles();
CMakeConfig parsedConfiguration() const; CMakeConfig parsedConfiguration() const;
@@ -115,10 +117,9 @@ private:
QTemporaryDir *m_tempDir = nullptr; QTemporaryDir *m_tempDir = nullptr;
mutable CMakeConfig m_cmakeCache; mutable CMakeConfig m_cmakeCache;
QSet<Utils::FileName> m_watchedFiles; QSet<Utils::FileName> m_cmakeFiles;
QString m_projectName; QString m_projectName;
QList<CMakeBuildTarget> m_buildTargets; QList<CMakeBuildTarget> m_buildTargets;
QFileSystemWatcher *m_watcher;
QList<ProjectExplorer::FileNode *> m_files; QList<ProjectExplorer::FileNode *> m_files;
// For error reporting: // For error reporting:

View File

@@ -71,6 +71,11 @@ CMakeBuildConfiguration::~CMakeBuildConfiguration()
m_buildDirManager->deleteLater(); // Do not block while waiting for cmake... m_buildDirManager->deleteLater(); // Do not block while waiting for cmake...
} }
void CMakeBuildConfiguration::cmakeFilesChanged()
{
m_buildDirManager->cmakeFilesChanged();
}
bool CMakeBuildConfiguration::isEnabled() const bool CMakeBuildConfiguration::isEnabled() const
{ {
return m_error.isEmpty(); return m_error.isEmpty();

View File

@@ -52,6 +52,8 @@ public:
CMakeBuildConfiguration(ProjectExplorer::Target *parent); CMakeBuildConfiguration(ProjectExplorer::Target *parent);
~CMakeBuildConfiguration(); ~CMakeBuildConfiguration();
void cmakeFilesChanged();
bool isEnabled() const override; bool isEnabled() const override;
QString disabledReason() const override; QString disabledReason() const override;

View File

@@ -27,6 +27,8 @@
#include "cmakeproject.h" #include "cmakeproject.h"
#include "cmakeprojectconstants.h" #include "cmakeprojectconstants.h"
#include <projectexplorer/target.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
using namespace Utils; using namespace Utils;
@@ -34,7 +36,7 @@ using namespace Utils;
namespace CMakeProjectManager { namespace CMakeProjectManager {
namespace Internal { namespace Internal {
CMakeFile::CMakeFile(const FileName &fileName) CMakeFile::CMakeFile(CMakeProject *project, const FileName &fileName) : m_project(project)
{ {
setId("Cmake.ProjectFile"); setId("Cmake.ProjectFile");
setMimeType(QLatin1String(Constants::CMAKEPROJECTMIMETYPE)); setMimeType(QLatin1String(Constants::CMAKEPROJECTMIMETYPE));
@@ -48,5 +50,15 @@ Core::IDocument::ReloadBehavior CMakeFile::reloadBehavior(ChangeTrigger state, C
return BehaviorSilent; 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 Internal
} // namespace CMakeProjectManager } // namespace CMakeProjectManager

View File

@@ -35,9 +35,13 @@ namespace Internal {
class CMakeFile : public Core::IDocument class CMakeFile : public Core::IDocument
{ {
public: public:
CMakeFile(const Utils::FileName &fileName); CMakeFile(CMakeProject *project, const Utils::FileName &fileName);
ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override; ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override;
bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
private:
CMakeProject *m_project;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -36,6 +36,7 @@
#include "cmakeprojectmanager.h" #include "cmakeprojectmanager.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/documentmanager.h>
#include <cpptools/cppmodelmanager.h> #include <cpptools/cppmodelmanager.h>
#include <cpptools/projectinfo.h> #include <cpptools/projectinfo.h>
#include <cpptools/projectpartbuilder.h> #include <cpptools/projectpartbuilder.h>
@@ -88,11 +89,13 @@ CMakeProject::CMakeProject(CMakeManager *manager, const FileName &fileName)
{ {
setId(Constants::CMAKEPROJECT_ID); setId(Constants::CMAKEPROJECT_ID);
setProjectManager(manager); setProjectManager(manager);
setDocument(new CMakeFile(fileName)); setDocument(new Internal::CMakeFile(this, fileName));
setRootProjectNode(new CMakeProjectNode(fileName)); setRootProjectNode(new CMakeProjectNode(fileName));
setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT)); setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT));
setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX)); setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX));
Core::DocumentManager::addDocument(document());
rootProjectNode()->setDisplayName(fileName.parentDir().fileName()); rootProjectNode()->setDisplayName(fileName.parentDir().fileName());
connect(this, &CMakeProject::activeTargetChanged, this, &CMakeProject::handleActiveTargetChanged); connect(this, &CMakeProject::activeTargetChanged, this, &CMakeProject::handleActiveTargetChanged);
@@ -217,6 +220,29 @@ void CMakeProject::parseCMakeOutput()
rootProjectNode()->setDisplayName(bdm->projectName()); rootProjectNode()->setDisplayName(bdm->projectName());
// Delete no longer necessary file watcher:
const QSet<Utils::FileName> currentWatched
= Utils::transform(m_watchedFiles, [](CMakeFile *cmf) { return cmf->filePath(); });
const QSet<Utils::FileName> toWatch = bdm->cmakeFiles();
QSet<Utils::FileName> 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<Utils::FileName> 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<CMakeProjectNode *>(rootProjectNode()), bdm->files()); buildTree(static_cast<CMakeProjectNode *>(rootProjectNode()), bdm->files());
bdm->clearFiles(); // Some of the FileNodes in files() were deleted! bdm->clearFiles(); // Some of the FileNodes in files() were deleted!
@@ -512,6 +538,15 @@ bool CMakeProject::setupTarget(Target *t)
return true; return true;
} }
void CMakeProject::handleCmakeFileChanged()
{
if (Target *t = activeTarget()) {
if (auto bc = qobject_cast<CMakeBuildConfiguration *>(t->activeBuildConfiguration())) {
bc->cmakeFilesChanged();
}
}
}
void CMakeProject::handleActiveTargetChanged() void CMakeProject::handleActiveTargetChanged()
{ {
if (m_connectedTarget) { if (m_connectedTarget) {

View File

@@ -120,6 +120,8 @@ protected:
bool setupTarget(ProjectExplorer::Target *t) override; bool setupTarget(ProjectExplorer::Target *t) override;
private: private:
void handleCmakeFileChanged();
void handleActiveTargetChanged(); void handleActiveTargetChanged();
void handleActiveBuildConfigurationChanged(); void handleActiveBuildConfigurationChanged();
void handleParsingStarted(); void handleParsingStarted();
@@ -144,7 +146,10 @@ private:
QFuture<void> m_codeModelFuture; QFuture<void> m_codeModelFuture;
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers; QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
QSet<Internal::CMakeFile *> m_watchedFiles;
friend class Internal::CMakeBuildConfiguration; friend class Internal::CMakeBuildConfiguration;
friend class Internal::CMakeFile;
}; };
} // namespace CMakeProjectManager } // namespace CMakeProjectManager

View File

@@ -36,6 +36,7 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/treemodel.h> #include <utils/treemodel.h>
#include <QCheckBox>
#include <QFormLayout> #include <QFormLayout>
#include <QHeaderView> #include <QHeaderView>
#include <QLabel> #include <QLabel>
@@ -56,7 +57,7 @@ class CMakeToolTreeItem;
// CMakeToolItemModel // CMakeToolItemModel
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
class CMakeToolItemModel : public LeveledTreeModel<TreeItem, CMakeToolTreeItem> class CMakeToolItemModel : public LeveledTreeModel<TreeItem, TreeItem, CMakeToolTreeItem>
{ {
Q_DECLARE_TR_FUNCTIONS(CMakeProjectManager::CMakeSettingsPage) Q_DECLARE_TR_FUNCTIONS(CMakeProjectManager::CMakeSettingsPage)
@@ -65,12 +66,13 @@ public:
CMakeToolTreeItem *cmakeToolItem(const Core::Id &id) const; CMakeToolTreeItem *cmakeToolItem(const Core::Id &id) const;
CMakeToolTreeItem *cmakeToolItem(const QModelIndex &index) 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); void addCMakeTool(const CMakeTool *item, bool changed);
TreeItem *autoGroupItem() const; TreeItem *autoGroupItem() const;
TreeItem *manualGroupItem() const; TreeItem *manualGroupItem() const;
void reevaluateChangedFlag(CMakeToolTreeItem *item) 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 removeCMakeTool(const Core::Id &id);
void apply(); void apply();
@@ -92,19 +94,22 @@ public:
m_id(item->id()), m_id(item->id()),
m_name(item->displayName()), m_name(item->displayName()),
m_executable(item->cmakeExecutable()), m_executable(item->cmakeExecutable()),
m_isAutoRun(item->isAutoRun()),
m_autodetected(item->isAutoDetected()), m_autodetected(item->isAutoDetected()),
m_changed(changed) 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_id(Core::Id::fromString(QUuid::createUuid().toString())),
m_name(name), m_name(name),
m_executable(executable), m_executable(executable),
m_isAutoRun(autoRun),
m_autodetected(autodetected), m_autodetected(autodetected),
m_changed(true) m_changed(true)
{} {}
CMakeToolTreeItem() : m_autodetected(false), m_changed(true) {} CMakeToolTreeItem() = default;
CMakeToolItemModel *model() const { return static_cast<CMakeToolItemModel *>(TreeItem::model()); } CMakeToolItemModel *model() const { return static_cast<CMakeToolItemModel *>(TreeItem::model()); }
@@ -135,8 +140,9 @@ public:
Core::Id m_id; Core::Id m_id;
QString m_name; QString m_name;
FileName m_executable; FileName m_executable;
bool m_autodetected; bool m_isAutoRun = true;
bool m_changed; bool m_autodetected = false;
bool m_changed = true;
}; };
CMakeToolItemModel::CMakeToolItemModel() 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) if (isAutoDetected)
autoGroupItem()->appendChild(item); autoGroupItem()->appendChild(item);
else else
@@ -208,13 +215,14 @@ void CMakeToolItemModel::reevaluateChangedFlag(CMakeToolTreeItem *item) const
} }
void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &displayName, void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &displayName,
const FileName &executable) const FileName &executable, bool autoRun)
{ {
CMakeToolTreeItem *treeItem = cmakeToolItem(id); CMakeToolTreeItem *treeItem = cmakeToolItem(id);
QTC_ASSERT(treeItem, return); QTC_ASSERT(treeItem, return);
treeItem->m_name = displayName; treeItem->m_name = displayName;
treeItem->m_executable = executable; treeItem->m_executable = executable;
treeItem->m_isAutoRun = autoRun;
reevaluateChangedFlag(treeItem); reevaluateChangedFlag(treeItem);
} }
@@ -249,6 +257,7 @@ void CMakeToolItemModel::apply()
if (CMakeTool *cmake = CMakeToolManager::findById(item->m_id)) { if (CMakeTool *cmake = CMakeToolManager::findById(item->m_id)) {
cmake->setDisplayName(item->m_name); cmake->setDisplayName(item->m_name);
cmake->setCMakeExecutable(item->m_executable); cmake->setCMakeExecutable(item->m_executable);
cmake->setAutorun(item->m_isAutoRun);
} else { } else {
toRegister.append(item); toRegister.append(item);
} }
@@ -315,6 +324,7 @@ public:
private: private:
CMakeToolItemModel *m_model; CMakeToolItemModel *m_model;
QLineEdit *m_displayNameLineEdit; QLineEdit *m_displayNameLineEdit;
QCheckBox *m_autoRunCheckBox;
PathChooser *m_binaryChooser; PathChooser *m_binaryChooser;
Core::Id m_id; Core::Id m_id;
bool m_loadingItem; bool m_loadingItem;
@@ -330,21 +340,28 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model)
m_binaryChooser->setMinimumWidth(400); m_binaryChooser->setMinimumWidth(400);
m_binaryChooser->setHistoryCompleter(QLatin1String("Cmake.Command.History")); m_binaryChooser->setHistoryCompleter(QLatin1String("Cmake.Command.History"));
m_autoRunCheckBox = new QCheckBox;
m_autoRunCheckBox->setText("Autorun CMake");
QFormLayout *formLayout = new QFormLayout(this); QFormLayout *formLayout = new QFormLayout(this);
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit); formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit);
formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser); formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser);
formLayout->addRow(m_autoRunCheckBox);
connect(m_binaryChooser, &PathChooser::rawPathChanged, connect(m_binaryChooser, &PathChooser::rawPathChanged,
this, &CMakeToolItemConfigWidget::store); this, &CMakeToolItemConfigWidget::store);
connect(m_displayNameLineEdit, &QLineEdit::textChanged, connect(m_displayNameLineEdit, &QLineEdit::textChanged,
this, &CMakeToolItemConfigWidget::store); this, &CMakeToolItemConfigWidget::store);
connect(m_autoRunCheckBox, &QCheckBox::toggled,
this, &CMakeToolItemConfigWidget::store);
} }
void CMakeToolItemConfigWidget::store() const void CMakeToolItemConfigWidget::store() const
{ {
if (!m_loadingItem && m_id.isValid()) 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) void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
@@ -363,6 +380,8 @@ void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
m_binaryChooser->setReadOnly(item->m_autodetected); m_binaryChooser->setReadOnly(item->m_autodetected);
m_binaryChooser->setFileName(item->m_executable); m_binaryChooser->setFileName(item->m_executable);
m_autoRunCheckBox->setChecked(item->m_isAutoRun);
m_id = item->m_id; m_id = item->m_id;
m_loadingItem = false; m_loadingItem = false;
} }
@@ -375,7 +394,7 @@ class CMakeToolConfigWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
CMakeToolConfigWidget() : m_currentItem(0) CMakeToolConfigWidget()
{ {
m_addButton = new QPushButton(tr("Add"), this); m_addButton = new QPushButton(tr("Add"), this);
@@ -452,7 +471,7 @@ public:
QPushButton *m_makeDefButton; QPushButton *m_makeDefButton;
DetailsWidget *m_container; DetailsWidget *m_container;
CMakeToolItemConfigWidget *m_itemConfigWidget; CMakeToolItemConfigWidget *m_itemConfigWidget;
CMakeToolTreeItem *m_currentItem; CMakeToolTreeItem *m_currentItem = nullptr;
}; };
void CMakeToolConfigWidget::apply() void CMakeToolConfigWidget::apply()
@@ -467,7 +486,7 @@ void CMakeToolConfigWidget::cloneCMakeTool()
QModelIndex newItem = m_model.addCMakeTool(tr("Clone of %1").arg(m_currentItem->m_name), QModelIndex newItem = m_model.addCMakeTool(tr("Clone of %1").arg(m_currentItem->m_name),
m_currentItem->m_executable, m_currentItem->m_executable,
false); m_currentItem->m_isAutoRun, false);
m_cmakeToolsView->setCurrentIndex(newItem); m_cmakeToolsView->setCurrentIndex(newItem);
} }
@@ -475,7 +494,7 @@ void CMakeToolConfigWidget::cloneCMakeTool()
void CMakeToolConfigWidget::addCMakeTool() void CMakeToolConfigWidget::addCMakeTool()
{ {
QModelIndex newItem = m_model.addCMakeTool(m_model.uniqueDisplayName(tr("New CMake")), QModelIndex newItem = m_model.addCMakeTool(m_model.uniqueDisplayName(tr("New CMake")),
FileName(), false); FileName(), true, false);
m_cmakeToolsView->setCurrentIndex(newItem); m_cmakeToolsView->setCurrentIndex(newItem);
} }

View File

@@ -42,6 +42,7 @@ namespace CMakeProjectManager {
const char CMAKE_INFORMATION_ID[] = "Id"; const char CMAKE_INFORMATION_ID[] = "Id";
const char CMAKE_INFORMATION_COMMAND[] = "Binary"; const char CMAKE_INFORMATION_COMMAND[] = "Binary";
const char CMAKE_INFORMATION_DISPLAYNAME[] = "DisplayName"; const char CMAKE_INFORMATION_DISPLAYNAME[] = "DisplayName";
const char CMAKE_INFORMATION_AUTORUN[] = "AutoRun";
const char CMAKE_INFORMATION_AUTODETECTED[] = "AutoDetected"; 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_id = Core::Id::fromSetting(map.value(QLatin1String(CMAKE_INFORMATION_ID)));
m_displayName = map.value(QLatin1String(CMAKE_INFORMATION_DISPLAYNAME)).toString(); 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 //loading a CMakeTool from SDK is always autodetection
if (!fromSdk) if (!fromSdk)
@@ -82,6 +84,15 @@ void CMakeTool::setCMakeExecutable(const Utils::FileName &executable)
CMakeToolManager::notifyAboutUpdate(this); CMakeToolManager::notifyAboutUpdate(this);
} }
void CMakeTool::setAutorun(bool autoRun)
{
if (m_isAutoRun == autoRun)
return;
m_isAutoRun = autoRun;
CMakeToolManager::notifyAboutUpdate(this);
}
bool CMakeTool::isValid() const bool CMakeTool::isValid() const
{ {
if (!m_id.isValid()) 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_DISPLAYNAME), m_displayName);
data.insert(QLatin1String(CMAKE_INFORMATION_ID), m_id.toSetting()); data.insert(QLatin1String(CMAKE_INFORMATION_ID), m_id.toSetting());
data.insert(QLatin1String(CMAKE_INFORMATION_COMMAND), m_executable.toString()); 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); data.insert(QLatin1String(CMAKE_INFORMATION_AUTODETECTED), m_isAutoDetected);
return data; return data;
} }
@@ -130,6 +142,11 @@ Utils::FileName CMakeTool::cmakeExecutable() const
return m_executable; return m_executable;
} }
bool CMakeTool::isAutoRun() const
{
return m_isAutoRun;
}
QStringList CMakeTool::supportedGenerators() const QStringList CMakeTool::supportedGenerators() const
{ {
if (m_generators.isEmpty()) { if (m_generators.isEmpty()) {

View File

@@ -66,8 +66,10 @@ public:
QVariantMap toMap () const; QVariantMap toMap () const;
void setCMakeExecutable(const Utils::FileName &executable); void setCMakeExecutable(const Utils::FileName &executable);
void setAutorun(bool autoRun);
Utils::FileName cmakeExecutable() const; Utils::FileName cmakeExecutable() const;
bool isAutoRun() const;
QStringList supportedGenerators() const; QStringList supportedGenerators() const;
TextEditor::Keywords keywords(); TextEditor::Keywords keywords();
@@ -87,6 +89,8 @@ private:
QString m_displayName; QString m_displayName;
Utils::FileName m_executable; Utils::FileName m_executable;
bool m_isAutoRun;
bool m_isAutoDetected; bool m_isAutoDetected;
mutable bool m_didAttemptToRun; mutable bool m_didAttemptToRun;

View File

@@ -56,6 +56,9 @@ SystemSettings::SystemSettings()
setCategory(Constants::SETTINGS_CATEGORY_CORE); setCategory(Constants::SETTINGS_CATEGORY_CORE);
setDisplayCategory(QCoreApplication::translate("Core", Constants::SETTINGS_TR_CATEGORY_CORE)); setDisplayCategory(QCoreApplication::translate("Core", Constants::SETTINGS_TR_CATEGORY_CORE));
setCategoryIcon(QLatin1String(Constants::SETTINGS_CATEGORY_CORE_ICON)); setCategoryIcon(QLatin1String(Constants::SETTINGS_CATEGORY_CORE_ICON));
connect(VcsManager::instance(), &VcsManager::configurationChanged,
this, &SystemSettings::updatePath);
} }
QWidget *SystemSettings::widget() QWidget *SystemSettings::widget()
@@ -138,9 +141,6 @@ QWidget *SystemSettings::widget()
} }
updatePath(); updatePath();
connect(VcsManager::instance(), &VcsManager::configurationChanged,
this, &SystemSettings::updatePath);
} }
return m_widget; return m_widget;
} }
@@ -200,6 +200,9 @@ void SystemSettings::resetFileBrowser()
void SystemSettings::updatePath() void SystemSettings::updatePath()
{ {
if (!m_page)
return;
Environment env = Environment::systemEnvironment(); Environment env = Environment::systemEnvironment();
QStringList toAdd = VcsManager::additionalToolsPath(); QStringList toAdd = VcsManager::additionalToolsPath();
env.appendOrSetPath(toAdd.join(HostOsInfo::pathListSeparator())); env.appendOrSetPath(toAdd.join(HostOsInfo::pathListSeparator()));

View File

@@ -996,34 +996,34 @@ void CppModelManager::delayedGC()
d->m_delayedGcTimer.start(500); d->m_delayedGcTimer.start(500);
} }
static QStringList idsOfAllProjectParts(const ProjectInfo &projectInfo) static QStringList removedProjectParts(const QStringList &before, const QStringList &after)
{ {
QStringList projectPaths; QSet<QString> b = before.toSet();
foreach (const ProjectPart::Ptr &part, projectInfo.projectParts()) b.subtract(after.toSet());
projectPaths << part->id();
return projectPaths; return b.toList();
} }
void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
{ {
QStringList projectPartIds; QStringList idsOfRemovedProjectParts;
d->m_projectToIndexerCanceled.remove(project); d->m_projectToIndexerCanceled.remove(project);
{ {
QMutexLocker locker(&d->m_projectMutex); QMutexLocker locker(&d->m_projectMutex);
d->m_dirty = true; d->m_dirty = true;
const QStringList projectPartsIdsBefore = d->m_projectPartIdToProjectProjectPart.keys();
// Save paths
const ProjectInfo projectInfo = d->m_projectToProjectsInfo.value(project, ProjectInfo());
projectPartIds = idsOfAllProjectParts(projectInfo);
d->m_projectToProjectsInfo.remove(project); d->m_projectToProjectsInfo.remove(project);
recalculateProjectPartMappings(); recalculateProjectPartMappings();
const QStringList projectPartsIdsAfter = d->m_projectPartIdToProjectProjectPart.keys();
idsOfRemovedProjectParts = removedProjectParts(projectPartsIdsBefore, projectPartsIdsAfter);
} }
if (!projectPartIds.isEmpty()) if (!idsOfRemovedProjectParts.isEmpty())
emit projectPartsRemoved(projectPartIds); emit projectPartsRemoved(idsOfRemovedProjectParts);
delayedGC(); delayedGC();
} }

View File

@@ -48,11 +48,10 @@ public:
QString displayName() const; QString displayName() const;
private slots: private:
void chooseSettings(int setting); void chooseSettings(int setting);
void restoreGlobal(); void restoreGlobal();
private:
QWidget *m_configWidget; QWidget *m_configWidget;
ProjectExplorer::IRunConfigurationAspect *m_aspect; ProjectExplorer::IRunConfigurationAspect *m_aspect;
ProjectExplorer::ISettingsAspect *m_config; ProjectExplorer::ISettingsAspect *m_config;

View File

@@ -157,7 +157,7 @@ inline uint qHash(const Debugger::Internal::Breakpoint &b) { return b.hash(); }
typedef QList<Breakpoint> Breakpoints; typedef QList<Breakpoint> Breakpoints;
class BreakHandler : public Utils::LeveledTreeModel<BreakpointItem, LocationItem> class BreakHandler : public Utils::LeveledTreeModel<Utils::TreeItem, BreakpointItem, LocationItem>
{ {
Q_OBJECT Q_OBJECT

View File

@@ -96,7 +96,6 @@ public:
void setParameters(const BreakpointParameters &data); void setParameters(const BreakpointParameters &data);
BreakpointParameters parameters() const; BreakpointParameters parameters() const;
public slots:
void typeChanged(int index); void typeChanged(int index);
private: private:

View File

@@ -116,7 +116,7 @@ public:
static QString extensionLibraryName(bool is64Bit); static QString extensionLibraryName(bool is64Bit);
private slots: private:
void readyReadStandardOut(); void readyReadStandardOut();
void readyReadStandardError(); void readyReadStandardError();
void processError(); void processError();
@@ -132,7 +132,6 @@ private slots:
void handleDoInterruptInferior(const QString &errorMessage); void handleDoInterruptInferior(const QString &errorMessage);
private:
typedef QHash<BreakpointModelId, BreakpointResponse> PendingBreakPointMap; typedef QHash<BreakpointModelId, BreakpointResponse> PendingBreakPointMap;
typedef QPair<QString, QString> SourcePathMapping; typedef QPair<QString, QString> SourcePathMapping;
struct NormalizedSourceFileName // Struct for caching mapped/normalized source files. struct NormalizedSourceFileName // Struct for caching mapped/normalized source files.

View File

@@ -44,8 +44,6 @@ public:
void emitSizeHintChanged(const QModelIndex &index); void emitSizeHintChanged(const QModelIndex &index);
QColor drawBackground(QPainter *painter, const QRect &rect, const QModelIndex &index, QColor drawBackground(QPainter *painter, const QRect &rect, const QModelIndex &index,
bool selected) const; bool selected) const;
public slots:
void currentChanged(const QModelIndex &current, const QModelIndex &previous); void currentChanged(const QModelIndex &current, const QModelIndex &previous);
protected: protected:

View File

@@ -51,7 +51,6 @@ public:
int sizeOfFile(const QFont &font); int sizeOfFile(const QFont &font);
int sizeOfLineNumber(const QFont &font); int sizeOfLineNumber(const QFont &font);
public slots:
void clear(); void clear();
signals: signals:

View File

@@ -39,7 +39,6 @@ class ConsoleProxyModel : public QSortFilterProxyModel
public: public:
explicit ConsoleProxyModel(QObject *parent); explicit ConsoleProxyModel(QObject *parent);
public slots:
void setShowLogs(bool show); void setShowLogs(bool show);
void setShowWarnings(bool show); void setShowWarnings(bool show);
void setShowErrors(bool show); void setShowErrors(bool show);

View File

@@ -39,7 +39,6 @@ class ConsoleView : public Utils::TreeView
public: public:
ConsoleView(ConsoleItemModel *model, QWidget *parent); ConsoleView(ConsoleItemModel *model, QWidget *parent);
public slots:
void onScrollToBottom(); void onScrollToBottom();
protected: protected:

View File

@@ -99,7 +99,7 @@ public:
// DebuggerItemModel // DebuggerItemModel
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
class DebuggerItemModel : public LeveledTreeModel<StaticTreeItem, DebuggerTreeItem> class DebuggerItemModel : public LeveledTreeModel<TreeItem, StaticTreeItem, DebuggerTreeItem>
{ {
Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerOptionsPage) Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerOptionsPage)

View File

@@ -3076,9 +3076,7 @@ void showModuleSections(const QString &moduleName, const Sections &sections)
void DebuggerPluginPrivate::aboutToShutdown() void DebuggerPluginPrivate::aboutToShutdown()
{ {
disconnect(SessionManager::instance(), disconnect(SessionManager::instance(), &SessionManager::startupProjectChanged, this, nullptr);
SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
this, 0);
m_mainWindow->saveCurrentPerspective(); m_mainWindow->saveCurrentPerspective();
delete m_mainWindow; delete m_mainWindow;

View File

@@ -62,7 +62,7 @@ public:
static SourcePathMap mergePlatformQtPath(const DebuggerRunParameters &sp, static SourcePathMap mergePlatformQtPath(const DebuggerRunParameters &sp,
const SourcePathMap &in); const SourcePathMap &in);
private slots: private:
void slotAdd(); void slotAdd();
void slotAddQt(); void slotAddQt();
void slotRemove(); void slotRemove();
@@ -70,7 +70,6 @@ private slots:
void slotEditSourceFieldChanged(); void slotEditSourceFieldChanged();
void slotEditTargetFieldChanged(); void slotEditTargetFieldChanged();
private:
void resizeColumns(); void resizeColumns();
void updateEnabled(); void updateEnabled();
QString editSourceField() const; QString editSourceField() const;

View File

@@ -122,7 +122,7 @@ protected: ////////// Gdb Process Management //////////
// Make sure to clean up everything before emitting this signal. // Make sure to clean up everything before emitting this signal.
void handleAdapterCrashed(const QString &msg); void handleAdapterCrashed(const QString &msg);
private slots: private:
friend class GdbPlainEngine; friend class GdbPlainEngine;
friend class GdbCoreEngine; friend class GdbCoreEngine;
void handleInterruptDeviceInferior(const QString &error); void handleInterruptDeviceInferior(const QString &error);
@@ -132,7 +132,6 @@ private slots:
void readGdbStandardError(); void readGdbStandardError();
void readDebuggeeOutput(const QByteArray &ba); void readDebuggeeOutput(const QByteArray &ba);
private:
QTextCodec *m_gdbOutputCodec; QTextCodec *m_gdbOutputCodec;
QTextCodec::ConverterState m_gdbOutputCodecState; QTextCodec::ConverterState m_gdbOutputCodecState;
QTextCodec *m_inferiorOutputCodec; QTextCodec *m_inferiorOutputCodec;
@@ -204,7 +203,7 @@ private:
private: ////////// Gdb Output, State & Capability Handling ////////// private: ////////// Gdb Output, State & Capability Handling //////////
protected: protected:
void handleResponse(const QString &buff); Q_INVOKABLE void handleResponse(const QString &buff);
void handleAsyncOutput(const QString &asyncClass, const GdbMi &result); void handleAsyncOutput(const QString &asyncClass, const GdbMi &result);
void handleStopResponse(const GdbMi &data); void handleStopResponse(const GdbMi &data);
void handleResultRecord(DebuggerResponse *response); void handleResultRecord(DebuggerResponse *response);

View File

@@ -45,7 +45,7 @@ public:
void run(); void run();
private slots: private:
void handleRemoteError(const QString &errorMessage); void handleRemoteError(const QString &errorMessage);
void portGathererError(const QString &errorMessage); void portGathererError(const QString &errorMessage);
void portListReady(); void portListReady();
@@ -56,7 +56,6 @@ private slots:
void handleProcessStarted(); void handleProcessStarted();
void handleConnectionError(); void handleConnectionError();
private:
void attach(int port); void attach(int port);
void logMessage(const QString &line); void logMessage(const QString &line);
StartGdbServerDialogPrivate *d; StartGdbServerDialogPrivate *d;

View File

@@ -310,7 +310,6 @@ public:
(void) new OutputHighlighter(this); (void) new OutputHighlighter(this);
} }
public slots:
void gotoResult(int i) void gotoResult(int i)
{ {
QString needle = QString::number(i) + QLatin1Char('^'); QString needle = QString::number(i) + QLatin1Char('^');

View File

@@ -64,7 +64,6 @@ public:
static QChar charForChannel(int channel); static QChar charForChannel(int channel);
static LogChannel channelForChar(QChar c); static LogChannel channelForChar(QChar c);
public slots:
void clearContents(); void clearContents();
void sendCommand(); void sendCommand();
void executeLine(); void executeLine();

View File

@@ -55,7 +55,7 @@ public:
void expressionEvaluated(quint32 queryId, const QVariant &result); void expressionEvaluated(quint32 queryId, const QVariant &result);
private slots: private:
void disconnected(); void disconnected();
void errorMessageBoxFinished(int result); void errorMessageBoxFinished(int result);
void updateCurrentContext(); void updateCurrentContext();
@@ -67,7 +67,6 @@ private slots:
void appStartupFailed(const QString &errorMessage); void appStartupFailed(const QString &errorMessage);
void appendMessage(const QString &msg, Utils::OutputFormat); void appendMessage(const QString &msg, Utils::OutputFormat);
private:
void notifyEngineRemoteServerRunning(const QString &, int pid) override; void notifyEngineRemoteServerRunning(const QString &, int pid) override;
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result) override; void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result) override;

View File

@@ -30,6 +30,8 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
using namespace Utils;
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
@@ -286,9 +288,10 @@ void RegisterValue::shiftOneDigit(uint digit, RegisterFormat format)
// //
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
class RegisterItem;
class RegisterSubItem; class RegisterSubItem;
class RegisterEditItem : public Utils::TreeItem class RegisterEditItem : public TypedTreeItem<TreeItem, RegisterSubItem>
{ {
public: public:
RegisterEditItem(int pos, RegisterKind subKind, int subSize, RegisterFormat format) RegisterEditItem(int pos, RegisterKind subKind, int subSize, RegisterFormat format)
@@ -306,7 +309,7 @@ public:
}; };
class RegisterSubItem : public Utils::TreeItem class RegisterSubItem : public TypedTreeItem<RegisterEditItem, RegisterItem>
{ {
public: public:
RegisterSubItem(RegisterKind subKind, int subSize, int count, RegisterFormat format) RegisterSubItem(RegisterKind subKind, int subSize, int count, RegisterFormat format)
@@ -333,7 +336,7 @@ public:
bool m_changed; bool m_changed;
}; };
class RegisterItem : public Utils::TreeItem class RegisterItem : public TypedTreeItem<RegisterSubItem>
{ {
public: public:
explicit RegisterItem(const Register &reg); explicit RegisterItem(const Register &reg);
@@ -460,10 +463,8 @@ QVariant RegisterSubItem::data(int column, int role) const
case RegisterChangedRole: case RegisterChangedRole:
return m_changed; return m_changed;
case RegisterFormatRole: { case RegisterFormatRole:
RegisterItem *registerItem = static_cast<RegisterItem *>(parent()); return int(parent()->m_format);
return int(registerItem->m_format);
}
case RegisterAsAddressRole: case RegisterAsAddressRole:
return 0; return 0;
@@ -474,8 +475,7 @@ QVariant RegisterSubItem::data(int column, int role) const
return subTypeName(m_subKind, m_subSize, m_subFormat); return subTypeName(m_subKind, m_subSize, m_subFormat);
case RegisterValueColumn: { case RegisterValueColumn: {
QTC_ASSERT(parent(), return QVariant()); QTC_ASSERT(parent(), return QVariant());
RegisterItem *registerItem = static_cast<RegisterItem *>(parent()); RegisterValue value = parent()->m_reg.value;
RegisterValue value = registerItem->m_reg.value;
QString ba; QString ba;
for (int i = 0; i != m_count; ++i) { for (int i = 0; i != m_count; ++i) {
int tab = 5 * (i + 1) * m_subSize; 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); return QString("[%1]").arg(m_index);
} }
case RegisterValueColumn: { case RegisterValueColumn: {
RegisterItem *registerItem = static_cast<RegisterItem *>(parent()->parent()); RegisterValue value = parent()->parent()->m_reg.value;
RegisterValue value = registerItem->m_reg.value;
return value.subValue(m_subSize, m_index) return value.subValue(m_subSize, m_index)
.toString(m_subKind, m_subSize, m_subFormat, role == Qt::EditRole); .toString(m_subKind, m_subSize, m_subFormat, role == Qt::EditRole);
} }
} }
case Qt::ToolTipRole: { case Qt::ToolTipRole: {
RegisterItem *registerItem = static_cast<RegisterItem *>(parent()->parent()); RegisterItem *registerItem = parent()->parent();
return RegisterHandler::tr("Edit bits %1...%2 of register %3") return RegisterHandler::tr("Edit bits %1...%2 of register %3")
.arg(m_index * 8).arg(m_index * 8 + 7).arg(registerItem->m_reg.name); .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) { if (column == RegisterValueColumn && role == Qt::EditRole) {
QTC_ASSERT(parent(), return false); QTC_ASSERT(parent(), return false);
QTC_ASSERT(parent()->parent(), return false); QTC_ASSERT(parent()->parent(), return false);
RegisterItem *registerItem = static_cast<RegisterItem *>(parent()->parent()); RegisterItem *registerItem = parent()->parent();
Register &reg = registerItem->m_reg; Register &reg = registerItem->m_reg;
RegisterValue vv; RegisterValue vv;
vv.fromString(value.toString(), m_subFormat); 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 Qt::ItemFlags RegisterEditItem::flags(int column) const
{ {
QTC_ASSERT(parent(), return Qt::ItemFlags()); QTC_ASSERT(parent(), return Qt::ItemFlags());
RegisterSubItem *registerSubItem = static_cast<RegisterSubItem *>(parent()); Qt::ItemFlags f = parent()->flags(column);
Qt::ItemFlags f = registerSubItem->flags(column);
if (column == RegisterValueColumn) if (column == RegisterValueColumn)
f |= Qt::ItemIsEditable; f |= Qt::ItemIsEditable;
return f; return f;

View File

@@ -37,7 +37,6 @@ class RegisterTreeView : public Utils::BaseTreeView
public: public:
RegisterTreeView(); RegisterTreeView();
public slots:
void reloadRegisters(); void reloadRegisters();
private: private:

View File

@@ -41,7 +41,7 @@ namespace Internal {
class GdbMi; class GdbMi;
class ThreadItem; class ThreadItem;
class ThreadsHandler : public Utils::LeveledTreeModel<ThreadItem> class ThreadsHandler : public Utils::LeveledTreeModel<Utils::TreeItem, ThreadItem>
{ {
Q_OBJECT Q_OBJECT

View File

@@ -36,7 +36,6 @@
#include "simplifytype.h" #include "simplifytype.h"
#include "imageviewer.h" #include "imageviewer.h"
#include "watchutils.h" #include "watchutils.h"
#include "cdb/cdbengine.h" // Remove after string freeze
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -1185,9 +1184,9 @@ QString WatchModel::nameForFormat(int format)
case AutomaticFormat: return tr("Automatic"); case AutomaticFormat: return tr("Automatic");
case RawFormat: return tr("Raw Data"); 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 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 Latin1StringFormat: return tr("Latin1 String");
case SeparateLatin1StringFormat: return tr("Latin1 String in Separate Window"); case SeparateLatin1StringFormat: return tr("Latin1 String in Separate Window");

View File

@@ -88,6 +88,9 @@ BranchDialog::BranchDialog(QWidget *parent) :
connect(m_ui->branchView->selectionModel(), &QItemSelectionModel::selectionChanged, connect(m_ui->branchView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &BranchDialog::enableButtons); 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(); enableButtons();
} }
@@ -109,8 +112,7 @@ void BranchDialog::refresh(const QString &repository, bool force)
VcsOutputWindow::appendError(errorMessage); VcsOutputWindow::appendError(errorMessage);
m_ui->branchView->expandAll(); m_ui->branchView->expandAll();
m_ui->branchView->resizeColumnToContents(0); resizeColumns();
m_ui->branchView->resizeColumnToContents(1);
} }
void BranchDialog::refreshIfSame(const QString &repository) void BranchDialog::refreshIfSame(const QString &repository)
@@ -119,6 +121,12 @@ void BranchDialog::refreshIfSame(const QString &repository)
refreshCurrentRepository(); refreshCurrentRepository();
} }
void BranchDialog::resizeColumns()
{
m_ui->branchView->resizeColumnToContents(0);
m_ui->branchView->resizeColumnToContents(1);
}
void BranchDialog::enableButtons() void BranchDialog::enableButtons()
{ {
QModelIndex idx = selectedIndex(); QModelIndex idx = selectedIndex();

View File

@@ -52,11 +52,11 @@ public:
explicit BranchDialog(QWidget *parent = 0); explicit BranchDialog(QWidget *parent = 0);
~BranchDialog() override; ~BranchDialog() override;
public slots:
void refresh(const QString &repository, bool force); void refresh(const QString &repository, bool force);
void refreshIfSame(const QString &repository); void refreshIfSame(const QString &repository);
private: private:
void resizeColumns();
void enableButtons(); void enableButtons();
void refreshCurrentRepository(); void refreshCurrentRepository();
void add(); void add();

View File

@@ -470,6 +470,14 @@ QString BranchModel::sha(const QModelIndex &idx) const
return node->sha; 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 bool BranchModel::hasTags() const
{ {
return m_rootNode->children.count() > Tags; return m_rootNode->children.count() > Tags;
@@ -590,6 +598,7 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel
QString startSha; QString startSha;
QString output; QString output;
QString errorMessage; QString errorMessage;
QDateTime branchDateTime;
QStringList args; QStringList args;
args << (track ? QLatin1String("--track") : QLatin1String("--no-track")); args << (track ? QLatin1String("--track") : QLatin1String("--no-track"));
@@ -597,8 +606,17 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel
if (!fullTrackedBranch.isEmpty()) { if (!fullTrackedBranch.isEmpty()) {
args << fullTrackedBranch; args << fullTrackedBranch;
startSha = sha(startPoint); startSha = sha(startPoint);
branchDateTime = dateTime(startPoint);
} else { } 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)) { 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; local = child;
} }
int pos = positionForName(local, leafName); 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) if (!added)
beginInsertRows(nodeToIndex(local, 0), pos, pos); beginInsertRows(nodeToIndex(local, 0), pos, pos);
newNode->parent = local; newNode->parent = local;

View File

@@ -68,6 +68,7 @@ public:
QString fullName(const QModelIndex &idx, bool includePrefix = false) const; QString fullName(const QModelIndex &idx, bool includePrefix = false) const;
QStringList localBranchNames() const; QStringList localBranchNames() const;
QString sha(const QModelIndex &idx) const; QString sha(const QModelIndex &idx) const;
QDateTime dateTime(const QModelIndex &idx) const;
bool hasTags() const; bool hasTags() const;
bool isLocal(const QModelIndex &idx) const; bool isLocal(const QModelIndex &idx) const;
bool isLeaf(const QModelIndex &idx) const; bool isLeaf(const QModelIndex &idx) const;

Some files were not shown because too many files have changed in this diff Show More