summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hartmann <Thomas.Hartmann@digia.com>2012-12-12 11:31:24 +0100
committerThomas Hartmann <Thomas.Hartmann@digia.com>2012-12-20 17:03:45 +0100
commit6376b2bb463754e02900e54111a99463edc6a68b (patch)
treef684ff6e637a7b4cb1a16903eca1fec3c2604895
parent9bfe944731408d5f67046fe4b215f4d4220d4322 (diff)
downloadqt-creator-6376b2bb463754e02900e54111a99463edc6a68b.tar.gz
QmlDesigner.ContextMenu: refactoring
Instead of a hardcoded context menu we now have a DesignerActionManager that can be extended by AbstractDesignerAction. Change-Id: Ia0c5860e5fffea78fa89b74bda881076e53c059a Reviewed-by: Marco Bubke <marco.bubke@digia.com>
-rw-r--r--src/plugins/qmldesigner/components/componentcore/abstractdesigneraction.h67
-rw-r--r--src/plugins/qmldesigner/components/componentcore/componentcore.pri10
-rw-r--r--src/plugins/qmldesigner/components/componentcore/componentcore_constants.h104
-rw-r--r--src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp408
-rw-r--r--src/plugins/qmldesigner/components/componentcore/designeractionmanager.h66
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp947
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.h82
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.cpp266
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h345
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp602
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h70
-rw-r--r--src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp59
-rw-r--r--src/plugins/qmldesigner/components/componentcore/selectioncontext.h99
-rw-r--r--src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp6
14 files changed, 2158 insertions, 973 deletions
diff --git a/src/plugins/qmldesigner/components/componentcore/abstractdesigneraction.h b/src/plugins/qmldesigner/components/componentcore/abstractdesigneraction.h
new file mode 100644
index 0000000000..2b14355cb5
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/abstractdesigneraction.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef ABSTRACTDESIGNERACTION_H
+#define ABSTRACTDESIGNERACTION_H
+
+#include "componentcore_constants.h"
+#include "selectioncontext.h"
+
+namespace QmlDesigner {
+
+class AbstractDesignerAction
+{
+public:
+ enum Type {
+ Menu,
+ Action
+ };
+
+ enum Priorities {
+ HighestPriority = ComponentCoreConstants::priorityFirst,
+ CustomActionsPriority = ComponentCoreConstants::priorityCustomActions,
+ RefactoringActionsPriority = ComponentCoreConstants::priorityRefactoring,
+ LowestPriority = ComponentCoreConstants::priorityLast
+ };
+
+ virtual QAction *action() const = 0;
+ virtual QString category() const = 0;
+ virtual QString menuId() const = 0;
+ virtual int priority() const = 0;
+ virtual Type type() const = 0;
+ virtual void setCurrentContext(const SelectionContext &selectionState) = 0;
+
+protected:
+ virtual bool isVisible(const SelectionContext &selectionState) const = 0;
+ virtual bool isEnabled(const SelectionContext &selectionState) const = 0;
+};
+
+} //QmlDesigner
+
+#endif //ABSTRACTDESIGNERACTION_H
diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore.pri b/src/plugins/qmldesigner/components/componentcore/componentcore.pri
index 9035a629d7..271a585736 100644
--- a/src/plugins/qmldesigner/components/componentcore/componentcore.pri
+++ b/src/plugins/qmldesigner/components/componentcore/componentcore.pri
@@ -1,5 +1,15 @@
VPATH += $$PWD
INCLUDEPATH += $$PWD
SOURCES += modelnodecontextmenu.cpp
+SOURCES += modelnodecontextmenu_helper.cpp
+SOURCES += selectioncontext.cpp
+SOURCES += designeractionmanager.cpp
+SOURCES += modelnodeoperations.cpp
HEADERS += modelnodecontextmenu.h
+HEADERS += modelnodecontextmenu_helper.h
+HEADERS += selectioncontext.h
+HEADERS += componentcore_constants.h
+HEADERS += designeractionmanager.h
+HEADERS += modelnodeoperations.h
+HEADERS += abstractdesigneraction.h
diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h
new file mode 100644
index 0000000000..7db98802bc
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef COMPONENTCORE_CONSTANTS_H
+#define COMPONENTCORE_CONSTANTS_H
+
+namespace QmlDesigner {
+
+namespace ComponentCoreConstants {
+
+const char rootCategory[] = "";
+
+const char selectionCategory[] = "Selection";
+const char stackCategory[] = "Stack (z)";
+const char editCategory[] = "Edit";
+const char anchorsCategory[] = "Anchors";
+const char layoutCategory[] = "Layout";
+
+const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection");
+const char stackCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Stack (z)");
+const char editCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit");
+const char anchorsCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Anchors");
+const char layoutCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout");
+
+const char selectParentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select parent: %1");
+const char selectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1");
+const char deSelectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "DeSelect: ");
+
+const char cutSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Cut");
+const char copySelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Copy");
+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 raiseDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Raise");
+const char lowerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Lower");
+
+const char undoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Undo");
+const char redoDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Redo");
+
+const char visibilityDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Visibility");
+
+const char resetSizeDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset size");
+const char resetPositionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset position");
+
+const char goIntoComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Go into Component");
+
+const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Id");
+
+const char resetZDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset z property");
+
+const char anchorsFillDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fill");
+const char anchorsResetDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset");
+
+const char layoutColumnDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout in Column");
+const char layoutRowDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout in Row");
+const char layoutGridDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout in Grid");
+const char layoutFlowDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout in Flow");
+
+const int priorityFirst = 220;
+const int prioritySelectionCategory = 200;
+const int priorityStackCategory = 180;
+const int priorityEditCategory = 160;
+const int priorityAnchorsCategory = 140;
+const int priorityLayoutCategory = 120;
+const int priorityTopLevelSeperator = 100;
+const int priorityCustomActions = 80;
+const int priorityRefactoring = 60;
+const int priorityGoIntoComponent = 40;
+const int priorityLast = 60;
+
+} //ComponentCoreConstants
+
+} //QmlDesigner
+
+#endif //COMPONENTCORE_CONSTANTS_H
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
new file mode 100644
index 0000000000..f032e48edc
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
@@ -0,0 +1,408 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "designeractionmanager.h"
+#include "modelnodecontextmenu_helper.h"
+#include "modelnodeoperations.h"
+#include "componentcore_constants.h"
+#include <nodeproperty.h>
+
+#include <QMenu>
+
+namespace QmlDesigner {
+
+static inline QString captionForModelNode(const ModelNode &modelNode)
+{
+ if (modelNode.id().isEmpty())
+ return modelNode.simplifiedTypeName();
+
+ return modelNode.id();
+}
+
+static inline bool contains(const QmlItemNode &node, const QPoint &position)
+{
+ return node.instanceSceneTransform().mapRect(node.instanceBoundingRect()).contains(position);
+}
+
+namespace Internal {
+
+class DesignerActionManagerView : public QmlModelView
+{
+public:
+ DesignerActionManagerView() : QmlModelView(0), m_isInRewriterTransaction(false), m_setupContextDirty(false)
+ {}
+
+ void modelAttached(Model *model)
+ {
+ QmlModelView::modelAttached(model);
+ setupContext();
+ }
+
+ void modelAboutToBeDetached(Model *model)
+ {
+ QmlModelView::modelAboutToBeDetached(model);
+ setupContext();
+ }
+
+ virtual void nodeCreated(const ModelNode &)
+ {
+ setupContext();
+ }
+
+ virtual void nodeAboutToBeRemoved(const ModelNode &)
+ {}
+
+ virtual void nodeRemoved(const ModelNode &, const NodeAbstractProperty &, PropertyChangeFlags)
+ {
+ setupContext();
+ }
+
+ virtual void nodeAboutToBeReparented(const ModelNode &,
+ const NodeAbstractProperty &,
+ const NodeAbstractProperty &,
+ AbstractView::PropertyChangeFlags )
+ {
+ setupContext();
+ }
+
+ virtual void nodeReparented(const ModelNode &, const NodeAbstractProperty &,
+ const NodeAbstractProperty &,
+ AbstractView::PropertyChangeFlags)
+ {
+ setupContext();
+ }
+
+ virtual void nodeIdChanged(const ModelNode&, const QString&, const QString&)
+ {}
+
+ virtual void propertiesAboutToBeRemoved(const QList<AbstractProperty>&)
+ {}
+
+ virtual void propertiesRemoved(const QList<AbstractProperty>&)
+ {
+ setupContext();
+ }
+
+ virtual void variantPropertiesChanged(const QList<VariantProperty>&, PropertyChangeFlags)
+ {}
+
+ virtual void bindingPropertiesChanged(const QList<BindingProperty>&, PropertyChangeFlags)
+ {}
+
+ virtual void rootNodeTypeChanged(const QString &, int , int )
+ {
+ setupContext();
+ }
+
+ virtual void instancePropertyChange(const QList<QPair<ModelNode, QString> > &)
+ {}
+
+ virtual void instancesCompleted(const QVector<ModelNode> &)
+ {}
+
+ virtual void instanceInformationsChange(const QMultiHash<ModelNode, InformationName> &)
+ {}
+
+ virtual void instancesRenderImageChanged(const QVector<ModelNode> &)
+ {}
+
+ virtual void instancesPreviewImageChanged(const QVector<ModelNode> &)
+ {}
+
+ virtual void instancesChildrenChanged(const QVector<ModelNode> &)
+ {}
+
+ virtual void instancesToken(const QString &, int , const QVector<ModelNode> &)
+ {}
+
+ virtual void nodeSourceChanged(const ModelNode &, const QString &)
+ {}
+
+ virtual void rewriterBeginTransaction()
+ {
+ m_isInRewriterTransaction = true;
+ }
+
+ virtual void rewriterEndTransaction()
+ {
+ m_isInRewriterTransaction = false;
+
+ if (m_setupContextDirty)
+ setupContext();
+ }
+
+ virtual void actualStateChanged(const ModelNode &)
+ {
+ setupContext();
+ }
+
+ virtual void selectedNodesChanged(const QList<ModelNode> &,
+ const QList<ModelNode> &)
+ {
+ setupContext();
+ }
+
+ virtual void nodeOrderChanged(const NodeListProperty &, const ModelNode &, int )
+ {
+ setupContext();
+ }
+
+ virtual void importsChanged(const QList<Import> &, const QList<Import> &)
+ {
+ setupContext();
+ }
+
+ virtual void scriptFunctionsChanged(const ModelNode &, const QStringList &)
+ {}
+
+ void setDesignerActionList(const QList<AbstractDesignerAction* > &designerActionList)
+ {
+ m_designerActionList = designerActionList;
+ }
+
+protected:
+ void setupContext()
+ {
+ if (m_isInRewriterTransaction) {
+ m_setupContextDirty = true;
+ return;
+ }
+ SelectionContext selectionContext(this);
+ foreach (AbstractDesignerAction* action, m_designerActionList) {
+ action->setCurrentContext(selectionContext);
+ }
+ m_setupContextDirty = false;
+ }
+
+ QList<AbstractDesignerAction* > m_designerActionList;
+ bool m_isInRewriterTransaction;
+ bool m_setupContextDirty;
+};
+
+} //Internal
+
+DesignerActionManager *DesignerActionManager::m_instance = 0;
+
+void DesignerActionManager::addDesignerAction(AbstractDesignerAction *newAction)
+{
+ instance()->addDesignerActionInternal(newAction);
+}
+
+QList<AbstractDesignerAction* > DesignerActionManager::designerActions()
+{
+ return instance()->factoriesInternal();
+}
+
+QmlModelView *DesignerActionManager::view()
+{
+ return instance()->m_view.data();
+}
+
+template <class ACTION,
+ class ENABLED = SelectionContextFunctors::Always,
+ class VISIBILITY = SelectionContextFunctors::Always>
+class VisiblityModelNodeActionFactory : public ModelNodeActionFactory<ACTION, ENABLED, VISIBILITY>
+{
+public:
+ VisiblityModelNodeActionFactory(const QString &description, const QString &category, int priority) :
+ ModelNodeActionFactory<ACTION, ENABLED, VISIBILITY>(description, category, priority)
+ {}
+ virtual void updateContext()
+ {
+ m_action->setSelectionContext(m_selectionContext);
+ if (m_selectionContext.isValid()) {
+ m_action->setEnabled(isEnabled(m_selectionContext));
+ m_action->setVisible(isVisible(m_selectionContext));
+
+ m_action->setCheckable(true);
+ QmlItemNode itemNode = QmlItemNode(m_selectionContext.currentSingleSelectedNode());
+ if (itemNode.isValid())
+ m_action->setChecked(itemNode.instanceValue("visible").toBool());
+ else
+ m_action->setEnabled(false);
+ }
+ }
+};
+
+template <void (*T)(const SelectionContext &)>
+struct Functor {
+ void operator() (const SelectionContext &selectionState) { T(selectionState); }
+};
+
+class SelectionModelNodeAction : public MenuDesignerAction<SelectionContextFunctors::Always, SelectionContextFunctors::SelectionEnabled>
+{
+typedef ActionTemplate<Functor<ModelNodeOperations::select> > SelectionAction;
+typedef QSharedPointer<SelectionAction> SelectionActionPtr;
+
+public:
+ SelectionModelNodeAction(const QString &displayName, const QString &menuId, int priority) :
+ MenuDesignerAction(displayName, menuId, priority)
+ {}
+
+ virtual void updateContext()
+ {
+ m_menu->clear();
+ if (m_selectionContext.isValid()) {
+ m_action->setEnabled(isEnabled(m_selectionContext));
+ m_action->setVisible(isVisible(m_selectionContext));
+ } else {
+ return;
+ }
+ if (m_action->isEnabled()) {
+ ModelNode parentNode;
+ if (m_selectionContext.singleSelected() && !m_selectionContext.currentSingleSelectedNode().isRootNode()) {
+ SelectionAction* selectionAction = new SelectionAction(QString());
+ selectionAction->setParent(m_menu.data());
+
+ parentNode = m_selectionContext.currentSingleSelectedNode().parentProperty().parentModelNode();
+ m_selectionContext.setTargetNode(parentNode);
+ selectionAction->setText(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select parent: %1")).arg(
+ captionForModelNode(parentNode)));
+ selectionAction->setSelectionContext(m_selectionContext);
+
+ m_menu->addAction(selectionAction);
+ }
+ foreach (const ModelNode &node, m_selectionContext.view()->allModelNodes()) {
+ if (node != m_selectionContext.currentSingleSelectedNode()
+ && node != parentNode
+ && contains(node, m_selectionContext.scenePos())
+ && !node.isRootNode()) {
+ m_selectionContext.setTargetNode(node);
+ SelectionAction* selectionAction =
+ new SelectionAction(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1")).arg(captionForModelNode(node)));
+ selectionAction->setSelectionContext(m_selectionContext);
+
+ m_menu->addAction(selectionAction);
+ }
+ }
+ }
+ }
+};
+
+char xProperty[] = "x";
+char yProperty[] = "y";
+char zProperty[] = "z";
+char widthProperty[] = "width";
+char heightProperty[] = "height";
+
+void DesignerActionManager::createDefaultDesignerActions()
+{
+ typedef Functor<ModelNodeOperations::resetPosition> resetPositionFunctor;
+
+ using namespace SelectionContextFunctors;
+ using namespace ComponentCoreConstants;
+
+ typedef Not<SingleSelection> MultiSelection;
+ typedef And<SingleSelection, InBaseState> SingleSelection_And_InBaseState;
+ typedef And<MultiSelection, InBaseState> MultiSelection_And_InBaseState;
+ typedef Or<SelectionHasProperty<xProperty>, SelectionHasProperty<yProperty> >
+ SelectionHasPropertyX_Or_SelectionHasPropertyY;
+ typedef Or<SelectionHasProperty<widthProperty>, SelectionHasProperty<heightProperty> >
+ SelectionHasPropertyWidth_Or_SelectionHasPropertyHeight;
+ typedef And<SelectionHasSameParent, InBaseState> SelectionHasSameParent_And_InBaseState;
+ typedef And<SelectionHasSameParent_And_InBaseState, MultiSelection> SelectionCanBeLayouted;
+
+ addDesignerAction(new SelectionModelNodeAction(selectionCategoryDisplayName, selectionCategory, prioritySelectionCategory));
+
+ addDesignerAction(new MenuDesignerAction<Always>(stackCategoryDisplayName, stackCategory, priorityStackCategory));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::toFront>, SingleSelection>
+ (toFrontDisplayName, stackCategory, 200));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::toBack>, SingleSelection>
+ (toBackDisplayName, stackCategory, 180));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::raise>, SelectionNotEmpty>
+ (raiseDisplayName, stackCategory, 160));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::lower>, SelectionNotEmpty>
+ (lowerDisplayName, stackCategory, 140));
+ addDesignerAction(new SeperatorDesignerAction<>(stackCategory, 120));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::resetZ>,
+ And<SelectionNotEmpty, SelectionHasProperty<zProperty> > >
+ (resetZDisplayName, stackCategory, 100));
+
+ addDesignerAction(new MenuDesignerAction<SelectionNotEmpty>(editCategoryDisplayName, editCategory, priorityEditCategory));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::resetPosition>,
+ And<SelectionNotEmpty, SelectionHasPropertyWidth_Or_SelectionHasPropertyHeight> >
+ (resetPositionDisplayName, editCategory, 200));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::resetSize>,
+ And<SelectionNotEmpty, SelectionHasPropertyX_Or_SelectionHasPropertyY> >
+ (resetSizeDisplayName, editCategory, 180));
+ addDesignerAction(new VisiblityModelNodeActionFactory<Functor<ModelNodeOperations::setVisible>, SingleSelectedItem>
+ (visibilityDisplayName, editCategory, 160));
+
+ addDesignerAction(new MenuDesignerAction<SingleSelection_And_InBaseState>(anchorsCategoryDisplayName, anchorsCategory, priorityAnchorsCategory));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::anchorsFill>, SingleSelectionItemNotAnchored>
+ (anchorsFillDisplayName, anchorsCategory, 200));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::anchorsReset>,
+ SingleSelectionItemIsAnchored>(anchorsResetDisplayName, anchorsCategory, 180));
+
+ addDesignerAction(new MenuDesignerAction<MultiSelection_And_InBaseState>(layoutCategoryDisplayName, layoutCategory, priorityLayoutCategory));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::layoutRow>, SelectionCanBeLayouted>
+ (layoutRowDisplayName, layoutCategory, 200));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::layoutColumn>, SelectionCanBeLayouted>
+ (layoutColumnDisplayName, layoutCategory, 180));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::layoutColumn>, SelectionCanBeLayouted>
+ (layoutGridDisplayName, layoutCategory, 160));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::layoutFlow>, SelectionCanBeLayouted>
+ (layoutFlowDisplayName, layoutCategory, 140));
+
+ addDesignerAction(new SeperatorDesignerAction<>(rootCategory, priorityTopLevelSeperator));
+ addDesignerAction(new ModelNodeActionFactory<Functor<ModelNodeOperations::goIntoComponent>,
+ SelectionIsComponent>(goIntoComponentDisplayName, rootCategory, priorityGoIntoComponent));
+}
+
+DesignerActionManager *DesignerActionManager::instance()
+{
+ if (!m_instance) {
+ m_instance = new DesignerActionManager;
+ createDefaultDesignerActions();
+ }
+
+ return m_instance;
+}
+
+void DesignerActionManager::addDesignerActionInternal(AbstractDesignerAction *newAction)
+{
+ m_designerActions.append(QSharedPointer<AbstractDesignerAction>(newAction));
+ m_view->setDesignerActionList(designerActions());
+}
+
+QList<AbstractDesignerAction* > DesignerActionManager::factoriesInternal() const
+{
+ QList<AbstractDesignerAction* > list;
+ foreach (const QSharedPointer<AbstractDesignerAction> &pointer, m_designerActions) {
+ list.append(pointer.data());
+ }
+
+ return list;
+}
+
+DesignerActionManager::DesignerActionManager() : m_view(new Internal::DesignerActionManagerView)
+{
+}
+
+} //QmlDesigner
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h
new file mode 100644
index 0000000000..87a4c91140
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef DESIGNERACTIONMANAGER_H
+#define DESIGNERACTIONMANAGER_H
+
+#include "abstractdesigneraction.h"
+#include "qmlmodelview.h"
+
+#include <QScopedPointer>
+
+namespace QmlDesigner {
+
+namespace Internal {
+class DesignerActionManagerView;
+}
+
+class DesignerActionManager {
+public:
+ static void addDesignerAction(AbstractDesignerAction *newAction);
+ static QList<AbstractDesignerAction* > designerActions();
+
+ static void createDefaultDesignerActions();
+ static QmlModelView *view();
+
+protected:
+ static DesignerActionManager *instance();
+ void addDesignerActionInternal(AbstractDesignerAction *newAction);
+ QList<AbstractDesignerAction* > factoriesInternal() const;
+ DesignerActionManager();
+
+private:
+ static DesignerActionManager *m_instance;
+ QList<QSharedPointer<AbstractDesignerAction> > m_designerActions;
+ QScopedPointer<Internal::DesignerActionManagerView> m_view;
+};
+
+} //QmlDesigner
+
+#endif //DESIGNERACTIONMANAGER_H
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp
index 53e67a44c4..51750ac6e6 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp
@@ -27,8 +27,11 @@
**
****************************************************************************/
-#include <cmath>
#include "modelnodecontextmenu.h"
+#include "modelnodecontextmenu_helper.h"
+#include "designeractionmanager.h"
+
+#include <cmath>
#include <QApplication>
#include <QMessageBox>
#include <coreplugin/editormanager/editormanager.h>
@@ -45,935 +48,93 @@
#include <designmodewidget.h>
#include <qmlanchors.h>
-const QString auxDataString = QLatin1String("anchors_");
+#include <QSet>
namespace QmlDesigner {
-static inline DesignDocumentController* designDocumentController()
-{
- return Internal::DesignModeWidget::instance()->currentDesignDocumentController();
-}
-
-static inline QString captionForModelNode(const ModelNode &modelNode)
-{
- if (modelNode.id().isEmpty())
- return modelNode.simplifiedTypeName();
-
- return modelNode.id();
-}
-
-static inline bool contains(const QmlItemNode &node, const QPoint &p)
-{
- return node.instanceSceneTransform().mapRect(node.instanceBoundingRect()).contains(p);
-}
-
-static inline bool checkIfNodeIsAView(const ModelNode &node)
-{
- return node.metaInfo().isValid() &&
- (node.metaInfo().isSubclassOf("QtQuick.ListView", -1, -1) ||
- node.metaInfo().isSubclassOf("QtQuick.GridView", -1, -1) ||
- node.metaInfo().isSubclassOf("QtQuick.PathView", -1, -1));
-}
-
-static inline bool isItem(const ModelNode &node)
-{
- return node.isValid() && node.metaInfo().isValid() && node.metaInfo().isSubclassOf("QtQuick.Item", -1, -1);
-}
-
-static inline bool itemsHaveSameParent(const QList<ModelNode> &siblingList)
+ModelNodeContextMenu::ModelNodeContextMenu(QmlModelView *view) :
+ m_view(view),
+ m_selectionContext(view)
{
- if (siblingList.isEmpty())
- return false;
-
-
- QmlItemNode item(siblingList.first());
- if (!item.isValid())
- return false;
-
- if (item.isRootModelNode())
- return false;
-
- QmlItemNode parent = item.instanceParent().toQmlItemNode();
- if (!parent.isValid())
- return false;
-
- foreach (const ModelNode &node, siblingList) {
- QmlItemNode currentItem(node);
- if (!currentItem.isValid())
- return false;
- QmlItemNode currentParent = currentItem.instanceParent().toQmlItemNode();
- if (!currentParent.isValid())
- return false;
- if (currentItem.instanceIsInPositioner())
- return false;
- if (currentParent != parent)
- return false;
- }
- return true;
}
-static inline QList<QmlItemNode> siblingsForNode(const QmlItemNode &itemNode)
+static bool sortFunction(AbstractDesignerAction * abstractDesignerAction01, AbstractDesignerAction *abstractDesignerAction02)
{
- QList<QmlItemNode> siblingList;
-
- if (itemNode.isValid() && itemNode.modelNode().parentProperty().isValid()) {
- QList<ModelNode> modelNodes = itemNode.modelNode().parentProperty().parentModelNode().allDirectSubModelNodes();
- foreach (const ModelNode &node, modelNodes) {
- QmlItemNode childItemNode = node;
- if (childItemNode.isValid())
- siblingList.append(childItemNode);
- }
- }
-
- return siblingList;
+ return abstractDesignerAction01->priority() > abstractDesignerAction02->priority();
}
-static signed int getMaxZValue(const QList<QmlItemNode> &siblingList)
+static QSet<AbstractDesignerAction* > findMembers(QSet<AbstractDesignerAction* > designerActionSet,
+ const QString &category)
{
- signed int maximum = INT_MIN;
- foreach (const QmlItemNode &node, siblingList) {
- signed int z = node.instanceValue("z").toInt();
- if (z > maximum)
- maximum = z;
- }
- return maximum;
-}
+ QSet<AbstractDesignerAction* > ret;
-static signed int getMinZValue(const QList<QmlItemNode> &siblingList)
-{
- signed int minimum = INT_MAX;
- foreach (const QmlItemNode &node, siblingList) {
- signed int z = node.instanceValue("z").toInt();
- if (z < minimum)
- minimum = z;
- }
- return minimum;
+ foreach (AbstractDesignerAction* factory, designerActionSet) {
+ if (factory->category() == category)
+ ret.insert(factory);
+ }
+ return ret;
}
-static inline bool modelNodeIsComponent(const ModelNode &node)
+void populateMenu(QSet<AbstractDesignerAction* > &abstractDesignerActions,
+ const QString &category,
+ QMenu* menu,
+ const SelectionContext &selectionContext)
{
- if (!node.isValid() || !node.metaInfo().isValid())
- return false;
+ QSet<AbstractDesignerAction* > matchingFactories = findMembers(abstractDesignerActions, category);
- if (node.metaInfo().isComponent())
- return true;
+ abstractDesignerActions.subtract(matchingFactories);
- if (node.nodeSourceType() == ModelNode::NodeWithComponentSource)
- return true;
- if (checkIfNodeIsAView(node) &&
- node.hasNodeProperty("delegate")) {
- if (node.nodeProperty("delegate").modelNode().metaInfo().isComponent())
- return true;
- if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource)
- return true;
- }
-
- return false;
-}
+ QList<AbstractDesignerAction* > matchingFactoriesList = matchingFactories.toList();
+ qSort(matchingFactoriesList.begin(), matchingFactoriesList.end(), &sortFunction);
-static inline bool isFileComponent(const ModelNode &node)
-{
- if (!node.isValid() || !node.metaInfo().isValid())
- return false;
+ foreach (AbstractDesignerAction* designerAction, matchingFactoriesList) {
+ if (designerAction->type() == AbstractDesignerAction::Menu) {
+ designerAction->setCurrentContext(selectionContext);
+ QMenu *newMenu = designerAction->action()->menu();
+ menu->addMenu(newMenu);
- if (node.metaInfo().isComponent())
- return true;
+ //recurse
- if (checkIfNodeIsAView(node) &&
- node.hasNodeProperty("delegate")) {
- if (node.nodeProperty("delegate").modelNode().metaInfo().isComponent())
- return true;
+ populateMenu(abstractDesignerActions, designerAction->menuId(), newMenu, selectionContext);
+ } else if (designerAction->type() == AbstractDesignerAction::Action) {
+ QAction* action = designerAction->action();
+ designerAction->setCurrentContext(selectionContext);
+ menu->addAction(action);
+ }
}
-
- return false;
-}
-
-static inline void getWidthHeight(const ModelNode &node, int &width, int &height)
-{
- QmlItemNode itemNode(node);
- if (itemNode.isValid()) {
- width = itemNode.instanceValue("width").toInt();
- height = itemNode.instanceValue("height").toInt();
- }
-}
-
-static inline void getProperties(const ModelNode node, QHash<QString, QVariant> &propertyHash)
-{
- if (QmlObjectNode(node).isValid()) {
- foreach (const QString &propertyName, node.propertyNames()) {
- if (node.property(propertyName).isVariantProperty() ||
- (node.property(propertyName).isBindingProperty() &&
- !propertyName.contains(QLatin1String("anchors.")))) {
- propertyHash.insert(propertyName, QmlObjectNode(node).instanceValue(propertyName));
- }
- }
- }
- QmlItemNode itemNode(node);
- if (itemNode.isValid()) {
- propertyHash.insert(QLatin1String("width"), itemNode.instanceValue(QLatin1String("width")));
- propertyHash.insert(QLatin1String("height"), itemNode.instanceValue(QLatin1String("height")));
- propertyHash.remove(QLatin1String("x"));
- propertyHash.remove(QLatin1String("y"));
- propertyHash.remove(QLatin1String("rotation"));
- propertyHash.remove(QLatin1String("opacity"));
- }
-}
-
-static inline void applyProperties(ModelNode &node, const QHash<QString, QVariant> &propertyHash)
-{
- QHash<QString, QVariant> auxiliaryData = node.auxiliaryData();
- foreach (const QString propertyName, auxiliaryData.keys()) {
- node.setAuxiliaryData(propertyName, QVariant());
- }
-
- QHashIterator<QString, QVariant> i(propertyHash);
- while (i.hasNext()) {
- i.next();
- if (i.key() == QLatin1String("width") || i.key() == QLatin1String("height")) {
- node.setAuxiliaryData(i.key(), i.value());
- } else if (node.property(i.key()).isDynamic() &&
- node.property(i.key()).dynamicTypeName() == QLatin1String("alias") &&
- node.property(i.key()).isBindingProperty()) {
- AbstractProperty targetProperty = node.bindingProperty(i.key()).resolveToProperty();
- if (targetProperty.isValid()) {
- targetProperty.parentModelNode().setAuxiliaryData(targetProperty.name() + QLatin1String("@NodeInstance"), i.value());
- }
- } else {
- node.setAuxiliaryData(i.key() + QLatin1String("@NodeInstance"), i.value());
- }
- }
-}
-
-static inline void openFileForComponent(const ModelNode &node)
-{
- //int width = 0;
- //int height = 0;
- QHash<QString, QVariant> propertyHash;
- if (node.metaInfo().isComponent()) {
- //getWidthHeight(node, width, height);
- getProperties(node, propertyHash);
- designDocumentController()->changeToExternalSubComponent(node.metaInfo().componentFileName());
- } else if (checkIfNodeIsAView(node) &&
- node.hasNodeProperty("delegate") &&
- node.nodeProperty("delegate").modelNode().metaInfo().isComponent()) {
- //getWidthHeight(node, width, height);
- getProperties(node, propertyHash);
- designDocumentController()->changeToExternalSubComponent(node.nodeProperty("delegate").modelNode().metaInfo().componentFileName());
- }
- ModelNode rootModelNode = designDocumentController()->model()->rewriterView()->rootModelNode();
- applyProperties(rootModelNode, propertyHash);
- //rootModelNode.setAuxiliaryData("width", width);
- //rootModelNode.setAuxiliaryData("height", height);
-}
-
-static inline void openInlineComponent(const ModelNode &node)
-{
- if (!node.isValid() || !node.metaInfo().isValid())
- return;
-
- if (!designDocumentController())
- return;
-
- //int width = 0;
- //int height = 0;
- QHash<QString, QVariant> propertyHash;
-
- if (node.nodeSourceType() == ModelNode::NodeWithComponentSource) {
- //getWidthHeight(node, width, height);
- getProperties(node, propertyHash);
- designDocumentController()->changeToSubComponent(node);
- } else if (checkIfNodeIsAView(node) &&
- node.hasNodeProperty("delegate")) {
- if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource) {
- //getWidthHeight(node, width, height);
- getProperties(node, propertyHash);
- designDocumentController()->changeToSubComponent(node.nodeProperty("delegate").modelNode());
- }
- }
-
- ModelNode rootModelNode = designDocumentController()->model()->rewriterView()->rootModelNode();
- applyProperties(rootModelNode, propertyHash);
- //rootModelNode.setAuxiliaryData("width", width);
- //rootModelNode.setAuxiliaryData("height", height);
-}
-
-static inline bool modelNodesHaveProperty(const QList<ModelNode> &modelNodeList, const QString &propertyName)
-{
- foreach (const ModelNode &modelNode, modelNodeList)
- if (modelNode.hasProperty(propertyName))
- return true;
-
- return false;
-}
-
-ModelNodeContextMenu::ModelNodeContextMenu(QmlModelView *view) : m_view(view)
-{
}
-void ModelNodeContextMenu::execute(const QPoint &pos, bool selectionMenuBool)
+void ModelNodeContextMenu::execute(const QPoint &position, bool selectionMenuBool)
{
- QMenu* menu = new QMenu();
+ QMenu* mainMenu = new QMenu();
- bool singleSelected = false;
- bool selectionIsEmpty = m_view->selectedModelNodes().isEmpty();
- ModelNode currentSingleNode;
- const bool isInBaseState = m_view->currentState().isBaseState();
- const QList<ModelNode> &selectedModelNodes = m_view->selectedModelNodes();
- if (selectedModelNodes.count()== 1) {
- singleSelected = true;
- currentSingleNode = selectedModelNodes.first();
- }
-
- if (selectionMenuBool) {
- QMenu *selectionMenu = new QMenu(tr("Selection"), menu);
- menu->addMenu(selectionMenu);
- ModelNode parentNode;
- if (singleSelected) {
- //ModelNodeAction *selectionAction;
- //selectionAction = createModelNodeAction(tr("DeSelect: ") + captionForModelNode(currentSingleNode), selectionMenu, QList<ModelNode>() << currentSingleNode, ModelNodeAction::DeSelectModelNode);
- //selectionMenu->addAction(selectionAction);
- if (!currentSingleNode.isRootNode()) {
- parentNode = currentSingleNode.parentProperty().parentModelNode();
- selectionMenu->addAction(createModelNodeAction(tr("Select parent: %1").arg(captionForModelNode(parentNode)),
- selectionMenu, QList<ModelNode>() << parentNode, ModelNodeAction::SelectModelNode));
- }
-
- selectionMenu->addSeparator();
- }
- foreach (const ModelNode &node, m_view->allModelNodes()) {
- if (node != currentSingleNode && node != parentNode && contains(node, m_scenePos) && !node.isRootNode())
- selectionMenu->addAction(createModelNodeAction(tr("Select: %1").arg(captionForModelNode(node)), selectionMenu, QList<ModelNode>() << node, ModelNodeAction::SelectModelNode));
- }
- }
-
- QMenu *stackMenu = new QMenu(tr("Stack (z)"), menu);
- menu->addMenu(stackMenu);
-
- stackMenu->addAction(createModelNodeAction(tr("To Front"), stackMenu, QList<ModelNode>() << currentSingleNode, ModelNodeAction::ToFront, singleSelected));
- stackMenu->addAction(createModelNodeAction(tr("To Back"), stackMenu, QList<ModelNode>() << currentSingleNode, ModelNodeAction::ToBack, singleSelected));
- stackMenu->addAction(createModelNodeAction(tr("Raise"), stackMenu, QList<ModelNode>() << selectedModelNodes, ModelNodeAction::Raise));
- stackMenu->addAction(createModelNodeAction(tr("Lower"), stackMenu, QList<ModelNode>() << selectedModelNodes, ModelNodeAction::Lower));
- stackMenu->addSeparator();
- stackMenu->addAction(createModelNodeAction(tr("Reset z property"), stackMenu, QList<ModelNode>() << selectedModelNodes, ModelNodeAction::ResetZ));
-
- QMenu *editMenu = new QMenu(tr("Edit"), menu);
- menu->addMenu(editMenu);
- if (!selectionIsEmpty) {
- //editMenu->addAction(createModelNodeAction(tr("Change Id"), editMenu, QList<ModelNode>() << currentSingleNode, ModelNodeAction::SetId, singleSelected));
- ModelNodeAction* action = createModelNodeAction(tr("Reset Position"), editMenu, selectedModelNodes, ModelNodeAction::ResetPosition);
- if (!modelNodesHaveProperty(selectedModelNodes, QLatin1String("x")) && !modelNodesHaveProperty(selectedModelNodes, QLatin1String("y")))
- action->setEnabled(false);
- editMenu->addAction(action);
- action = createModelNodeAction(tr("Reset Size"), editMenu, selectedModelNodes, ModelNodeAction::ResetSize);
- if (!modelNodesHaveProperty(selectedModelNodes, QLatin1String("width")) && !modelNodesHaveProperty(selectedModelNodes, QLatin1String("height")))
- action->setEnabled(false);
- editMenu->addAction(action);
- action = createModelNodeAction(tr("Visibility"), editMenu, QList<ModelNode>() << currentSingleNode, ModelNodeAction::ModelNodeVisibility, singleSelected);
- editMenu->addAction(action);
- if (singleSelected && !isItem(currentSingleNode))
- action->setEnabled(false);
-
- } else {
- editMenu->setEnabled(false);
- }
-
- QMenu *anchorMenu = new QMenu(tr("Anchors"), menu);
- menu->addMenu(anchorMenu);
-
-
- if (singleSelected && isInBaseState) {
- QmlItemNode itemNode(currentSingleNode);
-
- bool anchored = itemNode.instanceHasAnchors();
- bool isRootNode = itemNode.isRootNode();
-
- ModelNodeAction *action = createModelNodeAction(tr("Fill"), anchorMenu, QList<ModelNode>() << currentSingleNode, ModelNodeAction::AnchorFill, !anchored && !isRootNode);
- anchorMenu->addAction(action);
- action = createModelNodeAction(tr("Reset"), anchorMenu, QList<ModelNode>() << currentSingleNode, ModelNodeAction::AnchorReset, anchored && !isRootNode);
- anchorMenu->addAction(action);
- } else {
- anchorMenu->setEnabled(false);
- }
-
- QMenu *layoutMenu = new QMenu(tr("Layout"), menu);
- menu->addMenu(layoutMenu);
-
- bool layoutingIsPossible = itemsHaveSameParent(selectedModelNodes) && isInBaseState;
-
- if (!singleSelected && !selectionIsEmpty && layoutingIsPossible) {
+ m_selectionContext.setShowSelectionTools(selectionMenuBool);
+ m_selectionContext.setScenePos(m_scenePos);
- ModelNodeAction *action = createModelNodeAction(tr("Layout in Row"), layoutMenu, selectedModelNodes, ModelNodeAction::LayoutRow, true);
- layoutMenu->addAction(action);
- action = createModelNodeAction(tr("Layout in Column"), layoutMenu, selectedModelNodes, ModelNodeAction::LayoutColumn, true);
- layoutMenu->addAction(action);
- action = createModelNodeAction(tr("Layout in Grid"), layoutMenu, selectedModelNodes, ModelNodeAction::LayoutGrid, true);
- layoutMenu->addAction(action);
- action = createModelNodeAction(tr("Layout in Flow"), layoutMenu, selectedModelNodes, ModelNodeAction::LayoutFlow, true);
- layoutMenu->addAction(action);
-
- } else {
- layoutMenu->setEnabled(false);
- }
+ QSet<AbstractDesignerAction* > factories =
+ QSet<AbstractDesignerAction* >::fromList(DesignerActionManager::designerActions());
- menu->addSeparator();
- bool enterComponent = false;
- if (singleSelected) {
- enterComponent = modelNodeIsComponent(currentSingleNode);
- }
- menu->addAction(createModelNodeAction(tr("Go into Component"), editMenu, QList<ModelNode>() << currentSingleNode, ModelNodeAction::GoIntoComponent, enterComponent));
+ populateMenu(factories, QString(""), mainMenu, m_selectionContext);
- menu->exec(pos);
- menu->deleteLater();
+ mainMenu->exec(position);
+ mainMenu->deleteLater();
}
-void ModelNodeContextMenu::setScenePos(const QPoint &pos)
+void ModelNodeContextMenu::setScenePos(const QPoint &position)
{
- m_scenePos = pos;
+ m_scenePos = position;
}
-void ModelNodeContextMenu::showContextMenu(QmlModelView *view, const QPoint &globalPosition, const QPoint &scenePosition, bool showSelection)
+void ModelNodeContextMenu::showContextMenu(QmlModelView *view,
+ const QPoint &globalPosition,
+ const QPoint &scenePosition,
+ bool showSelection)
{
ModelNodeContextMenu contextMenu(view);
contextMenu.setScenePos(scenePosition);
contextMenu.execute(globalPosition, showSelection);
}
-ModelNodeAction* ModelNodeContextMenu::createModelNodeAction(const QString &description, QMenu *menu, const QList<ModelNode> &modelNodeList, ModelNodeAction::ModelNodeActionType type, bool enabled)
-{
- ModelNodeAction* action = new ModelNodeAction(description, menu, m_view, modelNodeList, type);
- action->setEnabled(enabled);
- return action;
-}
-
-
-ModelNodeAction::ModelNodeAction( const QString & text, QObject *parent, QmlModelView *view, const QList<ModelNode> &modelNodeList, ModelNodeActionType type) :
- QAction(text, parent), m_view(view), m_modelNodeList(modelNodeList), m_type(type)
-{
- if (type == ModelNodeVisibility) {
- setCheckable(true);
- QmlItemNode itemNode = QmlItemNode(m_modelNodeList.first());
- if (itemNode.isValid())
- setChecked(itemNode.instanceValue("visible").toBool());
- else
- setEnabled(false);
- }
- connect(this, SIGNAL(triggered(bool)), this, SLOT(actionTriggered(bool)));
-}
-
-void ModelNodeAction::goIntoComponent(const ModelNode &modelNode)
-{
-
- if (modelNode.isValid() && modelNodeIsComponent(modelNode)) {
- if (isFileComponent(modelNode))
- openFileForComponent(modelNode);
- else
- openInlineComponent(modelNode);
- }
-}
-
-void ModelNodeAction::actionTriggered(bool b)
-{
- try {
- switch (m_type) {
- case ModelNodeAction::SelectModelNode: select(); break;
- case ModelNodeAction::DeSelectModelNode: deSelect(); break;
- case ModelNodeAction::CutSelection: cut(); break;
- case ModelNodeAction::CopySelection: copy(); break;
- case ModelNodeAction::DeleteSelection: deleteSelection(); break;
- case ModelNodeAction::ToFront: toFront(); break;
- case ModelNodeAction::ToBack: toBack(); break;
- case ModelNodeAction::Raise: raise(); break;
- case ModelNodeAction::Lower: lower(); break;
- case ModelNodeAction::Paste: paste(); break;
- case ModelNodeAction::Undo: undo(); break;
- case ModelNodeAction::Redo: redo(); break;
- case ModelNodeAction::ModelNodeVisibility: setVisible(b); break;
- case ModelNodeAction::ResetSize: resetSize(); break;
- case ModelNodeAction::ResetPosition: resetPosition(); break;
- case ModelNodeAction::GoIntoComponent: goIntoComponent(); break;
- case ModelNodeAction::SetId: setId(); break;
- case ModelNodeAction::ResetZ: resetZ(); break;
- case ModelNodeAction::AnchorFill: anchorsFill(); break;
- case ModelNodeAction::AnchorReset: anchorsReset(); break;
- case ModelNodeAction::LayoutColumn: layoutColumn(); break;
- case ModelNodeAction::LayoutRow: layoutRow(); break;
- case ModelNodeAction::LayoutGrid: layoutGrid(); break;
- case ModelNodeAction::LayoutFlow: layoutFlow(); break;
- }
- } catch (RewritingException e) { //better save then sorry
- QMessageBox::warning(0, "Error", e.description());
- }
-}
-
-void ModelNodeAction::select()
-{
- if (m_view)
- m_view->setSelectedModelNodes(m_modelNodeList);
-}
-
-void ModelNodeAction::deSelect()
-{
- if (m_view) {
- QList<ModelNode> selectedNodes = m_view->selectedModelNodes();
- foreach (const ModelNode &node, m_modelNodeList) {
- if (selectedNodes.contains(node))
- selectedNodes.removeAll(node);
- }
- m_view->setSelectedModelNodes(selectedNodes);
- }
-}
-
-void ModelNodeAction::cut()
-{
-}
-
-
-void ModelNodeAction::copy()
-{
-}
-
-void ModelNodeAction::deleteSelection()
-{
-}
-
-void ModelNodeAction::toFront()
-{
- if (!m_view)
- return;
-
- try {
- QmlItemNode node = m_modelNodeList.first();
- if (node.isValid()) {
- signed int maximumZ = getMaxZValue(siblingsForNode(node));
- maximumZ++;
- node.setVariantProperty("z", maximumZ);
- }
- } catch (RewritingException &e) { //better save then sorry
- QMessageBox::warning(0, "Error", e.description());
- }
-}
-
-
-void ModelNodeAction::toBack()
-{
- if (!m_view)
- return;
- try {
- QmlItemNode node = m_modelNodeList.first();
- if (node.isValid()) {
- signed int minimumZ = getMinZValue(siblingsForNode(node));
- minimumZ--;
- node.setVariantProperty("z", minimumZ);
- }
-
- } catch (RewritingException &e) { //better save then sorry
- QMessageBox::warning(0, "Error", e.description());
- }
-}
-
-void ModelNodeAction::raise()
-{
- if (!m_view)
- return;
-
- try {
- RewriterTransaction transaction(m_view);
- foreach (ModelNode modelNode, m_modelNodeList) {
- QmlItemNode node = modelNode;
- if (node.isValid()) {
- signed int z = node.instanceValue("z").toInt();
- z++;
- node.setVariantProperty("z", z);
- }
- }
- } catch (RewritingException &e) { //better save then sorry
- QMessageBox::warning(0, "Error", e.description());
- }
-}
-
-void ModelNodeAction::lower()
-{
- if (!m_view)
- return;
- try {
- RewriterTransaction transaction(m_view);
- foreach (ModelNode modelNode, m_modelNodeList) {
- QmlItemNode node = modelNode;
- if (node.isValid()) {
- signed int z = node.instanceValue("z").toInt();
- z--;
- node.setVariantProperty("z", z);
- }
- }
- } catch (RewritingException &e) { //better save then sorry
- QMessageBox::warning(0, "Error", e.description());
- }
-}
-
-void ModelNodeAction::paste()
-{
-}
-
-void ModelNodeAction::undo()
-{
-}
-
-void ModelNodeAction::redo()
-{
-}
-
-void ModelNodeAction::setVisible(bool b)
-{
- if (!m_view)
- return;
- try {
- m_modelNodeList.first().variantProperty("visible") = b;
- } catch (RewritingException &e) { //better save then sorry
- QMessageBox::warning(0, "Error", e.description());
- }
-}
-
-
-void ModelNodeAction::resetSize()
-{
- if (!m_view)
- return;
- try {
- RewriterTransaction transaction(m_view);
- foreach (ModelNode node, m_modelNodeList) {
- node.removeProperty("width");
- node.removeProperty("height");
- }
- } catch (RewritingException &e) { //better save then sorry
- QMessageBox::warning(0, "Error", e.description());
- }
-}
-
-void ModelNodeAction::resetPosition()
-{
- if (!m_view)
- return;
- try {
- RewriterTransaction transaction(m_view);
- foreach (ModelNode node, m_modelNodeList) {
- node.removeProperty("x");
- node.removeProperty("y");
- }
- } catch (RewritingException &e) { //better save then sorry
- QMessageBox::warning(0, "Error", e.description());
- }
-}
-
-void ModelNodeAction::goIntoComponent()
-{
- goIntoComponent(m_modelNodeList.first());
-}
-
-void ModelNodeAction::setId()
-{
-}
-
-void ModelNodeAction::resetZ()
-{
- if (!m_view)
- return;
-
- RewriterTransaction transaction(m_view);
- foreach (ModelNode node, m_modelNodeList) {
- node.removeProperty("z");
- }
-}
-
-static inline void backupPropertyAndRemove(ModelNode node, const QString &propertyName)
-{
- if (node.hasVariantProperty(propertyName)) {
- node.setAuxiliaryData(auxDataString + propertyName, node.variantProperty(propertyName).value());
- node.removeProperty(propertyName);
-
- }
- if (node.hasBindingProperty(propertyName)) {
- node.setAuxiliaryData(auxDataString + propertyName, QmlItemNode(node).instanceValue(propertyName));
- node.removeProperty(propertyName);
- }
-}
-
-
-static inline void restoreProperty(ModelNode node, const QString &propertyName)
-{
- if (node.hasAuxiliaryData(auxDataString + propertyName))
- node.variantProperty(propertyName) = node.auxiliaryData(auxDataString + propertyName);
-}
-
-void ModelNodeAction::anchorsFill()
-{
- if (!m_view)
- return;
-
- RewriterTransaction transaction(m_view);
-
- foreach (ModelNode modelNode, m_modelNodeList) {
- QmlItemNode node = modelNode;
- if (node.isValid()) {
- node.anchors().fill();
- backupPropertyAndRemove(modelNode, QLatin1String("x"));
- backupPropertyAndRemove(modelNode, QLatin1String("y"));
- backupPropertyAndRemove(modelNode, QLatin1String("width"));
- backupPropertyAndRemove(modelNode, QLatin1String("height"));
- }
- }
-}
-
-void ModelNodeAction::anchorsReset()
-{
- if (!m_view)
- return;
- RewriterTransaction transaction(m_view);
-
- foreach (ModelNode modelNode, m_modelNodeList) {
- QmlItemNode node = modelNode;
- if (node.isValid()) {
- node.anchors().removeAnchors();
- node.anchors().removeMargins();
- restoreProperty(node, "x");
- restoreProperty(node, "y");
- restoreProperty(node, "width");
- restoreProperty(node, "height");
- }
- }
-}
-
-static inline void reparentTo(const ModelNode &node, const QmlItemNode &parent)
-{
-
- if (parent.isValid() && node.isValid()) {
- NodeAbstractProperty parentProperty;
-
- if (parent.hasDefaultProperty()) {
- parentProperty = parent.nodeAbstractProperty(parent.defaultProperty());
- } else {
- parentProperty = parent.nodeAbstractProperty(QLatin1String("data"));
- }
-
- parentProperty.reparentHere(node);
- }
-}
-
-
-bool compareByX(const ModelNode &node1, const ModelNode &node2)
-{
- QmlItemNode itemNode1 = QmlItemNode(node1);
- QmlItemNode itemNode2 = QmlItemNode(node2);
- if (itemNode1.isValid() && itemNode2.isValid())
- return itemNode1.instancePosition().x() < itemNode2.instancePosition().x();
- return false;
-}
-
-bool compareByY(const ModelNode &node1, const ModelNode &node2)
-{
- QmlItemNode itemNode1 = QmlItemNode(node1);
- QmlItemNode itemNode2 = QmlItemNode(node2);
- if (itemNode1.isValid() && itemNode2.isValid())
- return itemNode1.instancePosition().y() < itemNode2.instancePosition().y();
- return false;
-}
-
-bool compareByGrid(const ModelNode &node1, const ModelNode &node2)
-{
- QmlItemNode itemNode1 = QmlItemNode(node1);
- QmlItemNode itemNode2 = QmlItemNode(node2);
- if (itemNode1.isValid() && itemNode2.isValid()) {
- if ((itemNode1.instancePosition().y() + itemNode1.instanceSize().height()) < itemNode2.instancePosition().y())
- return true;
- if ((itemNode2.instancePosition().y() + itemNode2.instanceSize().height()) < itemNode1.instancePosition().y())
- return false; //first sort y (rows)
- return itemNode1.instancePosition().x() < itemNode2.instancePosition().x();
- }
- return false;
-}
-
-static inline QPoint getUpperLeftPosition(const QList<ModelNode> &modelNodeList)
-{
- QPoint p(INT_MAX, INT_MAX);
- foreach (ModelNode modelNode, modelNodeList) {
- QmlItemNode itemNode = QmlItemNode(modelNode);
- if (itemNode.isValid()) {
- if (itemNode.instancePosition().x() < p.x())
- p.setX(itemNode.instancePosition().x());
- if (itemNode.instancePosition().y() < p.y())
- p.setY(itemNode.instancePosition().y());
- }
-
- }
- return p;
-}
-
-void ModelNodeAction::layoutRow()
-{
- if (!m_view)
- return;
-
- NodeMetaInfo rowMetaInfo = m_view->model()->metaInfo(QLatin1String("QtQuick.Row"));
-
- if (!rowMetaInfo.isValid())
- return;
-
- ModelNode row;
- {
- RewriterTransaction transaction(m_view);
-
- QmlItemNode parent = QmlItemNode(m_modelNodeList.first()).instanceParent().toQmlItemNode();
- if (!parent.isValid())
- return;
-
- qDebug() << parent.modelNode().majorQtQuickVersion();
-
- row = m_view->createModelNode(QLatin1String("QtQuick.Row"), rowMetaInfo.majorVersion(), rowMetaInfo.minorVersion());
-
- reparentTo(row, parent);
- }
-
- {
- RewriterTransaction transaction(m_view);
-
- QPoint pos = getUpperLeftPosition(m_modelNodeList);
- row.variantProperty(QLatin1String("x")) = pos.x();
- row.variantProperty(QLatin1String("y")) = pos.y();
-
- QList<ModelNode> sortedList = m_modelNodeList;
- qSort(sortedList.begin(), sortedList.end(), compareByX);
-
- foreach (ModelNode modelNode, sortedList) {
- reparentTo(modelNode, row);
- modelNode.removeProperty(QLatin1String("x"));
- modelNode.removeProperty(QLatin1String("y"));
- }
- }
-}
-
-void ModelNodeAction::layoutColumn()
-{
- if (!m_view)
- return;
-
- NodeMetaInfo columnMetaInfo = m_view->model()->metaInfo(QLatin1String("QtQuick.Column"));
-
- if (!columnMetaInfo.isValid())
- return;
-
- ModelNode column;
- {
- RewriterTransaction transaction(m_view);
-
- QmlItemNode parent = QmlItemNode(m_modelNodeList.first()).instanceParent().toQmlItemNode();
- if (!parent.isValid())
- return;
-
- column = m_view->createModelNode(QLatin1String("QtQuick.Column"), columnMetaInfo.majorVersion(), columnMetaInfo.minorVersion());
-
- reparentTo(column, parent);
- }
-
- {
- RewriterTransaction transaction(m_view);
-
- QPoint pos = getUpperLeftPosition(m_modelNodeList);
- column.variantProperty(QLatin1String("x")) = pos.x();
- column.variantProperty(QLatin1String("y")) = pos.y();
-
- QList<ModelNode> sortedList = m_modelNodeList;
- qSort(sortedList.begin(), sortedList.end(), compareByY);
-
- foreach (ModelNode modelNode, sortedList) {
- reparentTo(modelNode, column);
- modelNode.removeProperty(QLatin1String("x"));
- modelNode.removeProperty(QLatin1String("y"));
- }
- }
-}
-
-void ModelNodeAction::layoutGrid()
-{
- if (!m_view)
- return;
-
- NodeMetaInfo gridMetaInfo = m_view->model()->metaInfo(QLatin1String("QtQuick.Grid"));
-
- if (!gridMetaInfo.isValid())
- return;
-
- ModelNode grid;
- {
- RewriterTransaction transaction(m_view);
-
- QmlItemNode parent = QmlItemNode(m_modelNodeList.first()).instanceParent().toQmlItemNode();
- if (!parent.isValid())
- return;
-
- grid = m_view->createModelNode(QLatin1String("QtQuick.Grid"), gridMetaInfo.majorVersion(), gridMetaInfo.minorVersion());
- grid.variantProperty(QLatin1String("columns")) = int(sqrt(double(m_modelNodeList.count())));
-
- reparentTo(grid, parent);
- }
-
- {
- RewriterTransaction transaction(m_view);
-
- QPoint pos = getUpperLeftPosition(m_modelNodeList);
- grid.variantProperty(QLatin1String("x")) = pos.x();
- grid.variantProperty(QLatin1String("y")) = pos.y();
-
- QList<ModelNode> sortedList = m_modelNodeList;
- qSort(sortedList.begin(), sortedList.end(), compareByGrid);
-
- foreach (ModelNode modelNode, sortedList) {
- reparentTo(modelNode, grid);
- modelNode.removeProperty(QLatin1String("x"));
- modelNode.removeProperty(QLatin1String("y"));
- }
- }
-}
-
-void ModelNodeAction::layoutFlow()
-{
- if (!m_view)
- return;
-
- NodeMetaInfo flowMetaInfo = m_view->model()->metaInfo(QLatin1String("QtQuick.Flow"));
-
- if (!flowMetaInfo.isValid())
- return;
-
- ModelNode flow;
- {
- RewriterTransaction transaction(m_view);
-
- QmlItemNode parent = QmlItemNode(m_modelNodeList.first()).instanceParent().toQmlItemNode();
- if (!parent.isValid())
- return;
-
- flow = m_view->createModelNode(QLatin1String("QtQuick.Flow"), flowMetaInfo.majorVersion(), flowMetaInfo.minorVersion());
-
- reparentTo(flow, parent);
- }
-
- {
- RewriterTransaction transaction(m_view);
-
- QPoint pos = getUpperLeftPosition(m_modelNodeList);
- flow.variantProperty(QLatin1String("x")) = pos.x();
- flow.variantProperty(QLatin1String("y")) = pos.y();
-
- QList<ModelNode> sortedList = m_modelNodeList;
- qSort(sortedList.begin(), sortedList.end(), compareByGrid);
-
- foreach (ModelNode modelNode, sortedList) {
- reparentTo(modelNode, flow);
- modelNode.removeProperty(QLatin1String("x"));
- modelNode.removeProperty(QLatin1String("y"));
- }
- }
-}
-
-}
+} //QmlDesigner
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.h b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.h
index 6aa11aa750..869890735c 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.h
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.h
@@ -30,85 +30,14 @@
#ifndef MODELNODECONTEXTMENU_H
#define MODELNODECONTEXTMENU_H
-#include <QObject>
#include <QPoint>
-#include <QAction>
#include <QCoreApplication>
-#include <QMenu>
+
#include <qmlmodelview.h>
+#include "selectioncontext.h"
namespace QmlDesigner {
-class ModelNodeAction : public QAction
-{
- Q_OBJECT
-public:
- enum ModelNodeActionType {
- SelectModelNode,
- DeSelectModelNode,
- CutSelection,
- CopySelection,
- DeleteSelection,
- ToFront,
- ToBack,
- Raise,
- Lower,
- Paste,
- Undo,
- Redo,
- ModelNodeVisibility,
- ResetSize,
- ResetPosition,
- GoIntoComponent,
- SetId,
- ResetZ,
- AnchorReset,
- AnchorFill,
- LayoutRow,
- LayoutColumn,
- LayoutGrid,
- LayoutFlow
- };
-
-
- ModelNodeAction( const QString & text, QObject *parent, QmlModelView *view, const QList<ModelNode> &modelNodeList, ModelNodeActionType type);
-
- static void goIntoComponent(const ModelNode &modelNode);
-
-public slots:
- void actionTriggered(bool);
-
-private:
- void select();
- void deSelect();
- void cut();
- void copy();
- void deleteSelection();
- void toFront();
- void toBack();
- void raise();
- void lower();
- void paste();
- void undo();
- void redo();
- void setVisible(bool);
- void resetSize();
- void resetPosition();
- void goIntoComponent();
- void setId();
- void resetZ();
- void anchorsFill();
- void anchorsReset();
- void layoutRow();
- void layoutColumn();
- void layoutGrid();
- void layoutFlow();
-
- QmlModelView *m_view;
- QList<ModelNode> m_modelNodeList;
- ModelNodeActionType m_type;
-};
-
class ModelNodeContextMenu
{
Q_DECLARE_TR_FUNCTIONS(QmlDesigner::ModelNodeContextMenu)
@@ -120,14 +49,11 @@ public:
static void showContextMenu(QmlModelView *view, const QPoint &globalPosition, const QPoint &scenePosition, bool showSelection);
private:
- ModelNodeAction* createModelNodeAction(const QString &description, QMenu *menu, const QList<ModelNode> &modelNodeList, ModelNodeAction::ModelNodeActionType type, bool enabled = true);
-
QmlModelView *m_view;
QPoint m_scenePos;
-
+ SelectionContext m_selectionContext;
};
-
-};
+}; //QmlDesigner
#endif // MODELNODECONTEXTMENU_H
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.cpp
new file mode 100644
index 0000000000..cdaaf86900
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.cpp
@@ -0,0 +1,266 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "modelnodecontextmenu_helper.h"
+
+#include <nodemetainfo.h>
+#include <modelnode.h>
+#include <qmlitemnode.h>
+#include <bindingproperty.h>
+#include <nodeproperty.h>
+#include <designmodewidget.h>
+
+namespace QmlDesigner {
+
+static inline DesignDocumentController* designDocumentController()
+{
+ return Internal::DesignModeWidget::instance()->currentDesignDocumentController();
+}
+
+static inline bool checkIfNodeIsAView(const ModelNode &node)
+{
+ return node.metaInfo().isValid() &&
+ (node.metaInfo().isSubclassOf("QtQuick.ListView", -1, -1) ||
+ node.metaInfo().isSubclassOf("QtQuick.GridView", -1, -1) ||
+ node.metaInfo().isSubclassOf("QtQuick.PathView", -1, -1));
+}
+
+static inline void getProperties(const ModelNode node, QHash<QString, QVariant> &propertyHash)
+{
+ if (QmlObjectNode(node).isValid()) {
+ foreach (const QString &propertyName, node.propertyNames()) {
+ if (node.property(propertyName).isVariantProperty() ||
+ (node.property(propertyName).isBindingProperty() &&
+ !propertyName.contains(QLatin1String("anchors.")))) {
+ propertyHash.insert(propertyName, QmlObjectNode(node).instanceValue(propertyName));
+ }
+ }
+ }
+ QmlItemNode itemNode(node);
+ if (itemNode.isValid()) {
+ propertyHash.insert(QLatin1String("width"), itemNode.instanceValue(QLatin1String("width")));
+ propertyHash.insert(QLatin1String("height"), itemNode.instanceValue(QLatin1String("height")));
+ propertyHash.remove(QLatin1String("x"));
+ propertyHash.remove(QLatin1String("y"));
+ propertyHash.remove(QLatin1String("rotation"));
+ propertyHash.remove(QLatin1String("opacity"));
+ }
+}
+
+static inline void applyProperties(ModelNode &node, const QHash<QString, QVariant> &propertyHash)
+{
+ QHash<QString, QVariant> auxiliaryData = node.auxiliaryData();
+ foreach (const QString propertyName, auxiliaryData.keys()) {
+ node.setAuxiliaryData(propertyName, QVariant());
+ }
+
+ QHashIterator<QString, QVariant> propertyIterator(propertyHash);
+ while (propertyIterator.hasNext()) {
+ propertyIterator.next();
+ const QString propertyName = propertyIterator.key();
+ if (propertyName == QLatin1String("width") || propertyName == QLatin1String("height")) {
+ node.setAuxiliaryData(propertyIterator.key(), propertyIterator.value());
+ } else if (node.property(propertyIterator.key()).isDynamic() &&
+ node.property(propertyIterator.key()).dynamicTypeName() == QLatin1String("alias") &&
+ node.property(propertyIterator.key()).isBindingProperty()) {
+ AbstractProperty targetProperty = node.bindingProperty(propertyIterator.key()).resolveToProperty();
+ if (targetProperty.isValid()) {
+ targetProperty.parentModelNode().setAuxiliaryData(targetProperty.name() + QLatin1String("@NodeInstance"), propertyIterator.value());
+ }
+ } else {
+ node.setAuxiliaryData(propertyIterator.key() + QLatin1String("@NodeInstance"), propertyIterator.value());
+ }
+ }
+}
+
+static inline bool modelNodeIsComponent(const ModelNode &node)
+{
+ if (!node.isValid() || !node.metaInfo().isValid())
+ return false;
+
+ if (node.metaInfo().isComponent())
+ return true;
+
+ if (node.nodeSourceType() == ModelNode::NodeWithComponentSource)
+ return true;
+ if (checkIfNodeIsAView(node) &&
+ node.hasNodeProperty("delegate")) {
+ if (node.nodeProperty("delegate").modelNode().metaInfo().isComponent())
+ return true;
+ if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource)
+ return true;
+ }
+
+ return false;
+}
+
+static inline bool itemsHaveSameParent(const QList<ModelNode> &siblingList)
+{
+ if (siblingList.isEmpty())
+ return false;
+
+
+ QmlItemNode item(siblingList.first());
+ if (!item.isValid())
+ return false;
+
+ if (item.isRootModelNode())
+ return false;
+
+ QmlItemNode parent = item.instanceParent().toQmlItemNode();
+ if (!parent.isValid())
+ return false;
+
+ foreach (const ModelNode &node, siblingList) {
+ QmlItemNode currentItem(node);
+ if (!currentItem.isValid())
+ return false;
+ QmlItemNode currentParent = currentItem.instanceParent().toQmlItemNode();
+ if (!currentParent.isValid())
+ return false;
+ if (currentItem.instanceIsInPositioner())
+ return false;
+ if (currentParent != parent)
+ return false;
+ }
+ return true;
+}
+
+static inline bool isFileComponent(const ModelNode &node)
+{
+ if (!node.isValid() || !node.metaInfo().isValid())
+ return false;
+
+ if (node.metaInfo().isComponent())
+ return true;
+
+ if (checkIfNodeIsAView(node) &&
+ node.hasNodeProperty("delegate")) {
+ if (node.nodeProperty("delegate").modelNode().metaInfo().isComponent())
+ return true;
+ }
+
+ return false;
+}
+
+static inline void openFileForComponent(const ModelNode &node)
+{
+ //int width = 0;
+ //int height = 0;
+ QHash<QString, QVariant> propertyHash;
+ if (node.metaInfo().isComponent()) {
+ //getWidthHeight(node, width, height);
+ getProperties(node, propertyHash);
+ designDocumentController()->changeToExternalSubComponent(node.metaInfo().componentFileName());
+ } else if (checkIfNodeIsAView(node) &&
+ node.hasNodeProperty("delegate") &&
+ node.nodeProperty("delegate").modelNode().metaInfo().isComponent()) {
+ //getWidthHeight(node, width, height);
+ getProperties(node, propertyHash);
+ designDocumentController()->changeToExternalSubComponent(node.nodeProperty("delegate").modelNode().metaInfo().componentFileName());
+ }
+ ModelNode rootModelNode = designDocumentController()->model()->rewriterView()->rootModelNode();
+ applyProperties(rootModelNode, propertyHash);
+ //rootModelNode.setAuxiliaryData("width", width);
+ //rootModelNode.setAuxiliaryData("height", height);
+}
+
+static inline void openInlineComponent(const ModelNode &node)
+{
+ if (!node.isValid() || !node.metaInfo().isValid())
+ return;
+
+ if (!designDocumentController())
+ return;
+
+ QHash<QString, QVariant> propertyHash;
+
+ if (node.nodeSourceType() == ModelNode::NodeWithComponentSource) {
+ //getWidthHeight(node, width, height);
+ getProperties(node, propertyHash);
+ designDocumentController()->changeToSubComponent(node);
+ } else if (checkIfNodeIsAView(node) &&
+ node.hasNodeProperty("delegate")) {
+ if (node.nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource) {
+ //getWidthHeight(node, width, height);
+ getProperties(node, propertyHash);
+ designDocumentController()->changeToSubComponent(node.nodeProperty("delegate").modelNode());
+ }
+ }
+
+ ModelNode rootModelNode = designDocumentController()->model()->rewriterView()->rootModelNode();
+ applyProperties(rootModelNode, propertyHash);
+ //rootModelNode.setAuxiliaryData("width", width);
+ //rootModelNode.setAuxiliaryData("height", height);
+}
+
+void ComponentUtils::goIntoComponent(const ModelNode &modelNode)
+{
+
+ if (modelNode.isValid() && modelNodeIsComponent(modelNode)) {
+ if (isFileComponent(modelNode))
+ openFileForComponent(modelNode);
+ else
+ openInlineComponent(modelNode);
+ }
+}
+
+namespace SelectionContextFunctors {
+
+bool SingleSelectionItemIsAnchored::operator() (const SelectionContext &selectionState) {
+ QmlItemNode itemNode(selectionState.currentSingleSelectedNode());
+ if (selectionState.isInBaseState() && itemNode.isValid()) {
+ bool anchored = itemNode.instanceHasAnchors();
+ return anchored;
+ }
+ return false;
+}
+
+bool SingleSelectionItemNotAnchored::operator() (const SelectionContext &selectionState) {
+ QmlItemNode itemNode(selectionState.currentSingleSelectedNode());
+ if (selectionState.isInBaseState() && itemNode.isValid()) {
+ bool anchored = itemNode.instanceHasAnchors();
+ return !anchored;
+ }
+ return false;
+}
+
+bool SelectionHasSameParent::operator() (const SelectionContext &selectionState)
+{
+ return !selectionState.selectedModelNodes().isEmpty() && itemsHaveSameParent(selectionState.selectedModelNodes());
+}
+
+bool SelectionIsComponent::operator() (const SelectionContext &selectionState)
+{
+ return modelNodeIsComponent(selectionState.currentSingleSelectedNode());
+}
+
+} //SelectionStateFunctors
+
+} //QmlDesigner
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h
new file mode 100644
index 0000000000..a8302a81f0
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h
@@ -0,0 +1,345 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef MODELNODECONTEXTMENU_HELPER_H
+#define MODELNODECONTEXTMENU_HELPER_H
+
+#include "modelnodecontextmenu.h"
+#include "designeractionmanager.h"
+#include <QAction>
+
+namespace QmlDesigner {
+
+class ComponentUtils {
+public:
+ static void goIntoComponent(const ModelNode &modelNode);
+};
+
+class DefaultAction : public QAction {
+
+ Q_OBJECT
+
+public:
+ DefaultAction(const QString &description) : QAction(description, 0)
+ {
+ connect(this, SIGNAL(triggered(bool)), this, SLOT(actionTriggered(bool)));
+ }
+
+public slots: //virtual method instead of slot
+ virtual void actionTriggered(bool )
+ { }
+
+ void setSelectionContext(const SelectionContext &selectionContext)
+ {
+ m_selectionContext = selectionContext;
+ }
+
+protected:
+ SelectionContext m_selectionContext;
+};
+
+class DefaultDesignerAction : public AbstractDesignerAction
+{
+public:
+ DefaultDesignerAction(const QString &description) : m_action(new DefaultAction(description))
+ {}
+
+ DefaultDesignerAction(DefaultAction *action) : m_action(action)
+ {}
+
+ virtual QAction *action() const
+ { return m_action; }
+
+ virtual void setCurrentContext(const SelectionContext &selectionContext)
+ {
+ m_selectionContext = selectionContext;
+ updateContext();
+ }
+
+ virtual void updateContext()
+ {
+ m_action->setSelectionContext(m_selectionContext);
+ if (m_selectionContext.isValid()) {
+ m_action->setEnabled(isEnabled(m_selectionContext));
+ m_action->setVisible(isVisible(m_selectionContext));
+ }
+ }
+
+protected:
+ DefaultAction *m_action;
+ SelectionContext m_selectionContext;
+};
+
+template <class ENABLED = SelectionContextFunctors::Always,
+ class VISIBILITY = SelectionContextFunctors::Always>
+class MenuDesignerAction : public AbstractDesignerAction
+{
+public:
+ MenuDesignerAction(const QString &displayName, const QString &menuId, int priority) :
+ m_displayName(displayName),
+ m_menuId(menuId),
+ m_priority(priority),
+ m_menu(new QMenu)
+ {
+ m_menu->setTitle(displayName);
+ m_action = m_menu->menuAction();
+ }
+
+ virtual bool isVisible(const SelectionContext &m_selectionState) const
+ { VISIBILITY visibility; return visibility(m_selectionState); }
+
+ virtual bool isEnabled(const SelectionContext &m_selectionState) const
+ { ENABLED enabled; return enabled(m_selectionState); }
+
+ virtual QString category() const
+ { return QString(""); }
+
+ virtual QString menuId() const
+ { return m_menuId; }
+
+ virtual int priority() const
+ { return m_priority; }
+
+ virtual AbstractDesignerAction::Type type() const
+ { return AbstractDesignerAction::Menu; }
+
+ virtual QAction *action() const
+ { return m_action; }
+
+ virtual void setCurrentContext(const SelectionContext &selectionContext)
+ {
+ m_selectionContext = selectionContext;
+ updateContext();
+ }
+
+ virtual void updateContext()
+ {
+ if (m_selectionContext.isValid()) {
+ m_action->setEnabled(isEnabled(m_selectionContext));
+ m_action->setVisible(isVisible(m_selectionContext));
+ }
+ }
+
+protected:
+ const QString m_displayName;
+ const QString m_menuId;
+ const int m_priority;
+ SelectionContext m_selectionContext;
+ QScopedPointer<QMenu> m_menu;
+ QAction *m_action;
+};
+
+template <class VISIBILITY = SelectionContextFunctors::Always>
+class SeperatorDesignerAction : public DefaultDesignerAction
+{
+public:
+ SeperatorDesignerAction(const QString &category, int priority) :
+ DefaultDesignerAction(QString()),
+ m_category(category), m_priority(priority)
+ { m_action->setSeparator(true); }
+
+ virtual bool isVisible(const SelectionContext &m_selectionState) const
+ { VISIBILITY visibility; return visibility(m_selectionState); }
+
+ virtual bool isEnabled(const SelectionContext &) const
+ { return true; }
+
+ virtual QString category() const
+ { return m_category; }
+
+ virtual QString menuId() const
+ { return QString(); }
+
+ virtual int priority() const
+ { return m_priority; }
+
+ virtual Type type() const
+ { return Action; }
+
+ virtual void setCurrentContext(const SelectionContext &)
+ {}
+private:
+ const QString m_category;
+ const int m_priority;
+};
+
+template <class ACTION>
+class ActionTemplate : public DefaultAction {
+
+public:
+ ActionTemplate(const QString &description) : DefaultAction(description)
+ { }
+
+public /*slots*/:
+ virtual void actionTriggered(bool b)
+ {
+ m_selectionContext.setToggled(b);
+ ACTION action;
+ return action(m_selectionContext);
+ }
+};
+
+template <class ACTION,
+ class ENABLED = SelectionContextFunctors::Always,
+ class VISIBILITY = SelectionContextFunctors::Always>
+class ModelNodeActionFactory : public DefaultDesignerAction
+{
+public:
+ ModelNodeActionFactory(const QString &description, const QString &category, int priority) :
+ DefaultDesignerAction(new ActionTemplate<ACTION>(description)),
+ m_category(category),
+ m_priority(priority)
+ {}
+
+ virtual bool isVisible(const SelectionContext &selectionState) const
+ { VISIBILITY visibility; return visibility(selectionState); }
+
+ virtual bool isEnabled(const SelectionContext &selectionState) const
+ { ENABLED enabled; return enabled(selectionState); }
+
+ virtual QString category() const
+ { return m_category; }
+
+ virtual QString menuId() const
+ { return QString(); }
+
+ virtual int priority() const
+ { return m_priority; }
+
+ virtual Type type() const
+ { return Action; }
+
+private:
+ const QString m_category;
+ const int m_priority;
+};
+
+namespace SelectionContextFunctors {
+
+struct Always {
+ bool operator() (const SelectionContext &) {
+ return true;
+ }
+};
+
+struct InBaseState {
+ bool operator() (const SelectionContext &selectionState) {
+ return selectionState.isInBaseState();
+ }
+};
+
+struct SingleSelection {
+ bool operator() (const SelectionContext &selectionState) {
+ return selectionState.singleSelected();
+ }
+};
+
+struct SelectionEnabled {
+ bool operator() (const SelectionContext &selectionState) {
+ return selectionState.showSelectionTools();
+ }
+};
+
+struct SelectionNotEmpty {
+ bool operator() (const SelectionContext &selectionState) {
+ return !selectionState.selectedModelNodes().isEmpty();
+ }
+};
+
+struct SingleSelectionNotRoot {
+ bool operator() (const SelectionContext &selectionState) {
+ return selectionState.singleSelected()
+ && !selectionState.currentSingleSelectedNode().isRootNode();
+ }
+};
+
+template <class T1, class T2>
+struct And {
+ bool operator() (const SelectionContext &selectionState) {
+ T1 t1;
+ T2 t2;
+ return t1(selectionState) && t2(selectionState);
+ }
+};
+
+template <class T1, class T2>
+struct Or {
+ bool operator() (const SelectionContext &selectionState) {
+ T1 t1;
+ T2 t2;
+ return t1(selectionState) || t2(selectionState);
+ }
+};
+
+template <class T1>
+struct Not {
+ bool operator() (const SelectionContext &selectionState) {
+ T1 t1;
+ return !t1(selectionState);
+ }
+};
+
+template <char* PROPERTYNAME>
+struct SelectionHasProperty {
+ bool operator() (const SelectionContext &selectionState) {
+ foreach (const ModelNode &modelNode, selectionState.selectedModelNodes())
+ if (modelNode.hasProperty(QLatin1String(PROPERTYNAME)))
+ return true;
+ return false;
+ }
+};
+
+struct SelectionHasSameParent {
+ bool operator() (const SelectionContext &selectionState);
+};
+
+struct SelectionIsComponent {
+ bool operator() (const SelectionContext &selectionState);
+};
+
+struct SingleSelectionItemIsAnchored {
+ bool operator() (const SelectionContext &selectionState);
+};
+
+struct SingleSelectionItemNotAnchored {
+ bool operator() (const SelectionContext &selectionState);
+};
+
+struct SingleSelectedItem {
+ bool operator() (const SelectionContext &selectionState) {
+ QmlItemNode itemNode(selectionState.currentSingleSelectedNode());
+ return itemNode.isValid();
+ }
+};
+
+} //SelectionStateFunctors
+
+} //QmlDesigner
+
+#endif // MODELNODECONTEXTMENU_HELPER_H
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
new file mode 100644
index 0000000000..45fad74cab
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
@@ -0,0 +1,602 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "modelnodeoperations.h"
+#include "modelnodecontextmenu_helper.h"
+
+#include <cmath>
+#include <QApplication>
+#include <QMessageBox>
+#include <coreplugin/editormanager/editormanager.h>
+#include <nodeabstractproperty.h>
+#include <nodelistproperty.h>
+#include <nodemetainfo.h>
+#include <modelnode.h>
+#include <qmlitemnode.h>
+#include <variantproperty.h>
+#include <bindingproperty.h>
+#include <nodeproperty.h>
+#include <rewritingexception.h>
+#include <rewritertransaction.h>
+#include <designmodewidget.h>
+#include <qmlanchors.h>
+
+namespace QmlDesigner {
+
+const QString auxDataString = QLatin1String("anchors_");
+
+static inline bool isItem(const ModelNode &node)
+{
+ return node.isValid() && node.metaInfo().isValid() && node.metaInfo().isSubclassOf("QtQuick.Item", -1, -1);
+}
+
+static inline QList<QmlItemNode> siblingsForNode(const QmlItemNode &itemNode)
+{
+ QList<QmlItemNode> siblingList;
+
+ if (itemNode.isValid() && itemNode.modelNode().parentProperty().isValid()) {
+ QList<ModelNode> modelNodes = itemNode.modelNode().parentProperty().parentModelNode().allDirectSubModelNodes();
+ foreach (const ModelNode &node, modelNodes) {
+ QmlItemNode childItemNode = node;
+ if (childItemNode.isValid())
+ siblingList.append(childItemNode);
+ }
+ }
+
+ return siblingList;
+}
+
+static signed int getMaxZValue(const QList<QmlItemNode> &siblingList)
+{
+ signed int maximum = INT_MIN;
+ foreach (const QmlItemNode &node, siblingList) {
+ signed int z = node.instanceValue("z").toInt();
+ if (z > maximum)
+ maximum = z;
+ }
+ return maximum;
+}
+
+static signed int getMinZValue(const QList<QmlItemNode> &siblingList)
+{
+ signed int minimum = INT_MAX;
+ foreach (const QmlItemNode &node, siblingList) {
+ signed int z = node.instanceValue("z").toInt();
+ if (z < minimum)
+ minimum = z;
+ }
+ return minimum;
+}
+
+static inline void getWidthHeight(const ModelNode &node, int &width, int &height)
+{
+ QmlItemNode itemNode(node);
+ if (itemNode.isValid()) {
+ width = itemNode.instanceValue("width").toInt();
+ height = itemNode.instanceValue("height").toInt();
+ }
+}
+
+static inline bool modelNodesHaveProperty(const QList<ModelNode> &modelNodeList, const QString &propertyName)
+{
+ foreach (const ModelNode &modelNode, modelNodeList)
+ if (modelNode.hasProperty(propertyName))
+ return true;
+
+ return false;
+}
+
+void ModelNodeOperations::goIntoComponent(const ModelNode &modelNode)
+{
+ ComponentUtils::goIntoComponent(modelNode);
+}
+
+void ModelNodeOperations::select(const SelectionContext &selectionState)
+{
+ if (selectionState.view())
+ selectionState.view()->setSelectedModelNodes(QList<ModelNode>() << selectionState.targetNode());
+}
+
+void ModelNodeOperations::deSelect(const SelectionContext &selectionState)
+{
+ if (selectionState.view()) {
+ QList<ModelNode> selectedNodes = selectionState.view()->selectedModelNodes();
+ foreach (const ModelNode &node, selectionState.selectedModelNodes()) {
+ if (selectedNodes.contains(node))
+ selectedNodes.removeAll(node);
+ }
+ selectionState.view()->setSelectedModelNodes(selectedNodes);
+ }
+}
+
+void ModelNodeOperations::cut(const SelectionContext &)
+{
+}
+
+
+void ModelNodeOperations::copy(const SelectionContext &)
+{
+}
+
+void ModelNodeOperations::deleteSelection(const SelectionContext &)
+{
+}
+
+void ModelNodeOperations::toFront(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ try {
+ QmlItemNode node = selectionState.selectedModelNodes().first();
+ if (node.isValid()) {
+ signed int maximumZ = getMaxZValue(siblingsForNode(node));
+ maximumZ++;
+ node.setVariantProperty("z", maximumZ);
+ }
+ } catch (RewritingException &e) { //better save then sorry
+ QMessageBox::warning(0, "Error", e.description());
+ }
+}
+
+
+void ModelNodeOperations::toBack(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+ try {
+ QmlItemNode node = selectionState.selectedModelNodes().first();
+ if (node.isValid()) {
+ signed int minimumZ = getMinZValue(siblingsForNode(node));
+ minimumZ--;
+ node.setVariantProperty("z", minimumZ);
+ }
+
+ } catch (RewritingException &e) { //better save then sorry
+ QMessageBox::warning(0, "Error", e.description());
+ }
+}
+
+void ModelNodeOperations::raise(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ try {
+ RewriterTransaction transaction(selectionState.view());
+ foreach (ModelNode modelNode, selectionState.selectedModelNodes()) {
+ QmlItemNode node = modelNode;
+ if (node.isValid()) {
+ signed int z = node.instanceValue("z").toInt();
+ z++;
+ node.setVariantProperty("z", z);
+ }
+ }
+ } catch (RewritingException &e) { //better save then sorry
+ QMessageBox::warning(0, "Error", e.description());
+ }
+}
+
+void ModelNodeOperations::lower(const SelectionContext &selectionState)
+{
+
+ if (!selectionState.view())
+ return;
+
+ try {
+ RewriterTransaction transaction(selectionState.view());
+ foreach (ModelNode modelNode, selectionState.selectedModelNodes()) {
+ QmlItemNode node = modelNode;
+ if (node.isValid()) {
+ signed int z = node.instanceValue("z").toInt();
+ z--;
+ node.setVariantProperty("z", z);
+ }
+ }
+ } catch (RewritingException &e) { //better save then sorry
+ QMessageBox::warning(0, "Error", e.description());
+ }
+}
+
+void ModelNodeOperations::paste(const SelectionContext &)
+{
+}
+
+void ModelNodeOperations::undo(const SelectionContext &)
+{
+}
+
+void ModelNodeOperations::redo(const SelectionContext &)
+{
+}
+
+void ModelNodeOperations::setVisible(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ try {
+ selectionState.selectedModelNodes().first().variantProperty("visible") = selectionState.toggled();
+ } catch (RewritingException &e) { //better save then sorry
+ QMessageBox::warning(0, "Error", e.description());
+ }
+}
+
+
+void ModelNodeOperations::resetSize(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ try {
+ RewriterTransaction transaction(selectionState.view());
+ foreach (ModelNode node, selectionState.selectedModelNodes()) {
+ node.removeProperty("width");
+ node.removeProperty("height");
+ }
+ } catch (RewritingException &e) { //better save then sorry
+ QMessageBox::warning(0, "Error", e.description());
+ }
+}
+
+void ModelNodeOperations::resetPosition(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ try {
+ RewriterTransaction transaction(selectionState.view());
+ foreach (ModelNode node, selectionState.selectedModelNodes()) {
+ node.removeProperty("x");
+ node.removeProperty("y");
+ }
+ } catch (RewritingException &e) { //better save then sorry
+ QMessageBox::warning(0, "Error", e.description());
+ }
+}
+
+void ModelNodeOperations::goIntoComponent(const SelectionContext &selectionState)
+{
+ goIntoComponent(selectionState.currentSingleSelectedNode());
+}
+
+void ModelNodeOperations::setId(const SelectionContext &)
+{
+}
+
+void ModelNodeOperations::resetZ(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ RewriterTransaction transaction(selectionState.view());
+ foreach (ModelNode node, selectionState.selectedModelNodes()) {
+ node.removeProperty("z");
+ }
+}
+
+static inline void backupPropertyAndRemove(ModelNode node, const QString &propertyName)
+{
+ if (node.hasVariantProperty(propertyName)) {
+ node.setAuxiliaryData(auxDataString + propertyName, node.variantProperty(propertyName).value());
+ node.removeProperty(propertyName);
+
+ }
+ if (node.hasBindingProperty(propertyName)) {
+ node.setAuxiliaryData(auxDataString + propertyName, QmlItemNode(node).instanceValue(propertyName));
+ node.removeProperty(propertyName);
+ }
+}
+
+
+static inline void restoreProperty(ModelNode node, const QString &propertyName)
+{
+ if (node.hasAuxiliaryData(auxDataString + propertyName))
+ node.variantProperty(propertyName) = node.auxiliaryData(auxDataString + propertyName);
+}
+
+void ModelNodeOperations::anchorsFill(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ RewriterTransaction transaction(selectionState.view());
+
+ ModelNode modelNode = selectionState.currentSingleSelectedNode();
+
+ QmlItemNode node = modelNode;
+ if (node.isValid()) {
+ node.anchors().fill();
+ backupPropertyAndRemove(modelNode, QLatin1String("x"));
+ backupPropertyAndRemove(modelNode, QLatin1String("y"));
+ backupPropertyAndRemove(modelNode, QLatin1String("width"));
+ backupPropertyAndRemove(modelNode, QLatin1String("height"));
+ }
+}
+
+void ModelNodeOperations::anchorsReset(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ RewriterTransaction transaction(selectionState.view());
+
+ ModelNode modelNode = selectionState.currentSingleSelectedNode();
+
+ QmlItemNode node = modelNode;
+ if (node.isValid()) {
+ node.anchors().removeAnchors();
+ node.anchors().removeMargins();
+ restoreProperty(node, "x");
+ restoreProperty(node, "y");
+ restoreProperty(node, "width");
+ restoreProperty(node, "height");
+ }
+}
+
+static inline void reparentTo(const ModelNode &node, const QmlItemNode &parent)
+{
+
+ if (parent.isValid() && node.isValid()) {
+ NodeAbstractProperty parentProperty;
+
+ if (parent.hasDefaultProperty()) {
+ parentProperty = parent.nodeAbstractProperty(parent.defaultProperty());
+ } else {
+ parentProperty = parent.nodeAbstractProperty(QLatin1String("data"));
+ }
+
+ parentProperty.reparentHere(node);
+ }
+}
+
+
+bool compareByX(const ModelNode &node1, const ModelNode &node2)
+{
+ QmlItemNode itemNode1 = QmlItemNode(node1);
+ QmlItemNode itemNode2 = QmlItemNode(node2);
+ if (itemNode1.isValid() && itemNode2.isValid())
+ return itemNode1.instancePosition().x() < itemNode2.instancePosition().x();
+ return false;
+}
+
+bool compareByY(const ModelNode &node1, const ModelNode &node2)
+{
+ QmlItemNode itemNode1 = QmlItemNode(node1);
+ QmlItemNode itemNode2 = QmlItemNode(node2);
+ if (itemNode1.isValid() && itemNode2.isValid())
+ return itemNode1.instancePosition().y() < itemNode2.instancePosition().y();
+ return false;
+}
+
+bool compareByGrid(const ModelNode &node1, const ModelNode &node2)
+{
+ QmlItemNode itemNode1 = QmlItemNode(node1);
+ QmlItemNode itemNode2 = QmlItemNode(node2);
+ if (itemNode1.isValid() && itemNode2.isValid()) {
+ if ((itemNode1.instancePosition().y() + itemNode1.instanceSize().height()) < itemNode2.instancePosition().y())
+ return true;
+ if ((itemNode2.instancePosition().y() + itemNode2.instanceSize().height()) < itemNode1.instancePosition().y())
+ return false; //first sort y (rows)
+ return itemNode1.instancePosition().x() < itemNode2.instancePosition().x();
+ }
+ return false;
+}
+
+static inline QPoint getUpperLeftPosition(const QList<ModelNode> &modelNodeList)
+{
+ QPoint p(INT_MAX, INT_MAX);
+ foreach (ModelNode modelNode, modelNodeList) {
+ QmlItemNode itemNode = QmlItemNode(modelNode);
+ if (itemNode.isValid()) {
+ if (itemNode.instancePosition().x() < p.x())
+ p.setX(itemNode.instancePosition().x());
+ if (itemNode.instancePosition().y() < p.y())
+ p.setY(itemNode.instancePosition().y());
+ }
+ }
+ return p;
+}
+
+void ModelNodeOperations::layoutRow(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ NodeMetaInfo rowMetaInfo = selectionState.view()->model()->metaInfo(QLatin1String("QtQuick.Row"));
+
+ if (!rowMetaInfo.isValid())
+ return;
+
+ QList<ModelNode> modelNodeList = selectionState.selectedModelNodes();
+
+ ModelNode row;
+ {
+ RewriterTransaction transaction(selectionState.view());
+
+ QmlItemNode parent = QmlItemNode(modelNodeList.first()).instanceParent().toQmlItemNode();
+ if (!parent.isValid())
+ return;
+
+ qDebug() << parent.modelNode().majorQtQuickVersion();
+
+ row = selectionState.view()->createModelNode(QLatin1String("QtQuick.Row"), rowMetaInfo.majorVersion(), rowMetaInfo.minorVersion());
+
+ reparentTo(row, parent);
+ }
+
+ {
+ RewriterTransaction transaction(selectionState.view());
+
+ QPoint pos = getUpperLeftPosition(modelNodeList);
+ row.variantProperty(QLatin1String("x")) = pos.x();
+ row.variantProperty(QLatin1String("y")) = pos.y();
+
+ QList<ModelNode> sortedList = modelNodeList;
+ qSort(sortedList.begin(), sortedList.end(), compareByX);
+
+ foreach (ModelNode modelNode, sortedList) {
+ reparentTo(modelNode, row);
+ modelNode.removeProperty(QLatin1String("x"));
+ modelNode.removeProperty(QLatin1String("y"));
+ }
+ }
+}
+
+void ModelNodeOperations::layoutColumn(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ NodeMetaInfo columnMetaInfo = selectionState.view()->model()->metaInfo(QLatin1String("QtQuick.Column"));
+
+ if (!columnMetaInfo.isValid())
+ return;
+
+ QList<ModelNode> modelNodeList = selectionState.selectedModelNodes();
+
+ ModelNode column;
+ {
+ RewriterTransaction transaction(selectionState.view());
+
+ QmlItemNode parent = QmlItemNode(modelNodeList.first()).instanceParent().toQmlItemNode();
+ if (!parent.isValid())
+ return;
+
+ column = selectionState.view()->createModelNode(QLatin1String("QtQuick.Column"), columnMetaInfo.majorVersion(), columnMetaInfo.minorVersion());
+
+ reparentTo(column, parent);
+ }
+
+ {
+ RewriterTransaction transaction(selectionState.view());
+
+ QPoint pos = getUpperLeftPosition(modelNodeList);
+ column.variantProperty(QLatin1String("x")) = pos.x();
+ column.variantProperty(QLatin1String("y")) = pos.y();
+
+ QList<ModelNode> sortedList = modelNodeList;
+ qSort(sortedList.begin(), sortedList.end(), compareByY);
+
+ foreach (ModelNode modelNode, sortedList) {
+ reparentTo(modelNode, column);
+ modelNode.removeProperty(QLatin1String("x"));
+ modelNode.removeProperty(QLatin1String("y"));
+ }
+ }
+}
+
+void ModelNodeOperations::layoutGrid(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ NodeMetaInfo gridMetaInfo = selectionState.view()->model()->metaInfo(QLatin1String("QtQuick.Grid"));
+
+ if (!gridMetaInfo.isValid())
+ return;
+
+ QList<ModelNode> modelNodeList = selectionState.selectedModelNodes();
+
+ ModelNode grid;
+ {
+ RewriterTransaction transaction(selectionState.view());
+
+ QmlItemNode parent = QmlItemNode(modelNodeList.first()).instanceParent().toQmlItemNode();
+ if (!parent.isValid())
+ return;
+
+ grid = selectionState.view()->createModelNode(QLatin1String("QtQuick.Grid"), gridMetaInfo.majorVersion(), gridMetaInfo.minorVersion());
+ grid.variantProperty(QLatin1String("columns")) = int(sqrt(double(modelNodeList.count())));
+
+ reparentTo(grid, parent);
+ }
+
+ {
+ RewriterTransaction transaction(selectionState.view());
+
+ QPoint pos = getUpperLeftPosition(modelNodeList);
+ grid.variantProperty(QLatin1String("x")) = pos.x();
+ grid.variantProperty(QLatin1String("y")) = pos.y();
+
+ QList<ModelNode> sortedList = modelNodeList;
+ qSort(sortedList.begin(), sortedList.end(), compareByGrid);
+
+ foreach (ModelNode modelNode, sortedList) {
+ reparentTo(modelNode, grid);
+ modelNode.removeProperty(QLatin1String("x"));
+ modelNode.removeProperty(QLatin1String("y"));
+ }
+ }
+}
+
+void ModelNodeOperations::layoutFlow(const SelectionContext &selectionState)
+{
+ if (!selectionState.view())
+ return;
+
+ NodeMetaInfo flowMetaInfo = selectionState.view()->model()->metaInfo(QLatin1String("QtQuick.Flow"));
+
+ if (!flowMetaInfo.isValid())
+ return;
+
+ QList<ModelNode> modelNodeList = selectionState.selectedModelNodes();
+
+ ModelNode flow;
+ {
+ RewriterTransaction transaction(selectionState.view());
+
+ QmlItemNode parent = QmlItemNode(modelNodeList.first()).instanceParent().toQmlItemNode();
+ if (!parent.isValid())
+ return;
+
+ flow = selectionState.view()->createModelNode(QLatin1String("QtQuick.Flow"), flowMetaInfo.majorVersion(), flowMetaInfo.minorVersion());
+
+ reparentTo(flow, parent);
+ }
+
+ {
+ RewriterTransaction transaction(selectionState.view());
+
+ QPoint pos = getUpperLeftPosition(modelNodeList);
+ flow.variantProperty(QLatin1String("x")) = pos.x();
+ flow.variantProperty(QLatin1String("y")) = pos.y();
+
+ QList<ModelNode> sortedList = modelNodeList;
+ qSort(sortedList.begin(), sortedList.end(), compareByGrid);
+
+ foreach (ModelNode modelNode, sortedList) {
+ reparentTo(modelNode, flow);
+ modelNode.removeProperty(QLatin1String("x"));
+ modelNode.removeProperty(QLatin1String("y"));
+ }
+ }
+}
+
+} //QmlDesigner
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h
new file mode 100644
index 0000000000..da652ddc40
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef MODELNODEOPERATIONS_H
+#define MODELNODEOPERATIONS_H
+
+#include "selectioncontext.h"
+
+namespace QmlDesigner {
+
+class ModelNodeOperations
+{
+public:
+ static void goIntoComponent(const ModelNode &modelNode);
+
+ static void select(const SelectionContext &selectionState);
+ static void deSelect(const SelectionContext &selectionState);
+ static void cut(const SelectionContext &selectionState);
+ static void copy(const SelectionContext &selectionState);
+ static void deleteSelection(const SelectionContext &selectionState);
+ static void toFront(const SelectionContext &selectionState);
+ static void toBack(const SelectionContext &selectionState);
+ static void raise(const SelectionContext &selectionState);
+ static void lower(const SelectionContext &selectionState);
+ static void paste(const SelectionContext &selectionState);
+ static void undo(const SelectionContext &selectionState);
+ static void redo(const SelectionContext &selectionState);
+ static void setVisible(const SelectionContext &selectionState);
+ static void resetSize(const SelectionContext &selectionState);
+ static void resetPosition(const SelectionContext &selectionState);
+ static void goIntoComponent(const SelectionContext &selectionState);
+ static void setId(const SelectionContext &selectionState);
+ static void resetZ(const SelectionContext &selectionState);
+ static void anchorsFill(const SelectionContext &selectionState);
+ static void anchorsReset(const SelectionContext &selectionState);
+ static void layoutRow(const SelectionContext &selectionState);
+ static void layoutColumn(const SelectionContext &selectionState);
+ static void layoutGrid(const SelectionContext &selectionState);
+ static void layoutFlow(const SelectionContext &selectionState);
+};
+
+} //QmlDesigner
+
+#endif //MODELNODEOPERATIONS_H
diff --git a/src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp b/src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp
new file mode 100644
index 0000000000..d321e2dd28
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "selectioncontext.h"
+
+namespace QmlDesigner {
+
+
+SelectionContext::SelectionContext() :
+ m_view(0),
+ m_isInBaseState(false),
+ m_toggled(false)
+{
+
+}
+
+SelectionContext::SelectionContext(QmlModelView *view) :
+ m_view(view),
+ m_isInBaseState(view->currentState().isBaseState()),
+ m_toggled(false)
+{
+ if (m_view && m_view->model())
+ m_selectedModelNodes = view->selectedModelNodes();
+
+ if (m_selectedModelNodes.count()== 1) {
+ m_singleSelected = true;
+ m_currentSingleSelectedNode = m_selectedModelNodes.first();
+ } else {
+ m_singleSelected = false;
+ }
+}
+
+} //QmlDesigner
diff --git a/src/plugins/qmldesigner/components/componentcore/selectioncontext.h b/src/plugins/qmldesigner/components/componentcore/selectioncontext.h
new file mode 100644
index 0000000000..f49417d792
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/selectioncontext.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include <qmlmodelview.h>
+
+#ifndef SELECTIONCONTEXT_H
+#define SELECTIONCONTEXT_H
+
+namespace QmlDesigner {
+
+class SelectionContext {
+
+public:
+ SelectionContext();
+ SelectionContext(QmlModelView *view);
+
+ void setTargetNode(const ModelNode &modelNode)
+ { m_targetNode = modelNode; }
+
+ bool singleSelected() const
+ { return m_singleSelected; }
+
+ bool isInBaseState() const
+ { return m_isInBaseState; }
+
+ ModelNode targetNode() const
+ { return m_targetNode; }
+
+ ModelNode currentSingleSelectedNode() const
+ { return m_currentSingleSelectedNode; }
+
+ QList<ModelNode> selectedModelNodes() const
+ { return m_selectedModelNodes; }
+
+ QmlModelView *view() const
+ { return m_view; }
+
+ void setShowSelectionTools(bool show)
+ { m_showSelectionTools = show; }
+
+ bool showSelectionTools() const
+ { return m_showSelectionTools; }
+
+ QPoint scenePos() const
+ { return m_scenePos; }
+
+ void setScenePos(const QPoint &pos)
+ { m_scenePos = pos; }
+
+ void setToggled(bool b)
+ { m_toggled = b; }
+
+ bool toggled() const
+ { return m_toggled; }
+
+ bool isValid() const
+ { return view() && view()->model() && view()->nodeInstanceView(); }
+
+private:
+ QmlModelView *m_view;
+ bool m_singleSelected;
+ ModelNode m_currentSingleSelectedNode;
+ ModelNode m_targetNode;
+ bool m_isInBaseState;
+ QList<ModelNode> m_selectedModelNodes;
+ bool m_showSelectionTools;
+ QPoint m_scenePos;
+ bool m_toggled;
+};
+
+} //QmlDesigner
+
+#endif //SELECTIONCONTEXT_H
diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp
index afb145d567..b298dfb5ba 100644
--- a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp
+++ b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp
@@ -38,12 +38,13 @@
#include <metainfo.h>
#include <invalidargumentexception.h>
#include <componentaction.h>
+#include <designeractionmanager.h>
#include <qmlobjectnode.h>
#include <rewritingexception.h>
#include <nodelistproperty.h>
#include <variantproperty.h>
#include <rewritingexception.h>
-#include <modelnodecontextmenu.h>
+#include <modelnodeoperations.h>
#include <designmodewidget.h>
#include <projectexplorer/projectexplorer.h>
@@ -489,7 +490,7 @@ void DesignDocumentController::goIntoComponent()
s_clearCrumblePath = false;
if (selectedNodes.count() == 1)
- ModelNodeAction::goIntoComponent(selectedNodes.first());
+ ModelNodeOperations::goIntoComponent(selectedNodes.first());
s_clearCrumblePath = true;
}
@@ -518,6 +519,7 @@ void DesignDocumentController::loadCurrentModel()
m_model->attachView(m_propertyEditorView.data());
+ m_model->attachView(DesignerActionManager::view());
if (s_clearCrumblePath)
m_formEditorView->crumblePath()->clear();