Merge remote-tracking branch 'origin/master' into 4.12

Change-Id: If4508ed26484913d803cdf9d4c06831ec4e98ae7
This commit is contained in:
Eike Ziller
2020-02-17 16:49:43 +01:00
43 changed files with 2799 additions and 132 deletions

View File

@@ -9,7 +9,6 @@ defines = Q_QDOC \
Q_OS_.* \ Q_OS_.* \
Q_BYTE_ORDER \ Q_BYTE_ORDER \
QT_DEPRECATED \ QT_DEPRECATED \
Q_NO_USING_KEYWORD \ Q_NO_USING_KEYWORD
__cplusplus
versionsym = QT_VERSION_STR versionsym = QT_VERSION_STR

View File

@@ -41,7 +41,7 @@ for (doc_file, DOC_FILES) {
DOC_TARGETDIR = $$DOC_TARGET DOC_TARGETDIR = $$DOC_TARGET
DOC_OUTPUTDIR = $${DOCS_BASE_OUTDIR}/$${DOC_TARGETDIR}$${DOC_OUTDIR_POSTFIX} DOC_OUTPUTDIR = $${DOCS_BASE_OUTDIR}/$${DOC_TARGETDIR}$${DOC_OUTDIR_POSTFIX}
html_docs_$${DOC_TARGET}.commands = $$QDOC -outputdir $$shell_quote($$DOC_OUTPUTDIR) $$doc_file $$DOC_INDEXES html_docs_$${DOC_TARGET}.commands = $$QDOC -outputdir $$shell_quote($$DOC_OUTPUTDIR) $$doc_file $$DOC_INDEXES $$DOC_INCLUDES
QMAKE_EXTRA_TARGETS += html_docs_$${DOC_TARGET} QMAKE_EXTRA_TARGETS += html_docs_$${DOC_TARGET}
!isEmpty(html_docs.commands): html_docs.commands += && !isEmpty(html_docs.commands): html_docs.commands += &&

View File

@@ -41,4 +41,17 @@ DOC_HTML_INSTALLDIR = $$INSTALL_DOC_PATH
DOC_QCH_OUTDIR = $$IDE_DOC_PATH DOC_QCH_OUTDIR = $$IDE_DOC_PATH
DOC_QCH_INSTALLDIR = $$INSTALL_DOC_PATH DOC_QCH_INSTALLDIR = $$INSTALL_DOC_PATH
minQtVersion(5, 11, 0) {
for (include_path, INCLUDEPATH): \
DOC_INCLUDES += -I $$shell_quote($$include_path)
for (module, QT) {
MOD_INCLUDES = $$eval(QT.$${module}.includes)
for (include_path, MOD_INCLUDES): \
DOC_INCLUDES += -I $$shell_quote($$include_path)
}
for (include_path, QMAKE_DEFAULT_INCDIRS): \
DOC_INCLUDES += -I $$shell_quote($$include_path)
macos: DOC_INCLUDES += -F $$shell_quote($$[QT_INSTALL_LIBS])
}
include(doc/doc_targets.pri) include(doc/doc_targets.pri)

View File

@@ -107,8 +107,8 @@ Rectangle {
} }
Item { Item {
Layout.preferredWidth: 16 Layout.preferredWidth: 20
Layout.preferredHeight: 16 Layout.preferredHeight: 20
} }
} }
@@ -134,8 +134,10 @@ Rectangle {
Image { Image {
visible: !modelNodeBackend.multiSelection visible: !modelNodeBackend.multiSelection
Layout.preferredWidth: 16 Layout.preferredWidth: 20
Layout.preferredHeight: 16 Layout.preferredHeight: 20
horizontalAlignment: Image.AlignHCenter
verticalAlignment: Image.AlignVCenter
source: hasAliasExport ? "image://icons/alias-export-checked" : "image://icons/alias-export-unchecked" source: hasAliasExport ? "image://icons/alias-export-checked" : "image://icons/alias-export-unchecked"
ToolTipArea { ToolTipArea {
enabled: !modelNodeBackend.multiSelection enabled: !modelNodeBackend.multiSelection
@@ -145,6 +147,110 @@ Rectangle {
} }
} }
} }
Label {
text: qsTr("Custom id")
}
SecondColumnLayout {
enabled: !modelNodeBackend.multiSelection
visible: enabled
spacing: 2
LineEdit {
id: annotationEdit
enabled: annotationEditor.hasAuxData
visible: enabled
backendValue: backendValues.customId__AUX
placeholderText: qsTr("customId")
text: backendValue.value
Layout.fillWidth: true
Layout.preferredWidth: 240
width: 240
showTranslateCheckBox: false
showExtendedFunctionButton: false
onHoveredChanged: annotationEditor.checkAux()
}
StudioControls.AbstractButton {
id: editAnnotationButton
enabled: annotationEditor.hasAuxData
visible: enabled
Layout.preferredWidth: 22
Layout.preferredHeight: 22
width: 22
buttonIcon: StudioTheme.Constants.edit
onClicked: annotationEditor.showWidget()
onHoveredChanged: annotationEditor.checkAux()
}
StudioControls.AbstractButton {
id: removeAnnotationButton
enabled: annotationEditor.hasAuxData
visible: enabled
Layout.preferredWidth: 22
Layout.preferredHeight: 22
width: 22
buttonIcon: StudioTheme.Constants.closeCross
onClicked: annotationEditor.removeFullAnnotation()
onHoveredChanged: annotationEditor.checkAux()
}
StudioControls.AbstractButton {
id: addAnnotationButton
enabled: !annotationEditor.hasAuxData
visible: enabled
buttonIcon: qsTr("Add Annotation")
iconFont: StudioTheme.Constants.font
Layout.fillWidth: true
Layout.preferredWidth: 240
onClicked: annotationEditor.showWidget()
onHoveredChanged: annotationEditor.checkAux()
}
Item {
Layout.preferredWidth: 22
Layout.preferredHeight: 22
enabled: !annotationEditor.hasAuxData
visible: enabled
}
AnnotationEditor {
id: annotationEditor
modelNodeBackendProperty: modelNodeBackend
property bool hasAuxData: (annotationEditor.hasAnnotation || annotationEditor.hasCustomId)
onModelNodeBackendChanged: checkAux()
onCustomIdChanged: checkAux()
onAnnotationChanged: checkAux()
function checkAux() {
hasAuxData = (annotationEditor.hasAnnotation || annotationEditor.hasCustomId)
annotationEdit.update()
}
onAccepted: {
hideWidget()
}
onCanceled: {
hideWidget()
}
}
}
} }
} }

View File

