QmlDesigner: Add qt insight infrastructure

* Add InsightSection for property editor
* Add functions in property editor qml backend, context object and view
* Add InsightTracker in text to model merger
* Add auxiliary data properties

Task-number: QDS-7489
Task-number: QDS-7833
Task-number: QDS-8073
Change-Id: I3fbec3d387f815d71640b512e67829076b600d11
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Henning Gruendl
2022-11-11 15:49:16 +01:00
committed by Henning Gründl
parent 740a65571f
commit d9054d1f10
11 changed files with 219 additions and 12 deletions

View File

@@ -15,6 +15,10 @@ PropertyEditorPane {
showState: true
}
InsightSection {
visible: insightEnabled
}
DynamicPropertiesSection {
propertiesModel: SelectionDynamicPropertiesModel {}
visible: !hasMultiSelection

View File

@@ -0,0 +1,88 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0 WITH Qt-GPL-exception-1.0
import QtQuick
import HelperWidgets 2.0
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
Section {
id: root
caption: qsTr("Analytics")
anchors.left: parent.left
anchors.right: parent.right
property string defaultItem: qsTr("[None]")
function addDefaultItem(arr)
{
var copy = arr.slice()
copy.unshift(root.defaultItem)
return copy
}
SectionLayout {
PropertyLabel { text: qsTr("Category") }
SecondColumnLayout {
Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth }
StudioControls.ComboBox {
id: comboBox
property var backendValue: backendValues.InsightCategory_category
property var valueFromBackend: comboBox.backendValue === undefined ? 0 : comboBox.backendValue.value
onValueFromBackendChanged: comboBox.invalidate()
onModelChanged: comboBox.invalidate()
actionIndicatorVisible: false
implicitWidth: StudioTheme.Values.singleControlColumnWidth
width: implicitWidth
model: root.addDefaultItem(insightCategories)
editable: false
onCompressedActivated: function(index, reason) {
if (comboBox.backendValue === undefined)
return
verifyInsightImport()
if (index === 0)
comboBox.backendValue.resetValue()
else
comboBox.backendValue.value = comboBox.currentText
}
Connections {
target: modelNodeBackend
function onSelectionToBeChanged() {
comboBox.popup.close()
}
}
function invalidate() {
var index = comboBox.find(comboBox.valueFromBackend)
if (index < 0) {
if (comboBox.valueFromBackend === "") {
comboBox.currentIndex = 0
comboBox.labelColor = StudioTheme.Values.themeTextColor
} else {
comboBox.currentIndex = index
comboBox.editText = comboBox.valueFromBackend
comboBox.labelColor = StudioTheme.Values.themeError
}
} else {
if (index !== comboBox.currentIndex)
comboBox.currentIndex = index
comboBox.labelColor = StudioTheme.Values.themeTextColor
}
}
Component.onCompleted: comboBox.invalidate()
}
ExpandingSpacer {}
}
}
}

View File

@@ -42,6 +42,7 @@ IconButton 2.0 IconButton.qml
IconLabel 2.0 IconLabel.qml
ImagePreviewTooltipArea 2.0 ImagePreviewTooltipArea.qml
ImageSection 2.0 ImageSection.qml
InsightSection 2.0 InsightSection.qml
ItemFilterComboBox 2.0 ItemFilterComboBox.qml
Label 2.0 Label.qml
LineEdit 2.0 LineEdit.qml

View File

