##// END OF EJS Templates
Handles desynchronisation when removing variable from a graph (2)...
Alexandre Leroux -
r677:48ebbf123b7f
parent child
Show More
@@ -1,97 +1,98
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QWidget>
7 #include <QWidget>
8
8
9 #include <memory>
9 #include <memory>
10
10
11 #include <Common/spimpl.h>
11 #include <Common/spimpl.h>
12
12
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
14
14
15 class QCPRange;
15 class QCPRange;
16 class QCustomPlot;
16 class QCustomPlot;
17 class SqpRange;
17 class SqpRange;
18 class Variable;
18 class Variable;
19
19
20 namespace Ui {
20 namespace Ui {
21 class VisualizationGraphWidget;
21 class VisualizationGraphWidget;
22 } // namespace Ui
22 } // namespace Ui
23
23
24 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
24 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
25 Q_OBJECT
25 Q_OBJECT
26
26
27 friend class QCustomPlotSynchronizer;
27 friend class QCustomPlotSynchronizer;
28 friend class VisualizationGraphRenderingDelegate;
28 friend class VisualizationGraphRenderingDelegate;
29
29
30 public:
30 public:
31 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
31 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
32 virtual ~VisualizationGraphWidget();
32 virtual ~VisualizationGraphWidget();
33
33
34 /// If acquisition isn't enable, requestDataLoading signal cannot be emit
34 /// If acquisition isn't enable, requestDataLoading signal cannot be emit
35 void enableAcquisition(bool enable);
35 void enableAcquisition(bool enable);
36
36
37 void addVariable(std::shared_ptr<Variable> variable, SqpRange range);
37 void addVariable(std::shared_ptr<Variable> variable, SqpRange range);
38
38
39 /// Removes a variable from the graph
39 /// Removes a variable from the graph
40 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
40 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
41
41
42 void setRange(std::shared_ptr<Variable> variable, const SqpRange &range);
42 void setRange(std::shared_ptr<Variable> variable, const SqpRange &range);
43 void setYRange(const SqpRange &range);
43 void setYRange(const SqpRange &range);
44 SqpRange graphRange() const noexcept;
44 SqpRange graphRange() const noexcept;
45 void setGraphRange(const SqpRange &range);
45 void setGraphRange(const SqpRange &range);
46
46
47 // IVisualizationWidget interface
47 // IVisualizationWidget interface
48 void accept(IVisualizationWidgetVisitor *visitor) override;
48 void accept(IVisualizationWidgetVisitor *visitor) override;
49 bool canDrop(const Variable &variable) const override;
49 bool canDrop(const Variable &variable) const override;
50 bool contains(const Variable &variable) const override;
50 bool contains(const Variable &variable) const override;
51 QString name() const override;
51 QString name() const override;
52
52
53
53
54 signals:
54 signals:
55 void synchronize(const SqpRange &range, const SqpRange &oldRange);
55 void synchronize(const SqpRange &range, const SqpRange &oldRange);
56 void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range,
56 void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range,
57 const SqpRange &oldRange, bool synchronise);
57 const SqpRange &oldRange, bool synchronise);
58
58
59 /// Signal emitted when the variable is about to be removed from the graph
59 /// Signal emitted when the variable is about to be removed from the graph
60 void variableAboutToBeRemoved(std::shared_ptr<Variable> var);
60 void variableAboutToBeRemoved(std::shared_ptr<Variable> var);
61 /// Signal emitted when the variable has been added to the graph
61 /// Signal emitted when the variable has been added to the graph
62 void variableAdded(std::shared_ptr<Variable> var);
62 void variableAdded(std::shared_ptr<Variable> var);
63
63
64 protected:
64 protected:
65 void closeEvent(QCloseEvent *event) override;
65 void enterEvent(QEvent *event) override;
66 void enterEvent(QEvent *event) override;
66 void leaveEvent(QEvent *event) override;
67 void leaveEvent(QEvent *event) override;
67
68
68 QCustomPlot &plot() noexcept;
69 QCustomPlot &plot() noexcept;
69
70
70 private:
71 private:
71 Ui::VisualizationGraphWidget *ui;
72 Ui::VisualizationGraphWidget *ui;
72
73
73 class VisualizationGraphWidgetPrivate;
74 class VisualizationGraphWidgetPrivate;
74 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
75 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
75
76
76 private slots:
77 private slots:
77 /// Slot called when right clicking on the graph (displays a menu)
78 /// Slot called when right clicking on the graph (displays a menu)
78 void onGraphMenuRequested(const QPoint &pos) noexcept;
79 void onGraphMenuRequested(const QPoint &pos) noexcept;
79
80
80 /// Rescale the X axe to range parameter
81 /// Rescale the X axe to range parameter
81 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
82 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
82
83
83 /// Slot called when a mouse move was made
84 /// Slot called when a mouse move was made
84 void onMouseMove(QMouseEvent *event) noexcept;
85 void onMouseMove(QMouseEvent *event) noexcept;
85 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
86 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
86 void onMouseWheel(QWheelEvent *event) noexcept;
87 void onMouseWheel(QWheelEvent *event) noexcept;
87 /// Slot called when a mouse press was made, to activate the calibration of a graph
88 /// Slot called when a mouse press was made, to activate the calibration of a graph
88 void onMousePress(QMouseEvent *event) noexcept;
89 void onMousePress(QMouseEvent *event) noexcept;
89 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
90 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
90 void onMouseRelease(QMouseEvent *event) noexcept;
91 void onMouseRelease(QMouseEvent *event) noexcept;
91
92
92 void onDataCacheVariableUpdated();
93 void onDataCacheVariableUpdated();
93
94
94 void onUpdateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
95 void onUpdateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
95 };
96 };
96
97
97 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
98 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,54 +1,57
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <Common/spimpl.h>
6 #include <Common/spimpl.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QWidget>
9 #include <QWidget>
10
10
11 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
11 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
12
12
13 class Variable;
13 class Variable;
14 class VisualizationZoneWidget;
14 class VisualizationZoneWidget;
15
15
16 namespace Ui {
16 namespace Ui {
17 class VisualizationTabWidget;
17 class VisualizationTabWidget;
18 } // namespace Ui
18 } // namespace Ui
19
19
20 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
20 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
21 Q_OBJECT
21 Q_OBJECT
22
22
23 public:
23 public:
24 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
24 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
25 virtual ~VisualizationTabWidget();
25 virtual ~VisualizationTabWidget();
26
26
27 /// Add a zone widget
27 /// Add a zone widget
28 void addZone(VisualizationZoneWidget *zoneWidget);
28 void addZone(VisualizationZoneWidget *zoneWidget);
29
29
30 /**
30 /**
31 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
31 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
32 * zone.
32 * zone.
33 * @param variable the variable for which to create the zone
33 * @param variable the variable for which to create the zone
34 * @return the pointer to the created zone
34 * @return the pointer to the created zone
35 */
35 */
36 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
36 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
37
37
38 // IVisualizationWidget interface
38 // IVisualizationWidget interface
39 void accept(IVisualizationWidgetVisitor *visitor) override;
39 void accept(IVisualizationWidgetVisitor *visitor) override;
40 bool canDrop(const Variable &variable) const override;
40 bool canDrop(const Variable &variable) const override;
41 bool contains(const Variable &variable) const override;
41 bool contains(const Variable &variable) const override;
42 QString name() const override;
42 QString name() const override;
43
43
44 protected:
45 void closeEvent(QCloseEvent *event) override;
46
44 private:
47 private:
45 /// @return the layout of tab in which zones are added
48 /// @return the layout of tab in which zones are added
46 QLayout &tabLayout() const noexcept;
49 QLayout &tabLayout() const noexcept;
47
50
48 Ui::VisualizationTabWidget *ui;
51 Ui::VisualizationTabWidget *ui;
49
52
50 class VisualizationTabWidgetPrivate;
53 class VisualizationTabWidgetPrivate;
51 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
54 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
52 };
55 };
53
56
54 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
57 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
@@ -1,51 +1,54
1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
2 #define SCIQLOP_VISUALIZATIONWIDGET_H
2 #define SCIQLOP_VISUALIZATIONWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5 #include <Data/SqpRange.h>
5 #include <Data/SqpRange.h>
6
6
7 #include <QLoggingCategory>
7 #include <QLoggingCategory>
8 #include <QWidget>
8 #include <QWidget>
9
9
10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
11
11
12 class QMenu;
12 class QMenu;
13 class Variable;
13 class Variable;
14 class VisualizationTabWidget;
14 class VisualizationTabWidget;
15
15
16 namespace Ui {
16 namespace Ui {
17 class VisualizationWidget;
17 class VisualizationWidget;
18 } // namespace Ui
18 } // namespace Ui
19
19
20 class VisualizationWidget : public QWidget, public IVisualizationWidget {
20 class VisualizationWidget : public QWidget, public IVisualizationWidget {
21 Q_OBJECT
21 Q_OBJECT
22
22
23 public:
23 public:
24 explicit VisualizationWidget(QWidget *parent = 0);
24 explicit VisualizationWidget(QWidget *parent = 0);
25 virtual ~VisualizationWidget();
25 virtual ~VisualizationWidget();
26
26
27 // IVisualizationWidget interface
27 // IVisualizationWidget interface
28 void accept(IVisualizationWidgetVisitor *visitor) override;
28 void accept(IVisualizationWidgetVisitor *visitor) override;
29 bool canDrop(const Variable &variable) const override;
29 bool canDrop(const Variable &variable) const override;
30 bool contains(const Variable &variable) const override;
30 bool contains(const Variable &variable) const override;
31 QString name() const override;
31 QString name() const override;
32
32
33 public slots:
33 public slots:
34 /**
34 /**
35 * Attaches to a menu the menu relative to the visualization of variables
35 * Attaches to a menu the menu relative to the visualization of variables
36 * @param menu the parent menu of the generated menu
36 * @param menu the parent menu of the generated menu
37 * @param variables the variables for which to generate the menu
37 * @param variables the variables for which to generate the menu
38 */
38 */
39 void attachVariableMenu(QMenu *menu,
39 void attachVariableMenu(QMenu *menu,
40 const QVector<std::shared_ptr<Variable> > &variables) noexcept;
40 const QVector<std::shared_ptr<Variable> > &variables) noexcept;
41
41
42 /// Slot called when a variable is about to be deleted from SciQlop
42 /// Slot called when a variable is about to be deleted from SciQlop
43 void onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept;
43 void onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept;
44
44
45 void onRangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range) noexcept;
45 void onRangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range) noexcept;
46
46
47 protected:
48 void closeEvent(QCloseEvent *event) override;
49
47 private:
50 private:
48 Ui::VisualizationWidget *ui;
51 Ui::VisualizationWidget *ui;
49 };
52 };
50
53
51 #endif // VISUALIZATIONWIDGET_H
54 #endif // VISUALIZATIONWIDGET_H
@@ -1,57 +1,60
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QWidget>
7 #include <QWidget>
8
8
9 #include <memory>
9 #include <memory>
10
10
11 #include <Common/spimpl.h>
11 #include <Common/spimpl.h>
12
12
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
14
14
15 namespace Ui {
15 namespace Ui {
16 class VisualizationZoneWidget;
16 class VisualizationZoneWidget;
17 } // Ui
17 } // Ui
18
18
19 class Variable;
19 class Variable;
20 class VisualizationGraphWidget;
20 class VisualizationGraphWidget;
21
21
22 class VisualizationZoneWidget : public QWidget, public IVisualizationWidget {
22 class VisualizationZoneWidget : public QWidget, public IVisualizationWidget {
23 Q_OBJECT
23 Q_OBJECT
24
24
25 public:
25 public:
26 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
26 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
27 virtual ~VisualizationZoneWidget();
27 virtual ~VisualizationZoneWidget();
28
28
29 /// Add a graph widget
29 /// Add a graph widget
30 void addGraph(VisualizationGraphWidget *graphWidget);
30 void addGraph(VisualizationGraphWidget *graphWidget);
31
31
32 /**
32 /**
33 * Creates a graph using a variable. The variable will be displayed in the new graph.
33 * Creates a graph using a variable. The variable will be displayed in the new graph.
34 * @param variable the variable for which to create the graph
34 * @param variable the variable for which to create the graph
35 * @return the pointer to the created graph
35 * @return the pointer to the created graph
36 */
36 */
37 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
37 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
38
38
39 // IVisualizationWidget interface
39 // IVisualizationWidget interface
40 void accept(IVisualizationWidgetVisitor *visitor) override;
40 void accept(IVisualizationWidgetVisitor *visitor) override;
41 bool canDrop(const Variable &variable) const override;
41 bool canDrop(const Variable &variable) const override;
42 bool contains(const Variable &variable) const override;
42 bool contains(const Variable &variable) const override;
43 QString name() const override;
43 QString name() const override;
44
44
45 protected:
46 void closeEvent(QCloseEvent *event) override;
47
45 private:
48 private:
46 Ui::VisualizationZoneWidget *ui;
49 Ui::VisualizationZoneWidget *ui;
47
50
48 class VisualizationZoneWidgetPrivate;
51 class VisualizationZoneWidgetPrivate;
49 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
52 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
50
53
51 private slots:
54 private slots:
52 void onVariableAdded(std::shared_ptr<Variable> variable);
55 void onVariableAdded(std::shared_ptr<Variable> variable);
53 /// Slot called when a variable is about to be removed from a graph contained in the zone
56 /// Slot called when a variable is about to be removed from a graph contained in the zone
54 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
57 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
55 };
58 };
56
59
57 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
60 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -1,346 +1,356
1 #include "Visualization/VisualizationGraphWidget.h"
1 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationDefs.h"
3 #include "Visualization/VisualizationDefs.h"
4 #include "Visualization/VisualizationGraphHelper.h"
4 #include "Visualization/VisualizationGraphHelper.h"
5 #include "Visualization/VisualizationGraphRenderingDelegate.h"
5 #include "Visualization/VisualizationGraphRenderingDelegate.h"
6 #include "ui_VisualizationGraphWidget.h"
6 #include "ui_VisualizationGraphWidget.h"
7
7
8 #include <Data/ArrayData.h>
8 #include <Data/ArrayData.h>
9 #include <Data/IDataSeries.h>
9 #include <Data/IDataSeries.h>
10 #include <Settings/SqpSettingsDefs.h>
10 #include <Settings/SqpSettingsDefs.h>
11 #include <SqpApplication.h>
11 #include <SqpApplication.h>
12 #include <Variable/Variable.h>
12 #include <Variable/Variable.h>
13 #include <Variable/VariableController.h>
13 #include <Variable/VariableController.h>
14
14
15 #include <unordered_map>
15 #include <unordered_map>
16
16
17 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
17 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
18
18
19 namespace {
19 namespace {
20
20
21 /// Key pressed to enable zoom on horizontal axis
21 /// Key pressed to enable zoom on horizontal axis
22 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
22 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
23
23
24 /// Key pressed to enable zoom on vertical axis
24 /// Key pressed to enable zoom on vertical axis
25 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
25 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
26
26
27 } // namespace
27 } // namespace
28
28
29 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
29 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
30
30
31 explicit VisualizationGraphWidgetPrivate(const QString &name)
31 explicit VisualizationGraphWidgetPrivate(const QString &name)
32 : m_Name{name},
32 : m_Name{name},
33 m_DoAcquisition{true},
33 m_DoAcquisition{true},
34 m_IsCalibration{false},
34 m_IsCalibration{false},
35 m_RenderingDelegate{nullptr}
35 m_RenderingDelegate{nullptr}
36 {
36 {
37 }
37 }
38
38
39 QString m_Name;
39 QString m_Name;
40 // 1 variable -> n qcpplot
40 // 1 variable -> n qcpplot
41 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
41 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
42 bool m_DoAcquisition;
42 bool m_DoAcquisition;
43 bool m_IsCalibration;
43 bool m_IsCalibration;
44 QCPItemTracer *m_TextTracer;
44 QCPItemTracer *m_TextTracer;
45 /// Delegate used to attach rendering features to the plot
45 /// Delegate used to attach rendering features to the plot
46 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
46 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
47 };
47 };
48
48
49 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
49 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
50 : QWidget{parent},
50 : QWidget{parent},
51 ui{new Ui::VisualizationGraphWidget},
51 ui{new Ui::VisualizationGraphWidget},
52 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
52 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
53 {
53 {
54 ui->setupUi(this);
54 ui->setupUi(this);
55
55
56 // 'Close' options : widget is deleted when closed
56 // 'Close' options : widget is deleted when closed
57 setAttribute(Qt::WA_DeleteOnClose);
57 setAttribute(Qt::WA_DeleteOnClose);
58
58
59 // Set qcpplot properties :
59 // Set qcpplot properties :
60 // - Drag (on x-axis) and zoom are enabled
60 // - Drag (on x-axis) and zoom are enabled
61 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
61 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
62 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectItems);
62 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectItems);
63 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
63 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
64
64
65 // The delegate must be initialized after the ui as it uses the plot
65 // The delegate must be initialized after the ui as it uses the plot
66 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this);
66 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this);
67
67
68 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
68 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
69 connect(ui->widget, &QCustomPlot::mouseRelease, this,
69 connect(ui->widget, &QCustomPlot::mouseRelease, this,
70 &VisualizationGraphWidget::onMouseRelease);
70 &VisualizationGraphWidget::onMouseRelease);
71 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
71 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
72 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
72 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
73 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
73 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
74 &QCPAxis::rangeChanged),
74 &QCPAxis::rangeChanged),
75 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
75 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
76
76
77 // Activates menu when right clicking on the graph
77 // Activates menu when right clicking on the graph
78 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
78 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
79 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
79 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
80 &VisualizationGraphWidget::onGraphMenuRequested);
80 &VisualizationGraphWidget::onGraphMenuRequested);
81
81
82 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
82 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
83 &VariableController::onRequestDataLoading);
83 &VariableController::onRequestDataLoading);
84
84
85 connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
85 connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
86 &VisualizationGraphWidget::onUpdateVarDisplaying);
86 &VisualizationGraphWidget::onUpdateVarDisplaying);
87 }
87 }
88
88
89
89
90 VisualizationGraphWidget::~VisualizationGraphWidget()
90 VisualizationGraphWidget::~VisualizationGraphWidget()
91 {
91 {
92 delete ui;
92 delete ui;
93 }
93 }
94
94
95 void VisualizationGraphWidget::enableAcquisition(bool enable)
95 void VisualizationGraphWidget::enableAcquisition(bool enable)
96 {
96 {
97 impl->m_DoAcquisition = enable;
97 impl->m_DoAcquisition = enable;
98 }
98 }
99
99
100 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
100 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
101 {
101 {
102 // Uses delegate to create the qcpplot components according to the variable
102 // Uses delegate to create the qcpplot components according to the variable
103 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
103 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
104 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
104 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
105
105
106 // Set axes properties according to the units of the data series
106 // Set axes properties according to the units of the data series
107 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
107 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
108 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
108 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
109 auto xAxisUnit = Unit{};
109 auto xAxisUnit = Unit{};
110 auto valuesUnit = Unit{};
110 auto valuesUnit = Unit{};
111
111
112 if (auto dataSeries = variable->dataSeries()) {
112 if (auto dataSeries = variable->dataSeries()) {
113 dataSeries->lockRead();
113 dataSeries->lockRead();
114 xAxisUnit = dataSeries->xAxisUnit();
114 xAxisUnit = dataSeries->xAxisUnit();
115 valuesUnit = dataSeries->valuesUnit();
115 valuesUnit = dataSeries->valuesUnit();
116 dataSeries->unlock();
116 dataSeries->unlock();
117 }
117 }
118 impl->m_RenderingDelegate->setAxesProperties(xAxisUnit, valuesUnit);
118 impl->m_RenderingDelegate->setAxesProperties(xAxisUnit, valuesUnit);
119
119
120 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
120 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
121
121
122 auto varRange = variable->range();
122 auto varRange = variable->range();
123
123
124 this->enableAcquisition(false);
124 this->enableAcquisition(false);
125 this->setGraphRange(range);
125 this->setGraphRange(range);
126 this->enableAcquisition(true);
126 this->enableAcquisition(true);
127
127
128 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, varRange,
128 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, varRange,
129 false);
129 false);
130
130
131 emit variableAdded(variable);
131 emit variableAdded(variable);
132 }
132 }
133
133
134 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
134 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
135 {
135 {
136 // Each component associated to the variable :
136 // Each component associated to the variable :
137 // - is removed from qcpplot (which deletes it)
137 // - is removed from qcpplot (which deletes it)
138 // - is no longer referenced in the map
138 // - is no longer referenced in the map
139 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
139 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
140 if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
140 if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
141 emit variableAboutToBeRemoved(variable);
141 emit variableAboutToBeRemoved(variable);
142
142
143 auto &plottablesMap = variableIt->second;
143 auto &plottablesMap = variableIt->second;
144
144
145 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
145 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
146 plottableIt != plottableEnd;) {
146 plottableIt != plottableEnd;) {
147 ui->widget->removePlottable(plottableIt->second);
147 ui->widget->removePlottable(plottableIt->second);
148 plottableIt = plottablesMap.erase(plottableIt);
148 plottableIt = plottablesMap.erase(plottableIt);
149 }
149 }
150
150
151 impl->m_VariableToPlotMultiMap.erase(variableIt);
151 impl->m_VariableToPlotMultiMap.erase(variableIt);
152 }
152 }
153
153
154 // Updates graph
154 // Updates graph
155 ui->widget->replot();
155 ui->widget->replot();
156 }
156 }
157
157
158 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable, const SqpRange &range)
158 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable, const SqpRange &range)
159 {
159 {
160 // Note: in case of different axes that depends on variable, we could start with a code like
160 // Note: in case of different axes that depends on variable, we could start with a code like
161 // that:
161 // that:
162 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
162 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
163 // for (auto it = componentsIt.first; it != componentsIt.second;) {
163 // for (auto it = componentsIt.first; it != componentsIt.second;) {
164 // }
164 // }
165 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
165 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
166 ui->widget->replot();
166 ui->widget->replot();
167 }
167 }
168
168
169 void VisualizationGraphWidget::setYRange(const SqpRange &range)
169 void VisualizationGraphWidget::setYRange(const SqpRange &range)
170 {
170 {
171 ui->widget->yAxis->setRange(range.m_TStart, range.m_TEnd);
171 ui->widget->yAxis->setRange(range.m_TStart, range.m_TEnd);
172 }
172 }
173
173
174 SqpRange VisualizationGraphWidget::graphRange() const noexcept
174 SqpRange VisualizationGraphWidget::graphRange() const noexcept
175 {
175 {
176 auto graphRange = ui->widget->xAxis->range();
176 auto graphRange = ui->widget->xAxis->range();
177 return SqpRange{graphRange.lower, graphRange.upper};
177 return SqpRange{graphRange.lower, graphRange.upper};
178 }
178 }
179
179
180 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
180 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
181 {
181 {
182 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
182 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
183 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
183 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
184 ui->widget->replot();
184 ui->widget->replot();
185 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
185 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
186 }
186 }
187
187
188 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
188 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
189 {
189 {
190 if (visitor) {
190 if (visitor) {
191 visitor->visit(this);
191 visitor->visit(this);
192 }
192 }
193 else {
193 else {
194 qCCritical(LOG_VisualizationGraphWidget())
194 qCCritical(LOG_VisualizationGraphWidget())
195 << tr("Can't visit widget : the visitor is null");
195 << tr("Can't visit widget : the visitor is null");
196 }
196 }
197 }
197 }
198
198
199 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
199 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
200 {
200 {
201 /// @todo : for the moment, a graph can always accomodate a variable
201 /// @todo : for the moment, a graph can always accomodate a variable
202 Q_UNUSED(variable);
202 Q_UNUSED(variable);
203 return true;
203 return true;
204 }
204 }
205
205
206 bool VisualizationGraphWidget::contains(const Variable &variable) const
206 bool VisualizationGraphWidget::contains(const Variable &variable) const
207 {
207 {
208 // Finds the variable among the keys of the map
208 // Finds the variable among the keys of the map
209 auto variablePtr = &variable;
209 auto variablePtr = &variable;
210 auto findVariable
210 auto findVariable
211 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
211 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
212
212
213 auto end = impl->m_VariableToPlotMultiMap.cend();
213 auto end = impl->m_VariableToPlotMultiMap.cend();
214 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
214 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
215 return it != end;
215 return it != end;
216 }
216 }
217
217
218 QString VisualizationGraphWidget::name() const
218 QString VisualizationGraphWidget::name() const
219 {
219 {
220 return impl->m_Name;
220 return impl->m_Name;
221 }
221 }
222
222
223 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
224 {
225 Q_UNUSED(event);
226
227 // Prevents that all variables will be removed from graph when it will be closed
228 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
229 emit variableAboutToBeRemoved(variableEntry.first);
230 }
231 }
232
223 void VisualizationGraphWidget::enterEvent(QEvent *event)
233 void VisualizationGraphWidget::enterEvent(QEvent *event)
224 {
234 {
225 Q_UNUSED(event);
235 Q_UNUSED(event);
226 impl->m_RenderingDelegate->showGraphOverlay(true);
236 impl->m_RenderingDelegate->showGraphOverlay(true);
227 }
237 }
228
238
229 void VisualizationGraphWidget::leaveEvent(QEvent *event)
239 void VisualizationGraphWidget::leaveEvent(QEvent *event)
230 {
240 {
231 Q_UNUSED(event);
241 Q_UNUSED(event);
232 impl->m_RenderingDelegate->showGraphOverlay(false);
242 impl->m_RenderingDelegate->showGraphOverlay(false);
233 }
243 }
234
244
235 QCustomPlot &VisualizationGraphWidget::plot() noexcept
245 QCustomPlot &VisualizationGraphWidget::plot() noexcept
236 {
246 {
237 return *ui->widget;
247 return *ui->widget;
238 }
248 }
239
249
240 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
250 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
241 {
251 {
242 QMenu graphMenu{};
252 QMenu graphMenu{};
243
253
244 // Iterates on variables (unique keys)
254 // Iterates on variables (unique keys)
245 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
255 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
246 end = impl->m_VariableToPlotMultiMap.cend();
256 end = impl->m_VariableToPlotMultiMap.cend();
247 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
257 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
248 // 'Remove variable' action
258 // 'Remove variable' action
249 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
259 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
250 [ this, var = it->first ]() { removeVariable(var); });
260 [ this, var = it->first ]() { removeVariable(var); });
251 }
261 }
252
262
253 if (!graphMenu.isEmpty()) {
263 if (!graphMenu.isEmpty()) {
254 graphMenu.exec(QCursor::pos());
264 graphMenu.exec(QCursor::pos());
255 }
265 }
256 }
266 }
257
267
258 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
268 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
259 {
269 {
260 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
270 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
261 << QThread::currentThread()->objectName() << "DoAcqui"
271 << QThread::currentThread()->objectName() << "DoAcqui"
262 << impl->m_DoAcquisition;
272 << impl->m_DoAcquisition;
263
273
264 auto graphRange = SqpRange{t1.lower, t1.upper};
274 auto graphRange = SqpRange{t1.lower, t1.upper};
265 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
275 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
266
276
267 if (impl->m_DoAcquisition) {
277 if (impl->m_DoAcquisition) {
268 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
278 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
269
279
270 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
280 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
271 end = impl->m_VariableToPlotMultiMap.end();
281 end = impl->m_VariableToPlotMultiMap.end();
272 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
282 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
273 variableUnderGraphVector.push_back(it->first);
283 variableUnderGraphVector.push_back(it->first);
274 }
284 }
275 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
285 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
276 !impl->m_IsCalibration);
286 !impl->m_IsCalibration);
277
287
278 if (!impl->m_IsCalibration) {
288 if (!impl->m_IsCalibration) {
279 qCDebug(LOG_VisualizationGraphWidget())
289 qCDebug(LOG_VisualizationGraphWidget())
280 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
290 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
281 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
291 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
282 emit synchronize(graphRange, oldGraphRange);
292 emit synchronize(graphRange, oldGraphRange);
283 }
293 }
284 }
294 }
285 }
295 }
286
296
287 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
297 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
288 {
298 {
289 // Handles plot rendering when mouse is moving
299 // Handles plot rendering when mouse is moving
290 impl->m_RenderingDelegate->onMouseMove(event);
300 impl->m_RenderingDelegate->onMouseMove(event);
291 }
301 }
292
302
293 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
303 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
294 {
304 {
295 auto zoomOrientations = QFlags<Qt::Orientation>{};
305 auto zoomOrientations = QFlags<Qt::Orientation>{};
296
306
297 // Lambda that enables a zoom orientation if the key modifier related to this orientation
307 // Lambda that enables a zoom orientation if the key modifier related to this orientation
298 // has
308 // has
299 // been pressed
309 // been pressed
300 auto enableOrientation
310 auto enableOrientation
301 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
311 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
302 auto orientationEnabled = event->modifiers().testFlag(modifier);
312 auto orientationEnabled = event->modifiers().testFlag(modifier);
303 zoomOrientations.setFlag(orientation, orientationEnabled);
313 zoomOrientations.setFlag(orientation, orientationEnabled);
304 };
314 };
305 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
315 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
306 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
316 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
307
317
308 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
318 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
309 }
319 }
310
320
311 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
321 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
312 {
322 {
313 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
323 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
314 }
324 }
315
325
316 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
326 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
317 {
327 {
318 impl->m_IsCalibration = false;
328 impl->m_IsCalibration = false;
319 }
329 }
320
330
321 void VisualizationGraphWidget::onDataCacheVariableUpdated()
331 void VisualizationGraphWidget::onDataCacheVariableUpdated()
322 {
332 {
323 auto graphRange = ui->widget->xAxis->range();
333 auto graphRange = ui->widget->xAxis->range();
324 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
334 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
325
335
326 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
336 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
327 auto variable = variableEntry.first;
337 auto variable = variableEntry.first;
328 qCDebug(LOG_VisualizationGraphWidget())
338 qCDebug(LOG_VisualizationGraphWidget())
329 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
339 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
330 qCDebug(LOG_VisualizationGraphWidget())
340 qCDebug(LOG_VisualizationGraphWidget())
331 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
341 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
332 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
342 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
333 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
343 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
334 variable->range());
344 variable->range());
335 }
345 }
336 }
346 }
337 }
347 }
338
348
339 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
349 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
340 const SqpRange &range)
350 const SqpRange &range)
341 {
351 {
342 auto it = impl->m_VariableToPlotMultiMap.find(variable);
352 auto it = impl->m_VariableToPlotMultiMap.find(variable);
343 if (it != impl->m_VariableToPlotMultiMap.end()) {
353 if (it != impl->m_VariableToPlotMultiMap.end()) {
344 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
354 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
345 }
355 }
346 }
356 }
@@ -1,110 +1,129
1 #include "Visualization/VisualizationTabWidget.h"
1 #include "Visualization/VisualizationTabWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "ui_VisualizationTabWidget.h"
3 #include "ui_VisualizationTabWidget.h"
4
4
5 #include "Visualization/VisualizationZoneWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
6
6
7 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
7 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
8
8
9 namespace {
9 namespace {
10
10
11 /// Generates a default name for a new zone, according to the number of zones already displayed in
11 /// Generates a default name for a new zone, according to the number of zones already displayed in
12 /// the tab
12 /// the tab
13 QString defaultZoneName(const QLayout &layout)
13 QString defaultZoneName(const QLayout &layout)
14 {
14 {
15 auto count = 0;
15 auto count = 0;
16 for (auto i = 0; i < layout.count(); ++i) {
16 for (auto i = 0; i < layout.count(); ++i) {
17 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
17 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
18 count++;
18 count++;
19 }
19 }
20 }
20 }
21
21
22 return QObject::tr("Zone %1").arg(count + 1);
22 return QObject::tr("Zone %1").arg(count + 1);
23 }
23 }
24
24
25 /**
26 * Applies a function to all zones of the tab represented by its layout
27 * @param layout the layout that contains zones
28 * @param fun the function to apply to each zone
29 */
30 template <typename Fun>
31 void processZones(QLayout &layout, Fun fun)
32 {
33 for (auto i = 0; i < layout.count(); ++i) {
34 if (auto item = layout.itemAt(i)) {
35 if (auto visualizationZoneWidget
36 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
37 fun(*visualizationZoneWidget);
38 }
39 }
40 }
41 }
42
25 } // namespace
43 } // namespace
26
44
27 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
45 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
28 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
46 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
29
47
30 QString m_Name;
48 QString m_Name;
31 };
49 };
32
50
33 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
51 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
34 : QWidget{parent},
52 : QWidget{parent},
35 ui{new Ui::VisualizationTabWidget},
53 ui{new Ui::VisualizationTabWidget},
36 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
54 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
37 {
55 {
38 ui->setupUi(this);
56 ui->setupUi(this);
39
57
40 // Widget is deleted when closed
58 // Widget is deleted when closed
41 setAttribute(Qt::WA_DeleteOnClose);
59 setAttribute(Qt::WA_DeleteOnClose);
42 }
60 }
43
61
44 VisualizationTabWidget::~VisualizationTabWidget()
62 VisualizationTabWidget::~VisualizationTabWidget()
45 {
63 {
46 delete ui;
64 delete ui;
47 }
65 }
48
66
49 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
67 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
50 {
68 {
51 tabLayout().addWidget(zoneWidget);
69 tabLayout().addWidget(zoneWidget);
52 }
70 }
53
71
54 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
72 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
55 {
73 {
56 auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(tabLayout()), this};
74 auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(tabLayout()), this};
57 this->addZone(zoneWidget);
75 this->addZone(zoneWidget);
58
76
59 // Creates a new graph into the zone
77 // Creates a new graph into the zone
60 zoneWidget->createGraph(variable);
78 zoneWidget->createGraph(variable);
61
79
62 return zoneWidget;
80 return zoneWidget;
63 }
81 }
64
82
65 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
83 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
66 {
84 {
67 if (visitor) {
85 if (visitor) {
68 visitor->visitEnter(this);
86 visitor->visitEnter(this);
69
87
70 // Apply visitor to zone children
88 // Apply visitor to zone children: widgets different from zones are not visited (no action)
71 auto &layout = tabLayout();
89 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
72 for (auto i = 0; i < layout.count(); ++i) {
90 zoneWidget.accept(visitor);
73 if (auto item = layout.itemAt(i)) {
91 });
74 // Widgets different from zones are not visited (no action)
75 if (auto visualizationZoneWidget
76 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
77 visualizationZoneWidget->accept(visitor);
78 }
79 }
80 }
81
92
82 visitor->visitLeave(this);
93 visitor->visitLeave(this);
83 }
94 }
84 else {
95 else {
85 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
96 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
86 }
97 }
87 }
98 }
88
99
89 bool VisualizationTabWidget::canDrop(const Variable &variable) const
100 bool VisualizationTabWidget::canDrop(const Variable &variable) const
90 {
101 {
91 // A tab can always accomodate a variable
102 // A tab can always accomodate a variable
92 Q_UNUSED(variable);
103 Q_UNUSED(variable);
93 return true;
104 return true;
94 }
105 }
95
106
96 bool VisualizationTabWidget::contains(const Variable &variable) const
107 bool VisualizationTabWidget::contains(const Variable &variable) const
97 {
108 {
98 Q_UNUSED(variable);
109 Q_UNUSED(variable);
99 return false;
110 return false;
100 }
111 }
101
112
102 QString VisualizationTabWidget::name() const
113 QString VisualizationTabWidget::name() const
103 {
114 {
104 return impl->m_Name;
115 return impl->m_Name;
105 }
116 }
106
117
118 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
119 {
120 // Closes zones in the tab
121 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
122
123 QWidget::closeEvent(event);
124 }
125
107 QLayout &VisualizationTabWidget::tabLayout() const noexcept
126 QLayout &VisualizationTabWidget::tabLayout() const noexcept
108 {
127 {
109 return *ui->scrollAreaWidgetContents->layout();
128 return *ui->scrollAreaWidgetContents->layout();
110 }
129 }
@@ -1,159 +1,172
1 #include "Visualization/VisualizationWidget.h"
1 #include "Visualization/VisualizationWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationGraphWidget.h"
3 #include "Visualization/VisualizationGraphWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/operations/FindVariableOperation.h"
6 #include "Visualization/operations/FindVariableOperation.h"
7 #include "Visualization/operations/GenerateVariableMenuOperation.h"
7 #include "Visualization/operations/GenerateVariableMenuOperation.h"
8 #include "Visualization/operations/RemoveVariableOperation.h"
8 #include "Visualization/operations/RemoveVariableOperation.h"
9 #include "Visualization/operations/RescaleAxeOperation.h"
9 #include "Visualization/operations/RescaleAxeOperation.h"
10 #include "Visualization/qcustomplot.h"
10 #include "Visualization/qcustomplot.h"
11
11
12 #include "ui_VisualizationWidget.h"
12 #include "ui_VisualizationWidget.h"
13
13
14 #include <QToolButton>
14 #include <QToolButton>
15
15
16 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
16 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
17
17
18 VisualizationWidget::VisualizationWidget(QWidget *parent)
18 VisualizationWidget::VisualizationWidget(QWidget *parent)
19 : QWidget{parent}, ui{new Ui::VisualizationWidget}
19 : QWidget{parent}, ui{new Ui::VisualizationWidget}
20 {
20 {
21 ui->setupUi(this);
21 ui->setupUi(this);
22
22
23 auto addTabViewButton = new QToolButton{ui->tabWidget};
23 auto addTabViewButton = new QToolButton{ui->tabWidget};
24 addTabViewButton->setText(tr("Add View"));
24 addTabViewButton->setText(tr("Add View"));
25 addTabViewButton->setCursor(Qt::ArrowCursor);
25 addTabViewButton->setCursor(Qt::ArrowCursor);
26 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
26 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
27
27
28 auto enableMinimumCornerWidgetSize = [this](bool enable) {
28 auto enableMinimumCornerWidgetSize = [this](bool enable) {
29
29
30 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
30 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
31 auto width = enable ? tabViewCornerWidget->width() : 0;
31 auto width = enable ? tabViewCornerWidget->width() : 0;
32 auto height = enable ? tabViewCornerWidget->height() : 0;
32 auto height = enable ? tabViewCornerWidget->height() : 0;
33 tabViewCornerWidget->setMinimumHeight(height);
33 tabViewCornerWidget->setMinimumHeight(height);
34 tabViewCornerWidget->setMinimumWidth(width);
34 tabViewCornerWidget->setMinimumWidth(width);
35 ui->tabWidget->setMinimumHeight(height);
35 ui->tabWidget->setMinimumHeight(height);
36 ui->tabWidget->setMinimumWidth(width);
36 ui->tabWidget->setMinimumWidth(width);
37 };
37 };
38
38
39 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
39 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
40 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
40 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
41 ui->tabWidget};
41 ui->tabWidget};
42 auto index = ui->tabWidget->addTab(widget, widget->name());
42 auto index = ui->tabWidget->addTab(widget, widget->name());
43 if (ui->tabWidget->count() > 0) {
43 if (ui->tabWidget->count() > 0) {
44 enableMinimumCornerWidgetSize(false);
44 enableMinimumCornerWidgetSize(false);
45 }
45 }
46 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
46 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
47 };
47 };
48
48
49 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
49 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
50 if (ui->tabWidget->count() == 1) {
50 if (ui->tabWidget->count() == 1) {
51 enableMinimumCornerWidgetSize(true);
51 enableMinimumCornerWidgetSize(true);
52 }
52 }
53
53
54 // Removes widget from tab and closes it
54 // Removes widget from tab and closes it
55 auto widget = ui->tabWidget->widget(index);
55 auto widget = ui->tabWidget->widget(index);
56 ui->tabWidget->removeTab(index);
56 ui->tabWidget->removeTab(index);
57 if (widget) {
57 if (widget) {
58 widget->close();
58 widget->close();
59 }
59 }
60
60
61 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
61 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
62
62
63 };
63 };
64
64
65 ui->tabWidget->setTabsClosable(true);
65 ui->tabWidget->setTabsClosable(true);
66
66
67 connect(addTabViewButton, &QToolButton::clicked, addTabView);
67 connect(addTabViewButton, &QToolButton::clicked, addTabView);
68 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
68 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
69
69
70 // Adds default tab
70 // Adds default tab
71 addTabView();
71 addTabView();
72 }
72 }
73
73
74 VisualizationWidget::~VisualizationWidget()
74 VisualizationWidget::~VisualizationWidget()
75 {
75 {
76 delete ui;
76 delete ui;
77 }
77 }
78
78
79 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
79 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
80 {
80 {
81 if (visitor) {
81 if (visitor) {
82 visitor->visitEnter(this);
82 visitor->visitEnter(this);
83
83
84 // Apply visitor for tab children
84 // Apply visitor for tab children
85 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
85 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
86 // Widgets different from tabs are not visited (no action)
86 // Widgets different from tabs are not visited (no action)
87 if (auto visualizationTabWidget
87 if (auto visualizationTabWidget
88 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
88 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
89 visualizationTabWidget->accept(visitor);
89 visualizationTabWidget->accept(visitor);
90 }
90 }
91 }
91 }
92
92
93 visitor->visitLeave(this);
93 visitor->visitLeave(this);
94 }
94 }
95 else {
95 else {
96 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
96 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
97 }
97 }
98 }
98 }
99
99
100 bool VisualizationWidget::canDrop(const Variable &variable) const
100 bool VisualizationWidget::canDrop(const Variable &variable) const
101 {
101 {
102 // The main widget can never accomodate a variable
102 // The main widget can never accomodate a variable
103 Q_UNUSED(variable);
103 Q_UNUSED(variable);
104 return false;
104 return false;
105 }
105 }
106
106
107 bool VisualizationWidget::contains(const Variable &variable) const
107 bool VisualizationWidget::contains(const Variable &variable) const
108 {
108 {
109 Q_UNUSED(variable);
109 Q_UNUSED(variable);
110 return false;
110 return false;
111 }
111 }
112
112
113 QString VisualizationWidget::name() const
113 QString VisualizationWidget::name() const
114 {
114 {
115 return QStringLiteral("MainView");
115 return QStringLiteral("MainView");
116 }
116 }
117
117
118 void VisualizationWidget::attachVariableMenu(
118 void VisualizationWidget::attachVariableMenu(
119 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
119 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
120 {
120 {
121 // Menu is generated only if there is a single variable
121 // Menu is generated only if there is a single variable
122 if (variables.size() == 1) {
122 if (variables.size() == 1) {
123 if (auto variable = variables.first()) {
123 if (auto variable = variables.first()) {
124 // Gets the containers of the variable
124 // Gets the containers of the variable
125 FindVariableOperation findVariableOperation{variable};
125 FindVariableOperation findVariableOperation{variable};
126 accept(&findVariableOperation);
126 accept(&findVariableOperation);
127 auto variableContainers = findVariableOperation.result();
127 auto variableContainers = findVariableOperation.result();
128
128
129 // Generates the actions that make it possible to visualize the variable
129 // Generates the actions that make it possible to visualize the variable
130 GenerateVariableMenuOperation generateVariableMenuOperation{
130 GenerateVariableMenuOperation generateVariableMenuOperation{
131 menu, variable, std::move(variableContainers)};
131 menu, variable, std::move(variableContainers)};
132 accept(&generateVariableMenuOperation);
132 accept(&generateVariableMenuOperation);
133 }
133 }
134 else {
134 else {
135 qCCritical(LOG_VisualizationWidget()) << tr(
135 qCCritical(LOG_VisualizationWidget()) << tr(
136 "Can't generate the menu relative to the visualization: the variable is null");
136 "Can't generate the menu relative to the visualization: the variable is null");
137 }
137 }
138 }
138 }
139 else {
139 else {
140 qCDebug(LOG_VisualizationWidget())
140 qCDebug(LOG_VisualizationWidget())
141 << tr("No generation of the menu related to the visualization: several variables are "
141 << tr("No generation of the menu related to the visualization: several variables are "
142 "selected");
142 "selected");
143 }
143 }
144 }
144 }
145
145
146 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
146 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
147 {
147 {
148 // Calls the operation of removing all references to the variable in the visualization
148 // Calls the operation of removing all references to the variable in the visualization
149 auto removeVariableOperation = RemoveVariableOperation{variable};
149 auto removeVariableOperation = RemoveVariableOperation{variable};
150 accept(&removeVariableOperation);
150 accept(&removeVariableOperation);
151 }
151 }
152
152
153 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
153 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
154 const SqpRange &range) noexcept
154 const SqpRange &range) noexcept
155 {
155 {
156 // Calls the operation of rescaling all graph that contrains variable in the visualization
156 // Calls the operation of rescaling all graph that contrains variable in the visualization
157 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
157 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
158 accept(&rescaleVariableOperation);
158 accept(&rescaleVariableOperation);
159 }
159 }
160
161 void VisualizationWidget::closeEvent(QCloseEvent *event)
162 {
163 // Closes tabs in the widget
164 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
165 if (auto visualizationTabWidget
166 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
167 visualizationTabWidget->close();
168 }
169 }
170
171 QWidget::closeEvent(event);
172 }
@@ -1,277 +1,298
1 #include "Visualization/VisualizationZoneWidget.h"
1 #include "Visualization/VisualizationZoneWidget.h"
2
2
3 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/IVisualizationWidgetVisitor.h"
4 #include "Visualization/QCustomPlotSynchronizer.h"
4 #include "Visualization/QCustomPlotSynchronizer.h"
5 #include "Visualization/VisualizationGraphWidget.h"
5 #include "Visualization/VisualizationGraphWidget.h"
6 #include "ui_VisualizationZoneWidget.h"
6 #include "ui_VisualizationZoneWidget.h"
7
7
8 #include <Data/SqpRange.h>
8 #include <Data/SqpRange.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10 #include <Variable/VariableController.h>
10 #include <Variable/VariableController.h>
11
11
12 #include <QUuid>
12 #include <QUuid>
13 #include <SqpApplication.h>
13 #include <SqpApplication.h>
14 #include <cmath>
14 #include <cmath>
15
15
16 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
16 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
17
17
18 namespace {
18 namespace {
19
19
20 /// Minimum height for graph added in zones (in pixels)
20 /// Minimum height for graph added in zones (in pixels)
21 const auto GRAPH_MINIMUM_HEIGHT = 300;
21 const auto GRAPH_MINIMUM_HEIGHT = 300;
22
22
23 /// Generates a default name for a new graph, according to the number of graphs already displayed in
23 /// Generates a default name for a new graph, according to the number of graphs already displayed in
24 /// the zone
24 /// the zone
25 QString defaultGraphName(const QLayout &layout)
25 QString defaultGraphName(const QLayout &layout)
26 {
26 {
27 auto count = 0;
27 auto count = 0;
28 for (auto i = 0; i < layout.count(); ++i) {
28 for (auto i = 0; i < layout.count(); ++i) {
29 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
29 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
30 count++;
30 count++;
31 }
31 }
32 }
32 }
33
33
34 return QObject::tr("Graph %1").arg(count + 1);
34 return QObject::tr("Graph %1").arg(count + 1);
35 }
35 }
36
36
37 /**
38 * Applies a function to all graphs of the zone represented by its layout
39 * @param layout the layout that contains graphs
40 * @param fun the function to apply to each graph
41 */
42 template <typename Fun>
43 void processGraphs(QLayout &layout, Fun fun)
44 {
45 for (auto i = 0; i < layout.count(); ++i) {
46 if (auto item = layout.itemAt(i)) {
47 if (auto visualizationGraphWidget
48 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
49 fun(*visualizationGraphWidget);
50 }
51 }
52 }
53 }
54
37 } // namespace
55 } // namespace
38
56
39 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
57 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
40
58
41 explicit VisualizationZoneWidgetPrivate()
59 explicit VisualizationZoneWidgetPrivate()
42 : m_SynchronisationGroupId{QUuid::createUuid()},
60 : m_SynchronisationGroupId{QUuid::createUuid()},
43 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
61 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
44 {
62 {
45 }
63 }
46 QUuid m_SynchronisationGroupId;
64 QUuid m_SynchronisationGroupId;
47 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
65 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
48 };
66 };
49
67
50 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
68 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
51 : QWidget{parent},
69 : QWidget{parent},
52 ui{new Ui::VisualizationZoneWidget},
70 ui{new Ui::VisualizationZoneWidget},
53 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
71 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
54 {
72 {
55 ui->setupUi(this);
73 ui->setupUi(this);
56
74
57 ui->zoneNameLabel->setText(name);
75 ui->zoneNameLabel->setText(name);
58
76
59 // 'Close' options : widget is deleted when closed
77 // 'Close' options : widget is deleted when closed
60 setAttribute(Qt::WA_DeleteOnClose);
78 setAttribute(Qt::WA_DeleteOnClose);
61 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
79 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
62 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
80 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
63
81
64 // Synchronisation id
82 // Synchronisation id
65 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
83 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
66 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
84 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
67 }
85 }
68
86
69 VisualizationZoneWidget::~VisualizationZoneWidget()
87 VisualizationZoneWidget::~VisualizationZoneWidget()
70 {
88 {
71 delete ui;
89 delete ui;
72 }
90 }
73
91
74 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
92 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
75 {
93 {
76 // Synchronize new graph with others in the zone
94 // Synchronize new graph with others in the zone
77 impl->m_Synchronizer->addGraph(*graphWidget);
95 impl->m_Synchronizer->addGraph(*graphWidget);
78
96
79 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
97 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
80 }
98 }
81
99
82 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
100 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
83 {
101 {
84 auto graphWidget = new VisualizationGraphWidget{
102 auto graphWidget = new VisualizationGraphWidget{
85 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
103 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
86
104
87
105
88 // Set graph properties
106 // Set graph properties
89 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
107 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
90 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
108 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
91
109
92
110
93 // Lambda to synchronize zone widget
111 // Lambda to synchronize zone widget
94 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
112 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
95 const SqpRange &oldGraphRange) {
113 const SqpRange &oldGraphRange) {
96
114
97 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
115 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
98 auto frameLayout = ui->visualizationZoneFrame->layout();
116 auto frameLayout = ui->visualizationZoneFrame->layout();
99 for (auto i = 0; i < frameLayout->count(); ++i) {
117 for (auto i = 0; i < frameLayout->count(); ++i) {
100 auto graphChild
118 auto graphChild
101 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
119 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
102 if (graphChild && (graphChild != graphWidget)) {
120 if (graphChild && (graphChild != graphWidget)) {
103
121
104 auto graphChildRange = graphChild->graphRange();
122 auto graphChildRange = graphChild->graphRange();
105 switch (zoomType) {
123 switch (zoomType) {
106 case AcquisitionZoomType::ZoomIn: {
124 case AcquisitionZoomType::ZoomIn: {
107 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
125 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
108 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
126 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
109 graphChildRange.m_TStart += deltaLeft;
127 graphChildRange.m_TStart += deltaLeft;
110 graphChildRange.m_TEnd -= deltaRight;
128 graphChildRange.m_TEnd -= deltaRight;
111 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
129 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
112 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
130 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
113 << deltaLeft;
131 << deltaLeft;
114 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
132 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
115 << deltaRight;
133 << deltaRight;
116 qCDebug(LOG_VisualizationZoneWidget())
134 qCDebug(LOG_VisualizationZoneWidget())
117 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
135 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
118
136
119 break;
137 break;
120 }
138 }
121
139
122 case AcquisitionZoomType::ZoomOut: {
140 case AcquisitionZoomType::ZoomOut: {
123 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
141 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
124 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
142 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
125 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
143 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
126 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
144 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
127 << deltaLeft;
145 << deltaLeft;
128 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
146 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
129 << deltaRight;
147 << deltaRight;
130 qCDebug(LOG_VisualizationZoneWidget())
148 qCDebug(LOG_VisualizationZoneWidget())
131 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
149 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
132 graphChildRange.m_TStart -= deltaLeft;
150 graphChildRange.m_TStart -= deltaLeft;
133 graphChildRange.m_TEnd += deltaRight;
151 graphChildRange.m_TEnd += deltaRight;
134 break;
152 break;
135 }
153 }
136 case AcquisitionZoomType::PanRight: {
154 case AcquisitionZoomType::PanRight: {
137 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
155 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
138 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
156 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
139 graphChildRange.m_TStart += deltaRight;
157 graphChildRange.m_TStart += deltaRight;
140 graphChildRange.m_TEnd += deltaRight;
158 graphChildRange.m_TEnd += deltaRight;
141 qCDebug(LOG_VisualizationZoneWidget())
159 qCDebug(LOG_VisualizationZoneWidget())
142 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
160 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
143 break;
161 break;
144 }
162 }
145 case AcquisitionZoomType::PanLeft: {
163 case AcquisitionZoomType::PanLeft: {
146 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
164 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
147 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
165 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
148 graphChildRange.m_TStart -= deltaLeft;
166 graphChildRange.m_TStart -= deltaLeft;
149 graphChildRange.m_TEnd -= deltaLeft;
167 graphChildRange.m_TEnd -= deltaLeft;
150 break;
168 break;
151 }
169 }
152 case AcquisitionZoomType::Unknown: {
170 case AcquisitionZoomType::Unknown: {
153 qCDebug(LOG_VisualizationZoneWidget())
171 qCDebug(LOG_VisualizationZoneWidget())
154 << tr("Impossible to synchronize: zoom type unknown");
172 << tr("Impossible to synchronize: zoom type unknown");
155 break;
173 break;
156 }
174 }
157 default:
175 default:
158 qCCritical(LOG_VisualizationZoneWidget())
176 qCCritical(LOG_VisualizationZoneWidget())
159 << tr("Impossible to synchronize: zoom type not take into account");
177 << tr("Impossible to synchronize: zoom type not take into account");
160 // No action
178 // No action
161 break;
179 break;
162 }
180 }
163 graphChild->enableAcquisition(false);
181 graphChild->enableAcquisition(false);
164 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
182 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
165 << graphChild->graphRange();
183 << graphChild->graphRange();
166 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
184 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
167 << graphChildRange;
185 << graphChildRange;
168 qCDebug(LOG_VisualizationZoneWidget())
186 qCDebug(LOG_VisualizationZoneWidget())
169 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
187 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
170 graphChild->setGraphRange(graphChildRange);
188 graphChild->setGraphRange(graphChildRange);
171 graphChild->enableAcquisition(true);
189 graphChild->enableAcquisition(true);
172 }
190 }
173 }
191 }
174 };
192 };
175
193
176 // connection for synchronization
194 // connection for synchronization
177 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
195 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
178 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
196 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
179 &VisualizationZoneWidget::onVariableAdded);
197 &VisualizationZoneWidget::onVariableAdded);
180 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
198 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
181 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
199 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
182
200
183 auto range = SqpRange{};
201 auto range = SqpRange{};
184
202
185 // Apply visitor to graph children
203 // Apply visitor to graph children
186 auto layout = ui->visualizationZoneFrame->layout();
204 auto layout = ui->visualizationZoneFrame->layout();
187 if (layout->count() > 0) {
205 if (layout->count() > 0) {
188 // Case of a new graph in a existant zone
206 // Case of a new graph in a existant zone
189 if (auto visualizationGraphWidget
207 if (auto visualizationGraphWidget
190 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
208 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
191 range = visualizationGraphWidget->graphRange();
209 range = visualizationGraphWidget->graphRange();
192 }
210 }
193 }
211 }
194 else {
212 else {
195 // Case of a new graph as the first of the zone
213 // Case of a new graph as the first of the zone
196 range = variable->range();
214 range = variable->range();
197 }
215 }
198
216
199 this->addGraph(graphWidget);
217 this->addGraph(graphWidget);
200
218
201 graphWidget->addVariable(variable, range);
219 graphWidget->addVariable(variable, range);
202
220
203 // get y using variable range
221 // get y using variable range
204 if (auto dataSeries = variable->dataSeries()) {
222 if (auto dataSeries = variable->dataSeries()) {
205 dataSeries->lockRead();
223 dataSeries->lockRead();
206 auto valuesBounds
224 auto valuesBounds
207 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
225 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
208 auto end = dataSeries->cend();
226 auto end = dataSeries->cend();
209 if (valuesBounds.first != end && valuesBounds.second != end) {
227 if (valuesBounds.first != end && valuesBounds.second != end) {
210 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
228 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
211
229
212 auto minValue = rangeValue(valuesBounds.first->minValue());
230 auto minValue = rangeValue(valuesBounds.first->minValue());
213 auto maxValue = rangeValue(valuesBounds.second->maxValue());
231 auto maxValue = rangeValue(valuesBounds.second->maxValue());
214
232
215 graphWidget->setYRange(SqpRange{minValue, maxValue});
233 graphWidget->setYRange(SqpRange{minValue, maxValue});
216 }
234 }
217 dataSeries->unlock();
235 dataSeries->unlock();
218 }
236 }
219
237
220 return graphWidget;
238 return graphWidget;
221 }
239 }
222
240
223 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
241 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
224 {
242 {
225 if (visitor) {
243 if (visitor) {
226 visitor->visitEnter(this);
244 visitor->visitEnter(this);
227
245
228 // Apply visitor to graph children
246 // Apply visitor to graph children: widgets different from graphs are not visited (no
229 auto layout = ui->visualizationZoneFrame->layout();
247 // action)
230 for (auto i = 0; i < layout->count(); ++i) {
248 processGraphs(
231 if (auto item = layout->itemAt(i)) {
249 *ui->visualizationZoneFrame->layout(),
232 // Widgets different from graphs are not visited (no action)
250 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
233 if (auto visualizationGraphWidget
234 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
235 visualizationGraphWidget->accept(visitor);
236 }
237 }
238 }
239
251
240 visitor->visitLeave(this);
252 visitor->visitLeave(this);
241 }
253 }
242 else {
254 else {
243 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
255 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
244 }
256 }
245 }
257 }
246
258
247 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
259 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
248 {
260 {
249 // A tab can always accomodate a variable
261 // A tab can always accomodate a variable
250 Q_UNUSED(variable);
262 Q_UNUSED(variable);
251 return true;
263 return true;
252 }
264 }
253
265
254 bool VisualizationZoneWidget::contains(const Variable &variable) const
266 bool VisualizationZoneWidget::contains(const Variable &variable) const
255 {
267 {
256 Q_UNUSED(variable);
268 Q_UNUSED(variable);
257 return false;
269 return false;
258 }
270 }
259
271
260 QString VisualizationZoneWidget::name() const
272 QString VisualizationZoneWidget::name() const
261 {
273 {
262 return ui->zoneNameLabel->text();
274 return ui->zoneNameLabel->text();
263 }
275 }
264
276
277 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
278 {
279 // Closes graphs in the zone
280 processGraphs(*ui->visualizationZoneFrame->layout(),
281 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
282
283 QWidget::closeEvent(event);
284 }
285
265 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
286 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
266 {
287 {
267 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
288 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
268 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
289 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
269 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
290 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
270 }
291 }
271
292
272 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
293 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
273 {
294 {
274 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
295 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
275 Q_ARG(std::shared_ptr<Variable>, variable),
296 Q_ARG(std::shared_ptr<Variable>, variable),
276 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
297 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
277 }
298 }
General Comments 0
You need to be logged in to leave comments. Login now