QmlDesigner: Lock node in properties view

Task-number: QDS-14557
Change-Id: I0b9bf07fe95f6ae85b8bf81eec29c09ab0aa5531
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Karol Herda
2025-03-13 12:24:28 +01:00
parent 58662eb626
commit 82ef60ac42
8 changed files with 231 additions and 82 deletions

View File

@@ -57,8 +57,17 @@ Rectangle {
HeaderBackground{}
}
PropertyEditorToolBar {
id: toolbar
anchors.top: dockedHeaderLoader.bottom
width: parent.width
onToolBarAction: action => handleToolBarAction(action)
}
MouseArea {
anchors.fill: parent
anchors.fill: mainScrollView
onClicked: itemPane.forceActiveFocus()
}
@@ -111,7 +120,7 @@ Rectangle {
clip: true
anchors {
top: dockedHeaderLoader.bottom
top: toolbar.bottom
bottom: itemPane.bottom
left: itemPane.left
right: itemPane.right

View File

@@ -0,0 +1,32 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import HelperWidgets as HelperWidgets
import StudioTheme as StudioTheme
import PropertyToolBarAction
Rectangle {
id: root
signal toolBarAction(int action)
color: StudioTheme.Values.themeToolbarBackground
height: StudioTheme.Values.toolbarHeight
HelperWidgets.AbstractButton {
id: lockButton
anchors.right: parent.right
anchors.rightMargin: StudioTheme.Values.toolbarHorizontalMargin
anchors.verticalCenter: parent.verticalCenter
buttonIcon: lockButton.checked ? StudioTheme.Constants.lockOn : StudioTheme.Constants.lockOff
checkable: true
checked: isSelectionLocked ?? false
enabled: !(hasMultiSelection ?? false)
style: StudioTheme.Values.viewBarButtonStyle
tooltip: qsTr("Lock current node")
onClicked: root.toolBarAction(lockButton.checked ? ToolBarAction.SelectionLock : ToolBarAction.SelectionUnlock)
}
}

View File

@@ -54,6 +54,7 @@ OriginIndicator 2.0 OriginIndicator.qml
OriginSelector 2.0 OriginSelector.qml
PopupLabel 2.0 PopupLabel.qml
PropertyEditorPane 2.0 PropertyEditorPane.qml
PropertyEditorToolBar 2.0 PropertyEditorToolBar.qml
PropertyLabel 2.0 PropertyLabel.qml
PaddingSection 2.0 PaddingSection.qml
RoundedPanel 2.0 RoundedPanel.qml

View File

@@ -443,6 +443,20 @@ void PropertyEditorContextObject::setHasMultiSelection(bool b)
emit hasMultiSelectionChanged();
}
bool PropertyEditorContextObject::isSelectionLocked() const
{
return m_isSelectionLocked;
}
void PropertyEditorContextObject::setIsSelectionLocked(bool lock)
{
if (lock == m_isSelectionLocked)
return;
m_isSelectionLocked = lock;
emit isSelectionLockedChanged();
}
void PropertyEditorContextObject::setInsightEnabled(bool value)
{
if (value != m_insightEnabled) {
@@ -696,6 +710,11 @@ QPoint PropertyEditorContextObject::globalPos(const QPoint &point) const
return point;
}
void PropertyEditorContextObject::handleToolBarAction(int action)
{
emit toolBarAction(action);
}
void EasingCurveEditor::registerDeclarativeType()
{
qmlRegisterType<EasingCurveEditor>("HelperWidgets", 2, 0, "EasingCurveEditor");

View File

@@ -49,6 +49,8 @@ class PropertyEditorContextObject : public QObject
Q_PROPERTY(bool hasMultiSelection READ hasMultiSelection WRITE setHasMultiSelection NOTIFY
hasMultiSelectionChanged)
Q_PROPERTY(bool isSelectionLocked READ isSelectionLocked WRITE setIsSelectionLocked NOTIFY isSelectionLockedChanged)
Q_PROPERTY(bool insightEnabled MEMBER m_insightEnabled NOTIFY insightEnabledChanged)
Q_PROPERTY(QStringList insightCategories MEMBER m_insightCategories NOTIFY insightCategoriesChanged)
@@ -100,6 +102,11 @@ public:
Q_INVOKABLE QRect screenRect() const;
Q_INVOKABLE QPoint globalPos(const QPoint &point) const;
Q_INVOKABLE void handleToolBarAction(int action);
enum ToolBarAction { SelectionLock, SelectionUnlock };
Q_ENUM(ToolBarAction)
QString activeDragSuffix() const;
void setActiveDragSuffix(const QString &suffix);
@@ -140,6 +147,9 @@ public:
void setSelectedNode(const ModelNode &node);
void setIsSelectionLocked(bool lock);
bool isSelectionLocked() const;
signals:
void specificsUrlChanged();
void specificQmlDataChanged();
@@ -161,9 +171,11 @@ signals:
void hasMaterialLibraryChanged();
void has3DModelSelectionChanged();
void isQt6ProjectChanged();
void isSelectionLockedChanged();
void insightEnabledChanged();
void insightCategoriesChanged();
void toolBarAction(int action);
public slots:
@@ -223,6 +235,7 @@ private:
QString m_activeDragSuffix;
bool m_hasMultiSelection = false;
bool m_isSelectionLocked = false;
bool m_insightEnabled = false;
QStringList m_insightCategories;

View File

@@ -66,7 +66,6 @@ PropertyEditorView::PropertyEditorView(AsynchronousImageCache &imageCache,
: AbstractView(externalDependencies)
, m_imageCache(imageCache)
, m_updateShortcut(nullptr)
, m_timerId(0)
, m_stackedWidget(new PropertyEditorWidget())
, m_qmlBackEndForCurrentType(nullptr)
, m_propertyComponentGenerator{PropertyEditorQmlBackend::propertyEditorResourcesPath(), model()}
@@ -117,15 +116,15 @@ void PropertyEditorView::changeValue(const QString &name)
PropertyEditorValue *value = m_qmlBackEndForCurrentType->propertyValueForName(QString::fromUtf8(propertyName));
const QString newId = value->value().toString();
if (newId == m_selectedNode.id())
if (newId == activeNode().id())
return;
if (QmlDesigner::ModelNode::isValidId(newId) && !hasId(newId)) {
executeInTransaction("PropertyEditorView::changeId",
[this, newId] { m_selectedNode.setIdWithRefactoring(newId); });
[&] { activeNode().setIdWithRefactoring(newId); });
} else {
m_locked = true;
value->setValue(m_selectedNode.id());
value->setValue(activeNode().id());
m_locked = false;
QString errMsg = QmlDesigner::ModelNode::getIdValidityErrorMessage(newId);
if (!errMsg.isEmpty())
@@ -148,7 +147,7 @@ void PropertyEditorView::changeValue(const QString &name)
return;
}
const NodeMetaInfo metaInfo = QmlObjectNode(m_selectedNode).modelNode().metaInfo();
const NodeMetaInfo metaInfo = QmlObjectNode(activeNode()).modelNode().metaInfo();
QVariant castedValue;
@@ -230,7 +229,7 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
PropertyName underscoreName(name);
underscoreName.replace('.', '_');
QmlObjectNode qmlObjectNode{m_selectedNode};
QmlObjectNode qmlObjectNode{activeNode()};
PropertyEditorValue *value = m_qmlBackEndForCurrentType->propertyValueForName(
QString::fromUtf8(underscoreName));
@@ -259,7 +258,7 @@ void PropertyEditorView::exportPropertyAsAlias(const QString &name)
return;
executeInTransaction("PropertyEditorView::exportPropertyAsAlias",
[this, name]() { generateAliasForProperty(m_selectedNode, name); });
[&]() { generateAliasForProperty(activeNode(), name); });
}
void PropertyEditorView::removeAliasExport(const QString &name)
@@ -274,7 +273,7 @@ void PropertyEditorView::removeAliasExport(const QString &name)
return;
executeInTransaction("PropertyEditorView::exportPropertyAsAlias",
[this, name]() { removeAliasForProperty(m_selectedNode, name); });
[&]() { removeAliasForProperty(activeNode(), name); });
}
bool PropertyEditorView::locked() const
@@ -431,19 +430,13 @@ void PropertyEditorView::resetView()
if (model() == nullptr)
return;
setSelelectedModelNode();
setActiveNodeToSelection();
m_locked = true;
if (debug)
qDebug() << "________________ RELOADING PROPERTY EDITOR QML _______________________";
if (m_timerId)
killTimer(m_timerId);
if (m_selectedNode.isValid() && model() != m_selectedNode.model())
m_selectedNode = ModelNode();
setupQmlBackend();
if (m_qmlBackEndForCurrentType) {
@@ -453,12 +446,20 @@ void PropertyEditorView::resetView()
m_locked = false;
if (m_timerId)
m_timerId = 0;
updateSize();
}
void PropertyEditorView::setIsSelectionLocked(bool locked)
{
m_isSelectionLocked = locked;
if (m_qmlBackEndForCurrentType)
m_qmlBackEndForCurrentType->contextObject()->setIsSelectionLocked(locked);
// Show current selection on unlock
if (!m_locked && !m_isSelectionLocked)
select();
}
namespace {
#ifndef QDS_USE_PROJECTSTORAGE
@@ -597,13 +598,27 @@ void setupWidget(PropertyEditorQmlBackend *currentQmlBackend,
} // namespace
void PropertyEditorView::handleToolBarAction(int action)
{
switch (action) {
case PropertyEditorContextObject::SelectionLock: {
setIsSelectionLocked(true);
break;
}
case PropertyEditorContextObject::SelectionUnlock: {
setIsSelectionLocked(false);
break;
}
}
}
void PropertyEditorView::setupQmlBackend()
{
#ifdef QDS_USE_PROJECTSTORAGE
const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(m_selectedNode);
const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(activeNode());
auto selfAndPrototypes = commonAncestor.selfAndPrototypes();
bool isEditableComponent = m_selectedNode.isComponent()
&& !QmlItemNode(m_selectedNode).isEffectItem();
bool isEditableComponent = activeNode().isComponent()
&& !QmlItemNode(activeNode()).isEffectItem();
auto specificQmlData = m_propertyEditorComponentGenerator.create(selfAndPrototypes,
isEditableComponent);
auto [panePath, specificsPath] = findPaneAndSpecificsPath(selfAndPrototypes, model()->pathCache());
@@ -614,7 +629,7 @@ void PropertyEditorView::setupQmlBackend()
m_stackedWidget,
this);
setupCurrentQmlBackend(currentQmlBackend,
m_selectedNode,
activeNode(),
QUrl::fromLocalFile(QString{specificsPath}),
currentStateNode(),
this,
@@ -626,7 +641,7 @@ void PropertyEditorView::setupQmlBackend()
setupInsight(rootModelNode(), currentQmlBackend);
#else
const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(m_selectedNode);
const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(activeNode());
// qmlFileUrl is panel url. and specifics is its metainfo
const auto [qmlFileUrl, specificsClassMetaInfo] = PropertyEditorQmlBackend::getQmlUrlForMetaInfo(
@@ -638,7 +653,7 @@ void PropertyEditorView::setupQmlBackend()
if (qmlFileUrl.toLocalFile().endsWith("TexturePane.qml"))
qmlSpecificsFile = QUrl{};
QString specificQmlData = getSpecificQmlData(commonAncestor, m_selectedNode, diffClassMetaInfo);
QString specificQmlData = getSpecificQmlData(commonAncestor, activeNode(), diffClassMetaInfo);
PropertyEditorQmlBackend *currentQmlBackend = getQmlBackend(m_qmlBackendHash,
qmlFileUrl,
@@ -647,7 +662,7 @@ void PropertyEditorView::setupQmlBackend()
this);
setupCurrentQmlBackend(currentQmlBackend,
m_selectedNode,
activeNode(),
qmlSpecificsFile,
currentStateNode(),
this,
@@ -660,7 +675,9 @@ void PropertyEditorView::setupQmlBackend()
setupInsight(rootModelNode(), currentQmlBackend);
#endif // QDS_USE_PROJECTSTORAGE
m_dynamicPropertiesModel->setSelectedNode(m_selectedNode);
m_dynamicPropertiesModel->setSelectedNode(activeNode());
QObject::connect(m_qmlBackEndForCurrentType->contextObject(), SIGNAL(toolBarAction(int)), this, SLOT(handleToolBarAction(int)));
}
void PropertyEditorView::commitVariantValueToModel(PropertyNameView propertyName, const QVariant &value)
@@ -669,7 +686,8 @@ void PropertyEditorView::commitVariantValueToModel(PropertyNameView propertyName
try {
RewriterTransaction transaction = beginRewriterTransaction("PropertyEditorView::commitVariantValueToMode");
for (const ModelNode &node : m_selectedNode.view()->selectedModelNodes()) {
const QList<ModelNode> nodes = currentNodes();
for (const ModelNode &node : nodes) {
if (auto qmlObjectNode = QmlObjectNode(node))
qmlObjectNode.setVariantProperty(propertyName, value);
}
@@ -689,14 +707,13 @@ void PropertyEditorView::commitAuxValueToModel(PropertyNameView propertyName, co
name.chop(5);
try {
const QList<ModelNode> nodes = currentNodes();
if (value.isValid()) {
for (const ModelNode &node : m_selectedNode.view()->selectedModelNodes()) {
for (const ModelNode &node : nodes)
node.setAuxiliaryData(AuxiliaryDataType::Document, name, value);
}
} else {
for (const ModelNode &node : m_selectedNode.view()->selectedModelNodes()) {
for (const ModelNode &node : nodes)
node.removeAuxiliaryData(AuxiliaryDataType::Document, name);
}
}
}
catch (const Exception &e) {
@@ -711,7 +728,8 @@ void PropertyEditorView::removePropertyFromModel(PropertyNameView propertyName)
try {
RewriterTransaction transaction = beginRewriterTransaction("PropertyEditorView::removePropertyFromModel");
for (const ModelNode &node : m_selectedNode.view()->selectedModelNodes()) {
const QList<ModelNode> nodes = currentNodes();
for (const ModelNode &node : nodes) {
if (QmlObjectNode::isValidQmlObjectNode(node))
QmlObjectNode(node).removeProperty(propertyName);
}
@@ -727,19 +745,62 @@ void PropertyEditorView::removePropertyFromModel(PropertyNameView propertyName)
bool PropertyEditorView::noValidSelection() const
{
QTC_ASSERT(m_qmlBackEndForCurrentType, return true);
return !QmlObjectNode::isValidQmlObjectNode(m_selectedNode);
return !QmlObjectNode::isValidQmlObjectNode(activeNode());
}
ModelNode PropertyEditorView::activeNode() const
{
return m_activeNode;
}
void PropertyEditorView::setActiveNode(const ModelNode &node)
{
m_activeNode = node;
}
QList<ModelNode> PropertyEditorView::currentNodes() const
{
if (m_isSelectionLocked)
return {m_activeNode};
return selectedModelNodes();
}
void PropertyEditorView::selectedNodesChanged(const QList<ModelNode> &,
const QList<ModelNode> &)
{
if (m_isSelectionLocked)
return;
select();
}
bool PropertyEditorView::isNodeOrChildSelected(const ModelNode &node) const
{
if (activeNode().isValid() && node.isValid()) {
const ModelNodes &nodeList = node.allSubModelNodesAndThisNode();
return nodeList.contains(activeNode());
}
return false;
}
void PropertyEditorView::resetSelectionLocked()
{
if (m_isSelectionLocked)
setIsSelectionLocked(false);
}
void PropertyEditorView::resetIfNodeIsRemoved(const ModelNode &removedNode)
{
if (isNodeOrChildSelected(removedNode)) {
resetSelectionLocked();
select();
}
}
void PropertyEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
{
if (m_selectedNode.isValid() && removedNode.isValid() && m_selectedNode == removedNode)
select();
resetIfNodeIsRemoved(removedNode);
const ModelNodes &allRemovedNodes = removedNode.allSubModelNodesAndThisNode();
@@ -795,10 +856,10 @@ void PropertyEditorView::propertiesRemoved(const QList<AbstractProperty> &proper
ModelNode node(property.parentModelNode());
if (node.isRootNode() && !m_selectedNode.isRootNode())
m_qmlBackEndForCurrentType->contextObject()->setHasAliasExport(QmlObjectNode(m_selectedNode).isAliasExported());
if (node.isRootNode() && !activeNode().isRootNode())
m_qmlBackEndForCurrentType->contextObject()->setHasAliasExport(QmlObjectNode(activeNode()).isAliasExported());
if (node == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == node) {
if (node == activeNode() || QmlObjectNode(activeNode()).propertyChangeForCurrentState() == node) {
m_locked = true;
changed = true;
@@ -813,41 +874,41 @@ void PropertyEditorView::propertiesRemoved(const QList<AbstractProperty> &proper
if (value) {
value->resetValue();
m_qmlBackEndForCurrentType
->setValue(m_selectedNode,
->setValue(activeNode(),
propertyName,
QmlObjectNode(m_selectedNode).instanceValue(propertyName));
QmlObjectNode(activeNode()).instanceValue(propertyName));
}
m_locked = false;
if (propertyIsAttachedLayoutProperty(propertyName)) {
m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(m_selectedNode,
m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(activeNode(),
propertyName);
if (propertyName == "Layout.margins") {
m_qmlBackEndForCurrentType
->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.topMargin");
->setValueforLayoutAttachedProperties(activeNode(), "Layout.topMargin");
m_qmlBackEndForCurrentType
->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.bottomMargin");
->setValueforLayoutAttachedProperties(activeNode(), "Layout.bottomMargin");
m_qmlBackEndForCurrentType
->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.leftMargin");
->setValueforLayoutAttachedProperties(activeNode(), "Layout.leftMargin");
m_qmlBackEndForCurrentType
->setValueforLayoutAttachedProperties(m_selectedNode, "Layout.rightMargin");
->setValueforLayoutAttachedProperties(activeNode(), "Layout.rightMargin");
}
}
if (propertyIsAttachedInsightProperty(propertyName)) {
m_qmlBackEndForCurrentType->setValueforInsightAttachedProperties(m_selectedNode,
m_qmlBackEndForCurrentType->setValueforInsightAttachedProperties(activeNode(),
propertyName);
}
if ("width" == propertyName || "height" == propertyName) {
const QmlItemNode qmlItemNode = m_selectedNode;
const QmlItemNode qmlItemNode = activeNode();
if (qmlItemNode.isInLayout())
resetPuppet();
}
if (propertyName.contains("anchor"))
m_qmlBackEndForCurrentType->backendAnchorBinding().invalidate(m_selectedNode);
m_qmlBackEndForCurrentType->backendAnchorBinding().invalidate(activeNode());
dynamicPropertiesModel()->dispatchPropertyChanges(property);
}
@@ -871,8 +932,8 @@ void PropertyEditorView::variantPropertiesChanged(const QList<VariantProperty>&
bool changed = false;
bool selectedNodeIsMaterial = m_selectedNode.metaInfo().isQtQuick3DMaterial();
bool selectedNodeHasBindingProperties = !m_selectedNode.bindingProperties().isEmpty();
bool selectedNodeIsMaterial = activeNode().metaInfo().isQtQuick3DMaterial();
bool selectedNodeHasBindingProperties = !activeNode().bindingProperties().isEmpty();
for (const VariantProperty &property : propertyList) {
m_qmlBackEndForCurrentType->handleVariantPropertyChangedInModelNodeProxy(property);
@@ -880,20 +941,20 @@ void PropertyEditorView::variantPropertiesChanged(const QList<VariantProperty>&
ModelNode node(property.parentModelNode());
if (propertyIsAttachedLayoutProperty(property.name()))
m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(m_selectedNode,
m_qmlBackEndForCurrentType->setValueforLayoutAttachedProperties(activeNode(),
property.name());
if (propertyIsAttachedInsightProperty(property.name()))
m_qmlBackEndForCurrentType->setValueforInsightAttachedProperties(m_selectedNode,
m_qmlBackEndForCurrentType->setValueforInsightAttachedProperties(activeNode(),
property.name());
if (node == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == node) {
if (node == activeNode() || QmlObjectNode(activeNode()).propertyChangeForCurrentState() == node) {
if (property.isDynamic())
m_dynamicPropertiesModel->updateItem(property);
if ( QmlObjectNode(m_selectedNode).modelNode().property(property.name()).isBindingProperty())
setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name()));
if ( QmlObjectNode(activeNode()).modelNode().property(property.name()).isBindingProperty())
setValue(activeNode(), property.name(), QmlObjectNode(activeNode()).instanceValue(property.name()));
else
setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).modelValue(property.name()));
setValue(activeNode(), property.name(), QmlObjectNode(activeNode()).modelValue(property.name()));
changed = true;
}
@@ -933,16 +994,16 @@ void PropertyEditorView::bindingPropertiesChanged(const QList<BindingProperty> &
ModelNode node(property.parentModelNode());
if (property.isAliasExport())
m_qmlBackEndForCurrentType->contextObject()->setHasAliasExport(QmlObjectNode(m_selectedNode).isAliasExported());
m_qmlBackEndForCurrentType->contextObject()->setHasAliasExport(QmlObjectNode(activeNode()).isAliasExported());
if (node == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == node) {
if (node == activeNode() || QmlObjectNode(activeNode()).propertyChangeForCurrentState() == node) {
if (property.isDynamic())
m_dynamicPropertiesModel->updateItem(property);
if (property.name().contains("anchor"))
m_qmlBackEndForCurrentType->backendAnchorBinding().invalidate(m_selectedNode);
m_qmlBackEndForCurrentType->backendAnchorBinding().invalidate(activeNode());
m_locked = true;
QString exp = QmlObjectNode(m_selectedNode).bindingProperty(property.name()).expression();
QString exp = QmlObjectNode(activeNode()).bindingProperty(property.name()).expression();
m_qmlBackEndForCurrentType->setExpression(property.name(), exp);
m_locked = false;
changed = true;
@@ -966,7 +1027,7 @@ void PropertyEditorView::auxiliaryDataChanged(const ModelNode &node,
QScopeGuard rootGuard([this, node, key, &saved] {
if (node.isRootNode()) {
if (!saved)
m_qmlBackEndForCurrentType->setValueforAuxiliaryProperties(m_selectedNode, key);
m_qmlBackEndForCurrentType->setValueforAuxiliaryProperties(activeNode(), key);
m_qmlBackEndForCurrentType->handleAuxiliaryDataChanges(node, key);
}
});
@@ -974,7 +1035,7 @@ void PropertyEditorView::auxiliaryDataChanged(const ModelNode &node,
if (!node.isSelected())
return;
m_qmlBackEndForCurrentType->setValueforAuxiliaryProperties(m_selectedNode, key);
m_qmlBackEndForCurrentType->setValueforAuxiliaryProperties(activeNode(), key);
saved = true;
if (key == insightEnabledProperty)
@@ -990,10 +1051,10 @@ void PropertyEditorView::instanceInformationsChanged(const QMultiHash<ModelNode,
return;
m_locked = true;
QList<InformationName> informationNameList = informationChangedHash.values(m_selectedNode);
QList<InformationName> informationNameList = informationChangedHash.values(activeNode());
if (informationNameList.contains(Anchor)
|| informationNameList.contains(HasAnchor))
m_qmlBackEndForCurrentType->backendAnchorBinding().setup(QmlItemNode(m_selectedNode));
m_qmlBackEndForCurrentType->backendAnchorBinding().setup(QmlItemNode(activeNode()));
m_locked = false;
}
@@ -1002,7 +1063,7 @@ void PropertyEditorView::nodeIdChanged(const ModelNode &node, const QString &new
if (noValidSelection())
return;
if (!QmlObjectNode(m_selectedNode).isValid())
if (!QmlObjectNode(activeNode()).isValid())
return;
m_dynamicPropertiesModel->reset();
@@ -1013,7 +1074,7 @@ void PropertyEditorView::nodeIdChanged(const ModelNode &node, const QString &new
else if (oldId == Constants::MATERIAL_LIB_ID)
m_qmlBackEndForCurrentType->contextObject()->setHasMaterialLibrary(false);
if (node == m_selectedNode)
if (node == activeNode())
setValue(node, "id", newId);
if (node.metaInfo().isQtQuick3DTexture())
m_qmlBackEndForCurrentType->refreshBackendModel();
@@ -1028,11 +1089,11 @@ void PropertyEditorView::select()
resetView();
}
void PropertyEditorView::setSelelectedModelNode()
void PropertyEditorView::setActiveNodeToSelection()
{
const auto selectedNodeList = selectedModelNodes();
const auto selectedNodeList = currentNodes();
m_selectedNode = ModelNode();
setActiveNode(ModelNode());
if (selectedNodeList.isEmpty())
return;
@@ -1040,7 +1101,7 @@ void PropertyEditorView::setSelelectedModelNode()
const ModelNode node = selectedNodeList.constFirst();
if (QmlObjectNode(node).isValid())
m_selectedNode = node;
setActiveNode(node);
}
bool PropertyEditorView::hasWidget() const
@@ -1068,7 +1129,7 @@ void PropertyEditorView::currentStateChanged(const ModelNode &node)
void PropertyEditorView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &propertyList)
{
if (!m_selectedNode.isValid())
if (!activeNode().isValid())
return;
QTC_ASSERT(m_qmlBackEndForCurrentType, return );
@@ -1084,7 +1145,7 @@ void PropertyEditorView::instancePropertyChanged(const QList<QPair<ModelNode, Pr
m_qmlBackEndForCurrentType->handleInstancePropertyChangedInModelNodeProxy(modelNode,
propertyName);
if (qmlObjectNode.isValid() && modelNode == m_selectedNode
if (qmlObjectNode.isValid() && modelNode == activeNode()
&& qmlObjectNode.currentState().isValid()) {
const AbstractProperty property = modelNode.property(propertyName);
if (!modelNode.hasProperty(propertyName) || property.isBindingProperty())
@@ -1110,7 +1171,7 @@ void PropertyEditorView::rootNodeTypeChanged(const QString &/*type*/, int /*majo
void PropertyEditorView::nodeTypeChanged(const ModelNode &node, const TypeName &, int, int)
{
if (node == m_selectedNode)
if (node == activeNode())
resetView();
}
@@ -1119,8 +1180,8 @@ void PropertyEditorView::nodeReparented(const ModelNode &node,
const NodeAbstractProperty & /*oldPropertyParent*/,
AbstractView::PropertyChangeFlags /*propertyChange*/)
{
if (node == m_selectedNode)
m_qmlBackEndForCurrentType->backendAnchorBinding().setup(QmlItemNode(m_selectedNode));
if (node == activeNode())
m_qmlBackEndForCurrentType->backendAnchorBinding().setup(QmlItemNode(activeNode()));
const ModelNodes &allNodes = node.allSubModelNodesAndThisNode();
if (Utils::contains(allNodes, model()->qtQuick3DTextureMetaInfo(), &ModelNode::metaInfo))
@@ -1147,7 +1208,7 @@ void PropertyEditorView::modelNodePreviewPixmapChanged(const ModelNode &node,
const QPixmap &pixmap,
const QByteArray &requestId)
{
if (node != m_selectedNode)
if (node != activeNode())
return;
if (m_qmlBackEndForCurrentType)
@@ -1156,7 +1217,7 @@ void PropertyEditorView::modelNodePreviewPixmapChanged(const ModelNode &node,
void PropertyEditorView::highlightTextureProperties(bool highlight)
{
NodeMetaInfo metaInfo = m_selectedNode.metaInfo();
NodeMetaInfo metaInfo = activeNode().metaInfo();
QTC_ASSERT(metaInfo.isValid(), return);
DesignerPropertyMap &propMap = m_qmlBackEndForCurrentType->backendValuesPropertyMap();

View File

@@ -107,6 +107,9 @@ public:
static void removeAliasForProperty(const ModelNode &modelNode,
const QString &propertyName);
public slots:
void handleToolBarAction(int action);
protected:
void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value);
bool eventFilter(QObject *obj, QEvent *event) override;
@@ -116,7 +119,7 @@ private: //functions
void updateSize();
void select();
void setSelelectedModelNode();
void setActiveNodeToSelection();
void delayedResetView();
void setupQmlBackend();
@@ -128,13 +131,22 @@ private: //functions
bool noValidSelection() const;
void highlightTextureProperties(bool highlight = true);
ModelNode activeNode() const;
void setActiveNode(const ModelNode &node);
QList<ModelNode> currentNodes() const;
void resetSelectionLocked();
void setIsSelectionLocked(bool locked);
bool isNodeOrChildSelected(const ModelNode &node) const;
void resetIfNodeIsRemoved(const ModelNode &removedNode);
static PropertyEditorView *instance();
private: //variables
AsynchronousImageCache &m_imageCache;
ModelNode m_selectedNode;
ModelNode m_activeNode;
QShortcut *m_updateShortcut;
int m_timerId;
PropertyEditorWidget* m_stackedWidget;
QString m_qmlDir;
QHash<QString, PropertyEditorQmlBackend *> m_qmlBackendHash;
@@ -143,6 +155,7 @@ private: //variables
PropertyEditorComponentGenerator m_propertyEditorComponentGenerator{m_propertyComponentGenerator};
bool m_locked;
bool m_textureAboutToBeRemoved = false;
bool m_isSelectionLocked = false;
DynamicPropertiesModel *m_dynamicPropertiesModel = nullptr;
friend class PropertyEditorDynamicPropertiesProxyModel;

View File

@@ -87,6 +87,7 @@ void Quick2PropertyEditorView::registerQmlTypes()
QUrl regExpUrl = QUrl::fromLocalFile(resourcePath + "/RegExpValidator.qml");
qmlRegisterType(regExpUrl, "HelperWidgets", 2, 0, "RegExpValidator");
qmlRegisterUncreatableType<PropertyEditorContextObject>("PropertyToolBarAction", 2, 0, "ToolBarAction", "Enum type");
}
}