1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "modelnodecontextmenu.h"
27 #include "modelnodecontextmenu_helper.h"
28 #include "designeractionmanager.h"
29 #include <qmldesignerplugin.h>
30
31 #include <modelnode.h>
32
33 #include <utils/algorithm.h>
34
35 #include <QSet>
36
37 namespace QmlDesigner {
38
ModelNodeContextMenu(AbstractView * view)39 ModelNodeContextMenu::ModelNodeContextMenu(AbstractView *view) :
40 m_selectionContext(view)
41 {
42 }
43
findMembers(QSet<ActionInterface * > actionInterface,const QByteArray & category)44 static QSet<ActionInterface* > findMembers(QSet<ActionInterface* > actionInterface,
45 const QByteArray &category)
46 {
47 QSet<ActionInterface* > ret;
48
49 foreach (ActionInterface* factory, actionInterface) {
50 if (factory->category() == category)
51 ret.insert(factory);
52 }
53 return ret;
54 }
55
56
populateMenu(QSet<ActionInterface * > & actionInterfaces,const QByteArray & category,QMenu * menu,const SelectionContext & selectionContext)57 void populateMenu(QSet<ActionInterface* > &actionInterfaces,
58 const QByteArray &category,
59 QMenu* menu,
60 const SelectionContext &selectionContext)
61 {
62 QSet<ActionInterface* > matchingFactories = findMembers(actionInterfaces, category);
63
64 actionInterfaces.subtract(matchingFactories);
65
66 QList<ActionInterface* > matchingFactoriesList = Utils::toList(matchingFactories);
67 Utils::sort(matchingFactoriesList, [](ActionInterface *l, ActionInterface *r) {
68 return l->priority() > r->priority();
69 });
70
71 foreach (ActionInterface* actionInterface, matchingFactoriesList) {
72 if (actionInterface->type() == ActionInterface::ContextMenu) {
73 actionInterface->currentContextChanged(selectionContext);
74 QMenu *newMenu = actionInterface->action()->menu();
75 if (newMenu && !newMenu->title().isEmpty())
76 menu->addMenu(newMenu);
77
78 //recurse
79
80 populateMenu(actionInterfaces, actionInterface->menuId(), newMenu, selectionContext);
81 } else if (actionInterface->type() == ActionInterface::ContextMenuAction
82 || actionInterface->type() == ActionInterface::Action
83 || actionInterface->type() == ActionInterface::FormEditorAction) {
84 QAction* action = actionInterface->action();
85 actionInterface->currentContextChanged(selectionContext);
86 action->setIconVisibleInMenu(false);
87 menu->addAction(action);
88 }
89 }
90 }
91
execute(const QPoint & position,bool selectionMenuBool)92 void ModelNodeContextMenu::execute(const QPoint &position, bool selectionMenuBool)
93 {
94 auto mainMenu = new QMenu();
95
96 m_selectionContext.setShowSelectionTools(selectionMenuBool);
97 m_selectionContext.setScenePosition(m_scenePos);
98
99 auto &manager = QmlDesignerPlugin::instance()->designerActionManager();
100
101 manager.setupContext();
102
103 QSet<ActionInterface* > factories = Utils::toSet(manager.designerActions());
104
105 populateMenu(factories, QByteArray(), mainMenu, m_selectionContext);
106
107 mainMenu->exec(position);
108 mainMenu->deleteLater();
109 }
110
setScenePos(const QPoint & position)111 void ModelNodeContextMenu::setScenePos(const QPoint &position)
112 {
113 m_scenePos = position;
114 }
115
showContextMenu(AbstractView * view,const QPoint & globalPosition,const QPoint & scenePosition,bool showSelection)116 void ModelNodeContextMenu::showContextMenu(AbstractView *view,
117 const QPoint &globalPosition,
118 const QPoint &scenePosition,
119 bool showSelection)
120 {
121 ModelNodeContextMenu contextMenu(view);
122 contextMenu.setScenePos(scenePosition);
123 contextMenu.execute(globalPosition, showSelection);
124 }
125
126 } //QmlDesigner
127