##// END OF EJS Templates
Moves MenuBuilder in a new class
Alexandre Leroux -
r207:76c2d7a04a27
parent child
Show More
@@ -0,0 +1,59
1 #ifndef SCIQLOP_MENUBUILDER_H
2 #define SCIQLOP_MENUBUILDER_H
3
4 #include <QLoggingCategory>
5 #include <QMenu>
6 #include <QStack>
7
8 Q_DECLARE_LOGGING_CATEGORY(LOG_MenuBuilder)
9
10 /// Helper assigned to build a hierarchical menu
11 class MenuBuilder {
12 public:
13 /**
14 * Ctor
15 * @param menu the parent menu
16 */
17 explicit MenuBuilder(QMenu *menu);
18
19 /**
20 * Adds action to the current menu
21 * @param actionName the name of the action
22 * @param actionFunction the function that will be executed when the action is triggered
23 */
24 template <typename ActionFun>
25 void addAction(const QString &actionName, ActionFun actionFunction);
26
27 /**
28 * Adds a new menu to the current menu
29 * @param name the name of the menu
30 */
31 void addMenu(const QString &name);
32
33 /// Adds a separator to the current menu. The separator is added only if the menu already
34 /// contains entries
35 void addSeparator();
36
37 /// Closes the current menu
38 void closeMenu();
39
40 private:
41 /// @return the current menu (i.e. the top menu of the stack), nullptr if there is no menu
42 QMenu *currentMenu() const;
43
44 /// Stack of all menus currently opened
45 QStack<QMenu *> m_Menus{};
46 };
47
48 template <typename ActionFun>
49 void MenuBuilder::addAction(const QString &actionName, ActionFun actionFunction)
50 {
51 if (auto currMenu = currentMenu()) {
52 currMenu->addAction(actionName, actionFunction);
53 }
54 else {
55 qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the action");
56 }
57 }
58
59 #endif // SCIQLOP_MENUBUILDER_H
@@ -0,0 +1,55
1 #include "Visualization/operations/MenuBuilder.h"
2
3 Q_LOGGING_CATEGORY(LOG_MenuBuilder, "MenuBuilder")
4
5 MenuBuilder::MenuBuilder(QMenu *menu)
6 {
7 if (menu) {
8 m_Menus.push(menu);
9 }
10 else {
11 qCCritical(LOG_MenuBuilder()) << QObject::tr("No parent menu has been defined");
12 }
13 }
14
15 void MenuBuilder::addMenu(const QString &name)
16 {
17 if (auto currMenu = currentMenu()) {
18 m_Menus.push(currMenu->addMenu(name));
19 }
20 else {
21 qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the new menu");
22 }
23 }
24
25 void MenuBuilder::addSeparator()
26 {
27 if (auto currMenu = currentMenu()) {
28 if (!currMenu->isEmpty()) {
29 currMenu->addSeparator();
30 }
31 }
32 else {
33 qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the separator");
34 }
35 }
36
37 void MenuBuilder::closeMenu()
38 {
39 if (!m_Menus.isEmpty()) {
40 if (auto closedMenu = m_Menus.pop()) {
41 // Purge menu : if the closed menu has no entries, we remove it from its parent (the
42 // current menu)
43 if (auto currMenu = currentMenu()) {
44 if (closedMenu->isEmpty()) {
45 currMenu->removeAction(closedMenu->menuAction());
46 }
47 }
48 }
49 }
50 }
51
52 QMenu *MenuBuilder::currentMenu() const
53 {
54 return !m_Menus.isEmpty() ? m_Menus.top() : nullptr;
55 }
@@ -1,220 +1,130
1 1 #include "Visualization/operations/GenerateVariableMenuOperation.h"
2 #include "Visualization/operations/MenuBuilder.h"
2 3
3 4 #include "Visualization/VisualizationGraphWidget.h"
4 5 #include "Visualization/VisualizationTabWidget.h"
5 6 #include "Visualization/VisualizationZoneWidget.h"
6 7
7 8 #include <Variable/Variable.h>
8 9
9 10 #include <QMenu>
10 11 #include <QStack>
11 12
12 13 Q_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation, "GenerateVariableMenuOperation")
13 14
14 namespace {
15
16 /// Helper assigned to build the hierarchical menu associated with a variable
17 struct MenuBuilder {
18 /**
19 * Ctor
20 * @param menu the parent menu
21 */
22 explicit MenuBuilder(QMenu *menu)
23 {
24 if (menu) {
25 m_Menus.push(menu);
26 }
27 else {
28 qCCritical(LOG_GenerateVariableMenuOperation())
29 << QObject::tr("No parent menu has been defined");
30 }
31 }
32
33 /**
34 * Adds action to the current menu
35 * @param actionName the name of the action
36 * @param actionFunction the function that will be executed when the action is triggered
37 */
38 template <typename ActionFun>
39 void addAction(const QString &actionName, ActionFun actionFunction)
40 {
41 if (auto currMenu = currentMenu()) {
42 currMenu->addAction(actionName, actionFunction);
43 }
44 else {
45 qCCritical(LOG_GenerateVariableMenuOperation())
46 << QObject::tr("No current menu to attach the action");
47 }
48 }
49
50 /**
51 * Adds a new menu to the current menu
52 * @param name the name of the menu
53 */
54 void addMenu(const QString &name)
55 {
56 if (auto currMenu = currentMenu()) {
57 m_Menus.push(currMenu->addMenu(name));
58 }
59 else {
60 qCCritical(LOG_GenerateVariableMenuOperation())
61 << QObject::tr("No current menu to attach the new menu");
62 }
63 }
64
65 /// Adds a separator to the current menu. The separator is added only if the menu already
66 /// contains entries
67 void addSeparator()
68 {
69 if (auto currMenu = currentMenu()) {
70 if (!currMenu->isEmpty()) {
71 currMenu->addSeparator();
72 }
73 }
74 else {
75 qCCritical(LOG_GenerateVariableMenuOperation())
76 << QObject::tr("No current menu to attach the separator");
77 }
78 }
79
80 /// Closes the current menu
81 void closeMenu()
82 {
83 if (!m_Menus.isEmpty()) {
84 if (auto closedMenu = m_Menus.pop()) {
85 // Purge menu : if the closed menu has no entries, we remove it from its parent (the
86 // current menu)
87 if (auto currMenu = currentMenu()) {
88 if (closedMenu->isEmpty()) {
89 currMenu->removeAction(closedMenu->menuAction());
90 }
91 }
92 }
93 }
94 }
95
96 /// @return the current menu (i.e. the top menu of the stack), nullptr if there is no menu
97 QMenu *currentMenu() const { return !m_Menus.isEmpty() ? m_Menus.top() : nullptr; }
98
99 /// Stack of all menus currently opened
100 QStack<QMenu *> m_Menus{};
101 };
102
103 } // namespace
104
105 15 struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate {
106 16 explicit GenerateVariableMenuOperationPrivate(QMenu *menu, std::shared_ptr<Variable> variable)
107 17 : m_Variable{variable}, m_MenuBuilder{menu}
108 18 {
109 19 }
110 20
111 21 void visitNodeEnter(const IVisualizationWidget &container)
112 22 {
113 23 // Opens a new menu associated to the node
114 24 m_MenuBuilder.addMenu(container.name());
115 25 }
116 26
117 27 template <typename ActionFun>
118 28 void visitNodeLeave(const IVisualizationWidget &container, const QString &actionName,
119 29 ActionFun actionFunction)
120 30 {
121 31 if (m_Variable && container.canDrop(*m_Variable)) {
122 32 m_MenuBuilder.addSeparator();
123 33 m_MenuBuilder.addAction(actionName, actionFunction);
124 34 }
125 35
126 36 // Closes the menu associated to the node
127 37 m_MenuBuilder.closeMenu();
128 38 }
129 39
130 40 template <typename ActionFun>
131 41 void visitLeaf(const IVisualizationWidget &container, const QString &actionName,
132 42 ActionFun actionFunction)
133 43 {
134 44 if (m_Variable && container.canDrop(*m_Variable)) {
135 45 m_MenuBuilder.addAction(actionName, actionFunction);
136 46 }
137 47 }
138 48
139 49 std::shared_ptr<Variable> m_Variable;
140 50 MenuBuilder m_MenuBuilder;
141 51 };
142 52
143 53 GenerateVariableMenuOperation::GenerateVariableMenuOperation(QMenu *menu,
144 54 std::shared_ptr<Variable> variable)
145 55 : impl{spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>(menu, variable)}
146 56 {
147 57 }
148 58
149 59 void GenerateVariableMenuOperation::visitEnter(VisualizationWidget *widget)
150 60 {
151 61 // VisualizationWidget is not intended to accommodate a variable
152 62 Q_UNUSED(widget)
153 63 }
154 64
155 65 void GenerateVariableMenuOperation::visitLeave(VisualizationWidget *widget)
156 66 {
157 67 // VisualizationWidget is not intended to accommodate a variable
158 68 Q_UNUSED(widget)
159 69 }
160 70
161 71 void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget *tabWidget)
162 72 {
163 73 if (tabWidget) {
164 74 impl->visitNodeEnter(*tabWidget);
165 75 }
166 76 else {
167 77 qCCritical(LOG_GenerateVariableMenuOperation(),
168 78 "Can't visit enter VisualizationTabWidget : the widget is null");
169 79 }
170 80 }
171 81
172 82 void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget)
173 83 {
174 84 if (tabWidget) {
175 85 impl->visitNodeLeave(
176 86 *tabWidget, QObject::tr("Open in a new zone"),
177 87 [ var = impl->m_Variable, tabWidget ]() { tabWidget->createZone(var); });
178 88 }
179 89 else {
180 90 qCCritical(LOG_GenerateVariableMenuOperation(),
181 91 "Can't visit leave VisualizationTabWidget : the widget is null");
182 92 }
183 93 }
184 94
185 95 void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
186 96 {
187 97 if (zoneWidget) {
188 98 impl->visitNodeEnter(*zoneWidget);
189 99 }
190 100 else {
191 101 qCCritical(LOG_GenerateVariableMenuOperation(),
192 102 "Can't visit enter VisualizationZoneWidget : the widget is null");
193 103 }
194 104 }
195 105
196 106 void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
197 107 {
198 108 if (zoneWidget) {
199 109 impl->visitNodeLeave(
200 110 *zoneWidget, QObject::tr("Open in a new graph"),
201 111 [ var = impl->m_Variable, zoneWidget ]() { zoneWidget->createGraph(var); });
202 112 }
203 113 else {
204 114 qCCritical(LOG_GenerateVariableMenuOperation(),
205 115 "Can't visit leave VisualizationZoneWidget : the widget is null");
206 116 }
207 117 }
208 118
209 119 void GenerateVariableMenuOperation::visit(VisualizationGraphWidget *graphWidget)
210 120 {
211 121 if (graphWidget) {
212 122 impl->visitLeaf(
213 123 *graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()),
214 124 [ var = impl->m_Variable, graphWidget ]() { graphWidget->addVariable(var); });
215 125 }
216 126 else {
217 127 qCCritical(LOG_GenerateVariableMenuOperation(),
218 128 "Can't visit VisualizationGraphWidget : the widget is null");
219 129 }
220 130 }
General Comments 0
You need to be logged in to leave comments. Login now