diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 411c019af8a..34c506ddce5 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -552,6 +552,7 @@ extend_qtc_plugin(QmlDesigner annotationeditordialog.cpp annotationeditordialog.h annotationeditordialog.ui annotationeditor.cpp annotationeditor.h annotationtool.cpp annotationtool.h + globalannotationeditor.cpp globalannotationeditor.h ) extend_qtc_plugin(QmlDesigner diff --git a/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.pri b/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.pri index e221b3bb615..9a3a00e2da3 100644 --- a/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.pri +++ b/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.pri @@ -2,11 +2,13 @@ HEADERS += $$PWD/annotationtool.h HEADERS += $$PWD/annotationcommenttab.h HEADERS += $$PWD/annotationeditordialog.h HEADERS += $$PWD/annotationeditor.h +HEADERS += $$PWD/globalannotationeditor.h SOURCES += $$PWD/annotationtool.cpp SOURCES += $$PWD/annotationcommenttab.cpp SOURCES += $$PWD/annotationeditordialog.cpp SOURCES += $$PWD/annotationeditor.cpp +SOURCES += $$PWD/globalannotationeditor.cpp FORMS += $$PWD/annotationcommenttab.ui FORMS += $$PWD/annotationeditordialog.ui diff --git a/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp b/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp index dd234a074cb..a25d93b666a 100644 --- a/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp +++ b/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp @@ -40,16 +40,16 @@ namespace QmlDesigner { -AnnotationEditorDialog::AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId, const Annotation &annotation) +AnnotationEditorDialog::AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId, const Annotation &annotation, EditorMode mode) : QDialog(parent) , ui(new Ui::AnnotationEditorDialog) , m_customId(customId) , m_annotation(annotation) + , m_editorMode(mode) { ui->setupUi(this); setWindowFlag(Qt::Tool, true); - setWindowTitle(titleString); setModal(true); connect(this, &QDialog::accepted, this, &AnnotationEditorDialog::acceptedClicked); @@ -98,6 +98,7 @@ AnnotationEditorDialog::AnnotationEditorDialog(QWidget *parent, const QString &t ui->tabWidget->setCornerWidget(commentCornerWidget, Qt::TopRightCorner); ui->targetIdEdit->setText(targetId); + changeEditorMode(m_editorMode); fillFields(); } @@ -128,6 +129,39 @@ QString AnnotationEditorDialog::customId() const return m_customId; } +void AnnotationEditorDialog::changeEditorMode(AnnotationEditorDialog::EditorMode mode) +{ + switch (mode) { + case ItemAnnotation: { + ui->customIdEdit->setVisible(true); + ui->customIdLabel->setVisible(true); + ui->targetIdEdit->setVisible(true); + ui->targetIdLabel->setVisible(true); + setWindowTitle(annotationEditorTitle); + + break; + } + case GlobalAnnotation: { + ui->customIdEdit->clear(); + ui->targetIdEdit->clear(); + ui->customIdEdit->setVisible(false); + ui->customIdLabel->setVisible(false); + ui->targetIdEdit->setVisible(false); + ui->targetIdLabel->setVisible(false); + setWindowTitle(globalEditorTitle); + + break; + } + } + + m_editorMode = mode; +} + +AnnotationEditorDialog::EditorMode AnnotationEditorDialog::editorMode() const +{ + return m_editorMode; +} + void AnnotationEditorDialog::acceptedClicked() { m_customId = ui->customIdEdit->text(); diff --git a/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.h b/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.h index 1324115a724..0c3cb50c807 100644 --- a/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.h +++ b/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.h @@ -40,7 +40,10 @@ class AnnotationEditorDialog : public QDialog Q_OBJECT public: - explicit AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId, const Annotation &annotation); + enum EditorMode { ItemAnnotation, GlobalAnnotation }; + + explicit AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId, const Annotation &annotation, + EditorMode mode = EditorMode::ItemAnnotation); ~AnnotationEditorDialog(); void setAnnotation(const Annotation &annotation); @@ -49,6 +52,9 @@ public: void setCustomId(const QString &customId); QString customId() const; + void changeEditorMode(EditorMode mode); + EditorMode editorMode() const; + signals: void accepted(); @@ -68,12 +74,15 @@ private: void deleteAllTabs(); private: - const QString titleString = {tr("Annotation Editor")}; + const QString annotationEditorTitle = {tr("Annotation Editor")}; + const QString globalEditorTitle = {tr("Global Annotation Editor")}; const QString defaultTabName = {tr("Annotation")}; Ui::AnnotationEditorDialog *ui; QString m_customId; Annotation m_annotation; + + EditorMode m_editorMode; }; } //namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/annotationeditor/globalannotationeditor.cpp b/src/plugins/qmldesigner/components/annotationeditor/globalannotationeditor.cpp new file mode 100644 index 00000000000..1beeacaf74c --- /dev/null +++ b/src/plugins/qmldesigner/components/annotationeditor/globalannotationeditor.cpp @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 "globalannotationeditor.h" + +#include "annotationeditordialog.h" +#include "annotation.h" + +#include "qmlmodelnodeproxy.h" +#include + +#include +#include +#include +#include + +namespace QmlDesigner { + +GlobalAnnotationEditor::GlobalAnnotationEditor(QObject *) +{ +} + +GlobalAnnotationEditor::~GlobalAnnotationEditor() +{ + hideWidget(); +} + +void GlobalAnnotationEditor::showWidget() +{ + m_dialog = new AnnotationEditorDialog(Core::ICore::dialogParent(), + modelNode().validId(), + "", + modelNode().globalAnnotation(), + AnnotationEditorDialog::EditorMode::GlobalAnnotation); + + QObject::connect(m_dialog, &AnnotationEditorDialog::accepted, + this, &GlobalAnnotationEditor::acceptedClicked); + QObject::connect(m_dialog, &AnnotationEditorDialog::rejected, + this, &GlobalAnnotationEditor::cancelClicked); + + m_dialog->setAttribute(Qt::WA_DeleteOnClose); + + m_dialog->show(); + m_dialog->raise(); +} + +void GlobalAnnotationEditor::showWidget(int x, int y) +{ + showWidget(); + m_dialog->move(x, y); +} + +void GlobalAnnotationEditor::hideWidget() +{ + if (m_dialog) + m_dialog->close(); + m_dialog = nullptr; +} + +void GlobalAnnotationEditor::setModelNode(const ModelNode &modelNode) +{ + m_modelNode = modelNode; +} + +ModelNode GlobalAnnotationEditor::modelNode() const +{ + return m_modelNode; +} + +bool GlobalAnnotationEditor::hasAnnotation() const +{ + if (m_modelNode.isValid()) + return m_modelNode.hasGlobalAnnotation(); + return false; +} + +void GlobalAnnotationEditor::removeFullAnnotation() +{ + if (!m_modelNode.isValid()) + return; + + QString dialogTitle = tr("Global Annotation"); + QMessageBox *deleteDialog = new QMessageBox(Core::ICore::dialogParent()); + deleteDialog->setWindowTitle(dialogTitle); + deleteDialog->setText(tr("Delete this annotation?")); + deleteDialog->setStandardButtons(QMessageBox::Yes | QMessageBox::No); + deleteDialog->setDefaultButton(QMessageBox::Yes); + + int result = deleteDialog->exec(); + if (deleteDialog) deleteDialog->deleteLater(); + + if (result == QMessageBox::Yes) { + m_modelNode.removeGlobalAnnotation(); + } + + emit annotationChanged(); +} + +void GlobalAnnotationEditor::acceptedClicked() +{ + if (m_dialog) { + Annotation annotation = m_dialog->annotation(); + + if (annotation.comments().isEmpty()) + m_modelNode.removeGlobalAnnotation(); + else + m_modelNode.setGlobalAnnotation(annotation); + } + + hideWidget(); + + emit accepted(); + + emit annotationChanged(); +} + +void GlobalAnnotationEditor::cancelClicked() +{ + hideWidget(); + + emit canceled(); + + emit annotationChanged(); +} + +} //namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/annotationeditor/globalannotationeditor.h b/src/plugins/qmldesigner/components/annotationeditor/globalannotationeditor.h new file mode 100644 index 00000000000..e0aa66a1193 --- /dev/null +++ b/src/plugins/qmldesigner/components/annotationeditor/globalannotationeditor.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 +#include +#include + +#include "annotationeditordialog.h" +#include "annotation.h" + +#include "modelnode.h" + +namespace QmlDesigner { + +class GlobalAnnotationEditor : public QObject +{ + Q_OBJECT + +public: + explicit GlobalAnnotationEditor(QObject *parent = nullptr); + ~GlobalAnnotationEditor(); + + Q_INVOKABLE void showWidget(); + Q_INVOKABLE void showWidget(int x, int y); + Q_INVOKABLE void hideWidget(); + + void setModelNode(const ModelNode &modelNode); + ModelNode modelNode() const; + + Q_INVOKABLE bool hasAnnotation() const; + + Q_INVOKABLE void removeFullAnnotation(); + +signals: + void accepted(); + void canceled(); + void modelNodeBackendChanged(); + + void annotationChanged(); + +private slots: + void acceptedClicked(); + void cancelClicked(); + +private: + QPointer m_dialog; + + ModelNode m_modelNode; +}; + +} //namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/annotation.h b/src/plugins/qmldesigner/designercore/include/annotation.h index 95fcf81fa21..2b7c64bb4a2 100644 --- a/src/plugins/qmldesigner/designercore/include/annotation.h +++ b/src/plugins/qmldesigner/designercore/include/annotation.h @@ -35,6 +35,7 @@ namespace QmlDesigner { static const PropertyName customIdProperty = {("customId")}; static const PropertyName annotationProperty = {("annotation")}; +static const PropertyName globalAnnotationProperty = {("globalAnnotation")}; class Comment { diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/designercore/include/modelnode.h index ac65de0240f..85302ad2c42 100644 --- a/src/plugins/qmldesigner/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/designercore/include/modelnode.h @@ -202,6 +202,11 @@ public: void setAnnotation(const Annotation &annotation); void removeAnnotation(); + Annotation globalAnnotation() const; + bool hasGlobalAnnotation() const; + void setGlobalAnnotation(const Annotation &annotation); + void removeGlobalAnnotation(); + qint32 internalId() const; void setNodeSource(const QString&); diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp index 61d0f93cf56..1d1a5386f21 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp @@ -1150,6 +1150,35 @@ void ModelNode::removeAnnotation() } } +Annotation ModelNode::globalAnnotation() const +{ + Annotation result; + ModelNode root = view()->rootModelNode(); + + if (hasGlobalAnnotation()) + result.fromQString(root.auxiliaryData(globalAnnotationProperty).value()); + + return result; +} + +bool ModelNode::hasGlobalAnnotation() const +{ + return view()->rootModelNode().hasAuxiliaryData(globalAnnotationProperty); +} + +void ModelNode::setGlobalAnnotation(const Annotation &annotation) +{ + view()->rootModelNode().setAuxiliaryData(globalAnnotationProperty, + QVariant::fromValue(annotation.toQString())); +} + +void ModelNode::removeGlobalAnnotation() +{ + if (hasGlobalAnnotation()) { + view()->rootModelNode().removeAuxiliaryData(globalAnnotationProperty); + } +} + void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList) { model()->d->setScriptFunctions(internalNode(), scriptFunctionList); diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index 9bc485fd906..9f49b0a6d02 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -431,6 +431,19 @@ void DesignModeWidget::setup() m_dockManager->openWorkspace(workspaceComboBox->currentText()); }); + const QIcon gaIcon = Utils::StyleHelper::getIconFromIconFont(fontName, + Theme::getIconUnicode(Theme::Icon::annotationBubble), 36, 36); + toolBar->addAction(gaIcon, tr("Edit global annotation for current file."), [&](){ + ModelNode node = currentDesignDocument()->rewriterView()->rootModelNode(); + + if (node.isValid()) { + m_globalAnnotationEditor.setModelNode(node); + m_globalAnnotationEditor.showWidget(); + } + }); + + + viewManager().enableWidgets(); readSettings(); show(); diff --git a/src/plugins/qmldesigner/designmodewidget.h b/src/plugins/qmldesigner/designmodewidget.h index 8e44ce8c49f..67f8f3d554d 100644 --- a/src/plugins/qmldesigner/designmodewidget.h +++ b/src/plugins/qmldesigner/designmodewidget.h @@ -36,6 +36,7 @@ #include #include +#include namespace Core { class SideBar; @@ -120,6 +121,7 @@ private: // variables ADS::DockManager *m_dockManager = nullptr; ADS::DockWidget *m_outputPaneDockWidget = nullptr; + GlobalAnnotationEditor m_globalAnnotationEditor; }; } // namespace Internal diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index 63fa8a07432..3eb8c5e2d55 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -654,6 +654,8 @@ Project { "annotationeditor/annotationcommenttab.ui", "annotationeditor/annotationeditor.cpp", "annotationeditor/annotationeditor.h", + "annotationeditor/globalannotationeditor.cpp", + "annotationeditor/globalannotationeditor.h", "annotationeditor/annotationeditordialog.cpp", "annotationeditor/annotationeditordialog.h", "annotationeditor/annotationeditordialog.ui",