From c019860809ea6de728c88c9e6aef65c2320e06bc Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Wed, 28 Oct 2020 09:32:44 +0100 Subject: [PATCH] QmlDesigner: Update the Stack (z) context menu * Rename arrange menu and items * Remove the "Reset z property" item * Add reverse item and functionality * Fix some related typos and formatting Task-number: QDS-2938 Change-Id: I0e706aefdaed99b28faae4b307146847a54a24ed Reviewed-by: Thomas Hartmann --- .../componentcore/componentcore_constants.h | 15 +++-- .../componentcore/designeractionmanager.cpp | 56 ++++++++++--------- .../componentcore/modelnodeoperations.cpp | 23 +++++--- .../componentcore/modelnodeoperations.h | 1 + .../designercore/include/nodelistproperty.h | 3 + .../designercore/model/nodelistproperty.cpp | 42 +++++++++++++- 6 files changed, 99 insertions(+), 41 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h index 6186575e43c..7de6c4fe64a 100644 --- a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h +++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h @@ -34,7 +34,7 @@ namespace ComponentCoreConstants { const char rootCategory[] = ""; const char selectionCategory[] = "Selection"; -const char stackCategory[] = "Stack (z)"; +const char arrangeCategory[] = "Arrange"; const char qmlPreviewCategory[] = "QmlPreview"; const char editCategory[] = "Edit"; const char anchorsCategory[] = "Anchors"; @@ -52,6 +52,7 @@ const char toBackCommandId[] = "ToBack"; const char raiseCommandId[] = "Raise"; const char lowerCommandId[] = "Lower"; const char resetZCommandId[] = "ResetZ"; +const char reverseCommandId[] = "Reverse"; const char resetSizeCommandId[] = "ResetSize"; const char resetPositionCommandId[] = "ResetPosition"; const char visiblityCommandId[] = "ToggleVisiblity"; @@ -90,7 +91,7 @@ const char fitSelectionToScreenCommandId[] = "FitSelectionToScreen"; const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection"); const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect"); const char selectEffectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select Effect"); -const char stackCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Stack (z)"); +const char arrangeCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Arrange"); const char editCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit"); const char anchorsCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Anchors"); const char positionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Position"); @@ -105,11 +106,11 @@ const char copySelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMen const char pasteSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Paste"); const char deleteSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Delete Selection"); -const char toFrontDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "To Front"); -const char toBackDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "To Back"); +const char toFrontDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Bring to Front"); +const char toBackDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Send to Back"); -const char raiseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Raise"); -const char lowerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Lower"); +const char raiseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Bring Forward"); +const char lowerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Send Backward"); const char undoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Undo"); const char redoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Redo"); @@ -129,6 +130,8 @@ const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set const char resetZDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset z Property"); +const char reverseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reverse"); + const char anchorsFillDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fill"); const char anchorsResetDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset"); diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index ea34b091cd4..f7953e2fbe6 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -594,6 +594,11 @@ bool selectionHasSameParentAndInBaseState(const SelectionContext &context) return selectionHasSameParent(context) && inBaseState(context); } +bool multiSelectionAndHasSameParent(const SelectionContext &context) +{ + return multiSelection(context) && selectionHasSameParent(context); +} + bool isNotInLayout(const SelectionContext &context) { if (selectionNotEmpty(context)) { @@ -914,8 +919,8 @@ void DesignerActionManager::createDefaultDesignerActions() prioritySelectionCategory)); addDesignerAction(new ActionGroup( - stackCategoryDisplayName, - stackCategory, + arrangeCategoryDisplayName, + arrangeCategory, priorityStackCategory, &selectionNotEmpty)); @@ -923,28 +928,19 @@ void DesignerActionManager::createDefaultDesignerActions() toFrontCommandId, toFrontDisplayName, {}, - stackCategory, + arrangeCategory, QKeySequence(), 200, &toFront, &singleSelection)); addDesignerAction(new ModelNodeContextMenuAction( - toBackCommandId, - toBackDisplayName, - {}, - stackCategory, + raiseCommandId, + raiseDisplayName, + Utils::Icon({{":/qmldesigner/icon/designeractions/images/raise.png", Utils::Theme::IconsBaseColor}}).icon(), + arrangeCategory, QKeySequence(), 180, - &toBack, - &singleSelection)); - - addDesignerAction(new ModelNodeContextMenuAction( - raiseCommandId, raiseDisplayName, - Utils::Icon({{":/qmldesigner/icon/designeractions/images/raise.png", Utils::Theme::IconsBaseColor}}).icon(), - stackCategory, - QKeySequence(), - 160, &raise, &raiseAvailable)); @@ -952,23 +948,31 @@ void DesignerActionManager::createDefaultDesignerActions() lowerCommandId, lowerDisplayName, Utils::Icon({{":/qmldesigner/icon/designeractions/images/lower.png", Utils::Theme::IconsBaseColor}}).icon(), - stackCategory, + arrangeCategory, QKeySequence(), - 140, + 160, &lower, &lowerAvailable)); - addDesignerAction(new SeperatorDesignerAction(stackCategory, 120)); + addDesignerAction(new ModelNodeContextMenuAction( + toBackCommandId, + toBackDisplayName, + {}, + arrangeCategory, + QKeySequence(), + 140, + &toBack, + &singleSelection)); addDesignerAction(new ModelNodeContextMenuAction( - resetZCommandId, - resetZDisplayName, + reverseCommandId, + reverseDisplayName, {}, - stackCategory, + arrangeCategory, QKeySequence(), 100, - &resetZ, - &selectionNotEmptyAndHasZProperty)); + &reverse, + &multiSelectionAndHasSameParent)); addDesignerAction(new ActionGroup(editCategoryDisplayName, editCategory, priorityEditCategory, &selectionNotEmpty)); @@ -979,7 +983,9 @@ void DesignerActionManager::createDefaultDesignerActions() resetPositionDisplayName, Utils::Icon({{":/utils/images/pan.png", Utils::Theme::IconsBaseColor}, {":/utils/images/iconoverlay_reset.png", Utils::Theme::IconsStopToolBarColor}}).icon(), - resetPositionTooltip, editCategory, QKeySequence("Ctrl+d"), + resetPositionTooltip, + editCategory, + QKeySequence("Ctrl+d"), 200, &resetPosition, &selectionNotEmptyAndHasXorYProperty)); diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index f76542d3789..7bda65bf1aa 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -206,9 +206,9 @@ void toBack(const SelectionContext &selectionState) } } -enum OderAction {RaiseItem, LowerItem}; +enum OrderAction {RaiseItem, LowerItem}; -void changeOrder(const SelectionContext &selectionState, OderAction orderAction) +void changeOrder(const SelectionContext &selectionState, OrderAction orderAction) { if (!selectionState.view()) return; @@ -221,13 +221,12 @@ void changeOrder(const SelectionContext &selectionState, OderAction orderAction) if (!modelNode.parentProperty().isNodeListProperty()) return; - selectionState.view()->executeInTransaction("DesignerActionManager|raise",[orderAction, selectionState, modelNode](){ + selectionState.view()->executeInTransaction("DesignerActionManager|changeOrder", [orderAction, selectionState, modelNode]() { ModelNode modelNode = selectionState.currentSingleSelectedNode(); NodeListProperty parentProperty = modelNode.parentProperty().toNodeListProperty(); const int index = parentProperty.indexOf(modelNode); if (orderAction == RaiseItem) { - if (index < parentProperty.count() - 1) parentProperty.slide(index, index + 1); } else if (orderAction == LowerItem) { @@ -244,7 +243,6 @@ void raise(const SelectionContext &selectionState) void lower(const SelectionContext &selectionState) { - changeOrder(selectionState, LowerItem); } @@ -344,8 +342,8 @@ void resetZ(const SelectionContext &selectionState) if (!selectionState.view()) return; - selectionState.view()->executeInTransaction("DesignerActionManager|resetZ",[selectionState](){ - foreach (ModelNode node, selectionState.selectedModelNodes()) { + selectionState.view()->executeInTransaction("DesignerActionManager|resetZ", [selectionState](){ + for (ModelNode node : selectionState.selectedModelNodes()) { QmlItemNode itemNode(node); if (itemNode.isValid()) itemNode.removeProperty("z"); @@ -353,6 +351,16 @@ void resetZ(const SelectionContext &selectionState) }); } +void reverse(const SelectionContext &selectionState) +{ + if (!selectionState.view()) + return; + + selectionState.view()->executeInTransaction("DesignerActionManager|reverse", [selectionState](){ + NodeListProperty::reverseModelNodes(selectionState.selectedModelNodes()); + }); +} + static inline void backupPropertyAndRemove(const ModelNode &node, const PropertyName &propertyName) { if (node.hasVariantProperty(propertyName)) { @@ -366,7 +374,6 @@ static inline void backupPropertyAndRemove(const ModelNode &node, const Property } } - static inline void restoreProperty(const ModelNode &node, const PropertyName &propertyName) { if (node.hasAuxiliaryData(auxDataString + propertyName)) diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index d22e673c801..aa43933224d 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -52,6 +52,7 @@ void resetPosition(const SelectionContext &selectionState); void goIntoComponentOperation(const SelectionContext &selectionState); void setId(const SelectionContext &selectionState); void resetZ(const SelectionContext &selectionState); +void reverse(const SelectionContext &selectionState); void anchorsFill(const SelectionContext &selectionState); void anchorsReset(const SelectionContext &selectionState); void layoutRowPositioner(const SelectionContext &selectionState); diff --git a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h index dc1967efec0..b10a5a45fd9 100644 --- a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h +++ b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h @@ -51,9 +51,12 @@ public: const QList toModelNodeList() const; const QList toQmlObjectNodeList() const; void slide(int, int) const; + void swap(int, int) const; void reparentHere(const ModelNode &modelNode); ModelNode at(int index) const; + static void reverseModelNodes(const QList &nodes); + protected: NodeListProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view); NodeListProperty(const Internal::InternalNodeListPropertyPointer &internalNodeListProperty, Model* model, AbstractView *view); diff --git a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp index 84864e5e518..8271bad362b 100644 --- a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp @@ -32,7 +32,7 @@ #include "model_p.h" #include - +#include namespace QmlDesigner { @@ -95,12 +95,30 @@ void NodeListProperty::slide(int from, int to) const Internal::WriteLocker locker(model()); if (!isValid()) throw InvalidPropertyException(__LINE__, __FUNCTION__, __FILE__, ""); - if (to > count() - 1) + if (to < 0 || to > count() - 1 || from < 0 || from > count() - 1) throw InvalidPropertyException(__LINE__, __FUNCTION__, __FILE__, ""); privateModel()->changeNodeOrder(internalNode(), name(), from, to); } +void NodeListProperty::swap(int from, int to) const +{ + if (from == to) + return; + + // Prerequisite a < b + int a = from; + int b = to; + + if (a > b) { + a = to; + b = from; + } + + slide(b, a); + slide(a + 1, b); +} + void NodeListProperty::reparentHere(const ModelNode &modelNode) { NodeAbstractProperty::reparentHere(modelNode, true); @@ -119,4 +137,24 @@ ModelNode NodeListProperty::at(int index) const return ModelNode(); } +void NodeListProperty::reverseModelNodes(const QList &nodes) +{ + ModelNode firstNode = nodes.first(); + if (!firstNode.isValid()) + return; + + NodeListProperty parentProperty = firstNode.parentProperty().toNodeListProperty(); + std::vector selectedNodeIndices; + + for (ModelNode modelNode : nodes) + selectedNodeIndices.push_back(parentProperty.indexOf(modelNode)); + + std::sort(selectedNodeIndices.begin(), selectedNodeIndices.end()); + + int mid = std::ceil(selectedNodeIndices.size() / 2); + + for (int i = 0; i != mid; ++i) + parentProperty.swap(selectedNodeIndices[i], selectedNodeIndices[selectedNodeIndices.size() - 1 - i]); +} + } // namespace QmlDesigner