aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2017-11-28 15:57:15 +0100
committerUlf Hermann <ulf.hermann@qt.io>2018-01-29 09:04:45 +0000
commite44504371c99960e05ca42bae4ce404bcc18998a (patch)
tree458c9a9e7bddf3dc113e72fcd2794d71bcd4fd82
parentc535cce8c670c17d018571e7f32a4f624b0c09a9 (diff)
QmlProjectManager: Prepare for running on remote devices
We add a "targetDirectory" property to the file format and fill in the deployment data. (cherry picked from commit fba61c5b55052c382e030748fa6e2703abb5401d) Change-Id: If207cd5c77175c54cffdb5df92ea85c425cd3191 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
-rw-r--r--share/qtcreator/qml-type-descriptions/qmlproject.qmltypes1
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp4
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp5
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h3
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.cpp96
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.h8
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp72
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h4
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfigurationfactory.cpp1
9 files changed, 141 insertions, 53 deletions
diff --git a/share/qtcreator/qml-type-descriptions/qmlproject.qmltypes b/share/qtcreator/qml-type-descriptions/qmlproject.qmltypes
index a0dbed2b56..c7e7cdf937 100644
--- a/share/qtcreator/qml-type-descriptions/qmlproject.qmltypes
+++ b/share/qtcreator/qml-type-descriptions/qmlproject.qmltypes
@@ -11,6 +11,7 @@ Module {
"QmlProject/Project 1.1"
]
Property { name: "sourceDirectory"; type: "string" }
+ Property { name: "targetDirectory": type: "string" }
Property { name: "mainFile"; type: "string" }
Property { name: "importPaths"; type: "string"; isList: true }
Property { name: "content"; type: "QmlProjectItem"; isList: true }
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp b/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
index 7893abc266..6154ecd3d7 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
@@ -88,6 +88,10 @@ QmlProjectItem *QmlProjectFileFormat::parseProjectFile(const Utils::FileName &fi
if (importPathsProperty.isValid())
projectItem->setImportPaths(importPathsProperty.toStringList());
+ const QVariant targetDirectoryPropery = rootNode->property("targetDirectory");
+ if (targetDirectoryPropery.isValid())
+ projectItem->setTargetDirectory(targetDirectoryPropery.toString());
+
if (debug)
qDebug() << "importPath:" << importPathsProperty << "mainFile:" << mainFileProperty;
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
index 0d8d4e1550..8e9e99475f 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
@@ -51,6 +51,11 @@ void QmlProjectItem::setSourceDirectory(const QString &directoryPath)
setImportPaths(m_importPaths);
}
+void QmlProjectItem::setTargetDirectory(const QString &directoryPath)
+{
+ m_targetDirectory = directoryPath;
+}
+
void QmlProjectItem::setImportPaths(const QStringList &importPaths)
{
if (m_importPaths != importPaths)
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
index 09298174a7..757e571468 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
@@ -46,6 +46,8 @@ class QmlProjectItem : public QObject
public:
QString sourceDirectory() const { return m_sourceDirectory; }
void setSourceDirectory(const QString &directoryPath);
+ QString targetDirectory() const { return m_targetDirectory; }
+ void setTargetDirectory(const QString &directoryPath);
QStringList importPaths() const { return m_absoluteImportPaths; }
void setImportPaths(const QStringList &paths);
@@ -63,6 +65,7 @@ signals:
protected:
QString m_sourceDirectory;
+ QString m_targetDirectory;
QStringList m_importPaths;
QStringList m_absoluteImportPaths;
QString m_mainFile;
diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp
index d1b32f8c36..2f9ab498da 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ b/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -36,6 +36,7 @@
#include <coreplugin/messagemanager.h>
#include <coreplugin/documentmanager.h>
+#include <projectexplorer/deploymentdata.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/target.h>
@@ -59,6 +60,10 @@ QmlProject::QmlProject(const Utils::FileName &fileName) :
Project(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName,
[this]() { refreshProjectFile(); })
{
+ const QString normalized
+ = Utils::FileUtils::normalizePathName(fileName.toFileInfo().canonicalFilePath());
+ m_canonicalProjectDir = Utils::FileName::fromString(normalized).parentDir();
+
setId(QmlProjectManager::Constants::QML_PROJECT_ID);
setProjectLanguages(Context(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID));
setDisplayName(fileName.toFileInfo().completeBaseName());
@@ -75,6 +80,7 @@ void QmlProject::addedTarget(Target *target)
this, &QmlProject::addedRunConfiguration);
foreach (RunConfiguration *rc, target->runConfigurations())
addedRunConfiguration(rc);
+ updateDeploymentData(target);
}
void QmlProject::onActiveTargetChanged(Target *target)
@@ -104,9 +110,9 @@ void QmlProject::addedRunConfiguration(RunConfiguration *rc)
qmlrc->updateEnabledState();
}
-QDir QmlProject::projectDir() const
+Utils::FileName QmlProject::canonicalProjectDir() const
{
- return projectFilePath().toFileInfo().dir();
+ return m_canonicalProjectDir;
}
void QmlProject::parseProject(RefreshOptions options)
@@ -129,13 +135,17 @@ void QmlProject::parseProject(RefreshOptions options)
}
}
if (m_projectItem) {
- m_projectItem.data()->setSourceDirectory(projectDir().path());
+ m_projectItem.data()->setSourceDirectory(canonicalProjectDir().toString());
+ if (m_projectItem->targetDirectory().isEmpty())
+ m_projectItem->setTargetDirectory(canonicalProjectDir().toString());
+
if (auto modelManager = QmlJS::ModelManagerInterface::instance())
modelManager->updateSourceFiles(m_projectItem.data()->files(), true);
QString mainFilePath = m_projectItem.data()->mainFile();
if (!mainFilePath.isEmpty()) {
- mainFilePath = projectDir().absoluteFilePath(mainFilePath);
+ mainFilePath
+ = QDir(canonicalProjectDir().toString()).absoluteFilePath(mainFilePath);
Utils::FileReader reader;
QString errorMessage;
if (!reader.fetch(mainFilePath, &errorMessage)) {
@@ -183,6 +193,26 @@ QString QmlProject::mainFile() const
return QString();
}
+Utils::FileName QmlProject::targetDirectory(const Target *target) const
+{
+ if (DeviceTypeKitInformation::deviceTypeId(target->kit())
+ == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
+ return canonicalProjectDir();
+
+ return m_projectItem ? Utils::FileName::fromString(m_projectItem->targetDirectory())
+ : Utils::FileName();
+}
+
+Utils::FileName QmlProject::targetFile(const Utils::FileName &sourceFile,
+ const Target *target) const
+{
+ const QDir sourceDir(m_projectItem ? m_projectItem->sourceDirectory()
+ : canonicalProjectDir().toString());
+ const QDir targetDir(targetDirectory(target).toString());
+ const QString relative = sourceDir.relativeFilePath(sourceFile.toString());
+ return Utils::FileName::fromString(QDir::cleanPath(targetDir.absoluteFilePath(relative)));
+}
+
bool QmlProject::validProjectFile() const
{
return !m_projectItem.isNull();
@@ -219,17 +249,18 @@ void QmlProject::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString
if (auto modelManager = QmlJS::ModelManagerInterface::instance())
modelManager->removeFiles(removed.toList());
}
+ refreshTargetDirectory();
}
-bool QmlProject::supportsKit(Kit *k, QString *errorMessage) const
+void QmlProject::refreshTargetDirectory()
{
- Id deviceType = DeviceTypeKitInformation::deviceTypeId(k);
- if (deviceType != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
- if (errorMessage)
- *errorMessage = tr("Device type is not desktop.");
- return false;
- }
+ const QList<Target *> targetList = targets();
+ for (Target *target : targetList)
+ updateDeploymentData(target);
+}
+bool QmlProject::supportsKit(Kit *k, QString *errorMessage) const
+{
QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k);
if (!version) {
if (errorMessage)
@@ -262,15 +293,28 @@ Project::RestoreResult QmlProject::fromMap(const QVariantMap &map, QString *erro
return false;
IDevice::ConstPtr dev = DeviceKitInformation::device(k);
- if (dev.isNull() || dev->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
+ if (dev.isNull())
return false;
+
QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k);
- if (!version || version->type() != QLatin1String(QtSupport::Constants::DESKTOPQT))
+ if (!version || version->qtVersion() < QtSupport::QtVersionNumber(5, 0, 0))
return false;
- return version->qtVersion() >= QtSupport::QtVersionNumber(5, 0, 0)
- && !static_cast<QtSupport::DesktopQtVersion *>(version)
- ->qmlsceneCommand().isEmpty();
+ if (dev->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
+ if (version->type() != QLatin1String(QtSupport::Constants::DESKTOPQT)) {
+ return !static_cast<QtSupport::DesktopQtVersion *>(version)
+ ->qmlsceneCommand().isEmpty();
+ } else {
+ // Non-desktop Qt on a desktop device? We don't support that.
+ return false;
+ }
+ }
+
+ // If not a desktop device, don't check the Qt version for qmlscene.
+ // The device is responsible for providing it and we assume qmlscene can be found
+ // in $PATH if it's not explicitly given.
+ return true;
+
})
);
@@ -322,7 +366,27 @@ void QmlProject::generateProjectTree()
newRoot->addNestedNode(new FileNode(projectFilePath(), FileType::Project, false));
setRootProjectNode(newRoot);
+ refreshTargetDirectory();
}
+void QmlProject::updateDeploymentData(ProjectExplorer::Target *target)
+{
+ if (!m_projectItem)
+ return;
+
+ if (DeviceTypeKitInformation::deviceTypeId(target->kit())
+ == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
+ return;
+ }
+
+ ProjectExplorer::DeploymentData deploymentData;
+ for (const QString &file : m_projectItem->files()) {
+ deploymentData.addFile(
+ file,
+ targetFile(Utils::FileName::fromString(file), target).parentDir().toString());
+ }
+
+ target->setDeploymentData(deploymentData);
+}
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h
index 62c7980a28..c1b667d21a 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.h
+++ b/src/plugins/qmlprojectmanager/qmlproject.h
@@ -60,8 +60,11 @@ public:
void refresh(RefreshOptions options);
- QDir projectDir() const;
+ Utils::FileName canonicalProjectDir() const;
QString mainFile() const;
+ Utils::FileName targetDirectory(const ProjectExplorer::Target *target) const;
+ Utils::FileName targetFile(const Utils::FileName &sourceFile,
+ const ProjectExplorer::Target *target) const;
QStringList customImportPaths() const;
bool addFiles(const QStringList &filePaths);
@@ -74,7 +77,9 @@ protected:
private:
void generateProjectTree();
+ void updateDeploymentData(ProjectExplorer::Target *target);
void refreshFiles(const QSet<QString> &added, const QSet<QString> &removed);
+ void refreshTargetDirectory();
void addedTarget(ProjectExplorer::Target *target);
void onActiveTargetChanged(ProjectExplorer::Target *target);
void onKitChanged();
@@ -86,6 +91,7 @@ private:
ProjectExplorer::Target *m_activeTarget = nullptr;
QPointer<QmlProjectItem> m_projectItem;
+ Utils::FileName m_canonicalProjectDir;
};
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
index 3cf0aaec9d..11afeee224 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
@@ -80,8 +80,7 @@ Runnable QmlProjectRunConfiguration::runnable() const
r.commandLineArguments = commandLineArguments();
r.runMode = ApplicationLauncher::Gui;
r.environment = extraAspect<QmlProjectEnvironmentAspect>()->environment();
- r.workingDirectory = canonicalCapsPath(target()->project()->projectFilePath()
- .toFileInfo().absolutePath());
+ r.workingDirectory = static_cast<QmlProject *>(project())->targetDirectory(target()).toString();
return r;
}
@@ -89,48 +88,60 @@ QString QmlProjectRunConfiguration::disabledReason() const
{
if (mainScript().isEmpty())
return tr("No script file to execute.");
- if (!QFileInfo::exists(executable()))
+ if (DeviceTypeKitInformation::deviceTypeId(target()->kit())
+ == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE
+ && !QFileInfo::exists(executable())) {
return tr("No qmlscene found.");
+ }
+ if (executable().isEmpty())
+ return tr("No qmlscene binary specified for target device.");
return RunConfiguration::disabledReason();
}
QString QmlProjectRunConfiguration::executable() const
{
BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit());
- if (!version)
+ if (!version) // No Qt version in Kit. Don't try to run qmlscene.
+ return QString();
+
+ const Id deviceType = DeviceTypeKitInformation::deviceTypeId(target()->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
+ ? static_cast<QtSupport::DesktopQtVersion *>(version)->qmlsceneCommand()
+ : QString("qmlscene");
+ }
+
+ IDevice::ConstPtr dev = DeviceKitInformation::device(target()->kit());
+ if (dev.isNull()) // No device set. We don't know where to run qmlscene.
return QString();
- QTC_ASSERT(version->type() == QLatin1String(QtSupport::Constants::DESKTOPQT), return QString());
- return static_cast<QtSupport::DesktopQtVersion *>(version)->qmlsceneCommand();
+ const QString qmlscene = dev->qmlsceneCommand();
+ // If not given explicitly by device, try to pick it from $PATH.
+ return qmlscene.isEmpty() ? QString("qmlscene") : qmlscene;
}
QString QmlProjectRunConfiguration::commandLineArguments() const
{
// arguments in .user file
QString args = m_qmlViewerArgs;
+ const IDevice::ConstPtr device = DeviceKitInformation::device(target()->kit());
+ const Utils::OsType osType = device ? device->osType() : Utils::HostOsInfo::hostOs();
// arguments from .qmlproject file
QmlProject *project = static_cast<QmlProject *>(target()->project());
foreach (const QString &importPath, project->customImportPaths()) {
- Utils::QtcProcess::addArg(&args, QLatin1String("-I"));
- Utils::QtcProcess::addArg(&args, importPath);
+ Utils::QtcProcess::addArg(&args, QLatin1String("-I"), osType);
+ Utils::QtcProcess::addArg(&args, importPath, osType);
}
- QString s = mainScript();
- if (!s.isEmpty()) {
- s = canonicalCapsPath(s);
- Utils::QtcProcess::addArg(&args, s);
- }
+ const QString main
+ = project->targetFile(Utils::FileName::fromString(mainScript()), target()).toString(); ;
+ if (!main.isEmpty())
+ Utils::QtcProcess::addArg(&args, main, osType);
return args;
}
-/* QtDeclarative checks explicitly that the capitalization for any URL / path
- is exactly like the capitalization on disk.*/
-QString QmlProjectRunConfiguration::canonicalCapsPath(const QString &fileName)
-{
- return Utils::FileUtils::normalizePathName(QFileInfo(fileName).canonicalFilePath());
-}
-
QWidget *QmlProjectRunConfiguration::createConfigurationWidget()
{
return new QmlProjectRunConfigurationWidget(this);
@@ -164,7 +175,7 @@ QString QmlProjectRunConfiguration::mainScript() const
if (QFileInfo(pathInProject).isAbsolute())
return pathInProject;
else
- return project->projectDir().absoluteFilePath(pathInProject);
+ return QDir(project->canonicalProjectDir().toString()).absoluteFilePath(pathInProject);
}
if (!m_mainScriptFilename.isEmpty())
@@ -272,17 +283,16 @@ void QmlProjectRunConfiguration::updateEnabledState()
qmlFileFound = !mainScript().isEmpty();
}
- if (QFileInfo::exists(executable()) && qmlFileFound)
- RunConfiguration::updateEnabledState();
- else
+ if (!qmlFileFound) {
setEnabled(false);
-}
-
-bool QmlProjectRunConfiguration::isValidVersion(QtSupport::BaseQtVersion *version)
-{
- return version
- && version->type() == QLatin1String(QtSupport::Constants::DESKTOPQT)
- && !static_cast<QtSupport::DesktopQtVersion *>(version)->qmlsceneCommand().isEmpty();
+ } else {
+ const QString exe = executable();
+ if (exe.isEmpty()) {
+ setEnabled(false);
+ } else {
+ RunConfiguration::updateEnabledState();
+ }
+ }
}
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
index 17a6dfcb52..7e8181c0ab 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
@@ -80,10 +80,6 @@ private:
QString executable() const;
QString commandLineArguments() const;
- static bool isValidVersion(QtSupport::BaseQtVersion *version);
-
- static QString canonicalCapsPath(const QString &filePath);
-
// absolute path to current file (if being used)
QString m_currentFileFilename;
// absolute path to selected main script (if being used)
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationfactory.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationfactory.cpp
index dcfd2c5163..436ec3dc2d 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationfactory.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationfactory.cpp
@@ -37,7 +37,6 @@ QmlProjectRunConfigurationFactory::QmlProjectRunConfigurationFactory(QObject *pa
setObjectName("QmlProjectRunConfigurationFactory");
registerRunConfiguration<QmlProjectRunConfiguration>(Constants::QML_SCENE_RC_ID);
addSupportedProjectType(QmlProjectManager::Constants::QML_PROJECT_ID);
- setSupportedTargetDeviceTypes({ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE});
addFixedBuildTarget(tr("QML Scene"));
}