##// END OF EJS Templates
Prohibits the plot of a variable in several graphs (2)...
Alexandre Leroux -
r736:bca343a0ae6b
parent child
Show More
@@ -1,42 +1,48
1 1 #ifndef SCIQLOP_GENERATEVARIABLEMENUOPERATION_H
2 2 #define SCIQLOP_GENERATEVARIABLEMENUOPERATION_H
3 3
4 4 #include "Visualization/IVisualizationWidgetVisitor.h"
5 5
6 6 #include <Common/spimpl.h>
7 7
8 8 #include <QLoggingCategory>
9 9
10 #include <set>
11
10 12 class QMenu;
13 class IVisualizationWidget;
11 14 class Variable;
12 15
13 16 Q_DECLARE_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation)
14 17
15 18 /**
16 19 * @brief The GenerateVariableMenuOperation class defines an operation that traverses all of
17 20 * visualization widgets to determine which can accommodate a variable. The result of the operation
18 21 * is a menu that contains actions to add the variable into the containers.
19 22 */
20 23 class GenerateVariableMenuOperation : public IVisualizationWidgetVisitor {
21 24 public:
22 25 /**
23 26 * Ctor
24 27 * @param menu the menu to which to attach the generated menu
25 28 * @param variable the variable for which to generate the menu
29 * @param variableContainers the containers that already contain the variable for which to
30 * generate the menu
26 31 */
27 explicit GenerateVariableMenuOperation(QMenu *menu, std::shared_ptr<Variable> variable);
32 explicit GenerateVariableMenuOperation(QMenu *menu, std::shared_ptr<Variable> variable,
33 std::set<IVisualizationWidget *> variableContainers);
28 34
29 35 void visitEnter(VisualizationWidget *widget) override final;
30 36 void visitLeave(VisualizationWidget *widget) override final;
31 37 void visitEnter(VisualizationTabWidget *tabWidget) override final;
32 38 void visitLeave(VisualizationTabWidget *tabWidget) override final;
33 39 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
34 40 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
35 41 void visit(VisualizationGraphWidget *graphWidget) override final;
36 42
37 43 private:
38 44 class GenerateVariableMenuOperationPrivate;
39 45 spimpl::unique_impl_ptr<GenerateVariableMenuOperationPrivate> impl;
40 46 };
41 47
42 48 #endif // SCIQLOP_GENERATEVARIABLEMENUOPERATION_H
@@ -1,152 +1,159
1 1 #include "Visualization/VisualizationWidget.h"
2 2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 3 #include "Visualization/VisualizationGraphWidget.h"
4 4 #include "Visualization/VisualizationTabWidget.h"
5 5 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/operations/FindVariableOperation.h"
6 7 #include "Visualization/operations/GenerateVariableMenuOperation.h"
7 8 #include "Visualization/operations/RemoveVariableOperation.h"
8 9 #include "Visualization/operations/RescaleAxeOperation.h"
9 10 #include "Visualization/qcustomplot.h"
10 11
11 12 #include "ui_VisualizationWidget.h"
12 13
13 14 #include <QToolButton>
14 15
15 16 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
16 17
17 18 VisualizationWidget::VisualizationWidget(QWidget *parent)
18 19 : QWidget{parent}, ui{new Ui::VisualizationWidget}
19 20 {
20 21 ui->setupUi(this);
21 22
22 23 auto addTabViewButton = new QToolButton{ui->tabWidget};
23 24 addTabViewButton->setText(tr("Add View"));
24 25 addTabViewButton->setCursor(Qt::ArrowCursor);
25 26 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
26 27
27 28 auto enableMinimumCornerWidgetSize = [this](bool enable) {
28 29
29 30 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
30 31 auto width = enable ? tabViewCornerWidget->width() : 0;
31 32 auto height = enable ? tabViewCornerWidget->height() : 0;
32 33 tabViewCornerWidget->setMinimumHeight(height);
33 34 tabViewCornerWidget->setMinimumWidth(width);
34 35 ui->tabWidget->setMinimumHeight(height);
35 36 ui->tabWidget->setMinimumWidth(width);
36 37 };
37 38
38 39 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
39 40 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
40 41 ui->tabWidget};
41 42 auto index = ui->tabWidget->addTab(widget, widget->name());
42 43 if (ui->tabWidget->count() > 0) {
43 44 enableMinimumCornerWidgetSize(false);
44 45 }
45 46 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
46 47 };
47 48
48 49 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
49 50 if (ui->tabWidget->count() == 1) {
50 51 enableMinimumCornerWidgetSize(true);
51 52 }
52 53
53 54 // Removes widget from tab and closes it
54 55 auto widget = ui->tabWidget->widget(index);
55 56 ui->tabWidget->removeTab(index);
56 57 if (widget) {
57 58 widget->close();
58 59 }
59 60
60 61 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
61 62
62 63 };
63 64
64 65 ui->tabWidget->setTabsClosable(true);
65 66
66 67 connect(addTabViewButton, &QToolButton::clicked, addTabView);
67 68 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
68 69
69 70 // Adds default tab
70 71 addTabView();
71 72 }
72 73
73 74 VisualizationWidget::~VisualizationWidget()
74 75 {
75 76 delete ui;
76 77 }
77 78
78 79 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
79 80 {
80 81 if (visitor) {
81 82 visitor->visitEnter(this);
82 83
83 84 // Apply visitor for tab children
84 85 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
85 86 // Widgets different from tabs are not visited (no action)
86 87 if (auto visualizationTabWidget
87 88 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
88 89 visualizationTabWidget->accept(visitor);
89 90 }
90 91 }
91 92
92 93 visitor->visitLeave(this);
93 94 }
94 95 else {
95 96 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
96 97 }
97 98 }
98 99
99 100 bool VisualizationWidget::canDrop(const Variable &variable) const
100 101 {
101 102 // The main widget can never accomodate a variable
102 103 Q_UNUSED(variable);
103 104 return false;
104 105 }
105 106
106 107 bool VisualizationWidget::contains(const Variable &variable) const
107 108 {
108 109 Q_UNUSED(variable);
109 110 return false;
110 111 }
111 112
112 113 QString VisualizationWidget::name() const
113 114 {
114 115 return QStringLiteral("MainView");
115 116 }
116 117
117 118 void VisualizationWidget::attachVariableMenu(
118 119 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
119 120 {
120 121 // Menu is generated only if there is a single variable
121 122 if (variables.size() == 1) {
122 123 if (auto variable = variables.first()) {
124 // Gets the containers of the variable
125 FindVariableOperation findVariableOperation{variable};
126 accept(&findVariableOperation);
127 auto variableContainers = findVariableOperation.result();
128
123 129 // Generates the actions that make it possible to visualize the variable
124 auto generateVariableMenuOperation = GenerateVariableMenuOperation{menu, variable};
130 GenerateVariableMenuOperation generateVariableMenuOperation{
131 menu, variable, std::move(variableContainers)};
125 132 accept(&generateVariableMenuOperation);
126 133 }
127 134 else {
128 135 qCCritical(LOG_VisualizationWidget()) << tr(
129 136 "Can't generate the menu relative to the visualization: the variable is null");
130 137 }
131 138 }
132 139 else {
133 140 qCDebug(LOG_VisualizationWidget())
134 141 << tr("No generation of the menu related to the visualization: several variables are "
135 142 "selected");
136 143 }
137 144 }
138 145
139 146 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
140 147 {
141 148 // Calls the operation of removing all references to the variable in the visualization
142 149 auto removeVariableOperation = RemoveVariableOperation{variable};
143 150 accept(&removeVariableOperation);
144 151 }
145 152
146 153 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
147 154 const SqpRange &range) noexcept
148 155 {
149 156 // Calls the operation of rescaling all graph that contrains variable in the visualization
150 157 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
151 158 accept(&rescaleVariableOperation);
152 159 }
@@ -1,201 +1,216
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 explicit GenerateVariableMenuOperationPrivate(QMenu *menu, std::shared_ptr<Variable> variable)
17 : m_Variable{variable}, m_PlotMenuBuilder{menu}, m_UnplotMenuBuilder{menu}
16 explicit GenerateVariableMenuOperationPrivate(
17 QMenu *menu, std::shared_ptr<Variable> variable,
18 std::set<IVisualizationWidget *> variableContainers)
19 : m_Variable{variable},
20 m_PlotMenuBuilder{menu},
21 m_UnplotMenuBuilder{menu},
22 m_VariableContainers{std::move(variableContainers)}
18 23 {
19 24 }
20 25
21 26 void visitRootEnter()
22 27 {
23 28 // Creates the root menu
24 29 if (auto plotMenu
25 30 = m_PlotMenuBuilder.addMenu(QObject::tr("Plot"), QIcon{":/icones/plot.png"})) {
26 31 plotMenu->setEnabled(m_Variable && m_Variable->dataSeries() != nullptr);
27 32 }
28 33
29 34 m_UnplotMenuBuilder.addMenu(QObject::tr("Unplot"), QIcon{":/icones/unplot.png"});
30 35 }
31 36
32 37 void visitRootLeave()
33 38 {
34 39 // Closes the root menu
35 40 m_PlotMenuBuilder.closeMenu();
36 41 m_UnplotMenuBuilder.closeMenu();
37 42 }
38 43
39 44 void visitNodeEnter(const IVisualizationWidget &container)
40 45 {
41 46 // Opens a new menu associated to the node
42 47 m_PlotMenuBuilder.addMenu(container.name());
43 48 m_UnplotMenuBuilder.addMenu(container.name());
44 49 }
45 50
46 51 template <typename ActionFun>
47 52 void visitNodeLeavePlot(const IVisualizationWidget &container, const QString &actionName,
48 53 ActionFun actionFunction)
49 54 {
50 if (m_Variable && container.canDrop(*m_Variable)) {
55 if (isValidContainer(container)) {
51 56 m_PlotMenuBuilder.addSeparator();
52 57 m_PlotMenuBuilder.addAction(actionName, actionFunction);
53 58 }
54 59
55 60 // Closes the menu associated to the node
56 61 m_PlotMenuBuilder.closeMenu();
57 62 }
58 63
59 64 void visitNodeLeaveUnplot()
60 65 {
61 66 // Closes the menu associated to the node
62 67 m_UnplotMenuBuilder.closeMenu();
63 68 }
64 69
65 70 template <typename ActionFun>
66 71 void visitLeafPlot(const IVisualizationWidget &container, const QString &actionName,
67 72 ActionFun actionFunction)
68 73 {
69 if (m_Variable && container.canDrop(*m_Variable)) {
74 if (isValidContainer(container)) {
70 75 m_PlotMenuBuilder.addAction(actionName, actionFunction);
71 76 }
72 77 }
73 78
74 79 template <typename ActionFun>
75 void visitLeafUnplot(const IVisualizationWidget &container, const QString &actionName,
80 void visitLeafUnplot(IVisualizationWidget *container, const QString &actionName,
76 81 ActionFun actionFunction)
77 82 {
78 if (m_Variable && container.contains(*m_Variable)) {
83 // If the container contains the variable, we generate 'unplot' action
84 if (m_VariableContainers.count(container) == 1) {
79 85 m_UnplotMenuBuilder.addAction(actionName, actionFunction);
80 86 }
81 87 }
82 88
89 bool isValidContainer(const IVisualizationWidget &container) const noexcept
90 {
91 // A container is valid if it can contain the variable and if the variable is not already
92 // contained in another container
93 return m_Variable && m_VariableContainers.size() == 0 && container.canDrop(*m_Variable);
94 }
95
83 96 std::shared_ptr<Variable> m_Variable;
97 std::set<IVisualizationWidget *> m_VariableContainers;
84 98 MenuBuilder m_PlotMenuBuilder; ///< Builder for the 'Plot' menu
85 99 MenuBuilder m_UnplotMenuBuilder; ///< Builder for the 'Unplot' menu
86 100 };
87 101
88 GenerateVariableMenuOperation::GenerateVariableMenuOperation(QMenu *menu,
89 std::shared_ptr<Variable> variable)
90 : impl{spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>(menu, variable)}
102 GenerateVariableMenuOperation::GenerateVariableMenuOperation(
103 QMenu *menu, std::shared_ptr<Variable> variable,
104 std::set<IVisualizationWidget *> variableContainers)
105 : impl{spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>(
106 menu, variable, std::move(variableContainers))}
91 107 {
92 108 }
93 109
94 110 void GenerateVariableMenuOperation::visitEnter(VisualizationWidget *widget)
95 111 {
96 112 // VisualizationWidget is not intended to accommodate a variable
97 113 Q_UNUSED(widget)
98 114
99 115 // 'Plot' and 'Unplot' menus
100 116 impl->visitRootEnter();
101 117 }
102 118
103 119 void GenerateVariableMenuOperation::visitLeave(VisualizationWidget *widget)
104 120 {
105 121 // VisualizationWidget is not intended to accommodate a variable
106 122 Q_UNUSED(widget)
107 123
108 124 // 'Plot' and 'Unplot' menus
109 125 impl->visitRootLeave();
110 126 }
111 127
112 128 void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget *tabWidget)
113 129 {
114 130 if (tabWidget) {
115 131 // 'Plot' and 'Unplot' menus
116 132 impl->visitNodeEnter(*tabWidget);
117 133 }
118 134 else {
119 135 qCCritical(LOG_GenerateVariableMenuOperation(),
120 136 "Can't visit enter VisualizationTabWidget : the widget is null");
121 137 }
122 138 }
123 139
124 140 void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget)
125 141 {
126 142 if (tabWidget) {
127 143 // 'Plot' menu
128 144 impl->visitNodeLeavePlot(*tabWidget, QObject::tr("Open in a new zone"),
129 145 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, tabWidget ]() {
130 146 if (auto var = varW.lock()) {
131 147 tabWidget->createZone(var);
132 148 }
133 149 });
134 150
135 151 // 'Unplot' menu
136 152 impl->visitNodeLeaveUnplot();
137 153 }
138 154 else {
139 155 qCCritical(LOG_GenerateVariableMenuOperation(),
140 156 "Can't visit leave VisualizationTabWidget : the widget is null");
141 157 }
142 158 }
143 159
144 160 void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
145 161 {
146 162 if (zoneWidget) {
147 163 // 'Plot' and 'Unplot' menus
148 164 impl->visitNodeEnter(*zoneWidget);
149 165 }
150 166 else {
151 167 qCCritical(LOG_GenerateVariableMenuOperation(),
152 168 "Can't visit enter VisualizationZoneWidget : the widget is null");
153 169 }
154 170 }
155 171
156 172 void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
157 173 {
158 qCCritical(LOG_GenerateVariableMenuOperation(), "Open in a new graph DETECTED !!");
159 174 if (zoneWidget) {
160 175 // 'Plot' menu
161 176 impl->visitNodeLeavePlot(
162 177 *zoneWidget, QObject::tr("Open in a new graph"),
163 178 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, zoneWidget ]() {
164 179 if (auto var = varW.lock()) {
165 180 zoneWidget->createGraph(var);
166 181 }
167 182 });
168 183
169 184 // 'Unplot' menu
170 185 impl->visitNodeLeaveUnplot();
171 186 }
172 187 else {
173 188 qCCritical(LOG_GenerateVariableMenuOperation(),
174 189 "Can't visit leave VisualizationZoneWidget : the widget is null");
175 190 }
176 191 }
177 192
178 193 void GenerateVariableMenuOperation::visit(VisualizationGraphWidget *graphWidget)
179 194 {
180 195 if (graphWidget) {
181 196 // 'Plot' menu
182 197 impl->visitLeafPlot(*graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()),
183 198 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, graphWidget ]() {
184 199 if (auto var = varW.lock()) {
185 200 graphWidget->addVariable(var, graphWidget->graphRange());
186 201 }
187 202 });
188 203
189 204 // 'Unplot' menu
190 impl->visitLeafUnplot(*graphWidget, QObject::tr("Remove from %1").arg(graphWidget->name()),
205 impl->visitLeafUnplot(graphWidget, QObject::tr("Remove from %1").arg(graphWidget->name()),
191 206 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, graphWidget ]() {
192 207 if (auto var = varW.lock()) {
193 208 graphWidget->removeVariable(var);
194 209 }
195 210 });
196 211 }
197 212 else {
198 213 qCCritical(LOG_GenerateVariableMenuOperation(),
199 214 "Can't visit VisualizationGraphWidget : the widget is null");
200 215 }
201 216 }
General Comments 0
You need to be logged in to leave comments. Login now