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