##// END OF EJS Templates
Switched to new TS impl but quite broken!...
jeandet -
r1420:3c3e24550401
parent child
Show More
@@ -13,8 +13,14 QT5_WRAP_UI(UiGenerated_SRCS
13 add_executable(sciqlopapp WIN32 ${app_SRCS} ${UiGenerated_SRCS})
13 add_executable(sciqlopapp WIN32 ${app_SRCS} ${UiGenerated_SRCS})
14 if(NOT BUILD_SHARED_LIBS)
14 if(NOT BUILD_SHARED_LIBS)
15 add_definitions(-DQT_STATICPLUGIN)
15 add_definitions(-DQT_STATICPLUGIN)
16 target_link_libraries(sciqlopapp mockplugin)
16 if(BUILD_PLUGINS)
17 target_link_libraries(sciqlopapp amdaplugin)
17 target_link_libraries(sciqlopapp mockplugin)
18 target_link_libraries(sciqlopapp amdaplugin)
19 endif()
20 endif()
21
22 if(NOT BUILD_PLUGINS)
23 add_definitions(-DSQP_NO_PLUGINS)
18 endif()
24 endif()
19
25
20 target_link_libraries(sciqlopapp
26 target_link_libraries(sciqlopapp
@@ -44,10 +44,12 const auto PLUGIN_DIRECTORY_NAME = QStringLiteral("plugins");
44 int main(int argc, char* argv[])
44 int main(int argc, char* argv[])
45 {
45 {
46 #ifdef QT_STATICPLUGIN
46 #ifdef QT_STATICPLUGIN
47 #ifndef SQP_NO_PLUGINS
47 Q_IMPORT_PLUGIN(MockPlugin)
48 Q_IMPORT_PLUGIN(MockPlugin)
48 Q_IMPORT_PLUGIN(AmdaPlugin)
49 Q_IMPORT_PLUGIN(AmdaPlugin)
49 Q_INIT_RESOURCE(amdaresources);
50 Q_INIT_RESOURCE(amdaresources);
50 #endif
51 #endif
52 #endif
51 Q_INIT_RESOURCE(sqpguiresources);
53 Q_INIT_RESOURCE(sqpguiresources);
52
54
53 SqpApplication::setOrganizationName("LPP");
55 SqpApplication::setOrganizationName("LPP");
@@ -1,1 +1,1
1 Subproject commit 00b9e6e4b7f57c09175c396576ac6e30f45a14ff
1 Subproject commit a8a4e48c21af5a28ad3f56582db7bbec0fe76978
@@ -11,11 +11,12
11
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableInspectorWidget)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableInspectorWidget)
13
13
14 class Variable;
14 class Variable2;
15
15
16 class QProgressBarItemDelegate;
16 class QProgressBarItemDelegate;
17
17
18 namespace Ui {
18 namespace Ui
19 {
19 class VariableInspectorWidget;
20 class VariableInspectorWidget;
20 } // Ui
21 } // Ui
21
22
@@ -24,11 +25,12 class VariableInspectorWidget;
24 * which it is possible to view the loaded variables, handle them or trigger their display in
25 * which it is possible to view the loaded variables, handle them or trigger their display in
25 * visualization
26 * visualization
26 */
27 */
27 class VariableInspectorWidget : public QWidget {
28 class VariableInspectorWidget : public QWidget
29 {
28 Q_OBJECT
30 Q_OBJECT
29
31
30 public:
32 public:
31 explicit VariableInspectorWidget(QWidget *parent = 0);
33 explicit VariableInspectorWidget(QWidget* parent = 0);
32 virtual ~VariableInspectorWidget();
34 virtual ~VariableInspectorWidget();
33
35
34 signals:
36 signals:
@@ -40,18 +42,18 signals:
40 * @remarks To make the dynamic addition of menus work, the connections to this signal must be
42 * @remarks To make the dynamic addition of menus work, the connections to this signal must be
41 * in Qt :: DirectConnection
43 * in Qt :: DirectConnection
42 */
44 */
43 void tableMenuAboutToBeDisplayed(QMenu *tableMenu,
45 void tableMenuAboutToBeDisplayed(
44 const QVector<std::shared_ptr<Variable> > &variables);
46 QMenu* tableMenu, const QVector<std::shared_ptr<Variable2>>& variables);
45
47
46 private:
48 private:
47 Ui::VariableInspectorWidget *ui;
49 Ui::VariableInspectorWidget* ui;
48
50
49 QProgressBarItemDelegate *m_ProgressBarItemDelegate;
51 QProgressBarItemDelegate* m_ProgressBarItemDelegate;
50 VariableModel2* m_model;
52 VariableModel2* m_model;
51
53
52 private slots:
54 private slots:
53 /// Slot called when right clicking on an variable in the table (displays a menu)
55 /// Slot called when right clicking on an variable in the table (displays a menu)
54 void onTableMenuRequested(const QPoint &pos) noexcept;
56 void onTableMenuRequested(const QPoint& pos) noexcept;
55 /// Refreshes instantly the variable view
57 /// Refreshes instantly the variable view
56 void refresh() noexcept;
58 void refresh() noexcept;
57 };
59 };
@@ -6,11 +6,12
6
6
7 #include <memory>
7 #include <memory>
8
8
9 namespace Ui {
9 namespace Ui
10 {
10 class VariableMenuHeaderWidget;
11 class VariableMenuHeaderWidget;
11 } // Ui
12 } // Ui
12
13
13 class Variable;
14 class Variable2;
14
15
15 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableMenuHeaderWidget)
16 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableMenuHeaderWidget)
16
17
@@ -19,19 +20,20 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableMenuHeaderWidget)
19 * variable inspector
20 * variable inspector
20 * @sa VariableInspectorWidget
21 * @sa VariableInspectorWidget
21 */
22 */
22 class VariableMenuHeaderWidget : public QWidget {
23 class VariableMenuHeaderWidget : public QWidget
24 {
23 public:
25 public:
24 /**
26 /**
25 * Ctor
27 * Ctor
26 * @param variables the list of variables used to generate the header
28 * @param variables the list of variables used to generate the header
27 * @param parent the parent widget
29 * @param parent the parent widget
28 */
30 */
29 explicit VariableMenuHeaderWidget(const QVector<std::shared_ptr<Variable> > &variables,
31 explicit VariableMenuHeaderWidget(
30 QWidget *parent = 0);
32 const QVector<std::shared_ptr<Variable2>>& variables, QWidget* parent = 0);
31 virtual ~VariableMenuHeaderWidget() noexcept;
33 virtual ~VariableMenuHeaderWidget() noexcept;
32
34
33 private:
35 private:
34 Ui::VariableMenuHeaderWidget *ui;
36 Ui::VariableMenuHeaderWidget* ui;
35 };
37 };
36
38
37 #endif // SCIQLOP_VARIABLEMENUHEADERWIDGET_H
39 #endif // SCIQLOP_VARIABLEMENUHEADERWIDGET_H
@@ -12,33 +12,35 class IDataSeries;
12 class QCPAxis;
12 class QCPAxis;
13 class QCustomPlot;
13 class QCustomPlot;
14 class SqpColorScale;
14 class SqpColorScale;
15 class Variable;
15 class Variable2;
16
16
17 /// Formats a data value according to the axis on which it is present
17 /// Formats a data value according to the axis on which it is present
18 QString formatValue(double value, const QCPAxis &axis);
18 QString formatValue(double value, const QCPAxis& axis);
19
19
20 /**
20 /**
21 * Helper used to handle axes rendering
21 * Helper used to handle axes rendering
22 */
22 */
23 struct IAxisHelper {
23 struct IAxisHelper
24 {
24 virtual ~IAxisHelper() noexcept = default;
25 virtual ~IAxisHelper() noexcept = default;
25
26
26 /// Set properties of the plot's axes and the color scale associated to plot passed as
27 /// Set properties of the plot's axes and the color scale associated to plot passed as
27 /// parameters
28 /// parameters
28 /// @param plot the plot for which to set axe properties
29 /// @param plot the plot for which to set axe properties
29 /// @param colorScale the color scale for which to set properties
30 /// @param colorScale the color scale for which to set properties
30 virtual void setProperties(QCustomPlot &plot, SqpColorScale &colorScale) = 0;
31 virtual void setProperties(QCustomPlot& plot, SqpColorScale& colorScale) = 0;
31
32
32 /// Set the units of the plot's axes and the color scale associated to plot passed as
33 /// Set the units of the plot's axes and the color scale associated to plot passed as
33 /// parameters
34 /// parameters
34 /// @param plot the plot for which to set axe units
35 /// @param plot the plot for which to set axe units
35 /// @param colorScale the color scale for which to set unit
36 /// @param colorScale the color scale for which to set unit
36 virtual void setUnits(QCustomPlot &plot, SqpColorScale &colorScale) = 0;
37 virtual void setUnits(QCustomPlot& plot, SqpColorScale& colorScale) = 0;
37 };
38 };
38
39
39 struct IAxisHelperFactory {
40 struct IAxisHelperFactory
41 {
40 /// Creates IPlottablesHelper according to the type of data series a variable holds
42 /// Creates IPlottablesHelper according to the type of data series a variable holds
41 static std::unique_ptr<IAxisHelper> create(const Variable &variable) noexcept;
43 static std::unique_ptr<IAxisHelper> create(Variable2& variable) noexcept;
42 };
44 };
43
45
44 #endif // SCIQLOP_AXISRENDERINGUTILS_H
46 #endif // SCIQLOP_AXISRENDERINGUTILS_H
@@ -1,21 +1,22
1 #ifndef SCIQLOP_IVARIABLECONTAINER_H
1 #ifndef SCIQLOP_IVARIABLECONTAINER_H
2 #define SCIQLOP_IVARIABLECONTAINER_H
2 #define SCIQLOP_IVARIABLECONTAINER_H
3
3
4 class Variable;
4 class Variable2;
5
5
6 /**
6 /**
7 * @brief The IVariableContainer interface represents an UI object that can accommodate a variable
7 * @brief The IVariableContainer interface represents an UI object that can accommodate a variable
8 */
8 */
9 class IVariableContainer {
9 class IVariableContainer
10 {
10
11
11 public:
12 public:
12 virtual ~IVariableContainer() = default;
13 virtual ~IVariableContainer() = default;
13
14
14 /// Checks if the container can handle the variable passed in parameter
15 /// Checks if the container can handle the variable passed in parameter
15 virtual bool canDrop(const Variable &variable) const = 0;
16 virtual bool canDrop(Variable2& variable) const = 0;
16
17
17 /// Checks if the container contains the variable passed in parameter
18 /// Checks if the container contains the variable passed in parameter
18 virtual bool contains(const Variable &variable) const = 0;
19 virtual bool contains(Variable2& variable) const = 0;
19 };
20 };
20
21
21
22
@@ -13,22 +13,24 Q_DECLARE_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils)
13
13
14 class QCPColorScale;
14 class QCPColorScale;
15 class QCustomPlot;
15 class QCustomPlot;
16 class Variable;
16 class Variable2;
17
17
18 /**
18 /**
19 * Helper used to handle plottables rendering
19 * Helper used to handle plottables rendering
20 */
20 */
21 struct IPlottablesHelper {
21 struct IPlottablesHelper
22 {
22 virtual ~IPlottablesHelper() noexcept = default;
23 virtual ~IPlottablesHelper() noexcept = default;
23
24
24 /// Set properties of the plottables passed as parameter
25 /// Set properties of the plottables passed as parameter
25 /// @param plottables the plottables for which to set properties
26 /// @param plottables the plottables for which to set properties
26 virtual void setProperties(PlottablesMap &plottables) = 0;
27 virtual void setProperties(PlottablesMap& plottables) = 0;
27 };
28 };
28
29
29 struct IPlottablesHelperFactory {
30 struct IPlottablesHelperFactory
31 {
30 /// Creates IPlottablesHelper according to the type of data series a variable holds
32 /// Creates IPlottablesHelper according to the type of data series a variable holds
31 static std::unique_ptr<IPlottablesHelper> create(const Variable &variable) noexcept;
33 static std::unique_ptr<IPlottablesHelper> create(Variable2& variable) noexcept;
32 };
34 };
33
35
34 #endif // SCIQLOP_PLOTTABLESRENDERINGUTILS_H
36 #endif // SCIQLOP_PLOTTABLESRENDERINGUTILS_H
@@ -15,13 +15,14 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphHelper)
15 class IDataSeries;
15 class IDataSeries;
16 class QCPAbstractPlottable;
16 class QCPAbstractPlottable;
17 class QCustomPlot;
17 class QCustomPlot;
18 class Variable;
18 class Variable2;
19
19
20 /**
20 /**
21 * @brief The VisualizationGraphHelper class aims to create the QCustomPlot components relative to a
21 * @brief The VisualizationGraphHelper class aims to create the QCustomPlot components relative to a
22 * variable, depending on the data series of this variable
22 * variable, depending on the data series of this variable
23 */
23 */
24 struct VisualizationGraphHelper {
24 struct VisualizationGraphHelper
25 {
25 /**
26 /**
26 * Creates (if possible) the QCustomPlot components relative to the variable passed in
27 * Creates (if possible) the QCustomPlot components relative to the variable passed in
27 * parameter, and adds these to the plot passed in parameter.
28 * parameter, and adds these to the plot passed in parameter.
@@ -30,12 +31,12 struct VisualizationGraphHelper {
30 * components.
31 * components.
31 * @return the list of the components created
32 * @return the list of the components created
32 */
33 */
33 static PlottablesMap create(std::shared_ptr<Variable> variable, QCustomPlot &plot) noexcept;
34 static PlottablesMap create(std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept;
34
35
35 static void updateData(PlottablesMap &plottables, std::shared_ptr<Variable> variable,
36 static void updateData(PlottablesMap& plottables, std::shared_ptr<Variable2> variable,
36 const DateTimeRange &dateTime);
37 const DateTimeRange& dateTime);
37
38
38 static void setYAxisRange(std::shared_ptr<Variable> variable, QCustomPlot &plot) noexcept;
39 static void setYAxisRange(std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept;
39 };
40 };
40
41
41 #endif // SCIQLOP_VISUALIZATIONGRAPHHELPER_H
42 #endif // SCIQLOP_VISUALIZATIONGRAPHHELPER_H
@@ -9,28 +9,29 class IDataSeries;
9 class QCustomPlot;
9 class QCustomPlot;
10 class QMouseEvent;
10 class QMouseEvent;
11 class Unit;
11 class Unit;
12 class Variable;
12 class Variable2;
13 class VisualizationGraphWidget;
13 class VisualizationGraphWidget;
14
14
15 class VisualizationGraphRenderingDelegate {
15 class VisualizationGraphRenderingDelegate
16 {
16 public:
17 public:
17 /// Ctor
18 /// Ctor
18 /// @param graphWidget the graph widget to which the delegate is associated
19 /// @param graphWidget the graph widget to which the delegate is associated
19 /// @remarks the graph widget must exist throughout the life cycle of the delegate
20 /// @remarks the graph widget must exist throughout the life cycle of the delegate
20 explicit VisualizationGraphRenderingDelegate(VisualizationGraphWidget &graphWidget);
21 explicit VisualizationGraphRenderingDelegate(VisualizationGraphWidget& graphWidget);
21
22
22 void onMouseDoubleClick(QMouseEvent *event) noexcept;
23 void onMouseDoubleClick(QMouseEvent* event) noexcept;
23 void updateTooltip(QMouseEvent *event) noexcept;
24 void updateTooltip(QMouseEvent* event) noexcept;
24 /// Updates rendering when data of plot changed
25 /// Updates rendering when data of plot changed
25 void onPlotUpdated() noexcept;
26 void onPlotUpdated() noexcept;
26
27
27 /// Sets units of the plot's axes according to the properties of the variable passed as
28 /// Sets units of the plot's axes according to the properties of the variable passed as
28 /// parameter
29 /// parameter
29 void setAxesUnits(const Variable &variable) noexcept;
30 void setAxesUnits(Variable2& variable) noexcept;
30
31
31 /// Sets graph properties of the plottables passed as parameter, from the variable that
32 /// Sets graph properties of the plottables passed as parameter, from the variable that
32 /// generated these
33 /// generated these
33 void setGraphProperties(const Variable &variable, PlottablesMap &plottables) noexcept;
34 void setGraphProperties(Variable2& variable, PlottablesMap& plottables) noexcept;
34
35
35
36
36 /// Shows or hides graph overlay (name, close button, etc.)
37 /// Shows or hides graph overlay (name, close button, etc.)
@@ -5,8 +5,8
5 #include "Visualization/VisualizationDragWidget.h"
5 #include "Visualization/VisualizationDragWidget.h"
6
6
7 #include <QLoggingCategory>
7 #include <QLoggingCategory>
8 #include <QWidget>
9 #include <QUuid>
8 #include <QUuid>
9 #include <QWidget>
10
10
11 #include <memory>
11 #include <memory>
12
12
@@ -18,18 +18,20 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
18
18
19 class QCPRange;
19 class QCPRange;
20 class QCustomPlot;
20 class QCustomPlot;
21 class Variable;
21 class Variable2;
22 class VisualizationWidget;
22 class VisualizationWidget;
23 class VisualizationZoneWidget;
23 class VisualizationZoneWidget;
24 class VisualizationSelectionZoneItem;
24 class VisualizationSelectionZoneItem;
25
25
26 namespace Ui {
26 namespace Ui
27 {
27 class VisualizationGraphWidget;
28 class VisualizationGraphWidget;
28 } // namespace Ui
29 } // namespace Ui
29
30
30 /// Defines options that can be associated with the graph
31 /// Defines options that can be associated with the graph
31 enum GraphFlag {
32 enum GraphFlag
32 DisableAll = 0x0, ///< Disables acquisition and synchronization
33 {
34 DisableAll = 0x0, ///< Disables acquisition and synchronization
33 EnableAcquisition = 0x1, ///< When this flag is set, the change of the graph's range leads to
35 EnableAcquisition = 0x1, ///< When this flag is set, the change of the graph's range leads to
34 /// the acquisition of data
36 /// the acquisition of data
35 EnableSynchronization = 0x2, ///< When this flag is set, the change of the graph's range causes
37 EnableSynchronization = 0x2, ///< When this flag is set, the change of the graph's range causes
@@ -41,66 +43,68 enum GraphFlag {
41 Q_DECLARE_FLAGS(GraphFlags, GraphFlag)
43 Q_DECLARE_FLAGS(GraphFlags, GraphFlag)
42 Q_DECLARE_OPERATORS_FOR_FLAGS(GraphFlags)
44 Q_DECLARE_OPERATORS_FOR_FLAGS(GraphFlags)
43
45
44 class VisualizationGraphWidget : public VisualizationDragWidget, public IVisualizationWidget {
46 class VisualizationGraphWidget : public VisualizationDragWidget, public IVisualizationWidget
47 {
45 Q_OBJECT
48 Q_OBJECT
46
49
47 friend class QCustomPlotSynchronizer;
50 friend class QCustomPlotSynchronizer;
48 friend class VisualizationGraphRenderingDelegate;
51 friend class VisualizationGraphRenderingDelegate;
49
52
50 public:
53 public:
51 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
54 explicit VisualizationGraphWidget(const QString& name = {}, QWidget* parent = 0);
52 virtual ~VisualizationGraphWidget();
55 virtual ~VisualizationGraphWidget();
53
56
54 /// Returns the VisualizationZoneWidget which contains the graph or nullptr
57 /// Returns the VisualizationZoneWidget which contains the graph or nullptr
55 VisualizationZoneWidget *parentZoneWidget() const noexcept;
58 VisualizationZoneWidget* parentZoneWidget() const noexcept;
56
59
57 /// Returns the main VisualizationWidget which contains the graph or nullptr
60 /// Returns the main VisualizationWidget which contains the graph or nullptr
58 VisualizationWidget *parentVisualizationWidget() const;
61 VisualizationWidget* parentVisualizationWidget() const;
59
62
60 /// Sets graph options
63 /// Sets graph options
61 void setFlags(GraphFlags flags);
64 void setFlags(GraphFlags flags);
62
65
63 void addVariable(std::shared_ptr<Variable> variable, DateTimeRange range);
66 void addVariable(std::shared_ptr<Variable2> variable, DateTimeRange range);
64
67
65 /// Removes a variable from the graph
68 /// Removes a variable from the graph
66 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
69 void removeVariable(std::shared_ptr<Variable2> variable) noexcept;
67
70
68 /// Returns the list of all variables used in the graph
71 /// Returns the list of all variables used in the graph
69 std::vector<std::shared_ptr<Variable> > variables() const;
72 std::vector<std::shared_ptr<Variable2>> variables() const;
70
73
71 /// Sets the y-axis range based on the data of a variable
74 /// Sets the y-axis range based on the data of a variable
72 void setYRange(std::shared_ptr<Variable> variable);
75 void setYRange(std::shared_ptr<Variable2> variable);
73 DateTimeRange graphRange() const noexcept;
76 DateTimeRange graphRange() const noexcept;
74 void setGraphRange(const DateTimeRange &range, bool updateVar=false, bool forward=false);
77 void setGraphRange(const DateTimeRange& range, bool updateVar = false, bool forward = false);
75 void setAutoRangeOnVariableInitialization(bool value);
78 void setAutoRangeOnVariableInitialization(bool value);
76
79
77 // Zones
80 // Zones
78 /// Returns the ranges of all the selection zones on the graph
81 /// Returns the ranges of all the selection zones on the graph
79 QVector<DateTimeRange> selectionZoneRanges() const;
82 QVector<DateTimeRange> selectionZoneRanges() const;
80 /// Adds new selection zones in the graph
83 /// Adds new selection zones in the graph
81 void addSelectionZones(const QVector<DateTimeRange> &ranges);
84 void addSelectionZones(const QVector<DateTimeRange>& ranges);
82 /// Adds a new selection zone in the graph
85 /// Adds a new selection zone in the graph
83 VisualizationSelectionZoneItem *addSelectionZone(const QString &name, const DateTimeRange &range);
86 VisualizationSelectionZoneItem* addSelectionZone(
87 const QString& name, const DateTimeRange& range);
84 /// Removes the specified selection zone
88 /// Removes the specified selection zone
85 void removeSelectionZone(VisualizationSelectionZoneItem *selectionZone);
89 void removeSelectionZone(VisualizationSelectionZoneItem* selectionZone);
86
90
87 /// Undo the last zoom done with a zoom box
91 /// Undo the last zoom done with a zoom box
88 void undoZoom();
92 void undoZoom();
89
93
90 void zoom(double factor, int center, Qt::Orientation orientation, bool forward=true);
94 void zoom(double factor, int center, Qt::Orientation orientation, bool forward = true);
91 void move(double factor, Qt::Orientation orientation, bool forward=true);
95 void move(double factor, Qt::Orientation orientation, bool forward = true);
92 void move(double dx, double dy, bool forward=true);
96 void move(double dx, double dy, bool forward = true);
93 void transform(const DateTimeRangeTransformation& tranformation, bool forward=true);
97 void transform(const DateTimeRangeTransformation& tranformation, bool forward = true);
94
98
95 // IVisualizationWidget interface
99 // IVisualizationWidget interface
96 void accept(IVisualizationWidgetVisitor *visitor) override;
100 void accept(IVisualizationWidgetVisitor* visitor) override;
97 bool canDrop(const Variable &variable) const override;
101 bool canDrop(Variable2& variable) const override;
98 bool contains(const Variable &variable) const override;
102 bool contains(Variable2& variable) const override;
99 QString name() const override;
103 QString name() const override;
100
104
101 // VisualisationDragWidget
105 // VisualisationDragWidget
102 QMimeData *mimeData(const QPoint &position) const override;
106 QMimeData* mimeData(const QPoint& position) const override;
103 QPixmap customDragPixmap(const QPoint &dragPosition) override;
107 QPixmap customDragPixmap(const QPoint& dragPosition) override;
104 bool isDragAllowed() const override;
108 bool isDragAllowed() const override;
105 void highlightForMerge(bool highlighted) override;
109 void highlightForMerge(bool highlighted) override;
106
110
@@ -117,65 +121,65 public:
117 void removeHorizontalCursor();
121 void removeHorizontalCursor();
118
122
119 signals:
123 signals:
120 void synchronize(const DateTimeRange &range, const DateTimeRange &oldRange);
124 void synchronize(const DateTimeRange& range, const DateTimeRange& oldRange);
121 void changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange &range);
125 void changeRange(const std::shared_ptr<Variable2>& variable, const DateTimeRange& range);
122
126
123 /// Signal emitted when the variable is about to be removed from the graph
127 /// Signal emitted when the variable is about to be removed from the graph
124 void variableAboutToBeRemoved(std::shared_ptr<Variable> var);
128 void variableAboutToBeRemoved(std::shared_ptr<Variable2> var);
125 /// Signal emitted when the variable has been added to the graph
129 /// Signal emitted when the variable has been added to the graph
126 void variableAdded(std::shared_ptr<Variable> var);
130 void variableAdded(std::shared_ptr<Variable2> var);
127
131
128
132
129 void zoom_sig(double factor, int center, Qt::Orientation orientation, bool forward=true);
133 void zoom_sig(double factor, int center, Qt::Orientation orientation, bool forward = true);
130 void move_sig(double factor, Qt::Orientation orientation, bool forward=true);
134 void move_sig(double factor, Qt::Orientation orientation, bool forward = true);
131 void move_sig(double dx, double dy, bool forward=true);
135 void move_sig(double dx, double dy, bool forward = true);
132 void transform_sig(const DateTimeRangeTransformation& tranformation, bool forward=true);
136 void transform_sig(const DateTimeRangeTransformation& tranformation, bool forward = true);
133 void setrange_sig(const DateTimeRange& range, bool updateVar=false, bool forward=true);
137 void setrange_sig(const DateTimeRange& range, bool updateVar = false, bool forward = true);
134
138
135 protected:
139 protected:
136 void closeEvent(QCloseEvent *event) override;
140 void closeEvent(QCloseEvent* event) override;
137 void enterEvent(QEvent *event) override;
141 void enterEvent(QEvent* event) override;
138 void leaveEvent(QEvent *event) override;
142 void leaveEvent(QEvent* event) override;
139 void wheelEvent(QWheelEvent * event) override;
143 void wheelEvent(QWheelEvent* event) override;
140 void mouseMoveEvent(QMouseEvent *event) override;
144 void mouseMoveEvent(QMouseEvent* event) override;
141 void mouseReleaseEvent(QMouseEvent *event) override;
145 void mouseReleaseEvent(QMouseEvent* event) override;
142 void mousePressEvent(QMouseEvent *event) override;
146 void mousePressEvent(QMouseEvent* event) override;
143 void mouseDoubleClickEvent(QMouseEvent *event) override;
147 void mouseDoubleClickEvent(QMouseEvent* event) override;
144 void keyReleaseEvent(QKeyEvent * event) override;
148 void keyReleaseEvent(QKeyEvent* event) override;
145 void keyPressEvent(QKeyEvent * event) override;
149 void keyPressEvent(QKeyEvent* event) override;
146
150
147 QCustomPlot &plot() const noexcept;
151 QCustomPlot& plot() const noexcept;
148
152
149 private:
153 private:
150 Ui::VisualizationGraphWidget *ui;
154 Ui::VisualizationGraphWidget* ui;
151
155
152 class VisualizationGraphWidgetPrivate;
156 class VisualizationGraphWidgetPrivate;
153 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
157 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
154
158
155 private slots:
159 private slots:
156 /// Slot called when right clicking on the graph (displays a menu)
160 /// Slot called when right clicking on the graph (displays a menu)
157 void onGraphMenuRequested(const QPoint &pos) noexcept;
161 void onGraphMenuRequested(const QPoint& pos) noexcept;
158
162
159 /// Rescale the X axe to range parameter
163 /// Rescale the X axe to range parameter
160 // void onRangeChanged(const QCPRange &newRange, const QCPRange &oldRange);
164 // void onRangeChanged(const QCPRange &newRange, const QCPRange &oldRange);
161
165
162 /// Slot called when a mouse double click was made
166 /// Slot called when a mouse double click was made
163 void onMouseDoubleClick(QMouseEvent *event) noexcept;
167 void onMouseDoubleClick(QMouseEvent* event) noexcept;
164 /// Slot called when a mouse move was made
168 /// Slot called when a mouse move was made
165 void onMouseMove(QMouseEvent *event) noexcept;
169 void onMouseMove(QMouseEvent* event) noexcept;
166 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
170 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
167 void onMouseWheel(QWheelEvent *event) noexcept;
171 void onMouseWheel(QWheelEvent* event) noexcept;
168 /// Slot called when a mouse press was made, to activate the calibration of a graph
172 /// Slot called when a mouse press was made, to activate the calibration of a graph
169 void onMousePress(QMouseEvent *event) noexcept;
173 void onMousePress(QMouseEvent* event) noexcept;
170 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
174 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
171 void onMouseRelease(QMouseEvent *event) noexcept;
175 void onMouseRelease(QMouseEvent* event) noexcept;
172
176
173 void onDataCacheVariableUpdated();
177 void onDataCacheVariableUpdated();
174
178
175 void onUpdateVarDisplaying(std::shared_ptr<Variable> variable, const DateTimeRange &range);
179 void onUpdateVarDisplaying(std::shared_ptr<Variable2> variable, const DateTimeRange& range);
176
180
177 void variableUpdated(QUuid id);
181 void variableUpdated(QUuid id);
178 void variableDeleted(const std::shared_ptr<Variable>&);
182 void variableDeleted(const std::shared_ptr<Variable2>&);
179 };
183 };
180
184
181 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
185 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -14,29 +14,31 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
14 class Variable;
14 class Variable;
15 class VisualizationZoneWidget;
15 class VisualizationZoneWidget;
16
16
17 namespace Ui {
17 namespace Ui
18 {
18 class VisualizationTabWidget;
19 class VisualizationTabWidget;
19 } // namespace Ui
20 } // namespace Ui
20
21
21 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
22 class VisualizationTabWidget : public QWidget, public IVisualizationWidget
23 {
22 Q_OBJECT
24 Q_OBJECT
23
25
24 public:
26 public:
25 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
27 explicit VisualizationTabWidget(const QString& name = {}, QWidget* parent = 0);
26 virtual ~VisualizationTabWidget();
28 virtual ~VisualizationTabWidget();
27
29
28 /// Adds a zone widget
30 /// Adds a zone widget
29 void addZone(VisualizationZoneWidget *zoneWidget);
31 void addZone(VisualizationZoneWidget* zoneWidget);
30
32
31 /// Inserts a zone widget at the specified position
33 /// Inserts a zone widget at the specified position
32 void insertZone(int index, VisualizationZoneWidget *zoneWidget);
34 void insertZone(int index, VisualizationZoneWidget* zoneWidget);
33
35
34 /// Returns the list of zone widget names in the order they are displayed
36 /// Returns the list of zone widget names in the order they are displayed
35 QStringList availableZoneWidgets() const;
37 QStringList availableZoneWidgets() const;
36
38
37 /// Returns the zone with the specified name.
39 /// Returns the zone with the specified name.
38 /// If multiple zone with the same name exist, the first one is returned.
40 /// If multiple zone with the same name exist, the first one is returned.
39 VisualizationZoneWidget *getZoneWithName(const QString &zoneName);
41 VisualizationZoneWidget* getZoneWithName(const QString& zoneName);
40
42
41 /**
43 /**
42 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
44 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
@@ -44,7 +46,7 public:
44 * @param variable the variable for which to create the zone
46 * @param variable the variable for which to create the zone
45 * @return the pointer to the created zone
47 * @return the pointer to the created zone
46 */
48 */
47 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
49 VisualizationZoneWidget* createZone(std::shared_ptr<Variable2> variable);
48
50
49 /**
51 /**
50 * Creates a zone using a list of variables. The variables will be displayed in a new graph of
52 * Creates a zone using a list of variables. The variables will be displayed in a new graph of
@@ -53,36 +55,36 public:
53 * @param index The index where the zone should be inserted in the layout
55 * @param index The index where the zone should be inserted in the layout
54 * @return the pointer to the created zone
56 * @return the pointer to the created zone
55 */
57 */
56 VisualizationZoneWidget *createZone(const std::vector<std::shared_ptr<Variable> > &variables,
58 VisualizationZoneWidget* createZone(
57 int index);
59 const std::vector<std::shared_ptr<Variable2>>& variables, int index);
58
60
59 /**
61 /**
60 * Creates a zone which is empty (no variables). The zone is inserted at the specified index.
62 * Creates a zone which is empty (no variables). The zone is inserted at the specified index.
61 * @param index The index where the zone should be inserted in the layout
63 * @param index The index where the zone should be inserted in the layout
62 * @return the pointer to the created zone
64 * @return the pointer to the created zone
63 */
65 */
64 VisualizationZoneWidget *createEmptyZone(int index);
66 VisualizationZoneWidget* createEmptyZone(int index);
65
67
66 // IVisualizationWidget interface
68 // IVisualizationWidget interface
67 void accept(IVisualizationWidgetVisitor *visitor) override;
69 void accept(IVisualizationWidgetVisitor* visitor) override;
68 bool canDrop(const Variable &variable) const override;
70 bool canDrop(Variable2& variable) const override;
69 bool contains(const Variable &variable) const override;
71 bool contains(Variable2& variable) const override;
70 QString name() const override;
72 QString name() const override;
71
73
72 protected:
74 protected:
73 void closeEvent(QCloseEvent *event) override;
75 void closeEvent(QCloseEvent* event) override;
74
76
75 private:
77 private:
76 /// @return the layout of tab in which zones are added
78 /// @return the layout of tab in which zones are added
77 QLayout &tabLayout() const noexcept;
79 QLayout& tabLayout() const noexcept;
78
80
79 Ui::VisualizationTabWidget *ui;
81 Ui::VisualizationTabWidget* ui;
80
82
81 class VisualizationTabWidgetPrivate;
83 class VisualizationTabWidgetPrivate;
82 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
84 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
83
85
84 private slots:
86 private slots:
85 void dropMimeData(int index, const QMimeData *mimeData);
87 void dropMimeData(int index, const QMimeData* mimeData);
86 };
88 };
87
89
88 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
90 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
@@ -12,30 +12,32
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
13
13
14 class QMenu;
14 class QMenu;
15 class Variable;
15 class Variable2;
16 class VisualizationTabWidget;
16 class VisualizationTabWidget;
17 class VisualizationSelectionZoneManager;
17 class VisualizationSelectionZoneManager;
18
18
19 namespace Ui {
19 namespace Ui
20 {
20 class VisualizationWidget;
21 class VisualizationWidget;
21 } // namespace Ui
22 } // namespace Ui
22
23
23 class VisualizationWidget : public QWidget, public IVisualizationWidget {
24 class VisualizationWidget : public QWidget, public IVisualizationWidget
25 {
24 Q_OBJECT
26 Q_OBJECT
25
27
26 public:
28 public:
27 explicit VisualizationWidget(QWidget *parent = 0);
29 explicit VisualizationWidget(QWidget* parent = 0);
28 virtual ~VisualizationWidget();
30 virtual ~VisualizationWidget();
29
31
30 /// Returns the class which manage the selection of selection zone across the visualization
32 /// Returns the class which manage the selection of selection zone across the visualization
31 VisualizationSelectionZoneManager &selectionZoneManager() const;
33 VisualizationSelectionZoneManager& selectionZoneManager() const;
32
34
33 VisualizationTabWidget *currentTabWidget() const;
35 VisualizationTabWidget* currentTabWidget() const;
34
36
35 // IVisualizationWidget interface
37 // IVisualizationWidget interface
36 void accept(IVisualizationWidgetVisitor *visitor) override;
38 void accept(IVisualizationWidgetVisitor* visitor) override;
37 bool canDrop(const Variable &variable) const override;
39 bool canDrop(Variable2& variable) const override;
38 bool contains(const Variable &variable) const override;
40 bool contains(Variable2& variable) const override;
39 QString name() const override;
41 QString name() const override;
40
42
41 public slots:
43 public slots:
@@ -44,19 +46,19 public slots:
44 * @param menu the parent menu of the generated menu
46 * @param menu the parent menu of the generated menu
45 * @param variables the variables for which to generate the menu
47 * @param variables the variables for which to generate the menu
46 */
48 */
47 void attachVariableMenu(QMenu *menu,
49 void attachVariableMenu(
48 const QVector<std::shared_ptr<Variable> > &variables) noexcept;
50 QMenu* menu, const QVector<std::shared_ptr<Variable2>>& variables) noexcept;
49
51
50 /// Slot called when a variable is about to be deleted from SciQlop
52 /// Slot called when a variable is about to be deleted from SciQlop
51 void onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept;
53 void onVariableAboutToBeDeleted(std::shared_ptr<Variable2> variable) noexcept;
52
54
53 void onRangeChanged(std::shared_ptr<Variable> variable, const DateTimeRange &range) noexcept;
55 void onRangeChanged(std::shared_ptr<Variable2> variable, const DateTimeRange& range) noexcept;
54
56
55 protected:
57 protected:
56 void closeEvent(QCloseEvent *event) override;
58 void closeEvent(QCloseEvent* event) override;
57
59
58 private:
60 private:
59 Ui::VisualizationWidget *ui;
61 Ui::VisualizationWidget* ui;
60
62
61 class VisualizationWidgetPrivate;
63 class VisualizationWidgetPrivate;
62 spimpl::unique_impl_ptr<VisualizationWidgetPrivate> impl;
64 spimpl::unique_impl_ptr<VisualizationWidgetPrivate> impl;
@@ -14,29 +14,31
14
14
15 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
15 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
16
16
17 namespace Ui {
17 namespace Ui
18 {
18 class VisualizationZoneWidget;
19 class VisualizationZoneWidget;
19 } // namespace Ui
20 } // namespace Ui
20
21
21 class Variable;
22 class Variable2;
22 class VisualizationGraphWidget;
23 class VisualizationGraphWidget;
23
24
24 class VisualizationZoneWidget : public VisualizationDragWidget, public IVisualizationWidget {
25 class VisualizationZoneWidget : public VisualizationDragWidget, public IVisualizationWidget
26 {
25 Q_OBJECT
27 Q_OBJECT
26
28
27 public:
29 public:
28 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
30 explicit VisualizationZoneWidget(const QString& name = {}, QWidget* parent = 0);
29 virtual ~VisualizationZoneWidget();
31 virtual ~VisualizationZoneWidget();
30
32
31 /// Sets the range of the zone, only works if there is at least one graph in the zone
33 /// Sets the range of the zone, only works if there is at least one graph in the zone
32 /// Note: calibrations between graphs are lost.
34 /// Note: calibrations between graphs are lost.
33 void setZoneRange(const DateTimeRange &range);
35 void setZoneRange(const DateTimeRange& range);
34
36
35 /// Adds a graph widget
37 /// Adds a graph widget
36 void addGraph(VisualizationGraphWidget *graphWidget);
38 void addGraph(VisualizationGraphWidget* graphWidget);
37
39
38 /// Inserts a graph widget
40 /// Inserts a graph widget
39 void insertGraph(int index, VisualizationGraphWidget *graphWidget);
41 void insertGraph(int index, VisualizationGraphWidget* graphWidget);
40
42
41 /**
43 /**
42 * Creates a graph using a variable. The variable will be displayed in the new graph.
44 * Creates a graph using a variable. The variable will be displayed in the new graph.
@@ -44,7 +46,7 public:
44 * @param variable the variable for which to create the graph
46 * @param variable the variable for which to create the graph
45 * @return the pointer to the created graph
47 * @return the pointer to the created graph
46 */
48 */
47 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
49 VisualizationGraphWidget* createGraph(std::shared_ptr<Variable2> variable);
48
50
49 /**
51 /**
50 * Creates a graph using a variable. The variable will be displayed in the new graph.
52 * Creates a graph using a variable. The variable will be displayed in the new graph.
@@ -53,7 +55,7 public:
53 * @param index The index where the graph should be inserted in the layout
55 * @param index The index where the graph should be inserted in the layout
54 * @return the pointer to the created graph
56 * @return the pointer to the created graph
55 */
57 */
56 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable, int index);
58 VisualizationGraphWidget* createGraph(std::shared_ptr<Variable2> variable, int index);
57
59
58 /**
60 /**
59 * Creates a graph using a list of variables. The variables will be displayed in the new graph.
61 * Creates a graph using a list of variables. The variables will be displayed in the new graph.
@@ -62,45 +64,45 public:
62 * @param index The index where the graph should be inserted in the layout
64 * @param index The index where the graph should be inserted in the layout
63 * @return the pointer to the created graph
65 * @return the pointer to the created graph
64 */
66 */
65 VisualizationGraphWidget *createGraph( std::vector<std::shared_ptr<Variable> > variables,
67 VisualizationGraphWidget* createGraph(
66 int index);
68 std::vector<std::shared_ptr<Variable2>> variables, int index);
67
69
68 /// Returns the first graph in the zone or nullptr if there is no graph inside
70 /// Returns the first graph in the zone or nullptr if there is no graph inside
69 VisualizationGraphWidget *firstGraph() const;
71 VisualizationGraphWidget* firstGraph() const;
70
72
71 /// Closes all graphes inside the zone
73 /// Closes all graphes inside the zone
72 void closeAllGraphs();
74 void closeAllGraphs();
73
75
74 // IVisualizationWidget interface
76 // IVisualizationWidget interface
75 void accept(IVisualizationWidgetVisitor *visitor) override;
77 void accept(IVisualizationWidgetVisitor* visitor) override;
76 bool canDrop(const Variable &variable) const override;
78 bool canDrop(Variable2& variable) const override;
77 bool contains(const Variable &variable) const override;
79 bool contains(Variable2& variable) const override;
78 QString name() const override;
80 QString name() const override;
79
81
80 // VisualisationDragWidget
82 // VisualisationDragWidget
81 QMimeData *mimeData(const QPoint &position) const override;
83 QMimeData* mimeData(const QPoint& position) const override;
82 bool isDragAllowed() const override;
84 bool isDragAllowed() const override;
83
85
84 void notifyMouseMoveInGraph(const QPointF &graphPosition, const QPointF &plotPosition,
86 void notifyMouseMoveInGraph(const QPointF& graphPosition, const QPointF& plotPosition,
85 VisualizationGraphWidget *graphWidget);
87 VisualizationGraphWidget* graphWidget);
86 void notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget);
88 void notifyMouseLeaveGraph(VisualizationGraphWidget* graphWidget);
87
89
88 protected:
90 protected:
89 void closeEvent(QCloseEvent *event) override;
91 void closeEvent(QCloseEvent* event) override;
90
92
91 private:
93 private:
92 Ui::VisualizationZoneWidget *ui;
94 Ui::VisualizationZoneWidget* ui;
93
95
94 class VisualizationZoneWidgetPrivate;
96 class VisualizationZoneWidgetPrivate;
95 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
97 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
96
98
97 private slots:
99 private slots:
98 void onVariableAdded(std::shared_ptr<Variable> variable);
100 void onVariableAdded(std::shared_ptr<Variable2> variable);
99 /// Slot called when a variable is about to be removed from a graph contained in the zone
101 /// Slot called when a variable is about to be removed from a graph contained in the zone
100 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
102 void onVariableAboutToBeRemoved(std::shared_ptr<Variable2> variable);
101
103
102 void dropMimeData(int index, const QMimeData *mimeData);
104 void dropMimeData(int index, const QMimeData* mimeData);
103 void dropMimeDataOnGraph(VisualizationDragWidget *dragWidget, const QMimeData *mimeData);
105 void dropMimeDataOnGraph(VisualizationDragWidget* dragWidget, const QMimeData* mimeData);
104 };
106 };
105
107
106 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
108 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -8,31 +8,32
8 #include <set>
8 #include <set>
9
9
10 class IVisualizationWidget;
10 class IVisualizationWidget;
11 class Variable;
11 class Variable2;
12
12
13 /**
13 /**
14 * @brief The FindVariableOperation class defines an operation that traverses all of visualization
14 * @brief The FindVariableOperation class defines an operation that traverses all of visualization
15 * widgets to determine which ones contain the variable passed as parameter. The result of the
15 * widgets to determine which ones contain the variable passed as parameter. The result of the
16 * operation is the list of widgets that contain the variable.
16 * operation is the list of widgets that contain the variable.
17 */
17 */
18 class FindVariableOperation : public IVisualizationWidgetVisitor {
18 class FindVariableOperation : public IVisualizationWidgetVisitor
19 {
19 public:
20 public:
20 /**
21 /**
21 * Ctor
22 * Ctor
22 * @param variable the variable to find
23 * @param variable the variable to find
23 */
24 */
24 explicit FindVariableOperation(std::shared_ptr<Variable> variable);
25 explicit FindVariableOperation(std::shared_ptr<Variable2> variable);
25
26
26 void visitEnter(VisualizationWidget *widget) override final;
27 void visitEnter(VisualizationWidget* widget) override final;
27 void visitLeave(VisualizationWidget *widget) override final;
28 void visitLeave(VisualizationWidget* widget) override final;
28 void visitEnter(VisualizationTabWidget *tabWidget) override final;
29 void visitEnter(VisualizationTabWidget* tabWidget) override final;
29 void visitLeave(VisualizationTabWidget *tabWidget) override final;
30 void visitLeave(VisualizationTabWidget* tabWidget) override final;
30 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
31 void visitEnter(VisualizationZoneWidget* zoneWidget) override final;
31 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
32 void visitLeave(VisualizationZoneWidget* zoneWidget) override final;
32 void visit(VisualizationGraphWidget *graphWidget) override final;
33 void visit(VisualizationGraphWidget* graphWidget) override final;
33
34
34 /// @return the widgets that contain the variable
35 /// @return the widgets that contain the variable
35 std::set<IVisualizationWidget *> result() const noexcept;
36 std::set<IVisualizationWidget*> result() const noexcept;
36
37
37 private:
38 private:
38 class FindVariableOperationPrivate;
39 class FindVariableOperationPrivate;
@@ -11,7 +11,7
11
11
12 class QMenu;
12 class QMenu;
13 class IVisualizationWidget;
13 class IVisualizationWidget;
14 class Variable;
14 class Variable2;
15
15
16 Q_DECLARE_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation)
16 Q_DECLARE_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation)
17
17
@@ -20,7 +20,8 Q_DECLARE_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation)
20 * visualization widgets to determine which can accommodate a variable. The result of the operation
20 * visualization widgets to determine which can accommodate a variable. The result of the operation
21 * is a menu that contains actions to add the variable into the containers.
21 * is a menu that contains actions to add the variable into the containers.
22 */
22 */
23 class GenerateVariableMenuOperation : public IVisualizationWidgetVisitor {
23 class GenerateVariableMenuOperation : public IVisualizationWidgetVisitor
24 {
24 public:
25 public:
25 /**
26 /**
26 * Ctor
27 * Ctor
@@ -29,16 +30,16 public:
29 * @param variableContainers the containers that already contain the variable for which to
30 * @param variableContainers the containers that already contain the variable for which to
30 * generate the menu
31 * generate the menu
31 */
32 */
32 explicit GenerateVariableMenuOperation(QMenu *menu, std::shared_ptr<Variable> variable,
33 explicit GenerateVariableMenuOperation(QMenu* menu, std::shared_ptr<Variable2> variable,
33 std::set<IVisualizationWidget *> variableContainers);
34 std::set<IVisualizationWidget*> variableContainers);
34
35
35 void visitEnter(VisualizationWidget *widget) override final;
36 void visitEnter(VisualizationWidget* widget) override final;
36 void visitLeave(VisualizationWidget *widget) override final;
37 void visitLeave(VisualizationWidget* widget) override final;
37 void visitEnter(VisualizationTabWidget *tabWidget) override final;
38 void visitEnter(VisualizationTabWidget* tabWidget) override final;
38 void visitLeave(VisualizationTabWidget *tabWidget) override final;
39 void visitLeave(VisualizationTabWidget* tabWidget) override final;
39 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
40 void visitEnter(VisualizationZoneWidget* zoneWidget) override final;
40 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
41 void visitLeave(VisualizationZoneWidget* zoneWidget) override final;
41 void visit(VisualizationGraphWidget *graphWidget) override final;
42 void visit(VisualizationGraphWidget* graphWidget) override final;
42
43
43 private:
44 private:
44 class GenerateVariableMenuOperationPrivate;
45 class GenerateVariableMenuOperationPrivate;
@@ -9,7 +9,7
9
9
10 #include <memory>
10 #include <memory>
11
11
12 class Variable;
12 class Variable2;
13
13
14 Q_DECLARE_LOGGING_CATEGORY(LOG_RemoveVariableOperation)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_RemoveVariableOperation)
15
15
@@ -17,21 +17,22 Q_DECLARE_LOGGING_CATEGORY(LOG_RemoveVariableOperation)
17 * @brief The RemoveVariableOperation class defines an operation that traverses all of visualization
17 * @brief The RemoveVariableOperation class defines an operation that traverses all of visualization
18 * widgets to remove a variable if they contain it
18 * widgets to remove a variable if they contain it
19 */
19 */
20 class RemoveVariableOperation : public IVisualizationWidgetVisitor {
20 class RemoveVariableOperation : public IVisualizationWidgetVisitor
21 {
21 public:
22 public:
22 /**
23 /**
23 * Ctor
24 * Ctor
24 * @param variable the variable to remove from widgets
25 * @param variable the variable to remove from widgets
25 */
26 */
26 explicit RemoveVariableOperation(std::shared_ptr<Variable> variable);
27 explicit RemoveVariableOperation(std::shared_ptr<Variable2> variable);
27
28
28 void visitEnter(VisualizationWidget *widget) override final;
29 void visitEnter(VisualizationWidget* widget) override final;
29 void visitLeave(VisualizationWidget *widget) override final;
30 void visitLeave(VisualizationWidget* widget) override final;
30 void visitEnter(VisualizationTabWidget *tabWidget) override final;
31 void visitEnter(VisualizationTabWidget* tabWidget) override final;
31 void visitLeave(VisualizationTabWidget *tabWidget) override final;
32 void visitLeave(VisualizationTabWidget* tabWidget) override final;
32 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
33 void visitEnter(VisualizationZoneWidget* zoneWidget) override final;
33 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
34 void visitLeave(VisualizationZoneWidget* zoneWidget) override final;
34 void visit(VisualizationGraphWidget *graphWidget) override final;
35 void visit(VisualizationGraphWidget* graphWidget) override final;
35
36
36 private:
37 private:
37 class RemoveVariableOperationPrivate;
38 class RemoveVariableOperationPrivate;
@@ -10,7 +10,7
10
10
11 #include <memory>
11 #include <memory>
12
12
13 class Variable;
13 class Variable2;
14
14
15 Q_DECLARE_LOGGING_CATEGORY(LOG_RescaleAxeOperation)
15 Q_DECLARE_LOGGING_CATEGORY(LOG_RescaleAxeOperation)
16
16
@@ -18,21 +18,22 Q_DECLARE_LOGGING_CATEGORY(LOG_RescaleAxeOperation)
18 * @brief The RescaleAxeOperation class defines an operation that traverses all of visualization
18 * @brief The RescaleAxeOperation class defines an operation that traverses all of visualization
19 * widgets to remove a variable if they contain it
19 * widgets to remove a variable if they contain it
20 */
20 */
21 class RescaleAxeOperation : public IVisualizationWidgetVisitor {
21 class RescaleAxeOperation : public IVisualizationWidgetVisitor
22 {
22 public:
23 public:
23 /**
24 /**
24 * Ctor
25 * Ctor
25 * @param variable the variable to remove from widgets
26 * @param variable the variable to remove from widgets
26 */
27 */
27 explicit RescaleAxeOperation(std::shared_ptr<Variable> variable, const DateTimeRange &range);
28 explicit RescaleAxeOperation(std::shared_ptr<Variable2> variable, const DateTimeRange& range);
28
29
29 void visitEnter(VisualizationWidget *widget) override final;
30 void visitEnter(VisualizationWidget* widget) override final;
30 void visitLeave(VisualizationWidget *widget) override final;
31 void visitLeave(VisualizationWidget* widget) override final;
31 void visitEnter(VisualizationTabWidget *tabWidget) override final;
32 void visitEnter(VisualizationTabWidget* tabWidget) override final;
32 void visitLeave(VisualizationTabWidget *tabWidget) override final;
33 void visitLeave(VisualizationTabWidget* tabWidget) override final;
33 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
34 void visitEnter(VisualizationZoneWidget* zoneWidget) override final;
34 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
35 void visitLeave(VisualizationZoneWidget* zoneWidget) override final;
35 void visit(VisualizationGraphWidget *graphWidget) override final;
36 void visit(VisualizationGraphWidget* graphWidget) override final;
36
37
37 private:
38 private:
38 class RescaleAxeOperationPrivate;
39 class RescaleAxeOperationPrivate;
@@ -23,39 +23,40
23 Q_LOGGING_CATEGORY(LOG_DragDropGuiController, "DragDropGuiController")
23 Q_LOGGING_CATEGORY(LOG_DragDropGuiController, "DragDropGuiController")
24
24
25
25
26 struct DragDropGuiController::DragDropGuiControllerPrivate {
26 struct DragDropGuiController::DragDropGuiControllerPrivate
27 {
27
28
28 VisualizationDragWidget *m_CurrentDragWidget = nullptr;
29 VisualizationDragWidget* m_CurrentDragWidget = nullptr;
29 std::unique_ptr<QWidget> m_PlaceHolder = nullptr;
30 std::unique_ptr<QWidget> m_PlaceHolder = nullptr;
30 QLabel *m_PlaceHolderLabel;
31 QLabel* m_PlaceHolderLabel;
31 QWidget *m_PlaceBackground;
32 QWidget* m_PlaceBackground;
32 std::unique_ptr<DragDropScroller> m_DragDropScroller = nullptr;
33 std::unique_ptr<DragDropScroller> m_DragDropScroller = nullptr;
33 std::unique_ptr<DragDropTabSwitcher> m_DragDropTabSwitcher = nullptr;
34 std::unique_ptr<DragDropTabSwitcher> m_DragDropTabSwitcher = nullptr;
34 QString m_ImageTempUrl; // Temporary file for image url generated by the drag & drop. Not using
35 QString m_ImageTempUrl; // Temporary file for image url generated by the drag & drop. Not using
35 // QTemporaryFile to have a name which is not generated.
36 // QTemporaryFile to have a name which is not generated.
36
37
37 VisualizationDragWidget *m_HighlightedDragWidget = nullptr;
38 VisualizationDragWidget* m_HighlightedDragWidget = nullptr;
38
39
39 QMetaObject::Connection m_DragWidgetDestroyedConnection;
40 QMetaObject::Connection m_DragWidgetDestroyedConnection;
40 QMetaObject::Connection m_HighlightedWidgetDestroyedConnection;
41 QMetaObject::Connection m_HighlightedWidgetDestroyedConnection;
41
42
42 QList<QWidget *> m_WidgetToClose;
43 QList<QWidget*> m_WidgetToClose;
43
44
44 explicit DragDropGuiControllerPrivate()
45 explicit DragDropGuiControllerPrivate()
45 : m_PlaceHolder{std::make_unique<QWidget>()},
46 : m_PlaceHolder { std::make_unique<QWidget>() }
46 m_DragDropScroller{std::make_unique<DragDropScroller>()},
47 , m_DragDropScroller { std::make_unique<DragDropScroller>() }
47 m_DragDropTabSwitcher{std::make_unique<DragDropTabSwitcher>()}
48 , m_DragDropTabSwitcher { std::make_unique<DragDropTabSwitcher>() }
48 {
49 {
49
50
50 auto layout = new QVBoxLayout{m_PlaceHolder.get()};
51 auto layout = new QVBoxLayout { m_PlaceHolder.get() };
51 layout->setSpacing(0);
52 layout->setSpacing(0);
52 layout->setContentsMargins(0, 0, 0, 0);
53 layout->setContentsMargins(0, 0, 0, 0);
53
54
54 m_PlaceHolderLabel = new QLabel{"", m_PlaceHolder.get()};
55 m_PlaceHolderLabel = new QLabel { "", m_PlaceHolder.get() };
55 m_PlaceHolderLabel->setMinimumHeight(25);
56 m_PlaceHolderLabel->setMinimumHeight(25);
56 layout->addWidget(m_PlaceHolderLabel);
57 layout->addWidget(m_PlaceHolderLabel);
57
58
58 m_PlaceBackground = new QWidget{m_PlaceHolder.get()};
59 m_PlaceBackground = new QWidget { m_PlaceHolder.get() };
59 m_PlaceBackground->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
60 m_PlaceBackground->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
60 layout->addWidget(m_PlaceBackground);
61 layout->addWidget(m_PlaceBackground);
61
62
@@ -65,14 +66,16 struct DragDropGuiController::DragDropGuiControllerPrivate {
65 m_ImageTempUrl = QDir::temp().absoluteFilePath("Sciqlop_graph.png");
66 m_ImageTempUrl = QDir::temp().absoluteFilePath("Sciqlop_graph.png");
66 }
67 }
67
68
68 void preparePlaceHolder(DragDropGuiController::PlaceHolderType type,
69 void preparePlaceHolder(
69 const QString &topLabelText) const
70 DragDropGuiController::PlaceHolderType type, const QString& topLabelText) const
70 {
71 {
71 if (m_CurrentDragWidget) {
72 if (m_CurrentDragWidget)
73 {
72 m_PlaceHolder->setMinimumSize(m_CurrentDragWidget->size());
74 m_PlaceHolder->setMinimumSize(m_CurrentDragWidget->size());
73 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
75 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
74 }
76 }
75 else {
77 else
78 {
76 // Configuration of the placeHolder when there is no dragWidget
79 // Configuration of the placeHolder when there is no dragWidget
77 // (for instance with a drag from a variable)
80 // (for instance with a drag from a variable)
78
81
@@ -80,7 +83,8 struct DragDropGuiController::DragDropGuiControllerPrivate {
80 m_PlaceHolder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
83 m_PlaceHolder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
81 }
84 }
82
85
83 switch (type) {
86 switch (type)
87 {
84 case DragDropGuiController::PlaceHolderType::Graph:
88 case DragDropGuiController::PlaceHolderType::Graph:
85 m_PlaceBackground->setStyleSheet(
89 m_PlaceBackground->setStyleSheet(
86 "background-color: #BBD5EE; border: 1px solid #2A7FD4");
90 "background-color: #BBD5EE; border: 1px solid #2A7FD4");
@@ -100,7 +104,7 struct DragDropGuiController::DragDropGuiControllerPrivate {
100
104
101
105
102 DragDropGuiController::DragDropGuiController()
106 DragDropGuiController::DragDropGuiController()
103 : impl{spimpl::make_unique_impl<DragDropGuiControllerPrivate>()}
107 : impl { spimpl::make_unique_impl<DragDropGuiControllerPrivate>() }
104 {
108 {
105 }
109 }
106
110
@@ -115,35 +119,36 void DragDropGuiController::resetDragAndDrop()
115 impl->m_HighlightedDragWidget = nullptr;
119 impl->m_HighlightedDragWidget = nullptr;
116 }
120 }
117
121
118 void DragDropGuiController::setCurrentDragWidget(VisualizationDragWidget *dragWidget)
122 void DragDropGuiController::setCurrentDragWidget(VisualizationDragWidget* dragWidget)
119 {
123 {
120 if (impl->m_CurrentDragWidget) {
124 if (impl->m_CurrentDragWidget)
125 {
121
126
122 QObject::disconnect(impl->m_DragWidgetDestroyedConnection);
127 QObject::disconnect(impl->m_DragWidgetDestroyedConnection);
123 }
128 }
124
129
125 if (dragWidget) {
130 if (dragWidget)
131 {
126 // ensures the impl->m_CurrentDragWidget is reset when the widget is destroyed
132 // ensures the impl->m_CurrentDragWidget is reset when the widget is destroyed
127 impl->m_DragWidgetDestroyedConnection
133 impl->m_DragWidgetDestroyedConnection = QObject::connect(dragWidget,
128 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
134 &VisualizationDragWidget::destroyed, [this]() { impl->m_CurrentDragWidget = nullptr; });
129 [this]() { impl->m_CurrentDragWidget = nullptr; });
130 }
135 }
131
136
132 impl->m_CurrentDragWidget = dragWidget;
137 impl->m_CurrentDragWidget = dragWidget;
133 }
138 }
134
139
135 VisualizationDragWidget *DragDropGuiController::getCurrentDragWidget() const
140 VisualizationDragWidget* DragDropGuiController::getCurrentDragWidget() const
136 {
141 {
137 return impl->m_CurrentDragWidget;
142 return impl->m_CurrentDragWidget;
138 }
143 }
139
144
140 QWidget &DragDropGuiController::placeHolder() const
145 QWidget& DragDropGuiController::placeHolder() const
141 {
146 {
142 return *impl->m_PlaceHolder;
147 return *impl->m_PlaceHolder;
143 }
148 }
144
149
145 void DragDropGuiController::insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type,
150 void DragDropGuiController::insertPlaceHolder(
146 const QString &topLabelText)
151 QVBoxLayout* layout, int index, PlaceHolderType type, const QString& topLabelText)
147 {
152 {
148 removePlaceHolder();
153 removePlaceHolder();
149 impl->preparePlaceHolder(type, topLabelText);
154 impl->preparePlaceHolder(type, topLabelText);
@@ -154,7 +159,8 void DragDropGuiController::insertPlaceHolder(QVBoxLayout *layout, int index, Pl
154 void DragDropGuiController::removePlaceHolder()
159 void DragDropGuiController::removePlaceHolder()
155 {
160 {
156 auto parentWidget = impl->m_PlaceHolder->parentWidget();
161 auto parentWidget = impl->m_PlaceHolder->parentWidget();
157 if (parentWidget) {
162 if (parentWidget)
163 {
158 parentWidget->layout()->removeWidget(impl->m_PlaceHolder.get());
164 parentWidget->layout()->removeWidget(impl->m_PlaceHolder.get());
159 impl->m_PlaceHolder->setParent(nullptr);
165 impl->m_PlaceHolder->setParent(nullptr);
160 impl->m_PlaceHolder->hide();
166 impl->m_PlaceHolder->hide();
@@ -166,57 +172,59 bool DragDropGuiController::isPlaceHolderSet() const
166 return impl->m_PlaceHolder->parentWidget();
172 return impl->m_PlaceHolder->parentWidget();
167 }
173 }
168
174
169 void DragDropGuiController::addDragDropScrollArea(QScrollArea *scrollArea)
175 void DragDropGuiController::addDragDropScrollArea(QScrollArea* scrollArea)
170 {
176 {
171 impl->m_DragDropScroller->addScrollArea(scrollArea);
177 impl->m_DragDropScroller->addScrollArea(scrollArea);
172 }
178 }
173
179
174 void DragDropGuiController::removeDragDropScrollArea(QScrollArea *scrollArea)
180 void DragDropGuiController::removeDragDropScrollArea(QScrollArea* scrollArea)
175 {
181 {
176 impl->m_DragDropScroller->removeScrollArea(scrollArea);
182 impl->m_DragDropScroller->removeScrollArea(scrollArea);
177 }
183 }
178
184
179 void DragDropGuiController::addDragDropTabBar(QTabBar *tabBar)
185 void DragDropGuiController::addDragDropTabBar(QTabBar* tabBar)
180 {
186 {
181 impl->m_DragDropTabSwitcher->addTabBar(tabBar);
187 impl->m_DragDropTabSwitcher->addTabBar(tabBar);
182 }
188 }
183
189
184 void DragDropGuiController::removeDragDropTabBar(QTabBar *tabBar)
190 void DragDropGuiController::removeDragDropTabBar(QTabBar* tabBar)
185 {
191 {
186 impl->m_DragDropTabSwitcher->removeTabBar(tabBar);
192 impl->m_DragDropTabSwitcher->removeTabBar(tabBar);
187 }
193 }
188
194
189 QUrl DragDropGuiController::imageTemporaryUrl(const QImage &image) const
195 QUrl DragDropGuiController::imageTemporaryUrl(const QImage& image) const
190 {
196 {
191 image.save(impl->m_ImageTempUrl);
197 image.save(impl->m_ImageTempUrl);
192 return QUrl::fromLocalFile(impl->m_ImageTempUrl);
198 return QUrl::fromLocalFile(impl->m_ImageTempUrl);
193 }
199 }
194
200
195 void DragDropGuiController::setHightlightedDragWidget(VisualizationDragWidget *dragWidget)
201 void DragDropGuiController::setHightlightedDragWidget(VisualizationDragWidget* dragWidget)
196 {
202 {
197 if (impl->m_HighlightedDragWidget) {
203 if (impl->m_HighlightedDragWidget)
204 {
198 impl->m_HighlightedDragWidget->highlightForMerge(false);
205 impl->m_HighlightedDragWidget->highlightForMerge(false);
199 QObject::disconnect(impl->m_HighlightedWidgetDestroyedConnection);
206 QObject::disconnect(impl->m_HighlightedWidgetDestroyedConnection);
200 }
207 }
201
208
202 if (dragWidget) {
209 if (dragWidget)
210 {
203 dragWidget->highlightForMerge(true);
211 dragWidget->highlightForMerge(true);
204
212
205 // ensures the impl->m_HighlightedDragWidget is reset when the widget is destroyed
213 // ensures the impl->m_HighlightedDragWidget is reset when the widget is destroyed
206 impl->m_DragWidgetDestroyedConnection
214 impl->m_DragWidgetDestroyedConnection
207 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
215 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
208 [this]() { impl->m_HighlightedDragWidget = nullptr; });
216 [this]() { impl->m_HighlightedDragWidget = nullptr; });
209 }
217 }
210
218
211 impl->m_HighlightedDragWidget = dragWidget;
219 impl->m_HighlightedDragWidget = dragWidget;
212 }
220 }
213
221
214 VisualizationDragWidget *DragDropGuiController::getHightlightedDragWidget() const
222 VisualizationDragWidget* DragDropGuiController::getHightlightedDragWidget() const
215 {
223 {
216 return impl->m_HighlightedDragWidget;
224 return impl->m_HighlightedDragWidget;
217 }
225 }
218
226
219 void DragDropGuiController::delayedCloseWidget(QWidget *widget)
227 void DragDropGuiController::delayedCloseWidget(QWidget* widget)
220 {
228 {
221 widget->hide();
229 widget->hide();
222 impl->m_WidgetToClose << widget;
230 impl->m_WidgetToClose << widget;
@@ -224,7 +232,8 void DragDropGuiController::delayedCloseWidget(QWidget *widget)
224
232
225 void DragDropGuiController::doCloseWidgets()
233 void DragDropGuiController::doCloseWidgets()
226 {
234 {
227 for (auto widget : impl->m_WidgetToClose) {
235 for (auto widget : impl->m_WidgetToClose)
236 {
228 widget->close();
237 widget->close();
229 }
238 }
230
239
@@ -232,9 +241,10 void DragDropGuiController::doCloseWidgets()
232 }
241 }
233
242
234 bool DragDropGuiController::checkMimeDataForVisualization(
243 bool DragDropGuiController::checkMimeDataForVisualization(
235 const QMimeData *mimeData, VisualizationDragDropContainer *dropContainer)
244 const QMimeData* mimeData, VisualizationDragDropContainer* dropContainer)
236 {
245 {
237 if (!mimeData || !dropContainer) {
246 if (!mimeData || !dropContainer)
247 {
238 qCWarning(LOG_DragDropGuiController()) << QObject::tr(
248 qCWarning(LOG_DragDropGuiController()) << QObject::tr(
239 "DragDropGuiController::checkMimeDataForVisualization, invalid input parameters.");
249 "DragDropGuiController::checkMimeDataForVisualization, invalid input parameters.");
240 Q_ASSERT(false);
250 Q_ASSERT(false);
@@ -243,61 +253,75 bool DragDropGuiController::checkMimeDataForVisualization(
243
253
244 auto result = false;
254 auto result = false;
245
255
246 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
256 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST))
257 {
247 auto variables = sqpApp->variableController().variables(
258 auto variables = sqpApp->variableController().variables(
248 Variable::variablesIDs(mimeData->data(MIME_TYPE_VARIABLE_LIST)));
259 Variable::variablesIDs(mimeData->data(MIME_TYPE_VARIABLE_LIST)));
249
260
250 if (variables.size() == 1) {
261 if (variables.size() == 1)
262 {
251
263
252 auto variable = variables[0];
264 auto variable = variables[0];
253 if (variable->dataSeries() != nullptr) {
265 if (variable->data() != nullptr)
266 {
254
267
255 // Check that the variable is not already in a graph
268 // Check that the variable is not already in a graph
256
269
257 auto parent = dropContainer->parentWidget();
270 auto parent = dropContainer->parentWidget();
258 while (parent && qobject_cast<VisualizationWidget *>(parent) == nullptr) {
271 while (parent && qobject_cast<VisualizationWidget*>(parent) == nullptr)
272 {
259 parent = parent->parentWidget(); // Search for the top level VisualizationWidget
273 parent = parent->parentWidget(); // Search for the top level VisualizationWidget
260 }
274 }
261
275
262 if (parent) {
276 if (parent)
263 auto visualizationWidget = static_cast<VisualizationWidget *>(parent);
277 {
278 auto visualizationWidget = static_cast<VisualizationWidget*>(parent);
264
279
265 FindVariableOperation findVariableOperation{variable};
280 FindVariableOperation findVariableOperation { variable };
266 visualizationWidget->accept(&findVariableOperation);
281 visualizationWidget->accept(&findVariableOperation);
267 auto variableContainers = findVariableOperation.result();
282 auto variableContainers = findVariableOperation.result();
268 if (variableContainers.empty()) {
283 if (variableContainers.empty())
284 {
269 result = true;
285 result = true;
270 }
286 }
271 else {
287 else
288 {
272 // result = false: the variable already exist in the visualisation
289 // result = false: the variable already exist in the visualisation
273 }
290 }
274 }
291 }
275 else {
292 else
293 {
276 qCWarning(LOG_DragDropGuiController()) << QObject::tr(
294 qCWarning(LOG_DragDropGuiController()) << QObject::tr(
277 "DragDropGuiController::checkMimeDataForVisualization, the parent "
295 "DragDropGuiController::checkMimeDataForVisualization, the parent "
278 "VisualizationWidget cannot be found. Cannot check if the variable is "
296 "VisualizationWidget cannot be found. Cannot check if the variable is "
279 "already used or not.");
297 "already used or not.");
280 }
298 }
281 }
299 }
282 else {
300 else
301 {
283 // result = false: the variable is not fully loaded
302 // result = false: the variable is not fully loaded
284 }
303 }
285 }
304 }
286 else {
305 else
306 {
287 // result = false: cannot drop multiple variables in the visualisation
307 // result = false: cannot drop multiple variables in the visualisation
288 }
308 }
289 }
309 }
290 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
310 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST))
311 {
291 auto productDataList = sqpApp->dataSourceController().productsDataForMimeData(
312 auto productDataList = sqpApp->dataSourceController().productsDataForMimeData(
292 mimeData->data(MIME_TYPE_PRODUCT_LIST));
313 mimeData->data(MIME_TYPE_PRODUCT_LIST));
293 if (productDataList.count() == 1) {
314 if (productDataList.count() == 1)
315 {
294 result = true;
316 result = true;
295 }
317 }
296 else {
318 else
319 {
297 // result = false: cannot drop multiple products in the visualisation
320 // result = false: cannot drop multiple products in the visualisation
298 }
321 }
299 }
322 }
300 else {
323 else
324 {
301 // Other MIME data
325 // Other MIME data
302 // no special rules, accepted by default
326 // no special rules, accepted by default
303 result = true;
327 result = true;
@@ -1,10 +1,10
1 #include <DataSource/DataSourceController.h>
1 #include <Variable/RenameVariableDialog.h>
2 #include <Variable/RenameVariableDialog.h>
2 #include <Variable/Variable.h>
3 #include <Variable/Variable.h>
3 #include <Variable/VariableController2.h>
4 #include <Variable/VariableController2.h>
4 #include <Variable/VariableInspectorWidget.h>
5 #include <Variable/VariableInspectorWidget.h>
5 #include <Variable/VariableMenuHeaderWidget.h>
6 #include <Variable/VariableMenuHeaderWidget.h>
6 #include <Variable/VariableModel2.h>
7 #include <Variable/VariableModel2.h>
7 #include <DataSource/DataSourceController.h>
8
8
9 #include <ui_VariableInspectorWidget.h>
9 #include <ui_VariableInspectorWidget.h>
10
10
@@ -19,22 +19,25
19 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
19 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
20
20
21
21
22 class QProgressBarItemDelegate : public QStyledItemDelegate {
22 class QProgressBarItemDelegate : public QStyledItemDelegate
23 {
23
24
24 public:
25 public:
25 QProgressBarItemDelegate(QObject *parent) : QStyledItemDelegate{parent} {}
26 QProgressBarItemDelegate(QObject* parent) : QStyledItemDelegate { parent } {}
26
27
27 void paint(QPainter *painter, const QStyleOptionViewItem &option,
28 void paint(
28 const QModelIndex &index) const
29 QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
29 {
30 {
30 auto data = index.data(Qt::DisplayRole);
31 auto data = index.data(Qt::DisplayRole);
31 auto progressData = index.data(VariableRoles::ProgressRole);
32 auto progressData = index.data(VariableRoles::ProgressRole);
32 if (data.isValid() && progressData.isValid()) {
33 if (data.isValid() && progressData.isValid())
34 {
33 auto name = data.value<QString>();
35 auto name = data.value<QString>();
34 auto progress = progressData.value<double>();
36 auto progress = progressData.value<double>();
35 if (progress > 0) {
37 if (progress > 0)
38 {
36 auto cancelButtonWidth = 20;
39 auto cancelButtonWidth = 20;
37 auto progressBarOption = QStyleOptionProgressBar{};
40 auto progressBarOption = QStyleOptionProgressBar {};
38 auto progressRect = option.rect;
41 auto progressRect = option.rect;
39 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
42 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
40 progressBarOption.rect = progressRect;
43 progressBarOption.rect = progressRect;
@@ -47,66 +50,75 public:
47 progressBarOption.textAlignment = Qt::AlignCenter;
50 progressBarOption.textAlignment = Qt::AlignCenter;
48
51
49
52
50 QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption,
53 QApplication::style()->drawControl(
51 painter);
54 QStyle::CE_ProgressBar, &progressBarOption, painter);
52
55
53 // Cancel button
56 // Cancel button
54 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
57 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
55 option.rect.height());
58 option.rect.height());
56 auto buttonOption = QStyleOptionButton{};
59 auto buttonOption = QStyleOptionButton {};
57 buttonOption.rect = buttonRect;
60 buttonOption.rect = buttonRect;
58 buttonOption.text = "X";
61 buttonOption.text = "X";
59
62
60 QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
63 QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
61 }
64 }
62 else {
65 else
66 {
63 QStyledItemDelegate::paint(painter, option, index);
67 QStyledItemDelegate::paint(painter, option, index);
64 }
68 }
65 }
69 }
66 else {
70 else
71 {
67 QStyledItemDelegate::paint(painter, option, index);
72 QStyledItemDelegate::paint(painter, option, index);
68 }
73 }
69 }
74 }
70
75
71 bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
76 bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option,
72 const QModelIndex &index)
77 const QModelIndex& index)
73 {
78 {
74 if (event->type() == QEvent::MouseButtonRelease) {
79 if (event->type() == QEvent::MouseButtonRelease)
80 {
75 auto data = index.data(Qt::DisplayRole);
81 auto data = index.data(Qt::DisplayRole);
76 auto progressData = index.data(VariableRoles::ProgressRole);
82 auto progressData = index.data(VariableRoles::ProgressRole);
77 if (data.isValid() && progressData.isValid()) {
83 if (data.isValid() && progressData.isValid())
84 {
78 auto cancelButtonWidth = 20;
85 auto cancelButtonWidth = 20;
79 auto progressRect = option.rect;
86 auto progressRect = option.rect;
80 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
87 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
81 // Cancel button
88 // Cancel button
82 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
89 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
83 option.rect.height());
90 option.rect.height());
84
91
85 auto e = (QMouseEvent *)event;
92 auto e = (QMouseEvent*)event;
86 auto clickX = e->x();
93 auto clickX = e->x();
87 auto clickY = e->y();
94 auto clickY = e->y();
88
95
89 auto x = buttonRect.left(); // the X coordinate
96 auto x = buttonRect.left(); // the X coordinate
90 auto y = buttonRect.top(); // the Y coordinate
97 auto y = buttonRect.top(); // the Y coordinate
91 auto w = buttonRect.width(); // button width
98 auto w = buttonRect.width(); // button width
92 auto h = buttonRect.height(); // button height
99 auto h = buttonRect.height(); // button height
93
100
94 if (clickX > x && clickX < x + w) {
101 if (clickX > x && clickX < x + w)
95 if (clickY > y && clickY < y + h) {
102 {
96 //auto& variableModel = sqpApp->variableModel();
103 if (clickY > y && clickY < y + h)
97 //variableModel->abortProgress(index);
104 {
105 // auto& variableModel = sqpApp->variableModel();
106 // variableModel->abortProgress(index);
98 }
107 }
99 return true;
108 return true;
100 }
109 }
101 else {
110 else
111 {
102 return QStyledItemDelegate::editorEvent(event, model, option, index);
112 return QStyledItemDelegate::editorEvent(event, model, option, index);
103 }
113 }
104 }
114 }
105 else {
115 else
116 {
106 return QStyledItemDelegate::editorEvent(event, model, option, index);
117 return QStyledItemDelegate::editorEvent(event, model, option, index);
107 }
118 }
108 }
119 }
109 else {
120 else
121 {
110 return QStyledItemDelegate::editorEvent(event, model, option, index);
122 return QStyledItemDelegate::editorEvent(event, model, option, index);
111 }
123 }
112
124
@@ -115,10 +127,10 public:
115 }
127 }
116 };
128 };
117
129
118 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
130 VariableInspectorWidget::VariableInspectorWidget(QWidget* parent)
119 : QWidget{parent},
131 : QWidget { parent }
120 ui{new Ui::VariableInspectorWidget},
132 , ui { new Ui::VariableInspectorWidget }
121 m_ProgressBarItemDelegate{new QProgressBarItemDelegate{this}}
133 , m_ProgressBarItemDelegate { new QProgressBarItemDelegate { this } }
122 {
134 {
123 ui->setupUi(this);
135 ui->setupUi(this);
124
136
@@ -128,9 +140,7 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
128
140
129 m_model = new VariableModel2();
141 m_model = new VariableModel2();
130 ui->tableView->setModel(m_model);
142 ui->tableView->setModel(m_model);
131 connect(m_model, &VariableModel2::createVariable,
143 connect(m_model, &VariableModel2::createVariable, [](const QVariantHash& productData) {
132 [](const QVariantHash &productData)
133 {
134 sqpApp->dataSourceController().requestVariable(productData);
144 sqpApp->dataSourceController().requestVariable(productData);
135 });
145 });
136 auto vc = &(sqpApp->variableController());
146 auto vc = &(sqpApp->variableController());
@@ -140,16 +150,17 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
140
150
141 // Adds extra signal/slot between view and model, so the view can be updated instantly when
151 // Adds extra signal/slot between view and model, so the view can be updated instantly when
142 // there is a change of data in the model
152 // there is a change of data in the model
143 //connect(m_model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this,
153 // connect(m_model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this,
144 // SLOT(refresh()));
154 // SLOT(refresh()));
145
155
146 //ui->tableView->setSelectionModel(sqpApp->variableController().variableSelectionModel());
156 // ui->tableView->setSelectionModel(sqpApp->variableController().variableSelectionModel());
147 ui->tableView->setItemDelegateForColumn(0, m_ProgressBarItemDelegate);
157 ui->tableView->setItemDelegateForColumn(0, m_ProgressBarItemDelegate);
148
158
149 // Fixes column sizes
159 // Fixes column sizes
150 auto model = ui->tableView->model();
160 auto model = ui->tableView->model();
151 const auto count = model->columnCount();
161 const auto count = model->columnCount();
152 for (auto i = 0; i < count; ++i) {
162 for (auto i = 0; i < count; ++i)
163 {
153 ui->tableView->setColumnWidth(
164 ui->tableView->setColumnWidth(
154 i, model->headerData(i, Qt::Horizontal, Qt::SizeHintRole).toSize().width());
165 i, model->headerData(i, Qt::Horizontal, Qt::SizeHintRole).toSize().width());
155 }
166 }
@@ -161,7 +172,7 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
161 // Connection to show a menu when right clicking on the tree
172 // Connection to show a menu when right clicking on the tree
162 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
173 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
163 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
174 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
164 &VariableInspectorWidget::onTableMenuRequested);
175 &VariableInspectorWidget::onTableMenuRequested);
165 }
176 }
166
177
167 VariableInspectorWidget::~VariableInspectorWidget()
178 VariableInspectorWidget::~VariableInspectorWidget()
@@ -169,50 +180,55 VariableInspectorWidget::~VariableInspectorWidget()
169 delete ui;
180 delete ui;
170 }
181 }
171
182
172 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
183 void VariableInspectorWidget::onTableMenuRequested(const QPoint& pos) noexcept
173 {
184 {
174 auto selectedRows = ui->tableView->selectionModel()->selectedRows();
185 auto selectedRows = ui->tableView->selectionModel()->selectedRows();
175 auto selectedVariables = QVector<std::shared_ptr<Variable> >{};
186 auto selectedVariables = QVector<std::shared_ptr<Variable2>> {};
176 for (const auto &selectedRow : qAsConst(selectedRows)) {
187 for (const auto& selectedRow : qAsConst(selectedRows))
177 if (auto selectedVariable = this->m_model->variables()[selectedRow.row()]) {
188 {
189 if (auto selectedVariable = this->m_model->variables()[selectedRow.row()])
190 {
178 selectedVariables.push_back(selectedVariable);
191 selectedVariables.push_back(selectedVariable);
179 }
192 }
180 }
193 }
181
194
182 QMenu tableMenu{};
195 QMenu tableMenu {};
183
196
184 // Emits a signal so that potential receivers can populate the menu before displaying it
197 // Emits a signal so that potential receivers can populate the menu before displaying it
185 emit tableMenuAboutToBeDisplayed(&tableMenu, selectedVariables);
198 emit tableMenuAboutToBeDisplayed(&tableMenu, selectedVariables);
186
199
187 // Adds menu-specific actions
200 // Adds menu-specific actions
188 if (!selectedVariables.isEmpty()) {
201 if (!selectedVariables.isEmpty())
202 {
189 tableMenu.addSeparator();
203 tableMenu.addSeparator();
190
204
191 // 'Rename' and 'Duplicate' actions (only if one variable selected)
205 // 'Rename' and 'Duplicate' actions (only if one variable selected)
192 if (selectedVariables.size() == 1) {
206 if (selectedVariables.size() == 1)
207 {
193 auto selectedVariable = selectedVariables.front();
208 auto selectedVariable = selectedVariables.front();
194
209
195 auto duplicateFun = [varW = std::weak_ptr<Variable>(selectedVariable)]()
210 auto duplicateFun = [varW = std::weak_ptr<Variable2>(selectedVariable)]() {
196 {
211 if (auto var = varW.lock())
197 if (auto var = varW.lock()) {
212 {
198 sqpApp->variableController().cloneVariable(var);
213 sqpApp->variableController().cloneVariable(var);
199 }
214 }
200 };
215 };
201
216
202 tableMenu.addAction(tr("Duplicate"), duplicateFun);
217 tableMenu.addAction(tr("Duplicate"), duplicateFun);
203
218
204 auto renameFun = [ varW = std::weak_ptr<Variable>(selectedVariable), this ]()
219 auto renameFun = [varW = std::weak_ptr<Variable2>(selectedVariable), this]() {
205 {
220 if (auto var = varW.lock())
206 if (auto var = varW.lock()) {
221 {
207 // Generates forbidden names (names associated to existing variables)
222 // Generates forbidden names (names associated to existing variables)
208 auto allVariables = sqpApp->variableController().variables();
223 auto allVariables = sqpApp->variableController().variables();
209 auto forbiddenNames = QVector<QString>(allVariables.size());
224 auto forbiddenNames = QVector<QString>(allVariables.size());
210 std::transform(allVariables.cbegin(), allVariables.cend(),
225 std::transform(allVariables.cbegin(), allVariables.cend(),
211 forbiddenNames.begin(),
226 forbiddenNames.begin(),
212 [](const auto &variable) { return variable->name(); });
227 [](const auto& variable) { return variable->name(); });
213
228
214 RenameVariableDialog dialog{var->name(), forbiddenNames, this};
229 RenameVariableDialog dialog { var->name(), forbiddenNames, this };
215 if (dialog.exec() == QDialog::Accepted) {
230 if (dialog.exec() == QDialog::Accepted)
231 {
216 var->setName(dialog.name());
232 var->setName(dialog.name());
217 }
233 }
218 }
234 }
@@ -223,18 +239,20 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
223
239
224 // 'Delete' action
240 // 'Delete' action
225 auto deleteFun = [&selectedVariables]() {
241 auto deleteFun = [&selectedVariables]() {
226 for(const auto& var:selectedVariables)
242 for (const auto& var : selectedVariables)
227 sqpApp->variableController().deleteVariable(var);
243 sqpApp->variableController().deleteVariable(var);
228 };
244 };
229
245
230 tableMenu.addAction(QIcon{":/icones/delete.png"}, tr("Delete"), deleteFun);
246 tableMenu.addAction(QIcon { ":/icones/delete.png" }, tr("Delete"), deleteFun);
231 }
247 }
232
248
233 if (!tableMenu.isEmpty()) {
249 if (!tableMenu.isEmpty())
250 {
234 // Generates menu header (inserted before first action)
251 // Generates menu header (inserted before first action)
235 auto firstAction = tableMenu.actions().first();
252 auto firstAction = tableMenu.actions().first();
236 auto headerAction = new QWidgetAction{&tableMenu};
253 auto headerAction = new QWidgetAction { &tableMenu };
237 headerAction->setDefaultWidget(new VariableMenuHeaderWidget{selectedVariables, &tableMenu});
254 headerAction->setDefaultWidget(
255 new VariableMenuHeaderWidget { selectedVariables, &tableMenu });
238 tableMenu.insertAction(firstAction, headerAction);
256 tableMenu.insertAction(firstAction, headerAction);
239
257
240 // Displays menu
258 // Displays menu
@@ -1,13 +1,13
1 #include "Variable/VariableMenuHeaderWidget.h"
1 #include "Variable/VariableMenuHeaderWidget.h"
2 #include "Variable/Variable.h"
2 #include "Variable/Variable2.h"
3
3
4 #include <ui_VariableMenuHeaderWidget.h>
4 #include <ui_VariableMenuHeaderWidget.h>
5
5
6 Q_LOGGING_CATEGORY(LOG_VariableMenuHeaderWidget, "VariableMenuHeaderWidget")
6 Q_LOGGING_CATEGORY(LOG_VariableMenuHeaderWidget, "VariableMenuHeaderWidget")
7
7
8 VariableMenuHeaderWidget::VariableMenuHeaderWidget(
8 VariableMenuHeaderWidget::VariableMenuHeaderWidget(
9 const QVector<std::shared_ptr<Variable> > &variables, QWidget *parent)
9 const QVector<std::shared_ptr<Variable2>>& variables, QWidget* parent)
10 : QWidget{parent}, ui{new Ui::VariableMenuHeaderWidget}
10 : QWidget { parent }, ui { new Ui::VariableMenuHeaderWidget }
11 {
11 {
12 ui->setupUi(this);
12 ui->setupUi(this);
13
13
@@ -15,19 +15,24 VariableMenuHeaderWidget::VariableMenuHeaderWidget(
15 // - the variable name if there is only one variable in the list
15 // - the variable name if there is only one variable in the list
16 // - 'x variables' where x is the number of variables otherwise
16 // - 'x variables' where x is the number of variables otherwise
17 const auto nbVariables = variables.size();
17 const auto nbVariables = variables.size();
18 if (nbVariables == 1) {
18 if (nbVariables == 1)
19 if (auto variable = variables.first()) {
19 {
20 if (auto variable = variables.first())
21 {
20 ui->label->setText(variable->name());
22 ui->label->setText(variable->name());
21 }
23 }
22 else {
24 else
25 {
23 qCCritical(LOG_VariableMenuHeaderWidget())
26 qCCritical(LOG_VariableMenuHeaderWidget())
24 << tr("Can't get the name of the variable : variable is null");
27 << tr("Can't get the name of the variable : variable is null");
25 }
28 }
26 }
29 }
27 else if (nbVariables > 1) {
30 else if (nbVariables > 1)
31 {
28 ui->label->setText(tr("%1 variables").arg(nbVariables));
32 ui->label->setText(tr("%1 variables").arg(nbVariables));
29 }
33 }
30 else {
34 else
35 {
31 ui->label->setText(tr("No variable"));
36 ui->label->setText(tr("No variable"));
32 }
37 }
33 }
38 }
@@ -1,17 +1,18
1 #include "Visualization/AxisRenderingUtils.h"
1 #include "Visualization/AxisRenderingUtils.h"
2
2
3 #include <Data/ScalarSeries.h>
3 #include <Data/ScalarTimeSerie.h>
4 #include <Data/SpectrogramSeries.h>
4 #include <Data/SpectrogramTimeSerie.h>
5 #include <Data/VectorSeries.h>
5 #include <Data/VectorTimeSerie.h>
6
6
7 #include <Variable/Variable.h>
7 #include <Variable/Variable2.h>
8
8
9 #include <Visualization/SqpColorScale.h>
9 #include <Visualization/SqpColorScale.h>
10 #include <Visualization/qcustomplot.h>
10 #include <Visualization/qcustomplot.h>
11
11
12 Q_LOGGING_CATEGORY(LOG_AxisRenderingUtils, "AxisRenderingUtils")
12 Q_LOGGING_CATEGORY(LOG_AxisRenderingUtils, "AxisRenderingUtils")
13
13
14 namespace {
14 namespace
15 {
15
16
16 /// Format for datetimes on a axis
17 /// Format for datetimes on a axis
17 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
18 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
@@ -23,17 +24,20 const auto NUMBER_PRECISION = 9;
23 /// non-time data
24 /// non-time data
24 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis, QCPAxis::ScaleType scaleType)
25 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis, QCPAxis::ScaleType scaleType)
25 {
26 {
26 if (isTimeAxis) {
27 if (isTimeAxis)
28 {
27 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
29 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
28 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
30 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
29 dateTicker->setDateTimeSpec(Qt::UTC);
31 dateTicker->setDateTimeSpec(Qt::UTC);
30
32
31 return dateTicker;
33 return dateTicker;
32 }
34 }
33 else if (scaleType == QCPAxis::stLogarithmic) {
35 else if (scaleType == QCPAxis::stLogarithmic)
36 {
34 return QSharedPointer<QCPAxisTickerLog>::create();
37 return QSharedPointer<QCPAxisTickerLog>::create();
35 }
38 }
36 else {
39 else
40 {
37 // default ticker
41 // default ticker
38 return QSharedPointer<QCPAxisTicker>::create();
42 return QSharedPointer<QCPAxisTicker>::create();
39 }
43 }
@@ -45,36 +49,38 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis, QCPAxis::ScaleType sca
45 * @param unit the unit to set for the axis
49 * @param unit the unit to set for the axis
46 * @param scaleType the scale type to set for the axis
50 * @param scaleType the scale type to set for the axis
47 */
51 */
48 void setAxisProperties(QCPAxis &axis, const Unit &unit,
52 void setAxisProperties(QCPAxis& axis, const std::string& unit, bool isTime,
49 QCPAxis::ScaleType scaleType = QCPAxis::stLinear)
53 QCPAxis::ScaleType scaleType = QCPAxis::stLinear)
50 {
54 {
51 // label (unit name)
55 // label (unit name)
52 axis.setLabel(unit.m_Name);
56 axis.setLabel(QString::fromStdString(unit));
53
57
54 // scale type
58 // scale type
55 axis.setScaleType(scaleType);
59 axis.setScaleType(scaleType);
56 if (scaleType == QCPAxis::stLogarithmic) {
60 if (scaleType == QCPAxis::stLogarithmic)
61 {
57 // Scientific notation
62 // Scientific notation
58 axis.setNumberPrecision(0);
63 axis.setNumberPrecision(0);
59 axis.setNumberFormat("eb");
64 axis.setNumberFormat("eb");
60 }
65 }
61
66
62 // ticker (depending on the type of unit)
67 // ticker (depending on the type of unit)
63 axis.setTicker(axisTicker(unit.m_TimeUnit, scaleType));
68 axis.setTicker(axisTicker(isTime, scaleType));
64 }
69 }
65
70
66 /**
71 /**
67 * Delegate used to set axes properties
72 * Delegate used to set axes properties
68 */
73 */
69 template <typename T, typename Enabled = void>
74 template <typename T, typename Enabled = void>
70 struct AxisSetter {
75 struct AxisSetter
71 static void setProperties(QCustomPlot &, SqpColorScale &)
76 {
77 static void setProperties(QCustomPlot&, SqpColorScale&)
72 {
78 {
73 // Default implementation does nothing
79 // Default implementation does nothing
74 qCCritical(LOG_AxisRenderingUtils()) << "Can't set axis properties: unmanaged type of data";
80 qCCritical(LOG_AxisRenderingUtils()) << "Can't set axis properties: unmanaged type of data";
75 }
81 }
76
82
77 static void setUnits(T &, QCustomPlot &, SqpColorScale &)
83 static void setUnits(T&, QCustomPlot&, SqpColorScale&)
78 {
84 {
79 // Default implementation does nothing
85 // Default implementation does nothing
80 qCCritical(LOG_AxisRenderingUtils()) << "Can't set axis units: unmanaged type of data";
86 qCCritical(LOG_AxisRenderingUtils()) << "Can't set axis units: unmanaged type of data";
@@ -87,24 +93,20 struct AxisSetter {
87 * @sa VectorSeries
93 * @sa VectorSeries
88 */
94 */
89 template <typename T>
95 template <typename T>
90 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
96 struct AxisSetter<T,
91 or std::is_base_of<VectorSeries, T>::value> > {
97 typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value
92 static void setProperties(QCustomPlot &, SqpColorScale &)
98 or std::is_base_of<VectorTimeSerie, T>::value>>
99 {
100 static void setProperties(QCustomPlot&, SqpColorScale&)
93 {
101 {
94 // Nothing to do
102 // Nothing to do
95 }
103 }
96
104
97 static void setUnits(T &dataSeries, QCustomPlot &plot, SqpColorScale &)
105 static void setUnits(T& dataSeries, QCustomPlot& plot, SqpColorScale&)
98 {
106 {
99 dataSeries.lockRead();
107 auto serie = dynamic_cast<TimeSeries::ITimeSerie*>(&dataSeries);
100 auto xAxisUnit = dataSeries.xAxisUnit();
108 setAxisProperties(*plot.xAxis, "s", true);
101 auto valuesUnit = dataSeries.valuesUnit();
109 setAxisProperties(*plot.yAxis, serie->unit(1), false);
102 dataSeries.unlock();
103
104 // setAxisProperties(*plot.xAxis, xAxisUnit);
105 // This is cheating but it's ok ;)
106 setAxisProperties(*plot.xAxis, Unit{"s", true});
107 setAxisProperties(*plot.yAxis, valuesUnit);
108 }
110 }
109 };
111 };
110
112
@@ -113,18 +115,20 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>:
113 * @sa SpectrogramSeries
115 * @sa SpectrogramSeries
114 */
116 */
115 template <typename T>
117 template <typename T>
116 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
118 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
117 static void setProperties(QCustomPlot &plot, SqpColorScale &colorScale)
119 {
120 static void setProperties(QCustomPlot& plot, SqpColorScale& colorScale)
118 {
121 {
119 // Displays color scale in plot
122 // Displays color scale in plot
120 plot.plotLayout()->insertRow(0);
123 plot.plotLayout()->insertRow(0);
121 plot.plotLayout()->addElement(0, 0, colorScale.m_Scale);
124 plot.plotLayout()->addElement(0, 0, colorScale.m_Scale);
122 colorScale.m_Scale->setType(QCPAxis::atTop);
125 colorScale.m_Scale->setType(QCPAxis::atTop);
123 colorScale.m_Scale->setMinimumMargins(QMargins{0, 0, 0, 0});
126 colorScale.m_Scale->setMinimumMargins(QMargins { 0, 0, 0, 0 });
124
127
125 // Aligns color scale with axes
128 // Aligns color scale with axes
126 auto marginGroups = plot.axisRect()->marginGroups();
129 auto marginGroups = plot.axisRect()->marginGroups();
127 for (auto it = marginGroups.begin(), end = marginGroups.end(); it != end; ++it) {
130 for (auto it = marginGroups.begin(), end = marginGroups.end(); it != end; ++it)
131 {
128 colorScale.m_Scale->setMarginGroup(it.key(), it.value());
132 colorScale.m_Scale->setMarginGroup(it.key(), it.value());
129 }
133 }
130
134
@@ -132,19 +136,13 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries
132 colorScale.m_AutomaticThreshold = true;
136 colorScale.m_AutomaticThreshold = true;
133 }
137 }
134
138
135 static void setUnits(T &dataSeries, QCustomPlot &plot, SqpColorScale &colorScale)
139 static void setUnits(T& dataSeries, QCustomPlot& plot, SqpColorScale& colorScale)
136 {
140 {
137 dataSeries.lockRead();
141 auto serie = dynamic_cast<TimeSeries::ITimeSerie*>(&dataSeries);
138 auto xAxisUnit = dataSeries.xAxisUnit();
142 setAxisProperties(*plot.xAxis, "s", true);
139 auto yAxisUnit = dataSeries.yAxisUnit();
143 setAxisProperties(*plot.yAxis, serie->unit(1), false, QCPAxis::stLogarithmic);
140 auto valuesUnit = dataSeries.valuesUnit();
144 setAxisProperties(
141 dataSeries.unlock();
145 *colorScale.m_Scale->axis(), serie->unit(2), false, QCPAxis::stLogarithmic);
142
143 //setAxisProperties(*plot.xAxis, xAxisUnit);
144 // This is cheating but it's ok ;)
145 setAxisProperties(*plot.xAxis, Unit{"s", true});
146 setAxisProperties(*plot.yAxis, yAxisUnit, QCPAxis::stLogarithmic);
147 setAxisProperties(*colorScale.m_Scale->axis(), valuesUnit, QCPAxis::stLogarithmic);
148 }
146 }
149 };
147 };
150
148
@@ -153,57 +151,63 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries
153 * @tparam T the data series' type
151 * @tparam T the data series' type
154 */
152 */
155 template <typename T>
153 template <typename T>
156 struct AxisHelper : public IAxisHelper {
154 struct AxisHelper : public IAxisHelper
157 explicit AxisHelper(std::shared_ptr<T> dataSeries) : m_DataSeries{dataSeries} {}
155 {
156 explicit AxisHelper(T* dataSeries) : m_DataSeries { dataSeries } {}
158
157
159 void setProperties(QCustomPlot &plot, SqpColorScale &colorScale) override
158 void setProperties(QCustomPlot& plot, SqpColorScale& colorScale) override
160 {
159 {
161 AxisSetter<T>::setProperties(plot, colorScale);
160 AxisSetter<T>::setProperties(plot, colorScale);
162 }
161 }
163
162
164 void setUnits(QCustomPlot &plot, SqpColorScale &colorScale) override
163 void setUnits(QCustomPlot& plot, SqpColorScale& colorScale) override
165 {
164 {
166 if (m_DataSeries) {
165 if (m_DataSeries)
166 {
167 AxisSetter<T>::setUnits(*m_DataSeries, plot, colorScale);
167 AxisSetter<T>::setUnits(*m_DataSeries, plot, colorScale);
168 }
168 }
169 else {
169 else
170 {
170 qCCritical(LOG_AxisRenderingUtils()) << "Can't set units: inconsistency between the "
171 qCCritical(LOG_AxisRenderingUtils()) << "Can't set units: inconsistency between the "
171 "type of data series and the type supposed";
172 "type of data series and the type supposed";
172 }
173 }
173 }
174 }
174
175
175 std::shared_ptr<T> m_DataSeries;
176 T* m_DataSeries;
176 };
177 };
177
178
178 } // namespace
179 } // namespace
179
180
180 QString formatValue(double value, const QCPAxis &axis)
181 QString formatValue(double value, const QCPAxis& axis)
181 {
182 {
182 // If the axis is a time axis, formats the value as a date
183 // If the axis is a time axis, formats the value as a date
183 if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) {
184 if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker()))
185 {
184 return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT);
186 return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT);
185 }
187 }
186 else {
188 else
189 {
187 return QString::number(value, NUMBER_FORMAT, NUMBER_PRECISION);
190 return QString::number(value, NUMBER_FORMAT, NUMBER_PRECISION);
188 }
191 }
189 }
192 }
190
193
191 std::unique_ptr<IAxisHelper> IAxisHelperFactory::create(const Variable &variable) noexcept
194 std::unique_ptr<IAxisHelper> IAxisHelperFactory::create(Variable2& variable) noexcept
192 {
195 {
193 switch (variable.type()) {
196 switch (variable.type())
197 {
194 case DataSeriesType::SCALAR:
198 case DataSeriesType::SCALAR:
195 return std::make_unique<AxisHelper<ScalarSeries> >(
199 return std::make_unique<AxisHelper<ScalarTimeSerie>>(
196 std::dynamic_pointer_cast<ScalarSeries>(variable.dataSeries()));
200 dynamic_cast<ScalarTimeSerie*>(variable.data()->base()));
197 case DataSeriesType::SPECTROGRAM:
201 case DataSeriesType::SPECTROGRAM:
198 return std::make_unique<AxisHelper<SpectrogramSeries> >(
202 return std::make_unique<AxisHelper<SpectrogramTimeSerie>>(
199 std::dynamic_pointer_cast<SpectrogramSeries>(variable.dataSeries()));
203 dynamic_cast<SpectrogramTimeSerie*>(variable.data()->base()));
200 case DataSeriesType::VECTOR:
204 case DataSeriesType::VECTOR:
201 return std::make_unique<AxisHelper<VectorSeries> >(
205 return std::make_unique<AxisHelper<VectorTimeSerie>>(
202 std::dynamic_pointer_cast<VectorSeries>(variable.dataSeries()));
206 dynamic_cast<VectorTimeSerie*>(variable.data()->base()));
203 default:
207 default:
204 // Creates default helper
208 // Creates default helper
205 break;
209 break;
206 }
210 }
207
211
208 return std::make_unique<AxisHelper<IDataSeries> >(nullptr);
212 return std::make_unique<AxisHelper<TimeSeries::ITimeSerie>>(nullptr);
209 }
213 }
@@ -6,20 +6,22
6 #include <Data/SpectrogramSeries.h>
6 #include <Data/SpectrogramSeries.h>
7 #include <Data/VectorSeries.h>
7 #include <Data/VectorSeries.h>
8
8
9 #include <Variable/Variable.h>
9 #include <Variable/Variable2.h>
10
10
11 #include <Visualization/qcustomplot.h>
11 #include <Visualization/qcustomplot.h>
12
12
13 Q_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils, "PlottablesRenderingUtils")
13 Q_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils, "PlottablesRenderingUtils")
14
14
15 namespace {
15 namespace
16 {
16
17
17 /**
18 /**
18 * Delegate used to set plottables properties
19 * Delegate used to set plottables properties
19 */
20 */
20 template <typename T, typename Enabled = void>
21 template <typename T, typename Enabled = void>
21 struct PlottablesSetter {
22 struct PlottablesSetter
22 static void setProperties(PlottablesMap &)
23 {
24 static void setProperties(PlottablesMap&)
23 {
25 {
24 // Default implementation does nothing
26 // Default implementation does nothing
25 qCCritical(LOG_PlottablesRenderingUtils())
27 qCCritical(LOG_PlottablesRenderingUtils())
@@ -33,26 +35,28 struct PlottablesSetter {
33 * @sa VectorSeries
35 * @sa VectorSeries
34 */
36 */
35 template <typename T>
37 template <typename T>
36 struct PlottablesSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
38 struct PlottablesSetter<T,
37 or std::is_base_of<VectorSeries, T>::value> > {
39 typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value
38 static void setProperties(PlottablesMap &plottables)
40 or std::is_base_of<VectorTimeSerie, T>::value>>
41 {
42 static void setProperties(PlottablesMap& plottables)
39 {
43 {
40 // Finds the plottable with the highest index to determine the number of colors to generate
44 // Finds the plottable with the highest index to determine the number of colors to generate
41 auto end = plottables.cend();
45 auto end = plottables.cend();
42 auto maxPlottableIndexIt
46 auto maxPlottableIndexIt = std::max_element(plottables.cbegin(), end,
43 = std::max_element(plottables.cbegin(), end, [](const auto &it1, const auto &it2) {
47 [](const auto& it1, const auto& it2) { return it1.first < it2.first; });
44 return it1.first < it2.first;
45 });
46 auto componentCount = maxPlottableIndexIt != end ? maxPlottableIndexIt->first + 1 : 0;
48 auto componentCount = maxPlottableIndexIt != end ? maxPlottableIndexIt->first + 1 : 0;
47
49
48 // Generates colors for each component
50 // Generates colors for each component
49 auto colors = ColorUtils::colors(Qt::blue, Qt::red, componentCount);
51 auto colors = ColorUtils::colors(Qt::blue, Qt::red, componentCount);
50
52
51 // For each component of the data series, creates a QCPGraph to add to the plot
53 // For each component of the data series, creates a QCPGraph to add to the plot
52 for (auto i = 0; i < componentCount; ++i) {
54 for (auto i = 0; i < componentCount; ++i)
55 {
53 auto graphIt = plottables.find(i);
56 auto graphIt = plottables.find(i);
54 if (graphIt != end) {
57 if (graphIt != end)
55 graphIt->second->setPen(QPen{colors.at(i)});
58 {
59 graphIt->second->setPen(QPen { colors.at(i) });
56 }
60 }
57 }
61 }
58 }
62 }
@@ -64,30 +68,36 struct PlottablesSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSerie
64 */
68 */
65 template <typename T>
69 template <typename T>
66 struct PlottablesSetter<T,
70 struct PlottablesSetter<T,
67 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
71 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
68 static void setProperties(PlottablesMap &plottables)
72 {
73 static void setProperties(PlottablesMap& plottables)
69 {
74 {
70 // Checks that for a spectrogram there is only one plottable, that is a colormap
75 // Checks that for a spectrogram there is only one plottable, that is a colormap
71 if (plottables.size() != 1) {
76 if (plottables.size() != 1)
77 {
72 return;
78 return;
73 }
79 }
74
80
75 if (auto colormap = dynamic_cast<QCPColorMap *>(plottables.begin()->second)) {
81 if (auto colormap = dynamic_cast<QCPColorMap*>(plottables.begin()->second))
82 {
76 colormap->setInterpolate(false); // No value interpolation
83 colormap->setInterpolate(false); // No value interpolation
77 colormap->setTightBoundary(true);
84 colormap->setTightBoundary(true);
78
85
79 // Finds color scale in the colormap's plot to associate with it
86 // Finds color scale in the colormap's plot to associate with it
80 auto plot = colormap->parentPlot();
87 auto plot = colormap->parentPlot();
81 auto plotElements = plot->plotLayout()->elements(false);
88 auto plotElements = plot->plotLayout()->elements(false);
82 for (auto plotElement : plotElements) {
89 for (auto plotElement : plotElements)
83 if (auto colorScale = dynamic_cast<QCPColorScale *>(plotElement)) {
90 {
91 if (auto colorScale = dynamic_cast<QCPColorScale*>(plotElement))
92 {
84 colormap->setColorScale(colorScale);
93 colormap->setColorScale(colorScale);
85 }
94 }
86 }
95 }
87
96
88 colormap->rescaleDataRange();
97 colormap->rescaleDataRange();
89 }
98 }
90 else {
99 else
100 {
91 qCCritical(LOG_PlottablesRenderingUtils()) << "Can't get colormap of the spectrogram";
101 qCCritical(LOG_PlottablesRenderingUtils()) << "Can't get colormap of the spectrogram";
92 }
102 }
93 }
103 }
@@ -98,8 +108,9 struct PlottablesSetter<T,
98 * @tparam T the data series' type
108 * @tparam T the data series' type
99 */
109 */
100 template <typename T>
110 template <typename T>
101 struct PlottablesHelper : public IPlottablesHelper {
111 struct PlottablesHelper : public IPlottablesHelper
102 void setProperties(PlottablesMap &plottables) override
112 {
113 void setProperties(PlottablesMap& plottables) override
103 {
114 {
104 PlottablesSetter<T>::setProperties(plottables);
115 PlottablesSetter<T>::setProperties(plottables);
105 }
116 }
@@ -107,20 +118,20 struct PlottablesHelper : public IPlottablesHelper {
107
118
108 } // namespace
119 } // namespace
109
120
110 std::unique_ptr<IPlottablesHelper>
121 std::unique_ptr<IPlottablesHelper> IPlottablesHelperFactory::create(Variable2& variable) noexcept
111 IPlottablesHelperFactory::create(const Variable &variable) noexcept
112 {
122 {
113 switch (variable.type()) {
123 switch (variable.type())
124 {
114 case DataSeriesType::SCALAR:
125 case DataSeriesType::SCALAR:
115 return std::make_unique<PlottablesHelper<ScalarSeries> >();
126 return std::make_unique<PlottablesHelper<ScalarTimeSerie>>();
116 case DataSeriesType::SPECTROGRAM:
127 case DataSeriesType::SPECTROGRAM:
117 return std::make_unique<PlottablesHelper<SpectrogramSeries> >();
128 return std::make_unique<PlottablesHelper<SpectrogramTimeSerie>>();
118 case DataSeriesType::VECTOR:
129 case DataSeriesType::VECTOR:
119 return std::make_unique<PlottablesHelper<VectorSeries> >();
130 return std::make_unique<PlottablesHelper<VectorTimeSerie>>();
120 default:
131 default:
121 // Returns default helper
132 // Returns default helper
122 break;
133 break;
123 }
134 }
124
135
125 return std::make_unique<PlottablesHelper<IDataSeries> >();
136 return std::make_unique<PlottablesHelper<IDataSeries>>();
126 }
137 }
@@ -2,19 +2,21
2 #include "Visualization/qcustomplot.h"
2 #include "Visualization/qcustomplot.h"
3
3
4 #include <Data/DataSeriesUtils.h>
4 #include <Data/DataSeriesUtils.h>
5 #include <Data/ScalarSeries.h>
5 #include <Data/ScalarTimeSerie.h>
6 #include <Data/SpectrogramSeries.h>
6 #include <Data/SpectrogramTimeSerie.h>
7 #include <Data/VectorSeries.h>
7 #include <Data/VectorTimeSerie.h>
8
8
9 #include <Variable/Variable.h>
9 #include <Variable/Variable2.h>
10
10
11 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
11 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
12
12
13 namespace {
13 namespace
14 {
14
15
15 class SqpDataContainer : public QCPGraphDataContainer {
16 class SqpDataContainer : public QCPGraphDataContainer
17 {
16 public:
18 public:
17 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
19 void appendGraphData(const QCPGraphData& data) { mData.append(data); }
18 };
20 };
19
21
20 /**
22 /**
@@ -24,23 +26,20 public:
24 * @remarks Default implementation can't create plottables
26 * @remarks Default implementation can't create plottables
25 */
27 */
26 template <typename T, typename Enabled = void>
28 template <typename T, typename Enabled = void>
27 struct PlottablesCreator {
29 struct PlottablesCreator
28 static PlottablesMap createPlottables(QCustomPlot &)
30 {
29 {
31 static PlottablesMap createPlottables(QCustomPlot&) { return {}; }
30 qCCritical(LOG_DataSeries())
31 << QObject::tr("Can't create plottables: unmanaged data series type");
32 return {};
33 }
34 };
32 };
35
33
36 PlottablesMap createGraphs(QCustomPlot &plot, int nbGraphs)
34 PlottablesMap createGraphs(QCustomPlot& plot, int nbGraphs)
37 {
35 {
38 PlottablesMap result{};
36 PlottablesMap result {};
39
37
40 // Creates {nbGraphs} QCPGraph to add to the plot
38 // Creates {nbGraphs} QCPGraph to add to the plot
41 for (auto i = 0; i < nbGraphs; ++i) {
39 for (auto i = 0; i < nbGraphs; ++i)
40 {
42 auto graph = plot.addGraph();
41 auto graph = plot.addGraph();
43 result.insert({i, graph});
42 result.insert({ i, graph });
44 }
43 }
45
44
46 plot.replot();
45 plot.replot();
@@ -53,8 +52,9 PlottablesMap createGraphs(QCustomPlot &plot, int nbGraphs)
53 * @sa ScalarSeries
52 * @sa ScalarSeries
54 */
53 */
55 template <typename T>
54 template <typename T>
56 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value> > {
55 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
57 static PlottablesMap createPlottables(QCustomPlot &plot) { return createGraphs(plot, 1); }
56 {
57 static PlottablesMap createPlottables(QCustomPlot& plot) { return createGraphs(plot, 1); }
58 };
58 };
59
59
60 /**
60 /**
@@ -62,8 +62,9 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<ScalarSeri
62 * @sa VectorSeries
62 * @sa VectorSeries
63 */
63 */
64 template <typename T>
64 template <typename T>
65 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<VectorSeries, T>::value> > {
65 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
66 static PlottablesMap createPlottables(QCustomPlot &plot) { return createGraphs(plot, 3); }
66 {
67 static PlottablesMap createPlottables(QCustomPlot& plot) { return createGraphs(plot, 3); }
67 };
68 };
68
69
69 /**
70 /**
@@ -72,11 +73,12 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<VectorSeri
72 */
73 */
73 template <typename T>
74 template <typename T>
74 struct PlottablesCreator<T,
75 struct PlottablesCreator<T,
75 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
76 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
76 static PlottablesMap createPlottables(QCustomPlot &plot)
77 {
78 static PlottablesMap createPlottables(QCustomPlot& plot)
77 {
79 {
78 PlottablesMap result{};
80 PlottablesMap result {};
79 result.insert({0, new QCPColorMap{plot.xAxis, plot.yAxis}});
81 result.insert({ 0, new QCPColorMap { plot.xAxis, plot.yAxis } });
80
82
81 plot.replot();
83 plot.replot();
82
84
@@ -91,14 +93,15 struct PlottablesCreator<T,
91 * @remarks Default implementation can't update plottables
93 * @remarks Default implementation can't update plottables
92 */
94 */
93 template <typename T, typename Enabled = void>
95 template <typename T, typename Enabled = void>
94 struct PlottablesUpdater {
96 struct PlottablesUpdater
95 static void setPlotYAxisRange(T &, const DateTimeRange &, QCustomPlot &)
97 {
98 static void setPlotYAxisRange(T&, const DateTimeRange&, QCustomPlot&)
96 {
99 {
97 qCCritical(LOG_VisualizationGraphHelper())
100 qCCritical(LOG_VisualizationGraphHelper())
98 << QObject::tr("Can't set plot y-axis range: unmanaged data series type");
101 << QObject::tr("Can't set plot y-axis range: unmanaged data series type");
99 }
102 }
100
103
101 static void updatePlottables(T &, PlottablesMap &, const DateTimeRange &, bool)
104 static void updatePlottables(T&, PlottablesMap&, const DateTimeRange&, bool)
102 {
105 {
103 qCCritical(LOG_VisualizationGraphHelper())
106 qCCritical(LOG_VisualizationGraphHelper())
104 << QObject::tr("Can't update plottables: unmanaged data series type");
107 << QObject::tr("Can't update plottables: unmanaged data series type");
@@ -111,154 +114,223 struct PlottablesUpdater {
111 * @sa VectorSeries
114 * @sa VectorSeries
112 */
115 */
113 template <typename T>
116 template <typename T>
114 struct PlottablesUpdater<T,
117 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
115 typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
118 {
116 or std::is_base_of<VectorSeries, T>::value> > {
119 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
117 static void setPlotYAxisRange(T &dataSeries, const DateTimeRange &xAxisRange, QCustomPlot &plot)
118 {
120 {
119 auto minValue = 0., maxValue = 0.;
121 auto minValue = 0., maxValue = 0.;
120
122 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
121 dataSeries.lockRead();
123 {
122 auto valuesBounds = dataSeries.valuesBounds(xAxisRange.m_TStart, xAxisRange.m_TEnd);
124 maxValue = (*std::max_element(std::begin(*serie), std::end(*serie))).v();
123 auto end = dataSeries.cend();
125 minValue = (*std::min_element(std::begin(*serie), std::end(*serie))).v();
124 if (valuesBounds.first != end && valuesBounds.second != end) {
125 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
126
127 minValue = rangeValue(valuesBounds.first->minValue());
128 maxValue = rangeValue(valuesBounds.second->maxValue());
129 }
126 }
130 dataSeries.unlock();
127 plot.yAxis->setRange(QCPRange { minValue, maxValue });
131
132 plot.yAxis->setRange(QCPRange{minValue, maxValue});
133 }
128 }
134
129
135 static void updatePlottables(T &dataSeries, PlottablesMap &plottables, const DateTimeRange &range,
130 static void updatePlottables(
136 bool rescaleAxes)
131 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
137 {
132 {
138
133
139 // For each plottable to update, resets its data
134 // For each plottable to update, resets its data
140 std::map<int, QSharedPointer<SqpDataContainer> > dataContainers{};
135 for (const auto& plottable : plottables)
141 for (const auto &plottable : plottables) {
136 {
142 if (auto graph = dynamic_cast<QCPGraph *>(plottable.second)) {
137 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
138 {
143 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
139 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
140 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
141 {
142 std::for_each(
143 std::begin(*serie), std::end(*serie), [&dataContainer](const auto& value) {
144 dataContainer->appendGraphData(QCPGraphData(value.t(), value.v()));
145 });
146 }
144 graph->setData(dataContainer);
147 graph->setData(dataContainer);
145
146 dataContainers.insert({plottable.first, dataContainer});
147 }
148 }
149 dataSeries.lockRead();
150
151 // - Gets the data of the series included in the current range
152 // - Updates each plottable by adding, for each data item, a point that takes x-axis data
153 // and value data. The correct value is retrieved according to the index of the component
154 auto subDataIts = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
155 for (auto it = subDataIts.first; it != subDataIts.second; ++it) {
156 for (const auto &dataContainer : dataContainers) {
157 auto componentIndex = dataContainer.first;
158 dataContainer.second->appendGraphData(
159 QCPGraphData(it->x(), it->value(componentIndex)));
160 }
148 }
161 }
149 }
162
150
163 dataSeries.unlock();
151 if (!plottables.empty())
164
152 {
165 if (!plottables.empty()) {
166 auto plot = plottables.begin()->second->parentPlot();
153 auto plot = plottables.begin()->second->parentPlot();
167
154
168 if (rescaleAxes) {
155 if (rescaleAxes)
156 {
169 plot->rescaleAxes();
157 plot->rescaleAxes();
170 }
158 }
171 }
159 }
172 }
160 }
173 };
161 };
174
162
175 /**
163
176 * Specialization of PlottablesUpdater for spectrograms
177 * @sa SpectrogramSeries
178 */
179 template <typename T>
164 template <typename T>
180 struct PlottablesUpdater<T,
165 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
181 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
166 {
182 static void setPlotYAxisRange(T &dataSeries, const DateTimeRange &xAxisRange, QCustomPlot &plot)
167 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
183 {
168 {
184 double min, max;
169 double minValue = 0., maxValue = 0.;
185 std::tie(min, max) = dataSeries.yBounds();
170 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
186
171 {
187 if (!std::isnan(min) && !std::isnan(max)) {
172 std::for_each(
188 plot.yAxis->setRange(QCPRange{min, max});
173 std::begin(*serie), std::end(*serie), [&minValue, &maxValue](const auto& v) {
174 minValue = std::min({ minValue, v.v().x, v.v().y, v.v().z });
175 maxValue = std::max({ maxValue, v.v().x, v.v().y, v.v().z });
176 });
189 }
177 }
178
179 plot.yAxis->setRange(QCPRange { minValue, maxValue });
190 }
180 }
191
181
192 static void updatePlottables(T &dataSeries, PlottablesMap &plottables, const DateTimeRange &range,
182 static void updatePlottables(
193 bool rescaleAxes)
183 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
194 {
184 {
195 if (plottables.empty()) {
196 qCDebug(LOG_VisualizationGraphHelper())
197 << QObject::tr("Can't update spectrogram: no colormap has been associated");
198 return;
199 }
200
201 // Gets the colormap to update (normally there is only one colormap)
202 Q_ASSERT(plottables.size() == 1);
203 auto colormap = dynamic_cast<QCPColorMap *>(plottables.at(0));
204 Q_ASSERT(colormap != nullptr);
205
206 dataSeries.lockRead();
207
208 // Processing spectrogram data for display in QCustomPlot
209 auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
210
185
211 // Computes logarithmic y-axis resolution for the spectrogram
186 // For each plottable to update, resets its data
212 auto yData = its.first->y();
187 for (const auto& plottable : plottables)
213 auto yResolution = DataSeriesUtils::resolution(yData.begin(), yData.end(), true);
188 {
214
189 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
215 // Generates mesh for colormap
190 {
216 auto mesh = DataSeriesUtils::regularMesh(
191 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
217 its.first, its.second, DataSeriesUtils::Resolution{dataSeries.xResolution()},
192 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
218 yResolution);
193 {
219
194 switch (plottable.first)
220 dataSeries.unlock();
195 {
221
196 case 0:
222 colormap->data()->setSize(mesh.m_NbX, mesh.m_NbY);
197 std::for_each(std::begin(*serie), std::end(*serie),
223 if (!mesh.isEmpty()) {
198 [&dataContainer](const auto& value) {
224 colormap->data()->setRange(
199 dataContainer->appendGraphData(
225 QCPRange{mesh.m_XMin, mesh.xMax()},
200 QCPGraphData(value.t(), value.v().x));
226 // y-axis range is converted to linear values
201 });
227 QCPRange{std::pow(10, mesh.m_YMin), std::pow(10, mesh.yMax())});
202 break;
228
203 case 1:
229 // Sets values
204 std::for_each(std::begin(*serie), std::end(*serie),
230 auto index = 0;
205 [&dataContainer](const auto& value) {
231 for (auto it = mesh.m_Data.begin(), end = mesh.m_Data.end(); it != end; ++it, ++index) {
206 dataContainer->appendGraphData(
232 auto xIndex = index % mesh.m_NbX;
207 QCPGraphData(value.t(), value.v().y));
233 auto yIndex = index / mesh.m_NbX;
208 });
234
209 break;
235 colormap->data()->setCell(xIndex, yIndex, *it);
210 case 2:
236
211 std::for_each(std::begin(*serie), std::end(*serie),
237 // Makes the NaN values to be transparent in the colormap
212 [&dataContainer](const auto& value) {
238 if (std::isnan(*it)) {
213 dataContainer->appendGraphData(
239 colormap->data()->setAlpha(xIndex, yIndex, 0);
214 QCPGraphData(value.t(), value.v().z));
215 });
216 break;
217 default:
218 break;
219 }
240 }
220 }
221 graph->setData(dataContainer);
241 }
222 }
242 }
223 }
243
224
244 // Rescales axes
225 if (!plottables.empty())
245 auto plot = colormap->parentPlot();
226 {
227 auto plot = plottables.begin()->second->parentPlot();
246
228
247 if (rescaleAxes) {
229 if (rescaleAxes)
248 plot->rescaleAxes();
230 {
231 plot->rescaleAxes();
232 }
249 }
233 }
250 }
234 }
251 };
235 };
252
236
253 /**
237 /**
238 * Specialization of PlottablesUpdater for spectrograms
239 * @sa SpectrogramSeries
240 */
241 template <typename T>
242 struct PlottablesUpdater<T,
243 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
244 {
245 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
246 {
247 // TODO
248 // double min, max;
249 // std::tie(min, max) = dataSeries.yBounds();
250
251 // if (!std::isnan(min) && !std::isnan(max))
252 // {
253 // plot.yAxis->setRange(QCPRange { min, max });
254 // }
255 }
256
257 static void updatePlottables(
258 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
259 {
260 // TODO
261 // if (plottables.empty())
262 // {
263 // qCDebug(LOG_VisualizationGraphHelper())
264 // << QObject::tr("Can't update spectrogram: no colormap has been
265 // associated");
266 // return;
267 // }
268
269 // // Gets the colormap to update (normally there is only one colormap)
270 // Q_ASSERT(plottables.size() == 1);
271 // auto colormap = dynamic_cast<QCPColorMap*>(plottables.at(0));
272 // Q_ASSERT(colormap != nullptr);
273
274 // dataSeries.lockRead();
275
276 // // Processing spectrogram data for display in QCustomPlot
277 // auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
278
279 // // Computes logarithmic y-axis resolution for the spectrogram
280 // auto yData = its.first->y();
281 // auto yResolution = DataSeriesUtils::resolution(yData.begin(), yData.end(), true);
282
283 // // Generates mesh for colormap
284 // auto mesh = DataSeriesUtils::regularMesh(its.first, its.second,
285 // DataSeriesUtils::Resolution { dataSeries.xResolution() }, yResolution);
286
287 // dataSeries.unlock();
288
289 // colormap->data()->setSize(mesh.m_NbX, mesh.m_NbY);
290 // if (!mesh.isEmpty())
291 // {
292 // colormap->data()->setRange(QCPRange { mesh.m_XMin, mesh.xMax() },
293 // // y-axis range is converted to linear values
294 // QCPRange { std::pow(10, mesh.m_YMin), std::pow(10, mesh.yMax()) });
295
296 // // Sets values
297 // auto index = 0;
298 // for (auto it = mesh.m_Data.begin(), end = mesh.m_Data.end(); it != end; ++it,
299 // ++index)
300 // {
301 // auto xIndex = index % mesh.m_NbX;
302 // auto yIndex = index / mesh.m_NbX;
303
304 // colormap->data()->setCell(xIndex, yIndex, *it);
305
306 // // Makes the NaN values to be transparent in the colormap
307 // if (std::isnan(*it))
308 // {
309 // colormap->data()->setAlpha(xIndex, yIndex, 0);
310 // }
311 // }
312 // }
313
314 // // Rescales axes
315 // auto plot = colormap->parentPlot();
316
317 // if (rescaleAxes)
318 // {
319 // plot->rescaleAxes();
320 // }
321 }
322 };
323
324 /**
254 * Helper used to create/update plottables
325 * Helper used to create/update plottables
255 */
326 */
256 struct IPlottablesHelper {
327 struct IPlottablesHelper
328 {
257 virtual ~IPlottablesHelper() noexcept = default;
329 virtual ~IPlottablesHelper() noexcept = default;
258 virtual PlottablesMap create(QCustomPlot &plot) const = 0;
330 virtual PlottablesMap create(QCustomPlot& plot) const = 0;
259 virtual void setYAxisRange(const DateTimeRange &xAxisRange, QCustomPlot &plot) const = 0;
331 virtual void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const = 0;
260 virtual void update(PlottablesMap &plottables, const DateTimeRange &range,
332 virtual void update(
261 bool rescaleAxes = false) const = 0;
333 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes = false) const = 0;
262 };
334 };
263
335
264 /**
336 /**
@@ -266,95 +338,105 struct IPlottablesHelper {
266 * @tparam T the data series' type
338 * @tparam T the data series' type
267 */
339 */
268 template <typename T>
340 template <typename T>
269 struct PlottablesHelper : public IPlottablesHelper {
341 struct PlottablesHelper : public IPlottablesHelper
270 explicit PlottablesHelper(std::shared_ptr<T> dataSeries) : m_DataSeries{dataSeries} {}
342 {
343 explicit PlottablesHelper(T* dataSeries) : m_DataSeries { dataSeries } {}
271
344
272 PlottablesMap create(QCustomPlot &plot) const override
345 PlottablesMap create(QCustomPlot& plot) const override
273 {
346 {
274 return PlottablesCreator<T>::createPlottables(plot);
347 return PlottablesCreator<T>::createPlottables(plot);
275 }
348 }
276
349
277 void update(PlottablesMap &plottables, const DateTimeRange &range, bool rescaleAxes) const override
350 void update(
351 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes) const override
278 {
352 {
279 if (m_DataSeries) {
353 if (m_DataSeries)
354 {
280 PlottablesUpdater<T>::updatePlottables(*m_DataSeries, plottables, range, rescaleAxes);
355 PlottablesUpdater<T>::updatePlottables(*m_DataSeries, plottables, range, rescaleAxes);
281 }
356 }
282 else {
357 else
358 {
283 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
359 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
284 "between the type of data series and the "
360 "between the type of data series and the "
285 "type supposed";
361 "type supposed";
286 }
362 }
287 }
363 }
288
364
289 void setYAxisRange(const DateTimeRange &xAxisRange, QCustomPlot &plot) const override
365 void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const override
290 {
366 {
291 if (m_DataSeries) {
367 if (m_DataSeries)
368 {
292 PlottablesUpdater<T>::setPlotYAxisRange(*m_DataSeries, xAxisRange, plot);
369 PlottablesUpdater<T>::setPlotYAxisRange(*m_DataSeries, xAxisRange, plot);
293 }
370 }
294 else {
371 else
372 {
295 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
373 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
296 "between the type of data series and the "
374 "between the type of data series and the "
297 "type supposed";
375 "type supposed";
298 }
376 }
299 }
377 }
300
378
301 std::shared_ptr<T> m_DataSeries;
379 T* m_DataSeries;
302 };
380 };
303
381
304 /// Creates IPlottablesHelper according to the type of data series a variable holds
382 /// Creates IPlottablesHelper according to the type of data series a variable holds
305 std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<Variable> variable) noexcept
383 std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<Variable2> variable) noexcept
306 {
384 {
307 switch (variable->type()) {
385 switch (variable->type())
386 {
308 case DataSeriesType::SCALAR:
387 case DataSeriesType::SCALAR:
309 return std::make_unique<PlottablesHelper<ScalarSeries> >(
388 return std::make_unique<PlottablesHelper<ScalarTimeSerie>>(
310 std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries()));
389 dynamic_cast<ScalarTimeSerie*>(variable->data()->base()));
311 case DataSeriesType::SPECTROGRAM:
390 case DataSeriesType::SPECTROGRAM:
312 return std::make_unique<PlottablesHelper<SpectrogramSeries> >(
391 return std::make_unique<PlottablesHelper<SpectrogramTimeSerie>>(
313 std::dynamic_pointer_cast<SpectrogramSeries>(variable->dataSeries()));
392 dynamic_cast<SpectrogramTimeSerie*>(variable->data()->base()));
314 case DataSeriesType::VECTOR:
393 case DataSeriesType::VECTOR:
315 return std::make_unique<PlottablesHelper<VectorSeries> >(
394 return std::make_unique<PlottablesHelper<VectorTimeSerie>>(
316 std::dynamic_pointer_cast<VectorSeries>(variable->dataSeries()));
395 dynamic_cast<VectorTimeSerie*>(variable->data()->base()));
317 default:
396 default:
318 // Creates default helper
397 // Creates default helper
319 break;
398 break;
320 }
399 }
321
400
322 return std::make_unique<PlottablesHelper<IDataSeries> >(nullptr);
401 return std::make_unique<PlottablesHelper<TimeSeries::ITimeSerie>>(nullptr);
323 }
402 }
324
403
325 } // namespace
404 } // namespace
326
405
327 PlottablesMap VisualizationGraphHelper::create(std::shared_ptr<Variable> variable,
406 PlottablesMap VisualizationGraphHelper::create(
328 QCustomPlot &plot) noexcept
407 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
329 {
408 {
330 if (variable) {
409 if (variable)
410 {
331 auto helper = createHelper(variable);
411 auto helper = createHelper(variable);
332 auto plottables = helper->create(plot);
412 auto plottables = helper->create(plot);
333 return plottables;
413 return plottables;
334 }
414 }
335 else {
415 else
416 {
336 qCDebug(LOG_VisualizationGraphHelper())
417 qCDebug(LOG_VisualizationGraphHelper())
337 << QObject::tr("Can't create graph plottables : the variable is null");
418 << QObject::tr("Can't create graph plottables : the variable is null");
338 return PlottablesMap{};
419 return PlottablesMap {};
339 }
420 }
340 }
421 }
341
422
342 void VisualizationGraphHelper::setYAxisRange(std::shared_ptr<Variable> variable,
423 void VisualizationGraphHelper::setYAxisRange(
343 QCustomPlot &plot) noexcept
424 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
344 {
425 {
345 if (variable) {
426 if (variable)
427 {
346 auto helper = createHelper(variable);
428 auto helper = createHelper(variable);
347 helper->setYAxisRange(variable->range(), plot);
429 helper->setYAxisRange(variable->range(), plot);
348 }
430 }
349 else {
431 else
432 {
350 qCDebug(LOG_VisualizationGraphHelper())
433 qCDebug(LOG_VisualizationGraphHelper())
351 << QObject::tr("Can't set y-axis range of plot: the variable is null");
434 << QObject::tr("Can't set y-axis range of plot: the variable is null");
352 }
435 }
353 }
436 }
354
437
355 void VisualizationGraphHelper::updateData(PlottablesMap &plottables,
438 void VisualizationGraphHelper::updateData(
356 std::shared_ptr<Variable> variable,
439 PlottablesMap& plottables, std::shared_ptr<Variable2> variable, const DateTimeRange& dateTime)
357 const DateTimeRange &dateTime)
358 {
440 {
359 auto helper = createHelper(variable);
441 auto helper = createHelper(variable);
360 helper->update(plottables, dateTime);
442 helper->update(plottables, dateTime);
@@ -13,7 +13,8
13
13
14 #include <SqpApplication.h>
14 #include <SqpApplication.h>
15
15
16 namespace {
16 namespace
17 {
17
18
18 /// Name of the axes layer in QCustomPlot
19 /// Name of the axes layer in QCustomPlot
19 const auto AXES_LAYER = QStringLiteral("axes");
20 const auto AXES_LAYER = QStringLiteral("axes");
@@ -34,15 +35,15 const auto GRAPH_TOOLTIP_FORMAT = QStringLiteral("key: %1\nvalue: %2");
34 const auto COLORMAP_TOOLTIP_FORMAT = QStringLiteral("x: %1\ny: %2\nvalue: %3");
35 const auto COLORMAP_TOOLTIP_FORMAT = QStringLiteral("x: %1\ny: %2\nvalue: %3");
35
36
36 /// Offset used to shift the tooltip of the mouse
37 /// Offset used to shift the tooltip of the mouse
37 const auto TOOLTIP_OFFSET = QPoint{20, 20};
38 const auto TOOLTIP_OFFSET = QPoint { 20, 20 };
38
39
39 /// Tooltip display rectangle (the tooltip is hidden when the mouse leaves this rectangle)
40 /// Tooltip display rectangle (the tooltip is hidden when the mouse leaves this rectangle)
40 const auto TOOLTIP_RECT = QRect{10, 10, 10, 10};
41 const auto TOOLTIP_RECT = QRect { 10, 10, 10, 10 };
41
42
42 /// Timeout after which the tooltip is displayed
43 /// Timeout after which the tooltip is displayed
43 const auto TOOLTIP_TIMEOUT = 500;
44 const auto TOOLTIP_TIMEOUT = 500;
44
45
45 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
46 void initPointTracerStyle(QCPItemTracer& tracer) noexcept
46 {
47 {
47 tracer.setInterpolating(false);
48 tracer.setInterpolating(false);
48 tracer.setStyle(QCPItemTracer::tsCircle);
49 tracer.setStyle(QCPItemTracer::tsCircle);
@@ -52,16 +53,16 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
52 tracer.setSelectable(false);
53 tracer.setSelectable(false);
53 }
54 }
54
55
55 QPixmap pixmap(const QString &iconPath) noexcept
56 QPixmap pixmap(const QString& iconPath) noexcept
56 {
57 {
57 return QIcon{iconPath}.pixmap(QSize{16, 16});
58 return QIcon { iconPath }.pixmap(QSize { 16, 16 });
58 }
59 }
59
60
60 void initClosePixmapStyle(QCPItemPixmap &pixmap) noexcept
61 void initClosePixmapStyle(QCPItemPixmap& pixmap) noexcept
61 {
62 {
62 // Icon
63 // Icon
63 pixmap.setPixmap(
64 pixmap.setPixmap(
64 sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton).pixmap(QSize{16, 16}));
65 sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton).pixmap(QSize { 16, 16 }));
65
66
66 // Position
67 // Position
67 pixmap.topLeft->setType(QCPItemPosition::ptAxisRectRatio);
68 pixmap.topLeft->setType(QCPItemPosition::ptAxisRectRatio);
@@ -72,7 +73,7 void initClosePixmapStyle(QCPItemPixmap &pixmap) noexcept
72 pixmap.setSelectable(true);
73 pixmap.setSelectable(true);
73 }
74 }
74
75
75 void initXAxisPixmapStyle(QCPItemPixmap &itemPixmap) noexcept
76 void initXAxisPixmapStyle(QCPItemPixmap& itemPixmap) noexcept
76 {
77 {
77 // Icon
78 // Icon
78 itemPixmap.setPixmap(pixmap(HIDE_AXIS_ICON_PATH));
79 itemPixmap.setPixmap(pixmap(HIDE_AXIS_ICON_PATH));
@@ -86,7 +87,7 void initXAxisPixmapStyle(QCPItemPixmap &itemPixmap) noexcept
86 itemPixmap.setSelectable(true);
87 itemPixmap.setSelectable(true);
87 }
88 }
88
89
89 void initTitleTextStyle(QCPItemText &text) noexcept
90 void initTitleTextStyle(QCPItemText& text) noexcept
90 {
91 {
91 // Font and background styles
92 // Font and background styles
92 text.setColor(Qt::gray);
93 text.setColor(Qt::gray);
@@ -107,13 +108,14 void initTitleTextStyle(QCPItemText &text) noexcept
107 * @param xCoord calculates the x index if true, calculates y index if false
108 * @param xCoord calculates the x index if true, calculates y index if false
108 * @return the cell index
109 * @return the cell index
109 */
110 */
110 int colorMapCellIndex(const QCPColorMap &colormap, double coord, bool xCoord)
111 int colorMapCellIndex(const QCPColorMap& colormap, double coord, bool xCoord)
111 {
112 {
112 // Determines the axis of the colormap according to xCoord, and whether it is logarithmic or not
113 // Determines the axis of the colormap according to xCoord, and whether it is logarithmic or not
113 auto isLogarithmic = (xCoord ? colormap.keyAxis() : colormap.valueAxis())->scaleType()
114 auto isLogarithmic = (xCoord ? colormap.keyAxis() : colormap.valueAxis())->scaleType()
114 == QCPAxis::stLogarithmic;
115 == QCPAxis::stLogarithmic;
115
116
116 if (isLogarithmic) {
117 if (isLogarithmic)
118 {
117 // For a logarithmic axis we can't use the conversion method of colormap, so we calculate
119 // For a logarithmic axis we can't use the conversion method of colormap, so we calculate
118 // the index manually based on the position of the coordinate on the axis
120 // the index manually based on the position of the coordinate on the axis
119
121
@@ -127,13 +129,16 int colorMapCellIndex(const QCPColorMap &colormap, double coord, bool xCoord)
127 // According to the coord position, calculates the closest index in the range
129 // According to the coord position, calculates the closest index in the range
128 return std::round((std::log10(coord) - std::log10(range.lower)) / valueStep);
130 return std::round((std::log10(coord) - std::log10(range.lower)) / valueStep);
129 }
131 }
130 else {
132 else
133 {
131 // For a linear axis, we use the conversion method of colormap
134 // For a linear axis, we use the conversion method of colormap
132 int index;
135 int index;
133 if (xCoord) {
136 if (xCoord)
137 {
134 colormap.data()->coordToCell(coord, 0., &index, nullptr);
138 colormap.data()->coordToCell(coord, 0., &index, nullptr);
135 }
139 }
136 else {
140 else
141 {
137 colormap.data()->coordToCell(0., coord, nullptr, &index);
142 colormap.data()->coordToCell(0., coord, nullptr, &index);
138 }
143 }
139
144
@@ -143,17 +148,18 int colorMapCellIndex(const QCPColorMap &colormap, double coord, bool xCoord)
143
148
144 } // namespace
149 } // namespace
145
150
146 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegatePrivate {
151 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegatePrivate
147 explicit VisualizationGraphRenderingDelegatePrivate(VisualizationGraphWidget &graphWidget)
152 {
148 : m_Plot{graphWidget.plot()},
153 explicit VisualizationGraphRenderingDelegatePrivate(VisualizationGraphWidget& graphWidget)
149 m_PointTracer{new QCPItemTracer{&m_Plot}},
154 : m_Plot { graphWidget.plot() }
150 m_TracerTimer{},
155 , m_PointTracer { new QCPItemTracer { &m_Plot } }
151 m_ClosePixmap{new QCPItemPixmap{&m_Plot}},
156 , m_TracerTimer {}
152 m_TitleText{new QCPItemText{&m_Plot}},
157 , m_ClosePixmap { new QCPItemPixmap { &m_Plot } }
153 m_XAxisPixmap{new QCPItemPixmap{&m_Plot}},
158 , m_TitleText { new QCPItemText { &m_Plot } }
154 m_ShowXAxis{true},
159 , m_XAxisPixmap { new QCPItemPixmap { &m_Plot } }
155 m_XAxisLabel{},
160 , m_ShowXAxis { true }
156 m_ColorScale{SqpColorScale{m_Plot}}
161 , m_XAxisLabel {}
162 , m_ColorScale { SqpColorScale { m_Plot } }
157 {
163 {
158 initPointTracerStyle(*m_PointTracer);
164 initPointTracerStyle(*m_PointTracer);
159
165
@@ -165,12 +171,13 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegateP
165 initClosePixmapStyle(*m_ClosePixmap);
171 initClosePixmapStyle(*m_ClosePixmap);
166
172
167 // Connects pixmap selection to graph widget closing
173 // Connects pixmap selection to graph widget closing
168 QObject::connect(&m_Plot, &QCustomPlot::itemClick,
174 QObject::connect(
169 [&graphWidget, this](auto item, auto mouseEvent) {
175 &m_Plot, &QCustomPlot::itemClick, [&graphWidget, this](auto item, auto mouseEvent) {
170 if (item == m_ClosePixmap) {
176 if (item == m_ClosePixmap)
171 graphWidget.close();
177 {
172 }
178 graphWidget.close();
173 });
179 }
180 });
174
181
175 // Inits graph name in plot overlay
182 // Inits graph name in plot overlay
176 m_TitleText->setLayer(OVERLAY_LAYER);
183 m_TitleText->setLayer(OVERLAY_LAYER);
@@ -183,7 +190,8 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegateP
183
190
184 // Connects pixmap selection to graph x-axis showing/hiding
191 // Connects pixmap selection to graph x-axis showing/hiding
185 QObject::connect(&m_Plot, &QCustomPlot::itemClick, [this](auto item, auto mouseEvent) {
192 QObject::connect(&m_Plot, &QCustomPlot::itemClick, [this](auto item, auto mouseEvent) {
186 if (m_XAxisPixmap == item) {
193 if (m_XAxisPixmap == item)
194 {
187 // Changes the selection state and refreshes the x-axis
195 // Changes the selection state and refreshes the x-axis
188 m_ShowXAxis = !m_ShowXAxis;
196 m_ShowXAxis = !m_ShowXAxis;
189 this->updateXAxisState();
197 this->updateXAxisState();
@@ -202,38 +210,40 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegateP
202 void updateXAxisState() noexcept
210 void updateXAxisState() noexcept
203 {
211 {
204 m_Plot.xAxis->setTickLabels(m_ShowXAxis);
212 m_Plot.xAxis->setTickLabels(m_ShowXAxis);
205 m_Plot.xAxis->setLabel(m_ShowXAxis ? m_XAxisLabel : QString{});
213 m_Plot.xAxis->setLabel(m_ShowXAxis ? m_XAxisLabel : QString {});
206 }
214 }
207
215
208 QCustomPlot &m_Plot;
216 QCustomPlot& m_Plot;
209 QCPItemTracer *m_PointTracer;
217 QCPItemTracer* m_PointTracer;
210 QTimer m_TracerTimer;
218 QTimer m_TracerTimer;
211 QCPItemPixmap *m_ClosePixmap; /// Graph's close button
219 QCPItemPixmap* m_ClosePixmap; /// Graph's close button
212 QCPItemText *m_TitleText; /// Graph's title
220 QCPItemText* m_TitleText; /// Graph's title
213 QCPItemPixmap *m_XAxisPixmap;
221 QCPItemPixmap* m_XAxisPixmap;
214 bool m_ShowXAxis; /// X-axis properties are shown or hidden
222 bool m_ShowXAxis; /// X-axis properties are shown or hidden
215 QString m_XAxisLabel;
223 QString m_XAxisLabel;
216 SqpColorScale m_ColorScale; /// Color scale used for some types of graphs (as spectrograms)
224 SqpColorScale m_ColorScale; /// Color scale used for some types of graphs (as spectrograms)
217 };
225 };
218
226
219 VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegate(
227 VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegate(
220 VisualizationGraphWidget &graphWidget)
228 VisualizationGraphWidget& graphWidget)
221 : impl{spimpl::make_unique_impl<VisualizationGraphRenderingDelegatePrivate>(graphWidget)}
229 : impl { spimpl::make_unique_impl<VisualizationGraphRenderingDelegatePrivate>(graphWidget) }
222 {
230 {
223 }
231 }
224
232
225 void VisualizationGraphRenderingDelegate::onMouseDoubleClick(QMouseEvent *event) noexcept
233 void VisualizationGraphRenderingDelegate::onMouseDoubleClick(QMouseEvent* event) noexcept
226 {
234 {
227 // Opens color scale editor if color scale is double clicked
235 // Opens color scale editor if color scale is double clicked
228 auto colorScale = static_cast<QCPColorScale *>(impl->m_Plot.layoutElementAt(event->pos()));
236 auto colorScale = static_cast<QCPColorScale*>(impl->m_Plot.layoutElementAt(event->pos()));
229 if (impl->m_ColorScale.m_Scale == colorScale) {
237 if (impl->m_ColorScale.m_Scale == colorScale)
230 if (ColorScaleEditor{impl->m_ColorScale}.exec() == QDialog::Accepted) {
238 {
239 if (ColorScaleEditor { impl->m_ColorScale }.exec() == QDialog::Accepted)
240 {
231 impl->m_Plot.replot();
241 impl->m_Plot.replot();
232 }
242 }
233 }
243 }
234 }
244 }
235
245
236 void VisualizationGraphRenderingDelegate::updateTooltip(QMouseEvent *event) noexcept
246 void VisualizationGraphRenderingDelegate::updateTooltip(QMouseEvent* event) noexcept
237 {
247 {
238 // Cancels pending refresh
248 // Cancels pending refresh
239 impl->m_TracerTimer.disconnect();
249 impl->m_TracerTimer.disconnect();
@@ -243,17 +253,19 void VisualizationGraphRenderingDelegate::updateTooltip(QMouseEvent *event) noex
243 impl->m_PointTracer->setVisible(false);
253 impl->m_PointTracer->setVisible(false);
244 impl->m_Plot.replot();
254 impl->m_Plot.replot();
245
255
246 QString tooltip{};
256 QString tooltip {};
247
257
248 // Gets the graph under the mouse position
258 // Gets the graph under the mouse position
249 auto eventPos = event->pos();
259 auto eventPos = event->pos();
250 if (auto graph = qobject_cast<QCPGraph *>(impl->m_Plot.plottableAt(eventPos))) {
260 if (auto graph = qobject_cast<QCPGraph*>(impl->m_Plot.plottableAt(eventPos)))
261 {
251 auto mouseKey = graph->keyAxis()->pixelToCoord(eventPos.x());
262 auto mouseKey = graph->keyAxis()->pixelToCoord(eventPos.x());
252 auto graphData = graph->data();
263 auto graphData = graph->data();
253
264
254 // Gets the closest data point to the mouse
265 // Gets the closest data point to the mouse
255 auto graphDataIt = graphData->findBegin(mouseKey);
266 auto graphDataIt = graphData->findBegin(mouseKey);
256 if (graphDataIt != graphData->constEnd()) {
267 if (graphDataIt != graphData->constEnd())
268 {
257 // Sets tooltip
269 // Sets tooltip
258 auto key = formatValue(graphDataIt->key, *graph->keyAxis());
270 auto key = formatValue(graphDataIt->key, *graph->keyAxis());
259 auto value = formatValue(graphDataIt->value, *graph->valueAxis());
271 auto value = formatValue(graphDataIt->value, *graph->valueAxis());
@@ -268,7 +280,8 void VisualizationGraphRenderingDelegate::updateTooltip(QMouseEvent *event) noex
268 impl->m_Plot.replot();
280 impl->m_Plot.replot();
269 }
281 }
270 }
282 }
271 else if (auto colorMap = qobject_cast<QCPColorMap *>(impl->m_Plot.plottableAt(eventPos))) {
283 else if (auto colorMap = qobject_cast<QCPColorMap*>(impl->m_Plot.plottableAt(eventPos)))
284 {
272 // Gets x and y coords
285 // Gets x and y coords
273 auto x = colorMap->keyAxis()->pixelToCoord(eventPos.x());
286 auto x = colorMap->keyAxis()->pixelToCoord(eventPos.x());
274 auto y = colorMap->valueAxis()->pixelToCoord(eventPos.y());
287 auto y = colorMap->valueAxis()->pixelToCoord(eventPos.y());
@@ -280,15 +293,16 void VisualizationGraphRenderingDelegate::updateTooltip(QMouseEvent *event) noex
280
293
281 // Sets tooltips
294 // Sets tooltips
282 tooltip = COLORMAP_TOOLTIP_FORMAT.arg(formatValue(x, *colorMap->keyAxis()),
295 tooltip = COLORMAP_TOOLTIP_FORMAT.arg(formatValue(x, *colorMap->keyAxis()),
283 formatValue(y, *colorMap->valueAxis()),
296 formatValue(y, *colorMap->valueAxis()),
284 formatValue(value, *colorMap->colorScale()->axis()));
297 formatValue(value, *colorMap->colorScale()->axis()));
285 }
298 }
286
299
287 if (!tooltip.isEmpty()) {
300 if (!tooltip.isEmpty())
301 {
288 // Starts timer to show tooltip after timeout
302 // Starts timer to show tooltip after timeout
289 auto showTooltip = [tooltip, eventPos, this]() {
303 auto showTooltip = [tooltip, eventPos, this]() {
290 QToolTip::showText(impl->m_Plot.mapToGlobal(eventPos) + TOOLTIP_OFFSET, tooltip,
304 QToolTip::showText(impl->m_Plot.mapToGlobal(eventPos) + TOOLTIP_OFFSET, tooltip,
291 &impl->m_Plot, TOOLTIP_RECT);
305 &impl->m_Plot, TOOLTIP_RECT);
292 };
306 };
293
307
294 QObject::connect(&impl->m_TracerTimer, &QTimer::timeout, showTooltip);
308 QObject::connect(&impl->m_TracerTimer, &QTimer::timeout, showTooltip);
@@ -303,7 +317,7 void VisualizationGraphRenderingDelegate::onPlotUpdated() noexcept
303 impl->m_Plot.replot();
317 impl->m_Plot.replot();
304 }
318 }
305
319
306 void VisualizationGraphRenderingDelegate::setAxesUnits(const Variable &variable) noexcept
320 void VisualizationGraphRenderingDelegate::setAxesUnits(Variable2& variable) noexcept
307 {
321 {
308
322
309 auto axisHelper = IAxisHelperFactory::create(variable);
323 auto axisHelper = IAxisHelperFactory::create(variable);
@@ -318,8 +332,8 void VisualizationGraphRenderingDelegate::setAxesUnits(const Variable &variable)
318 impl->m_Plot.layer(AXES_LAYER)->replot();
332 impl->m_Plot.layer(AXES_LAYER)->replot();
319 }
333 }
320
334
321 void VisualizationGraphRenderingDelegate::setGraphProperties(const Variable &variable,
335 void VisualizationGraphRenderingDelegate::setGraphProperties(
322 PlottablesMap &plottables) noexcept
336 Variable2& variable, PlottablesMap& plottables) noexcept
323 {
337 {
324 // Axes' properties
338 // Axes' properties
325 auto axisHelper = IAxisHelperFactory::create(variable);
339 auto axisHelper = IAxisHelperFactory::create(variable);
This diff has been collapsed as it changes many lines, (787 lines changed) Show them Hide them
@@ -16,21 +16,22
16 #include <Common/MimeTypesDef.h>
16 #include <Common/MimeTypesDef.h>
17 #include <Common/containers.h>
17 #include <Common/containers.h>
18 #include <Data/ArrayData.h>
18 #include <Data/ArrayData.h>
19 #include <Data/DateTimeRangeHelper.h>
19 #include <Data/IDataSeries.h>
20 #include <Data/IDataSeries.h>
20 #include <Data/SpectrogramSeries.h>
21 #include <Data/SpectrogramSeries.h>
21 #include <DragAndDrop/DragDropGuiController.h>
22 #include <DragAndDrop/DragDropGuiController.h>
22 #include <Settings/SqpSettingsDefs.h>
23 #include <Settings/SqpSettingsDefs.h>
23 #include <SqpApplication.h>
24 #include <SqpApplication.h>
24 #include <Time/TimeController.h>
25 #include <Time/TimeController.h>
25 #include <Variable/Variable.h>
26 #include <Variable/Variable2.h>
26 #include <Variable/VariableController2.h>
27 #include <Variable/VariableController2.h>
27 #include <Data/DateTimeRangeHelper.h>
28
28
29 #include <unordered_map>
29 #include <unordered_map>
30
30
31 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
31 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
32
32
33 namespace {
33 namespace
34 {
34
35
35 /// Key pressed to enable drag&drop in all modes
36 /// Key pressed to enable drag&drop in all modes
36 const auto DRAG_DROP_MODIFIER = Qt::AltModifier;
37 const auto DRAG_DROP_MODIFIER = Qt::AltModifier;
@@ -58,21 +59,22 const auto CURSOR_LABELS_DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd\nhh:mm:ss:
58
59
59 } // namespace
60 } // namespace
60
61
61 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
62 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate
63 {
62
64
63 explicit VisualizationGraphWidgetPrivate(const QString &name)
65 explicit VisualizationGraphWidgetPrivate(const QString& name)
64 : m_Name{name},
66 : m_Name { name }
65 m_Flags{GraphFlag::EnableAll},
67 , m_Flags { GraphFlag::EnableAll }
66 m_IsCalibration{false},
68 , m_IsCalibration { false }
67 m_RenderingDelegate{nullptr}
69 , m_RenderingDelegate { nullptr }
68 {
70 {
69 m_plot = new QCustomPlot();
71 m_plot = new QCustomPlot();
70 // Necessary for all platform since Qt::AA_EnableHighDpiScaling is enable.
72 // Necessary for all platform since Qt::AA_EnableHighDpiScaling is enable.
71 m_plot->setPlottingHint(QCP::phFastPolylines, true);
73 m_plot->setPlottingHint(QCP::phFastPolylines, true);
72 }
74 }
73
75
74 void updateData(PlottablesMap &plottables, std::shared_ptr<Variable> variable,
76 void updateData(
75 const DateTimeRange &range)
77 PlottablesMap& plottables, std::shared_ptr<Variable2> variable, const DateTimeRange& range)
76 {
78 {
77 VisualizationGraphHelper::updateData(plottables, variable, range);
79 VisualizationGraphHelper::updateData(plottables, variable, range);
78
80
@@ -82,7 +84,7 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
82
84
83 QString m_Name;
85 QString m_Name;
84 // 1 variable -> n qcpplot
86 // 1 variable -> n qcpplot
85 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
87 std::map<std::shared_ptr<Variable2>, PlottablesMap> m_VariableToPlotMultiMap;
86 GraphFlags m_Flags;
88 GraphFlags m_Flags;
87 bool m_IsCalibration;
89 bool m_IsCalibration;
88 QCustomPlot* m_plot;
90 QCustomPlot* m_plot;
@@ -93,14 +95,14 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
93 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
95 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
94
96
95 QCPItemRect* m_DrawingZoomRect = nullptr;
97 QCPItemRect* m_DrawingZoomRect = nullptr;
96 QStack<QPair<QCPRange, QCPRange> > m_ZoomStack;
98 QStack<QPair<QCPRange, QCPRange>> m_ZoomStack;
97
99
98 std::unique_ptr<VisualizationCursorItem> m_HorizontalCursor = nullptr;
100 std::unique_ptr<VisualizationCursorItem> m_HorizontalCursor = nullptr;
99 std::unique_ptr<VisualizationCursorItem> m_VerticalCursor = nullptr;
101 std::unique_ptr<VisualizationCursorItem> m_VerticalCursor = nullptr;
100
102
101 VisualizationSelectionZoneItem *m_DrawingZone = nullptr;
103 VisualizationSelectionZoneItem* m_DrawingZone = nullptr;
102 VisualizationSelectionZoneItem *m_HoveredZone = nullptr;
104 VisualizationSelectionZoneItem* m_HoveredZone = nullptr;
103 QVector<VisualizationSelectionZoneItem *> m_SelectionZones;
105 QVector<VisualizationSelectionZoneItem*> m_SelectionZones;
104
106
105 bool m_HasMovedMouse = false; // Indicates if the mouse moved in a releaseMouse even
107 bool m_HasMovedMouse = false; // Indicates if the mouse moved in a releaseMouse even
106
108
@@ -111,13 +113,13 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
111 m_lastMousePos = m_plot->mapFromParent(position);
113 m_lastMousePos = m_plot->mapFromParent(position);
112 m_lastXRange = m_plot->xAxis->range();
114 m_lastXRange = m_plot->xAxis->range();
113 m_lastYRange = m_plot->yAxis->range();
115 m_lastYRange = m_plot->yAxis->range();
114
115 }
116 }
116
117
117 inline bool isDrawingZoomRect(){return m_DrawingZoomRect!=nullptr;}
118 inline bool isDrawingZoomRect() { return m_DrawingZoomRect != nullptr; }
118 void updateZoomRect(const QPoint& newPos)
119 void updateZoomRect(const QPoint& newPos)
119 {
120 {
120 QPointF pos{m_plot->xAxis->pixelToCoord(newPos.x()), m_plot->yAxis->pixelToCoord(newPos.y())};
121 QPointF pos { m_plot->xAxis->pixelToCoord(newPos.x()),
122 m_plot->yAxis->pixelToCoord(newPos.y()) };
121 m_DrawingZoomRect->bottomRight->setCoords(pos);
123 m_DrawingZoomRect->bottomRight->setCoords(pos);
122 m_plot->replot(QCustomPlot::rpQueuedReplot);
124 m_plot->replot(QCustomPlot::rpQueuedReplot);
123 }
125 }
@@ -127,16 +129,17 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
127 auto axisX = m_plot->axisRect()->axis(QCPAxis::atBottom);
129 auto axisX = m_plot->axisRect()->axis(QCPAxis::atBottom);
128 auto axisY = m_plot->axisRect()->axis(QCPAxis::atLeft);
130 auto axisY = m_plot->axisRect()->axis(QCPAxis::atLeft);
129
131
130 auto newAxisXRange = QCPRange{m_DrawingZoomRect->topLeft->coords().x(),
132 auto newAxisXRange = QCPRange { m_DrawingZoomRect->topLeft->coords().x(),
131 m_DrawingZoomRect->bottomRight->coords().x()};
133 m_DrawingZoomRect->bottomRight->coords().x() };
132
134
133 auto newAxisYRange = QCPRange{m_DrawingZoomRect->topLeft->coords().y(),
135 auto newAxisYRange = QCPRange { m_DrawingZoomRect->topLeft->coords().y(),
134 m_DrawingZoomRect->bottomRight->coords().y()};
136 m_DrawingZoomRect->bottomRight->coords().y() };
135
137
136 removeDrawingRect();
138 removeDrawingRect();
137
139
138 if (newAxisXRange.size() > axisX->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)
140 if (newAxisXRange.size() > axisX->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)
139 && newAxisYRange.size() > axisY->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)) {
141 && newAxisYRange.size() > axisY->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0))
142 {
140 m_ZoomStack.push(qMakePair(axisX->range(), axisY->range()));
143 m_ZoomStack.push(qMakePair(axisX->range(), axisY->range()));
141 axisX->setRange(newAxisXRange);
144 axisX->setRange(newAxisXRange);
142 axisY->setRange(newAxisYRange);
145 axisY->setRange(newAxisYRange);
@@ -145,20 +148,20 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
145 }
148 }
146 }
149 }
147
150
148 inline bool isDrawingZoneRect(){return m_DrawingZone!=nullptr;}
151 inline bool isDrawingZoneRect() { return m_DrawingZone != nullptr; }
149 void updateZoneRect(const QPoint& newPos)
152 void updateZoneRect(const QPoint& newPos)
150 {
153 {
151 m_DrawingZone->setEnd(m_plot->xAxis->pixelToCoord(newPos.x()));
154 m_DrawingZone->setEnd(m_plot->xAxis->pixelToCoord(newPos.x()));
152 m_plot->replot(QCustomPlot::rpQueuedReplot);
155 m_plot->replot(QCustomPlot::rpQueuedReplot);
153 }
156 }
154
157
155 void startDrawingRect(const QPoint &pos)
158 void startDrawingRect(const QPoint& pos)
156 {
159 {
157 removeDrawingRect();
160 removeDrawingRect();
158
161
159 auto axisPos = posToAxisPos(pos);
162 auto axisPos = posToAxisPos(pos);
160
163
161 m_DrawingZoomRect = new QCPItemRect{m_plot};
164 m_DrawingZoomRect = new QCPItemRect { m_plot };
162 QPen p;
165 QPen p;
163 p.setWidth(2);
166 p.setWidth(2);
164 m_DrawingZoomRect->setPen(p);
167 m_DrawingZoomRect->setPen(p);
@@ -169,39 +172,44 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
169
172
170 void removeDrawingRect()
173 void removeDrawingRect()
171 {
174 {
172 if (m_DrawingZoomRect) {
175 if (m_DrawingZoomRect)
176 {
173 m_plot->removeItem(m_DrawingZoomRect); // the item is deleted by QCustomPlot
177 m_plot->removeItem(m_DrawingZoomRect); // the item is deleted by QCustomPlot
174 m_DrawingZoomRect = nullptr;
178 m_DrawingZoomRect = nullptr;
175 m_plot->replot(QCustomPlot::rpQueuedReplot);
179 m_plot->replot(QCustomPlot::rpQueuedReplot);
176 }
180 }
177 }
181 }
178
182
179 void selectZone(const QPoint &pos)
183 void selectZone(const QPoint& pos)
180 {
184 {
181 auto zoneAtPos = selectionZoneAt(pos);
185 auto zoneAtPos = selectionZoneAt(pos);
182 setSelectionZonesEditionEnabled(sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones);
186 setSelectionZonesEditionEnabled(
187 sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones);
183 }
188 }
184
189
185 void startDrawingZone(const QPoint &pos)
190 void startDrawingZone(const QPoint& pos)
186 {
191 {
187 endDrawingZone();
192 endDrawingZone();
188
193
189 auto axisPos = posToAxisPos(pos);
194 auto axisPos = posToAxisPos(pos);
190
195
191 m_DrawingZone = new VisualizationSelectionZoneItem{m_plot};
196 m_DrawingZone = new VisualizationSelectionZoneItem { m_plot };
192 m_DrawingZone->setRange(axisPos.x(), axisPos.x());
197 m_DrawingZone->setRange(axisPos.x(), axisPos.x());
193 m_DrawingZone->setEditionEnabled(false);
198 m_DrawingZone->setEditionEnabled(false);
194 }
199 }
195
200
196 void endDrawingZone()
201 void endDrawingZone()
197 {
202 {
198 if (m_DrawingZone) {
203 if (m_DrawingZone)
204 {
199 auto drawingZoneRange = m_DrawingZone->range();
205 auto drawingZoneRange = m_DrawingZone->range();
200 if (qAbs(drawingZoneRange.m_TEnd - drawingZoneRange.m_TStart) > 0) {
206 if (qAbs(drawingZoneRange.m_TEnd - drawingZoneRange.m_TStart) > 0)
207 {
201 m_DrawingZone->setEditionEnabled(true);
208 m_DrawingZone->setEditionEnabled(true);
202 addSelectionZone(m_DrawingZone);
209 addSelectionZone(m_DrawingZone);
203 }
210 }
204 else {
211 else
212 {
205 m_plot->removeItem(m_DrawingZone);
213 m_plot->removeItem(m_DrawingZone);
206 }
214 }
207
215
@@ -217,26 +225,29 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
217 * @TODO implement this, the difficulty is that selection zones have their own
225 * @TODO implement this, the difficulty is that selection zones have their own
218 * event handling code which seems to rely on QCP GUI event handling propagation
226 * event handling code which seems to rely on QCP GUI event handling propagation
219 * which was a realy bad design choice.
227 * which was a realy bad design choice.
220 */
228 */
221 }
229 }
222
230
223 void setSelectionZonesEditionEnabled(bool value)
231 void setSelectionZonesEditionEnabled(bool value)
224 {
232 {
225 for (auto s : m_SelectionZones) {
233 for (auto s : m_SelectionZones)
234 {
226 s->setEditionEnabled(value);
235 s->setEditionEnabled(value);
227 }
236 }
228 }
237 }
229
238
230 void addSelectionZone(VisualizationSelectionZoneItem *zone) { m_SelectionZones << zone; }
239 void addSelectionZone(VisualizationSelectionZoneItem* zone) { m_SelectionZones << zone; }
231
240
232 VisualizationSelectionZoneItem *selectionZoneAt(const QPoint &pos) const
241 VisualizationSelectionZoneItem* selectionZoneAt(const QPoint& pos) const
233 {
242 {
234 VisualizationSelectionZoneItem *selectionZoneItemUnderCursor = nullptr;
243 VisualizationSelectionZoneItem* selectionZoneItemUnderCursor = nullptr;
235 auto minDistanceToZone = -1;
244 auto minDistanceToZone = -1;
236 for (auto zone : m_SelectionZones) {
245 for (auto zone : m_SelectionZones)
246 {
237 auto distanceToZone = zone->selectTest(pos, false);
247 auto distanceToZone = zone->selectTest(pos, false);
238 if ((minDistanceToZone < 0 || distanceToZone <= minDistanceToZone)
248 if ((minDistanceToZone < 0 || distanceToZone <= minDistanceToZone)
239 && distanceToZone >= 0 && distanceToZone < m_plot->selectionTolerance()) {
249 && distanceToZone >= 0 && distanceToZone < m_plot->selectionTolerance())
250 {
240 selectionZoneItemUnderCursor = zone;
251 selectionZoneItemUnderCursor = zone;
241 }
252 }
242 }
253 }
@@ -244,13 +255,15 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
244 return selectionZoneItemUnderCursor;
255 return selectionZoneItemUnderCursor;
245 }
256 }
246
257
247 QVector<VisualizationSelectionZoneItem *> selectionZonesAt(const QPoint &pos,
258 QVector<VisualizationSelectionZoneItem*> selectionZonesAt(
248 const QCustomPlot &plot) const
259 const QPoint& pos, const QCustomPlot& plot) const
249 {
260 {
250 QVector<VisualizationSelectionZoneItem *> zones;
261 QVector<VisualizationSelectionZoneItem*> zones;
251 for (auto zone : m_SelectionZones) {
262 for (auto zone : m_SelectionZones)
263 {
252 auto distanceToZone = zone->selectTest(pos, false);
264 auto distanceToZone = zone->selectTest(pos, false);
253 if (distanceToZone >= 0 && distanceToZone < plot.selectionTolerance()) {
265 if (distanceToZone >= 0 && distanceToZone < plot.selectionTolerance())
266 {
254 zones << zone;
267 zones << zone;
255 }
268 }
256 }
269 }
@@ -258,50 +271,50 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
258 return zones;
271 return zones;
259 }
272 }
260
273
261 void moveSelectionZoneOnTop(VisualizationSelectionZoneItem *zone, QCustomPlot &plot)
274 void moveSelectionZoneOnTop(VisualizationSelectionZoneItem* zone, QCustomPlot& plot)
262 {
275 {
263 if (!m_SelectionZones.isEmpty() && m_SelectionZones.last() != zone) {
276 if (!m_SelectionZones.isEmpty() && m_SelectionZones.last() != zone)
277 {
264 zone->moveToTop();
278 zone->moveToTop();
265 m_SelectionZones.removeAll(zone);
279 m_SelectionZones.removeAll(zone);
266 m_SelectionZones.append(zone);
280 m_SelectionZones.append(zone);
267 }
281 }
268 }
282 }
269
283
270 QPointF posToAxisPos(const QPoint &pos) const
284 QPointF posToAxisPos(const QPoint& pos) const
271 {
285 {
272 auto axisX = m_plot->axisRect()->axis(QCPAxis::atBottom);
286 auto axisX = m_plot->axisRect()->axis(QCPAxis::atBottom);
273 auto axisY = m_plot->axisRect()->axis(QCPAxis::atLeft);
287 auto axisY = m_plot->axisRect()->axis(QCPAxis::atLeft);
274 return QPointF{axisX->pixelToCoord(pos.x()), axisY->pixelToCoord(pos.y())};
288 return QPointF { axisX->pixelToCoord(pos.x()), axisY->pixelToCoord(pos.y()) };
275 }
289 }
276
290
277 bool pointIsInAxisRect(const QPointF &axisPoint, QCustomPlot &plot) const
291 bool pointIsInAxisRect(const QPointF& axisPoint, QCustomPlot& plot) const
278 {
292 {
279 auto axisX = plot.axisRect()->axis(QCPAxis::atBottom);
293 auto axisX = plot.axisRect()->axis(QCPAxis::atBottom);
280 auto axisY = plot.axisRect()->axis(QCPAxis::atLeft);
294 auto axisY = plot.axisRect()->axis(QCPAxis::atLeft);
281 return axisX->range().contains(axisPoint.x()) && axisY->range().contains(axisPoint.y());
295 return axisX->range().contains(axisPoint.x()) && axisY->range().contains(axisPoint.y());
282 }
296 }
283
297
284 inline QCPRange _pixDistanceToRange(double pos1, double pos2, QCPAxis *axis)
298 inline QCPRange _pixDistanceToRange(double pos1, double pos2, QCPAxis* axis)
285 {
299 {
286 if (axis->scaleType() == QCPAxis::stLinear)
300 if (axis->scaleType() == QCPAxis::stLinear)
287 {
301 {
288 auto diff = axis->pixelToCoord(pos1) - axis->pixelToCoord(pos2);
302 auto diff = axis->pixelToCoord(pos1) - axis->pixelToCoord(pos2);
289 return QCPRange{axis->range().lower + diff, axis->range().upper + diff};
303 return QCPRange { axis->range().lower + diff, axis->range().upper + diff };
290 }
304 }
291 else
305 else
292 {
306 {
293 auto diff = axis->pixelToCoord(pos1) / axis->pixelToCoord(pos2);
307 auto diff = axis->pixelToCoord(pos1) / axis->pixelToCoord(pos2);
294 return QCPRange{axis->range().lower * diff, axis->range().upper * diff};
308 return QCPRange { axis->range().lower * diff, axis->range().upper * diff };
295 }
309 }
296 }
310 }
297
311
298 void setRange(const DateTimeRange &newRange, bool updateVar=true)
312 void setRange(const DateTimeRange& newRange, bool updateVar = true)
299 {
313 {
300 this->m_plot->xAxis->setRange(newRange.m_TStart, newRange.m_TEnd);
314 this->m_plot->xAxis->setRange(newRange.m_TStart, newRange.m_TEnd);
301 if(updateVar)
315 if (updateVar)
302 {
316 {
303 for (auto it = m_VariableToPlotMultiMap.begin(),
317 for (auto it = m_VariableToPlotMultiMap.begin(), end = m_VariableToPlotMultiMap.end();
304 end = m_VariableToPlotMultiMap.end();
305 it != end; it = m_VariableToPlotMultiMap.upper_bound(it->first))
318 it != end; it = m_VariableToPlotMultiMap.upper_bound(it->first))
306 {
319 {
307 sqpApp->variableController().asyncChangeRange(it->first, newRange);
320 sqpApp->variableController().asyncChangeRange(it->first, newRange);
@@ -310,18 +323,15 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
310 m_plot->replot(QCustomPlot::rpQueuedReplot);
323 m_plot->replot(QCustomPlot::rpQueuedReplot);
311 }
324 }
312
325
313 void setRange(const QCPRange &newRange)
326 void setRange(const QCPRange& newRange)
314 {
327 {
315 auto graphRange = DateTimeRange{newRange.lower, newRange.upper};
328 auto graphRange = DateTimeRange { newRange.lower, newRange.upper };
316 setRange(graphRange);
329 setRange(graphRange);
317 }
330 }
318
331
319 void rescaleY()
332 void rescaleY() { m_plot->yAxis->rescale(true); }
320 {
321 m_plot->yAxis->rescale(true);
322 }
323
333
324 std::tuple<double,double> moveGraph(const QPoint& destination)
334 std::tuple<double, double> moveGraph(const QPoint& destination)
325 {
335 {
326 auto currentPos = m_plot->mapFromParent(destination);
336 auto currentPos = m_plot->mapFromParent(destination);
327 auto xAxis = m_plot->axisRect()->rangeDragAxis(Qt::Horizontal);
337 auto xAxis = m_plot->axisRect()->rangeDragAxis(Qt::Horizontal);
@@ -329,37 +339,39 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
329 auto oldXRange = xAxis->range();
339 auto oldXRange = xAxis->range();
330 auto oldYRange = yAxis->range();
340 auto oldYRange = yAxis->range();
331 double dx = xAxis->pixelToCoord(m_lastMousePos.x()) - xAxis->pixelToCoord(currentPos.x());
341 double dx = xAxis->pixelToCoord(m_lastMousePos.x()) - xAxis->pixelToCoord(currentPos.x());
332 xAxis->setRange(m_lastXRange.lower+dx, m_lastXRange.upper+dx);
342 xAxis->setRange(m_lastXRange.lower + dx, m_lastXRange.upper + dx);
333 if(yAxis->scaleType() == QCPAxis::stLinear)
343 if (yAxis->scaleType() == QCPAxis::stLinear)
334 {
344 {
335 double dy = yAxis->pixelToCoord(m_lastMousePos.y()) - yAxis->pixelToCoord(currentPos.y());
345 double dy
336 yAxis->setRange(m_lastYRange.lower+dy, m_lastYRange.upper+dy);
346 = yAxis->pixelToCoord(m_lastMousePos.y()) - yAxis->pixelToCoord(currentPos.y());
347 yAxis->setRange(m_lastYRange.lower + dy, m_lastYRange.upper + dy);
337 }
348 }
338 else
349 else
339 {
350 {
340 double dy = yAxis->pixelToCoord(m_lastMousePos.y()) / yAxis->pixelToCoord(currentPos.y());
351 double dy
341 yAxis->setRange(m_lastYRange.lower*dy, m_lastYRange.upper*dy);
352 = yAxis->pixelToCoord(m_lastMousePos.y()) / yAxis->pixelToCoord(currentPos.y());
353 yAxis->setRange(m_lastYRange.lower * dy, m_lastYRange.upper * dy);
342 }
354 }
343 auto newXRange = xAxis->range();
355 auto newXRange = xAxis->range();
344 auto newYRange = yAxis->range();
356 auto newYRange = yAxis->range();
345 setRange(xAxis->range());
357 setRange(xAxis->range());
346 //m_lastMousePos = currentPos;
358 // m_lastMousePos = currentPos;
347 return {newXRange.lower - oldXRange.lower, newYRange.lower - oldYRange.lower};
359 return { newXRange.lower - oldXRange.lower, newYRange.lower - oldYRange.lower };
348 }
360 }
349
361
350 void zoom(double factor, int center, Qt::Orientation orientation)
362 void zoom(double factor, int center, Qt::Orientation orientation)
351 {
363 {
352 QCPAxis *axis = m_plot->axisRect()->rangeZoomAxis(orientation);
364 QCPAxis* axis = m_plot->axisRect()->rangeZoomAxis(orientation);
353 axis->scaleRange(factor, axis->pixelToCoord(center));
365 axis->scaleRange(factor, axis->pixelToCoord(center));
354 if (orientation == Qt::Horizontal)
366 if (orientation == Qt::Horizontal)
355 setRange(axis->range());
367 setRange(axis->range());
356 m_plot->replot(QCustomPlot::rpQueuedReplot);
368 m_plot->replot(QCustomPlot::rpQueuedReplot);
357 }
369 }
358
370
359 void transform(const DateTimeRangeTransformation &tranformation)
371 void transform(const DateTimeRangeTransformation& tranformation)
360 {
372 {
361 auto graphRange = m_plot->xAxis->range();
373 auto graphRange = m_plot->xAxis->range();
362 DateTimeRange range{graphRange.lower, graphRange.upper};
374 DateTimeRange range { graphRange.lower, graphRange.upper };
363 range = range.transform(tranformation);
375 range = range.transform(tranformation);
364 setRange(range);
376 setRange(range);
365 m_plot->replot(QCustomPlot::rpQueuedReplot);
377 m_plot->replot(QCustomPlot::rpQueuedReplot);
@@ -369,8 +381,8 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
369 {
381 {
370 auto xAxis = m_plot->axisRect()->rangeDragAxis(Qt::Horizontal);
382 auto xAxis = m_plot->axisRect()->rangeDragAxis(Qt::Horizontal);
371 auto yAxis = m_plot->axisRect()->rangeDragAxis(Qt::Vertical);
383 auto yAxis = m_plot->axisRect()->rangeDragAxis(Qt::Vertical);
372 xAxis->setRange(QCPRange(xAxis->range().lower+dx, xAxis->range().upper+dx));
384 xAxis->setRange(QCPRange(xAxis->range().lower + dx, xAxis->range().upper + dx));
373 yAxis->setRange(QCPRange(yAxis->range().lower+dy, yAxis->range().upper+dy));
385 yAxis->setRange(QCPRange(yAxis->range().lower + dy, yAxis->range().upper + dy));
374 setRange(xAxis->range());
386 setRange(xAxis->range());
375 m_plot->replot(QCustomPlot::rpQueuedReplot);
387 m_plot->replot(QCustomPlot::rpQueuedReplot);
376 }
388 }
@@ -378,26 +390,30 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
378 void move(double factor, Qt::Orientation orientation)
390 void move(double factor, Qt::Orientation orientation)
379 {
391 {
380 auto oldRange = m_plot->xAxis->range();
392 auto oldRange = m_plot->xAxis->range();
381 QCPAxis *axis = m_plot->axisRect()->rangeDragAxis(orientation);
393 QCPAxis* axis = m_plot->axisRect()->rangeDragAxis(orientation);
382 if (m_plot->xAxis->scaleType() == QCPAxis::stLinear) {
394 if (m_plot->xAxis->scaleType() == QCPAxis::stLinear)
395 {
383 double rg = (axis->range().upper - axis->range().lower) * (factor / 10);
396 double rg = (axis->range().upper - axis->range().lower) * (factor / 10);
384 axis->setRange(axis->range().lower + (rg), axis->range().upper + (rg));
397 axis->setRange(axis->range().lower + (rg), axis->range().upper + (rg));
385 }
398 }
386 else if (m_plot->xAxis->scaleType() == QCPAxis::stLogarithmic) {
399 else if (m_plot->xAxis->scaleType() == QCPAxis::stLogarithmic)
400 {
387 int start = 0, stop = 0;
401 int start = 0, stop = 0;
388 double diff = 0.;
402 double diff = 0.;
389 if (factor > 0.0) {
403 if (factor > 0.0)
404 {
390 stop = m_plot->width() * factor / 10;
405 stop = m_plot->width() * factor / 10;
391 start = 2 * m_plot->width() * factor / 10;
406 start = 2 * m_plot->width() * factor / 10;
392 }
407 }
393 if (factor < 0.0) {
408 if (factor < 0.0)
409 {
394 factor *= -1.0;
410 factor *= -1.0;
395 start = m_plot->width() * factor / 10;
411 start = m_plot->width() * factor / 10;
396 stop = 2 * m_plot->width() * factor / 10;
412 stop = 2 * m_plot->width() * factor / 10;
397 }
413 }
398 diff = axis->pixelToCoord(start) / axis->pixelToCoord(stop);
414 diff = axis->pixelToCoord(start) / axis->pixelToCoord(stop);
399 axis->setRange(m_plot->axisRect()->rangeDragAxis(orientation)->range().lower * diff,
415 axis->setRange(m_plot->axisRect()->rangeDragAxis(orientation)->range().lower * diff,
400 m_plot->axisRect()->rangeDragAxis(orientation)->range().upper * diff);
416 m_plot->axisRect()->rangeDragAxis(orientation)->range().upper * diff);
401 }
417 }
402 if (orientation == Qt::Horizontal)
418 if (orientation == Qt::Horizontal)
403 setRange(axis->range());
419 setRange(axis->range());
@@ -405,10 +421,10 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
405 }
421 }
406 };
422 };
407
423
408 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
424 VisualizationGraphWidget::VisualizationGraphWidget(const QString& name, QWidget* parent)
409 : VisualizationDragWidget{parent},
425 : VisualizationDragWidget { parent }
410 ui{new Ui::VisualizationGraphWidget},
426 , ui { new Ui::VisualizationGraphWidget }
411 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
427 , impl { spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name) }
412 {
428 {
413 ui->setupUi(this);
429 ui->setupUi(this);
414 this->layout()->addWidget(impl->m_plot);
430 this->layout()->addWidget(impl->m_plot);
@@ -430,7 +446,8 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget
430 impl->m_plot->setContextMenuPolicy(Qt::CustomContextMenu);
446 impl->m_plot->setContextMenuPolicy(Qt::CustomContextMenu);
431 impl->m_plot->setParent(this);
447 impl->m_plot->setParent(this);
432
448
433 connect(&sqpApp->variableController(), &VariableController2::variableDeleted, this, &VisualizationGraphWidget::variableDeleted);
449 connect(&sqpApp->variableController(), &VariableController2::variableDeleted, this,
450 &VisualizationGraphWidget::variableDeleted);
434 }
451 }
435
452
436
453
@@ -439,24 +456,26 VisualizationGraphWidget::~VisualizationGraphWidget()
439 delete ui;
456 delete ui;
440 }
457 }
441
458
442 VisualizationZoneWidget *VisualizationGraphWidget::parentZoneWidget() const noexcept
459 VisualizationZoneWidget* VisualizationGraphWidget::parentZoneWidget() const noexcept
443 {
460 {
444 auto parent = parentWidget();
461 auto parent = parentWidget();
445 while (parent != nullptr && !qobject_cast<VisualizationZoneWidget *>(parent)) {
462 while (parent != nullptr && !qobject_cast<VisualizationZoneWidget*>(parent))
463 {
446 parent = parent->parentWidget();
464 parent = parent->parentWidget();
447 }
465 }
448
466
449 return qobject_cast<VisualizationZoneWidget *>(parent);
467 return qobject_cast<VisualizationZoneWidget*>(parent);
450 }
468 }
451
469
452 VisualizationWidget *VisualizationGraphWidget::parentVisualizationWidget() const
470 VisualizationWidget* VisualizationGraphWidget::parentVisualizationWidget() const
453 {
471 {
454 auto parent = parentWidget();
472 auto parent = parentWidget();
455 while (parent != nullptr && !qobject_cast<VisualizationWidget *>(parent)) {
473 while (parent != nullptr && !qobject_cast<VisualizationWidget*>(parent))
474 {
456 parent = parent->parentWidget();
475 parent = parent->parentWidget();
457 }
476 }
458
477
459 return qobject_cast<VisualizationWidget *>(parent);
478 return qobject_cast<VisualizationWidget*>(parent);
460 }
479 }
461
480
462 void VisualizationGraphWidget::setFlags(GraphFlags flags)
481 void VisualizationGraphWidget::setFlags(GraphFlags flags)
@@ -464,7 +483,7 void VisualizationGraphWidget::setFlags(GraphFlags flags)
464 impl->m_Flags = std::move(flags);
483 impl->m_Flags = std::move(flags);
465 }
484 }
466
485
467 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, DateTimeRange range)
486 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable2> variable, DateTimeRange range)
468 {
487 {
469 // Uses delegate to create the qcpplot components according to the variable
488 // Uses delegate to create the qcpplot components according to the variable
470 auto createdPlottables = VisualizationGraphHelper::create(variable, *impl->m_plot);
489 auto createdPlottables = VisualizationGraphHelper::create(variable, *impl->m_plot);
@@ -472,45 +491,46 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, D
472 // Sets graph properties
491 // Sets graph properties
473 impl->m_RenderingDelegate->setGraphProperties(*variable, createdPlottables);
492 impl->m_RenderingDelegate->setGraphProperties(*variable, createdPlottables);
474
493
475 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
494 impl->m_VariableToPlotMultiMap.insert({ variable, std::move(createdPlottables) });
476
495
477 setGraphRange(range);
496 setGraphRange(range);
478 // If the variable already has its data loaded, load its units and its range in the graph
497 // If the variable already has its data loaded, load its units and its range in the graph
479 if (variable->dataSeries() != nullptr) {
498 if (variable->data() != nullptr)
499 {
480 impl->m_RenderingDelegate->setAxesUnits(*variable);
500 impl->m_RenderingDelegate->setAxesUnits(*variable);
481 }
501 }
482 else
502 else
483 {
503 {
484 auto context = new QObject{this};
504 auto context = new QObject { this };
485 connect(variable.get(), &Variable::updated, context,
505 connect(
486 [this, variable, context, range](QUuid)
506 variable.get(), &Variable2::updated, context, [this, variable, context, range](QUuid) {
487 {
507 this->impl->m_RenderingDelegate->setAxesUnits(*variable);
488 this->impl->m_RenderingDelegate->setAxesUnits(*variable);
508 this->impl->m_plot->replot(QCustomPlot::rpQueuedReplot);
489 this->impl->m_plot->replot(QCustomPlot::rpQueuedReplot);
509 delete context;
490 delete context;
510 });
491 }
492 );
493 }
511 }
494 //@TODO this is bad! when variable is moved to another graph it still fires
512 //@TODO this is bad! when variable is moved to another graph it still fires
495 // even if this has been deleted
513 // even if this has been deleted
496 connect(variable.get(), &Variable::updated, this, &VisualizationGraphWidget::variableUpdated);
514 connect(variable.get(), &Variable2::updated, this, &VisualizationGraphWidget::variableUpdated);
497 this->onUpdateVarDisplaying(variable, range); // My bullshit
515 this->onUpdateVarDisplaying(variable, range); // My bullshit
498 emit variableAdded(variable);
516 emit variableAdded(variable);
499 }
517 }
500
518
501 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
519 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable2> variable) noexcept
502 {
520 {
503 // Each component associated to the variable :
521 // Each component associated to the variable :
504 // - is removed from qcpplot (which deletes it)
522 // - is removed from qcpplot (which deletes it)
505 // - is no longer referenced in the map
523 // - is no longer referenced in the map
506 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
524 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
507 if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
525 if (variableIt != impl->m_VariableToPlotMultiMap.cend())
526 {
508 emit variableAboutToBeRemoved(variable);
527 emit variableAboutToBeRemoved(variable);
509
528
510 auto &plottablesMap = variableIt->second;
529 auto& plottablesMap = variableIt->second;
511
530
512 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
531 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
513 plottableIt != plottableEnd;) {
532 plottableIt != plottableEnd;)
533 {
514 impl->m_plot->removePlottable(plottableIt->second);
534 impl->m_plot->removePlottable(plottableIt->second);
515 plottableIt = plottablesMap.erase(plottableIt);
535 plottableIt = plottablesMap.erase(plottableIt);
516 }
536 }
@@ -522,20 +542,22 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable
522 impl->m_plot->replot(QCustomPlot::rpQueuedReplot);
542 impl->m_plot->replot(QCustomPlot::rpQueuedReplot);
523 }
543 }
524
544
525 std::vector<std::shared_ptr<Variable> > VisualizationGraphWidget::variables() const
545 std::vector<std::shared_ptr<Variable2>> VisualizationGraphWidget::variables() const
526 {
546 {
527 auto variables = std::vector<std::shared_ptr<Variable> >{};
547 auto variables = std::vector<std::shared_ptr<Variable2>> {};
528 for (auto it = std::cbegin(impl->m_VariableToPlotMultiMap);
548 for (auto it = std::cbegin(impl->m_VariableToPlotMultiMap);
529 it != std::cend(impl->m_VariableToPlotMultiMap); ++it) {
549 it != std::cend(impl->m_VariableToPlotMultiMap); ++it)
550 {
530 variables.push_back(it->first);
551 variables.push_back(it->first);
531 }
552 }
532
553
533 return variables;
554 return variables;
534 }
555 }
535
556
536 void VisualizationGraphWidget::setYRange(std::shared_ptr<Variable> variable)
557 void VisualizationGraphWidget::setYRange(std::shared_ptr<Variable2> variable)
537 {
558 {
538 if (!variable) {
559 if (!variable)
560 {
539 qCCritical(LOG_VisualizationGraphWidget()) << "Can't set y-axis range: variable is null";
561 qCCritical(LOG_VisualizationGraphWidget()) << "Can't set y-axis range: variable is null";
540 return;
562 return;
541 }
563 }
@@ -546,17 +568,17 void VisualizationGraphWidget::setYRange(std::shared_ptr<Variable> variable)
546 DateTimeRange VisualizationGraphWidget::graphRange() const noexcept
568 DateTimeRange VisualizationGraphWidget::graphRange() const noexcept
547 {
569 {
548 auto graphRange = impl->m_plot->xAxis->range();
570 auto graphRange = impl->m_plot->xAxis->range();
549 return DateTimeRange{graphRange.lower, graphRange.upper};
571 return DateTimeRange { graphRange.lower, graphRange.upper };
550 }
572 }
551
573
552 void VisualizationGraphWidget::setGraphRange(const DateTimeRange &range, bool updateVar, bool forward)
574 void VisualizationGraphWidget::setGraphRange(
575 const DateTimeRange& range, bool updateVar, bool forward)
553 {
576 {
554 impl->setRange(range, updateVar);
577 impl->setRange(range, updateVar);
555 if(forward)
578 if (forward)
556 {
579 {
557 emit this->setrange_sig(this->graphRange(), true, false);
580 emit this->setrange_sig(this->graphRange(), true, false);
558 }
581 }
559
560 }
582 }
561
583
562 void VisualizationGraphWidget::setAutoRangeOnVariableInitialization(bool value)
584 void VisualizationGraphWidget::setAutoRangeOnVariableInitialization(bool value)
@@ -567,16 +589,18 void VisualizationGraphWidget::setAutoRangeOnVariableInitialization(bool value)
567 QVector<DateTimeRange> VisualizationGraphWidget::selectionZoneRanges() const
589 QVector<DateTimeRange> VisualizationGraphWidget::selectionZoneRanges() const
568 {
590 {
569 QVector<DateTimeRange> ranges;
591 QVector<DateTimeRange> ranges;
570 for (auto zone : impl->m_SelectionZones) {
592 for (auto zone : impl->m_SelectionZones)
593 {
571 ranges << zone->range();
594 ranges << zone->range();
572 }
595 }
573
596
574 return ranges;
597 return ranges;
575 }
598 }
576
599
577 void VisualizationGraphWidget::addSelectionZones(const QVector<DateTimeRange> &ranges)
600 void VisualizationGraphWidget::addSelectionZones(const QVector<DateTimeRange>& ranges)
578 {
601 {
579 for (const auto &range : ranges) {
602 for (const auto& range : ranges)
603 {
580 // note: ownership is transfered to QCustomPlot
604 // note: ownership is transfered to QCustomPlot
581 auto zone = new VisualizationSelectionZoneItem(&plot());
605 auto zone = new VisualizationSelectionZoneItem(&plot());
582 zone->setRange(range.m_TStart, range.m_TEnd);
606 zone->setRange(range.m_TStart, range.m_TEnd);
@@ -586,8 +610,8 void VisualizationGraphWidget::addSelectionZones(const QVector<DateTimeRange> &r
586 plot().replot(QCustomPlot::rpQueuedReplot);
610 plot().replot(QCustomPlot::rpQueuedReplot);
587 }
611 }
588
612
589 VisualizationSelectionZoneItem *
613 VisualizationSelectionZoneItem* VisualizationGraphWidget::addSelectionZone(
590 VisualizationGraphWidget::addSelectionZone(const QString &name, const DateTimeRange &range)
614 const QString& name, const DateTimeRange& range)
591 {
615 {
592 // note: ownership is transfered to QCustomPlot
616 // note: ownership is transfered to QCustomPlot
593 auto zone = new VisualizationSelectionZoneItem(&plot());
617 auto zone = new VisualizationSelectionZoneItem(&plot());
@@ -600,11 +624,12 VisualizationGraphWidget::addSelectionZone(const QString &name, const DateTimeRa
600 return zone;
624 return zone;
601 }
625 }
602
626
603 void VisualizationGraphWidget::removeSelectionZone(VisualizationSelectionZoneItem *selectionZone)
627 void VisualizationGraphWidget::removeSelectionZone(VisualizationSelectionZoneItem* selectionZone)
604 {
628 {
605 parentVisualizationWidget()->selectionZoneManager().setSelected(selectionZone, false);
629 parentVisualizationWidget()->selectionZoneManager().setSelected(selectionZone, false);
606
630
607 if (impl->m_HoveredZone == selectionZone) {
631 if (impl->m_HoveredZone == selectionZone)
632 {
608 impl->m_HoveredZone = nullptr;
633 impl->m_HoveredZone = nullptr;
609 setCursor(Qt::ArrowCursor);
634 setCursor(Qt::ArrowCursor);
610 }
635 }
@@ -626,66 +651,69 void VisualizationGraphWidget::undoZoom()
626 plot().replot(QCustomPlot::rpQueuedReplot);
651 plot().replot(QCustomPlot::rpQueuedReplot);
627 }
652 }
628
653
629 void VisualizationGraphWidget::zoom(double factor, int center, Qt::Orientation orientation, bool forward)
654 void VisualizationGraphWidget::zoom(
655 double factor, int center, Qt::Orientation orientation, bool forward)
630 {
656 {
631 impl->zoom(factor, center, orientation);
657 impl->zoom(factor, center, orientation);
632 if(forward && orientation==Qt::Horizontal)
658 if (forward && orientation == Qt::Horizontal)
633 emit this->setrange_sig(this->graphRange(), true, false);
659 emit this->setrange_sig(this->graphRange(), true, false);
634 }
660 }
635
661
636 void VisualizationGraphWidget::move(double factor, Qt::Orientation orientation, bool forward)
662 void VisualizationGraphWidget::move(double factor, Qt::Orientation orientation, bool forward)
637 {
663 {
638 impl->move(factor, orientation);
664 impl->move(factor, orientation);
639 if(forward)
665 if (forward)
640 emit this->setrange_sig(this->graphRange(), true, false);
666 emit this->setrange_sig(this->graphRange(), true, false);
641 }
667 }
642
668
643 void VisualizationGraphWidget::move(double dx, double dy, bool forward)
669 void VisualizationGraphWidget::move(double dx, double dy, bool forward)
644 {
670 {
645 impl->move(dx, dy);
671 impl->move(dx, dy);
646 if(forward)
672 if (forward)
647 emit this->setrange_sig(this->graphRange(), true, false);
673 emit this->setrange_sig(this->graphRange(), true, false);
648 }
674 }
649
675
650 void VisualizationGraphWidget::transform(const DateTimeRangeTransformation &tranformation, bool forward)
676 void VisualizationGraphWidget::transform(
677 const DateTimeRangeTransformation& tranformation, bool forward)
651 {
678 {
652 impl->transform(tranformation);
679 impl->transform(tranformation);
653 if(forward)
680 if (forward)
654 emit this->setrange_sig(this->graphRange(), true, false);
681 emit this->setrange_sig(this->graphRange(), true, false);
655 }
682 }
656
683
657 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
684 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor* visitor)
658 {
685 {
659 if (visitor) {
686 if (visitor)
687 {
660 visitor->visit(this);
688 visitor->visit(this);
661 }
689 }
662 else {
690 else
691 {
663 qCCritical(LOG_VisualizationGraphWidget())
692 qCCritical(LOG_VisualizationGraphWidget())
664 << tr("Can't visit widget : the visitor is null");
693 << tr("Can't visit widget : the visitor is null");
665 }
694 }
666 }
695 }
667
696
668 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
697 bool VisualizationGraphWidget::canDrop(Variable2& variable) const
669 {
698 {
670 auto isSpectrogram = [](const auto &variable) {
699 auto isSpectrogram
671 return std::dynamic_pointer_cast<SpectrogramSeries>(variable.dataSeries()) != nullptr;
700 = [](auto& variable) { return variable.type() == DataSeriesType::SPECTROGRAM; };
672 };
673
701
674 // - A spectrogram series can't be dropped on graph with existing plottables
702 // - A spectrogram series can't be dropped on graph with existing plottables
675 // - No data series can be dropped on graph with existing spectrogram series
703 // - No data series can be dropped on graph with existing spectrogram series
676 return isSpectrogram(variable)
704 return isSpectrogram(variable)
677 ? impl->m_VariableToPlotMultiMap.empty()
705 ? impl->m_VariableToPlotMultiMap.empty()
678 : std::none_of(
706 : std::none_of(impl->m_VariableToPlotMultiMap.cbegin(),
679 impl->m_VariableToPlotMultiMap.cbegin(), impl->m_VariableToPlotMultiMap.cend(),
707 impl->m_VariableToPlotMultiMap.cend(),
680 [isSpectrogram](const auto &entry) { return isSpectrogram(*entry.first); });
708 [isSpectrogram](const auto& entry) { return isSpectrogram(*entry.first); });
681 }
709 }
682
710
683 bool VisualizationGraphWidget::contains(const Variable &variable) const
711 bool VisualizationGraphWidget::contains(Variable2& variable) const
684 {
712 {
685 // Finds the variable among the keys of the map
713 // Finds the variable among the keys of the map
686 auto variablePtr = &variable;
714 auto variablePtr = &variable;
687 auto findVariable
715 auto findVariable
688 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
716 = [variablePtr](const auto& entry) { return variablePtr == entry.first.get(); };
689
717
690 auto end = impl->m_VariableToPlotMultiMap.cend();
718 auto end = impl->m_VariableToPlotMultiMap.cend();
691 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
719 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
@@ -697,20 +725,22 QString VisualizationGraphWidget::name() const
697 return impl->m_Name;
725 return impl->m_Name;
698 }
726 }
699
727
700 QMimeData *VisualizationGraphWidget::mimeData(const QPoint &position) const
728 QMimeData* VisualizationGraphWidget::mimeData(const QPoint& position) const
701 {
729 {
702 auto mimeData = new QMimeData;
730 auto mimeData = new QMimeData;
703
731
704 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(position);
732 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(position);
705 if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones
733 if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones
706 && selectionZoneItemUnderCursor) {
734 && selectionZoneItemUnderCursor)
707 mimeData->setData(MIME_TYPE_TIME_RANGE, TimeController::mimeDataForTimeRange(
735 {
708 selectionZoneItemUnderCursor->range()));
736 mimeData->setData(MIME_TYPE_TIME_RANGE,
709 mimeData->setData(MIME_TYPE_SELECTION_ZONE, TimeController::mimeDataForTimeRange(
737 TimeController::mimeDataForTimeRange(selectionZoneItemUnderCursor->range()));
710 selectionZoneItemUnderCursor->range()));
738 mimeData->setData(MIME_TYPE_SELECTION_ZONE,
739 TimeController::mimeDataForTimeRange(selectionZoneItemUnderCursor->range()));
711 }
740 }
712 else {
741 else
713 mimeData->setData(MIME_TYPE_GRAPH, QByteArray{});
742 {
743 mimeData->setData(MIME_TYPE_GRAPH, QByteArray {});
714
744
715 auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange());
745 auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange());
716 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
746 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
@@ -719,21 +749,22 QMimeData *VisualizationGraphWidget::mimeData(const QPoint &position) const
719 return mimeData;
749 return mimeData;
720 }
750 }
721
751
722 QPixmap VisualizationGraphWidget::customDragPixmap(const QPoint &dragPosition)
752 QPixmap VisualizationGraphWidget::customDragPixmap(const QPoint& dragPosition)
723 {
753 {
724 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(dragPosition);
754 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(dragPosition);
725 if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones
755 if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones
726 && selectionZoneItemUnderCursor) {
756 && selectionZoneItemUnderCursor)
757 {
727
758
728 auto zoneTopLeft = selectionZoneItemUnderCursor->topLeft->pixelPosition();
759 auto zoneTopLeft = selectionZoneItemUnderCursor->topLeft->pixelPosition();
729 auto zoneBottomRight = selectionZoneItemUnderCursor->bottomRight->pixelPosition();
760 auto zoneBottomRight = selectionZoneItemUnderCursor->bottomRight->pixelPosition();
730
761
731 auto zoneSize = QSizeF{qAbs(zoneBottomRight.x() - zoneTopLeft.x()),
762 auto zoneSize = QSizeF { qAbs(zoneBottomRight.x() - zoneTopLeft.x()),
732 qAbs(zoneBottomRight.y() - zoneTopLeft.y())}
763 qAbs(zoneBottomRight.y() - zoneTopLeft.y()) }
733 .toSize();
764 .toSize();
734
765
735 auto pixmap = QPixmap(zoneSize);
766 auto pixmap = QPixmap(zoneSize);
736 render(&pixmap, QPoint(), QRegion{QRect{zoneTopLeft.toPoint(), zoneSize}});
767 render(&pixmap, QPoint(), QRegion { QRect { zoneTopLeft.toPoint(), zoneSize } });
737
768
738 return pixmap;
769 return pixmap;
739 }
770 }
@@ -748,10 +779,12 bool VisualizationGraphWidget::isDragAllowed() const
748
779
749 void VisualizationGraphWidget::highlightForMerge(bool highlighted)
780 void VisualizationGraphWidget::highlightForMerge(bool highlighted)
750 {
781 {
751 if (highlighted) {
782 if (highlighted)
783 {
752 plot().setBackground(QBrush(QColor("#BBD5EE")));
784 plot().setBackground(QBrush(QColor("#BBD5EE")));
753 }
785 }
754 else {
786 else
787 {
755 plot().setBackground(QBrush(Qt::white));
788 plot().setBackground(QBrush(Qt::white));
756 }
789 }
757
790
@@ -807,49 +840,55 void VisualizationGraphWidget::removeHorizontalCursor()
807 plot().replot(QCustomPlot::rpQueuedReplot);
840 plot().replot(QCustomPlot::rpQueuedReplot);
808 }
841 }
809
842
810 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
843 void VisualizationGraphWidget::closeEvent(QCloseEvent* event)
811 {
844 {
812 Q_UNUSED(event);
845 Q_UNUSED(event);
813
846
814 for (auto i : impl->m_SelectionZones) {
847 for (auto i : impl->m_SelectionZones)
848 {
815 parentVisualizationWidget()->selectionZoneManager().setSelected(i, false);
849 parentVisualizationWidget()->selectionZoneManager().setSelected(i, false);
816 }
850 }
817
851
818 // Prevents that all variables will be removed from graph when it will be closed
852 // Prevents that all variables will be removed from graph when it will be closed
819 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
853 for (auto& variableEntry : impl->m_VariableToPlotMultiMap)
854 {
820 emit variableAboutToBeRemoved(variableEntry.first);
855 emit variableAboutToBeRemoved(variableEntry.first);
821 }
856 }
822 }
857 }
823
858
824 void VisualizationGraphWidget::enterEvent(QEvent *event)
859 void VisualizationGraphWidget::enterEvent(QEvent* event)
825 {
860 {
826 Q_UNUSED(event);
861 Q_UNUSED(event);
827 impl->m_RenderingDelegate->showGraphOverlay(true);
862 impl->m_RenderingDelegate->showGraphOverlay(true);
828 }
863 }
829
864
830 void VisualizationGraphWidget::leaveEvent(QEvent *event)
865 void VisualizationGraphWidget::leaveEvent(QEvent* event)
831 {
866 {
832 Q_UNUSED(event);
867 Q_UNUSED(event);
833 impl->m_RenderingDelegate->showGraphOverlay(false);
868 impl->m_RenderingDelegate->showGraphOverlay(false);
834
869
835 if (auto parentZone = parentZoneWidget()) {
870 if (auto parentZone = parentZoneWidget())
871 {
836 parentZone->notifyMouseLeaveGraph(this);
872 parentZone->notifyMouseLeaveGraph(this);
837 }
873 }
838 else {
874 else
875 {
839 qCWarning(LOG_VisualizationGraphWidget()) << "leaveEvent: No parent zone widget";
876 qCWarning(LOG_VisualizationGraphWidget()) << "leaveEvent: No parent zone widget";
840 }
877 }
841
878
842 if (impl->m_HoveredZone) {
879 if (impl->m_HoveredZone)
880 {
843 impl->m_HoveredZone->setHovered(false);
881 impl->m_HoveredZone->setHovered(false);
844 impl->m_HoveredZone = nullptr;
882 impl->m_HoveredZone = nullptr;
845 }
883 }
846 }
884 }
847
885
848 void VisualizationGraphWidget::wheelEvent(QWheelEvent *event)
886 void VisualizationGraphWidget::wheelEvent(QWheelEvent* event)
849 {
887 {
850 double factor;
888 double factor;
851 double wheelSteps = event->delta() / 120.0; // a single step delta is +/-120 usually
889 double wheelSteps = event->delta() / 120.0; // a single step delta is +/-120 usually
852 if (event->modifiers() == Qt::ControlModifier) {
890 if (event->modifiers() == Qt::ControlModifier)
891 {
853 if (event->orientation() == Qt::Vertical) // mRangeZoom.testFlag(Qt::Vertical))
892 if (event->orientation() == Qt::Vertical) // mRangeZoom.testFlag(Qt::Vertical))
854 {
893 {
855 setCursor(Qt::SizeVerCursor);
894 setCursor(Qt::SizeVerCursor);
@@ -857,7 +896,8 void VisualizationGraphWidget::wheelEvent(QWheelEvent *event)
857 zoom(factor, event->pos().y(), Qt::Vertical);
896 zoom(factor, event->pos().y(), Qt::Vertical);
858 }
897 }
859 }
898 }
860 else if (event->modifiers() == Qt::ShiftModifier) {
899 else if (event->modifiers() == Qt::ShiftModifier)
900 {
861 if (event->orientation() == Qt::Vertical) // mRangeZoom.testFlag(Qt::Vertical))
901 if (event->orientation() == Qt::Vertical) // mRangeZoom.testFlag(Qt::Vertical))
862 {
902 {
863 setCursor(Qt::SizeHorCursor);
903 setCursor(Qt::SizeHorCursor);
@@ -865,17 +905,17 void VisualizationGraphWidget::wheelEvent(QWheelEvent *event)
865 zoom(factor, event->pos().x(), Qt::Horizontal);
905 zoom(factor, event->pos().x(), Qt::Horizontal);
866 }
906 }
867 }
907 }
868 else {
908 else
909 {
869 move(wheelSteps, Qt::Horizontal);
910 move(wheelSteps, Qt::Horizontal);
870 }
911 }
871 event->accept();
912 event->accept();
872 }
913 }
873
914
874
915
875
916 void VisualizationGraphWidget::mouseMoveEvent(QMouseEvent* event)
876 void VisualizationGraphWidget::mouseMoveEvent(QMouseEvent *event)
877 {
917 {
878 if(impl->isDrawingZoomRect())
918 if (impl->isDrawingZoomRect())
879 {
919 {
880 impl->updateZoomRect(event->pos());
920 impl->updateZoomRect(event->pos());
881 }
921 }
@@ -885,45 +925,46 void VisualizationGraphWidget::mouseMoveEvent(QMouseEvent *event)
885 }
925 }
886 else if (event->buttons() == Qt::LeftButton)
926 else if (event->buttons() == Qt::LeftButton)
887 {
927 {
888 if(sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::None)
928 if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::None)
889 {
929 {
890 auto [dx,dy] = impl->moveGraph(event->pos());
930 auto [dx, dy] = impl->moveGraph(event->pos());
891 emit this->setrange_sig(this->graphRange(), true, false);
931 emit this->setrange_sig(this->graphRange(), true, false);
892 }
932 }
893 else if(sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones)
933 else if (sqpApp->plotsInteractionMode()
934 == SqpApplication::PlotsInteractionMode::SelectionZones)
894 {
935 {
895 auto posInPlot = this->impl->m_plot->mapFromParent(event->pos());
936 auto posInPlot = this->impl->m_plot->mapFromParent(event->pos());
896 if(auto item = impl->m_plot->itemAt(posInPlot))
937 if (auto item = impl->m_plot->itemAt(posInPlot))
897 {
938 {
898 if(qobject_cast<VisualizationSelectionZoneItem*>(item))
939 if (qobject_cast<VisualizationSelectionZoneItem*>(item))
899 {
940 {
900 QMouseEvent e{QEvent::MouseMove, posInPlot, event->button(),event->buttons(),event->modifiers()};
941 QMouseEvent e { QEvent::MouseMove, posInPlot, event->button(), event->buttons(),
942 event->modifiers() };
901 sqpApp->sendEvent(this->impl->m_plot, &e);
943 sqpApp->sendEvent(this->impl->m_plot, &e);
902 this->impl->m_plot->replot(QCustomPlot::rpImmediateRefresh);
944 this->impl->m_plot->replot(QCustomPlot::rpImmediateRefresh);
903 }
945 }
904 }
946 }
905
906 }
947 }
907 }
948 }
908 else
949 else
909 {
950 {
910 impl->m_RenderingDelegate->updateTooltip(event);
951 impl->m_RenderingDelegate->updateTooltip(event);
911 }
952 }
912 //event->accept();
953 // event->accept();
913 QWidget::mouseMoveEvent(event);
954 QWidget::mouseMoveEvent(event);
914 }
955 }
915
956
916 void VisualizationGraphWidget::mouseReleaseEvent(QMouseEvent *event)
957 void VisualizationGraphWidget::mouseReleaseEvent(QMouseEvent* event)
917 {
958 {
918 if(impl->isDrawingZoomRect())
959 if (impl->isDrawingZoomRect())
919 {
960 {
920 auto oldRange = this->graphRange();
961 auto oldRange = this->graphRange();
921 impl->applyZoomRect();
962 impl->applyZoomRect();
922 auto newRange = this->graphRange();
963 auto newRange = this->graphRange();
923 if(auto tf = DateTimeRangeHelper::computeTransformation(oldRange,newRange))
964 if (auto tf = DateTimeRangeHelper::computeTransformation(oldRange, newRange))
924 emit this->transform_sig(tf.value(), false);
965 emit this->transform_sig(tf.value(), false);
925 }
966 }
926 else if(impl->isDrawingZoneRect())
967 else if (impl->isDrawingZoneRect())
927 {
968 {
928 impl->endDrawingZone();
969 impl->endDrawingZone();
929 }
970 }
@@ -932,20 +973,21 void VisualizationGraphWidget::mouseReleaseEvent(QMouseEvent *event)
932 setCursor(Qt::ArrowCursor);
973 setCursor(Qt::ArrowCursor);
933 }
974 }
934 auto posInPlot = this->impl->m_plot->mapFromParent(event->pos());
975 auto posInPlot = this->impl->m_plot->mapFromParent(event->pos());
935 if(auto item = impl->m_plot->itemAt(posInPlot))
976 if (auto item = impl->m_plot->itemAt(posInPlot))
936 {
977 {
937 if(qobject_cast<VisualizationSelectionZoneItem*>(item))
978 if (qobject_cast<VisualizationSelectionZoneItem*>(item))
938 {
979 {
939 QMouseEvent e{QEvent::MouseButtonRelease, posInPlot, event->button(), event->buttons(), event->modifiers()};
980 QMouseEvent e { QEvent::MouseButtonRelease, posInPlot, event->button(),
981 event->buttons(), event->modifiers() };
940 sqpApp->sendEvent(this->impl->m_plot, &e);
982 sqpApp->sendEvent(this->impl->m_plot, &e);
941 }
983 }
942 }
984 }
943 event->accept();
985 event->accept();
944 }
986 }
945
987
946 void VisualizationGraphWidget::mousePressEvent(QMouseEvent *event)
988 void VisualizationGraphWidget::mousePressEvent(QMouseEvent* event)
947 {
989 {
948 if (event->button()==Qt::RightButton)
990 if (event->button() == Qt::RightButton)
949 {
991 {
950 onGraphMenuRequested(event->pos());
992 onGraphMenuRequested(event->pos());
951 }
993 }
@@ -954,15 +996,16 void VisualizationGraphWidget::mousePressEvent(QMouseEvent *event)
954 auto selectedZone = impl->selectionZoneAt(event->pos());
996 auto selectedZone = impl->selectionZoneAt(event->pos());
955 switch (sqpApp->plotsInteractionMode())
997 switch (sqpApp->plotsInteractionMode())
956 {
998 {
957 case SqpApplication::PlotsInteractionMode::DragAndDrop :
999 case SqpApplication::PlotsInteractionMode::DragAndDrop:
958 break;
1000 break;
959 case SqpApplication::PlotsInteractionMode::SelectionZones :
1001 case SqpApplication::PlotsInteractionMode::SelectionZones:
960 impl->setSelectionZonesEditionEnabled(true);
1002 impl->setSelectionZonesEditionEnabled(true);
961 if ((event->modifiers() == Qt::ControlModifier) && (selectedZone != nullptr))
1003 if ((event->modifiers() == Qt::ControlModifier) && (selectedZone != nullptr))
962 {
1004 {
963 auto alreadySelectedZones = parentVisualizationWidget()->selectionZoneManager().selectedItems();
1005 auto alreadySelectedZones
1006 = parentVisualizationWidget()->selectionZoneManager().selectedItems();
964 selectedZone->setAssociatedEditedZones(alreadySelectedZones);
1007 selectedZone->setAssociatedEditedZones(alreadySelectedZones);
965 if(SciQLop::containers::contains(alreadySelectedZones, selectedZone))
1008 if (SciQLop::containers::contains(alreadySelectedZones, selectedZone))
966 {
1009 {
967 alreadySelectedZones.removeOne(selectedZone);
1010 alreadySelectedZones.removeOne(selectedZone);
968 }
1011 }
@@ -970,64 +1013,68 void VisualizationGraphWidget::mousePressEvent(QMouseEvent *event)
970 {
1013 {
971 alreadySelectedZones.append(selectedZone);
1014 alreadySelectedZones.append(selectedZone);
972 }
1015 }
973 parentVisualizationWidget()->selectionZoneManager().select(alreadySelectedZones);
1016 parentVisualizationWidget()->selectionZoneManager().select(
974 }
1017 alreadySelectedZones);
975 else
976 {
977 if (!selectedZone)
978 {
979 parentVisualizationWidget()->selectionZoneManager().clearSelection();
980 impl->startDrawingZone(event->pos());
981 }
1018 }
982 else
1019 else
983 {
1020 {
984 parentVisualizationWidget()->selectionZoneManager().select({ selectedZone });
1021 if (!selectedZone)
1022 {
1023 parentVisualizationWidget()->selectionZoneManager().clearSelection();
1024 impl->startDrawingZone(event->pos());
1025 }
1026 else
1027 {
1028 parentVisualizationWidget()->selectionZoneManager().select(
1029 { selectedZone });
1030 }
985 }
1031 }
986 }
987 {
988 auto posInPlot = this->impl->m_plot->mapFromParent(event->pos());
989 if(auto item = impl->m_plot->itemAt(posInPlot))
990 {
1032 {
991 if(qobject_cast<VisualizationSelectionZoneItem*>(item))
1033 auto posInPlot = this->impl->m_plot->mapFromParent(event->pos());
1034 if (auto item = impl->m_plot->itemAt(posInPlot))
992 {
1035 {
993 QMouseEvent e{QEvent::MouseButtonPress, posInPlot, event->button(), event->buttons(), event->modifiers()};
1036 if (qobject_cast<VisualizationSelectionZoneItem*>(item))
994 sqpApp->sendEvent(this->impl->m_plot, &e);
1037 {
1038 QMouseEvent e { QEvent::MouseButtonPress, posInPlot, event->button(),
1039 event->buttons(), event->modifiers() };
1040 sqpApp->sendEvent(this->impl->m_plot, &e);
1041 }
995 }
1042 }
996 }
1043 }
997 }
1044 break;
998 break;
1045 case SqpApplication::PlotsInteractionMode::ZoomBox:
999 case SqpApplication::PlotsInteractionMode::ZoomBox :
1046 impl->startDrawingRect(event->pos());
1000 impl->startDrawingRect(event->pos());
1047 break;
1001 break;
1048 default:
1002 default:
1049 if (auto item = impl->m_plot->itemAt(event->pos()))
1003 if(auto item = impl->m_plot->itemAt(event->pos()))
1050 {
1004 {
1051 emit impl->m_plot->itemClick(item, event);
1005 emit impl->m_plot->itemClick(item,event);
1052 if (qobject_cast<VisualizationSelectionZoneItem*>(item))
1006 if(qobject_cast<VisualizationSelectionZoneItem*>(item))
1053 {
1054 setCursor(Qt::ClosedHandCursor);
1055 impl->enterPlotDrag(event->pos());
1056 }
1057 }
1058 else
1007 {
1059 {
1008 setCursor(Qt::ClosedHandCursor);
1060 setCursor(Qt::ClosedHandCursor);
1009 impl->enterPlotDrag(event->pos());
1061 impl->enterPlotDrag(event->pos());
1010 }
1062 }
1011 }
1012 else
1013 {
1014 setCursor(Qt::ClosedHandCursor);
1015 impl->enterPlotDrag(event->pos());
1016 }
1017 }
1063 }
1018 }
1064 }
1019 //event->accept();
1065 // event->accept();
1020 QWidget::mousePressEvent(event);
1066 QWidget::mousePressEvent(event);
1021 }
1067 }
1022
1068
1023 void VisualizationGraphWidget::mouseDoubleClickEvent(QMouseEvent *event)
1069 void VisualizationGraphWidget::mouseDoubleClickEvent(QMouseEvent* event)
1024 {
1070 {
1025 impl->m_RenderingDelegate->onMouseDoubleClick(event);
1071 impl->m_RenderingDelegate->onMouseDoubleClick(event);
1026 }
1072 }
1027
1073
1028 void VisualizationGraphWidget::keyReleaseEvent(QKeyEvent *event)
1074 void VisualizationGraphWidget::keyReleaseEvent(QKeyEvent* event)
1029 {
1075 {
1030 switch (event->key()) {
1076 switch (event->key())
1077 {
1031 case Qt::Key_Control:
1078 case Qt::Key_Control:
1032 event->accept();
1079 event->accept();
1033 break;
1080 break;
@@ -1039,12 +1086,13 void VisualizationGraphWidget::keyReleaseEvent(QKeyEvent *event)
1039 break;
1086 break;
1040 }
1087 }
1041 setCursor(Qt::ArrowCursor);
1088 setCursor(Qt::ArrowCursor);
1042 //event->accept();
1089 // event->accept();
1043 }
1090 }
1044
1091
1045 void VisualizationGraphWidget::keyPressEvent(QKeyEvent *event)
1092 void VisualizationGraphWidget::keyPressEvent(QKeyEvent* event)
1046 {
1093 {
1047 switch (event->key()) {
1094 switch (event->key())
1095 {
1048 case Qt::Key_Control:
1096 case Qt::Key_Control:
1049 setCursor(Qt::CrossCursor);
1097 setCursor(Qt::CrossCursor);
1050 break;
1098 break;
@@ -1055,34 +1103,42 void VisualizationGraphWidget::keyPressEvent(QKeyEvent *event)
1055 impl->m_plot->replot(QCustomPlot::rpQueuedReplot);
1103 impl->m_plot->replot(QCustomPlot::rpQueuedReplot);
1056 break;
1104 break;
1057 case Qt::Key_Left:
1105 case Qt::Key_Left:
1058 if (event->modifiers() != Qt::ControlModifier) {
1106 if (event->modifiers() != Qt::ControlModifier)
1107 {
1059 move(-0.1, Qt::Horizontal);
1108 move(-0.1, Qt::Horizontal);
1060 }
1109 }
1061 else {
1110 else
1111 {
1062 zoom(2, this->width() / 2, Qt::Horizontal);
1112 zoom(2, this->width() / 2, Qt::Horizontal);
1063 }
1113 }
1064 break;
1114 break;
1065 case Qt::Key_Right:
1115 case Qt::Key_Right:
1066 if (event->modifiers() != Qt::ControlModifier) {
1116 if (event->modifiers() != Qt::ControlModifier)
1117 {
1067 move(0.1, Qt::Horizontal);
1118 move(0.1, Qt::Horizontal);
1068 }
1119 }
1069 else {
1120 else
1121 {
1070 zoom(0.5, this->width() / 2, Qt::Horizontal);
1122 zoom(0.5, this->width() / 2, Qt::Horizontal);
1071 }
1123 }
1072 break;
1124 break;
1073 case Qt::Key_Up:
1125 case Qt::Key_Up:
1074 if (event->modifiers() != Qt::ControlModifier) {
1126 if (event->modifiers() != Qt::ControlModifier)
1127 {
1075 move(0.1, Qt::Vertical);
1128 move(0.1, Qt::Vertical);
1076 }
1129 }
1077 else {
1130 else
1131 {
1078 zoom(0.5, this->height() / 2, Qt::Vertical);
1132 zoom(0.5, this->height() / 2, Qt::Vertical);
1079 }
1133 }
1080 break;
1134 break;
1081 case Qt::Key_Down:
1135 case Qt::Key_Down:
1082 if (event->modifiers() != Qt::ControlModifier) {
1136 if (event->modifiers() != Qt::ControlModifier)
1137 {
1083 move(-0.1, Qt::Vertical);
1138 move(-0.1, Qt::Vertical);
1084 }
1139 }
1085 else {
1140 else
1141 {
1086 zoom(2, this->height() / 2, Qt::Vertical);
1142 zoom(2, this->height() / 2, Qt::Vertical);
1087 }
1143 }
1088 break;
1144 break;
@@ -1092,26 +1148,29 void VisualizationGraphWidget::keyPressEvent(QKeyEvent *event)
1092 }
1148 }
1093 }
1149 }
1094
1150
1095 QCustomPlot &VisualizationGraphWidget::plot() const noexcept
1151 QCustomPlot& VisualizationGraphWidget::plot() const noexcept
1096 {
1152 {
1097 return *impl->m_plot;
1153 return *impl->m_plot;
1098 }
1154 }
1099
1155
1100 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
1156 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint& pos) noexcept
1101 {
1157 {
1102 QMenu graphMenu{};
1158 QMenu graphMenu {};
1103
1159
1104 // Iterates on variables (unique keys)
1160 // Iterates on variables (unique keys)
1105 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
1161 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
1106 end = impl->m_VariableToPlotMultiMap.cend();
1162 end = impl->m_VariableToPlotMultiMap.cend();
1107 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
1163 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first))
1164 {
1108 // 'Remove variable' action
1165 // 'Remove variable' action
1109 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
1166 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
1110 [this, var = it->first]() { removeVariable(var); });
1167 [this, var = it->first]() { removeVariable(var); });
1111 }
1168 }
1112
1169
1113 if (!impl->m_ZoomStack.isEmpty()) {
1170 if (!impl->m_ZoomStack.isEmpty())
1114 if (!graphMenu.isEmpty()) {
1171 {
1172 if (!graphMenu.isEmpty())
1173 {
1115 graphMenu.addSeparator();
1174 graphMenu.addSeparator();
1116 }
1175 }
1117
1176
@@ -1120,49 +1179,58 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
1120
1179
1121 // Selection Zone Actions
1180 // Selection Zone Actions
1122 auto selectionZoneItem = impl->selectionZoneAt(pos);
1181 auto selectionZoneItem = impl->selectionZoneAt(pos);
1123 if (selectionZoneItem) {
1182 if (selectionZoneItem)
1183 {
1124 auto selectedItems = parentVisualizationWidget()->selectionZoneManager().selectedItems();
1184 auto selectedItems = parentVisualizationWidget()->selectionZoneManager().selectedItems();
1125 selectedItems.removeAll(selectionZoneItem);
1185 selectedItems.removeAll(selectionZoneItem);
1126 selectedItems.prepend(selectionZoneItem); // Put the current selection zone first
1186 selectedItems.prepend(selectionZoneItem); // Put the current selection zone first
1127
1187
1128 auto zoneActions = sqpApp->actionsGuiController().selectionZoneActions();
1188 auto zoneActions = sqpApp->actionsGuiController().selectionZoneActions();
1129 if (!zoneActions.isEmpty() && !graphMenu.isEmpty()) {
1189 if (!zoneActions.isEmpty() && !graphMenu.isEmpty())
1190 {
1130 graphMenu.addSeparator();
1191 graphMenu.addSeparator();
1131 }
1192 }
1132
1193
1133 QHash<QString, QMenu *> subMenus;
1194 QHash<QString, QMenu*> subMenus;
1134 QHash<QString, bool> subMenusEnabled;
1195 QHash<QString, bool> subMenusEnabled;
1135 QHash<QString, FilteringAction *> filteredMenu;
1196 QHash<QString, FilteringAction*> filteredMenu;
1136
1197
1137 for (auto zoneAction : zoneActions) {
1198 for (auto zoneAction : zoneActions)
1199 {
1138
1200
1139 auto isEnabled = zoneAction->isEnabled(selectedItems);
1201 auto isEnabled = zoneAction->isEnabled(selectedItems);
1140
1202
1141 auto menu = &graphMenu;
1203 auto menu = &graphMenu;
1142 QString menuPath;
1204 QString menuPath;
1143 for (auto subMenuName : zoneAction->subMenuList()) {
1205 for (auto subMenuName : zoneAction->subMenuList())
1206 {
1144 menuPath += '/';
1207 menuPath += '/';
1145 menuPath += subMenuName;
1208 menuPath += subMenuName;
1146
1209
1147 if (!subMenus.contains(menuPath)) {
1210 if (!subMenus.contains(menuPath))
1211 {
1148 menu = menu->addMenu(subMenuName);
1212 menu = menu->addMenu(subMenuName);
1149 subMenus[menuPath] = menu;
1213 subMenus[menuPath] = menu;
1150 subMenusEnabled[menuPath] = isEnabled;
1214 subMenusEnabled[menuPath] = isEnabled;
1151 }
1215 }
1152 else {
1216 else
1217 {
1153 menu = subMenus.value(menuPath);
1218 menu = subMenus.value(menuPath);
1154 if (isEnabled) {
1219 if (isEnabled)
1220 {
1155 // The sub menu is enabled if at least one of its actions is enabled
1221 // The sub menu is enabled if at least one of its actions is enabled
1156 subMenusEnabled[menuPath] = true;
1222 subMenusEnabled[menuPath] = true;
1157 }
1223 }
1158 }
1224 }
1159 }
1225 }
1160
1226
1161 FilteringAction *filterAction = nullptr;
1227 FilteringAction* filterAction = nullptr;
1162 if (sqpApp->actionsGuiController().isMenuFiltered(zoneAction->subMenuList())) {
1228 if (sqpApp->actionsGuiController().isMenuFiltered(zoneAction->subMenuList()))
1229 {
1163 filterAction = filteredMenu.value(menuPath);
1230 filterAction = filteredMenu.value(menuPath);
1164 if (!filterAction) {
1231 if (!filterAction)
1165 filterAction = new FilteringAction{this};
1232 {
1233 filterAction = new FilteringAction { this };
1166 filteredMenu[menuPath] = filterAction;
1234 filteredMenu[menuPath] = filterAction;
1167 menu->addAction(filterAction);
1235 menu->addAction(filterAction);
1168 }
1236 }
@@ -1172,29 +1240,32 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
1172 action->setEnabled(isEnabled);
1240 action->setEnabled(isEnabled);
1173 action->setShortcut(zoneAction->displayedShortcut());
1241 action->setShortcut(zoneAction->displayedShortcut());
1174 QObject::connect(action, &QAction::triggered,
1242 QObject::connect(action, &QAction::triggered,
1175 [zoneAction, selectedItems]() { zoneAction->execute(selectedItems); });
1243 [zoneAction, selectedItems]() { zoneAction->execute(selectedItems); });
1176
1244
1177 if (filterAction && zoneAction->isFilteringAllowed()) {
1245 if (filterAction && zoneAction->isFilteringAllowed())
1246 {
1178 filterAction->addActionToFilter(action);
1247 filterAction->addActionToFilter(action);
1179 }
1248 }
1180 }
1249 }
1181
1250
1182 for (auto it = subMenus.cbegin(); it != subMenus.cend(); ++it) {
1251 for (auto it = subMenus.cbegin(); it != subMenus.cend(); ++it)
1252 {
1183 it.value()->setEnabled(subMenusEnabled[it.key()]);
1253 it.value()->setEnabled(subMenusEnabled[it.key()]);
1184 }
1254 }
1185 }
1255 }
1186
1256
1187 if (!graphMenu.isEmpty()) {
1257 if (!graphMenu.isEmpty())
1258 {
1188 graphMenu.exec(QCursor::pos());
1259 graphMenu.exec(QCursor::pos());
1189 }
1260 }
1190 }
1261 }
1191
1262
1192 void VisualizationGraphWidget::onMouseDoubleClick(QMouseEvent *event) noexcept
1263 void VisualizationGraphWidget::onMouseDoubleClick(QMouseEvent* event) noexcept
1193 {
1264 {
1194 impl->m_RenderingDelegate->onMouseDoubleClick(event);
1265 impl->m_RenderingDelegate->onMouseDoubleClick(event);
1195 }
1266 }
1196
1267
1197 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
1268 void VisualizationGraphWidget::onMouseMove(QMouseEvent* event) noexcept
1198 {
1269 {
1199 // Handles plot rendering when mouse is moving
1270 // Handles plot rendering when mouse is moving
1200 impl->m_RenderingDelegate->updateTooltip(event);
1271 impl->m_RenderingDelegate->updateTooltip(event);
@@ -1202,19 +1273,24 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
1202 auto axisPos = impl->posToAxisPos(event->pos());
1273 auto axisPos = impl->posToAxisPos(event->pos());
1203
1274
1204 // Zoom box and zone drawing
1275 // Zoom box and zone drawing
1205 if (impl->m_DrawingZoomRect) {
1276 if (impl->m_DrawingZoomRect)
1277 {
1206 impl->m_DrawingZoomRect->bottomRight->setCoords(axisPos);
1278 impl->m_DrawingZoomRect->bottomRight->setCoords(axisPos);
1207 }
1279 }
1208 else if (impl->m_DrawingZone) {
1280 else if (impl->m_DrawingZone)
1281 {
1209 impl->m_DrawingZone->setEnd(axisPos.x());
1282 impl->m_DrawingZone->setEnd(axisPos.x());
1210 }
1283 }
1211
1284
1212 // Cursor
1285 // Cursor
1213 if (auto parentZone = parentZoneWidget()) {
1286 if (auto parentZone = parentZoneWidget())
1214 if (impl->pointIsInAxisRect(axisPos, plot())) {
1287 {
1288 if (impl->pointIsInAxisRect(axisPos, plot()))
1289 {
1215 parentZone->notifyMouseMoveInGraph(event->pos(), axisPos, this);
1290 parentZone->notifyMouseMoveInGraph(event->pos(), axisPos, this);
1216 }
1291 }
1217 else {
1292 else
1293 {
1218 parentZone->notifyMouseLeaveGraph(this);
1294 parentZone->notifyMouseLeaveGraph(this);
1219 }
1295 }
1220 }
1296 }
@@ -1222,15 +1298,18 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
1222 // Search for the selection zone under the mouse
1298 // Search for the selection zone under the mouse
1223 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos());
1299 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos());
1224 if (selectionZoneItemUnderCursor && !impl->m_DrawingZone
1300 if (selectionZoneItemUnderCursor && !impl->m_DrawingZone
1225 && sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones) {
1301 && sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones)
1302 {
1226
1303
1227 // Sets the appropriate cursor shape
1304 // Sets the appropriate cursor shape
1228 auto cursorShape = selectionZoneItemUnderCursor->curshorShapeForPosition(event->pos());
1305 auto cursorShape = selectionZoneItemUnderCursor->curshorShapeForPosition(event->pos());
1229 setCursor(cursorShape);
1306 setCursor(cursorShape);
1230
1307
1231 // Manages the hovered zone
1308 // Manages the hovered zone
1232 if (selectionZoneItemUnderCursor != impl->m_HoveredZone) {
1309 if (selectionZoneItemUnderCursor != impl->m_HoveredZone)
1233 if (impl->m_HoveredZone) {
1310 {
1311 if (impl->m_HoveredZone)
1312 {
1234 impl->m_HoveredZone->setHovered(false);
1313 impl->m_HoveredZone->setHovered(false);
1235 }
1314 }
1236 selectionZoneItemUnderCursor->setHovered(true);
1315 selectionZoneItemUnderCursor->setHovered(true);
@@ -1238,9 +1317,11 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
1238 plot().replot(QCustomPlot::rpQueuedReplot);
1317 plot().replot(QCustomPlot::rpQueuedReplot);
1239 }
1318 }
1240 }
1319 }
1241 else {
1320 else
1321 {
1242 // There is no zone under the mouse or the interaction mode is not "selection zones"
1322 // There is no zone under the mouse or the interaction mode is not "selection zones"
1243 if (impl->m_HoveredZone) {
1323 if (impl->m_HoveredZone)
1324 {
1244 impl->m_HoveredZone->setHovered(false);
1325 impl->m_HoveredZone->setHovered(false);
1245 impl->m_HoveredZone = nullptr;
1326 impl->m_HoveredZone = nullptr;
1246 }
1327 }
@@ -1252,34 +1333,38 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
1252 VisualizationDragWidget::mouseMoveEvent(event);
1333 VisualizationDragWidget::mouseMoveEvent(event);
1253 }
1334 }
1254
1335
1255 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
1336 void VisualizationGraphWidget::onMouseWheel(QWheelEvent* event) noexcept
1256 {
1337 {
1257 // Processes event only if the wheel occurs on axis rect
1338 // Processes event only if the wheel occurs on axis rect
1258 if (!dynamic_cast<QCPAxisRect *>(impl->m_plot->layoutElementAt(event->posF()))) {
1339 if (!dynamic_cast<QCPAxisRect*>(impl->m_plot->layoutElementAt(event->posF())))
1340 {
1259 return;
1341 return;
1260 }
1342 }
1261
1343
1262 auto value = event->angleDelta().x() + event->angleDelta().y();
1344 auto value = event->angleDelta().x() + event->angleDelta().y();
1263 if (value != 0) {
1345 if (value != 0)
1346 {
1264
1347
1265 auto direction = value > 0 ? 1.0 : -1.0;
1348 auto direction = value > 0 ? 1.0 : -1.0;
1266 auto isZoomX = event->modifiers().testFlag(HORIZONTAL_ZOOM_MODIFIER);
1349 auto isZoomX = event->modifiers().testFlag(HORIZONTAL_ZOOM_MODIFIER);
1267 auto isZoomY = event->modifiers().testFlag(VERTICAL_ZOOM_MODIFIER);
1350 auto isZoomY = event->modifiers().testFlag(VERTICAL_ZOOM_MODIFIER);
1268 impl->m_IsCalibration = event->modifiers().testFlag(VERTICAL_PAN_MODIFIER);
1351 impl->m_IsCalibration = event->modifiers().testFlag(VERTICAL_PAN_MODIFIER);
1269
1352
1270 auto zoomOrientations = QFlags<Qt::Orientation>{};
1353 auto zoomOrientations = QFlags<Qt::Orientation> {};
1271 zoomOrientations.setFlag(Qt::Horizontal, isZoomX);
1354 zoomOrientations.setFlag(Qt::Horizontal, isZoomX);
1272 zoomOrientations.setFlag(Qt::Vertical, isZoomY);
1355 zoomOrientations.setFlag(Qt::Vertical, isZoomY);
1273
1356
1274 impl->m_plot->axisRect()->setRangeZoom(zoomOrientations);
1357 impl->m_plot->axisRect()->setRangeZoom(zoomOrientations);
1275
1358
1276 if (!isZoomX && !isZoomY) {
1359 if (!isZoomX && !isZoomY)
1360 {
1277 auto axis = plot().axisRect()->axis(QCPAxis::atBottom);
1361 auto axis = plot().axisRect()->axis(QCPAxis::atBottom);
1278 auto diff = direction * (axis->range().size() * (PAN_SPEED / 100.0));
1362 auto diff = direction * (axis->range().size() * (PAN_SPEED / 100.0));
1279
1363
1280 axis->setRange(axis->range() + diff);
1364 axis->setRange(axis->range() + diff);
1281
1365
1282 if (plot().noAntialiasingOnDrag()) {
1366 if (plot().noAntialiasingOnDrag())
1367 {
1283 plot().setNotAntialiasedElements(QCP::aeAll);
1368 plot().setNotAntialiasedElements(QCP::aeAll);
1284 }
1369 }
1285
1370
@@ -1288,22 +1373,26 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
1288 }
1373 }
1289 }
1374 }
1290
1375
1291 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
1376 void VisualizationGraphWidget::onMousePress(QMouseEvent* event) noexcept
1292 {
1377 {
1293 auto isDragDropClick = event->modifiers().testFlag(DRAG_DROP_MODIFIER);
1378 auto isDragDropClick = event->modifiers().testFlag(DRAG_DROP_MODIFIER);
1294 auto isSelectionZoneMode
1379 auto isSelectionZoneMode
1295 = sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones;
1380 = sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones;
1296 auto isLeftClick = event->buttons().testFlag(Qt::LeftButton);
1381 auto isLeftClick = event->buttons().testFlag(Qt::LeftButton);
1297
1382
1298 if (!isDragDropClick && isLeftClick) {
1383 if (!isDragDropClick && isLeftClick)
1299 if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::ZoomBox) {
1384 {
1385 if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::ZoomBox)
1386 {
1300 // Starts a zoom box
1387 // Starts a zoom box
1301 impl->startDrawingRect(event->pos());
1388 impl->startDrawingRect(event->pos());
1302 }
1389 }
1303 else if (isSelectionZoneMode && impl->m_DrawingZone == nullptr) {
1390 else if (isSelectionZoneMode && impl->m_DrawingZone == nullptr)
1391 {
1304 // Starts a new selection zone
1392 // Starts a new selection zone
1305 auto zoneAtPos = impl->selectionZoneAt(event->pos());
1393 auto zoneAtPos = impl->selectionZoneAt(event->pos());
1306 if (!zoneAtPos) {
1394 if (!zoneAtPos)
1395 {
1307 impl->startDrawingZone(event->pos());
1396 impl->startDrawingZone(event->pos());
1308 }
1397 }
1309 }
1398 }
@@ -1314,24 +1403,29 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
1314 impl->setSelectionZonesEditionEnabled(isSelectionZoneMode && !isDragDropClick);
1403 impl->setSelectionZonesEditionEnabled(isSelectionZoneMode && !isDragDropClick);
1315
1404
1316 // Selection / Deselection
1405 // Selection / Deselection
1317 if (isSelectionZoneMode) {
1406 if (isSelectionZoneMode)
1407 {
1318 auto isMultiSelectionClick = event->modifiers().testFlag(MULTI_ZONE_SELECTION_MODIFIER);
1408 auto isMultiSelectionClick = event->modifiers().testFlag(MULTI_ZONE_SELECTION_MODIFIER);
1319 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos());
1409 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos());
1320
1410
1321
1411
1322 if (selectionZoneItemUnderCursor && !selectionZoneItemUnderCursor->selected()
1412 if (selectionZoneItemUnderCursor && !selectionZoneItemUnderCursor->selected()
1323 && !isMultiSelectionClick) {
1413 && !isMultiSelectionClick)
1414 {
1324 parentVisualizationWidget()->selectionZoneManager().select(
1415 parentVisualizationWidget()->selectionZoneManager().select(
1325 {selectionZoneItemUnderCursor});
1416 { selectionZoneItemUnderCursor });
1326 }
1417 }
1327 else if (!selectionZoneItemUnderCursor && !isMultiSelectionClick && isLeftClick) {
1418 else if (!selectionZoneItemUnderCursor && !isMultiSelectionClick && isLeftClick)
1419 {
1328 parentVisualizationWidget()->selectionZoneManager().clearSelection();
1420 parentVisualizationWidget()->selectionZoneManager().clearSelection();
1329 }
1421 }
1330 else {
1422 else
1423 {
1331 // No selection change
1424 // No selection change
1332 }
1425 }
1333
1426
1334 if (selectionZoneItemUnderCursor && isLeftClick) {
1427 if (selectionZoneItemUnderCursor && isLeftClick)
1428 {
1335 selectionZoneItemUnderCursor->setAssociatedEditedZones(
1429 selectionZoneItemUnderCursor->setAssociatedEditedZones(
1336 parentVisualizationWidget()->selectionZoneManager().selectedItems());
1430 parentVisualizationWidget()->selectionZoneManager().selectedItems());
1337 }
1431 }
@@ -1342,23 +1436,25 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
1342 VisualizationDragWidget::mousePressEvent(event);
1436 VisualizationDragWidget::mousePressEvent(event);
1343 }
1437 }
1344
1438
1345 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
1439 void VisualizationGraphWidget::onMouseRelease(QMouseEvent* event) noexcept
1346 {
1440 {
1347 if (impl->m_DrawingZoomRect) {
1441 if (impl->m_DrawingZoomRect)
1442 {
1348
1443
1349 auto axisX = plot().axisRect()->axis(QCPAxis::atBottom);
1444 auto axisX = plot().axisRect()->axis(QCPAxis::atBottom);
1350 auto axisY = plot().axisRect()->axis(QCPAxis::atLeft);
1445 auto axisY = plot().axisRect()->axis(QCPAxis::atLeft);
1351
1446
1352 auto newAxisXRange = QCPRange{impl->m_DrawingZoomRect->topLeft->coords().x(),
1447 auto newAxisXRange = QCPRange { impl->m_DrawingZoomRect->topLeft->coords().x(),
1353 impl->m_DrawingZoomRect->bottomRight->coords().x()};
1448 impl->m_DrawingZoomRect->bottomRight->coords().x() };
1354
1449
1355 auto newAxisYRange = QCPRange{impl->m_DrawingZoomRect->topLeft->coords().y(),
1450 auto newAxisYRange = QCPRange { impl->m_DrawingZoomRect->topLeft->coords().y(),
1356 impl->m_DrawingZoomRect->bottomRight->coords().y()};
1451 impl->m_DrawingZoomRect->bottomRight->coords().y() };
1357
1452
1358 impl->removeDrawingRect();
1453 impl->removeDrawingRect();
1359
1454
1360 if (newAxisXRange.size() > axisX->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)
1455 if (newAxisXRange.size() > axisX->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)
1361 && newAxisYRange.size() > axisY->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)) {
1456 && newAxisYRange.size() > axisY->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0))
1457 {
1362 impl->m_ZoomStack.push(qMakePair(axisX->range(), axisY->range()));
1458 impl->m_ZoomStack.push(qMakePair(axisX->range(), axisY->range()));
1363 axisX->setRange(newAxisXRange);
1459 axisX->setRange(newAxisXRange);
1364 axisY->setRange(newAxisYRange);
1460 axisY->setRange(newAxisYRange);
@@ -1372,55 +1468,67 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
1372 // Selection / Deselection
1468 // Selection / Deselection
1373 auto isSelectionZoneMode
1469 auto isSelectionZoneMode
1374 = sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones;
1470 = sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones;
1375 if (isSelectionZoneMode) {
1471 if (isSelectionZoneMode)
1472 {
1376 auto isMultiSelectionClick = event->modifiers().testFlag(MULTI_ZONE_SELECTION_MODIFIER);
1473 auto isMultiSelectionClick = event->modifiers().testFlag(MULTI_ZONE_SELECTION_MODIFIER);
1377 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos());
1474 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos());
1378 if (selectionZoneItemUnderCursor && event->button() == Qt::LeftButton
1475 if (selectionZoneItemUnderCursor && event->button() == Qt::LeftButton
1379 && !impl->m_HasMovedMouse) {
1476 && !impl->m_HasMovedMouse)
1477 {
1380
1478
1381 auto zonesUnderCursor = impl->selectionZonesAt(event->pos(), plot());
1479 auto zonesUnderCursor = impl->selectionZonesAt(event->pos(), plot());
1382 if (zonesUnderCursor.count() > 1) {
1480 if (zonesUnderCursor.count() > 1)
1481 {
1383 // There are multiple zones under the mouse.
1482 // There are multiple zones under the mouse.
1384 // Performs the selection with a selection dialog.
1483 // Performs the selection with a selection dialog.
1385 VisualizationMultiZoneSelectionDialog dialog{this};
1484 VisualizationMultiZoneSelectionDialog dialog { this };
1386 dialog.setZones(zonesUnderCursor);
1485 dialog.setZones(zonesUnderCursor);
1387 dialog.move(mapToGlobal(event->pos() - QPoint(dialog.width() / 2, 20)));
1486 dialog.move(mapToGlobal(event->pos() - QPoint(dialog.width() / 2, 20)));
1388 dialog.activateWindow();
1487 dialog.activateWindow();
1389 dialog.raise();
1488 dialog.raise();
1390 if (dialog.exec() == QDialog::Accepted) {
1489 if (dialog.exec() == QDialog::Accepted)
1490 {
1391 auto selection = dialog.selectedZones();
1491 auto selection = dialog.selectedZones();
1392
1492
1393 if (!isMultiSelectionClick) {
1493 if (!isMultiSelectionClick)
1494 {
1394 parentVisualizationWidget()->selectionZoneManager().clearSelection();
1495 parentVisualizationWidget()->selectionZoneManager().clearSelection();
1395 }
1496 }
1396
1497
1397 for (auto it = selection.cbegin(); it != selection.cend(); ++it) {
1498 for (auto it = selection.cbegin(); it != selection.cend(); ++it)
1499 {
1398 auto zone = it.key();
1500 auto zone = it.key();
1399 auto isSelected = it.value();
1501 auto isSelected = it.value();
1400 parentVisualizationWidget()->selectionZoneManager().setSelected(zone,
1502 parentVisualizationWidget()->selectionZoneManager().setSelected(
1401 isSelected);
1503 zone, isSelected);
1402
1504
1403 if (isSelected) {
1505 if (isSelected)
1506 {
1404 // Puts the zone on top of the stack so it can be moved or resized
1507 // Puts the zone on top of the stack so it can be moved or resized
1405 impl->moveSelectionZoneOnTop(zone, plot());
1508 impl->moveSelectionZoneOnTop(zone, plot());
1406 }
1509 }
1407 }
1510 }
1408 }
1511 }
1409 }
1512 }
1410 else {
1513 else
1411 if (!isMultiSelectionClick) {
1514 {
1515 if (!isMultiSelectionClick)
1516 {
1412 parentVisualizationWidget()->selectionZoneManager().select(
1517 parentVisualizationWidget()->selectionZoneManager().select(
1413 {selectionZoneItemUnderCursor});
1518 { selectionZoneItemUnderCursor });
1414 impl->moveSelectionZoneOnTop(selectionZoneItemUnderCursor, plot());
1519 impl->moveSelectionZoneOnTop(selectionZoneItemUnderCursor, plot());
1415 }
1520 }
1416 else {
1521 else
1522 {
1417 parentVisualizationWidget()->selectionZoneManager().setSelected(
1523 parentVisualizationWidget()->selectionZoneManager().setSelected(
1418 selectionZoneItemUnderCursor, !selectionZoneItemUnderCursor->selected()
1524 selectionZoneItemUnderCursor,
1419 || event->button() == Qt::RightButton);
1525 !selectionZoneItemUnderCursor->selected()
1526 || event->button() == Qt::RightButton);
1420 }
1527 }
1421 }
1528 }
1422 }
1529 }
1423 else {
1530 else
1531 {
1424 // No selection change
1532 // No selection change
1425 }
1533 }
1426 }
1534 }
@@ -1429,39 +1537,44 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
1429 void VisualizationGraphWidget::onDataCacheVariableUpdated()
1537 void VisualizationGraphWidget::onDataCacheVariableUpdated()
1430 {
1538 {
1431 auto graphRange = impl->m_plot->xAxis->range();
1539 auto graphRange = impl->m_plot->xAxis->range();
1432 auto dateTime = DateTimeRange{graphRange.lower, graphRange.upper};
1540 auto dateTime = DateTimeRange { graphRange.lower, graphRange.upper };
1433
1541
1434 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
1542 for (auto& variableEntry : impl->m_VariableToPlotMultiMap)
1543 {
1435 auto variable = variableEntry.first;
1544 auto variable = variableEntry.first;
1436 qCDebug(LOG_VisualizationGraphWidget())
1545 qCDebug(LOG_VisualizationGraphWidget())
1437 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
1546 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
1438 qCDebug(LOG_VisualizationGraphWidget())
1547 qCDebug(LOG_VisualizationGraphWidget())
1439 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
1548 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
1440 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
1549 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range()))
1550 {
1441 impl->updateData(variableEntry.second, variable, variable->range());
1551 impl->updateData(variableEntry.second, variable, variable->range());
1442 }
1552 }
1443 }
1553 }
1444 }
1554 }
1445
1555
1446 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
1556 void VisualizationGraphWidget::onUpdateVarDisplaying(
1447 const DateTimeRange &range)
1557 std::shared_ptr<Variable2> variable, const DateTimeRange& range)
1448 {
1558 {
1449 auto it = impl->m_VariableToPlotMultiMap.find(variable);
1559 auto it = impl->m_VariableToPlotMultiMap.find(variable);
1450 if (it != impl->m_VariableToPlotMultiMap.end()) {
1560 if (it != impl->m_VariableToPlotMultiMap.end())
1561 {
1451 impl->updateData(it->second, variable, range);
1562 impl->updateData(it->second, variable, range);
1452 }
1563 }
1453 }
1564 }
1454
1565
1455 void VisualizationGraphWidget::variableUpdated(QUuid id)
1566 void VisualizationGraphWidget::variableUpdated(QUuid id)
1456 {
1567 {
1457 for (auto &[var, plotables] : impl->m_VariableToPlotMultiMap) {
1568 for (auto& [var, plotables] : impl->m_VariableToPlotMultiMap)
1458 if (var->ID() == id) {
1569 {
1570 if (var->ID() == id)
1571 {
1459 impl->updateData(plotables, var, this->graphRange());
1572 impl->updateData(plotables, var, this->graphRange());
1460 }
1573 }
1461 }
1574 }
1462 }
1575 }
1463
1576
1464 void VisualizationGraphWidget::variableDeleted(const std::shared_ptr<Variable> & variable)
1577 void VisualizationGraphWidget::variableDeleted(const std::shared_ptr<Variable2>& variable)
1465 {
1578 {
1466 this->removeVariable(variable);
1579 this->removeVariable(variable);
1467 }
1580 }
@@ -17,7 +17,8
17
17
18 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
18 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
19
19
20 namespace {
20 namespace
21 {
21
22
22 /**
23 /**
23 * Applies a function to all zones of the tab represented by its layout
24 * Applies a function to all zones of the tab represented by its layout
@@ -25,12 +26,15 namespace {
25 * @param fun the function to apply to each zone
26 * @param fun the function to apply to each zone
26 */
27 */
27 template <typename Fun>
28 template <typename Fun>
28 void processZones(QLayout &layout, Fun fun)
29 void processZones(QLayout& layout, Fun fun)
29 {
30 {
30 for (auto i = 0; i < layout.count(); ++i) {
31 for (auto i = 0; i < layout.count(); ++i)
31 if (auto item = layout.itemAt(i)) {
32 {
33 if (auto item = layout.itemAt(i))
34 {
32 if (auto visualizationZoneWidget
35 if (auto visualizationZoneWidget
33 = qobject_cast<VisualizationZoneWidget *>(item->widget())) {
36 = qobject_cast<VisualizationZoneWidget*>(item->widget()))
37 {
34 fun(*visualizationZoneWidget);
38 fun(*visualizationZoneWidget);
35 }
39 }
36 }
40 }
@@ -39,15 +43,16 void processZones(QLayout &layout, Fun fun)
39
43
40 /// Generates a default name for a new zone, according to the number of zones already displayed in
44 /// Generates a default name for a new zone, according to the number of zones already displayed in
41 /// the tab
45 /// the tab
42 QString defaultZoneName(QLayout &layout)
46 QString defaultZoneName(QLayout& layout)
43 {
47 {
44 QSet<QString> existingNames;
48 QSet<QString> existingNames;
45 processZones(layout,
49 processZones(
46 [&existingNames](auto &zoneWidget) { existingNames.insert(zoneWidget.name()); });
50 layout, [&existingNames](auto& zoneWidget) { existingNames.insert(zoneWidget.name()); });
47
51
48 int zoneNum = 1;
52 int zoneNum = 1;
49 QString name;
53 QString name;
50 do {
54 do
55 {
51 name = QObject::tr("Zone ").append(QString::number(zoneNum));
56 name = QObject::tr("Zone ").append(QString::number(zoneNum));
52 ++zoneNum;
57 ++zoneNum;
53 } while (existingNames.contains(name));
58 } while (existingNames.contains(name));
@@ -57,8 +62,9 QString defaultZoneName(QLayout &layout)
57
62
58 } // namespace
63 } // namespace
59
64
60 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
65 struct VisualizationTabWidget::VisualizationTabWidgetPrivate
61 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
66 {
67 explicit VisualizationTabWidgetPrivate(const QString& name) : m_Name { name } {}
62
68
63 QString m_Name;
69 QString m_Name;
64
70
@@ -66,18 +72,18 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
66 std::unique_ptr<MacScrollBarStyle> m_MacScrollBarStyle = std::make_unique<MacScrollBarStyle>();
72 std::unique_ptr<MacScrollBarStyle> m_MacScrollBarStyle = std::make_unique<MacScrollBarStyle>();
67 #endif
73 #endif
68
74
69 void dropGraph(int index, VisualizationTabWidget *tabWidget);
75 void dropGraph(int index, VisualizationTabWidget* tabWidget);
70 void dropZone(int index, VisualizationTabWidget *tabWidget);
76 void dropZone(int index, VisualizationTabWidget* tabWidget);
71 void dropVariables(const std::vector<std::shared_ptr<Variable> > &variables, int index,
77 void dropVariables(const std::vector<std::shared_ptr<Variable2>>& variables, int index,
72 VisualizationTabWidget *tabWidget);
78 VisualizationTabWidget* tabWidget);
73 void dropProducts(const QVariantList &productsMetaData, int index,
79 void dropProducts(
74 VisualizationTabWidget *tabWidget);
80 const QVariantList& productsMetaData, int index, VisualizationTabWidget* tabWidget);
75 };
81 };
76
82
77 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
83 VisualizationTabWidget::VisualizationTabWidget(const QString& name, QWidget* parent)
78 : QWidget{parent},
84 : QWidget { parent }
79 ui{new Ui::VisualizationTabWidget},
85 , ui { new Ui::VisualizationTabWidget }
80 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
86 , impl { spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name) }
81 {
87 {
82 ui->setupUi(this);
88 ui->setupUi(this);
83
89
@@ -88,22 +94,22 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *par
88 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Zone, "Zone");
94 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Zone, "Zone");
89 ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 12);
95 ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 12);
90 ui->dragDropContainer->layout()->setSpacing(0);
96 ui->dragDropContainer->layout()->setSpacing(0);
91 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
97 ui->dragDropContainer->setMimeType(
92 VisualizationDragDropContainer::DropBehavior::Inserted);
98 MIME_TYPE_GRAPH, VisualizationDragDropContainer::DropBehavior::Inserted);
93 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
99 ui->dragDropContainer->setMimeType(
94 VisualizationDragDropContainer::DropBehavior::Inserted);
100 MIME_TYPE_ZONE, VisualizationDragDropContainer::DropBehavior::Inserted);
95 ui->dragDropContainer->setMimeType(MIME_TYPE_VARIABLE_LIST,
101 ui->dragDropContainer->setMimeType(
96 VisualizationDragDropContainer::DropBehavior::Inserted);
102 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::Inserted);
97 ui->dragDropContainer->setMimeType(MIME_TYPE_PRODUCT_LIST,
103 ui->dragDropContainer->setMimeType(
98 VisualizationDragDropContainer::DropBehavior::Inserted);
104 MIME_TYPE_PRODUCT_LIST, VisualizationDragDropContainer::DropBehavior::Inserted);
99
105
100 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
106 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
101 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
107 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(
102 ui->dragDropContainer);
108 mimeData, ui->dragDropContainer);
103 });
109 });
104
110
105 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
111 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
106 &VisualizationTabWidget::dropMimeData);
112 &VisualizationTabWidget::dropMimeData);
107
113
108 sqpApp->dragDropGuiController().addDragDropScrollArea(ui->scrollArea);
114 sqpApp->dragDropGuiController().addDragDropScrollArea(ui->scrollArea);
109
115
@@ -117,12 +123,12 VisualizationTabWidget::~VisualizationTabWidget()
117 delete ui;
123 delete ui;
118 }
124 }
119
125
120 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
126 void VisualizationTabWidget::addZone(VisualizationZoneWidget* zoneWidget)
121 {
127 {
122 ui->dragDropContainer->addDragWidget(zoneWidget);
128 ui->dragDropContainer->addDragWidget(zoneWidget);
123 }
129 }
124
130
125 void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget)
131 void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget* zoneWidget)
126 {
132 {
127 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
133 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
128 }
134 }
@@ -130,17 +136,18 void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zone
130 QStringList VisualizationTabWidget::availableZoneWidgets() const
136 QStringList VisualizationTabWidget::availableZoneWidgets() const
131 {
137 {
132 QStringList zones;
138 QStringList zones;
133 processZones(tabLayout(),
139 processZones(
134 [&zones](VisualizationZoneWidget &zoneWidget) { zones << zoneWidget.name(); });
140 tabLayout(), [&zones](VisualizationZoneWidget& zoneWidget) { zones << zoneWidget.name(); });
135
141
136 return zones;
142 return zones;
137 }
143 }
138
144
139 VisualizationZoneWidget *VisualizationTabWidget::getZoneWithName(const QString &zoneName)
145 VisualizationZoneWidget* VisualizationTabWidget::getZoneWithName(const QString& zoneName)
140 {
146 {
141 VisualizationZoneWidget *result = nullptr;
147 VisualizationZoneWidget* result = nullptr;
142 processZones(tabLayout(), [&zoneName, &result](VisualizationZoneWidget &zoneWidget) {
148 processZones(tabLayout(), [&zoneName, &result](VisualizationZoneWidget& zoneWidget) {
143 if (!result && zoneWidget.name() == zoneName) {
149 if (!result && zoneWidget.name() == zoneName)
150 {
144 result = &zoneWidget;
151 result = &zoneWidget;
145 }
152 }
146 });
153 });
@@ -148,13 +155,13 VisualizationZoneWidget *VisualizationTabWidget::getZoneWithName(const QString &
148 return result;
155 return result;
149 }
156 }
150
157
151 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
158 VisualizationZoneWidget* VisualizationTabWidget::createZone(std::shared_ptr<Variable2> variable)
152 {
159 {
153 return createZone({variable}, -1);
160 return createZone({ variable }, -1);
154 }
161 }
155
162
156 VisualizationZoneWidget *
163 VisualizationZoneWidget* VisualizationTabWidget::createZone(
157 VisualizationTabWidget::createZone(const std::vector<std::shared_ptr<Variable> > &variables, int index)
164 const std::vector<std::shared_ptr<Variable2>>& variables, int index)
158 {
165 {
159 auto zoneWidget = createEmptyZone(index);
166 auto zoneWidget = createEmptyZone(index);
160
167
@@ -164,40 +171,41 VisualizationTabWidget::createZone(const std::vector<std::shared_ptr<Variable> >
164 return zoneWidget;
171 return zoneWidget;
165 }
172 }
166
173
167 VisualizationZoneWidget *VisualizationTabWidget::createEmptyZone(int index)
174 VisualizationZoneWidget* VisualizationTabWidget::createEmptyZone(int index)
168 {
175 {
169 auto zoneWidget
176 auto zoneWidget
170 = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this};
177 = new VisualizationZoneWidget { defaultZoneName(*ui->dragDropContainer->layout()), this };
171 this->insertZone(index, zoneWidget);
178 this->insertZone(index, zoneWidget);
172
179
173 return zoneWidget;
180 return zoneWidget;
174 }
181 }
175
182
176 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
183 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor* visitor)
177 {
184 {
178 if (visitor) {
185 if (visitor)
186 {
179 visitor->visitEnter(this);
187 visitor->visitEnter(this);
180
188
181 // Apply visitor to zone children: widgets different from zones are not visited (no action)
189 // Apply visitor to zone children: widgets different from zones are not visited (no action)
182 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
190 processZones(tabLayout(),
183 zoneWidget.accept(visitor);
191 [visitor](VisualizationZoneWidget& zoneWidget) { zoneWidget.accept(visitor); });
184 });
185
192
186 visitor->visitLeave(this);
193 visitor->visitLeave(this);
187 }
194 }
188 else {
195 else
196 {
189 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
197 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
190 }
198 }
191 }
199 }
192
200
193 bool VisualizationTabWidget::canDrop(const Variable &variable) const
201 bool VisualizationTabWidget::canDrop(Variable2& variable) const
194 {
202 {
195 // A tab can always accomodate a variable
203 // A tab can always accomodate a variable
196 Q_UNUSED(variable);
204 Q_UNUSED(variable);
197 return true;
205 return true;
198 }
206 }
199
207
200 bool VisualizationTabWidget::contains(const Variable &variable) const
208 bool VisualizationTabWidget::contains(Variable2& variable) const
201 {
209 {
202 Q_UNUSED(variable);
210 Q_UNUSED(variable);
203 return false;
211 return false;
@@ -208,50 +216,56 QString VisualizationTabWidget::name() const
208 return impl->m_Name;
216 return impl->m_Name;
209 }
217 }
210
218
211 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
219 void VisualizationTabWidget::closeEvent(QCloseEvent* event)
212 {
220 {
213 // Closes zones in the tab
221 // Closes zones in the tab
214 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
222 processZones(tabLayout(), [](VisualizationZoneWidget& zoneWidget) { zoneWidget.close(); });
215
223
216 QWidget::closeEvent(event);
224 QWidget::closeEvent(event);
217 }
225 }
218
226
219 QLayout &VisualizationTabWidget::tabLayout() const noexcept
227 QLayout& VisualizationTabWidget::tabLayout() const noexcept
220 {
228 {
221 return *ui->dragDropContainer->layout();
229 return *ui->dragDropContainer->layout();
222 }
230 }
223
231
224 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
232 void VisualizationTabWidget::dropMimeData(int index, const QMimeData* mimeData)
225 {
233 {
226 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
234 if (mimeData->hasFormat(MIME_TYPE_GRAPH))
235 {
227 impl->dropGraph(index, this);
236 impl->dropGraph(index, this);
228 }
237 }
229 else if (mimeData->hasFormat(MIME_TYPE_ZONE)) {
238 else if (mimeData->hasFormat(MIME_TYPE_ZONE))
239 {
230 impl->dropZone(index, this);
240 impl->dropZone(index, this);
231 }
241 }
232 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
242 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST))
243 {
233 auto variables = sqpApp->variableController().variables(
244 auto variables = sqpApp->variableController().variables(
234 Variable::variablesIDs(mimeData->data(MIME_TYPE_VARIABLE_LIST)));
245 Variable2::IDs(mimeData->data(MIME_TYPE_VARIABLE_LIST)));
235 impl->dropVariables(variables, index, this);
246 impl->dropVariables(variables, index, this);
236 }
247 }
237 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
248 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST))
249 {
238 auto productsData = sqpApp->dataSourceController().productsDataForMimeData(
250 auto productsData = sqpApp->dataSourceController().productsDataForMimeData(
239 mimeData->data(MIME_TYPE_PRODUCT_LIST));
251 mimeData->data(MIME_TYPE_PRODUCT_LIST));
240 impl->dropProducts(productsData, index, this);
252 impl->dropProducts(productsData, index, this);
241 }
253 }
242 else {
254 else
255 {
243 qCWarning(LOG_VisualizationZoneWidget())
256 qCWarning(LOG_VisualizationZoneWidget())
244 << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received.");
257 << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received.");
245 }
258 }
246 }
259 }
247
260
248 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
261 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
249 int index, VisualizationTabWidget *tabWidget)
262 int index, VisualizationTabWidget* tabWidget)
250 {
263 {
251 auto &helper = sqpApp->dragDropGuiController();
264 auto& helper = sqpApp->dragDropGuiController();
252
265
253 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
266 auto graphWidget = qobject_cast<VisualizationGraphWidget*>(helper.getCurrentDragWidget());
254 if (!graphWidget) {
267 if (!graphWidget)
268 {
255 qCWarning(LOG_VisualizationZoneWidget())
269 qCWarning(LOG_VisualizationZoneWidget())
256 << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not "
270 << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not "
257 "found or invalid.");
271 "found or invalid.");
@@ -260,8 +274,9 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
260 }
274 }
261
275
262 auto parentDragDropContainer
276 auto parentDragDropContainer
263 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
277 = qobject_cast<VisualizationDragDropContainer*>(graphWidget->parentWidget());
264 if (!parentDragDropContainer) {
278 if (!parentDragDropContainer)
279 {
265 qCWarning(LOG_VisualizationZoneWidget())
280 qCWarning(LOG_VisualizationZoneWidget())
266 << tr("VisualizationTabWidget::dropGraph, drop aborted, the parent container of "
281 << tr("VisualizationTabWidget::dropGraph, drop aborted, the parent container of "
267 "the dropped graph is not found.");
282 "the dropped graph is not found.");
@@ -271,9 +286,10 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
271
286
272 auto nbGraph = parentDragDropContainer->countDragWidget();
287 auto nbGraph = parentDragDropContainer->countDragWidget();
273
288
274 const auto &variables = graphWidget->variables();
289 const auto& variables = graphWidget->variables();
275
290
276 if (!variables.empty()) {
291 if (!variables.empty())
292 {
277 // Abort the requests for the variables (if any)
293 // Abort the requests for the variables (if any)
278 // Commented, because it's not sure if it's needed or not
294 // Commented, because it's not sure if it's needed or not
279 // for (const auto& var : variables)
295 // for (const auto& var : variables)
@@ -281,27 +297,32 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
281 // sqpApp->variableController().onAbortProgressRequested(var);
297 // sqpApp->variableController().onAbortProgressRequested(var);
282 //}
298 //}
283
299
284 if (nbGraph == 1) {
300 if (nbGraph == 1)
301 {
285 // This is the only graph in the previous zone, close the zone
302 // This is the only graph in the previous zone, close the zone
286 helper.delayedCloseWidget(graphWidget->parentZoneWidget());
303 helper.delayedCloseWidget(graphWidget->parentZoneWidget());
287 }
304 }
288 else {
305 else
306 {
289 // Close the graph
307 // Close the graph
290 helper.delayedCloseWidget(graphWidget);
308 helper.delayedCloseWidget(graphWidget);
291 }
309 }
292
310
293 auto zoneWidget = tabWidget->createZone(variables, index);
311 auto zoneWidget = tabWidget->createZone(variables, index);
294 auto firstGraph = zoneWidget->firstGraph();
312 auto firstGraph = zoneWidget->firstGraph();
295 if (firstGraph) {
313 if (firstGraph)
314 {
296 firstGraph->addSelectionZones(graphWidget->selectionZoneRanges());
315 firstGraph->addSelectionZones(graphWidget->selectionZoneRanges());
297 }
316 }
298 else {
317 else
318 {
299 qCWarning(LOG_VisualizationZoneWidget())
319 qCWarning(LOG_VisualizationZoneWidget())
300 << tr("VisualizationTabWidget::dropGraph, no graph added in the widget.");
320 << tr("VisualizationTabWidget::dropGraph, no graph added in the widget.");
301 Q_ASSERT(false);
321 Q_ASSERT(false);
302 }
322 }
303 }
323 }
304 else {
324 else
325 {
305 // The graph is empty, create an empty zone and move the graph inside
326 // The graph is empty, create an empty zone and move the graph inside
306
327
307 auto parentZoneWidget = graphWidget->parentZoneWidget();
328 auto parentZoneWidget = graphWidget->parentZoneWidget();
@@ -312,19 +333,21 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
312 zoneWidget->addGraph(graphWidget);
333 zoneWidget->addGraph(graphWidget);
313
334
314 // Close the old zone if it was the only graph inside
335 // Close the old zone if it was the only graph inside
315 if (nbGraph == 1) {
336 if (nbGraph == 1)
337 {
316 helper.delayedCloseWidget(parentZoneWidget);
338 helper.delayedCloseWidget(parentZoneWidget);
317 }
339 }
318 }
340 }
319 }
341 }
320
342
321 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
343 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
322 int index, VisualizationTabWidget *tabWidget)
344 int index, VisualizationTabWidget* tabWidget)
323 {
345 {
324 auto &helper = sqpApp->dragDropGuiController();
346 auto& helper = sqpApp->dragDropGuiController();
325
347
326 auto zoneWidget = qobject_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget());
348 auto zoneWidget = qobject_cast<VisualizationZoneWidget*>(helper.getCurrentDragWidget());
327 if (!zoneWidget) {
349 if (!zoneWidget)
350 {
328 qCWarning(LOG_VisualizationZoneWidget())
351 qCWarning(LOG_VisualizationZoneWidget())
329 << tr("VisualizationTabWidget::dropZone, drop aborted, the dropped zone is not "
352 << tr("VisualizationTabWidget::dropZone, drop aborted, the dropped zone is not "
330 "found or invalid.");
353 "found or invalid.");
@@ -333,8 +356,9 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
333 }
356 }
334
357
335 auto parentDragDropContainer
358 auto parentDragDropContainer
336 = qobject_cast<VisualizationDragDropContainer *>(zoneWidget->parentWidget());
359 = qobject_cast<VisualizationDragDropContainer*>(zoneWidget->parentWidget());
337 if (!parentDragDropContainer) {
360 if (!parentDragDropContainer)
361 {
338 qCWarning(LOG_VisualizationZoneWidget())
362 qCWarning(LOG_VisualizationZoneWidget())
339 << tr("VisualizationTabWidget::dropZone, drop aborted, the parent container of "
363 << tr("VisualizationTabWidget::dropZone, drop aborted, the parent container of "
340 "the dropped zone is not found.");
364 "the dropped zone is not found.");
@@ -348,12 +372,13 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
348 }
372 }
349
373
350 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables(
374 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables(
351 const std::vector<std::shared_ptr<Variable> > &variables, int index,
375 const std::vector<std::shared_ptr<Variable2>>& variables, int index,
352 VisualizationTabWidget *tabWidget)
376 VisualizationTabWidget* tabWidget)
353 {
377 {
354 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
378 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
355 // compatible variable here
379 // compatible variable here
356 if (variables.size() > 1) {
380 if (variables.size() > 1)
381 {
357 qCWarning(LOG_VisualizationZoneWidget())
382 qCWarning(LOG_VisualizationZoneWidget())
358 << tr("VisualizationTabWidget::dropVariables, dropping multiple variables, operation "
383 << tr("VisualizationTabWidget::dropVariables, dropping multiple variables, operation "
359 "aborted.");
384 "aborted.");
@@ -364,26 +389,27 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables(
364 }
389 }
365
390
366 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropProducts(
391 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropProducts(
367 const QVariantList &productsMetaData, int index, VisualizationTabWidget *tabWidget)
392 const QVariantList& productsMetaData, int index, VisualizationTabWidget* tabWidget)
368 {
393 {
369 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
394 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
370 // compatible variable here
395 // compatible variable here
371 if (productsMetaData.count() != 1) {
396 if (productsMetaData.count() != 1)
397 {
372 qCWarning(LOG_VisualizationZoneWidget())
398 qCWarning(LOG_VisualizationZoneWidget())
373 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
399 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
374 "aborted.");
400 "aborted.");
375 return;
401 return;
376 }
402 }
377
403
378 auto context = new QObject{tabWidget};
404 auto context = new QObject { tabWidget };
379 connect(&sqpApp->variableController(), &VariableController2::variableAdded, context,
405 connect(&sqpApp->variableController(), &VariableController2::variableAdded, context,
380 [this, index, tabWidget, context](auto variable) {
406 [this, index, tabWidget, context](auto variable) {
381 tabWidget->createZone({variable}, index);
407 tabWidget->createZone({ variable }, index);
382 delete context; // removes the connection
408 delete context; // removes the connection
383 },
409 },
384 Qt::QueuedConnection);
410 Qt::QueuedConnection);
385
411
386 auto productData = productsMetaData.first().toHash();
412 auto productData = productsMetaData.first().toHash();
387 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
413 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
388 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
414 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
389 }
415 }
@@ -23,7 +23,8
23
23
24 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
24 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
25
25
26 struct VisualizationWidget::VisualizationWidgetPrivate {
26 struct VisualizationWidget::VisualizationWidgetPrivate
27 {
27 std::unique_ptr<VisualizationSelectionZoneManager> m_ZoneSelectionManager = nullptr;
28 std::unique_ptr<VisualizationSelectionZoneManager> m_ZoneSelectionManager = nullptr;
28 VisualizationActionManager m_ActionManager;
29 VisualizationActionManager m_ActionManager;
29
30
@@ -33,20 +34,19 struct VisualizationWidget::VisualizationWidgetPrivate {
33 }
34 }
34 };
35 };
35
36
36 VisualizationWidget::VisualizationWidget(QWidget *parent)
37 VisualizationWidget::VisualizationWidget(QWidget* parent)
37 : QWidget{parent},
38 : QWidget { parent }
38 ui{new Ui::VisualizationWidget},
39 , ui { new Ui::VisualizationWidget }
39 impl{spimpl::make_unique_impl<VisualizationWidgetPrivate>()}
40 , impl { spimpl::make_unique_impl<VisualizationWidgetPrivate>() }
40 {
41 {
41 ui->setupUi(this);
42 ui->setupUi(this);
42
43
43 auto addTabViewButton = new QToolButton{ui->tabWidget};
44 auto addTabViewButton = new QToolButton { ui->tabWidget };
44 addTabViewButton->setText(tr("Add View"));
45 addTabViewButton->setText(tr("Add View"));
45 addTabViewButton->setCursor(Qt::ArrowCursor);
46 addTabViewButton->setCursor(Qt::ArrowCursor);
46 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
47 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
47
48
48 auto enableMinimumCornerWidgetSize = [this](bool enable) {
49 auto enableMinimumCornerWidgetSize = [this](bool enable) {
49
50 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
50 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
51 auto width = enable ? tabViewCornerWidget->width() : 0;
51 auto width = enable ? tabViewCornerWidget->width() : 0;
52 auto height = enable ? tabViewCornerWidget->height() : 0;
52 auto height = enable ? tabViewCornerWidget->height() : 0;
@@ -57,29 +57,32 VisualizationWidget::VisualizationWidget(QWidget *parent)
57 };
57 };
58
58
59 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
59 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
60 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
60 auto widget
61 ui->tabWidget};
61 = new VisualizationTabWidget { QString { "View %1" }.arg(ui->tabWidget->count() + 1),
62 ui->tabWidget };
62 auto index = ui->tabWidget->addTab(widget, widget->name());
63 auto index = ui->tabWidget->addTab(widget, widget->name());
63 if (ui->tabWidget->count() > 0) {
64 if (ui->tabWidget->count() > 0)
65 {
64 enableMinimumCornerWidgetSize(false);
66 enableMinimumCornerWidgetSize(false);
65 }
67 }
66 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
68 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
67 };
69 };
68
70
69 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
71 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
70 if (ui->tabWidget->count() == 1) {
72 if (ui->tabWidget->count() == 1)
73 {
71 enableMinimumCornerWidgetSize(true);
74 enableMinimumCornerWidgetSize(true);
72 }
75 }
73
76
74 // Removes widget from tab and closes it
77 // Removes widget from tab and closes it
75 auto widget = ui->tabWidget->widget(index);
78 auto widget = ui->tabWidget->widget(index);
76 ui->tabWidget->removeTab(index);
79 ui->tabWidget->removeTab(index);
77 if (widget) {
80 if (widget)
81 {
78 widget->close();
82 widget->close();
79 }
83 }
80
84
81 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
85 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
82
83 };
86 };
84
87
85 ui->tabWidget->setTabsClosable(true);
88 ui->tabWidget->setTabsClosable(true);
@@ -96,8 +99,10 VisualizationWidget::VisualizationWidget(QWidget *parent)
96 removeZoneAction->setShortcut(QKeySequence::Delete);
99 removeZoneAction->setShortcut(QKeySequence::Delete);
97 connect(removeZoneAction, &QAction::triggered, [this]() {
100 connect(removeZoneAction, &QAction::triggered, [this]() {
98 auto selection = impl->m_ZoneSelectionManager->selectedItems();
101 auto selection = impl->m_ZoneSelectionManager->selectedItems();
99 for (auto selectionZone : selection) {
102 for (auto selectionZone : selection)
100 if (auto graph = selectionZone->parentGraphWidget()) {
103 {
104 if (auto graph = selectionZone->parentGraphWidget())
105 {
101 graph->removeSelectionZone(selectionZone);
106 graph->removeSelectionZone(selectionZone);
102 }
107 }
103 }
108 }
@@ -114,49 +119,54 VisualizationWidget::~VisualizationWidget()
114 delete ui;
119 delete ui;
115 }
120 }
116
121
117 VisualizationSelectionZoneManager &VisualizationWidget::selectionZoneManager() const
122 VisualizationSelectionZoneManager& VisualizationWidget::selectionZoneManager() const
118 {
123 {
119 return *impl->m_ZoneSelectionManager.get();
124 return *impl->m_ZoneSelectionManager.get();
120 }
125 }
121
126
122 VisualizationTabWidget *VisualizationWidget::currentTabWidget() const
127 VisualizationTabWidget* VisualizationWidget::currentTabWidget() const
123 {
128 {
124 if (auto tab = qobject_cast<VisualizationTabWidget *>(ui->tabWidget->currentWidget())) {
129 if (auto tab = qobject_cast<VisualizationTabWidget*>(ui->tabWidget->currentWidget()))
130 {
125 return tab;
131 return tab;
126 }
132 }
127
133
128 return nullptr;
134 return nullptr;
129 }
135 }
130
136
131 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
137 void VisualizationWidget::accept(IVisualizationWidgetVisitor* visitor)
132 {
138 {
133 if (visitor) {
139 if (visitor)
140 {
134 visitor->visitEnter(this);
141 visitor->visitEnter(this);
135
142
136 // Apply visitor for tab children
143 // Apply visitor for tab children
137 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
144 for (auto i = 0; i < ui->tabWidget->count(); ++i)
145 {
138 // Widgets different from tabs are not visited (no action)
146 // Widgets different from tabs are not visited (no action)
139 if (auto visualizationTabWidget
147 if (auto visualizationTabWidget
140 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
148 = dynamic_cast<VisualizationTabWidget*>(ui->tabWidget->widget(i)))
149 {
141 visualizationTabWidget->accept(visitor);
150 visualizationTabWidget->accept(visitor);
142 }
151 }
143 }
152 }
144
153
145 visitor->visitLeave(this);
154 visitor->visitLeave(this);
146 }
155 }
147 else {
156 else
157 {
148 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
158 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
149 }
159 }
150 }
160 }
151
161
152 bool VisualizationWidget::canDrop(const Variable &variable) const
162 bool VisualizationWidget::canDrop(Variable2& variable) const
153 {
163 {
154 // The main widget can never accomodate a variable
164 // The main widget can never accomodate a variable
155 Q_UNUSED(variable);
165 Q_UNUSED(variable);
156 return false;
166 return false;
157 }
167 }
158
168
159 bool VisualizationWidget::contains(const Variable &variable) const
169 bool VisualizationWidget::contains(Variable2& variable) const
160 {
170 {
161 Q_UNUSED(variable);
171 Q_UNUSED(variable);
162 return false;
172 return false;
@@ -168,54 +178,60 QString VisualizationWidget::name() const
168 }
178 }
169
179
170 void VisualizationWidget::attachVariableMenu(
180 void VisualizationWidget::attachVariableMenu(
171 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
181 QMenu* menu, const QVector<std::shared_ptr<Variable2>>& variables) noexcept
172 {
182 {
173 // Menu is generated only if there is a single variable
183 // Menu is generated only if there is a single variable
174 if (variables.size() == 1) {
184 if (variables.size() == 1)
175 if (auto variable = variables.first()) {
185 {
186 if (auto variable = variables.first())
187 {
176 // Gets the containers of the variable
188 // Gets the containers of the variable
177 FindVariableOperation findVariableOperation{variable};
189 FindVariableOperation findVariableOperation { variable };
178 accept(&findVariableOperation);
190 accept(&findVariableOperation);
179 auto variableContainers = findVariableOperation.result();
191 auto variableContainers = findVariableOperation.result();
180
192
181 // Generates the actions that make it possible to visualize the variable
193 // Generates the actions that make it possible to visualize the variable
182 GenerateVariableMenuOperation generateVariableMenuOperation{
194 GenerateVariableMenuOperation generateVariableMenuOperation { menu, variable,
183 menu, variable, std::move(variableContainers)};
195 std::move(variableContainers) };
184 accept(&generateVariableMenuOperation);
196 accept(&generateVariableMenuOperation);
185 }
197 }
186 else {
198 else
199 {
187 qCCritical(LOG_VisualizationWidget()) << tr(
200 qCCritical(LOG_VisualizationWidget()) << tr(
188 "Can't generate the menu relative to the visualization: the variable is null");
201 "Can't generate the menu relative to the visualization: the variable is null");
189 }
202 }
190 }
203 }
191 else {
204 else
205 {
192 qCDebug(LOG_VisualizationWidget())
206 qCDebug(LOG_VisualizationWidget())
193 << tr("No generation of the menu related to the visualization: several variables are "
207 << tr("No generation of the menu related to the visualization: several variables are "
194 "selected");
208 "selected");
195 }
209 }
196 }
210 }
197
211
198 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
212 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable2> variable) noexcept
199 {
213 {
200 // Calls the operation of removing all references to the variable in the visualization
214 // Calls the operation of removing all references to the variable in the visualization
201 auto removeVariableOperation = RemoveVariableOperation{variable};
215 auto removeVariableOperation = RemoveVariableOperation { variable };
202 accept(&removeVariableOperation);
216 accept(&removeVariableOperation);
203 }
217 }
204
218
205 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
219 void VisualizationWidget::onRangeChanged(
206 const DateTimeRange &range) noexcept
220 std::shared_ptr<Variable2> variable, const DateTimeRange& range) noexcept
207 {
221 {
208 // Calls the operation of rescaling all graph that contrains variable in the visualization
222 // Calls the operation of rescaling all graph that contrains variable in the visualization
209 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
223 auto rescaleVariableOperation = RescaleAxeOperation { variable, range };
210 accept(&rescaleVariableOperation);
224 accept(&rescaleVariableOperation);
211 }
225 }
212
226
213 void VisualizationWidget::closeEvent(QCloseEvent *event)
227 void VisualizationWidget::closeEvent(QCloseEvent* event)
214 {
228 {
215 // Closes tabs in the widget
229 // Closes tabs in the widget
216 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
230 for (auto i = 0; i < ui->tabWidget->count(); ++i)
231 {
217 if (auto visualizationTabWidget
232 if (auto visualizationTabWidget
218 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
233 = dynamic_cast<VisualizationTabWidget*>(ui->tabWidget->widget(i)))
234 {
219 visualizationTabWidget->close();
235 visualizationTabWidget->close();
220 }
236 }
221 }
237 }
This diff has been collapsed as it changes many lines, (553 lines changed) Show them Hide them
@@ -13,7 +13,7
13 #include <Data/DateTimeRangeHelper.h>
13 #include <Data/DateTimeRangeHelper.h>
14 #include <DataSource/DataSourceController.h>
14 #include <DataSource/DataSourceController.h>
15 #include <Time/TimeController.h>
15 #include <Time/TimeController.h>
16 #include <Variable/Variable.h>
16 #include <Variable/Variable2.h>
17 #include <Variable/VariableController2.h>
17 #include <Variable/VariableController2.h>
18
18
19 #include <Visualization/operations/FindVariableOperation.h>
19 #include <Visualization/operations/FindVariableOperation.h>
@@ -28,7 +28,8
28
28
29 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
29 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
30
30
31 namespace {
31 namespace
32 {
32
33
33 /**
34 /**
34 * Applies a function to all graphs of the zone represented by its layout
35 * Applies a function to all graphs of the zone represented by its layout
@@ -36,12 +37,15 namespace {
36 * @param fun the function to apply to each graph
37 * @param fun the function to apply to each graph
37 */
38 */
38 template <typename Fun>
39 template <typename Fun>
39 void processGraphs(QLayout &layout, Fun fun)
40 void processGraphs(QLayout& layout, Fun fun)
40 {
41 {
41 for (auto i = 0; i < layout.count(); ++i) {
42 for (auto i = 0; i < layout.count(); ++i)
42 if (auto item = layout.itemAt(i)) {
43 {
44 if (auto item = layout.itemAt(i))
45 {
43 if (auto visualizationGraphWidget
46 if (auto visualizationGraphWidget
44 = qobject_cast<VisualizationGraphWidget *>(item->widget())) {
47 = qobject_cast<VisualizationGraphWidget*>(item->widget()))
48 {
45 fun(*visualizationGraphWidget);
49 fun(*visualizationGraphWidget);
46 }
50 }
47 }
51 }
@@ -50,15 +54,16 void processGraphs(QLayout &layout, Fun fun)
50
54
51 /// Generates a default name for a new graph, according to the number of graphs already displayed in
55 /// Generates a default name for a new graph, according to the number of graphs already displayed in
52 /// the zone
56 /// the zone
53 QString defaultGraphName(QLayout &layout)
57 QString defaultGraphName(QLayout& layout)
54 {
58 {
55 QSet<QString> existingNames;
59 QSet<QString> existingNames;
56 processGraphs(
60 processGraphs(
57 layout, [&existingNames](auto &graphWidget) { existingNames.insert(graphWidget.name()); });
61 layout, [&existingNames](auto& graphWidget) { existingNames.insert(graphWidget.name()); });
58
62
59 int zoneNum = 1;
63 int zoneNum = 1;
60 QString name;
64 QString name;
61 do {
65 do
66 {
62 name = QObject::tr("Graph ").append(QString::number(zoneNum));
67 name = QObject::tr("Graph ").append(QString::number(zoneNum));
63 ++zoneNum;
68 ++zoneNum;
64 } while (existingNames.contains(name));
69 } while (existingNames.contains(name));
@@ -68,65 +73,70 QString defaultGraphName(QLayout &layout)
68
73
69 } // namespace
74 } // namespace
70
75
71 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
76 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate
77 {
72
78
73 explicit VisualizationZoneWidgetPrivate()
79 explicit VisualizationZoneWidgetPrivate()
74 : m_SynchronisationGroupId{QUuid::createUuid()},
80 : m_SynchronisationGroupId { QUuid::createUuid() }
75 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
81 , m_Synchronizer { std::make_unique<QCustomPlotSynchronizer>() }
76 {
82 {
77 }
83 }
78 QUuid m_SynchronisationGroupId;
84 QUuid m_SynchronisationGroupId;
79 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
85 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
80
86
81 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
87 void dropGraph(int index, VisualizationZoneWidget* zoneWidget);
82 void dropVariables(const std::vector<std::shared_ptr<Variable> > &variables, int index,
88 void dropVariables(const std::vector<std::shared_ptr<Variable2>>& variables, int index,
83 VisualizationZoneWidget *zoneWidget);
89 VisualizationZoneWidget* zoneWidget);
84 void dropProducts(const QVariantList &productsData, int index,
90 void dropProducts(
85 VisualizationZoneWidget *zoneWidget);
91 const QVariantList& productsData, int index, VisualizationZoneWidget* zoneWidget);
86 };
92 };
87
93
88 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
94 VisualizationZoneWidget::VisualizationZoneWidget(const QString& name, QWidget* parent)
89 : VisualizationDragWidget{parent},
95 : VisualizationDragWidget { parent }
90 ui{new Ui::VisualizationZoneWidget},
96 , ui { new Ui::VisualizationZoneWidget }
91 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
97 , impl { spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>() }
92 {
98 {
93 ui->setupUi(this);
99 ui->setupUi(this);
94
100
95 ui->zoneNameLabel->setText(name);
101 ui->zoneNameLabel->setText(name);
96
102
97 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Graph);
103 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Graph);
98 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
104 ui->dragDropContainer->setMimeType(
99 VisualizationDragDropContainer::DropBehavior::Inserted);
105 MIME_TYPE_GRAPH, VisualizationDragDropContainer::DropBehavior::Inserted);
100 ui->dragDropContainer->setMimeType(
106 ui->dragDropContainer->setMimeType(
101 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
107 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
102 ui->dragDropContainer->setMimeType(
108 ui->dragDropContainer->setMimeType(
103 MIME_TYPE_PRODUCT_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
109 MIME_TYPE_PRODUCT_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
104 ui->dragDropContainer->setMimeType(MIME_TYPE_TIME_RANGE,
110 ui->dragDropContainer->setMimeType(
105 VisualizationDragDropContainer::DropBehavior::Merged);
111 MIME_TYPE_TIME_RANGE, VisualizationDragDropContainer::DropBehavior::Merged);
106 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
112 ui->dragDropContainer->setMimeType(
107 VisualizationDragDropContainer::DropBehavior::Forbidden);
113 MIME_TYPE_ZONE, VisualizationDragDropContainer::DropBehavior::Forbidden);
108 ui->dragDropContainer->setMimeType(MIME_TYPE_SELECTION_ZONE,
114 ui->dragDropContainer->setMimeType(
109 VisualizationDragDropContainer::DropBehavior::Forbidden);
115 MIME_TYPE_SELECTION_ZONE, VisualizationDragDropContainer::DropBehavior::Forbidden);
110 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
116 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
111 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
117 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(
112 ui->dragDropContainer);
118 mimeData, ui->dragDropContainer);
113 });
119 });
114
120
115 auto acceptDragWidgetFun = [](auto dragWidget, auto mimeData) {
121 auto acceptDragWidgetFun = [](auto dragWidget, auto mimeData) {
116 if (!mimeData) {
122 if (!mimeData)
123 {
117 return false;
124 return false;
118 }
125 }
119
126
120 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
127 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST))
128 {
121 auto variables = sqpApp->variableController().variables(
129 auto variables = sqpApp->variableController().variables(
122 Variable::variablesIDs(mimeData->data(MIME_TYPE_VARIABLE_LIST)));
130 Variable2::IDs(mimeData->data(MIME_TYPE_VARIABLE_LIST)));
123
131
124 if (variables.size() != 1) {
132 if (variables.size() != 1)
133 {
125 return false;
134 return false;
126 }
135 }
127 auto variable = variables.front();
136 auto variable = variables.front();
128
137
129 if (auto graphWidget = dynamic_cast<const VisualizationGraphWidget *>(dragWidget)) {
138 if (auto graphWidget = dynamic_cast<const VisualizationGraphWidget*>(dragWidget))
139 {
130 return graphWidget->canDrop(*variable);
140 return graphWidget->canDrop(*variable);
131 }
141 }
132 }
142 }
@@ -136,9 +146,9 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p
136 ui->dragDropContainer->setAcceptDragWidgetFunction(acceptDragWidgetFun);
146 ui->dragDropContainer->setAcceptDragWidgetFunction(acceptDragWidgetFun);
137
147
138 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
148 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
139 &VisualizationZoneWidget::dropMimeData);
149 &VisualizationZoneWidget::dropMimeData);
140 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredOnWidget, this,
150 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredOnWidget, this,
141 &VisualizationZoneWidget::dropMimeDataOnGraph);
151 &VisualizationZoneWidget::dropMimeDataOnGraph);
142
152
143 // 'Close' options : widget is deleted when closed
153 // 'Close' options : widget is deleted when closed
144 setAttribute(Qt::WA_DeleteOnClose);
154 setAttribute(Qt::WA_DeleteOnClose);
@@ -146,8 +156,8 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p
146 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
156 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
147
157
148 // Synchronisation id
158 // Synchronisation id
149 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
159 // QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
150 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
160 // Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
151 }
161 }
152
162
153 VisualizationZoneWidget::~VisualizationZoneWidget()
163 VisualizationZoneWidget::~VisualizationZoneWidget()
@@ -155,60 +165,55 VisualizationZoneWidget::~VisualizationZoneWidget()
155 delete ui;
165 delete ui;
156 }
166 }
157
167
158 void VisualizationZoneWidget::setZoneRange(const DateTimeRange &range)
168 void VisualizationZoneWidget::setZoneRange(const DateTimeRange& range)
159 {
169 {
160 if (auto graph = firstGraph()) {
170 if (auto graph = firstGraph())
171 {
161 graph->setGraphRange(range);
172 graph->setGraphRange(range);
162 }
173 }
163 else {
174 else
175 {
164 qCWarning(LOG_VisualizationZoneWidget())
176 qCWarning(LOG_VisualizationZoneWidget())
165 << tr("setZoneRange:Cannot set the range of an empty zone.");
177 << tr("setZoneRange:Cannot set the range of an empty zone.");
166 }
178 }
167 }
179 }
168
180
169 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
181 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget* graphWidget)
170 {
182 {
171 // Synchronize new graph with others in the zone
183 // Synchronize new graph with others in the zone
172 // impl->m_Synchronizer->addGraph(*graphWidget);
184 // impl->m_Synchronizer->addGraph(*graphWidget);
173
174 // ui->dragDropContainer->addDragWidget(graphWidget);
175 insertGraph(0,graphWidget);
176
185
186 // ui->dragDropContainer->addDragWidget(graphWidget);
187 insertGraph(0, graphWidget);
177 }
188 }
178
189
179 void VisualizationZoneWidget::insertGraph(int index, VisualizationGraphWidget *graphWidget)
190 void VisualizationZoneWidget::insertGraph(int index, VisualizationGraphWidget* graphWidget)
180 {
191 {
181 DEPRECATE(
192 DEPRECATE(
182 auto layout = ui->dragDropContainer->layout();
193 auto layout = ui->dragDropContainer->layout(); for (int i = 0; i < layout->count(); i++) {
183 for(int i=0;i<layout->count();i++)
194 auto graph = qobject_cast<VisualizationGraphWidget*>(layout->itemAt(i)->widget());
184 {
195 connect(graphWidget, &VisualizationGraphWidget::setrange_sig, graph,
185 auto graph = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(i)->widget());
196 &VisualizationGraphWidget::setGraphRange);
186 connect(graphWidget, &VisualizationGraphWidget::setrange_sig, graph, &VisualizationGraphWidget::setGraphRange);
197 connect(graph, &VisualizationGraphWidget::setrange_sig, graphWidget,
187 connect(graph, &VisualizationGraphWidget::setrange_sig, graphWidget, &VisualizationGraphWidget::setGraphRange);
198 &VisualizationGraphWidget::setGraphRange);
188 }
199 } if (auto graph = firstGraph()) { graphWidget->setGraphRange(graph->graphRange(), true); })
189 if(auto graph = firstGraph())
190 {
191 graphWidget->setGraphRange(graph->graphRange(), true);
192 }
193 )
194
200
195 // Synchronize new graph with others in the zone
201 // Synchronize new graph with others in the zone
196 impl->m_Synchronizer->addGraph(*graphWidget);
202 impl->m_Synchronizer->addGraph(*graphWidget);
197
203
198 ui->dragDropContainer->insertDragWidget(index, graphWidget);
204 ui->dragDropContainer->insertDragWidget(index, graphWidget);
199
200 }
205 }
201
206
202 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
207 VisualizationGraphWidget* VisualizationZoneWidget::createGraph(std::shared_ptr<Variable2> variable)
203 {
208 {
204 return createGraph(variable, -1);
209 return createGraph(variable, -1);
205 }
210 }
206
211
207 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable,
212 VisualizationGraphWidget* VisualizationZoneWidget::createGraph(
208 int index)
213 std::shared_ptr<Variable2> variable, int index)
209 {
214 {
210 auto graphWidget
215 auto graphWidget
211 = new VisualizationGraphWidget{defaultGraphName(*ui->dragDropContainer->layout()), this};
216 = new VisualizationGraphWidget { defaultGraphName(*ui->dragDropContainer->layout()), this };
212
217
213
218
214 // Set graph properties
219 // Set graph properties
@@ -217,76 +222,79 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
217
222
218
223
219 // Lambda to synchronize zone widget
224 // Lambda to synchronize zone widget
220 // auto synchronizeZoneWidget = [this, graphWidget](const DateTimeRange &graphRange,
225 // auto synchronizeZoneWidget = [this, graphWidget](const DateTimeRange &graphRange,
221 // const DateTimeRange &oldGraphRange) {
226 // const DateTimeRange &oldGraphRange) {
222
227
223 // auto zoomType = DateTimeRangeHelper::getTransformationType(oldGraphRange, graphRange);
228 // auto zoomType = DateTimeRangeHelper::getTransformationType(oldGraphRange, graphRange);
224 // auto frameLayout = ui->dragDropContainer->layout();
229 // auto frameLayout = ui->dragDropContainer->layout();
225 // for (auto i = 0; i < frameLayout->count(); ++i) {
230 // for (auto i = 0; i < frameLayout->count(); ++i) {
226 // auto graphChild
231 // auto graphChild
227 // = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
232 // = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
228 // if (graphChild && (graphChild != graphWidget)) {
233 // if (graphChild && (graphChild != graphWidget)) {
229
234
230 // auto graphChildRange = graphChild->graphRange();
235 // auto graphChildRange = graphChild->graphRange();
231 // switch (zoomType) {
236 // switch (zoomType) {
232 // case TransformationType::ZoomIn: {
237 // case TransformationType::ZoomIn: {
233 // auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
238 // auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
234 // auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
239 // auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
235 // graphChildRange.m_TStart += deltaLeft;
240 // graphChildRange.m_TStart += deltaLeft;
236 // graphChildRange.m_TEnd -= deltaRight;
241 // graphChildRange.m_TEnd -= deltaRight;
237 // break;
242 // break;
238 // }
243 // }
239
244
240 // case TransformationType::ZoomOut: {
245 // case TransformationType::ZoomOut: {
241 // auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
246 // auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
242 // auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
247 // auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
243 // graphChildRange.m_TStart -= deltaLeft;
248 // graphChildRange.m_TStart -= deltaLeft;
244 // graphChildRange.m_TEnd += deltaRight;
249 // graphChildRange.m_TEnd += deltaRight;
245 // break;
250 // break;
246 // }
251 // }
247 // case TransformationType::PanRight: {
252 // case TransformationType::PanRight: {
248 // auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
253 // auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
249 // auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
254 // auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
250 // graphChildRange.m_TStart += deltaLeft;
255 // graphChildRange.m_TStart += deltaLeft;
251 // graphChildRange.m_TEnd += deltaRight;
256 // graphChildRange.m_TEnd += deltaRight;
252 // break;
257 // break;
253 // }
258 // }
254 // case TransformationType::PanLeft: {
259 // case TransformationType::PanLeft: {
255 // auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
260 // auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
256 // auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
261 // auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
257 // graphChildRange.m_TStart -= deltaLeft;
262 // graphChildRange.m_TStart -= deltaLeft;
258 // graphChildRange.m_TEnd -= deltaRight;
263 // graphChildRange.m_TEnd -= deltaRight;
259 // break;
264 // break;
260 // }
265 // }
261 // case TransformationType::Unknown: {
266 // case TransformationType::Unknown: {
262 // break;
267 // break;
263 // }
268 // }
264 // default:
269 // default:
265 // qCCritical(LOG_VisualizationZoneWidget())
270 // qCCritical(LOG_VisualizationZoneWidget())
266 // << tr("Impossible to synchronize: zoom type not take into account");
271 // << tr("Impossible to synchronize: zoom type not take into
267 // // No action
272 // account");
268 // break;
273 // // No action
269 // }
274 // break;
270 // graphChild->setFlags(GraphFlag::DisableAll);
275 // }
271 // graphChild->setGraphRange(graphChildRange, true);
276 // graphChild->setFlags(GraphFlag::DisableAll);
272 // graphChild->setFlags(GraphFlag::EnableAll);
277 // graphChild->setGraphRange(graphChildRange, true);
273 // }
278 // graphChild->setFlags(GraphFlag::EnableAll);
274 // }
279 // }
275 // };
280 // }
281 // };
276
282
277 // connection for synchronization
283 // connection for synchronization
278 //connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
284 // connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
279 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
285 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
280 &VisualizationZoneWidget::onVariableAdded);
286 &VisualizationZoneWidget::onVariableAdded);
281 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
287 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
282 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
288 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
283
289
284 auto range = DateTimeRange{};
290 auto range = DateTimeRange {};
285 if (auto firstGraph = this->firstGraph()) {
291 if (auto firstGraph = this->firstGraph())
292 {
286 // Case of a new graph in a existant zone
293 // Case of a new graph in a existant zone
287 range = firstGraph->graphRange();
294 range = firstGraph->graphRange();
288 }
295 }
289 else {
296 else
297 {
290 // Case of a new graph as the first of the zone
298 // Case of a new graph as the first of the zone
291 range = variable->range();
299 range = variable->range();
292 }
300 }
@@ -299,28 +307,32 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
299 return graphWidget;
307 return graphWidget;
300 }
308 }
301
309
302 VisualizationGraphWidget *
310 VisualizationGraphWidget* VisualizationZoneWidget::createGraph(
303 VisualizationZoneWidget::createGraph(const std::vector<std::shared_ptr<Variable> > variables, int index)
311 const std::vector<std::shared_ptr<Variable2>> variables, int index)
304 {
312 {
305 if (variables.empty()) {
313 if (variables.empty())
314 {
306 return nullptr;
315 return nullptr;
307 }
316 }
308
317
309 auto graphWidget = createGraph(variables.front(), index);
318 auto graphWidget = createGraph(variables.front(), index);
310 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt) {
319 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt)
320 {
311 graphWidget->addVariable(*variableIt, graphWidget->graphRange());
321 graphWidget->addVariable(*variableIt, graphWidget->graphRange());
312 }
322 }
313
323
314 return graphWidget;
324 return graphWidget;
315 }
325 }
316
326
317 VisualizationGraphWidget *VisualizationZoneWidget::firstGraph() const
327 VisualizationGraphWidget* VisualizationZoneWidget::firstGraph() const
318 {
328 {
319 VisualizationGraphWidget *firstGraph = nullptr;
329 VisualizationGraphWidget* firstGraph = nullptr;
320 auto layout = ui->dragDropContainer->layout();
330 auto layout = ui->dragDropContainer->layout();
321 if (layout->count() > 0) {
331 if (layout->count() > 0)
332 {
322 if (auto visualizationGraphWidget
333 if (auto visualizationGraphWidget
323 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
334 = qobject_cast<VisualizationGraphWidget*>(layout->itemAt(0)->widget()))
335 {
324 firstGraph = visualizationGraphWidget;
336 firstGraph = visualizationGraphWidget;
325 }
337 }
326 }
338 }
@@ -331,35 +343,36 VisualizationGraphWidget *VisualizationZoneWidget::firstGraph() const
331 void VisualizationZoneWidget::closeAllGraphs()
343 void VisualizationZoneWidget::closeAllGraphs()
332 {
344 {
333 processGraphs(*ui->dragDropContainer->layout(),
345 processGraphs(*ui->dragDropContainer->layout(),
334 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
346 [](VisualizationGraphWidget& graphWidget) { graphWidget.close(); });
335 }
347 }
336
348
337 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
349 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor* visitor)
338 {
350 {
339 if (visitor) {
351 if (visitor)
352 {
340 visitor->visitEnter(this);
353 visitor->visitEnter(this);
341
354
342 // Apply visitor to graph children: widgets different from graphs are not visited (no
355 // Apply visitor to graph children: widgets different from graphs are not visited (no
343 // action)
356 // action)
344 processGraphs(
357 processGraphs(*ui->dragDropContainer->layout(),
345 *ui->dragDropContainer->layout(),
358 [visitor](VisualizationGraphWidget& graphWidget) { graphWidget.accept(visitor); });
346 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
347
359
348 visitor->visitLeave(this);
360 visitor->visitLeave(this);
349 }
361 }
350 else {
362 else
363 {
351 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
364 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
352 }
365 }
353 }
366 }
354
367
355 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
368 bool VisualizationZoneWidget::canDrop(Variable2& variable) const
356 {
369 {
357 // A tab can always accomodate a variable
370 // A tab can always accomodate a variable
358 Q_UNUSED(variable);
371 Q_UNUSED(variable);
359 return true;
372 return true;
360 }
373 }
361
374
362 bool VisualizationZoneWidget::contains(const Variable &variable) const
375 bool VisualizationZoneWidget::contains(Variable2& variable) const
363 {
376 {
364 Q_UNUSED(variable);
377 Q_UNUSED(variable);
365 return false;
378 return false;
@@ -370,14 +383,15 QString VisualizationZoneWidget::name() const
370 return ui->zoneNameLabel->text();
383 return ui->zoneNameLabel->text();
371 }
384 }
372
385
373 QMimeData *VisualizationZoneWidget::mimeData(const QPoint &position) const
386 QMimeData* VisualizationZoneWidget::mimeData(const QPoint& position) const
374 {
387 {
375 Q_UNUSED(position);
388 Q_UNUSED(position);
376
389
377 auto mimeData = new QMimeData;
390 auto mimeData = new QMimeData;
378 mimeData->setData(MIME_TYPE_ZONE, QByteArray{});
391 mimeData->setData(MIME_TYPE_ZONE, QByteArray {});
379
392
380 if (auto firstGraph = this->firstGraph()) {
393 if (auto firstGraph = this->firstGraph())
394 {
381 auto timeRangeData = TimeController::mimeDataForTimeRange(firstGraph->graphRange());
395 auto timeRangeData = TimeController::mimeDataForTimeRange(firstGraph->graphRange());
382 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
396 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
383 }
397 }
@@ -390,112 +404,117 bool VisualizationZoneWidget::isDragAllowed() const
390 return true;
404 return true;
391 }
405 }
392
406
393 void VisualizationZoneWidget::notifyMouseMoveInGraph(const QPointF &graphPosition,
407 void VisualizationZoneWidget::notifyMouseMoveInGraph(const QPointF& graphPosition,
394 const QPointF &plotPosition,
408 const QPointF& plotPosition, VisualizationGraphWidget* graphWidget)
395 VisualizationGraphWidget *graphWidget)
396 {
409 {
397 processGraphs(*ui->dragDropContainer->layout(), [&graphPosition, &plotPosition, &graphWidget](
410 processGraphs(*ui->dragDropContainer->layout(),
398 VisualizationGraphWidget &processedGraph) {
411 [&graphPosition, &plotPosition, &graphWidget](VisualizationGraphWidget& processedGraph) {
399
412 switch (sqpApp->plotsCursorMode())
400 switch (sqpApp->plotsCursorMode()) {
413 {
401 case SqpApplication::PlotsCursorMode::Vertical:
414 case SqpApplication::PlotsCursorMode::Vertical:
402 processedGraph.removeHorizontalCursor();
403 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
404 break;
405 case SqpApplication::PlotsCursorMode::Temporal:
406 processedGraph.addVerticalCursor(plotPosition.x());
407 processedGraph.removeHorizontalCursor();
408 break;
409 case SqpApplication::PlotsCursorMode::Horizontal:
410 processedGraph.removeVerticalCursor();
411 if (&processedGraph == graphWidget) {
412 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
413 }
414 else {
415 processedGraph.removeHorizontalCursor();
415 processedGraph.removeHorizontalCursor();
416 }
417 break;
418 case SqpApplication::PlotsCursorMode::Cross:
419 if (&processedGraph == graphWidget) {
420 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
416 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
421 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
417 break;
422 }
418 case SqpApplication::PlotsCursorMode::Temporal:
423 else {
419 processedGraph.addVerticalCursor(plotPosition.x());
424 processedGraph.removeHorizontalCursor();
420 processedGraph.removeHorizontalCursor();
421 break;
422 case SqpApplication::PlotsCursorMode::Horizontal:
425 processedGraph.removeVerticalCursor();
423 processedGraph.removeVerticalCursor();
426 }
424 if (&processedGraph == graphWidget)
427 break;
425 {
428 case SqpApplication::PlotsCursorMode::NoCursor:
426 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
429 processedGraph.removeHorizontalCursor();
427 }
430 processedGraph.removeVerticalCursor();
428 else
431 break;
429 {
432 }
430 processedGraph.removeHorizontalCursor();
433
431 }
434
432 break;
435 });
433 case SqpApplication::PlotsCursorMode::Cross:
434 if (&processedGraph == graphWidget)
435 {
436 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
437 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
438 }
439 else
440 {
441 processedGraph.removeHorizontalCursor();
442 processedGraph.removeVerticalCursor();
443 }
444 break;
445 case SqpApplication::PlotsCursorMode::NoCursor:
446 processedGraph.removeHorizontalCursor();
447 processedGraph.removeVerticalCursor();
448 break;
449 }
450 });
436 }
451 }
437
452
438 void VisualizationZoneWidget::notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget)
453 void VisualizationZoneWidget::notifyMouseLeaveGraph(VisualizationGraphWidget* graphWidget)
439 {
454 {
440 processGraphs(*ui->dragDropContainer->layout(), [](VisualizationGraphWidget &processedGraph) {
455 processGraphs(*ui->dragDropContainer->layout(), [](VisualizationGraphWidget& processedGraph) {
441 processedGraph.removeHorizontalCursor();
456 processedGraph.removeHorizontalCursor();
442 processedGraph.removeVerticalCursor();
457 processedGraph.removeVerticalCursor();
443 });
458 });
444 }
459 }
445
460
446 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
461 void VisualizationZoneWidget::closeEvent(QCloseEvent* event)
447 {
462 {
448 // Closes graphs in the zone
463 // Closes graphs in the zone
449 processGraphs(*ui->dragDropContainer->layout(),
464 processGraphs(*ui->dragDropContainer->layout(),
450 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
465 [](VisualizationGraphWidget& graphWidget) { graphWidget.close(); });
451
466
452 // Delete synchronization group from variable controller
467 // Delete synchronization group from variable controller
453 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
468 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
454 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
469 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
455
470
456 QWidget::closeEvent(event);
471 QWidget::closeEvent(event);
457 }
472 }
458
473
459 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
474 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable2> variable)
460 {
475 {
461 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
476 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
462 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
477 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable2>, variable),
463 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
478 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
464 }
479 }
465
480
466 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
481 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable2> variable)
467 {
482 {
468 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
483 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
469 Q_ARG(std::shared_ptr<Variable>, variable),
484 Q_ARG(std::shared_ptr<Variable2>, variable), Q_ARG(QUuid, impl->m_SynchronisationGroupId));
470 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
471 }
485 }
472
486
473 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
487 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData* mimeData)
474 {
488 {
475 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
489 if (mimeData->hasFormat(MIME_TYPE_GRAPH))
490 {
476 impl->dropGraph(index, this);
491 impl->dropGraph(index, this);
477 }
492 }
478 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
493 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST))
494 {
479 auto variables = sqpApp->variableController().variables(
495 auto variables = sqpApp->variableController().variables(
480 Variable::variablesIDs(mimeData->data(MIME_TYPE_VARIABLE_LIST)));
496 Variable2::IDs(mimeData->data(MIME_TYPE_VARIABLE_LIST)));
481 impl->dropVariables(variables, index, this);
497 impl->dropVariables(variables, index, this);
482 }
498 }
483 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
499 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST))
500 {
484 auto products = sqpApp->dataSourceController().productsDataForMimeData(
501 auto products = sqpApp->dataSourceController().productsDataForMimeData(
485 mimeData->data(MIME_TYPE_PRODUCT_LIST));
502 mimeData->data(MIME_TYPE_PRODUCT_LIST));
486 impl->dropProducts(products, index, this);
503 impl->dropProducts(products, index, this);
487 }
504 }
488 else {
505 else
506 {
489 qCWarning(LOG_VisualizationZoneWidget())
507 qCWarning(LOG_VisualizationZoneWidget())
490 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
508 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
491 }
509 }
492 }
510 }
493
511
494 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragWidget,
512 void VisualizationZoneWidget::dropMimeDataOnGraph(
495 const QMimeData *mimeData)
513 VisualizationDragWidget* dragWidget, const QMimeData* mimeData)
496 {
514 {
497 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(dragWidget);
515 auto graphWidget = qobject_cast<VisualizationGraphWidget*>(dragWidget);
498 if (!graphWidget) {
516 if (!graphWidget)
517 {
499 qCWarning(LOG_VisualizationZoneWidget())
518 qCWarning(LOG_VisualizationZoneWidget())
500 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, dropping in an unknown widget, "
519 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, dropping in an unknown widget, "
501 "drop aborted");
520 "drop aborted");
@@ -503,62 +522,66 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragW
503 return;
522 return;
504 }
523 }
505
524
506 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
525 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST))
526 {
507 auto variables = sqpApp->variableController().variables(
527 auto variables = sqpApp->variableController().variables(
508 Variable::variablesIDs(mimeData->data(MIME_TYPE_VARIABLE_LIST)));
528 Variable2::IDs(mimeData->data(MIME_TYPE_VARIABLE_LIST)));
509 for (const auto &var : variables) {
529 for (const auto& var : variables)
530 {
510 graphWidget->addVariable(var, graphWidget->graphRange());
531 graphWidget->addVariable(var, graphWidget->graphRange());
511 }
532 }
512 }
533 }
513 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
534 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST))
535 {
514 auto products = sqpApp->dataSourceController().productsDataForMimeData(
536 auto products = sqpApp->dataSourceController().productsDataForMimeData(
515 mimeData->data(MIME_TYPE_PRODUCT_LIST));
537 mimeData->data(MIME_TYPE_PRODUCT_LIST));
516
538
517 auto context = new QObject{this};
539 auto context = new QObject { this };
518 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
540 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
519 // BTW this is really dangerous, this assumes the next created variable will be this one...
541 // BTW this is really dangerous, this assumes the next created variable will be this one...
520 connect(&sqpApp->variableController(), &VariableController2::variableAdded, context,
542 connect(&sqpApp->variableController(), &VariableController2::variableAdded, context,
521 [this, graphWidget, context, range](auto variable) {
543 [this, graphWidget, context, range](auto variable) {
522 if(sqpApp->variableController().isReady(variable))
544 if (sqpApp->variableController().isReady(variable))
523 {
545 {
524 graphWidget->addVariable(variable, range);
546 graphWidget->addVariable(variable, range);
525 delete context;
547 delete context;
526 }
548 }
527 else
549 else
528 {
550 {
529 // -> this is pure insanity! this is a workaround to make a bad design work
551 // -> this is pure insanity! this is a workaround to make a bad design work
530 QObject::connect(variable.get(), &Variable::updated,context,
552 QObject::connect(variable.get(), &Variable2::updated, context,
531 [graphWidget, context, range, variable]()
553 [graphWidget, context, range, variable]() {
532 {
554 graphWidget->addVariable(variable, range);
533 graphWidget->addVariable(variable, range);
555 delete context;
534 delete context;
556 });
535 });
557 }
536 }
558 },
537
559 Qt::QueuedConnection);
538 },
539 Qt::QueuedConnection);
540
560
541 auto productData = products.first().toHash();
561 auto productData = products.first().toHash();
542 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
562 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
543 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
563 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
544 }
564 }
545 else if (mimeData->hasFormat(MIME_TYPE_TIME_RANGE)) {
565 else if (mimeData->hasFormat(MIME_TYPE_TIME_RANGE))
566 {
546 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
567 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
547 graphWidget->setGraphRange(range, true, true);
568 graphWidget->setGraphRange(range, true, true);
548 }
569 }
549 else {
570 else
571 {
550 qCWarning(LOG_VisualizationZoneWidget())
572 qCWarning(LOG_VisualizationZoneWidget())
551 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, unknown MIME data received.");
573 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, unknown MIME data received.");
552 }
574 }
553 }
575 }
554
576
555 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
577 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
556 int index, VisualizationZoneWidget *zoneWidget)
578 int index, VisualizationZoneWidget* zoneWidget)
557 {
579 {
558 auto &helper = sqpApp->dragDropGuiController();
580 auto& helper = sqpApp->dragDropGuiController();
559
581
560 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
582 auto graphWidget = qobject_cast<VisualizationGraphWidget*>(helper.getCurrentDragWidget());
561 if (!graphWidget) {
583 if (!graphWidget)
584 {
562 qCWarning(LOG_VisualizationZoneWidget())
585 qCWarning(LOG_VisualizationZoneWidget())
563 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the dropped graph is not "
586 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the dropped graph is not "
564 "found or invalid.");
587 "found or invalid.");
@@ -567,8 +590,9 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
567 }
590 }
568
591
569 auto parentDragDropContainer
592 auto parentDragDropContainer
570 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
593 = qobject_cast<VisualizationDragDropContainer*>(graphWidget->parentWidget());
571 if (!parentDragDropContainer) {
594 if (!parentDragDropContainer)
595 {
572 qCWarning(LOG_VisualizationZoneWidget())
596 qCWarning(LOG_VisualizationZoneWidget())
573 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the parent container of "
597 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the parent container of "
574 "the dropped graph is not found.");
598 "the dropped graph is not found.");
@@ -576,9 +600,10 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
576 return;
600 return;
577 }
601 }
578
602
579 const auto &variables = graphWidget->variables();
603 const auto& variables = graphWidget->variables();
580
604
581 if (parentDragDropContainer != zoneWidget->ui->dragDropContainer && !variables.empty()) {
605 if (parentDragDropContainer != zoneWidget->ui->dragDropContainer && !variables.empty())
606 {
582 // The drop didn't occur in the same zone
607 // The drop didn't occur in the same zone
583
608
584 // Abort the requests for the variables (if any)
609 // Abort the requests for the variables (if any)
@@ -590,11 +615,13 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
590
615
591 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
616 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
592 auto nbGraph = parentDragDropContainer->countDragWidget();
617 auto nbGraph = parentDragDropContainer->countDragWidget();
593 if (nbGraph == 1) {
618 if (nbGraph == 1)
619 {
594 // This is the only graph in the previous zone, close the zone
620 // This is the only graph in the previous zone, close the zone
595 helper.delayedCloseWidget(previousParentZoneWidget);
621 helper.delayedCloseWidget(previousParentZoneWidget);
596 }
622 }
597 else {
623 else
624 {
598 // Close the graph
625 // Close the graph
599 helper.delayedCloseWidget(graphWidget);
626 helper.delayedCloseWidget(graphWidget);
600 }
627 }
@@ -603,18 +630,22 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
603 auto newGraphWidget = zoneWidget->createGraph(variables, index);
630 auto newGraphWidget = zoneWidget->createGraph(variables, index);
604 newGraphWidget->addSelectionZones(graphWidget->selectionZoneRanges());
631 newGraphWidget->addSelectionZones(graphWidget->selectionZoneRanges());
605 }
632 }
606 else {
633 else
634 {
607 // The drop occurred in the same zone or the graph is empty
635 // The drop occurred in the same zone or the graph is empty
608 // Simple move of the graph, no variable operation associated
636 // Simple move of the graph, no variable operation associated
609 parentDragDropContainer->layout()->removeWidget(graphWidget);
637 parentDragDropContainer->layout()->removeWidget(graphWidget);
610
638
611 if (variables.empty() && parentDragDropContainer != zoneWidget->ui->dragDropContainer) {
639 if (variables.empty() && parentDragDropContainer != zoneWidget->ui->dragDropContainer)
640 {
612 // The graph is empty and dropped in a different zone.
641 // The graph is empty and dropped in a different zone.
613 // Take the range of the first graph in the zone (if existing).
642 // Take the range of the first graph in the zone (if existing).
614 auto layout = zoneWidget->ui->dragDropContainer->layout();
643 auto layout = zoneWidget->ui->dragDropContainer->layout();
615 if (layout->count() > 0) {
644 if (layout->count() > 0)
645 {
616 if (auto visualizationGraphWidget
646 if (auto visualizationGraphWidget
617 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
647 = qobject_cast<VisualizationGraphWidget*>(layout->itemAt(0)->widget()))
648 {
618 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
649 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
619 }
650 }
620 }
651 }
@@ -625,38 +656,40 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
625 }
656 }
626
657
627 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables(
658 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables(
628 const std::vector<std::shared_ptr<Variable> > &variables, int index,
659 const std::vector<std::shared_ptr<Variable2>>& variables, int index,
629 VisualizationZoneWidget *zoneWidget)
660 VisualizationZoneWidget* zoneWidget)
630 {
661 {
631 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
662 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
632 // compatible variable here
663 // compatible variable here
633 if (variables.size() > 1) {
664 if (variables.size() > 1)
665 {
634 return;
666 return;
635 }
667 }
636 zoneWidget->createGraph(variables, index);
668 zoneWidget->createGraph(variables, index);
637 }
669 }
638
670
639 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropProducts(
671 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropProducts(
640 const QVariantList &productsData, int index, VisualizationZoneWidget *zoneWidget)
672 const QVariantList& productsData, int index, VisualizationZoneWidget* zoneWidget)
641 {
673 {
642 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
674 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
643 // compatible variable here
675 // compatible variable here
644 if (productsData.count() != 1) {
676 if (productsData.count() != 1)
677 {
645 qCWarning(LOG_VisualizationZoneWidget())
678 qCWarning(LOG_VisualizationZoneWidget())
646 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
679 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
647 "aborted.");
680 "aborted.");
648 return;
681 return;
649 }
682 }
650
683
651 auto context = new QObject{zoneWidget};
684 auto context = new QObject { zoneWidget };
652 connect(&sqpApp->variableController(), &VariableController2::variableAdded, context,
685 connect(&sqpApp->variableController(), &VariableController2::variableAdded, context,
653 [this, index, zoneWidget, context](auto variable) {
686 [this, index, zoneWidget, context](auto variable) {
654 zoneWidget->createGraph(variable, index);
687 zoneWidget->createGraph(variable, index);
655 delete context; // removes the connection
688 delete context; // removes the connection
656 },
689 },
657 Qt::QueuedConnection);
690 Qt::QueuedConnection);
658
691
659 auto productData = productsData.first().toHash();
692 auto productData = productsData.first().toHash();
660 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
693 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
661 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
694 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
662 }
695 }
@@ -5,68 +5,71
5 #include "Visualization/VisualizationWidget.h"
5 #include "Visualization/VisualizationWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
7
7
8 #include <Variable/Variable.h>
8 #include <Variable/Variable2.h>
9
9
10 struct FindVariableOperation::FindVariableOperationPrivate {
10 struct FindVariableOperation::FindVariableOperationPrivate
11 explicit FindVariableOperationPrivate(std::shared_ptr<Variable> variable) : m_Variable{variable}
11 {
12 explicit FindVariableOperationPrivate(std::shared_ptr<Variable2> variable)
13 : m_Variable { variable }
12 {
14 {
13 }
15 }
14
16
15 void visit(IVisualizationWidget *widget)
17 void visit(IVisualizationWidget* widget)
16 {
18 {
17 if (m_Variable && widget && widget->contains(*m_Variable)) {
19 if (m_Variable && widget && widget->contains(*m_Variable))
20 {
18 m_Containers.insert(widget);
21 m_Containers.insert(widget);
19 }
22 }
20 }
23 }
21
24
22 std::shared_ptr<Variable> m_Variable; ///< Variable to find
25 std::shared_ptr<Variable2> m_Variable; ///< Variable to find
23 std::set<IVisualizationWidget *> m_Containers; ///< Containers found for the variable
26 std::set<IVisualizationWidget*> m_Containers; ///< Containers found for the variable
24 };
27 };
25
28
26 FindVariableOperation::FindVariableOperation(std::shared_ptr<Variable> variable)
29 FindVariableOperation::FindVariableOperation(std::shared_ptr<Variable2> variable)
27 : impl{spimpl::make_unique_impl<FindVariableOperationPrivate>(variable)}
30 : impl { spimpl::make_unique_impl<FindVariableOperationPrivate>(variable) }
28 {
31 {
29 }
32 }
30
33
31 void FindVariableOperation::visitEnter(VisualizationWidget *widget)
34 void FindVariableOperation::visitEnter(VisualizationWidget* widget)
32 {
35 {
33 impl->visit(widget);
36 impl->visit(widget);
34 }
37 }
35
38
36 void FindVariableOperation::visitLeave(VisualizationWidget *widget)
39 void FindVariableOperation::visitLeave(VisualizationWidget* widget)
37 {
40 {
38 // Does nothing
41 // Does nothing
39 Q_UNUSED(widget);
42 Q_UNUSED(widget);
40 }
43 }
41
44
42 void FindVariableOperation::visitEnter(VisualizationTabWidget *tabWidget)
45 void FindVariableOperation::visitEnter(VisualizationTabWidget* tabWidget)
43 {
46 {
44 impl->visit(tabWidget);
47 impl->visit(tabWidget);
45 }
48 }
46
49
47 void FindVariableOperation::visitLeave(VisualizationTabWidget *tabWidget)
50 void FindVariableOperation::visitLeave(VisualizationTabWidget* tabWidget)
48 {
51 {
49 // Does nothing
52 // Does nothing
50 Q_UNUSED(tabWidget);
53 Q_UNUSED(tabWidget);
51 }
54 }
52
55
53 void FindVariableOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
56 void FindVariableOperation::visitEnter(VisualizationZoneWidget* zoneWidget)
54 {
57 {
55 impl->visit(zoneWidget);
58 impl->visit(zoneWidget);
56 }
59 }
57
60
58 void FindVariableOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
61 void FindVariableOperation::visitLeave(VisualizationZoneWidget* zoneWidget)
59 {
62 {
60 // Does nothing
63 // Does nothing
61 Q_UNUSED(zoneWidget);
64 Q_UNUSED(zoneWidget);
62 }
65 }
63
66
64 void FindVariableOperation::visit(VisualizationGraphWidget *graphWidget)
67 void FindVariableOperation::visit(VisualizationGraphWidget* graphWidget)
65 {
68 {
66 impl->visit(graphWidget);
69 impl->visit(graphWidget);
67 }
70 }
68
71
69 std::set<IVisualizationWidget *> FindVariableOperation::result() const noexcept
72 std::set<IVisualizationWidget*> FindVariableOperation::result() const noexcept
70 {
73 {
71 return impl->m_Containers;
74 return impl->m_Containers;
72 }
75 }
@@ -5,21 +5,21
5 #include "Visualization/VisualizationTabWidget.h"
5 #include "Visualization/VisualizationTabWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
7
7
8 #include <Variable/Variable.h>
8 #include <Variable/Variable2.h>
9
9
10 #include <QMenu>
10 #include <QMenu>
11 #include <QStack>
11 #include <QStack>
12
12
13 Q_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation, "GenerateVariableMenuOperation")
13 Q_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation, "GenerateVariableMenuOperation")
14
14
15 struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate {
15 struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate
16 explicit GenerateVariableMenuOperationPrivate(
16 {
17 QMenu *menu, std::shared_ptr<Variable> variable,
17 explicit GenerateVariableMenuOperationPrivate(QMenu* menu, std::shared_ptr<Variable2> variable,
18 std::set<IVisualizationWidget *> variableContainers)
18 std::set<IVisualizationWidget*> variableContainers)
19 : m_Variable{variable},
19 : m_Variable { variable }
20 m_VariableContainers{std::move(variableContainers)},
20 , m_VariableContainers { std::move(variableContainers) }
21 m_PlotMenuBuilder{menu},
21 , m_PlotMenuBuilder { menu }
22 m_UnplotMenuBuilder{menu}
22 , m_UnplotMenuBuilder { menu }
23 {
23 {
24 }
24 }
25
25
@@ -27,11 +27,12 struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate {
27 {
27 {
28 // Creates the root menu
28 // Creates the root menu
29 if (auto plotMenu
29 if (auto plotMenu
30 = m_PlotMenuBuilder.addMenu(QObject::tr("Plot"), QIcon{":/icones/plot.png"})) {
30 = m_PlotMenuBuilder.addMenu(QObject::tr("Plot"), QIcon { ":/icones/plot.png" }))
31 plotMenu->setEnabled(m_Variable && m_Variable->dataSeries() != nullptr);
31 {
32 plotMenu->setEnabled(m_Variable && m_Variable->data() != nullptr);
32 }
33 }
33
34
34 m_UnplotMenuBuilder.addMenu(QObject::tr("Unplot"), QIcon{":/icones/unplot.png"});
35 m_UnplotMenuBuilder.addMenu(QObject::tr("Unplot"), QIcon { ":/icones/unplot.png" });
35 }
36 }
36
37
37 void visitRootLeave()
38 void visitRootLeave()
@@ -41,7 +42,7 struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate {
41 m_UnplotMenuBuilder.closeMenu();
42 m_UnplotMenuBuilder.closeMenu();
42 }
43 }
43
44
44 void visitNodeEnter(const IVisualizationWidget &container)
45 void visitNodeEnter(const IVisualizationWidget& container)
45 {
46 {
46 // Opens a new menu associated to the node
47 // Opens a new menu associated to the node
47 m_PlotMenuBuilder.addMenu(container.name());
48 m_PlotMenuBuilder.addMenu(container.name());
@@ -49,10 +50,11 struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate {
49 }
50 }
50
51
51 template <typename ActionFun>
52 template <typename ActionFun>
52 void visitNodeLeavePlot(const IVisualizationWidget &container, const QString &actionName,
53 void visitNodeLeavePlot(
53 ActionFun actionFunction)
54 const IVisualizationWidget& container, const QString& actionName, ActionFun actionFunction)
54 {
55 {
55 if (isValidContainer(container)) {
56 if (isValidContainer(container))
57 {
56 m_PlotMenuBuilder.addSeparator();
58 m_PlotMenuBuilder.addSeparator();
57 m_PlotMenuBuilder.addAction(actionName, actionFunction);
59 m_PlotMenuBuilder.addAction(actionName, actionFunction);
58 }
60 }
@@ -68,46 +70,47 struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate {
68 }
70 }
69
71
70 template <typename ActionFun>
72 template <typename ActionFun>
71 void visitLeafPlot(const IVisualizationWidget &container, const QString &actionName,
73 void visitLeafPlot(
72 ActionFun actionFunction)
74 const IVisualizationWidget& container, const QString& actionName, ActionFun actionFunction)
73 {
75 {
74 if (isValidContainer(container)) {
76 if (isValidContainer(container))
77 {
75 m_PlotMenuBuilder.addAction(actionName, actionFunction);
78 m_PlotMenuBuilder.addAction(actionName, actionFunction);
76 }
79 }
77 }
80 }
78
81
79 template <typename ActionFun>
82 template <typename ActionFun>
80 void visitLeafUnplot(IVisualizationWidget *container, const QString &actionName,
83 void visitLeafUnplot(
81 ActionFun actionFunction)
84 IVisualizationWidget* container, const QString& actionName, ActionFun actionFunction)
82 {
85 {
83 // If the container contains the variable, we generate 'unplot' action
86 // If the container contains the variable, we generate 'unplot' action
84 if (m_VariableContainers.count(container) == 1) {
87 if (m_VariableContainers.count(container) == 1)
88 {
85 m_UnplotMenuBuilder.addAction(actionName, actionFunction);
89 m_UnplotMenuBuilder.addAction(actionName, actionFunction);
86 }
90 }
87 }
91 }
88
92
89 bool isValidContainer(const IVisualizationWidget &container) const noexcept
93 bool isValidContainer(const IVisualizationWidget& container) const noexcept
90 {
94 {
91 // A container is valid if it can contain the variable and if the variable is not already
95 // A container is valid if it can contain the variable and if the variable is not already
92 // contained in another container
96 // contained in another container
93 return m_Variable && m_VariableContainers.size() == 0 && container.canDrop(*m_Variable);
97 return m_Variable && m_VariableContainers.size() == 0 && container.canDrop(*m_Variable);
94 }
98 }
95
99
96 std::shared_ptr<Variable> m_Variable;
100 std::shared_ptr<Variable2> m_Variable;
97 std::set<IVisualizationWidget *> m_VariableContainers;
101 std::set<IVisualizationWidget*> m_VariableContainers;
98 MenuBuilder m_PlotMenuBuilder; ///< Builder for the 'Plot' menu
102 MenuBuilder m_PlotMenuBuilder; ///< Builder for the 'Plot' menu
99 MenuBuilder m_UnplotMenuBuilder; ///< Builder for the 'Unplot' menu
103 MenuBuilder m_UnplotMenuBuilder; ///< Builder for the 'Unplot' menu
100 };
104 };
101
105
102 GenerateVariableMenuOperation::GenerateVariableMenuOperation(
106 GenerateVariableMenuOperation::GenerateVariableMenuOperation(QMenu* menu,
103 QMenu *menu, std::shared_ptr<Variable> variable,
107 std::shared_ptr<Variable2> variable, std::set<IVisualizationWidget*> variableContainers)
104 std::set<IVisualizationWidget *> variableContainers)
108 : impl { spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>(
105 : impl{spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>(
109 menu, variable, std::move(variableContainers)) }
106 menu, variable, std::move(variableContainers))}
107 {
110 {
108 }
111 }
109
112
110 void GenerateVariableMenuOperation::visitEnter(VisualizationWidget *widget)
113 void GenerateVariableMenuOperation::visitEnter(VisualizationWidget* widget)
111 {
114 {
112 // VisualizationWidget is not intended to accommodate a variable
115 // VisualizationWidget is not intended to accommodate a variable
113 Q_UNUSED(widget)
116 Q_UNUSED(widget)
@@ -116,7 +119,7 void GenerateVariableMenuOperation::visitEnter(VisualizationWidget *widget)
116 impl->visitRootEnter();
119 impl->visitRootEnter();
117 }
120 }
118
121
119 void GenerateVariableMenuOperation::visitLeave(VisualizationWidget *widget)
122 void GenerateVariableMenuOperation::visitLeave(VisualizationWidget* widget)
120 {
123 {
121 // VisualizationWidget is not intended to accommodate a variable
124 // VisualizationWidget is not intended to accommodate a variable
122 Q_UNUSED(widget)
125 Q_UNUSED(widget)
@@ -125,58 +128,66 void GenerateVariableMenuOperation::visitLeave(VisualizationWidget *widget)
125 impl->visitRootLeave();
128 impl->visitRootLeave();
126 }
129 }
127
130
128 void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget *tabWidget)
131 void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget* tabWidget)
129 {
132 {
130 if (tabWidget) {
133 if (tabWidget)
134 {
131 // 'Plot' and 'Unplot' menus
135 // 'Plot' and 'Unplot' menus
132 impl->visitNodeEnter(*tabWidget);
136 impl->visitNodeEnter(*tabWidget);
133 }
137 }
134 else {
138 else
139 {
135 qCCritical(LOG_GenerateVariableMenuOperation(),
140 qCCritical(LOG_GenerateVariableMenuOperation(),
136 "Can't visit enter VisualizationTabWidget : the widget is null");
141 "Can't visit enter VisualizationTabWidget : the widget is null");
137 }
142 }
138 }
143 }
139
144
140 void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget)
145 void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget* tabWidget)
141 {
146 {
142 if (tabWidget) {
147 if (tabWidget)
148 {
143 // 'Plot' menu
149 // 'Plot' menu
144 impl->visitNodeLeavePlot(*tabWidget, QObject::tr("Open in a new zone"),
150 impl->visitNodeLeavePlot(*tabWidget, QObject::tr("Open in a new zone"),
145 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, tabWidget ]() {
151 [varW = std::weak_ptr<Variable2> { impl->m_Variable }, tabWidget]() {
146 if (auto var = varW.lock()) {
152 if (auto var = varW.lock())
147 tabWidget->createZone(var);
153 {
148 }
154 tabWidget->createZone(var);
149 });
155 }
156 });
150
157
151 // 'Unplot' menu
158 // 'Unplot' menu
152 impl->visitNodeLeaveUnplot();
159 impl->visitNodeLeaveUnplot();
153 }
160 }
154 else {
161 else
162 {
155 qCCritical(LOG_GenerateVariableMenuOperation(),
163 qCCritical(LOG_GenerateVariableMenuOperation(),
156 "Can't visit leave VisualizationTabWidget : the widget is null");
164 "Can't visit leave VisualizationTabWidget : the widget is null");
157 }
165 }
158 }
166 }
159
167
160 void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
168 void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget* zoneWidget)
161 {
169 {
162 if (zoneWidget) {
170 if (zoneWidget)
171 {
163 // 'Plot' and 'Unplot' menus
172 // 'Plot' and 'Unplot' menus
164 impl->visitNodeEnter(*zoneWidget);
173 impl->visitNodeEnter(*zoneWidget);
165 }
174 }
166 else {
175 else
176 {
167 qCCritical(LOG_GenerateVariableMenuOperation(),
177 qCCritical(LOG_GenerateVariableMenuOperation(),
168 "Can't visit enter VisualizationZoneWidget : the widget is null");
178 "Can't visit enter VisualizationZoneWidget : the widget is null");
169 }
179 }
170 }
180 }
171
181
172 void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
182 void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget* zoneWidget)
173 {
183 {
174 if (zoneWidget) {
184 if (zoneWidget)
185 {
175 // 'Plot' menu
186 // 'Plot' menu
176 impl->visitNodeLeavePlot(
187 impl->visitNodeLeavePlot(*zoneWidget, QObject::tr("Open in a new graph"),
177 *zoneWidget, QObject::tr("Open in a new graph"),
188 [varW = std::weak_ptr<Variable2> { impl->m_Variable }, zoneWidget]() {
178 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, zoneWidget ]() {
189 if (auto var = varW.lock())
179 if (auto var = varW.lock()) {
190 {
180 zoneWidget->createGraph(var);
191 zoneWidget->createGraph(var);
181 }
192 }
182 });
193 });
@@ -184,33 +195,38 void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidg
184 // 'Unplot' menu
195 // 'Unplot' menu
185 impl->visitNodeLeaveUnplot();
196 impl->visitNodeLeaveUnplot();
186 }
197 }
187 else {
198 else
199 {
188 qCCritical(LOG_GenerateVariableMenuOperation(),
200 qCCritical(LOG_GenerateVariableMenuOperation(),
189 "Can't visit leave VisualizationZoneWidget : the widget is null");
201 "Can't visit leave VisualizationZoneWidget : the widget is null");
190 }
202 }
191 }
203 }
192
204
193 void GenerateVariableMenuOperation::visit(VisualizationGraphWidget *graphWidget)
205 void GenerateVariableMenuOperation::visit(VisualizationGraphWidget* graphWidget)
194 {
206 {
195 if (graphWidget) {
207 if (graphWidget)
208 {
196 // 'Plot' menu
209 // 'Plot' menu
197 impl->visitLeafPlot(*graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()),
210 impl->visitLeafPlot(*graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()),
198 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, graphWidget ]() {
211 [varW = std::weak_ptr<Variable2> { impl->m_Variable }, graphWidget]() {
199 if (auto var = varW.lock()) {
212 if (auto var = varW.lock())
200 graphWidget->addVariable(var, graphWidget->graphRange());
213 {
201 }
214 graphWidget->addVariable(var, graphWidget->graphRange());
202 });
215 }
216 });
203
217
204 // 'Unplot' menu
218 // 'Unplot' menu
205 impl->visitLeafUnplot(graphWidget, QObject::tr("Remove from %1").arg(graphWidget->name()),
219 impl->visitLeafUnplot(graphWidget, QObject::tr("Remove from %1").arg(graphWidget->name()),
206 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, graphWidget ]() {
220 [varW = std::weak_ptr<Variable2> { impl->m_Variable }, graphWidget]() {
207 if (auto var = varW.lock()) {
221 if (auto var = varW.lock())
208 graphWidget->removeVariable(var);
222 {
209 }
223 graphWidget->removeVariable(var);
210 });
224 }
225 });
211 }
226 }
212 else {
227 else
228 {
213 qCCritical(LOG_GenerateVariableMenuOperation(),
229 qCCritical(LOG_GenerateVariableMenuOperation(),
214 "Can't visit VisualizationGraphWidget : the widget is null");
230 "Can't visit VisualizationGraphWidget : the widget is null");
215 }
231 }
216 }
232 }
@@ -1,70 +1,74
1 #include "Visualization/operations/RemoveVariableOperation.h"
1 #include "Visualization/operations/RemoveVariableOperation.h"
2 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/VisualizationGraphWidget.h"
3
3
4 #include <Variable/Variable.h>
4 #include <Variable/Variable2.h>
5
5
6 Q_LOGGING_CATEGORY(LOG_RemoveVariableOperation, "RemoveVariableOperation")
6 Q_LOGGING_CATEGORY(LOG_RemoveVariableOperation, "RemoveVariableOperation")
7
7
8 struct RemoveVariableOperation::RemoveVariableOperationPrivate {
8 struct RemoveVariableOperation::RemoveVariableOperationPrivate
9 explicit RemoveVariableOperationPrivate(std::shared_ptr<Variable> variable)
9 {
10 explicit RemoveVariableOperationPrivate(std::shared_ptr<Variable2> variable)
10 : m_Variable(variable)
11 : m_Variable(variable)
11 {
12 {
12 }
13 }
13
14
14 std::shared_ptr<Variable> m_Variable;
15 std::shared_ptr<Variable2> m_Variable;
15 };
16 };
16
17
17 RemoveVariableOperation::RemoveVariableOperation(std::shared_ptr<Variable> variable)
18 RemoveVariableOperation::RemoveVariableOperation(std::shared_ptr<Variable2> variable)
18 : impl{spimpl::make_unique_impl<RemoveVariableOperationPrivate>(variable)}
19 : impl { spimpl::make_unique_impl<RemoveVariableOperationPrivate>(variable) }
19 {
20 {
20 }
21 }
21
22
22 void RemoveVariableOperation::visitEnter(VisualizationWidget *widget)
23 void RemoveVariableOperation::visitEnter(VisualizationWidget* widget)
23 {
24 {
24 // VisualizationWidget is not intended to contain a variable
25 // VisualizationWidget is not intended to contain a variable
25 Q_UNUSED(widget)
26 Q_UNUSED(widget)
26 }
27 }
27
28
28 void RemoveVariableOperation::visitLeave(VisualizationWidget *widget)
29 void RemoveVariableOperation::visitLeave(VisualizationWidget* widget)
29 {
30 {
30 // VisualizationWidget is not intended to contain a variable
31 // VisualizationWidget is not intended to contain a variable
31 Q_UNUSED(widget)
32 Q_UNUSED(widget)
32 }
33 }
33
34
34 void RemoveVariableOperation::visitEnter(VisualizationTabWidget *tabWidget)
35 void RemoveVariableOperation::visitEnter(VisualizationTabWidget* tabWidget)
35 {
36 {
36 // VisualizationTabWidget is not intended to contain a variable
37 // VisualizationTabWidget is not intended to contain a variable
37 Q_UNUSED(tabWidget)
38 Q_UNUSED(tabWidget)
38 }
39 }
39
40
40 void RemoveVariableOperation::visitLeave(VisualizationTabWidget *tabWidget)
41 void RemoveVariableOperation::visitLeave(VisualizationTabWidget* tabWidget)
41 {
42 {
42 // VisualizationTabWidget is not intended to contain a variable
43 // VisualizationTabWidget is not intended to contain a variable
43 Q_UNUSED(tabWidget)
44 Q_UNUSED(tabWidget)
44 }
45 }
45
46
46 void RemoveVariableOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
47 void RemoveVariableOperation::visitEnter(VisualizationZoneWidget* zoneWidget)
47 {
48 {
48 // VisualizationZoneWidget is not intended to contain a variable
49 // VisualizationZoneWidget is not intended to contain a variable
49 Q_UNUSED(zoneWidget)
50 Q_UNUSED(zoneWidget)
50 }
51 }
51
52
52 void RemoveVariableOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
53 void RemoveVariableOperation::visitLeave(VisualizationZoneWidget* zoneWidget)
53 {
54 {
54 // VisualizationZoneWidget is not intended to contain a variable
55 // VisualizationZoneWidget is not intended to contain a variable
55 Q_UNUSED(zoneWidget)
56 Q_UNUSED(zoneWidget)
56 }
57 }
57
58
58 void RemoveVariableOperation::visit(VisualizationGraphWidget *graphWidget)
59 void RemoveVariableOperation::visit(VisualizationGraphWidget* graphWidget)
59 {
60 {
60 if (graphWidget) {
61 if (graphWidget)
62 {
61 // If the widget contains the variable, removes it
63 // If the widget contains the variable, removes it
62 if (impl->m_Variable && graphWidget->contains(*impl->m_Variable)) {
64 if (impl->m_Variable && graphWidget->contains(*impl->m_Variable))
65 {
63 graphWidget->removeVariable(impl->m_Variable);
66 graphWidget->removeVariable(impl->m_Variable);
64 }
67 }
65 }
68 }
66 else {
69 else
70 {
67 qCCritical(LOG_RemoveVariableOperation(),
71 qCCritical(LOG_RemoveVariableOperation(),
68 "Can't visit VisualizationGraphWidget : the widget is null");
72 "Can't visit VisualizationGraphWidget : the widget is null");
69 }
73 }
70 }
74 }
@@ -3,62 +3,67
3
3
4 Q_LOGGING_CATEGORY(LOG_RescaleAxeOperation, "RescaleAxeOperation")
4 Q_LOGGING_CATEGORY(LOG_RescaleAxeOperation, "RescaleAxeOperation")
5
5
6 struct RescaleAxeOperation::RescaleAxeOperationPrivate {
6 struct RescaleAxeOperation::RescaleAxeOperationPrivate
7 explicit RescaleAxeOperationPrivate(std::shared_ptr<Variable> variable, const DateTimeRange &range)
7 {
8 : m_Variable{variable}, m_Range{range}
8 explicit RescaleAxeOperationPrivate(
9 std::shared_ptr<Variable2> variable, const DateTimeRange& range)
10 : m_Variable { variable }, m_Range { range }
9 {
11 {
10 }
12 }
11
13
12 std::shared_ptr<Variable> m_Variable;
14 std::shared_ptr<Variable2> m_Variable;
13 DateTimeRange m_Range;
15 DateTimeRange m_Range;
14 };
16 };
15
17
16 RescaleAxeOperation::RescaleAxeOperation(std::shared_ptr<Variable> variable, const DateTimeRange &range)
18 RescaleAxeOperation::RescaleAxeOperation(
17 : impl{spimpl::make_unique_impl<RescaleAxeOperationPrivate>(variable, range)}
19 std::shared_ptr<Variable2> variable, const DateTimeRange& range)
20 : impl { spimpl::make_unique_impl<RescaleAxeOperationPrivate>(variable, range) }
18 {
21 {
19 }
22 }
20
23
21 void RescaleAxeOperation::visitEnter(VisualizationWidget *widget)
24 void RescaleAxeOperation::visitEnter(VisualizationWidget* widget)
22 {
25 {
23 // VisualizationWidget is not intended to contain a variable
26 // VisualizationWidget is not intended to contain a variable
24 Q_UNUSED(widget)
27 Q_UNUSED(widget)
25 }
28 }
26
29
27 void RescaleAxeOperation::visitLeave(VisualizationWidget *widget)
30 void RescaleAxeOperation::visitLeave(VisualizationWidget* widget)
28 {
31 {
29 // VisualizationWidget is not intended to contain a variable
32 // VisualizationWidget is not intended to contain a variable
30 Q_UNUSED(widget)
33 Q_UNUSED(widget)
31 }
34 }
32
35
33 void RescaleAxeOperation::visitEnter(VisualizationTabWidget *tabWidget)
36 void RescaleAxeOperation::visitEnter(VisualizationTabWidget* tabWidget)
34 {
37 {
35 // VisualizationTabWidget is not intended to contain a variable
38 // VisualizationTabWidget is not intended to contain a variable
36 Q_UNUSED(tabWidget)
39 Q_UNUSED(tabWidget)
37 }
40 }
38
41
39 void RescaleAxeOperation::visitLeave(VisualizationTabWidget *tabWidget)
42 void RescaleAxeOperation::visitLeave(VisualizationTabWidget* tabWidget)
40 {
43 {
41 // VisualizationTabWidget is not intended to contain a variable
44 // VisualizationTabWidget is not intended to contain a variable
42 Q_UNUSED(tabWidget)
45 Q_UNUSED(tabWidget)
43 }
46 }
44
47
45 void RescaleAxeOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
48 void RescaleAxeOperation::visitEnter(VisualizationZoneWidget* zoneWidget)
46 {
49 {
47 // VisualizationZoneWidget is not intended to contain a variable
50 // VisualizationZoneWidget is not intended to contain a variable
48 Q_UNUSED(zoneWidget)
51 Q_UNUSED(zoneWidget)
49 }
52 }
50
53
51 void RescaleAxeOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
54 void RescaleAxeOperation::visitLeave(VisualizationZoneWidget* zoneWidget)
52 {
55 {
53 // VisualizationZoneWidget is not intended to contain a variable
56 // VisualizationZoneWidget is not intended to contain a variable
54 Q_UNUSED(zoneWidget)
57 Q_UNUSED(zoneWidget)
55 }
58 }
56
59
57 void RescaleAxeOperation::visit(VisualizationGraphWidget *graphWidget)
60 void RescaleAxeOperation::visit(VisualizationGraphWidget* graphWidget)
58 {
61 {
59 if (graphWidget) {
62 if (graphWidget)
63 {
60 // If the widget contains the variable, rescale it
64 // If the widget contains the variable, rescale it
61 if (impl->m_Variable && graphWidget->contains(*impl->m_Variable)) {
65 if (impl->m_Variable && graphWidget->contains(*impl->m_Variable))
66 {
62 // During rescale, acquisition for the graph is disabled but synchronization is still
67 // During rescale, acquisition for the graph is disabled but synchronization is still
63 // enabled
68 // enabled
64 graphWidget->setFlags(GraphFlag::EnableSynchronization);
69 graphWidget->setFlags(GraphFlag::EnableSynchronization);
@@ -66,8 +71,9 void RescaleAxeOperation::visit(VisualizationGraphWidget *graphWidget)
66 graphWidget->setFlags(GraphFlag::EnableAll);
71 graphWidget->setFlags(GraphFlag::EnableAll);
67 }
72 }
68 }
73 }
69 else {
74 else
70 qCCritical(LOG_RescaleAxeOperation(),
75 {
71 "Can't visit VisualizationGraphWidget : the widget is null");
76 qCCritical(
77 LOG_RescaleAxeOperation(), "Can't visit VisualizationGraphWidget : the widget is null");
72 }
78 }
73 }
79 }
@@ -148,7 +148,7 void scroll_graph(T* w, int dx)
148
148
149 ALIAS_TEMPLATE_FUNCTION(isReady, static_cast<SqpApplication*>(qApp)->variableController().isReady)
149 ALIAS_TEMPLATE_FUNCTION(isReady, static_cast<SqpApplication*>(qApp)->variableController().isReady)
150
150
151 void waitForVar(std::shared_ptr<Variable> var)
151 void waitForVar(std::shared_ptr<Variable2> var)
152 {
152 {
153 while (!isReady(var))
153 while (!isReady(var))
154 QCoreApplication::processEvents();
154 QCoreApplication::processEvents();
@@ -1,37 +1,36
1 #include <QtTest>
1 #include <QMainWindow>
2 #include <QObject>
2 #include <QObject>
3 #include <QString>
4 #include <QScreen>
3 #include <QScreen>
5 #include <QMainWindow>
4 #include <QString>
6 #include <QWheelEvent>
5 #include <QWheelEvent>
6 #include <QtTest>
7
7
8 #include <qcustomplot.h>
8 #include <qcustomplot.h>
9
9
10 #include <Common/cpp_utils.h>
10 #include <SqpApplication.h>
11 #include <SqpApplication.h>
11 #include <Variable/VariableController2.h>
12 #include <Variable/VariableController2.h>
12 #include <Common/cpp_utils.h>
13
13
14 #include <Visualization/VisualizationZoneWidget.h>
15 #include <Visualization/VisualizationGraphWidget.h>
16 #include <TestProviders.h>
17 #include <GUITestUtils.h>
14 #include <GUITestUtils.h>
15 #include <TestProviders.h>
16 #include <Visualization/VisualizationGraphWidget.h>
17 #include <Visualization/VisualizationZoneWidget.h>
18
18
19 template <int GraphCount=2>
19 template <int GraphCount = 2>
20 std::tuple< std::unique_ptr<VisualizationZoneWidget>,
20 std::tuple<std::unique_ptr<VisualizationZoneWidget>, std::vector<std::shared_ptr<Variable2>>,
21 std::vector<std::shared_ptr<Variable>>,
21 std::vector<VisualizationGraphWidget*>, DateTimeRange>
22 std::vector<VisualizationGraphWidget*>,
23 DateTimeRange>
24 build_multi_graph_test()
22 build_multi_graph_test()
25 {
23 {
26 auto w = std::make_unique<VisualizationZoneWidget>();
24 auto w = std::make_unique<VisualizationZoneWidget>();
27 auto provider = std::make_shared<SimpleRange<10> >();
25 auto provider = std::make_shared<SimpleRange<10>>();
28 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), QDate(2018, 8, 7),QTime(16, 00));
26 auto range = DateTimeRange::fromDateTime(
29 std::vector<std::shared_ptr<Variable>> variables;
27 QDate(2018, 8, 7), QTime(14, 00), QDate(2018, 8, 7), QTime(16, 00));
28 std::vector<std::shared_ptr<Variable2>> variables;
30 std::vector<VisualizationGraphWidget*> graphs;
29 std::vector<VisualizationGraphWidget*> graphs;
31 for(auto i=0;i<GraphCount;i++)
30 for (auto i = 0; i < GraphCount; i++)
32 {
31 {
33 auto var = static_cast<SqpApplication *>(qApp)->variableController().createVariable(
32 auto var = static_cast<SqpApplication*>(qApp)->variableController().createVariable(
34 QString("V%1").arg(i), {{"", "scalar"}}, provider, range);
33 QString("V%1").arg(i), { { "", "scalar" } }, provider, range);
35 auto graph = new VisualizationGraphWidget();
34 auto graph = new VisualizationGraphWidget();
36 graph->addVariable(var, range);
35 graph->addVariable(var, range);
37 while (!isReady(var))
36 while (!isReady(var))
@@ -40,23 +39,25 build_multi_graph_test()
40 graphs.push_back(graph);
39 graphs.push_back(graph);
41 w->addGraph(graph);
40 w->addGraph(graph);
42 }
41 }
43 return {std::move(w), variables, graphs, range};
42 return { std::move(w), variables, graphs, range };
44 }
43 }
45
44
46
45
47 class A_MultipleSyncGraphs : public QObject {
46 class A_MultipleSyncGraphs : public QObject
47 {
48 Q_OBJECT
48 Q_OBJECT
49 public:
49 public:
50 explicit A_MultipleSyncGraphs(QObject *parent = Q_NULLPTR) : QObject(parent) {}
50 explicit A_MultipleSyncGraphs(QObject* parent = Q_NULLPTR) : QObject(parent) {}
51
51
52 private slots:
52 private slots:
53 void scrolls_left_with_mouse()
53 void scrolls_left_with_mouse()
54 {
54 {
55 auto [w, variables, graphs, range] = build_multi_graph_test<3>();
55 auto [w, variables, graphs, range] = build_multi_graph_test<3>();
56 auto var = variables.front();
56 auto var = variables.front();
57 auto graph = graphs.front();
57 auto graph = graphs.front();
58 QVERIFY(prepare_gui_test(w.get()));
58 QVERIFY(prepare_gui_test(w.get()));
59 for (auto i = 0; i < 100; i++) {
59 for (auto i = 0; i < 100; i++)
60 {
60 scroll_graph(graph, -200);
61 scroll_graph(graph, -200);
61 waitForVar(var);
62 waitForVar(var);
62 }
63 }
@@ -65,18 +66,19 private slots:
65 /*
66 /*
66 * Scrolling to the left implies going back in time
67 * Scrolling to the left implies going back in time
67 * Scroll only implies keeping the same delta T -> shit only transformation
68 * Scroll only implies keeping the same delta T -> shit only transformation
68 */
69 */
69 QVERIFY(r.m_TEnd < range.m_TEnd);
70 QVERIFY(r.m_TEnd < range.m_TEnd);
70 QVERIFY(SciQLop::numeric::almost_equal<double>(r.delta(),range.delta(),1));
71 QVERIFY(SciQLop::numeric::almost_equal<double>(r.delta(), range.delta(), 1));
71 }
72 }
72
73
73 void scrolls_right_with_mouse()
74 void scrolls_right_with_mouse()
74 {
75 {
75 auto [w, variables, graphs, range] = build_multi_graph_test<3>();
76 auto [w, variables, graphs, range] = build_multi_graph_test<3>();
76 auto var = variables.front();
77 auto var = variables.front();
77 auto graph = graphs.front();
78 auto graph = graphs.front();
78 QVERIFY(prepare_gui_test(w.get()));
79 QVERIFY(prepare_gui_test(w.get()));
79 for (auto i = 0; i < 100; i++) {
80 for (auto i = 0; i < 100; i++)
81 {
80 scroll_graph(graph, 200);
82 scroll_graph(graph, 200);
81 waitForVar(var);
83 waitForVar(var);
82 }
84 }
@@ -85,9 +87,9 private slots:
85 /*
87 /*
86 * Scrolling to the right implies going forward in time
88 * Scrolling to the right implies going forward in time
87 * Scroll only implies keeping the same delta T -> shit only transformation
89 * Scroll only implies keeping the same delta T -> shit only transformation
88 */
90 */
89 QVERIFY(r.m_TEnd > range.m_TEnd);
91 QVERIFY(r.m_TEnd > range.m_TEnd);
90 QVERIFY(SciQLop::numeric::almost_equal<double>(r.delta(),range.delta(),1));
92 QVERIFY(SciQLop::numeric::almost_equal<double>(r.delta(), range.delta(), 1));
91 }
93 }
92 };
94 };
93
95
@@ -95,9 +97,9 private slots:
95 QT_BEGIN_NAMESPACE
97 QT_BEGIN_NAMESPACE
96 QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
98 QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
97 QT_END_NAMESPACE
99 QT_END_NAMESPACE
98 int main(int argc, char *argv[])
100 int main(int argc, char* argv[])
99 {
101 {
100 SqpApplication app{argc, argv};
102 SqpApplication app { argc, argv };
101 app.setAttribute(Qt::AA_Use96Dpi, true);
103 app.setAttribute(Qt::AA_Use96Dpi, true);
102 QTEST_DISABLE_KEYPAD_NAVIGATION;
104 QTEST_DISABLE_KEYPAD_NAVIGATION;
103 QTEST_ADD_GPU_BLACKLIST_SUPPORT;
105 QTEST_ADD_GPU_BLACKLIST_SUPPORT;
@@ -1,48 +1,52
1 #include <QtTest>
1 #include <QMainWindow>
2 #include <QObject>
2 #include <QObject>
3 #include <QString>
4 #include <QScreen>
3 #include <QScreen>
5 #include <QMainWindow>
4 #include <QString>
6 #include <QWheelEvent>
5 #include <QWheelEvent>
6 #include <QtTest>
7
7
8 #include <qcustomplot.h>
8 #include <qcustomplot.h>
9
9
10 #include <Common/cpp_utils.h>
10 #include <SqpApplication.h>
11 #include <SqpApplication.h>
11 #include <Variable/VariableController2.h>
12 #include <Variable/VariableController2.h>
12 #include <Common/cpp_utils.h>
13
13
14 #include <Visualization/VisualizationGraphWidget.h>
15 #include <TestProviders.h>
16 #include <GUITestUtils.h>
14 #include <GUITestUtils.h>
17 #include <Variable/Variable.h>
15 #include <TestProviders.h>
16 #include <Variable/Variable2.h>
17 #include <Visualization/VisualizationGraphWidget.h>
18
18
19 std::tuple< std::unique_ptr<VisualizationGraphWidget>,
19 std::tuple<std::unique_ptr<VisualizationGraphWidget>, std::shared_ptr<Variable2>, DateTimeRange>
20 std::shared_ptr<Variable>,
21 DateTimeRange >
22 build_simple_graph_test()
20 build_simple_graph_test()
23 {
21 {
24 auto w = std::make_unique<VisualizationGraphWidget>();
22 auto w = std::make_unique<VisualizationGraphWidget>();
25 auto provider = std::make_shared<SimpleRange<10> >();
23 auto provider = std::make_shared<SimpleRange<10>>();
26 auto range = DateTimeRange::fromDateTime(QDate(2018, 8, 7), QTime(14, 00), QDate(2018, 8, 7),QTime(16, 00));
24 auto range = DateTimeRange::fromDateTime(
27 auto var = static_cast<SqpApplication *>(qApp)->variableController().createVariable("V1", {{"", "scalar"}}, provider, range);
25 QDate(2018, 8, 7), QTime(14, 00), QDate(2018, 8, 7), QTime(16, 00));
28 while (!isReady(var)) QCoreApplication::processEvents();
26 auto var = static_cast<SqpApplication*>(qApp)->variableController().createVariable(
27 "V1", { { "", "scalar" } }, provider, range);
28 while (!isReady(var))
29 QCoreApplication::processEvents();
29 w->addVariable(var, range);
30 w->addVariable(var, range);
30 while (!isReady(var)) QCoreApplication::processEvents();
31 while (!isReady(var))
31 return {std::move(w), var, range};
32 QCoreApplication::processEvents();
33 return { std::move(w), var, range };
32 }
34 }
33
35
34
36
35 class A_SimpleGraph : public QObject {
37 class A_SimpleGraph : public QObject
38 {
36 Q_OBJECT
39 Q_OBJECT
37 public:
40 public:
38 explicit A_SimpleGraph(QObject *parent = Q_NULLPTR) : QObject(parent) {}
41 explicit A_SimpleGraph(QObject* parent = Q_NULLPTR) : QObject(parent) {}
39
42
40 private slots:
43 private slots:
41 void scrolls_left_with_mouse()
44 void scrolls_left_with_mouse()
42 {
45 {
43 auto [w, var, range] = build_simple_graph_test();
46 auto [w, var, range] = build_simple_graph_test();
44 QVERIFY(prepare_gui_test(w.get()));
47 QVERIFY(prepare_gui_test(w.get()));
45 for (auto i = 0; i < 100; i++) {
48 for (auto i = 0; i < 100; i++)
49 {
46 scroll_graph(w.get(), 200);
50 scroll_graph(w.get(), 200);
47 waitForVar(var);
51 waitForVar(var);
48 }
52 }
@@ -50,16 +54,17 private slots:
50 /*
54 /*
51 * Scrolling to the left implies going back in time
55 * Scrolling to the left implies going back in time
52 * Scroll only implies keeping the same delta T -> shit only transformation
56 * Scroll only implies keeping the same delta T -> shit only transformation
53 */
57 */
54 QVERIFY(r.m_TEnd < range.m_TEnd);
58 QVERIFY(r.m_TEnd < range.m_TEnd);
55 QVERIFY(SciQLop::numeric::almost_equal<double>(r.delta(),range.delta(),1));
59 QVERIFY(SciQLop::numeric::almost_equal<double>(r.delta(), range.delta(), 1));
56 }
60 }
57
61
58 void scrolls_right_with_mouse()
62 void scrolls_right_with_mouse()
59 {
63 {
60 auto [w, var, range] = build_simple_graph_test();
64 auto [w, var, range] = build_simple_graph_test();
61 QVERIFY(prepare_gui_test(w.get()));
65 QVERIFY(prepare_gui_test(w.get()));
62 for (auto i = 0; i < 100; i++) {
66 for (auto i = 0; i < 100; i++)
67 {
63 scroll_graph(w.get(), -200);
68 scroll_graph(w.get(), -200);
64 waitForVar(var);
69 waitForVar(var);
65 }
70 }
@@ -67,18 +72,18 private slots:
67 /*
72 /*
68 * Scrolling to the right implies going forward in time
73 * Scrolling to the right implies going forward in time
69 * Scroll only implies keeping the same delta T -> shit only transformation
74 * Scroll only implies keeping the same delta T -> shit only transformation
70 */
75 */
71 QVERIFY(r.m_TEnd > range.m_TEnd);
76 QVERIFY(r.m_TEnd > range.m_TEnd);
72 QVERIFY(SciQLop::numeric::almost_equal<double>(r.delta(),range.delta(),1));
77 QVERIFY(SciQLop::numeric::almost_equal<double>(r.delta(), range.delta(), 1));
73 }
78 }
74 };
79 };
75
80
76 QT_BEGIN_NAMESPACE
81 QT_BEGIN_NAMESPACE
77 QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
82 QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
78 QT_END_NAMESPACE
83 QT_END_NAMESPACE
79 int main(int argc, char *argv[])
84 int main(int argc, char* argv[])
80 {
85 {
81 SqpApplication app{argc, argv};
86 SqpApplication app { argc, argv };
82 app.setAttribute(Qt::AA_Use96Dpi, true);
87 app.setAttribute(Qt::AA_Use96Dpi, true);
83 QTEST_DISABLE_KEYPAD_NAVIGATION;
88 QTEST_DISABLE_KEYPAD_NAVIGATION;
84 QTEST_ADD_GPU_BLACKLIST_SUPPORT;
89 QTEST_ADD_GPU_BLACKLIST_SUPPORT;
General Comments 0
You need to be logged in to leave comments. Login now