forked from qt-creator/qt-creator
QmlProjectManager: Integrate QDS landing page
Task-number: QDS-6564 Change-Id: Ia1a4188ba1bb561bbfeadf5fb29bcba75d05b5ce Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -23,16 +23,19 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdslandingpage.h"
|
||||
#include "qmlprojectplugin.h"
|
||||
#include "qmlproject.h"
|
||||
#include "qmlprojectconstants.h"
|
||||
#include "qmlprojectrunconfiguration.h"
|
||||
#include "projectfilecontenttools.h"
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/designmode.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagebox.h>
|
||||
#include <coreplugin/modemanager.h>
|
||||
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
#include <projectexplorer/runcontrol.h>
|
||||
@@ -40,14 +43,18 @@
|
||||
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
|
||||
#include <qmljseditor/qmljseditor.h>
|
||||
#include <qmljseditor/qmljseditorconstants.h>
|
||||
|
||||
#include <qmljstools/qmljstoolsconstants.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <extensionsystem/pluginspec.h>
|
||||
|
||||
#include <utils/infobar.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
@@ -58,8 +65,8 @@ using namespace ProjectExplorer;
|
||||
namespace QmlProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
const char openInQDSAppInfoBar[] = "OpenInQDSAppUiQml";
|
||||
const char alwaysOpenUiQmlInQDS[] = "J.QtQuick/QmlJSEditor.openUiQmlFilesInQDS";
|
||||
const char alwaysOpenUiQmlMode[] = "J.QtQuick/QmlJSEditor.openUiQmlMode";
|
||||
const char installQdsUrl[] = "https://www.qt.io/product/ui-design-tools";
|
||||
|
||||
static bool isQmlDesigner(const ExtensionSystem::PluginSpec *spec)
|
||||
{
|
||||
@@ -76,14 +83,19 @@ static bool qmlDesignerEnabled()
|
||||
return it != plugins.end() && (*it)->plugin();
|
||||
}
|
||||
|
||||
static bool alwaysOpenUiQmlfileInQds()
|
||||
static QString alwaysOpenWithMode()
|
||||
{
|
||||
return Core::ICore::settings()->value(alwaysOpenUiQmlInQDS, false).toBool();
|
||||
return Core::ICore::settings()->value(alwaysOpenUiQmlMode, "").toString();
|
||||
}
|
||||
|
||||
static void enableAlwaysOpenUiQmlfileInQds()
|
||||
static void setAlwaysOpenWithMode(const QString &mode)
|
||||
{
|
||||
return Core::ICore::settings()->setValue(alwaysOpenUiQmlInQDS, true);
|
||||
Core::ICore::settings()->setValue(alwaysOpenUiQmlMode, mode);
|
||||
}
|
||||
|
||||
static void clearAlwaysOpenWithMode()
|
||||
{
|
||||
Core::ICore::settings()->remove(alwaysOpenUiQmlMode);
|
||||
}
|
||||
|
||||
class QmlProjectPluginPrivate
|
||||
@@ -94,12 +106,15 @@ public:
|
||||
{ProjectExplorer::Constants::NORMAL_RUN_MODE},
|
||||
{runConfigFactory.runConfigurationId()}};
|
||||
QPointer<QMessageBox> lastMessageBox;
|
||||
QdsLandingPage *landingPage = nullptr;
|
||||
};
|
||||
|
||||
QmlProjectPlugin::~QmlProjectPlugin()
|
||||
{
|
||||
if (d->lastMessageBox)
|
||||
d->lastMessageBox->deleteLater();
|
||||
if (d->landingPage)
|
||||
d->landingPage->deleteLater();
|
||||
delete d;
|
||||
}
|
||||
|
||||
@@ -119,6 +134,8 @@ void QmlProjectPlugin::openQDS(const Utils::FilePath &fileName)
|
||||
QMessageBox::warning(Core::ICore::dialogParent(),
|
||||
fileName.fileName(),
|
||||
QObject::tr("Failed to start Qt Design Studio."));
|
||||
if (alwaysOpenWithMode() == Core::Constants::MODE_DESIGN)
|
||||
clearAlwaysOpenWithMode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,15 +152,30 @@ bool QmlProjectPlugin::qdsInstallationExists()
|
||||
return qdsInstallationEntry().exists();
|
||||
}
|
||||
|
||||
Utils::FilePath findQmlProject(const Utils::FilePath &folder)
|
||||
bool QmlProjectPlugin::checkIfEditorIsuiQml(Core::IEditor *editor)
|
||||
{
|
||||
QDir dir = folder.toDir();
|
||||
for (const QString &file : dir.entryList({"*.qmlproject"}))
|
||||
return Utils::FilePath::fromString(folder.toString() + "/" + file);
|
||||
return {};
|
||||
if (editor
|
||||
&& (editor->document()->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID
|
||||
|| editor->document()->id() == QmlJSEditor::Constants::C_QTQUICKDESIGNEREDITOR_ID)) {
|
||||
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
|
||||
QmlJS::Document::Ptr document =
|
||||
modelManager->ensuredGetDocumentForPath(editor->document()->filePath().toString());
|
||||
if (!document.isNull())
|
||||
return document->language() == QmlJS::Dialect::QmlQtQuick2Ui;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Utils::FilePath findQmlProjectUpwards(const Utils::FilePath &folder)
|
||||
const Utils::FilePath findQmlProject(const Utils::FilePath &folder)
|
||||
{
|
||||
const Utils::FilePaths files = folder.dirEntries({QStringList("*.qmlproject"), QDir::Files});
|
||||
if (files.isEmpty())
|
||||
return {};
|
||||
|
||||
return files.constFirst();
|
||||
}
|
||||
|
||||
const Utils::FilePath findQmlProjectUpwards(const Utils::FilePath &folder)
|
||||
{
|
||||
auto ret = findQmlProject(folder);
|
||||
if (ret.exists())
|
||||
@@ -205,55 +237,7 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
|
||||
d = new QmlProjectPluginPrivate;
|
||||
|
||||
if (!qmlDesignerEnabled()) {
|
||||
connect(Core::EditorManager::instance(),
|
||||
&Core::EditorManager::currentEditorChanged,
|
||||
[this](Core::IEditor *editor) {
|
||||
QmlJS::ModelManagerInterface *modelManager
|
||||
= QmlJS::ModelManagerInterface::instance();
|
||||
|
||||
if (!editor || !modelManager)
|
||||
return;
|
||||
|
||||
if (d->lastMessageBox)
|
||||
return;
|
||||
auto filePath = editor->document()->filePath();
|
||||
QmlJS::Document::Ptr document = modelManager->ensuredGetDocumentForPath(
|
||||
filePath.toString());
|
||||
if (!document.isNull()
|
||||
&& document->language() == QmlJS::Dialect::QmlQtQuick2Ui) {
|
||||
|
||||
const QString description = tr("Files of the type ui.qml are intended for Qt Design Studio.");
|
||||
|
||||
if (!qdsInstallationExists()) {
|
||||
if (Core::ICore::infoBar()->canInfoBeAdded(openInQDSAppInfoBar)) {
|
||||
Utils::InfoBarEntry
|
||||
info(openInQDSAppInfoBar,
|
||||
description + tr(" Learn more about Qt Design Studio here: ")
|
||||
+ "<a href='https://www.qt.io/product/ui-design-tools'>Qt Design Studio</a>",
|
||||
Utils::InfoBarEntry::GlobalSuppression::Disabled);
|
||||
Core::ICore::infoBar()->addInfo(info);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (alwaysOpenUiQmlfileInQds()) {
|
||||
openInQDSWithProject(filePath);
|
||||
} else if (Core::ICore::infoBar()->canInfoBeAdded(openInQDSAppInfoBar)) {
|
||||
Utils::InfoBarEntry
|
||||
info(openInQDSAppInfoBar,
|
||||
description + "\n" + tr("Do you want to open this file always in Qt Design Studio?"),
|
||||
Utils::InfoBarEntry::GlobalSuppression::Disabled);
|
||||
info.addCustomButton(tr("Always open in Qt Design Studio"), [filePath] {
|
||||
Core::ICore::infoBar()->removeInfo(openInQDSAppInfoBar);
|
||||
|
||||
enableAlwaysOpenUiQmlfileInQds();
|
||||
openInQDSWithProject(filePath);
|
||||
});
|
||||
Core::ICore::infoBar()->addInfo(info);
|
||||
}
|
||||
}
|
||||
});
|
||||
initializeQmlLandingPage();
|
||||
}
|
||||
|
||||
ProjectManager::registerProjectType<QmlProject>(QmlJSTools::Constants::QMLPROJECT_MIMETYPE);
|
||||
@@ -262,5 +246,112 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
|
||||
return true;
|
||||
}
|
||||
|
||||
void QmlProjectPlugin::initializeQmlLandingPage()
|
||||
{
|
||||
d->landingPage = new QdsLandingPage();
|
||||
connect(d->landingPage, &QdsLandingPage::openCreator, this, &QmlProjectPlugin::openQtc);
|
||||
connect(d->landingPage, &QdsLandingPage::openDesigner, this, &QmlProjectPlugin::openQds);
|
||||
connect(d->landingPage, &QdsLandingPage::installDesigner, this, &QmlProjectPlugin::installQds);
|
||||
connect(d->landingPage, &QdsLandingPage::generateCmake, this, &QmlProjectPlugin::generateCmake);
|
||||
connect(d->landingPage, &QdsLandingPage::generateProjectFile, this, &QmlProjectPlugin::generateProjectFile);
|
||||
|
||||
auto dialog = d->landingPage->dialog();
|
||||
|
||||
const QStringList mimeTypes = {QmlJSTools::Constants::QMLUI_MIMETYPE};
|
||||
auto context = new Internal::DesignModeContext(dialog);
|
||||
Core::ICore::addContextObject(context);
|
||||
|
||||
Core::DesignMode::registerDesignWidget(dialog, mimeTypes, context->context());
|
||||
|
||||
connect(Core::ModeManager::instance(), &Core::ModeManager::currentModeChanged,
|
||||
this, &QmlProjectPlugin::editorModeChanged);
|
||||
}
|
||||
|
||||
void QmlProjectPlugin::displayQmlLandingPage()
|
||||
{
|
||||
const QString qtVersionString = ProjectFileContentTools::qtVersion(projectFilePath());
|
||||
const QString qdsVersionString = ProjectFileContentTools::qdsVersion(projectFilePath());
|
||||
|
||||
d->landingPage->setQdsInstalled(qdsInstallationExists());
|
||||
d->landingPage->setProjectFileExists(projectFilePath().exists());
|
||||
d->landingPage->setCmakeResources(ProjectFileContentTools::rootCmakeFiles());
|
||||
d->landingPage->setQtVersion(qtVersionString);
|
||||
d->landingPage->setQdsVersion(qdsVersionString);
|
||||
d->landingPage->show();
|
||||
}
|
||||
|
||||
void QmlProjectPlugin::hideQmlLandingPage()
|
||||
{
|
||||
d->landingPage->hide();
|
||||
}
|
||||
|
||||
static bool isDesignerMode(Utils::Id mode)
|
||||
{
|
||||
return mode == Core::Constants::MODE_DESIGN;
|
||||
}
|
||||
|
||||
void QmlProjectPlugin::editorModeChanged(Utils::Id newMode, Utils::Id oldMode)
|
||||
{
|
||||
Core::IEditor *currentEditor = Core::EditorManager::currentEditor();
|
||||
if (checkIfEditorIsuiQml(currentEditor)) {
|
||||
if (isDesignerMode(newMode)) {
|
||||
if (alwaysOpenWithMode() == Core::Constants::MODE_DESIGN)
|
||||
openQds();
|
||||
else if (alwaysOpenWithMode() == Core::Constants::MODE_EDIT)
|
||||
openQtc();
|
||||
else
|
||||
displayQmlLandingPage();
|
||||
} else if (isDesignerMode(oldMode)) {
|
||||
hideQmlLandingPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QmlProjectPlugin::openQtc(bool permanent)
|
||||
{
|
||||
if (permanent)
|
||||
setAlwaysOpenWithMode(Core::Constants::MODE_EDIT);
|
||||
|
||||
hideQmlLandingPage();
|
||||
Core::ModeManager::activateMode(Core::Constants::MODE_EDIT);
|
||||
}
|
||||
|
||||
void QmlProjectPlugin::openQds(bool permanent)
|
||||
{
|
||||
if (permanent)
|
||||
setAlwaysOpenWithMode(Core::Constants::MODE_DESIGN);
|
||||
|
||||
hideQmlLandingPage();
|
||||
auto editor = Core::EditorManager::currentEditor();
|
||||
if (editor)
|
||||
openInQDSWithProject(editor->document()->filePath());
|
||||
}
|
||||
|
||||
void QmlProjectPlugin::installQds()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl(installQdsUrl));
|
||||
hideQmlLandingPage();
|
||||
}
|
||||
|
||||
void QmlProjectPlugin::generateCmake()
|
||||
{
|
||||
qWarning() << "TODO generate cmake";
|
||||
}
|
||||
|
||||
void QmlProjectPlugin::generateProjectFile()
|
||||
{
|
||||
qWarning() << "TODO generate .qmlproject";
|
||||
}
|
||||
|
||||
Utils::FilePath QmlProjectPlugin::projectFilePath()
|
||||
{
|
||||
auto project = ProjectExplorer::SessionManager::startupProject();
|
||||
const QmlProjectManager::QmlProject *qmlProject = qobject_cast<const QmlProjectManager::QmlProject*>(project);
|
||||
if (qmlProject)
|
||||
return qmlProject->projectFilePath();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlProjectManager
|
||||
|
Reference in New Issue
Block a user