summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--cmake/QtCreatorAPI.cmake7
-rw-r--r--doc/src/howto/creator-only/creator-cli.qdoc5
-rw-r--r--doc/src/howto/creator-sidebar-views.qdoc3
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp2
-rw-r--r--src/libs/qmljs/CMakeLists.txt2
-rw-r--r--src/libs/qmljs/qmljs-lib.pri1
-rw-r--r--src/libs/qmljs/qmljs.qbs2
-rw-r--r--src/libs/qmljs/qmljsdocument.cpp11
-rw-r--r--src/libs/qmljs/qmljsdocument.h5
-rw-r--r--src/libs/qmljs/qmljsimportdependencies.cpp38
-rw-r--r--src/libs/qmljs/qmljsimportdependencies.h2
-rw-r--r--src/libs/qmljs/qmljslink.cpp265
-rw-r--r--src/libs/qmljs/qmljslink.h5
-rw-r--r--src/libs/qmljs/qmljsmodelmanagerinterface.cpp494
-rw-r--r--src/libs/qmljs/qmljsmodelmanagerinterface.h103
-rw-r--r--src/libs/qmljs/qmljsplugindumper.cpp24
-rw-r--r--src/libs/qmljs/qmljsviewercontext.cpp84
-rw-r--r--src/libs/qmljs/qmljsviewercontext.h16
-rw-r--r--src/libs/utils/fancylineedit.cpp6
-rw-r--r--src/libs/utils/fileutils.cpp4
-rw-r--r--src/libs/utils/hostosinfo.cpp2
-rw-r--r--src/libs/utils/process_ctrlc_stub.cpp3
-rw-r--r--src/libs/utils/winutils.cpp3
-rw-r--r--src/plugins/CMakeLists.txt8
-rw-r--r--src/plugins/android/adbcommandswidget.cpp5
-rw-r--r--src/plugins/android/adbcommandswidget.h2
-rw-r--r--src/plugins/android/androidrunconfiguration.cpp6
-rw-r--r--src/plugins/android/androidrunconfiguration.h2
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/builddirmanager.cpp98
-rw-r--r--src/plugins/cmakeprojectmanager/builddirmanager.h1
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp14
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp3
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildstep.cpp67
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildstep.h6
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp9
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.h9
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp32
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeconfigitem.h2
-rw-r--r--src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp1
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeparser.cpp7
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprocess.cpp10
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprocess.h2
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeproject.cpp10
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeproject.h15
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp35
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectnodes.h5
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp56
-rw-r--r--src/plugins/cmakeprojectmanager/cmakesettingspage.cpp88
-rw-r--r--src/plugins/cmakeprojectmanager/cmakespecificsettingspage.cpp5
-rw-r--r--src/plugins/cmakeprojectmanager/cmakespecificsettingspage.h3
-rw-r--r--src/plugins/cmakeprojectmanager/cmaketool.cpp52
-rw-r--r--src/plugins/cmakeprojectmanager/cmaketool.h5
-rw-r--r--src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp19
-rw-r--r--src/plugins/cmakeprojectmanager/cmaketoolmanager.h2
-rw-r--r--src/plugins/cmakeprojectmanager/fileapireader.cpp6
-rw-r--r--src/plugins/cmakeprojectmanager/tealeafreader.cpp3
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp59
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h17
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp76
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.h16
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp44
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h13
-rw-r--r--src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp26
-rw-r--r--src/plugins/ctfvisualizer/ctfstatisticsmodel.h5
-rw-r--r--src/plugins/ctfvisualizer/ctftimelinemodel.cpp26
-rw-r--r--src/plugins/ctfvisualizer/ctftimelinemodel.h3
-rw-r--r--src/plugins/ctfvisualizer/ctftracemanager.cpp63
-rw-r--r--src/plugins/ctfvisualizer/ctftracemanager.h8
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizertool.cpp33
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizertool.h7
-rw-r--r--src/plugins/debugger/debuggerrunconfigurationaspect.cpp37
-rw-r--r--src/plugins/debugger/procinterrupt.cpp4
-rw-r--r--src/plugins/debugger/registerpostmortemaction.cpp4
-rw-r--r--src/plugins/debugger/shared/hostutils.cpp4
-rw-r--r--src/plugins/genericprojectmanager/genericproject.cpp225
-rw-r--r--src/plugins/genericprojectmanager/genericproject.h57
-rw-r--r--src/plugins/genericprojectmanager/genericprojectplugin.cpp21
-rw-r--r--src/plugins/genericprojectmanager/genericprojectplugin.h2
-rw-r--r--src/plugins/ios/iosbuildconfiguration.cpp5
-rw-r--r--src/plugins/ios/iosrunconfiguration.cpp11
-rw-r--r--src/plugins/nim/project/nimbuildsystem.cpp64
-rw-r--r--src/plugins/nim/project/nimbuildsystem.h12
-rw-r--r--src/plugins/nim/project/nimproject.cpp2
-rw-r--r--src/plugins/nim/project/nimprojectnode.cpp51
-rw-r--r--src/plugins/nim/project/nimprojectnode.h14
-rw-r--r--src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp142
-rw-r--r--src/plugins/perfprofiler/perfprofilerflamegraphmodel.h23
-rw-r--r--src/plugins/projectexplorer/CMakeLists.txt1
-rw-r--r--src/plugins/projectexplorer/ProjectExplorer.json.in5
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.cpp159
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.h28
-rw-r--r--src/plugins/projectexplorer/buildenvironmentwidget.cpp12
-rw-r--r--src/plugins/projectexplorer/buildsettingspropertiespage.cpp17
-rw-r--r--src/plugins/projectexplorer/buildsettingspropertiespage.h1
-rw-r--r--src/plugins/projectexplorer/buildstep.cpp15
-rw-r--r--src/plugins/projectexplorer/buildstepspage.cpp76
-rw-r--r--src/plugins/projectexplorer/buildstepspage.h4
-rw-r--r--src/plugins/projectexplorer/buildsystem.cpp60
-rw-r--r--src/plugins/projectexplorer/buildsystem.h32
-rw-r--r--src/plugins/projectexplorer/customexecutablerunconfiguration.cpp21
-rw-r--r--src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp1
-rw-r--r--src/plugins/projectexplorer/devicesupport/localprocesslist.cpp3
-rw-r--r--src/plugins/projectexplorer/environmentaspect.cpp13
-rw-r--r--src/plugins/projectexplorer/environmentaspect.h2
-rw-r--r--src/plugins/projectexplorer/environmentaspectwidget.cpp8
-rw-r--r--src/plugins/projectexplorer/gccparser.cpp15
-rw-r--r--src/plugins/projectexplorer/kitmanager.cpp159
-rw-r--r--src/plugins/projectexplorer/kitmanager.h2
-rw-r--r--src/plugins/projectexplorer/ldparser.cpp28
-rw-r--r--src/plugins/projectexplorer/ldparser.h6
-rw-r--r--src/plugins/projectexplorer/localenvironmentaspect.cpp36
-rw-r--r--src/plugins/projectexplorer/localenvironmentaspect.h2
-rw-r--r--src/plugins/projectexplorer/namedwidget.cpp20
-rw-r--r--src/plugins/projectexplorer/namedwidget.h8
-rw-r--r--src/plugins/projectexplorer/processparameters.cpp15
-rw-r--r--src/plugins/projectexplorer/project.cpp5
-rw-r--r--src/plugins/projectexplorer/project.h55
-rw-r--r--src/plugins/projectexplorer/projectconfiguration.cpp89
-rw-r--r--src/plugins/projectexplorer/projectconfiguration.h41
-rw-r--r--src/plugins/projectexplorer/projectconfigurationaspects.cpp54
-rw-r--r--src/plugins/projectexplorer/projectconfigurationaspects.h8
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp23
-rw-r--r--src/plugins/projectexplorer/projectexplorer.h1
-rw-r--r--src/plugins/projectexplorer/projectexplorer.pro2
-rw-r--r--src/plugins/projectexplorer/projectexplorer.qbs1
-rw-r--r--src/plugins/projectexplorer/projectmodels.cpp10
-rw-r--r--src/plugins/projectexplorer/projectmodels.h3
-rw-r--r--src/plugins/projectexplorer/projectnodes.cpp33
-rw-r--r--src/plugins/projectexplorer/projectnodes.h17
-rw-r--r--src/plugins/projectexplorer/projecttreewidget.cpp20
-rw-r--r--src/plugins/projectexplorer/projecttreewidget.h3
-rw-r--r--src/plugins/projectexplorer/runconfiguration.cpp15
-rw-r--r--src/plugins/projectexplorer/runconfigurationaspects.cpp38
-rw-r--r--src/plugins/projectexplorer/runconfigurationaspects.h8
-rw-r--r--src/plugins/projectexplorer/runsettingspropertiespage.cpp3
-rw-r--r--src/plugins/projectexplorer/runsettingspropertiespage.h2
-rw-r--r--src/plugins/projectexplorer/subscription.cpp135
-rw-r--r--src/plugins/projectexplorer/subscription.h76
-rw-r--r--src/plugins/projectexplorer/target.h2
-rw-r--r--src/plugins/python/pythonproject.cpp131
-rw-r--r--src/plugins/python/pythonproject.h19
-rw-r--r--src/plugins/python/pythonrunconfiguration.cpp17
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodes.cpp272
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodes.h32
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodes.cpp267
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodes.h37
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.cpp3
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp4
-rw-r--r--src/plugins/qmldesigner/components/integration/designdocument.cpp47
-rw-r--r--src/plugins/qmldesigner/components/integration/designdocument.h10
-rw-r--r--src/plugins/qmldesigner/designercore/include/nodeinstanceview.h16
-rw-r--r--src/plugins/qmldesigner/designercore/include/viewmanager.h6
-rw-r--r--src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp5
-rw-r--r--src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h6
-rw-r--r--src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp20
-rw-r--r--src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp47
-rw-r--r--src/plugins/qmldesigner/designercore/instances/puppetcreator.h10
-rw-r--r--src/plugins/qmldesigner/designercore/model/viewmanager.cpp11
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.cpp4
-rw-r--r--src/plugins/qmljstools/qmljsmodelmanager.cpp77
-rw-r--r--src/plugins/qmljstools/qmljsmodelmanager.h5
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.cpp2
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.h24
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectnodes.cpp113
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectnodes.h5
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp7
-rw-r--r--src/plugins/qtsupport/baseqtversion.cpp294
-rw-r--r--src/plugins/qtsupport/baseqtversion.h5
-rw-r--r--src/plugins/qtsupport/qtoptionspage.cpp2
-rw-r--r--src/plugins/qtsupport/qtversionmanager.cpp4
-rw-r--r--src/plugins/qtsupport/qtversionmanager.h3
-rw-r--r--src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp7
-rw-r--r--src/plugins/webassembly/webassemblyrunconfigurationaspects.h2
-rw-r--r--src/shared/qtcreator_pch.h28
m---------src/tools/perfparser0
-rw-r--r--tests/auto/qml/codemodel/importscheck/tst_importscheck.cpp6
-rw-r--r--tests/manual/genericproject/Makefile18
-rw-r--r--tests/manual/genericproject/genericproject.cflags1
-rw-r--r--tests/manual/genericproject/genericproject.config2
-rw-r--r--tests/manual/genericproject/genericproject.creator1
-rw-r--r--tests/manual/genericproject/genericproject.cxxflags1
-rw-r--r--tests/manual/genericproject/genericproject.files2
-rw-r--r--tests/manual/genericproject/genericproject.includes0
-rw-r--r--tests/manual/genericproject/main.cpp7
187 files changed, 3269 insertions, 2459 deletions
diff --git a/README.md b/README.md
index 7ff6307201..04063db975 100644
--- a/README.md
+++ b/README.md
@@ -276,7 +276,7 @@ http://llvm.org/docs/GettingStarted.html#git-mirror:
The ClangFormat plugin depends on the additional patch
- https://code.qt.io/cgit/clang/clang.git/commit/?h=release_80-based&id=f98a155c89df094fb8f419a20629065f25fe599a
+ https://code.qt.io/cgit/clang/clang.git/commit/?h=release_80-based&id=fa1b9053729ec6a4425a44ec5502dd388928274a
While the plugin builds without it, it will be disabled on start with an error message.
diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake
index 300b7cd50a..35ba699ee0 100644
--- a/cmake/QtCreatorAPI.cmake
+++ b/cmake/QtCreatorAPI.cmake
@@ -15,6 +15,13 @@ list(APPEND DEFAULT_DEFINES
if (WIN32)
list(APPEND DEFAULT_DEFINES UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS)
+
+ if (NOT BUILD_WITH_PCH)
+ # Windows 8 0x0602
+ list(APPEND DEFAULT_DEFINES
+ WINVER=0x0602 _WIN32_WINNT=0x0602
+ WIN32_LEAN_AND_MEAN)
+ endif()
endif()
#
diff --git a/doc/src/howto/creator-only/creator-cli.qdoc b/doc/src/howto/creator-only/creator-cli.qdoc
index 1982c00655..e02b026409 100644
--- a/doc/src/howto/creator-only/creator-cli.qdoc
+++ b/doc/src/howto/creator-only/creator-cli.qdoc
@@ -219,6 +219,11 @@
wizards, see \l{Adding New Custom Wizards}
\row
+ \li -ensure-kit-for-binary <path to binary>
+ \li ProjectExplorer plugin: create a kit with a toolchain
+ corresponding to the given binary's architecture.
+
+ \row
\li -lastsession
\li ProjectExplorer plugin: load the last session when \QC starts.
Open the projects and files that were open when you last exited
diff --git a/doc/src/howto/creator-sidebar-views.qdoc b/doc/src/howto/creator-sidebar-views.qdoc
index 444a601842..1966224775 100644
--- a/doc/src/howto/creator-sidebar-views.qdoc
+++ b/doc/src/howto/creator-sidebar-views.qdoc
@@ -145,6 +145,9 @@
\li To hide source files which are automatically generated by the build
system, select \uicontrol {Filter Tree > Hide Generated Files}.
+ \li To hide source files which are not enabled for the current target,
+ select \uicontrol {Filter Tree} > \uicontrol {Hide Disabled Files}.
+
\li To hide directories that do not contain any files, select
\uicontrol {Filter Tree} > \uicontrol {Hide Empty Directories}.
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp
index ff555f6514..61b21b7810 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp
@@ -97,7 +97,7 @@ void Quick3DNodeInstance::setHideInEditor(bool b)
if (privateNode)
privateNode->setIsHiddenInEditor(b);
#else
- Q_UNUSED(b);
+ Q_UNUSED(b)
#endif
}
diff --git a/src/libs/qmljs/CMakeLists.txt b/src/libs/qmljs/CMakeLists.txt
index 6a4ef362bc..9576fe860b 100644
--- a/src/libs/qmljs/CMakeLists.txt
+++ b/src/libs/qmljs/CMakeLists.txt
@@ -49,5 +49,5 @@ add_qtc_library(qmljs
qmljstypedescriptionreader.cpp qmljstypedescriptionreader.h
qmljsutils.cpp qmljsutils.h
qmljsvalueowner.cpp qmljsvalueowner.h
- qmljsviewercontext.cpp qmljsviewercontext.h
+ qmljsviewercontext.h
)
diff --git a/src/libs/qmljs/qmljs-lib.pri b/src/libs/qmljs/qmljs-lib.pri
index 47967446bf..c9800eab81 100644
--- a/src/libs/qmljs/qmljs-lib.pri
+++ b/src/libs/qmljs/qmljs-lib.pri
@@ -70,7 +70,6 @@ SOURCES += \
$$PWD/qmljssimplereader.cpp \
$$PWD/persistenttrie.cpp \
$$PWD/qmljsimportdependencies.cpp \
- $$PWD/qmljsviewercontext.cpp \
$$PWD/qmljsdialect.cpp
contains(QT, gui) {
diff --git a/src/libs/qmljs/qmljs.qbs b/src/libs/qmljs/qmljs.qbs
index a2580cab1e..d75bfcef7b 100644
--- a/src/libs/qmljs/qmljs.qbs
+++ b/src/libs/qmljs/qmljs.qbs
@@ -53,7 +53,7 @@ Project {
"qmljstypedescriptionreader.cpp", "qmljstypedescriptionreader.h",
"qmljsutils.cpp", "qmljsutils.h",
"qmljsvalueowner.cpp", "qmljsvalueowner.h",
- "qmljsviewercontext.cpp", "qmljsviewercontext.h"
+ "qmljsviewercontext.h"
]
}
diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp
index 659531f130..dfa7414438 100644
--- a/src/libs/qmljs/qmljsdocument.cpp
+++ b/src/libs/qmljs/qmljsdocument.cpp
@@ -359,8 +359,6 @@ Bind *Document::bind() const
}
LibraryInfo::LibraryInfo()
- : _status(NotScanned)
- , _dumpStatus(NoTypeInfo)
{
static const QByteArray emptyFingerprint = calculateFingerprint();
_fingerprint = emptyFingerprint;
@@ -368,18 +366,23 @@ LibraryInfo::LibraryInfo()
LibraryInfo::LibraryInfo(Status status)
: _status(status)
- , _dumpStatus(NoTypeInfo)
{
updateFingerprint();
}
+LibraryInfo::LibraryInfo(const QmlDirParser::TypeInfo &typeInfo)
+ : _status(Found)
+{
+ _typeinfos.append(typeInfo);
+ updateFingerprint();
+}
+
LibraryInfo::LibraryInfo(const QmlDirParser &parser, const QByteArray &fingerprint)
: _status(Found)
, _components(parser.components().values())
, _plugins(parser.plugins())
, _typeinfos(parser.typeInfos())
, _fingerprint(fingerprint)
- , _dumpStatus(NoTypeInfo)
{
if (_fingerprint.isEmpty())
updateFingerprint();
diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h
index 5e80e7612b..7e3b499f5a 100644
--- a/src/libs/qmljs/qmljsdocument.h
+++ b/src/libs/qmljs/qmljsdocument.h
@@ -150,7 +150,7 @@ public:
};
private:
- Status _status;
+ Status _status = NotScanned;
QList<QmlDirParser::Component> _components;
QList<QmlDirParser::Plugin> _plugins;
QList<QmlDirParser::TypeInfo> _typeinfos;
@@ -160,12 +160,13 @@ private:
QStringList _dependencies;
QByteArray _fingerprint;
- PluginTypeInfoStatus _dumpStatus;
+ PluginTypeInfoStatus _dumpStatus = NoTypeInfo;
QString _dumpError;
public:
LibraryInfo();
explicit LibraryInfo(Status status);
+ explicit LibraryInfo(const QmlDirParser::TypeInfo &typeInfo);
explicit LibraryInfo(const QmlDirParser &parser, const QByteArray &fingerprint = QByteArray());
~LibraryInfo() = default;
LibraryInfo(const LibraryInfo &other) = default;
diff --git a/src/libs/qmljs/qmljsimportdependencies.cpp b/src/libs/qmljs/qmljsimportdependencies.cpp
index e5d0161665..a438b93a73 100644
--- a/src/libs/qmljs/qmljsimportdependencies.cpp
+++ b/src/libs/qmljs/qmljsimportdependencies.cpp
@@ -40,6 +40,34 @@ static Q_LOGGING_CATEGORY(importsLog, "qtc.qmljs.imports", QtWarningMsg)
namespace QmlJS {
+/*
+ which languages might be imported in this context
+ */
+static bool languageIsCompatible(Dialect contextLanguage, Dialect importLanguage)
+{
+ if (importLanguage == Dialect::AnyLanguage && contextLanguage != Dialect::NoLanguage)
+ return true;
+ switch (contextLanguage.dialect()) {
+ case Dialect::JavaScript:
+ case Dialect::Json:
+ case Dialect::QmlProject:
+ case Dialect::QmlQbs:
+ case Dialect::QmlTypeInfo:
+ return contextLanguage == importLanguage;
+ case Dialect::Qml:
+ return importLanguage == Dialect::Qml || importLanguage == Dialect::QmlQtQuick2 || importLanguage == Dialect::JavaScript;
+ case Dialect::QmlQtQuick2:
+ case Dialect::QmlQtQuick2Ui:
+ return importLanguage == Dialect::Qml || importLanguage == Dialect::QmlQtQuick2 || importLanguage == Dialect::QmlQtQuick2Ui
+ || importLanguage == Dialect::JavaScript;
+ case Dialect::AnyLanguage:
+ return true;
+ case Dialect::NoLanguage:
+ break;
+ }
+ return false;
+}
+
ImportKind::Enum toImportKind(ImportType::Enum type)
{
switch (type) {
@@ -587,7 +615,7 @@ void ImportDependencies::filter(const ViewerContext &vContext)
bool hasChanges = false;
for (auto j = m_coreImports.cbegin(), end = m_coreImports.cend(); j != end; ++j) {
const CoreImport &cImport = j.value();
- if (vContext.languageIsCompatible(cImport.language)) {
+ if (languageIsCompatible(vContext.language, cImport.language)) {
QList<Export> newExports;
foreach (const Export &e, cImport.possibleExports) {
if (e.visibleInVContext(vContext)) {
@@ -637,7 +665,7 @@ void ImportDependencies::iterateOnCandidateImports(
const QStringList imp = m_importCache.value(key.flatKey());
foreach (const QString &cImportName, imp) {
CoreImport cImport = coreImport(cImportName);
- if (vContext.languageIsCompatible(cImport.language)) {
+ if (languageIsCompatible(vContext.language, cImport.language)) {
foreach (const Export e, cImport.possibleExports) {
if (e.visibleInVContext(vContext)) {
ImportMatchStrength m = e.exportName.matchImport(key, vContext);
@@ -659,7 +687,7 @@ void ImportDependencies::iterateOnCandidateImports(
if (c == ImportKey::SameDir) {
foreach (const QString &cImportName, lb.value()) {
CoreImport cImport = coreImport(cImportName);
- if (vContext.languageIsCompatible(cImport.language)) {
+ if (languageIsCompatible(vContext.language, cImport.language)) {
foreach (const Export e, cImport.possibleExports) {
if (e.visibleInVContext(vContext)) {
ImportMatchStrength m = e.exportName.matchImport(key, vContext);
@@ -835,7 +863,7 @@ void ImportDependencies::iterateOnLibraryImports(
qCDebug(importsLog) << "libloop:" << i.key().toString() << i.value();
foreach (const QString &cImportName, i.value()) {
CoreImport cImport = coreImport(cImportName);
- if (vContext.languageIsCompatible(cImport.language)) {
+ if (languageIsCompatible(vContext.language, cImport.language)) {
foreach (const Export &e, cImport.possibleExports) {
if (e.visibleInVContext(vContext) && e.exportName.type == ImportType::Library) {
ImportMatchStrength m = e.exportName.matchImport(i.key(), vContext);
@@ -869,7 +897,7 @@ void ImportDependencies::iterateOnSubImports(
break;
foreach (const QString &cImportName, i.value()) {
CoreImport cImport = coreImport(cImportName);
- if (vContext.languageIsCompatible(cImport.language)) {
+ if (languageIsCompatible(vContext.language, cImport.language)) {
foreach (const Export &e, cImport.possibleExports) {
if (e.visibleInVContext(vContext)) {
ImportMatchStrength m = e.exportName.matchImport(i.key(), vContext);
diff --git a/src/libs/qmljs/qmljsimportdependencies.h b/src/libs/qmljs/qmljsimportdependencies.h
index 7b6fae431d..903246c034 100644
--- a/src/libs/qmljs/qmljsimportdependencies.h
+++ b/src/libs/qmljs/qmljsimportdependencies.h
@@ -46,7 +46,7 @@ QT_END_NAMESPACE
namespace QmlJS {
class ImportInfo;
-class ViewerContext;
+struct ViewerContext;
namespace Internal { class ImportDependenciesPrivate; }
class ImportDependencies;
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index 396e69b8e5..1f62cf1343 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -46,63 +46,51 @@ class ImportCacheKey
{
public:
explicit ImportCacheKey(const ImportInfo &info)
- : type(info.type())
- , path(info.path())
- , majorVersion(info.version().majorVersion())
- , minorVersion(info.version().minorVersion())
+ : m_type(info.type())
+ , m_path(info.path())
+ , m_majorVersion(info.version().majorVersion())
+ , m_minorVersion(info.version().minorVersion())
{}
- int type;
- QString path;
- int majorVersion;
- int minorVersion;
+private:
+ friend uint qHash(const ImportCacheKey &);
+ friend bool operator==(const ImportCacheKey &, const ImportCacheKey &);
+
+ int m_type;
+ QString m_path;
+ int m_majorVersion;
+ int m_minorVersion;
};
uint qHash(const ImportCacheKey &info)
{
- return ::qHash(info.type) ^ ::qHash(info.path) ^
- ::qHash(info.majorVersion) ^ ::qHash(info.minorVersion);
+ return ::qHash(info.m_type) ^ ::qHash(info.m_path) ^
+ ::qHash(info.m_majorVersion) ^ ::qHash(info.m_minorVersion);
}
bool operator==(const ImportCacheKey &i1, const ImportCacheKey &i2)
{
- return i1.type == i2.type
- && i1.path == i2.path
- && i1.majorVersion == i2.majorVersion
- && i1.minorVersion == i2.minorVersion;
+ return i1.m_type == i2.m_type
+ && i1.m_path == i2.m_path
+ && i1.m_majorVersion == i2.m_majorVersion
+ && i1.m_minorVersion == i2.m_minorVersion;
}
}
class LinkPrivate
{
public:
- Snapshot snapshot;
- ValueOwner *valueOwner;
- QStringList importPaths;
- LibraryInfo builtins;
- ViewerContext vContext;
-
- QHash<ImportCacheKey, Import> importCache;
-
- QHash<QString, QList<ModuleApiInfo> > importableModuleApis;
-
- Document::Ptr document;
- QList<DiagnosticMessage> *diagnosticMessages;
-
- QHash<QString, QList<DiagnosticMessage> > *allDiagnosticMessages;
-
Context::ImportsPerDocument linkImports();
- void populateImportedTypes(Imports *imports, Document::Ptr doc);
+ void populateImportedTypes(Imports *imports, const Document::Ptr &doc);
Import importFileOrDirectory(
- Document::Ptr doc,
+ const Document::Ptr &doc,
const ImportInfo &importInfo);
Import importNonFile(
- Document::Ptr doc,
+ const Document::Ptr &doc,
const ImportInfo &importInfo);
- void importObject(Bind *bind, const QString &name, ObjectValue *object, NameId *targetNamespace);
- bool importLibrary(Document::Ptr doc,
+ bool importLibrary(const Document::Ptr &doc,
const QString &libraryPath,
Import *import,
const QString &importPath = QString());
@@ -110,12 +98,30 @@ public:
LanguageUtils::ComponentVersion version,
const LibraryInfo &libraryInfo,
const QString &libraryPath);
- void loadImplicitDirectoryImports(Imports *imports, Document::Ptr doc);
+ void loadImplicitDirectoryImports(Imports *imports, const Document::Ptr &doc);
void loadImplicitDefaultImports(Imports *imports);
void error(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message);
void warning(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message);
void appendDiagnostic(const Document::Ptr &doc, const DiagnosticMessage &message);
+
+private:
+ friend class Link;
+
+ Snapshot m_snapshot;
+ ValueOwner *m_valueOwner = nullptr;
+ QStringList m_importPaths;
+ QStringList m_applicationDirectories;
+ LibraryInfo m_builtins;
+ ViewerContext m_vContext;
+
+ QHash<ImportCacheKey, Import> importCache;
+ QHash<QString, QList<ModuleApiInfo>> importableModuleApis;
+
+ Document::Ptr document;
+
+ QList<DiagnosticMessage> *diagnosticMessages = nullptr;
+ QHash<QString, QList<DiagnosticMessage>> *allDiagnosticMessages = nullptr;
};
/*!
@@ -132,11 +138,12 @@ public:
Link::Link(const Snapshot &snapshot, const ViewerContext &vContext, const LibraryInfo &builtins)
: d(new LinkPrivate)
{
- d->valueOwner = new ValueOwner;
- d->snapshot = snapshot;
- d->importPaths = vContext.paths;
- d->builtins = builtins;
- d->vContext = vContext;
+ d->m_valueOwner = new ValueOwner;
+ d->m_snapshot = snapshot;
+ d->m_importPaths = vContext.paths;
+ d->m_applicationDirectories = vContext.applicationDirectories;
+ d->m_builtins = builtins;
+ d->m_vContext = vContext;
d->diagnosticMessages = nullptr;
d->allDiagnosticMessages = nullptr;
@@ -147,38 +154,39 @@ Link::Link(const Snapshot &snapshot, const ViewerContext &vContext, const Librar
{
// populate engine with types from C++
for (auto it = cppDataHash.cbegin(), end = cppDataHash.cend(); it != end; ++it)
- d->valueOwner->cppQmlTypes().load(it.key(), it.value().exportedTypes);
+ d->m_valueOwner->cppQmlTypes().load(it.key(), it.value().exportedTypes);
}
// build an object with the context properties from C++
- ObjectValue *cppContextProperties = d->valueOwner->newObject(/* prototype = */ nullptr);
+ ObjectValue *cppContextProperties = d->m_valueOwner->newObject(/* prototype = */ nullptr);
for (const ModelManagerInterface::CppData &cppData : cppDataHash) {
- for (auto it = cppData.contextProperties.cbegin(), end = cppData.contextProperties.cend();
- it != end; ++it) {
+ for (auto it = cppData.contextProperties.cbegin(),
+ end = cppData.contextProperties.cend();
+ it != end; ++it) {
const Value *value = nullptr;
- const QString cppTypeName = it.value();
+ const QString &cppTypeName = it.value();
if (!cppTypeName.isEmpty())
- value = d->valueOwner->cppQmlTypes().objectByCppName(cppTypeName);
+ value = d->m_valueOwner->cppQmlTypes().objectByCppName(cppTypeName);
if (!value)
- value = d->valueOwner->unknownValue();
+ value = d->m_valueOwner->unknownValue();
cppContextProperties->setMember(it.key(), value);
}
}
- d->valueOwner->cppQmlTypes().setCppContextProperties(cppContextProperties);
+ d->m_valueOwner->cppQmlTypes().setCppContextProperties(cppContextProperties);
}
}
ContextPtr Link::operator()(QHash<QString, QList<DiagnosticMessage> > *messages)
{
d->allDiagnosticMessages = messages;
- return Context::create(d->snapshot, d->valueOwner, d->linkImports(), d->vContext);
+ return Context::create(d->m_snapshot, d->m_valueOwner, d->linkImports(), d->m_vContext);
}
ContextPtr Link::operator()(const Document::Ptr &doc, QList<DiagnosticMessage> *messages)
{
d->document = doc;
d->diagnosticMessages = messages;
- return Context::create(d->snapshot, d->valueOwner, d->linkImports(), d->vContext);
+ return Context::create(d->m_snapshot, d->m_valueOwner, d->linkImports(), d->m_vContext);
}
Link::~Link()
@@ -191,34 +199,38 @@ Context::ImportsPerDocument LinkPrivate::linkImports()
Context::ImportsPerDocument importsPerDocument;
// load builtin objects
- if (builtins.pluginTypeInfoStatus() == LibraryInfo::DumpDone
- || builtins.pluginTypeInfoStatus() == LibraryInfo::TypeInfoFileDone) {
- valueOwner->cppQmlTypes().load(QLatin1String("<builtins>"), builtins.metaObjects());
+ if (m_builtins.pluginTypeInfoStatus() == LibraryInfo::DumpDone
+ || m_builtins.pluginTypeInfoStatus() == LibraryInfo::TypeInfoFileDone) {
+ m_valueOwner->cppQmlTypes().load(QLatin1String("<builtins>"), m_builtins.metaObjects());
} else {
- valueOwner->cppQmlTypes().load(QLatin1String("<defaults>"), CppQmlTypesLoader::defaultQtObjects);
+ m_valueOwner->cppQmlTypes().load(QLatin1String("<defaults>"),
+ CppQmlTypesLoader::defaultQtObjects);
}
// load library objects shipped with Creator
- valueOwner->cppQmlTypes().load(QLatin1String("<defaultQt4>"), CppQmlTypesLoader::defaultLibraryObjects);
+ m_valueOwner->cppQmlTypes().load(QLatin1String("<defaultQt4>"),
+ CppQmlTypesLoader::defaultLibraryObjects);
if (document) {
// do it on document first, to make sure import errors are shown
- Imports *imports = new Imports(valueOwner);
+ auto *imports = new Imports(m_valueOwner);
// Add custom imports for the opened document
- for (const auto &provider : CustomImportsProvider::allProviders())
- foreach (const auto &import, provider->imports(valueOwner, document.data()))
+ for (const auto &provider : CustomImportsProvider::allProviders()) {
+ const auto providerImports = provider->imports(m_valueOwner, document.data());
+ for (const auto &import : providerImports)
importCache.insert(ImportCacheKey(import.info), import);
+ }
populateImportedTypes(imports, document);
importsPerDocument.insert(document.data(), QSharedPointer<Imports>(imports));
}
- foreach (Document::Ptr doc, snapshot) {
+ for (const Document::Ptr &doc : qAsConst(m_snapshot)) {
if (doc == document)
continue;
- Imports *imports = new Imports(valueOwner);
+ auto *imports = new Imports(m_valueOwner);
populateImportedTypes(imports, doc);
importsPerDocument.insert(doc.data(), QSharedPointer<Imports>(imports));
}
@@ -226,7 +238,7 @@ Context::ImportsPerDocument LinkPrivate::linkImports()
return importsPerDocument;
}
-void LinkPrivate::populateImportedTypes(Imports *imports, Document::Ptr doc)
+void LinkPrivate::populateImportedTypes(Imports *imports, const Document::Ptr &doc)
{
importableModuleApis.clear();
@@ -239,7 +251,8 @@ void LinkPrivate::populateImportedTypes(Imports *imports, Document::Ptr doc)
loadImplicitDirectoryImports(imports, doc);
// explicit imports, whether directories, files or libraries
- foreach (const ImportInfo &info, doc->bind()->imports()) {
+ const auto docImports = doc->bind()->imports();
+ for (const ImportInfo &info : docImports) {
Import import = importCache.value(ImportCacheKey(info));
// ensure usage of the right ImportInfo, the cached import
@@ -285,7 +298,7 @@ void LinkPrivate::populateImportedTypes(Imports *imports, Document::Ptr doc)
import "file.js" as Foo
*/
-Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &importInfo)
+Import LinkPrivate::importFileOrDirectory(const Document::Ptr &doc, const ImportInfo &importInfo)
{
Import import;
import.info = importInfo;
@@ -296,20 +309,19 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
if (importInfo.type() == ImportType::Directory
|| importInfo.type() == ImportType::ImplicitDirectory) {
- import.object = new ObjectValue(valueOwner);
+ import.object = new ObjectValue(m_valueOwner);
importLibrary(doc, path, &import);
- const QList<Document::Ptr> &documentsInDirectory = snapshot.documentsInDirectory(path);
- foreach (Document::Ptr importedDoc, documentsInDirectory) {
+ const QList<Document::Ptr> documentsInDirectory = m_snapshot.documentsInDirectory(path);
+ for (const Document::Ptr &importedDoc : documentsInDirectory) {
if (importedDoc->bind()->rootObjectValue()) {
const QString targetName = importedDoc->componentName();
import.object->setMember(targetName, importedDoc->bind()->rootObjectValue());
}
}
} else if (importInfo.type() == ImportType::File) {
- Document::Ptr importedDoc = snapshot.document(path);
- if (importedDoc)
+ if (Document::Ptr importedDoc = m_snapshot.document(path))
import.object = importedDoc->bind()->rootObjectValue();
} else if (importInfo.type() == ImportType::QrcFile) {
QLocale locale;
@@ -318,19 +330,19 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
if (filePaths.isEmpty())
filePaths = ModelManagerInterface::instance()->filesAtQrcPath(path);
if (!filePaths.isEmpty()) {
- Document::Ptr importedDoc = snapshot.document(filePaths.at(0));
- if (importedDoc)
+ if (Document::Ptr importedDoc = m_snapshot.document(filePaths.at(0)))
import.object = importedDoc->bind()->rootObjectValue();
}
} else if (importInfo.type() == ImportType::QrcDirectory){
- import.object = new ObjectValue(valueOwner);
+ import.object = new ObjectValue(m_valueOwner);
importLibrary(doc, path, &import);
- const QMap<QString, QStringList> paths = ModelManagerInterface::instance()->filesInQrcPath(path);
+ const QMap<QString, QStringList> paths
+ = ModelManagerInterface::instance()->filesInQrcPath(path);
for (auto iter = paths.cbegin(), end = paths.cend(); iter != end; ++iter) {
if (ModelManagerInterface::guessLanguageOfFile(iter.key()).isQmlLikeLanguage()) {
- Document::Ptr importedDoc = snapshot.document(iter.value().at(0));
+ Document::Ptr importedDoc = m_snapshot.document(iter.value().at(0));
if (importedDoc && importedDoc->bind()->rootObjectValue()) {
const QString targetName = QFileInfo(iter.key()).baseName();
import.object->setMember(targetName, importedDoc->bind()->rootObjectValue());
@@ -341,10 +353,11 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
return import;
}
-static ModuleApiInfo findBestModuleApi(const QList<ModuleApiInfo> &apis, const ComponentVersion &version)
+static ModuleApiInfo findBestModuleApi(const QList<ModuleApiInfo> &apis,
+ const ComponentVersion &version)
{
ModuleApiInfo best;
- foreach (const ModuleApiInfo &moduleApi, apis) {
+ for (const ModuleApiInfo &moduleApi : apis) {
if (moduleApi.version <= version
&& (!best.version.isValid() || best.version < moduleApi.version)) {
best = moduleApi;
@@ -357,33 +370,41 @@ static ModuleApiInfo findBestModuleApi(const QList<ModuleApiInfo> &apis, const C
import Qt 4.6
import Qt 4.6 as Xxx
*/
-Import LinkPrivate::importNonFile(Document::Ptr doc, const ImportInfo &importInfo)
+Import LinkPrivate::importNonFile(const Document::Ptr &doc, const ImportInfo &importInfo)
{
Import import;
import.info = importInfo;
- import.object = new ObjectValue(valueOwner);
+ import.object = new ObjectValue(m_valueOwner);
import.valid = true;
const QString packageName = importInfo.name();
const ComponentVersion version = importInfo.version();
- QString libraryPath = modulePath(packageName, version.toString(), importPaths);
+ QString libraryPath = modulePath(packageName, version.toString(), m_importPaths);
bool importFound = !libraryPath.isEmpty() && importLibrary(doc, libraryPath, &import);
+ if (!importFound) {
+ for (const QString &dir : qAsConst(m_applicationDirectories)) {
+ // This adds the types to the C++ types, to be found below if applicable.
+ if (QFile::exists(dir + "/app.qmltypes"))
+ importLibrary(doc, dir, &import);
+ }
+ }
+
// if there are cpp-based types for this package, use them too
- if (valueOwner->cppQmlTypes().hasModule(packageName)) {
+ if (m_valueOwner->cppQmlTypes().hasModule(packageName)) {
importFound = true;
- foreach (const CppComponentValue *object,
- valueOwner->cppQmlTypes().createObjectsForImport(packageName, version)) {
+ const auto objects = m_valueOwner->cppQmlTypes().createObjectsForImport(packageName,
+ version);
+ for (const CppComponentValue *object : objects)
import.object->setMember(object->className(), object);
- }
}
// check module apis that previous imports may have enabled
ModuleApiInfo moduleApi = findBestModuleApi(importableModuleApis.value(packageName), version);
if (moduleApi.version.isValid()) {
importFound = true;
- import.object->setPrototype(valueOwner->cppQmlTypes().objectByCppName(moduleApi.cppName));
+ import.object->setPrototype(m_valueOwner->cppQmlTypes().objectByCppName(moduleApi.cppName));
}
// TODO: at the moment there is not any types information on Qbs imports.
@@ -402,22 +423,21 @@ Import LinkPrivate::importNonFile(Document::Ptr doc, const ImportInfo &importInf
"For Qbs projects, declare and set a qmlImportPaths property in your product "
"to add import paths.\n"
"For qmlproject projects, use the importPaths property to add import paths.\n"
- "For CMake projects, make sure QML_IMPORT_PATH variable is in CMakeCache.txt.\n").arg(
- importInfo.name(), importPaths.join(QLatin1Char('\n'))));
+ "For CMake projects, make sure QML_IMPORT_PATH variable is in CMakeCache.txt.\n")
+ .arg(importInfo.name(), m_importPaths.join(QLatin1Char('\n'))));
}
return import;
}
-bool LinkPrivate::importLibrary(Document::Ptr doc,
- const QString &libraryPath_,
- Import *import,
- const QString &importPath)
+bool LinkPrivate::importLibrary(const Document::Ptr &doc,
+ const QString &libraryPath,
+ Import *import,
+ const QString &importPath)
{
const ImportInfo &importInfo = import->info;
- QString libraryPath = libraryPath_;
- LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath);
+ LibraryInfo libraryInfo = m_snapshot.libraryInfo(libraryPath);
if (!libraryInfo.isValid())
return false;
@@ -446,9 +466,10 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
}
}
if (errorLoc.isValid()) {
- appendDiagnostic(doc, DiagnosticMessage(Severity::ReadingTypeInfoWarning,
- errorLoc,
- Link::tr("QML module contains C++ plugins, currently reading type information...")));
+ appendDiagnostic(doc, DiagnosticMessage(
+ Severity::ReadingTypeInfoWarning, errorLoc,
+ Link::tr("QML module contains C++ plugins, "
+ "currently reading type information...")));
import->valid = false;
}
} else if (libraryInfo.pluginTypeInfoStatus() == LibraryInfo::DumpError
@@ -456,21 +477,25 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
// Only underline import if package isn't described in .qmltypes anyway
// and is not a private package
QString packageName = importInfo.name();
- if (errorLoc.isValid() && (packageName.isEmpty() || !valueOwner->cppQmlTypes().hasModule(packageName))
+ if (errorLoc.isValid()
+ && (packageName.isEmpty()
+ || !m_valueOwner->cppQmlTypes().hasModule(packageName))
&& !packageName.endsWith(QLatin1String("private"), Qt::CaseInsensitive)) {
error(doc, errorLoc, libraryInfo.pluginTypeInfoError());
import->valid = false;
}
} else {
const QString packageName = importInfo.name();
- valueOwner->cppQmlTypes().load(libraryPath, libraryInfo.metaObjects(), packageName);
- foreach (const CppComponentValue *object, valueOwner->cppQmlTypes().createObjectsForImport(packageName, version)) {
+ m_valueOwner->cppQmlTypes().load(libraryPath, libraryInfo.metaObjects(), packageName);
+ const auto objects = m_valueOwner->cppQmlTypes().createObjectsForImport(packageName,
+ version);
+ for (const CppComponentValue *object : objects)
import->object->setMember(object->className(), object);
- }
// all but no-uri module apis become available for import
QList<ModuleApiInfo> noUriModuleApis;
- foreach (const ModuleApiInfo &moduleApi, libraryInfo.moduleApis()) {
+ const auto moduleApis = libraryInfo.moduleApis();
+ for (const ModuleApiInfo &moduleApi : moduleApis) {
if (moduleApi.uri.isEmpty())
noUriModuleApis += moduleApi;
else
@@ -479,8 +504,10 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
// if a module api has no uri, it shares the same name
ModuleApiInfo sameUriModuleApi = findBestModuleApi(noUriModuleApis, version);
- if (sameUriModuleApi.version.isValid())
- import->object->setPrototype(valueOwner->cppQmlTypes().objectByCppName(sameUriModuleApi.cppName));
+ if (sameUriModuleApi.version.isValid()) {
+ import->object->setPrototype(m_valueOwner->cppQmlTypes()
+ .objectByCppName(sameUriModuleApi.cppName));
+ }
}
}
@@ -489,12 +516,14 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
return true;
}
-void LinkPrivate::error(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message)
+void LinkPrivate::error(const Document::Ptr &doc, const AST::SourceLocation &loc,
+ const QString &message)
{
appendDiagnostic(doc, DiagnosticMessage(Severity::Error, loc, message));
}
-void LinkPrivate::warning(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message)
+void LinkPrivate::warning(const Document::Ptr &doc, const AST::SourceLocation &loc,
+ const QString &message)
{
appendDiagnostic(doc, DiagnosticMessage(Severity::Warning, loc, message));
}
@@ -516,17 +545,17 @@ void LinkPrivate::loadQmldirComponents(ObjectValue *import, ComponentVersion ver
QSet<QString> importedTypes;
- foreach (const QmlDirParser::Component &component, libraryInfo.components()) {
+ const auto components = libraryInfo.components();
+ for (const QmlDirParser::Component &component : components) {
if (importedTypes.contains(component.typeName))
continue;
- ComponentVersion componentVersion(component.majorVersion,
- component.minorVersion);
+ ComponentVersion componentVersion(component.majorVersion, component.minorVersion);
if (version < componentVersion)
continue;
importedTypes.insert(component.typeName);
- if (Document::Ptr importedDoc = snapshot.document(
+ if (Document::Ptr importedDoc = m_snapshot.document(
libraryPath + QLatin1Char('/') + component.fileName)) {
if (ObjectValue *v = importedDoc->bind()->rootObjectValue())
import->setMember(component.typeName, v);
@@ -534,7 +563,7 @@ void LinkPrivate::loadQmldirComponents(ObjectValue *import, ComponentVersion ver
}
}
-void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, Document::Ptr doc)
+void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, const Document::Ptr &doc)
{
auto processImport = [this, imports, doc](const ImportInfo &importInfo){
Import directoryImport = importCache.value(ImportCacheKey(importInfo));
@@ -548,8 +577,8 @@ void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, Document::Ptr d
};
processImport(ImportInfo::implicitDirectoryImport(doc->path()));
- foreach (const QString &path,
- ModelManagerInterface::instance()->qrcPathsForFile(doc->fileName())) {
+ const auto qrcPaths = ModelManagerInterface::instance()->qrcPathsForFile(doc->fileName());
+ for (const QString &path : qrcPaths) {
processImport(ImportInfo::qrcDirectoryImport(
Utils::QrcParser::qrcDirectoryPathForQrcFilePath(path)));
}
@@ -558,19 +587,21 @@ void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, Document::Ptr d
void LinkPrivate::loadImplicitDefaultImports(Imports *imports)
{
const QString defaultPackage = CppQmlTypes::defaultPackage;
- if (valueOwner->cppQmlTypes().hasModule(defaultPackage)) {
- const ComponentVersion maxVersion(ComponentVersion::MaxVersion, ComponentVersion::MaxVersion);
+ if (m_valueOwner->cppQmlTypes().hasModule(defaultPackage)) {
+ const ComponentVersion maxVersion(ComponentVersion::MaxVersion,
+ ComponentVersion::MaxVersion);
const ImportInfo info = ImportInfo::moduleImport(defaultPackage, maxVersion, QString());
Import import = importCache.value(ImportCacheKey(info));
if (!import.object) {
import.valid = true;
import.info = info;
- import.object = new ObjectValue(valueOwner, QLatin1String("<defaults>"));
- foreach (const CppComponentValue *object,
- valueOwner->cppQmlTypes().createObjectsForImport(
- defaultPackage, maxVersion)) {
+ import.object = new ObjectValue(m_valueOwner, QLatin1String("<defaults>"));
+
+ const auto objects = m_valueOwner->cppQmlTypes().createObjectsForImport(defaultPackage,
+ maxVersion);
+ for (const CppComponentValue *object : objects)
import.object->setMember(object->className(), object);
- }
+
importCache.insert(ImportCacheKey(info), import);
}
imports->append(import);
diff --git a/src/libs/qmljs/qmljslink.h b/src/libs/qmljs/qmljslink.h
index e4357061b3..78e97c90cf 100644
--- a/src/libs/qmljs/qmljslink.h
+++ b/src/libs/qmljs/qmljslink.h
@@ -43,10 +43,13 @@ class QMLJS_EXPORT Link
Q_DECLARE_TR_FUNCTIONS(QmlJS::Link)
public:
+ Link(Link &&) = delete;
+ Link &operator=(Link &&) = delete;
+
Link(const Snapshot &snapshot, const ViewerContext &vContext, const LibraryInfo &builtins);
// Link all documents in snapshot, collecting all diagnostic messages (if messages != 0)
- ContextPtr operator()(QHash<QString, QList<DiagnosticMessage> > *messages = nullptr);
+ ContextPtr operator()(QHash<QString, QList<DiagnosticMessage>> *messages = nullptr);
// Link all documents in snapshot, appending the diagnostic messages
// for 'doc' in 'messages'
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
index 4453172e8a..a7f2b3d3ae 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
@@ -50,8 +50,6 @@
#include <QtAlgorithms>
#include <QLibraryInfo>
-#include <stdio.h>
-
using namespace Utils;
namespace QmlJS {
@@ -78,8 +76,13 @@ QMLJS_EXPORT Q_LOGGING_CATEGORY(qmljsLog, "qtc.qmljs.common", QtWarningMsg)
*/
static ModelManagerInterface *g_instance = nullptr;
+static const char *qtQuickUISuffix = "ui.qml";
-const char qtQuickUISuffix[] = "ui.qml";
+static void maybeAddPath(ViewerContext &context, const QString &path)
+{
+ if (!path.isEmpty() && !context.paths.contains(path))
+ context.paths.append(path);
+}
static QStringList environmentImportPaths()
{
@@ -105,13 +108,15 @@ ModelManagerInterface::ModelManagerInterface(QObject *parent)
m_indexerDisabled = qEnvironmentVariableIsSet("QTC_NO_CODE_INDEXER");
m_updateCppQmlTypesTimer = new QTimer(this);
- m_updateCppQmlTypesTimer->setInterval(1000);
+ const int second = 1000;
+ m_updateCppQmlTypesTimer->setInterval(second);
m_updateCppQmlTypesTimer->setSingleShot(true);
connect(m_updateCppQmlTypesTimer, &QTimer::timeout,
this, &ModelManagerInterface::startCppQmlTypeUpdate);
m_asyncResetTimer = new QTimer(this);
- m_asyncResetTimer->setInterval(15000);
+ const int fifteenSeconds = 15000;
+ m_asyncResetTimer->setInterval(fifteenSeconds);
m_asyncResetTimer->setSingleShot(true);
connect(m_asyncResetTimer, &QTimer::timeout, this, &ModelManagerInterface::resetCodeModel);
@@ -173,7 +178,7 @@ Dialect ModelManagerInterface::guessLanguageOfFile(const QString &fileName)
return lMapping.value(fileSuffix, Dialect::NoLanguage);
}
-QStringList ModelManagerInterface::globPatternsForLanguages(const QList<Dialect> languages)
+QStringList ModelManagerInterface::globPatternsForLanguages(const QList<Dialect> &languages)
{
QStringList patterns;
const QHash<QString, Dialect> lMapping =
@@ -229,7 +234,7 @@ ModelManagerInterface::WorkingCopy ModelManagerInterface::workingCopyInternal()
return res;
}
-void ModelManagerInterface::addTaskInternal(QFuture<void> result, const QString &msg,
+void ModelManagerInterface::addTaskInternal(const QFuture<void> &result, const QString &msg,
const char *taskId) const
{
Q_UNUSED(result)
@@ -264,9 +269,9 @@ void ModelManagerInterface::loadQmlTypeDescriptionsInternal(const QString &resou
CppQmlTypesLoader::defaultLibraryObjects.unite(
CppQmlTypesLoader::loadQmlTypes(qmlTypesFiles, &errors, &warnings));
- foreach (const QString &error, errors)
+ for (const QString &error : qAsConst(errors))
writeMessageInternal(error);
- foreach (const QString &warning, warnings)
+ for (const QString &warning : qAsConst(warnings))
writeMessageInternal(warning);
}
@@ -291,7 +296,7 @@ Snapshot ModelManagerInterface::newestSnapshot() const
}
void ModelManagerInterface::updateSourceFiles(const QStringList &files,
- bool emitDocumentOnDiskChanged)
+ bool emitDocumentOnDiskChanged)
{
if (m_indexerDisabled)
return;
@@ -300,10 +305,11 @@ void ModelManagerInterface::updateSourceFiles(const QStringList &files,
void ModelManagerInterface::cleanupFutures()
{
- if (m_futures.size() > 10) {
- QList<QFuture<void> > futures = m_futures;
+ const int maxFutures = 10;
+ if (m_futures.size() > maxFutures) {
+ const QList<QFuture<void>> futures = m_futures;
m_futures.clear();
- foreach (const QFuture<void> &future, futures) {
+ for (const QFuture<void> &future : futures) {
if (!(future.isFinished() || future.isCanceled()))
m_futures.append(future);
}
@@ -311,7 +317,7 @@ void ModelManagerInterface::cleanupFutures()
}
QFuture<void> ModelManagerInterface::refreshSourceFiles(const QStringList &sourceFiles,
- bool emitDocumentOnDiskChanged)
+ bool emitDocumentOnDiskChanged)
{
if (sourceFiles.isEmpty())
return QFuture<void>();
@@ -356,14 +362,15 @@ void ModelManagerInterface::removeFiles(const QStringList &files)
QMutexLocker locker(&m_mutex);
- foreach (const QString &file, files) {
+ for (const QString &file : files) {
m_validSnapshot.remove(file);
m_newestSnapshot.remove(file);
}
}
namespace {
-bool pInfoLessThanActive(const ModelManagerInterface::ProjectInfo &p1, const ModelManagerInterface::ProjectInfo &p2)
+bool pInfoLessThanActive(const ModelManagerInterface::ProjectInfo &p1,
+ const ModelManagerInterface::ProjectInfo &p2)
{
QStringList s1 = p1.activeResourceFiles;
QStringList s2 = p2.activeResourceFiles;
@@ -374,13 +381,14 @@ bool pInfoLessThanActive(const ModelManagerInterface::ProjectInfo &p1, const Mod
for (int i = 0; i < s1.size(); ++i) {
if (s1.at(i) < s2.at(i))
return true;
- else if (s1.at(i) > s2.at(i))
+ if (s1.at(i) > s2.at(i))
return false;
}
return false;
}
-bool pInfoLessThanAll(const ModelManagerInterface::ProjectInfo &p1, const ModelManagerInterface::ProjectInfo &p2)
+bool pInfoLessThanAll(const ModelManagerInterface::ProjectInfo &p1,
+ const ModelManagerInterface::ProjectInfo &p2)
{
QStringList s1 = p1.allResourceFiles;
QStringList s2 = p2.allResourceFiles;
@@ -391,13 +399,14 @@ bool pInfoLessThanAll(const ModelManagerInterface::ProjectInfo &p1, const ModelM
for (int i = 0; i < s1.size(); ++i) {
if (s1.at(i) < s2.at(i))
return true;
- else if (s1.at(i) > s2.at(i))
+ if (s1.at(i) > s2.at(i))
return false;
}
return false;
}
-bool pInfoLessThanImports(const ModelManagerInterface::ProjectInfo &p1, const ModelManagerInterface::ProjectInfo &p2)
+bool pInfoLessThanImports(const ModelManagerInterface::ProjectInfo &p1,
+ const ModelManagerInterface::ProjectInfo &p2)
{
if (p1.qtQmlPath < p2.qtQmlPath)
return true;
@@ -412,7 +421,7 @@ bool pInfoLessThanImports(const ModelManagerInterface::ProjectInfo &p1, const Mo
for (int i = 0; i < s1.size(); ++i) {
if (s1.at(i) < s2.at(i))
return true;
- else if (s2.at(i) < s1.at(i))
+ if (s2.at(i) < s1.at(i))
return false;
}
return false;
@@ -420,9 +429,9 @@ bool pInfoLessThanImports(const ModelManagerInterface::ProjectInfo &p1, const Mo
}
-void ModelManagerInterface::iterateQrcFiles(ProjectExplorer::Project *project,
- QrcResourceSelector resources,
- std::function<void(QrcParser::ConstPtr)> callback)
+void ModelManagerInterface::iterateQrcFiles(
+ ProjectExplorer::Project *project, QrcResourceSelector resources,
+ const std::function<void(QrcParser::ConstPtr)> &callback)
{
QList<ProjectInfo> pInfos;
if (project) {
@@ -436,13 +445,13 @@ void ModelManagerInterface::iterateQrcFiles(ProjectExplorer::Project *project,
}
QSet<QString> pathsChecked;
- foreach (const ModelManagerInterface::ProjectInfo &pInfo, pInfos) {
+ for (const ModelManagerInterface::ProjectInfo &pInfo : qAsConst(pInfos)) {
QStringList qrcFilePaths;
if (resources == ActiveQrcResources)
qrcFilePaths = pInfo.activeResourceFiles;
else
qrcFilePaths = pInfo.allResourceFiles;
- foreach (const QString &qrcFilePath, qrcFilePaths) {
+ for (const QString &qrcFilePath : qAsConst(qrcFilePaths)) {
if (pathsChecked.contains(qrcFilePath))
continue;
pathsChecked.insert(qrcFilePath);
@@ -459,7 +468,7 @@ QStringList ModelManagerInterface::qrcPathsForFile(const QString &file, const QL
QrcResourceSelector resources)
{
QStringList res;
- iterateQrcFiles(project, resources, [&](QrcParser::ConstPtr qrcFile) {
+ iterateQrcFiles(project, resources, [&](const QrcParser::ConstPtr &qrcFile) {
qrcFile->collectResourceFilesForSourceFile(file, &res, locale);
});
return res;
@@ -471,7 +480,7 @@ QStringList ModelManagerInterface::filesAtQrcPath(const QString &path, const QLo
{
QString normPath = QrcParser::normalizedQrcFilePath(path);
QStringList res;
- iterateQrcFiles(project, resources, [&](QrcParser::ConstPtr qrcFile) {
+ iterateQrcFiles(project, resources, [&](const QrcParser::ConstPtr &qrcFile) {
qrcFile->collectFilesAtPath(normPath, &res, locale);
});
return res;
@@ -485,7 +494,7 @@ QMap<QString, QStringList> ModelManagerInterface::filesInQrcPath(const QString &
{
QString normPath = QrcParser::normalizedQrcDirectoryPath(path);
QMap<QString, QStringList> res;
- iterateQrcFiles(project, resources, [&](QrcParser::ConstPtr qrcFile) {
+ iterateQrcFiles(project, resources, [&](const QrcParser::ConstPtr &qrcFile) {
qrcFile->collectFilesInPath(normPath, &res, addDirs, locale);
});
return res;
@@ -498,18 +507,22 @@ QList<ModelManagerInterface::ProjectInfo> ModelManagerInterface::projectInfos()
return m_projects.values();
}
-ModelManagerInterface::ProjectInfo ModelManagerInterface::projectInfo(
- ProjectExplorer::Project *project,
- const ModelManagerInterface::ProjectInfo &defaultValue) const
+bool ModelManagerInterface::containsProject(ProjectExplorer::Project *project) const
{
QMutexLocker locker(&m_mutex);
+ return m_projects.contains(project);
+}
- return m_projects.value(project, defaultValue);
+ModelManagerInterface::ProjectInfo ModelManagerInterface::projectInfo(
+ ProjectExplorer::Project *project) const
+{
+ QMutexLocker locker(&m_mutex);
+ return m_projects.value(project);
}
void ModelManagerInterface::updateProjectInfo(const ProjectInfo &pinfo, ProjectExplorer::Project *p)
{
- if (! pinfo.isValid() || !p || m_indexerDisabled)
+ if (pinfo.project.isNull() || !p || m_indexerDisabled)
return;
Snapshot snapshot;
@@ -533,7 +546,7 @@ void ModelManagerInterface::updateProjectInfo(const ProjectInfo &pinfo, ProjectE
// remove files that are no longer in the project and have been deleted
QStringList deletedFiles;
- foreach (const QString &oldFile, oldInfo.sourceFiles) {
+ for (const QString &oldFile : qAsConst(oldInfo.sourceFiles)) {
if (snapshot.document(oldFile)
&& !pinfo.sourceFiles.contains(oldFile)
&& !QFile::exists(oldFile)) {
@@ -541,38 +554,27 @@ void ModelManagerInterface::updateProjectInfo(const ProjectInfo &pinfo, ProjectE
}
}
removeFiles(deletedFiles);
- foreach (const QString &oldFile, deletedFiles)
+ for (const QString &oldFile : qAsConst(deletedFiles))
m_fileToProject.remove(oldFile, p);
// parse any files not yet in the snapshot
QStringList newFiles;
- foreach (const QString &file, pinfo.sourceFiles) {
+ for (const QString &file : qAsConst(pinfo.sourceFiles)) {
if (!snapshot.document(file))
newFiles += file;
}
- foreach (const QString &newFile, newFiles)
+ for (const QString &newFile : qAsConst(newFiles))
m_fileToProject.insert(newFile, p);
updateSourceFiles(newFiles, false);
// update qrc cache
m_qrcContents = pinfo.resourceFileContents;
- foreach (const QString &newQrc, pinfo.allResourceFiles)
+ for (const QString &newQrc : qAsConst(pinfo.allResourceFiles))
m_qrcCache.addPath(newQrc, m_qrcContents.value(newQrc));
- foreach (const QString &oldQrc, oldInfo.allResourceFiles)
+ for (const QString &oldQrc : qAsConst(oldInfo.allResourceFiles))
m_qrcCache.removePath(oldQrc);
- int majorVersion, minorVersion, patchVersion;
- // dump builtin types if the shipped definitions are probably outdated and the
- // Qt version ships qmlplugindump
- if (::sscanf(pinfo.qtVersionString.toLatin1().constData(), "%d.%d.%d",
- &majorVersion, &minorVersion, &patchVersion) != 3)
- majorVersion = minorVersion = patchVersion = -1;
-
- if (majorVersion > 4 || (majorVersion == 4 && (minorVersion > 8 || (minorVersion == 8
- && patchVersion >= 5)))) {
- m_pluginDumper->loadBuiltinTypes(pinfo);
- }
-
+ m_pluginDumper->loadBuiltinTypes(pinfo);
emit projectInfoUpdated(pinfo);
}
@@ -595,22 +597,27 @@ void ModelManagerInterface::removeProjectInfo(ProjectExplorer::Project *project)
\note Project pointer will be empty
*/
-ModelManagerInterface::ProjectInfo ModelManagerInterface::projectInfoForPath(const QString &path) const
+ModelManagerInterface::ProjectInfo ModelManagerInterface::projectInfoForPath(
+ const QString &path) const
{
ProjectInfo res;
- foreach (const ProjectInfo &pInfo, allProjectInfosForPath(path)) {
+ const auto allProjectInfos = allProjectInfosForPath(path);
+ for (const ProjectInfo &pInfo : allProjectInfos) {
if (res.qtQmlPath.isEmpty())
res.qtQmlPath = pInfo.qtQmlPath;
- for (int i = 0; i < pInfo.importPaths.size(); ++i)
- res.importPaths.maybeInsert(pInfo.importPaths.at(i));
+ res.applicationDirectories.append(pInfo.applicationDirectories);
+ for (const auto &importPath : pInfo.importPaths)
+ res.importPaths.maybeInsert(importPath);
}
+ res.applicationDirectories = Utils::filteredUnique(res.applicationDirectories);
return res;
}
/*!
Returns list of project infos for \a path
*/
-QList<ModelManagerInterface::ProjectInfo> ModelManagerInterface::allProjectInfosForPath(const QString &path) const
+QList<ModelManagerInterface::ProjectInfo> ModelManagerInterface::allProjectInfosForPath(
+ const QString &path) const
{
QList<ProjectExplorer::Project *> projects;
{
@@ -622,9 +629,9 @@ QList<ModelManagerInterface::ProjectInfo> ModelManagerInterface::allProjectInfos
}
}
QList<ProjectInfo> infos;
- foreach (ProjectExplorer::Project *project, projects) {
+ for (ProjectExplorer::Project *project : qAsConst(projects)) {
ProjectInfo info = projectInfo(project);
- if (info.isValid())
+ if (!info.project.isNull())
infos.append(info);
}
std::sort(infos.begin(), infos.end(), &pInfoLessThanImports);
@@ -638,14 +645,16 @@ bool ModelManagerInterface::isIdle() const
}
void ModelManagerInterface::emitDocumentChangedOnDisk(Document::Ptr doc)
-{ emit documentChangedOnDisk(doc); }
+{
+ emit documentChangedOnDisk(std::move(doc));
+}
void ModelManagerInterface::updateQrcFile(const QString &path)
{
m_qrcCache.updatePath(path, m_qrcContents.value(path));
}
-void ModelManagerInterface::updateDocument(Document::Ptr doc)
+void ModelManagerInterface::updateDocument(const Document::Ptr &doc)
{
{
QMutexLocker locker(&m_mutex);
@@ -670,27 +679,29 @@ void ModelManagerInterface::updateLibraryInfo(const QString &path, const Library
emit libraryInfoUpdated(path, info);
}
-static QStringList filesInDirectoryForLanguages(const QString &path, QList<Dialect> languages)
+static QStringList filesInDirectoryForLanguages(const QString &path,
+ const QList<Dialect> &languages)
{
const QStringList pattern = ModelManagerInterface::globPatternsForLanguages(languages);
QStringList files;
const QDir dir(path);
- foreach (const QFileInfo &fi, dir.entryInfoList(pattern, QDir::Files))
+ const auto entries = dir.entryInfoList(pattern, QDir::Files);
+ for (const QFileInfo &fi : entries)
files += fi.absoluteFilePath();
return files;
}
static void findNewImplicitImports(const Document::Ptr &doc, const Snapshot &snapshot,
- QStringList *importedFiles, QSet<QString> *scannedPaths)
+ QStringList *importedFiles, QSet<QString> *scannedPaths)
{
// scan files that could be implicitly imported
// it's important we also do this for JS files, otherwise the isEmpty check will fail
if (snapshot.documentsInDirectory(doc->path()).isEmpty()) {
- if (! scannedPaths->contains(doc->path())) {
+ if (!scannedPaths->contains(doc->path())) {
*importedFiles += filesInDirectoryForLanguages(doc->path(),
- doc->language().companionLanguages());
+ doc->language().companionLanguages());
scannedPaths->insert(doc->path());
}
}
@@ -700,7 +711,8 @@ static void findNewFileImports(const Document::Ptr &doc, const Snapshot &snapsho
QStringList *importedFiles, QSet<QString> *scannedPaths)
{
// scan files and directories that are explicitly imported
- foreach (const ImportInfo &import, doc->bind()->imports()) {
+ const auto imports = doc->bind()->imports();
+ for (const ImportInfo &import : imports) {
const QString &importName = import.path();
if (import.type() == ImportType::File) {
if (! snapshot.document(importName))
@@ -708,24 +720,26 @@ static void findNewFileImports(const Document::Ptr &doc, const Snapshot &snapsho
} else if (import.type() == ImportType::Directory) {
if (snapshot.documentsInDirectory(importName).isEmpty()) {
if (! scannedPaths->contains(importName)) {
- *importedFiles += filesInDirectoryForLanguages(importName,
- doc->language().companionLanguages());
+ *importedFiles += filesInDirectoryForLanguages(
+ importName, doc->language().companionLanguages());
scannedPaths->insert(importName);
}
}
} else if (import.type() == ImportType::QrcFile) {
- QStringList importPaths = ModelManagerInterface::instance()->filesAtQrcPath(importName);
- foreach (const QString &importPath, importPaths) {
- if (! snapshot.document(importPath))
+ const QStringList importPaths
+ = ModelManagerInterface::instance()->filesAtQrcPath(importName);
+ for (const QString &importPath : importPaths) {
+ if (!snapshot.document(importPath))
*importedFiles += importPath;
}
} else if (import.type() == ImportType::QrcDirectory) {
- const QMap<QString, QStringList> files = ModelManagerInterface::instance()->filesInQrcPath(importName);
- for (auto dirContents = files.cbegin(), end = files.cend(); dirContents != end; ++dirContents) {
- if (ModelManagerInterface::guessLanguageOfFile(dirContents.key()).isQmlLikeOrJsLanguage()) {
- foreach (const QString &filePath, dirContents.value()) {
- if (! snapshot.document(filePath))
- *importedFiles += filePath;
+ const QMap<QString, QStringList> files
+ = ModelManagerInterface::instance()->filesInQrcPath(importName);
+ for (auto qrc = files.cbegin(), end = files.cend(); qrc != end; ++qrc) {
+ if (ModelManagerInterface::guessLanguageOfFile(qrc.key()).isQmlLikeOrJsLanguage()) {
+ for (const QString &sourceFile : qrc.value()) {
+ if (!snapshot.document(sourceFile))
+ *importedFiles += sourceFile;
}
}
}
@@ -733,6 +747,55 @@ static void findNewFileImports(const Document::Ptr &doc, const Snapshot &snapsho
}
}
+enum class LibraryStatus {
+ Accepted,
+ Rejected,
+ Unknown
+};
+
+static LibraryStatus libraryStatus(const QString &path, const Snapshot &snapshot,
+ QSet<QString> *newLibraries)
+{
+ if (path.isEmpty())
+ return LibraryStatus::Rejected;
+ // if we know there is a library, done
+ const LibraryInfo &existingInfo = snapshot.libraryInfo(path);
+ if (existingInfo.isValid())
+ return LibraryStatus::Accepted;
+ if (newLibraries->contains(path))
+ return LibraryStatus::Accepted;
+ // if we looked at the path before, done
+ return existingInfo.wasScanned()
+ ? LibraryStatus::Rejected
+ : LibraryStatus::Unknown;
+}
+
+static bool findNewQmlApplicationInPath(const QString &path,
+ const Snapshot &snapshot,
+ ModelManagerInterface *modelManager,
+ QSet<QString> *newLibraries)
+{
+ switch (libraryStatus(path, snapshot, newLibraries)) {
+ case LibraryStatus::Accepted: return true;
+ case LibraryStatus::Rejected: return false;
+ default: break;
+ }
+
+ const QDir dir(path);
+ const QLatin1String appQmltypes("app.qmltypes");
+ QFile appQmltypesFile(dir.filePath(appQmltypes));
+ if (!appQmltypesFile.exists())
+ return false;
+
+ LibraryInfo libraryInfo = LibraryInfo(QmlDirParser::TypeInfo(appQmltypes));
+ const QString libraryPath = dir.absolutePath();
+ newLibraries->insert(libraryPath);
+ modelManager->updateLibraryInfo(path, libraryInfo);
+ modelManager->loadPluginTypes(QFileInfo(libraryPath).canonicalFilePath(), libraryPath,
+ QString(), QString());
+ return true;
+}
+
static bool findNewQmlLibraryInPath(const QString &path,
const Snapshot &snapshot,
ModelManagerInterface *modelManager,
@@ -741,15 +804,11 @@ static bool findNewQmlLibraryInPath(const QString &path,
QSet<QString> *newLibraries,
bool ignoreMissing)
{
- // if we know there is a library, done
- const LibraryInfo &existingInfo = snapshot.libraryInfo(path);
- if (existingInfo.isValid())
- return true;
- if (newLibraries->contains(path))
- return true;
- // if we looked at the path before, done
- if (existingInfo.wasScanned())
- return false;
+ switch (libraryStatus(path, snapshot, newLibraries)) {
+ case LibraryStatus::Accepted: return true;
+ case LibraryStatus::Rejected: return false;
+ default: break;
+ }
const QDir dir(path);
QFile qmldirFile(dir.filePath(QLatin1String("qmldir")));
@@ -780,13 +839,14 @@ static bool findNewQmlLibraryInPath(const QString &path,
QString(), QString());
// scan the qml files in the library
- foreach (const QmlDirParser::Component &component, qmldirParser.components()) {
- if (! component.fileName.isEmpty()) {
+ const auto components = qmldirParser.components();
+ for (const QmlDirParser::Component &component : components) {
+ if (!component.fileName.isEmpty()) {
const QFileInfo componentFileInfo(dir.filePath(component.fileName));
const QString path = QDir::cleanPath(componentFileInfo.absolutePath());
- if (! scannedPaths->contains(path)) {
- *importedFiles += filesInDirectoryForLanguages(path,
- Dialect(Dialect::AnyLanguage).companionLanguages());
+ if (!scannedPaths->contains(path)) {
+ *importedFiles += filesInDirectoryForLanguages(path, Dialect(Dialect::AnyLanguage)
+ .companionLanguages());
scannedPaths->insert(path);
}
}
@@ -803,8 +863,8 @@ static QString modulePath(const ImportInfo &import, const QStringList &paths)
}
static void findNewLibraryImports(const Document::Ptr &doc, const Snapshot &snapshot,
- ModelManagerInterface *modelManager,
- QStringList *importedFiles, QSet<QString> *scannedPaths, QSet<QString> *newLibraries)
+ ModelManagerInterface *modelManager, QStringList *importedFiles,
+ QSet<QString> *scannedPaths, QSet<QString> *newLibraries)
{
// scan current dir
findNewQmlLibraryInPath(doc->path(), snapshot, modelManager,
@@ -812,31 +872,31 @@ static void findNewLibraryImports(const Document::Ptr &doc, const Snapshot &snap
// scan dir and lib imports
const QStringList importPaths = modelManager->importPathsNames();
- foreach (const ImportInfo &import, doc->bind()->imports()) {
- if (import.type() == ImportType::Directory) {
- const QString targetPath = import.path();
- findNewQmlLibraryInPath(targetPath, snapshot, modelManager,
+ const auto imports = doc->bind()->imports();
+ for (const ImportInfo &import : imports) {
+ switch (import.type()) {
+ case ImportType::Directory:
+ findNewQmlLibraryInPath(import.path(), snapshot, modelManager,
importedFiles, scannedPaths, newLibraries, false);
- }
-
- if (import.type() == ImportType::Library) {
- const QString libraryPath = modulePath(import, importPaths);
- if (libraryPath.isEmpty())
- continue;
- findNewQmlLibraryInPath(libraryPath, snapshot, modelManager, importedFiles,
- scannedPaths, newLibraries, false);
+ break;
+ case ImportType::Library:
+ findNewQmlLibraryInPath(modulePath(import, importPaths), snapshot, modelManager,
+ importedFiles, scannedPaths, newLibraries, false);
+ break;
+ default:
+ break;
}
}
}
void ModelManagerInterface::parseLoop(QSet<QString> &scannedPaths,
- QSet<QString> &newLibraries,
- WorkingCopy workingCopy,
- QStringList files,
- ModelManagerInterface *modelManager,
- Dialect mainLanguage,
- bool emitDocChangedOnDisk,
- std::function<bool(qreal)> reportProgress)
+ QSet<QString> &newLibraries,
+ const WorkingCopy &workingCopy,
+ QStringList files,
+ ModelManagerInterface *modelManager,
+ Dialect mainLanguage,
+ bool emitDocChangedOnDisk,
+ const std::function<bool(qreal)> &reportProgress)
{
for (int i = 0; i < files.size(); ++i) {
if (!reportProgress(qreal(i) / files.size()))
@@ -889,11 +949,12 @@ void ModelManagerInterface::parseLoop(QSet<QString> &scannedPaths,
QStringList importedFiles;
findNewImplicitImports(doc, snapshot, &importedFiles, &scannedPaths);
findNewFileImports(doc, snapshot, &importedFiles, &scannedPaths);
- findNewLibraryImports(doc, snapshot, modelManager, &importedFiles, &scannedPaths, &newLibraries);
+ findNewLibraryImports(doc, snapshot, modelManager, &importedFiles, &scannedPaths,
+ &newLibraries);
// add new files to parse list
- foreach (const QString &file, importedFiles) {
- if (! files.contains(file))
+ for (const QString &file : qAsConst(importedFiles)) {
+ if (!files.contains(file))
files.append(file);
}
@@ -906,9 +967,10 @@ void ModelManagerInterface::parseLoop(QSet<QString> &scannedPaths,
class FutureReporter
{
public:
- FutureReporter(QFutureInterface<void> &future, int multiplier = 100, int base = 0)
- :future(future), multiplier(multiplier), base(base)
- { }
+ FutureReporter(QFutureInterface<void> &future, int multiplier, int base)
+ : future(future), multiplier(multiplier), base(base)
+ {}
+
bool operator()(qreal val)
{
if (future.isCanceled())
@@ -923,37 +985,36 @@ private:
};
void ModelManagerInterface::parse(QFutureInterface<void> &future,
- WorkingCopy workingCopy,
- QStringList files,
- ModelManagerInterface *modelManager,
- Dialect mainLanguage,
- bool emitDocChangedOnDisk)
+ const WorkingCopy &workingCopy,
+ QStringList files,
+ ModelManagerInterface *modelManager,
+ Dialect mainLanguage,
+ bool emitDocChangedOnDisk)
{
- FutureReporter reporter(future);
- future.setProgressRange(0, 100);
+ const int progressMax = 100;
+ FutureReporter reporter(future, progressMax, 0);
+ future.setProgressRange(0, progressMax);
// paths we have scanned for files and added to the files list
QSet<QString> scannedPaths;
// libraries we've found while scanning imports
QSet<QString> newLibraries;
- parseLoop(scannedPaths, newLibraries, workingCopy, files, modelManager, mainLanguage,
+ parseLoop(scannedPaths, newLibraries, workingCopy, std::move(files), modelManager, mainLanguage,
emitDocChangedOnDisk, reporter);
- future.setProgressValue(100);
+ future.setProgressValue(progressMax);
}
struct ScanItem {
QString path;
- int depth;
- Dialect language;
- ScanItem(QString path = QString(), int depth = 0, Dialect language = Dialect::AnyLanguage)
- : path(path), depth(depth), language(language)
- { }
+ int depth = 0;
+ Dialect language = Dialect::AnyLanguage;
};
void ModelManagerInterface::importScan(QFutureInterface<void> &future,
- ModelManagerInterface::WorkingCopy workingCopy,
- PathsAndLanguages paths, ModelManagerInterface *modelManager,
- bool emitDocChangedOnDisk, bool libOnly, bool forceRescan)
+ const ModelManagerInterface::WorkingCopy &workingCopy,
+ const PathsAndLanguages &paths,
+ ModelManagerInterface *modelManager,
+ bool emitDocChangedOnDisk, bool libOnly, bool forceRescan)
{
// paths we have scanned for files and added to the files list
QSet<QString> scannedPaths;
@@ -968,18 +1029,18 @@ void ModelManagerInterface::importScan(QFutureInterface<void> &future,
pathsToScan.reserve(paths.size());
{
QMutexLocker l(&modelManager->m_mutex);
- for (int i = 0; i < paths.size(); ++i) {
- PathAndLanguage pAndL = paths.at(i);
- QString cPath = QDir::cleanPath(pAndL.path().toString());
+ for (const auto &path : paths) {
+ QString cPath = QDir::cleanPath(path.path().toString());
if (!forceRescan && modelManager->m_scannedPaths.contains(cPath))
continue;
- pathsToScan.append(ScanItem(cPath, 0, pAndL.language()));
+ pathsToScan.append({cPath, 0, path.language()});
modelManager->m_scannedPaths.insert(cPath);
}
}
const int maxScanDepth = 5;
int progressRange = pathsToScan.size() * (1 << (2 + maxScanDepth));
- int totalWork(progressRange), workDone(0);
+ int totalWork = progressRange;
+ int workDone = 0;
future.setProgressRange(0, progressRange); // update max length while iterating?
const Snapshot snapshot = modelManager->snapshot();
bool isCanceled = future.isCanceled();
@@ -991,10 +1052,10 @@ void ModelManagerInterface::importScan(QFutureInterface<void> &future,
QStringList importedFiles;
if (forceRescan ||
(!findNewQmlLibraryInPath(toScan.path, snapshot, modelManager, &importedFiles,
- &scannedPaths, &newLibraries, true)
+ &scannedPaths, &newLibraries, true)
&& !libOnly && snapshot.documentsInDirectory(toScan.path).isEmpty())) {
importedFiles += filesInDirectoryForLanguages(toScan.path,
- toScan.language.companionLanguages());
+ toScan.language.companionLanguages());
}
workDone += 1;
future.setProgressValue(progressRange * workDone / totalWork);
@@ -1016,8 +1077,8 @@ void ModelManagerInterface::importScan(QFutureInterface<void> &future,
QStringList subDirs(dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot));
workDone += 1;
totalWork += pathBudget / 2 * subDirs.size() - pathBudget * 3 / 4 + 1;
- foreach (const QString path, subDirs)
- pathsToScan.append(ScanItem(dir.absoluteFilePath(path), toScan.depth + 1, toScan.language));
+ for (const QString &path : qAsConst(subDirs))
+ pathsToScan.append({dir.absoluteFilePath(path), toScan.depth + 1, toScan.language});
} else {
workDone += pathBudget * 3 / 4;
}
@@ -1028,8 +1089,8 @@ void ModelManagerInterface::importScan(QFutureInterface<void> &future,
if (isCanceled) {
// assume no work has been done
QMutexLocker l(&modelManager->m_mutex);
- for (int i = 0; i < paths.size(); ++i)
- modelManager->m_scannedPaths.remove(paths.at(i).path().toString());
+ for (const auto &path : paths)
+ modelManager->m_scannedPaths.remove(path.path().toString());
}
}
@@ -1062,7 +1123,7 @@ void ModelManagerInterface::maybeScan(const PathsAndLanguages &importPaths)
PathsAndLanguages pathToScan;
{
QMutexLocker l(&m_mutex);
- foreach (const PathAndLanguage &importPath, importPaths)
+ for (const PathAndLanguage &importPath : importPaths)
if (!m_scannedPaths.contains(importPath.path().toString()))
pathToScan.maybeInsert(importPath);
}
@@ -1083,48 +1144,56 @@ void ModelManagerInterface::updateImportPaths()
if (m_indexerDisabled)
return;
PathsAndLanguages allImportPaths;
+ QStringList allApplicationDirectories;
QmlLanguageBundles activeBundles;
QmlLanguageBundles extendedBundles;
- for (auto pInfoIter = m_projects.cbegin(), end = m_projects.cend(); pInfoIter != end; ++pInfoIter) {
- const PathsAndLanguages &iPaths = pInfoIter.value().importPaths;
- for (int i = 0; i < iPaths.size(); ++i) {
- PathAndLanguage pAndL = iPaths.at(i);
- const QString canonicalPath = pAndL.path().toFileInfo().canonicalFilePath();
- if (!canonicalPath.isEmpty())
+ for (const ProjectInfo &pInfo : qAsConst(m_projects)) {
+ for (const auto &importPath : pInfo.importPaths) {
+ const QString canonicalPath = importPath.path().toFileInfo().canonicalFilePath();
+ if (!canonicalPath.isEmpty()) {
allImportPaths.maybeInsert(Utils::FilePath::fromString(canonicalPath),
- pAndL.language());
+ importPath.language());
+ }
}
+ allApplicationDirectories.append(pInfo.applicationDirectories);
}
- for (auto vCtxsIter = m_defaultVContexts.cbegin(), end = m_defaultVContexts.cend();
- vCtxsIter != end; ++ vCtxsIter) {
- foreach (const QString &path, vCtxsIter.value().paths)
- allImportPaths.maybeInsert(Utils::FilePath::fromString(path), vCtxsIter.value().language);
+
+ for (const ViewerContext &vContext : qAsConst(m_defaultVContexts)) {
+ for (const QString &path : vContext.paths)
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(path), vContext.language);
+ allApplicationDirectories.append(vContext.applicationDirectories);
}
- for (auto pInfoIter = m_projects.cbegin(), end = m_projects.cend(); pInfoIter != end; ++pInfoIter) {
- activeBundles.mergeLanguageBundles(pInfoIter.value().activeBundle);
- foreach (Dialect l, pInfoIter.value().activeBundle.languages()) {
- foreach (const QString &path, pInfoIter.value().activeBundle.bundleForLanguage(l)
- .searchPaths().stringList()) {
+
+ for (const ProjectInfo &pInfo : qAsConst(m_projects)) {
+ activeBundles.mergeLanguageBundles(pInfo.activeBundle);
+ const auto languages = pInfo.activeBundle.languages();
+ for (Dialect l : languages) {
+ const auto paths = pInfo.activeBundle.bundleForLanguage(l).searchPaths().stringList();
+ for (const QString &path : paths) {
const QString canonicalPath = QFileInfo(path).canonicalFilePath();
if (!canonicalPath.isEmpty())
allImportPaths.maybeInsert(Utils::FilePath::fromString(canonicalPath), l);
}
}
}
- for (auto pInfoIter = m_projects.cbegin(), end = m_projects.cend(); pInfoIter != end; ++pInfoIter) {
- QString pathAtt = pInfoIter.value().qtQmlPath;
- if (!pathAtt.isEmpty())
- allImportPaths.maybeInsert(Utils::FilePath::fromString(pathAtt), Dialect::QmlQtQuick2);
+
+ for (const ProjectInfo &pInfo : qAsConst(m_projects)) {
+ if (!pInfo.qtQmlPath.isEmpty()) {
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(pInfo.qtQmlPath),
+ Dialect::QmlQtQuick2);
+ }
}
+
{
- QString pathAtt = defaultProjectInfo().qtQmlPath;
+ const QString pathAtt = defaultProjectInfo().qtQmlPath;
if (!pathAtt.isEmpty())
allImportPaths.maybeInsert(Utils::FilePath::fromString(pathAtt), Dialect::QmlQtQuick2);
}
- foreach (const QString &path, m_defaultImportPaths)
+ for (const QString &path : qAsConst(m_defaultImportPaths))
allImportPaths.maybeInsert(Utils::FilePath::fromString(path), Dialect::Qml);
allImportPaths.compact();
+ allApplicationDirectories = Utils::filteredUnique(allApplicationDirectories);
{
QMutexLocker l(&m_mutex);
@@ -1139,8 +1208,10 @@ void ModelManagerInterface::updateImportPaths()
QStringList importedFiles;
QSet<QString> scannedPaths;
QSet<QString> newLibraries;
- foreach (const Document::Ptr &doc, snapshot)
+ for (const Document::Ptr &doc : qAsConst(snapshot))
findNewLibraryImports(doc, snapshot, this, &importedFiles, &scannedPaths, &newLibraries);
+ for (const QString &path : allApplicationDirectories)
+ findNewQmlApplicationInPath(path, snapshot, this, &newLibraries);
updateSourceFiles(importedFiles, true);
@@ -1224,13 +1295,14 @@ bool rescanExports(const QString &fileName, FindExportedCppTypes &finder,
} else {
ModelManagerInterface::CppData &data = newData[fileName];
if (!hasNewInfo && (data.exportedTypes.size() != exported.size()
- || data.contextProperties != contextProperties))
+ || data.contextProperties != contextProperties)) {
hasNewInfo = true;
+ }
if (!hasNewInfo) {
QHash<QString, QByteArray> newFingerprints;
- foreach (LanguageUtils::FakeMetaObject::ConstPtr newType, exported)
+ for (const auto &newType : qAsConst(exported))
newFingerprints[newType->className()]=newType->fingerprint();
- foreach (LanguageUtils::FakeMetaObject::ConstPtr oldType, data.exportedTypes) {
+ for (const auto &oldType : qAsConst(data.exportedTypes)) {
if (newFingerprints.value(oldType->className()) != oldType->fingerprint()) {
hasNewInfo = true;
break;
@@ -1243,16 +1315,16 @@ bool rescanExports(const QString &fileName, FindExportedCppTypes &finder,
return hasNewInfo;
}
-void ModelManagerInterface::updateCppQmlTypes(QFutureInterface<void> &futureInterface,
- ModelManagerInterface *qmlModelManager,
- CPlusPlus::Snapshot snapshot,
- QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > documents)
+void ModelManagerInterface::updateCppQmlTypes(
+ QFutureInterface<void> &futureInterface, ModelManagerInterface *qmlModelManager,
+ const CPlusPlus::Snapshot &snapshot,
+ const QHash<QString, QPair<CPlusPlus::Document::Ptr, bool>> &documents)
{
futureInterface.setProgressRange(0, documents.size());
futureInterface.setProgressValue(0);
CppDataHash newData;
- QHash<QString, QList<CPlusPlus::Document::Ptr> > newDeclarations;
+ QHash<QString, QList<CPlusPlus::Document::Ptr>> newDeclarations;
{
QMutexLocker locker(&qmlModelManager->m_cppDataMutex);
newData = qmlModelManager->m_cppDataHash;
@@ -1262,8 +1334,8 @@ void ModelManagerInterface::updateCppQmlTypes(QFutureInterface<void> &futureInte
FindExportedCppTypes finder(snapshot);
bool hasNewInfo = false;
- typedef QPair<CPlusPlus::Document::Ptr, bool> DocScanPair;
- foreach (const DocScanPair &pair, documents) {
+ using DocScanPair = QPair<CPlusPlus::Document::Ptr, bool>;
+ for (const DocScanPair &pair : documents) {
if (futureInterface.isCanceled())
return;
futureInterface.setProgressValue(futureInterface.progressValue() + 1);
@@ -1273,7 +1345,8 @@ void ModelManagerInterface::updateCppQmlTypes(QFutureInterface<void> &futureInte
const QString fileName = doc->fileName();
if (!scan) {
hasNewInfo = newData.remove(fileName) > 0 || hasNewInfo;
- foreach (const CPlusPlus::Document::Ptr &savedDoc, newDeclarations.value(fileName)) {
+ const auto savedDocs = newDeclarations.value(fileName);
+ for (const CPlusPlus::Document::Ptr &savedDoc : savedDocs) {
finder(savedDoc);
hasNewInfo = rescanExports(savedDoc->fileName(), finder, newData) || hasNewInfo;
}
@@ -1282,14 +1355,13 @@ void ModelManagerInterface::updateCppQmlTypes(QFutureInterface<void> &futureInte
for (auto it = newDeclarations.begin(), end = newDeclarations.end(); it != end;) {
for (auto docIt = it->begin(), endDocIt = it->end(); docIt != endDocIt;) {
- CPlusPlus::Document::Ptr &savedDoc = *docIt;
+ const CPlusPlus::Document::Ptr &savedDoc = *docIt;
if (savedDoc->fileName() == fileName) {
savedDoc->releaseSourceAndAST();
it->erase(docIt);
break;
- } else {
- ++docIt;
}
+ ++docIt;
}
if (it->isEmpty())
it = newDeclarations.erase(it);
@@ -1297,7 +1369,8 @@ void ModelManagerInterface::updateCppQmlTypes(QFutureInterface<void> &futureInte
++it;
}
- foreach (const QString &declarationFile, finder(doc)) {
+ const auto found = finder(doc);
+ for (const QString &declarationFile : found) {
newDeclarations[declarationFile].append(doc);
doc->keepSourceAndAST(); // keep for later reparsing when dependent doc changes
}
@@ -1323,7 +1396,7 @@ ModelManagerInterface::CppDataHash ModelManagerInterface::cppData() const
LibraryInfo ModelManagerInterface::builtins(const Document::Ptr &doc) const
{
const ProjectInfo info = projectInfoForPath(doc->fileName());
- if (info.isValid() && !info.qtQmlPath.isEmpty())
+ if (!info.project.isNull() && !info.qtQmlPath.isEmpty())
return m_validSnapshot.libraryInfo(info.qtQmlPath);
return LibraryInfo();
}
@@ -1346,6 +1419,8 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx,
ProjectInfo defaultInfo = defaultProjectInfo();
if (info.qtQmlPath.isEmpty())
info.qtQmlPath = defaultInfo.qtQmlPath;
+ info.applicationDirectories = Utils::filteredUnique(info.applicationDirectories
+ + defaultInfo.applicationDirectories);
switch (res.flags) {
case ViewerContext::Complete:
break;
@@ -1354,18 +1429,18 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx,
Q_FALLTHROUGH();
case ViewerContext::AddAllPaths:
{
- foreach (const QString &path, defaultVCtx.paths)
- res.maybeAddPath(path);
+ for (const QString &path : qAsConst(defaultVCtx.paths))
+ maybeAddPath(res, path);
switch (res.language.dialect()) {
case Dialect::AnyLanguage:
case Dialect::Qml:
- res.maybeAddPath(info.qtQmlPath);
+ maybeAddPath(res, info.qtQmlPath);
Q_FALLTHROUGH();
case Dialect::QmlQtQuick2:
case Dialect::QmlQtQuick2Ui:
{
if (res.language == Dialect::QmlQtQuick2 || res.language == Dialect::QmlQtQuick2Ui)
- res.maybeAddPath(info.qtQmlPath);
+ maybeAddPath(res, info.qtQmlPath);
QList<ProjectInfo> allProjects;
{
QMutexLocker locker(&m_mutex);
@@ -1373,15 +1448,17 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx,
}
std::sort(allProjects.begin(), allProjects.end(), &pInfoLessThanImports);
QList<Dialect> languages = res.language.companionLanguages();
- foreach (const ProjectInfo &pInfo, allProjects) {
- for (int i = 0; i< pInfo.importPaths.size(); ++i) {
- PathAndLanguage pAndL = pInfo.importPaths.at(i);
- if (languages.contains(pAndL.language()) || pAndL.language().companionLanguages().contains(res.language))
- res.maybeAddPath(pAndL.path().toString());
+ for (const ProjectInfo &pInfo : qAsConst(allProjects)) {
+ for (const auto &importPath : pInfo.importPaths) {
+ if (languages.contains(importPath.language())
+ || importPath.language().companionLanguages().contains(res.language)) {
+ maybeAddPath(res, importPath.path().toString());
+ }
}
}
- foreach (const QString &path, environmentImportPaths())
- res.maybeAddPath(path);
+ const auto environmentPaths = environmentImportPaths();
+ for (const QString &path : environmentPaths)
+ maybeAddPath(res, path);
break;
}
case Dialect::NoLanguage:
@@ -1398,18 +1475,20 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx,
res.selectors.append(defaultVCtx.selectors);
Q_FALLTHROUGH();
case ViewerContext::AddDefaultPaths:
- foreach (const QString &path, defaultVCtx.paths)
- res.maybeAddPath(path);
+ for (const QString &path : qAsConst(defaultVCtx.paths))
+ maybeAddPath(res, path);
if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml)
- res.maybeAddPath(info.qtQmlPath);
+ maybeAddPath(res, info.qtQmlPath);
if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml
|| res.language == Dialect::QmlQtQuick2 || res.language == Dialect::QmlQtQuick2Ui) {
- foreach (const QString &path, environmentImportPaths())
- res.maybeAddPath(path);
+ const auto environemntPaths = environmentImportPaths();
+ for (const QString &path : environemntPaths)
+ maybeAddPath(res, path);
}
break;
}
res.flags = ViewerContext::Complete;
+ res.applicationDirectories = info.applicationDirectories;
return res;
}
@@ -1431,10 +1510,7 @@ ViewerContext ModelManagerInterface::defaultVContext(Dialect language,
defaultCtx = m_defaultVContexts.value(language);
}
defaultCtx.language = language;
- if (autoComplete)
- return completeVContext(defaultCtx, doc);
- else
- return defaultCtx;
+ return autoComplete ? completeVContext(defaultCtx, doc) : defaultCtx;
}
ModelManagerInterface::ProjectInfo ModelManagerInterface::defaultProjectInfo() const
@@ -1457,7 +1533,7 @@ void ModelManagerInterface::setDefaultVContext(const ViewerContext &vContext)
void ModelManagerInterface::joinAllThreads()
{
- foreach (QFuture<void> future, m_futures)
+ for (QFuture<void> &future : m_futures)
future.waitForFinished();
m_futures.clear();
}
@@ -1483,7 +1559,7 @@ void ModelManagerInterface::resetCodeModel()
QMutexLocker locker(&m_mutex);
// find all documents currently in the code model
- foreach (Document::Ptr doc, m_validSnapshot)
+ for (const Document::Ptr &doc : qAsConst(m_validSnapshot))
documents.append(doc->fileName());
// reset the snapshot
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.h b/src/libs/qmljs/qmljsmodelmanagerinterface.h
index b9bfe67db4..4337adcb79 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.h
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.h
@@ -49,48 +49,33 @@ namespace QmlJS {
class Snapshot;
class PluginDumper;
-class QMLJS_EXPORT ModelManagerInterface: public QObject
+class QMLJS_EXPORT ModelManagerInterface : public QObject
{
Q_OBJECT
+ Q_DISABLE_COPY(ModelManagerInterface)
public:
+ ModelManagerInterface(ModelManagerInterface &&) = delete;
+ ModelManagerInterface &operator=(ModelManagerInterface &&) = delete;
+
enum QrcResourceSelector {
ActiveQrcResources,
AllQrcResources
};
- class ProjectInfo
+ struct ProjectInfo
{
- public:
- ProjectInfo()
- : tryQmlDump(false), qmlDumpHasRelocatableFlag(true)
- { }
-
- ProjectInfo(QPointer<ProjectExplorer::Project> project)
- : project(project)
- , tryQmlDump(false), qmlDumpHasRelocatableFlag(true)
- { }
-
- explicit operator bool() const
- { return ! project.isNull(); }
-
- bool isValid() const
- { return ! project.isNull(); }
-
- bool isNull() const
- { return project.isNull(); }
-
- public: // attributes
QPointer<ProjectExplorer::Project> project;
QStringList sourceFiles;
PathsAndLanguages importPaths;
QStringList activeResourceFiles;
QStringList allResourceFiles;
QHash<QString, QString> resourceFileContents;
+ QStringList applicationDirectories;
// whether trying to run qmldump makes sense
- bool tryQmlDump;
- bool qmlDumpHasRelocatableFlag;
+ bool tryQmlDump = false;
+ bool qmlDumpHasRelocatableFlag = true;
QString qmlDumpPath;
::Utils::Environment qmlDumpEnvironment;
@@ -103,42 +88,41 @@ public:
class WorkingCopy
{
public:
- typedef QHash<QString, QPair<QString, int> > Table;
+ using Table = QHash<QString, QPair<QString, int>>;
void insert(const QString &fileName, const QString &source, int revision = 0)
- { _elements.insert(fileName, {source, revision}); }
+ { m_elements.insert(fileName, {source, revision}); }
bool contains(const QString &fileName) const
- { return _elements.contains(fileName); }
+ { return m_elements.contains(fileName); }
QString source(const QString &fileName) const
- { return _elements.value(fileName).first; }
+ { return m_elements.value(fileName).first; }
QPair<QString, int> get(const QString &fileName) const
- { return _elements.value(fileName); }
+ { return m_elements.value(fileName); }
Table all() const
- { return _elements; }
+ { return m_elements; }
private:
- Table _elements;
+ Table m_elements;
};
- class CppData
+ struct CppData
{
- public:
QList<LanguageUtils::FakeMetaObject::ConstPtr> exportedTypes;
QHash<QString, QString> contextProperties;
};
- typedef QHash<QString, CppData> CppDataHash;
+ using CppDataHash = QHash<QString, CppData>;
public:
ModelManagerInterface(QObject *parent = nullptr);
~ModelManagerInterface() override;
static Dialect guessLanguageOfFile(const QString &fileName);
- static QStringList globPatternsForLanguages(const QList<Dialect> languages);
+ static QStringList globPatternsForLanguages(const QList<Dialect> &languages);
static ModelManagerInterface *instance();
static void writeWarning(const QString &msg);
static WorkingCopy workingCopy();
@@ -157,18 +141,18 @@ public:
QStringList filesAtQrcPath(const QString &path, const QLocale *locale = nullptr,
ProjectExplorer::Project *project = nullptr,
QrcResourceSelector resources = AllQrcResources);
- QMap<QString,QStringList> filesInQrcPath(const QString &path,
- const QLocale *locale = nullptr,
- ProjectExplorer::Project *project = nullptr,
- bool addDirs = false,
- QrcResourceSelector resources = AllQrcResources);
+ QMap<QString, QStringList> filesInQrcPath(const QString &path,
+ const QLocale *locale = nullptr,
+ ProjectExplorer::Project *project = nullptr,
+ bool addDirs = false,
+ QrcResourceSelector resources = AllQrcResources);
QList<ProjectInfo> projectInfos() const;
- ProjectInfo projectInfo(ProjectExplorer::Project *project,
- const ModelManagerInterface::ProjectInfo &defaultValue = ProjectInfo()) const;
+ bool containsProject(ProjectExplorer::Project *project) const;
+ ProjectInfo projectInfo(ProjectExplorer::Project *project) const;
void updateProjectInfo(const ProjectInfo &pinfo, ProjectExplorer::Project *p);
- void updateDocument(QmlJS::Document::Ptr doc);
+ void updateDocument(const QmlJS::Document::Ptr& doc);
void updateLibraryInfo(const QString &path, const QmlJS::LibraryInfo &info);
void emitDocumentChangedOnDisk(QmlJS::Document::Ptr doc);
void updateQrcFile(const QString &path);
@@ -199,11 +183,10 @@ public:
void joinAllThreads();
QmlJS::Document::Ptr ensuredGetDocumentForPath(const QString &filePath);
- static void importScan(QFutureInterface<void> &future,
- WorkingCopy workingCopyInternal,
- PathsAndLanguages paths,
- ModelManagerInterface *modelManager,
- bool emitDocChangedOnDisk, bool libOnly = true, bool forceRescan = false);
+ static void importScan(QFutureInterface<void> &future, const WorkingCopy& workingCopyInternal,
+ const PathsAndLanguages& paths, ModelManagerInterface *modelManager,
+ bool emitDocChangedOnDisk, bool libOnly = true,
+ bool forceRescan = false);
virtual void resetCodeModel();
void removeProjectInfo(ProjectExplorer::Project *project);
@@ -225,25 +208,27 @@ protected:
virtual QHash<QString,Dialect> languageForSuffix() const;
virtual void writeMessageInternal(const QString &msg) const;
virtual WorkingCopy workingCopyInternal() const;
- virtual void addTaskInternal(QFuture<void> result, const QString &msg, const char *taskId) const;
+ virtual void addTaskInternal(const QFuture<void> &result, const QString &msg,
+ const char *taskId) const;
QFuture<void> refreshSourceFiles(const QStringList &sourceFiles,
bool emitDocumentOnDiskChanged);
static void parseLoop(QSet<QString> &scannedPaths, QSet<QString> &newLibraries,
- WorkingCopy workingCopyInternal, QStringList files, ModelManagerInterface *modelManager,
+ const WorkingCopy &workingCopyInternal, QStringList files,
+ ModelManagerInterface *modelManager,
QmlJS::Dialect mainLanguage, bool emitDocChangedOnDisk,
- std::function<bool (qreal)> reportProgress);
+ const std::function<bool(qreal)> &reportProgress);
static void parse(QFutureInterface<void> &future,
- WorkingCopy workingCopyInternal,
+ const WorkingCopy &workingCopyInternal,
QStringList files,
ModelManagerInterface *modelManager,
QmlJS::Dialect mainLanguage,
bool emitDocChangedOnDisk);
- static void updateCppQmlTypes(QFutureInterface<void> &futureInterface,
- ModelManagerInterface *qmlModelManager,
- CPlusPlus::Snapshot snapshot,
- QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > documents);
+ static void updateCppQmlTypes(
+ QFutureInterface<void> &futureInterface, ModelManagerInterface *qmlModelManager,
+ const CPlusPlus::Snapshot &snapshot,
+ const QHash<QString, QPair<CPlusPlus::Document::Ptr, bool>> &documents);
void maybeScan(const PathsAndLanguages &importPaths);
void updateImportPaths();
@@ -254,7 +239,7 @@ private:
void cleanupFutures();
void iterateQrcFiles(ProjectExplorer::Project *project,
QrcResourceSelector resources,
- std::function<void(Utils::QrcParser::ConstPtr)> callback);
+ const std::function<void(Utils::QrcParser::ConstPtr)> &callback);
mutable QMutex m_mutex;
QmlJS::Snapshot m_validSnapshot;
@@ -269,13 +254,13 @@ private:
QTimer *m_updateCppQmlTypesTimer = nullptr;
QTimer *m_asyncResetTimer = nullptr;
- QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > m_queuedCppDocuments;
+ QHash<QString, QPair<CPlusPlus::Document::Ptr, bool>> m_queuedCppDocuments;
QFuture<void> m_cppQmlTypesUpdater;
Utils::QrcCache m_qrcCache;
QHash<QString, QString> m_qrcContents;
CppDataHash m_cppDataHash;
- QHash<QString, QList<CPlusPlus::Document::Ptr> > m_cppDeclarationFiles;
+ QHash<QString, QList<CPlusPlus::Document::Ptr>> m_cppDeclarationFiles;
mutable QMutex m_cppDataMutex;
// project integration
diff --git a/src/libs/qmljs/qmljsplugindumper.cpp b/src/libs/qmljs/qmljsplugindumper.cpp
index e4f51e64c2..d74b4663fa 100644
--- a/src/libs/qmljs/qmljsplugindumper.cpp
+++ b/src/libs/qmljs/qmljsplugindumper.cpp
@@ -41,6 +41,12 @@
using namespace LanguageUtils;
using namespace QmlJS;
+static const QStringList qmltypesFileNames = {
+ QLatin1String("plugins.qmltypes"),
+ QLatin1String("app.qmltypes"),
+ QLatin1String("lib.qmltypes")
+};
+
PluginDumper::PluginDumper(ModelManagerInterface *modelManager)
: QObject(modelManager)
, m_modelManager(modelManager)
@@ -146,10 +152,11 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &
plugin.importVersion = importVersion;
// add default qmltypes file if it exists
- const QLatin1String defaultQmltypesFileName("plugins.qmltypes");
- const QString defaultQmltypesPath = makeAbsolute(defaultQmltypesFileName, canonicalLibraryPath);
- if (!plugin.typeInfoPaths.contains(defaultQmltypesPath) && QFile::exists(defaultQmltypesPath))
- plugin.typeInfoPaths += defaultQmltypesPath;
+ for (const QString &qmltypesFileName : qmltypesFileNames) {
+ const QString defaultQmltypesPath = makeAbsolute(qmltypesFileName, canonicalLibraryPath);
+ if (!plugin.typeInfoPaths.contains(defaultQmltypesPath) && QFile::exists(defaultQmltypesPath))
+ plugin.typeInfoPaths += defaultQmltypesPath;
+ }
// add typeinfo files listed in qmldir
foreach (const QmlDirParser::TypeInfo &typeInfo, libraryInfo.typeInfos()) {
@@ -398,10 +405,11 @@ QString PluginDumper::buildQmltypesPath(const QString &name) const
if (path.isEmpty())
return QString();
- const QString filename = path + QLatin1String("/plugins.qmltypes");
-
- if (QFile::exists(filename))
- return filename;
+ for (const QString &qmltypesFileName : qmltypesFileNames) {
+ const QString filename = path + QLatin1Char('/') + qmltypesFileName;
+ if (QFile::exists(filename))
+ return filename;
+ }
return QString();
}
diff --git a/src/libs/qmljs/qmljsviewercontext.cpp b/src/libs/qmljs/qmljsviewercontext.cpp
deleted file mode 100644
index bc5d8e5b48..0000000000
--- a/src/libs/qmljs/qmljsviewercontext.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "qmljsviewercontext.h"
-
-namespace QmlJS {
-/*!
- \class QmlJS::ViewerContext
- \brief The ViewerContext class encapsulate selector and paths for a given viewer.
-
- Using a a different viewer context can emulate (the pure qml part) of a device.
- This allows checking how a given qml would be interpreted on another platform/viewer.
-
- Screen information will also most likely need to be added here.
-*/
-ViewerContext::ViewerContext()
- : language(Dialect::Qml), flags(AddAllPaths)
-{ }
-
-ViewerContext::ViewerContext(const QStringList &selectors, const QStringList &paths,
- QmlJS::Dialect language,
- QmlJS::ViewerContext::Flags flags)
- : selectors(selectors), paths(paths), language(language),
- flags(flags)
-{ }
-
-
-/*
- which languages might be imported in this context
- */
-bool ViewerContext::languageIsCompatible(Dialect l) const
-{
- if (l == Dialect::AnyLanguage && language != Dialect::NoLanguage)
- return true;
- switch (language.dialect()) {
- case Dialect::JavaScript:
- case Dialect::Json:
- case Dialect::QmlProject:
- case Dialect::QmlQbs:
- case Dialect::QmlTypeInfo:
- return language == l;
- case Dialect::Qml:
- return l == Dialect::Qml || l == Dialect::QmlQtQuick2 || l == Dialect::JavaScript;
- case Dialect::QmlQtQuick2:
- case Dialect::QmlQtQuick2Ui:
- return l == Dialect::Qml || l == Dialect::QmlQtQuick2 || l == Dialect::QmlQtQuick2Ui
- || l == Dialect::JavaScript;
- case Dialect::AnyLanguage:
- return true;
- case Dialect::NoLanguage:
- break;
- }
- return false;
-}
-
-void ViewerContext::maybeAddPath(const QString &path)
-{
- if (!path.isEmpty() && !paths.contains(path))
- paths.append(path);
-}
-
-} // namespace QmlJS
diff --git a/src/libs/qmljs/qmljsviewercontext.h b/src/libs/qmljs/qmljsviewercontext.h
index a04596cdd3..1598bcfe18 100644
--- a/src/libs/qmljs/qmljsviewercontext.h
+++ b/src/libs/qmljs/qmljsviewercontext.h
@@ -32,9 +32,8 @@
namespace QmlJS {
-class QMLJS_EXPORT ViewerContext
+struct QMLJS_EXPORT ViewerContext
{
-public:
enum Flags {
Complete,
AddAllPathsAndDefaultSelectors,
@@ -43,18 +42,11 @@ public:
AddDefaultPathsAndSelectors
};
- ViewerContext();
- ViewerContext(const QStringList &selectors, const QStringList &paths,
- Dialect language = Dialect::Qml,
- Flags flags = AddAllPaths);
-
- bool languageIsCompatible(Dialect l) const;
- void maybeAddPath(const QString &path);
-
QStringList selectors;
QStringList paths;
- Dialect language;
- Flags flags;
+ QStringList applicationDirectories;
+ Dialect language = Dialect::Qml;
+ Flags flags = AddAllPaths;
};
} // namespace QmlJS
diff --git a/src/libs/utils/fancylineedit.cpp b/src/libs/utils/fancylineedit.cpp
index d67c336544..0f96122a94 100644
--- a/src/libs/utils/fancylineedit.cpp
+++ b/src/libs/utils/fancylineedit.cpp
@@ -129,6 +129,7 @@ public:
bool m_isFiltering = false;
bool m_firstChange = true;
+ bool m_toolTipSet = false;
QString m_lastFilterText;
@@ -520,7 +521,10 @@ void FancyLineEdit::validate()
const bool validates = d->m_validationFunction(this, &d->m_errorMessage);
const State newState = isDisplayingPlaceholderText ? DisplayingPlaceholderText
: (validates ? Valid : Invalid);
- setToolTip(d->m_errorMessage);
+ if (!validates || d->m_toolTipSet) {
+ setToolTip(d->m_errorMessage);
+ d->m_toolTipSet = true;
+ }
// Changed..figure out if valid changed. DisplayingPlaceholderText is not valid,
// but should not show error color. Also trigger on the first change.
if (newState != d->m_state || d->m_firstChange) {
diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp
index 3e8e2ac3bc..8b79923c51 100644
--- a/src/libs/utils/fileutils.cpp
+++ b/src/libs/utils/fileutils.cpp
@@ -45,10 +45,6 @@
#endif
#ifdef Q_OS_WIN
-// We need defines for Windows 8
-#undef _WIN32_WINNT
-#define _WIN32_WINNT _WIN32_WINNT_WIN8
-
#include <qt_windows.h>
#include <shlobj.h>
#endif
diff --git a/src/libs/utils/hostosinfo.cpp b/src/libs/utils/hostosinfo.cpp
index 8a3c0e814d..c5f313d5ce 100644
--- a/src/libs/utils/hostosinfo.cpp
+++ b/src/libs/utils/hostosinfo.cpp
@@ -32,8 +32,6 @@
#endif
#ifdef Q_OS_WIN
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501 /* WinXP, needed for GetNativeSystemInfo() */
#include <qt_windows.h>
#endif
diff --git a/src/libs/utils/process_ctrlc_stub.cpp b/src/libs/utils/process_ctrlc_stub.cpp
index e5469e208d..951c135265 100644
--- a/src/libs/utils/process_ctrlc_stub.cpp
+++ b/src/libs/utils/process_ctrlc_stub.cpp
@@ -36,7 +36,10 @@
#define _WIN32_WINNT 0x0501
#endif
+#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
+#endif
+
#include <windows.h>
#include <shellapi.h>
#include <wchar.h>
diff --git a/src/libs/utils/winutils.cpp b/src/libs/utils/winutils.cpp
index 69eb0d11e8..0f98d91ace 100644
--- a/src/libs/utils/winutils.cpp
+++ b/src/libs/utils/winutils.cpp
@@ -26,10 +26,7 @@
#include "winutils.h"
#include "qtcassert.h"
-// Enable WinAPI Windows Vista and later
#ifdef Q_OS_WIN
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600 // Needed for QueryFullProcessImageName
#include <windows.h>
#endif
diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt
index 8d3f734c2b..1744739288 100644
--- a/src/plugins/CMakeLists.txt
+++ b/src/plugins/CMakeLists.txt
@@ -82,7 +82,13 @@ add_subdirectory(ctfvisualizer)
# Level 7:
add_subdirectory(boot2qt)
-add_subdirectory(qmldesigner)
+unset(qmldesigner_builddir)
+if (WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ # Workaround for @CMakeFiles\QmlDesigner.rsp ld.lld.exe: The filename or extension is too long.
+ # Clang on Windows is having problems with QmlDesigner.rsp which is bigger than 32KiB
+ set(qmldesigner_builddir ${PROJECT_BINARY_DIR}/qmldsgnr)
+endif()
+add_subdirectory(qmldesigner ${qmldesigner_builddir})
add_subdirectory(qnx)
add_subdirectory(webassembly)
add_subdirectory(mcusupport)
diff --git a/src/plugins/android/adbcommandswidget.cpp b/src/plugins/android/adbcommandswidget.cpp
index 282f4c7644..4fe5c76d8c 100644
--- a/src/plugins/android/adbcommandswidget.cpp
+++ b/src/plugins/android/adbcommandswidget.cpp
@@ -71,9 +71,8 @@ private:
friend class AdbCommandsWidget;
};
-AdbCommandsWidget::AdbCommandsWidget(QWidget *parent) :
- QGroupBox(parent),
- d(new AdbCommandsWidgetPrivate(this))
+AdbCommandsWidget::AdbCommandsWidget()
+ : d(new AdbCommandsWidgetPrivate(this))
{
}
diff --git a/src/plugins/android/adbcommandswidget.h b/src/plugins/android/adbcommandswidget.h
index 6231d4e414..4650639cc2 100644
--- a/src/plugins/android/adbcommandswidget.h
+++ b/src/plugins/android/adbcommandswidget.h
@@ -39,7 +39,7 @@ class AdbCommandsWidget : public QGroupBox
{
Q_OBJECT
public:
- explicit AdbCommandsWidget(QWidget *parent);
+ AdbCommandsWidget();
~AdbCommandsWidget() override;
QStringList commandsList() const;
diff --git a/src/plugins/android/androidrunconfiguration.cpp b/src/plugins/android/androidrunconfiguration.cpp
index 01b0c6050a..ac4aa5f0c0 100644
--- a/src/plugins/android/androidrunconfiguration.cpp
+++ b/src/plugins/android/androidrunconfiguration.cpp
@@ -62,13 +62,13 @@ BaseStringListAspect::BaseStringListAspect(const QString &settingsKey, Core::Id
BaseStringListAspect::~BaseStringListAspect() = default;
-void BaseStringListAspect::addToConfigurationLayout(QFormLayout *layout)
+void BaseStringListAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(!m_widget);
- m_widget = new AdbCommandsWidget(layout->parentWidget());
+ m_widget = new AdbCommandsWidget;
m_widget->setCommandList(m_value);
m_widget->setTitleText(m_label);
- layout->addRow(m_widget);
+ builder.addItem(m_widget.data());
connect(m_widget.data(), &AdbCommandsWidget::commandsChanged, this, [this] {
m_value = m_widget->commandsList();
emit changed();
diff --git a/src/plugins/android/androidrunconfiguration.h b/src/plugins/android/androidrunconfiguration.h
index 6723048f37..5d1d32c7e5 100644
--- a/src/plugins/android/androidrunconfiguration.h
+++ b/src/plugins/android/androidrunconfiguration.h
@@ -43,7 +43,7 @@ public:
Core::Id id = Core::Id());
~BaseStringListAspect() override;
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(ProjectExplorer::LayoutBuilder &builder) override;
QStringList value() const;
void setValue(const QStringList &val);
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp
index e3cd87f0ce..977ddade3e 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp
@@ -50,7 +50,7 @@ AutotoolsProject::AutotoolsProject(const Utils::FilePath &fileName)
setHasMakeInstallEquivalent(true);
- setBuildSystem(std::make_unique<AutotoolsBuildSystem>(this));
+ setBuildSystemCreator([](Project *p) { return new AutotoolsBuildSystem(p); });
}
class AutotoolsProjectPluginPrivate
diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
index 7e92932d20..aa0caae7ec 100644
--- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
@@ -51,6 +51,8 @@
#include <QPushButton>
#include <QSet>
+#include <app/app_version.h>
+
using namespace ProjectExplorer;
using namespace Utils;
@@ -123,28 +125,44 @@ void BuildDirManager::emitErrorOccured(const QString &message) const
void BuildDirManager::emitReparseRequest() const
{
- if (m_reparseParameters & REPARSE_URGENT)
+ if (m_reparseParameters & REPARSE_URGENT) {
+ qCDebug(cmakeBuildDirManagerLog) << "emitting requestReparse";
emit requestReparse();
- else
+ } else {
+ qCDebug(cmakeBuildDirManagerLog) << "emitting requestDelayedReparse";
emit requestDelayedReparse();
+ }
}
void BuildDirManager::updateReaderType(const BuildDirParameters &p,
std::function<void()> todo)
{
- if (!m_reader || !m_reader->isCompatible(p))
+ if (!m_reader || !m_reader->isCompatible(p)) {
+ if (m_reader) {
+ stopParsingAndClearState();
+ qCDebug(cmakeBuildDirManagerLog) << "Creating new reader do to incompatible parameters";
+ } else {
+ qCDebug(cmakeBuildDirManagerLog) << "Creating first reader";
+ }
m_reader = BuildDirReader::createReader(p);
- QTC_ASSERT(m_reader, return);
+ connect(m_reader.get(),
+ &BuildDirReader::configurationStarted,
+ this,
+ &BuildDirManager::parsingStarted);
+ connect(m_reader.get(),
+ &BuildDirReader::dataAvailable,
+ this,
+ &BuildDirManager::emitDataAvailable);
+ connect(m_reader.get(),
+ &BuildDirReader::errorOccured,
+ this,
+ &BuildDirManager::emitErrorOccured);
+ connect(m_reader.get(), &BuildDirReader::dirty, this, &BuildDirManager::becameDirty);
+ connect(m_reader.get(), &BuildDirReader::isReadyNow, this, todo);
+ }
- connect(m_reader.get(), &BuildDirReader::configurationStarted,
- this, &BuildDirManager::parsingStarted);
- connect(m_reader.get(), &BuildDirReader::dataAvailable,
- this, &BuildDirManager::emitDataAvailable);
- connect(m_reader.get(), &BuildDirReader::errorOccured,
- this, &BuildDirManager::emitErrorOccured);
- connect(m_reader.get(), &BuildDirReader::dirty, this, &BuildDirManager::becameDirty);
- connect(m_reader.get(), &BuildDirReader::isReadyNow, this, todo);
+ QTC_ASSERT(m_reader, return );
m_reader->setParameters(p);
}
@@ -213,6 +231,28 @@ bool BuildDirManager::hasConfigChanged()
return mustReparse || kcit != targetConfig.constEnd();
}
+void BuildDirManager::writeConfigurationIntoBuildDirectory(const Utils::MacroExpander *expander)
+{
+ QTC_ASSERT(expander, return );
+
+ const FilePath buildDir = workDirectory(m_parameters);
+ QTC_ASSERT(buildDir.exists(), return );
+
+ const FilePath settingsFile = buildDir.pathAppended("qtcsettings.cmake");
+
+ QByteArray contents;
+ contents.append("# This file is managed by Qt Creator, do not edit!\n\n");
+ contents.append(
+ transform(m_parameters.configuration,
+ [expander](const CMakeConfigItem &item) { return item.toCMakeSetLine(expander); })
+ .join('\n')
+ .toUtf8());
+
+ QFile file(settingsFile.toString());
+ QTC_ASSERT(file.open(QFile::WriteOnly | QFile::Truncate), return );
+ file.write(contents);
+}
+
bool BuildDirManager::isParsing() const
{
return m_reader && m_reader->isParsing();
@@ -220,7 +260,10 @@ bool BuildDirManager::isParsing() const
void BuildDirManager::stopParsingAndClearState()
{
+ qCDebug(cmakeBuildDirManagerLog) << "stopping parsing run!";
if (m_reader) {
+ if (m_reader->isParsing())
+ m_reader->errorOccured(tr("Parsing has been canceled."));
disconnect(m_reader.get(), nullptr, this, nullptr);
m_reader->stop();
}
@@ -231,6 +274,7 @@ void BuildDirManager::stopParsingAndClearState()
void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters &parameters,
const int reparseParameters)
{
+ qCDebug(cmakeBuildDirManagerLog) << "setting parameters and requesting reparse";
if (!parameters.cmakeTool()) {
TaskHub::addTask(Task::Error,
tr("The kit needs to define a CMake tool to parse this project."),
@@ -239,8 +283,6 @@ void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters &par
}
QTC_ASSERT(parameters.isValid(), return );
- stopParsingAndClearState();
-
m_parameters = parameters;
m_parameters.workDirectory = workDirectory(parameters);
updateReparseParameters(reparseParameters);
@@ -262,6 +304,7 @@ FilePath BuildDirManager::buildDirectory() const
void BuildDirManager::becameDirty()
{
+ qCDebug(cmakeBuildDirManagerLog) << "BuildDirManager: becameDirty was triggered.";
if (isParsing() || !buildConfiguration())
return;
@@ -310,8 +353,10 @@ bool BuildDirManager::isFilesystemScanRequested() const
void BuildDirManager::parse()
{
+ qCDebug(cmakeBuildDirManagerLog) << "parsing!";
QTC_ASSERT(m_parameters.isValid(), return );
- QTC_ASSERT(m_reader, return);
+ QTC_ASSERT(m_reader, return );
+ QTC_ASSERT(!m_reader->isParsing(), return );
m_reader->stop();
@@ -335,6 +380,9 @@ void BuildDirManager::parse()
}
}
+ writeConfigurationIntoBuildDirectory(m_parameters.expander);
+
+ qCDebug(cmakeBuildDirManagerLog) << "Asking reader to parse";
m_reader->parse(reparseParameters & REPARSE_FORCE_CMAKE_RUN,
reparseParameters & REPARSE_FORCE_CONFIGURATION);
}
@@ -512,21 +560,27 @@ bool BuildDirManager::checkConfiguration()
QStringList keyList = changedKeys.keys();
Utils::sort(keyList);
QString table = QString::fromLatin1("<table><tr><th>%1</th><th>%2</th><th>%3</th></tr>")
- .arg(tr("Key")).arg(tr("CMakeCache.txt")).arg(tr("Project"));
+ .arg(tr("Key"))
+ .arg(tr("%1 Project").arg(Core::Constants::IDE_DISPLAY_NAME))
+ .arg(tr("Changed value"));
foreach (const QString &k, keyList) {
const QPair<QString, QString> data = changedKeys.value(k);
table += QString::fromLatin1("\n<tr><td>%1</td><td>%2</td><td>%3</td></tr>")
- .arg(k)
- .arg(data.first.toHtmlEscaped())
- .arg(data.second.toHtmlEscaped());
+ .arg(k)
+ .arg(data.second.toHtmlEscaped())
+ .arg(data.first.toHtmlEscaped());
}
table += QLatin1String("\n</table>");
QPointer<QMessageBox> box = new QMessageBox(Core::ICore::mainWindow());
- box->setText(tr("CMake configuration has changed on disk."));
+ box->setText(tr("The project has been changed outside of %1.")
+ .arg(Core::Constants::IDE_DISPLAY_NAME));
box->setInformativeText(table);
- auto *defaultButton = box->addButton(tr("Overwrite Changes in CMakeCache.txt"), QMessageBox::RejectRole);
- auto *applyButton = box->addButton(tr("Apply Changes to Project"), QMessageBox::ApplyRole);
+ auto *defaultButton = box->addButton(tr("Discard external changes"),
+ QMessageBox::RejectRole);
+ auto *applyButton = box->addButton(tr("Adapt %1 project to changes")
+ .arg(Core::Constants::IDE_DISPLAY_NAME),
+ QMessageBox::ApplyRole);
box->setDefaultButton(defaultButton);
box->exec();
diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h
index 91233b79a8..d3537104cc 100644
--- a/src/plugins/cmakeprojectmanager/builddirmanager.h
+++ b/src/plugins/cmakeprojectmanager/builddirmanager.h
@@ -127,6 +127,7 @@ private:
bool hasConfigChanged();
+ void writeConfigurationIntoBuildDirectory(const Utils::MacroExpander *expander);
void becameDirty();
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
index adbf2bc3f8..a638ec439a 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
@@ -287,7 +287,8 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
const QList<BuildTargetInfo> CMakeBuildConfiguration::appTargets() const
{
QList<BuildTargetInfo> appTargetList;
- bool forAndroid = DeviceTypeKitAspect::deviceTypeId(target()->kit()) == Android::Constants::ANDROID_DEVICE_TYPE;
+ const bool forAndroid = DeviceTypeKitAspect::deviceTypeId(target()->kit())
+ == Android::Constants::ANDROID_DEVICE_TYPE;
for (const CMakeBuildTarget &ct : m_buildTargets) {
if (ct.targetType == UtilityType)
continue;
@@ -464,8 +465,10 @@ void CMakeBuildConfiguration::clearError(ForceEnabledChanged fec)
m_error.clear();
fec = ForceEnabledChanged::True;
}
- if (fec == ForceEnabledChanged::True)
+ if (fec == ForceEnabledChanged::True) {
+ qCDebug(cmakeBuildConfigurationLog) << "Emitting enabledChanged signal";
emit enabledChanged();
+ }
}
void CMakeBuildConfiguration::emitBuildTypeChanged()
@@ -524,11 +527,16 @@ CMakeConfig CMakeBuildConfiguration::configurationForCMake() const
void CMakeBuildConfiguration::setError(const QString &message)
{
+ qCDebug(cmakeBuildConfigurationLog) << "Setting error to" << message;
+ QTC_ASSERT(!message.isEmpty(), return );
+
const QString oldMessage = m_error;
if (m_error != message)
m_error = message;
- if (oldMessage.isEmpty() && !message.isEmpty())
+ if (oldMessage.isEmpty() != !message.isEmpty()) {
+ qCDebug(cmakeBuildConfigurationLog) << "Emitting enabledChanged signal";
emit enabledChanged();
+ }
emit errorOccured(m_error);
}
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
index 5814083832..710828ff01 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
@@ -81,6 +81,7 @@ static QModelIndex mapToSource(const QAbstractItemView *view, const QModelIndex
// --------------------------------------------------------------------
CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) :
+ NamedWidget(tr("CMake")),
m_buildConfiguration(bc),
m_configModel(new ConfigModel(this)),
m_configFilterModel(new Utils::CategorySortFilterModel),
@@ -88,8 +89,6 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
{
QTC_CHECK(bc);
- setDisplayName(tr("CMake"));
-
auto vbox = new QVBoxLayout(this);
vbox->setContentsMargins(0, 0, 0, 0);
auto container = new Utils::DetailsWidget;
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
index 68b514d6f1..00032dabff 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
@@ -57,6 +57,7 @@
#include <QGroupBox>
#include <QLineEdit>
#include <QListWidget>
+#include <QRadioButton>
using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
@@ -321,11 +322,6 @@ void CMakeBuildStep::setBuildTarget(const QString &buildTarget)
emit targetToBuildChanged();
}
-void CMakeBuildStep::clearBuildTargets()
-{
- m_buildTarget.clear();
-}
-
QString CMakeBuildStep::toolArguments() const
{
return m_toolArguments;
@@ -440,11 +436,20 @@ CMakeBuildStepConfigWidget::CMakeBuildStepConfigWidget(CMakeBuildStep *buildStep
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
this, &CMakeBuildStepConfigWidget::updateDetails);
- connect(m_buildStep, &CMakeBuildStep::buildTargetsChanged, this, &CMakeBuildStepConfigWidget::buildTargetsChanged);
- connect(m_buildStep, &CMakeBuildStep::targetToBuildChanged, this, &CMakeBuildStepConfigWidget::selectedBuildTargetsChanged);
+ connect(m_buildStep,
+ &CMakeBuildStep::buildTargetsChanged,
+ this,
+ &CMakeBuildStepConfigWidget::buildTargetsChanged);
- connect(m_buildStep->buildConfiguration(), &BuildConfiguration::environmentChanged,
- this, &CMakeBuildStepConfigWidget::updateDetails);
+ connect(m_buildStep,
+ &CMakeBuildStep::targetToBuildChanged,
+ this,
+ &CMakeBuildStepConfigWidget::updateBuildTarget);
+
+ connect(m_buildStep->buildConfiguration(),
+ &BuildConfiguration::environmentChanged,
+ this,
+ &CMakeBuildStepConfigWidget::updateDetails);
}
void CMakeBuildStepConfigWidget::toolArgumentsEdited()
@@ -464,6 +469,19 @@ void CMakeBuildStepConfigWidget::itemChanged(QListWidgetItem *item)
void CMakeBuildStepConfigWidget::buildTargetsChanged()
{
{
+ auto addItem = [this](const QString &buildTarget,
+ const QString &displayName) {
+ auto item = new QListWidgetItem(m_buildTargetsList);
+ auto button = new QRadioButton(displayName);
+ connect(button, &QRadioButton::toggled, this, [this, buildTarget](bool toggled) {
+ if (toggled) {
+ m_buildStep->setBuildTarget(buildTarget);
+ }
+ });
+ m_buildTargetsList->setItemWidget(item, button);
+ item->setData(Qt::UserRole, buildTarget);
+ };
+
QSignalBlocker blocker(m_buildTargetsList);
m_buildTargetsList->clear();
@@ -473,42 +491,49 @@ void CMakeBuildStepConfigWidget::buildTargetsChanged()
QFont italics;
italics.setItalic(true);
- auto exeItem = new QListWidgetItem(tr(ADD_RUNCONFIGURATION_TEXT), m_buildTargetsList);
- exeItem->setData(Qt::UserRole, ADD_RUNCONFIGURATION_TEXT);
+ addItem(ADD_RUNCONFIGURATION_TEXT, tr(ADD_RUNCONFIGURATION_TEXT));
- foreach (const QString &buildTarget, targetList) {
- auto item = new QListWidgetItem(buildTarget, m_buildTargetsList);
- item->setData(Qt::UserRole, buildTarget);
- }
+ foreach (const QString &buildTarget, targetList)
+ addItem(buildTarget, buildTarget);
for (int i = 0; i < m_buildTargetsList->count(); ++i) {
QListWidgetItem *item = m_buildTargetsList->item(i);
const QString title = item->data(Qt::UserRole).toString();
+ QRadioButton *radio = itemWidget(item);
- item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
- item->setCheckState(m_buildStep->buildsBuildTarget(title) ? Qt::Checked : Qt::Unchecked);
+ radio->setChecked(m_buildStep->buildsBuildTarget(title));
// Print utility targets in italics:
if (CMakeBuildStep::specialTargets().contains(title) || title == ADD_RUNCONFIGURATION_TEXT)
- item->setFont(italics);
+ radio->setFont(italics);
}
}
updateDetails();
}
-void CMakeBuildStepConfigWidget::selectedBuildTargetsChanged()
+void CMakeBuildStepConfigWidget::updateBuildTarget()
{
+ const QString buildTarget = m_buildStep->buildTarget();
{
QSignalBlocker blocker(m_buildTargetsList);
for (int y = 0; y < m_buildTargetsList->count(); ++y) {
QListWidgetItem *item = m_buildTargetsList->item(y);
- item->setCheckState(m_buildStep->buildsBuildTarget(item->data(Qt::UserRole).toString())
- ? Qt::Checked : Qt::Unchecked);
+ const QString itemTarget = item->data(Qt::UserRole).toString();
+
+ if (itemTarget == buildTarget) {
+ QRadioButton *radio = itemWidget(item);
+ radio->setChecked(true);
+ }
}
}
updateDetails();
}
+QRadioButton *CMakeBuildStepConfigWidget::itemWidget(QListWidgetItem *item)
+{
+ return static_cast<QRadioButton *>(m_buildTargetsList->itemWidget(item));
+}
+
void CMakeBuildStepConfigWidget::updateDetails()
{
BuildConfiguration *bc = m_buildStep->buildConfiguration();
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.h b/src/plugins/cmakeprojectmanager/cmakebuildstep.h
index 28c6ccb46e..99de0046d5 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildstep.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.h
@@ -33,6 +33,7 @@ QT_BEGIN_NAMESPACE
class QLineEdit;
class QListWidget;
class QListWidgetItem;
+class QRadioButton;
QT_END_NAMESPACE
namespace Utils {
@@ -64,7 +65,6 @@ public:
QString buildTarget() const;
bool buildsBuildTarget(const QString &target) const;
void setBuildTarget(const QString &target);
- void clearBuildTargets();
QString toolArguments() const;
void setToolArguments(const QString &list);
@@ -131,7 +131,9 @@ private:
void toolArgumentsEdited();
void updateDetails();
void buildTargetsChanged();
- void selectedBuildTargetsChanged();
+ void updateBuildTarget();
+
+ QRadioButton *itemWidget(QListWidgetItem *item);
CMakeBuildStep *m_buildStep;
QLineEdit *m_toolArguments;
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
index 4b71fa135c..ae1e20972f 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
@@ -57,8 +57,8 @@ Q_LOGGING_CATEGORY(cmakeBuildSystemLog, "qtc.cmake.buildsystem", QtWarningMsg);
// CMakeBuildSystem:
// --------------------------------------------------------------------
-CMakeBuildSystem::CMakeBuildSystem(CMakeProject *p)
- : BuildSystem(p)
+CMakeBuildSystem::CMakeBuildSystem(Project *project)
+ : BuildSystem(project)
, m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
{
// TreeScanner:
@@ -67,9 +67,9 @@ CMakeBuildSystem::CMakeBuildSystem(CMakeProject *p)
this,
&CMakeBuildSystem::handleTreeScanningFinished);
- m_treeScanner.setFilter([this, p](const Utils::MimeType &mimeType, const Utils::FilePath &fn) {
+ m_treeScanner.setFilter([this](const MimeType &mimeType, const FilePath &fn) {
// Mime checks requires more resources, so keep it last in check list
- auto isIgnored = fn.toString().startsWith(p->projectFilePath().toString() + ".user")
+ auto isIgnored = fn.toString().startsWith(projectFilePath().toString() + ".user")
|| TreeScanner::isWellKnownBinary(mimeType, fn);
// Cache mime check result for speed up
@@ -114,6 +114,7 @@ CMakeBuildSystem::~CMakeBuildSystem()
bool CMakeBuildSystem::validateParsingContext(const ParsingContext &ctx)
{
+ QTC_ASSERT(!m_currentContext.guard.guardsProject(), return false);
return ctx.project && qobject_cast<CMakeBuildConfiguration *>(ctx.buildConfiguration);
}
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
index 1170a38e12..c1325dcc0c 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
@@ -48,13 +48,20 @@ class CMakeBuildSystem : public ProjectExplorer::BuildSystem
Q_OBJECT
public:
- explicit CMakeBuildSystem(CMakeProject *project);
+ explicit CMakeBuildSystem(ProjectExplorer::Project *project);
~CMakeBuildSystem() final;
protected:
bool validateParsingContext(const ParsingContext &ctx) final;
void parseProject(ParsingContext &&ctx) final;
+ bool supportsAction(ProjectExplorer::Node *context,
+ ProjectExplorer::ProjectAction action,
+ const ProjectExplorer::Node *node) const override;
+
+ bool addFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths, QStringList *) final;
+
private:
// Treescanner states:
void handleTreeScanningFinished();
diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
index e63641cf28..7fdb7b2d60 100644
--- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
@@ -149,6 +149,26 @@ CMakeConfigItem::Type CMakeConfigItem::typeStringToType(const QByteArray &type)
return CMakeConfigItem::INTERNAL;
}
+QString CMakeConfigItem::typeToTypeString(const CMakeConfigItem::Type t)
+{
+ switch (t) {
+ case CMakeProjectManager::CMakeConfigItem::FILEPATH:
+ return {"FILEPATH"};
+ case CMakeProjectManager::CMakeConfigItem::PATH:
+ return {"PATH"};
+ case CMakeProjectManager::CMakeConfigItem::STRING:
+ return {"STRING"};
+ case CMakeProjectManager::CMakeConfigItem::INTERNAL:
+ return {"INTERNAL"};
+ case CMakeProjectManager::CMakeConfigItem::STATIC:
+ return {"STATIC"};
+ case CMakeConfigItem::BOOL:
+ return {"BOOL"};
+ }
+ QTC_CHECK(false);
+ return {};
+}
+
Utils::optional<bool> CMakeConfigItem::toBool(const QByteArray &value)
{
// Taken from CMakes if(<constant>) documentation:
@@ -367,6 +387,18 @@ QString CMakeConfigItem::toArgument(const Utils::MacroExpander *expander) const
return "-D" + toString(expander);
}
+QString CMakeConfigItem::toCMakeSetLine(const Utils::MacroExpander *expander) const
+{
+ if (isUnset) {
+ return QString("unset(\"%1\" CACHE)").arg(QString::fromUtf8(key));
+ }
+ return QString("set(\"%1\" \"%2\" CACHE \"%3\" \"%4\" FORCE)")
+ .arg(QString::fromUtf8(key))
+ .arg(expandedValue(expander))
+ .arg(typeToTypeString(type))
+ .arg(QString::fromUtf8(documentation));
+}
+
bool CMakeConfigItem::operator==(const CMakeConfigItem &o) const
{
// type, isAdvanced and documentation do not matter for a match!
diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
index 8b5fce8eb7..15dae12a9c 100644
--- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
+++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
@@ -54,6 +54,7 @@ public:
const QList<CMakeConfigItem> &input);
static QStringList cmakeSplitValue(const QString &in, bool keepEmpty = false);
static Type typeStringToType(const QByteArray &typeString);
+ static QString typeToTypeString(const Type t);
static Utils::optional<bool> toBool(const QByteArray &value);
bool isNull() const { return key.isEmpty(); }
@@ -65,6 +66,7 @@ public:
static QList<CMakeConfigItem> itemsFromFile(const Utils::FilePath &input, QString *errorMessage);
QString toString(const Utils::MacroExpander *expander = nullptr) const;
QString toArgument(const Utils::MacroExpander *expander = nullptr) const;
+ QString toCMakeSetLine(const Utils::MacroExpander *expander = nullptr) const;
bool operator==(const CMakeConfigItem &o) const;
diff --git a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp
index 4745dc4cfa..f7149a4eb2 100644
--- a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp
@@ -155,7 +155,6 @@ void BuildCMakeTargetLocatorFilter::accept(Core::LocatorFilterEntry selection,
// Change the make step to build only the given target
QString oldTarget = buildStep->buildTarget();
- buildStep->clearBuildTargets();
buildStep->setBuildTarget(selection.displayName);
// Build
diff --git a/src/plugins/cmakeprojectmanager/cmakeparser.cpp b/src/plugins/cmakeprojectmanager/cmakeparser.cpp
index 515bf89222..458b7b8b4e 100644
--- a/src/plugins/cmakeprojectmanager/cmakeparser.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeparser.cpp
@@ -105,6 +105,9 @@ void CMakeParser::stdError(const QString &line)
Utils::FilePath(), -1, Constants::TASK_CATEGORY_BUILDSYSTEM);
m_lines = 1;
return;
+ } else if (trimmedLine.startsWith("-- ") || trimmedLine.startsWith(" * ")) {
+ // Do not pass on lines starting with "-- " or "* ". Those are typical CMake output
+ return;
}
IOutputParser::stdError(line);
return;
@@ -288,6 +291,10 @@ void Internal::CMakeProjectPlugin::testCMakeParser_data()
Utils::FilePath::fromUserInput(QLatin1String("/test/path/CMakeLists.txt")), 9,
categoryBuild))
<< QString();
+ QTest::newRow("eat normal CMake output")
+ << QString::fromLatin1("-- Qt5 install prefix: /usr/lib\n"
+ " * Plugin componentsplugin, with CONDITION TARGET QmlDesigner")
+ << OutputParserTester::STDERR << QString() << QString() << (Tasks()) << QString();
}
void Internal::CMakeProjectPlugin::testCMakeParser()
diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
index 07bf943f3d..8517a5ee7f 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
@@ -84,13 +84,6 @@ CMakeProcess::~CMakeProcess()
}
}
-QStringList CMakeProcess::toArguments(const CMakeConfig &config,
- const Utils::MacroExpander *expander) {
- return Utils::transform(config, [expander](const CMakeConfigItem &i) -> QString {
- return i.toArgument(expander);
- });
-}
-
void CMakeProcess::run(const BuildDirParameters &parameters, const QStringList &arguments)
{
QTC_ASSERT(!m_process && !m_parser && !m_future, return);
@@ -135,9 +128,10 @@ void CMakeProcess::run(const BuildDirParameters &parameters, const QStringList &
connect(process.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &CMakeProcess::handleProcessFinished);
- QStringList args(srcDir);
+ QStringList args;
args += parameters.generatorArguments;
args += arguments;
+ args += srcDir;
Utils::CommandLine commandLine(cmake->cmakeExecutable(), args);
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.h b/src/plugins/cmakeprojectmanager/cmakeprocess.h
index 9675822435..6d03d1ab83 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprocess.h
+++ b/src/plugins/cmakeprojectmanager/cmakeprocess.h
@@ -47,8 +47,6 @@ public:
CMakeProcess(const CMakeProcess&) = delete;
~CMakeProcess();
- static QStringList toArguments(const CMakeConfig &config, const Utils::MacroExpander *expander);
-
void run(const BuildDirParameters &parameters, const QStringList &arguments);
QProcess::ProcessState state() const;
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index 9ebc052b06..e44018affd 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -91,7 +91,7 @@ CMakeProject::CMakeProject(const FilePath &fileName)
setKnowsAllBuildExecutables(false);
setHasMakeInstallEquivalent(true);
- setBuildSystem(std::make_unique<CMakeBuildSystem>(this));
+ setBuildSystemCreator([](Project *p) { return new CMakeBuildSystem(p); });
}
CMakeProject::~CMakeProject() = default;
@@ -115,10 +115,10 @@ void CMakeProject::runCMake()
return;
BuildDirParameters parameters(bc);
- bc->m_buildDirManager
- .setParametersAndRequestParse(parameters,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION
- | BuildDirManager::REPARSE_FORCE_CMAKE_RUN);
+ bc->m_buildDirManager.setParametersAndRequestParse(parameters,
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION
+ | BuildDirManager::REPARSE_FORCE_CMAKE_RUN
+ | BuildDirManager::REPARSE_URGENT);
}
void CMakeProject::runCMakeAndScanProjectTree()
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h
index cf7a1f058e..1b5dcca35c 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.h
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.h
@@ -35,25 +35,10 @@
#include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h>
-#include <utils/fileutils.h>
-
-#include <QFuture>
-#include <QHash>
-#include <QTimer>
-
#include <memory>
-namespace CppTools { class CppProjectUpdater; }
-namespace ProjectExplorer { class FileNode; }
-
namespace CMakeProjectManager {
-namespace Internal {
-class CMakeBuildConfiguration;
-class CMakeBuildSettingsWidget;
-class CMakeProjectNode;
-} // namespace Internal
-
class CMAKE_EXPORT CMakeProject : public ProjectExplorer::Project
{
Q_OBJECT
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
index 8d66d920cf..9943ca5784 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
@@ -138,11 +138,6 @@ bool CMakeListsNode::showInSimpleTree() const
return false;
}
-bool CMakeListsNode::supportsAction(ProjectExplorer::ProjectAction action, const ProjectExplorer::Node *) const
-{
- return action == ProjectExplorer::ProjectAction::AddNewFile;
-}
-
Utils::optional<Utils::FilePath> CMakeListsNode::visibleAfterAddFileAction() const
{
return filePath().pathAppended("CMakeLists.txt");
@@ -161,10 +156,19 @@ QString CMakeProjectNode::tooltip() const
return QString();
}
-bool CMakeProjectNode::addFiles(const QStringList &filePaths, QStringList *)
+bool CMakeBuildSystem::addFiles(Node *context, const QStringList &filePaths, QStringList *notAdded)
{
- noAutoAdditionNotify(filePaths, this);
- return true; // Return always true as autoadd is not supported!
+ if (auto n = dynamic_cast<CMakeProjectNode *>(context)) {
+ noAutoAdditionNotify(filePaths, n);
+ return true; // Return always true as autoadd is not supported!
+ }
+
+ if (auto n = dynamic_cast<CMakeTargetNode *>(context)) {
+ noAutoAdditionNotify(filePaths, n);
+ return true; // Return always true as autoadd is not supported!
+ }
+
+ return BuildSystem::addFiles(context, filePaths, notAdded);
}
CMakeTargetNode::CMakeTargetNode(const Utils::FilePath &directory, const QString &target) :
@@ -243,16 +247,15 @@ void CMakeTargetNode::setConfig(const CMakeConfig &config)
m_config = config;
}
-bool CMakeTargetNode::supportsAction(ProjectExplorer::ProjectAction action,
- const ProjectExplorer::Node *) const
+bool CMakeBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
{
- return action == ProjectExplorer::ProjectAction::AddNewFile;
-}
+ if (dynamic_cast<CMakeTargetNode *>(context))
+ return action == ProjectAction::AddNewFile;
-bool CMakeTargetNode::addFiles(const QStringList &filePaths, QStringList *)
-{
- noAutoAdditionNotify(filePaths, this);
- return true; // Return always true as autoadd is not supported!
+ if (dynamic_cast<CMakeListsNode *>(context))
+ return action == ProjectAction::AddNewFile;
+
+ return BuildSystem::supportsAction(context, action, node);
}
Utils::optional<Utils::FilePath> CMakeTargetNode::visibleAfterAddFileAction() const
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
index f4cea98db4..5698f00c9c 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
@@ -44,7 +44,6 @@ public:
CMakeListsNode(const Utils::FilePath &cmakeListPath);
bool showInSimpleTree() const final;
- bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
Utils::optional<Utils::FilePath> visibleAfterAddFileAction() const override;
};
@@ -54,8 +53,6 @@ public:
CMakeProjectNode(const Utils::FilePath &directory);
QString tooltip() const final;
-
- bool addFiles(const QStringList &filePaths, QStringList *notAdded) override;
};
class CMakeTargetNode : public ProjectExplorer::ProjectNode
@@ -70,8 +67,6 @@ public:
Utils::FilePath buildDirectory() const;
void setBuildDirectory(const Utils::FilePath &directory);
- bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
- bool addFiles(const QStringList &filePaths, QStringList *notAdded) override;
Utils::optional<Utils::FilePath> visibleAfterAddFileAction() const override;
void build() override;
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
index 5418a1994e..9eeeb71048 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
@@ -54,6 +54,7 @@
using namespace Core;
using namespace ProjectExplorer;
+using namespace Utils;
namespace CMakeProjectManager {
namespace Internal {
@@ -63,11 +64,17 @@ class CMakeProjectPluginPrivate
public:
CMakeToolManager cmakeToolManager; // have that before the first CMakeKitAspect
- Utils::ParameterAction *m_buildTargetContextAction = nullptr;
+ ParameterAction buildTargetContextAction{
+ CMakeProjectPlugin::tr("Build"),
+ CMakeProjectPlugin:: tr("Build \"%1\""),
+ ParameterAction::AlwaysEnabled/*handled manually*/
+ };
+
QMetaObject::Connection m_actionConnect;
CMakeSettingsPage settingsPage;
- static const std::unique_ptr<CMakeSpecificSettings> projectTypeSpecificSettings;
+ CMakeSpecificSettingsPage specificSettings{CMakeProjectPlugin::projectTypeSpecificSettings()};
+
CMakeManager manager;
CMakeBuildStepFactory buildStepFactory;
CMakeBuildConfigurationFactory buildConfigFactory;
@@ -80,12 +87,10 @@ public:
CMakeConfigurationKitAspect cmakeConfigurationKitAspect;
};
-const std::unique_ptr<CMakeSpecificSettings>
-CMakeProjectPluginPrivate::projectTypeSpecificSettings{std::make_unique<CMakeSpecificSettings>()};
-
CMakeSpecificSettings *CMakeProjectPlugin::projectTypeSpecificSettings()
{
- return CMakeProjectPluginPrivate::projectTypeSpecificSettings.get();
+ static CMakeSpecificSettings theSettings;
+ return &theSettings;
}
CMakeProjectPlugin::~CMakeProjectPlugin()
@@ -98,36 +103,27 @@ bool CMakeProjectPlugin::initialize(const QStringList & /*arguments*/, QString *
Q_UNUSED(errorMessage)
d = new CMakeProjectPluginPrivate;
- CMakeProjectPluginPrivate::projectTypeSpecificSettings->fromSettings(ICore::settings());
- new CMakeSpecificSettingsPage(CMakeProjectPluginPrivate::projectTypeSpecificSettings.get(),
- this); //do not store as this will be cleaned after program close
+ projectTypeSpecificSettings()->fromSettings(ICore::settings());
- const Context projectContext(CMakeProjectManager::Constants::CMAKEPROJECT_ID);
+ const Context projectContext{CMakeProjectManager::Constants::CMAKEPROJECT_ID};
- Core::FileIconProvider::registerIconOverlayForSuffix(Constants::FILEOVERLAY_CMAKE, "cmake");
- Core::FileIconProvider::registerIconOverlayForFilename(Constants::FILEOVERLAY_CMAKE,
- "CMakeLists.txt");
+ FileIconProvider::registerIconOverlayForSuffix(Constants::FILEOVERLAY_CMAKE, "cmake");
+ FileIconProvider::registerIconOverlayForFilename(Constants::FILEOVERLAY_CMAKE,
+ "CMakeLists.txt");
TextEditor::SnippetProvider::registerGroup(Constants::CMAKE_SNIPPETS_GROUP_ID,
tr("CMake", "SnippetProvider"));
ProjectManager::registerProjectType<CMakeProject>(Constants::CMAKEPROJECTMIMETYPE);
- //menus
- ActionContainer *msubproject =
- ActionManager::actionContainer(ProjectExplorer::Constants::M_SUBPROJECTCONTEXT);
-
//register actions
- Command *command = nullptr;
-
- d->m_buildTargetContextAction = new Utils::ParameterAction(tr("Build"), tr("Build \"%1\""),
- Utils::ParameterAction::AlwaysEnabled/*handled manually*/,
- this);
- command = ActionManager::registerAction(d->m_buildTargetContextAction,
- Constants::BUILD_TARGET_CONTEXTMENU, projectContext);
+ Command *command = ActionManager::registerAction(&d->buildTargetContextAction,
+ Constants::BUILD_TARGET_CONTEXTMENU, projectContext);
command->setAttribute(Command::CA_Hide);
command->setAttribute(Command::CA_UpdateText);
- command->setDescription(d->m_buildTargetContextAction->text());
- msubproject->addAction(command, ProjectExplorer::Constants::G_PROJECT_BUILD);
+ command->setDescription(d->buildTargetContextAction.text());
+
+ ActionManager::actionContainer(ProjectExplorer::Constants::M_SUBPROJECTCONTEXT)
+ ->addAction(command, ProjectExplorer::Constants::G_PROJECT_BUILD);
// Wire up context menu updates:
connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged,
@@ -153,11 +149,11 @@ void CMakeProjectPlugin::updateContextActions()
// Build Target:
disconnect(d->m_actionConnect);
- d->m_buildTargetContextAction->setParameter(targetDisplayName);
- d->m_buildTargetContextAction->setEnabled(targetNode);
- d->m_buildTargetContextAction->setVisible(targetNode);
+ d->buildTargetContextAction.setParameter(targetDisplayName);
+ d->buildTargetContextAction.setEnabled(targetNode);
+ d->buildTargetContextAction.setVisible(targetNode);
if (cmProject && targetNode) {
- d->m_actionConnect = connect(d->m_buildTargetContextAction, &Utils::ParameterAction::triggered,
+ d->m_actionConnect = connect(&d->buildTargetContextAction, &ParameterAction::triggered,
cmProject, [cmProject, targetDisplayName]() {
cmProject->buildCMakeTarget(targetDisplayName);
});
diff --git a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp
index 5b4ca9d051..939383672d 100644
--- a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp
@@ -69,13 +69,22 @@ public:
CMakeToolTreeItem *cmakeToolItem(const Core::Id &id) const;
CMakeToolTreeItem *cmakeToolItem(const QModelIndex &index) const;
- QModelIndex addCMakeTool(const QString &name, const FilePath &executable, const bool autoRun, const bool autoCreate, const bool isAutoDetected);
+ QModelIndex addCMakeTool(const QString &name,
+ const FilePath &executable,
+ const FilePath &qchFile,
+ const bool autoRun,
+ const bool autoCreate,
+ const bool isAutoDetected);
void addCMakeTool(const CMakeTool *item, bool changed);
TreeItem *autoGroupItem() const;
TreeItem *manualGroupItem() const;
void reevaluateChangedFlag(CMakeToolTreeItem *item) const;
- void updateCMakeTool(const Core::Id &id, const QString &displayName, const FilePath &executable,
- bool autoRun, bool autoCreate);
+ void updateCMakeTool(const Core::Id &id,
+ const QString &displayName,
+ const FilePath &executable,
+ const FilePath &qchFile,
+ bool autoRun,
+ bool autoCreate);
void removeCMakeTool(const Core::Id &id);
void apply();
@@ -97,6 +106,7 @@ public:
: m_id(item->id())
, m_name(item->displayName())
, m_executable(item->filePath())
+ , m_qchFile(item->qchFilePath())
, m_isAutoRun(item->isAutoRun())
, m_autoCreateBuildDirectory(item->autoCreateBuildDirectory())
, m_autodetected(item->isAutoDetected())
@@ -111,12 +121,14 @@ public:
CMakeToolTreeItem(const QString &name,
const Utils::FilePath &executable,
+ const FilePath &qchFile,
bool autoRun,
bool autoCreate,
bool autodetected)
: m_id(Core::Id::fromString(QUuid::createUuid().toString()))
, m_name(name)
, m_executable(executable)
+ , m_qchFile(qchFile)
, m_isAutoRun(autoRun)
, m_autoCreateBuildDirectory(autoCreate)
, m_autodetected(autodetected)
@@ -197,6 +209,7 @@ public:
QString m_name;
QString m_tooltip;
FilePath m_executable;
+ FilePath m_qchFile;
bool m_isAutoRun = true;
bool m_pathExists = false;
bool m_pathIsFile = false;
@@ -224,11 +237,14 @@ CMakeToolItemModel::CMakeToolItemModel()
}
-QModelIndex CMakeToolItemModel::addCMakeTool(const QString &name, const FilePath &executable,
- const bool autoRun, const bool autoCreate,
+QModelIndex CMakeToolItemModel::addCMakeTool(const QString &name,
+ const FilePath &executable,
+ const FilePath &qchFile,
+ const bool autoRun,
+ const bool autoCreate,
const bool isAutoDetected)
{
- auto item = new CMakeToolTreeItem(name, executable, autoRun, autoCreate, isAutoDetected);
+ auto item = new CMakeToolTreeItem(name, executable, qchFile, autoRun, autoCreate, isAutoDetected);
if (isAutoDetected)
autoGroupItem()->appendChild(item);
else
@@ -265,7 +281,8 @@ void CMakeToolItemModel::reevaluateChangedFlag(CMakeToolTreeItem *item) const
{
CMakeTool *orig = CMakeToolManager::findById(item->m_id);
item->m_changed = !orig || orig->displayName() != item->m_name
- || orig->filePath() != item->m_executable;
+ || orig->filePath() != item->m_executable
+ || orig->qchFilePath() != item->m_qchFile;
//make sure the item is marked as changed when the default cmake was changed
CMakeTool *origDefTool = CMakeToolManager::defaultCMakeTool();
@@ -278,8 +295,11 @@ void CMakeToolItemModel::reevaluateChangedFlag(CMakeToolTreeItem *item) const
item->update(); // Notify views.
}
-void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &displayName,
- const FilePath &executable, bool autoRun,
+void CMakeToolItemModel::updateCMakeTool(const Core::Id &id,
+ const QString &displayName,
+ const FilePath &executable,
+ const FilePath &qchFile,
+ bool autoRun,
bool autoCreate)
{
CMakeToolTreeItem *treeItem = cmakeToolItem(id);
@@ -287,6 +307,7 @@ void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &disp
treeItem->m_name = displayName;
treeItem->m_executable = executable;
+ treeItem->m_qchFile = qchFile;
treeItem->m_isAutoRun = autoRun;
treeItem->m_autoCreateBuildDirectory = autoCreate;
@@ -328,6 +349,7 @@ void CMakeToolItemModel::apply()
if (CMakeTool *cmake = CMakeToolManager::findById(item->m_id)) {
cmake->setDisplayName(item->m_name);
cmake->setFilePath(item->m_executable);
+ cmake->setQchFilePath(item->m_qchFile);
cmake->setAutorun(item->m_isAutoRun);
cmake->setAutoCreateBuildDirectory(item->m_autoCreateBuildDirectory);
} else {
@@ -341,6 +363,7 @@ void CMakeToolItemModel::apply()
auto cmake = std::make_unique<CMakeTool>(detection, item->m_id);
cmake->setDisplayName(item->m_name);
cmake->setFilePath(item->m_executable);
+ cmake->setQchFilePath(item->m_qchFile);
if (!CMakeToolManager::registerCMakeTool(std::move(cmake)))
item->m_changed = true;
}
@@ -392,11 +415,14 @@ public:
void store() const;
private:
+ void updateQchFilePath();
+
CMakeToolItemModel *m_model;
QLineEdit *m_displayNameLineEdit;
QCheckBox *m_autoRunCheckBox;
QCheckBox *m_autoCreateBuildDirectoryCheckBox;
PathChooser *m_binaryChooser;
+ PathChooser *m_qchFileChooser;
Core::Id m_id;
bool m_loadingItem;
};
@@ -412,6 +438,13 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model)
m_binaryChooser->setHistoryCompleter(QLatin1String("Cmake.Command.History"));
m_binaryChooser->setCommandVersionArguments({"--version"});
+ m_qchFileChooser = new PathChooser(this);
+ m_qchFileChooser->setExpectedKind(PathChooser::File);
+ m_qchFileChooser->setMinimumWidth(400);
+ m_qchFileChooser->setHistoryCompleter(QLatin1String("Cmake.qchFile.History"));
+ m_qchFileChooser->setPromptDialogFilter("*.qch");
+ m_qchFileChooser->setPromptDialogTitle(tr("CMake .qch File"));
+
m_autoRunCheckBox = new QCheckBox;
m_autoRunCheckBox->setText(tr("Autorun CMake"));
m_autoRunCheckBox->setToolTip(tr("Automatically run CMake after changes to CMake project files."));
@@ -424,13 +457,17 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model)
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit);
formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser);
+ formLayout->addRow(new QLabel(tr("Help File:")), m_qchFileChooser);
formLayout->addRow(m_autoRunCheckBox);
formLayout->addRow(m_autoCreateBuildDirectoryCheckBox);
- connect(m_binaryChooser, &PathChooser::rawPathChanged,
- this, &CMakeToolItemConfigWidget::store);
- connect(m_displayNameLineEdit, &QLineEdit::textChanged,
- this, &CMakeToolItemConfigWidget::store);
+ connect(m_binaryChooser, &PathChooser::rawPathChanged, this, [this]() {
+ updateQchFilePath();
+ m_qchFileChooser->setBaseFileName(m_binaryChooser->fileName().parentDir());
+ store();
+ });
+ connect(m_qchFileChooser, &PathChooser::rawPathChanged, this, &CMakeToolItemConfigWidget::store);
+ connect(m_displayNameLineEdit, &QLineEdit::textChanged, this, &CMakeToolItemConfigWidget::store);
connect(m_autoRunCheckBox, &QCheckBox::toggled,
this, &CMakeToolItemConfigWidget::store);
connect(m_autoCreateBuildDirectoryCheckBox, &QCheckBox::toggled,
@@ -440,11 +477,20 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model)
void CMakeToolItemConfigWidget::store() const
{
if (!m_loadingItem && m_id.isValid())
- m_model->updateCMakeTool(m_id, m_displayNameLineEdit->text(), m_binaryChooser->fileName(),
+ m_model->updateCMakeTool(m_id,
+ m_displayNameLineEdit->text(),
+ m_binaryChooser->fileName(),
+ m_qchFileChooser->fileName(),
m_autoRunCheckBox->checkState() == Qt::Checked,
m_autoCreateBuildDirectoryCheckBox->checkState() == Qt::Checked);
}
+void CMakeToolItemConfigWidget::updateQchFilePath()
+{
+ if (m_qchFileChooser->fileName().isEmpty())
+ m_qchFileChooser->setFileName(CMakeTool::searchQchFile(m_binaryChooser->fileName()));
+}
+
void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
{
m_loadingItem = true; // avoid intermediate signal handling
@@ -461,6 +507,10 @@ void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
m_binaryChooser->setReadOnly(item->m_autodetected);
m_binaryChooser->setFileName(item->m_executable);
+ m_qchFileChooser->setReadOnly(item->m_autodetected);
+ m_qchFileChooser->setBaseFileName(item->m_executable.parentDir());
+ m_qchFileChooser->setFileName(item->m_qchFile);
+
m_autoRunCheckBox->setChecked(item->m_isAutoRun);
m_autoCreateBuildDirectoryCheckBox->setChecked(item->m_autoCreateBuildDirectory);
@@ -568,8 +618,10 @@ void CMakeToolConfigWidget::cloneCMakeTool()
QModelIndex newItem = m_model.addCMakeTool(tr("Clone of %1").arg(m_currentItem->m_name),
m_currentItem->m_executable,
+ m_currentItem->m_qchFile,
m_currentItem->m_isAutoRun,
- m_currentItem->m_autoCreateBuildDirectory, false);
+ m_currentItem->m_autoCreateBuildDirectory,
+ false);
m_cmakeToolsView->setCurrentIndex(newItem);
}
@@ -577,7 +629,11 @@ void CMakeToolConfigWidget::cloneCMakeTool()
void CMakeToolConfigWidget::addCMakeTool()
{
QModelIndex newItem = m_model.addCMakeTool(m_model.uniqueDisplayName(tr("New CMake")),
- FilePath(), true, false, false);
+ FilePath(),
+ FilePath(),
+ true,
+ false,
+ false);
m_cmakeToolsView->setCurrentIndex(newItem);
}
diff --git a/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.cpp
index e458e7fbd5..cc37b325e5 100644
--- a/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.cpp
@@ -72,9 +72,8 @@ void CMakeSpecificSettingWidget::setProjectPopupSetting(AfterAddFileAction mode)
}
}
-CMakeSpecificSettingsPage::CMakeSpecificSettingsPage(CMakeSpecificSettings *settings,
- QObject *parent):
- Core::IOptionsPage(parent), m_settings(settings)
+CMakeSpecificSettingsPage::CMakeSpecificSettingsPage(CMakeSpecificSettings *settings)
+ : m_settings(settings)
{
setId("CMakeSpecificSettings");
setDisplayName(tr("CMake"));
diff --git a/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.h b/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.h
index 2d4419d0d5..f54b1bc8ac 100644
--- a/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.h
+++ b/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.h
@@ -54,8 +54,9 @@ private:
class CMakeSpecificSettingsPage : public Core::IOptionsPage
{
Q_OBJECT
+
public:
- CMakeSpecificSettingsPage(CMakeSpecificSettings *settings, QObject *parent);
+ explicit CMakeSpecificSettingsPage(CMakeSpecificSettings *settings);
QWidget *widget() override;
void apply() override;
diff --git a/src/plugins/cmakeprojectmanager/cmaketool.cpp b/src/plugins/cmakeprojectmanager/cmaketool.cpp
index 361e0acd88..e8284c5e7e 100644
--- a/src/plugins/cmakeprojectmanager/cmaketool.cpp
+++ b/src/plugins/cmakeprojectmanager/cmaketool.cpp
@@ -30,6 +30,7 @@
#include <utils/environment.h>
#include <utils/qtcassert.h>
+#include <QDir>
#include <QFileInfo>
#include <QJsonDocument>
#include <QJsonObject>
@@ -46,6 +47,7 @@ const char CMAKE_INFORMATION_ID[] = "Id";
const char CMAKE_INFORMATION_COMMAND[] = "Binary";
const char CMAKE_INFORMATION_DISPLAYNAME[] = "DisplayName";
const char CMAKE_INFORMATION_AUTORUN[] = "AutoRun";
+const char CMAKE_INFORMATION_QCH_FILE_PATH[] = "QchFile";
const char CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY[] = "AutoCreateBuildDirectory";
const char CMAKE_INFORMATION_AUTODETECTED[] = "AutoDetected";
const char CMAKE_INFORMATION_READERTYPE[] = "ReaderType";
@@ -146,6 +148,11 @@ CMakeTool::CMakeTool(const QVariantMap &map, bool fromSdk) :
m_isAutoDetected = map.value(CMAKE_INFORMATION_AUTODETECTED, false).toBool();
setFilePath(Utils::FilePath::fromString(map.value(CMAKE_INFORMATION_COMMAND).toString()));
+
+ m_qchFilePath = Utils::FilePath::fromVariant(map.value(CMAKE_INFORMATION_QCH_FILE_PATH));
+
+ if (m_qchFilePath.isEmpty())
+ m_qchFilePath = searchQchFile(m_executable);
}
CMakeTool::~CMakeTool() = default;
@@ -228,6 +235,7 @@ QVariantMap CMakeTool::toMap() const
data.insert(CMAKE_INFORMATION_DISPLAYNAME, m_displayName);
data.insert(CMAKE_INFORMATION_ID, m_id.toSetting());
data.insert(CMAKE_INFORMATION_COMMAND, m_executable.toString());
+ data.insert(CMAKE_INFORMATION_QCH_FILE_PATH, m_qchFilePath.toString());
data.insert(CMAKE_INFORMATION_AUTORUN, m_isAutoRun);
data.insert(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, m_autoCreateBuildDirectory);
if (m_readerType.has_value())
@@ -242,6 +250,16 @@ Utils::FilePath CMakeTool::cmakeExecutable() const
return cmakeExecutable(m_executable);
}
+void CMakeTool::setQchFilePath(const Utils::FilePath &path)
+{
+ m_qchFilePath = path;
+}
+
+Utils::FilePath CMakeTool::qchFilePath() const
+{
+ return m_qchFilePath;
+}
+
Utils::FilePath CMakeTool::cmakeExecutable(const Utils::FilePath &path)
{
if (Utils::HostOsInfo::isMacHost()) {
@@ -375,21 +393,41 @@ CMakeTool::ReaderType CMakeTool::readerType() const
return m_readerType.value();
}
-void CMakeTool::readInformation(CMakeTool::QueryType type) const
+Utils::FilePath CMakeTool::searchQchFile(const Utils::FilePath &executable)
{
- if ((type == QueryType::GENERATORS && !m_introspection->m_generators.isEmpty())
- || (type == QueryType::SERVER_MODE && m_introspection->m_queriedServerMode)
- || (type == QueryType::VERSION && !m_introspection->m_version.fullVersion.isEmpty()))
- return;
+ if (executable.isEmpty())
+ return {};
+
+ Utils::FilePath prefixDir = executable.parentDir().parentDir();
+ QDir docDir{prefixDir.pathAppended("doc/cmake").toString()};
+ if (!docDir.exists())
+ docDir.setPath(prefixDir.pathAppended("share/doc/cmake").toString());
+ if (!docDir.exists())
+ return {};
+ const QStringList files = docDir.entryList(QStringList("*.qch"));
+ for (const QString &docFile : files) {
+ if (docFile.startsWith("cmake", Qt::CaseInsensitive)) {
+ return Utils::FilePath::fromString(docDir.absoluteFilePath(docFile));
+ }
+ }
+
+ return {};
+}
+
+void CMakeTool::readInformation(CMakeTool::QueryType type) const
+{
if (!m_introspection->m_triedCapabilities) {
fetchFromCapabilities();
m_introspection->m_triedCapabilities = true;
m_introspection->m_queriedServerMode = true; // Got added after "-E capabilities" support!
- if (type == QueryType::GENERATORS && !m_introspection->m_generators.isEmpty())
- return;
}
+ if ((type == QueryType::GENERATORS && !m_introspection->m_generators.isEmpty())
+ || (type == QueryType::SERVER_MODE && m_introspection->m_queriedServerMode)
+ || (type == QueryType::VERSION && !m_introspection->m_version.fullVersion.isEmpty()))
+ return;
+
if (type == QueryType::GENERATORS) {
fetchGeneratorsFromHelp();
} else if (type == QueryType::SERVER_MODE) {
diff --git a/src/plugins/cmakeprojectmanager/cmaketool.h b/src/plugins/cmakeprojectmanager/cmaketool.h
index 579f6e4d72..1e305b2dd3 100644
--- a/src/plugins/cmakeprojectmanager/cmaketool.h
+++ b/src/plugins/cmakeprojectmanager/cmaketool.h
@@ -95,6 +95,8 @@ public:
void setFilePath(const Utils::FilePath &executable);
Utils::FilePath filePath() const;
Utils::FilePath cmakeExecutable() const;
+ void setQchFilePath(const Utils::FilePath &path);
+ Utils::FilePath qchFilePath() const;
static Utils::FilePath cmakeExecutable(const Utils::FilePath &path);
bool isAutoRun() const;
bool autoCreateBuildDirectory() const;
@@ -114,6 +116,8 @@ public:
ReaderType readerType() const;
+ static Utils::FilePath searchQchFile(const Utils::FilePath &executable);
+
private:
enum class QueryType {
GENERATORS,
@@ -136,6 +140,7 @@ private:
Core::Id m_id;
QString m_displayName;
Utils::FilePath m_executable;
+ Utils::FilePath m_qchFilePath;
bool m_isAutoRun = true;
bool m_isAutoDetected = false;
diff --git a/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp b/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp
index 77f3e077a2..fd7af452c7 100644
--- a/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp
@@ -27,6 +27,7 @@
#include "cmaketoolsettingsaccessor.h"
+#include <coreplugin/helpmanager.h>
#include <coreplugin/icore.h>
#include <utils/pointeralgorithm.h>
@@ -105,6 +106,8 @@ bool CMakeToolManager::registerCMakeTool(std::unique_ptr<CMakeTool> &&tool)
ensureDefaultCMakeToolIsValid();
+ updateDocumentation();
+
return true;
}
@@ -112,9 +115,10 @@ void CMakeToolManager::deregisterCMakeTool(const Id &id)
{
auto toRemove = Utils::take(d->m_cmakeTools, Utils::equal(&CMakeTool::id, id));
if (toRemove.has_value()) {
-
ensureDefaultCMakeToolIsValid();
+ updateDocumentation();
+
emit m_instance->cmakeRemoved(id);
}
}
@@ -152,9 +156,22 @@ void CMakeToolManager::restoreCMakeTools()
d->m_cmakeTools = std::move(tools.cmakeTools);
setDefaultCMakeTool(tools.defaultToolId);
+ updateDocumentation();
+
emit m_instance->cmakeToolsLoaded();
}
+void CMakeToolManager::updateDocumentation()
+{
+ const QList<CMakeTool *> tools = cmakeTools();
+ QStringList docs;
+ for (const auto tool : tools) {
+ if (!tool->qchFilePath().isEmpty())
+ docs.append(tool->qchFilePath().toString());
+ }
+ Core::HelpManager::registerDocumentation(docs);
+}
+
void CMakeToolManager::notifyAboutUpdate(CMakeTool *tool)
{
if (!tool || !Utils::contains(d->m_cmakeTools, tool))
diff --git a/src/plugins/cmakeprojectmanager/cmaketoolmanager.h b/src/plugins/cmakeprojectmanager/cmaketoolmanager.h
index b5ea3221dd..c91f649850 100644
--- a/src/plugins/cmakeprojectmanager/cmaketoolmanager.h
+++ b/src/plugins/cmakeprojectmanager/cmaketoolmanager.h
@@ -58,6 +58,8 @@ public:
static void notifyAboutUpdate(CMakeTool *);
static void restoreCMakeTools();
+ static void updateDocumentation();
+
signals:
void cmakeAdded (const Core::Id &id);
void cmakeRemoved (const Core::Id &id);
diff --git a/src/plugins/cmakeprojectmanager/fileapireader.cpp b/src/plugins/cmakeprojectmanager/fileapireader.cpp
index f1fcbe1ea2..0ef2df3370 100644
--- a/src/plugins/cmakeprojectmanager/fileapireader.cpp
+++ b/src/plugins/cmakeprojectmanager/fileapireader.cpp
@@ -131,8 +131,8 @@ void FileApiReader::parse(bool forceCMakeRun, bool forceConfiguration)
if (forceConfiguration) {
// Initial create:
qCDebug(cmakeFileApiMode) << "FileApiReader: Starting CMake with forced configuration.";
- startCMakeState(
- CMakeProcess::toArguments(m_parameters.configuration, m_parameters.expander));
+ const FilePath path = m_parameters.workDirectory.pathAppended("qtcsettings.cmake");
+ startCMakeState(QStringList({QString("-C"), path.toUserOutput()}));
// Keep m_isParsing enabled!
return;
}
@@ -294,6 +294,8 @@ void FileApiReader::cmakeFinishedState(int code, QProcess::ExitStatus status)
Q_UNUSED(code)
Q_UNUSED(status)
+ m_cmakeProcess.release()->deleteLater();
+
endState(m_fileApi->scanForCMakeReplyFile());
}
diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
index b611f12c65..31f13234a6 100644
--- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp
+++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
@@ -133,7 +133,8 @@ void TeaLeafReader::parse(bool forceCMakeRun, bool forceConfiguration)
const QFileInfo cbpFileFi = cbpFile.isEmpty() ? QFileInfo() : QFileInfo(cbpFile);
if (!cbpFileFi.exists() || forceConfiguration) {
// Initial create:
- startCMake(CMakeProcess::toArguments(m_parameters.configuration, m_parameters.expander));
+ const FilePath path = m_parameters.workDirectory.pathAppended("qtcsettings.cmake");
+ startCMake(QStringList({QString("-C"), path.toUserOutput()}));
return;
}
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
index ec16d72bd5..d9bf685f08 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
@@ -34,6 +34,7 @@
#include <projectexplorer/buildinfo.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/buildtargetinfo.h>
+#include <projectexplorer/deploymentdata.h>
#include <projectexplorer/gcctoolchain.h>
#include <projectexplorer/headerpath.h>
#include <projectexplorer/kitinformation.h>
@@ -47,6 +48,7 @@
#include <texteditor/textdocument.h>
#include <utils/algorithm.h>
+#include <utils/filesystemwatcher.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
@@ -390,26 +392,27 @@ void CompilationDatabaseProject::buildTreeAndProjectParts()
setRootProjectNode(std::move(root));
m_cppCodeModelUpdater->update({this, kitInfo, activeParseEnvironment(), rpps});
+ updateDeploymentData();
}
CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FilePath &projectFile)
: Project(Constants::COMPILATIONDATABASEMIMETYPE, projectFile)
, m_cppCodeModelUpdater(std::make_unique<CppTools::CppProjectUpdater>())
, m_parseDelay(new QTimer(this))
+ , m_deployFileWatcher(new FileSystemWatcher(this))
{
setId(Constants::COMPILATIONDATABASEPROJECT_ID);
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
setDisplayName(projectDirectory().fileName());
- setRequiredKitPredicate([](const Kit *) { return false; });
- setPreferredKitPredicate([](const Kit *) { return false; });
m_kit.reset(KitManager::defaultKit()->clone());
addTargetForKit(m_kit.get());
- connect(this,
- &CompilationDatabaseProject::rootProjectDirectoryChanged,
- m_parseDelay,
- QOverload<>::of(&QTimer::start));
+ connect(this, &CompilationDatabaseProject::rootProjectDirectoryChanged,
+ this, [this] {
+ m_projectFileHash.clear();
+ m_parseDelay->start();
+ });
setExtraProjectFiles(
{projectFile.stringAppended(Constants::COMPILATIONDATABASEPROJECT_FILES_SUFFIX)});
@@ -419,6 +422,10 @@ CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FilePath &pr
m_parseDelay->setInterval(1000);
connect(this, &Project::projectFileIsDirty, this, &CompilationDatabaseProject::reparseProject);
+ connect(m_deployFileWatcher, &FileSystemWatcher::fileChanged,
+ this, &CompilationDatabaseProject::updateDeploymentData);
+ connect(this, &Project::activeTargetChanged,
+ this, &CompilationDatabaseProject::updateDeploymentData);
}
Utils::FilePath CompilationDatabaseProject::rootPathFromSettings() const
@@ -458,14 +465,34 @@ void CompilationDatabaseProject::reparseProject()
m_mimeBinaryCache,
guardParsingRun(),
this);
- connect(m_parser, &CompilationDbParser::finished, this, [this](bool success) {
- if (success)
+ connect(m_parser, &CompilationDbParser::finished, this, [this](ParseResult result) {
+ m_projectFileHash = m_parser->projectFileHash();
+ if (result == ParseResult::Success)
buildTreeAndProjectParts();
m_parser = nullptr;
});
+ m_parser->setPreviousProjectFileHash(m_projectFileHash);
m_parser->start();
}
+void CompilationDatabaseProject::updateDeploymentData()
+{
+ Target * const target = activeTarget();
+ if (!target)
+ return;
+ const Utils::FilePath deploymentFilePath = projectDirectory()
+ .pathAppended("QtCreatorDeployment.txt");
+ DeploymentData deploymentData;
+ deploymentData.addFilesFromDeploymentFile(deploymentFilePath.toString(),
+ projectDirectory().toString());
+ target->setDeploymentData(deploymentData);
+ if (m_deployFileWatcher->files() != QStringList(deploymentFilePath.toString())) {
+ m_deployFileWatcher->removeFiles(m_deployFileWatcher->files());
+ m_deployFileWatcher->addFile(deploymentFilePath.toString(),
+ FileSystemWatcher::WatchModifiedDate);
+ }
+}
+
CompilationDatabaseProject::~CompilationDatabaseProject()
{
m_parserWatcher.cancel();
@@ -498,19 +525,6 @@ CompilationDatabaseBuildConfiguration::CompilationDatabaseBuildConfiguration(
ProjectExplorer::Target *target, Core::Id id)
: ProjectExplorer::BuildConfiguration(target, id)
{
- target->setApplicationTargets({BuildTargetInfo()});
-}
-
-void CompilationDatabaseBuildConfiguration::initialize()
-{
- ProjectExplorer::BuildConfiguration::initialize();
- BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
- buildSteps->appendStep(ProjectExplorer::Constants::PROCESS_STEP_ID);
-}
-
-ProjectExplorer::NamedWidget *CompilationDatabaseBuildConfiguration::createConfigWidget()
-{
- return new ProjectExplorer::NamedWidget();
}
CompilationDatabaseBuildConfigurationFactory::CompilationDatabaseBuildConfigurationFactory()
@@ -523,13 +537,14 @@ CompilationDatabaseBuildConfigurationFactory::CompilationDatabaseBuildConfigurat
}
QList<BuildInfo> CompilationDatabaseBuildConfigurationFactory::availableBuilds
- (const Kit *kit, const FilePath &, bool) const
+ (const Kit *kit, const FilePath &projectPath, bool) const
{
const QString name = tr("Release");
ProjectExplorer::BuildInfo info(this);
info.typeName = name;
info.displayName = name;
info.buildType = BuildConfiguration::Release;
+ info.buildDirectory = projectPath.parentDir();
info.kitId = kit->id();
return {info};
}
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h
index ca829f312a..900f7d3675 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h
@@ -38,13 +38,9 @@ QT_BEGIN_NAMESPACE
class QTimer;
QT_END_NAMESPACE
-namespace CppTools {
-class CppProjectUpdater;
-}
-
-namespace ProjectExplorer {
-class Kit;
-}
+namespace CppTools { class CppProjectUpdater; }
+namespace ProjectExplorer { class Kit; }
+namespace Utils { class FileSystemWatcher; }
namespace CompilationDatabaseProjectManager {
namespace Internal {
@@ -63,6 +59,7 @@ private:
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
void reparseProject();
+ void updateDeploymentData();
void buildTreeAndProjectParts();
Utils::FilePath rootPathFromSettings() const;
@@ -70,8 +67,10 @@ private:
std::unique_ptr<CppTools::CppProjectUpdater> m_cppCodeModelUpdater;
std::unique_ptr<ProjectExplorer::Kit> m_kit;
MimeBinaryCache m_mimeBinaryCache;
+ QByteArray m_projectFileHash;
QTimer * const m_parseDelay;
CompilationDbParser *m_parser = nullptr;
+ Utils::FileSystemWatcher * const m_deployFileWatcher;
};
class CompilationDatabaseEditorFactory : public TextEditor::TextEditorFactory
@@ -87,10 +86,6 @@ class CompilationDatabaseBuildConfiguration : public ProjectExplorer::BuildConfi
Q_OBJECT
public:
CompilationDatabaseBuildConfiguration(ProjectExplorer::Target *target, Core::Id id);
- ProjectExplorer::NamedWidget *createConfigWidget() override;
-
-protected:
- void initialize() override;
};
class CompilationDatabaseBuildConfigurationFactory
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
index 0eca37325c..04d9af3e91 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
@@ -33,75 +33,87 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/fileiconprovider.h>
+
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectmanager.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/session.h>
+
+#include <utils/parameteraction.h>
#include <utils/utilsicons.h>
+using namespace Core;
+using namespace ProjectExplorer;
+
namespace CompilationDatabaseProjectManager {
namespace Internal {
const char CHANGEROOTDIR[] = "CompilationDatabaseProjectManager.ChangeRootDirectory";
const char COMPILE_COMMANDS_JSON[] = "compile_commands.json";
+class CompilationDatabaseProjectManagerPluginPrivate
+{
+public:
+ CompilationDatabaseEditorFactory editorFactory;
+ CompilationDatabaseBuildConfigurationFactory buildConfigFactory;
+ QAction changeRootAction{CompilationDatabaseProjectManagerPlugin::tr("Change Root Directory")};
+};
+
+CompilationDatabaseProjectManagerPlugin::~CompilationDatabaseProjectManagerPlugin()
+{
+ delete d;
+}
+
bool CompilationDatabaseProjectManagerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
Q_UNUSED(arguments)
Q_UNUSED(errorMessage)
- Core::FileIconProvider::registerIconOverlayForFilename(
+
+ d = new CompilationDatabaseProjectManagerPluginPrivate;
+
+ FileIconProvider::registerIconOverlayForFilename(
Utils::Icons::PROJECT.imageFileName(),
COMPILE_COMMANDS_JSON);
- Core::FileIconProvider::registerIconOverlayForFilename(
+ FileIconProvider::registerIconOverlayForFilename(
Utils::Icons::PROJECT.imageFileName(),
QString(COMPILE_COMMANDS_JSON) + Constants::COMPILATIONDATABASEPROJECT_FILES_SUFFIX);
- ProjectExplorer::ProjectManager::registerProjectType<CompilationDatabaseProject>(
+ ProjectManager::registerProjectType<CompilationDatabaseProject>(
Constants::COMPILATIONDATABASEMIMETYPE);
- m_changeProjectRootDirectoryAction = new QAction(tr("Change Root Directory"), this);
- Core::Command *cmd = Core::ActionManager::registerAction(m_changeProjectRootDirectoryAction,
- CHANGEROOTDIR);
- Core::ActionContainer *mprojectContextMenu = Core::ActionManager::actionContainer(
+
+ Command *cmd = ActionManager::registerAction(&d->changeRootAction, CHANGEROOTDIR);
+
+ ActionContainer *mprojectContextMenu = ActionManager::actionContainer(
ProjectExplorer::Constants::M_PROJECTCONTEXT);
mprojectContextMenu->addSeparator(ProjectExplorer::Constants::G_PROJECT_TREE);
mprojectContextMenu->addAction(cmd, ProjectExplorer::Constants::G_PROJECT_TREE);
- connect(m_changeProjectRootDirectoryAction,
- &QAction::triggered,
- ProjectExplorer::ProjectTree::instance(),
- &ProjectExplorer::ProjectTree::changeProjectRootDirectory);
+ connect(&d->changeRootAction, &QAction::triggered,
+ ProjectTree::instance(), &ProjectTree::changeProjectRootDirectory);
- connect(ProjectExplorer::SessionManager::instance(),
- &ProjectExplorer::SessionManager::startupProjectChanged,
- this,
- &CompilationDatabaseProjectManagerPlugin::projectChanged);
- connect(ProjectExplorer::ProjectTree::instance(),
- &ProjectExplorer::ProjectTree::currentProjectChanged,
- this,
- &CompilationDatabaseProjectManagerPlugin::projectChanged);
+ const auto onProjectChanged = [this] {
+ const auto currentProject = qobject_cast<CompilationDatabaseProject *>(
+ ProjectTree::currentProject());
- return true;
-}
+ d->changeRootAction.setEnabled(currentProject);
+ };
-void CompilationDatabaseProjectManagerPlugin::projectChanged()
-{
- const auto *currentProject = qobject_cast<CompilationDatabaseProject *>(
- ProjectExplorer::ProjectTree::currentProject());
+ connect(SessionManager::instance(), &SessionManager::startupProjectChanged,
+ this, onProjectChanged);
- m_changeProjectRootDirectoryAction->setEnabled(currentProject);
-}
+ connect(ProjectTree::instance(), &ProjectTree::currentProjectChanged,
+ this, onProjectChanged);
-void CompilationDatabaseProjectManagerPlugin::extensionsInitialized()
-{
+ return true;
}
QVector<QObject *> CompilationDatabaseProjectManagerPlugin::createTestObjects() const
{
- QVector<QObject *> tests;
+ return {
#ifdef WITH_TESTS
- tests << new CompilationDatabaseTests;
+ new CompilationDatabaseTests
#endif
- return tests;
+ };
}
} // namespace Internal
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.h b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.h
index 42a15ad3cf..b825172ca6 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.h
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.h
@@ -25,11 +25,7 @@
#pragma once
-#include "compilationdatabaseproject.h"
-
-#include <coreplugin/id.h>
#include <extensionsystem/iplugin.h>
-#include <utils/parameteraction.h>
namespace CompilationDatabaseProjectManager {
namespace Internal {
@@ -39,17 +35,13 @@ class CompilationDatabaseProjectManagerPlugin final : public ExtensionSystem::IP
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "CompilationDatabaseProjectManager.json")
-public:
- bool initialize(const QStringList &arguments, QString *errorMessage) final;
- void extensionsInitialized() final;
-private:
- void projectChanged();
+ ~CompilationDatabaseProjectManagerPlugin();
+ bool initialize(const QStringList &arguments, QString *errorMessage) final;
+ void extensionsInitialized() final {}
QVector<QObject *> createTestObjects() const final;
- CompilationDatabaseEditorFactory factory;
- CompilationDatabaseBuildConfigurationFactory buildConfigFactory;
- QAction *m_changeProjectRootDirectoryAction;
+ class CompilationDatabaseProjectManagerPluginPrivate *d = nullptr;
};
} // namespace Internal
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp
index 6c91311898..374c245b23 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp
@@ -31,6 +31,7 @@
#include <utils/mimetypes/mimetype.h>
#include <utils/runextensions.h>
+#include <QCryptographicHash>
#include <QDir>
#include <QFileInfo>
#include <QJsonArray>
@@ -59,12 +60,27 @@ CompilationDbParser::CompilationDbParser(const QString &projectName,
connect(&m_parserWatcher, &QFutureWatcher<void>::finished, this, [this] {
m_dbContents = m_parserWatcher.result();
if (!m_treeScanner || m_treeScanner->isFinished())
- finish();
+ finish(ParseResult::Success);
});
}
void CompilationDbParser::start()
{
+ // Check hash first.
+ QFile file(m_projectFilePath.toString());
+ if (!file.open(QIODevice::ReadOnly)) {
+ finish(ParseResult::Failure);
+ return;
+ }
+ m_projectFileContents = file.readAll();
+ const QByteArray newHash = QCryptographicHash::hash(m_projectFileContents,
+ QCryptographicHash::Sha1);
+ if (m_projectFileHash == newHash) {
+ finish(ParseResult::Cached);
+ return;
+ }
+ m_projectFileHash = newHash;
+
// Thread 1: Scan disk.
if (!m_rootPath.isEmpty()) {
m_treeScanner = new TreeScanner(this);
@@ -95,7 +111,7 @@ void CompilationDbParser::start()
"CompilationDatabase.Scan.Tree");
connect(m_treeScanner, &TreeScanner::finished, this, [this] {
if (m_parserWatcher.isFinished())
- finish();
+ finish(ParseResult::Success);
});
}
@@ -126,9 +142,9 @@ QList<FileNode *> CompilationDbParser::scannedFiles() const
? m_treeScanner->release() : QList<FileNode *>();
}
-void CompilationDbParser::finish()
+void CompilationDbParser::finish(ParseResult result)
{
- emit finished(true);
+ emit finished(result);
deleteLater();
}
@@ -158,24 +174,20 @@ static FilePath jsonObjectFilename(const QJsonObject &object)
return fileName;
}
-static std::vector<DbEntry> readJsonObjects(const QString &filePath)
+std::vector<DbEntry> CompilationDbParser::readJsonObjects() const
{
std::vector<DbEntry> result;
- QFile file(filePath);
- if (!file.open(QIODevice::ReadOnly))
- return result;
- const QByteArray contents = file.readAll();
- int objectStart = contents.indexOf('{');
- int objectEnd = contents.indexOf('}', objectStart + 1);
+ int objectStart = m_projectFileContents.indexOf('{');
+ int objectEnd = m_projectFileContents.indexOf('}', objectStart + 1);
QSet<QString> flagsCache;
while (objectStart >= 0 && objectEnd >= 0) {
const QJsonDocument document = QJsonDocument::fromJson(
- contents.mid(objectStart, objectEnd - objectStart + 1));
+ m_projectFileContents.mid(objectStart, objectEnd - objectStart + 1));
if (document.isNull()) {
// The end was found incorrectly, search for the next one.
- objectEnd = contents.indexOf('}', objectEnd + 1);
+ objectEnd = m_projectFileContents.indexOf('}', objectEnd + 1);
continue;
}
@@ -185,8 +197,8 @@ static std::vector<DbEntry> readJsonObjects(const QString &filePath)
fileName.toFileInfo().baseName());
result.push_back({flags, fileName, object["directory"].toString()});
- objectStart = contents.indexOf('{', objectEnd + 1);
- objectEnd = contents.indexOf('}', objectStart + 1);
+ objectStart = m_projectFileContents.indexOf('{', objectEnd + 1);
+ objectEnd = m_projectFileContents.indexOf('}', objectStart + 1);
}
return result;
@@ -217,7 +229,7 @@ QStringList readExtraFiles(const QString &filePath)
DbContents CompilationDbParser::parseProject()
{
DbContents dbContents;
- dbContents.entries = readJsonObjects(m_projectFilePath.toString());
+ dbContents.entries = readJsonObjects();
dbContents.extraFileName = m_projectFilePath.toString() +
Constants::COMPILATIONDATABASEPROJECT_FILES_SUFFIX;
dbContents.extras = readExtraFiles(dbContents.extraFileName);
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h
index fe3e319076..ac5fbb0afb 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h
@@ -46,6 +46,8 @@ class TreeScanner;
namespace CompilationDatabaseProjectManager {
namespace Internal {
+enum class ParseResult { Success, Failure, Cached };
+
class CompilationDbParser : public QObject
{
Q_OBJECT
@@ -57,6 +59,10 @@ public:
ProjectExplorer::Project::ParseGuard &&guard,
QObject *parent = nullptr);
+
+ void setPreviousProjectFileHash(const QByteArray &fileHash) { m_projectFileHash = fileHash; }
+ QByteArray projectFileHash() const { return m_projectFileHash; }
+
void start();
void stop();
@@ -68,11 +74,12 @@ public:
}
signals:
- void finished(bool success);
+ void finished(ParseResult result);
private:
- void finish();
+ void finish(ParseResult result);
DbContents parseProject();
+ std::vector<DbEntry> readJsonObjects() const;
const QString m_projectName;
const Utils::FilePath m_projectFilePath;
@@ -81,6 +88,8 @@ private:
ProjectExplorer::TreeScanner *m_treeScanner = nullptr;
QFutureWatcher<DbContents> m_parserWatcher;
DbContents m_dbContents;
+ QByteArray m_projectFileContents;
+ QByteArray m_projectFileHash;
ProjectExplorer::Project::ParseGuard m_guard;
};
diff --git a/src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp b/src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp
index 1f1320c403..8738d3d747 100644
--- a/src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp
+++ b/src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp
@@ -47,11 +47,9 @@ void CtfStatisticsModel::beginLoading()
m_data.clear();
}
-void CtfStatisticsModel::addEvent(const json &event, qint64 durationInNs)
+void CtfStatisticsModel::addEvent(const QString &title, qint64 durationInNs)
{
- const std::string name = event.value(CtfEventNameKey, "");
-
- EventData &data = m_data[QString::fromStdString(name)];
+ EventData &data = m_data[title];
++data.count;
if (durationInNs >= 0) {
data.totalDuration += durationInNs;
@@ -60,6 +58,11 @@ void CtfStatisticsModel::addEvent(const json &event, qint64 durationInNs)
}
}
+void CtfStatisticsModel::setMeasurementDuration(qint64 timeInNs)
+{
+ m_measurementDurationInNs = timeInNs;
+}
+
void CtfStatisticsModel::endLoading()
{
endResetModel();
@@ -89,6 +92,7 @@ QVariant CtfStatisticsModel::data(const QModelIndex &index, int role) const
return Qt::AlignLeft;
case Column::Count:
case Column::TotalDuration:
+ case Column::RelativeDuration:
case Column::MinDuration:
case Column::AvgDuration:
case Column::MaxDuration:
@@ -105,6 +109,8 @@ QVariant CtfStatisticsModel::data(const QModelIndex &index, int role) const
return m_data.value(title).count;
case Column::TotalDuration:
return m_data.value(title).totalDuration;
+ case Column::RelativeDuration:
+ return m_data.value(title).totalDuration;
case Column::MinDuration:
{
auto minDuration = m_data.value(title).minDuration;
@@ -136,6 +142,16 @@ QVariant CtfStatisticsModel::data(const QModelIndex &index, int role) const
else
return "-";
}
+ case Column::RelativeDuration:
+ {
+ auto totalDuration = m_data.value(title).totalDuration;
+ if (m_measurementDurationInNs > 0 && totalDuration > 0) {
+ const double percent = (totalDuration / double(m_measurementDurationInNs)) * 100;
+ return QString("%1 %").arg(percent, 0, 'f', 2);
+ } else {
+ return "-";
+ }
+ }
case Column::MinDuration:
{
auto minDuration = m_data.value(title).minDuration;
@@ -177,6 +193,8 @@ QVariant CtfStatisticsModel::headerData(int section, Qt::Orientation orientation
return tr("Count");
case Column::TotalDuration:
return tr("Total Time");
+ case Column::RelativeDuration:
+ return tr("Percentage");
case Column::MinDuration:
return tr("Minimum Time");
case Column::AvgDuration:
diff --git a/src/plugins/ctfvisualizer/ctfstatisticsmodel.h b/src/plugins/ctfvisualizer/ctfstatisticsmodel.h
index 10af0b8b3a..434d7c9c96 100644
--- a/src/plugins/ctfvisualizer/ctfstatisticsmodel.h
+++ b/src/plugins/ctfvisualizer/ctfstatisticsmodel.h
@@ -49,6 +49,7 @@ public:
Title = 0,
Count,
TotalDuration,
+ RelativeDuration,
MinDuration,
AvgDuration,
MaxDuration,
@@ -66,7 +67,8 @@ public:
~CtfStatisticsModel() override = default;
void beginLoading();
- void addEvent(const nlohmann::json &event, qint64 duration);
+ void addEvent(const QString &title, qint64 durationInNs);
+ void setMeasurementDuration(qint64 timeInNs);
void endLoading();
private:
@@ -77,6 +79,7 @@ private:
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
QHash<QString, EventData> m_data;
+ qint64 m_measurementDurationInNs = 0;
};
diff --git a/src/plugins/ctfvisualizer/ctftimelinemodel.cpp b/src/plugins/ctfvisualizer/ctftimelinemodel.cpp
index 4b0d6b1a61..827f919055 100644
--- a/src/plugins/ctfvisualizer/ctftimelinemodel.cpp
+++ b/src/plugins/ctfvisualizer/ctftimelinemodel.cpp
@@ -87,6 +87,14 @@ QVariantList CtfTimelineModel::labels() const
QVariantMap CtfTimelineModel::orderedDetails(int index) const
{
QMap<int, QPair<QString, QString>> info = m_details.value(index);
+ const int counterIdx = m_itemToCounterIdx.value(index, 0);
+ if (counterIdx > 0) {
+ // this item is a counter, add its properties:
+ info.insert(0, {{}, QString::fromStdString(m_counterNames.at(counterIdx - 1))});
+ info.insert(4, {tr("Value"), QString::number(double(m_counterValues.at(index)), 'g')});
+ info.insert(5, {tr("Min"), QString::number(double(m_counterData.at(counterIdx - 1).min), 'g')});
+ info.insert(6, {tr("Max"), QString::number(double(m_counterData.at(counterIdx - 1).max), 'g')});
+ }
info.insert(2, {tr("Start"), Timeline::formatTime(startTime(index))});
info.insert(3, {tr("Wall Duration"), Timeline::formatTime(duration(index))});
QVariantMap data;
@@ -209,12 +217,26 @@ void CtfTimelineModel::finalize(double traceBegin, double traceEnd, const QStrin
emit contentChanged();
}
+int CtfTimelineModel::tid() const
+{
+ return m_threadId;
+}
+
+QString CtfTimelineModel::eventTitle(int index) const
+{
+ const int counterIdx = m_itemToCounterIdx.value(index, 0);
+ if (counterIdx > 0) {
+ return QString::fromStdString(m_counterNames.at(counterIdx - 1));
+ }
+ return m_details.value(index).value(0).second;
+}
+
void CtfTimelineModel::updateName()
{
if (m_threadName.isEmpty()) {
- setDisplayName(tr("> Thread %1").arg(m_threadId));
+ setDisplayName(tr("Thread %1").arg(m_threadId));
} else {
- setDisplayName(QString("> %1 (%2)").arg(m_threadName).arg(m_threadId));
+ setDisplayName(QString("%1 (%2)").arg(m_threadName).arg(m_threadId));
}
QString process = m_processName.isEmpty() ? QString::number(m_processId) :
QString("%1 (%2)").arg(m_processName).arg(m_processId);
diff --git a/src/plugins/ctfvisualizer/ctftimelinemodel.h b/src/plugins/ctfvisualizer/ctftimelinemodel.h
index 4be3012ba4..3c80cb6ec9 100644
--- a/src/plugins/ctfvisualizer/ctftimelinemodel.h
+++ b/src/plugins/ctfvisualizer/ctftimelinemodel.h
@@ -67,6 +67,9 @@ public:
void finalize(double traceBegin, double traceEnd, const QString &processName, const QString &threadName);
+ int tid() const;
+ QString eventTitle(int index) const;
+
signals:
void detailsRequested(const QString &eventName) const;
diff --git a/src/plugins/ctfvisualizer/ctftracemanager.cpp b/src/plugins/ctfvisualizer/ctftracemanager.cpp
index 855f834128..52859e08b1 100644
--- a/src/plugins/ctfvisualizer/ctftracemanager.cpp
+++ b/src/plugins/ctfvisualizer/ctftracemanager.cpp
@@ -146,7 +146,6 @@ void CtfTraceManager::addEvent(const json &event)
if (visibleOnTimeline) {
m_traceBegin = std::min(m_traceBegin, timestamp);
m_traceEnd = std::max(m_traceEnd, timestamp);
- m_statisticsModel->addEvent(event, result.second);
} else if (m_timeOffset == timestamp) {
// this timestamp was used as the time offset but it is not a visible element
// -> reset the time offset again:
@@ -169,10 +168,9 @@ void CtfVisualizer::Internal::CtfTraceManager::load(const QString &filename)
json::parser_callback_t callback = [&ctfParser](int depth, json::parse_event_t event, json &parsed) {
return ctfParser.callback(depth, event, parsed);
};
- m_statisticsModel->beginLoading();
json unusedValues = json::parse(file, callback, /*allow_exceptions*/ false);
- m_statisticsModel->endLoading();
file.close();
+ updateStatistics();
}
void CtfTraceManager::finalize()
@@ -192,6 +190,7 @@ void CtfTraceManager::finalize()
}
}
m_threadModels.remove(tid);
+ m_threadRestrictions.remove(tid);
}
}
for (CtfTimelineModel *model: m_threadModels) {
@@ -216,27 +215,75 @@ int CtfTraceManager::getSelectionId(const std::string &name)
return *it;
}
+QList<CtfTimelineModel *> CtfTraceManager::getSortedThreads() const
+{
+ QList<CtfTimelineModel *> models = m_threadModels.values();
+ std::sort(models.begin(), models.end(), [](const CtfTimelineModel *a, const CtfTimelineModel *b) -> bool {
+ return (a->m_processId != b->m_processId) ? (a->m_processId < b->m_processId)
+ : (std::abs(a->m_threadId) < std::abs(b->m_threadId));
+ });
+ return models;
+}
+
+void CtfTraceManager::setThreadRestriction(int tid, bool restrictToThisThread)
+{
+ if (m_threadRestrictions.value(tid) == restrictToThisThread)
+ return;
+
+ m_threadRestrictions[tid] = restrictToThisThread;
+ addModelsToAggregator();
+}
+
+bool CtfTraceManager::isRestrictedTo(int tid) const
+{
+ return m_threadRestrictions.value(tid);
+}
+
void CtfTraceManager::addModelForThread(int threadId, int processId)
{
CtfTimelineModel *model = new CtfTimelineModel(m_modelAggregator, this, threadId, processId);
m_threadModels.insert(threadId, model);
+ m_threadRestrictions.insert(threadId, false);
connect(model, &CtfTimelineModel::detailsRequested, this,
&CtfTraceManager::detailsRequested);
}
void CtfTraceManager::addModelsToAggregator()
{
- QList<CtfTimelineModel *> models = m_threadModels.values();
- std::sort(models.begin(), models.end(), [](const CtfTimelineModel *a, const CtfTimelineModel *b) -> bool {
- return (a->m_processId != b->m_processId) ? (a->m_processId < b->m_processId)
- : (std::abs(a->m_threadId) < std::abs(b->m_threadId));
+ const QList<CtfTimelineModel *> models = getSortedThreads();
+
+ const bool showAll = std::none_of(m_threadRestrictions.begin(), m_threadRestrictions.end(), [](bool value) {
+ return value;
});
QVariantList modelsToAdd;
for (CtfTimelineModel *model: models) {
- modelsToAdd.append(QVariant::fromValue(model));
+ if (showAll || isRestrictedTo(model->tid()))
+ modelsToAdd.append(QVariant::fromValue(model));
}
m_modelAggregator->setModels(modelsToAdd);
+ updateStatistics();
+}
+
+void CtfTraceManager::updateStatistics()
+{
+ const bool showAll = std::none_of(m_threadRestrictions.begin(), m_threadRestrictions.end(), [](bool value) {
+ return value;
+ });
+
+ m_statisticsModel->beginLoading();
+ for (auto thread : m_threadModels) {
+ if (showAll || m_threadRestrictions[thread->tid()])
+ {
+ const int eventCount = thread->count();
+ for (int i = 0; i < eventCount; ++i) {
+ QString title = thread->eventTitle(i);
+ m_statisticsModel->addEvent(title, thread->duration(i));
+ }
+ }
+ }
+ m_statisticsModel->setMeasurementDuration(qint64((m_traceEnd - m_traceBegin) * 1000));
+ m_statisticsModel->endLoading();
}
void CtfTraceManager::clearAll()
diff --git a/src/plugins/ctfvisualizer/ctftracemanager.h b/src/plugins/ctfvisualizer/ctftracemanager.h
index 5de87eafad..adcb65c35e 100644
--- a/src/plugins/ctfvisualizer/ctftracemanager.h
+++ b/src/plugins/ctfvisualizer/ctftracemanager.h
@@ -64,6 +64,11 @@ public:
int getSelectionId(const std::string &name);
+ QList<CtfTimelineModel *> getSortedThreads() const;
+
+ void setThreadRestriction(int tid, bool restrictToThisThread);
+ bool isRestrictedTo(int tid) const;
+
signals:
void detailsRequested(const QString &title);
@@ -72,6 +77,8 @@ protected:
void addModelForThread(int threadId, int processId);
void addModelsToAggregator();
+ void updateStatistics();
+
void clearAll();
Timeline::TimelineModelAggregator *const m_modelAggregator;
@@ -81,6 +88,7 @@ protected:
QHash<qint64, QString> m_processNames;
QHash<qint64, QString> m_threadNames;
QMap<std::string, int> m_name2selectionId;
+ QHash<qint64, bool> m_threadRestrictions;
double m_traceBegin = std::numeric_limits<double>::max();
double m_traceEnd = std::numeric_limits<double>::min();
diff --git a/src/plugins/ctfvisualizer/ctfvisualizertool.cpp b/src/plugins/ctfvisualizer/ctfvisualizertool.cpp
index 96b1489978..2c7a38b7b7 100644
--- a/src/plugins/ctfvisualizer/ctfvisualizertool.cpp
+++ b/src/plugins/ctfvisualizer/ctfvisualizertool.cpp
@@ -29,6 +29,7 @@
#include "ctfstatisticsmodel.h"
#include "ctfstatisticsview.h"
+#include "ctftimelinemodel.h"
#include "ctfvisualizertraceview.h"
#include <coreplugin/actionmanager/actioncontainer.h>
@@ -36,6 +37,7 @@
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <debugger/analyzer/analyzerconstants.h>
+#include <utils/utilsicons.h>
#include <QAction>
#include <QApplication>
@@ -62,6 +64,8 @@ CtfVisualizerTool::CtfVisualizerTool()
, m_statisticsModel(new CtfStatisticsModel(this))
, m_statisticsView(nullptr)
, m_traceManager(new CtfTraceManager(this, m_modelAggregator.get(), m_statisticsModel.get()))
+ , m_restrictToThreadsButton(new QToolButton)
+ , m_restrictToThreadsMenu(new QMenu(m_restrictToThreadsButton))
{
ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);
ActionContainer *options = ActionManager::createMenu(Constants::CtfVisualizerMenuId);
@@ -78,6 +82,16 @@ CtfVisualizerTool::CtfVisualizerTool()
options->addAction(command);
m_perspective.setAboutToActivateCallback([this]() { createViews(); });
+
+ m_restrictToThreadsButton->setIcon(Utils::Icons::FILTER.icon());
+ m_restrictToThreadsButton->setToolTip(tr("Restrict to threads"));
+ m_restrictToThreadsButton->setPopupMode(QToolButton::InstantPopup);
+ m_restrictToThreadsButton->setProperty("noArrow", true);
+ m_restrictToThreadsButton->setMenu(m_restrictToThreadsMenu);
+ connect(m_restrictToThreadsMenu, &QMenu::triggered,
+ this, &CtfVisualizerTool::toggleThreadRestriction);
+
+ m_perspective.addToolBarWidget(m_restrictToThreadsButton);
}
CtfVisualizerTool::~CtfVisualizerTool() = default;
@@ -116,6 +130,24 @@ void CtfVisualizerTool::createViews()
m_perspective.setAboutToActivateCallback(Utils::Perspective::Callback());
}
+void CtfVisualizerTool::setAvailableThreads(const QList<CtfTimelineModel *> &threads)
+{
+ m_restrictToThreadsMenu->clear();
+
+ for (auto timelineModel : threads) {
+ QAction *action = m_restrictToThreadsMenu->addAction(timelineModel->displayName());
+ action->setCheckable(true);
+ action->setData(timelineModel->tid());
+ action->setChecked(m_traceManager->isRestrictedTo(timelineModel->tid()));
+ }
+}
+
+void CtfVisualizerTool::toggleThreadRestriction(QAction *action)
+{
+ const int tid = action->data().toInt();
+ m_traceManager->setThreadRestriction(tid, action->isChecked());
+}
+
Timeline::TimelineModelAggregator *CtfVisualizerTool::modelAggregator() const
{
return m_modelAggregator.get();
@@ -169,6 +201,7 @@ void CtfVisualizerTool::loadJson()
zoomControl()->setTrace(m_traceManager->traceBegin(), m_traceManager->traceEnd() + m_traceManager->traceDuration() / 20);
zoomControl()->setRange(m_traceManager->traceBegin(), m_traceManager->traceEnd() + m_traceManager->traceDuration() / 20);
}
+ setAvailableThreads(m_traceManager->getSortedThreads());
thread->deleteLater();
delete task;
delete futureInterface;
diff --git a/src/plugins/ctfvisualizer/ctfvisualizertool.h b/src/plugins/ctfvisualizer/ctfvisualizertool.h
index c5085d0f04..c1bec1def1 100644
--- a/src/plugins/ctfvisualizer/ctfvisualizertool.h
+++ b/src/plugins/ctfvisualizer/ctfvisualizertool.h
@@ -40,6 +40,7 @@ namespace Internal {
class CtfTraceManager;
class CtfStatisticsModel;
class CtfStatisticsView;
+class CtfTimelineModel;
class CtfVisualizerTraceView;
@@ -63,6 +64,9 @@ private:
void initialize();
void finalize();
+ void setAvailableThreads(const QList<CtfTimelineModel *> &threads);
+ void toggleThreadRestriction(QAction *action);
+
Utils::Perspective m_perspective{Constants::CtfVisualizerPerspectiveId,
tr("Chrome Trace Format Visualizer")};
@@ -77,6 +81,9 @@ private:
CtfStatisticsView *m_statisticsView;
const QScopedPointer<CtfTraceManager> m_traceManager;
+
+ QToolButton *const m_restrictToThreadsButton;
+ QMenu *const m_restrictToThreadsMenu;
};
} // namespace Internal
diff --git a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
index 702fe98c84..bf9d4d9a20 100644
--- a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
+++ b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
@@ -62,7 +62,7 @@ class DebuggerLanguageAspect : public ProjectConfigurationAspect
public:
DebuggerLanguageAspect() = default;
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(LayoutBuilder &builder) override;
bool value() const;
void setValue(bool val);
@@ -91,35 +91,29 @@ public:
std::function<void(bool)> m_clickCallBack;
};
-void DebuggerLanguageAspect::addToConfigurationLayout(QFormLayout *layout)
+void DebuggerLanguageAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(!m_checkBox);
- m_checkBox = new QCheckBox(m_label, layout->parentWidget());
+ m_checkBox = new QCheckBox(m_label);
m_checkBox->setChecked(m_value);
QTC_CHECK(m_clickCallBack);
connect(m_checkBox, &QAbstractButton::clicked, this, m_clickCallBack, Qt::QueuedConnection);
- auto innerLayout = new QHBoxLayout;
- innerLayout->setContentsMargins(0, 0, 0, 0);
-
connect(m_checkBox.data(), &QAbstractButton::clicked, this, [this] {
m_value = m_checkBox->isChecked() ? EnabledLanguage : DisabledLanguage;
emit changed();
});
- innerLayout->addWidget(m_checkBox);
+ builder.addItem(m_checkBox.data());
if (!m_infoLabelText.isEmpty()) {
QTC_CHECK(!m_infoLabel);
- m_infoLabel = new QLabel(m_infoLabelText, layout->parentWidget());
+ m_infoLabel = new QLabel(m_infoLabelText);
connect(m_infoLabel, &QLabel::linkActivated, [](const QString &link) {
Core::HelpManager::showHelpUrl(link);
});
- innerLayout->addWidget(m_infoLabel);
+ builder.addItem(m_infoLabel.data());
}
-
- innerLayout->addStretch();
- layout->addRow(innerLayout);
}
void DebuggerLanguageAspect::setAutoSettingsKey(const QString &settingsKey)
@@ -172,18 +166,19 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
setConfigWidgetCreator([this] {
QWidget *w = new QWidget;
- auto layout = new QFormLayout;
- layout->setContentsMargins(0, 0, 0, 0);
-
- m_cppAspect->addToConfigurationLayout(layout);
- m_qmlAspect->addToConfigurationLayout(layout);
- m_overrideStartupAspect->addToConfigurationLayout(layout);
+ LayoutBuilder builder(w);
+ m_cppAspect->addToLayout(builder);
+ builder.startNewRow();
+ m_qmlAspect->addToLayout(builder);
+ builder.startNewRow();
+ m_overrideStartupAspect->addToLayout(builder);
static const QByteArray env = qgetenv("QTC_DEBUGGER_MULTIPROCESS");
- if (env.toInt())
- m_multiProcessAspect->addToConfigurationLayout(layout);
+ if (env.toInt()) {
+ builder.startNewRow();
+ m_multiProcessAspect->addToLayout(builder);
+ }
- w->setLayout(layout);
return w;
});
diff --git a/src/plugins/debugger/procinterrupt.cpp b/src/plugins/debugger/procinterrupt.cpp
index 085747ea60..b9605e653a 100644
--- a/src/plugins/debugger/procinterrupt.cpp
+++ b/src/plugins/debugger/procinterrupt.cpp
@@ -40,10 +40,6 @@ static inline QString msgCannotInterrupt(qint64 pid, const QString &why)
}
#if defined(Q_OS_WIN)
-
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501 /* WinXP, needed for DebugBreakProcess() */
-
#include <utils/winutils.h>
#include <windows.h>
diff --git a/src/plugins/debugger/registerpostmortemaction.cpp b/src/plugins/debugger/registerpostmortemaction.cpp
index be37504a70..477b04b354 100644
--- a/src/plugins/debugger/registerpostmortemaction.cpp
+++ b/src/plugins/debugger/registerpostmortemaction.cpp
@@ -23,10 +23,6 @@
**
****************************************************************************/
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0400
-#endif
-
#include "registerpostmortemaction.h"
#include <registryaccess.h>
diff --git a/src/plugins/debugger/shared/hostutils.cpp b/src/plugins/debugger/shared/hostutils.cpp
index 5a65d5a6ea..326876fe5a 100644
--- a/src/plugins/debugger/shared/hostutils.cpp
+++ b/src/plugins/debugger/shared/hostutils.cpp
@@ -28,10 +28,6 @@
#ifdef Q_OS_WIN
#include <QTextStream>
-
-// Enable Win API of XP SP1 and later
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0502
#include <windows.h>
#include <utils/winutils.h>
#include <tlhelp32.h>
diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp
index 1c280eb490..4cbfdd2117 100644
--- a/src/plugins/genericprojectmanager/genericproject.cpp
+++ b/src/plugins/genericprojectmanager/genericproject.cpp
@@ -40,13 +40,16 @@
#include <projectexplorer/abi.h>
#include <projectexplorer/buildsteplist.h>
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/customexecutablerunconfiguration.h>
#include <projectexplorer/deploymentdata.h>
#include <projectexplorer/headerpath.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectnodes.h>
+#include <projectexplorer/selectablefilesmodel.h>
#include <projectexplorer/target.h>
+#include <projectexplorer/taskhub.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtcppkitinfo.h>
@@ -72,6 +75,12 @@ using namespace Utils;
namespace GenericProjectManager {
namespace Internal {
+enum RefreshOptions {
+ Files = 0x01,
+ Configuration = 0x02,
+ Everything = Files | Configuration
+};
+
////////////////////////////////////////////////////////////////////////////////////
//
// GenericProjectFile
@@ -81,10 +90,8 @@ namespace Internal {
class GenericProjectFile : public Core::IDocument
{
public:
- GenericProjectFile(GenericProject *parent, const FilePath &fileName,
- GenericProject::RefreshOptions options) :
- m_project(parent),
- m_options(options)
+ GenericProjectFile(GenericProject *parent, const FilePath &fileName, RefreshOptions options)
+ : m_project(parent), m_options(options)
{
setId("Generic.ProjectFile");
setMimeType(Constants::GENERICMIMETYPE);
@@ -96,19 +103,11 @@ public:
return BehaviorSilent;
}
- bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override
- {
- Q_UNUSED(errorString)
- Q_UNUSED(flag)
- if (type == TypePermissions)
- return true;
- m_project->refresh(m_options);
- return true;
- }
+ bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
private:
GenericProject *m_project = nullptr;
- GenericProject::RefreshOptions m_options;
+ RefreshOptions m_options;
};
@@ -118,17 +117,13 @@ private:
//
////////////////////////////////////////////////////////////////////////////////////
-class GenericProjectNode : public ProjectNode
+class GenericBuildSystem : public BuildSystem
{
public:
- explicit GenericProjectNode(GenericProject *project) :
- ProjectNode(project->projectDirectory()),
- m_project(project)
- {
- setDisplayName(project->projectFilePath().toFileInfo().completeBaseName());
- }
+ explicit GenericBuildSystem(Project *project);
+ ~GenericBuildSystem();
- bool supportsAction(ProjectAction action, const Node *) const override
+ bool supportsAction(Node *, ProjectAction action, const Node *) const final
{
return action == AddNewFile
|| action == AddExistingFile
@@ -137,25 +132,47 @@ public:
|| action == Rename;
}
- bool addFiles(const QStringList &filePaths, QStringList * = nullptr) override
- {
- return m_project->addFiles(filePaths);
- }
+ RemovedFilesFromProject removeFiles(Node *, const QStringList &filePaths, QStringList *) final;
+ bool renameFile(Node *, const QString &filePath, const QString &newFilePath) final;
+ bool addFiles(Node *, const QStringList &filePaths, QStringList *) final;
- RemovedFilesFromProject removeFiles(const QStringList &filePaths,
- QStringList * = nullptr) override
- {
- return m_project->removeFiles(filePaths) ? RemovedFilesFromProject::Ok
- : RemovedFilesFromProject::Error;
- }
+ GenericProject *project() const { return static_cast<GenericProject *>(BuildSystem::project()); }
- bool renameFile(const QString &filePath, const QString &newFilePath) override
- {
- return m_project->renameFile(filePath, newFilePath);
- }
+ FilePath filesFilePath() const { return ::FilePath::fromString(m_filesFileName); }
+
+ void refresh(RefreshOptions options);
+
+ bool saveRawFileList(const QStringList &rawFileList);
+ bool saveRawList(const QStringList &rawList, const QString &fileName);
+ void parse(RefreshOptions options);
+
+ QStringList processEntries(const QStringList &paths,
+ QHash<QString, QString> *map = nullptr) const;
+
+ Utils::FilePath findCommonSourceRoot();
+ void refreshCppCodeModel();
+ void updateDeploymentData();
+
+ bool setFiles(const QStringList &filePaths);
+ void removeFiles(const QStringList &filesToRemove);
private:
- GenericProject *m_project = nullptr;
+ QString m_filesFileName;
+ QString m_includesFileName;
+ QString m_configFileName;
+ QString m_cxxflagsFileName;
+ QString m_cflagsFileName;
+ QStringList m_rawFileList;
+ QStringList m_files;
+ QHash<QString, QString> m_rawListEntries;
+ QStringList m_rawProjectIncludePaths;
+ ProjectExplorer::HeaderPaths m_projectIncludePaths;
+ QStringList m_cxxflags;
+ QStringList m_cflags;
+
+ CppTools::CppProjectUpdaterInterface *m_cppCodeModelUpdater = nullptr;
+
+ Utils::FileSystemWatcher * const m_deployFileWatcher = nullptr;
};
@@ -173,12 +190,16 @@ static bool writeFile(const QString &filePath, const QString &contents)
GenericProject::GenericProject(const Utils::FilePath &fileName)
: Project(Constants::GENERICMIMETYPE, fileName)
- , m_deployFileWatcher(new FileSystemWatcher(this))
{
setId(Constants::GENERICPROJECT_ID);
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
setDisplayName(fileName.toFileInfo().completeBaseName());
+ setBuildSystemCreator([](Project *p) { return new GenericBuildSystem(p); });
+}
+GenericBuildSystem::GenericBuildSystem(Project *project)
+ : BuildSystem(project)
+{
QObject *projectUpdaterFactory = ExtensionSystem::PluginManager::getObjectByName(
"CppProjectUpdaterFactory");
if (projectUpdaterFactory) {
@@ -190,7 +211,7 @@ GenericProject::GenericProject(const Utils::FilePath &fileName)
QTC_CHECK(successFullyCreatedProjectUpdater);
}
- connect(this, &GenericProject::projectFileIsDirty, this, [this](const FilePath &p) {
+ connect(project, &Project::projectFileIsDirty, this, [this](const FilePath &p) {
if (p.endsWith(".files"))
refresh(Files);
else if (p.endsWith(".includes") || p.endsWith(".config") || p.endsWith(".cxxflags")
@@ -221,23 +242,21 @@ GenericProject::GenericProject(const Utils::FilePath &fileName)
QTC_CHECK(writeFile(m_cflagsFileName, Constants::GENERICPROJECT_CFLAGS_FILE_TEMPLATE));
}
- setExtraProjectFiles({FilePath::fromString(m_filesFileName),
- FilePath::fromString(m_includesFileName),
- FilePath::fromString(m_configFileName),
- FilePath::fromString(m_cxxflagsFileName),
- FilePath::fromString(m_cflagsFileName)});
+ project->setExtraProjectFiles({FilePath::fromString(m_filesFileName),
+ FilePath::fromString(m_includesFileName),
+ FilePath::fromString(m_configFileName),
+ FilePath::fromString(m_cxxflagsFileName),
+ FilePath::fromString(m_cflagsFileName)});
- connect(m_deployFileWatcher,
- &FileSystemWatcher::fileChanged,
- this,
- &GenericProject::updateDeploymentData);
+ connect(m_deployFileWatcher, &FileSystemWatcher::fileChanged,
+ this, &GenericBuildSystem::updateDeploymentData);
- connect(this, &Project::activeTargetChanged, this, [this] { refresh(Everything); });
+ connect(project, &Project::activeTargetChanged, this, [this] { refresh(Everything); });
- connect(this, &Project::activeBuildConfigurationChanged, this, [this] { refresh(Everything); });
+ connect(project, &Project::activeBuildConfigurationChanged, this, [this] { refresh(Everything); });
}
-GenericProject::~GenericProject()
+GenericBuildSystem::~GenericBuildSystem()
{
delete m_cppCodeModelUpdater;
}
@@ -262,14 +281,14 @@ static QStringList readLines(const QString &absoluteFileName)
return lines;
}
-bool GenericProject::saveRawFileList(const QStringList &rawFileList)
+bool GenericBuildSystem::saveRawFileList(const QStringList &rawFileList)
{
bool result = saveRawList(rawFileList, m_filesFileName);
- refresh(GenericProject::Files);
+ refresh(Files);
return result;
}
-bool GenericProject::saveRawList(const QStringList &rawList, const QString &fileName)
+bool GenericBuildSystem::saveRawList(const QStringList &rawList, const QString &fileName)
{
FileChangeBlocker changeGuard(fileName);
// Make sure we can open the file for writing
@@ -293,7 +312,7 @@ static void insertSorted(QStringList *list, const QString &value)
list->insert(pos, value);
}
-bool GenericProject::addFiles(const QStringList &filePaths)
+bool GenericBuildSystem::addFiles(Node *, const QStringList &filePaths, QStringList *)
{
QStringList newList = m_rawFileList;
@@ -322,12 +341,12 @@ bool GenericProject::addFiles(const QStringList &filePaths)
bool result = saveRawList(newList, m_filesFileName);
result &= saveRawList(m_rawProjectIncludePaths, m_includesFileName);
- refresh(GenericProject::Everything);
+ refresh(Everything);
return result;
}
-bool GenericProject::removeFiles(const QStringList &filePaths)
+RemovedFilesFromProject GenericBuildSystem::removeFiles(Node *, const QStringList &filePaths, QStringList *)
{
QStringList newList = m_rawFileList;
@@ -337,10 +356,11 @@ bool GenericProject::removeFiles(const QStringList &filePaths)
newList.removeOne(i.value());
}
- return saveRawFileList(newList);
+ return saveRawFileList(newList) ? RemovedFilesFromProject::Ok
+ : RemovedFilesFromProject::Error;
}
-bool GenericProject::setFiles(const QStringList &filePaths)
+bool GenericBuildSystem::setFiles(const QStringList &filePaths)
{
QStringList newList;
QDir baseDir(projectDirectory().toString());
@@ -351,7 +371,7 @@ bool GenericProject::setFiles(const QStringList &filePaths)
return saveRawFileList(newList);
}
-bool GenericProject::renameFile(const QString &filePath, const QString &newFilePath)
+bool GenericBuildSystem::renameFile(Node *, const QString &filePath, const QString &newFilePath)
{
QStringList newList = m_rawFileList;
@@ -376,7 +396,7 @@ static QStringList readFlags(const QString &filePath)
return QtcProcess::splitArgs(lines.first());
}
-void GenericProject::parseProject(RefreshOptions options)
+void GenericBuildSystem::parse(RefreshOptions options)
{
if (options & Files) {
m_rawListEntries.clear();
@@ -406,7 +426,7 @@ void GenericProject::parseProject(RefreshOptions options)
}
}
-FilePath GenericProject::findCommonSourceRoot()
+FilePath GenericBuildSystem::findCommonSourceRoot()
{
if (m_files.isEmpty())
return FilePath::fromFileInfo(QFileInfo(m_filesFileName).absolutePath());
@@ -426,16 +446,17 @@ FilePath GenericProject::findCommonSourceRoot()
return FilePath::fromString(QFileInfo(root).absolutePath());
}
-void GenericProject::refresh(RefreshOptions options)
+void GenericBuildSystem::refresh(RefreshOptions options)
{
- ParseGuard guard = guardParsingRun();
- parseProject(options);
+ Project::ParseGuard guard = project()->guardParsingRun();
+ parse(options);
if (options & Files) {
- auto newRoot = std::make_unique<GenericProjectNode>(this);
+ auto newRoot = std::make_unique<ProjectNode>(projectDirectory());
+ newRoot->setDisplayName(projectFilePath().toFileInfo().completeBaseName());
// find the common base directory of all source files
- Utils::FilePath baseDir = findCommonSourceRoot();
+ FilePath baseDir = findCommonSourceRoot();
for (const QString &f : qAsConst(m_files)) {
FileType fileType = FileType::Source; // ### FIXME
@@ -456,7 +477,7 @@ void GenericProject::refresh(RefreshOptions options)
FileType::Project));
newRoot->compress();
- setRootProjectNode(std::move(newRoot));
+ project()->setRootProjectNode(std::move(newRoot));
}
refreshCppCodeModel();
@@ -471,20 +492,21 @@ void GenericProject::refresh(RefreshOptions options)
* The \a map variable is an optional argument that will map the returned
* absolute paths back to their original \a entries.
*/
-QStringList GenericProject::processEntries(const QStringList &paths,
- QHash<QString, QString> *map) const
+QStringList GenericBuildSystem::processEntries(const QStringList &paths,
+ QHash<QString, QString> *map) const
{
- const BuildConfiguration *const buildConfig = activeTarget() ? activeTarget()->activeBuildConfiguration()
- : nullptr;
+ Target *target = project()->activeTarget();
+ const BuildConfiguration *const buildConfig = target ? target->activeBuildConfiguration()
+ : nullptr;
const Utils::Environment buildEnv = buildConfig ? buildConfig->environment()
: Utils::Environment::systemEnvironment();
- const Utils::MacroExpander *expander = macroExpander();
+ const Utils::MacroExpander *expander = project()->macroExpander();
if (buildConfig)
expander = buildConfig->macroExpander();
- else if (activeTarget())
- expander = activeTarget()->macroExpander();
+ else if (target)
+ expander = target->macroExpander();
const QDir projectDir(projectDirectory().toString());
@@ -512,15 +534,15 @@ QStringList GenericProject::processEntries(const QStringList &paths,
return absolutePaths;
}
-void GenericProject::refreshCppCodeModel()
+void GenericBuildSystem::refreshCppCodeModel()
{
if (!m_cppCodeModelUpdater)
return;
- QtSupport::CppKitInfo kitInfo(this);
+ QtSupport::CppKitInfo kitInfo(project());
QTC_ASSERT(kitInfo.isValid(), return);
RawProjectPart rpp;
- rpp.setDisplayName(displayName());
+ rpp.setDisplayName(project()->displayName());
rpp.setProjectFileLocation(projectFilePath().toString());
rpp.setQtVersion(kitInfo.projectPartQtVersion);
rpp.setHeaderPaths(m_projectIncludePaths);
@@ -529,15 +551,16 @@ void GenericProject::refreshCppCodeModel()
rpp.setFlagsForC({nullptr, m_cflags});
rpp.setFiles(m_files);
- m_cppCodeModelUpdater->update({this, kitInfo, activeParseEnvironment(), {rpp}});
+ m_cppCodeModelUpdater->update({project(), kitInfo, project()->activeParseEnvironment(), {rpp}});
}
-void GenericProject::updateDeploymentData()
+void GenericBuildSystem::updateDeploymentData()
{
static const QString fileName("QtCreatorDeployment.txt");
Utils::FilePath deploymentFilePath;
- if (activeTarget() && activeTarget()->activeBuildConfiguration()) {
- deploymentFilePath = activeTarget()->activeBuildConfiguration()->buildDirectory()
+ Target *target = project()->activeTarget();
+ if (target && target->activeBuildConfiguration()) {
+ deploymentFilePath = target->activeBuildConfiguration()->buildDirectory()
.pathAppended(fileName);
}
bool hasDeploymentData = QFileInfo::exists(deploymentFilePath.toString());
@@ -549,7 +572,7 @@ void GenericProject::updateDeploymentData()
DeploymentData deploymentData;
deploymentData.addFilesFromDeploymentFile(deploymentFilePath.toString(),
projectDirectory().toString());
- activeTarget()->setDeploymentData(deploymentData);
+ project()->activeTarget()->setDeploymentData(deploymentData);
if (m_deployFileWatcher->files() != QStringList(deploymentFilePath.toString())) {
m_deployFileWatcher->removeFiles(m_deployFileWatcher->files());
m_deployFileWatcher->addFile(deploymentFilePath.toString(),
@@ -558,6 +581,15 @@ void GenericProject::updateDeploymentData()
}
}
+void GenericBuildSystem::removeFiles(const QStringList &filesToRemove)
+{
+ if (removeFiles(nullptr, filesToRemove, nullptr) == RemovedFilesFromProject::Error) {
+ TaskHub::addTask(Task::Error, tr("Project files list update failed."),
+ ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM,
+ filesFilePath());
+ }
+}
+
Project::RestoreResult GenericProject::fromMap(const QVariantMap &map, QString *errorMessage)
{
const RestoreResult result = Project::fromMap(map, errorMessage);
@@ -581,7 +613,7 @@ Project::RestoreResult GenericProject::fromMap(const QVariantMap &map, QString *
t->addRunConfiguration(new CustomExecutableRunConfiguration(t));
}
- refresh(Everything);
+ static_cast<GenericBuildSystem *>(buildSystem())->refresh(Everything);
return RestoreResult::Ok;
}
@@ -590,5 +622,30 @@ ProjectExplorer::DeploymentKnowledge GenericProject::deploymentKnowledge() const
return DeploymentKnowledge::Approximative;
}
+bool GenericProjectFile::reload(QString *errorString, IDocument::ReloadFlag flag, IDocument::ChangeType type)
+{
+ Q_UNUSED(errorString)
+ Q_UNUSED(flag)
+ if (type == TypePermissions)
+ return true;
+ static_cast<GenericBuildSystem *>(m_project->buildSystem())->refresh(m_options);
+ return true;
+}
+
+void GenericProject::editFilesTriggered()
+{
+ SelectableFilesDialogEditFiles sfd(projectDirectory(),
+ files(Project::AllFiles),
+ ICore::mainWindow());
+ if (sfd.exec() == QDialog::Accepted)
+ static_cast<GenericBuildSystem *>(buildSystem())
+ ->setFiles(transform(sfd.selectedFiles(), &FilePath::toString));
+}
+
+void GenericProject::removeFilesTriggered(const QStringList &filesToRemove)
+{
+ static_cast<GenericBuildSystem *>(buildSystem())->removeFiles(filesToRemove);
+}
+
} // namespace Internal
} // namespace GenericProjectManager
diff --git a/src/plugins/genericprojectmanager/genericproject.h b/src/plugins/genericprojectmanager/genericproject.h
index 37053e0de3..f1a1763032 100644
--- a/src/plugins/genericprojectmanager/genericproject.h
+++ b/src/plugins/genericprojectmanager/genericproject.h
@@ -25,14 +25,7 @@
#pragma once
-#include <projectexplorer/headerpath.h>
#include <projectexplorer/project.h>
-#include <utils/fileutils.h>
-
-namespace CppTools {
-class CppProjectUpdaterInterface;
-}
-namespace Utils { class FileSystemWatcher; }
namespace GenericProjectManager {
namespace Internal {
@@ -43,55 +36,13 @@ class GenericProject : public ProjectExplorer::Project
public:
explicit GenericProject(const Utils::FilePath &filename);
- ~GenericProject() override;
-
- bool addFiles(const QStringList &filePaths);
- bool removeFiles(const QStringList &filePaths);
- bool setFiles(const QStringList &filePaths);
- bool renameFile(const QString &filePath, const QString &newFilePath);
-
- Utils::FilePath filesFilePath() const { return Utils::FilePath::fromString(m_filesFileName); }
-
- enum RefreshOptions {
- Files = 0x01,
- Configuration = 0x02,
- Everything = Files | Configuration
- };
-
- void refresh(RefreshOptions options);
-protected:
- RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
+ void editFilesTriggered();
+ void removeFilesTriggered(const QStringList &filesToRemove);
private:
- ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
-
- bool saveRawFileList(const QStringList &rawFileList);
- bool saveRawList(const QStringList &rawList, const QString &fileName);
- void parseProject(RefreshOptions options);
- QStringList processEntries(const QStringList &paths,
- QHash<QString, QString> *map = nullptr) const;
-
- Utils::FilePath findCommonSourceRoot();
- void refreshCppCodeModel();
- void updateDeploymentData();
-
- QString m_filesFileName;
- QString m_includesFileName;
- QString m_configFileName;
- QString m_cxxflagsFileName;
- QString m_cflagsFileName;
- QStringList m_rawFileList;
- QStringList m_files;
- QHash<QString, QString> m_rawListEntries;
- QStringList m_rawProjectIncludePaths;
- ProjectExplorer::HeaderPaths m_projectIncludePaths;
- QStringList m_cxxflags;
- QStringList m_cflags;
-
- CppTools::CppProjectUpdaterInterface *m_cppCodeModelUpdater = nullptr;
-
- Utils::FileSystemWatcher * const m_deployFileWatcher = nullptr;
+ RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
+ ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const final;
};
} // namespace Internal
diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp
index 0ffa12e2cf..b585980c3b 100644
--- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp
+++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp
@@ -70,16 +70,14 @@ public:
QAction editFilesAction{GenericProjectPlugin::tr("Edit Files..."), nullptr};
};
-static GenericProjectPluginPrivate *dd = nullptr;
-
GenericProjectPlugin::~GenericProjectPlugin()
{
- delete dd;
+ delete d;
}
bool GenericProjectPlugin::initialize(const QStringList &, QString *)
{
- dd = new GenericProjectPluginPrivate;
+ d = new GenericProjectPluginPrivate;
return true;
}
@@ -97,14 +95,8 @@ GenericProjectPluginPrivate::GenericProjectPluginPrivate()
mproject->addAction(command, PEC::G_PROJECT_FILES);
connect(&editFilesAction, &QAction::triggered, this, [] {
- auto genericProject = qobject_cast<GenericProject *>(ProjectTree::currentProject());
- if (!genericProject)
- return;
- SelectableFilesDialogEditFiles sfd(genericProject->projectDirectory(),
- genericProject->files(Project::AllFiles),
- ICore::mainWindow());
- if (sfd.exec() == QDialog::Accepted)
- genericProject->setFiles(transform(sfd.selectedFiles(), &FilePath::toString));
+ if (auto genericProject = qobject_cast<GenericProject *>(ProjectTree::currentProject()))
+ genericProject->editFilesTriggered();
});
@@ -120,10 +112,7 @@ GenericProjectPluginPrivate::GenericProjectPluginPrivate()
const QStringList filesToRemove = transform<QStringList>(
folderNode->findNodes([](const Node *node) { return node->asFileNode(); }),
[](const Node *node) { return node->filePath().toString();});
- if (!project->removeFiles(filesToRemove)) {
- TaskHub::addTask(Task::Error, tr("Project files list update failed."),
- PEC::TASK_CATEGORY_BUILDSYSTEM, project->filesFilePath());
- }
+ project->removeFilesTriggered(filesToRemove);
});
}
diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.h b/src/plugins/genericprojectmanager/genericprojectplugin.h
index 84865383cb..7158920534 100644
--- a/src/plugins/genericprojectmanager/genericprojectplugin.h
+++ b/src/plugins/genericprojectmanager/genericprojectplugin.h
@@ -41,6 +41,8 @@ public:
private:
bool initialize(const QStringList &arguments, QString *errorString) override;
void extensionsInitialized() override { }
+
+ class GenericProjectPluginPrivate *d = nullptr;
};
} // namespace Internal
diff --git a/src/plugins/ios/iosbuildconfiguration.cpp b/src/plugins/ios/iosbuildconfiguration.cpp
index 4a37779ca3..e7b4fdd03a 100644
--- a/src/plugins/ios/iosbuildconfiguration.cpp
+++ b/src/plugins/ios/iosbuildconfiguration.cpp
@@ -98,7 +98,8 @@ private:
};
IosBuildSettingsWidget::IosBuildSettingsWidget(IosBuildConfiguration *bc)
- : m_bc(bc),
+ : NamedWidget(IosBuildConfiguration::tr("iOS Settings")),
+ m_bc(bc),
m_isDevice(DeviceTypeKitAspect::deviceTypeId(bc->target()->kit())
== Constants::IOS_DEVICE_TYPE)
{
@@ -166,8 +167,6 @@ IosBuildSettingsWidget::IosBuildSettingsWidget(IosBuildConfiguration *bc)
detailsWidget->setState(Utils::DetailsWidget::NoSummary);
detailsWidget->setWidget(container);
- setDisplayName(IosBuildConfiguration::tr("iOS Settings"));
-
if (m_isDevice) {
connect(IosConfigurations::instance(), &IosConfigurations::provisioningDataChanged,
this, &IosBuildSettingsWidget::populateDevelopmentTeams);
diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp
index b49f383051..92cb1965ab 100644
--- a/src/plugins/ios/iosrunconfiguration.cpp
+++ b/src/plugins/ios/iosrunconfiguration.cpp
@@ -84,7 +84,7 @@ public:
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(ProjectExplorer::LayoutBuilder &builder) override;
IosDeviceType deviceType() const;
void setDeviceType(const IosDeviceType &deviceType);
@@ -321,14 +321,15 @@ IosDeviceTypeAspect::IosDeviceTypeAspect(IosRunConfiguration *runConfiguration)
this, &IosDeviceTypeAspect::deviceChanges);
}
-void IosDeviceTypeAspect::addToConfigurationLayout(QFormLayout *layout)
+void IosDeviceTypeAspect::addToLayout(LayoutBuilder &builder)
{
- m_deviceTypeComboBox = new QComboBox(layout->parentWidget());
+ m_deviceTypeComboBox = new QComboBox;
m_deviceTypeComboBox->setModel(&m_deviceTypeModel);
- m_deviceTypeLabel = new QLabel(IosRunConfiguration::tr("Device type:"), layout->parentWidget());
+ m_deviceTypeLabel = new QLabel(IosRunConfiguration::tr("Device type:"));
- layout->addRow(m_deviceTypeLabel, m_deviceTypeComboBox);
+ builder.addItem(m_deviceTypeLabel);
+ builder.addItem(m_deviceTypeComboBox);
updateValues();
diff --git a/src/plugins/nim/project/nimbuildsystem.cpp b/src/plugins/nim/project/nimbuildsystem.cpp
index d5d34452d4..21b87702ea 100644
--- a/src/plugins/nim/project/nimbuildsystem.cpp
+++ b/src/plugins/nim/project/nimbuildsystem.cpp
@@ -34,34 +34,6 @@
#include <QVariantMap>
-#if 0
-#include "nimbuildconfiguration.h"
-#include "nimtoolchain.h"
-
-#include "../nimconstants.h"
-
-#include <coreplugin/icontext.h>
-#include <coreplugin/progressmanager/progressmanager.h>
-#include <coreplugin/iversioncontrol.h>
-#include <coreplugin/vcsmanager.h>
-#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/kit.h>
-#include <projectexplorer/projectexplorerconstants.h>
-#include <projectexplorer/projectnodes.h>
-#include <projectexplorer/target.h>
-#include <projectexplorer/toolchain.h>
-#include <projectexplorer/kitinformation.h>
-#include <texteditor/textdocument.h>
-
-#include <utils/runextensions.h>
-
-#include <coreplugin/editormanager/editormanager.h>
-#include <coreplugin/editormanager/ieditor.h>
-
-#include <QFileInfo>
-#include <QQueue>
-#endif
-
using namespace ProjectExplorer;
using namespace Utils;
@@ -176,4 +148,40 @@ void NimBuildSystem::updateProject()
m_currentContext = {};
}
+bool NimBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
+{
+ if (node->asFileNode()) {
+ return action == ProjectAction::Rename
+ || action == ProjectAction::RemoveFile;
+ }
+ if (node->isFolderNodeType() || node->isProjectNodeType()) {
+ return action == ProjectAction::AddNewFile
+ || action == ProjectAction::RemoveFile
+ || action == ProjectAction::AddExistingFile;
+ }
+ return BuildSystem::supportsAction(context, action, node);
+}
+
+bool NimBuildSystem::addFiles(Node *, const QStringList &filePaths, QStringList *)
+{
+ return addFiles(filePaths);
+}
+
+RemovedFilesFromProject NimBuildSystem::removeFiles(Node *,
+ const QStringList &filePaths,
+ QStringList *)
+{
+ return removeFiles(filePaths) ? RemovedFilesFromProject::Ok
+ : RemovedFilesFromProject::Error;
+}
+
+bool NimBuildSystem::deleteFiles(Node *, const QStringList &)
+{
+ return true;
+}
+
+bool NimBuildSystem::renameFile(Node *, const QString &filePath, const QString &newFilePath)
+{
+ return renameFile(filePath, newFilePath);
+}
} // namespace Nim
diff --git a/src/plugins/nim/project/nimbuildsystem.h b/src/plugins/nim/project/nimbuildsystem.h
index dde498f452..b725cf4d9d 100644
--- a/src/plugins/nim/project/nimbuildsystem.h
+++ b/src/plugins/nim/project/nimbuildsystem.h
@@ -43,6 +43,18 @@ public:
bool removeFiles(const QStringList &filePaths);
bool renameFile(const QString &filePath, const QString &newFilePath);
+ bool supportsAction(ProjectExplorer::Node *,
+ ProjectExplorer::ProjectAction action,
+ const ProjectExplorer::Node *node) const override;
+ bool addFiles(ProjectExplorer::Node *node,
+ const QStringList &filePaths, QStringList *) override;
+ ProjectExplorer::RemovedFilesFromProject removeFiles(ProjectExplorer::Node *node,
+ const QStringList &filePaths,
+ QStringList *) override;
+ bool deleteFiles(ProjectExplorer::Node *, const QStringList &) override;
+ bool renameFile(ProjectExplorer::Node *,
+ const QString &filePath, const QString &newFilePath) override;
+
void setExcludedFiles(const QStringList &list); // Keep for compatibility with Qt Creator 4.10
QStringList excludedFiles(); // Make private when no longer supporting Qt Creator 4.10
diff --git a/src/plugins/nim/project/nimproject.cpp b/src/plugins/nim/project/nimproject.cpp
index 08f1019c8a..7fb17f2c36 100644
--- a/src/plugins/nim/project/nimproject.cpp
+++ b/src/plugins/nim/project/nimproject.cpp
@@ -45,7 +45,7 @@ NimProject::NimProject(const FilePath &fileName) : Project(Constants::C_NIM_MIME
// ensure debugging is enabled (Nim plugin translates nim code to C code)
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
- setBuildSystem(std::make_unique<NimBuildSystem>(this));
+ setBuildSystemCreator([](Project *p) { return new NimBuildSystem(p); });
}
Tasks NimProject::projectIssues(const Kit *k) const
diff --git a/src/plugins/nim/project/nimprojectnode.cpp b/src/plugins/nim/project/nimprojectnode.cpp
index 5232ea500c..8e2570d950 100644
--- a/src/plugins/nim/project/nimprojectnode.cpp
+++ b/src/plugins/nim/project/nimprojectnode.cpp
@@ -25,59 +25,10 @@
#include "nimprojectnode.h"
-#include "nimbuildsystem.h"
-
-#include <projectexplorer/projecttree.h>
-
-using namespace ProjectExplorer;
-using namespace Utils;
-
namespace Nim {
-NimProjectNode::NimProjectNode(const FilePath &projectFilePath)
+NimProjectNode::NimProjectNode(const Utils::FilePath &projectFilePath)
: ProjectNode(projectFilePath)
{}
-bool NimProjectNode::supportsAction(ProjectAction action, const Node *node) const
-{
- if (node->asFileNode()) {
- return action == ProjectAction::Rename
- || action == ProjectAction::RemoveFile;
- }
- if (node->isFolderNodeType() || node->isProjectNodeType()) {
- return action == ProjectAction::AddNewFile
- || action == ProjectAction::RemoveFile
- || action == ProjectAction::AddExistingFile;
- }
- return ProjectNode::supportsAction(action, node);
-}
-
-bool NimProjectNode::addFiles(const QStringList &filePaths, QStringList *)
-{
- return buildSystem()->addFiles(filePaths);
-}
-
-RemovedFilesFromProject NimProjectNode::removeFiles(const QStringList &filePaths,
- QStringList *)
-{
- return buildSystem()->removeFiles(filePaths) ? RemovedFilesFromProject::Ok
- : RemovedFilesFromProject::Error;
-}
-
-bool NimProjectNode::deleteFiles(const QStringList &)
-{
- return true;
-}
-
-bool NimProjectNode::renameFile(const QString &filePath, const QString &newFilePath)
-{
- return buildSystem()->renameFile(filePath, newFilePath);
-}
-
-NimBuildSystem *NimProjectNode::buildSystem() const
-{
- return qobject_cast<NimBuildSystem *>(
- ProjectTree::instance()->projectForNode(this)->buildSystem());
-}
-
} // namespace Nim
diff --git a/src/plugins/nim/project/nimprojectnode.h b/src/plugins/nim/project/nimprojectnode.h
index 98ea5aeff1..3eb4ac709e 100644
--- a/src/plugins/nim/project/nimprojectnode.h
+++ b/src/plugins/nim/project/nimprojectnode.h
@@ -27,26 +27,12 @@
#include <projectexplorer/projectnodes.h>
-namespace Utils { class FilePath; }
-
namespace Nim {
-class NimBuildSystem;
-
class NimProjectNode : public ProjectExplorer::ProjectNode
{
public:
NimProjectNode(const Utils::FilePath &projectFilePath);
-
- bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
- bool addFiles(const QStringList &filePaths, QStringList *) override;
- ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths,
- QStringList *) override;
- bool deleteFiles(const QStringList &) override;
- bool renameFile(const QString &filePath, const QString &newFilePath) override;
-
-private:
- NimBuildSystem *buildSystem() const;
};
}
diff --git a/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp b/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp
index 14716e4a29..49385fbaa9 100644
--- a/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp
+++ b/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp
@@ -38,9 +38,10 @@ class Payload
{
public:
Payload(const PerfProfilerFlameGraphData *parent, PerfProfilerFlameGraphModel::Data *data,
- int numSamples)
+ uint numSamples)
: m_parent(parent), m_data(data), m_numSamples(numSamples)
{}
+ ~Payload() = default;
Payload(const Payload &other) = delete;
Payload &operator=(const Payload &other) = delete;
@@ -55,12 +56,12 @@ public:
void countLostRequest();
private:
- const PerfProfilerFlameGraphData *m_parent;
- PerfProfilerFlameGraphModel::Data *m_data;
- int m_numSamples;
+ const PerfProfilerFlameGraphData *m_parent = nullptr;
+ PerfProfilerFlameGraphModel::Data *m_data = nullptr;
+ uint m_numSamples = 0;
};
-typedef PerfResourceCounter<Payload> ThreadResourceCounter;
+using ThreadResourceCounter = PerfResourceCounter<Payload>;
class ProcessResourceCounter
{
@@ -78,29 +79,41 @@ private:
ThreadResourceCounter::Container m_container;
};
-struct PerfProfilerFlameGraphData
+class PerfProfilerFlameGraphData
{
-
+public:
PerfProfilerFlameGraphData() { clear(); }
void loadEvent(const PerfEvent &event, const PerfEventType &type);
PerfProfilerFlameGraphModel::Data *pushChild(PerfProfilerFlameGraphModel::Data *parent,
int typeId, int numSamples);
void updateTraceData(const PerfEvent &event, const PerfEventType &type,
- PerfProfilerFlameGraphModel::Data *data, int numSamples);
+ PerfProfilerFlameGraphModel::Data *data, uint numSamples);
void clear();
bool isEmpty() const;
- QScopedPointer<PerfProfilerFlameGraphModel::Data> stackBottom;
- std::unordered_map<quint32, ProcessResourceCounter> resourceBlocks;
- QPointer<const PerfProfilerTraceManager> manager;
- uint resourcePeakId = 0;
+ void setManager(const PerfProfilerTraceManager *manager) { m_manager = manager; }
+ const PerfProfilerTraceManager *manager() const { return m_manager; }
+
+ PerfProfilerFlameGraphModel::Data *stackBottom() const { return m_stackBottom.data(); }
+ void swapStackBottom(QScopedPointer<PerfProfilerFlameGraphModel::Data> &stackBottom)
+ {
+ m_stackBottom.swap(stackBottom);
+ }
+
+ uint resourcePeakId() const { return m_resourcePeakId; }
+
+private:
+ QScopedPointer<PerfProfilerFlameGraphModel::Data> m_stackBottom;
+ std::unordered_map<quint32, ProcessResourceCounter> m_resourceBlocks;
+ QPointer<const PerfProfilerTraceManager> m_manager;
+ uint m_resourcePeakId = 0;
};
PerfProfilerFlameGraphModel::PerfProfilerFlameGraphModel(PerfProfilerTraceManager *manager) :
- QAbstractItemModel(manager), m_stackBottom(new Data(nullptr, -1, 0))
+ QAbstractItemModel(manager), m_stackBottom(new Data)
{
- PerfProfilerFlameGraphData *data = new PerfProfilerFlameGraphData;
+ auto *data = new PerfProfilerFlameGraphData;
manager->registerFeatures(PerfEventType::attributeFeatures(),
std::bind(&PerfProfilerFlameGraphData::loadEvent, data,
std::placeholders::_1, std::placeholders::_2),
@@ -120,10 +133,9 @@ QModelIndex PerfProfilerFlameGraphModel::index(int row, int column, const QModel
{
if (parent.isValid()) {
Data *parentData = static_cast<Data *>(parent.internalPointer());
- return createIndex(row, column, parentData->children[row]);
- } else {
- return createIndex(row, column, row >= 0 ? m_stackBottom->children[row] : nullptr);
+ return createIndex(row, column, parentData->children[row].get());
}
+ return createIndex(row, column, row >= 0 ? m_stackBottom->children[row].get() : nullptr);
}
QModelIndex PerfProfilerFlameGraphModel::parent(const QModelIndex &child) const
@@ -132,19 +144,17 @@ QModelIndex PerfProfilerFlameGraphModel::parent(const QModelIndex &child) const
Data *childData = static_cast<Data *>(child.internalPointer());
return childData->parent == m_stackBottom.data() ? QModelIndex()
: createIndex(0, 0, childData->parent);
- } else {
- return QModelIndex();
}
+ return {};
}
int PerfProfilerFlameGraphModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
Data *parentData = static_cast<Data *>(parent.internalPointer());
- return parentData->children.count();
- } else {
- return m_stackBottom->children.count();
+ return parentData->children.size();
}
+ return m_stackBottom->children.size();
}
int PerfProfilerFlameGraphModel::columnCount(const QModelIndex &parent) const
@@ -192,16 +202,19 @@ QVariant PerfProfilerFlameGraphModel::data(const QModelIndex &index, int role) c
return QVariant();
// Need to look up stuff from modelmanager
- PerfProfilerTraceManager *manager =
- static_cast<PerfProfilerTraceManager *>(QObject::parent());
+ auto *manager = qobject_cast<PerfProfilerTraceManager *>(QObject::parent());
+ QTC_ASSERT(manager, return QVariant());
const bool aggregated = manager->aggregateAddresses();
const PerfProfilerTraceManager::Symbol &symbol
= manager->symbol(aggregated ? data->typeId
: manager->symbolLocation(data->typeId));
const PerfEventType::Location &location = manager->location(data->typeId);
+ const int hexBase = 16;
+ const int addressWidth = 16;
switch (role) {
case DisplayNameRole:
- return QString::fromLatin1("0x%1").arg(location.address, 16, 16, QLatin1Char('0'));
+ return QString::fromLatin1("0x%1").arg(location.address, addressWidth, hexBase,
+ QLatin1Char('0'));
case FunctionRole:
return orUnknown(manager->string(symbol.name));
case ElfFileRole:
@@ -220,37 +233,38 @@ void PerfProfilerFlameGraphModel::initialize()
PerfProfilerFlameGraphData *offline = m_offlineData.take();
QTC_ASSERT(offline, return);
QTC_ASSERT(offline->isEmpty(), offline->clear());
- offline->manager = static_cast<PerfProfilerTraceManager *>(QObject::parent());
+ offline->setManager(qobject_cast<PerfProfilerTraceManager *>(QObject::parent()));
+ QTC_CHECK(offline->manager());
}
void PerfProfilerFlameGraphData::updateTraceData(const PerfEvent &event, const PerfEventType &type,
PerfProfilerFlameGraphModel::Data *data,
- int numSamples)
+ uint numSamples)
{
Q_UNUSED(type)
for (int i = 0, end = event.numAttributes(); i < end; ++i) {
- const PerfEventType::Attribute &attribute = manager->attribute(event.attributeId(i));
+ const PerfEventType::Attribute &attribute = m_manager->attribute(event.attributeId(i));
if (attribute.type != PerfEventType::TypeTracepoint)
continue;
const PerfProfilerTraceManager::TracePoint &tracePoint
- = manager->tracePoint(static_cast<int>(attribute.config));
+ = m_manager->tracePoint(static_cast<int>(attribute.config));
- const QByteArray &name = manager->string(tracePoint.name);
+ const QByteArray &name = m_manager->string(tracePoint.name);
if (name.startsWith(PerfProfilerTraceManager::s_resourceNamePrefix)) {
const QHash<qint32, QVariant> &traceData = event.traceData();
const auto end = traceData.end();
- const auto released = traceData.find(manager->resourceReleasedIdId());
- const auto amount = traceData.find(manager->resourceRequestedAmountId());
- const auto obtained = traceData.find(manager->resourceObtainedIdId());
- const auto moved = traceData.find(manager->resourceMovedIdId());
+ const auto released = traceData.find(m_manager->resourceReleasedIdId());
+ const auto amount = traceData.find(m_manager->resourceRequestedAmountId());
+ const auto obtained = traceData.find(m_manager->resourceObtainedIdId());
+ const auto moved = traceData.find(m_manager->resourceMovedIdId());
- auto &threadCounter = resourceBlocks[event.pid()][event.tid()];
+ auto &threadCounter = m_resourceBlocks[event.pid()][event.tid()];
Payload payload(this, data, numSamples);
if (amount != end) {
- const auto blocks = traceData.find(manager->resourceRequestedBlocksId());
+ const auto blocks = traceData.find(m_manager->resourceRequestedBlocksId());
const qint64 amountValue = amount.value().toLongLong()
* (blocks == end ? 1 : blocks.value().toLongLong());
@@ -270,32 +284,32 @@ void PerfProfilerFlameGraphData::updateTraceData(const PerfEvent &event, const P
threadCounter.move(moved.value().toULongLong(), std::move(payload));
}
- if (stackBottom->resourceUsage > stackBottom->resourcePeak)
- resourcePeakId += numSamples;
+ if (m_stackBottom->resourceUsage > m_stackBottom->resourcePeak)
+ m_resourcePeakId += numSamples;
}
}
}
void PerfProfilerFlameGraphData::clear()
{
- if (!stackBottom || !stackBottom->isEmpty())
- stackBottom.reset(new PerfProfilerFlameGraphModel::Data(nullptr, -1, 0));
- resourceBlocks.clear();
- manager.clear();
- resourcePeakId = 0;
+ if (!m_stackBottom || m_stackBottom->samples != 0)
+ m_stackBottom.reset(new PerfProfilerFlameGraphModel::Data);
+ m_resourceBlocks.clear();
+ m_manager.clear();
+ m_resourcePeakId = 0;
}
bool PerfProfilerFlameGraphData::isEmpty() const
{
- return stackBottom->isEmpty() && resourceBlocks.empty() && manager.isNull()
- && resourcePeakId == 0;
+ return m_stackBottom->samples == 0 && m_resourceBlocks.empty() && m_manager.isNull()
+ && m_resourcePeakId == 0;
}
void PerfProfilerFlameGraphData::loadEvent(const PerfEvent &event, const PerfEventType &type)
{
- const int numSamples = (event.timestamp() < 0) ? 0 : 1;
- stackBottom->samples += numSamples;
- auto data = stackBottom.data();
+ const uint numSamples = (event.timestamp() < 0) ? 0 : 1;
+ m_stackBottom->samples += numSamples;
+ auto data = m_stackBottom.data();
const QVector<int> &stack = event.frames();
for (auto it = stack.rbegin(), end = stack.rend(); it != end; ++it)
data = pushChild(data, *it, numSamples);
@@ -307,23 +321,23 @@ void PerfProfilerFlameGraphModel::finalize(PerfProfilerFlameGraphData *data)
{
beginResetModel();
- m_stackBottom.swap(data->stackBottom);
+ data->swapStackBottom(m_stackBottom);
QQueue<Data *> nodes;
nodes.enqueue(m_stackBottom.data());
while (!nodes.isEmpty()) {
Data *node = nodes.dequeue();
- if (node->lastResourceChangeId < data->resourcePeakId) {
+ if (node->lastResourceChangeId < data->resourcePeakId()) {
node->resourcePeak = node->resourceUsage;
- node->lastResourceChangeId = data->resourcePeakId;
+ node->lastResourceChangeId = data->resourcePeakId();
}
- for (Data *child : qAsConst(node->children))
- nodes.enqueue(child);
+ for (const auto &child : qAsConst(node->children))
+ nodes.enqueue(child.get());
}
endResetModel();
- QTC_CHECK(data->stackBottom->isEmpty());
+ QTC_CHECK(data->stackBottom()->samples == 0);
data->clear();
m_offlineData.reset(data);
}
@@ -338,17 +352,17 @@ void PerfProfilerFlameGraphModel::clear(PerfProfilerFlameGraphData *data)
} else {
QTC_CHECK(data == m_offlineData.data());
}
- m_stackBottom.reset(new Data(nullptr, -1, 0));
+ m_stackBottom.reset(new Data);
endResetModel();
}
PerfProfilerFlameGraphModel::Data *PerfProfilerFlameGraphData::pushChild(
PerfProfilerFlameGraphModel::Data *parent, int typeId, int numSamples)
{
- QVector<PerfProfilerFlameGraphModel::Data *> &siblings = parent->children;
+ auto &siblings = parent->children;
for (auto it = siblings.begin(), end = siblings.end(); it != end; ++it) {
- PerfProfilerFlameGraphModel::Data *child = *it;
+ PerfProfilerFlameGraphModel::Data *child = it->get();
if (child->typeId == typeId) {
child->samples += numSamples;
for (auto back = it, front = siblings.begin(); back != front;) {
@@ -362,19 +376,21 @@ PerfProfilerFlameGraphModel::Data *PerfProfilerFlameGraphData::pushChild(
}
}
- PerfProfilerFlameGraphModel::Data *child
- = new PerfProfilerFlameGraphModel::Data(parent, typeId, numSamples);
- parent->children.append(child);
- return child;
+ auto child = std::make_unique<PerfProfilerFlameGraphModel::Data>();
+ child->parent = parent;
+ child->typeId = typeId;
+ child->samples = numSamples;
+ parent->children.push_back(std::move(child));
+ return parent->children.back().get();
}
void Payload::adjust(qint64 diff)
{
for (auto allocator = m_data; allocator; allocator = allocator->parent) {
- if (allocator->lastResourceChangeId < m_parent->resourcePeakId)
+ if (allocator->lastResourceChangeId < m_parent->resourcePeakId())
allocator->resourcePeak = allocator->resourceUsage;
- allocator->lastResourceChangeId = m_parent->resourcePeakId;
+ allocator->lastResourceChangeId = m_parent->resourcePeakId();
allocator->resourceUsage += diff;
}
}
diff --git a/src/plugins/perfprofiler/perfprofilerflamegraphmodel.h b/src/plugins/perfprofiler/perfprofilerflamegraphmodel.h
index 45691fa10e..712e96a5e8 100644
--- a/src/plugins/perfprofiler/perfprofilerflamegraphmodel.h
+++ b/src/plugins/perfprofiler/perfprofilerflamegraphmodel.h
@@ -38,8 +38,12 @@ struct PerfProfilerFlameGraphData;
class PerfProfilerFlameGraphModel : public QAbstractItemModel
{
Q_OBJECT
+ Q_DISABLE_COPY(PerfProfilerFlameGraphModel);
Q_ENUMS(Role)
public:
+ PerfProfilerFlameGraphModel(PerfProfilerFlameGraphModel &&) = delete;
+ PerfProfilerFlameGraphModel &operator=(PerfProfilerFlameGraphModel &&) = delete;
+
enum Role {
TypeIdRole = Qt::UserRole + 1, // Sort by data, not by displayed string
DisplayNameRole,
@@ -59,20 +63,9 @@ public:
};
struct Data {
- Data(Data *parent = nullptr, int typeId = -1, uint samples = 1) :
- parent(parent), typeId(typeId), samples(samples)
- {}
-
- ~Data() { qDeleteAll(children); }
-
- bool isEmpty() const
- {
- return samples == 0;
- }
-
- Data *parent;
- int typeId;
- uint samples;
+ Data *parent = nullptr;
+ int typeId = -1;
+ uint samples = 0;
uint lastResourceChangeId = 0;
uint observedResourceAllocations = 0;
@@ -84,7 +77,7 @@ public:
qint64 resourceUsage = 0;
qint64 resourcePeak = 0;
- QVector<Data *> children;
+ std::vector<std::unique_ptr<Data>> children;
};
PerfProfilerFlameGraphModel(PerfProfilerTraceManager *manager);
diff --git a/src/plugins/projectexplorer/CMakeLists.txt b/src/plugins/projectexplorer/CMakeLists.txt
index aae6811779..a2ccaa1170 100644
--- a/src/plugins/projectexplorer/CMakeLists.txt
+++ b/src/plugins/projectexplorer/CMakeLists.txt
@@ -161,7 +161,6 @@ add_qtc_plugin(ProjectExplorer
sessionview.cpp sessionview.h
showineditortaskhandler.cpp showineditortaskhandler.h
showoutputtaskhandler.cpp showoutputtaskhandler.h
- subscription.cpp subscription.h
target.cpp target.h
targetsettingspanel.cpp targetsettingspanel.h
targetsetuppage.cpp targetsetuppage.h
diff --git a/src/plugins/projectexplorer/ProjectExplorer.json.in b/src/plugins/projectexplorer/ProjectExplorer.json.in
index 6b87ce64a6..d6efb13cde 100644
--- a/src/plugins/projectexplorer/ProjectExplorer.json.in
+++ b/src/plugins/projectexplorer/ProjectExplorer.json.in
@@ -22,6 +22,11 @@
\"Description\" : \"Verbose loading of custom wizards\"
},
{
+ \"Name\" : \"-ensure-kit-for-binary\",
+ \"Parameter\" : \"<file path>\",
+ \"Description\" : \"Create kit with architecture matching a given application or library\"
+ },
+ {
\"Name\" : \"-lastsession\",
\"Description\" : \"Restore the last session\"
},
diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp
index ccf333aa21..9496ec76a1 100644
--- a/src/plugins/projectexplorer/buildconfiguration.cpp
+++ b/src/plugins/projectexplorer/buildconfiguration.cpp
@@ -62,9 +62,31 @@ static const char USER_ENVIRONMENT_CHANGES_KEY[] = "ProjectExplorer.BuildConfigu
static const char BUILDDIRECTORY_KEY[] = "ProjectExplorer.BuildConfiguration.BuildDirectory";
namespace ProjectExplorer {
+namespace Internal {
+
+class BuildConfigurationPrivate
+{
+public:
+ bool m_clearSystemEnvironment = false;
+ Utils::EnvironmentItems m_userEnvironmentChanges;
+ QList<BuildStepList *> m_stepLists;
+ ProjectExplorer::BaseStringAspect *m_buildDirectoryAspect = nullptr;
+ Utils::FilePath m_lastEmittedBuildDirectory;
+ mutable Utils::Environment m_cachedEnvironment;
+ QString m_configWidgetDisplayName;
+ bool m_configWidgetHasFrame = false;
+
+ // FIXME: Remove.
+ BuildConfiguration::BuildType m_initialBuildType = BuildConfiguration::Unknown;
+ Utils::FilePath m_initialBuildDirectory;
+ QString m_initialDisplayName;
+ QVariant m_extraInfo;
+};
+
+} // Internal
BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
- : ProjectConfiguration(target, id)
+ : ProjectConfiguration(target, id), d(new Internal::BuildConfigurationPrivate)
{
QTC_CHECK(target && target == this->target());
Utils::MacroExpander *expander = macroExpander();
@@ -91,18 +113,18 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
connect(ProjectTree::instance(), &ProjectTree::currentProjectChanged,
this, &BuildConfiguration::updateCacheAndEmitEnvironmentChanged);
- m_buildDirectoryAspect = addAspect<BaseStringAspect>();
- m_buildDirectoryAspect->setSettingsKey(BUILDDIRECTORY_KEY);
- m_buildDirectoryAspect->setLabelText(tr("Build directory:"));
- m_buildDirectoryAspect->setDisplayStyle(BaseStringAspect::PathChooserDisplay);
- m_buildDirectoryAspect->setExpectedKind(Utils::PathChooser::Directory);
- m_buildDirectoryAspect->setBaseFileName(target->project()->projectDirectory());
- m_buildDirectoryAspect->setEnvironment(environment());
- connect(m_buildDirectoryAspect, &BaseStringAspect::changed,
+ d->m_buildDirectoryAspect = addAspect<BaseStringAspect>();
+ d->m_buildDirectoryAspect->setSettingsKey(BUILDDIRECTORY_KEY);
+ d->m_buildDirectoryAspect->setLabelText(tr("Build directory:"));
+ d->m_buildDirectoryAspect->setDisplayStyle(BaseStringAspect::PathChooserDisplay);
+ d->m_buildDirectoryAspect->setExpectedKind(Utils::PathChooser::Directory);
+ d->m_buildDirectoryAspect->setBaseFileName(target->project()->projectDirectory());
+ d->m_buildDirectoryAspect->setEnvironment(environment());
+ connect(d->m_buildDirectoryAspect, &BaseStringAspect::changed,
this, &BuildConfiguration::buildDirectoryChanged);
connect(this, &BuildConfiguration::environmentChanged, this, [this] {
- m_buildDirectoryAspect->setEnvironment(environment());
+ d->m_buildDirectoryAspect->setEnvironment(environment());
this->target()->buildEnvironmentChanged(this);
});
@@ -117,34 +139,38 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
});
}
+BuildConfiguration::~BuildConfiguration()
+{
+ delete d;
+}
+
Utils::FilePath BuildConfiguration::buildDirectory() const
{
- QString path = environment().expandVariables(m_buildDirectoryAspect->value().trimmed());
+ QString path = environment().expandVariables(d->m_buildDirectoryAspect->value().trimmed());
path = QDir::cleanPath(macroExpander()->expand(path));
return Utils::FilePath::fromString(QDir::cleanPath(QDir(target()->project()->projectDirectory().toString()).absoluteFilePath(path)));
}
Utils::FilePath BuildConfiguration::rawBuildDirectory() const
{
- return m_buildDirectoryAspect->filePath();
+ return d->m_buildDirectoryAspect->filePath();
}
void BuildConfiguration::setBuildDirectory(const Utils::FilePath &dir)
{
- if (dir == m_buildDirectoryAspect->filePath())
+ if (dir == d->m_buildDirectoryAspect->filePath())
return;
- m_buildDirectoryAspect->setFilePath(dir);
+ d->m_buildDirectoryAspect->setFilePath(dir);
emitBuildDirectoryChanged();
}
NamedWidget *BuildConfiguration::createConfigWidget()
{
- NamedWidget *named = new NamedWidget;
- named->setDisplayName(m_configWidgetDisplayName);
+ NamedWidget *named = new NamedWidget(d->m_configWidgetDisplayName);
QWidget *widget = nullptr;
- if (m_configWidgetHasFrame) {
+ if (d->m_configWidgetHasFrame) {
auto container = new Utils::DetailsWidget(named);
widget = new QWidget(container);
container->setState(Utils::DetailsWidget::NoSummary);
@@ -157,13 +183,12 @@ NamedWidget *BuildConfiguration::createConfigWidget()
widget = named;
}
- auto formLayout = new QFormLayout(widget);
- formLayout->setContentsMargins(0, 0, 0, 0);
- formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
-
+ LayoutBuilder builder(widget);
for (ProjectConfigurationAspect *aspect : aspects()) {
- if (aspect->isVisible())
- aspect->addToConfigurationLayout(formLayout);
+ if (aspect->isVisible()) {
+ builder.startNewRow();
+ aspect->addToLayout(builder);
+ }
}
return named;
@@ -171,8 +196,8 @@ NamedWidget *BuildConfiguration::createConfigWidget()
void BuildConfiguration::initialize()
{
- m_stepLists.append(new BuildStepList(this, Constants::BUILDSTEPS_BUILD));
- m_stepLists.append(new BuildStepList(this, Constants::BUILDSTEPS_CLEAN));
+ d->m_stepLists.append(new BuildStepList(this, Constants::BUILDSTEPS_BUILD));
+ d->m_stepLists.append(new BuildStepList(this, Constants::BUILDSTEPS_CLEAN));
}
QList<NamedWidget *> BuildConfiguration::createSubConfigWidgets()
@@ -182,36 +207,36 @@ QList<NamedWidget *> BuildConfiguration::createSubConfigWidgets()
QList<Core::Id> BuildConfiguration::knownStepLists() const
{
- return Utils::transform(m_stepLists, &BuildStepList::id);
+ return Utils::transform(d->m_stepLists, &BuildStepList::id);
}
BuildStepList *BuildConfiguration::stepList(Core::Id id) const
{
- return Utils::findOrDefault(m_stepLists, Utils::equal(&BuildStepList::id, id));
+ return Utils::findOrDefault(d->m_stepLists, Utils::equal(&BuildStepList::id, id));
}
QVariantMap BuildConfiguration::toMap() const
{
QVariantMap map(ProjectConfiguration::toMap());
- map.insert(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY), m_clearSystemEnvironment);
- map.insert(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY), Utils::EnvironmentItem::toStringList(m_userEnvironmentChanges));
+ map.insert(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY), d->m_clearSystemEnvironment);
+ map.insert(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY), Utils::EnvironmentItem::toStringList(d->m_userEnvironmentChanges));
- map.insert(QLatin1String(BUILD_STEP_LIST_COUNT), m_stepLists.count());
- for (int i = 0; i < m_stepLists.count(); ++i)
- map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QString::number(i), m_stepLists.at(i)->toMap());
+ map.insert(QLatin1String(BUILD_STEP_LIST_COUNT), d->m_stepLists.count());
+ for (int i = 0; i < d->m_stepLists.count(); ++i)
+ map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QString::number(i), d->m_stepLists.at(i)->toMap());
return map;
}
bool BuildConfiguration::fromMap(const QVariantMap &map)
{
- m_clearSystemEnvironment = map.value(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY)).toBool();
- m_userEnvironmentChanges = Utils::EnvironmentItem::fromStringList(map.value(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY)).toStringList());
+ d->m_clearSystemEnvironment = map.value(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY)).toBool();
+ d->m_userEnvironmentChanges = Utils::EnvironmentItem::fromStringList(map.value(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY)).toStringList());
updateCacheAndEmitEnvironmentChanged();
- qDeleteAll(m_stepLists);
- m_stepLists.clear();
+ qDeleteAll(d->m_stepLists);
+ d->m_stepLists.clear();
int maxI = map.value(QLatin1String(BUILD_STEP_LIST_COUNT), 0).toInt();
for (int i = 0; i < maxI; ++i) {
@@ -226,7 +251,7 @@ bool BuildConfiguration::fromMap(const QVariantMap &map)
delete list;
return false;
}
- m_stepLists.append(list);
+ d->m_stepLists.append(list);
}
// We currently assume there to be at least a clean and build list!
@@ -240,48 +265,53 @@ void BuildConfiguration::updateCacheAndEmitEnvironmentChanged()
{
Utils::Environment env = baseEnvironment();
env.modify(userEnvironmentChanges());
- if (env == m_cachedEnvironment)
+ if (env == d->m_cachedEnvironment)
return;
- m_cachedEnvironment = env;
+ d->m_cachedEnvironment = env;
emit environmentChanged(); // might trigger buildDirectoryChanged signal!
}
void BuildConfiguration::emitBuildDirectoryChanged()
{
- if (buildDirectory() != m_lastEmmitedBuildDirectory) {
- m_lastEmmitedBuildDirectory = buildDirectory();
+ if (buildDirectory() != d->m_lastEmittedBuildDirectory) {
+ d->m_lastEmittedBuildDirectory = buildDirectory();
emit buildDirectoryChanged();
}
}
QString BuildConfiguration::initialDisplayName() const
{
- return m_initialDisplayName;
+ return d->m_initialDisplayName;
+}
+
+QVariant BuildConfiguration::extraInfo() const
+{
+ return d->m_extraInfo;
}
ProjectExplorer::BaseStringAspect *BuildConfiguration::buildDirectoryAspect() const
{
- return m_buildDirectoryAspect;
+ return d->m_buildDirectoryAspect;
}
void BuildConfiguration::setConfigWidgetDisplayName(const QString &display)
{
- m_configWidgetDisplayName = display;
+ d->m_configWidgetDisplayName = display;
}
void BuildConfiguration::setBuildDirectoryHistoryCompleter(const QString &history)
{
- m_buildDirectoryAspect->setHistoryCompleter(history);
+ d->m_buildDirectoryAspect->setHistoryCompleter(history);
}
void BuildConfiguration::setConfigWidgetHasFrame(bool configWidgetHasFrame)
{
- m_configWidgetHasFrame = configWidgetHasFrame;
+ d->m_configWidgetHasFrame = configWidgetHasFrame;
}
void BuildConfiguration::setBuildDirectorySettingsKey(const QString &key)
{
- m_buildDirectoryAspect->setSettingsKey(key);
+ d->m_buildDirectoryAspect->setSettingsKey(key);
}
Utils::Environment BuildConfiguration::baseEnvironment() const
@@ -304,14 +334,14 @@ QString BuildConfiguration::baseEnvironmentText() const
Utils::Environment BuildConfiguration::environment() const
{
- return m_cachedEnvironment;
+ return d->m_cachedEnvironment;
}
void BuildConfiguration::setUseSystemEnvironment(bool b)
{
if (useSystemEnvironment() == b)
return;
- m_clearSystemEnvironment = !b;
+ d->m_clearSystemEnvironment = !b;
updateCacheAndEmitEnvironmentChanged();
}
@@ -322,19 +352,19 @@ void BuildConfiguration::addToEnvironment(Utils::Environment &env) const
bool BuildConfiguration::useSystemEnvironment() const
{
- return !m_clearSystemEnvironment;
+ return !d->m_clearSystemEnvironment;
}
Utils::EnvironmentItems BuildConfiguration::userEnvironmentChanges() const
{
- return m_userEnvironmentChanges;
+ return d->m_userEnvironmentChanges;
}
void BuildConfiguration::setUserEnvironmentChanges(const Utils::EnvironmentItems &diff)
{
- if (m_userEnvironmentChanges == diff)
+ if (d->m_userEnvironmentChanges == diff)
return;
- m_userEnvironmentChanges = diff;
+ d->m_userEnvironmentChanges = diff;
updateCacheAndEmitEnvironmentChanged();
}
@@ -358,6 +388,21 @@ bool BuildConfiguration::regenerateBuildFiles(Node *node)
return false;
}
+BuildConfiguration::BuildType BuildConfiguration::buildType() const
+{
+ return d->m_initialBuildType;
+}
+
+BuildConfiguration::BuildType BuildConfiguration::initialBuildType() const
+{
+ return d->m_initialBuildType;
+}
+
+FilePath BuildConfiguration::initialBuildDirectory() const
+{
+ return d->m_initialBuildDirectory;
+}
+
QString BuildConfiguration::buildTypeName(BuildConfiguration::BuildType type)
{
switch (type) {
@@ -511,10 +556,10 @@ BuildConfiguration *BuildConfigurationFactory::create(Target *parent, const Buil
bc->setDefaultDisplayName(info.displayName);
bc->setBuildDirectory(info.buildDirectory);
- bc->m_initialBuildType = info.buildType;
- bc->m_initialDisplayName = info.displayName;
- bc->m_initialBuildDirectory = info.buildDirectory;
- bc->m_extraInfo = info.extraInfo;
+ bc->d->m_initialBuildType = info.buildType;
+ bc->d->m_initialDisplayName = info.displayName;
+ bc->d->m_initialBuildDirectory = info.buildDirectory;
+ bc->d->m_extraInfo = info.extraInfo;
bc->initialize();
diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h
index 89cbc77f53..6160e3b6a4 100644
--- a/src/plugins/projectexplorer/buildconfiguration.h
+++ b/src/plugins/projectexplorer/buildconfiguration.h
@@ -34,6 +34,8 @@
namespace ProjectExplorer {
+namespace Internal { class BuildConfigurationPrivate; }
+
class BaseStringAspect;
class BuildInfo;
class BuildStepList;
@@ -51,6 +53,8 @@ protected:
explicit BuildConfiguration(Target *target, Core::Id id);
public:
+ ~BuildConfiguration();
+
Utils::FilePath buildDirectory() const;
Utils::FilePath rawBuildDirectory() const;
void setBuildDirectory(const Utils::FilePath &dir);
@@ -86,12 +90,12 @@ public:
Profile,
Release
};
- virtual BuildType buildType() const { return m_initialBuildType; }
+ virtual BuildType buildType() const;
- BuildType initialBuildType() const { return m_initialBuildType; } // FIXME: Remove.
- Utils::FilePath initialBuildDirectory() const { return m_initialBuildDirectory; } // FIXME: Remove.
+ BuildType initialBuildType() const; // FIXME: Remove.
+ Utils::FilePath initialBuildDirectory() const; // FIXME: Remove.
QString initialDisplayName() const; // FIXME: Remove.
- QVariant extraInfo() const { return m_extraInfo; } // FIXME: Remove.
+ QVariant extraInfo() const; // FIXME: Remove.
static QString buildTypeName(BuildType type);
@@ -117,21 +121,7 @@ protected:
private:
void emitBuildDirectoryChanged();
-
- bool m_clearSystemEnvironment = false;
- Utils::EnvironmentItems m_userEnvironmentChanges;
- QList<BuildStepList *> m_stepLists;
- ProjectExplorer::BaseStringAspect *m_buildDirectoryAspect = nullptr;
- Utils::FilePath m_lastEmmitedBuildDirectory;
- mutable Utils::Environment m_cachedEnvironment;
- QString m_configWidgetDisplayName;
- bool m_configWidgetHasFrame = false;
-
- // FIXME: Remove.
- BuildConfiguration::BuildType m_initialBuildType = BuildConfiguration::Unknown;
- Utils::FilePath m_initialBuildDirectory;
- QString m_initialDisplayName;
- QVariant m_extraInfo;
+ Internal::BuildConfigurationPrivate *d = nullptr;
};
class PROJECTEXPLORER_EXPORT BuildConfigurationFactory : public QObject
diff --git a/src/plugins/projectexplorer/buildenvironmentwidget.cpp b/src/plugins/projectexplorer/buildenvironmentwidget.cpp
index 4995d1bc50..68211385e8 100644
--- a/src/plugins/projectexplorer/buildenvironmentwidget.cpp
+++ b/src/plugins/projectexplorer/buildenvironmentwidget.cpp
@@ -33,10 +33,10 @@
#include <QVBoxLayout>
#include <QCheckBox>
-using namespace ProjectExplorer;
+namespace ProjectExplorer {
-BuildEnvironmentWidget::BuildEnvironmentWidget(BuildConfiguration *bc) :
- m_buildConfiguration(nullptr)
+BuildEnvironmentWidget::BuildEnvironmentWidget(BuildConfiguration *bc)
+ : NamedWidget(tr("Build Environment")), m_buildConfiguration(bc)
{
auto vbox = new QVBoxLayout(this);
vbox->setContentsMargins(0, 0, 0, 0);
@@ -52,8 +52,6 @@ BuildEnvironmentWidget::BuildEnvironmentWidget(BuildConfiguration *bc) :
connect(m_clearSystemEnvironmentCheckBox, &QAbstractButton::toggled,
this, &BuildEnvironmentWidget::clearSystemEnvironmentCheckBoxClicked);
- m_buildConfiguration = bc;
-
connect(m_buildConfiguration, &BuildConfiguration::environmentChanged,
this, &BuildEnvironmentWidget::environmentChanged);
@@ -61,8 +59,6 @@ BuildEnvironmentWidget::BuildEnvironmentWidget(BuildConfiguration *bc) :
m_buildEnvironmentWidget->setBaseEnvironment(m_buildConfiguration->baseEnvironment());
m_buildEnvironmentWidget->setBaseEnvironmentText(m_buildConfiguration->baseEnvironmentText());
m_buildEnvironmentWidget->setUserChanges(m_buildConfiguration->userEnvironmentChanges());
-
- setDisplayName(tr("Build Environment"));
}
void BuildEnvironmentWidget::environmentModelUserChangesChanged()
@@ -82,3 +78,5 @@ void BuildEnvironmentWidget::environmentChanged()
m_buildEnvironmentWidget->setBaseEnvironment(m_buildConfiguration->baseEnvironment());
m_buildEnvironmentWidget->setBaseEnvironmentText(m_buildConfiguration->baseEnvironmentText());
}
+
+} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
index eabce92bee..468d4751ac 100644
--- a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
@@ -143,8 +143,6 @@ void BuildSettingsWidget::addSubWidget(NamedWidget *widget)
auto label = new QLabel(this);
label->setText(widget->displayName());
- connect(widget, &NamedWidget::displayNameChanged,
- label, &QLabel::setText);
QFont f = label->font();
f.setBold(true);
f.setPointSizeF(f.pointSizeF() * 1.2);
@@ -167,11 +165,6 @@ void BuildSettingsWidget::clearWidgets()
m_labels.clear();
}
-QList<NamedWidget *> BuildSettingsWidget::subWidgets() const
-{
- return m_subWidgets;
-}
-
void BuildSettingsWidget::updateAddButtonMenu()
{
m_addButtonMenu->clear();
@@ -207,13 +200,11 @@ void BuildSettingsWidget::updateBuildSettings()
if (generalConfigWidget)
addSubWidget(generalConfigWidget);
- auto buildStepsWidget = new BuildStepListWidget(this);
- buildStepsWidget->init(m_buildConfiguration->stepList(Constants::BUILDSTEPS_BUILD));
- addSubWidget(buildStepsWidget);
+ BuildStepList *buildSteps = m_buildConfiguration->stepList(Constants::BUILDSTEPS_BUILD);
+ addSubWidget(new BuildStepListWidget(buildSteps, this));
- auto cleanStepsWidget = new BuildStepListWidget(this);
- cleanStepsWidget->init(m_buildConfiguration->stepList(Constants::BUILDSTEPS_CLEAN));
- addSubWidget(cleanStepsWidget);
+ BuildStepList *cleanSteps = m_buildConfiguration->stepList(Constants::BUILDSTEPS_CLEAN);
+ addSubWidget(new BuildStepListWidget(cleanSteps, this));
QList<NamedWidget *> subConfigWidgets = m_buildConfiguration->createSubConfigWidgets();
foreach (NamedWidget *subConfigWidget, subConfigWidgets)
diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.h b/src/plugins/projectexplorer/buildsettingspropertiespage.h
index 990b43c69c..778109d189 100644
--- a/src/plugins/projectexplorer/buildsettingspropertiespage.h
+++ b/src/plugins/projectexplorer/buildsettingspropertiespage.h
@@ -52,7 +52,6 @@ public:
void clearWidgets();
void addSubWidget(NamedWidget *widget);
- QList<NamedWidget *> subWidgets() const;
private:
void updateBuildSettings();
diff --git a/src/plugins/projectexplorer/buildstep.cpp b/src/plugins/projectexplorer/buildstep.cpp
index 38968fe514..97d1874e81 100644
--- a/src/plugins/projectexplorer/buildstep.cpp
+++ b/src/plugins/projectexplorer/buildstep.cpp
@@ -149,13 +149,14 @@ BuildStepConfigWidget *BuildStep::createConfigWidget()
{
auto widget = new BuildStepConfigWidget(this);
- auto formLayout = new QFormLayout(widget);
- formLayout->setContentsMargins(0, 0, 0, 0);
- formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
-
- for (ProjectConfigurationAspect *aspect : m_aspects) {
- if (aspect->isVisible())
- aspect->addToConfigurationLayout(formLayout);
+ {
+ LayoutBuilder builder(widget);
+ for (ProjectConfigurationAspect *aspect : m_aspects) {
+ if (aspect->isVisible()) {
+ builder.startNewRow();
+ aspect->addToLayout(builder);
+ }
+ }
}
connect(buildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
diff --git a/src/plugins/projectexplorer/buildstepspage.cpp b/src/plugins/projectexplorer/buildstepspage.cpp
index de40258b11..76fadceb68 100644
--- a/src/plugins/projectexplorer/buildstepspage.cpp
+++ b/src/plugins/projectexplorer/buildstepspage.cpp
@@ -191,9 +191,33 @@ BuildStepsWidgetData::~BuildStepsWidgetData()
// We do not own the step
}
-BuildStepListWidget::BuildStepListWidget(QWidget *parent) :
- NamedWidget(parent)
-{ }
+BuildStepListWidget::BuildStepListWidget(BuildStepList *bsl, QWidget *parent)
+ //: %1 is the name returned by BuildStepList::displayName
+ : NamedWidget(tr("%1 Steps").arg(bsl->displayName()), parent), m_buildStepList(bsl)
+{
+ setupUi();
+
+ connect(bsl, &BuildStepList::stepInserted, this, &BuildStepListWidget::addBuildStep);
+ connect(bsl, &BuildStepList::stepRemoved, this, &BuildStepListWidget::removeBuildStep);
+ connect(bsl, &BuildStepList::stepMoved, this, &BuildStepListWidget::stepMoved);
+
+ for (int i = 0; i < bsl->count(); ++i) {
+ addBuildStep(i);
+ // addBuilStep expands the config widget by default, which we don't want here
+ if (m_buildStepsData.at(i)->step->widgetExpandedByDefault()) {
+ m_buildStepsData.at(i)->detailsWidget->setState(
+ m_buildStepsData.at(i)->step->wasUserExpanded()
+ ? DetailsWidget::Expanded : DetailsWidget::Collapsed);
+ }
+ }
+
+ m_noStepsLabel->setVisible(bsl->isEmpty());
+ m_noStepsLabel->setText(tr("No %1 Steps").arg(m_buildStepList->displayName()));
+
+ m_addButton->setText(tr("Add %1 Step").arg(m_buildStepList->displayName()));
+
+ updateBuildStepButtonsState();
+}
BuildStepListWidget::~BuildStepListWidget()
{
@@ -227,52 +251,6 @@ void BuildStepListWidget::updateEnabledState()
}
}
-void BuildStepListWidget::init(BuildStepList *bsl)
-{
- Q_ASSERT(bsl);
- if (bsl == m_buildStepList)
- return;
-
- setupUi();
-
- if (m_buildStepList) {
- disconnect(m_buildStepList, &BuildStepList::stepInserted,
- this, &BuildStepListWidget::addBuildStep);
- disconnect(m_buildStepList, &BuildStepList::stepRemoved,
- this, &BuildStepListWidget::removeBuildStep);
- disconnect(m_buildStepList, &BuildStepList::stepMoved,
- this, &BuildStepListWidget::stepMoved);
- }
-
- connect(bsl, &BuildStepList::stepInserted, this, &BuildStepListWidget::addBuildStep);
- connect(bsl, &BuildStepList::stepRemoved, this, &BuildStepListWidget::removeBuildStep);
- connect(bsl, &BuildStepList::stepMoved, this, &BuildStepListWidget::stepMoved);
-
- qDeleteAll(m_buildStepsData);
- m_buildStepsData.clear();
-
- m_buildStepList = bsl;
- //: %1 is the name returned by BuildStepList::displayName
- setDisplayName(tr("%1 Steps").arg(m_buildStepList->displayName()));
-
- for (int i = 0; i < bsl->count(); ++i) {
- addBuildStep(i);
- // addBuilStep expands the config widget by default, which we don't want here
- if (m_buildStepsData.at(i)->step->widgetExpandedByDefault()) {
- m_buildStepsData.at(i)->detailsWidget->setState(
- m_buildStepsData.at(i)->step->wasUserExpanded()
- ? DetailsWidget::Expanded : DetailsWidget::Collapsed);
- }
- }
-
- m_noStepsLabel->setVisible(bsl->isEmpty());
- m_noStepsLabel->setText(tr("No %1 Steps").arg(m_buildStepList->displayName()));
-
- m_addButton->setText(tr("Add %1 Step").arg(m_buildStepList->displayName()));
-
- updateBuildStepButtonsState();
-}
-
void BuildStepListWidget::updateAddBuildStepMenu()
{
QMap<QString, QPair<Core::Id, BuildStepFactory *> > map;
diff --git a/src/plugins/projectexplorer/buildstepspage.h b/src/plugins/projectexplorer/buildstepspage.h
index 2453c9e784..7eade2d663 100644
--- a/src/plugins/projectexplorer/buildstepspage.h
+++ b/src/plugins/projectexplorer/buildstepspage.h
@@ -97,11 +97,9 @@ class BuildStepListWidget : public NamedWidget
Q_OBJECT
public:
- BuildStepListWidget(QWidget *parent = nullptr);
+ BuildStepListWidget(BuildStepList *bsl, QWidget *parent = nullptr);
~BuildStepListWidget() override;
- void init(BuildStepList *bsl);
-
private:
void updateAddBuildStepMenu();
void addBuildStep(int pos);
diff --git a/src/plugins/projectexplorer/buildsystem.cpp b/src/plugins/projectexplorer/buildsystem.cpp
index 84c9b12381..496f9cc9f4 100644
--- a/src/plugins/projectexplorer/buildsystem.cpp
+++ b/src/plugins/projectexplorer/buildsystem.cpp
@@ -54,6 +54,16 @@ Project *BuildSystem::project() const
return m_project;
}
+FilePath BuildSystem::projectFilePath() const
+{
+ return m_project->projectFilePath();
+}
+
+FilePath BuildSystem::projectDirectory() const
+{
+ return m_project->projectDirectory();
+}
+
bool BuildSystem::isWaitingForParse() const
{
return m_delayedParsingTimer.isActive();
@@ -77,7 +87,7 @@ void BuildSystem::requestParse(int delay)
void BuildSystem::triggerParsing()
{
- QTC_CHECK(!project()->isParsing());
+ QTC_ASSERT(!project()->isParsing(), return );
Project *p = project();
Target *t = p->activeTarget();
@@ -95,8 +105,56 @@ void BuildSystem::triggerParsing()
ParsingContext ctx(p->guardParsingRun(), p, bc, e, env);
+ QTC_ASSERT(ctx.guard.guardsProject(), return );
+
if (validateParsingContext(ctx))
parseProject(std::move(ctx));
}
+bool BuildSystem::addFiles(Node *, const QStringList &filePaths, QStringList *notAdded)
+{
+ Q_UNUSED(filePaths)
+ Q_UNUSED(notAdded)
+ return false;
+}
+
+RemovedFilesFromProject BuildSystem::removeFiles(Node *, const QStringList &filePaths,
+ QStringList *notRemoved)
+{
+ Q_UNUSED(filePaths)
+ Q_UNUSED(notRemoved)
+ return RemovedFilesFromProject::Error;
+}
+
+bool BuildSystem::deleteFiles(Node *, const QStringList &filePaths)
+{
+ Q_UNUSED(filePaths)
+ return false;
+}
+
+bool BuildSystem::canRenameFile(Node *, const QString &filePath, const QString &newFilePath)
+{
+ Q_UNUSED(filePath)
+ Q_UNUSED(newFilePath)
+ return true;
+}
+
+bool BuildSystem::renameFile(Node *, const QString &filePath, const QString &newFilePath)
+{
+ Q_UNUSED(filePath)
+ Q_UNUSED(newFilePath)
+ return false;
+}
+
+bool BuildSystem::addDependencies(Node *, const QStringList &dependencies)
+{
+ Q_UNUSED(dependencies)
+ return false;
+}
+
+bool BuildSystem::supportsAction(Node *, ProjectAction, const Node *) const
+{
+ return false;
+}
+
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildsystem.h b/src/plugins/projectexplorer/buildsystem.h
index dd8456074c..9bd5de6639 100644
--- a/src/plugins/projectexplorer/buildsystem.h
+++ b/src/plugins/projectexplorer/buildsystem.h
@@ -36,6 +36,7 @@ namespace ProjectExplorer {
class BuildConfiguration;
class ExtraCompiler;
+class Node;
// --------------------------------------------------------------------
// BuildSystem:
@@ -51,12 +52,23 @@ public:
BuildSystem(const BuildSystem &other) = delete;
Project *project() const;
+ Utils::FilePath projectFilePath() const;
+ Utils::FilePath projectDirectory() const;
bool isWaitingForParse() const;
void requestParse();
void requestDelayedParse();
+ virtual bool addFiles(Node *context, const QStringList &filePaths, QStringList *notAdded = nullptr);
+ virtual RemovedFilesFromProject removeFiles(Node *context, const QStringList &filePaths,
+ QStringList *notRemoved = nullptr);
+ virtual bool deleteFiles(Node *context, const QStringList &filePaths);
+ virtual bool canRenameFile(Node *context, const QString &filePath, const QString &newFilePath);
+ virtual bool renameFile(Node *context, const QString &filePath, const QString &newFilePath);
+ virtual bool addDependencies(Node *context, const QStringList &dependencies);
+ virtual bool supportsAction(Node *context, ProjectAction action, const Node *node) const;
+
protected:
class ParsingContext
{
@@ -65,8 +77,22 @@ protected:
ParsingContext(const ParsingContext &other) = delete;
ParsingContext &operator=(const ParsingContext &other) = delete;
- ParsingContext(ParsingContext &&other) = default;
- ParsingContext &operator=(ParsingContext &&other) = default;
+ ParsingContext(ParsingContext &&other)
+ : guard{std::move(other.guard)}
+ , project{std::move(other.project)}
+ , buildConfiguration{std::move(other.buildConfiguration)}
+ , expander{std::move(other.expander)}
+ , environment{std::move(other.environment)}
+ {}
+ ParsingContext &operator=(ParsingContext &&other)
+ {
+ guard = std::move(other.guard);
+ project = std::move(other.project);
+ buildConfiguration = std::move(other.buildConfiguration);
+ expander = std::move(other.expander);
+ environment = std::move(other.environment);
+ return *this;
+ }
Project::ParseGuard guard;
@@ -97,7 +123,7 @@ protected:
return true;
}
- virtual void parseProject(ParsingContext &&ctx) = 0; // actual code to parse project
+ virtual void parseProject(ParsingContext &&) {} // actual code to parse project
private:
void requestParse(int delay); // request a (delayed!) parser run.
diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
index 2f5e4463b7..e3dfd2f1a0 100644
--- a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
+++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
@@ -99,10 +99,6 @@ CustomExecutableDialog::CustomExecutableDialog(RunConfiguration *rc)
auto vbox = new QVBoxLayout(this);
vbox->addWidget(new QLabel(tr("Could not find the executable, please specify one.")));
- auto layout = new QFormLayout;
- layout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
- layout->setContentsMargins(0, 0, 0, 0);
-
auto detailsContainer = new DetailsWidget(this);
detailsContainer->setState(DetailsWidget::NoSummary);
vbox->addWidget(detailsContainer);
@@ -116,24 +112,27 @@ CustomExecutableDialog::CustomExecutableDialog(RunConfiguration *rc)
auto detailsWidget = new QWidget(detailsContainer);
detailsContainer->setWidget(detailsWidget);
- detailsWidget->setLayout(layout);
m_executableChooser = new PathChooser(this);
m_executableChooser->setHistoryCompleter("Qt.CustomExecutable.History");
m_executableChooser->setExpectedKind(PathChooser::ExistingCommand);
m_executableChooser->setPath(rc->aspect<ExecutableAspect>()->executable().toString());
- layout->addRow(tr("Executable:"), m_executableChooser);
connect(m_executableChooser, &PathChooser::rawPathChanged,
this, &CustomExecutableDialog::changed);
copyAspect(rc->aspect<ArgumentsAspect>(), &m_arguments);
- m_arguments.addToConfigurationLayout(layout);
-
copyAspect(rc->aspect<WorkingDirectoryAspect>(), &m_workingDirectory);
- m_workingDirectory.addToConfigurationLayout(layout);
-
copyAspect(rc->aspect<TerminalAspect>(), &m_terminal);
- m_terminal.addToConfigurationLayout(layout);
+
+ {
+ LayoutBuilder builder(detailsWidget);
+ builder.addItem(tr("Executable:"));
+ builder.addItem(m_executableChooser);
+ builder.startNewRow();
+ m_arguments.addToLayout(builder);
+ m_workingDirectory.addToLayout(builder);
+ m_terminal.addToLayout(builder);
+ }
auto enviromentAspect = rc->aspect<EnvironmentAspect>();
connect(enviromentAspect, &EnvironmentAspect::environmentChanged,
diff --git a/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp b/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp
index e0ac77deca..b53d8dbeb7 100644
--- a/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp
+++ b/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp
@@ -36,7 +36,6 @@
#include <QProcess>
#ifdef Q_OS_WIN
-#define _WIN32_WINNT 0x0502
#include <windows.h>
#ifndef PROCESS_SUSPEND_RESUME
#define PROCESS_SUSPEND_RESUME 0x0800
diff --git a/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp b/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp
index 24d692dd28..46249f1c24 100644
--- a/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp
+++ b/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp
@@ -40,9 +40,6 @@
#endif
#ifdef Q_OS_WIN
-// Enable Win API of XP SP1 and later
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0502
#include <windows.h>
#include <utils/winutils.h>
#include <tlhelp32.h>
diff --git a/src/plugins/projectexplorer/environmentaspect.cpp b/src/plugins/projectexplorer/environmentaspect.cpp
index 68eff43620..a3c2cb4b23 100644
--- a/src/plugins/projectexplorer/environmentaspect.cpp
+++ b/src/plugins/projectexplorer/environmentaspect.cpp
@@ -43,7 +43,7 @@ namespace ProjectExplorer {
EnvironmentAspect::EnvironmentAspect()
{
- setDisplayName(tr("Run Environment"));
+ setDisplayName(tr("Environment"));
setId("EnvironmentAspect");
setConfigWidgetCreator([this] { return new EnvironmentAspectWidget(this); });
}
@@ -74,9 +74,7 @@ void EnvironmentAspect::setUserEnvironmentChanges(const Utils::EnvironmentItems
Utils::Environment EnvironmentAspect::environment() const
{
QTC_ASSERT(m_base >= 0 && m_base < m_baseEnvironments.size(), return Environment());
- Environment env = m_baseEnvironments.at(m_base).unmodifiedBaseEnvironment();
- for (const EnvironmentModifier &modifier : m_modifiers)
- modifier(env);
+ Environment env = baseEnvironment();
env.modify(m_userChanges);
return env;
}
@@ -124,10 +122,13 @@ void EnvironmentAspect::toMap(QVariantMap &data) const
data.insert(QLatin1String(CHANGES_KEY), Utils::EnvironmentItem::toStringList(m_userChanges));
}
-Environment EnvironmentAspect::currentUnmodifiedBaseEnvironment() const
+Environment EnvironmentAspect::baseEnvironment() const
{
QTC_ASSERT(m_base >= 0 && m_base < m_baseEnvironments.size(), return Environment());
- return m_baseEnvironments.at(m_base).unmodifiedBaseEnvironment();
+ Environment env = m_baseEnvironments.at(m_base).unmodifiedBaseEnvironment();
+ for (const EnvironmentModifier &modifier : m_modifiers)
+ modifier(env);
+ return env;
}
QString EnvironmentAspect::currentDisplayName() const
diff --git a/src/plugins/projectexplorer/environmentaspect.h b/src/plugins/projectexplorer/environmentaspect.h
index ef5ed2907e..5b73f93e63 100644
--- a/src/plugins/projectexplorer/environmentaspect.h
+++ b/src/plugins/projectexplorer/environmentaspect.h
@@ -58,7 +58,7 @@ public:
const std::function<Utils::Environment()> &getter);
// The environment the user chose as base for his modifications.
- Utils::Environment currentUnmodifiedBaseEnvironment() const;
+ Utils::Environment baseEnvironment() const;
QString currentDisplayName() const;
const QStringList displayNames() const;
diff --git a/src/plugins/projectexplorer/environmentaspectwidget.cpp b/src/plugins/projectexplorer/environmentaspectwidget.cpp
index d846c1b303..d287f3b771 100644
--- a/src/plugins/projectexplorer/environmentaspectwidget.cpp
+++ b/src/plugins/projectexplorer/environmentaspectwidget.cpp
@@ -75,7 +75,7 @@ EnvironmentAspectWidget::EnvironmentAspectWidget(EnvironmentAspect *aspect, QWid
const EnvironmentWidget::Type widgetType = aspect->isLocal()
? EnvironmentWidget::TypeLocal : EnvironmentWidget::TypeRemote;
m_environmentWidget = new EnvironmentWidget(this, widgetType, baseEnvironmentWidget);
- m_environmentWidget->setBaseEnvironment(m_aspect->currentUnmodifiedBaseEnvironment());
+ m_environmentWidget->setBaseEnvironment(m_aspect->baseEnvironment());
m_environmentWidget->setBaseEnvironmentText(m_aspect->currentDisplayName());
m_environmentWidget->setUserChanges(m_aspect->userEnvironmentChanges());
m_environmentWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
@@ -106,7 +106,7 @@ void EnvironmentAspectWidget::baseEnvironmentSelected(int idx)
{
m_ignoreChange = true;
m_aspect->setBaseEnvironmentBase(idx);
- m_environmentWidget->setBaseEnvironment(m_aspect->currentUnmodifiedBaseEnvironment());
+ m_environmentWidget->setBaseEnvironment(m_aspect->baseEnvironment());
m_environmentWidget->setBaseEnvironmentText(m_aspect->currentDisplayName());
m_ignoreChange = false;
}
@@ -122,7 +122,7 @@ void EnvironmentAspectWidget::changeBaseEnvironment()
m_baseEnvironmentComboBox->setCurrentIndex(i);
}
m_environmentWidget->setBaseEnvironmentText(m_aspect->currentDisplayName());
- m_environmentWidget->setBaseEnvironment(m_aspect->currentUnmodifiedBaseEnvironment());
+ m_environmentWidget->setBaseEnvironment(m_aspect->baseEnvironment());
}
void EnvironmentAspectWidget::userChangesEdited()
@@ -143,7 +143,7 @@ void EnvironmentAspectWidget::environmentChanged()
{
if (m_ignoreChange)
return;
- m_environmentWidget->setBaseEnvironment(m_aspect->currentUnmodifiedBaseEnvironment());
+ m_environmentWidget->setBaseEnvironment(m_aspect->baseEnvironment());
}
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp
index ef88b51403..344474db0a 100644
--- a/src/plugins/projectexplorer/gccparser.cpp
+++ b/src/plugins/projectexplorer/gccparser.cpp
@@ -132,7 +132,7 @@ void GccParser::stdError(const QString &line)
match.captured(3).toInt() /* linenumber */,
Constants::TASK_CATEGORY_COMPILE));
return;
- } else if (lne.startsWith(QLatin1Char(' '))) {
+ } else if (lne.startsWith(' ') && !m_currentTask.isNull()) {
amendDescription(lne, true);
return;
}
@@ -866,6 +866,19 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
)
<< QString();
+
+ QTest::newRow("Undefined symbol (Apple ld)")
+ << "Undefined symbols for architecture x86_64:\n"
+ " \"SvgLayoutTest()\", referenced from:\n"
+ " _main in main.cpp.o"
+ << OutputParserTester::STDERR
+ << QString() << QString()
+ << Tasks({Task(Task::Error, "Undefined symbols for architecture x86_64:\n"
+ " \"SvgLayoutTest()\", referenced from:\n"
+ " _main in main.cpp.o",
+ FilePath::fromString("main.cpp.o"), -1, categoryCompile)})
+ << QString();
+
QTest::newRow("ld: undefined member function reference")
<< "obj/gtest-clang-printing.o:gtest-clang-printing.cpp:llvm::VerifyDisableABIBreakingChecks: error: undefined reference to 'llvm::DisableABIBreakingChecks'"
<< OutputParserTester::STDERR
diff --git a/src/plugins/projectexplorer/kitmanager.cpp b/src/plugins/projectexplorer/kitmanager.cpp
index c9597844af..ecb8c52ae7 100644
--- a/src/plugins/projectexplorer/kitmanager.cpp
+++ b/src/plugins/projectexplorer/kitmanager.cpp
@@ -38,6 +38,11 @@
#include <coreplugin/icore.h>
+#include <android/androidconstants.h>
+#include <baremetal/baremetalconstants.h>
+#include <qnx/qnxconstants.h>
+#include <remotelinux/remotelinux_constants.h>
+
#include <utils/environment.h>
#include <utils/persistentsettings.h>
#include <utils/pointeralgorithm.h>
@@ -114,11 +119,16 @@ public:
return m_aspectList;
}
+ void setBinaryForKit(const FilePath &fp) { m_binaryForKit = fp; }
+ FilePath binaryForKit() const { return m_binaryForKit; }
+
private:
// Sorted by priority, in descending order...
QList<KitAspect *> m_aspectList;
// ... if this here is set:
bool m_aspectListIsSorted = true;
+
+ FilePath m_binaryForKit;
};
} // namespace Internal
@@ -225,17 +235,33 @@ void KitManager::restoreKits()
// Delete all loaded autodetected kits that were not rediscovered:
kitsToCheck.clear();
- if (resultList.empty()) {
- // No kits exist yet, so let's try to autoconfigure some from the toolchains we know.
- // We consider only host toolchains, because for other ones we lack the knowledge how to
- // map them to their respective device type.
- static const auto isHostToolchain = [](const ToolChain *tc) {
- static const Abi hostAbi = Abi::hostAbi();
+ static const auto kitMatchesAbiList = [](const Kit *kit, const Abis &abis) {
+ const QList<ToolChain *> toolchains = ToolChainKitAspect::toolChains(kit);
+ for (const ToolChain * const tc : toolchains) {
const Abi tcAbi = tc->targetAbi();
- return tcAbi.os() == hostAbi.os() && tcAbi.architecture() == hostAbi.architecture()
- && (tcAbi.os() != Abi::LinuxOS || tcAbi.osFlavor() == hostAbi.osFlavor());
- };
- const QList<ToolChain *> allToolchains = ToolChainManager::toolChains(isHostToolchain);
+ for (const Abi &abi : abis) {
+ if (tcAbi.os() == abi.os() && tcAbi.architecture() == abi.architecture()
+ && (tcAbi.os() != Abi::LinuxOS || tcAbi.osFlavor() == abi.osFlavor())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ const Abis abisOfBinary = d->binaryForKit().isEmpty()
+ ? Abis() : Abi::abisOfBinary(d->binaryForKit());
+ const auto kitMatchesAbiOfBinary = [&abisOfBinary](const Kit *kit) {
+ return kitMatchesAbiList(kit, abisOfBinary);
+ };
+ const bool haveKitForBinary = abisOfBinary.isEmpty()
+ || contains(resultList, [&kitMatchesAbiOfBinary](const std::unique_ptr<Kit> &kit) {
+ return kitMatchesAbiOfBinary(kit.get());
+ });
+ Kit *kitForBinary = nullptr;
+
+ if (resultList.empty() || !haveKitForBinary) {
+ // No kits exist yet, so let's try to autoconfigure some from the toolchains we know.
QHash<Abi, QHash<Core::Id, ToolChain *>> uniqueToolchains;
// On Linux systems, we usually detect a plethora of same-ish toolchains. The following
@@ -244,7 +270,7 @@ void KitManager::restoreKits()
// TODO: This should not need to be done here. Instead, it should be a convenience
// operation on some lower level, e.g. in the toolchain class(es).
// Also, we shouldn't detect so many doublets in the first place.
- for (ToolChain * const tc : allToolchains) {
+ for (ToolChain * const tc : ToolChainManager::toolChains()) {
ToolChain *&bestTc = uniqueToolchains[tc->targetAbi()][tc->language()];
if (!bestTc) {
bestTc = tc;
@@ -269,28 +295,111 @@ void KitManager::restoreKits()
bestTc = tc;
}
- int maxWeight = 0;
+ static const auto isHostKit = [](const Kit *kit) {
+ return kitMatchesAbiList(kit, {Abi::hostAbi()});
+ };
+
+ static const auto deviceTypeForKit = [](const Kit *kit) {
+ if (isHostKit(kit))
+ return Constants::DESKTOP_DEVICE_TYPE;
+ const QList<ToolChain *> toolchains = ToolChainKitAspect::toolChains(kit);
+ for (const ToolChain * const tc : toolchains) {
+ const Abi tcAbi = tc->targetAbi();
+ switch (tcAbi.os()) {
+ case Abi::BareMetalOS:
+ return BareMetal::Constants::BareMetalOsType;
+ case Abi::BsdOS:
+ case Abi::DarwinOS:
+ case Abi::UnixOS:
+ return RemoteLinux::Constants::GenericLinuxOsType;
+ case Abi::LinuxOS:
+ if (tcAbi.osFlavor() == Abi::AndroidLinuxFlavor)
+ return Android::Constants::ANDROID_DEVICE_TYPE;
+ return RemoteLinux::Constants::GenericLinuxOsType;
+ case Abi::QnxOS:
+ return Qnx::Constants::QNX_QNX_OS_TYPE;
+ case Abi::VxWorks:
+ return "VxWorks.Device.Type";
+ default:
+ break;
+ }
+ }
+ return Constants::DESKTOP_DEVICE_TYPE;
+ };
+
+ // Create temporary kits for all toolchains found.
+ decltype(resultList) tempList;
for (auto it = uniqueToolchains.cbegin(); it != uniqueToolchains.cend(); ++it) {
auto kit = std::make_unique<Kit>();
kit->setSdkProvided(false);
kit->setAutoDetected(false); // TODO: Why false? What does autodetected mean here?
for (ToolChain * const tc : it.value())
ToolChainKitAspect::setToolChain(kit.get(), tc);
- kit->setUnexpandedDisplayName(tr("Desktop (%1)").arg(it.key().toString()));
- kit->setup();
- if (kit->weight() < maxWeight)
+ if (contains(resultList, [&kit](const std::unique_ptr<Kit> &existingKit) {
+ return ToolChainKitAspect::toolChains(kit.get())
+ == ToolChainKitAspect::toolChains(existingKit.get());
+ })) {
continue;
- if (kit->weight() > maxWeight) {
- maxWeight = kit->weight();
- resultList.clear();
}
- resultList.emplace_back(std::move(kit));
+ if (isHostKit(kit.get()))
+ kit->setUnexpandedDisplayName(tr("Desktop (%1)").arg(it.key().toString()));
+ else
+ kit->setUnexpandedDisplayName(it.key().toString());
+ DeviceTypeKitAspect::setDeviceTypeId(kit.get(), deviceTypeForKit(kit.get()));
+ kit->setup();
+ tempList.emplace_back(std::move(kit));
}
- if (resultList.size() == 1)
- resultList.front()->setUnexpandedDisplayName(tr("Desktop"));
+
+ // Now make the "best" temporary kits permanent. The logic is as follows:
+ // - If the user has requested a kit for a given binary and one or more kits
+ // with a matching ABI exist, then we randomly choose exactly one among those with
+ // the highest weight.
+ // - If the user has not requested a kit for a given binary or no such kit could
+ // be created, we choose all kits with the highest weight. If none of these
+ // is a host kit, then we also add the host kit with the highest weight.
+ Utils::sort(tempList, [](const std::unique_ptr<Kit> &k1, const std::unique_ptr<Kit> &k2) {
+ return k1->weight() > k2->weight();
+ });
+ if (!abisOfBinary.isEmpty()) {
+ for (auto it = tempList.begin(); it != tempList.end(); ++it) {
+ if (kitMatchesAbiOfBinary(it->get())) {
+ kitForBinary = it->get();
+ resultList.emplace_back(std::move(*it));
+ tempList.erase(it);
+ break;
+ }
+ }
+ }
+ QList<Kit *> hostKits;
+ if (!kitForBinary && !tempList.empty()) {
+ const int maxWeight = tempList.front()->weight();
+ for (auto it = tempList.begin(); it != tempList.end(); it = tempList.erase(it)) {
+ if ((*it)->weight() < maxWeight)
+ break;
+ if (isHostKit(it->get()))
+ hostKits << it->get();
+ resultList.emplace_back(std::move(*it));
+ }
+ if (!contains(resultList, [](const std::unique_ptr<Kit> &kit) {
+ return isHostKit(kit.get());})) {
+ QTC_ASSERT(hostKits.isEmpty(), hostKits.clear());
+ for (auto &kit : tempList) {
+ if (isHostKit(kit.get())) {
+ hostKits << kit.get();
+ resultList.emplace_back(std::move(kit));
+ break;
+ }
+ }
+ }
+ }
+
+ if (hostKits.size() == 1)
+ hostKits.first()->setUnexpandedDisplayName(tr("Desktop"));
}
- Kit *k = Utils::findOrDefault(resultList, Utils::equal(&Kit::id, defaultUserKit));
+ Kit *k = kitForBinary;
+ if (!k)
+ k = Utils::findOrDefault(resultList, Utils::equal(&Kit::id, defaultUserKit));
if (!k)
k = Utils::findOrDefault(resultList, &Kit::isValid);
std::swap(resultList, d->m_kitList);
@@ -359,6 +468,12 @@ void KitManager::deregisterKitAspect(KitAspect *ki)
d->removeKitAspect(ki);
}
+void KitManager::setBinaryForKit(const FilePath &binary)
+{
+ QTC_ASSERT(d, return);
+ d->setBinaryForKit(binary);
+}
+
QList<Kit *> KitManager::sortKits(const QList<Kit *> &kits)
{
// This method was added to delay the sorting of kits as long as possible.
diff --git a/src/plugins/projectexplorer/kitmanager.h b/src/plugins/projectexplorer/kitmanager.h
index c33c176e5c..610ee159a2 100644
--- a/src/plugins/projectexplorer/kitmanager.h
+++ b/src/plugins/projectexplorer/kitmanager.h
@@ -208,6 +208,8 @@ private:
static void registerKitAspect(KitAspect *ki);
static void deregisterKitAspect(KitAspect *ki);
+ static void setBinaryForKit(const Utils::FilePath &binary);
+
// Make sure the this is only called after all
// KitAspects are registered!
static void restoreKits();
diff --git a/src/plugins/projectexplorer/ldparser.cpp b/src/plugins/projectexplorer/ldparser.cpp
index 919c9db30b..8c00f9f424 100644
--- a/src/plugins/projectexplorer/ldparser.cpp
+++ b/src/plugins/projectexplorer/ldparser.cpp
@@ -25,7 +25,6 @@
#include "ldparser.h"
#include "projectexplorerconstants.h"
-#include "task.h"
#include <utils/qtcassert.h>
@@ -58,6 +57,9 @@ LdParser::LdParser()
void LdParser::stdError(const QString &line)
{
QString lne = rightTrimmed(line);
+ if (!lne.isEmpty() && !lne.at(0).isSpace() && !m_incompleteTask.isNull())
+ flush();
+
if (lne.startsWith(QLatin1String("TeamBuilder "))
|| lne.startsWith(QLatin1String("distcc["))
|| lne.contains(QLatin1String("ar: creating "))) {
@@ -65,6 +67,21 @@ void LdParser::stdError(const QString &line)
return;
}
+ // ld on macOS
+ if (lne.startsWith("Undefined symbols for architecture") && lne.endsWith(":")) {
+ m_incompleteTask = Task(Task::Error, lne, Utils::FilePath(), -1,
+ Constants::TASK_CATEGORY_COMPILE);
+ return;
+ }
+ if (!m_incompleteTask.isNull() && lne.startsWith(" ")) {
+ m_incompleteTask.description.append('\n').append(lne);
+ static const QRegularExpression locRegExp(" (?<symbol>\\S+) in (?<file>\\S+)");
+ const QRegularExpressionMatch match = locRegExp.match(lne);
+ if (match.hasMatch())
+ m_incompleteTask.setFile(Utils::FilePath::fromString(match.captured("file")));
+ return;
+ }
+
if (lne.startsWith("collect2:") || lne.startsWith("collect2.exe:")) {
Task task = Task(Task::Error,
lne /* description */,
@@ -134,3 +151,12 @@ void LdParser::stdError(const QString &line)
IOutputParser::stdError(line);
}
+
+void LdParser::doFlush()
+{
+ if (m_incompleteTask.isNull())
+ return;
+ const Task t = m_incompleteTask;
+ m_incompleteTask.clear();
+ emit addTask(t);
+}
diff --git a/src/plugins/projectexplorer/ldparser.h b/src/plugins/projectexplorer/ldparser.h
index ccee344d0e..bf6a441cbe 100644
--- a/src/plugins/projectexplorer/ldparser.h
+++ b/src/plugins/projectexplorer/ldparser.h
@@ -26,6 +26,7 @@
#pragma once
#include "ioutputparser.h"
+#include "task.h"
#include <QRegularExpression>
@@ -37,12 +38,15 @@ class LdParser : public ProjectExplorer::IOutputParser
public:
LdParser();
+private:
void stdError(const QString &line) override;
+ void doFlush() override;
-private:
QRegularExpression m_ranlib;
QRegularExpression m_regExpLinker;
QRegularExpression m_regExpGccNames;
+
+ Task m_incompleteTask;
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/localenvironmentaspect.cpp b/src/plugins/projectexplorer/localenvironmentaspect.cpp
index 48eac49492..92a0319e1f 100644
--- a/src/plugins/projectexplorer/localenvironmentaspect.cpp
+++ b/src/plugins/projectexplorer/localenvironmentaspect.cpp
@@ -34,7 +34,7 @@ using namespace Utils;
namespace ProjectExplorer {
-LocalEnvironmentAspect::LocalEnvironmentAspect(Target *target)
+LocalEnvironmentAspect::LocalEnvironmentAspect(Target *target, bool includeBuildEnvironment)
{
setIsLocal(true);
addSupportedBaseEnvironment(tr("Clean Environment"), {});
@@ -43,21 +43,27 @@ LocalEnvironmentAspect::LocalEnvironmentAspect(Target *target)
return Environment::systemEnvironment();
});
- addPreferredBaseEnvironment(tr("Build Environment"), [target] {
- Environment env;
- if (BuildConfiguration *bc = target->activeBuildConfiguration()) {
- env = bc->environment();
- } else { // Fallback for targets without buildconfigurations:
- env = Environment::systemEnvironment();
- target->kit()->addToEnvironment(env);
- }
- return env;
- });
+ if (includeBuildEnvironment) {
+ addPreferredBaseEnvironment(tr("Build Environment"), [target] {
+ Environment env;
+ if (BuildConfiguration *bc = target->activeBuildConfiguration()) {
+ env = bc->environment();
+ } else { // Fallback for targets without buildconfigurations:
+ env = Environment::systemEnvironment();
+ target->kit()->addToEnvironment(env);
+ }
+ return env;
+ });
- connect(target, &Target::activeBuildConfigurationChanged,
- this, &EnvironmentAspect::environmentChanged);
- connect(target, &Target::buildEnvironmentChanged,
- this, &EnvironmentAspect::environmentChanged);
+ connect(target,
+ &Target::activeBuildConfigurationChanged,
+ this,
+ &EnvironmentAspect::environmentChanged);
+ connect(target,
+ &Target::buildEnvironmentChanged,
+ this,
+ &EnvironmentAspect::environmentChanged);
+ }
}
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/localenvironmentaspect.h b/src/plugins/projectexplorer/localenvironmentaspect.h
index b1e4d5fd55..e00f4252c6 100644
--- a/src/plugins/projectexplorer/localenvironmentaspect.h
+++ b/src/plugins/projectexplorer/localenvironmentaspect.h
@@ -34,7 +34,7 @@ class PROJECTEXPLORER_EXPORT LocalEnvironmentAspect : public EnvironmentAspect
Q_OBJECT
public:
- explicit LocalEnvironmentAspect(Target *parent);
+ explicit LocalEnvironmentAspect(Target *parent, bool includeBuildEnvironment = true);
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/namedwidget.cpp b/src/plugins/projectexplorer/namedwidget.cpp
index f3a0e4beb4..9aed84c73a 100644
--- a/src/plugins/projectexplorer/namedwidget.cpp
+++ b/src/plugins/projectexplorer/namedwidget.cpp
@@ -25,24 +25,16 @@
#include "namedwidget.h"
-using namespace ProjectExplorer;
+namespace ProjectExplorer {
-///
-// NamedWidget
-///
-
-NamedWidget::NamedWidget(QWidget *parent) : QWidget(parent)
-{ }
+NamedWidget::NamedWidget(const QString &displayName, QWidget *parent)
+ : QWidget(parent), m_displayName(displayName)
+{
+}
QString NamedWidget::displayName() const
{
return m_displayName;
}
-void NamedWidget::setDisplayName(const QString &displayName)
-{
- if (m_displayName == displayName)
- return;
- m_displayName = displayName;
- emit displayNameChanged(m_displayName);
-}
+} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/namedwidget.h b/src/plugins/projectexplorer/namedwidget.h
index 870941c73b..b1e80111e2 100644
--- a/src/plugins/projectexplorer/namedwidget.h
+++ b/src/plugins/projectexplorer/namedwidget.h
@@ -33,16 +33,10 @@ namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT NamedWidget : public QWidget
{
- Q_OBJECT
-
public:
- explicit NamedWidget(QWidget *parent = nullptr);
+ explicit NamedWidget(const QString &displayName, QWidget *parent = nullptr);
QString displayName() const;
- void setDisplayName(const QString &displayName);
-
-signals:
- void displayNameChanged(const QString &);
private:
QString m_displayName;
diff --git a/src/plugins/projectexplorer/processparameters.cpp b/src/plugins/projectexplorer/processparameters.cpp
index d8b91e49b9..6d7c78b22a 100644
--- a/src/plugins/projectexplorer/processparameters.cpp
+++ b/src/plugins/projectexplorer/processparameters.cpp
@@ -28,6 +28,7 @@
#include <utils/fileutils.h>
#include <utils/macroexpander.h>
#include <utils/qtcprocess.h>
+#include <utils/theme/theme.h>
#include <QDir>
@@ -169,8 +170,19 @@ QString ProcessParameters::prettyArguments() const
return args.toString();
}
+static QString invalidCommandMessage(const QString &displayName)
+{
+ return QString("<b>%1:</b> <font color='%3'>%2</font>")
+ .arg(displayName,
+ QtcProcess::tr("Invalid command"),
+ creatorTheme()->color(Theme::TextColorError).name());
+}
+
QString ProcessParameters::summary(const QString &displayName) const
{
+ if (m_commandMissing)
+ return invalidCommandMessage(displayName);
+
return QString::fromLatin1("<b>%1:</b> %2 %3")
.arg(displayName,
Utils::QtcProcess::quoteArg(prettyCommand()),
@@ -179,6 +191,9 @@ QString ProcessParameters::summary(const QString &displayName) const
QString ProcessParameters::summaryInWorkdir(const QString &displayName) const
{
+ if (m_commandMissing)
+ return invalidCommandMessage(displayName);
+
return QString::fromLatin1("<b>%1:</b> %2 %3 in %4")
.arg(displayName,
Utils::QtcProcess::quoteArg(prettyCommand()),
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index 9735203427..2e75cd3caf 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -888,10 +888,9 @@ Utils::Environment Project::activeParseEnvironment() const
return result;
}
-void Project::setBuildSystem(std::unique_ptr<BuildSystem> &&bs)
+void Project::setBuildSystemCreator(const std::function<BuildSystem *(Project *)> &creator)
{
- QTC_ASSERT(!bs->parent(), bs->setParent(nullptr));
- d->m_buildSystem = std::move(bs);
+ d->m_buildSystem.reset(creator(this));
}
Core::Context Project::projectContext() const
diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index 9c4f38fecb..326763bf8c 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -29,7 +29,6 @@
#include "deploymentdata.h"
#include "kit.h"
-#include "subscription.h"
#include <coreplugin/id.h>
#include <coreplugin/idocument.h>
@@ -54,7 +53,6 @@ class BuildSystem;
class ContainerNode;
class EditorConfiguration;
class FolderNode;
-class NamedWidget;
class Node;
class ProjectConfiguration;
class ProjectImporter;
@@ -164,24 +162,6 @@ public:
ProjectNode *findNodeForBuildKey(const QString &buildKey) const;
- template<typename S, typename R, typename T, typename ...Args1, typename ...Args2>
- void subscribeSignal(void (S::*sig)(Args1...), R*recv, T (R::*sl)(Args2...)) {
- new Internal::ProjectSubscription([sig, recv, sl, this](ProjectConfiguration *pc) {
- if (S* sender = qobject_cast<S*>(pc))
- return connect(sender, sig, recv, sl);
- return QMetaObject::Connection();
- }, recv, this);
- }
-
- template<typename S, typename R, typename T, typename ...Args1>
- void subscribeSignal(void (S::*sig)(Args1...), R*recv, T sl) {
- new Internal::ProjectSubscription([sig, recv, sl, this](ProjectConfiguration *pc) {
- if (S* sender = qobject_cast<S*>(pc))
- return connect(sender, sig, recv, sl);
- return QMetaObject::Connection();
- }, recv, this);
- }
-
bool needsInitialExpansion() const;
void setNeedsInitialExpansion(bool needsInitialExpansion);
@@ -192,27 +172,29 @@ public:
: ParseGuard(nullptr)
{}
- ~ParseGuard()
- {
- if (m_project)
- m_project->emitParsingFinished(m_success);
- }
+ ~ParseGuard() { release(); }
void markAsSuccess() const { m_success = true; }
bool isSuccess() const { return m_success; }
- bool isNull() const { return !m_project; }
+ bool guardsProject() const { return m_project; }
ParseGuard(const ParseGuard &other) = delete;
ParseGuard &operator=(const ParseGuard &other) = delete;
ParseGuard(ParseGuard &&other)
+ : m_project{std::move(other.m_project)}
+ , m_success{std::move(other.m_success)}
{
- std::swap(m_project, other.m_project);
- std::swap(m_success, other.m_success);
+ // No need to release this as this is invalid anyway:-)
+ other.m_project = nullptr;
}
ParseGuard &operator=(ParseGuard &&other)
{
- std::swap(m_project, other.m_project);
- std::swap(m_success, other.m_success);
+ release();
+
+ m_project = std::move(other.m_project);
+ m_success = std::move(other.m_success);
+
+ other.m_project = nullptr;
return *this;
}
@@ -220,8 +202,17 @@ public:
ParseGuard(Project *p)
: m_project(p)
{
- if (m_project)
+ if (m_project && !m_project->isParsing())
m_project->emitParsingStarted();
+ else
+ m_project = nullptr;
+ }
+
+ void release()
+ {
+ if (m_project)
+ m_project->emitParsingFinished(m_success);
+ m_project = nullptr;
}
Project *m_project = nullptr;
@@ -299,7 +290,7 @@ protected:
static ProjectExplorer::Task createProjectTask(ProjectExplorer::Task::TaskType type,
const QString &description);
- void setBuildSystem(std::unique_ptr<BuildSystem> &&bs); // takes ownership!
+ void setBuildSystemCreator(const std::function<BuildSystem *(Project *)> &creator);
private:
// Helper methods to manage parsing state and signalling
diff --git a/src/plugins/projectexplorer/projectconfiguration.cpp b/src/plugins/projectexplorer/projectconfiguration.cpp
index 5ad0299034..442438fc3d 100644
--- a/src/plugins/projectexplorer/projectconfiguration.cpp
+++ b/src/plugins/projectexplorer/projectconfiguration.cpp
@@ -29,6 +29,9 @@
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
+#include <QFormLayout>
+#include <QWidget>
+
using namespace ProjectExplorer;
const char CONFIGURATION_ID_KEY[] = "ProjectExplorer.ProjectConfiguration.Id";
@@ -51,6 +54,92 @@ QWidget *ProjectConfigurationAspect::createConfigWidget() const
return m_configWidgetCreator ? m_configWidgetCreator() : nullptr;
}
+void ProjectConfigurationAspect::addToLayout(LayoutBuilder &)
+{
+}
+
+// LayoutBuilder
+
+LayoutBuilder::LayoutBuilder(QWidget *parent)
+ : m_layout(new QFormLayout(parent))
+{
+ m_layout->setContentsMargins(0, 0, 0, 0);
+ if (auto fl = qobject_cast<QFormLayout *>(m_layout))
+ fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
+}
+
+LayoutBuilder::~LayoutBuilder()
+{
+ flushPendingItems();
+}
+
+void LayoutBuilder::startNewRow()
+{
+ flushPendingItems();
+}
+
+void LayoutBuilder::flushPendingItems()
+{
+ if (m_pendingItems.isEmpty())
+ return;
+
+ if (auto fl = qobject_cast<QFormLayout *>(m_layout)) {
+ // If there are more than two items, we cram the last ones in one hbox.
+ if (m_pendingItems.size() > 2) {
+ auto hbox = new QHBoxLayout;
+ for (int i = 1; i < m_pendingItems.size(); ++i) {
+ if (QWidget *w = m_pendingItems.at(i).widget)
+ hbox->addWidget(w);
+ else if (QLayout *l = m_pendingItems.at(i).layout)
+ hbox->addItem(l);
+ else
+ QTC_CHECK(false);
+ }
+ while (m_pendingItems.size() >= 2)
+ m_pendingItems.takeLast();
+ m_pendingItems.append(LayoutItem(hbox));
+ }
+
+ if (m_pendingItems.size() == 1) { // One one item given, so this spans both columns.
+ if (auto layout = m_pendingItems.at(0).layout)
+ fl->addRow(layout);
+ else if (auto widget = m_pendingItems.at(0).widget)
+ fl->addRow(widget);
+ } else if (m_pendingItems.size() == 2) { // Normal case, both columns used.
+ if (auto label = m_pendingItems.at(0).widget) {
+ if (auto layout = m_pendingItems.at(1).layout)
+ fl->addRow(label, layout);
+ else if (auto widget = m_pendingItems.at(1).widget)
+ fl->addRow(label, widget);
+ } else {
+ if (auto layout = m_pendingItems.at(1).layout)
+ fl->addRow(m_pendingItems.at(0).text, layout);
+ else if (auto widget = m_pendingItems.at(1).widget)
+ fl->addRow(m_pendingItems.at(0).text, widget);
+ }
+ } else {
+ QTC_CHECK(false);
+ }
+ } else {
+ QTC_CHECK(false);
+ }
+
+ m_pendingItems.clear();
+}
+
+QLayout *LayoutBuilder::layout() const
+{
+ return m_layout;
+}
+
+void LayoutBuilder::addItem(LayoutItem item)
+{
+ if (item.widget && !item.widget->parent())
+ item.widget->setParent(m_layout->parentWidget());
+
+ m_pendingItems.append(item);
+}
+
// ProjectConfigurationAspects
diff --git a/src/plugins/projectexplorer/projectconfiguration.h b/src/plugins/projectexplorer/projectconfiguration.h
index 4f7a219455..76b3080291 100644
--- a/src/plugins/projectexplorer/projectconfiguration.h
+++ b/src/plugins/projectexplorer/projectconfiguration.h
@@ -32,12 +32,10 @@
#include <utils/macroexpander.h>
#include <QObject>
+#include <QPointer>
#include <QString>
#include <QVariantMap>
-
-QT_BEGIN_NAMESPACE
-class QFormLayout;
-QT_END_NAMESPACE
+#include <QWidget>
namespace ProjectExplorer {
@@ -45,6 +43,36 @@ class Project;
class ProjectConfigurationAspects;
class Target;
+class PROJECTEXPLORER_EXPORT LayoutBuilder
+{
+public:
+ explicit LayoutBuilder(QWidget *parent);
+ ~LayoutBuilder();
+
+ class LayoutItem
+ {
+ public:
+ LayoutItem(QLayout *layout) : layout(layout) {}
+ LayoutItem(QWidget *widget) : widget(widget) {}
+ LayoutItem(const QString &text) : text(text) {}
+
+ QLayout *layout = nullptr;
+ QWidget *widget = nullptr;
+ QString text;
+ };
+
+ void addItem(LayoutItem item);
+ void startNewRow();
+
+ QLayout *layout() const;
+
+private:
+ void flushPendingItems();
+
+ QLayout *m_layout = nullptr;
+ QList<LayoutItem> m_pendingItems;
+};
+
class PROJECTEXPLORER_EXPORT ProjectConfigurationAspect : public QObject
{
Q_OBJECT
@@ -70,9 +98,10 @@ public:
virtual void fromMap(const QVariantMap &) {}
virtual void toMap(QVariantMap &) const {}
- virtual void addToConfigurationLayout(QFormLayout *) {}
virtual void acquaintSiblings(const ProjectConfigurationAspects &) {}
+ virtual void addToLayout(LayoutBuilder &builder);
+
signals:
void changed();
@@ -182,7 +211,7 @@ protected:
ProjectConfigurationAspects m_aspects;
private:
- Target *m_target = nullptr;
+ QPointer<Target> m_target;
const Core::Id m_id;
Utils::DisplayName m_displayName;
QString m_toolTip;
diff --git a/src/plugins/projectexplorer/projectconfigurationaspects.cpp b/src/plugins/projectexplorer/projectconfigurationaspects.cpp
index 692c5d77b9..60b1ff400b 100644
--- a/src/plugins/projectexplorer/projectconfigurationaspects.cpp
+++ b/src/plugins/projectexplorer/projectconfigurationaspects.cpp
@@ -253,20 +253,19 @@ void BaseStringAspect::setReadOnly(bool readOnly)
d->m_textEditDisplay->setReadOnly(readOnly);
}
-void BaseStringAspect::addToConfigurationLayout(QFormLayout *layout)
+void BaseStringAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(!d->m_label);
- QWidget *parent = layout->parentWidget();
- d->m_label = new QLabel(parent);
+ d->m_label = new QLabel;
d->m_label->setTextInteractionFlags(Qt::TextSelectableByMouse);
d->m_label->setText(d->m_labelText);
if (!d->m_labelPixmap.isNull())
d->m_label->setPixmap(d->m_labelPixmap);
+ builder.addItem(d->m_label.data());
- auto hbox = new QHBoxLayout;
switch (d->m_displayStyle) {
case PathChooserDisplay:
- d->m_pathChooserDisplay = new PathChooser(parent);
+ d->m_pathChooserDisplay = new PathChooser;
d->m_pathChooserDisplay->setExpectedKind(d->m_expectedKind);
if (!d->m_historyCompleterKey.isEmpty())
d->m_pathChooserDisplay->setHistoryCompleter(d->m_historyCompleterKey);
@@ -275,20 +274,20 @@ void BaseStringAspect::addToConfigurationLayout(QFormLayout *layout)
d->m_pathChooserDisplay->setReadOnly(d->m_readOnly);
connect(d->m_pathChooserDisplay, &PathChooser::pathChanged,
this, &BaseStringAspect::setValue);
- hbox->addWidget(d->m_pathChooserDisplay);
+ builder.addItem(d->m_pathChooserDisplay.data());
break;
case LineEditDisplay:
- d->m_lineEditDisplay = new FancyLineEdit(parent);
+ d->m_lineEditDisplay = new FancyLineEdit;
d->m_lineEditDisplay->setPlaceholderText(d->m_placeHolderText);
if (!d->m_historyCompleterKey.isEmpty())
d->m_lineEditDisplay->setHistoryCompleter(d->m_historyCompleterKey);
d->m_lineEditDisplay->setReadOnly(d->m_readOnly);
connect(d->m_lineEditDisplay, &FancyLineEdit::textEdited,
this, &BaseStringAspect::setValue);
- hbox->addWidget(d->m_lineEditDisplay);
+ builder.addItem(d->m_lineEditDisplay.data());
break;
case TextEditDisplay:
- d->m_textEditDisplay = new QTextEdit(parent);
+ d->m_textEditDisplay = new QTextEdit;
d->m_textEditDisplay->setPlaceholderText(d->m_placeHolderText);
d->m_textEditDisplay->setReadOnly(d->m_readOnly);
connect(d->m_textEditDisplay, &QTextEdit::textChanged, this, [this] {
@@ -298,23 +297,17 @@ void BaseStringAspect::addToConfigurationLayout(QFormLayout *layout)
emit changed();
}
});
- hbox->addWidget(d->m_textEditDisplay);
+ builder.addItem(d->m_textEditDisplay.data());
break;
case LabelDisplay:
- d->m_labelDisplay = new QLabel(parent);
+ d->m_labelDisplay = new QLabel;
d->m_labelDisplay->setTextInteractionFlags(Qt::TextSelectableByMouse);
- hbox->addWidget(d->m_labelDisplay);
+ builder.addItem(d->m_labelDisplay.data());
break;
}
- if (d->m_checker) {
- auto form = new QFormLayout;
- form->setContentsMargins(0, 0, 0, 0);
- form->setFormAlignment(Qt::AlignLeft | Qt::AlignVCenter);
- d->m_checker->addToConfigurationLayout(form);
- hbox->addLayout(form);
- }
- layout->addRow(d->m_label, hbox);
+ if (d->m_checker)
+ d->m_checker->addToLayout(builder);
update();
}
@@ -378,13 +371,14 @@ BaseBoolAspect::BaseBoolAspect(const QString &settingsKey)
BaseBoolAspect::~BaseBoolAspect() = default;
-void BaseBoolAspect::addToConfigurationLayout(QFormLayout *layout)
+void BaseBoolAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(!d->m_checkBox);
- d->m_checkBox = new QCheckBox(d->m_label, layout->parentWidget());
+ d->m_checkBox = new QCheckBox(d->m_label);
d->m_checkBox->setChecked(d->m_value);
d->m_checkBox->setToolTip(d->m_tooltip);
- layout->addRow(QString(), d->m_checkBox);
+ builder.addItem(QString());
+ builder.addItem(d->m_checkBox.data());
connect(d->m_checkBox.data(), &QAbstractButton::clicked, this, [this] {
d->m_value = d->m_checkBox->isChecked();
emit changed();
@@ -444,7 +438,7 @@ BaseSelectionAspect::BaseSelectionAspect()
BaseSelectionAspect::~BaseSelectionAspect() = default;
-void BaseSelectionAspect::addToConfigurationLayout(QFormLayout *layout)
+void BaseSelectionAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(d->m_buttonGroup == nullptr);
d->m_buttonGroup = new QButtonGroup;
@@ -453,10 +447,11 @@ void BaseSelectionAspect::addToConfigurationLayout(QFormLayout *layout)
QTC_ASSERT(d->m_buttons.isEmpty(), d->m_buttons.clear());
for (int i = 0, n = d->m_options.size(); i < n; ++i) {
const Internal::BaseSelectionAspectPrivate::Option &option = d->m_options.at(i);
- auto button = new QRadioButton(option.displayName, layout->parentWidget());
+ auto button = new QRadioButton(option.displayName);
button->setChecked(i == d->m_value);
button->setToolTip(option.tooltip);
- layout->addRow(QString(), button);
+ builder.addItem(QString());
+ builder.addItem(button);
d->m_buttons.append(button);
d->m_buttonGroup->addButton(button);
connect(button, &QAbstractButton::clicked, this, [this, i] {
@@ -515,10 +510,10 @@ BaseIntegerAspect::BaseIntegerAspect()
BaseIntegerAspect::~BaseIntegerAspect() = default;
-void BaseIntegerAspect::addToConfigurationLayout(QFormLayout *layout)
+void BaseIntegerAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(!d->m_spinBox);
- d->m_spinBox = new QSpinBox(layout->parentWidget());
+ d->m_spinBox = new QSpinBox;
d->m_spinBox->setValue(int(d->m_value / d->m_displayScaleFactor));
d->m_spinBox->setDisplayIntegerBase(d->m_displayIntegerBase);
d->m_spinBox->setPrefix(d->m_prefix);
@@ -526,7 +521,8 @@ void BaseIntegerAspect::addToConfigurationLayout(QFormLayout *layout)
if (d->m_maximumValue.isValid() && d->m_maximumValue.isValid())
d->m_spinBox->setRange(int(d->m_minimumValue.toLongLong() / d->m_displayScaleFactor),
int(d->m_maximumValue.toLongLong() / d->m_displayScaleFactor));
- layout->addRow(d->m_label, d->m_spinBox);
+ builder.addItem(d->m_label);
+ builder.addItem(d->m_spinBox.data());
connect(d->m_spinBox.data(), QOverload<int>::of(&QSpinBox::valueChanged),
this, [this](int value) {
d->m_value = value * d->m_displayScaleFactor;
diff --git a/src/plugins/projectexplorer/projectconfigurationaspects.h b/src/plugins/projectexplorer/projectconfigurationaspects.h
index 3195ad63fc..90bdcbc2bb 100644
--- a/src/plugins/projectexplorer/projectconfigurationaspects.h
+++ b/src/plugins/projectexplorer/projectconfigurationaspects.h
@@ -50,7 +50,7 @@ public:
explicit BaseBoolAspect(const QString &settingsKey = QString());
~BaseBoolAspect() override;
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(LayoutBuilder &builder) override;
bool value() const;
void setValue(bool val);
@@ -76,7 +76,7 @@ public:
BaseSelectionAspect();
~BaseSelectionAspect() override;
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(LayoutBuilder &builder) override;
int value() const;
void setValue(int val);
@@ -101,7 +101,7 @@ public:
BaseStringAspect();
~BaseStringAspect() override;
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(LayoutBuilder &builder) override;
QString value() const;
void setValue(const QString &val);
@@ -150,7 +150,7 @@ public:
BaseIntegerAspect();
~BaseIntegerAspect() override;
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(LayoutBuilder &builder) override;
qint64 value() const;
void setValue(qint64 val);
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index 30fdbcc58a..4d7aee5fc8 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -659,8 +659,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
qRegisterMetaType<ProjectExplorer::RunControl *>();
qRegisterMetaType<ProjectExplorer::DeployableFile>("ProjectExplorer::DeployableFile");
- CustomWizard::setVerbose(arguments.count(QLatin1String("-customwizard-verbose")));
- JsonWizardFactory::setVerbose(arguments.count(QLatin1String("-customwizard-verbose")));
+ handleCommandLineArguments(arguments);
dd->m_toolChainManager = new ToolChainManager;
@@ -2794,6 +2793,26 @@ bool ProjectExplorerPlugin::coreAboutToClose()
return dd->m_outputPane.aboutToClose();
}
+void ProjectExplorerPlugin::handleCommandLineArguments(const QStringList &arguments)
+{
+ CustomWizard::setVerbose(arguments.count(QLatin1String("-customwizard-verbose")));
+ JsonWizardFactory::setVerbose(arguments.count(QLatin1String("-customwizard-verbose")));
+
+ const int kitForBinaryOptionIndex = arguments.indexOf("-ensure-kit-for-binary");
+ if (kitForBinaryOptionIndex != -1) {
+ if (kitForBinaryOptionIndex == arguments.count() - 1) {
+ qWarning() << "The \"-ensure-kit-for-binary\" option requires a file path argument.";
+ } else {
+ const Utils::FilePath binary =
+ Utils::FilePath::fromString(arguments.at(kitForBinaryOptionIndex + 1));
+ if (binary.isEmpty() || !binary.exists())
+ qWarning() << QString("No such file \"%1\".").arg(binary.toUserOutput());
+ else
+ KitManager::setBinaryForKit(binary);
+ }
+ }
+}
+
static bool hasDeploySettings(Project *pro)
{
return Utils::anyOf(SessionManager::projectOrder(pro), [](Project *project) {
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index feb53ccdef..c2dffd4f6f 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -187,6 +187,7 @@ signals:
private:
static bool coreAboutToClose();
+ void handleCommandLineArguments(const QStringList &arguments);
#ifdef WITH_TESTS
private slots:
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index a63af418d9..6fbc74ea24 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -32,7 +32,6 @@ HEADERS += projectexplorer.h \
projectimporter.h \
projectwindow.h \
removetaskhandler.h \
- subscription.h \
targetsetuppage.h \
targetsetupwidget.h \
kit.h \
@@ -191,7 +190,6 @@ SOURCES += projectexplorer.cpp \
projectimporter.cpp \
projectwindow.cpp \
removetaskhandler.cpp \
- subscription.cpp \
targetsetuppage.cpp \
targetsetupwidget.cpp \
kit.cpp \
diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs
index 9fabfcb98f..9a4131d0fd 100644
--- a/src/plugins/projectexplorer/projectexplorer.qbs
+++ b/src/plugins/projectexplorer/projectexplorer.qbs
@@ -141,7 +141,6 @@ Project {
"sessiondialog.cpp", "sessiondialog.h", "sessiondialog.ui",
"showineditortaskhandler.cpp", "showineditortaskhandler.h",
"showoutputtaskhandler.cpp", "showoutputtaskhandler.h",
- "subscription.cpp", "subscription.h",
"target.cpp", "target.h",
"targetsettingspanel.cpp", "targetsettingspanel.h",
"targetsetuppage.cpp", "targetsetuppage.h",
diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp
index 9714c1aa09..ce39300600 100644
--- a/src/plugins/projectexplorer/projectmodels.cpp
+++ b/src/plugins/projectexplorer/projectmodels.cpp
@@ -425,6 +425,8 @@ void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<
for (Node *node : folderNode->nodes()) {
if (m_filterGeneratedFiles && node->isGenerated())
continue;
+ if (m_filterDisabledFiles && !node->isEnabled())
+ continue;
if (FolderNode *subFolderNode = node->asFolderNode()) {
const bool isHidden = m_filterProjects && !subFolderNode->showInSimpleTree();
if (!isHidden && !seen->contains(subFolderNode)) {
@@ -810,6 +812,14 @@ void FlatModel::setGeneratedFilesFilterEnabled(bool filter)
rebuildModel();
}
+void FlatModel::setDisabledFilesFilterEnabled(bool filter)
+{
+ if (filter == m_filterDisabledFiles)
+ return;
+ m_filterDisabledFiles = filter;
+ rebuildModel();
+}
+
void FlatModel::setTrimEmptyDirectories(bool filter)
{
if (filter == m_trimEmptyDirectories)
diff --git a/src/plugins/projectexplorer/projectmodels.h b/src/plugins/projectexplorer/projectmodels.h
index f4412eae28..835e28993d 100644
--- a/src/plugins/projectexplorer/projectmodels.h
+++ b/src/plugins/projectexplorer/projectmodels.h
@@ -80,9 +80,11 @@ public:
bool projectFilterEnabled();
bool generatedFilesFilterEnabled();
+ bool disabledFilesFilterEnabled() const { return m_filterDisabledFiles; }
bool trimEmptyDirectoriesEnabled();
void setProjectFilterEnabled(bool filter);
void setGeneratedFilesFilterEnabled(bool filter);
+ void setDisabledFilesFilterEnabled(bool filter);
void setTrimEmptyDirectories(bool filter);
void onExpanded(const QModelIndex &idx);
@@ -95,6 +97,7 @@ signals:
private:
bool m_filterProjects = false;
bool m_filterGeneratedFiles = true;
+ bool m_filterDisabledFiles = false;
bool m_trimEmptyDirectories = true;
static const QLoggingCategory &logger();
diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp
index c2244ed010..1424333fcc 100644
--- a/src/plugins/projectexplorer/projectnodes.cpp
+++ b/src/plugins/projectexplorer/projectnodes.cpp
@@ -25,6 +25,7 @@
#include "projectnodes.h"
+#include "buildsystem.h"
#include "project.h"
#include "projectexplorerconstants.h"
#include "projecttree.h"
@@ -882,47 +883,51 @@ bool ProjectNode::removeSubProject(const QString &proFilePath)
bool ProjectNode::addFiles(const QStringList &filePaths, QStringList *notAdded)
{
- Q_UNUSED(filePaths)
- Q_UNUSED(notAdded)
+ if (BuildSystem *bs = buildSystem())
+ return bs->addFiles(this, filePaths, notAdded);
return false;
}
RemovedFilesFromProject ProjectNode::removeFiles(const QStringList &filePaths,
QStringList *notRemoved)
{
- Q_UNUSED(filePaths)
- Q_UNUSED(notRemoved)
+ if (BuildSystem *bs = buildSystem())
+ return bs->removeFiles(this, filePaths, notRemoved);
return RemovedFilesFromProject::Error;
}
bool ProjectNode::deleteFiles(const QStringList &filePaths)
{
- Q_UNUSED(filePaths)
+ if (BuildSystem *bs = buildSystem())
+ return bs->deleteFiles(this, filePaths);
return false;
}
bool ProjectNode::canRenameFile(const QString &filePath, const QString &newFilePath)
{
- Q_UNUSED(filePath)
- Q_UNUSED(newFilePath)
+ if (BuildSystem *bs = buildSystem())
+ return bs->canRenameFile(this, filePath, newFilePath);
return true;
}
bool ProjectNode::renameFile(const QString &filePath, const QString &newFilePath)
{
- Q_UNUSED(filePath)
- Q_UNUSED(newFilePath)
+ if (BuildSystem *bs = buildSystem())
+ return bs->renameFile(this, filePath, newFilePath);
return false;
}
bool ProjectNode::addDependencies(const QStringList &dependencies)
{
- Q_UNUSED(dependencies)
+ if (BuildSystem *bs = buildSystem())
+ return bs->addDependencies(this, dependencies);
return false;
}
-bool ProjectNode::supportsAction(ProjectAction, const Node *) const
+bool ProjectNode::supportsAction(ProjectAction action, const Node *node) const
{
+ if (BuildSystem *bs = buildSystem())
+ return bs->supportsAction(const_cast<ProjectNode *>(this), action, node);
return false;
}
@@ -959,6 +964,12 @@ void ProjectNode::setFallbackData(Core::Id key, const QVariant &value)
m_fallbackData.insert(key, value);
}
+BuildSystem *ProjectNode::buildSystem() const
+{
+ Project *p = getProject();
+ return p ? p->buildSystem() : nullptr;
+}
+
bool FolderNode::isEmpty() const
{
return m_nodes.size() == 0;
diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h
index 68e11a178d..7ad184cdf7 100644
--- a/src/plugins/projectexplorer/projectnodes.h
+++ b/src/plugins/projectexplorer/projectnodes.h
@@ -42,6 +42,7 @@ namespace Utils { class MimeType; }
namespace ProjectExplorer {
+class BuildSystem;
class Project;
// File types common for qt projects
@@ -357,14 +358,14 @@ public:
bool isProjectNodeType() const override { return true; }
bool showInSimpleTree() const override { return true; }
- bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override;
+ bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) final;
RemovedFilesFromProject removeFiles(const QStringList &filePaths,
- QStringList *notRemoved = nullptr) override;
- bool deleteFiles(const QStringList &filePaths) override;
- bool canRenameFile(const QString &filePath, const QString &newFilePath) override;
- bool renameFile(const QString &filePath, const QString &newFilePath) override;
- bool addDependencies(const QStringList &dependencies) override;
- bool supportsAction(ProjectAction action, const Node *node) const override;
+ QStringList *notRemoved = nullptr) final;
+ bool deleteFiles(const QStringList &filePaths) final;
+ bool canRenameFile(const QString &filePath, const QString &newFilePath) final;
+ bool renameFile(const QString &filePath, const QString &newFilePath) final;
+ bool addDependencies(const QStringList &dependencies) final;
+ bool supportsAction(ProjectAction action, const Node *node) const final;
// by default returns false
virtual bool deploysFolder(const QString &folder) const;
@@ -399,6 +400,8 @@ protected:
QString m_target;
private:
+ BuildSystem *buildSystem() const;
+
QHash<Core::Id, QVariant> m_fallbackData; // Used in data(), unless overridden.
ProductType m_productType = ProductType::None;
};
diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp
index 14e6feca16..b3ae5756e7 100644
--- a/src/plugins/projectexplorer/projecttreewidget.cpp
+++ b/src/plugins/projectexplorer/projecttreewidget.cpp
@@ -257,6 +257,12 @@ ProjectTreeWidget::ProjectTreeWidget(QWidget *parent) : QWidget(parent)
connect(m_filterGeneratedFilesAction, &QAction::toggled,
this, &ProjectTreeWidget::setGeneratedFilesFilter);
+ m_filterDisabledFilesAction = new QAction(tr("Hide Disabled Files"), this);
+ m_filterDisabledFilesAction->setCheckable(true);
+ m_filterDisabledFilesAction->setChecked(false);
+ connect(m_filterDisabledFilesAction, &QAction::toggled,
+ this, &ProjectTreeWidget::setDisabledFilesFilter);
+
const char focusActionId[] = "ProjectExplorer.FocusDocumentInProjectTree";
if (!ActionManager::command(focusActionId)) {
auto focusDocumentInProjectTree = new QAction(tr("Focus Document in Project Tree"), this);
@@ -557,6 +563,12 @@ void ProjectTreeWidget::setGeneratedFilesFilter(bool filter)
m_filterGeneratedFilesAction->setChecked(filter);
}
+void ProjectTreeWidget::setDisabledFilesFilter(bool filter)
+{
+ m_model->setDisabledFilesFilterEnabled(filter);
+ m_filterDisabledFilesAction->setChecked(filter);
+}
+
void ProjectTreeWidget::setTrimEmptyDirectories(bool filter)
{
m_model->setTrimEmptyDirectories(filter);
@@ -568,6 +580,11 @@ bool ProjectTreeWidget::generatedFilesFilter()
return m_model->generatedFilesFilterEnabled();
}
+bool ProjectTreeWidget::disabledFilesFilter()
+{
+ return m_model->disabledFilesFilterEnabled();
+}
+
bool ProjectTreeWidget::trimEmptyDirectoriesFilter()
{
return m_model->trimEmptyDirectoriesEnabled();
@@ -601,6 +618,7 @@ NavigationView ProjectTreeWidgetFactory::createWidget()
auto filterMenu = new QMenu(filter);
filterMenu->addAction(ptw->m_filterProjectsAction);
filterMenu->addAction(ptw->m_filterGeneratedFilesAction);
+ filterMenu->addAction(ptw->m_filterDisabledFilesAction);
filterMenu->addAction(ptw->m_trimEmptyDirectoriesAction);
filter->setMenu(filterMenu);
@@ -615,6 +633,7 @@ void ProjectTreeWidgetFactory::saveSettings(QSettings *settings, int position, Q
const QString baseKey = QLatin1String("ProjectTreeWidget.") + QString::number(position);
settings->setValue(baseKey + QLatin1String(".ProjectFilter"), ptw->projectFilter());
settings->setValue(baseKey + QLatin1String(".GeneratedFilter"), ptw->generatedFilesFilter());
+ settings->setValue(baseKey + ".DisabledFilesFilter", ptw->disabledFilesFilter());
settings->setValue(baseKey + QLatin1String(".TrimEmptyDirsFilter"), ptw->trimEmptyDirectoriesFilter());
settings->setValue(baseKey + QLatin1String(".SyncWithEditor"), ptw->autoSynchronization());
}
@@ -626,6 +645,7 @@ void ProjectTreeWidgetFactory::restoreSettings(QSettings *settings, int position
const QString baseKey = QLatin1String("ProjectTreeWidget.") + QString::number(position);
ptw->setProjectFilter(settings->value(baseKey + QLatin1String(".ProjectFilter"), false).toBool());
ptw->setGeneratedFilesFilter(settings->value(baseKey + QLatin1String(".GeneratedFilter"), true).toBool());
+ ptw->setDisabledFilesFilter(settings->value(baseKey + ".DisabledFilesFilter", false).toBool());
ptw->setTrimEmptyDirectories(settings->value(baseKey + QLatin1String(".TrimEmptyDirsFilter"), true).toBool());
ptw->setAutoSynchronization(settings->value(baseKey + QLatin1String(".SyncWithEditor"), true).toBool());
}
diff --git a/src/plugins/projectexplorer/projecttreewidget.h b/src/plugins/projectexplorer/projecttreewidget.h
index 74b301e93b..e53396c4b9 100644
--- a/src/plugins/projectexplorer/projecttreewidget.h
+++ b/src/plugins/projectexplorer/projecttreewidget.h
@@ -56,6 +56,7 @@ public:
void setAutoSynchronization(bool sync);
bool projectFilter();
bool generatedFilesFilter();
+ bool disabledFilesFilter();
bool trimEmptyDirectoriesFilter();
QToolButton *toggleSync();
Node *currentNode();
@@ -72,6 +73,7 @@ public:
private:
void setProjectFilter(bool filter);
void setGeneratedFilesFilter(bool filter);
+ void setDisabledFilesFilter(bool filter);
void setTrimEmptyDirectories(bool filter);
void handleCurrentItemChange(const QModelIndex &current);
@@ -89,6 +91,7 @@ private:
FlatModel *m_model = nullptr;
QAction *m_filterProjectsAction = nullptr;
QAction *m_filterGeneratedFilesAction = nullptr;
+ QAction *m_filterDisabledFilesAction = nullptr;
QAction *m_trimEmptyDirectoriesAction = nullptr;
QToolButton *m_toggleSync = nullptr;
diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp
index 2c2394c7e3..903c6f878a 100644
--- a/src/plugins/projectexplorer/runconfiguration.cpp
+++ b/src/plugins/projectexplorer/runconfiguration.cpp
@@ -248,13 +248,14 @@ QString RunConfiguration::disabledReason() const
QWidget *RunConfiguration::createConfigurationWidget()
{
auto widget = new QWidget;
- auto formLayout = new QFormLayout(widget);
- formLayout->setContentsMargins(0, 0, 0, 0);
- formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
-
- for (ProjectConfigurationAspect *aspect : m_aspects) {
- if (aspect->isVisible())
- aspect->addToConfigurationLayout(formLayout);
+ {
+ LayoutBuilder builder(widget);
+ for (ProjectConfigurationAspect *aspect : m_aspects) {
+ if (aspect->isVisible()) {
+ builder.startNewRow();
+ aspect->addToLayout(builder);
+ }
+ }
}
Core::VariableChooser::addSupportForChildWidgets(widget, macroExpander());
diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp
index 0358dd54a5..0d1e963263 100644
--- a/src/plugins/projectexplorer/runconfigurationaspects.cpp
+++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp
@@ -63,12 +63,13 @@ TerminalAspect::TerminalAspect()
this, &TerminalAspect::calculateUseTerminal);
}
-void TerminalAspect::addToConfigurationLayout(QFormLayout *layout)
+void TerminalAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(!m_checkBox);
- m_checkBox = new QCheckBox(tr("Run in terminal"), layout->parentWidget());
+ m_checkBox = new QCheckBox(tr("Run in terminal"));
m_checkBox->setChecked(m_useTerminal);
- layout->addRow(QString(), m_checkBox);
+ builder.addItem(QString());
+ builder.addItem(m_checkBox.data());
connect(m_checkBox.data(), &QAbstractButton::clicked, this, [this] {
m_userSet = true;
m_useTerminal = m_checkBox->isChecked();
@@ -103,7 +104,7 @@ void TerminalAspect::calculateUseTerminal()
switch (ProjectExplorerPlugin::projectExplorerSettings().terminalMode) {
case Internal::TerminalMode::On: useTerminal = true; break;
case Internal::TerminalMode::Off: useTerminal = false; break;
- case Internal::TerminalMode::Smart: useTerminal = m_useTerminalHint;
+ default: useTerminal = m_useTerminalHint;
}
if (m_useTerminal != useTerminal) {
m_useTerminal = useTerminal;
@@ -140,10 +141,10 @@ WorkingDirectoryAspect::WorkingDirectoryAspect()
setSettingsKey("RunConfiguration.WorkingDirectory");
}
-void WorkingDirectoryAspect::addToConfigurationLayout(QFormLayout *layout)
+void WorkingDirectoryAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(!m_chooser);
- m_chooser = new PathChooser(layout->parentWidget());
+ m_chooser = new PathChooser;
m_chooser->setHistoryCompleter(settingsKey());
m_chooser->setExpectedKind(Utils::PathChooser::Directory);
m_chooser->setPromptDialogTitle(tr("Select Working Directory"));
@@ -155,7 +156,7 @@ void WorkingDirectoryAspect::addToConfigurationLayout(QFormLayout *layout)
m_resetButton->setEnabled(m_workingDirectory != m_defaultWorkingDirectory);
});
- m_resetButton = new QToolButton(layout->parentWidget());
+ m_resetButton = new QToolButton;
m_resetButton->setToolTip(tr("Reset to Default"));
m_resetButton->setIcon(Utils::Icons::RESET.icon());
connect(m_resetButton.data(), &QAbstractButton::clicked, this, &WorkingDirectoryAspect::resetPath);
@@ -168,10 +169,9 @@ void WorkingDirectoryAspect::addToConfigurationLayout(QFormLayout *layout)
m_chooser->setEnvironment(m_envAspect->environment());
}
- auto hbox = new QHBoxLayout;
- hbox->addWidget(m_chooser);
- hbox->addWidget(m_resetButton);
- layout->addRow(tr("Working directory:"), hbox);
+ builder.addItem(tr("Working directory:"));
+ builder.addItem(m_chooser.data());
+ builder.addItem(m_resetButton.data());
}
void WorkingDirectoryAspect::acquaintSiblings(const ProjectConfigurationAspects &siblings)
@@ -337,9 +337,10 @@ QWidget *ArgumentsAspect::setupChooser()
return m_chooser.data();
}
-void ArgumentsAspect::addToConfigurationLayout(QFormLayout *layout)
+void ArgumentsAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(!m_chooser && !m_multiLineChooser && !m_multiLineButton);
+ builder.addItem(tr("Command line arguments:"));
const auto container = new QWidget;
const auto containerLayout = new QHBoxLayout(container);
@@ -371,7 +372,8 @@ void ArgumentsAspect::addToConfigurationLayout(QFormLayout *layout)
});
containerLayout->addWidget(m_multiLineButton);
containerLayout->setAlignment(m_multiLineButton, Qt::AlignTop);
- layout->addRow(tr("Command line arguments:"), container);
+
+ builder.addItem(container);
}
/*!
@@ -450,11 +452,13 @@ FilePath ExecutableAspect::executable() const
return m_executable.filePath();
}
-void ExecutableAspect::addToConfigurationLayout(QFormLayout *layout)
+void ExecutableAspect::addToLayout(LayoutBuilder &builder)
{
- m_executable.addToConfigurationLayout(layout);
- if (m_alternativeExecutable)
- m_alternativeExecutable->addToConfigurationLayout(layout);
+ m_executable.addToLayout(builder);
+ if (m_alternativeExecutable) {
+ builder.startNewRow();
+ m_alternativeExecutable->addToLayout(builder);
+ }
}
void ExecutableAspect::setLabelText(const QString &labelText)
diff --git a/src/plugins/projectexplorer/runconfigurationaspects.h b/src/plugins/projectexplorer/runconfigurationaspects.h
index 2b65737789..ca41d04df8 100644
--- a/src/plugins/projectexplorer/runconfigurationaspects.h
+++ b/src/plugins/projectexplorer/runconfigurationaspects.h
@@ -48,7 +48,7 @@ class PROJECTEXPLORER_EXPORT TerminalAspect : public ProjectConfigurationAspect
public:
TerminalAspect();
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(LayoutBuilder &builder) override;
bool useTerminal() const;
void setUseTerminalHint(bool useTerminal);
@@ -74,7 +74,7 @@ class PROJECTEXPLORER_EXPORT WorkingDirectoryAspect : public ProjectConfiguratio
public:
WorkingDirectoryAspect();
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(LayoutBuilder &builder) override;
void acquaintSiblings(const ProjectConfigurationAspects &) override;
Utils::FilePath workingDirectory(const Utils::MacroExpander *expander) const;
@@ -104,7 +104,7 @@ class PROJECTEXPLORER_EXPORT ArgumentsAspect : public ProjectConfigurationAspect
public:
ArgumentsAspect();
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(LayoutBuilder &builder) override;
QString arguments(const Utils::MacroExpander *expander) const;
QString unexpandedArguments() const;
@@ -157,7 +157,7 @@ public:
void setSettingsKey(const QString &key);
void makeOverridable(const QString &overridingKey, const QString &useOverridableKey);
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(LayoutBuilder &builder) override;
void setLabelText(const QString &labelText);
void setPlaceHolderText(const QString &placeHolderText);
void setExecutablePathStyle(Utils::OsType osType);
diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
index 4695eff651..1cde0b89d4 100644
--- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
@@ -424,8 +424,7 @@ void RunSettingsWidget::updateDeployConfiguration(DeployConfiguration *dc)
if (m_deployConfigurationWidget)
m_deployLayout->addWidget(m_deployConfigurationWidget);
- m_deploySteps = new BuildStepListWidget;
- m_deploySteps->init(dc->stepList());
+ m_deploySteps = new BuildStepListWidget(dc->stepList());
m_deployLayout->addWidget(m_deploySteps);
}
diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.h b/src/plugins/projectexplorer/runsettingspropertiespage.h
index 12f1403c42..7db4db3e9a 100644
--- a/src/plugins/projectexplorer/runsettingspropertiespage.h
+++ b/src/plugins/projectexplorer/runsettingspropertiespage.h
@@ -39,9 +39,7 @@ QT_END_NAMESPACE
namespace ProjectExplorer {
class DeployConfiguration;
-class NamedWidget;
class RunConfiguration;
-class RunConfigWidget;
class Target;
namespace Internal {
diff --git a/src/plugins/projectexplorer/subscription.cpp b/src/plugins/projectexplorer/subscription.cpp
deleted file mode 100644
index a8092ed3ba..0000000000
--- a/src/plugins/projectexplorer/subscription.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "subscription.h"
-
-#include "project.h"
-#include "projectconfiguration.h"
-#include "session.h"
-#include "target.h"
-
-#include <utils/qtcassert.h>
-
-namespace ProjectExplorer {
-namespace Internal {
-
-Subscription::Subscription(const Subscription::Connector &s, const QObject *receiver, QObject *parent) :
- QObject(parent), m_subscriber(s)
-{
- if (receiver != parent)
- connect(receiver, &QObject::destroyed, this, &Subscription::destroy);
-}
-
-Subscription::~Subscription()
-{
- unsubscribeAll();
-}
-
-void Subscription::subscribe(ProjectConfiguration *pc)
-{
- if (!m_subscriber)
- return;
-
- connectTo(pc);
-}
-
-void Subscription::subscribeTarget(Target *target)
-{
- if (!m_subscriber)
- return;
-
- for (ProjectConfiguration *pc : target->projectConfigurations())
- connectTo(pc);
-}
-
-void Subscription::unsubscribe(ProjectConfiguration *pc)
-{
- disconnectFrom(pc);
-}
-
-void Subscription::unsubscribeTarget(Target *target)
-{
- for (ProjectConfiguration *pc : target->projectConfigurations())
- disconnectFrom(pc);
-}
-
-void Subscription::unsubscribeAll()
-{
- for (const auto &c : qAsConst(m_connections))
- disconnect(c);
- m_connections.clear();
-}
-
-void Subscription::connectTo(ProjectConfiguration *pc)
-{
- if (!m_subscriber)
- return; // May happen during shutdown of a subscription
-
- QTC_ASSERT(!m_connections.contains(pc), return);
-
- QMetaObject::Connection conn = m_subscriber(pc);
- if (conn)
- m_connections.insert(pc, conn);
-}
-
-void Subscription::disconnectFrom(ProjectConfiguration *pc)
-{
- auto c = m_connections.value(pc);
- if (!c)
- return;
-
- disconnect(c);
- m_connections.remove(pc);
-}
-
-void Subscription::destroy()
-{
- unsubscribeAll();
- m_subscriber = Connector(); // Reset subscriber
- deleteLater();
-}
-
-ProjectSubscription::ProjectSubscription(const Subscription::Connector &s, const QObject *r,
- Project *p) :
- Subscription(s, r, p)
-{
- QTC_ASSERT(m_subscriber, return);
-
- for (Target *t : p->targets())
- subscribeTarget(t);
-
- // Disconnect on removal of a project, to make it save to remove/add a project:
- connect(SessionManager::instance(), &SessionManager::projectRemoved,
- this, [this, p](Project *reported) { if (p == reported) { destroy(); } });
- connect(p, &Project::addedProjectConfiguration, this, &ProjectSubscription::subscribe);
- connect(p, &Project::addedTarget, this, &ProjectSubscription::subscribeTarget);
- connect(p, &Project::removedProjectConfiguration, this, &ProjectSubscription::unsubscribe);
- connect(p, &Project::removedTarget, this, &ProjectSubscription::unsubscribeTarget);
-}
-
-ProjectSubscription::~ProjectSubscription() = default;
-
-} // namespace Internal
-} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/subscription.h b/src/plugins/projectexplorer/subscription.h
deleted file mode 100644
index baff689d8e..0000000000
--- a/src/plugins/projectexplorer/subscription.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "projectexplorer_export.h"
-
-#include <QHash>
-#include <QObject>
-
-#include <functional>
-
-namespace ProjectExplorer {
-
-class Project;
-class ProjectConfiguration;
-class Target;
-
-namespace Internal {
-
-class PROJECTEXPLORER_EXPORT Subscription : public QObject
-{
- Q_OBJECT
-public:
- using Connector = std::function<QMetaObject::Connection(ProjectConfiguration *)>;
-
- Subscription(const Connector &s, const QObject *receiver, QObject *parent);
- ~Subscription() override;
-
-protected:
- void subscribe(ProjectConfiguration *pc);
- void subscribeTarget(Target *target);
- void unsubscribe(ProjectConfiguration *pc);
- void unsubscribeTarget(Target *target);
-
- void unsubscribeAll();
- void connectTo(ProjectConfiguration *pc);
- void disconnectFrom(ProjectConfiguration *pc);
-
- void destroy();
-
- Connector m_subscriber;
- QHash<ProjectConfiguration *, QMetaObject::Connection> m_connections;
-};
-
-class PROJECTEXPLORER_EXPORT ProjectSubscription : public Subscription
-{
-public:
- ProjectSubscription(const Connector &s, const QObject *receiver, Project *p);
- ~ProjectSubscription() final;
-};
-
-} // namespace Internal
-} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h
index d7e64beda4..2fdf555bf3 100644
--- a/src/plugins/projectexplorer/target.h
+++ b/src/plugins/projectexplorer/target.h
@@ -28,8 +28,6 @@
#include "projectconfiguration.h"
#include "projectexplorer_export.h"
-#include "subscription.h"
-
#include <memory>
QT_FORWARD_DECLARE_CLASS(QIcon)
diff --git a/src/plugins/python/pythonproject.cpp b/src/plugins/python/pythonproject.cpp
index c38394a0be..921f66b043 100644
--- a/src/plugins/python/pythonproject.cpp
+++ b/src/plugins/python/pythonproject.cpp
@@ -27,6 +27,7 @@
#include "pythonconstants.h"
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
@@ -53,19 +54,34 @@ using namespace Utils;
namespace Python {
namespace Internal {
-class PythonProjectNode : public ProjectNode
+class PythonBuildSystem : public BuildSystem
{
public:
- PythonProjectNode(PythonProject *project);
+ explicit PythonBuildSystem(Project *project);
+
+ bool supportsAction(Node *context, ProjectAction action, const Node *node) const override;
+ bool addFiles(Node *, const QStringList &filePaths, QStringList *) override;
+ RemovedFilesFromProject removeFiles(Node *, const QStringList &filePaths, QStringList *) override;
+ bool deleteFiles(Node *, const QStringList &) override;
+ bool renameFile(Node *, const QString &filePath, const QString &newFilePath) override;
+
+ bool saveRawFileList(const QStringList &rawFileList);
+ bool saveRawList(const QStringList &rawList, const QString &fileName);
+ void parse();
+ QStringList processEntries(const QStringList &paths,
+ QHash<QString, QString> *map = nullptr) const;
- bool supportsAction(ProjectAction action, const Node *node) const override;
- bool addFiles(const QStringList &filePaths, QStringList *) override;
- RemovedFilesFromProject removeFiles(const QStringList &filePaths, QStringList *) override;
- bool deleteFiles(const QStringList &) override;
- bool renameFile(const QString &filePath, const QString &newFilePath) override;
+ bool writePyProjectFile(const QString &fileName, QString &content,
+ const QStringList &rawList, QString *errorMessage);
+
+ void refresh();
private:
- PythonProject *m_project;
+ PythonProject *project() const;
+
+ QStringList m_rawFileList;
+ QStringList m_files;
+ QHash<QString, QString> m_rawListEntries;
};
@@ -156,6 +172,17 @@ static QStringList readLinesJson(const FilePath &projectFile, QString *errorMess
return lines;
}
+class PythonProjectNode : public ProjectNode
+{
+public:
+ PythonProjectNode(const Utils::FilePath &path)
+ : ProjectNode(path)
+ {
+ setDisplayName(path.toFileInfo().completeBaseName());
+ setAddFileFilter("*.py");
+ }
+};
+
PythonProject::PythonProject(const FilePath &fileName)
: Project(Constants::C_PY_MIMETYPE, fileName)
{
@@ -164,18 +191,18 @@ PythonProject::PythonProject(const FilePath &fileName)
setDisplayName(fileName.toFileInfo().completeBaseName());
setNeedsBuildConfigurations(false);
-
- connect(this, &PythonProject::projectFileIsDirty, this, [this]() { refresh(); });
+ setBuildSystemCreator([](Project *p) { return new PythonBuildSystem(p); });
}
-void PythonProject::refresh(Target *target)
+void PythonBuildSystem::refresh()
{
- ParseGuard guard = guardParsingRun();
- parseProject();
+ Project::ParseGuard guard = project()->guardParsingRun();
+ parse();
const QDir baseDir(projectDirectory().toString());
QList<BuildTargetInfo> appTargets;
- auto newRoot = std::make_unique<PythonProjectNode>(this);
+
+ auto newRoot = std::make_unique<PythonProjectNode>(projectDirectory());
for (const QString &f : qAsConst(m_files)) {
const QString displayName = baseDir.relativeFilePath(f);
const FileType fileType = f.endsWith(".pyproject") || f.endsWith(".pyqtc") ? FileType::Project
@@ -190,24 +217,22 @@ void PythonProject::refresh(Target *target)
appTargets.append(bti);
}
}
- setRootProjectNode(std::move(newRoot));
+ project()->setRootProjectNode(std::move(newRoot));
- if (!target)
- target = activeTarget();
- if (target)
+ if (Target *target = project()->activeTarget())
target->setApplicationTargets(appTargets);
guard.markAsSuccess();
}
-bool PythonProject::saveRawFileList(const QStringList &rawFileList)
+bool PythonBuildSystem::saveRawFileList(const QStringList &rawFileList)
{
const bool result = saveRawList(rawFileList, projectFilePath().toString());
// refresh(PythonProject::Files);
return result;
}
-bool PythonProject::saveRawList(const QStringList &rawList, const QString &fileName)
+bool PythonBuildSystem::saveRawList(const QStringList &rawList, const QString &fileName)
{
FileChangeBlocker changeGuarg(fileName);
bool result = false;
@@ -238,7 +263,7 @@ bool PythonProject::saveRawList(const QStringList &rawList, const QString &fileN
return result;
}
-bool PythonProject::writePyProjectFile(const QString &fileName, QString &content,
+bool PythonBuildSystem::writePyProjectFile(const QString &fileName, QString &content,
const QStringList &rawList, QString *errorMessage)
{
QFile file(fileName);
@@ -265,7 +290,7 @@ bool PythonProject::writePyProjectFile(const QString &fileName, QString &content
return true;
}
-bool PythonProject::addFiles(const QStringList &filePaths)
+bool PythonBuildSystem::addFiles(Node *, const QStringList &filePaths, QStringList *)
{
QStringList newList = m_rawFileList;
@@ -276,7 +301,7 @@ bool PythonProject::addFiles(const QStringList &filePaths)
return saveRawFileList(newList);
}
-bool PythonProject::removeFiles(const QStringList &filePaths)
+RemovedFilesFromProject PythonBuildSystem::removeFiles(Node *, const QStringList &filePaths, QStringList *)
{
QStringList newList = m_rawFileList;
@@ -286,10 +311,17 @@ bool PythonProject::removeFiles(const QStringList &filePaths)
newList.removeOne(i.value());
}
- return saveRawFileList(newList);
+ bool res = saveRawFileList(newList);
+
+ return res ? RemovedFilesFromProject::Ok : RemovedFilesFromProject::Error;
}
-bool PythonProject::renameFile(const QString &filePath, const QString &newFilePath)
+bool PythonBuildSystem::deleteFiles(Node *, const QStringList &)
+{
+ return true;
+}
+
+bool PythonBuildSystem::renameFile(Node *, const QString &filePath, const QString &newFilePath)
{
QStringList newList = m_rawFileList;
@@ -305,7 +337,7 @@ bool PythonProject::renameFile(const QString &filePath, const QString &newFilePa
return saveRawFileList(newList);
}
-void PythonProject::parseProject()
+void PythonBuildSystem::parse()
{
m_rawListEntries.clear();
const FilePath filePath = projectFilePath();
@@ -323,6 +355,7 @@ void PythonProject::parseProject()
m_files = processEntries(m_rawFileList, &m_rawListEntries);
}
+
/**
* Expands environment variables in the given \a string when they are written
* like $$(VARIABLE).
@@ -349,7 +382,7 @@ static void expandEnvironmentVariables(const QProcessEnvironment &env, QString &
* The \a map variable is an optional argument that will map the returned
* absolute paths back to their original \a paths.
*/
-QStringList PythonProject::processEntries(const QStringList &paths,
+QStringList PythonBuildSystem::processEntries(const QStringList &paths,
QHash<QString, QString> *map) const
{
const QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
@@ -382,10 +415,11 @@ Project::RestoreResult PythonProject::fromMap(const QVariantMap &map, QString *e
{
Project::RestoreResult res = Project::fromMap(map, errorMessage);
if (res == RestoreResult::Ok) {
- refresh();
-
if (!activeTarget())
addTargetForDefaultKit();
+
+ if (auto bs = dynamic_cast<PythonBuildSystem *>(buildSystem()))
+ bs->refresh();
}
return res;
@@ -393,19 +427,20 @@ Project::RestoreResult PythonProject::fromMap(const QVariantMap &map, QString *e
bool PythonProject::setupTarget(Target *t)
{
- refresh(t);
- return Project::setupTarget(t);
+ bool res = Project::setupTarget(t);
+ if (auto bs = dynamic_cast<PythonBuildSystem *>(buildSystem()))
+ QTimer::singleShot(0, bs, &PythonBuildSystem::refresh);
+ return res;
}
-PythonProjectNode::PythonProjectNode(PythonProject *project)
- : ProjectNode(project->projectDirectory())
- , m_project(project)
+PythonBuildSystem::PythonBuildSystem(Project *project)
+ : BuildSystem(project)
{
- setDisplayName(project->projectFilePath().toFileInfo().completeBaseName());
- setAddFileFilter("*.py");
+ connect(project, &Project::projectFileIsDirty, this, [this]() { refresh(); });
+ QTimer::singleShot(0, this, &PythonBuildSystem::refresh);
}
-bool PythonProjectNode::supportsAction(ProjectAction action, const Node *node) const
+bool PythonBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
{
if (node->asFileNode()) {
return action == ProjectAction::Rename
@@ -416,28 +451,12 @@ bool PythonProjectNode::supportsAction(ProjectAction action, const Node *node) c
|| action == ProjectAction::RemoveFile
|| action == ProjectAction::AddExistingFile;
}
- return ProjectNode::supportsAction(action, node);
-}
-
-bool PythonProjectNode::addFiles(const QStringList &filePaths, QStringList *)
-{
- return m_project->addFiles(filePaths);
-}
-
-RemovedFilesFromProject PythonProjectNode::removeFiles(const QStringList &filePaths, QStringList *)
-{
- return m_project->removeFiles(filePaths) ? RemovedFilesFromProject::Ok
- : RemovedFilesFromProject::Error;
-}
-
-bool PythonProjectNode::deleteFiles(const QStringList &)
-{
- return true;
+ return BuildSystem::supportsAction(context, action, node);
}
-bool PythonProjectNode::renameFile(const QString &filePath, const QString &newFilePath)
+PythonProject *PythonBuildSystem::project() const
{
- return m_project->renameFile(filePath, newFilePath);
+ return static_cast<PythonProject *>(BuildSystem::project());
}
} // namespace Internal
diff --git a/src/plugins/python/pythonproject.h b/src/plugins/python/pythonproject.h
index 6f2d4b6d73..d030c92dcd 100644
--- a/src/plugins/python/pythonproject.h
+++ b/src/plugins/python/pythonproject.h
@@ -40,29 +40,10 @@ class PythonProject : public ProjectExplorer::Project
public:
explicit PythonProject(const Utils::FilePath &filename);
- bool addFiles(const QStringList &filePaths);
- bool removeFiles(const QStringList &filePaths);
- bool renameFile(const QString &filePath, const QString &newFilePath);
- void refresh(ProjectExplorer::Target *target = nullptr);
-
bool needsConfiguration() const final { return false; }
-
- bool writePyProjectFile(const QString &fileName, QString &content,
- const QStringList &rawList, QString *errorMessage);
-
private:
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
bool setupTarget(ProjectExplorer::Target *t) override;
-
- bool saveRawFileList(const QStringList &rawFileList);
- bool saveRawList(const QStringList &rawList, const QString &fileName);
- void parseProject();
- QStringList processEntries(const QStringList &paths,
- QHash<QString, QString> *map = nullptr) const;
-
- QStringList m_rawFileList;
- QStringList m_files;
- QHash<QString, QString> m_rawListEntries;
};
} // namespace Internal
diff --git a/src/plugins/python/pythonrunconfiguration.cpp b/src/plugins/python/pythonrunconfiguration.cpp
index d6bc6061e1..41386ef611 100644
--- a/src/plugins/python/pythonrunconfiguration.cpp
+++ b/src/plugins/python/pythonrunconfiguration.cpp
@@ -157,7 +157,7 @@ public:
void fromMap(const QVariantMap &) override;
void toMap(QVariantMap &) const override;
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(LayoutBuilder &builder) override;
private:
void updateCurrentInterpreter();
@@ -190,26 +190,23 @@ void InterpreterAspect::toMap(QVariantMap &map) const
map.insert(settingsKey(), m_currentId);
}
-void InterpreterAspect::addToConfigurationLayout(QFormLayout *layout)
+void InterpreterAspect::addToLayout(LayoutBuilder &builder)
{
if (QTC_GUARD(m_comboBox.isNull()))
m_comboBox = new QComboBox;
updateComboBox();
- connect(m_comboBox,
- &QComboBox::currentTextChanged,
- this,
- &InterpreterAspect::updateCurrentInterpreter);
+ connect(m_comboBox, &QComboBox::currentTextChanged,
+ this, &InterpreterAspect::updateCurrentInterpreter);
auto manageButton = new QPushButton(tr("Manage..."));
connect(manageButton, &QPushButton::clicked, []() {
Core::ICore::showOptionsDialog(Constants::C_PYTHONOPTIONS_PAGE_ID);
});
- auto rowLayout = new QHBoxLayout;
- rowLayout->addWidget(m_comboBox);
- rowLayout->addWidget(manageButton);
- layout->addRow(tr("Interpreter"), rowLayout);
+ builder.addItem(tr("Interpreter"));
+ builder.addItem(m_comboBox.data());
+ builder.addItem(manageButton);
}
void InterpreterAspect::updateCurrentInterpreter()
diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp
index 4a7f5fa541..002ebe77fb 100644
--- a/src/plugins/qbsprojectmanager/qbsnodes.cpp
+++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp
@@ -236,72 +236,6 @@ QbsGroupNode::QbsGroupNode(const qbs::GroupData &grp, const QString &productPath
m_qbsGroupData = grp;
}
-bool QbsGroupNode::supportsAction(ProjectAction action, const Node *node) const
-{
- if (action == AddNewFile || action == AddExistingFile)
- return true;
-
- return supportsNodeAction(action, node);
-}
-
-bool QbsGroupNode::addFiles(const QStringList &filePaths, QStringList *notAdded)
-{
- QStringList notAddedDummy;
- if (!notAdded)
- notAdded = &notAddedDummy;
-
- const QbsProjectNode *prjNode = parentQbsProjectNode(this);
- if (!prjNode || !prjNode->qbsProject().isValid()) {
- *notAdded += filePaths;
- return false;
- }
-
- const QbsProductNode *prdNode = parentQbsProductNode(this);
- if (!prdNode || !prdNode->qbsProductData().isValid()) {
- *notAdded += filePaths;
- return false;
- }
-
- return prjNode->project()->addFilesToProduct(filePaths, prdNode->qbsProductData(),
- m_qbsGroupData, notAdded);
-}
-
-RemovedFilesFromProject QbsGroupNode::removeFiles(const QStringList &filePaths,
- QStringList *notRemoved)
-{
- QStringList notRemovedDummy;
- if (!notRemoved)
- notRemoved = &notRemovedDummy;
-
- const QbsProjectNode *prjNode = parentQbsProjectNode(this);
- if (!prjNode || !prjNode->qbsProject().isValid()) {
- *notRemoved += filePaths;
- return RemovedFilesFromProject::Error;
- }
-
- const QbsProductNode *prdNode = parentQbsProductNode(this);
- if (!prdNode || !prdNode->qbsProductData().isValid()) {
- *notRemoved += filePaths;
- return RemovedFilesFromProject::Error;
- }
-
- return prjNode->project()->removeFilesFromProduct(filePaths, prdNode->qbsProductData(),
- m_qbsGroupData, notRemoved);
-}
-
-bool QbsGroupNode::renameFile(const QString &filePath, const QString &newFilePath)
-{
- const QbsProjectNode *prjNode = parentQbsProjectNode(this);
- if (!prjNode || !prjNode->qbsProject().isValid())
- return false;
- const QbsProductNode *prdNode = parentQbsProductNode(this);
- if (!prdNode || !prdNode->qbsProductData().isValid())
- return false;
-
- return prjNode->project()->renameFileInProduct(filePath, newFilePath,
- prdNode->qbsProductData(), m_qbsGroupData);
-}
-
FolderNode::AddNewInformation QbsGroupNode::addNewInformation(const QStringList &files,
Node *context) const
{
@@ -338,66 +272,6 @@ QbsProductNode::QbsProductNode(const qbs::ProductData &prd) :
}
}
-bool QbsProductNode::supportsAction(ProjectAction action, const Node *node) const
-{
- if (action == AddNewFile || action == AddExistingFile)
- return true;
-
- return supportsNodeAction(action, node);
-}
-
-bool QbsProductNode::addFiles(const QStringList &filePaths, QStringList *notAdded)
-{
- QStringList notAddedDummy;
- if (!notAdded)
- notAdded = &notAddedDummy;
-
- const QbsProjectNode *prjNode = parentQbsProjectNode(this);
- if (!prjNode || !prjNode->qbsProject().isValid()) {
- *notAdded += filePaths;
- return false;
- }
-
- qbs::GroupData grp = findMainQbsGroup(m_qbsProductData);
- if (grp.isValid()) {
- return prjNode->project()->addFilesToProduct(filePaths, m_qbsProductData, grp, notAdded);
- }
-
- QTC_ASSERT(false, return false);
-}
-
-RemovedFilesFromProject QbsProductNode::removeFiles(const QStringList &filePaths,
- QStringList *notRemoved)
-{
- QStringList notRemovedDummy;
- if (!notRemoved)
- notRemoved = &notRemovedDummy;
-
- const QbsProjectNode *prjNode = parentQbsProjectNode(this);
- if (!prjNode || !prjNode->qbsProject().isValid()) {
- *notRemoved += filePaths;
- return RemovedFilesFromProject::Error;
- }
-
- qbs::GroupData grp = findMainQbsGroup(m_qbsProductData);
- if (grp.isValid()) {
- return prjNode->project()->removeFilesFromProduct(filePaths, m_qbsProductData, grp,
- notRemoved);
- }
-
- QTC_ASSERT(false, return RemovedFilesFromProject::Error);
-}
-
-bool QbsProductNode::renameFile(const QString &filePath, const QString &newFilePath)
-{
- const QbsProjectNode * prjNode = parentQbsProjectNode(this);
- if (!prjNode || !prjNode->qbsProject().isValid())
- return false;
- const qbs::GroupData grp = findMainQbsGroup(m_qbsProductData);
- QTC_ASSERT(grp.isValid(), return false);
- return prjNode->project()->renameFileInProduct(filePath, newFilePath, m_qbsProductData, grp);
-}
-
void QbsProductNode::build()
{
QbsProjectManagerPlugin::buildNamedProduct(static_cast<QbsProject *>(getProject()),
@@ -487,5 +361,151 @@ QbsRootProjectNode::QbsRootProjectNode(QbsProject *project) :
m_project(project)
{ }
+// --------------------------------------------------------------------
+// QbsBuildSystem:
+// --------------------------------------------------------------------
+
+QbsBuildSystem::QbsBuildSystem(Project *project)
+ : BuildSystem(project)
+{
+}
+
+bool QbsBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
+{
+ if (dynamic_cast<QbsGroupNode *>(context)) {
+ if (action == AddNewFile || action == AddExistingFile)
+ return true;
+ }
+
+ if (dynamic_cast<QbsProductNode *>(context)) {
+ if (action == AddNewFile || action == AddExistingFile)
+ return true;
+ }
+
+ return supportsNodeAction(action, node);
+}
+
+bool QbsBuildSystem::addFiles(Node *context, const QStringList &filePaths, QStringList *notAdded)
+{
+ if (auto n = dynamic_cast<QbsGroupNode *>(context)) {
+ QStringList notAddedDummy;
+ if (!notAdded)
+ notAdded = &notAddedDummy;
+
+ const QbsProjectNode *prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !prjNode->qbsProject().isValid()) {
+ *notAdded += filePaths;
+ return false;
+ }
+
+ const QbsProductNode *prdNode = parentQbsProductNode(n);
+ if (!prdNode || !prdNode->qbsProductData().isValid()) {
+ *notAdded += filePaths;
+ return false;
+ }
+
+ return prjNode->project()->addFilesToProduct(filePaths, prdNode->qbsProductData(),
+ n->m_qbsGroupData, notAdded);
+ }
+
+ if (auto n = dynamic_cast<QbsProductNode *>(context)) {
+ QStringList notAddedDummy;
+ if (!notAdded)
+ notAdded = &notAddedDummy;
+
+ const QbsProjectNode *prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !prjNode->qbsProject().isValid()) {
+ *notAdded += filePaths;
+ return false;
+ }
+
+ qbs::GroupData grp = findMainQbsGroup(n->qbsProductData());
+ if (grp.isValid())
+ return prjNode->project()->addFilesToProduct(filePaths, n->qbsProductData(), grp, notAdded);
+
+ QTC_ASSERT(false, return false);
+ }
+
+ return BuildSystem::addFiles(context, filePaths, notAdded);
+}
+
+RemovedFilesFromProject QbsBuildSystem::removeFiles(Node *context, const QStringList &filePaths,
+ QStringList *notRemoved)
+{
+ if (auto n = dynamic_cast<QbsGroupNode *>(context)) {
+ QStringList notRemovedDummy;
+ if (!notRemoved)
+ notRemoved = &notRemovedDummy;
+
+ const QbsProjectNode *prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !prjNode->qbsProject().isValid()) {
+ *notRemoved += filePaths;
+ return RemovedFilesFromProject::Error;
+ }
+
+ const QbsProductNode *prdNode = parentQbsProductNode(n);
+ if (!prdNode || !prdNode->qbsProductData().isValid()) {
+ *notRemoved += filePaths;
+ return RemovedFilesFromProject::Error;
+ }
+
+ return project()->removeFilesFromProduct(filePaths, prdNode->qbsProductData(),
+ n->m_qbsGroupData, notRemoved);
+ }
+
+ if (auto n = dynamic_cast<QbsProductNode *>(context)) {
+ QStringList notRemovedDummy;
+ if (!notRemoved)
+ notRemoved = &notRemovedDummy;
+
+ const QbsProjectNode *prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !prjNode->qbsProject().isValid()) {
+ *notRemoved += filePaths;
+ return RemovedFilesFromProject::Error;
+ }
+
+ qbs::GroupData grp = findMainQbsGroup(n->qbsProductData());
+ if (grp.isValid()) {
+ return prjNode->project()->removeFilesFromProduct(filePaths, n->qbsProductData(), grp,
+ notRemoved);
+ }
+
+ QTC_ASSERT(false, return RemovedFilesFromProject::Error);
+ }
+
+ return BuildSystem::removeFiles(context, filePaths, notRemoved);
+}
+
+bool QbsBuildSystem::renameFile(Node *context, const QString &filePath, const QString &newFilePath)
+{
+ if (auto *n = dynamic_cast<QbsGroupNode *>(context)) {
+ const QbsProjectNode *prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !prjNode->qbsProject().isValid())
+ return false;
+ const QbsProductNode *prdNode = parentQbsProductNode(n);
+ if (!prdNode || !prdNode->qbsProductData().isValid())
+ return false;
+
+ return project()->renameFileInProduct(filePath, newFilePath,
+ prdNode->qbsProductData(), n->m_qbsGroupData);
+ }
+
+ if (auto *n = dynamic_cast<QbsProductNode *>(context)) {
+ const QbsProjectNode * prjNode = parentQbsProjectNode(n);
+ if (!prjNode || !prjNode->qbsProject().isValid())
+ return false;
+ const qbs::GroupData grp = findMainQbsGroup(n->qbsProductData());
+ QTC_ASSERT(grp.isValid(), return false);
+ return prjNode->project()->renameFileInProduct(filePath, newFilePath, n->qbsProductData(), grp);
+ }
+
+ return BuildSystem::renameFile(context, filePath, newFilePath);
+}
+
+QbsProject *QbsBuildSystem::project() const
+{
+ return static_cast<QbsProject *>(BuildSystem::project());
+}
+
} // namespace Internal
} // namespace QbsProjectManager
diff --git a/src/plugins/qbsprojectmanager/qbsnodes.h b/src/plugins/qbsprojectmanager/qbsnodes.h
index e31fc2b9b9..a2439dcdb6 100644
--- a/src/plugins/qbsprojectmanager/qbsnodes.h
+++ b/src/plugins/qbsprojectmanager/qbsnodes.h
@@ -25,6 +25,7 @@
#pragma once
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/projectnodes.h>
#include <qbs.h>
@@ -35,6 +36,26 @@ namespace Internal {
class QbsNodeTreeBuilder;
class QbsProject;
+class QbsBuildSystem : public ProjectExplorer::BuildSystem
+{
+public:
+ explicit QbsBuildSystem(ProjectExplorer::Project *project);
+
+ bool supportsAction(ProjectExplorer::Node *context,
+ ProjectExplorer::ProjectAction action,
+ const ProjectExplorer::Node *node) const final;
+ bool addFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths,
+ QStringList *notAdded = nullptr) override;
+ ProjectExplorer::RemovedFilesFromProject removeFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths,
+ QStringList *notRemoved = nullptr) override;
+ bool renameFile(ProjectExplorer::Node *context,
+ const QString &filePath, const QString &newFilePath) override;
+
+ QbsProject *project() const;
+};
+
// --------------------------------------------------------------------
// QbsGroupNode:
// --------------------------------------------------------------------
@@ -45,13 +66,9 @@ public:
QbsGroupNode(const qbs::GroupData &grp, const QString &productPath);
bool showInSimpleTree() const final { return false; }
- bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const final;
- bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override;
- ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths,
- QStringList *notRemoved = nullptr) override;
- bool renameFile(const QString &filePath, const QString &newFilePath) override;
private:
+ friend class QbsBuildSystem;
AddNewInformation addNewInformation(const QStringList &files, Node *context) const override;
QVariant data(Core::Id role) const override;
@@ -68,11 +85,6 @@ class QbsProductNode : public ProjectExplorer::ProjectNode
public:
explicit QbsProductNode(const qbs::ProductData &prd);
- bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const final;
- bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override;
- ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths,
- QStringList *notRemoved = nullptr) override;
- bool renameFile(const QString &filePath, const QString &newFilePath) override;
void build() override;
QStringList targetApplications() const override;
diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp
index 37e94751ff..ade70195c9 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.cpp
+++ b/src/plugins/qbsprojectmanager/qbsproject.cpp
@@ -135,6 +135,8 @@ QbsProject::QbsProject(const FilePath &fileName)
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
setCanBuildProducts();
+ setBuildSystemCreator([](Project *p) { return new QbsBuildSystem(p); });
+
rebuildProjectTree();
connect(this, &Project::activeTargetChanged, this, &QbsProject::changeActiveTarget);
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
index c2a15c9eaf..59c650e675 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
@@ -82,67 +82,76 @@ QmakeProFileNode *QmakePriFileNode::proFileNode() const
return m_qmakeProFileNode;
}
-bool QmakePriFileNode::supportsAction(ProjectAction action, const Node *node) const
+bool QmakeBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
{
- if (action == Rename) {
- const FileNode *fileNode = node->asFileNode();
- return (fileNode && fileNode->fileType() != FileType::Project)
- || dynamic_cast<const ResourceEditor::ResourceTopLevelNode *>(node);
- }
+ if (auto n = dynamic_cast<QmakePriFileNode *>(context)) { // Covers QmakeProfile, too.
+ if (action == Rename) {
+ const FileNode *fileNode = node->asFileNode();
+ return (fileNode && fileNode->fileType() != FileType::Project)
+ || dynamic_cast<const ResourceEditor::ResourceTopLevelNode *>(node);
+ }
- const FolderNode *folderNode = this;
- const QmakeProFileNode *proFileNode;
- while (!(proFileNode = dynamic_cast<const QmakeProFileNode*>(folderNode))) {
- folderNode = folderNode->parentFolderNode();
- QTC_ASSERT(folderNode, return false);
- }
- QTC_ASSERT(proFileNode, return false);
- const QmakeProFile *pro = proFileNode->proFile();
-
- switch (pro ? pro->projectType() : ProjectType::Invalid) {
- case ProjectType::ApplicationTemplate:
- case ProjectType::StaticLibraryTemplate:
- case ProjectType::SharedLibraryTemplate:
- case ProjectType::AuxTemplate: {
- // TODO: Some of the file types don't make much sense for aux
- // projects (e.g. cpp). It'd be nice if the "add" action could
- // work on a subset of the file types according to project type.
- if (action == AddNewFile)
- return true;
- if (action == EraseFile)
- return pro && pro->knowsFile(node->filePath());
- if (action == RemoveFile)
- return !(pro && pro->knowsFile(node->filePath()));
-
- bool addExistingFiles = true;
- if (node->isVirtualFolderType()) {
- // A virtual folder, we do what the projectexplorer does
- const FolderNode *folder = node->asFolderNode();
- if (folder) {
- QStringList list;
- foreach (FolderNode *f, folder->folderNodes())
- list << f->filePath().toString() + QLatin1Char('/');
- if (deploysFolder(Utils::commonPath(list)))
- addExistingFiles = false;
- }
+ const FolderNode *folderNode = n;
+ const QmakeProFileNode *proFileNode;
+ while (!(proFileNode = dynamic_cast<const QmakeProFileNode*>(folderNode))) {
+ folderNode = folderNode->parentFolderNode();
+ QTC_ASSERT(folderNode, return false);
}
+ QTC_ASSERT(proFileNode, return false);
+ const QmakeProFile *pro = proFileNode->proFile();
+
+ switch (pro ? pro->projectType() : ProjectType::Invalid) {
+ case ProjectType::ApplicationTemplate:
+ case ProjectType::StaticLibraryTemplate:
+ case ProjectType::SharedLibraryTemplate:
+ case ProjectType::AuxTemplate: {
+ // TODO: Some of the file types don't make much sense for aux
+ // projects (e.g. cpp). It'd be nice if the "add" action could
+ // work on a subset of the file types according to project type.
+ if (action == AddNewFile)
+ return true;
+ if (action == EraseFile)
+ return pro && pro->knowsFile(node->filePath());
+ if (action == RemoveFile)
+ return !(pro && pro->knowsFile(node->filePath()));
+
+ bool addExistingFiles = true;
+ if (node->isVirtualFolderType()) {
+ // A virtual folder, we do what the projectexplorer does
+ const FolderNode *folder = node->asFolderNode();
+ if (folder) {
+ QStringList list;
+ foreach (FolderNode *f, folder->folderNodes())
+ list << f->filePath().toString() + QLatin1Char('/');
+ if (n->deploysFolder(Utils::commonPath(list)))
+ addExistingFiles = false;
+ }
+ }
- addExistingFiles = addExistingFiles && !deploysFolder(node->filePath().toString());
+ addExistingFiles = addExistingFiles && !n->deploysFolder(node->filePath().toString());
- if (action == AddExistingFile || action == AddExistingDirectory)
- return addExistingFiles;
+ if (action == AddExistingFile || action == AddExistingDirectory)
+ return addExistingFiles;
- break;
+ break;
+ }
+ case ProjectType::SubDirsTemplate:
+ if (action == AddSubProject || action == AddExistingProject)
+ return true;
+ break;
+ default:
+ break;
+ }
+
+ return false;
}
- case ProjectType::SubDirsTemplate:
- if (action == AddSubProject || action == AddExistingProject)
- return true;
- break;
- default:
- break;
+
+ if (auto n = dynamic_cast<QmakeProFileNode *>(context)) {
+ if (action == RemoveSubProject)
+ return n->parentProjectNode() && !n->parentProjectNode()->asContainerNode();
}
- return false;
+ return BuildSystem::supportsAction(context, action, node);
}
bool QmakePriFileNode::canAddSubProject(const QString &proFilePath) const
@@ -168,80 +177,104 @@ QStringList QmakePriFileNode::subProjectFileNamePatterns() const
return QStringList("*.pro");
}
-bool QmakePriFileNode::addFiles(const QStringList &filePaths, QStringList *notAdded)
-{
- QmakePriFile *pri = priFile();
- if (!pri)
- return false;
- QList<Node *> matchingNodes = findNodes([filePaths](const Node *n) {
- return n->asFileNode() && filePaths.contains(n->filePath().toString());
- });
- matchingNodes = filtered(matchingNodes, [](const Node *n) {
- for (const Node *parent = n->parentFolderNode(); parent;
- parent = parent->parentFolderNode()) {
- if (dynamic_cast<const ResourceEditor::ResourceTopLevelNode *>(parent))
- return false;
- }
- return true;
- });
- QStringList alreadyPresentFiles = transform<QStringList>(matchingNodes,
- [](const Node *n) { return n->filePath().toString(); });
- alreadyPresentFiles.removeDuplicates();
- QStringList actualFilePaths = filePaths;
- for (const QString &e : alreadyPresentFiles)
- actualFilePaths.removeOne(e);
- if (notAdded)
- *notAdded = alreadyPresentFiles;
- return pri->addFiles(actualFilePaths, notAdded);
-}
-
-RemovedFilesFromProject QmakePriFileNode::removeFiles(const QStringList &filePaths,
+bool QmakeBuildSystem::addFiles(Node *context, const QStringList &filePaths, QStringList *notAdded)
+{
+ if (auto n = dynamic_cast<QmakePriFileNode *>(context)) {
+ QmakePriFile *pri = n->priFile();
+ if (!pri)
+ return false;
+ QList<Node *> matchingNodes = n->findNodes([filePaths](const Node *nn) {
+ return nn->asFileNode() && filePaths.contains(nn->filePath().toString());
+ });
+ matchingNodes = filtered(matchingNodes, [](const Node *n) {
+ for (const Node *parent = n->parentFolderNode(); parent;
+ parent = parent->parentFolderNode()) {
+ if (dynamic_cast<const ResourceEditor::ResourceTopLevelNode *>(parent))
+ return false;
+ }
+ return true;
+ });
+ QStringList alreadyPresentFiles = transform<QStringList>(matchingNodes,
+ [](const Node *n) { return n->filePath().toString(); });
+ alreadyPresentFiles.removeDuplicates();
+ QStringList actualFilePaths = filePaths;
+ for (const QString &e : alreadyPresentFiles)
+ actualFilePaths.removeOne(e);
+ if (notAdded)
+ *notAdded = alreadyPresentFiles;
+ return pri->addFiles(actualFilePaths, notAdded);
+ }
+
+ return BuildSystem::addFiles(context, filePaths, notAdded);
+}
+
+RemovedFilesFromProject QmakeBuildSystem::removeFiles(Node *context, const QStringList &filePaths,
QStringList *notRemoved)
{
- QmakePriFile * const pri = priFile();
- if (!pri)
- return RemovedFilesFromProject::Error;
- QStringList wildcardFiles;
- QStringList nonWildcardFiles;
- for (const QString &file : filePaths) {
- if (pri->proFile()->isFileFromWildcard(file))
- wildcardFiles << file;
- else
- nonWildcardFiles << file;
+ if (auto n = dynamic_cast<QmakePriFileNode *>(context)) {
+ QmakePriFile * const pri = n->priFile();
+ if (!pri)
+ return RemovedFilesFromProject::Error;
+ QStringList wildcardFiles;
+ QStringList nonWildcardFiles;
+ for (const QString &file : filePaths) {
+ if (pri->proFile()->isFileFromWildcard(file))
+ wildcardFiles << file;
+ else
+ nonWildcardFiles << file;
+ }
+ const bool success = pri->removeFiles(nonWildcardFiles, notRemoved);
+ if (notRemoved)
+ *notRemoved += wildcardFiles;
+ if (!success)
+ return RemovedFilesFromProject::Error;
+ if (!wildcardFiles.isEmpty())
+ return RemovedFilesFromProject::Wildcard;
+ return RemovedFilesFromProject::Ok;
}
- const bool success = pri->removeFiles(nonWildcardFiles, notRemoved);
- if (notRemoved)
- *notRemoved += wildcardFiles;
- if (!success)
- return RemovedFilesFromProject::Error;
- if (!wildcardFiles.isEmpty())
- return RemovedFilesFromProject::Wildcard;
- return RemovedFilesFromProject::Ok;
+
+ return BuildSystem::removeFiles(context, filePaths, notRemoved);
}
-bool QmakePriFileNode::deleteFiles(const QStringList &filePaths)
+bool QmakeBuildSystem::deleteFiles(Node *context, const QStringList &filePaths)
{
- QmakePriFile *pri = priFile();
- return pri ? pri->deleteFiles(filePaths) : false;
+ if (auto n = dynamic_cast<QmakePriFileNode *>(context)) {
+ QmakePriFile *pri = n->priFile();
+ return pri ? pri->deleteFiles(filePaths) : false;
+ }
+
+ return BuildSystem::deleteFiles(context, filePaths);
}
-bool QmakePriFileNode::canRenameFile(const QString &filePath, const QString &newFilePath)
+bool QmakeBuildSystem::canRenameFile(Node *context, const QString &filePath, const QString &newFilePath)
{
- QmakePriFile *pri = priFile();
- return pri ? pri->canRenameFile(filePath, newFilePath) : false;
+ if (auto n = dynamic_cast<QmakePriFileNode *>(context)) {
+ QmakePriFile *pri = n->priFile();
+ return pri ? pri->canRenameFile(filePath, newFilePath) : false;
+ }
+
+ return BuildSystem::canRenameFile(context, filePath, newFilePath);
}
-bool QmakePriFileNode::renameFile(const QString &filePath, const QString &newFilePath)
+bool QmakeBuildSystem::renameFile(Node *context, const QString &filePath, const QString &newFilePath)
{
- QmakePriFile *pri = priFile();
- return pri ? pri->renameFile(filePath, newFilePath) : false;
+ if (auto n = dynamic_cast<QmakePriFileNode *>(context)) {
+ QmakePriFile *pri = n->priFile();
+ return pri ? pri->renameFile(filePath, newFilePath) : false;
+ }
+
+ return BuildSystem::renameFile(context, filePath, newFilePath);
}
-bool QmakePriFileNode::addDependencies(const QStringList &dependencies)
+bool QmakeBuildSystem::addDependencies(Node *context, const QStringList &dependencies)
{
- if (QmakePriFile * const pri = priFile())
- return pri->addDependencies(dependencies);
- return false;
+ if (auto n = dynamic_cast<QmakePriFileNode *>(context)) {
+ if (QmakePriFile * const pri = n->priFile())
+ return pri->addDependencies(dependencies);
+ return false;
+ }
+
+ return BuildSystem::addDependencies(context, dependencies);
}
FolderNode::AddNewInformation QmakePriFileNode::addNewInformation(const QStringList &files, Node *context) const
@@ -405,13 +438,6 @@ bool QmakeProFileNode::includedInExactParse() const
return pro && pro->includedInExactParse();
}
-bool QmakeProFileNode::supportsAction(ProjectAction action, const Node *node) const
-{
- if (action == RemoveSubProject)
- return parentProjectNode() && !parentProjectNode()->asContainerNode();
- return QmakePriFileNode::supportsAction(action, node);
-}
-
FolderNode::AddNewInformation QmakeProFileNode::addNewInformation(const QStringList &files, Node *context) const
{
Q_UNUSED(files)
@@ -474,4 +500,9 @@ TargetInformation QmakeProFileNode::targetInformation() const
return proFile() ? proFile()->targetInformation() : TargetInformation();
}
+QmakeBuildSystem::QmakeBuildSystem(Project *project)
+ : BuildSystem(project)
+{
+}
+
} // namespace QmakeProjectManager
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h
index 7d9138615e..473f400620 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.h
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.h
@@ -28,6 +28,7 @@
#include "qmakeprojectmanager_global.h"
#include "qmakeparsernodes.h"
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/projectnodes.h>
namespace Utils { class FilePath; }
@@ -36,6 +37,31 @@ namespace QmakeProjectManager {
class QmakeProFileNode;
class QmakeProject;
+class QmakeBuildSystem : public ProjectExplorer::BuildSystem
+{
+public:
+ explicit QmakeBuildSystem(ProjectExplorer::Project *project);
+
+ bool supportsAction(ProjectExplorer::Node *context,
+ ProjectExplorer::ProjectAction action,
+ const ProjectExplorer::Node *node) const override;
+
+ bool addFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths,
+ QStringList *notAdded = nullptr) override;
+ ProjectExplorer::RemovedFilesFromProject removeFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths,
+ QStringList *notRemoved = nullptr) override;
+ bool deleteFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths) override;
+ bool canRenameFile(ProjectExplorer::Node *context,
+ const QString &filePath, const QString &newFilePath) override;
+ bool renameFile(ProjectExplorer::Node *context,
+ const QString &filePath, const QString &newFilePath) override;
+ bool addDependencies(ProjectExplorer::Node *context,
+ const QStringList &dependencies) override;
+};
+
// Implements ProjectNode for qmake .pri files
class QMAKEPROJECTMANAGER_EXPORT QmakePriFileNode : public ProjectExplorer::ProjectNode
{
@@ -45,9 +71,6 @@ public:
QmakePriFile *priFile() const;
- // ProjectNode interface
- bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
-
bool showInSimpleTree() const override { return false; }
bool canAddSubProject(const QString &proFilePath) const override;
@@ -55,13 +78,6 @@ public:
bool removeSubProject(const QString &proFilePath) override;
QStringList subProjectFileNamePatterns() const override;
- bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override;
- ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths,
- QStringList *notRemoved = nullptr) override;
- bool deleteFiles(const QStringList &filePaths) override;
- bool canRenameFile(const QString &filePath, const QString &newFilePath) override;
- bool renameFile(const QString &filePath, const QString &newFilePath) override;
- bool addDependencies(const QStringList &dependencies) override;
AddNewInformation addNewInformation(const QStringList &files, Node *context) const override;
bool deploysFolder(const QString &folder) const override;
@@ -92,7 +108,6 @@ public:
bool isQtcRunnable() const;
bool includedInExactParse() const;
- bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
bool showInSimpleTree() const override;
QString buildKey() const override;
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
index 2865841453..01916251c7 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
@@ -145,6 +145,7 @@ QmakeProject::QmakeProject(const FilePath &fileName) :
this, &QmakeProject::buildFinished);
setPreferredKitPredicate([this](const Kit *kit) -> bool { return matchesKit(kit); });
+ setBuildSystemCreator([](Project *p) { return new QmakeBuildSystem(p); });
}
QmakeProject::~QmakeProject()
@@ -476,8 +477,8 @@ void QmakeProject::decrementPendingEvaluateFutures()
// After being done, we need to call:
m_asyncUpdateState = Base;
- updateCodeModels();
updateBuildSystemData();
+ updateCodeModels();
if (activeTarget())
activeTarget()->updateDefaultDeployConfigurations();
m_guard.markAsSuccess(); // Qmake always returns (some) data, even when it failed:-)
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
index 962fd13b31..7949d21f72 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
@@ -54,7 +54,7 @@ static bool isShadowBuild(BuildConfiguration *bc)
}
QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc)
- : NamedWidget(),
+ : NamedWidget(tr("General")),
m_buildConfiguration(bc)
{
Project *project = bc->target()->project();
@@ -164,8 +164,6 @@ QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc)
connect(m_buildConfiguration, &QmakeBuildConfiguration::qmakeBuildConfigurationChanged,
this, &QmakeProjectConfigWidget::updateProblemLabel);
- setDisplayName(tr("General"));
-
updateDetails();
updateProblemLabel();
}
diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp
index 4f23154945..5adc18347c 100644
--- a/src/plugins/qmldesigner/components/integration/designdocument.cpp
+++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp
@@ -76,7 +76,7 @@ DesignDocument::DesignDocument(QObject *parent) :
m_subComponentManager(new SubComponentManager(m_documentModel.data(), this)),
m_rewriterView (new RewriterView(RewriterView::Amend, m_documentModel.data())),
m_documentLoaded(false),
- m_currentKit(nullptr)
+ m_currentTarget(nullptr)
{
}
@@ -216,9 +216,9 @@ Utils::FilePath DesignDocument::fileName() const
return Utils::FilePath();
}
-Kit *DesignDocument::currentKit() const
+ProjectExplorer::Target *DesignDocument::currentTarget() const
{
- return m_currentKit;
+ return m_currentTarget;
}
bool DesignDocument::isDocumentLoaded() const
@@ -551,8 +551,8 @@ void DesignDocument::setEditor(Core::IEditor *editor)
connect(editor->document(), &Core::IDocument::filePathChanged,
this, &DesignDocument::updateFileName);
- updateActiveQtVersion();
- updateCurrentProject();
+ updateActiveTarget();
+ updateActiveTarget();
}
Core::IEditor *DesignDocument::editor() const
@@ -594,53 +594,38 @@ void DesignDocument::redo()
viewManager().resetPropertyEditorView();
}
-static inline Kit *getActiveKit(DesignDocument *designDocument)
+static Target *getActiveTarget(DesignDocument *designDocument)
{
- ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile(designDocument->fileName());
+ Project *currentProject = SessionManager::projectForFile(designDocument->fileName());
if (!currentProject)
- currentProject = ProjectExplorer::ProjectTree::currentProject();
+ currentProject = ProjectTree::currentProject();
if (!currentProject)
return nullptr;
QObject::connect(ProjectTree::instance(), &ProjectTree::currentProjectChanged,
- designDocument, &DesignDocument::updateActiveQtVersion, Qt::UniqueConnection);
+ designDocument, &DesignDocument::updateActiveTarget, Qt::UniqueConnection);
QObject::connect(currentProject, &Project::activeTargetChanged,
- designDocument, &DesignDocument::updateActiveQtVersion, Qt::UniqueConnection);
-
- QObject::connect(ProjectTree::instance(), &ProjectTree::currentProjectChanged,
- designDocument, &DesignDocument::updateCurrentProject, Qt::UniqueConnection);
-
- QObject::connect(currentProject, &Project::activeTargetChanged,
- designDocument, &DesignDocument::updateCurrentProject, Qt::UniqueConnection);
-
+ designDocument, &DesignDocument::updateActiveTarget, Qt::UniqueConnection);
Target *target = currentProject->activeTarget();
- if (!target)
+ if (!target || !target->kit()->isValid())
return nullptr;
- if (!target->kit() || !target->kit()->isValid())
- return nullptr;
QObject::connect(target, &Target::kitChanged,
- designDocument, &DesignDocument::updateActiveQtVersion, Qt::UniqueConnection);
+ designDocument, &DesignDocument::updateActiveTarget, Qt::UniqueConnection);
- return target->kit();
+ return target;
}
-void DesignDocument::updateActiveQtVersion()
+void DesignDocument::updateActiveTarget()
{
- m_currentKit = getActiveKit(this);
- viewManager().setNodeInstanceViewKit(m_currentKit);
-}
-
-void DesignDocument::updateCurrentProject()
-{
- ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile(fileName());
- viewManager().setNodeInstanceViewProject(currentProject);
+ m_currentTarget = getActiveTarget(this);
+ viewManager().setNodeInstanceViewTarget(m_currentTarget);
}
void DesignDocument::contextHelp(const Core::IContext::HelpCallback &callback) const
diff --git a/src/plugins/qmldesigner/components/integration/designdocument.h b/src/plugins/qmldesigner/components/integration/designdocument.h
index eba0cf4060..7e8509eb4d 100644
--- a/src/plugins/qmldesigner/components/integration/designdocument.h
+++ b/src/plugins/qmldesigner/components/integration/designdocument.h
@@ -39,12 +39,11 @@
#include <QStackedWidget>
QT_BEGIN_NAMESPACE
-class QWidget;
class QPlainTextEdit;
QT_END_NAMESPACE
namespace ProjectExplorer {
-class Kit;
+class Target;
}
namespace QmlDesigner {
@@ -91,7 +90,7 @@ public:
TextEditor::BaseTextEditor *textEditor() const;
QPlainTextEdit *plainTextEdit() const;
Utils::FilePath fileName() const;
- ProjectExplorer::Kit *currentKit() const;
+ ProjectExplorer::Target *currentTarget() const;
bool isDocumentLoaded() const;
void resetToDocumentModel();
@@ -115,8 +114,7 @@ public:
void selectAll();
void undo();
void redo();
- void updateActiveQtVersion();
- void updateCurrentProject();
+ void updateActiveTarget();
void changeToSubComponent(const ModelNode &componentNode);
void changeToMaster();
@@ -152,7 +150,7 @@ private: // variables
QScopedPointer<RewriterView> m_rewriterView;
bool m_documentLoaded;
- ProjectExplorer::Kit *m_currentKit;
+ ProjectExplorer::Target *m_currentTarget;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
index a2aa30f40a..ba2f6b283c 100644
--- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
+++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
@@ -40,16 +40,8 @@
#include <QRectF>
#include <QTime>
-QT_BEGIN_NAMESPACE
-class QDeclarativeEngine;
-class QGraphicsView;
-class QFileSystemWatcher;
-class QPainter;
-QT_END_NAMESPACE
-
namespace ProjectExplorer {
-class Kit;
-class Project;
+class Target;
}
namespace QmlDesigner {
@@ -131,8 +123,7 @@ public:
QImage statePreviewImage(const ModelNode &stateNode) const;
- void setKit(ProjectExplorer::Kit *kit);
- void setProject(ProjectExplorer::Project *project);
+ void setTarget(ProjectExplorer::Target *newTarget);
void sendToken(const QString &token, int number, const QVector<ModelNode> &nodeVector);
@@ -208,8 +199,7 @@ private: //variables
QImage m_baseStatePreviewImage;
QElapsedTimer m_lastCrashTime;
NodeInstanceServerInterface::RunModus m_runModus;
- ProjectExplorer::Kit *m_currentKit = nullptr;
- ProjectExplorer::Project *m_currentProject = nullptr;
+ ProjectExplorer::Target *m_currentTarget = nullptr;
int m_restartProcessTimerId;
RewriterTransaction m_puppetTransaction;
};
diff --git a/src/plugins/qmldesigner/designercore/include/viewmanager.h b/src/plugins/qmldesigner/designercore/include/viewmanager.h
index 71c869916e..8f1ccbfe08 100644
--- a/src/plugins/qmldesigner/designercore/include/viewmanager.h
+++ b/src/plugins/qmldesigner/designercore/include/viewmanager.h
@@ -32,8 +32,7 @@
#include <utils/fileutils.h>
namespace ProjectExplorer {
-class Kit;
-class Project;
+class Target;
}
namespace QmlDesigner {
@@ -66,8 +65,7 @@ public:
void setItemLibraryViewResourcePath(const QString &resourcePath);
void setComponentNode(const ModelNode &componentNode);
void setComponentViewToMaster();
- void setNodeInstanceViewKit(ProjectExplorer::Kit *kit);
- void setNodeInstanceViewProject(ProjectExplorer::Project *project);
+ void setNodeInstanceViewTarget(ProjectExplorer::Target *target);
void resetPropertyEditorView();
diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp
index 3d57b3a16a..025402f7bc 100644
--- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp
+++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp
@@ -103,8 +103,7 @@ void NodeInstanceServerProxy::showCannotConnectToPuppetWarningAndSwitchToEditMod
NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceView,
RunModus runModus,
- ProjectExplorer::Kit *kit,
- ProjectExplorer::Project *project)
+ ProjectExplorer::Target *target)
: NodeInstanceServerInterface(nodeInstanceView),
m_localServer(new QLocalServer(this)),
m_nodeInstanceView(nodeInstanceView),
@@ -117,7 +116,7 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV
m_localServer->listen(socketToken);
m_localServer->setMaxPendingConnections(3);
- PuppetCreator puppetCreator(kit, project, nodeInstanceView->model());
+ PuppetCreator puppetCreator(target, nodeInstanceView->model());
puppetCreator.setQrcMappingString(qrcMappingString());
puppetCreator.createQml2PuppetExecutableIfMissing();
diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h
index a6a7f6ce99..b79857d925 100644
--- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h
+++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h
@@ -40,8 +40,7 @@ class QProcess;
QT_END_NAMESPACE
namespace ProjectExplorer {
-class Kit;
-class Project;
+class Target;
}
namespace QmlDesigner {
@@ -63,8 +62,7 @@ public:
explicit NodeInstanceServerProxy(NodeInstanceView *nodeInstanceView,
RunModus runModus,
- ProjectExplorer::Kit *kit,
- ProjectExplorer::Project *project);
+ ProjectExplorer::Target *target);
~NodeInstanceServerProxy() override;
void createInstances(const CreateInstancesCommand &command) override;
void changeFileUrl(const ChangeFileUrlCommand &command) override;
diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
index fd17c83551..899dc5caee 100644
--- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
+++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
@@ -123,7 +123,7 @@ NodeInstanceView::~NodeInstanceView()
{
removeAllInstanceNodeRelationships();
delete nodeInstanceServer();
- m_currentKit = nullptr;
+ m_currentTarget = nullptr;
}
//\{
@@ -173,7 +173,7 @@ bool static parentTakesOverRendering(const ModelNode &modelNode)
void NodeInstanceView::modelAttached(Model *model)
{
AbstractView::modelAttached(model);
- auto server = new NodeInstanceServerProxy(this, m_runModus, m_currentKit, m_currentProject);
+ auto server = new NodeInstanceServerProxy(this, m_runModus, m_currentTarget);
m_nodeInstanceServer = server;
m_lastCrashTime.start();
connect(server, &NodeInstanceServerProxy::processCrashed, this, &NodeInstanceView::handleCrash);
@@ -256,7 +256,7 @@ void NodeInstanceView::restartProcess()
if (model()) {
delete nodeInstanceServer();
- auto server = new NodeInstanceServerProxy(this, m_runModus, m_currentKit, m_currentProject);
+ auto server = new NodeInstanceServerProxy(this, m_runModus, m_currentTarget);
m_nodeInstanceServer = server;
connect(server, &NodeInstanceServerProxy::processCrashed, this, &NodeInstanceView::handleCrash);
@@ -1304,18 +1304,10 @@ QImage NodeInstanceView::statePreviewImage(const ModelNode &stateNode) const
return m_statePreviewImage.value(stateNode);
}
-void NodeInstanceView::setKit(ProjectExplorer::Kit *newKit)
+void NodeInstanceView::setTarget(ProjectExplorer::Target *newTarget)
{
- if (m_currentKit != newKit) {
- m_currentKit = newKit;
- restartProcess();
- }
-}
-
-void NodeInstanceView::setProject(ProjectExplorer::Project *project)
-{
- if (m_currentProject != project) {
- m_currentProject = project;
+ if (m_currentTarget != newTarget) {
+ m_currentTarget = newTarget;
restartProcess();
}
}
diff --git a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp
index adf962c2cc..a577abc3a2 100644
--- a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp
+++ b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp
@@ -90,7 +90,7 @@ QHash<Core::Id, PuppetCreator::PuppetType> PuppetCreator::m_qml2PuppetForKitPupp
QByteArray PuppetCreator::qtHash() const
{
- QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitAspect::qtVersion(m_kit);
+ QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitAspect::qtVersion(m_target->kit());
if (currentQtVersion) {
return QCryptographicHash::hash(currentQtVersion->dataPath().toString().toUtf8(),
QCryptographicHash::Sha1)
@@ -102,7 +102,7 @@ QByteArray PuppetCreator::qtHash() const
QDateTime PuppetCreator::qtLastModified() const
{
- QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitAspect::qtVersion(m_kit);
+ QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitAspect::qtVersion(m_target->kit());
if (currentQtVersion)
return currentQtVersion->libraryPath().toFileInfo().lastModified();
@@ -140,10 +140,10 @@ QDateTime PuppetCreator::puppetSourceLastModified() const
bool PuppetCreator::useOnlyFallbackPuppet() const
{
#ifndef QMLDESIGNER_TEST
- if (!m_kit || !m_kit->isValid())
+ if (!m_target || !m_target->kit()->isValid())
qWarning() << "Invalid kit for QML puppet";
- return m_designerSettings.value(DesignerSettingsKey::USE_DEFAULT_PUPPET
- ).toBool() || m_kit == nullptr || !m_kit->isValid();
+ return m_designerSettings.value(DesignerSettingsKey::USE_DEFAULT_PUPPET).toBool()
+ || m_target == nullptr || !m_target->kit()->isValid();
#else
return true;
#endif
@@ -152,8 +152,8 @@ bool PuppetCreator::useOnlyFallbackPuppet() const
QString PuppetCreator::getStyleConfigFileName() const
{
#ifndef QMLDESIGNER_TEST
- if (m_currentProject) {
- for (const Utils::FilePath &fileName : m_currentProject->files(ProjectExplorer::Project::SourceFiles)) {
+ if (m_target) {
+ for (const Utils::FilePath &fileName : m_target->project()->files(ProjectExplorer::Project::SourceFiles)) {
if (fileName.fileName() == "qtquickcontrols2.conf")
return fileName.toString();
}
@@ -162,17 +162,14 @@ QString PuppetCreator::getStyleConfigFileName() const
return QString();
}
-PuppetCreator::PuppetCreator(ProjectExplorer::Kit *kit,
- ProjectExplorer::Project *project,
- const Model *model)
+PuppetCreator::PuppetCreator(ProjectExplorer::Target *target, const Model *model)
- : m_kit(kit)
+ : m_target(target)
, m_availablePuppetType(FallbackPuppet)
, m_model(model)
#ifndef QMLDESIGNER_TEST
, m_designerSettings(QmlDesignerPlugin::instance()->settings())
#endif
- , m_currentProject(project)
{
}
@@ -330,18 +327,18 @@ void PuppetCreator::createQml2PuppetExecutableIfMissing()
if (!useOnlyFallbackPuppet()) {
// check if there was an already failing try to get the UserSpacePuppet
// -> imagine as result a FallbackPuppet and nothing will happen again
- if (m_qml2PuppetForKitPuppetHash.value(m_kit->id(), UserSpacePuppet) == UserSpacePuppet ) {
+ if (m_qml2PuppetForKitPuppetHash.value(m_target->id(), UserSpacePuppet) == UserSpacePuppet ) {
if (checkPuppetIsReady(qml2PuppetPath(UserSpacePuppet))) {
m_availablePuppetType = UserSpacePuppet;
} else {
- if (m_kit->isValid()) {
+ if (m_target->kit()->isValid()) {
bool buildSucceeded = build(qml2PuppetProjectFile());
if (buildSucceeded)
m_availablePuppetType = UserSpacePuppet;
} else {
warnAboutInvalidKit();
}
- m_qml2PuppetForKitPuppetHash.insert(m_kit->id(), m_availablePuppetType);
+ m_qml2PuppetForKitPuppetHash.insert(m_target->id(), m_availablePuppetType);
}
}
}
@@ -418,8 +415,8 @@ QProcessEnvironment PuppetCreator::processEnvironment() const
static const QString pathSep = Utils::HostOsInfo::pathListSeparator();
Utils::Environment environment = Utils::Environment::systemEnvironment();
if (!useOnlyFallbackPuppet())
- m_kit->addToEnvironment(environment);
- const QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(m_kit);
+ m_target->kit()->addToEnvironment(environment);
+ const QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(m_target->kit());
if (QTC_GUARD(qt)) { // Kits without a Qt version should not have a puppet!
// Update PATH to include QT_HOST_BINS
const Utils::FilePath qtBinPath = qt->hostBinPath();
@@ -490,13 +487,11 @@ QProcessEnvironment PuppetCreator::processEnvironment() const
QStringList customFileSelectors;
- if (m_currentProject && m_currentProject->activeTarget()) {
- QStringList designerImports = m_currentProject->activeTarget()
- ->additionalData("QmlDesignerImportPath").toStringList();
+ if (m_target) {
+ QStringList designerImports = m_target->additionalData("QmlDesignerImportPath").toStringList();
importPaths.append(designerImports);
- customFileSelectors = m_currentProject->activeTarget()
- ->additionalData("CustomFileSelectorsData").toStringList();
+ customFileSelectors = m_target->additionalData("CustomFileSelectorsData").toStringList();
}
if (m_availablePuppetType == FallbackPuppet)
@@ -519,10 +514,10 @@ QProcessEnvironment PuppetCreator::processEnvironment() const
QString PuppetCreator::buildCommand() const
{
Utils::Environment environment = Utils::Environment::systemEnvironment();
- m_kit->addToEnvironment(environment);
+ m_target->kit()->addToEnvironment(environment);
ProjectExplorer::ToolChain *toolChain
- = ProjectExplorer::ToolChainKitAspect::toolChain(m_kit,
+ = ProjectExplorer::ToolChainKitAspect::toolChain(m_target->kit(),
ProjectExplorer::Constants::CXX_LANGUAGE_ID);
if (toolChain)
@@ -533,7 +528,7 @@ QString PuppetCreator::buildCommand() const
QString PuppetCreator::qmakeCommand() const
{
- QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitAspect::qtVersion(m_kit);
+ QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitAspect::qtVersion(m_target->kit());
if (currentQtVersion)
return currentQtVersion->qmakeCommand().toString();
@@ -620,7 +615,7 @@ static bool nonEarlyQt5Version(const QtSupport::QtVersionNumber &currentQtVersio
bool PuppetCreator::qtIsSupported() const
{
- QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitAspect::qtVersion(m_kit);
+ QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitAspect::qtVersion(m_target->kit());
return currentQtVersion
&& currentQtVersion->isValid()
diff --git a/src/plugins/qmldesigner/designercore/instances/puppetcreator.h b/src/plugins/qmldesigner/designercore/instances/puppetcreator.h
index 8cde9692ad..d11a798a31 100644
--- a/src/plugins/qmldesigner/designercore/instances/puppetcreator.h
+++ b/src/plugins/qmldesigner/designercore/instances/puppetcreator.h
@@ -33,8 +33,7 @@
#include <coreplugin/id.h>
namespace ProjectExplorer {
-class Kit;
-class Project;
+class Target;
} // namespace ProjectExplorer
namespace QmlDesigner {
@@ -50,9 +49,7 @@ public:
UserSpacePuppet
};
- PuppetCreator(ProjectExplorer::Kit *kit,
- ProjectExplorer::Project *project,
- const Model *model);
+ PuppetCreator(ProjectExplorer::Target *target, const Model *model);
void createQml2PuppetExecutableIfMissing();
@@ -106,7 +103,7 @@ protected:
private:
mutable QString m_compileLog;
- ProjectExplorer::Kit *m_kit = nullptr;
+ ProjectExplorer::Target *m_target = nullptr;
PuppetType m_availablePuppetType;
static QHash<Core::Id, PuppetType> m_qml2PuppetForKitPuppetHash;
const Model *m_model = nullptr;
@@ -114,7 +111,6 @@ private:
const DesignerSettings m_designerSettings;
#endif
QString m_qrcMapping;
- ProjectExplorer::Project *m_currentProject = nullptr;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp
index 989ea8dbb4..65d7616484 100644
--- a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp
+++ b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp
@@ -109,7 +109,7 @@ void ViewManager::attachNodeInstanceView()
qCInfo(viewBenchmark) << Q_FUNC_INFO;
- setNodeInstanceViewKit(currentDesignDocument()->currentKit());
+ setNodeInstanceViewTarget(currentDesignDocument()->currentTarget());
currentModel()->setNodeInstanceView(&d->nodeInstanceView);
qCInfo(viewBenchmark) << "NodeInstanceView:" << time.elapsed();
@@ -328,14 +328,9 @@ void ViewManager::setComponentViewToMaster()
d->componentView.setComponentToMaster();
}
-void ViewManager::setNodeInstanceViewKit(ProjectExplorer::Kit *kit)
+void ViewManager::setNodeInstanceViewTarget(ProjectExplorer::Target *target)
{
- d->nodeInstanceView.setKit(kit);
-}
-
-void QmlDesigner::ViewManager::setNodeInstanceViewProject(ProjectExplorer::Project *project)
-{
- d->nodeInstanceView.setProject(project);
+ d->nodeInstanceView.setTarget(target);
}
QList<WidgetInfo> ViewManager::widgetInfos() const
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp
index 928c19b02c..2dbf40a7bb 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.cpp
+++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp
@@ -436,8 +436,8 @@ void QmlDesignerPlugin::activateAutoSynchronization()
if (!currentDesignDocument()->isDocumentLoaded())
currentDesignDocument()->loadDocument(currentDesignDocument()->plainTextEdit());
- currentDesignDocument()->updateActiveQtVersion();
- currentDesignDocument()->updateCurrentProject();
+ currentDesignDocument()->updateActiveTarget();
+ currentDesignDocument()->updateActiveTarget();
d->mainWidget.enableWidgets();
currentDesignDocument()->attachRewriterToModel();
diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp
index b33846faf9..e5b9014543 100644
--- a/src/plugins/qmljstools/qmljsmodelmanager.cpp
+++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp
@@ -41,6 +41,7 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/projecttree.h>
+#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/session.h>
#include <projectexplorer/target.h>
#include <qmljs/qmljsbind.h>
@@ -76,10 +77,36 @@ using namespace QmlJS;
namespace QmlJSTools {
namespace Internal {
+static void setupProjectInfoQmlBundles(ModelManagerInterface::ProjectInfo &projectInfo)
+{
+ Target *activeTarget = nullptr;
+ if (projectInfo.project)
+ activeTarget = projectInfo.project->activeTarget();
+ Kit *activeKit = activeTarget ? activeTarget->kit() : KitManager::defaultKit();
+ const QHash<QString, QString> replacements = {{QLatin1String("$(QT_INSTALL_QML)"), projectInfo.qtQmlPath}};
+
+ for (IBundleProvider *bp : IBundleProvider::allBundleProviders())
+ bp->mergeBundlesForKit(activeKit, projectInfo.activeBundle, replacements);
+
+ projectInfo.extendedBundle = projectInfo.activeBundle;
+
+ if (projectInfo.project) {
+ QSet<Kit *> currentKits;
+ foreach (const Target *t, projectInfo.project->targets())
+ currentKits.insert(t->kit());
+ currentKits.remove(activeKit);
+ foreach (Kit *kit, currentKits) {
+ for (IBundleProvider *bp : IBundleProvider::allBundleProviders())
+ bp->mergeBundlesForKit(kit, projectInfo.extendedBundle, replacements);
+ }
+ }
+}
+
ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject(
Project *project) const
{
- ModelManagerInterface::ProjectInfo projectInfo(project);
+ ModelManagerInterface::ProjectInfo projectInfo;
+ projectInfo.project = project;
projectInfo.qmlDumpEnvironment = Utils::Environment::systemEnvironment();
Target *activeTarget = nullptr;
if (project) {
@@ -113,6 +140,13 @@ ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject(
// plugins that are not installed in default Qt qml installation directory.
projectInfo.qmlDumpEnvironment.appendOrSet("QML2_IMPORT_PATH", bc->environment().expandedValueForKey("QML2_IMPORT_PATH"), ":");
}
+
+ const auto appTargets = activeTarget->applicationTargets();
+ for (const auto &target : appTargets) {
+ if (target.targetFilePath.isEmpty())
+ continue;
+ projectInfo.applicationDirectories.append(target.targetFilePath.parentDir().toString());
+ }
}
if (!setPreferDump && qtVersion)
preferDebugDump = (qtVersion->defaultBuildConfig() & QtSupport::BaseQtVersion::DebugBuild);
@@ -139,35 +173,6 @@ ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject(
return projectInfo;
}
-} // namespace Internal
-
-void setupProjectInfoQmlBundles(ModelManagerInterface::ProjectInfo &projectInfo)
-{
- Target *activeTarget = nullptr;
- if (projectInfo.project)
- activeTarget = projectInfo.project->activeTarget();
- Kit *activeKit = activeTarget ? activeTarget->kit() : KitManager::defaultKit();
- const QHash<QString, QString> replacements = {{QLatin1String("$(QT_INSTALL_QML)"), projectInfo.qtQmlPath}};
-
- for (IBundleProvider *bp : IBundleProvider::allBundleProviders())
- bp->mergeBundlesForKit(activeKit, projectInfo.activeBundle, replacements);
-
- projectInfo.extendedBundle = projectInfo.activeBundle;
-
- if (projectInfo.project) {
- QSet<Kit *> currentKits;
- foreach (const Target *t, projectInfo.project->targets())
- currentKits.insert(t->kit());
- currentKits.remove(activeKit);
- foreach (Kit *kit, currentKits) {
- for (IBundleProvider *bp : IBundleProvider::allBundleProviders())
- bp->mergeBundlesForKit(kit, projectInfo.extendedBundle, replacements);
- }
- }
-}
-
-namespace Internal {
-
QHash<QString,Dialect> ModelManager::initLanguageForSuffix() const
{
QHash<QString,Dialect> res = ModelManagerInterface::languageForSuffix();
@@ -224,7 +229,7 @@ void ModelManager::delayedInitialization()
ViewerContext qbsVContext;
qbsVContext.language = Dialect::QmlQbs;
- qbsVContext.maybeAddPath(ICore::resourcePath() + QLatin1String("/qbs"));
+ qbsVContext.paths.append(ICore::resourcePath() + QLatin1String("/qbs"));
setDefaultVContext(qbsVContext);
}
@@ -267,13 +272,15 @@ void ModelManager::updateDefaultProjectInfo()
{
// needs to be performed in the ui thread
Project *currentProject = SessionManager::startupProject();
- ProjectInfo newDefaultProjectInfo = projectInfo(currentProject,
- defaultProjectInfoForProject(currentProject));
- setDefaultProject(projectInfo(currentProject,newDefaultProjectInfo), currentProject);
+ setDefaultProject(containsProject(currentProject)
+ ? projectInfo(currentProject)
+ : defaultProjectInfoForProject(currentProject),
+ currentProject);
}
-void ModelManager::addTaskInternal(QFuture<void> result, const QString &msg, const char *taskId) const
+void ModelManager::addTaskInternal(const QFuture<void> &result, const QString &msg,
+ const char *taskId) const
{
ProgressManager::addTask(result, msg, taskId);
}
diff --git a/src/plugins/qmljstools/qmljsmodelmanager.h b/src/plugins/qmljstools/qmljsmodelmanager.h
index 678882ec3a..ae31fe6282 100644
--- a/src/plugins/qmljstools/qmljsmodelmanager.h
+++ b/src/plugins/qmljstools/qmljsmodelmanager.h
@@ -54,7 +54,8 @@ protected:
QHash<QString, QmlJS::Dialect> languageForSuffix() const override;
void writeMessageInternal(const QString &msg) const override;
WorkingCopy workingCopyInternal() const override;
- void addTaskInternal(QFuture<void> result, const QString &msg, const char *taskId) const override;
+ void addTaskInternal(const QFuture<void> &result, const QString &msg,
+ const char *taskId) const override;
ProjectInfo defaultProjectInfoForProject(ProjectExplorer::Project *project) const override;
private:
void updateDefaultProjectInfo();
@@ -64,6 +65,4 @@ private:
} // namespace Internal
-QMLJSTOOLS_EXPORT void setupProjectInfoQmlBundles(QmlJS::ModelManagerInterface::ProjectInfo &projectInfo);
-
} // namespace QmlJSTools
diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp
index d3d96c20ce..d227db6fe5 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ b/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -67,6 +67,7 @@ QmlProject::QmlProject(const Utils::FilePath &fileName)
setDisplayName(fileName.toFileInfo().completeBaseName());
setNeedsBuildConfigurations(false);
+ setBuildSystemCreator([](Project *p) { return new Internal::QmlBuildSystem(p); });
connect(this, &QmlProject::projectFileIsDirty, this, &QmlProject::refreshProjectFile);
}
@@ -398,5 +399,6 @@ void QmlProject::updateDeploymentData(ProjectExplorer::Target *target)
target->setDeploymentData(deploymentData);
}
+
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h
index 9b09cbd528..d911d7946e 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.h
+++ b/src/plugins/qmlprojectmanager/qmlproject.h
@@ -28,6 +28,7 @@
#include "qmlprojectmanager_global.h"
#include "qmlprojectnodes.h"
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h>
#include <utils/environment.h>
@@ -38,8 +39,31 @@ namespace ProjectExplorer { class RunConfiguration; }
namespace QmlProjectManager {
+class QmlProject;
class QmlProjectItem;
+namespace Internal {
+
+class QmlBuildSystem : public ProjectExplorer::BuildSystem
+{
+public:
+ explicit QmlBuildSystem(ProjectExplorer::Project *project) : BuildSystem(project) {}
+
+ bool supportsAction(ProjectExplorer::Node *context,
+ ProjectExplorer::ProjectAction action,
+ const ProjectExplorer::Node *node) const override;
+ bool addFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths, QStringList *notAdded = nullptr) override;
+ bool deleteFiles(ProjectExplorer::Node *context,
+ const QStringList &filePaths) override;
+ bool renameFile(ProjectExplorer::Node *context,
+ const QString &filePath, const QString &newFilePath) override;
+
+ QmlProject *project() const;
+};
+
+} // Internal
+
class QMLPROJECTMANAGER_EXPORT QmlProject : public ProjectExplorer::Project
{
Q_OBJECT
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
index a4494e7064..2d7a4daddb 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
@@ -53,71 +53,90 @@ QmlProjectNode::QmlProjectNode(QmlProject *project) : ProjectNode(project->proje
setIcon(qmlProjectIcon);
}
-bool QmlProjectNode::supportsAction(ProjectAction action, const Node *node) const
+bool QmlBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
{
- if (action == AddNewFile || action == EraseFile)
- return true;
- QTC_ASSERT(node, return false);
+ if (dynamic_cast<QmlProjectNode *>(context)) {
+ if (action == AddNewFile || action == EraseFile)
+ return true;
+ QTC_ASSERT(node, return false);
+
+ if (action == Rename && node->asFileNode()) {
+ const FileNode *fileNode = node->asFileNode();
+ QTC_ASSERT(fileNode, return false);
+ return fileNode->fileType() != FileType::Project;
+ }
- if (action == Rename && node->asFileNode()) {
- const FileNode *fileNode = node->asFileNode();
- QTC_ASSERT(fileNode, return false);
- return fileNode->fileType() != FileType::Project;
+ return false;
}
- return false;
+ return BuildSystem::supportsAction(context, action, node);
}
-bool QmlProjectNode::addFiles(const QStringList &filePaths, QStringList * /*notAdded*/)
+QmlProject *QmlBuildSystem::project() const
{
- return m_project->addFiles(filePaths);
+ return static_cast<QmlProject *>(BuildSystem::project());
}
-bool QmlProjectNode::deleteFiles(const QStringList & /*filePaths*/)
+bool QmlBuildSystem::addFiles(Node *context, const QStringList &filePaths, QStringList *notAdded)
{
- return true;
+ if (dynamic_cast<QmlProjectNode *>(context))
+ return project()->addFiles(filePaths);
+
+ return BuildSystem::addFiles(context, filePaths, notAdded);
}
-bool QmlProjectNode::renameFile(const QString & filePath, const QString & newFilePath)
+bool QmlBuildSystem::deleteFiles(Node *context, const QStringList &filePaths)
{
- if (filePath.endsWith(m_project->mainFile())) {
- m_project->setMainFile(newFilePath);
-
- // make sure to change it also in the qmlproject file
- const QString qmlProjectFilePath = m_project->projectFilePath().toString();
- Core::FileChangeBlocker fileChangeBlocker(qmlProjectFilePath);
- const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(qmlProjectFilePath);
- TextEditor::TextDocument *document = nullptr;
- if (!editors.isEmpty()) {
- document = qobject_cast<TextEditor::TextDocument*>(editors.first()->document());
- if (document && document->isModified())
- if (!Core::DocumentManager::saveDocument(document))
- return false;
- }
-
- QString fileContent;
- QString error;
- Utils::TextFileFormat textFileFormat;
- const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
- if (Utils::TextFileFormat::readFile(qmlProjectFilePath, codec, &fileContent, &textFileFormat, &error)
- != Utils::TextFileFormat::ReadSuccess) {
- qWarning() << "Failed to read file" << qmlProjectFilePath << ":" << error;
- }
+ if (dynamic_cast<QmlProjectNode *>(context))
+ return true;
- // find the mainFile and do the file name with brackets in a capture group and mask the . with \.
- QString originalFileName = QFileInfo(filePath).fileName();
- originalFileName.replace(".", "\\.");
- const QRegularExpression expression(QString("mainFile:\\s*\"(%1)\"").arg(originalFileName));
- const QRegularExpressionMatch match = expression.match(fileContent);
+ return BuildSystem::deleteFiles(context, filePaths);
+}
- fileContent.replace(match.capturedStart(1), match.capturedLength(1), QFileInfo(newFilePath).fileName());
+bool QmlBuildSystem::renameFile(Node * context, const QString &filePath, const QString &newFilePath)
+{
+ if (dynamic_cast<QmlProjectNode *>(context)) {
+ if (filePath.endsWith(project()->mainFile())) {
+ project()->setMainFile(newFilePath);
+
+ // make sure to change it also in the qmlproject file
+ const QString qmlProjectFilePath = project()->projectFilePath().toString();
+ Core::FileChangeBlocker fileChangeBlocker(qmlProjectFilePath);
+ const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(qmlProjectFilePath);
+ TextEditor::TextDocument *document = nullptr;
+ if (!editors.isEmpty()) {
+ document = qobject_cast<TextEditor::TextDocument*>(editors.first()->document());
+ if (document && document->isModified())
+ if (!Core::DocumentManager::saveDocument(document))
+ return false;
+ }
+
+ QString fileContent;
+ QString error;
+ Utils::TextFileFormat textFileFormat;
+ const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
+ if (Utils::TextFileFormat::readFile(qmlProjectFilePath, codec, &fileContent, &textFileFormat, &error)
+ != Utils::TextFileFormat::ReadSuccess) {
+ qWarning() << "Failed to read file" << qmlProjectFilePath << ":" << error;
+ }
+
+ // find the mainFile and do the file name with brackets in a capture group and mask the . with \.
+ QString originalFileName = QFileInfo(filePath).fileName();
+ originalFileName.replace(".", "\\.");
+ const QRegularExpression expression(QString("mainFile:\\s*\"(%1)\"").arg(originalFileName));
+ const QRegularExpressionMatch match = expression.match(fileContent);
+
+ fileContent.replace(match.capturedStart(1), match.capturedLength(1), QFileInfo(newFilePath).fileName());
+
+ if (!textFileFormat.writeFile(qmlProjectFilePath, fileContent, &error))
+ qWarning() << "Failed to write file" << qmlProjectFilePath << ":" << error;
+ project()->refresh(QmlProject::Everything);
+ }
- if (!textFileFormat.writeFile(qmlProjectFilePath, fileContent, &error))
- qWarning() << "Failed to write file" << qmlProjectFilePath << ":" << error;
- m_project->refresh(QmlProject::Everything);
+ return true;
}
- return true;
+ return BuildSystem::renameFile(context, filePath, newFilePath);
}
} // namespace Internal
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.h b/src/plugins/qmlprojectmanager/qmlprojectnodes.h
index 4d6fe4cfcf..13c25a31a7 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectnodes.h
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.h
@@ -38,11 +38,6 @@ class QmlProjectNode : public ProjectExplorer::ProjectNode
public:
QmlProjectNode(QmlProject *project);
- bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
- bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override;
- bool deleteFiles(const QStringList &filePaths) override;
- bool renameFile(const QString &filePath, const QString &newFilePath) override;
-
private:
QmlProject *m_project;
};
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
index 6e67361d11..2b093fd7af 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
@@ -82,7 +82,7 @@ public:
FileInSettings
};
- void addToConfigurationLayout(QFormLayout *layout) final;
+ void addToLayout(LayoutBuilder &builder) final;
void toMap(QVariantMap &map) const final;
void fromMap(const QVariantMap &map) final;
@@ -117,7 +117,7 @@ MainQmlFileAspect::MainQmlFileAspect(QmlProject *project)
this, [this] { changeCurrentFile(); });
}
-void MainQmlFileAspect::addToConfigurationLayout(QFormLayout *layout)
+void MainQmlFileAspect::addToLayout(LayoutBuilder &builder)
{
QTC_ASSERT(!m_fileListCombo, delete m_fileListCombo);
m_fileListCombo = new QComboBox;
@@ -130,7 +130,8 @@ void MainQmlFileAspect::addToConfigurationLayout(QFormLayout *layout)
connect(m_fileListCombo, QOverload<int>::of(&QComboBox::activated),
this, &MainQmlFileAspect::setMainScript);
- layout->addRow(QmlProjectRunConfiguration::tr("Main QML file:"), m_fileListCombo);
+ builder.addItem(QmlProjectRunConfiguration::tr("Main QML file:"));
+ builder.addItem(m_fileListCombo.data());
}
void MainQmlFileAspect::toMap(QVariantMap &map) const
diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp
index 603a19aff5..8300b28b27 100644
--- a/src/plugins/qtsupport/baseqtversion.cpp
+++ b/src/plugins/qtsupport/baseqtversion.cpp
@@ -48,13 +48,14 @@
#include <qtsupport/qtsupportconstants.h>
#include <utils/algorithm.h>
+#include <utils/displayname.h>
+#include <utils/fileinprojectfinder.h>
#include <utils/hostosinfo.h>
#include <utils/macroexpander.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
#include <utils/synchronousprocess.h>
#include <utils/winutils.h>
-#include <utils/fileinprojectfinder.h>
#include <resourceeditor/resourcenode.h>
@@ -87,6 +88,51 @@ const char QTVERSION_ABIS[] = "Abis";
const char MKSPEC_VALUE_LIBINFIX[] = "QT_LIBINFIX";
const char MKSPEC_VALUE_NAMESPACE[] = "QT_NAMESPACE";
+// --------------------------------------------------------------------
+// QtVersionData:
+// --------------------------------------------------------------------
+
+class QtVersionData
+{
+public:
+ bool installed = true;
+ bool hasExamples = false;
+ bool hasDemos = false;
+ bool hasDocumentation = false;
+ bool hasQtAbis = false;
+
+ DisplayName unexpandedDisplayName;
+ QString qtVersionString;
+
+ FilePath sourcePath;
+ FilePath qtSources;
+
+ Utils::FilePath prefix;
+
+ Utils::FilePath binPath;
+ Utils::FilePath configurationPath;
+ Utils::FilePath dataPath;
+ Utils::FilePath demosPath;
+ Utils::FilePath docsPath;
+ Utils::FilePath examplesPath;
+ // Utils::FilePath frameworkPath; // is derived from libraryPath
+ Utils::FilePath headerPath;
+ Utils::FilePath importsPath;
+ Utils::FilePath libraryPath;
+ Utils::FilePath pluginPath;
+ Utils::FilePath qmlPath;
+ Utils::FilePath translationsPath;
+
+ Utils::FilePath hostBinPath;
+ Utils::FilePath hostDataPath;
+
+ Abis qtAbis;
+};
+
+// --------------------------------------------------------------------
+// Helpers:
+// --------------------------------------------------------------------
+
static QSet<Id> versionedIds(const QByteArray &prefix, int major, int minor)
{
QSet<Id> result;
@@ -129,9 +175,10 @@ enum HostBinaries { Designer, Linguist, Uic, QScxmlc };
class BaseQtVersionPrivate
{
public:
- BaseQtVersionPrivate(BaseQtVersion *parent) : q(parent) {}
+ BaseQtVersionPrivate(BaseQtVersion *parent)
+ : q(parent)
+ {}
- void setupQmakePathAndId(const FilePath &path);
void updateVersionInfo();
QString findHostBinary(HostBinaries binary) const;
@@ -160,6 +207,8 @@ public:
bool m_isAutodetected = false;
QString m_type;
+ QtVersionData m_data;
+
bool m_isUpdating = false;
bool m_hasQmlDump = false; // controlled by m_versionInfoUpToDate
bool m_mkspecUpToDate = false;
@@ -168,18 +217,10 @@ public:
bool m_defaultConfigIsDebugAndRelease = true;
bool m_frameworkBuild = false;
bool m_versionInfoUpToDate = false;
- bool m_installed = true;
- bool m_hasExamples = false;
- bool m_hasDemos = false;
- bool m_hasDocumentation = false;
bool m_qmakeIsExecutable = true;
- bool m_hasQtAbis = false;
- QString m_unexpandedDisplayName;
QString m_autodetectionSource;
QSet<Core::Id> m_overrideFeatures;
- FilePath m_sourcePath;
- FilePath m_qtSources;
FilePath m_mkspec;
FilePath m_mkspecFullPath;
@@ -189,15 +230,13 @@ public:
QHash<ProKey, ProString> m_versionInfo;
FilePath m_qmakeCommand;
- QString m_qtVersionString;
+
QString m_uicCommand;
QString m_designerCommand;
QString m_linguistCommand;
QString m_qscxmlcCommand;
QString m_qmlsceneCommand;
- Abis m_qtAbis;
-
MacroExpanderWrapper m_expander;
};
@@ -293,29 +332,20 @@ BaseQtVersion::BaseQtVersion()
: d(new BaseQtVersionPrivate(this))
{}
-
BaseQtVersion::~BaseQtVersion()
{
delete d;
}
-void BaseQtVersionPrivate::setupQmakePathAndId(const FilePath &qmakeCommand)
-{
- m_id = QtVersionManager::getUniqueId();
- QTC_CHECK(m_qmakeCommand.isEmpty()); // Should only be used once.
- m_qmakeCommand = qmakeCommand;
- m_unexpandedDisplayName = BaseQtVersion::defaultUnexpandedDisplayName(m_qmakeCommand, false);
-}
-
-QString BaseQtVersion::defaultUnexpandedDisplayName(const FilePath &qmakePath, bool fromPath)
+QString BaseQtVersion::defaultUnexpandedDisplayName() const
{
QString location;
- if (qmakePath.isEmpty()) {
+ if (qmakeCommand().isEmpty()) {
location = QCoreApplication::translate("QtVersion", "<unknown>");
} else {
// Deduce a description from '/foo/qt-folder/[qtbase]/bin/qmake' -> '/foo/qt-folder'.
// '/usr' indicates System Qt 4.X on Linux.
- QDir dir = qmakePath.toFileInfo().absoluteDir();
+ QDir dir = qmakeCommand().toFileInfo().absoluteDir();
do {
const QString dirName = dir.dirName();
if (dirName == "usr") { // System-installed Qt.
@@ -332,7 +362,7 @@ QString BaseQtVersion::defaultUnexpandedDisplayName(const FilePath &qmakePath, b
} while (!dir.isRoot() && dir.cdUp());
}
- return fromPath ?
+ return autodetectionSource() == "PATH" ?
QCoreApplication::translate("QtVersion", "Qt %{Qt:Version} in PATH (%2)").arg(location) :
QCoreApplication::translate("QtVersion", "Qt %{Qt:Version} (%2)").arg(location);
}
@@ -520,67 +550,80 @@ Tasks BaseQtVersion::validateKit(const Kit *k)
FilePath BaseQtVersion::prefix() const // QT_INSTALL_PREFIX
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_INSTALL_PREFIX"));
+ d->updateVersionInfo();
+ return d->m_data.prefix;
}
FilePath BaseQtVersion::binPath() const // QT_INSTALL_BINS
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_INSTALL_BINS"));
+ d->updateVersionInfo();
+ return d->m_data.binPath;
}
FilePath BaseQtVersion::configurationPath() const // QT_INSTALL_CONFIGURATION
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_INSTALL_CONFIGURATION"));
+ d->updateVersionInfo();
+ return d->m_data.configurationPath;
}
FilePath BaseQtVersion::headerPath() const // QT_INSTALL_HEADERS
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_INSTALL_HEADERS"));
+ d->updateVersionInfo();
+ return d->m_data.headerPath;
}
FilePath BaseQtVersion::dataPath() const // QT_INSTALL_DATA
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_INSTALL_DATA"));
+ d->updateVersionInfo();
+ return d->m_data.dataPath;
}
FilePath BaseQtVersion::docsPath() const // QT_INSTALL_DOCS
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_INSTALL_DOCS"));
+ d->updateVersionInfo();
+ return d->m_data.docsPath;
}
FilePath BaseQtVersion::importsPath() const // QT_INSTALL_IMPORTS
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_INSTALL_IMPORTS"));
+ d->updateVersionInfo();
+ return d->m_data.importsPath;
}
FilePath BaseQtVersion::libraryPath() const // QT_INSTALL_LIBS
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_INSTALL_LIBS"));
+ d->updateVersionInfo();
+ return d->m_data.libraryPath;
}
FilePath BaseQtVersion::pluginPath() const // QT_INSTALL_PLUGINS
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_INSTALL_PLUGINS"));
+ d->updateVersionInfo();
+ return d->m_data.pluginPath;
}
FilePath BaseQtVersion::qmlPath() const // QT_INSTALL_QML
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_INSTALL_QML"));
+ d->updateVersionInfo();
+ return d->m_data.qmlPath;
}
FilePath BaseQtVersion::translationsPath() const // QT_INSTALL_TRANSLATIONS
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_INSTALL_TRANSLATIONS"));
+ d->updateVersionInfo();
+ return d->m_data.translationsPath;
}
FilePath BaseQtVersion::hostBinPath() const // QT_HOST_BINS
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_HOST_BINS"));
+ d->updateVersionInfo();
+ return d->m_data.hostBinPath;
}
FilePath BaseQtVersion::hostDataPath() const // QT_HOST_DATA
{
- return FilePath::fromUserInput(d->qmakeProperty("QT_HOST_DATA"));
+ d->updateVersionInfo();
+ return d->m_data.hostDataPath;
}
FilePath BaseQtVersion::mkspecsPath() const
@@ -593,6 +636,7 @@ FilePath BaseQtVersion::mkspecsPath() const
FilePath BaseQtVersion::qmlBinPath() const
{
+ d->updateVersionInfo();
return FilePath::fromUserInput(d->m_mkspecValues.value("QT.qml.bins"));
}
@@ -651,22 +695,22 @@ void BaseQtVersion::fromMap(const QVariantMap &map)
d->m_id = map.value(Constants::QTVERSIONID).toInt();
if (d->m_id == -1) // this happens on adding from installer, see updateFromInstaller => get a new unique id
d->m_id = QtVersionManager::getUniqueId();
- d->m_unexpandedDisplayName = map.value(Constants::QTVERSIONNAME).toString();
+ d->m_data.unexpandedDisplayName.fromMap(map, Constants::QTVERSIONNAME);
d->m_isAutodetected = map.value(QTVERSIONAUTODETECTED).toBool();
- if (d->m_isAutodetected)
- d->m_autodetectionSource = map.value(QTVERSIONAUTODETECTIONSOURCE).toString();
+ d->m_autodetectionSource = map.value(QTVERSIONAUTODETECTIONSOURCE).toString();
d->m_overrideFeatures = Core::Id::fromStringList(map.value(QTVERSION_OVERRIDE_FEATURES).toStringList());
QString string = map.value(QTVERSIONQMAKEPATH).toString();
if (string.startsWith('~'))
string.remove(0, 1).prepend(QDir::homePath());
- d->m_qtSources = FilePath::fromUserInput(map.value(QTVERSIONSOURCEPATH).toString());
+ d->m_data.qtSources = FilePath::fromUserInput(map.value(QTVERSIONSOURCEPATH).toString());
// Handle ABIs provided by the SDKTool:
// Note: Creator does not write these settings itself, so it has to come from the SDKTool!
- d->m_qtAbis = Utils::transform<Abis>(map.value(QTVERSION_ABIS).toStringList(), &Abi::fromString);
- d->m_qtAbis = Utils::filtered(d->m_qtAbis, &Abi::isValid);
- d->m_hasQtAbis = !d->m_qtAbis.isEmpty();
+ d->m_data.qtAbis = Utils::transform<Abis>(map.value(QTVERSION_ABIS).toStringList(),
+ &Abi::fromString);
+ d->m_data.qtAbis = Utils::filtered(d->m_data.qtAbis, &Abi::isValid);
+ d->m_data.hasQtAbis = !d->m_data.qtAbis.isEmpty();
QFileInfo fi(string);
if (BuildableHelperLibrary::isQtChooser(fi)) {
@@ -677,6 +721,7 @@ void BaseQtVersion::fromMap(const QVariantMap &map)
}
d->m_qmakeCommand = FilePath::fromString(string);
+ updateDefaultDisplayName();
// Clear the cached qmlscene command, it might not match the restored path anymore.
d->m_qmlsceneCommand.clear();
@@ -686,10 +731,9 @@ QVariantMap BaseQtVersion::toMap() const
{
QVariantMap result;
result.insert(Constants::QTVERSIONID, uniqueId());
- result.insert(Constants::QTVERSIONNAME, unexpandedDisplayName());
+ d->m_data.unexpandedDisplayName.toMap(result, Constants::QTVERSIONNAME);
result.insert(QTVERSIONAUTODETECTED, isAutodetected());
- if (isAutodetected())
- result.insert(QTVERSIONAUTODETECTIONSOURCE, autodetectionSource());
+ result.insert(QTVERSIONAUTODETECTIONSOURCE, autodetectionSource());
if (!d->m_overrideFeatures.isEmpty())
result.insert(QTVERSION_OVERRIDE_FEATURES, Core::Id::toStringList(d->m_overrideFeatures));
@@ -704,7 +748,7 @@ bool BaseQtVersion::isValid() const
d->updateVersionInfo();
d->updateMkspec();
- return !qmakeCommand().isEmpty() && d->m_installed && !binPath().isEmpty()
+ return !qmakeCommand().isEmpty() && d->m_data.installed && !binPath().isEmpty()
&& !d->m_mkspecFullPath.isEmpty() && d->m_qmakeIsExecutable;
}
@@ -723,7 +767,7 @@ QString BaseQtVersion::invalidReason() const
return QCoreApplication::translate("QtVersion", "No qmake path set");
if (!d->m_qmakeIsExecutable)
return QCoreApplication::translate("QtVersion", "qmake does not exist or is not executable");
- if (!d->m_installed)
+ if (!d->m_data.installed)
return QCoreApplication::translate("QtVersion", "Qt version is not properly installed, please run make install");
if (binPath().isEmpty())
return QCoreApplication::translate("QtVersion",
@@ -752,11 +796,11 @@ FilePath BaseQtVersion::qmakeCommand() const
Abis BaseQtVersion::qtAbis() const
{
- if (!d->m_hasQtAbis) {
- d->m_qtAbis = detectQtAbis();
- d->m_hasQtAbis = true;
+ if (!d->m_data.hasQtAbis) {
+ d->m_data.qtAbis = detectQtAbis();
+ d->m_data.hasQtAbis = true;
}
- return d->m_qtAbis;
+ return d->m_data.qtAbis;
}
Abis BaseQtVersion::detectQtAbis() const
@@ -802,17 +846,22 @@ QString BaseQtVersion::autodetectionSource() const
QString BaseQtVersion::displayName() const
{
- return macroExpander()->expand(d->m_unexpandedDisplayName);
+ return macroExpander()->expand(unexpandedDisplayName());
}
QString BaseQtVersion::unexpandedDisplayName() const
{
- return d->m_unexpandedDisplayName;
+ return d->m_data.unexpandedDisplayName.value();
}
void BaseQtVersion::setUnexpandedDisplayName(const QString &name)
{
- d->m_unexpandedDisplayName = name;
+ d->m_data.unexpandedDisplayName.setValue(name);
+}
+
+void BaseQtVersion::updateDefaultDisplayName()
+{
+ d->m_data.unexpandedDisplayName.setDefaultValue(defaultUnexpandedDisplayName());
}
QString BaseQtVersion::toHtml(bool verbose) const
@@ -898,16 +947,16 @@ QString BaseQtVersion::toHtml(bool verbose) const
FilePath BaseQtVersion::sourcePath() const
{
- if (d->m_sourcePath.isEmpty()) {
+ if (d->m_data.sourcePath.isEmpty()) {
d->updateVersionInfo();
- d->m_sourcePath = d->sourcePath(d->m_versionInfo);
+ d->m_data.sourcePath = d->sourcePath(d->m_versionInfo);
}
- return d->m_sourcePath;
+ return d->m_data.sourcePath;
}
FilePath BaseQtVersion::qtPackageSourcePath() const
{
- return d->m_qtSources;
+ return d->m_data.qtSources;
}
QString BaseQtVersion::designerCommand() const
@@ -1172,7 +1221,7 @@ BaseQtVersion::QmakeBuildConfigs BaseQtVersion::defaultBuildConfig() const
QString BaseQtVersion::qtVersionString() const
{
d->updateVersionInfo();
- return d->m_qtVersionString;
+ return d->m_data.qtVersionString;
}
QtVersionNumber BaseQtVersion::qtVersion() const
@@ -1189,9 +1238,9 @@ void BaseQtVersionPrivate::updateVersionInfo()
// extract data from qmake executable
m_versionInfo.clear();
- m_installed = true;
- m_hasExamples = false;
- m_hasDocumentation = false;
+ m_data.installed = true;
+ m_data.hasExamples = false;
+ m_data.hasDocumentation = false;
m_hasQmlDump = false;
if (!queryQMakeVariables(m_qmakeCommand, q->qmakeRunEnvironment(), &m_versionInfo)) {
@@ -1217,35 +1266,55 @@ void BaseQtVersionPrivate::updateVersionInfo()
QString installDir = q->hostBinPath().toString();
if (!installDir.isNull()) {
if (!QFileInfo::exists(installDir))
- m_installed = false;
+ m_data.installed = false;
}
// Framework builds for Qt 4.8 don't use QT_INSTALL_HEADERS
// so we don't check on mac
if (!HostOsInfo::isMacHost()) {
if (!qtHeaderData.isNull()) {
if (!QFileInfo::exists(qtHeaderData))
- m_installed = false;
+ m_data.installed = false;
}
}
const QString qtInstallDocs = q->docsPath().toString();
if (!qtInstallDocs.isNull()) {
if (QFileInfo::exists(qtInstallDocs))
- m_hasDocumentation = true;
+ m_data.hasDocumentation = true;
}
const QString qtInstallExamples = q->examplesPath().toString();
if (!qtInstallExamples.isNull()) {
if (QFileInfo::exists(qtInstallExamples))
- m_hasExamples = true;
+ m_data.hasExamples = true;
}
const QString qtInstallDemos = q->demosPath().toString();
if (!qtInstallDemos.isNull()) {
if (QFileInfo::exists(qtInstallDemos))
- m_hasDemos = true;
+ m_data.hasDemos = true;
}
- m_qtVersionString = qmakeProperty("QT_VERSION");
+ m_data.qtVersionString = qmakeProperty("QT_VERSION");
m_isUpdating = false;
m_versionInfoUpToDate = true;
+
+ m_data.prefix = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_PREFIX"));
+
+ m_data.binPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_BINS"));
+ m_data.configurationPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_CONFIGURATION"));
+ m_data.dataPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_DATA"));
+ m_data.demosPath = FilePath::fromString(
+ QFileInfo(qmakeProperty("QT_INSTALL_DEMOS")).canonicalFilePath());
+ m_data.docsPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_DOCS"));
+ m_data.examplesPath = FilePath::fromString(
+ QFileInfo(qmakeProperty("QT_INSTALL_EXAMPLES")).canonicalFilePath());
+ m_data.headerPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_HEADERS"));
+ m_data.importsPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_IMPORTS"));
+ m_data.libraryPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_LIBS"));
+ m_data.pluginPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_PLUGINS"));
+ m_data.qmlPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_QML"));
+ m_data.translationsPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_TRANSLATIONS"));
+
+ m_data.hostBinPath = FilePath::fromUserInput(qmakeProperty("QT_HOST_BINS"));
+ m_data.hostDataPath = FilePath::fromUserInput(qmakeProperty("QT_HOST_DATA"));
}
QHash<ProKey,ProString> BaseQtVersionPrivate::versionInfo()
@@ -1278,18 +1347,18 @@ void BaseQtVersion::applyProperties(QMakeGlobals *qmakeGlobals) const
bool BaseQtVersion::hasDocs() const
{
d->updateVersionInfo();
- return d->m_hasDocumentation;
+ return d->m_data.hasDocumentation;
}
bool BaseQtVersion::hasDemos() const
{
d->updateVersionInfo();
- return d->m_hasDemos;
+ return d->m_data.hasDemos;
}
FilePath BaseQtVersion::demosPath() const
{
- return FilePath::fromString(QFileInfo(d->qmakeProperty("QT_INSTALL_DEMOS")).canonicalFilePath());
+ return d->m_data.demosPath;
}
FilePath BaseQtVersion::frameworkPath() const
@@ -1302,28 +1371,21 @@ FilePath BaseQtVersion::frameworkPath() const
bool BaseQtVersion::hasExamples() const
{
d->updateVersionInfo();
- return d->m_hasExamples;
+ return d->m_data.hasExamples;
}
FilePath BaseQtVersion::examplesPath() const // QT_INSTALL_EXAMPLES
{
- return FilePath::fromString(
- QFileInfo(d->qmakeProperty("QT_INSTALL_EXAMPLES")).canonicalFilePath());
+ return d->m_data.examplesPath;
}
QStringList BaseQtVersion::qtSoPaths() const
{
- static const char * const qMakeVariables[] = {
- "QT_INSTALL_LIBS",
- "QT_INSTALL_PLUGINS",
- "QT_INSTALL_QML",
- "QT_INSTALL_IMPORTS"
- };
-
+ const FilePathList qtPaths = {libraryPath(), pluginPath(), qmlPath(), importsPath()};
QSet<QString> paths;
- for (uint i = 0; i < sizeof qMakeVariables / sizeof qMakeVariables[0]; ++i) {
- QString path = d->qmakeProperty(qMakeVariables[i]);
- if (path.isNull())
+ for (const FilePath &p : qtPaths) {
+ QString path = p.toString();
+ if (path.isEmpty())
continue;
QDirIterator it(path, QStringList("*.so"), QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()) {
@@ -1461,33 +1523,32 @@ BaseQtVersion::createMacroExpander(const std::function<const BaseQtVersion *()>
return version->demosPath().toString();
}));
- expander->registerVariable(
- "Qt:QMAKE_MKSPECS",
- QtKitAspect::tr("The current Qt version's default mkspecs (Qt 4)."),
- versionProperty([](const BaseQtVersion *version) {
- return version->d->qmakeProperty(version->d->m_versionInfo, "QMAKE_MKSPECS");
- }));
+ expander->registerVariable("Qt:QMAKE_MKSPECS",
+ QtKitAspect::tr("The current Qt version's default mkspecs (Qt 4)."),
+ versionProperty([](const BaseQtVersion *version) {
+ return version->d->qmakeProperty("QMAKE_MKSPECS");
+ }));
- expander->registerVariable(
- "Qt:QMAKE_SPEC",
- QtKitAspect::tr("The current Qt version's default mkspec (Qt 5; host system)."),
- versionProperty([](const BaseQtVersion *version) {
- return version->d->qmakeProperty(version->d->m_versionInfo, "QMAKE_SPEC");
- }));
+ expander->registerVariable("Qt:QMAKE_SPEC",
+ QtKitAspect::tr(
+ "The current Qt version's default mkspec (Qt 5; host system)."),
+ versionProperty([](const BaseQtVersion *version) {
+ return version->d->qmakeProperty("QMAKE_SPEC");
+ }));
- expander->registerVariable(
- "Qt:QMAKE_XSPEC",
- QtKitAspect::tr("The current Qt version's default mkspec (Qt 5; target system)."),
- versionProperty([](const BaseQtVersion *version) {
- return version->d->qmakeProperty(version->d->m_versionInfo, "QMAKE_XSPEC");
- }));
+ expander
+ ->registerVariable("Qt:QMAKE_XSPEC",
+ QtKitAspect::tr(
+ "The current Qt version's default mkspec (Qt 5; target system)."),
+ versionProperty([](const BaseQtVersion *version) {
+ return version->d->qmakeProperty("QMAKE_XSPEC");
+ }));
- expander->registerVariable(
- "Qt:QMAKE_VERSION",
- QtKitAspect::tr("The current Qt's qmake version."),
- versionProperty([](const BaseQtVersion *version) {
- return version->d->qmakeProperty(version->d->m_versionInfo, "QMAKE_VERSION");
- }));
+ expander->registerVariable("Qt:QMAKE_VERSION",
+ QtKitAspect::tr("The current Qt's qmake version."),
+ versionProperty([](const BaseQtVersion *version) {
+ return version->d->qmakeProperty("QMAKE_VERSION");
+ }));
// FIXME: Re-enable once we can detect expansion loops.
// expander->registerVariable("Qt:Name",
@@ -1944,7 +2005,7 @@ bool BaseQtVersion::isQtQuickCompilerSupported(QString *reason) const
FilePathList BaseQtVersionPrivate::qtCorePaths()
{
updateVersionInfo();
- const QString versionString = m_qtVersionString;
+ const QString versionString = m_data.qtVersionString;
const QString installLibsDir = q->libraryPath().toString();
const QString installBinDir = q->binPath().toString();
@@ -2209,9 +2270,12 @@ BaseQtVersion *QtVersionFactory::createQtVersionFromQMakePath
if (!factory->m_restrictionChecker || factory->m_restrictionChecker(setup)) {
BaseQtVersion *ver = factory->create();
QTC_ASSERT(ver, continue);
- ver->d->setupQmakePathAndId(qmakePath);
+ ver->d->m_id = QtVersionManager::getUniqueId();
+ QTC_CHECK(ver->d->m_qmakeCommand.isEmpty()); // Should only be used once.
+ ver->d->m_qmakeCommand = qmakePath;
ver->d->m_autodetectionSource = autoDetectionSource;
ver->d->m_isAutodetected = isAutoDetected;
+ ver->updateDefaultDisplayName();
ProFileCacheManager::instance()->decRefCount();
return ver;
}
diff --git a/src/plugins/qtsupport/baseqtversion.h b/src/plugins/qtsupport/baseqtversion.h
index 8de93f138b..4a90ca531b 100644
--- a/src/plugins/qtsupport/baseqtversion.h
+++ b/src/plugins/qtsupport/baseqtversion.h
@@ -187,8 +187,7 @@ public:
virtual QtConfigWidget *createConfigurationWidget() const;
- static QString defaultUnexpandedDisplayName(const Utils::FilePath &qmakePath,
- bool fromPath = false);
+ QString defaultUnexpandedDisplayName() const;
virtual QSet<Core::Id> targetDeviceTypes() const = 0;
@@ -249,6 +248,8 @@ protected:
virtual void parseMkSpec(ProFileEvaluator *) const;
private:
+ void updateDefaultDisplayName();
+
friend class QtVersionFactory;
friend class QtVersionManager;
friend class Internal::BaseQtVersionPrivate;
diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp
index d531677e14..5ce7e34a6a 100644
--- a/src/plugins/qtsupport/qtoptionspage.cpp
+++ b/src/plugins/qtsupport/qtoptionspage.cpp
@@ -637,7 +637,7 @@ void QtOptionsPageWidget::editPath()
}
// same type, replace
version->setId(current->uniqueId());
- if (current->unexpandedDisplayName() != current->defaultUnexpandedDisplayName(current->qmakeCommand()))
+ if (current->unexpandedDisplayName() != current->defaultUnexpandedDisplayName())
version->setUnexpandedDisplayName(current->displayName());
// Update ui
diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp
index 6f888e5401..5888f6a938 100644
--- a/src/plugins/qtsupport/qtversionmanager.cpp
+++ b/src/plugins/qtsupport/qtversionmanager.cpp
@@ -436,10 +436,8 @@ static void findSystemQt()
BaseQtVersion *version = QtVersionFactory::createQtVersionFromQMakePath(qmakePath,
false,
"PATH");
- if (version) {
- version->setUnexpandedDisplayName(BaseQtVersion::defaultUnexpandedDisplayName(qmakePath, true));
+ if (version)
m_versions.insert(version->uniqueId(), version);
- }
}
}
diff --git a/src/plugins/qtsupport/qtversionmanager.h b/src/plugins/qtsupport/qtversionmanager.h
index fefe5b4273..2c05485c60 100644
--- a/src/plugins/qtsupport/qtversionmanager.h
+++ b/src/plugins/qtsupport/qtversionmanager.h
@@ -35,8 +35,9 @@ class QTSUPPORT_EXPORT QtVersionManager : public QObject
Q_OBJECT
// for getUniqueId();
friend class BaseQtVersion;
- friend class Internal::BaseQtVersionPrivate;
+ friend class QtVersionFactory;
friend class Internal::QtOptionsPageWidget;
+
public:
static QtVersionManager *instance();
QtVersionManager();
diff --git a/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp b/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp
index b74d73a5d4..c4c9f8f376 100644
--- a/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp
+++ b/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp
@@ -77,10 +77,10 @@ WebBrowserSelectionAspect::WebBrowserSelectionAspect(ProjectExplorer::Target *ta
setSettingsKey("RunConfiguration.WebBrowser");
}
-void WebBrowserSelectionAspect::addToConfigurationLayout(QFormLayout *layout)
+void WebBrowserSelectionAspect::addToLayout(ProjectExplorer::LayoutBuilder &builder)
{
QTC_CHECK(!m_webBrowserComboBox);
- m_webBrowserComboBox = new QComboBox(layout->parentWidget());
+ m_webBrowserComboBox = new QComboBox;
m_webBrowserComboBox->addItems(m_availableBrowsers);
m_webBrowserComboBox->setCurrentText(m_currentBrowser);
connect(m_webBrowserComboBox, &QComboBox::currentTextChanged,
@@ -88,7 +88,8 @@ void WebBrowserSelectionAspect::addToConfigurationLayout(QFormLayout *layout)
m_currentBrowser = selectedBrowser;
emit changed();
});
- layout->addRow(tr("Web browser:"), m_webBrowserComboBox);
+ builder.addItem(tr("Web browser:"));
+ builder.addItem(m_webBrowserComboBox);
}
void WebBrowserSelectionAspect::fromMap(const QVariantMap &map)
diff --git a/src/plugins/webassembly/webassemblyrunconfigurationaspects.h b/src/plugins/webassembly/webassemblyrunconfigurationaspects.h
index 16b2d842ee..1f640f35a3 100644
--- a/src/plugins/webassembly/webassemblyrunconfigurationaspects.h
+++ b/src/plugins/webassembly/webassemblyrunconfigurationaspects.h
@@ -39,7 +39,7 @@ class WebBrowserSelectionAspect : public ProjectExplorer::ProjectConfigurationAs
public:
WebBrowserSelectionAspect(ProjectExplorer::Target *target);
- void addToConfigurationLayout(QFormLayout *layout) override;
+ void addToLayout(ProjectExplorer::LayoutBuilder &builder) override;
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
diff --git a/src/shared/qtcreator_pch.h b/src/shared/qtcreator_pch.h
index 4988f3d939..bd6ba76506 100644
--- a/src/shared/qtcreator_pch.h
+++ b/src/shared/qtcreator_pch.h
@@ -31,11 +31,29 @@
#if defined __cplusplus
#include <QtGlobal>
-#ifdef Q_WS_WIN
-# define _POSIX_
-# include <limits.h>
-# undef _POSIX_
-#endif
+#ifdef Q_OS_WIN
+#undef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+
+// lib/Utils needs defines for Windows 8
+#undef WINVER
+#define WINVER 0x0602
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0602
+
+#define NOHELP
+#include <qt_windows.h>
+
+#undef DELETE
+#undef IN
+#undef OUT
+#undef ERROR
+#undef ABSOLUTE
+
+#define _POSIX_
+#include <limits.h>
+#undef _POSIX_
+#endif // Q_OS_WIN
#include <QCoreApplication>
#include <QList>
diff --git a/src/tools/perfparser b/src/tools/perfparser
-Subproject f010f12d68fa5269e6b7e16b8c2c2dffcb97a26
+Subproject d25737577023ce9fa3bd593f22fa23c3fcaedbf
diff --git a/tests/auto/qml/codemodel/importscheck/tst_importscheck.cpp b/tests/auto/qml/codemodel/importscheck/tst_importscheck.cpp
index 0c11438e12..f6126b73af 100644
--- a/tests/auto/qml/codemodel/importscheck/tst_importscheck.cpp
+++ b/tests/auto/qml/codemodel/importscheck/tst_importscheck.cpp
@@ -70,7 +70,8 @@ void scanDir(const QString &dir)
paths.maybeInsert(Utils::FilePath::fromString(dir), Dialect::Qml);
ModelManagerInterface::importScan(result, ModelManagerInterface::workingCopy(), paths,
ModelManagerInterface::instance(), false);
- ViewerContext vCtx = ViewerContext(QStringList(), QStringList(dir));
+ ViewerContext vCtx;
+ vCtx.paths.append(dir);
Snapshot snap = ModelManagerInterface::instance()->snapshot();
ImportDependencies *iDeps = snap.importDependencies();
@@ -181,7 +182,8 @@ void tst_ImportCheck::test()
lPaths.maybeInsert(Utils::FilePath::fromString(path), Dialect::Qml);
ModelManagerInterface::importScan(result, ModelManagerInterface::workingCopy(), lPaths,
ModelManagerInterface::instance(), false);
- ViewerContext vCtx(QStringList(), paths);
+ ViewerContext vCtx;
+ vCtx.paths.append(paths);
Snapshot snap = ModelManagerInterface::instance()->snapshot();
ImportDependencies *iDeps = snap.importDependencies();
diff --git a/tests/manual/genericproject/Makefile b/tests/manual/genericproject/Makefile
new file mode 100644
index 0000000000..c8dc9d0154
--- /dev/null
+++ b/tests/manual/genericproject/Makefile
@@ -0,0 +1,18 @@
+CC := g++
+FLAGS :=
+FILES := $(shell find . -name '*.cpp' -o -name '*.h')
+DESTNAME:= generic
+
+.PHONY: all clean
+
+TARGETS := Generic
+
+all: $(TARGETS)
+
+clean:
+ find . -type f -name '*.o' -delete
+ rm -rf .obj
+ rm -f generic
+
+$(TARGETS):
+ $(CC) $(FLAGS) $(FILES) -o $(DESTNAME)
diff --git a/tests/manual/genericproject/genericproject.cflags b/tests/manual/genericproject/genericproject.cflags
new file mode 100644
index 0000000000..85d51b3f9a
--- /dev/null
+++ b/tests/manual/genericproject/genericproject.cflags
@@ -0,0 +1 @@
+-std=c17
diff --git a/tests/manual/genericproject/genericproject.config b/tests/manual/genericproject/genericproject.config
new file mode 100644
index 0000000000..e0284f4257
--- /dev/null
+++ b/tests/manual/genericproject/genericproject.config
@@ -0,0 +1,2 @@
+// Add predefined macros for your project here. For example:
+// #define THE_ANSWER 42
diff --git a/tests/manual/genericproject/genericproject.creator b/tests/manual/genericproject/genericproject.creator
new file mode 100644
index 0000000000..e94cbbd302
--- /dev/null
+++ b/tests/manual/genericproject/genericproject.creator
@@ -0,0 +1 @@
+[General]
diff --git a/tests/manual/genericproject/genericproject.cxxflags b/tests/manual/genericproject/genericproject.cxxflags
new file mode 100644
index 0000000000..2d81d9d6e3
--- /dev/null
+++ b/tests/manual/genericproject/genericproject.cxxflags
@@ -0,0 +1 @@
+-std=c++17
diff --git a/tests/manual/genericproject/genericproject.files b/tests/manual/genericproject/genericproject.files
new file mode 100644
index 0000000000..5454ad1511
--- /dev/null
+++ b/tests/manual/genericproject/genericproject.files
@@ -0,0 +1,2 @@
+main.cpp
+Makefile
diff --git a/tests/manual/genericproject/genericproject.includes b/tests/manual/genericproject/genericproject.includes
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/manual/genericproject/genericproject.includes
diff --git a/tests/manual/genericproject/main.cpp b/tests/manual/genericproject/main.cpp
new file mode 100644
index 0000000000..b007649eb1
--- /dev/null
+++ b/tests/manual/genericproject/main.cpp
@@ -0,0 +1,7 @@
+#include <iostream>
+
+int main()
+{
+ std::cout << "Generic hi!\n";
+ return 0;
+}