@@ -44,9 +44,14 @@ namespace Internal {
// FullCommandLineAspect // FullCommandLineAspect
FullCommandLineAspect::FullCommandLineAspect(RunConfiguration *rc) class FullCommandLineAspect : public BaseStringAspect
{ {
setLabelText(QdbRunConfiguration::tr("Full command line:")); Q_DECLARE_TR_FUNCTIONS(Qdb::Internal::QdbRunConfiguration);
public:
explicit FullCommandLineAspect(RunConfiguration *rc)
{
setLabelText(tr("Full command line:"));
auto exeAspect = rc->aspect<ExecutableAspect>(); auto exeAspect = rc->aspect<ExecutableAspect>();
auto argumentsAspect = rc->aspect<ArgumentsAspect>(); auto argumentsAspect = rc->aspect<ArgumentsAspect>();
@@ -62,9 +67,23 @@ FullCommandLineAspect::FullCommandLineAspect(RunConfiguration *rc)
connect(exeAspect, &ExecutableAspect::changed, this, updateCommandLine); connect(exeAspect, &ExecutableAspect::changed, this, updateCommandLine);
updateCommandLine(); updateCommandLine();
} }
};
// QdbRunConfiguration // QdbRunConfiguration
class QdbRunConfiguration : public RunConfiguration
{
Q_DECLARE_TR_FUNCTIONS(Qdb::Internal::QdbRunConfiguration);
public:
QdbRunConfiguration(Target *target, Core::Id id);
private:
Tasks checkForIssues() const override;
QString defaultDisplayName() const;
};
QdbRunConfiguration::QdbRunConfiguration(Target *target, Core::Id id) QdbRunConfiguration::QdbRunConfiguration(Target *target, Core::Id id)
: RunConfiguration(target, id) : RunConfiguration(target, id)
{ {

View File

@@ -30,26 +30,6 @@
namespace Qdb { namespace Qdb {
namespace Internal { namespace Internal {
class FullCommandLineAspect : public ProjectExplorer::BaseStringAspect
{
Q_OBJECT
public:
explicit FullCommandLineAspect(ProjectExplorer::RunConfiguration *rc);
};
class QdbRunConfiguration : public ProjectExplorer::RunConfiguration
{
Q_OBJECT
public:
QdbRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
private:
ProjectExplorer::Tasks checkForIssues() const override;
QString defaultDisplayName() const;
};
class QdbRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory class QdbRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
{ {
public: public:

View File

@@ -37,10 +37,18 @@
#include <QStandardPaths> #include <QStandardPaths>
using namespace Nim;
using namespace ProjectExplorer; using namespace ProjectExplorer;
NimbleRunConfiguration::NimbleRunConfiguration(ProjectExplorer::Target *target, Core::Id id) namespace Nim {
// NimbleRunConfiguration
class NimbleRunConfiguration : public RunConfiguration
{
Q_DECLARE_TR_FUNCTIONS(Nim::NimbleRunConfiguration)
public:
NimbleRunConfiguration(Target *target, Core::Id id)
: RunConfiguration(target, id) : RunConfiguration(target, id)
{ {
addAspect<LocalEnvironmentAspect>(target); addAspect<LocalEnvironmentAspect>(target);
@@ -60,6 +68,7 @@ NimbleRunConfiguration::NimbleRunConfiguration(ProjectExplorer::Target *target,
connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update);
update(); update();
} }
};
NimbleRunConfigurationFactory::NimbleRunConfigurationFactory() NimbleRunConfigurationFactory::NimbleRunConfigurationFactory()
: RunConfigurationFactory() : RunConfigurationFactory()
@@ -69,12 +78,15 @@ NimbleRunConfigurationFactory::NimbleRunConfigurationFactory()
addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
} }
QList<RunConfigurationCreationInfo> NimbleRunConfigurationFactory::availableCreators(Target *parent) const
{
return RunConfigurationFactory::availableCreators(parent);
}
NimbleTestConfiguration::NimbleTestConfiguration(Target *target, Core::Id id) // NimbleTestConfiguration
class NimbleTestConfiguration : public RunConfiguration
{
Q_DECLARE_TR_FUNCTIONS(Nim::NimbleTestConfiguration)
public:
NimbleTestConfiguration(ProjectExplorer::Target *target, Core::Id id)
: RunConfiguration(target, id) : RunConfiguration(target, id)
{ {
addAspect<ExecutableAspect>()->setExecutable(Utils::FilePath::fromString(QStandardPaths::findExecutable("nimble"))); addAspect<ExecutableAspect>()->setExecutable(Utils::FilePath::fromString(QStandardPaths::findExecutable("nimble")));
@@ -85,6 +97,7 @@ NimbleTestConfiguration::NimbleTestConfiguration(Target *target, Core::Id id)
setDisplayName(tr("Nimble Test")); setDisplayName(tr("Nimble Test"));
setDefaultDisplayName(tr("Nimble Test")); setDefaultDisplayName(tr("Nimble Test"));
} }
};
NimbleTestConfigurationFactory::NimbleTestConfigurationFactory() NimbleTestConfigurationFactory::NimbleTestConfigurationFactory()
: FixedRunConfigurationFactory(QString()) : FixedRunConfigurationFactory(QString())
@@ -92,3 +105,5 @@ NimbleTestConfigurationFactory::NimbleTestConfigurationFactory()
registerRunConfiguration<NimbleTestConfiguration>("Nim.NimbleTestConfiguration"); registerRunConfiguration<NimbleTestConfiguration>("Nim.NimbleTestConfiguration");
addSupportedProjectType(Constants::C_NIMBLEPROJECT_ID); addSupportedProjectType(Constants::C_NIMBLEPROJECT_ID);
} }
} // Nim

View File

@@ -29,35 +29,16 @@
namespace Nim { namespace Nim {
class NimbleRunConfiguration : public ProjectExplorer::RunConfiguration class NimbleRunConfigurationFactory final : public ProjectExplorer::RunConfigurationFactory
{
Q_OBJECT
public:
NimbleRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
};
class NimbleRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
{ {
public: public:
NimbleRunConfigurationFactory(); NimbleRunConfigurationFactory();
protected:
QList<ProjectExplorer::RunConfigurationCreationInfo> availableCreators(ProjectExplorer::Target *parent) const override;
}; };
class NimbleTestConfiguration : public ProjectExplorer::RunConfiguration class NimbleTestConfigurationFactory final : public ProjectExplorer::FixedRunConfigurationFactory
{
Q_OBJECT
public:
NimbleTestConfiguration(ProjectExplorer::Target *target, Core::Id id);
};
class NimbleTestConfigurationFactory : public ProjectExplorer::FixedRunConfigurationFactory
{ {
public: public:
NimbleTestConfigurationFactory(); NimbleTestConfigurationFactory();
}; };
} } // Nim

View File

@@ -41,7 +41,12 @@ using namespace Utils;
namespace Nim { namespace Nim {
NimRunConfiguration::NimRunConfiguration(Target *target, Core::Id id) class NimRunConfiguration final : public RunConfiguration
{
Q_DECLARE_TR_FUNCTIONS(Nim::NimRunConfiguration)
public:
NimRunConfiguration(Target *target, Core::Id id)
: RunConfiguration(target, id) : RunConfiguration(target, id)
{ {
addAspect<LocalEnvironmentAspect>(target); addAspect<LocalEnvironmentAspect>(target);
@@ -66,6 +71,7 @@ NimRunConfiguration::NimRunConfiguration(Target *target, Core::Id id)
connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update);
update(); update();
} }
};
// NimRunConfigurationFactory // NimRunConfigurationFactory

View File

@@ -29,15 +29,7 @@
namespace Nim { namespace Nim {
class NimRunConfiguration : public ProjectExplorer::RunConfiguration class NimRunConfigurationFactory final : public ProjectExplorer::FixedRunConfigurationFactory
{
Q_OBJECT
public:
NimRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
};
class NimRunConfigurationFactory : public ProjectExplorer::FixedRunConfigurationFactory
{ {
public: public:
NimRunConfigurationFactory(); NimRunConfigurationFactory();

View File

@@ -208,6 +208,7 @@ extend_qtc_plugin(QmlDesigner
controlelement.cpp controlelement.h controlelement.cpp controlelement.h
dragtool.cpp dragtool.h dragtool.cpp dragtool.h
formeditor.qrc formeditor.qrc
formeditorannotationicon.cpp formeditorannotationicon.h
formeditorgraphicsview.cpp formeditorgraphicsview.h formeditorgraphicsview.cpp formeditorgraphicsview.h
formeditoritem.cpp formeditoritem.h formeditoritem.cpp formeditoritem.h
formeditorscene.cpp formeditorscene.h formeditorscene.cpp formeditorscene.h
@@ -538,6 +539,15 @@ extend_qtc_plugin(QmlDesigner
SOURCES colortool.cpp colortool.h SOURCES colortool.cpp colortool.h
) )
extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/annotationeditor
SOURCES annotation.cpp annotation.h
annotationcommenttab.cpp annotationcommenttab.h annotationcommenttab.ui
annotationeditordialog.cpp annotationeditordialog.h annotationeditordialog.ui
annotationeditor.cpp annotationeditor.h
annotationtool.cpp annotationtool.h
)
extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/connectioneditor SOURCES_PREFIX components/connectioneditor
SOURCES SOURCES

View File

@@ -0,0 +1,307 @@
/****************************************************************************
**
** 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 "annotation.h"
#include <QDateTime>
namespace QmlDesigner {
static const QString s_sep = " //;;// "; //separator
Comment::Comment()
: m_title(QString())
, m_author(QString())
, m_text(QString())
, m_timestamp(0)
{}
Comment::Comment(const QString &title, const QString &author, const QString &text, qint64 timestamp)
: m_title(title)
, m_author(author)
, m_text(text)
, m_timestamp(timestamp)
{}
QString Comment::title() const
{
return m_title;
}
void Comment::setTitle(const QString &title)
{
m_title = title;
}
QString Comment::author() const
{
return m_author;
}
void Comment::setAuthor(const QString &author)
{
m_author = author;
}
QString Comment::text() const
{
return m_text;
}
void Comment::setText(const QString &text)
{
m_text = text;
}
QString Comment::timestampStr() const
{
return QDateTime::fromSecsSinceEpoch(m_timestamp).toString();
}
QString Comment::timestampStr(const QString &format) const
{
return QDateTime::fromSecsSinceEpoch(m_timestamp).toString(format);
}
qint64 Comment::timestamp() const
{
return m_timestamp;
}
void Comment::setTimestamp(qint64 timestamp)
{
m_timestamp = timestamp;
}
void Comment::updateTimestamp()
{
m_timestamp = QDateTime::currentSecsSinceEpoch();
}
bool Comment::sameContent(const Comment &comment) const
{
return sameContent(*this, comment);
}
bool Comment::sameContent(const Comment &a, const Comment &b)
{
return ((a.title() == b.title())
&& (a.author() == b.author())
&& (a.text() == b.text()));
}
bool Comment::operator==(const Comment &comment) const
{
return (sameContent(comment) && (m_timestamp == comment.timestamp()));
}
bool Comment::isEmpty()
{
return sameContent(Comment());
}
QString Comment::toQString() const
{
QStringList result;
result.push_back(m_title);
result.push_back(m_author);
result.push_back(m_text);
result.push_back(QString::number(m_timestamp));
return result.join(s_sep);
}
QDebug &operator<<(QDebug &stream, const Comment &comment)
{
stream << "\"title: " << comment.m_title << "\" ";
stream << "\"author: " << comment.m_author << "\" ";
stream << "\"text: " << comment.m_text << "\" ";
stream << "\"timestamp: " << comment.m_timestamp << "\" ";
stream << "\"date/time: " << QDateTime::fromSecsSinceEpoch(comment.m_timestamp).toString() << "\" ";
return stream;
}
QDataStream &operator<<(QDataStream &stream, const Comment &comment)
{
stream << comment.m_title;
stream << comment.m_author;
stream << comment.m_text;
stream << comment.m_timestamp;
return stream;
}
QDataStream &operator>>(QDataStream &stream, Comment &comment)
{
stream >> comment.m_title;
stream >> comment.m_author;
stream >> comment.m_text;
stream >> comment.m_timestamp;
return stream;
}
//Annotation
Annotation::Annotation()
: m_comments()
{
}
QVector<Comment> Annotation::comments() const
{
return m_comments;
}
bool Annotation::hasComments() const
{
return !m_comments.isEmpty();
}
void Annotation::setComments(const QVector<Comment> &comments)
{
m_comments = comments;
}
void Annotation::removeComments()
{
m_comments.clear();
}
int Annotation::commentsSize() const
{
return m_comments.size();
}
Comment Annotation::comment(int n) const
{
if (m_comments.size() > n)
return m_comments.at(n);
else
return Comment();
}
void Annotation::addComment(const Comment &comment)
{
m_comments.push_back(comment);
}
bool Annotation::updateComment(const Comment &comment, int n)
{
bool result = false;
if ((m_comments.size() > n) && (n > 0)) {
m_comments[n] = comment;
result = true;
}
return result;
}
bool Annotation::removeComment(int n)
{
bool result = false;
if (m_comments.size() > n) {
m_comments.remove(n);
result = true;
}
return result;
}
QString Annotation::toQString() const
{
QStringList result;
result.push_back(QString::number(m_comments.size()));
for (const Comment &com : m_comments)
result.push_back(com.toQString());
return result.join(s_sep);
}
void Annotation::fromQString(const QString &str)
{
QStringList strl (str.split(s_sep, QString::SplitBehavior::KeepEmptyParts));
removeComments();
const int intro = 1;
const int comSize = 4;
if (!strl.isEmpty()) {
if (strl.size() >= intro) {
int size = strl.at(0).toInt();
if (size > 0) {
if (strl.size() == (size*comSize) + intro)
{
for (int i = 0; i < size; i++)
{
const int offset = intro + (i * comSize);
Comment com;
com.setTitle(strl.at(offset + 0));
com.setAuthor(strl.at(offset + 1));
com.setText(strl.at(offset + 2));
com.setTimestamp(strl.at(offset + 3).toLongLong());
m_comments.push_back(com);
}
}
}
}
}
}
QDebug &operator<<(QDebug &stream, const Annotation &annotation)
{
stream << "\"Annotation: " << annotation.m_comments << "\" ";
return stream;
}
QDataStream &operator<<(QDataStream &stream, const Annotation &annotation)
{
stream << annotation.m_comments;
return stream;
}
QDataStream &operator>>(QDataStream &stream, Annotation &annotation)
{
stream >> annotation.m_comments;
return stream;
}
} // QmlDesigner namespace

View File

@@ -0,0 +1,122 @@
/****************************************************************************
**
** 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 <QObject>
#include <QDebug>
#include <QDataStream>
#include "nodeinstanceglobal.h"
namespace QmlDesigner {
static const PropertyName customIdProperty = {("customId")};
static const PropertyName annotationProperty = {("annotation")};
class Comment
{
public:
Comment();
Comment(const QString &title, const QString &author = QString(), const QString &text = QString(), qint64 timestamp = 0);
~Comment() = default;
QString title() const;
void setTitle(const QString &title);
QString text() const;
void setText(const QString &text);
QString author() const;
void setAuthor(const QString &author);
QString timestampStr() const;
QString timestampStr(const QString &format) const;
qint64 timestamp() const;
void setTimestamp(qint64 timestamp);
void updateTimestamp();
bool sameContent(const Comment &comment) const; //everything is similar besides timestamp
static bool sameContent(const Comment &a, const Comment &b);
bool operator==(const Comment &comment) const; //everything is similar.
bool isEmpty();
QString toQString() const;
friend QDebug &operator<<(QDebug &stream, const Comment &comment);
friend QDataStream &operator<<(QDataStream &stream, const Comment &comment);
friend QDataStream &operator>>(QDataStream &stream, Comment &comment);
private:
QString m_title;
QString m_author;
QString m_text;
qint64 m_timestamp;
};
class Annotation
{
public:
Annotation();
~Annotation() = default;
QVector<Comment> comments() const;
bool hasComments() const;
void setComments(const QVector<Comment> &comments);
void removeComments();
int commentsSize() const;
Comment comment(int n) const;
void addComment(const Comment &comment);
bool updateComment(const Comment &comment, int n);
bool removeComment(int n);
QString toQString() const;
void fromQString(const QString &str);
friend QDebug &operator<<(QDebug &stream, const Annotation &annotation);
friend QDataStream &operator<<(QDataStream &stream, const Annotation &annotation);
friend QDataStream &operator>>(QDataStream &stream, Annotation &annotation);
private:
QVector<Comment> m_comments;
};
QDebug &operator<<(QDebug &stream, const Comment &comment);
QDebug &operator<<(QDebug &stream, const Annotation &annotation);
QDataStream &operator<<(QDataStream &stream, const Comment &comment);
QDataStream &operator>>(QDataStream &stream, Comment &comment);
QDataStream &operator<<(QDataStream &stream, const Annotation &annotation);
QDataStream &operator>>(QDataStream &stream, Annotation &annotation);
}
Q_DECLARE_METATYPE(QmlDesigner::Comment);
Q_DECLARE_METATYPE(QmlDesigner::Annotation);

View File

@@ -0,0 +1,95 @@
/****************************************************************************
**
** 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 "annotationcommenttab.h"
#include "ui_annotationcommenttab.h"
namespace QmlDesigner {
AnnotationCommentTab::AnnotationCommentTab(QWidget *parent) :
QWidget(parent),
ui(new Ui::AnnotationCommentTab)
{
ui->setupUi(this);
connect(ui->titleEdit, &QLineEdit::textEdited,
this, &AnnotationCommentTab::commentTitleChanged);
}
AnnotationCommentTab::~AnnotationCommentTab()
{
delete ui;
}
Comment AnnotationCommentTab::currentComment() const
{
Comment result;
result.setTitle(ui->titleEdit->text().trimmed());
result.setAuthor(ui->authorEdit->text().trimmed());
result.setText(ui->textEdit->toPlainText().trimmed());
if (m_comment.sameContent(result))
result.setTimestamp(m_comment.timestamp());
else
result.updateTimestamp();
return result;
}
Comment AnnotationCommentTab::originalComment() const
{
return m_comment;
}
void AnnotationCommentTab::setComment(const Comment &comment)
{
m_comment = comment;
resetUI();
}
void AnnotationCommentTab::resetUI()
{
ui->titleEdit->setText(m_comment.title());
ui->authorEdit->setText(m_comment.author());
ui->textEdit->setText(m_comment.text());
if (m_comment.timestamp() > 0)
ui->timeLabel->setText(m_comment.timestampStr());
else
ui->timeLabel->setText("");
}
void AnnotationCommentTab::resetComment()
{
m_comment = currentComment();
}
void AnnotationCommentTab::commentTitleChanged(const QString &text)
{
emit titleChanged(text, this);
}
} //namespace QmlDesigner

View File

@@ -0,0 +1,66 @@
/****************************************************************************
**
** 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 <QWidget>
#include "annotation.h"
namespace QmlDesigner {
namespace Ui {
class AnnotationCommentTab;
}
class AnnotationCommentTab : public QWidget
{
Q_OBJECT
public:
explicit AnnotationCommentTab(QWidget *parent = nullptr);
~AnnotationCommentTab();
Comment currentComment() const;
Comment originalComment() const;
void setComment(const Comment &comment);
void resetUI();
void resetComment();
signals:
void titleChanged(const QString &text, QWidget *widget);
private slots:
void commentTitleChanged(const QString &text);
private:
Ui::AnnotationCommentTab *ui;
Comment m_comment;
};
} //namespace QmlDesigner

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmlDesigner::AnnotationCommentTab</class>
<widget class="QWidget" name="QmlDesigner::AnnotationCommentTab">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>537</width>
<height>382</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="1" column="0">
<widget class="QLabel" name="titileLabel">
<property name="text">
<string>Title</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="titleEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="textLabel">
<property name="text">
<string>Text</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QTextEdit" name="textEdit">
<property name="tabChangesFocus">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="authorLabel">
<property name="text">
<string>Author</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="authorEdit"/>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="timeLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>titleEdit</tabstop>
<tabstop>authorEdit</tabstop>
<tabstop>textEdit</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,190 @@
/****************************************************************************
**
** 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 "annotationeditor.h"
#include "annotationeditordialog.h"
#include "annotation.h"
#include "qmlmodelnodeproxy.h"
#include <coreplugin/icore.h>
#include <QObject>
#include <QToolBar>
#include <QAction>
#include <QMessageBox>
namespace QmlDesigner {
AnnotationEditor::AnnotationEditor(QObject *)
{
}
AnnotationEditor::~AnnotationEditor()
{
hideWidget();
}
void AnnotationEditor::registerDeclarativeType()
{
qmlRegisterType<AnnotationEditor>("HelperWidgets", 2, 0, "AnnotationEditor");
}
void AnnotationEditor::showWidget()
{
m_dialog = new AnnotationEditorDialog(Core::ICore::dialogParent(),
modelNode().validId(),
modelNode().customId(),
modelNode().annotation());
QObject::connect(m_dialog, &AnnotationEditorDialog::accepted,
this, &AnnotationEditor::acceptedClicked);
QObject::connect(m_dialog, &AnnotationEditorDialog::rejected,
this, &AnnotationEditor::cancelClicked);
m_dialog->setAttribute(Qt::WA_DeleteOnClose);
m_dialog->open();
}
void AnnotationEditor::showWidget(int x, int y)
{
showWidget();
m_dialog->move(x, y);
}
void AnnotationEditor::hideWidget()
{
if (m_dialog)
m_dialog->close();
m_dialog = nullptr;
}
void AnnotationEditor::setModelNode(const ModelNode &modelNode)
{
m_modelNodeBackend = {};
m_modelNode = modelNode;
}
ModelNode AnnotationEditor::modelNode() const
{
return m_modelNode;
}
void AnnotationEditor::setModelNodeBackend(const QVariant &modelNodeBackend)
{
if (!modelNodeBackend.isNull() && modelNodeBackend.isValid()) {
m_modelNodeBackend = modelNodeBackend;
const auto modelNodeBackendObject = modelNodeBackend.value<QObject*>();
const auto backendObjectCasted =
qobject_cast<const QmlDesigner::QmlModelNodeProxy *>(modelNodeBackendObject);
if (backendObjectCasted)
m_modelNode = backendObjectCasted->qmlObjectNode().modelNode();
emit modelNodeBackendChanged();
}
}
QVariant AnnotationEditor::modelNodeBackend() const
{
return m_modelNodeBackend;
}
bool AnnotationEditor::hasCustomId() const
{
if (m_modelNode.isValid())
return m_modelNode.hasCustomId();
return false;
}
bool AnnotationEditor::hasAnnotation() const
{
if (m_modelNode.isValid())
return m_modelNode.hasAnnotation();
return false;
}
void AnnotationEditor::removeFullAnnotation()
{
if (!m_modelNode.isValid())
return;
QString dialogTitle = tr("Annotation");
if (!m_modelNode.customId().isNull()) {
dialogTitle = m_modelNode.customId();
}
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.removeCustomId();
m_modelNode.removeAnnotation();
}
emit customIdChanged();
emit annotationChanged();
}
void AnnotationEditor::acceptedClicked()
{
if (m_dialog) {
QString customId = m_dialog->customId();
Annotation annotation = m_dialog->annotation();
m_modelNode.setCustomId(customId);
if (annotation.comments().isEmpty())
m_modelNode.removeAnnotation();
else
m_modelNode.setAnnotation(annotation);
}
hideWidget();
emit accepted();
emit customIdChanged();
emit annotationChanged();
}
void AnnotationEditor::cancelClicked()
{
hideWidget();
emit canceled();
emit customIdChanged();
emit annotationChanged();
}
} //namespace QmlDesigner

View File

@@ -0,0 +1,89 @@
/****************************************************************************
**
** 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 <QObject>
#include <QtQml>
#include <QPointer>
#include "annotationeditordialog.h"
#include "annotation.h"
#include "modelnode.h"
namespace QmlDesigner {
class AnnotationEditor : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged)
Q_PROPERTY(bool hasCustomId READ hasCustomId NOTIFY customIdChanged)
Q_PROPERTY(bool hasAnnotation READ hasAnnotation NOTIFY annotationChanged)
public:
explicit AnnotationEditor(QObject *parent = nullptr);
~AnnotationEditor();
static void registerDeclarativeType();
Q_INVOKABLE void showWidget();
Q_INVOKABLE void showWidget(int x, int y);
Q_INVOKABLE void hideWidget();
void setModelNode(const ModelNode &modelNode);
ModelNode modelNode() const;
void setModelNodeBackend(const QVariant &modelNodeBackend);
QVariant modelNodeBackend() const;
Q_INVOKABLE bool hasCustomId() const;
Q_INVOKABLE bool hasAnnotation() const;
Q_INVOKABLE void removeFullAnnotation();
signals:
void accepted();
void canceled();
void modelNodeBackendChanged();
void customIdChanged();
void annotationChanged();
private slots:
void acceptedClicked();
void cancelClicked();
private:
QPointer<AnnotationEditorDialog> m_dialog;
ModelNode m_modelNode;
QVariant m_modelNodeBackend;
};
} //namespace QmlDesigner
QML_DECLARE_TYPE(QmlDesigner::AnnotationEditor)

View File

@@ -0,0 +1,14 @@
HEADERS += $$PWD/annotation.h
HEADERS += $$PWD/annotationtool.h
HEADERS += $$PWD/annotationcommenttab.h
HEADERS += $$PWD/annotationeditordialog.h
HEADERS += $$PWD/annotationeditor.h
SOURCES += $$PWD/annotation.cpp
SOURCES += $$PWD/annotationtool.cpp
SOURCES += $$PWD/annotationcommenttab.cpp
SOURCES += $$PWD/annotationeditordialog.cpp
SOURCES += $$PWD/annotationeditor.cpp
FORMS += $$PWD/annotationcommenttab.ui
FORMS += $$PWD/annotationeditordialog.ui

View File

@@ -0,0 +1,248 @@
/****************************************************************************
**
** 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 "annotationeditordialog.h"
#include "ui_annotationeditordialog.h"
#include "annotation.h"
#include "annotationcommenttab.h"
#include "ui_annotationcommenttab.h"
#include <QObject>
#include <QToolBar>
#include <QAction>
#include <QMessageBox>
#include "timelineicons.h" //replace timeline icons with our own?
namespace QmlDesigner {
AnnotationEditorDialog::AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId, const Annotation &annotation)
: QDialog(parent)
, ui(new Ui::AnnotationEditorDialog)
, m_customId(customId)
, m_annotation(annotation)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setWindowFlag(Qt::Tool, true);
setWindowTitle(titleString);
connect(this, &QDialog::accepted, this, &AnnotationEditorDialog::acceptedClicked);
connect(ui->tabWidget, &QTabWidget::currentChanged, this, &AnnotationEditorDialog::tabChanged);
auto *commentCornerWidget = new QToolBar;
auto *commentAddAction = new QAction(TimelineIcons::ADD_TIMELINE.icon(), tr("Add Comment")); //timeline icons?
auto *commentRemoveAction = new QAction(TimelineIcons::REMOVE_TIMELINE.icon(),
tr("Remove Comment")); //timeline icons?
connect(commentAddAction, &QAction::triggered, this, [this]() {
addComment(Comment());
});
connect(commentRemoveAction, &QAction::triggered, this, [this]() {
if (ui->tabWidget->count() == 0) //it is not even supposed to happen but lets be sure
return;
int currentIndex = ui->tabWidget->currentIndex();
QString currentTitle = ui->tabWidget->tabText(currentIndex);
QMessageBox *deleteDialog = new QMessageBox(this);
deleteDialog->setWindowTitle(currentTitle);
deleteDialog->setText(tr("Delete this comment?"));
deleteDialog->setStandardButtons(QMessageBox::Yes | QMessageBox::No);
deleteDialog->setDefaultButton(QMessageBox::Yes);
int result = deleteDialog->exec();
if (result == QMessageBox::Yes) {
removeComment(currentIndex);
}
if (ui->tabWidget->count() == 0) //lets be sure that tabWidget is never empty
addComment(Comment());
});
commentCornerWidget->addAction(commentAddAction);
commentCornerWidget->addAction(commentRemoveAction);
ui->tabWidget->setCornerWidget(commentCornerWidget, Qt::TopRightCorner);
ui->targetIdEdit->setText(targetId);
fillFields();
}
AnnotationEditorDialog::~AnnotationEditorDialog()
{
delete ui;
}
void AnnotationEditorDialog::setAnnotation(const Annotation &annotation)
{
m_annotation = annotation;
fillFields();
}
Annotation AnnotationEditorDialog::annotation() const
{
return m_annotation;
}
void AnnotationEditorDialog::setCustomId(const QString &customId)
{
m_customId = customId;
ui->customIdEdit->setText(m_customId);
}
QString AnnotationEditorDialog::customId() const
{
return m_customId;
}
void AnnotationEditorDialog::acceptedClicked()
{
m_customId = ui->customIdEdit->text();
Annotation annotation;
annotation.removeComments();
for (int i = 0; i < ui->tabWidget->count(); i++) {
AnnotationCommentTab* tab = reinterpret_cast<AnnotationCommentTab*>(ui->tabWidget->widget(i));
if (!tab)
continue;
Comment comment = tab->currentComment();
if (!comment.isEmpty())
annotation.addComment(comment);
}
m_annotation = annotation;
emit AnnotationEditorDialog::accepted();
}
void AnnotationEditorDialog::commentTitleChanged(const QString &text, QWidget *tab)
{
int tabIndex = ui->tabWidget->indexOf(tab);
if (tabIndex >= 0)
ui->tabWidget->setTabText(tabIndex, text);
if (text.isEmpty())
ui->tabWidget->setTabText(tabIndex,
(defaultTabName + " " + QString::number(tabIndex+1)));
}
void AnnotationEditorDialog::fillFields()
{
ui->customIdEdit->setText(m_customId);
setupComments();
}
void AnnotationEditorDialog::setupComments()
{
ui->tabWidget->setUpdatesEnabled(false);
deleteAllTabs();
const QVector<Comment> comments = m_annotation.comments();
if (comments.isEmpty())
addComment(Comment());
for (const Comment &comment : comments) {
addCommentTab(comment);
}
ui->tabWidget->setUpdatesEnabled(true);
}
void AnnotationEditorDialog::addComment(const Comment &comment)
{
m_annotation.addComment(comment);
addCommentTab(comment);
}
void AnnotationEditorDialog::removeComment(int index)
{
if ((m_annotation.commentsSize() > index) && (index >= 0)) {
m_annotation.removeComment(index);
removeCommentTab(index);
}
}
void AnnotationEditorDialog::addCommentTab(const Comment &comment)
{
auto commentTab = new AnnotationCommentTab();
commentTab->setComment(comment);
int tabIndex = ui->tabWidget->addTab(commentTab, comment.title());
if (comment.title().isEmpty())
ui->tabWidget->setTabText(tabIndex,
(defaultTabName + " " + QString::number(tabIndex+1)));
connect(commentTab, &AnnotationCommentTab::titleChanged,
this, &AnnotationEditorDialog::commentTitleChanged);
}
void AnnotationEditorDialog::removeCommentTab(int index)
{
if ((ui->tabWidget->count() > index) && (index >= 0)) {
ui->tabWidget->removeTab(index);
}
}
void AnnotationEditorDialog::deleteAllTabs()
{
while (ui->tabWidget->count() > 0) {
QWidget *w = ui->tabWidget->widget(0);
ui->tabWidget->removeTab(0);
delete w;
}
}
void AnnotationEditorDialog::tabChanged(int index)
{
QWidget *w = ui->tabWidget->widget(index);
AnnotationCommentTab *tab = nullptr;
if (w)
tab = reinterpret_cast<AnnotationCommentTab*>(w);
if (tab) {
//this tab order resetting doesn't work
QWidget::setTabOrder(ui->targetIdEdit, ui->customIdEdit);
QWidget::setTabOrder(ui->customIdEdit, ui->tabWidget);
QWidget::setTabOrder(ui->tabWidget, tab);
QWidget::setTabOrder(tab, ui->buttonBox);
}
}
} //namespace QmlDesigner

View File

@@ -0,0 +1,79 @@
/****************************************************************************
**
** 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 <QDialog>
#include "annotation.h"
namespace QmlDesigner {
namespace Ui {
class AnnotationEditorDialog;
}
class AnnotationEditorDialog : public QDialog
{
Q_OBJECT
public:
explicit AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId, const Annotation &annotation);
~AnnotationEditorDialog();
void setAnnotation(const Annotation &annotation);
Annotation annotation() const;
void setCustomId(const QString &customId);
QString customId() const;
signals:
void accepted();
private slots:
void acceptedClicked();
void tabChanged(int index);
void commentTitleChanged(const QString &text, QWidget *tab);
private:
void fillFields();
void setupComments();
void addComment(const Comment &comment);
void removeComment(int index);
void addCommentTab(const Comment &comment);
void removeCommentTab(int index);
void deleteAllTabs();
private:
const QString titleString = {tr("Annotation Editor")};
const QString defaultTabName = {tr("Annotation")};
Ui::AnnotationEditorDialog *ui;
QString m_customId;
Annotation m_annotation;
};
} //namespace QmlDesigner

View File

@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmlDesigner::AnnotationEditorDialog</class>
<widget class="QDialog" name="QmlDesigner::AnnotationEditorDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>700</width>
<height>487</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QHBoxLayout" name="targetIdLayout">
<item>
<widget class="QLabel" name="targetIdLabel">
<property name="text">
<string>Selected Item</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="targetIdEdit">
<property name="frame">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="customIdLayout">
<item>
<widget class="QLabel" name="customIdLabel">
<property name="text">
<string>Custom ID</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="customIdEdit"/>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<property name="movable">
<bool>true</bool>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tab 1</string>
</attribute>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Tab 2</string>
</attribute>
</widget>
</widget>
</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>
<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>
</ui>

View File

@@ -0,0 +1,258 @@
/****************************************************************************
**
** 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 "annotationtool.h"
#include "formeditorscene.h"
#include "formeditorview.h"
#include "formeditorwidget.h"
#include "itemutilfunctions.h"
#include "formeditoritem.h"
#include "nodemetainfo.h"
#include "qmlitemnode.h"
#include <qmldesignerplugin.h>
#include <abstractaction.h>
#include <designeractionmanager.h>
#include <QApplication>
#include <QGraphicsSceneMouseEvent>
#include <QAction>
#include <QDebug>
#include <QPair>
#include <QUrl>
#include <QMetaType>
namespace QmlDesigner {
class AnnotationToolAction : public AbstractAction
{
public:
AnnotationToolAction() : AbstractAction(QCoreApplication::translate("AnnotationToolAction","Edit Annotation"))
{
}
QByteArray category() const override
{
return QByteArray();
}
QByteArray menuId() const override
{
return "AnnotationTool";
}
int priority() const override
{
return CustomActionsPriority + 5;
}
Type type() const override
{
return FormEditorAction;
}
protected:
bool isVisible(const SelectionContext &selectionContext) const override
{
return selectionContext.singleNodeIsSelected();
}
bool isEnabled(const SelectionContext &selectionContext) const override
{
return isVisible(selectionContext);
}
};
AnnotationTool::AnnotationTool()
{
auto annotationToolAction = new AnnotationToolAction;
QmlDesignerPlugin::instance()->designerActionManager().addDesignerAction(annotationToolAction);
connect(annotationToolAction->action(), &QAction::triggered, [=]() {
view()->changeCurrentToolTo(this);
});
}
AnnotationTool::~AnnotationTool() = default;
void AnnotationTool::clear()
{
if (m_annotationEditor)
m_annotationEditor->deleteLater();
AbstractFormEditorTool::clear();
}
void AnnotationTool::mousePressEvent(const QList<QGraphicsItem*> &itemList,
QGraphicsSceneMouseEvent *event)
{
AbstractFormEditorTool::mousePressEvent(itemList, event);
}
void AnnotationTool::mouseMoveEvent(const QList<QGraphicsItem*> & /*itemList*/,
QGraphicsSceneMouseEvent * /*event*/)
{
}
void AnnotationTool::hoverMoveEvent(const QList<QGraphicsItem*> & /*itemList*/,
QGraphicsSceneMouseEvent * /*event*/)
{
}
void AnnotationTool::keyPressEvent(QKeyEvent * /*keyEvent*/)
{
}
void AnnotationTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/)
{
}
void AnnotationTool::dragLeaveEvent(const QList<QGraphicsItem*> &/*itemList*/, QGraphicsSceneDragDropEvent * /*event*/)
{
}
void AnnotationTool::dragMoveEvent(const QList<QGraphicsItem*> &/*itemList*/, QGraphicsSceneDragDropEvent * /*event*/)
{
}
void AnnotationTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
QGraphicsSceneMouseEvent *event)
{
AbstractFormEditorTool::mouseReleaseEvent(itemList, event);
}
void AnnotationTool::mouseDoubleClickEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneMouseEvent *event)
{
AbstractFormEditorTool::mouseDoubleClickEvent(itemList, event);
}
void AnnotationTool::itemsAboutToRemoved(const QList<FormEditorItem*> &removedItemList)
{
if (m_annotationEditor.isNull())
return;
if (removedItemList.contains(m_formEditorItem))
view()->changeToSelectionTool();
}
void AnnotationTool::selectedItemsChanged(const QList<FormEditorItem*> &itemList)
{
if (!itemList.isEmpty()) {
m_formEditorItem = itemList.constFirst();
m_oldCustomId = m_formEditorItem->qmlItemNode().modelNode().customId();
m_oldAnnotation = m_formEditorItem->qmlItemNode().modelNode().annotation();
if (m_annotationEditor.isNull()) {
m_annotationEditor = new AnnotationEditorDialog(view()->formEditorWidget()->parentWidget(),
m_formEditorItem->qmlItemNode().modelNode().displayName(),
m_oldCustomId, m_oldAnnotation);
connect(m_annotationEditor, &AnnotationEditorDialog::accepted, this, &AnnotationTool::annotationDialogAccepted);
connect(m_annotationEditor, &QDialog::rejected, this, &AnnotationTool::annotationDialogRejected);
// connect(m_colorDialog.data(), &QColorDialog::currentColorChanged, this, &ColorTool::currentColorChanged);
m_annotationEditor->exec();
}
} else {
view()->changeToSelectionTool();
}
}
void AnnotationTool::instancesCompleted(const QList<FormEditorItem*> & /*itemList*/)
{
}
void AnnotationTool::instancesParentChanged(const QList<FormEditorItem *> & /*itemList*/)
{
}
void AnnotationTool::instancePropertyChange(const QList<QPair<ModelNode, PropertyName> > & /*propertyList*/)
{
}
void AnnotationTool::formEditorItemsChanged(const QList<FormEditorItem*> & /*itemList*/)
{
}
int AnnotationTool::wantHandleItem(const ModelNode & /*modelNode*/) const
{
return 10;
}
QString AnnotationTool::name() const
{
return tr("Annotation Tool");
}
void AnnotationTool::annotationDialogAccepted()
{
if (m_annotationEditor) {
saveNewCustomId(m_annotationEditor->customId());
saveNewAnnotation(m_annotationEditor->annotation());
m_annotationEditor->close();
m_annotationEditor->deleteLater();
}
m_annotationEditor = nullptr;
view()->changeToSelectionTool();
}
void AnnotationTool::saveNewCustomId(const QString &customId)
{
if (m_formEditorItem) {
m_oldCustomId = customId;
m_formEditorItem->qmlItemNode().modelNode().setCustomId(customId);
}
}
void AnnotationTool::saveNewAnnotation(const Annotation &annotation)
{
if (m_formEditorItem) {
if (annotation.comments().isEmpty())
m_formEditorItem->qmlItemNode().modelNode().removeAnnotation();
else
m_formEditorItem->qmlItemNode().modelNode().setAnnotation(annotation);
m_oldAnnotation = annotation;
}
}
void AnnotationTool::annotationDialogRejected()
{
if (m_annotationEditor) {
m_annotationEditor->close();
m_annotationEditor->deleteLater();
}
m_annotationEditor = nullptr;
view()->changeToSelectionTool();
}
}

View File

@@ -0,0 +1,93 @@
/****************************************************************************
**
** 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 "annotation.h"
#include "annotationeditordialog.h"
#include "abstractcustomtool.h"
#include "selectionindicator.h"
#include <QHash>
#include <QPointer>
#include <QDialog>
namespace QmlDesigner {
class AnnotationTool : public QObject, public AbstractCustomTool
{
Q_OBJECT
public:
AnnotationTool();
~AnnotationTool() override;
void mousePressEvent(const QList<QGraphicsItem*> &itemList,
QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(const QList<QGraphicsItem*> &itemList,
QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
QGraphicsSceneMouseEvent *event) override;
void mouseDoubleClickEvent(const QList<QGraphicsItem*> &itemList,
QGraphicsSceneMouseEvent *event) override;
void hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
QGraphicsSceneMouseEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
void keyReleaseEvent(QKeyEvent *keyEvent) override;
void dragLeaveEvent(const QList<QGraphicsItem*> &itemList,
QGraphicsSceneDragDropEvent * event) override;
void dragMoveEvent(const QList<QGraphicsItem*> &itemList,
QGraphicsSceneDragDropEvent * event) override;
void itemsAboutToRemoved(const QList<FormEditorItem*> &itemList) override;
void selectedItemsChanged(const QList<FormEditorItem*> &itemList) override; //impl needed
void instancesCompleted(const QList<FormEditorItem*> &itemList) override;
void instancesParentChanged(const QList<FormEditorItem *> &itemList) override;
void instancePropertyChange(const QList<QPair<ModelNode, PropertyName> > &propertyList) override;
void clear() override;
void formEditorItemsChanged(const QList<FormEditorItem*> &itemList) override;
int wantHandleItem(const ModelNode &modelNode) const override;
QString name() const override;
private:
void annotationDialogAccepted();
void annotationDialogRejected();
void saveNewCustomId(const QString &customId);
void saveNewAnnotation(const Annotation &annotation);
private:
FormEditorItem *m_formEditorItem = nullptr;
QString m_oldCustomId;
Annotation m_oldAnnotation;
QPointer<AnnotationEditorDialog> m_annotationEditor;
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -36,7 +36,8 @@ SOURCES += formeditoritem.cpp \
contentnoteditableindicator.cpp \ contentnoteditableindicator.cpp \
backgroundaction.cpp \ backgroundaction.cpp \
formeditortoolbutton.cpp \ formeditortoolbutton.cpp \
option3daction.cpp option3daction.cpp \
formeditorannotationicon.cpp
HEADERS += formeditorscene.h \ HEADERS += formeditorscene.h \
formeditorwidget.h \ formeditorwidget.h \
@@ -75,6 +76,7 @@ HEADERS += formeditorscene.h \
contentnoteditableindicator.h \ contentnoteditableindicator.h \
backgroundaction.h \ backgroundaction.h \
formeditortoolbutton.h \ formeditortoolbutton.h \
option3daction.h option3daction.h \
formeditorannotationicon.h
RESOURCES += formeditor.qrc RESOURCES += formeditor.qrc

View File

@@ -6,5 +6,7 @@
<file>no_snapping@2x.png</file> <file>no_snapping@2x.png</file>
<file>snapping_and_anchoring.png</file> <file>snapping_and_anchoring.png</file>
<file>snapping_and_anchoring@2x.png</file> <file>snapping_and_anchoring@2x.png</file>
<file>annotationsIcon.png</file>
<file>annotationsIconActive.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -0,0 +1,463 @@
/****************************************************************************
**
** 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 "formeditorannotationicon.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsLinearLayout>
#include <QPainter>
#include <QAction>
#include <QMenu>
#include <QMessageBox>
#include <coreplugin/icore.h>
#include <utils/theme/theme.h>
#include <utils/stylehelper.h>
#include <annotationeditor/annotation.h>
#include <annotationeditor/annotationeditordialog.h>
#include <formeditorscene.h>
namespace QmlDesigner {
FormEditorAnnotationIcon::FormEditorAnnotationIcon(const ModelNode &modelNode, QGraphicsItem *parent)
: QGraphicsObject(parent)
, m_modelNode(modelNode)
, m_readerIsActive(false)
, m_customId(modelNode.customId())
, m_annotation(modelNode.annotation())
, m_annotationEditor(nullptr)
, m_normalIconStr(":icon/layout/annotationsIcon.png")
, m_activeIconStr(":icon/layout/annotationsIconActive.png")
, m_iconW(40)
, m_iconH(32)
{
setAcceptHoverEvents(true);
bool hasAuxData = modelNode.hasAnnotation() || modelNode.hasCustomId();
setEnabled(hasAuxData);
setVisible(hasAuxData);
FormEditorScene *scene = qobject_cast<FormEditorScene*>(parentItem()->scene());
if (scene) {
m_readerIsActive = scene->annotationVisibility();
if (m_readerIsActive) {
drawReader();
}
}
setToolTip(tr("Annotation"));
setCursor(Qt::ArrowCursor);
}
FormEditorAnnotationIcon::~FormEditorAnnotationIcon()
{
if (m_annotationEditor) {
m_annotationEditor->deleteLater();
}
}
void FormEditorAnnotationIcon::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
painter->setPen(Qt::NoPen);
if (!isEnabled())
setOpacity(0.5);
bool hasAuxData = m_modelNode.hasAnnotation() || m_modelNode.hasCustomId();
if (hasAuxData) {
FormEditorScene *scene = qobject_cast<FormEditorScene*>(parentItem()->scene());
if (scene)
m_readerIsActive = scene->annotationVisibility();
QPixmap icon( (m_readerIsActive ? m_activeIconStr : m_normalIconStr) );
painter->drawPixmap(0, 0,
static_cast<int>(m_iconW), static_cast<int>(m_iconH),
icon);
m_customId = m_modelNode.customId();
m_annotation = m_modelNode.annotation();
if (m_readerIsActive)
resetReader();
}
else {
hideReader();
}
setEnabled(hasAuxData);
setVisible(hasAuxData);
painter->restore();
}
QRectF FormEditorAnnotationIcon::boundingRect() const
{
return QRectF(0, 0, m_iconW, m_iconH);
}
qreal FormEditorAnnotationIcon::iconWidth()
{
return m_iconW;
}
qreal FormEditorAnnotationIcon::iconHeight()
{
return m_iconH;
}
bool FormEditorAnnotationIcon::isReaderActive()
{
return m_readerIsActive;
}
void FormEditorAnnotationIcon::setActive(bool readerStatus)
{
m_readerIsActive = readerStatus;
if (m_readerIsActive)
resetReader();
else
hideReader();
update();
}
void FormEditorAnnotationIcon::hoverEnterEvent(QGraphicsSceneHoverEvent * event)
{
QGraphicsItem::hoverEnterEvent(event);
event->accept();
update();
}
void FormEditorAnnotationIcon::hoverLeaveEvent(QGraphicsSceneHoverEvent * event)
{
QGraphicsItem::hoverLeaveEvent(event);
event->accept();
update();
}
void FormEditorAnnotationIcon::hoverMoveEvent(QGraphicsSceneHoverEvent * event)
{
QGraphicsItem::hoverMoveEvent(event);
}
void FormEditorAnnotationIcon::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
event->accept();
Qt::MouseButton button = event->button();
if (button == Qt::LeftButton) {
if (m_readerIsActive) {
hideReader();
m_readerIsActive = false;
} else {
drawReader();
m_readerIsActive = true;
}
}
FormEditorScene *scene = qobject_cast<FormEditorScene*>(parentItem()->scene());
if (scene)
scene->setAnnotationVisibility(m_readerIsActive);
update();
}
void FormEditorAnnotationIcon::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
event->accept();
}
void FormEditorAnnotationIcon::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
QMenu menu;
menu.addAction(tr("Edit Annotation"), [this]() {
createAnnotationEditor();
});
menu.addAction(tr("Remove Annotation"), [this]() {
removeAnnotationDialog();
});
menu.exec(event->screenPos());
event->accept();
}
void FormEditorAnnotationIcon::resetReader()
{
hideReader();
drawReader();
}
void FormEditorAnnotationIcon::drawReader()
{
const qreal width = 290;
const qreal height = 200;
const qreal offset = 5;
const QRectF titleRect(0, 0, width, 30);
const QPointF cornerPosition(m_iconW + offset, 0);
QGraphicsItem *titleBubble = createTitleBubble(titleRect, m_customId, this);
titleBubble->setPos(cornerPosition);
if (m_annotation.hasComments()) {
QList<QGraphicsItem*> comments;
QPointF commentPosition(cornerPosition.x(), 40);
QRectF commentRect(0, 0, width, height);
for (const Comment &comment : m_annotation.comments()) {
QGraphicsItem *commentBubble = createCommentBubble(commentRect, comment.title(),
comment.author(), comment.text(),
comment.timestampStr(), this);
commentBubble->setPos(commentPosition);
commentPosition += QPointF(width + offset, 0);
comments.push_back(commentBubble);
}
int currentColumn = 0;
qreal columnHeight = 0;
const qreal maxHeight = 650;
const QPointF commentsStartPosition(cornerPosition.x(), cornerPosition.y() + titleRect.height() + (offset*2));
QPointF newPos(commentsStartPosition);
for (QGraphicsItem *comment : comments) {
qreal itemHeight = comment->boundingRect().height();
if ((columnHeight + offset + itemHeight) > maxHeight) {
// have no extra space
columnHeight = 0;
++currentColumn;
newPos = commentsStartPosition + QPointF(currentColumn * (offset + width), 0);
} else {
//few normal comments, lets stack them
}
columnHeight += itemHeight + offset;
comment->setPos(newPos);
newPos += QPointF(0, itemHeight + offset);
}
}
}
void FormEditorAnnotationIcon::hideReader()
{
if (!childItems().isEmpty()) {
for (QGraphicsItem *item : childItems()) {
delete item;
}
}
}
QGraphicsItem *FormEditorAnnotationIcon::createCommentBubble(const QRectF &rect, const QString &title,
const QString &author, const QString &text,
const QString &date, QGraphicsItem *parent)
{
static QColor textColor = Utils::creatorTheme()->color(Utils::Theme::QmlDesigner_FormEditorForegroundColor);
static QColor backgroundColor = Utils::creatorTheme()->color(Utils::Theme::QmlDesigner_BackgroundColorDarker);
static QColor frameColor = Utils::creatorTheme()->color(Utils::Theme::QmlDesigner_BackgroundColor);
QFont font;
font.setBold(true);
QGraphicsRectItem *frameItem = new QGraphicsRectItem(rect, parent);
QGraphicsTextItem *titleItem = new QGraphicsTextItem(frameItem);
titleItem->setPlainText(title);
titleItem->setFont(font);
titleItem->setDefaultTextColor(textColor);
titleItem->setTextWidth(rect.width());
titleItem->update();
QGraphicsTextItem *authorItem = new QGraphicsTextItem(frameItem);
authorItem->setPlainText(tr("By: ") + author);
authorItem->setDefaultTextColor(textColor);
authorItem->setTextWidth(rect.width());
authorItem->setPos(titleItem->x(), titleItem->boundingRect().height() + titleItem->y());
authorItem->update();
QGraphicsTextItem *textItem = new QGraphicsTextItem(frameItem);
textItem->setPlainText(text);
textItem->setDefaultTextColor(textColor);
textItem->setTextWidth(rect.width());
textItem->setPos(authorItem->x(), authorItem->boundingRect().height() + authorItem->y() + 5);
textItem->update();
qreal contentRect = titleItem->boundingRect().height()
+ authorItem->boundingRect().height()
+ textItem->boundingRect().height();
if ((contentRect + 60) > rect.height()) {
frameItem->setRect(rect.x(), rect.y(), rect.width(), contentRect+60);
}
QGraphicsTextItem *dateItem = new QGraphicsTextItem(frameItem);
dateItem->setPlainText(tr("Edited: ") + date);
dateItem->setDefaultTextColor(textColor);
dateItem->setTextWidth(rect.width());
dateItem->setPos(frameItem->boundingRect().bottomLeft() + QPointF(0, -30));
dateItem->update();
QPen pen;
pen.setCosmetic(true);
pen.setWidth(2);
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::BevelJoin);
pen.setColor(frameColor);
frameItem->setPen(pen); //outline
frameItem->setBrush(backgroundColor); //back
frameItem->update();
return frameItem;
}
QGraphicsItem *FormEditorAnnotationIcon::createTitleBubble(const QRectF &rect, const QString &text, QGraphicsItem *parent)
{
static QColor textColor = Utils::creatorTheme()->color(Utils::Theme::QmlDesigner_FormEditorForegroundColor);
static QColor backgroundColor = Utils::creatorTheme()->color(Utils::Theme::QmlDesigner_BackgroundColorDarker);
static QColor frameColor = Utils::creatorTheme()->color(Utils::Theme::QmlDesigner_BackgroundColor);
QFont font;
font.setBold(true);
QGraphicsRectItem *frameItem = new QGraphicsRectItem(rect, parent);
QGraphicsTextItem *titleItem = new QGraphicsTextItem(text, frameItem);
titleItem->setDefaultTextColor(textColor);
titleItem->setFont(font);
titleItem->update();
if (titleItem->boundingRect().width() > rect.width()) {
frameItem->setRect(QRectF(rect.x(), rect.y(),
titleItem->boundingRect().width(), rect.height()));
}
QPen pen;
pen.setCosmetic(true);
pen.setWidth(2);
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::BevelJoin);
pen.setColor(frameColor);
frameItem->setPen(pen); //outline
frameItem->setBrush(backgroundColor); //back
frameItem->update();
return frameItem;
}
void FormEditorAnnotationIcon::createAnnotationEditor()
{
if (m_annotationEditor) {
m_annotationEditor->close();
m_annotationEditor->deleteLater();
m_annotationEditor = nullptr;
}
m_annotationEditor = new AnnotationEditorDialog(Core::ICore::dialogParent(),
m_modelNode.displayName(),
m_modelNode.customId(),
m_modelNode.annotation());
connect(m_annotationEditor, &AnnotationEditorDialog::accepted,
this, &FormEditorAnnotationIcon::annotationDialogAccepted);
connect(m_annotationEditor, &QDialog::rejected,
this, &FormEditorAnnotationIcon::annotationDialogRejected);
m_annotationEditor->open();
}
void FormEditorAnnotationIcon::removeAnnotationDialog()
{
QString dialogTitle = tr("Annotation");
if (!m_customId.isNull()) {
dialogTitle = m_customId;
}
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.removeCustomId();
m_modelNode.removeAnnotation();
update();
}
}
void FormEditorAnnotationIcon::annotationDialogAccepted()
{
if (m_annotationEditor) {
QString customId = m_annotationEditor->customId();
m_customId = customId;
m_modelNode.setCustomId(customId);
Annotation annotation = m_annotationEditor->annotation();
if (annotation.comments().isEmpty())
m_modelNode.removeAnnotation();
else
m_modelNode.setAnnotation(annotation);
m_annotation = annotation;
m_annotationEditor->close();
m_annotationEditor->deleteLater();
}
m_annotationEditor = nullptr;
if (m_readerIsActive)
resetReader();
}
void FormEditorAnnotationIcon::annotationDialogRejected()
{
if (m_annotationEditor) {
m_annotationEditor->close();
m_annotationEditor->deleteLater();
}
m_annotationEditor = nullptr;
}
} //QmlDesigner

View File

@@ -0,0 +1,100 @@
/****************************************************************************
**
** 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 <annotationeditor/annotation.h>
#include <QGraphicsItem>
#include <QGraphicsObject>
#include <QIcon>
#include <QObject>
#include <modelnode.h>
QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
namespace QmlDesigner {
class AnnotationEditorDialog;
class FormEditorAnnotationIcon : public QGraphicsObject
{
Q_OBJECT
public:
explicit FormEditorAnnotationIcon(const ModelNode &modelNode, QGraphicsItem *parent = nullptr);
~FormEditorAnnotationIcon() override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
QRectF boundingRect() const override;
qreal iconWidth();
qreal iconHeight();
bool isReaderActive();
void setActive(bool readerStatus);
void resetReader();
protected:
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
private:
void drawReader();
void hideReader();
QGraphicsItem *createCommentBubble(const QRectF &rect, const QString &title,
const QString &author, const QString &text,
const QString &date, QGraphicsItem *parent);
QGraphicsItem *createTitleBubble(const QRectF &rect, const QString &text, QGraphicsItem *parent);
void createAnnotationEditor();
void removeAnnotationDialog();
void annotationDialogAccepted();
void annotationDialogRejected();
private:
ModelNode m_modelNode;
bool m_readerIsActive;
QString m_customId;
Annotation m_annotation;
AnnotationEditorDialog *m_annotationEditor;
QString m_normalIconStr;
QString m_activeIconStr;
qreal m_iconW;
qreal m_iconH;
};
} //QmlDesigner

View File

@@ -49,9 +49,10 @@
namespace QmlDesigner { namespace QmlDesigner {
FormEditorScene::FormEditorScene(FormEditorWidget *view, FormEditorView *editorView) FormEditorScene::FormEditorScene(FormEditorWidget *view, FormEditorView *editorView)
: QGraphicsScene(), : QGraphicsScene()
m_editorView(editorView), , m_editorView(editorView)
m_showBoundingRects(false) , m_showBoundingRects(false)
, m_annotationVisibility(false)
{ {
setupScene(); setupScene();
view->setScene(this); view->setScene(this);
@@ -431,5 +432,15 @@ bool FormEditorScene::showBoundingRects() const
return m_showBoundingRects; return m_showBoundingRects;
} }
bool FormEditorScene::annotationVisibility() const
{
return m_annotationVisibility;
}
void FormEditorScene::setAnnotationVisibility(bool status)
{
m_annotationVisibility = status;
}
} }

View File

@@ -95,6 +95,9 @@ public:
void setShowBoundingRects(bool show); void setShowBoundingRects(bool show);
bool showBoundingRects() const; bool showBoundingRects() const;
bool annotationVisibility() const;
void setAnnotationVisibility(bool status);
protected: protected:
bool event(QEvent *event) override; bool event(QEvent *event) override;
void dropEvent(QGraphicsSceneDragDropEvent * event) override; void dropEvent(QGraphicsSceneDragDropEvent * event) override;
@@ -129,6 +132,7 @@ private:
QPointer<LayerItem> m_manipulatorLayerItem; QPointer<LayerItem> m_manipulatorLayerItem;
ModelNode m_dragNode; ModelNode m_dragNode;
bool m_showBoundingRects; bool m_showBoundingRects;
bool m_annotationVisibility;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -501,6 +501,7 @@ void FormEditorView::changeCurrentToolTo(AbstractFormEditorTool *newTool)
m_currentTool->clear(); m_currentTool->clear();
m_currentTool->setItems(scene()->itemsForQmlItemNodes(toQmlItemNodeList( m_currentTool->setItems(scene()->itemsForQmlItemNodes(toQmlItemNodeList(
selectedModelNodes()))); selectedModelNodes())));
m_currentTool->start(); m_currentTool->start();
} }
@@ -530,6 +531,10 @@ void FormEditorView::auxiliaryDataChanged(const ModelNode &node, const PropertyN
FormEditorItem *editorItem = m_scene->itemForQmlItemNode(item); FormEditorItem *editorItem = m_scene->itemForQmlItemNode(item);
if (editorItem) if (editorItem)
editorItem->update(); editorItem->update();
} else if (name == "annotation" || name == "customId") {
if (FormEditorItem *editorItem = scene()->itemForQmlItemNode(item)) {
editorItem->update();
}
} }
} }

View File

@@ -26,6 +26,8 @@
#include "selectionindicator.h" #include "selectionindicator.h"
#include <designeractionmanager.h> #include <designeractionmanager.h>
#include "annotationeditor/annotation.h"
#include <formeditorannotationicon.h>
#include <QPen> #include <QPen>
#include <QGraphicsScene> #include <QGraphicsScene>
@@ -42,6 +44,7 @@ namespace QmlDesigner {
SelectionIndicator::SelectionIndicator(LayerItem *layerItem) SelectionIndicator::SelectionIndicator(LayerItem *layerItem)
: m_layerItem(layerItem) : m_layerItem(layerItem)
, m_annotationItem(nullptr)
{ {
} }
@@ -75,6 +78,7 @@ void SelectionIndicator::clear()
} }
} }
m_labelItem.reset(nullptr); m_labelItem.reset(nullptr);
m_annotationItem = nullptr;
m_indicatorShapeHash.clear(); m_indicatorShapeHash.clear();
} }
@@ -119,6 +123,7 @@ void SelectionIndicator::setItems(const QList<FormEditorItem*> &itemList)
if (checkSingleSelection(itemList)) { if (checkSingleSelection(itemList)) {
FormEditorItem *selectedItem = itemList.constFirst(); FormEditorItem *selectedItem = itemList.constFirst();
m_labelItem = std::make_unique<QGraphicsPolygonItem>(m_layerItem.data()); m_labelItem = std::make_unique<QGraphicsPolygonItem>(m_layerItem.data());
const qreal scaleFactor = m_layerItem->viewportTransform().m11();
QGraphicsWidget *toolbar = DesignerActionManager::instance().createFormEditorToolBar(m_labelItem.get()); QGraphicsWidget *toolbar = DesignerActionManager::instance().createFormEditorToolBar(m_labelItem.get());
toolbar->setPos(1, -1); toolbar->setPos(1, -1);
@@ -129,6 +134,14 @@ void SelectionIndicator::setItems(const QList<FormEditorItem*> &itemList)
if (modelNode.hasId()) if (modelNode.hasId())
textItem->setPlainText(modelNode.id()); textItem->setPlainText(modelNode.id());
if (modelNode.hasAnnotation() || modelNode.hasCustomId()) {
m_annotationItem = new FormEditorAnnotationIcon(modelNode, m_labelItem.get());
m_annotationItem->update();
}
else {
m_annotationItem = nullptr;
}
static QColor textColor = Utils::creatorTheme()->color(Utils::Theme::QmlDesigner_FormEditorForegroundColor); static QColor textColor = Utils::creatorTheme()->color(Utils::Theme::QmlDesigner_FormEditorForegroundColor);
textItem->setDefaultTextColor(textColor); textItem->setDefaultTextColor(textColor);
@@ -139,18 +152,25 @@ void SelectionIndicator::setItems(const QList<FormEditorItem*> &itemList)
QPointF pos = labelRect.topLeft(); QPointF pos = labelRect.topLeft();
labelRect.moveTo(0, 0); labelRect.moveTo(0, 0);
m_labelItem->setPolygon(labelRect); m_labelItem->setPolygon(labelRect);
const int scaledHeight = labelHeight / m_layerItem->viewportTransform().m11(); const int scaledHeight = labelHeight / scaleFactor;
m_labelItem->setPos(pos + QPointF(0, -scaledHeight)); m_labelItem->setPos(pos + QPointF(0, -scaledHeight));
const int offset = (labelHeight - textItem->boundingRect().height()) / 2; const int offset = (labelHeight - textItem->boundingRect().height()) / 2;
textItem->setPos(QPointF(toolbar->size().width(), offset)); textItem->setPos(QPointF(toolbar->size().width(), offset));
m_labelItem->setFlag(QGraphicsItem::ItemIsSelectable, false); m_labelItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
m_labelItem->setFlag(QGraphicsItem::ItemIgnoresTransformations, true); m_labelItem->setFlag(QGraphicsItem::ItemIgnoresTransformations, true);
QPen pen; QPen pen;
pen.setCosmetic(true); pen.setCosmetic(true);
pen.setWidth(2); pen.setWidth(2);
pen.setCapStyle(Qt::RoundCap); pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::BevelJoin); pen.setJoinStyle(Qt::BevelJoin);
pen.setColor(selectionColor); pen.setColor(selectionColor);
if (m_annotationItem) {
m_annotationItem->setFlags(QGraphicsItem::ItemIgnoresTransformations);
adjustAnnotationPosition(labelPolygon.boundingRect(), m_labelItem->boundingRect(), scaleFactor);
}
m_labelItem->setPen(pen); m_labelItem->setPen(pen);
m_labelItem->setBrush(selectionColor); m_labelItem->setBrush(selectionColor);
m_labelItem->update(); m_labelItem->update();
@@ -172,8 +192,14 @@ void SelectionIndicator::updateItems(const QList<FormEditorItem*> &itemList)
QPolygonF labelPolygon = boundingRectInLayerItemSpaceForItem(selectedItem, m_layerItem.data()); QPolygonF labelPolygon = boundingRectInLayerItemSpaceForItem(selectedItem, m_layerItem.data());
QRectF labelRect = labelPolygon.boundingRect(); QRectF labelRect = labelPolygon.boundingRect();
QPointF pos = labelRect.topLeft(); QPointF pos = labelRect.topLeft();
const int scaledHeight = labelHeight / m_layerItem->viewportTransform().m11(); const qreal scaleFactor = m_layerItem->viewportTransform().m11();
const int scaledHeight = labelHeight / scaleFactor;
m_labelItem->setPos(pos + QPointF(0, -scaledHeight)); m_labelItem->setPos(pos + QPointF(0, -scaledHeight));
if (m_annotationItem) {
adjustAnnotationPosition(labelPolygon.boundingRect(), m_labelItem->boundingRect(), scaleFactor);
}
m_layerItem->update(); m_layerItem->update();
} }
} }
@@ -186,5 +212,24 @@ void SelectionIndicator::setCursor(const QCursor &cursor)
item->setCursor(cursor); item->setCursor(cursor);
} }
void SelectionIndicator::adjustAnnotationPosition(const QRectF &itemRect, const QRectF &labelRect, qreal scaleFactor)
{
if (!m_annotationItem) return;
const qreal iconW = 40 * 0.5; //*0.5 for a shift of an icon outide the item
qreal iconX = 0.0;
qreal iconY = -15.0/scaleFactor; //small offset
if (((labelRect.width() + iconW)/scaleFactor) > itemRect.width())
iconY -= labelRect.height()/scaleFactor;
if ((iconW/scaleFactor) > itemRect.width())
iconX = 0.0;
else
iconX = (itemRect.width()) - (iconW/scaleFactor);
m_annotationItem->setPos(iconX*scaleFactor, iconY*scaleFactor);
}
} }

View File

@@ -35,6 +35,8 @@
namespace QmlDesigner { namespace QmlDesigner {
class FormEditorAnnotationIcon;
class SelectionIndicator class SelectionIndicator
{ {
public: public:
@@ -50,12 +52,16 @@ public:
void updateItems(const QList<FormEditorItem*> &itemList); void updateItems(const QList<FormEditorItem*> &itemList);
void setCursor(const QCursor &cursor); void setCursor(const QCursor &cursor);
private:
void adjustAnnotationPosition(const QRectF &itemRect, const QRectF &labelRect, qreal scaleFactor);
private: private:
QHash<FormEditorItem*, QGraphicsPolygonItem *> m_indicatorShapeHash; QHash<FormEditorItem*, QGraphicsPolygonItem *> m_indicatorShapeHash;
FormEditorItem *m_selectedItem;
QPointer<LayerItem> m_layerItem; QPointer<LayerItem> m_layerItem;
QCursor m_cursor; QCursor m_cursor;
std::unique_ptr<QGraphicsPolygonItem> m_labelItem; std::unique_ptr<QGraphicsPolygonItem> m_labelItem;
FormEditorAnnotationIcon *m_annotationItem; //handled by m_labelItem
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -159,6 +159,8 @@ QVariant properDefaultAuxiliaryProperties(const QmlObjectNode &qmlObjectNode,
return 0; return 0;
else if (propertyName == "break") else if (propertyName == "break")
return 50; return 50;
else if (propertyName == "customId")
return QString();
return {}; return {};
} }
@@ -221,6 +223,8 @@ void PropertyEditorQmlBackend::setupAuxiliaryProperties(const QmlObjectNode &qml
PropertyNameList propertyNames; PropertyNameList propertyNames;
propertyNames.append("customId");
if (itemNode.isFlowTransition()) { if (itemNode.isFlowTransition()) {
propertyNames.append({"color", "width", "inOffset", "outOffset", "dash", "break"}); propertyNames.append({"color", "width", "inOffset", "outOffset", "dash", "break"});
} else if (itemNode.isFlowItem()) { } else if (itemNode.isFlowItem()) {

View File

@@ -34,6 +34,7 @@
#include "simplecolorpalettemodel.h" #include "simplecolorpalettemodel.h"
#include "bindingeditor/bindingeditor.h" #include "bindingeditor/bindingeditor.h"
#include "bindingeditor/actioneditor.h" #include "bindingeditor/actioneditor.h"
#include "annotationeditor/annotationeditor.h"
#include "qmlanchorbindingproxy.h" #include "qmlanchorbindingproxy.h"
#include "theme.h" #include "theme.h"
#include "aligndistribute.h" #include "aligndistribute.h"
@@ -63,6 +64,7 @@ void Quick2PropertyEditorView::registerQmlTypes()
Internal::QmlAnchorBindingProxy::registerDeclarativeType(); Internal::QmlAnchorBindingProxy::registerDeclarativeType();
BindingEditor::registerDeclarativeType(); BindingEditor::registerDeclarativeType();
ActionEditor::registerDeclarativeType(); ActionEditor::registerDeclarativeType();
AnnotationEditor::registerDeclarativeType();
AlignDistribute::registerDeclarativeType(); AlignDistribute::registerDeclarativeType();
Tooltip::registerDeclarativeType(); Tooltip::registerDeclarativeType();
} }

View File

@@ -28,6 +28,7 @@
#include "qmldesignercorelib_global.h" #include "qmldesignercorelib_global.h"
#include <QPointer> #include <QPointer>
#include <QList> #include <QList>
#include <QVector>
#include <QVariant> #include <QVariant>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -56,6 +57,8 @@ class NodeListProperty;
class NodeProperty; class NodeProperty;
class NodeAbstractProperty; class NodeAbstractProperty;
class ModelNode; class ModelNode;
class Comment;
class Annotation;
QMLDESIGNERCORE_EXPORT QList<Internal::InternalNodePointer> toInternalNodeList(const QList<ModelNode> &nodeList); QMLDESIGNERCORE_EXPORT QList<Internal::InternalNodePointer> toInternalNodeList(const QList<ModelNode> &nodeList);
@@ -183,6 +186,22 @@ public:
bool hasAuxiliaryData(const PropertyName &name) const; bool hasAuxiliaryData(const PropertyName &name) const;
QHash<PropertyName, QVariant> auxiliaryData() const; QHash<PropertyName, QVariant> auxiliaryData() const;
QString customId() const;
bool hasCustomId() const;
void setCustomId(const QString &str);
void removeCustomId();
QVector<Comment> comments() const;
bool hasComments() const;
void setComments(const QVector<Comment> &coms);
void addComment(const Comment &com);
bool updateComment(const Comment &com, int position);
Annotation annotation() const;
bool hasAnnotation() const;
void setAnnotation(const Annotation &annotation);
void removeAnnotation();
qint32 internalId() const; qint32 internalId() const;
void setNodeSource(const QString&); void setNodeSource(const QString&);

View File

@@ -41,6 +41,7 @@
#include "nodelistproperty.h" #include "nodelistproperty.h"
#include "nodeproperty.h" #include "nodeproperty.h"
#include <rewriterview.h> #include <rewriterview.h>
#include "annotationeditor/annotation.h"
#include <utils/algorithm.h> #include <utils/algorithm.h>
@@ -1052,6 +1053,100 @@ QHash<PropertyName, QVariant> ModelNode::auxiliaryData() const
return internalNode()->auxiliaryData(); return internalNode()->auxiliaryData();
} }
QString ModelNode::customId() const
{
QString result;
if (hasCustomId())
result = auxiliaryData(customIdProperty).value<QString>();
return result;
}
bool ModelNode::hasCustomId() const
{
return hasAuxiliaryData(customIdProperty);
}
void ModelNode::setCustomId(const QString &str)
{
setAuxiliaryData(customIdProperty, QVariant::fromValue<QString>(str));
}
void ModelNode::removeCustomId()
{
if (hasCustomId()) {
removeAuxiliaryData(customIdProperty);
}
}
QVector<Comment> ModelNode::comments() const
{
return annotation().comments();
}
bool ModelNode::hasComments() const
{
return annotation().hasComments();
}
void ModelNode::setComments(const QVector<Comment> &coms)
{
Annotation anno = annotation();
anno.setComments(coms);
setAnnotation(anno);
}
void ModelNode::addComment(const Comment &com)
{
Annotation anno = annotation();
anno.addComment(com);
setAnnotation(anno);
}
bool ModelNode::updateComment(const Comment &com, int position)
{
bool result = false;
if (hasAnnotation()) {
Annotation anno = annotation();
if (anno.updateComment(com, position)) {
setAnnotation(anno);
result = true;
}
}
return result;
}
Annotation ModelNode::annotation() const
{
Annotation result;
if (hasAnnotation())
result.fromQString(auxiliaryData(annotationProperty).value<QString>());
return result;
}
bool ModelNode::hasAnnotation() const
{
return hasAuxiliaryData(annotationProperty);
}
void ModelNode::setAnnotation(const Annotation &annotation)
{
setAuxiliaryData(annotationProperty, QVariant::fromValue<QString>(annotation.toQString()));
}
void ModelNode::removeAnnotation()
{
if (hasAnnotation()) {
removeAuxiliaryData(annotationProperty);
}
}
void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList) void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList)
{ {
model()->d->setScriptFunctions(internalNode(), scriptFunctionList); model()->d->setScriptFunctions(internalNode(), scriptFunctionList);

View File

@@ -530,6 +530,14 @@ QString RewriterView::auxiliaryDataAsQML() const
if (metaType == QMetaType::QString if (metaType == QMetaType::QString
|| metaType == QMetaType::QColor) { || metaType == QMetaType::QColor) {
strValue.replace(QStringLiteral("\\"), QStringLiteral("\\\\"));
strValue.replace(QStringLiteral("\""), QStringLiteral("\\\""));
strValue.replace(QStringLiteral("\t"), QStringLiteral("\\t"));
strValue.replace(QStringLiteral("\r"), QStringLiteral("\\r"));
strValue.replace(QStringLiteral("\n"), QStringLiteral("\\n"));
strValue.replace(QStringLiteral("*/"), QStringLiteral("*\\/"));
strValue = "\"" + strValue + "\""; strValue = "\"" + strValue + "\"";
} }

View File

@@ -37,6 +37,7 @@
#include <connectionview.h> #include <connectionview.h>
#include <sourcetool/sourcetool.h> #include <sourcetool/sourcetool.h>
#include <colortool/colortool.h> #include <colortool/colortool.h>
#include <annotationeditor/annotationtool.h>
#include <texttool/texttool.h> #include <texttool/texttool.h>
#include <timelineeditor/timelineview.h> #include <timelineeditor/timelineview.h>
#include <pathtool/pathtool.h> #include <pathtool/pathtool.h>
@@ -238,6 +239,7 @@ bool QmlDesignerPlugin::delayedInitialize()
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::SourceTool); d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::SourceTool);
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::ColorTool); d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::ColorTool);
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::AnnotationTool);
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::TextTool); d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::TextTool);
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::PathTool); d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::PathTool);

