forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/master' into 4.12
Change-Id: If4508ed26484913d803cdf9d4c06831ec4e98ae7
This commit is contained in:
@@ -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
|
||||||
|
@@ -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 += &&
|
||||||
|
13
docs.pri
13
docs.pri
@@ -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)
|
||||||
|
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,27 +44,46 @@ 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);
|
||||||
|
|
||||||
auto exeAspect = rc->aspect<ExecutableAspect>();
|
public:
|
||||||
auto argumentsAspect = rc->aspect<ArgumentsAspect>();
|
explicit FullCommandLineAspect(RunConfiguration *rc)
|
||||||
|
{
|
||||||
|
setLabelText(tr("Full command line:"));
|
||||||
|
|
||||||
auto updateCommandLine = [this, rc, exeAspect, argumentsAspect] {
|
auto exeAspect = rc->aspect<ExecutableAspect>();
|
||||||
const QString usedExecutable = exeAspect->executable().toString();
|
auto argumentsAspect = rc->aspect<ArgumentsAspect>();
|
||||||
const QString args = argumentsAspect->arguments(rc->macroExpander());
|
|
||||||
setValue(QString(Constants::AppcontrollerFilepath)
|
auto updateCommandLine = [this, rc, exeAspect, argumentsAspect] {
|
||||||
+ ' ' + usedExecutable + ' ' + args);
|
const QString usedExecutable = exeAspect->executable().toString();
|
||||||
};
|
const QString args = argumentsAspect->arguments(rc->macroExpander());
|
||||||
|
setValue(QString(Constants::AppcontrollerFilepath)
|
||||||
|
+ ' ' + usedExecutable + ' ' + args);
|
||||||
|
};
|
||||||
|
|
||||||
|
connect(argumentsAspect, &ArgumentsAspect::argumentsChanged, this, updateCommandLine);
|
||||||
|
connect(exeAspect, &ExecutableAspect::changed, this, updateCommandLine);
|
||||||
|
updateCommandLine();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
connect(argumentsAspect, &ArgumentsAspect::argumentsChanged, this, updateCommandLine);
|
|
||||||
connect(exeAspect, &ExecutableAspect::changed, this, 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)
|
||||||
{
|
{
|
||||||
|
@@ -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:
|
||||||
|
@@ -37,29 +37,38 @@
|
|||||||
|
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
|
||||||
using namespace Nim;
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
NimbleRunConfiguration::NimbleRunConfiguration(ProjectExplorer::Target *target, Core::Id id)
|
namespace Nim {
|
||||||
: RunConfiguration(target, id)
|
|
||||||
|
// NimbleRunConfiguration
|
||||||
|
|
||||||
|
class NimbleRunConfiguration : public RunConfiguration
|
||||||
{
|
{
|
||||||
addAspect<LocalEnvironmentAspect>(target);
|
Q_DECLARE_TR_FUNCTIONS(Nim::NimbleRunConfiguration)
|
||||||
addAspect<ExecutableAspect>();
|
|
||||||
addAspect<ArgumentsAspect>();
|
|
||||||
addAspect<WorkingDirectoryAspect>();
|
|
||||||
addAspect<TerminalAspect>();
|
|
||||||
|
|
||||||
setUpdater([this] {
|
public:
|
||||||
BuildTargetInfo bti = buildTargetInfo();
|
NimbleRunConfiguration(Target *target, Core::Id id)
|
||||||
setDisplayName(bti.displayName);
|
: RunConfiguration(target, id)
|
||||||
setDefaultDisplayName(bti.displayName);
|
{
|
||||||
aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
|
addAspect<LocalEnvironmentAspect>(target);
|
||||||
aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(bti.workingDirectory);
|
addAspect<ExecutableAspect>();
|
||||||
});
|
addAspect<ArgumentsAspect>();
|
||||||
|
addAspect<WorkingDirectoryAspect>();
|
||||||
|
addAspect<TerminalAspect>();
|
||||||
|
|
||||||
connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update);
|
setUpdater([this] {
|
||||||
update();
|
BuildTargetInfo bti = buildTargetInfo();
|
||||||
}
|
setDisplayName(bti.displayName);
|
||||||
|
setDefaultDisplayName(bti.displayName);
|
||||||
|
aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
|
||||||
|
aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(bti.workingDirectory);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
NimbleRunConfigurationFactory::NimbleRunConfigurationFactory()
|
NimbleRunConfigurationFactory::NimbleRunConfigurationFactory()
|
||||||
: RunConfigurationFactory()
|
: RunConfigurationFactory()
|
||||||
@@ -69,22 +78,26 @@ 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
|
||||||
: RunConfiguration(target, id)
|
|
||||||
{
|
|
||||||
addAspect<ExecutableAspect>()->setExecutable(Utils::FilePath::fromString(QStandardPaths::findExecutable("nimble")));
|
|
||||||
addAspect<ArgumentsAspect>()->setArguments("test");
|
|
||||||
addAspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(project()->projectDirectory());
|
|
||||||
addAspect<TerminalAspect>();
|
|
||||||
|
|
||||||
setDisplayName(tr("Nimble Test"));
|
class NimbleTestConfiguration : public RunConfiguration
|
||||||
setDefaultDisplayName(tr("Nimble Test"));
|
{
|
||||||
}
|
Q_DECLARE_TR_FUNCTIONS(Nim::NimbleTestConfiguration)
|
||||||
|
|
||||||
|
public:
|
||||||
|
NimbleTestConfiguration(ProjectExplorer::Target *target, Core::Id id)
|
||||||
|
: RunConfiguration(target, id)
|
||||||
|
{
|
||||||
|
addAspect<ExecutableAspect>()->setExecutable(Utils::FilePath::fromString(QStandardPaths::findExecutable("nimble")));
|
||||||
|
addAspect<ArgumentsAspect>()->setArguments("test");
|
||||||
|
addAspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(project()->projectDirectory());
|
||||||
|
addAspect<TerminalAspect>();
|
||||||
|
|
||||||
|
setDisplayName(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
|
||||||
|
@@ -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
|
||||||
|
@@ -41,31 +41,37 @@ using namespace Utils;
|
|||||||
|
|
||||||
namespace Nim {
|
namespace Nim {
|
||||||
|
|
||||||
NimRunConfiguration::NimRunConfiguration(Target *target, Core::Id id)
|
class NimRunConfiguration final : public RunConfiguration
|
||||||
: RunConfiguration(target, id)
|
|
||||||
{
|
{
|
||||||
addAspect<LocalEnvironmentAspect>(target);
|
Q_DECLARE_TR_FUNCTIONS(Nim::NimRunConfiguration)
|
||||||
addAspect<ExecutableAspect>();
|
|
||||||
addAspect<ArgumentsAspect>();
|
|
||||||
addAspect<WorkingDirectoryAspect>();
|
|
||||||
addAspect<TerminalAspect>();
|
|
||||||
|
|
||||||
setDisplayName(tr("Current Build Target"));
|
public:
|
||||||
setDefaultDisplayName(tr("Current Build Target"));
|
NimRunConfiguration(Target *target, Core::Id id)
|
||||||
|
: RunConfiguration(target, id)
|
||||||
|
{
|
||||||
|
addAspect<LocalEnvironmentAspect>(target);
|
||||||
|
addAspect<ExecutableAspect>();
|
||||||
|
addAspect<ArgumentsAspect>();
|
||||||
|
addAspect<WorkingDirectoryAspect>();
|
||||||
|
addAspect<TerminalAspect>();
|
||||||
|
|
||||||
setUpdater([this] {
|
setDisplayName(tr("Current Build Target"));
|
||||||
auto buildConfiguration = qobject_cast<NimBuildConfiguration *>(activeBuildConfiguration());
|
setDefaultDisplayName(tr("Current Build Target"));
|
||||||
QTC_ASSERT(buildConfiguration, return);
|
|
||||||
const QFileInfo outFileInfo = buildConfiguration->outFilePath().toFileInfo();
|
|
||||||
aspect<ExecutableAspect>()->setExecutable(FilePath::fromString(outFileInfo.absoluteFilePath()));
|
|
||||||
const QString workingDirectory = outFileInfo.absoluteDir().absolutePath();
|
|
||||||
aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(FilePath::fromString(workingDirectory));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Connect target signals
|
setUpdater([this] {
|
||||||
connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update);
|
auto buildConfiguration = qobject_cast<NimBuildConfiguration *>(activeBuildConfiguration());
|
||||||
update();
|
QTC_ASSERT(buildConfiguration, return);
|
||||||
}
|
const QFileInfo outFileInfo = buildConfiguration->outFilePath().toFileInfo();
|
||||||
|
aspect<ExecutableAspect>()->setExecutable(FilePath::fromString(outFileInfo.absoluteFilePath()));
|
||||||
|
const QString workingDirectory = outFileInfo.absoluteDir().absolutePath();
|
||||||
|
aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(FilePath::fromString(workingDirectory));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Connect target signals
|
||||||
|
connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// NimRunConfigurationFactory
|
// NimRunConfigurationFactory
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
122
src/plugins/qmldesigner/components/annotationeditor/annotation.h
Normal file
122
src/plugins/qmldesigner/components/annotationeditor/annotation.h
Normal 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);
|
@@ -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
|
@@ -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
|
@@ -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>
|
@@ -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
|
@@ -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)
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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>
|
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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 |
@@ -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
|
||||||
|
@@ -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>
|
||||||
|
@@ -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
|
@@ -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
|
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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()) {
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
@@ -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&);
|
||||||
|
@@ -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);
|
||||||
|
@@ -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 + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
@@ -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",
|
||||||
|
Reference in New Issue
Block a user