aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmlprojectmanager
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qmlprojectmanager')
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.cpp262
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.h63
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectnodes.cpp84
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectnodes.h13
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp141
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h4
6 files changed, 292 insertions, 275 deletions
diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp
index 5da4acf317..6d93305e6d 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ b/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -24,6 +24,7 @@
****************************************************************************/
#include "qmlproject.h"
+
#include "fileformat/qmlprojectfileformat.h"
#include "fileformat/qmlprojectitem.h"
#include "qmlprojectrunconfiguration.h"
@@ -31,6 +32,9 @@
#include "qmlprojectmanagerconstants.h"
#include "qmlprojectnodes.h"
+#include <coreplugin/documentmanager.h>
+#include <coreplugin/editormanager/documentmodel.h>
+#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
@@ -46,65 +50,84 @@
#include <qmljs/qmljsmodelmanagerinterface.h>
+#include <texteditor/textdocument.h>
+
#include <utils/algorithm.h>
#include <QDebug>
+#include <QRegularExpression>
+#include <QTextCodec>
using namespace Core;
using namespace ProjectExplorer;
+using namespace QmlProjectManager::Internal;
namespace QmlProjectManager {
QmlProject::QmlProject(const Utils::FilePath &fileName)
: Project(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName)
{
- const QString normalized
- = Utils::FileUtils::normalizePathName(fileName.toFileInfo().canonicalFilePath());
- m_canonicalProjectDir = Utils::FilePath::fromString(normalized).parentDir();
-
setId(QmlProjectManager::Constants::QML_PROJECT_ID);
setProjectLanguages(Context(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID));
setDisplayName(fileName.toFileInfo().completeBaseName());
setNeedsBuildConfigurations(false);
+ setBuildSystemCreator([](Target *t) { return new QmlBuildSystem(t); });
+}
- connect(this, &QmlProject::projectFileIsDirty, this, &QmlProject::refreshProjectFile);
+QmlBuildSystem::QmlBuildSystem(Target *target)
+ : BuildSystem(target)
+{
+ const QString normalized
+ = Utils::FileUtils::normalizePathName(target->project()
+ ->projectFilePath().toFileInfo().canonicalFilePath());
+ m_canonicalProjectDir = Utils::FilePath::fromString(normalized).parentDir();
+
+ connect(target->project(), &Project::projectFileIsDirty,
+ this, &QmlBuildSystem::refreshProjectFile);
+
+ // refresh first - project information is used e.g. to decide the default RC's
+ refresh(Everything);
+
+// FIXME: Check. Probably bogus after the BuildSystem move.
+// // addedTarget calls updateEnabled on the runconfigurations
+// // which needs to happen after refresh
+// foreach (Target *t, targets())
+// addedTarget(t);
+
+ connect(target->project(), &Project::activeTargetChanged,
+ this, &QmlBuildSystem::onActiveTargetChanged);
+ updateDeploymentData();
}
-QmlProject::~QmlProject()
+QmlBuildSystem::~QmlBuildSystem()
{
delete m_projectItem.data();
}
-void QmlProject::addedTarget(Target *target)
+void QmlBuildSystem::triggerParsing()
{
- updateDeploymentData(target);
+ refresh(Everything);
}
-void QmlProject::onActiveTargetChanged(Target *target)
+void QmlBuildSystem::onActiveTargetChanged(Target *)
{
- if (m_activeTarget)
- disconnect(m_activeTarget, &Target::kitChanged, this, &QmlProject::onKitChanged);
- m_activeTarget = target;
- if (m_activeTarget)
- connect(target, &Target::kitChanged, this, &QmlProject::onKitChanged);
-
// make sure e.g. the default qml imports are adapted
refresh(Configuration);
}
-void QmlProject::onKitChanged()
+void QmlBuildSystem::onKitChanged()
{
// make sure e.g. the default qml imports are adapted
refresh(Configuration);
}
-Utils::FilePath QmlProject::canonicalProjectDir() const
+Utils::FilePath QmlBuildSystem::canonicalProjectDir() const
{
return m_canonicalProjectDir;
}
-void QmlProject::parseProject(RefreshOptions options)
+void QmlBuildSystem::parseProject(RefreshOptions options)
{
if (options & Files) {
if (options & ProjectFile)
@@ -114,7 +137,7 @@ void QmlProject::parseProject(RefreshOptions options)
m_projectItem = QmlProjectFileFormat::parseProjectFile(projectFilePath(), &errorMessage);
if (m_projectItem) {
connect(m_projectItem.data(), &QmlProjectItem::qmlFilesChanged,
- this, &QmlProject::refreshFiles);
+ this, &QmlBuildSystem::refreshFiles);
} else {
MessageManager::write(tr("Error while loading project file %1.")
@@ -152,7 +175,7 @@ void QmlProject::parseProject(RefreshOptions options)
}
}
-void QmlProject::refresh(RefreshOptions options)
+void QmlBuildSystem::refresh(RefreshOptions options)
{
ParseGuard guard = guardParsingRun();
parseProject(options);
@@ -165,32 +188,32 @@ void QmlProject::refresh(RefreshOptions options)
return;
QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
- modelManager->defaultProjectInfoForProject(this);
+ modelManager->defaultProjectInfoForProject(project());
foreach (const QString &searchPath, makeAbsolute(canonicalProjectDir(), customImportPaths()))
projectInfo.importPaths.maybeInsert(Utils::FilePath::fromString(searchPath),
QmlJS::Dialect::Qml);
- modelManager->updateProjectInfo(projectInfo, this);
+ modelManager->updateProjectInfo(projectInfo, project());
guard.markAsSuccess();
}
-QString QmlProject::mainFile() const
+QString QmlBuildSystem::mainFile() const
{
if (m_projectItem)
return m_projectItem.data()->mainFile();
return QString();
}
-void QmlProject::setMainFile(const QString &mainFilePath)
+void QmlBuildSystem::setMainFile(const QString &mainFilePath)
{
if (m_projectItem)
m_projectItem.data()->setMainFile(mainFilePath);
}
-Utils::FilePath QmlProject::targetDirectory(const Target *target) const
+Utils::FilePath QmlBuildSystem::targetDirectory() const
{
- if (DeviceTypeKitAspect::deviceTypeId(target->kit())
+ if (DeviceTypeKitAspect::deviceTypeId(target()->kit())
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
return canonicalProjectDir();
@@ -198,60 +221,42 @@ Utils::FilePath QmlProject::targetDirectory(const Target *target) const
: Utils::FilePath();
}
-Utils::FilePath QmlProject::targetFile(const Utils::FilePath &sourceFile,
- const Target *target) const
+Utils::FilePath QmlBuildSystem::targetFile(const Utils::FilePath &sourceFile) const
{
const QDir sourceDir(m_projectItem ? m_projectItem->sourceDirectory()
: canonicalProjectDir().toString());
- const QDir targetDir(targetDirectory(target).toString());
+ const QDir targetDir(targetDirectory().toString());
const QString relative = sourceDir.relativeFilePath(sourceFile.toString());
return Utils::FilePath::fromString(QDir::cleanPath(targetDir.absoluteFilePath(relative)));
}
-Utils::EnvironmentItems QmlProject::environment() const
+Utils::EnvironmentItems QmlBuildSystem::environment() const
{
if (m_projectItem)
return m_projectItem.data()->environment();
return {};
}
-QStringList QmlProject::customImportPaths() const
+QStringList QmlBuildSystem::customImportPaths() const
{
if (m_projectItem)
return m_projectItem.data()->importPaths();
return {};
}
-QStringList QmlProject::customFileSelectors() const
+QStringList QmlBuildSystem::customFileSelectors() const
{
if (m_projectItem)
return m_projectItem.data()->fileSelectors();
return {};
}
-bool QmlProject::forceFreeType() const
-{
- if (m_projectItem)
- return m_projectItem.data()->forceFreeType();
- return false;
-}
-
-bool QmlProject::addFiles(const QStringList &filePaths)
-{
- QStringList toAdd;
- foreach (const QString &filePath, filePaths) {
- if (!m_projectItem.data()->matchesFile(filePath))
- toAdd << filePaths;
- }
- return toAdd.isEmpty();
-}
-
-void QmlProject::refreshProjectFile()
+void QmlBuildSystem::refreshProjectFile()
{
- refresh(QmlProject::ProjectFile | Files);
+ refresh(QmlBuildSystem::ProjectFile | Files);
}
-QStringList QmlProject::makeAbsolute(const Utils::FilePath &path, const QStringList &relativePaths)
+QStringList QmlBuildSystem::makeAbsolute(const Utils::FilePath &path, const QStringList &relativePaths)
{
if (path.isEmpty())
return relativePaths;
@@ -262,16 +267,7 @@ QStringList QmlProject::makeAbsolute(const Utils::FilePath &path, const QStringL
});
}
-QVariant QmlProject::additionalData(Id id, const Target *) const
-{
- if (id == Constants::customFileSelectorsData)
- return customFileSelectors();
- if (id == Constants::customForceFreeTypeData)
- return forceFreeType();
- return {};
-}
-
-void QmlProject::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString> &removed)
+void QmlBuildSystem::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString> &removed)
{
refresh(Files);
if (!removed.isEmpty()) {
@@ -281,11 +277,9 @@ void QmlProject::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString
refreshTargetDirectory();
}
-void QmlProject::refreshTargetDirectory()
+void QmlBuildSystem::refreshTargetDirectory()
{
- const QList<Target *> targetList = targets();
- for (Target *target : targetList)
- updateDeploymentData(target);
+ updateDeploymentData();
}
Tasks QmlProject::projectIssues(const Kit *k) const
@@ -332,9 +326,6 @@ Project::RestoreResult QmlProject::fromMap(const QVariantMap &map, QString *erro
if (result != RestoreResult::Ok)
return result;
- // refresh first - project information is used e.g. to decide the default RC's
- refresh(Everything);
-
if (!activeTarget()) {
// find a kit that matches prerequisites (prefer default one)
const QList<Kit*> kits = Utils::filtered(KitManager::kits(), [this](const Kit *k) {
@@ -349,18 +340,6 @@ Project::RestoreResult QmlProject::fromMap(const QVariantMap &map, QString *erro
}
}
- // addedTarget calls updateEnabled on the runconfigurations
- // which needs to happen after refresh
- foreach (Target *t, targets())
- addedTarget(t);
-
- connect(this, &ProjectExplorer::Project::addedTarget, this, &QmlProject::addedTarget);
-
- connect(this, &ProjectExplorer::Project::activeTargetChanged,
- this, &QmlProject::onActiveTargetChanged);
-
- onActiveTargetChanged(activeTarget());
-
return RestoreResult::Ok;
}
@@ -369,12 +348,12 @@ ProjectExplorer::DeploymentKnowledge QmlProject::deploymentKnowledge() const
return DeploymentKnowledge::Perfect;
}
-void QmlProject::generateProjectTree()
+void QmlBuildSystem::generateProjectTree()
{
if (!m_projectItem)
return;
- auto newRoot = std::make_unique<Internal::QmlProjectNode>(this);
+ auto newRoot = std::make_unique<QmlProjectNode>(project());
for (const QString &f : m_projectItem.data()->files()) {
const Utils::FilePath fileName = Utils::FilePath::fromString(f);
@@ -388,12 +367,12 @@ void QmlProject::generateProjectTree()
refreshTargetDirectory();
}
-void QmlProject::updateDeploymentData(ProjectExplorer::Target *target)
+void QmlBuildSystem::updateDeploymentData()
{
if (!m_projectItem)
return;
- if (DeviceTypeKitAspect::deviceTypeId(target->kit())
+ if (DeviceTypeKitAspect::deviceTypeId(target()->kit())
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
return;
}
@@ -402,10 +381,119 @@ void QmlProject::updateDeploymentData(ProjectExplorer::Target *target)
for (const QString &file : m_projectItem->files()) {
deploymentData.addFile(
file,
- targetFile(Utils::FilePath::fromString(file), target).parentDir().toString());
+ targetFile(Utils::FilePath::fromString(file)).parentDir().toString());
+ }
+
+ setDeploymentData(deploymentData);
+}
+
+QVariant QmlBuildSystem::additionalData(Id id) const
+{
+ if (id == Constants::customFileSelectorsData)
+ return customFileSelectors();
+ if (id == Constants::customForceFreeTypeData)
+ return forceFreeType();
+ return {};
+}
+
+bool QmlBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
+{
+ 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;
+ }
+
+ return false;
+ }
+
+ return BuildSystem::supportsAction(context, action, node);
+}
+
+QmlProject *QmlBuildSystem::qmlProject() const
+{
+ return static_cast<QmlProject *>(BuildSystem::project());
+}
+
+bool QmlBuildSystem::forceFreeType() const
+{
+ if (m_projectItem)
+ return m_projectItem.data()->forceFreeType();
+ return false;
+}
+
+bool QmlBuildSystem::addFiles(Node *context, const QStringList &filePaths, QStringList *)
+{
+ if (!dynamic_cast<QmlProjectNode *>(context))
+ return false;
+
+ QStringList toAdd;
+ foreach (const QString &filePath, filePaths) {
+ if (!m_projectItem.data()->matchesFile(filePath))
+ toAdd << filePaths;
}
+ return toAdd.isEmpty();
+}
+
+bool QmlBuildSystem::deleteFiles(Node *context, const QStringList &filePaths)
+{
+ if (dynamic_cast<QmlProjectNode *>(context))
+ return true;
- target->setDeploymentData(deploymentData);
+ return BuildSystem::deleteFiles(context, filePaths);
}
+
+bool QmlBuildSystem::renameFile(Node * context, const QString &filePath, const QString &newFilePath)
+{
+ if (dynamic_cast<QmlProjectNode *>(context)) {
+ if (filePath.endsWith(mainFile())) {
+ 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;
+
+ refresh(Everything);
+ }
+
+ return true;
+ }
+
+ return BuildSystem::renameFile(context, filePath, newFilePath);
+}
+
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h
index 6433333278..f12da342fe 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.h
+++ b/src/plugins/qmlprojectmanager/qmlproject.h
@@ -28,27 +28,41 @@
#include "qmlprojectmanager_global.h"
#include "qmlprojectnodes.h"
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h>
#include <utils/environment.h>
#include <QPointer>
-namespace ProjectExplorer { class RunConfiguration; }
-
namespace QmlProjectManager {
+class QmlProject;
class QmlProjectItem;
-class QMLPROJECTMANAGER_EXPORT QmlProject : public ProjectExplorer::Project
+class QmlBuildSystem : public ProjectExplorer::BuildSystem
{
Q_OBJECT
public:
- explicit QmlProject(const Utils::FilePath &filename);
- ~QmlProject() override;
+ explicit QmlBuildSystem(ProjectExplorer::Target *target);
+ ~QmlBuildSystem();
- ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
+ void triggerParsing() final;
+
+ 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 *qmlProject() const;
+
+ QVariant additionalData(Core::Id id) const override;
enum RefreshOption {
ProjectFile = 0x01,
@@ -63,9 +77,8 @@ public:
Utils::FilePath canonicalProjectDir() const;
QString mainFile() const;
void setMainFile(const QString &mainFilePath);
- Utils::FilePath targetDirectory(const ProjectExplorer::Target *target) const;
- Utils::FilePath targetFile(const Utils::FilePath &sourceFile,
- const ProjectExplorer::Target *target) const;
+ Utils::FilePath targetDirectory() const;
+ Utils::FilePath targetFile(const Utils::FilePath &sourceFile) const;
Utils::EnvironmentItems environment() const;
QStringList customImportPaths() const;
@@ -78,31 +91,37 @@ public:
static QStringList makeAbsolute(const Utils::FilePath &path, const QStringList &relativePaths);
- QVariant additionalData(Core::Id id, const ProjectExplorer::Target *target) const override;
-
-protected:
- RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
-
-private:
- ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
-
void generateProjectTree();
- void updateDeploymentData(ProjectExplorer::Target *target);
+ void updateDeploymentData();
void refreshFiles(const QSet<QString> &added, const QSet<QString> &removed);
void refreshTargetDirectory();
- void addedTarget(ProjectExplorer::Target *target);
void onActiveTargetChanged(ProjectExplorer::Target *target);
void onKitChanged();
// plain format
void parseProject(RefreshOptions options);
- ProjectExplorer::Target *m_activeTarget = nullptr;
-
QPointer<QmlProjectItem> m_projectItem;
Utils::FilePath m_canonicalProjectDir;
};
+class QMLPROJECTMANAGER_EXPORT QmlProject : public ProjectExplorer::Project
+{
+ Q_OBJECT
+
+public:
+ explicit QmlProject(const Utils::FilePath &filename);
+
+ ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
+
+protected:
+ RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
+
+private:
+ ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
+
+};
+
} // namespace QmlProjectManager
-Q_DECLARE_OPERATORS_FOR_FLAGS(QmlProjectManager::QmlProject::RefreshOptions)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QmlProjectManager::QmlBuildSystem::RefreshOptions)
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
index a4494e7064..cfa6c5e74e 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
@@ -24,28 +24,19 @@
****************************************************************************/
#include "qmlprojectnodes.h"
-#include "qmlproject.h"
-#include <coreplugin/idocument.h>
#include <coreplugin/fileiconprovider.h>
-#include <coreplugin/documentmanager.h>
-#include <coreplugin/editormanager/documentmodel.h>
-#include <coreplugin/editormanager/ieditor.h>
-#include <projectexplorer/projectexplorer.h>
-#include <texteditor/textdocument.h>
-#include <utils/algorithm.h>
-#include <utils/textfileformat.h>
-#include <QRegularExpression>
-#include <QTextCodec>
+#include <projectexplorer/project.h>
+#include <projectexplorer/projectexplorer.h>
using namespace ProjectExplorer;
namespace QmlProjectManager {
namespace Internal {
-QmlProjectNode::QmlProjectNode(QmlProject *project) : ProjectNode(project->projectDirectory()),
- m_project(project)
+QmlProjectNode::QmlProjectNode(Project *project)
+ : ProjectNode(project->projectDirectory())
{
setDisplayName(project->projectFilePath().toFileInfo().completeBaseName());
@@ -53,72 +44,5 @@ QmlProjectNode::QmlProjectNode(QmlProject *project) : ProjectNode(project->proje
setIcon(qmlProjectIcon);
}
-bool QmlProjectNode::supportsAction(ProjectAction action, const Node *node) const
-{
- 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;
- }
-
- return false;
-}
-
-bool QmlProjectNode::addFiles(const QStringList &filePaths, QStringList * /*notAdded*/)
-{
- return m_project->addFiles(filePaths);
-}
-
-bool QmlProjectNode::deleteFiles(const QStringList & /*filePaths*/)
-{
- return true;
-}
-
-bool QmlProjectNode::renameFile(const QString & filePath, const QString & newFilePath)
-{
- 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;
- }
-
- // 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;
- m_project->refresh(QmlProject::Everything);
- }
-
- return true;
-}
-
} // namespace Internal
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.h b/src/plugins/qmlprojectmanager/qmlprojectnodes.h
index 4d6fe4cfcf..b400a21c69 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectnodes.h
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.h
@@ -28,23 +28,12 @@
#include <projectexplorer/projectnodes.h>
namespace QmlProjectManager {
-
-class QmlProject;
-
namespace Internal {
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;
+ explicit QmlProjectNode(ProjectExplorer::Project *project);
};
} // namespace Internal
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
index 01b946a47b..1be8e33a2f 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
@@ -73,7 +73,7 @@ static bool caseInsensitiveLessThan(const QString &s1, const QString &s2)
class MainQmlFileAspect : public ProjectConfigurationAspect
{
public:
- explicit MainQmlFileAspect(QmlProject *project);
+ explicit MainQmlFileAspect(Target *target);
~MainQmlFileAspect() override { delete m_fileListCombo; }
enum MainScriptSource {
@@ -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;
@@ -97,7 +97,12 @@ public:
bool isQmlFilePresent();
public:
- QmlProject *m_project;
+ QmlBuildSystem *qmlBuildSystem() const
+ {
+ return static_cast<QmlBuildSystem *>(m_target->buildSystem());
+ }
+
+ Target *m_target = nullptr;
QPointer<QComboBox> m_fileListCombo;
QStandardItemModel m_fileListModel;
QString m_scriptFile;
@@ -107,8 +112,8 @@ public:
QString m_mainScriptFilename;
};
-MainQmlFileAspect::MainQmlFileAspect(QmlProject *project)
- : m_project(project)
+MainQmlFileAspect::MainQmlFileAspect(Target *target)
+ : m_target(target)
, m_scriptFile(M_CURRENT_FILE)
{
connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
@@ -117,7 +122,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 +135,7 @@ 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.addItems(QmlProjectRunConfiguration::tr("Main QML file:"), m_fileListCombo.data());
}
void MainQmlFileAspect::toMap(QVariantMap &map) const
@@ -153,7 +158,7 @@ void MainQmlFileAspect::fromMap(const QVariantMap &map)
void MainQmlFileAspect::updateFileComboBox()
{
- QDir projectDir(m_project->projectDirectory().toString());
+ QDir projectDir(m_target->project()->projectDirectory().toString());
if (mainScriptSource() == FileInProjectFile) {
const QString mainScriptInFilePath = projectDir.relativeFilePath(mainScript());
@@ -170,8 +175,8 @@ void MainQmlFileAspect::updateFileComboBox()
m_fileListModel.appendRow(new QStandardItem(QLatin1String(CURRENT_FILE)));
QModelIndex currentIndex;
- QStringList sortedFiles = Utils::transform(m_project->files(Project::SourceFiles),
- &Utils::FilePath::toString);
+ QStringList sortedFiles = Utils::transform(m_target->project()->files(Project::SourceFiles),
+ &FilePath::toString);
// make paths relative to project directory
QStringList relativeFiles;
@@ -207,7 +212,7 @@ void MainQmlFileAspect::updateFileComboBox()
MainQmlFileAspect::MainScriptSource MainQmlFileAspect::mainScriptSource() const
{
- if (!m_project->mainFile().isEmpty())
+ if (!qmlBuildSystem()->mainFile().isEmpty())
return FileInProjectFile;
if (!m_mainScriptFilename.isEmpty())
return FileInSettings;
@@ -234,7 +239,7 @@ void MainQmlFileAspect::setScriptSource(MainScriptSource source, const QString &
m_mainScriptFilename.clear();
} else { // FileInSettings
m_scriptFile = settingsPath;
- m_mainScriptFilename = m_project->projectDirectory().toString() + '/' + m_scriptFile;
+ m_mainScriptFilename = m_target->project()->projectDirectory().toString() + '/' + m_scriptFile;
}
emit changed();
@@ -246,12 +251,12 @@ void MainQmlFileAspect::setScriptSource(MainScriptSource source, const QString &
*/
QString MainQmlFileAspect::mainScript() const
{
- if (!m_project->mainFile().isEmpty()) {
- const QString pathInProject = m_project->mainFile();
+ if (!qmlBuildSystem()->mainFile().isEmpty()) {
+ const QString pathInProject = qmlBuildSystem()->mainFile();
if (QFileInfo(pathInProject).isAbsolute())
return pathInProject;
else
- return QDir(m_project->canonicalProjectDir().toString()).absoluteFilePath(pathInProject);
+ return QDir(qmlBuildSystem()->canonicalProjectDir().toString()).absoluteFilePath(pathInProject);
}
if (!m_mainScriptFilename.isEmpty())
@@ -279,9 +284,9 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id)
{
auto envAspect = addAspect<EnvironmentAspect>();
- auto envModifier = [target](Environment env) {
- if (auto project = qobject_cast<const QmlProject *>(target->project()))
- env.modify(project->environment());
+ auto envModifier = [this](Environment env) {
+ if (auto bs = dynamic_cast<const QmlBuildSystem *>(activeBuildSystem()))
+ env.modify(bs->environment());
return env;
};
@@ -306,22 +311,16 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id)
argumentAspect->setSettingsKey(Constants::QML_VIEWER_ARGUMENTS_KEY);
setCommandLineGetter([this] {
- return CommandLine(FilePath::fromString(theExecutable()),
- commandLineArguments(),
- CommandLine::Raw);
+ return CommandLine(qmlScenePath(), commandLineArguments(), CommandLine::Raw);
});
- auto qmlProject = qobject_cast<QmlProject *>(target->project());
- QTC_ASSERT(qmlProject, return);
- m_mainQmlFileAspect = addAspect<MainQmlFileAspect>(qmlProject);
- connect(m_mainQmlFileAspect, &MainQmlFileAspect::changed,
- this, &QmlProjectRunConfiguration::updateEnabledState);
+ m_mainQmlFileAspect = addAspect<MainQmlFileAspect>(target);
+ connect(m_mainQmlFileAspect, &MainQmlFileAspect::changed, this, &RunConfiguration::update);
- connect(target, &Target::kitChanged,
- this, &QmlProjectRunConfiguration::updateEnabledState);
+ connect(target, &Target::kitChanged, this, &RunConfiguration::update);
setDisplayName(tr("QML Scene", "QMLRunConfiguration display name."));
- updateEnabledState();
+ update();
}
Runnable QmlProjectRunConfiguration::runnable() const
@@ -329,7 +328,8 @@ Runnable QmlProjectRunConfiguration::runnable() const
Runnable r;
r.setCommandLine(commandLine());
r.environment = aspect<EnvironmentAspect>()->environment();
- r.workingDirectory = static_cast<QmlProject *>(project())->targetDirectory(target()).toString();
+ const QmlBuildSystem *bs = static_cast<QmlBuildSystem *>(activeBuildSystem());
+ r.workingDirectory = bs->targetDirectory().toString();
return r;
}
@@ -337,83 +337,83 @@ QString QmlProjectRunConfiguration::disabledReason() const
{
if (mainScript().isEmpty())
return tr("No script file to execute.");
+
+ const FilePath viewer = qmlScenePath();
if (DeviceTypeKitAspect::deviceTypeId(target()->kit())
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE
- && !commandLine().executable().exists()) {
+ && !viewer.exists()) {
return tr("No qmlscene found.");
}
- if (commandLine().executable().isEmpty())
+ if (viewer.isEmpty())
return tr("No qmlscene binary specified for target device.");
return RunConfiguration::disabledReason();
}
-QString QmlProjectRunConfiguration::theExecutable() const
+FilePath QmlProjectRunConfiguration::qmlScenePath() const
{
const QString qmlViewer = m_qmlViewerAspect->value();
if (!qmlViewer.isEmpty())
- return qmlViewer;
+ return FilePath::fromString(qmlViewer);
- BaseQtVersion *version = QtKitAspect::qtVersion(target()->kit());
+ Kit *kit = target()->kit();
+ BaseQtVersion *version = QtKitAspect::qtVersion(kit);
if (!version) // No Qt version in Kit. Don't try to run qmlscene.
- return QString();
+ return {};
- const Id deviceType = DeviceTypeKitAspect::deviceTypeId(target()->kit());
+ const Id deviceType = DeviceTypeKitAspect::deviceTypeId(kit);
if (deviceType == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
// If not given explicitly by Qt Version, try to pick it from $PATH.
- return version->type() == QtSupport::Constants::DESKTOPQT
- ? version->qmlsceneCommand() : QString("qmlscene");
+ const bool isDesktop = version->type() == QtSupport::Constants::DESKTOPQT;
+ return FilePath::fromString(isDesktop ? version->qmlsceneCommand() : QString("qmlscene"));
}
- IDevice::ConstPtr dev = DeviceKitAspect::device(target()->kit());
+ IDevice::ConstPtr dev = DeviceKitAspect::device(kit);
if (dev.isNull()) // No device set. We don't know where to run qmlscene.
- return QString();
+ return {};
const QString qmlscene = dev->qmlsceneCommand();
// If not given explicitly by device, try to pick it from $PATH.
- return qmlscene.isEmpty() ? QString("qmlscene") : qmlscene;
+ return FilePath::fromString(qmlscene.isEmpty() ? QString("qmlscene") : qmlscene);
}
QString QmlProjectRunConfiguration::commandLineArguments() const
{
// arguments in .user file
QString args = aspect<ArgumentsAspect>()->arguments(macroExpander());
- const Target *currentTarget = target();
- const IDevice::ConstPtr device = DeviceKitAspect::device(currentTarget->kit());
- const Utils::OsType osType = device ? device->osType() : Utils::HostOsInfo::hostOs();
+ const IDevice::ConstPtr device = DeviceKitAspect::device(target()->kit());
+ const OsType osType = device ? device->osType() : HostOsInfo::hostOs();
// arguments from .qmlproject file
- const QmlProject *project = qobject_cast<QmlProject *>(currentTarget->project());
+ const QmlBuildSystem *bs = qobject_cast<QmlBuildSystem *>(target()->buildSystem());
foreach (const QString &importPath,
- QmlProject::makeAbsolute(project->targetDirectory(currentTarget), project->customImportPaths())) {
- Utils::QtcProcess::addArg(&args, QLatin1String("-I"), osType);
- Utils::QtcProcess::addArg(&args, importPath, osType);
+ QmlBuildSystem::makeAbsolute(bs->targetDirectory(), bs->customImportPaths())) {
+ QtcProcess::addArg(&args, "-I", osType);
+ QtcProcess::addArg(&args, importPath, osType);
}
- for (const QString &fileSelector : project->customFileSelectors()) {
- Utils::QtcProcess::addArg(&args, QLatin1String("-S"), osType);
- Utils::QtcProcess::addArg(&args, fileSelector, osType);
+ for (const QString &fileSelector : bs->customFileSelectors()) {
+ QtcProcess::addArg(&args, "-S", osType);
+ QtcProcess::addArg(&args, fileSelector, osType);
}
- if (Utils::HostOsInfo::isWindowsHost() && project->forceFreeType()) {
+ if (Utils::HostOsInfo::isWindowsHost() && bs->forceFreeType()) {
Utils::QtcProcess::addArg(&args, "-platform", osType);
Utils::QtcProcess::addArg(&args, "windows:fontengine=freetype", osType);
}
- const QString main = project->targetFile(Utils::FilePath::fromString(mainScript()),
- currentTarget).toString();
+ const QString main = bs->targetFile(FilePath::fromString(mainScript())).toString();
if (!main.isEmpty())
- Utils::QtcProcess::addArg(&args, main, osType);
+ QtcProcess::addArg(&args, main, osType);
return args;
}
-void QmlProjectRunConfiguration::updateEnabledState()
+bool QmlProjectRunConfiguration::isEnabled() const
{
- bool enabled = false;
if (m_mainQmlFileAspect->isQmlFilePresent() && !commandLine().executable().isEmpty()) {
- Project *p = target()->project();
- enabled = !p->isParsing() && p->hasParsingData();
+ BuildSystem *bs = activeBuildSystem();
+ return !bs->isParsing() && bs->hasParsingData();
}
- setEnabled(enabled);
+ return false;
}
bool MainQmlFileAspect::isQmlFilePresent()
@@ -421,29 +421,26 @@ bool MainQmlFileAspect::isQmlFilePresent()
bool qmlFileFound = false;
if (mainScriptSource() == FileInEditor) {
IDocument *document = EditorManager::currentDocument();
- Utils::MimeType mainScriptMimeType = Utils::mimeTypeForFile(mainScript());
+ MimeType mainScriptMimeType = Utils::mimeTypeForFile(mainScript());
if (document) {
m_currentFileFilename = document->filePath().toString();
- if (mainScriptMimeType.matchesName(
- QLatin1String(ProjectExplorer::Constants::QML_MIMETYPE))
- || mainScriptMimeType.matchesName(
- QLatin1String(ProjectExplorer::Constants::QMLUI_MIMETYPE))) {
+ if (mainScriptMimeType.matchesName(ProjectExplorer::Constants::QML_MIMETYPE)
+ || mainScriptMimeType.matchesName(ProjectExplorer::Constants::QMLUI_MIMETYPE)) {
qmlFileFound = true;
}
}
if (!document
- || mainScriptMimeType.matchesName(QLatin1String(QmlJSTools::Constants::QMLPROJECT_MIMETYPE))) {
+ || mainScriptMimeType.matchesName(QmlJSTools::Constants::QMLPROJECT_MIMETYPE)) {
// find a qml file with lowercase filename. This is slow, but only done
// in initialization/other border cases.
- const auto files = m_project->files(Project::SourceFiles);
- for (const Utils::FilePath &filename : files) {
+ const auto files = m_target->project()->files(Project::SourceFiles);
+ for (const FilePath &filename : files) {
const QFileInfo fi = filename.toFileInfo();
if (!filename.isEmpty() && fi.baseName().at(0).isLower()) {
Utils::MimeType type = Utils::mimeTypeForFile(fi);
- if (type.matchesName(QLatin1String(ProjectExplorer::Constants::QML_MIMETYPE))
- || type.matchesName(
- QLatin1String(ProjectExplorer::Constants::QMLUI_MIMETYPE))) {
+ if (type.matchesName(ProjectExplorer::Constants::QML_MIMETYPE)
+ || type.matchesName(ProjectExplorer::Constants::QMLUI_MIMETYPE)) {
m_currentFileFilename = filename.toString();
qmlFileFound = true;
break;
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
index 8a18fd0ef9..d905f2758b 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
@@ -44,10 +44,10 @@ public:
private:
ProjectExplorer::Runnable runnable() const final;
QString disabledReason() const final;
- void updateEnabledState() final;
+ bool isEnabled() const final;
QString mainScript() const;
- QString theExecutable() const;
+ Utils::FilePath qmlScenePath() const;
QString commandLineArguments() const;
ProjectExplorer::BaseStringAspect *m_qmlViewerAspect;