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