QmlDesigner: Annotation List

- Annotation Dialog structure was reworked
 - Added ListView to Global Annotation Dialog
 - Added Apply button to all Annotation dialogs

Task-number: QDS-2243
Change-Id: I2f271d4ae91d33b26a050287b20a86050e081830
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Aleksei German
2021-07-09 17:34:17 +02:00
parent 9eee8e4b84
commit 3e1fa0f170
22 changed files with 1468 additions and 299 deletions

View File

@@ -638,9 +638,13 @@ extend_qtc_plugin(QmlDesigner
extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/annotationeditor
SOURCES annotationcommenttab.cpp annotationcommenttab.h annotationcommenttab.ui
annotationeditordialog.cpp annotationeditordialog.h annotationeditordialog.ui
annotationeditordialog.cpp annotationeditordialog.h
annotationeditorwidget.cpp annotationeditorwidget.h annotationeditorwidget.ui
annotationeditor.cpp annotationeditor.h
annotationlist.cpp annotationlist.h
annotationlistwidget.cpp annotationlistwidget.h
globalannotationeditor.cpp globalannotationeditor.h
globalannotationdialog.cpp globalannotationdialog.h
defaultannotations.cpp defaultannotations.h
annotationtableview.cpp annotationtableview.h
annotationtabwidget.cpp annotationtabwidget.h

View File

@@ -46,8 +46,6 @@ AnnotationEditor::AnnotationEditor(QObject *parent)
: ModelNodeEditorProxy(parent)
{}
AnnotationEditor::~AnnotationEditor() {}
QWidget *AnnotationEditor::createWidget()
{
const auto &node = m_modelNode;
@@ -64,6 +62,8 @@ QWidget *AnnotationEditor::createWidget()
&AnnotationEditorDialog::rejected,
this,
&AnnotationEditor::cancelClicked);
QObject::connect(dialog, &AnnotationEditorDialog::appliedDialog,
this, &AnnotationEditor::appliedClicked);
return dialog;
}
@@ -91,19 +91,7 @@ void AnnotationEditor::removeFullAnnotation()
void AnnotationEditor::acceptedClicked()
{
if (const auto *dialog = qobject_cast<AnnotationEditorDialog *>(widget())) {
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_ANNOTATION_ADDED);
const QString customId = dialog->customId();
const Annotation annotation = dialog->annotation();
auto &node = this->m_modelNode;
node.setCustomId(customId);
if (annotation.comments().isEmpty())
node.removeAnnotation();
else
node.setAnnotation(annotation);
}
applyChanges();
hideWidget();
@@ -122,4 +110,30 @@ void AnnotationEditor::cancelClicked()
emit annotationChanged();
}
void AnnotationEditor::appliedClicked()
{
applyChanges();
emit applied();
emit customIdChanged();
emit annotationChanged();
}
void AnnotationEditor::applyChanges()
{
if (const auto *dialog = qobject_cast<AnnotationEditorDialog *>(widget())) {
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_ANNOTATION_ADDED);
const QString customId = dialog->customId();
const Annotation annotation = dialog->annotation();
auto &node = this->m_modelNode;
node.setCustomId(customId);
if (annotation.comments().isEmpty())
node.removeAnnotation();
else
node.setAnnotation(annotation);
}
}
} //namespace QmlDesigner

View File

@@ -36,7 +36,7 @@ class AnnotationEditor : public ModelNodeEditorProxy
Q_OBJECT
public:
explicit AnnotationEditor(QObject *parent = nullptr);
~AnnotationEditor();
~AnnotationEditor() = default;
QWidget *createWidget() override;
Q_INVOKABLE void removeFullAnnotation();
@@ -46,10 +46,15 @@ public:
signals:
void accepted();
void canceled();
void applied();
private slots:
void acceptedClicked();
void cancelClicked();
void appliedClicked();
private:
void applyChanges();
};
} //namespace QmlDesigner

View File