@@ -57,7 +57,7 @@ TextInput {
myControl.focus = false
} else {
myControl.popup.open()
myControl.forceActiveFocus()
//myControl.forceActiveFocus()
}
} else {
textInput.forceActiveFocus()

View File

@@ -424,6 +424,20 @@ void PropertyEditorContextObject::setHasMultiSelection(bool b)
emit hasMultiSelectionChanged();
}
void PropertyEditorContextObject::setInsightEnabled(bool value)
{
if (value != m_insightEnabled) {
m_insightEnabled = value;
emit insightEnabledChanged();
}
}
void PropertyEditorContextObject::setInsightCategories(const QStringList &categories)
{
m_insightCategories = categories;
emit insightCategoriesChanged();
}
void PropertyEditorContextObject::setSpecificsUrl(const QUrl &newSpecificsUrl)
{
if (newSpecificsUrl == m_specificsUrl)
@@ -581,6 +595,14 @@ bool PropertyEditorContextObject::isBlocked(const QString &propName) const
return false;
}
void PropertyEditorContextObject::verifyInsightImport()
{
Import import = Import::createLibraryImport("QtInsightTracker", "1.0");
if (!m_model->hasImport(import))
m_model->changeImports({import}, {});
}
void EasingCurveEditor::registerDeclarativeType()
{
qmlRegisterType<EasingCurveEditor>("HelperWidgets", 2, 0, "EasingCurveEditor");

View File

@@ -49,6 +49,9 @@ class PropertyEditorContextObject : public QObject
Q_PROPERTY(bool hasMultiSelection READ hasMultiSelection WRITE setHasMultiSelection NOTIFY
hasMultiSelectionChanged)
Q_PROPERTY(bool insightEnabled MEMBER m_insightEnabled NOTIFY insightEnabledChanged)
Q_PROPERTY(QStringList insightCategories MEMBER m_insightCategories NOTIFY insightCategoriesChanged)
public:
PropertyEditorContextObject(QObject *parent = nullptr);
@@ -87,6 +90,8 @@ public:
Q_INVOKABLE bool isBlocked(const QString &propName) const;
Q_INVOKABLE void verifyInsightImport();
QString activeDragSuffix() const;
void setActiveDragSuffix(const QString &suffix);
@@ -111,6 +116,9 @@ public:
void setHasMultiSelection(bool);
void setInsightEnabled(bool value);
void setInsightCategories(const QStringList &categories);
signals:
void specificsUrlChanged();
void specificQmlDataChanged();
@@ -129,6 +137,9 @@ signals:
void activeDragSuffixChanged();
void hasMultiSelectionChanged();
void insightEnabledChanged();
void insightCategoriesChanged();
public slots:
void setSpecificsUrl(const QUrl &newSpecificsUrl);
@@ -180,6 +191,9 @@ private:
QString m_activeDragSuffix;
bool m_hasMultiSelection = false;
bool m_insightEnabled = false;
QStringList m_insightCategories;
};
class EasingCurveEditor : public QObject

View File

