##// END OF EJS Templates
Switched to new TS impl but quite broken!...
jeandet -
r1420:3c3e24550401
parent child
Show More
@@ -13,9 +13,15 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 if(BUILD_PLUGINS)
16 target_link_libraries(sciqlopapp mockplugin)
17 target_link_libraries(sciqlopapp mockplugin)
17 target_link_libraries(sciqlopapp amdaplugin)
18 target_link_libraries(sciqlopapp amdaplugin)
18 endif()
19 endif()
20 endif()
21
22 if(NOT BUILD_PLUGINS)
23 add_definitions(-DSQP_NO_PLUGINS)
24 endif()
19
25
20 target_link_libraries(sciqlopapp
26 target_link_libraries(sciqlopapp
21 Qt5::Core
27 Qt5::Core
@@ -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,7 +25,8 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:
@@ -40,8 +42,8 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;
@@ -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,15 +20,16 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:
@@ -12,7 +12,7 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);
@@ -20,7 +20,8 QString formatValue(double value, const QCPAxis &axis);
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
@@ -36,9 +37,10 struct IAxisHelper {
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,12 +13,13 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
@@ -26,9 +27,10 struct IPlottablesHelper {
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,10 +9,11 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
@@ -26,11 +27,11 public:
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,17 +18,19 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
33 {
32 DisableAll = 0x0, ///< Disables acquisition and synchronization
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
@@ -41,7 +43,8 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;
@@ -60,16 +63,16 public:
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);
@@ -80,7 +83,8 public:
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
@@ -94,8 +98,8 public:
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
@@ -118,12 +122,12 public:
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);
@@ -172,10 +176,10 private slots:
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,11 +14,13 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:
@@ -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,8 +55,8 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.
@@ -65,8 +67,8 public:
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:
@@ -12,15 +12,17
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:
@@ -34,8 +36,8 public:
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,13 +46,13 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;
@@ -14,14 +14,16
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:
@@ -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,8 +64,8 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;
@@ -73,8 +75,8 public:
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
@@ -95,9 +97,9 private:
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);
@@ -8,20 +8,21
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;
@@ -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,7 +30,7 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;
@@ -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,13 +17,14 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;
@@ -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,13 +18,14 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;
@@ -23,7 +23,8
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;
@@ -42,9 +43,9 struct DragDropGuiController::DragDropGuiControllerPrivate {
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() };
@@ -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
71 {
72 if (m_CurrentDragWidget)
70 {
73 {
71 if (m_CurrentDragWidget) {
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");
@@ -117,16 +121,17 void DragDropGuiController::resetDragAndDrop()
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;
@@ -142,8 +147,8 QWidget &DragDropGuiController::placeHolder() const
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();
@@ -194,12 +200,14 QUrl DragDropGuiController::imageTemporaryUrl(const QImage &image) const
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
@@ -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
@@ -234,7 +243,8 void DragDropGuiController::doCloseWidgets()
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)
277 {
263 auto visualizationWidget = static_cast<VisualizationWidget *>(parent);
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,20 +19,23
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;
@@ -47,8 +50,8 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,
@@ -59,11 +62,13 public:
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 }
@@ -71,10 +76,12 public:
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);
@@ -91,22 +98,27 public:
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 {
103 if (clickY > y && clickY < y + h)
104 {
96 //auto& variableModel = sqpApp->variableModel();
105 // auto& variableModel = sqpApp->variableModel();
97 //variableModel->abortProgress(index);
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
@@ -116,9 +128,9 public:
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());
@@ -149,7 +159,8 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
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 }
@@ -172,9 +183,11 VariableInspectorWidget::~VariableInspectorWidget()
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 }
@@ -185,25 +198,27 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
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)]() {
211 if (auto var = varW.lock())
196 {
212 {
197 if (auto var = varW.lock()) {
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]() {
220 if (auto var = varW.lock())
205 {
221 {
206 if (auto var = varW.lock()) {
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());
@@ -212,7 +227,8 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
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 }
@@ -230,11 +246,13 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
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,12 +1,12
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);
@@ -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,29 +49,31 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
76 {
71 static void setProperties(QCustomPlot &, SqpColorScale &)
77 static void setProperties(QCustomPlot&, SqpColorScale&)
72 {
78 {
73 // Default implementation does nothing
79 // Default implementation does nothing
@@ -87,8 +93,10 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
98 or std::is_base_of<VectorTimeSerie, T>::value>>
99 {
92 static void setProperties(QCustomPlot &, SqpColorScale &)
100 static void setProperties(QCustomPlot&, SqpColorScale&)
93 {
101 {
94 // Nothing to do
102 // Nothing to do
@@ -96,15 +104,9 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>:
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,7 +115,8 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>>
119 {
117 static void setProperties(QCustomPlot &plot, SqpColorScale &colorScale)
120 static void setProperties(QCustomPlot& plot, SqpColorScale& colorScale)
118 {
121 {
119 // Displays color scale in plot
122 // Displays color scale in plot
@@ -124,7 +127,8 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries
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
@@ -134,17 +138,11 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries
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,8 +151,9 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 {
@@ -163,16 +162,18 struct AxisHelper : public IAxisHelper {
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
@@ -180,30 +181,33 struct AxisHelper : public IAxisHelper {
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
195 {
196 switch (variable.type())
192 {
197 {
193 switch (variable.type()) {
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,19 +6,21
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
23 {
22 static void setProperties(PlottablesMap &)
24 static void setProperties(PlottablesMap&)
23 {
25 {
24 // Default implementation does nothing
26 // Default implementation does nothing
@@ -33,25 +35,27 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
40 or std::is_base_of<VectorTimeSerie, T>::value>>
41 {
38 static void setProperties(PlottablesMap &plottables)
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)
58 {
55 graphIt->second->setPen(QPen{colors.at(i)});
59 graphIt->second->setPen(QPen { colors.at(i) });
56 }
60 }
57 }
61 }
@@ -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>>
72 {
68 static void setProperties(PlottablesMap &plottables)
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,7 +108,8 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
112 {
102 void setProperties(PlottablesMap &plottables) override
113 void setProperties(PlottablesMap& plottables) override
103 {
114 {
104 PlottablesSetter<T>::setProperties(plottables);
115 PlottablesSetter<T>::setProperties(plottables);
@@ -107,16 +118,16 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
122 {
123 switch (variable.type())
112 {
124 {
113 switch (variable.type()) {
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;
@@ -2,17 +2,19
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 };
@@ -24,13 +26,9 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 &)
29 {
30 {
30 qCCritical(LOG_DataSeries())
31 static PlottablesMap createPlottables(QCustomPlot&) { return {}; }
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)
@@ -38,7 +36,8 PlottablesMap createGraphs(QCustomPlot &plot, int nbGraphs)
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 }
@@ -53,7 +52,8 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>>
56 {
57 static PlottablesMap createPlottables(QCustomPlot &plot) { return createGraphs(plot, 1); }
57 static PlottablesMap createPlottables(QCustomPlot& plot) { return createGraphs(plot, 1); }
58 };
58 };
59
59
@@ -62,7 +62,8 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 {
66 static PlottablesMap createPlottables(QCustomPlot &plot) { return createGraphs(plot, 3); }
67 static PlottablesMap createPlottables(QCustomPlot& plot) { return createGraphs(plot, 3); }
67 };
68 };
68
69
@@ -72,7 +73,8 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>>
77 {
76 static PlottablesMap createPlottables(QCustomPlot &plot)
78 static PlottablesMap createPlottables(QCustomPlot& plot)
77 {
79 {
78 PlottablesMap result{};
80 PlottablesMap result {};
@@ -91,7 +93,8 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
97 {
95 static void setPlotYAxisRange(T &, const DateTimeRange &, QCustomPlot &)
98 static void setPlotYAxisRange(T&, const DateTimeRange&, QCustomPlot&)
96 {
99 {
97 qCCritical(LOG_VisualizationGraphHelper())
100 qCCritical(LOG_VisualizationGraphHelper())
@@ -111,61 +114,120 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> > {
117 static void setPlotYAxisRange(T &dataSeries, const DateTimeRange &xAxisRange, QCustomPlot &plot)
119 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();
131
132 plot.yAxis->setRange(QCPRange{minValue, maxValue});
127 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);
148 }
149 }
150
151 if (!plottables.empty())
152 {
153 auto plot = plottables.begin()->second->parentPlot();
145
154
146 dataContainers.insert({plottable.first, dataContainer});
155 if (rescaleAxes)
156 {
157 plot->rescaleAxes();
147 }
158 }
148 }
159 }
149 dataSeries.lockRead();
160 }
161 };
162
150
163
151 // - Gets the data of the series included in the current range
164 template <typename T>
152 // - Updates each plottable by adding, for each data item, a point that takes x-axis data
165 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
153 // and value data. The correct value is retrieved according to the index of the component
166 {
154 auto subDataIts = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
167 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
155 for (auto it = subDataIts.first; it != subDataIts.second; ++it) {
168 {
156 for (const auto &dataContainer : dataContainers) {
169 double minValue = 0., maxValue = 0.;
157 auto componentIndex = dataContainer.first;
170 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
158 dataContainer.second->appendGraphData(
171 {
159 QCPGraphData(it->x(), it->value(componentIndex)));
172 std::for_each(
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 });
160 }
177 }
178
179 plot.yAxis->setRange(QCPRange { minValue, maxValue });
161 }
180 }
162
181
163 dataSeries.unlock();
182 static void updatePlottables(
183 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
184 {
164
185
165 if (!plottables.empty()) {
186 // For each plottable to update, resets its data
187 for (const auto& plottable : plottables)
188 {
189 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
190 {
191 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
192 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
193 {
194 switch (plottable.first)
195 {
196 case 0:
197 std::for_each(std::begin(*serie), std::end(*serie),
198 [&dataContainer](const auto& value) {
199 dataContainer->appendGraphData(
200 QCPGraphData(value.t(), value.v().x));
201 });
202 break;
203 case 1:
204 std::for_each(std::begin(*serie), std::end(*serie),
205 [&dataContainer](const auto& value) {
206 dataContainer->appendGraphData(
207 QCPGraphData(value.t(), value.v().y));
208 });
209 break;
210 case 2:
211 std::for_each(std::begin(*serie), std::end(*serie),
212 [&dataContainer](const auto& value) {
213 dataContainer->appendGraphData(
214 QCPGraphData(value.t(), value.v().z));
215 });
216 break;
217 default:
218 break;
219 }
220 }
221 graph->setData(dataContainer);
222 }
223 }
224
225 if (!plottables.empty())
226 {
166 auto plot = plottables.begin()->second->parentPlot();
227 auto plot = plottables.begin()->second->parentPlot();
167
228
168 if (rescaleAxes) {
229 if (rescaleAxes)
230 {
169 plot->rescaleAxes();
231 plot->rescaleAxes();
170 }
232 }
171 }
233 }
@@ -178,87 +240,97 struct PlottablesUpdater<T,
178 */
240 */
179 template <typename T>
241 template <typename T>
180 struct PlottablesUpdater<T,
242 struct PlottablesUpdater<T,
181 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
243 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
244 {
182 static void setPlotYAxisRange(T &dataSeries, const DateTimeRange &xAxisRange, QCustomPlot &plot)
245 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
183 {
246 {
184 double min, max;
247 // TODO
185 std::tie(min, max) = dataSeries.yBounds();
248 // double min, max;
249 // std::tie(min, max) = dataSeries.yBounds();
186
250
187 if (!std::isnan(min) && !std::isnan(max)) {
251 // if (!std::isnan(min) && !std::isnan(max))
188 plot.yAxis->setRange(QCPRange{min, max});
252 // {
189 }
253 // plot.yAxis->setRange(QCPRange { min, max });
254 // }
190 }
255 }
191
256
192 static void updatePlottables(T &dataSeries, PlottablesMap &plottables, const DateTimeRange &range,
257 static void updatePlottables(
193 bool rescaleAxes)
258 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
194 {
259 {
195 if (plottables.empty()) {
260 // TODO
196 qCDebug(LOG_VisualizationGraphHelper())
261 // if (plottables.empty())
197 << QObject::tr("Can't update spectrogram: no colormap has been associated");
262 // {
198 return;
263 // qCDebug(LOG_VisualizationGraphHelper())
199 }
264 // << QObject::tr("Can't update spectrogram: no colormap has been
200
265 // associated");
201 // Gets the colormap to update (normally there is only one colormap)
266 // return;
202 Q_ASSERT(plottables.size() == 1);
267 // }
203 auto colormap = dynamic_cast<QCPColorMap *>(plottables.at(0));
268
204 Q_ASSERT(colormap != nullptr);
269 // // Gets the colormap to update (normally there is only one colormap)
205
270 // Q_ASSERT(plottables.size() == 1);
206 dataSeries.lockRead();
271 // auto colormap = dynamic_cast<QCPColorMap*>(plottables.at(0));
207
272 // Q_ASSERT(colormap != nullptr);
208 // Processing spectrogram data for display in QCustomPlot
273
209 auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
274 // dataSeries.lockRead();
210
275
211 // Computes logarithmic y-axis resolution for the spectrogram
276 // // Processing spectrogram data for display in QCustomPlot
212 auto yData = its.first->y();
277 // auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
213 auto yResolution = DataSeriesUtils::resolution(yData.begin(), yData.end(), true);
278
214
279 // // Computes logarithmic y-axis resolution for the spectrogram
215 // Generates mesh for colormap
280 // auto yData = its.first->y();
216 auto mesh = DataSeriesUtils::regularMesh(
281 // auto yResolution = DataSeriesUtils::resolution(yData.begin(), yData.end(), true);
217 its.first, its.second, DataSeriesUtils::Resolution{dataSeries.xResolution()},
282
218 yResolution);
283 // // Generates mesh for colormap
219
284 // auto mesh = DataSeriesUtils::regularMesh(its.first, its.second,
220 dataSeries.unlock();
285 // DataSeriesUtils::Resolution { dataSeries.xResolution() }, yResolution);
221
286
222 colormap->data()->setSize(mesh.m_NbX, mesh.m_NbY);
287 // dataSeries.unlock();
223 if (!mesh.isEmpty()) {
288
224 colormap->data()->setRange(
289 // colormap->data()->setSize(mesh.m_NbX, mesh.m_NbY);
225 QCPRange{mesh.m_XMin, mesh.xMax()},
290 // if (!mesh.isEmpty())
226 // y-axis range is converted to linear values
291 // {
227 QCPRange{std::pow(10, mesh.m_YMin), std::pow(10, mesh.yMax())});
292 // colormap->data()->setRange(QCPRange { mesh.m_XMin, mesh.xMax() },
228
293 // // y-axis range is converted to linear values
229 // Sets values
294 // QCPRange { std::pow(10, mesh.m_YMin), std::pow(10, mesh.yMax()) });
230 auto index = 0;
295
231 for (auto it = mesh.m_Data.begin(), end = mesh.m_Data.end(); it != end; ++it, ++index) {
296 // // Sets values
232 auto xIndex = index % mesh.m_NbX;
297 // auto index = 0;
233 auto yIndex = index / mesh.m_NbX;
298 // for (auto it = mesh.m_Data.begin(), end = mesh.m_Data.end(); it != end; ++it,
234
299 // ++index)
235 colormap->data()->setCell(xIndex, yIndex, *it);
300 // {
236
301 // auto xIndex = index % mesh.m_NbX;
237 // Makes the NaN values to be transparent in the colormap
302 // auto yIndex = index / mesh.m_NbX;
238 if (std::isnan(*it)) {
303
239 colormap->data()->setAlpha(xIndex, yIndex, 0);
304 // colormap->data()->setCell(xIndex, yIndex, *it);
240 }
305
241 }
306 // // Makes the NaN values to be transparent in the colormap
242 }
307 // if (std::isnan(*it))
243
308 // {
244 // Rescales axes
309 // colormap->data()->setAlpha(xIndex, yIndex, 0);
245 auto plot = colormap->parentPlot();
310 // }
246
311 // }
247 if (rescaleAxes) {
312 // }
248 plot->rescaleAxes();
313
249 }
314 // // Rescales axes
315 // auto plot = colormap->parentPlot();
316
317 // if (rescaleAxes)
318 // {
319 // plot->rescaleAxes();
320 // }
250 }
321 }
251 };
322 };
252
323
253 /**
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,20 +338,24 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
352 {
353 if (m_DataSeries)
278 {
354 {
279 if (m_DataSeries) {
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";
@@ -288,73 +364,79 struct PlottablesHelper : public IPlottablesHelper {
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
384 {
385 switch (variable->type())
306 {
386 {
307 switch (variable->type()) {
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
408 {
409 if (variable)
329 {
410 {
330 if (variable) {
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
425 {
426 if (variable)
344 {
427 {
345 if (variable) {
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");
@@ -113,7 +114,8 int colorMapCellIndex(const QCPColorMap &colormap, double coord, bool xCoord)
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
152 {
147 explicit VisualizationGraphRenderingDelegatePrivate(VisualizationGraphWidget &graphWidget)
153 explicit VisualizationGraphRenderingDelegatePrivate(VisualizationGraphWidget& graphWidget)
148 : m_Plot{graphWidget.plot()},
154 : m_Plot { graphWidget.plot() }
149 m_PointTracer{new QCPItemTracer{&m_Plot}},
155 , m_PointTracer { new QCPItemTracer { &m_Plot } }
150 m_TracerTimer{},
156 , m_TracerTimer {}
151 m_ClosePixmap{new QCPItemPixmap{&m_Plot}},
157 , m_ClosePixmap { new QCPItemPixmap { &m_Plot } }
152 m_TitleText{new QCPItemText{&m_Plot}},
158 , m_TitleText { new QCPItemText { &m_Plot } }
153 m_XAxisPixmap{new QCPItemPixmap{&m_Plot}},
159 , m_XAxisPixmap { new QCPItemPixmap { &m_Plot } }
154 m_ShowXAxis{true},
160 , m_ShowXAxis { true }
155 m_XAxisLabel{},
161 , m_XAxisLabel {}
156 m_ColorScale{SqpColorScale{m_Plot}}
162 , m_ColorScale { SqpColorScale { m_Plot } }
157 {
163 {
158 initPointTracerStyle(*m_PointTracer);
164 initPointTracerStyle(*m_PointTracer);
159
165
@@ -165,9 +171,10 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)
177 {
171 graphWidget.close();
178 graphWidget.close();
172 }
179 }
173 });
180 });
@@ -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();
@@ -226,8 +234,10 void VisualizationGraphRenderingDelegate::onMouseDoubleClick(QMouseEvent *event)
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 }
@@ -247,13 +257,15 void VisualizationGraphRenderingDelegate::updateTooltip(QMouseEvent *event) noex
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());
@@ -284,7 +297,8 void VisualizationGraphRenderingDelegate::updateTooltip(QMouseEvent *event) noex
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,
@@ -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);
@@ -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;
@@ -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 }
@@ -136,7 +138,8 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
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);
@@ -169,7 +172,8 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);
@@ -179,7 +183,8 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
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)
@@ -195,13 +200,16 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
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
@@ -222,7 +230,8 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
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 }
@@ -233,10 +242,12 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
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 }
@@ -260,7 +273,8 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
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);
@@ -300,8 +314,7 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
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);
@@ -316,10 +329,7 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
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 {
@@ -332,12 +342,14 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
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
346 = yAxis->pixelToCoord(m_lastMousePos.y()) - yAxis->pixelToCoord(currentPos.y());
336 yAxis->setRange(m_lastYRange.lower+dy, m_lastYRange.upper+dy);
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
352 = yAxis->pixelToCoord(m_lastMousePos.y()) / yAxis->pixelToCoord(currentPos.y());
341 yAxis->setRange(m_lastYRange.lower*dy, m_lastYRange.upper*dy);
353 yAxis->setRange(m_lastYRange.lower * dy, m_lastYRange.upper * dy);
342 }
354 }
343 auto newXRange = xAxis->range();
355 auto newXRange = xAxis->range();
@@ -379,18 +391,22 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
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;
@@ -406,9 +422,9 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
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
@@ -442,7 +459,8 VisualizationGraphWidget::~VisualizationGraphWidget()
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
@@ -452,7 +470,8 VisualizationZoneWidget *VisualizationGraphWidget::parentZoneWidget() const noex
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
@@ -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);
@@ -476,41 +495,42 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, D
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 {
488 this->impl->m_RenderingDelegate->setAxesUnits(*variable);
507 this->impl->m_RenderingDelegate->setAxesUnits(*variable);
489 this->impl->m_plot->replot(QCustomPlot::rpQueuedReplot);
508 this->impl->m_plot->replot(QCustomPlot::rpQueuedReplot);
490 delete context;
509 delete context;
491 }
510 });
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)
558 {
559 if (!variable)
537 {
560 {
538 if (!variable) {
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 }
@@ -549,14 +571,14 DateTimeRange VisualizationGraphWidget::graphRange() const noexcept
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,7 +589,8 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
@@ -576,7 +599,8 QVector<DateTimeRange> VisualizationGraphWidget::selectionZoneRanges() const
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());
@@ -604,7 +628,8 void VisualizationGraphWidget::removeSelectionZone(VisualizationSelectionZoneIte
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,7 +651,8 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)
@@ -647,7 +673,8 void VisualizationGraphWidget::move(double dx, double dy, bool 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)
@@ -656,31 +683,32 void VisualizationGraphWidget::transform(const DateTimeRangeTransformation &tran
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;
@@ -703,13 +731,15 QMimeData *VisualizationGraphWidget::mimeData(const QPoint &position) const
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
742 {
713 mimeData->setData(MIME_TYPE_GRAPH, QByteArray{});
743 mimeData->setData(MIME_TYPE_GRAPH, QByteArray {});
714
744
715 auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange());
745 auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange());
@@ -723,7 +753,8 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();
@@ -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
@@ -811,12 +844,14 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 }
@@ -832,14 +867,17 void VisualizationGraphWidget::leaveEvent(QEvent *event)
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 }
@@ -849,7 +887,8 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,14 +905,14 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
876 void VisualizationGraphWidget::mouseMoveEvent(QMouseEvent *event)
916 void VisualizationGraphWidget::mouseMoveEvent(QMouseEvent* event)
877 {
917 {
878 if(impl->isDrawingZoomRect())
918 if (impl->isDrawingZoomRect())
@@ -890,19 +930,20 void VisualizationGraphWidget::mouseMoveEvent(QMouseEvent *event)
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
@@ -936,7 +977,8 void VisualizationGraphWidget::mouseReleaseEvent(QMouseEvent *event)
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 }
@@ -960,7 +1002,8 void VisualizationGraphWidget::mousePressEvent(QMouseEvent *event)
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 {
@@ -970,7 +1013,8 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(
1017 alreadySelectedZones);
974 }
1018 }
975 else
1019 else
976 {
1020 {
@@ -981,7 +1025,8 void VisualizationGraphWidget::mousePressEvent(QMouseEvent *event)
981 }
1025 }
982 else
1026 else
983 {
1027 {
984 parentVisualizationWidget()->selectionZoneManager().select({ selectedZone });
1028 parentVisualizationWidget()->selectionZoneManager().select(
1029 { selectedZone });
985 }
1030 }
986 }
1031 }
987 {
1032 {
@@ -990,7 +1035,8 void VisualizationGraphWidget::mousePressEvent(QMouseEvent *event)
990 {
1035 {
991 if(qobject_cast<VisualizationSelectionZoneItem*>(item))
1036 if (qobject_cast<VisualizationSelectionZoneItem*>(item))
992 {
1037 {
993 QMouseEvent e{QEvent::MouseButtonPress, posInPlot, event->button(), event->buttons(), event->modifiers()};
1038 QMouseEvent e { QEvent::MouseButtonPress, posInPlot, event->button(),
1039 event->buttons(), event->modifiers() };
994 sqpApp->sendEvent(this->impl->m_plot, &e);
1040 sqpApp->sendEvent(this->impl->m_plot, &e);
995 }
1041 }
996 }
1042 }
@@ -1027,7 +1073,8 void VisualizationGraphWidget::mouseDoubleClickEvent(QMouseEvent *event)
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;
@@ -1044,7 +1091,8 void VisualizationGraphWidget::keyReleaseEvent(QKeyEvent *event)
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;
@@ -1104,14 +1160,17 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
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,13 +1179,15 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
@@ -1134,24 +1195,29 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
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 }
@@ -1159,9 +1225,11 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
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)
1232 {
1165 filterAction = new FilteringAction{this};
1233 filterAction = new FilteringAction { this };
1166 filteredMenu[menuPath] = filterAction;
1234 filteredMenu[menuPath] = filterAction;
1167 menu->addAction(filterAction);
1235 menu->addAction(filterAction);
@@ -1174,17 +1242,20 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
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 }
@@ -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 }
@@ -1255,12 +1336,14 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
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);
@@ -1273,13 +1356,15 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
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
@@ -1295,15 +1380,19 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
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 }
@@ -1344,7 +1438,8 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
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);
@@ -1358,7 +1453,8 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
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,14 +1468,17 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 };
@@ -1387,40 +1486,49 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
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,
1525 !selectionZoneItemUnderCursor->selected()
1419 || event->button() == Qt::RightButton);
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 }
@@ -1431,37 +1539,42 void VisualizationGraphWidget::onDataCacheVariableUpdated()
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
@@ -27,10 +28,13 namespace {
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 }
@@ -42,12 +46,13 void processZones(QLayout &layout, Fun fun)
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,7 +62,8 QString defaultZoneName(QLayout &layout)
57
62
58 } // namespace
63 } // namespace
59
64
60 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
65 struct VisualizationTabWidget::VisualizationTabWidgetPrivate
66 {
61 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
67 explicit VisualizationTabWidgetPrivate(const QString& name) : m_Name { name } {}
62
68
63 QString m_Name;
69 QString m_Name;
@@ -68,16 +74,16 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
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);
73 void dropProducts(const QVariantList &productsMetaData, int index,
74 VisualizationTabWidget *tabWidget);
78 VisualizationTabWidget* tabWidget);
79 void dropProducts(
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,18 +94,18 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,
@@ -130,8 +136,8 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 }
@@ -140,7 +146,8 VisualizationZoneWidget *VisualizationTabWidget::getZoneWithName(const QString &
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
@@ -175,29 +182,30 VisualizationZoneWidget *VisualizationTabWidget::createEmptyZone(int index)
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;
@@ -223,23 +231,28 QLayout &VisualizationTabWidget::tabLayout() const noexcept
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 }
@@ -251,7 +264,8 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
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.");
@@ -261,7 +275,8 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
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.");
@@ -273,7 +288,8 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
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,7 +333,8 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 }
@@ -324,7 +346,8 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
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.");
@@ -334,7 +357,8 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
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.");
@@ -368,7 +393,8 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropProducts(
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.");
@@ -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
@@ -34,9 +35,9 struct VisualizationWidget::VisualizationWidgetPrivate {
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
@@ -46,7 +47,6 VisualizationWidget::VisualizationWidget(QWidget *parent)
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 = new VisualizationTabWidget { QString { "View %1" }.arg(ui->tabWidget->count() + 1),
61 ui->tabWidget};
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 }
@@ -121,7 +126,8 VisualizationSelectionZoneManager &VisualizationWidget::selectionZoneManager() c
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
@@ -130,33 +136,37 VisualizationTabWidget *VisualizationWidget::currentTabWidget() const
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,42 +178,46 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 };
@@ -213,9 +227,11 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
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 }
@@ -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
@@ -38,10 +39,13 namespace {
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 }
@@ -58,7 +62,8 QString defaultGraphName(QLayout &layout)
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);
84 void dropProducts(const QVariantList &productsData, int index,
85 VisualizationZoneWidget *zoneWidget);
89 VisualizationZoneWidget* zoneWidget);
90 void dropProducts(
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 }
@@ -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()
@@ -157,10 +167,12 VisualizationZoneWidget::~VisualizationZoneWidget()
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 }
@@ -173,39 +185,32 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
173
185
174 // ui->dragDropContainer->addDragWidget(graphWidget);
186 // ui->dragDropContainer->addDragWidget(graphWidget);
175 insertGraph(0,graphWidget);
187 insertGraph(0, graphWidget);
176
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++)
184 {
185 auto graph = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(i)->widget());
194 auto graph = qobject_cast<VisualizationGraphWidget*>(layout->itemAt(i)->widget());
186 connect(graphWidget, &VisualizationGraphWidget::setrange_sig, graph, &VisualizationGraphWidget::setGraphRange);
195 connect(graphWidget, &VisualizationGraphWidget::setrange_sig, graph,
187 connect(graph, &VisualizationGraphWidget::setrange_sig, graphWidget, &VisualizationGraphWidget::setGraphRange);
196 &VisualizationGraphWidget::setGraphRange);
188 }
197 connect(graph, &VisualizationGraphWidget::setrange_sig, graphWidget,
189 if(auto graph = firstGraph())
198 &VisualizationGraphWidget::setGraphRange);
190 {
199 } if (auto graph = firstGraph()) { graphWidget->setGraphRange(graph->graphRange(), true); })
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 };
@@ -263,7 +268,8 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
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
272 // account");
267 // // No action
273 // // No action
268 // break;
274 // break;
269 // }
275 // }
@@ -282,11 +288,13 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
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,15 +307,17 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)
312 {
313 if (variables.empty())
304 {
314 {
305 if (variables.empty()) {
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
@@ -318,9 +328,11 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 }
@@ -336,30 +348,31 void VisualizationZoneWidget::closeAllGraphs()
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(),
346 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
358 [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;
@@ -377,7 +390,8 QMimeData *VisualizationZoneWidget::mimeData(const QPoint &position) const
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 }
@@ -391,13 +405,12 bool VisualizationZoneWidget::isDragAllowed() const
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)
409 {
410 processGraphs(*ui->dragDropContainer->layout(),
411 [&graphPosition, &plotPosition, &graphWidget](VisualizationGraphWidget& processedGraph) {
412 switch (sqpApp->plotsCursorMode())
396 {
413 {
397 processGraphs(*ui->dragDropContainer->layout(), [&graphPosition, &plotPosition, &graphWidget](
398 VisualizationGraphWidget &processedGraph) {
399
400 switch (sqpApp->plotsCursorMode()) {
401 case SqpApplication::PlotsCursorMode::Vertical:
414 case SqpApplication::PlotsCursorMode::Vertical:
402 processedGraph.removeHorizontalCursor();
415 processedGraph.removeHorizontalCursor();
403 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
416 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
@@ -408,19 +421,23 void VisualizationZoneWidget::notifyMouseMoveInGraph(const QPointF &graphPositio
408 break;
421 break;
409 case SqpApplication::PlotsCursorMode::Horizontal:
422 case SqpApplication::PlotsCursorMode::Horizontal:
410 processedGraph.removeVerticalCursor();
423 processedGraph.removeVerticalCursor();
411 if (&processedGraph == graphWidget) {
424 if (&processedGraph == graphWidget)
425 {
412 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
426 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
413 }
427 }
414 else {
428 else
429 {
415 processedGraph.removeHorizontalCursor();
430 processedGraph.removeHorizontalCursor();
416 }
431 }
417 break;
432 break;
418 case SqpApplication::PlotsCursorMode::Cross:
433 case SqpApplication::PlotsCursorMode::Cross:
419 if (&processedGraph == graphWidget) {
434 if (&processedGraph == graphWidget)
435 {
420 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
436 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
421 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
437 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
422 }
438 }
423 else {
439 else
440 {
424 processedGraph.removeHorizontalCursor();
441 processedGraph.removeHorizontalCursor();
425 processedGraph.removeVerticalCursor();
442 processedGraph.removeVerticalCursor();
426 }
443 }
@@ -430,8 +447,6 void VisualizationZoneWidget::notifyMouseMoveInGraph(const QPointF &graphPositio
430 processedGraph.removeVerticalCursor();
447 processedGraph.removeVerticalCursor();
431 break;
448 break;
432 }
449 }
433
434
435 });
450 });
436 }
451 }
437
452
@@ -456,46 +471,50 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
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,14 +522,17 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
@@ -527,14 +549,12 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragW
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 {
533 graphWidget->addVariable(variable, range);
554 graphWidget->addVariable(variable, range);
534 delete context;
555 delete context;
535 });
556 });
536 }
557 }
537
538 },
558 },
539 Qt::QueuedConnection);
559 Qt::QueuedConnection);
540
560
@@ -542,11 +562,13 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragW
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 }
@@ -558,7 +580,8 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
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.");
@@ -568,7 +591,8 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
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.");
@@ -578,7 +602,8 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
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,12 +656,13 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);
@@ -641,7 +673,8 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropProducts(
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.");
@@ -5,25 +5,28
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 }
@@ -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,8 +27,9 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" });
@@ -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)
55 {
56 if (isValidContainer(container))
54 {
57 {
55 if (isValidContainer(container)) {
56 m_PlotMenuBuilder.addSeparator();
58 m_PlotMenuBuilder.addSeparator();
57 m_PlotMenuBuilder.addAction(actionName, actionFunction);
59 m_PlotMenuBuilder.addAction(actionName, actionFunction);
58 }
60 }
@@ -68,20 +70,22 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)
75 {
76 if (isValidContainer(container))
73 {
77 {
74 if (isValidContainer(container)) {
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 }
@@ -93,15 +97,14 struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate {
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)
105 : impl{spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>(
108 : impl { spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>(
106 menu, variable, std::move(variableContainers))}
109 menu, variable, std::move(variableContainers)) }
107 {
110 {
@@ -127,11 +130,13 void GenerateVariableMenuOperation::visitLeave(VisualizationWidget *widget)
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 }
@@ -139,11 +144,13 void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget *tabWidget
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())
153 {
147 tabWidget->createZone(var);
154 tabWidget->createZone(var);
148 }
155 }
149 });
156 });
@@ -151,7 +158,8 void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget
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 }
@@ -159,11 +167,13 void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget
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 }
@@ -171,12 +181,13 void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget *zoneWidg
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,7 +195,8 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 }
@@ -192,24 +204,28 void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidg
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())
213 {
200 graphWidget->addVariable(var, graphWidget->graphRange());
214 graphWidget->addVariable(var, graphWidget->graphRange());
201 }
215 }
202 });
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())
222 {
208 graphWidget->removeVariable(var);
223 graphWidget->removeVariable(var);
209 }
224 }
210 });
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 }
@@ -1,20 +1,21
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 }
@@ -57,13 +58,16 void RemoveVariableOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
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 }
@@ -3,17 +3,20
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 explicit RescaleAxeOperationPrivate(
9 std::shared_ptr<Variable2> variable, const DateTimeRange& range)
8 : m_Variable{variable}, m_Range{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(
19 std::shared_ptr<Variable2> variable, const DateTimeRange& range)
17 : impl{spimpl::make_unique_impl<RescaleAxeOperationPrivate>(variable, range)}
20 : impl { spimpl::make_unique_impl<RescaleAxeOperationPrivate>(variable, range) }
18 {
21 {
19 }
22 }
@@ -56,9 +59,11 void RescaleAxeOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
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,32 +1,31
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 {
@@ -44,7 +43,8 build_multi_graph_test()
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) {}
@@ -56,7 +56,8 private slots:
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 }
@@ -76,7 +77,8 private slots:
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 }
@@ -1,38 +1,41
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))
32 QCoreApplication::processEvents();
31 return {std::move(w), var, range};
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) {}
@@ -42,7 +45,8 private slots:
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 }
@@ -59,7 +63,8 private slots:
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 }
General Comments 0
You need to be logged in to leave comments. Login now