@@ -5,6 +5,10 @@ HEADERS += $$PWD/globalannotationeditor.h
HEADERS += $$PWD/defaultannotations.h
HEADERS += $$PWD/annotationtableview.h
HEADERS += $$PWD/annotationtabwidget.h
HEADERS += $$PWD/annotationeditorwidget.h
HEADERS += $$PWD/globalannotationdialog.h
HEADERS += $$PWD/annotationlist.h
HEADERS += $$PWD/annotationlistwidget.h
SOURCES += $$PWD/annotationcommenttab.cpp
SOURCES += $$PWD/annotationeditordialog.cpp
@@ -13,9 +17,13 @@ SOURCES += $$PWD/globalannotationeditor.cpp
SOURCES += $$PWD/defaultannotations.cpp
SOURCES += $$PWD/annotationtableview.cpp
SOURCES += $$PWD/annotationtabwidget.cpp
SOURCES += $$PWD/annotationeditorwidget.cpp
SOURCES += $$PWD/globalannotationdialog.cpp
SOURCES += $$PWD/annotationlist.cpp
SOURCES += $$PWD/annotationlistwidget.cpp
FORMS += $$PWD/annotationcommenttab.ui
FORMS += $$PWD/annotationeditordialog.ui
FORMS += $$PWD/annotationeditorwidget.ui
INCLUDEPATH += $$PWD

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -27,126 +27,67 @@
#include "annotation.h"
#include "annotationcommenttab.h"
#include "defaultannotations.h"
#include "ui_annotationeditordialog.h"
#include "annotationeditorwidget.h"
#include <timelineicons.h>
#include <utils/qtcassert.h>
#include <QAction>
#include <QMessageBox>
#include <QDialogButtonBox>
#include <QAbstractButton>
#include <QObject>
#include <QToolBar>
#include <QVBoxLayout>
namespace QmlDesigner {
AnnotationEditorDialog::AnnotationEditorDialog(QWidget *parent,
const QString &targetId,
const QString &customId)
: QDialog(parent)
, ui(std::make_unique<Ui::AnnotationEditorDialog>())
, m_customId(customId)
, m_defaults(std::make_unique<DefaultAnnotationsModel>())
, m_editorWidget(new AnnotationEditorWidget(this, targetId, customId))
{
ui->setupUi(this);
setGlobal(m_isGlobal);
setWindowTitle(tr("Annotation Editor"));
setWindowFlag(Qt::Tool, true);
setModal(true);
loadDefaultAnnotations(DefaultAnnotationsModel::defaultJsonFilePath());
ui->tabWidget->setDefaultAnnotations(defaultAnnotations());
ui->tableView->setDefaultAnnotations(defaultAnnotations());
connect(ui->tableView,
&AnnotationTableView::richTextEditorRequested,
this,
[&](int index, QString const &) {
switchToTabView();
ui->tabWidget->setCurrentIndex(index);
});
const QDialogButtonBox::StandardButtons buttonsToCreate =
QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply;
connect(ui->statusAddButton, &QPushButton::clicked, this, [&](bool) {
setStatusVisibility(true);
});
m_buttonBox = new QDialogButtonBox(buttonsToCreate, this);
connect(ui->rbTableView,
&QRadioButton::clicked,
this,
&AnnotationEditorDialog::switchToTableView);
connect(ui->rbTabView,
&QRadioButton::clicked,
this, &AnnotationEditorDialog::switchToTabView);
if (!QWidget::layout())
new QVBoxLayout(this);
setStatus(m_globalStatus);
switchToTabView();
QWidget::layout()->addWidget(m_editorWidget);
QWidget::layout()->addWidget(m_buttonBox);
connect(this, &QDialog::accepted, this, &AnnotationEditorDialog::acceptedClicked);
ui->targetIdEdit->setText(targetId);
connect(this, &QDialog::accepted,
this, &AnnotationEditorDialog::acceptedClicked);
connect(m_buttonBox, &QDialogButtonBox::accepted,
this, &AnnotationEditorDialog::acceptedClicked);
connect(m_buttonBox, &QDialogButtonBox::clicked,
this, &AnnotationEditorDialog::buttonClicked);
connect(m_buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::close);
}
AnnotationEditorDialog::~AnnotationEditorDialog() {
}
AnnotationEditorDialog::~AnnotationEditorDialog() = default;
bool AnnotationEditorDialog::isGlobal() const {
return m_isGlobal;
}
void AnnotationEditorDialog::setGlobal(bool global) {
ui->annotationContainer->setVisible(!global);
ui->statusAddButton->setVisible(global);
ui->statusComboBox->setVisible(global);
setWindowTitle(global ? tr("Global Annotation Editor") : tr("Annotation Editor"));
if (m_isGlobal != global) {
m_isGlobal = global;
emit globalChanged();
}
}
AnnotationEditorDialog::ViewMode AnnotationEditorDialog::viewMode() const
void AnnotationEditorDialog::buttonClicked(QAbstractButton *button)
{
return ui->rbTableView->isChecked() ? TableView : TabsView;
if (button) {
const QDialogButtonBox::StandardButton buttonType = m_buttonBox->standardButton(button);
if (buttonType == QDialogButtonBox::Apply) {
appliedClicked();
}
void AnnotationEditorDialog::setStatus(GlobalAnnotationStatus status)
{
m_globalStatus = status;
bool hasStatus = status.status() != GlobalAnnotationStatus::NoStatus;
if (hasStatus)
ui->statusComboBox->setCurrentIndex(int(status.status()));
setStatusVisibility(hasStatus);
}
GlobalAnnotationStatus AnnotationEditorDialog::globalStatus() const
{
return m_globalStatus;
}
void AnnotationEditorDialog::showStatusContainer(bool show)
{
ui->statusContainer->setVisible(show);
}
void AnnotationEditorDialog::switchToTabView()
{
m_annotation.setComments(ui->tableView->fetchComments());
ui->rbTabView->setChecked(true);
ui->tableView->hide();
ui->tabWidget->show();
fillFields();
}
void AnnotationEditorDialog::switchToTableView()
{
m_annotation.setComments(ui->tabWidget->fetchComments());
ui->rbTableView->setChecked(true);
ui->tabWidget->hide();
ui->tableView->show();
fillFields();
}
void AnnotationEditorDialog::acceptedClicked()
@@ -155,56 +96,20 @@ void AnnotationEditorDialog::acceptedClicked()
emit AnnotationEditorDialog::acceptedDialog();
}
void AnnotationEditorDialog::fillFields()
void AnnotationEditorDialog::appliedClicked()
{
ui->customIdEdit->setText(m_customId);
ui->tabWidget->setupComments(m_annotation.comments());
ui->tableView->setupComments(m_annotation.comments());
updateAnnotation();
emit AnnotationEditorDialog::appliedDialog();
}
void AnnotationEditorDialog::updateAnnotation()
{
m_customId = ui->customIdEdit->text();
Annotation annotation;
switch (viewMode()) {
case TabsView:
annotation.setComments(ui->tabWidget->fetchComments());
break;
case TableView:
annotation.setComments(ui->tableView->fetchComments());
break;
m_editorWidget->updateAnnotation();
m_customId = m_editorWidget->customId();
m_annotation = m_editorWidget->annotation();
}
m_annotation = annotation;
if (m_statusIsActive && m_isGlobal)
m_globalStatus.setStatus(ui->statusComboBox->currentIndex());
}
void AnnotationEditorDialog::addComment(const Comment &comment)
{
m_annotation.addComment(comment);
ui->tabWidget->addCommentTab(comment);
}
void AnnotationEditorDialog::removeComment(int index)
{
if ((m_annotation.commentsSize() > index) && (index >= 0)) {
m_annotation.removeComment(index);
ui->tabWidget->removeTab(index);
}
}
void AnnotationEditorDialog::setStatusVisibility(bool hasStatus)
{
ui->statusAddButton->setVisible(!hasStatus && m_isGlobal);
ui->statusComboBox->setVisible(hasStatus && m_isGlobal);
m_statusIsActive = hasStatus;
}
Annotation const &AnnotationEditorDialog::annotation() const
const Annotation &AnnotationEditorDialog::annotation() const
{
return m_annotation;
}
@@ -212,29 +117,28 @@ Annotation const &AnnotationEditorDialog::annotation() const
void AnnotationEditorDialog::setAnnotation(const Annotation &annotation)
{
m_annotation = annotation;
fillFields();
m_editorWidget->setAnnotation(m_annotation);
}
void AnnotationEditorDialog::loadDefaultAnnotations(QString const &filename)
void AnnotationEditorDialog::loadDefaultAnnotations(const QString &filename)
{
m_defaults->loadFromFile(filename);
m_editorWidget->loadDefaultAnnotations(filename);
}
DefaultAnnotationsModel *AnnotationEditorDialog::defaultAnnotations() const
{
return m_defaults.get();
return m_editorWidget->defaultAnnotations();
}
void AnnotationEditorDialog::setCustomId(const QString &customId)
{
m_customId = customId;
ui->customIdEdit->setText(m_customId);
m_editorWidget->setCustomId(customId);
}
QString AnnotationEditorDialog::customId() const
const QString &AnnotationEditorDialog::customId() const
{
return m_customId;
}
} //namespace QmlDesigner

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,72 +25,63 @@
#pragma once
#include "annotation.h"
#include <QDialog>
#include "annotation.h"
QT_BEGIN_NAMESPACE
class QAbstractButton;
class QDialogButtonBox;
QT_END_NAMESPACE
namespace QmlDesigner {
namespace Ui {
class AnnotationEditorDialog;
}
class DefaultAnnotationsModel;
class AnnotationEditorWidget;
class AnnotationEditorDialog : public QDialog
{
Q_OBJECT
public:
enum ViewMode { TableView, TabsView };
enum class ViewMode { TableView,
TabsView };
explicit AnnotationEditorDialog(QWidget *parent,
const QString &targetId = {},
const QString &customId = {});
~AnnotationEditorDialog();
ViewMode viewMode() const;
Annotation const &annotation() const;
const Annotation &annotation() const;
void setAnnotation(const Annotation &annotation);
QString customId() const;
const QString &customId() const;
void setCustomId(const QString &customId);
bool isGlobal() const;
void setGlobal(bool = true);
void loadDefaultAnnotations(QString const &filename);
DefaultAnnotationsModel *defaultAnnotations() const;
void setStatus(GlobalAnnotationStatus status);
GlobalAnnotationStatus globalStatus() const;
public slots:
void showStatusContainer(bool show);
void switchToTabView();
void switchToTableView();
void loadDefaultAnnotations(const QString &filename);
private slots:
void buttonClicked(QAbstractButton *button);
void acceptedClicked();
void appliedClicked();
signals:
void acceptedDialog(); //use instead of QDialog::accepted
void globalChanged();
void appliedDialog();
private:
void fillFields();
void updateAnnotation();
void addComment(const Comment &comment);
void removeComment(int index);
void setStatusVisibility(bool hasStatus);
std::unique_ptr<Ui::AnnotationEditorDialog> ui;
private:
GlobalAnnotationStatus m_globalStatus = GlobalAnnotationStatus::NoStatus;
bool m_statusIsActive = false;
bool m_isGlobal = false;
Annotation m_annotation;
QString m_customId;
std::unique_ptr<DefaultAnnotationsModel> m_defaults;
AnnotationEditorWidget *m_editorWidget;
QDialogButtonBox *m_buttonBox;
};

View File

@@ -0,0 +1,243 @@
/****************************************************************************
**
** Copyright (C) 2021 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 "annotationeditorwidget.h"
#include "annotation.h"
#include "annotationcommenttab.h"
#include "defaultannotations.h"
#include "ui_annotationeditorwidget.h"
#include <timelineicons.h>
#include <utils/qtcassert.h>
#include <QAction>
#include <QMessageBox>
#include <QObject>
#include <QToolBar>
#include <QAbstractButton>
namespace QmlDesigner {
AnnotationEditorWidget::AnnotationEditorWidget(QWidget *parent,
const QString &targetId,
const QString &customId)
: QWidget(parent)
, m_defaults(std::make_unique<DefaultAnnotationsModel>())
, ui(std::make_unique<Ui::AnnotationEditorWidget>())
, m_statusIsActive(false)
, m_customId(customId)
{
ui->setupUi(this);
setGlobal(m_isGlobal);
loadDefaultAnnotations(DefaultAnnotationsModel::defaultJsonFilePath());
ui->tabWidget->setDefaultAnnotations(defaultAnnotations());
ui->tableView->setDefaultAnnotations(defaultAnnotations());
connect(ui->tableView,
&AnnotationTableView::richTextEditorRequested,
this,
[&](int index, const QString &) {
switchToTabView();
ui->tabWidget->setCurrentIndex(index);
});
connect(ui->statusAddButton, &QPushButton::clicked, this, [&](bool) {
setStatusVisibility(true);
});
connect(ui->rbTableView,
&QRadioButton::clicked,
this,
&AnnotationEditorWidget::switchToTableView);
connect(ui->rbTabView,
&QRadioButton::clicked,
this, &AnnotationEditorWidget::switchToTabView);
setStatus(m_globalStatus);
switchToTabView();
ui->targetIdEdit->setText(targetId);
}
//have to default it in here instead of the header because of unique_ptr with forward declared type
AnnotationEditorWidget::~AnnotationEditorWidget() = default;
bool AnnotationEditorWidget::isGlobal() const
{
return m_isGlobal;
}
void AnnotationEditorWidget::setGlobal(bool global)
{
ui->annotationContainer->setVisible(!global);
ui->statusAddButton->setVisible(global);
ui->statusComboBox->setVisible(global);
if (m_isGlobal != global) {
m_isGlobal = global;
emit globalChanged();
}
}
AnnotationEditorWidget::ViewMode AnnotationEditorWidget::viewMode() const
{
return ui->rbTableView->isChecked() ? ViewMode::TableView : ViewMode::TabsView;
}
void AnnotationEditorWidget::setStatus(GlobalAnnotationStatus status)
{
m_globalStatus = status;
bool hasStatus = status.status() != GlobalAnnotationStatus::NoStatus;
if (hasStatus)
ui->statusComboBox->setCurrentIndex(static_cast<int>(status.status()));
setStatusVisibility(hasStatus);
}
GlobalAnnotationStatus AnnotationEditorWidget::globalStatus() const
{
return m_globalStatus;
}
void AnnotationEditorWidget::showStatusContainer(bool show)
{
ui->statusContainer->setVisible(show);
}
void AnnotationEditorWidget::switchToTabView()
{
m_annotation.setComments(ui->tableView->fetchComments());
ui->rbTabView->setChecked(true);
ui->tableView->hide();
ui->tabWidget->show();
fillFields();
if (ui->tabWidget->count() > 0)
ui->tabWidget->setCurrentIndex(0);
}
void AnnotationEditorWidget::switchToTableView()
{
m_annotation.setComments(ui->tabWidget->fetchComments());
ui->rbTableView->setChecked(true);
ui->tabWidget->hide();
ui->tableView->show();
fillFields();
}
void AnnotationEditorWidget::fillFields()
{
ui->customIdEdit->setText(m_customId);
ui->tabWidget->setupComments(m_annotation.comments());
ui->tableView->setupComments(m_annotation.comments());
}
void AnnotationEditorWidget::updateAnnotation()
{
m_customId = ui->customIdEdit->text();
Annotation annotation;
switch (viewMode()) {
case ViewMode::TabsView:
annotation.setComments(ui->tabWidget->fetchComments());
break;
case ViewMode::TableView:
annotation.setComments(ui->tableView->fetchComments());
break;
}
m_annotation = annotation;
if (m_statusIsActive && m_isGlobal)
m_globalStatus.setStatus(ui->statusComboBox->currentIndex());
}
void AnnotationEditorWidget::addComment(const Comment &comment)
{
m_annotation.addComment(comment);
ui->tabWidget->addCommentTab(comment);
}
void AnnotationEditorWidget::removeComment(int index)
{
if ((m_annotation.commentsSize() > index) && (index >= 0)) {
m_annotation.removeComment(index);
ui->tabWidget->removeTab(index);
}
}
void AnnotationEditorWidget::setStatusVisibility(bool hasStatus)
{
ui->statusAddButton->setVisible(!hasStatus && m_isGlobal);
ui->statusComboBox->setVisible(hasStatus && m_isGlobal);
m_statusIsActive = hasStatus;
}
const Annotation &AnnotationEditorWidget::annotation() const
{
return m_annotation;
}
void AnnotationEditorWidget::setAnnotation(const Annotation &annotation)
{
m_annotation = annotation;
fillFields();
}
void AnnotationEditorWidget::loadDefaultAnnotations(const QString &filename)
{
m_defaults->loadFromFile(filename);
}
DefaultAnnotationsModel *AnnotationEditorWidget::defaultAnnotations() const
{
return m_defaults.get();
}
void AnnotationEditorWidget::setTargetId(const QString &targetId)
{
ui->targetIdEdit->setText(targetId);
}
QString AnnotationEditorWidget::targetId() const
{
return ui->targetIdEdit->text();
}
void AnnotationEditorWidget::setCustomId(const QString &customId)
{
m_customId = customId;
ui->customIdEdit->setText(m_customId);
}
const QString &AnnotationEditorWidget::customId() const
{
return m_customId;
}
} //namespace QmlDesigner

View File

@@ -0,0 +1,104 @@
/****************************************************************************
**
** Copyright (C) 2021 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 "annotation.h"
#include <QWidget>
QT_BEGIN_NAMESPACE
class QAbstractButton;
QT_END_NAMESPACE
namespace QmlDesigner {
namespace Ui {
class AnnotationEditorWidget;
}
class DefaultAnnotationsModel;
class AnnotationEditorWidget : public QWidget
{
Q_OBJECT
public:
enum class ViewMode { TableView, TabsView };
explicit AnnotationEditorWidget(QWidget *parent,
const QString &targetId = {},
const QString &customId = {});
~AnnotationEditorWidget();
ViewMode viewMode() const;
const Annotation &annotation() const;
void setAnnotation(const Annotation &annotation);
QString targetId() const;
void setTargetId(const QString &targetId);
const QString &customId() const;
void setCustomId(const QString &customId);
bool isGlobal() const;
void setGlobal(bool = true);
DefaultAnnotationsModel *defaultAnnotations() const;
void loadDefaultAnnotations(const QString &filename);
GlobalAnnotationStatus globalStatus() const;
void setStatus(GlobalAnnotationStatus status);
void updateAnnotation();
public slots:
void showStatusContainer(bool show);
void switchToTabView();
void switchToTableView();
signals:
void globalChanged();
private:
void fillFields();
void addComment(const Comment &comment);
void removeComment(int index);
void setStatusVisibility(bool hasStatus);
private:
std::unique_ptr<DefaultAnnotationsModel> m_defaults;
std::unique_ptr<Ui::AnnotationEditorWidget> ui;
GlobalAnnotationStatus m_globalStatus = GlobalAnnotationStatus::NoStatus;
bool m_statusIsActive = false;
bool m_isGlobal = false;
Annotation m_annotation;
QString m_customId;
};
} //namespace QmlDesigner

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmlDesigner::AnnotationEditorDialog</class>
<widget class="QDialog" name="QmlDesigner::AnnotationEditorDialog">
<class>QmlDesigner::AnnotationEditorWidget</class>
<widget class="QWidget" name="QmlDesigner::AnnotationEditorWidget">
<property name="geometry">
<rect>
<x>0</x>
@@ -10,10 +10,7 @@
<height>819</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="statusContainer" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_3">
@@ -170,19 +167,6 @@
<item>
<widget class="AnnotationTableView" name="tableView"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
@@ -198,44 +182,6 @@
<header>annotationtableview.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>targetIdEdit</tabstop>
<tabstop>customIdEdit</tabstop>
<tabstop>tabWidget</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QmlDesigner::AnnotationEditorDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>261</x>
<y>473</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QmlDesigner::AnnotationEditorDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>329</x>
<y>473</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>

View File

@@ -0,0 +1,322 @@
/****************************************************************************
**
** Copyright (C) 2021 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 "annotationlist.h"
#include <QPainter>
#include <QItemSelectionModel>
#include <variant>
namespace QmlDesigner {
// Entry
AnnotationListEntry::AnnotationListEntry(const ModelNode &modelnode)
: id(modelnode.id())
, annotationName(modelnode.customId())
, annotation(modelnode.annotation())
, node(modelnode)
{
}
AnnotationListEntry::AnnotationListEntry(const QString &argId, const QString &argAnnotationName,
const Annotation &argAnnotation, const ModelNode &argNode)
: id(argId)
, annotationName(argAnnotationName)
, annotation(argAnnotation)
, node(argNode)
{
}
// Model
AnnotationListModel::AnnotationListModel(ModelNode rootNode, AnnotationListView *parent)
: QAbstractItemModel(parent)
, m_annotationView(parent)
, m_rootNode(rootNode)
{
fillModel();
}
void AnnotationListModel::setRootNode(ModelNode rootNode)
{
m_rootNode = rootNode;
resetModel();
}
void AnnotationListModel::resetModel()
{
beginResetModel();
m_annoList.clear();
fillModel();
endResetModel();
}
ModelNode AnnotationListModel::getModelNode(int id) const
{
if (id >= 0 && id < m_annoList.size())
return m_annoList.at(id).node;
return {};
}
AnnotationListEntry AnnotationListModel::getStoredAnnotation(int id) const
{
if (id >= 0 && id < m_annoList.size())
return m_annoList.at(id);
return {};
}
void AnnotationListModel::fillModel()
{
if (m_rootNode.isValid()) {
const QList<QmlDesigner::ModelNode> allNodes = m_rootNode.allSubModelNodesAndThisNode();
for (const QmlDesigner::ModelNode &node : allNodes) {
if (node.hasCustomId() || node.hasAnnotation()) {
m_annoList.emplace_back(node);
}
}
}
}
QModelIndex AnnotationListModel::index(int row, int column, const QModelIndex &parent) const
{
Q_UNUSED(parent)
return createIndex(row, column);
}
QModelIndex AnnotationListModel::parent(const QModelIndex &) const
{
return {};
}
int AnnotationListModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return static_cast<int>(m_annoList.size());
}
int AnnotationListModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return m_numberOfColumns;
}
QVariant AnnotationListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_annoList.size())
return {};
const auto &item = m_annoList.at(index.row());
switch (role) {
case AnnotationListModel::IdRow:
return item.id;
case AnnotationListModel::NameRow:
return item.annotationName;
case AnnotationListModel::AnnotationsCountRow:
return item.annotation.commentsSize();
default:
return {};
}
}
Qt::ItemFlags AnnotationListModel::flags(const QModelIndex &index) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_annoList.size())
return Qt::NoItemFlags;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
void AnnotationListModel::storeChanges(int row, const QString &customId, const Annotation &annotation)
{
if (row < 0 || row >= rowCount())
return;
auto &item = m_annoList[row];
item.annotationName = customId;
item.annotation = annotation;
emit dataChanged(index(row, 1), index(row, 2));
}
void AnnotationListModel::saveChanges()
{
for (auto &item : m_annoList) {
ModelNode &node = item.node;
if (node.isValid()) {
const QString &annoName = item.annotationName;
const Annotation &anno = item.annotation;
node.setCustomId(annoName);
node.setAnnotation(anno);
}
}
}
// View
AnnotationListView::AnnotationListView(ModelNode rootNode, QWidget *parent)
: Utils::ListView(parent)
, m_model(new AnnotationListModel(rootNode, this))
{
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
setModel(m_model);
setItemDelegate(new AnnotationListDelegate(this));
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setSelectionMode(QAbstractItemView::SingleSelection);
setSelectionBehavior(QAbstractItemView::SelectRows);
setActivationMode(Utils::SingleClickActivation);
setSelectionRectVisible(true);
setDragEnabled(false);
}
void AnnotationListView::setRootNode(ModelNode rootNode)
{
m_model->setRootNode(rootNode);
}
ModelNode AnnotationListView::getModelNodeByAnnotationId(int id) const
{
return m_model->getModelNode(id);
}
AnnotationListEntry AnnotationListView::getStoredAnnotationById(int id) const
{
return m_model->getStoredAnnotation(id);
}
void AnnotationListView::selectRow(int row)
{
if (m_model->rowCount() > row) {
QModelIndex index = m_model->index(row, 0);
setCurrentIndex(index);
emit activated(index);
}
}
int AnnotationListView::rowCount() const
{
return m_model->rowCount();
}
void AnnotationListView::storeChangesInModel(int row, const QString &customId, const Annotation &annotation)
{
m_model->storeChanges(row, customId, annotation);
}
void AnnotationListView::saveChangesFromModel()
{
m_model->saveChanges();
}
// Delegate
AnnotationListDelegate::AnnotationListDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
QSize AnnotationListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
QFontMetrics fm(option.font);
QSize s;
s.setWidth(option.rect.width());
s.setHeight(fm.height() * 2 + 10);
return s;
}
void AnnotationListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
painter->save();
QFontMetrics fm(opt.font);
QColor backgroundColor;
QColor textColor;
bool selected = opt.state & QStyle::State_Selected;
if (selected) {
painter->setBrush(opt.palette.highlight().color());
backgroundColor = opt.palette.highlight().color();
} else {
backgroundColor = opt.palette.window().color();
painter->setBrush(backgroundColor);
}
painter->setPen(Qt::NoPen);
painter->drawRect(opt.rect);
// Set Text Color
if (opt.state & QStyle::State_Selected)
textColor = opt.palette.highlightedText().color();
else
textColor = opt.palette.text().color();
painter->setPen(textColor);
const QString itemId = index.data(AnnotationListModel::IdRow).toString();
painter->drawText(6, 2 + opt.rect.top() + fm.ascent(), itemId);
const QString annotationCounter = index.data(AnnotationListModel::AnnotationsCountRow).toString();
painter->drawText(opt.rect.right() - fm.horizontalAdvance(annotationCounter) - 6,
2 + opt.rect.top() + fm.ascent(), annotationCounter);
// Annotation name block:
QColor mix;
mix.setRgbF(0.7 * textColor.redF() + 0.3 * backgroundColor.redF(),
0.7 * textColor.greenF() + 0.3 * backgroundColor.greenF(),
0.7 * textColor.blueF() + 0.3 * backgroundColor.blueF());
painter->setPen(mix);
const QString annotationName = index.data(AnnotationListModel::NameRow).toString().trimmed();
painter->drawText(6, opt.rect.top() + fm.ascent() + fm.height() + 6, annotationName);
// Separator lines
const QRectF innerRect = QRectF(opt.rect).adjusted(0.5, 0.5, -0.5, -0.5);
painter->setPen(QColor::fromRgb(150, 150, 150));
painter->drawLine(innerRect.bottomLeft(), innerRect.bottomRight());
painter->restore();
}
}

View File

@@ -0,0 +1,139 @@
/****************************************************************************
**
** Copyright (C) 2021 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 "annotation.h"
#include "modelnode.h"
#include <utils/itemviews.h>
#include <QWidget>
#include <QStandardItemModel>
#include <QListView>
#include <QStyledItemDelegate>
#include <tuple>
#include <vector>
namespace QmlDesigner {
class AnnotationListView;
//structure is used as a storage for the model data
//id, annotationname and annotation are storages, that will be submited into node on save
struct AnnotationListEntry {
QString id;
QString annotationName;
Annotation annotation;
ModelNode node;
AnnotationListEntry() = default;
AnnotationListEntry(const ModelNode &modelnode);
AnnotationListEntry(const QString &argId, const QString &argAnnotationName,
const Annotation &argAnnotation, const ModelNode &argNode);
};
class AnnotationListModel final : public QAbstractItemModel
{
Q_OBJECT
public:
enum ColumnRoles {
IdRow = Qt::UserRole,
NameRow,
AnnotationsCountRow
};
AnnotationListModel(ModelNode rootNode, AnnotationListView *view = nullptr);
~AnnotationListModel() = default;
void setRootNode(ModelNode rootNode);
void resetModel();
ModelNode getModelNode(int id) const;
AnnotationListEntry getStoredAnnotation(int id) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &child) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
void storeChanges(int row, const QString &customId, const Annotation &annotation);
void saveChanges();
private:
void fillModel();
private:
QListView *m_annotationView = nullptr;
ModelNode m_rootNode;
std::vector<AnnotationListEntry> m_annoList;
const int m_numberOfColumns = 3;
};
class AnnotationListView final : public Utils::ListView
{
Q_OBJECT
public:
explicit AnnotationListView(ModelNode rootNode, QWidget *parent = nullptr);
~AnnotationListView() = default;
void setRootNode(ModelNode rootNode);
ModelNode getModelNodeByAnnotationId(int id) const;
AnnotationListEntry getStoredAnnotationById(int id) const;
void selectRow(int row);
int rowCount() const;
void storeChangesInModel(int row, const QString &customId, const Annotation &annotation);
void saveChangesFromModel();
private:
AnnotationListModel *m_model = nullptr;
};
class AnnotationListDelegate final : public QStyledItemDelegate
{
Q_OBJECT
public:
AnnotationListDelegate(QObject *parent = nullptr);
private:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
}

View File

@@ -0,0 +1,119 @@
/****************************************************************************
**
** Copyright (C) 2021 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 "annotationlistwidget.h"
#include "annotationeditorwidget.h"
#include "annotationlist.h"
#include <QLayout>
#include <QVBoxLayout>
#include <QHBoxLayout>
namespace QmlDesigner {
AnnotationListWidget::AnnotationListWidget(ModelNode rootNode, QWidget *parent)
: QWidget(parent)
, m_listView(new AnnotationListView(rootNode, this))
, m_editor(new AnnotationEditorWidget(this))
{
createUI();
connect(m_listView, &Utils::ListView::activated,
this, &AnnotationListWidget::changeAnnotation);
if (validateListSize())
m_listView->selectRow(0);
}
void AnnotationListWidget::setRootNode(ModelNode rootNode)
{
m_listView->setRootNode(rootNode);
m_currentItem = -1;
if (validateListSize())
m_listView->selectRow(0);
}
void AnnotationListWidget::saveAllChanges()
{
//first commit currently opened item
if (m_currentItem != -1) {
m_editor->updateAnnotation();
const QString oldCustomId = m_editor->customId();
const Annotation oldAnno = m_editor->annotation();
m_listView->storeChangesInModel(m_currentItem, oldCustomId, oldAnno);
}
//save all
m_listView->saveChangesFromModel();
}
void AnnotationListWidget::createUI()
{
QHBoxLayout *layout = new QHBoxLayout(this);
const QSizePolicy policy = m_listView->sizePolicy();
m_listView->setSizePolicy(QSizePolicy::Minimum, policy.verticalPolicy());
layout->addWidget(m_listView);
layout->addWidget(m_editor);
}
bool AnnotationListWidget::validateListSize()
{
const bool isFilled = m_listView->rowCount() > 0;
m_editor->setEnabled(isFilled);
return isFilled;
}
void AnnotationListWidget::changeAnnotation(const QModelIndex &index)
{
//store previous data
if (m_currentItem != -1) {
m_editor->updateAnnotation();
const QString &oldCustomId = m_editor->customId();
const Annotation &oldAnno = m_editor->annotation();
m_listView->storeChangesInModel(m_currentItem, oldCustomId, oldAnno);
}
//show new data
if (!index.isValid() || index.row() < 0 || index.row() >= m_listView->rowCount())
return;
const auto annotationData = m_listView->getStoredAnnotationById(index.row());
m_editor->setTargetId(annotationData.id);
m_editor->setCustomId(annotationData.annotationName);
m_editor->setAnnotation(annotationData.annotation);
m_currentItem = index.row();
}
}

View File

@@ -0,0 +1,70 @@
/****************************************************************************
**
** Copyright (C) 2021 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 "modelnode.h"
#include <coreplugin/icore.h>
#include <QWidget>
#include <QDialog>
#include <QListView>
namespace QmlDesigner {
class AnnotationListView;
class AnnotationEditorWidget;
class AnnotationListWidget : public QWidget
{
Q_OBJECT
public:
explicit AnnotationListWidget(ModelNode rootNode, QWidget *parent = nullptr);
~AnnotationListWidget() = default;
void setRootNode(ModelNode rootNode);
void saveAllChanges();
private:
void createUI();
bool validateListSize();
private slots:
void changeAnnotation(const QModelIndex &index);
private:
AnnotationListView *m_listView;
AnnotationEditorWidget *m_editor;
int m_currentItem = -1;
};
}

View File

@@ -84,7 +84,7 @@ public:
QAbstractItemModel *model,
const QModelIndex &index) const override;
signals:
void commentChanged(int row, Comment const &);
void commentChanged(int row, const QmlDesigner::Comment &comment);
};
class CommentValueDelegate : public CommentDelegate

View File

@@ -66,8 +66,6 @@ AnnotationTabWidget::AnnotationTabWidget(QWidget *parent)
setCornerWidget(commentCornerWidget, Qt::TopRightCorner);
}
AnnotationTabWidget::~AnnotationTabWidget() {}
QVector<Comment> AnnotationTabWidget::fetchComments() const
{
QVector<Comment> comments;
@@ -85,7 +83,7 @@ QVector<Comment> AnnotationTabWidget::fetchComments() const
return comments;
}
void AnnotationTabWidget::setupComments(QVector<Comment> const &comments)
void AnnotationTabWidget::setupComments(const QVector<Comment> &comments)
{
setUpdatesEnabled(false);
@@ -124,7 +122,7 @@ void AnnotationTabWidget::onCommentTitleChanged(const QString &text, QWidget *ta
setTabText(tabIndex, defaultTabName + " " + QString::number(tabIndex + 1));
}
void AnnotationTabWidget::addCommentTab(const Comment &comment)
void AnnotationTabWidget::addCommentTab(const QmlDesigner::Comment &comment)
{
auto *commentTab = new AnnotationCommentTab();
commentTab->setDefaultAnnotations(m_defaults);

View File

@@ -37,16 +37,16 @@ class AnnotationTabWidget : public QTabWidget
Q_OBJECT
public:
AnnotationTabWidget(QWidget *parent = nullptr);
~AnnotationTabWidget();
~AnnotationTabWidget() = default;
QVector<Comment> fetchComments() const;
void setupComments(QVector<Comment> const &comments);
void setupComments(const QVector<Comment> &comments);
DefaultAnnotationsModel *defaultAnnotations() const;
void setDefaultAnnotations(DefaultAnnotationsModel *);
public slots:
void addCommentTab(const Comment &comment = {});
void addCommentTab(const QmlDesigner::Comment &comment = {});
void deleteAllTabs();
private slots:

View File

@@ -0,0 +1,176 @@
/****************************************************************************
**
** Copyright (C) 2021 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 "globalannotationdialog.h"
#include "annotation.h"
#include "annotationcommenttab.h"
#include "defaultannotations.h"
#include "annotationeditorwidget.h"
#include "annotationlistwidget.h"
#include <timelineicons.h>
#include <utils/qtcassert.h>
#include <QAction>
#include <QMessageBox>
#include <QObject>
#include <QToolBar>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QDialogButtonBox>
#include <QAbstractButton>
namespace QmlDesigner {
GlobalAnnotationDialog::GlobalAnnotationDialog(ModelNode rootNode, QWidget *parent)
: QDialog(parent)
, m_statusIsActive(false)
, m_defaults(std::make_unique<DefaultAnnotationsModel>())
, m_editorWidget(new AnnotationEditorWidget(this))
, m_annotationListWidget(new AnnotationListWidget(rootNode, this))
{
setupUI();
setStatus(m_globalStatus);
m_editorWidget->setGlobal(true);
connect(this, &QDialog::accepted,
this, &GlobalAnnotationDialog::acceptedClicked);
connect(m_buttonBox, &QDialogButtonBox::accepted,
this, &GlobalAnnotationDialog::acceptedClicked);
connect(m_buttonBox, &QDialogButtonBox::clicked,
this, &GlobalAnnotationDialog::buttonClicked);
connect(m_buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::close);
}
GlobalAnnotationDialog::~GlobalAnnotationDialog() = default;
void GlobalAnnotationDialog::setStatus(GlobalAnnotationStatus status)
{
m_editorWidget->setStatus(status);
}
GlobalAnnotationStatus GlobalAnnotationDialog::globalStatus() const
{
return m_editorWidget->globalStatus();
}
GlobalAnnotationDialog::ViewMode GlobalAnnotationDialog::viewMode() const
{
if (!m_tabWidget)
return ViewMode::GlobalAnnotation;
return (m_tabWidget->currentIndex() == 0)
? ViewMode::GlobalAnnotation
: ViewMode::List;
}
void GlobalAnnotationDialog::saveAnnotationListChanges()
{
m_annotationListWidget->saveAllChanges();
}
void GlobalAnnotationDialog::buttonClicked(QAbstractButton *button)
{
if (button) {
const QDialogButtonBox::StandardButton buttonType = m_buttonBox->standardButton(button);
if (buttonType == QDialogButtonBox::Apply) {
appliedClicked();
}
}
}
void GlobalAnnotationDialog::acceptedClicked()
{
updateAnnotation();
emit GlobalAnnotationDialog::acceptedDialog();
}
void GlobalAnnotationDialog::appliedClicked()
{
updateAnnotation();
emit GlobalAnnotationDialog::appliedDialog();
}
void GlobalAnnotationDialog::updateAnnotation()
{
m_editorWidget->updateAnnotation();
m_annotation = m_editorWidget->annotation();
m_statusIsActive = (m_editorWidget->globalStatus().status() != GlobalAnnotationStatus::NoStatus);
m_globalStatus = m_editorWidget->globalStatus();
}
void GlobalAnnotationDialog::setupUI()
{
setWindowFlag(Qt::Tool, true);
setWindowTitle(tr("Global Annotation Editor"));
setModal(true);
if (!QWidget::layout())
new QVBoxLayout(this);
m_tabWidget = new QTabWidget(this);
m_tabWidget->setTabsClosable(false);
m_tabWidget->setMovable(false);
QWidget::layout()->addWidget(m_tabWidget);
m_tabWidget->addTab(m_editorWidget, tr("Global Annotation"));
m_tabWidget->addTab(m_annotationListWidget, tr("All Annotations"));
const QDialogButtonBox::StandardButtons buttonsToCreate =
QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply;
m_buttonBox = new QDialogButtonBox(buttonsToCreate, this);
QWidget::layout()->addWidget(m_buttonBox);
}
const Annotation &GlobalAnnotationDialog::annotation() const
{
return m_annotation;
}
void GlobalAnnotationDialog::setAnnotation(const Annotation &annotation)
{
m_annotation = annotation;
m_editorWidget->setAnnotation(m_annotation);
}
void GlobalAnnotationDialog::loadDefaultAnnotations(const QString &filename)
{
m_editorWidget->loadDefaultAnnotations(filename);
}
DefaultAnnotationsModel *GlobalAnnotationDialog::defaultAnnotations() const
{
return m_editorWidget->defaultAnnotations();
}
} //namespace QmlDesigner

View File

@@ -0,0 +1,96 @@
/****************************************************************************
**
** Copyright (C) 2021 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 "annotation.h"
#include "modelnode.h"
#include <QDialog>
QT_BEGIN_NAMESPACE
class QTabWidget;
class QDialogButtonBox;
class QAbstractButton;
QT_END_NAMESPACE
namespace QmlDesigner {
class DefaultAnnotationsModel;
class AnnotationEditorWidget;
class AnnotationListWidget;
class GlobalAnnotationDialog : public QDialog
{
Q_OBJECT
public:
enum class ViewMode { GlobalAnnotation,
List };
explicit GlobalAnnotationDialog(ModelNode rootNode, QWidget *parent);
~GlobalAnnotationDialog();
const Annotation &annotation() const;
void setAnnotation(const Annotation &annotation);
DefaultAnnotationsModel *defaultAnnotations() const;
void loadDefaultAnnotations(const QString &filename);
GlobalAnnotationStatus globalStatus() const;
void setStatus(GlobalAnnotationStatus status);
ViewMode viewMode() const;
void saveAnnotationListChanges();
private slots:
void buttonClicked(QAbstractButton *button);
void acceptedClicked();
void appliedClicked();
signals:
void acceptedDialog(); //use instead of QDialog::accepted
void appliedDialog();
void globalChanged();
private:
void updateAnnotation();
void setupUI();
private:
GlobalAnnotationStatus m_globalStatus = GlobalAnnotationStatus::NoStatus;
bool m_statusIsActive = false;
Annotation m_annotation;
std::unique_ptr<DefaultAnnotationsModel> m_defaults;
AnnotationEditorWidget *m_editorWidget = nullptr;
AnnotationListWidget *m_annotationListWidget = nullptr;
QTabWidget *m_tabWidget = nullptr;
QDialogButtonBox *m_buttonBox = nullptr;
};
} //namespace QmlDesigner

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -26,10 +26,10 @@
#include "globalannotationeditor.h"
#include "annotation.h"
#include "annotationeditordialog.h"
#include "globalannotationdialog.h"
#include <coreplugin/icore.h>
#include <QMessageBox>
namespace QmlDesigner {
@@ -38,24 +38,19 @@ GlobalAnnotationEditor::GlobalAnnotationEditor(QObject *parent)
: ModelNodeEditorProxy(parent)
{}
GlobalAnnotationEditor::~GlobalAnnotationEditor() {}
QWidget *GlobalAnnotationEditor::createWidget()
{
auto *dialog = new AnnotationEditorDialog(Core::ICore::dialogParent());
GlobalAnnotationDialog *dialog = new GlobalAnnotationDialog(m_modelNode, Core::ICore::dialogParent());
dialog->setGlobal(true);
dialog->setStatus(m_modelNode.globalStatus());
dialog->setAnnotation(this->m_modelNode.globalAnnotation());
QObject::connect(dialog,
&AnnotationEditorDialog::acceptedDialog,
this,
&GlobalAnnotationEditor::acceptedClicked);
QObject::connect(dialog,
&AnnotationEditorDialog::rejected,
this,
&GlobalAnnotationEditor::cancelClicked);
QObject::connect(dialog, &GlobalAnnotationDialog::acceptedDialog,
this, &GlobalAnnotationEditor::acceptedClicked);
QObject::connect(dialog, &GlobalAnnotationDialog::rejected,
this, &GlobalAnnotationEditor::cancelClicked);
QObject::connect(dialog, &GlobalAnnotationDialog::appliedDialog,
this, &GlobalAnnotationEditor::appliedClicked);
return dialog;
};
@@ -65,9 +60,9 @@ void GlobalAnnotationEditor::removeFullAnnotation()
if (!node.isValid())
return;
QString dialogTitle = tr("Global Annotation");
const QString dialogTitle = tr("Global Annotation");
if (QMessageBox::question(Core::ICore::dialogParent(),
tr("Global Annotation"),
dialogTitle,
tr("Delete this annotation?"))
== QMessageBox::Yes) {
node.removeGlobalAnnotation();
@@ -77,9 +72,42 @@ void GlobalAnnotationEditor::removeFullAnnotation()
void GlobalAnnotationEditor::acceptedClicked()
{
if (const auto *dialog = qobject_cast<AnnotationEditorDialog *>(widget())) {
applyChanges();
hideWidget();
emit accepted();
emit annotationChanged();
emit customIdChanged();
}
void GlobalAnnotationEditor::appliedClicked()
{
applyChanges();
emit applied();
emit annotationChanged();
emit customIdChanged();
}
void GlobalAnnotationEditor::cancelClicked()
{
hideWidget();
emit canceled();
emit annotationChanged();
emit customIdChanged();
}
void GlobalAnnotationEditor::applyChanges()
{
if (GlobalAnnotationDialog * const dialog = qobject_cast<GlobalAnnotationDialog *>(widget())) {
//first save global annotation:
auto &node = this->m_modelNode;
const Annotation annotation = dialog->annotation();
const Annotation &annotation = dialog->annotation();
if (annotation.comments().isEmpty())
node.removeGlobalAnnotation();
@@ -92,20 +120,11 @@ void GlobalAnnotationEditor::acceptedClicked()
node.removeGlobalStatus();
else
node.setGlobalStatus(status);
//then save annotations list:
dialog->saveAnnotationListChanges();
}
hideWidget();
emit accepted();
emit annotationChanged();
}
void GlobalAnnotationEditor::cancelClicked()
{
hideWidget();
emit canceled();
emit annotationChanged();
}
} //namespace QmlDesigner

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,23 +25,23 @@
#pragma once
#include "annotation.h"
#include "editorproxy.h"
#include "modelnode.h"
#include <QObject>
#include <QPointer>
#include <QtQml>
#include "abstractaction.h"
#include "annotation.h"
#include "editorproxy.h"
#include "modelnode.h"
namespace QmlDesigner {
class GlobalAnnotationEditor : public ModelNodeEditorProxy
{
Q_OBJECT
public:
explicit GlobalAnnotationEditor(QObject *parent = nullptr);
~GlobalAnnotationEditor();
~GlobalAnnotationEditor() = default;
QWidget *createWidget() override;
@@ -50,12 +50,15 @@ public:
signals:
void accepted();
void canceled();
void modelNodeBackendChanged();
void annotationChanged();
void applied();
private slots:
void acceptedClicked();
void appliedClicked();
void cancelClicked();
private:
void applyChanges();
};
} //namespace QmlDesigner

View File

@@ -36,7 +36,7 @@ EditorProxy::EditorProxy(QObject *parent)
EditorProxy::~EditorProxy()
{
hideWidget();
EditorProxy::hideWidget();
}
void EditorProxy::showWidget()

View File

@@ -737,11 +737,19 @@ Project {
"annotationeditor/annotationeditor.cpp",
"annotationeditor/annotationeditor.h",
"annotationeditor/annotationeditor.qrc",
"annotationeditor/annotationlist.cpp",
"annotationeditor/annotationlist.h",
"annotationeditor/annotationlistwidget.cpp",
"annotationeditor/annotationlistwidget.h",
"annotationeditor/globalannotationeditor.cpp",
"annotationeditor/globalannotationeditor.h",
"annotationeditor/globalannotationdialog.cpp",
"annotationeditor/globalannotationdialog.h",
"annotationeditor/annotationeditordialog.cpp",
"annotationeditor/annotationeditordialog.h",
"annotationeditor/annotationeditordialog.ui",
"annotationeditor/annotationeditorwidget.cpp",
"annotationeditor/annotationeditorwidget.h",
"annotationeditor/annotationeditorwidget.ui",
"annotationeditor/defaultannotations.cpp",
"annotationeditor/defaultannotations.h",
"annotationeditor/annotationtableview.cpp",