##// END OF EJS Templates
Unplot menu (5): adds contains() method to an IVariableContainer...
Alexandre Leroux -
r327:87af69bdce8a
parent child
Show More
@@ -1,19 +1,22
1 1 #ifndef SCIQLOP_IVARIABLECONTAINER_H
2 2 #define SCIQLOP_IVARIABLECONTAINER_H
3 3
4 4 class Variable;
5 5
6 6 /**
7 7 * @brief The IVariableContainer interface represents an UI object that can accommodate a variable
8 8 */
9 9 class IVariableContainer {
10 10
11 11 public:
12 12 virtual ~IVariableContainer() = default;
13 13
14 14 /// Checks if the container can handle the variable passed in parameter
15 15 virtual bool canDrop(const Variable &variable) const = 0;
16
17 /// Checks if the container contains the variable passed in parameter
18 virtual bool contains(const Variable &variable) const = 0;
16 19 };
17 20
18 21
19 22 #endif // SCIQLOP_IVARIABLECONTAINER_H
@@ -1,64 +1,65
1 1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
3 3
4 4 #include "Visualization/IVisualizationWidget.h"
5 5
6 6 #include <QLoggingCategory>
7 7 #include <QWidget>
8 8
9 9 #include <memory>
10 10
11 11 #include <Common/spimpl.h>
12 12
13 13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
14 14
15 15 class QCPRange;
16 16 class SqpDateTime;
17 17 class Variable;
18 18
19 19 namespace Ui {
20 20 class VisualizationGraphWidget;
21 21 } // namespace Ui
22 22
23 23 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
24 24 Q_OBJECT
25 25
26 26 public:
27 27 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
28 28 virtual ~VisualizationGraphWidget();
29 29
30 30 void addVariable(std::shared_ptr<Variable> variable);
31 31 void addVariableUsingGraph(std::shared_ptr<Variable> variable);
32 32 /// Removes a variable from the graph
33 33 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
34 34
35 35 // IVisualizationWidget interface
36 36 void accept(IVisualizationWidgetVisitor *visitor) override;
37 37 bool canDrop(const Variable &variable) const override;
38 bool contains(const Variable &variable) const override;
38 39 QString name() const override;
39 40
40 41 void updateDisplay(std::shared_ptr<Variable> variable);
41 42
42 43 signals:
43 44 void requestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
44 45
45 46
46 47 private:
47 48 Ui::VisualizationGraphWidget *ui;
48 49
49 50 class VisualizationGraphWidgetPrivate;
50 51 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
51 52
52 53 private slots:
53 54 /// Slot called when right clicking on the graph (displays a menu)
54 55 void onGraphMenuRequested(const QPoint &pos) noexcept;
55 56
56 57 void onRangeChanged(const QCPRange &t1);
57 58
58 59 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
59 60 void onMouseWheel(QWheelEvent *event) noexcept;
60 61
61 62 void onDataCacheVariableUpdated();
62 63 };
63 64
64 65 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,53 +1,54
1 1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
2 2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
3 3
4 4 #include "Visualization/IVisualizationWidget.h"
5 5
6 6 #include <Common/spimpl.h>
7 7
8 8 #include <QLoggingCategory>
9 9 #include <QWidget>
10 10
11 11 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
12 12
13 13 class Variable;
14 14 class VisualizationZoneWidget;
15 15
16 16 namespace Ui {
17 17 class VisualizationTabWidget;
18 18 } // namespace Ui
19 19
20 20 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
21 21 Q_OBJECT
22 22
23 23 public:
24 24 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
25 25 virtual ~VisualizationTabWidget();
26 26
27 27 /// Add a zone widget
28 28 void addZone(VisualizationZoneWidget *zoneWidget);
29 29
30 30 /**
31 31 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
32 32 * zone.
33 33 * @param variable the variable for which to create the zone
34 34 * @return the pointer to the created zone
35 35 */
36 36 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
37 37
38 38 // IVisualizationWidget interface
39 39 void accept(IVisualizationWidgetVisitor *visitor) override;
40 40 bool canDrop(const Variable &variable) const override;
41 bool contains(const Variable &variable) const override;
41 42 QString name() const override;
42 43
43 44 private:
44 45 /// @return the layout of tab in which zones are added
45 46 QLayout &tabLayout() const noexcept;
46 47
47 48 Ui::VisualizationTabWidget *ui;
48 49
49 50 class VisualizationTabWidgetPrivate;
50 51 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
51 52 };
52 53
53 54 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
@@ -1,44 +1,45
1 1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
2 2 #define SCIQLOP_VISUALIZATIONWIDGET_H
3 3
4 4 #include "Visualization/IVisualizationWidget.h"
5 5
6 6 #include <QLoggingCategory>
7 7 #include <QWidget>
8 8
9 9 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
10 10
11 11 class QMenu;
12 12 class Variable;
13 13 class VisualizationTabWidget;
14 14
15 15 namespace Ui {
16 16 class VisualizationWidget;
17 17 } // namespace Ui
18 18
19 19 class VisualizationWidget : public QWidget, public IVisualizationWidget {
20 20 Q_OBJECT
21 21
22 22 public:
23 23 explicit VisualizationWidget(QWidget *parent = 0);
24 24 virtual ~VisualizationWidget();
25 25
26 26 // IVisualizationWidget interface
27 27 void accept(IVisualizationWidgetVisitor *visitor) override;
28 28 bool canDrop(const Variable &variable) const override;
29 bool contains(const Variable &variable) const override;
29 30 QString name() const override;
30 31
31 32 public slots:
32 33 /**
33 34 * Attaches to a menu the menu relative to the visualization of variables
34 35 * @param menu the parent menu of the generated menu
35 36 * @param variables the variables for which to generate the menu
36 37 */
37 38 void attachVariableMenu(QMenu *menu,
38 39 const QVector<std::shared_ptr<Variable> > &variables) noexcept;
39 40
40 41 private:
41 42 Ui::VisualizationWidget *ui;
42 43 };
43 44
44 45 #endif // VISUALIZATIONWIDGET_H
@@ -1,44 +1,45
1 1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
3 3
4 4 #include "Visualization/IVisualizationWidget.h"
5 5
6 6 #include <QLoggingCategory>
7 7 #include <QWidget>
8 8
9 9 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
10 10
11 11 namespace Ui {
12 12 class VisualizationZoneWidget;
13 13 } // Ui
14 14
15 15 class Variable;
16 16 class VisualizationGraphWidget;
17 17
18 18 class VisualizationZoneWidget : public QWidget, public IVisualizationWidget {
19 19 Q_OBJECT
20 20
21 21 public:
22 22 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
23 23 virtual ~VisualizationZoneWidget();
24 24
25 25 /// Add a graph widget
26 26 void addGraph(VisualizationGraphWidget *graphWidget);
27 27
28 28 /**
29 29 * Creates a graph using a variable. The variable will be displayed in the new graph.
30 30 * @param variable the variable for which to create the graph
31 31 * @return the pointer to the created graph
32 32 */
33 33 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
34 34
35 35 // IVisualizationWidget interface
36 36 void accept(IVisualizationWidgetVisitor *visitor) override;
37 37 bool canDrop(const Variable &variable) const override;
38 bool contains(const Variable &variable) const override;
38 39 QString name() const override;
39 40
40 41 private:
41 42 Ui::VisualizationZoneWidget *ui;
42 43 };
43 44
44 45 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -1,273 +1,285
1 1 #include "Visualization/VisualizationGraphWidget.h"
2 2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 3 #include "Visualization/VisualizationGraphHelper.h"
4 4 #include "ui_VisualizationGraphWidget.h"
5 5
6 6 #include <Data/ArrayData.h>
7 7 #include <Data/IDataSeries.h>
8 8 #include <SqpApplication.h>
9 9 #include <Variable/Variable.h>
10 10 #include <Variable/VariableController.h>
11 11
12 12 #include <unordered_map>
13 13
14 14 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
15 15
16 16 namespace {
17 17
18 18 /// Key pressed to enable zoom on horizontal axis
19 19 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
20 20
21 21 /// Key pressed to enable zoom on vertical axis
22 22 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
23 23
24 24 } // namespace
25 25
26 26 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
27 27
28 28 // 1 variable -> n qcpplot
29 29 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
30 30 };
31 31
32 32 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
33 33 : QWidget{parent},
34 34 ui{new Ui::VisualizationGraphWidget},
35 35 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
36 36 {
37 37 ui->setupUi(this);
38 38
39 39 ui->graphNameLabel->setText(name);
40 40
41 41 // 'Close' options : widget is deleted when closed
42 42 setAttribute(Qt::WA_DeleteOnClose);
43 43 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
44 44 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
45 45
46 46 // Set qcpplot properties :
47 47 // - Drag (on x-axis) and zoom are enabled
48 48 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
49 49 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
50 50 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
51 51 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
52 52 connect(ui->widget->xAxis,
53 53 static_cast<void (QCPAxis::*)(const QCPRange &)>(&QCPAxis::rangeChanged), this,
54 54 &VisualizationGraphWidget::onRangeChanged);
55 55
56 56 // Activates menu when right clicking on the graph
57 57 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
58 58 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
59 59 &VisualizationGraphWidget::onGraphMenuRequested);
60 60
61 61 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
62 62 &VariableController::onRequestDataLoading);
63 63 }
64 64
65 65
66 66 VisualizationGraphWidget::~VisualizationGraphWidget()
67 67 {
68 68 delete ui;
69 69 }
70 70
71 71 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
72 72 {
73 73 // Uses delegate to create the qcpplot components according to the variable
74 74 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
75 75
76 76 for (auto createdPlottable : qAsConst(createdPlottables)) {
77 77 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
78 78 }
79 79
80 80 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
81 81 }
82 82
83 83 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
84 84 {
85 85
86 86 // when adding a variable, we need to set its time range to the current graph range
87 87 auto grapheRange = ui->widget->xAxis->range();
88 88 auto dateTime = SqpDateTime{grapheRange.lower, grapheRange.upper};
89 89 variable->setDateTime(dateTime);
90 90
91 91 auto variableDateTimeWithTolerance = dateTime;
92 92
93 93 // add 10% tolerance for each side
94 94 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
95 95 variableDateTimeWithTolerance.m_TStart -= tolerance;
96 96 variableDateTimeWithTolerance.m_TEnd += tolerance;
97 97
98 98 // Uses delegate to create the qcpplot components according to the variable
99 99 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
100 100
101 101 for (auto createdPlottable : qAsConst(createdPlottables)) {
102 102 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
103 103 }
104 104
105 105 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
106 106
107 107 // CHangement detected, we need to ask controller to request data loading
108 108 emit requestDataLoading(variable, variableDateTimeWithTolerance);
109 109 }
110 110
111 111 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
112 112 {
113 113 // Each component associated to the variable :
114 114 // - is removed from qcpplot (which deletes it)
115 115 // - is no longer referenced in the map
116 116 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
117 117 for (auto it = componentsIt.first; it != componentsIt.second;) {
118 118 ui->widget->removePlottable(it->second);
119 119 it = impl->m_VariableToPlotMultiMap.erase(it);
120 120 }
121 121
122 122 // Updates graph
123 123 ui->widget->replot();
124 124 }
125 125
126 126 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
127 127 {
128 128 if (visitor) {
129 129 visitor->visit(this);
130 130 }
131 131 else {
132 132 qCCritical(LOG_VisualizationGraphWidget())
133 133 << tr("Can't visit widget : the visitor is null");
134 134 }
135 135 }
136 136
137 137 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
138 138 {
139 139 /// @todo : for the moment, a graph can always accomodate a variable
140 140 Q_UNUSED(variable);
141 141 return true;
142 142 }
143 143
144 bool VisualizationGraphWidget::contains(const Variable &variable) const
145 {
146 // Finds the variable among the keys of the map
147 auto variablePtr = &variable;
148 auto findVariable
149 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
150
151 auto end = impl->m_VariableToPlotMultiMap.cend();
152 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
153 return it != end;
154 }
155
144 156 QString VisualizationGraphWidget::name() const
145 157 {
146 158 return ui->graphNameLabel->text();
147 159 }
148 160
149 161 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
150 162 {
151 163 QMenu graphMenu{};
152 164
153 165 // Iterates on variables (unique keys)
154 166 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
155 167 end = impl->m_VariableToPlotMultiMap.cend();
156 168 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
157 169 // 'Remove variable' action
158 170 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
159 171 [ this, var = it->first ]() { removeVariable(var); });
160 172 }
161 173
162 174 if (!graphMenu.isEmpty()) {
163 175 graphMenu.exec(mapToGlobal(pos));
164 176 }
165 177 }
166 178
167 179 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1)
168 180 {
169 181 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged");
170 182
171 183 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
172 184 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
173 185
174 186 auto variable = it->first;
175 187 auto dateTime = SqpDateTime{t1.lower, t1.upper};
176 188
177 189 if (!variable->contains(dateTime)) {
178 190
179 191 auto variableDateTimeWithTolerance = dateTime;
180 192 if (!variable->isInside(dateTime)) {
181 193 auto variableDateTime = variable->dateTime();
182 194 if (variableDateTime.m_TStart < dateTime.m_TStart) {
183 195 qCDebug(LOG_VisualizationGraphWidget()) << tr("TDetection pan to right:");
184 196
185 197 auto diffEndToKeepDelta = dateTime.m_TEnd - variableDateTime.m_TEnd;
186 198 dateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
187 199 // Tolerance have to be added to the right
188 200 // add 10% tolerance for right (end) side
189 201 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
190 202 variableDateTimeWithTolerance.m_TEnd += tolerance;
191 203 }
192 204 else if (variableDateTime.m_TEnd > dateTime.m_TEnd) {
193 205 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection pan to left: ");
194 206 auto diffStartToKeepDelta = variableDateTime.m_TStart - dateTime.m_TStart;
195 207 dateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
196 208 // Tolerance have to be added to the left
197 209 // add 10% tolerance for left (start) side
198 210 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
199 211 variableDateTimeWithTolerance.m_TStart -= tolerance;
200 212 }
201 213 else {
202 214 qCWarning(LOG_VisualizationGraphWidget())
203 215 << tr("Detection anormal zoom detection: ");
204 216 }
205 217 }
206 218 else {
207 219 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection zoom out: ");
208 220 // add 10% tolerance for each side
209 221 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
210 222 variableDateTimeWithTolerance.m_TStart -= tolerance;
211 223 variableDateTimeWithTolerance.m_TEnd += tolerance;
212 224 }
213 225 variable->setDateTime(dateTime);
214 226
215 227 // CHangement detected, we need to ask controller to request data loading
216 228 emit requestDataLoading(variable, variableDateTimeWithTolerance);
217 229 }
218 230 else {
219 231 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection zoom in: ");
220 232 }
221 233 }
222 234 }
223 235
224 236 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
225 237 {
226 238 auto zoomOrientations = QFlags<Qt::Orientation>{};
227 239
228 240 // Lambda that enables a zoom orientation if the key modifier related to this orientation
229 241 // has
230 242 // been pressed
231 243 auto enableOrientation
232 244 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
233 245 auto orientationEnabled = event->modifiers().testFlag(modifier);
234 246 zoomOrientations.setFlag(orientation, orientationEnabled);
235 247 };
236 248 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
237 249 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
238 250
239 251 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
240 252 }
241 253
242 254 void VisualizationGraphWidget::onDataCacheVariableUpdated()
243 255 {
244 256 // NOTE:
245 257 // We don't want to call the method for each component of a variable unitarily, but for
246 258 // all
247 259 // its components at once (eg its three components in the case of a vector).
248 260
249 261 // The unordered_multimap does not do this easily, so the question is whether to:
250 262 // - use an ordered_multimap and the algos of std to group the values by key
251 263 // - use a map (unique keys) and store as values directly the list of components
252 264
253 265 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
254 266 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
255 267 auto variable = it->first;
256 268 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
257 269 variable->dataSeries(), variable->dateTime());
258 270 }
259 271 }
260 272
261 273 void VisualizationGraphWidget::updateDisplay(std::shared_ptr<Variable> variable)
262 274 {
263 275 auto abstractPlotableItPair = impl->m_VariableToPlotMultiMap.equal_range(variable);
264 276
265 277 auto abstractPlotableVect = QVector<QCPAbstractPlottable *>{};
266 278
267 279 for (auto it = abstractPlotableItPair.first; it != abstractPlotableItPair.second; ++it) {
268 280 abstractPlotableVect.push_back(it->second);
269 281 }
270 282
271 283 VisualizationGraphHelper::updateData(abstractPlotableVect, variable->dataSeries(),
272 284 variable->dateTime());
273 285 }
@@ -1,104 +1,110
1 1 #include "Visualization/VisualizationTabWidget.h"
2 2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 3 #include "ui_VisualizationTabWidget.h"
4 4
5 5 #include "Visualization/VisualizationZoneWidget.h"
6 6
7 7 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
8 8
9 9 namespace {
10 10
11 11 /// Generates a default name for a new zone, according to the number of zones already displayed in
12 12 /// the tab
13 13 QString defaultZoneName(const QLayout &layout)
14 14 {
15 15 auto count = 0;
16 16 for (auto i = 0; i < layout.count(); ++i) {
17 17 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
18 18 count++;
19 19 }
20 20 }
21 21
22 22 return QObject::tr("Zone %1").arg(count + 1);
23 23 }
24 24
25 25 } // namespace
26 26
27 27 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
28 28 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
29 29
30 30 QString m_Name;
31 31 };
32 32
33 33 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
34 34 : QWidget{parent},
35 35 ui{new Ui::VisualizationTabWidget},
36 36 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
37 37 {
38 38 ui->setupUi(this);
39 39
40 40 // Widget is deleted when closed
41 41 setAttribute(Qt::WA_DeleteOnClose);
42 42 }
43 43
44 44 VisualizationTabWidget::~VisualizationTabWidget()
45 45 {
46 46 delete ui;
47 47 }
48 48
49 49 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
50 50 {
51 51 tabLayout().addWidget(zoneWidget);
52 52 }
53 53
54 54 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
55 55 {
56 56 auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(tabLayout()), this};
57 57 this->addZone(zoneWidget);
58 58
59 59 // Creates a new graph into the zone
60 60 zoneWidget->createGraph(variable);
61 61
62 62 return zoneWidget;
63 63 }
64 64
65 65 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
66 66 {
67 67 if (visitor) {
68 68 visitor->visitEnter(this);
69 69
70 70 // Apply visitor to zone children
71 71 auto &layout = tabLayout();
72 72 for (auto i = 0; i < layout.count(); ++i) {
73 73 if (auto item = layout.itemAt(i)) {
74 74 // Widgets different from zones are not visited (no action)
75 75 if (auto visualizationZoneWidget
76 76 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
77 77 visualizationZoneWidget->accept(visitor);
78 78 }
79 79 }
80 80 }
81 81
82 82 visitor->visitLeave(this);
83 83 }
84 84 else {
85 85 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
86 86 }
87 87 }
88 88
89 89 bool VisualizationTabWidget::canDrop(const Variable &variable) const
90 90 {
91 91 // A tab can always accomodate a variable
92 92 Q_UNUSED(variable);
93 93 return true;
94 94 }
95 95
96 bool VisualizationTabWidget::contains(const Variable &variable) const
97 {
98 Q_UNUSED(variable);
99 return false;
100 }
101
96 102 QString VisualizationTabWidget::name() const
97 103 {
98 104 return impl->m_Name;
99 105 }
100 106
101 107 QLayout &VisualizationTabWidget::tabLayout() const noexcept
102 108 {
103 109 return *ui->scrollAreaWidgetContents->layout();
104 110 }
@@ -1,129 +1,135
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 6 #include "Visualization/operations/GenerateVariableMenuOperation.h"
7 7 #include "Visualization/qcustomplot.h"
8 8
9 9 #include "ui_VisualizationWidget.h"
10 10
11 11 #include <QToolButton>
12 12
13 13 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
14 14
15 15 VisualizationWidget::VisualizationWidget(QWidget *parent)
16 16 : QWidget{parent}, ui{new Ui::VisualizationWidget}
17 17 {
18 18 ui->setupUi(this);
19 19
20 20 auto addTabViewButton = new QToolButton{ui->tabWidget};
21 21 addTabViewButton->setText(tr("Add View"));
22 22 addTabViewButton->setCursor(Qt::ArrowCursor);
23 23 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
24 24
25 25 auto enableMinimumCornerWidgetSize = [this](bool enable) {
26 26
27 27 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
28 28 auto width = enable ? tabViewCornerWidget->width() : 0;
29 29 auto height = enable ? tabViewCornerWidget->height() : 0;
30 30 tabViewCornerWidget->setMinimumHeight(height);
31 31 tabViewCornerWidget->setMinimumWidth(width);
32 32 ui->tabWidget->setMinimumHeight(height);
33 33 ui->tabWidget->setMinimumWidth(width);
34 34 };
35 35
36 36 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
37 37 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
38 38 ui->tabWidget};
39 39 auto index = ui->tabWidget->addTab(widget, widget->name());
40 40 if (ui->tabWidget->count() > 0) {
41 41 enableMinimumCornerWidgetSize(false);
42 42 }
43 43 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
44 44 };
45 45
46 46 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
47 47 if (ui->tabWidget->count() == 1) {
48 48 enableMinimumCornerWidgetSize(true);
49 49 }
50 50
51 51 // Removes widget from tab and closes it
52 52 auto widget = ui->tabWidget->widget(index);
53 53 ui->tabWidget->removeTab(index);
54 54 if (widget) {
55 55 widget->close();
56 56 }
57 57
58 58 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
59 59
60 60 };
61 61
62 62 ui->tabWidget->setTabsClosable(true);
63 63
64 64 connect(addTabViewButton, &QToolButton::clicked, addTabView);
65 65 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
66 66
67 67 // Adds default tab
68 68 addTabView();
69 69 }
70 70
71 71 VisualizationWidget::~VisualizationWidget()
72 72 {
73 73 delete ui;
74 74 }
75 75
76 76 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
77 77 {
78 78 if (visitor) {
79 79 visitor->visitEnter(this);
80 80
81 81 // Apply visitor for tab children
82 82 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
83 83 // Widgets different from tabs are not visited (no action)
84 84 if (auto visualizationTabWidget
85 85 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
86 86 visualizationTabWidget->accept(visitor);
87 87 }
88 88 }
89 89
90 90 visitor->visitLeave(this);
91 91 }
92 92 else {
93 93 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
94 94 }
95 95 }
96 96
97 97 bool VisualizationWidget::canDrop(const Variable &variable) const
98 98 {
99 99 // The main widget can never accomodate a variable
100 100 Q_UNUSED(variable);
101 101 return false;
102 102 }
103 103
104 bool VisualizationWidget::contains(const Variable &variable) const
105 {
106 Q_UNUSED(variable);
107 return false;
108 }
109
104 110 QString VisualizationWidget::name() const
105 111 {
106 112 return QStringLiteral("MainView");
107 113 }
108 114
109 115 void VisualizationWidget::attachVariableMenu(
110 116 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
111 117 {
112 118 // Menu is generated only if there is a single variable
113 119 if (variables.size() == 1) {
114 120 if (auto variable = variables.first()) {
115 121 // Generates the actions that make it possible to visualize the variable
116 122 auto generateVariableMenuOperation = GenerateVariableMenuOperation{menu, variable};
117 123 accept(&generateVariableMenuOperation);
118 124 }
119 125 else {
120 126 qCCritical(LOG_VisualizationWidget()) << tr(
121 127 "Can't generate the menu relative to the visualization: the variable is null");
122 128 }
123 129 }
124 130 else {
125 131 qCDebug(LOG_VisualizationWidget())
126 132 << tr("No generation of the menu related to the visualization: several variables are "
127 133 "selected");
128 134 }
129 135 }
@@ -1,105 +1,111
1 1 #include "Visualization/VisualizationZoneWidget.h"
2 2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 3 #include "ui_VisualizationZoneWidget.h"
4 4
5 5 #include "Visualization/VisualizationGraphWidget.h"
6 6
7 7 #include <SqpApplication.h>
8 8
9 9 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
10 10
11 11 namespace {
12 12
13 13 /// Minimum height for graph added in zones (in pixels)
14 14 const auto GRAPH_MINIMUM_HEIGHT = 300;
15 15
16 16 /// Generates a default name for a new graph, according to the number of graphs already displayed in
17 17 /// the zone
18 18 QString defaultGraphName(const QLayout &layout)
19 19 {
20 20 auto count = 0;
21 21 for (auto i = 0; i < layout.count(); ++i) {
22 22 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
23 23 count++;
24 24 }
25 25 }
26 26
27 27 return QObject::tr("Graph %1").arg(count + 1);
28 28 }
29 29
30 30 } // namespace
31 31
32 32 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
33 33 : QWidget{parent}, ui{new Ui::VisualizationZoneWidget}
34 34 {
35 35 ui->setupUi(this);
36 36
37 37 ui->zoneNameLabel->setText(name);
38 38
39 39 // 'Close' options : widget is deleted when closed
40 40 setAttribute(Qt::WA_DeleteOnClose);
41 41 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
42 42 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
43 43 }
44 44
45 45 VisualizationZoneWidget::~VisualizationZoneWidget()
46 46 {
47 47 delete ui;
48 48 }
49 49
50 50 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
51 51 {
52 52 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
53 53 }
54 54
55 55 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
56 56 {
57 57 auto graphWidget = new VisualizationGraphWidget{
58 58 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
59 59
60 60 // Set graph properties
61 61 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
62 62 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
63 63
64 64 this->addGraph(graphWidget);
65 65
66 66 graphWidget->addVariable(variable);
67 67
68 68 return graphWidget;
69 69 }
70 70
71 71 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
72 72 {
73 73 if (visitor) {
74 74 visitor->visitEnter(this);
75 75
76 76 // Apply visitor to graph children
77 77 auto layout = ui->visualizationZoneFrame->layout();
78 78 for (auto i = 0; i < layout->count(); ++i) {
79 79 if (auto item = layout->itemAt(i)) {
80 80 // Widgets different from graphs are not visited (no action)
81 81 if (auto visualizationGraphWidget
82 82 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
83 83 visualizationGraphWidget->accept(visitor);
84 84 }
85 85 }
86 86 }
87 87
88 88 visitor->visitLeave(this);
89 89 }
90 90 else {
91 91 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
92 92 }
93 93 }
94 94
95 95 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
96 96 {
97 97 // A tab can always accomodate a variable
98 98 Q_UNUSED(variable);
99 99 return true;
100 100 }
101 101
102 bool VisualizationZoneWidget::contains(const Variable &variable) const
103 {
104 Q_UNUSED(variable);
105 return false;
106 }
107
102 108 QString VisualizationZoneWidget::name() const
103 109 {
104 110 return ui->zoneNameLabel->text();
105 111 }
General Comments 0
You need to be logged in to leave comments. Login now