@@ -171,6 +171,17 @@ QVariant properDefaultLayoutAttachedProperties(const QmlObjectNode &qmlObjectNod
return QVariant();
}
QVariant properDefaultInsightAttachedProperties(const QmlObjectNode &qmlObjectNode,
const PropertyName &propertyName)
{
const QVariant value = qmlObjectNode.modelValue("InsightCategory." + propertyName);
if (value.isValid())
return value;
return QString();
}
} // namespace
void PropertyEditorQmlBackend::setupLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode, PropertyEditorView *propertyEditor)
@@ -188,6 +199,16 @@ void PropertyEditorQmlBackend::setupLayoutAttachedProperties(const QmlObjectNode
}
}
void PropertyEditorQmlBackend::setupInsightAttachedProperties(const QmlObjectNode &qmlObjectNode,
PropertyEditorView *propertyEditor)
{
const PropertyName propertyName = "category";
createPropertyEditorValue(qmlObjectNode,
"InsightCategory." + propertyName,
properDefaultInsightAttachedProperties(qmlObjectNode, propertyName),
propertyEditor);
}
void PropertyEditorQmlBackend::setupAuxiliaryProperties(const QmlObjectNode &qmlObjectNode,
PropertyEditorView *propertyEditor)
{
@@ -262,9 +283,9 @@ void PropertyEditorQmlBackend::setupAuxiliaryProperties(const QmlObjectNode &qml
}
void PropertyEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qmlObjectNode,
const PropertyName &name,
const QVariant &value,
PropertyEditorView *propertyEditor)
const PropertyName &name,
const QVariant &value,
PropertyEditorView *propertyEditor)
{
PropertyName propertyName(name);
propertyName.replace('.', '_');
@@ -397,6 +418,7 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
propertyEditor);
}
setupLayoutAttachedProperties(qmlObjectNode, propertyEditor);
setupInsightAttachedProperties(qmlObjectNode, propertyEditor);
setupAuxiliaryProperties(qmlObjectNode, propertyEditor);
// model node
@@ -888,6 +910,14 @@ void PropertyEditorQmlBackend::setValueforLayoutAttachedProperties(const QmlObje
}
}
void PropertyEditorQmlBackend::setValueforInsightAttachedProperties(const QmlObjectNode &qmlObjectNode,
const PropertyName &name)
{
PropertyName propertyName = name;
propertyName.replace("InsightCategory.", "");
setValue(qmlObjectNode, name, properDefaultInsightAttachedProperties(qmlObjectNode, propertyName));
}
void PropertyEditorQmlBackend::setValueforAuxiliaryProperties(const QmlObjectNode &qmlObjectNode,
AuxiliaryDataKeyView key)
{

View File

@@ -57,10 +57,16 @@ public:
void emitSelectionToBeChanged();
void emitSelectionChanged();
void setValueforLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode, const PropertyName &name);
void setValueforLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode,
const PropertyName &name);
void setValueforInsightAttachedProperties(const QmlObjectNode &qmlObjectNode,
const PropertyName &name);
void setValueforAuxiliaryProperties(const QmlObjectNode &qmlObjectNode, AuxiliaryDataKeyView key);
void setupLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode, PropertyEditorView *propertyEditor);
void setupLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode,
PropertyEditorView *propertyEditor);
void setupInsightAttachedProperties(const QmlObjectNode &qmlObjectNode,
PropertyEditorView *propertyEditor);
void setupAuxiliaryProperties(const QmlObjectNode &qmlObjectNode, PropertyEditorView *propertyEditor);
static NodeMetaInfo findCommonAncestor(const ModelNode &node);

View File

