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