View File

@@ -29,6 +29,7 @@ include(components/timelineeditor/timelineeditor.pri)
include(components/connectioneditor/connectioneditor.pri) include(components/connectioneditor/connectioneditor.pri)
include(components/curveeditor/curveeditor.pri) include(components/curveeditor/curveeditor.pri)
include(components/bindingeditor/bindingeditor.pri) include(components/bindingeditor/bindingeditor.pri)
include(components/annotationeditor/annotationeditor.pri)
BUILD_PUPPET_IN_CREATOR_BINPATH = $$(BUILD_PUPPET_IN_CREATOR_BINPATH) BUILD_PUPPET_IN_CREATOR_BINPATH = $$(BUILD_PUPPET_IN_CREATOR_BINPATH)

View File

@@ -461,6 +461,8 @@ Project {
"formeditor/dragtool.cpp", "formeditor/dragtool.cpp",
"formeditor/dragtool.h", "formeditor/dragtool.h",
"formeditor/formeditor.qrc", "formeditor/formeditor.qrc",
"formeditor/formeditorannotationicon.cpp",
"formeditor/formeditorannotationicon.h",
"formeditor/formeditorgraphicsview.cpp", "formeditor/formeditorgraphicsview.cpp",
"formeditor/formeditorgraphicsview.h", "formeditor/formeditorgraphicsview.h",
"formeditor/formeditoritem.cpp", "formeditor/formeditoritem.cpp",
@@ -636,6 +638,18 @@ Project {
name: "extension" name: "extension"
prefix: "components/" prefix: "components/"
files: [ files: [
"annotationeditor/annotation.cpp",
"annotationeditor/annotation.h",
"annotationeditor/annotationcommenttab.cpp",
"annotationeditor/annotationcommenttab.h",
"annotationeditor/annotationcommenttab.ui",
"annotationeditor/annotationeditor.cpp",
"annotationeditor/annotationeditor.h",
"annotationeditor/annotationeditordialog.cpp",
"annotationeditor/annotationeditordialog.h",
"annotationeditor/annotationeditordialog.ui
"annotationeditor/annotationtool.cpp",
"annotationeditor/annotationtool.h",
"bindingeditor/bindingeditor.cpp", "bindingeditor/bindingeditor.cpp",
"bindingeditor/bindingeditor.h", "bindingeditor/bindingeditor.h",
"bindingeditor/actioneditor.cpp", "bindingeditor/actioneditor.cpp",