@@ -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( |
|
45 | void tableMenuAboutToBeDisplayed( | |
44 |
|
|
46 | QMenu* tableMenu, const QVector<std::shared_ptr<Variable2>>& variables); | |
45 |
|
47 | |||
46 | private: |
|
48 | private: | |
47 |
Ui::VariableInspectorWidget |
|
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 |
|
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 |
|
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( |
|
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( |
|
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( |
|
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 |
|
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( |
|
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 |
|
34 | static PlottablesMap create(std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept; | |
34 |
|
35 | |||
35 |
static void updateData(PlottablesMap |
|
36 | static void updateData(PlottablesMap& plottables, std::shared_ptr<Variable2> variable, | |
36 |
|
|
37 | const DateTimeRange& dateTime); | |
37 |
|
38 | |||
38 |
static void setYAxisRange(std::shared_ptr<Variable> variable, QCustomPlot |
|
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( |
|
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( |
|
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, |
|
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> |
|
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 |
|
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> |
|
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 |
|
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 |
|
89 | void removeSelectionZone(VisualizationSelectionZoneItem* selectionZone); | |
86 |
|
90 | |||
@@ -94,8 +98,8 public: | |||||
94 |
|
98 | |||
95 | // IVisualizationWidget interface |
|
99 | // IVisualizationWidget interface | |
96 |
void accept(IVisualizationWidgetVisitor |
|
100 | void accept(IVisualizationWidgetVisitor* visitor) override; | |
97 |
bool canDrop( |
|
101 | bool canDrop(Variable2& variable) const override; | |
98 |
bool contains( |
|
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 |
|
124 | void synchronize(const DateTimeRange& range, const DateTimeRange& oldRange); | |
121 |
void changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange |
|
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 |
|
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 |
|
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 |
|
69 | void accept(IVisualizationWidgetVisitor* visitor) override; | |
68 |
bool canDrop( |
|
70 | bool canDrop(Variable2& variable) const override; | |
69 |
bool contains( |
|
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 |
|
38 | void accept(IVisualizationWidgetVisitor* visitor) override; | |
37 |
bool canDrop( |
|
39 | bool canDrop(Variable2& variable) const override; | |
38 |
bool contains( |
|
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( |
|
49 | void attachVariableMenu( | |
48 |
|
|
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 |
|
55 | void onRangeChanged(std::shared_ptr<Variable2> variable, const DateTimeRange& range) noexcept; | |
54 |
|
56 | |||
55 | protected: |
|
57 | protected: | |
56 |
void closeEvent(QCloseEvent |
|
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 |
|
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 |
|
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 |
|
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 |
|
71 | VisualizationGraphWidget* firstGraph() const; | |
@@ -73,8 +75,8 public: | |||||
73 |
|
75 | |||
74 | // IVisualizationWidget interface |
|
76 | // IVisualizationWidget interface | |
75 |
void accept(IVisualizationWidgetVisitor |
|
77 | void accept(IVisualizationWidgetVisitor* visitor) override; | |
76 |
bool canDrop( |
|
78 | bool canDrop(Variable2& variable) const override; | |
77 |
bool contains( |
|
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 |
|
104 | void dropMimeData(int index, const QMimeData* mimeData); | |
103 |
void dropMimeDataOnGraph(VisualizationDragWidget |
|
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 |
|
27 | void visitEnter(VisualizationWidget* widget) override final; | |
27 |
void visitLeave(VisualizationWidget |
|
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 |
|
33 | explicit GenerateVariableMenuOperation(QMenu* menu, std::shared_ptr<Variable2> variable, | |
33 |
|
|
34 | std::set<IVisualizationWidget*> variableContainers); | |
34 |
|
35 | |||
35 |
void visitEnter(VisualizationWidget |
|
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 |
|
29 | void visitEnter(VisualizationWidget* widget) override final; | |
29 |
void visitLeave(VisualizationWidget |
|
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 |
|
28 | explicit RescaleAxeOperation(std::shared_ptr<Variable2> variable, const DateTimeRange& range); | |
28 |
|
29 | |||
29 |
void visitEnter(VisualizationWidget |
|
30 | void visitEnter(VisualizationWidget* widget) override final; | |
30 |
void visitLeave(VisualizationWidget |
|
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 |
|
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 |
|
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 |
|
|
47 | , m_DragDropScroller { std::make_unique<DragDropScroller>() } | |
47 |
|
|
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 |
|
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( |
|
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 |
|
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 |
|
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->data |
|
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 |
|
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 |
|
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 |
|
26 | QProgressBarItemDelegate(QObject* parent) : QStyledItemDelegate { parent } {} | |
26 |
|
27 | |||
27 | void paint(QPainter *painter, const QStyleOptionViewItem &option, |
|
28 | void paint( | |
28 |
|
|
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( |
|
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 |
|
76 | bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, | |
72 |
|
|
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(); |
|
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 |
|
130 | VariableInspectorWidget::VariableInspectorWidget(QWidget* parent) | |
119 |
: QWidget{parent} |
|
131 | : QWidget { parent } | |
120 |
|
|
132 | , ui { new Ui::VariableInspectorWidget } | |
121 |
|
|
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 |
|
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 |
|
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 = [ |
|
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 |
|
|
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> |
|
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/ScalarSerie |
|
3 | #include <Data/ScalarTimeSerie.h> | |
4 |
#include <Data/SpectrogramSerie |
|
4 | #include <Data/SpectrogramTimeSerie.h> | |
5 |
#include <Data/VectorSerie |
|
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 |
|
52 | void setAxisProperties(QCPAxis& axis, const std::string& unit, bool isTime, | |
49 |
|
|
53 | QCPAxis::ScaleType scaleType = QCPAxis::stLinear) | |
50 | { |
|
54 | { | |
51 | // label (unit name) |
|
55 | // label (unit name) | |
52 |
axis.setLabel(unit |
|
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( |
|
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 |
|
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 |
|
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 |
|
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<SpectrogramSerie |
|
118 | struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>> | |
|
119 | { | |||
117 |
static void setProperties(QCustomPlot |
|
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 |
|
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 |
|
158 | void setProperties(QCustomPlot& plot, SqpColorScale& colorScale) override | |
160 | { |
|
159 | { | |
@@ -163,16 +162,18 struct AxisHelper : public IAxisHelper { | |||||
163 |
|
162 | |||
164 |
void setUnits(QCustomPlot |
|
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 |
|
|
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 |
|
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( |
|
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<ScalarSerie |
|
199 | return std::make_unique<AxisHelper<ScalarTimeSerie>>( | |
196 |
|
|
200 | dynamic_cast<ScalarTimeSerie*>(variable.data()->base())); | |
197 | case DataSeriesType::SPECTROGRAM: |
|
201 | case DataSeriesType::SPECTROGRAM: | |
198 |
return std::make_unique<AxisHelper<SpectrogramSerie |
|
202 | return std::make_unique<AxisHelper<SpectrogramTimeSerie>>( | |
199 |
|
|
203 | dynamic_cast<SpectrogramTimeSerie*>(variable.data()->base())); | |
200 | case DataSeriesType::VECTOR: |
|
204 | case DataSeriesType::VECTOR: | |
201 |
return std::make_unique<AxisHelper<VectorSerie |
|
205 | return std::make_unique<AxisHelper<VectorTimeSerie>>( | |
202 |
|
|
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< |
|
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 |
|
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 |
|
|
71 | typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>> | |
|
72 | { | |||
68 |
static void setProperties(PlottablesMap |
|
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 |
|
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 |
|
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<ScalarSerie |
|
126 | return std::make_unique<PlottablesHelper<ScalarTimeSerie>>(); | |
116 | case DataSeriesType::SPECTROGRAM: |
|
127 | case DataSeriesType::SPECTROGRAM: | |
117 |
return std::make_unique<PlottablesHelper<SpectrogramSerie |
|
128 | return std::make_unique<PlottablesHelper<SpectrogramTimeSerie>>(); | |
118 | case DataSeriesType::VECTOR: |
|
129 | case DataSeriesType::VECTOR: | |
119 |
return std::make_unique<PlottablesHelper<VectorSerie |
|
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/ScalarSerie |
|
5 | #include <Data/ScalarTimeSerie.h> | |
6 |
#include <Data/SpectrogramSerie |
|
6 | #include <Data/SpectrogramTimeSerie.h> | |
7 |
#include <Data/VectorSerie |
|
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 |
|
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 |
|
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<ScalarSerie |
|
55 | struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>> | |
|
56 | { | |||
57 |
static PlottablesMap createPlottables(QCustomPlot |
|
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<VectorSerie |
|
65 | struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>> | |
|
66 | { | |||
66 |
static PlottablesMap createPlottables(QCustomPlot |
|
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 |
|
|
76 | typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>> | |
|
77 | { | |||
76 |
static PlottablesMap createPlottables(QCustomPlot |
|
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 |
|
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 |
|
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 |
|
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 |
|
|
243 | typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>> | |
|
244 | { | |||
182 |
static void setPlotYAxisRange(T |
|
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()->set |
|
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 |
|
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()->set |
|
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 |
|
330 | virtual PlottablesMap create(QCustomPlot& plot) const = 0; | |
259 |
virtual void setYAxisRange(const DateTimeRange |
|
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 |
|
|
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 |
|
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 |
|
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 |
|
|
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<ScalarSerie |
|
388 | return std::make_unique<PlottablesHelper<ScalarTimeSerie>>( | |
310 |
|
|
389 | dynamic_cast<ScalarTimeSerie*>(variable->data()->base())); | |
311 | case DataSeriesType::SPECTROGRAM: |
|
390 | case DataSeriesType::SPECTROGRAM: | |
312 |
return std::make_unique<PlottablesHelper<SpectrogramSerie |
|
391 | return std::make_unique<PlottablesHelper<SpectrogramTimeSerie>>( | |
313 |
|
|
392 | dynamic_cast<SpectrogramTimeSerie*>(variable->data()->base())); | |
314 | case DataSeriesType::VECTOR: |
|
393 | case DataSeriesType::VECTOR: | |
315 |
return std::make_unique<PlottablesHelper<VectorSerie |
|
394 | return std::make_unique<PlottablesHelper<VectorTimeSerie>>( | |
316 |
|
|
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< |
|
401 | return std::make_unique<PlottablesHelper<TimeSeries::ITimeSerie>>(nullptr); | |
323 | } |
|
402 | } | |
324 |
|
403 | |||
325 | } // namespace |
|
404 | } // namespace | |
326 |
|
405 | |||
327 |
PlottablesMap VisualizationGraphHelper::create( |
|
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( |
|
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( |
|
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 |
|
|
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 |
|
153 | explicit VisualizationGraphRenderingDelegatePrivate(VisualizationGraphWidget& graphWidget) | |
148 |
: m_Plot{graphWidget.plot()} |
|
154 | : m_Plot { graphWidget.plot() } | |
149 |
|
|
155 | , m_PointTracer { new QCPItemTracer { &m_Plot } } | |
150 |
|
|
156 | , m_TracerTimer {} | |
151 |
|
|
157 | , m_ClosePixmap { new QCPItemPixmap { &m_Plot } } | |
152 |
|
|
158 | , m_TitleText { new QCPItemText { &m_Plot } } | |
153 |
|
|
159 | , m_XAxisPixmap { new QCPItemPixmap { &m_Plot } } | |
154 |
|
|
160 | , m_ShowXAxis { true } | |
155 |
|
|
161 | , m_XAxisLabel {} | |
156 |
|
|
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( |
|
174 | QObject::connect( | |
169 |
|
|
175 | &m_Plot, &QCustomPlot::itemClick, [&graphWidget, this](auto item, auto mouseEvent) { | |
170 |
|
|
176 | if (item == m_ClosePixmap) | |
|
177 | { | |||
171 |
|
|
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 |
|
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 |
|
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 |
|
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 |
|
|
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( |
|
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( |
|
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 |
|
65 | explicit VisualizationGraphWidgetPrivate(const QString& name) | |
64 |
: m_Name{name} |
|
66 | : m_Name { name } | |
65 |
|
|
67 | , m_Flags { GraphFlag::EnableAll } | |
66 |
|
|
68 | , m_IsCalibration { false } | |
67 |
|
|
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()), |
|
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 |
|
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 |
|
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 |
|
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 |
|
258 | QVector<VisualizationSelectionZoneItem*> selectionZonesAt( | |
248 | const QCustomPlot &plot) const |
|
259 | const QPoint& pos, const QCustomPlot& plot) const | |
249 | { |
|
260 | { | |
250 |
QVector<VisualizationSelectionZoneItem |
|
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 |
|
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 |
|
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 |
|
424 | VisualizationGraphWidget::VisualizationGraphWidget(const QString& name, QWidget* parent) | |
409 |
: VisualizationDragWidget{parent} |
|
425 | : VisualizationDragWidget { parent } | |
410 |
|
|
426 | , ui { new Ui::VisualizationGraphWidget } | |
411 |
|
|
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, |
|
449 | connect(&sqpApp->variableController(), &VariableController2::variableDeleted, this, | |
|
450 | &VisualizationGraphWidget::variableDeleted); | |||
434 | } |
|
451 | } | |
435 |
|
452 | |||
436 |
|
453 | |||
@@ -442,7 +459,8 VisualizationGraphWidget::~VisualizationGraphWidget() | |||||
442 |
VisualizationZoneWidget |
|
459 | VisualizationZoneWidget* VisualizationGraphWidget::parentZoneWidget() const noexcept | |
443 | { |
|
460 | { | |
444 | auto parent = parentWidget(); |
|
461 | auto parent = parentWidget(); | |
445 |
while (parent != nullptr && !qobject_cast<VisualizationZoneWidget |
|
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 |
|
470 | VisualizationWidget* VisualizationGraphWidget::parentVisualizationWidget() const | |
453 | { |
|
471 | { | |
454 | auto parent = parentWidget(); |
|
472 | auto parent = parentWidget(); | |
455 |
while (parent != nullptr && !qobject_cast<VisualizationWidget |
|
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->data |
|
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 |
|
|
506 | variable.get(), &Variable2::updated, context, [this, variable, context, range](QUuid) { | |
487 | { |
|
|||
488 |
|
|
507 | this->impl->m_RenderingDelegate->setAxesUnits(*variable); | |
489 |
|
|
508 | this->impl->m_plot->replot(QCustomPlot::rpQueuedReplot); | |
490 |
|
|
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 |
|
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> |
|
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( |
|
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> |
|
600 | void VisualizationGraphWidget::addSelectionZones(const QVector<DateTimeRange>& ranges) | |
578 | { |
|
601 | { | |
579 |
for (const auto |
|
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 |
|
|
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 |
|
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( |
|
697 | bool VisualizationGraphWidget::canDrop(Variable2& variable) const | |
669 | { |
|
698 | { | |
670 |
auto isSpectrogram |
|
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 |
|
|
705 | ? impl->m_VariableToPlotMultiMap.empty() | |
678 | : std::none_of( |
|
706 | : std::none_of(impl->m_VariableToPlotMultiMap.cbegin(), | |
679 |
|
|
707 | impl->m_VariableToPlotMultiMap.cend(), | |
680 |
|
|
708 | [isSpectrogram](const auto& entry) { return isSpectrogram(*entry.first); }); | |
681 | } |
|
709 | } | |
682 |
|
710 | |||
683 |
bool VisualizationGraphWidget::contains( |
|
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 |
|
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 |
|
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() |
|
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(), |
|
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(), |
|
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( |
|
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( |
|
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(), |
|
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 |
|
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 |
|
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 |
|
|
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 |
|
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 |
|
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 |
|
|
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 |
|
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 |
|
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 |
|
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( |
|
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, |
|
1524 | selectionZoneItemUnderCursor, | |
|
1525 | !selectionZoneItemUnderCursor->selected() | |||
1419 |
|
|
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 |
|
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( |
|
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 |
|
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> |
|
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 |
|
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 |
|
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 |
|
46 | QString defaultZoneName(QLayout& layout) | |
43 | { |
|
47 | { | |
44 | QSet<QString> existingNames; |
|
48 | QSet<QString> existingNames; | |
45 |
processZones( |
|
49 | processZones( | |
46 |
|
|
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 |
|
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 |
|
75 | void dropGraph(int index, VisualizationTabWidget* tabWidget); | |
70 |
void dropZone(int index, VisualizationTabWidget |
|
76 | void dropZone(int index, VisualizationTabWidget* tabWidget); | |
71 |
void dropVariables(const std::vector<std::shared_ptr<Variable> |
|
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 |
|
|
78 | VisualizationTabWidget* tabWidget); | |
|
79 | void dropProducts( | |||
|
80 | const QVariantList& productsMetaData, int index, VisualizationTabWidget* tabWidget); | |||
75 | }; |
|
81 | }; | |
76 |
|
82 | |||
77 |
VisualizationTabWidget::VisualizationTabWidget(const QString |
|
83 | VisualizationTabWidget::VisualizationTabWidget(const QString& name, QWidget* parent) | |
78 |
: QWidget{parent} |
|
84 | : QWidget { parent } | |
79 |
|
|
85 | , ui { new Ui::VisualizationTabWidget } | |
80 |
|
|
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( |
|
97 | ui->dragDropContainer->setMimeType( | |
92 |
|
|
98 | MIME_TYPE_GRAPH, VisualizationDragDropContainer::DropBehavior::Inserted); | |
93 |
ui->dragDropContainer->setMimeType( |
|
99 | ui->dragDropContainer->setMimeType( | |
94 |
|
|
100 | MIME_TYPE_ZONE, VisualizationDragDropContainer::DropBehavior::Inserted); | |
95 |
ui->dragDropContainer->setMimeType( |
|
101 | ui->dragDropContainer->setMimeType( | |
96 |
|
|
102 | MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::Inserted); | |
97 |
ui->dragDropContainer->setMimeType( |
|
103 | ui->dragDropContainer->setMimeType( | |
98 |
|
|
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( |
|
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( |
|
139 | processZones( | |
134 |
|
|
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 |
|
147 | VisualizationZoneWidget* result = nullptr; | |
142 |
processZones(tabLayout(), [&zoneName, &result](VisualizationZoneWidget |
|
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 |
|
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 |
|
|
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 |
|
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( |
|
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( |
|
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 |
|
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:: |
|
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 |
|
264 | auto& helper = sqpApp->dragDropGuiController(); | |
252 |
|
265 | |||
253 |
auto graphWidget = qobject_cast<VisualizationGraphWidget |
|
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 |
|
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 |
|
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 |
|
346 | auto& helper = sqpApp->dragDropGuiController(); | |
325 |
|
347 | |||
326 |
auto zoneWidget = qobject_cast<VisualizationZoneWidget |
|
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 |
|
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> |
|
375 | const std::vector<std::shared_ptr<Variable2>>& variables, int index, | |
352 |
VisualizationTabWidget |
|
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 |
|
37 | VisualizationWidget::VisualizationWidget(QWidget* parent) | |
37 |
: QWidget{parent} |
|
38 | : QWidget { parent } | |
38 |
|
|
39 | , ui { new Ui::VisualizationWidget } | |
39 |
|
|
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 |
|
|
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 |
|
127 | VisualizationTabWidget* VisualizationWidget::currentTabWidget() const | |
123 | { |
|
128 | { | |
124 |
if (auto tab = qobject_cast<VisualizationTabWidget |
|
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 |
|
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 |
|
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( |
|
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( |
|
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 |
|
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 |
|
|
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( |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
|
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 |
|
87 | void dropGraph(int index, VisualizationZoneWidget* zoneWidget); | |
82 |
void dropVariables(const std::vector<std::shared_ptr<Variable> |
|
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 |
|
|
89 | VisualizationZoneWidget* zoneWidget); | |
|
90 | void dropProducts( | |||
|
91 | const QVariantList& productsData, int index, VisualizationZoneWidget* zoneWidget); | |||
86 | }; |
|
92 | }; | |
87 |
|
93 | |||
88 |
VisualizationZoneWidget::VisualizationZoneWidget(const QString |
|
94 | VisualizationZoneWidget::VisualizationZoneWidget(const QString& name, QWidget* parent) | |
89 |
: VisualizationDragWidget{parent} |
|
95 | : VisualizationDragWidget { parent } | |
90 |
|
|
96 | , ui { new Ui::VisualizationZoneWidget } | |
91 |
|
|
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( |
|
104 | ui->dragDropContainer->setMimeType( | |
99 |
|
|
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( |
|
110 | ui->dragDropContainer->setMimeType( | |
105 |
|
|
111 | MIME_TYPE_TIME_RANGE, VisualizationDragDropContainer::DropBehavior::Merged); | |
106 |
ui->dragDropContainer->setMimeType( |
|
112 | ui->dragDropContainer->setMimeType( | |
107 |
|
|
113 | MIME_TYPE_ZONE, VisualizationDragDropContainer::DropBehavior::Forbidden); | |
108 |
ui->dragDropContainer->setMimeType( |
|
114 | ui->dragDropContainer->setMimeType( | |
109 |
|
|
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( |
|
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:: |
|
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 |
|
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 |
|
|
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 |
|
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 |
|
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 |
|
194 | auto graph = qobject_cast<VisualizationGraphWidget*>(layout->itemAt(i)->widget()); | |
186 |
connect(graphWidget, &VisualizationGraphWidget::setrange_sig, graph, |
|
195 | connect(graphWidget, &VisualizationGraphWidget::setrange_sig, graph, | |
187 |
|
|
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 |
|
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 |
|
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 |
|
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 |
|
|
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 |
|
|
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 |
|
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 |
|
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 |
|
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 |
|
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( |
|
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( |
|
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 |
|
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 |
|
|
477 | Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable2>, variable), | |
463 |
|
|
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 |
|
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:: |
|
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( |
|
512 | void VisualizationZoneWidget::dropMimeDataOnGraph( | |
495 | const QMimeData *mimeData) |
|
513 | VisualizationDragWidget* dragWidget, const QMimeData* mimeData) | |
496 | { |
|
514 | { | |
497 |
auto graphWidget = qobject_cast<VisualizationGraphWidget |
|
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:: |
|
528 | Variable2::IDs(mimeData->data(MIME_TYPE_VARIABLE_LIST))); | |
509 |
for (const auto |
|
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 |
|
|
549 | else | |
528 |
|
|
550 | { | |
529 |
|
|
551 | // -> this is pure insanity! this is a workaround to make a bad design work | |
530 |
|
|
552 | QObject::connect(variable.get(), &Variable2::updated, context, | |
531 |
|
|
553 | [graphWidget, context, range, variable]() { | |
532 | { |
|
|||
533 |
|
|
554 | graphWidget->addVariable(variable, range); | |
534 |
|
|
555 | delete context; | |
535 |
|
|
556 | }); | |
536 |
|
|
557 | } | |
537 |
|
||||
538 |
|
|
558 | }, | |
539 |
|
|
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 |
|
|
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 |
|
580 | auto& helper = sqpApp->dragDropGuiController(); | |
559 |
|
581 | |||
560 |
auto graphWidget = qobject_cast<VisualizationGraphWidget |
|
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 |
|
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 |
|
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 |
|
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> |
|
659 | const std::vector<std::shared_ptr<Variable2>>& variables, int index, | |
629 |
VisualizationZoneWidget |
|
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 |
|
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; |
|
25 | std::shared_ptr<Variable2> m_Variable; ///< Variable to find | |
23 |
std::set<IVisualizationWidget |
|
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 |
|
|
17 | explicit GenerateVariableMenuOperationPrivate(QMenu* menu, std::shared_ptr<Variable2> variable, | |
18 |
std::set<IVisualizationWidget |
|
18 | std::set<IVisualizationWidget*> variableContainers) | |
19 |
: m_Variable{variable} |
|
19 | : m_Variable { variable } | |
20 |
|
|
20 | , m_VariableContainers { std::move(variableContainers) } | |
21 |
|
|
21 | , m_PlotMenuBuilder { menu } | |
22 |
|
|
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 |
|
101 | std::set<IVisualizationWidget*> m_VariableContainers; | |
98 |
MenuBuilder m_PlotMenuBuilder; |
|
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 |
|
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 |
|
|
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 |
|
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 |
|
|
151 | [varW = std::weak_ptr<Variable2> { impl->m_Variable }, tabWidget]() { | |
146 |
|
|
152 | if (auto var = varW.lock()) | |
|
153 | { | |||
147 |
|
|
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 |
|
|
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 |
|
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 |
|
|
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 |
|
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 |
|
|
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 |
|
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 |
|
|
211 | [varW = std::weak_ptr<Variable2> { impl->m_Variable }, graphWidget]() { | |
199 |
|
|
212 | if (auto var = varW.lock()) | |
|
213 | { | |||
200 |
|
|
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 |
|
|
220 | [varW = std::weak_ptr<Variable2> { impl->m_Variable }, graphWidget]() { | |
207 |
|
|
221 | if (auto var = varW.lock()) | |
|
222 | { | |||
208 |
|
|
223 | graphWidget->removeVariable(var); | |
209 |
|
|
224 | } | |
210 |
|
|
225 | }); | |
211 | } |
|
226 | } | |
212 |
else |
|
227 | else | |
|
228 | { | |||
213 | qCCritical(LOG_GenerateVariableMenuOperation(), |
|
229 | qCCritical(LOG_GenerateVariableMenuOperation(), | |
214 |
|
|
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 |
|
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 |
|
|
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 |
|
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 <Q |
|
1 | #include <QMainWindow> | |
2 | #include <QObject> |
|
2 | #include <QObject> | |
3 | #include <QString> |
|
|||
4 | #include <QScreen> |
|
3 | #include <QScreen> | |
5 |
#include <Q |
|
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< |
|
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 |
|
50 | explicit A_MultipleSyncGraphs(QObject* parent = Q_NULLPTR) : QObject(parent) {} | |
@@ -56,7 +56,8 private slots: | |||||
56 |
auto var |
|
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 |
|
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 <Q |
|
1 | #include <QMainWindow> | |
2 | #include <QObject> |
|
2 | #include <QObject> | |
3 | #include <QString> |
|
|||
4 | #include <QScreen> |
|
3 | #include <QScreen> | |
5 |
#include <Q |
|
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 < |
|
15 | #include <TestProviders.h> | |
|
16 | #include <Variable/Variable2.h> | |||
|
17 | #include <Visualization/VisualizationGraphWidget.h> | |||
18 |
|
18 | |||
19 |
std::tuple< |
|
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 |
|
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