From e1f5fd202aa421c8b510d902a68a03a5345f3ec4 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 23 Jun 2016 15:09:32 +0200 Subject: [PATCH] QmlDesigner: Propose to open a .ui.qml file instead of .qml If the project contains .ui.qml files the designer proposes to open .ui.qml files instead of opening a .qml file. This encourages to not open the .qml files in the designer. This feature can be disabled. Change-Id: I47a877ea72fafb07ebee485b8f22509f6162993c Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/designersettings.cpp | 1 + src/plugins/qmldesigner/designersettings.h | 1 + .../qmldesigner/openuiqmlfiledialog.cpp | 92 +++++++++++++++++++ src/plugins/qmldesigner/openuiqmlfiledialog.h | 54 +++++++++++ .../qmldesigner/openuiqmlfiledialog.ui | 58 ++++++++++++ src/plugins/qmldesigner/qmldesignerplugin.cpp | 53 ++++++++++- src/plugins/qmldesigner/qmldesignerplugin.pri | 9 +- src/plugins/qmldesigner/settingspage.cpp | 7 +- src/plugins/qmldesigner/settingspage.ui | 18 +++- 9 files changed, 284 insertions(+), 9 deletions(-) create mode 100644 src/plugins/qmldesigner/openuiqmlfiledialog.cpp create mode 100644 src/plugins/qmldesigner/openuiqmlfiledialog.h create mode 100644 src/plugins/qmldesigner/openuiqmlfiledialog.ui diff --git a/src/plugins/qmldesigner/designersettings.cpp b/src/plugins/qmldesigner/designersettings.cpp index b931ab99839..6a371a50b49 100644 --- a/src/plugins/qmldesigner/designersettings.cpp +++ b/src/plugins/qmldesigner/designersettings.cpp @@ -53,6 +53,7 @@ void DesignerSettings::fromSettings(QSettings *settings) restoreValue(settings, DesignerSettingsKey::CANVASWIDTH, 10000); restoreValue(settings, DesignerSettingsKey::CANVASHEIGHT, 10000); restoreValue(settings, DesignerSettingsKey::WARNING_FOR_FEATURES_IN_DESIGNER, true); + restoreValue(settings, DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES, true); restoreValue(settings, DesignerSettingsKey::WARNING_FOR_DESIGNER_FEATURES_IN_EDITOR, false); restoreValue(settings, DesignerSettingsKey::SHOW_DEBUGVIEW, false); restoreValue(settings, DesignerSettingsKey::ENABLE_DEBUGVIEW, false); diff --git a/src/plugins/qmldesigner/designersettings.h b/src/plugins/qmldesigner/designersettings.h index b5e0b2fd297..2159230cbfd 100644 --- a/src/plugins/qmldesigner/designersettings.h +++ b/src/plugins/qmldesigner/designersettings.h @@ -42,6 +42,7 @@ const char CONTAINERPADDING[] = "ContainerPadding"; const char CANVASWIDTH[] = "CanvasWidth"; const char CANVASHEIGHT[] = "CanvasHeight"; const char WARNING_FOR_FEATURES_IN_DESIGNER[] = "WarnAboutQtQuickFeaturesInDesigner"; +const char WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES[] = "WarnAboutQmlFilesInsteadOfUiQmlFiles"; const char WARNING_FOR_DESIGNER_FEATURES_IN_EDITOR[] = "WarnAboutQtQuickDesignerFeaturesInCodeEditor"; const char SHOW_DEBUGVIEW[] = "ShowQtQuickDesignerDebugView"; const char ENABLE_DEBUGVIEW[] = "EnableQtQuickDesignerDebugView"; diff --git a/src/plugins/qmldesigner/openuiqmlfiledialog.cpp b/src/plugins/qmldesigner/openuiqmlfiledialog.cpp new file mode 100644 index 00000000000..75837654dce --- /dev/null +++ b/src/plugins/qmldesigner/openuiqmlfiledialog.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** 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 "openuiqmlfiledialog.h" +#include "ui_openuiqmlfiledialog.h" + +#include + +#include + +namespace QmlDesigner { + +OpenUiQmlFileDialog::OpenUiQmlFileDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::OpenUiQmlFileDialog) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + ui->setupUi(this); + + connect(ui->cancelButton, &QPushButton::clicked, this, &QDialog::close); + connect(ui->openButton, &QPushButton::clicked, [this] { + QListWidgetItem *item = ui->listWidget->currentItem(); + if (item) { + m_uiFileOpened = true; + m_uiQmlFile = item->data(Qt::UserRole).toString(); + } + close(); + }); + connect(ui->listWidget, &QListWidget::itemDoubleClicked, [this](QListWidgetItem *item) { + if (item) { + m_uiFileOpened = true; + m_uiQmlFile = item->data(Qt::UserRole).toString(); + } + close(); + }); + connect(ui->checkBox, &QCheckBox::toggled, [this](bool b){ + DesignerSettings settings = QmlDesignerPlugin::instance()->settings(); + settings.insert(DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES, !b); + QmlDesignerPlugin::instance()->setSettings(settings); + }); +} + +OpenUiQmlFileDialog::~OpenUiQmlFileDialog() +{ + delete ui; +} + +bool OpenUiQmlFileDialog::uiFileOpened() const +{ + return m_uiFileOpened; +} + +void OpenUiQmlFileDialog::setUiQmlFiles(const QString &projectPath, const QStringList &stringList) +{ + QDir projectDir(projectPath); + + foreach (const QString &fileName, stringList) { + QListWidgetItem *item = new QListWidgetItem(projectDir.relativeFilePath(fileName), ui->listWidget); + item->setData(Qt::UserRole, fileName); + ui->listWidget->addItem(item); + } + ui->listWidget->setCurrentItem(ui->listWidget->item(0)); +} + +QString OpenUiQmlFileDialog::uiQmlFile() const +{ + return m_uiQmlFile; +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/openuiqmlfiledialog.h b/src/plugins/qmldesigner/openuiqmlfiledialog.h new file mode 100644 index 00000000000..8f9dac0531e --- /dev/null +++ b/src/plugins/qmldesigner/openuiqmlfiledialog.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +namespace QmlDesigner { + +namespace Ui { +class OpenUiQmlFileDialog; +} + +class OpenUiQmlFileDialog : public QDialog +{ + Q_OBJECT + +public: + explicit OpenUiQmlFileDialog(QWidget *parent = 0); + ~OpenUiQmlFileDialog(); + bool uiFileOpened() const; + void setUiQmlFiles(const QString &projectPath, const QStringList &stringList); + QString uiQmlFile() const; + +private: + Ui::OpenUiQmlFileDialog *ui; + bool m_uiFileOpened = false; + QString m_uiQmlFile; +}; + + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/openuiqmlfiledialog.ui b/src/plugins/qmldesigner/openuiqmlfiledialog.ui new file mode 100644 index 00000000000..a2fab6e786a --- /dev/null +++ b/src/plugins/qmldesigner/openuiqmlfiledialog.ui @@ -0,0 +1,58 @@ + + + QmlDesigner::OpenUiQmlFileDialog + + + + 0 + 0 + 600 + 300 + + + + Open ui.qml file + + + true + + + + + + You are opening a .qml file in the designer. Do you want to open a .ui.qml file instead? + + + + + + + Do not show this dialog again + + + + + + + Open ui.qml file + + + + + + + Cancel + + + true + + + + + + + + + + + diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index a656f85a7c1..0ef7f450b7d 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -29,6 +29,7 @@ #include "designmodewidget.h" #include "settingspage.h" #include "designmodecontext.h" +#include "openuiqmlfiledialog.h" #include #include @@ -53,6 +54,9 @@ #include #include #include +#include +#include +#include #include #include @@ -220,6 +224,32 @@ void QmlDesignerPlugin::extensionsInitialized() &d->shortCutManager, &ShortCutManager::updateActions); } +static QStringList allUiQmlFilesforCurrentProject(const Utils::FileName &fileName) +{ + QStringList list; + ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile(fileName); + + if (currentProject) { + foreach (const QString &fileName, currentProject->files(ProjectExplorer::Project::SourceFiles)) { + if (fileName.endsWith(".ui.qml")) + list.append(fileName); + } + } + + return list; +} + +static QString projectPath(const Utils::FileName &fileName) +{ + QString path; + ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile(fileName); + + if (currentProject) + path = currentProject->projectDirectory().toString(); + + return path; +} + void QmlDesignerPlugin::createDesignModeWidget() { d->mainWidget = new Internal::DesignModeWidget; @@ -256,6 +286,7 @@ void QmlDesignerPlugin::createDesignModeWidget() connect(Core::ModeManager::instance(), &Core::ModeManager::currentModeChanged, [=] (Core::Id newMode, Core::Id oldMode) { + if (d && Core::EditorManager::currentEditor() && checkIfEditorIsQtQuick (Core::EditorManager::currentEditor()) && !documentIsAlreadyOpen( currentDesignDocument(), Core::EditorManager::currentEditor(), newMode)) { @@ -270,14 +301,34 @@ void QmlDesignerPlugin::createDesignModeWidget() }); } +static bool warningsForQmlFilesInsteadOfUiQmlEnabled() +{ + DesignerSettings settings = QmlDesignerPlugin::instance()->settings(); + return settings.value(DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES).toBool(); +} + void QmlDesignerPlugin::showDesigner() { QTC_ASSERT(!d->documentManager.hasCurrentDesignDocument(), return); + d->mainWidget->initialize(); + + const Utils::FileName fileName = Core::EditorManager::currentEditor()->document()->filePath(); + const QStringList allUiQmlFiles = allUiQmlFilesforCurrentProject(fileName); + if (warningsForQmlFilesInsteadOfUiQmlEnabled() && !fileName.endsWith(".ui.qml") && !allUiQmlFiles.isEmpty()) { + OpenUiQmlFileDialog dialog(d->mainWidget); + dialog.setUiQmlFiles(projectPath(fileName), allUiQmlFiles); + dialog.exec(); + if (dialog.uiFileOpened()) { + Core::ModeManager::activateMode(Core::Constants::MODE_EDIT); + Core::EditorManager::openEditorAt(dialog.uiQmlFile(), 0, 0); + return; + } + } + d->shortCutManager.disconnectUndoActions(currentDesignDocument()); d->documentManager.setCurrentDesignDocument(Core::EditorManager::currentEditor()); d->shortCutManager.connectUndoActions(currentDesignDocument()); - d->mainWidget->initialize(); if (d->documentManager.hasCurrentDesignDocument()) { activateAutoSynchronization(); diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pri b/src/plugins/qmldesigner/qmldesignerplugin.pri index 8afc86cf9df..b9be0d0a558 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.pri +++ b/src/plugins/qmldesigner/qmldesignerplugin.pri @@ -8,7 +8,8 @@ HEADERS += $$PWD/qmldesignerconstants.h \ $$PWD/documentmanager.h \ $$PWD/documentwarningwidget.h \ $$PWD/styledoutputpaneplaceholder.h \ - $$PWD/qmldesignericons.h + $$PWD/qmldesignericons.h \ + $$PWD/openuiqmlfiledialog.h SOURCES += $$PWD/qmldesignerplugin.cpp \ $$PWD/shortcutmanager.cpp \ @@ -18,6 +19,8 @@ SOURCES += $$PWD/qmldesignerplugin.cpp \ $$PWD/designmodecontext.cpp \ $$PWD/documentmanager.cpp \ $$PWD/documentwarningwidget.cpp \ - $$PWD/styledoutputpaneplaceholder.cpp + $$PWD/styledoutputpaneplaceholder.cpp \ + $$PWD/openuiqmlfiledialog.cpp -FORMS += $$PWD/settingspage.ui +FORMS += $$PWD/settingspage.ui \ + $$PWD/openuiqmlfiledialog.ui diff --git a/src/plugins/qmldesigner/settingspage.cpp b/src/plugins/qmldesigner/settingspage.cpp index 9c5ac641490..3e236631e13 100644 --- a/src/plugins/qmldesigner/settingspage.cpp +++ b/src/plugins/qmldesigner/settingspage.cpp @@ -94,7 +94,10 @@ DesignerSettings SettingsPageWidget::settings() const settings.insert(DesignerSettingsKey::CANVASWIDTH, m_ui.spinCanvasWidth->value()); settings.insert(DesignerSettingsKey::CANVASHEIGHT, m_ui.spinCanvasHeight->value()); settings.insert(DesignerSettingsKey::WARNING_FOR_FEATURES_IN_DESIGNER, - m_ui.designerWarningsCheckBox->isChecked()); + m_ui.designerWarningsCheckBox->isChecked()); + settings.insert(DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES, + m_ui.designerWarningsUiQmlfiles->isChecked()); + settings.insert(DesignerSettingsKey::WARNING_FOR_DESIGNER_FEATURES_IN_EDITOR, m_ui.designerWarningsInEditorCheckBox->isChecked()); settings.insert(DesignerSettingsKey::SHOW_DEBUGVIEW, @@ -144,6 +147,8 @@ void SettingsPageWidget::setSettings(const DesignerSettings &settings) DesignerSettingsKey::CANVASHEIGHT).toInt()); m_ui.designerWarningsCheckBox->setChecked(settings.value( DesignerSettingsKey::WARNING_FOR_FEATURES_IN_DESIGNER).toBool()); + m_ui.designerWarningsUiQmlfiles->setChecked(settings.value( + DesignerSettingsKey::WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES).toBool()); m_ui.designerWarningsInEditorCheckBox->setChecked(settings.value( DesignerSettingsKey::WARNING_FOR_DESIGNER_FEATURES_IN_EDITOR).toBool()); m_ui.designerShowDebuggerCheckBox->setChecked(settings.value( diff --git a/src/plugins/qmldesigner/settingspage.ui b/src/plugins/qmldesigner/settingspage.ui index 2623092d6e9..72a828bffb8 100644 --- a/src/plugins/qmldesigner/settingspage.ui +++ b/src/plugins/qmldesigner/settingspage.ui @@ -293,6 +293,16 @@ Warnings + + + + Also warns in the code editor about QML features that are not properly supported by the Qt Quick Designer. + + + Warn about unsupported features of Qt Quick Designer in the code editor + + + @@ -303,13 +313,13 @@ - - + + - Also warns in the code editor about QML features that are not properly supported by the Qt Quick Designer. + Qt Quick Designer will propose to open .ui.qml files instead of opening a .qml file. - Warn about unsupported features of Qt Quick Designer in the code editor + Warn about using .qml files instead of .ui.qml files