@@ -7,9 +7,10 @@
#include "propertyeditortransaction.h"
#include "propertyeditorvalue.h"
#include <auxiliarydataproperties.h>
#include <nodemetainfo.h>
#include <qmldesignerconstants.h>
#include <qmltimeline.h>
#include <nodemetainfo.h>
#include <invalididexception.h>
#include <rewritingexception.h>
@@ -48,6 +49,11 @@ static bool propertyIsAttachedLayoutProperty(const PropertyName &propertyName)
return propertyName.contains("Layout.");
}
static bool propertyIsAttachedInsightProperty(const PropertyName &propertyName)
{
return propertyName.contains("InsightCategory.");
}
PropertyEditorView::PropertyEditorView(AsynchronousImageCache &imageCache,
ExternalDependenciesInterface &externalDependencies)
: AbstractView(externalDependencies)
@@ -164,7 +170,8 @@ void PropertyEditorView::changeValue(const QString &name)
if (auto property = metaInfo.property(propertyName)) {
castedValue = property.castedValue(value->value());
} else if (propertyIsAttachedLayoutProperty(propertyName)) {
} else if (propertyIsAttachedLayoutProperty(propertyName)
|| propertyIsAttachedInsightProperty(propertyName)) {
castedValue = value->value();
} else {
qWarning() << "PropertyEditor:" << propertyName << "cannot be casted (metainfo)";
@@ -500,6 +507,13 @@ void PropertyEditorView::setupQmlBackend()
m_qmlBackEndForCurrentType = currentQmlBackend;
if (rootModelNode().hasAuxiliaryData(insightEnabledProperty))
m_qmlBackEndForCurrentType->contextObject()->setInsightEnabled(
rootModelNode().auxiliaryData(insightEnabledProperty)->toBool());
if (rootModelNode().hasAuxiliaryData(insightCategoriesProperty))
m_qmlBackEndForCurrentType->contextObject()->setInsightCategories(
rootModelNode().auxiliaryData(insightCategoriesProperty)->toStringList());
}
void PropertyEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value)
@@ -641,6 +655,11 @@ void PropertyEditorView::propertiesRemoved(const QList<AbstractProperty>& proper
}
}
if (propertyIsAttachedInsightProperty(property.name())) {
m_qmlBackEndForCurrentType->setValueforInsightAttachedProperties(m_selectedNode,
property.name());
}
if ("width" == property.name() || "height" == property.name()) {
const QmlItemNode qmlItemNode = m_selectedNode;
if (qmlItemNode.isInLayout())
@@ -662,7 +681,12 @@ void PropertyEditorView::variantPropertiesChanged(const QList<VariantProperty>&
ModelNode node(property.parentModelNode());
if (propertyIsAttachedLayoutProperty(property.name()))
m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(m_selectedNode, property.name());
m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(m_selectedNode,
property.name());
if (propertyIsAttachedInsightProperty(property.name()))
m_qmlBackEndForCurrentType->setValueforInsightAttachedProperties(m_selectedNode,
property.name());
if (node == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == node) {
if ( QmlObjectNode(m_selectedNode).modelNode().property(property.name()).isBindingProperty())
@@ -701,9 +725,8 @@ void PropertyEditorView::bindingPropertiesChanged(const QList<BindingProperty>&
void PropertyEditorView::auxiliaryDataChanged(const ModelNode &node,
[[maybe_unused]] AuxiliaryDataKeyView key,
const QVariant &)
const QVariant &data)
{
if (noValidSelection())
return;
@@ -711,6 +734,12 @@ void PropertyEditorView::auxiliaryDataChanged(const ModelNode &node,
return;
m_qmlBackEndForCurrentType->setValueforAuxiliaryProperties(m_selectedNode, key);
if (key == insightEnabledProperty)
m_qmlBackEndForCurrentType->contextObject()->setInsightEnabled(data.toBool());
if (key == insightCategoriesProperty)
m_qmlBackEndForCurrentType->contextObject()->setInsightCategories(data.toStringList());
}
void PropertyEditorView::instanceInformationsChanged(const QMultiHash<ModelNode, InformationName> &informationChangedHash)
@@ -747,6 +776,12 @@ void PropertyEditorView::select()
m_qmlBackEndForCurrentType->emitSelectionToBeChanged();
delayedResetView();
auto nodes = selectedModelNodes();
for (const auto &n : nodes) {
n.metaInfo().isFileComponent();
}
}
void PropertyEditorView::setSelelectedModelNode()

View File

@@ -81,6 +81,12 @@ inline constexpr AuxiliaryDataKeyDefaultValue areaFillColorProperty{AuxiliaryDat
inline constexpr AuxiliaryDataKeyDefaultValue fillColorProperty{AuxiliaryDataType::Document,
"fillColor",
QColor{0, 0, 0, 0}};
inline constexpr AuxiliaryDataKeyDefaultValue insightEnabledProperty{AuxiliaryDataType::Temporary,
"insightEnabled",
false};
inline constexpr AuxiliaryDataKeyDefaultValue insightCategoriesProperty{AuxiliaryDataType::Temporary,
"insightCategories",
{}};
inline constexpr AuxiliaryDataKeyView uuidProperty{AuxiliaryDataType::Document, "uuid"};
inline constexpr AuxiliaryDataKeyView active3dSceneProperty{AuxiliaryDataType::Temporary,
"active3dScene"};

View File

@@ -54,7 +54,8 @@ namespace {
bool isSupportedAttachedProperties(const QString &propertyName)
{
return propertyName.startsWith(QLatin1String("Layout."));
return propertyName.startsWith(QLatin1String("Layout."))
|| propertyName.startsWith(QLatin1String("InsightCategory."));
}
QStringList supportedVersionsList()