##// END OF EJS Templates
Merge branch 'feature/GraphFixes' into develop
Alexandre Leroux -
r679:c3be9e8d665b merge
parent child
Show More
@@ -0,0 +1,42
1 #ifndef SCIQLOP_FINDVARIABLEOPERATION_H
2 #define SCIQLOP_FINDVARIABLEOPERATION_H
3
4 #include "Visualization/IVisualizationWidgetVisitor.h"
5
6 #include <Common/spimpl.h>
7
8 #include <set>
9
10 class IVisualizationWidget;
11 class Variable;
12
13 /**
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
16 * operation is the list of widgets that contain the variable.
17 */
18 class FindVariableOperation : public IVisualizationWidgetVisitor {
19 public:
20 /**
21 * Ctor
22 * @param variable the variable to find
23 */
24 explicit FindVariableOperation(std::shared_ptr<Variable> variable);
25
26 void visitEnter(VisualizationWidget *widget) override final;
27 void visitLeave(VisualizationWidget *widget) override final;
28 void visitEnter(VisualizationTabWidget *tabWidget) override final;
29 void visitLeave(VisualizationTabWidget *tabWidget) override final;
30 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
31 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
32 void visit(VisualizationGraphWidget *graphWidget) override final;
33
34 /// @return the widgets that contain the variable
35 std::set<IVisualizationWidget *> result() const noexcept;
36
37 private:
38 class FindVariableOperationPrivate;
39 spimpl::unique_impl_ptr<FindVariableOperationPrivate> impl;
40 };
41
42 #endif // SCIQLOP_FINDVARIABLEOPERATION_H
@@ -0,0 +1,72
1 #include "Visualization/operations/FindVariableOperation.h"
2
3 #include "Visualization/VisualizationGraphWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
5 #include "Visualization/VisualizationWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
7
8 #include <Variable/Variable.h>
9
10 struct FindVariableOperation::FindVariableOperationPrivate {
11 explicit FindVariableOperationPrivate(std::shared_ptr<Variable> variable) : m_Variable{variable}
12 {
13 }
14
15 void visit(IVisualizationWidget *widget)
16 {
17 if (m_Variable && widget && widget->contains(*m_Variable)) {
18 m_Containers.insert(widget);
19 }
20 }
21
22 std::shared_ptr<Variable> m_Variable; ///< Variable to find
23 std::set<IVisualizationWidget *> m_Containers; ///< Containers found for the variable
24 };
25
26 FindVariableOperation::FindVariableOperation(std::shared_ptr<Variable> variable)
27 : impl{spimpl::make_unique_impl<FindVariableOperationPrivate>(variable)}
28 {
29 }
30
31 void FindVariableOperation::visitEnter(VisualizationWidget *widget)
32 {
33 impl->visit(widget);
34 }
35
36 void FindVariableOperation::visitLeave(VisualizationWidget *widget)
37 {
38 // Does nothing
39 Q_UNUSED(widget);
40 }
41
42 void FindVariableOperation::visitEnter(VisualizationTabWidget *tabWidget)
43 {
44 impl->visit(tabWidget);
45 }
46
47 void FindVariableOperation::visitLeave(VisualizationTabWidget *tabWidget)
48 {
49 // Does nothing
50 Q_UNUSED(tabWidget);
51 }
52
53 void FindVariableOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
54 {
55 impl->visit(zoneWidget);
56 }
57
58 void FindVariableOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
59 {
60 // Does nothing
61 Q_UNUSED(zoneWidget);
62 }
63
64 void FindVariableOperation::visit(VisualizationGraphWidget *graphWidget)
65 {
66 impl->visit(graphWidget);
67 }
68
69 std::set<IVisualizationWidget *> FindVariableOperation::result() const noexcept
70 {
71 return impl->m_Containers;
72 }
@@ -1,129 +1,133
1 #ifndef SCIQLOP_VARIABLECONTROLLER_H
1 #ifndef SCIQLOP_VARIABLECONTROLLER_H
2 #define SCIQLOP_VARIABLECONTROLLER_H
2 #define SCIQLOP_VARIABLECONTROLLER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/AcquisitionDataPacket.h>
6 #include <Data/AcquisitionDataPacket.h>
7 #include <Data/SqpRange.h>
7 #include <Data/SqpRange.h>
8
8
9 #include <QLoggingCategory>
9 #include <QLoggingCategory>
10 #include <QObject>
10 #include <QObject>
11 #include <QUuid>
11 #include <QUuid>
12
12
13 #include <Common/spimpl.h>
13 #include <Common/spimpl.h>
14
14
15 class IDataProvider;
15 class IDataProvider;
16 class QItemSelectionModel;
16 class QItemSelectionModel;
17 class TimeController;
17 class TimeController;
18 class Variable;
18 class Variable;
19 class VariableModel;
19 class VariableModel;
20
20
21 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
21 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
22
22
23
23
24 /**
24 /**
25 * Possible types of zoom operation
25 * Possible types of zoom operation
26 */
26 */
27 enum class AcquisitionZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
27 enum class AcquisitionZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
28
28
29
29
30 /**
30 /**
31 * @brief The VariableController class aims to handle the variables in SciQlop.
31 * @brief The VariableController class aims to handle the variables in SciQlop.
32 */
32 */
33 class SCIQLOP_CORE_EXPORT VariableController : public QObject {
33 class SCIQLOP_CORE_EXPORT VariableController : public QObject {
34 Q_OBJECT
34 Q_OBJECT
35 public:
35 public:
36 explicit VariableController(QObject *parent = 0);
36 explicit VariableController(QObject *parent = 0);
37 virtual ~VariableController();
37 virtual ~VariableController();
38
38
39 VariableModel *variableModel() noexcept;
39 VariableModel *variableModel() noexcept;
40 QItemSelectionModel *variableSelectionModel() noexcept;
40 QItemSelectionModel *variableSelectionModel() noexcept;
41
41
42 void setTimeController(TimeController *timeController) noexcept;
42 void setTimeController(TimeController *timeController) noexcept;
43
43
44 /**
44 /**
45 * Clones the variable passed in parameter and adds the duplicate to the controller
45 * Clones the variable passed in parameter and adds the duplicate to the controller
46 * @param variable the variable to duplicate
46 * @param variable the variable to duplicate
47 * @return the duplicate created, nullptr if the variable couldn't be created
47 * @return the duplicate created, nullptr if the variable couldn't be created
48 */
48 */
49 std::shared_ptr<Variable> cloneVariable(std::shared_ptr<Variable> variable) noexcept;
49 std::shared_ptr<Variable> cloneVariable(std::shared_ptr<Variable> variable) noexcept;
50
50
51 /**
51 /**
52 * Deletes from the controller the variable passed in parameter.
52 * Deletes from the controller the variable passed in parameter.
53 *
53 *
54 * Delete a variable includes:
54 * Delete a variable includes:
55 * - the deletion of the various references to the variable in SciQlop
55 * - the deletion of the various references to the variable in SciQlop
56 * - the deletion of the model variable
56 * - the deletion of the model variable
57 * - the deletion of the provider associated with the variable
57 * - the deletion of the provider associated with the variable
58 * - removing the cache associated with the variable
58 * - removing the cache associated with the variable
59 *
59 *
60 * @param variable the variable to delete from the controller.
60 * @param variable the variable to delete from the controller.
61 */
61 */
62 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
62 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
63
63
64 /**
64 /**
65 * Deletes from the controller the variables passed in parameter.
65 * Deletes from the controller the variables passed in parameter.
66 * @param variables the variables to delete from the controller.
66 * @param variables the variables to delete from the controller.
67 * @sa deleteVariable()
67 * @sa deleteVariable()
68 */
68 */
69 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
69 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
70
70
71 /**
71 /**
72 * @brief abort the variable retrieve data progression
72 * @brief abort the variable retrieve data progression
73 */
73 */
74 void abortProgress(std::shared_ptr<Variable> variable);
74 void abortProgress(std::shared_ptr<Variable> variable);
75
75
76 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
76 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
77 signals:
77 signals:
78 /// Signal emitted when a variable is about to be deleted from the controller
78 /// Signal emitted when a variable is about to be deleted from the controller
79 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
79 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
80
80
81 /// Signal emitted when a data acquisition is requested on a range for a variable
81 /// Signal emitted when a data acquisition is requested on a range for a variable
82 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
82 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
83
83
84 /// Signal emitted when a sub range of the cacheRange of the variable can be displayed
84 /// Signal emitted when a sub range of the cacheRange of the variable can be displayed
85 void updateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
85 void updateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
86
86
87 public slots:
87 public slots:
88 /// Request the data loading of the variable whithin range
88 /// Request the data loading of the variable whithin range
89 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
89 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
90 const SqpRange &oldRange, bool synchronise);
90 const SqpRange &oldRange, bool synchronise);
91 /**
91 /**
92 * Creates a new variable and adds it to the model
92 * Creates a new variable and adds it to the model
93 * @param name the name of the new variable
93 * @param name the name of the new variable
94 * @param metadata the metadata of the new variable
94 * @param metadata the metadata of the new variable
95 * @param provider the data provider for the new variable
95 * @param provider the data provider for the new variable
96 * @return the pointer to the new variable or nullptr if the creation failed
96 * @return the pointer to the new variable or nullptr if the creation failed
97 */
97 */
98 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
98 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
99 std::shared_ptr<IDataProvider> provider) noexcept;
99 std::shared_ptr<IDataProvider> provider) noexcept;
100
100
101 /// Update the temporal parameters of every selected variable to dateTime
101 /// Update the temporal parameters of every selected variable to dateTime
102 void onDateTimeOnSelection(const SqpRange &dateTime);
102 void onDateTimeOnSelection(const SqpRange &dateTime);
103
103
104
104
105 void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
105 void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
106 const SqpRange &cacheRangeRequested,
106 const SqpRange &cacheRangeRequested,
107 QVector<AcquisitionDataPacket> dataAcquired);
107 QVector<AcquisitionDataPacket> dataAcquired);
108
108
109 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
109 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
110
110
111 /// Cancel the current request for the variable
111 /// Cancel the current request for the variable
112 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
112 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
113
113
114 /// synchronization group methods
114 // synchronization group methods
115 void onAddSynchronizationGroupId(QUuid synchronizationGroupId);
115 void onAddSynchronizationGroupId(QUuid synchronizationGroupId);
116 void onRemoveSynchronizationGroupId(QUuid synchronizationGroupId);
116 void onRemoveSynchronizationGroupId(QUuid synchronizationGroupId);
117 void onAddSynchronized(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
117 void onAddSynchronized(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
118
118
119 /// Desynchronizes the variable of the group whose identifier is passed in parameter
120 /// @remarks the method does nothing if the variable is not part of the group
121 void desynchronize(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
122
119 void initialize();
123 void initialize();
120 void finalize();
124 void finalize();
121
125
122 private:
126 private:
123 void waitForFinish();
127 void waitForFinish();
124
128
125 class VariableControllerPrivate;
129 class VariableControllerPrivate;
126 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
130 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
127 };
131 };
128
132
129 #endif // SCIQLOP_VARIABLECONTROLLER_H
133 #endif // SCIQLOP_VARIABLECONTROLLER_H
@@ -1,775 +1,805
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 #include <Variable/VariableAcquisitionWorker.h>
3 #include <Variable/VariableCacheStrategy.h>
3 #include <Variable/VariableCacheStrategy.h>
4 #include <Variable/VariableController.h>
4 #include <Variable/VariableController.h>
5 #include <Variable/VariableModel.h>
5 #include <Variable/VariableModel.h>
6 #include <Variable/VariableSynchronizationGroup.h>
6 #include <Variable/VariableSynchronizationGroup.h>
7
7
8 #include <Data/DataProviderParameters.h>
8 #include <Data/DataProviderParameters.h>
9 #include <Data/IDataProvider.h>
9 #include <Data/IDataProvider.h>
10 #include <Data/IDataSeries.h>
10 #include <Data/IDataSeries.h>
11 #include <Data/VariableRequest.h>
11 #include <Data/VariableRequest.h>
12 #include <Time/TimeController.h>
12 #include <Time/TimeController.h>
13
13
14 #include <QMutex>
14 #include <QMutex>
15 #include <QThread>
15 #include <QThread>
16 #include <QUuid>
16 #include <QUuid>
17 #include <QtCore/QItemSelectionModel>
17 #include <QtCore/QItemSelectionModel>
18
18
19 #include <deque>
19 #include <deque>
20 #include <set>
20 #include <set>
21 #include <unordered_map>
21 #include <unordered_map>
22
22
23 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
23 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
24
24
25 namespace {
25 namespace {
26
26
27 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
27 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
28 const SqpRange &oldGraphRange)
28 const SqpRange &oldGraphRange)
29 {
29 {
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
31
31
32 auto varRangeRequested = varRange;
32 auto varRangeRequested = varRange;
33 switch (zoomType) {
33 switch (zoomType) {
34 case AcquisitionZoomType::ZoomIn: {
34 case AcquisitionZoomType::ZoomIn: {
35 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
35 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
36 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
36 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
37 varRangeRequested.m_TStart += deltaLeft;
37 varRangeRequested.m_TStart += deltaLeft;
38 varRangeRequested.m_TEnd -= deltaRight;
38 varRangeRequested.m_TEnd -= deltaRight;
39 break;
39 break;
40 }
40 }
41
41
42 case AcquisitionZoomType::ZoomOut: {
42 case AcquisitionZoomType::ZoomOut: {
43 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
43 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
44 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
44 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
45 varRangeRequested.m_TStart -= deltaLeft;
45 varRangeRequested.m_TStart -= deltaLeft;
46 varRangeRequested.m_TEnd += deltaRight;
46 varRangeRequested.m_TEnd += deltaRight;
47 break;
47 break;
48 }
48 }
49 case AcquisitionZoomType::PanRight: {
49 case AcquisitionZoomType::PanRight: {
50 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
50 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
51 varRangeRequested.m_TStart += deltaRight;
51 varRangeRequested.m_TStart += deltaRight;
52 varRangeRequested.m_TEnd += deltaRight;
52 varRangeRequested.m_TEnd += deltaRight;
53 break;
53 break;
54 }
54 }
55 case AcquisitionZoomType::PanLeft: {
55 case AcquisitionZoomType::PanLeft: {
56 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
56 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
57 varRangeRequested.m_TStart -= deltaLeft;
57 varRangeRequested.m_TStart -= deltaLeft;
58 varRangeRequested.m_TEnd -= deltaLeft;
58 varRangeRequested.m_TEnd -= deltaLeft;
59 break;
59 break;
60 }
60 }
61 case AcquisitionZoomType::Unknown: {
61 case AcquisitionZoomType::Unknown: {
62 qCCritical(LOG_VariableController())
62 qCCritical(LOG_VariableController())
63 << VariableController::tr("Impossible to synchronize: zoom type unknown");
63 << VariableController::tr("Impossible to synchronize: zoom type unknown");
64 break;
64 break;
65 }
65 }
66 default:
66 default:
67 qCCritical(LOG_VariableController()) << VariableController::tr(
67 qCCritical(LOG_VariableController()) << VariableController::tr(
68 "Impossible to synchronize: zoom type not take into account");
68 "Impossible to synchronize: zoom type not take into account");
69 // No action
69 // No action
70 break;
70 break;
71 }
71 }
72
72
73 return varRangeRequested;
73 return varRangeRequested;
74 }
74 }
75 }
75 }
76
76
77 struct VariableController::VariableControllerPrivate {
77 struct VariableController::VariableControllerPrivate {
78 explicit VariableControllerPrivate(VariableController *parent)
78 explicit VariableControllerPrivate(VariableController *parent)
79 : m_WorkingMutex{},
79 : m_WorkingMutex{},
80 m_VariableModel{new VariableModel{parent}},
80 m_VariableModel{new VariableModel{parent}},
81 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
81 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
84 q{parent}
84 q{parent}
85 {
85 {
86
86
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
89 }
89 }
90
90
91
91
92 virtual ~VariableControllerPrivate()
92 virtual ~VariableControllerPrivate()
93 {
93 {
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
95 m_VariableAcquisitionWorkerThread.quit();
95 m_VariableAcquisitionWorkerThread.quit();
96 m_VariableAcquisitionWorkerThread.wait();
96 m_VariableAcquisitionWorkerThread.wait();
97 }
97 }
98
98
99
99
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
101 QUuid varRequestId);
101 QUuid varRequestId);
102
102
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
104 const SqpRange &dateTime);
104 const SqpRange &dateTime);
105
105
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
107 std::shared_ptr<IDataSeries>
107 std::shared_ptr<IDataSeries>
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
109
109
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
111
111
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
114 void updateVariableRequest(QUuid varRequestId);
114 void updateVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
116
116
117 QMutex m_WorkingMutex;
117 QMutex m_WorkingMutex;
118 /// Variable model. The VariableController has the ownership
118 /// Variable model. The VariableController has the ownership
119 VariableModel *m_VariableModel;
119 VariableModel *m_VariableModel;
120 QItemSelectionModel *m_VariableSelectionModel;
120 QItemSelectionModel *m_VariableSelectionModel;
121
121
122
122
123 TimeController *m_TimeController{nullptr};
123 TimeController *m_TimeController{nullptr};
124 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
124 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
125 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
125 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
126 QThread m_VariableAcquisitionWorkerThread;
126 QThread m_VariableAcquisitionWorkerThread;
127
127
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
129 m_VariableToProviderMap;
129 m_VariableToProviderMap;
130 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
130 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
131 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
131 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
132 m_GroupIdToVariableSynchronizationGroupMap;
132 m_GroupIdToVariableSynchronizationGroupMap;
133 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
133 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
135
135
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
137
137
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
139
139
140
140
141 VariableController *q;
141 VariableController *q;
142 };
142 };
143
143
144
144
145 VariableController::VariableController(QObject *parent)
145 VariableController::VariableController(QObject *parent)
146 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
146 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
147 {
147 {
148 qCDebug(LOG_VariableController()) << tr("VariableController construction")
148 qCDebug(LOG_VariableController()) << tr("VariableController construction")
149 << QThread::currentThread();
149 << QThread::currentThread();
150
150
151 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
151 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
152 &VariableController::onAbortProgressRequested);
152 &VariableController::onAbortProgressRequested);
153
153
154 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
154 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
155 &VariableController::onDataProvided);
155 &VariableController::onDataProvided);
156 connect(impl->m_VariableAcquisitionWorker.get(),
156 connect(impl->m_VariableAcquisitionWorker.get(),
157 &VariableAcquisitionWorker::variableRequestInProgress, this,
157 &VariableAcquisitionWorker::variableRequestInProgress, this,
158 &VariableController::onVariableRetrieveDataInProgress);
158 &VariableController::onVariableRetrieveDataInProgress);
159
159
160 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
160 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
161 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
161 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
162 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
162 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
163 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
163 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
164
164
165
165
166 impl->m_VariableAcquisitionWorkerThread.start();
166 impl->m_VariableAcquisitionWorkerThread.start();
167 }
167 }
168
168
169 VariableController::~VariableController()
169 VariableController::~VariableController()
170 {
170 {
171 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
171 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
172 << QThread::currentThread();
172 << QThread::currentThread();
173 this->waitForFinish();
173 this->waitForFinish();
174 }
174 }
175
175
176 VariableModel *VariableController::variableModel() noexcept
176 VariableModel *VariableController::variableModel() noexcept
177 {
177 {
178 return impl->m_VariableModel;
178 return impl->m_VariableModel;
179 }
179 }
180
180
181 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
181 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
182 {
182 {
183 return impl->m_VariableSelectionModel;
183 return impl->m_VariableSelectionModel;
184 }
184 }
185
185
186 void VariableController::setTimeController(TimeController *timeController) noexcept
186 void VariableController::setTimeController(TimeController *timeController) noexcept
187 {
187 {
188 impl->m_TimeController = timeController;
188 impl->m_TimeController = timeController;
189 }
189 }
190
190
191 std::shared_ptr<Variable>
191 std::shared_ptr<Variable>
192 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
192 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
193 {
193 {
194 if (impl->m_VariableModel->containsVariable(variable)) {
194 if (impl->m_VariableModel->containsVariable(variable)) {
195 // Clones variable
195 // Clones variable
196 auto duplicate = variable->clone();
196 auto duplicate = variable->clone();
197
197
198 // Adds clone to model
198 // Adds clone to model
199 impl->m_VariableModel->addVariable(duplicate);
199 impl->m_VariableModel->addVariable(duplicate);
200
200
201 // Generates clone identifier
201 // Generates clone identifier
202 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
202 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
203
203
204 // Registers provider
204 // Registers provider
205 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
205 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
206 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
206 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
207
207
208 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
208 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
209 if (duplicateProvider) {
209 if (duplicateProvider) {
210 impl->registerProvider(duplicateProvider);
210 impl->registerProvider(duplicateProvider);
211 }
211 }
212
212
213 return duplicate;
213 return duplicate;
214 }
214 }
215 else {
215 else {
216 qCCritical(LOG_VariableController())
216 qCCritical(LOG_VariableController())
217 << tr("Can't create duplicate of variable %1: variable not registered in the model")
217 << tr("Can't create duplicate of variable %1: variable not registered in the model")
218 .arg(variable->name());
218 .arg(variable->name());
219 return nullptr;
219 return nullptr;
220 }
220 }
221 }
221 }
222
222
223 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
223 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
224 {
224 {
225 if (!variable) {
225 if (!variable) {
226 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
226 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
227 return;
227 return;
228 }
228 }
229
229
230 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
230 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
231 // make some treatments before the deletion
231 // make some treatments before the deletion
232 emit variableAboutToBeDeleted(variable);
232 emit variableAboutToBeDeleted(variable);
233
233
234 // Deletes identifier
234 // Deletes identifier
235 impl->m_VariableToIdentifierMap.erase(variable);
235 impl->m_VariableToIdentifierMap.erase(variable);
236
236
237 // Deletes provider
237 // Deletes provider
238 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
238 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
239 qCDebug(LOG_VariableController())
239 qCDebug(LOG_VariableController())
240 << tr("Number of providers deleted for variable %1: %2")
240 << tr("Number of providers deleted for variable %1: %2")
241 .arg(variable->name(), QString::number(nbProvidersDeleted));
241 .arg(variable->name(), QString::number(nbProvidersDeleted));
242
242
243
243
244 // Deletes from model
244 // Deletes from model
245 impl->m_VariableModel->deleteVariable(variable);
245 impl->m_VariableModel->deleteVariable(variable);
246 }
246 }
247
247
248 void VariableController::deleteVariables(
248 void VariableController::deleteVariables(
249 const QVector<std::shared_ptr<Variable> > &variables) noexcept
249 const QVector<std::shared_ptr<Variable> > &variables) noexcept
250 {
250 {
251 for (auto variable : qAsConst(variables)) {
251 for (auto variable : qAsConst(variables)) {
252 deleteVariable(variable);
252 deleteVariable(variable);
253 }
253 }
254 }
254 }
255
255
256 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
256 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
257 {
257 {
258 }
258 }
259
259
260 std::shared_ptr<Variable>
260 std::shared_ptr<Variable>
261 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
261 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
262 std::shared_ptr<IDataProvider> provider) noexcept
262 std::shared_ptr<IDataProvider> provider) noexcept
263 {
263 {
264 if (!impl->m_TimeController) {
264 if (!impl->m_TimeController) {
265 qCCritical(LOG_VariableController())
265 qCCritical(LOG_VariableController())
266 << tr("Impossible to create variable: The time controller is null");
266 << tr("Impossible to create variable: The time controller is null");
267 return nullptr;
267 return nullptr;
268 }
268 }
269
269
270 auto range = impl->m_TimeController->dateTime();
270 auto range = impl->m_TimeController->dateTime();
271
271
272 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
272 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
273 auto identifier = QUuid::createUuid();
273 auto identifier = QUuid::createUuid();
274
274
275 // store the provider
275 // store the provider
276 impl->registerProvider(provider);
276 impl->registerProvider(provider);
277
277
278 // Associate the provider
278 // Associate the provider
279 impl->m_VariableToProviderMap[newVariable] = provider;
279 impl->m_VariableToProviderMap[newVariable] = provider;
280 impl->m_VariableToIdentifierMap[newVariable] = identifier;
280 impl->m_VariableToIdentifierMap[newVariable] = identifier;
281
281
282
282
283 auto varRequestId = QUuid::createUuid();
283 auto varRequestId = QUuid::createUuid();
284 qCInfo(LOG_VariableController()) << "processRequest for" << name << varRequestId;
284 qCInfo(LOG_VariableController()) << "processRequest for" << name << varRequestId;
285 impl->processRequest(newVariable, range, varRequestId);
285 impl->processRequest(newVariable, range, varRequestId);
286 impl->updateVariableRequest(varRequestId);
286 impl->updateVariableRequest(varRequestId);
287
287
288 return newVariable;
288 return newVariable;
289 }
289 }
290 }
290 }
291
291
292 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
292 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
293 {
293 {
294 // TODO check synchronisation and Rescale
294 // TODO check synchronisation and Rescale
295 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
295 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
296 << QThread::currentThread()->objectName();
296 << QThread::currentThread()->objectName();
297 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
297 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
298 auto varRequestId = QUuid::createUuid();
298 auto varRequestId = QUuid::createUuid();
299
299
300 for (const auto &selectedRow : qAsConst(selectedRows)) {
300 for (const auto &selectedRow : qAsConst(selectedRows)) {
301 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
301 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
302 selectedVariable->setRange(dateTime);
302 selectedVariable->setRange(dateTime);
303 impl->processRequest(selectedVariable, dateTime, varRequestId);
303 impl->processRequest(selectedVariable, dateTime, varRequestId);
304
304
305 // notify that rescale operation has to be done
305 // notify that rescale operation has to be done
306 emit rangeChanged(selectedVariable, dateTime);
306 emit rangeChanged(selectedVariable, dateTime);
307 }
307 }
308 }
308 }
309 impl->updateVariableRequest(varRequestId);
309 impl->updateVariableRequest(varRequestId);
310 }
310 }
311
311
312 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
312 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
313 const SqpRange &cacheRangeRequested,
313 const SqpRange &cacheRangeRequested,
314 QVector<AcquisitionDataPacket> dataAcquired)
314 QVector<AcquisitionDataPacket> dataAcquired)
315 {
315 {
316 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
316 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
317 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
317 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
318 if (!varRequestId.isNull()) {
318 if (!varRequestId.isNull()) {
319 impl->updateVariableRequest(varRequestId);
319 impl->updateVariableRequest(varRequestId);
320 }
320 }
321 }
321 }
322
322
323 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
323 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
324 {
324 {
325 if (auto var = impl->findVariable(identifier)) {
325 if (auto var = impl->findVariable(identifier)) {
326 impl->m_VariableModel->setDataProgress(var, progress);
326 impl->m_VariableModel->setDataProgress(var, progress);
327 }
327 }
328 else {
328 else {
329 qCCritical(LOG_VariableController())
329 qCCritical(LOG_VariableController())
330 << tr("Impossible to notify progression of a null variable");
330 << tr("Impossible to notify progression of a null variable");
331 }
331 }
332 }
332 }
333
333
334 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
334 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
335 {
335 {
336 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
336 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
337 << QThread::currentThread()->objectName();
337 << QThread::currentThread()->objectName();
338
338
339 auto it = impl->m_VariableToIdentifierMap.find(variable);
339 auto it = impl->m_VariableToIdentifierMap.find(variable);
340 if (it != impl->m_VariableToIdentifierMap.cend()) {
340 if (it != impl->m_VariableToIdentifierMap.cend()) {
341 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
341 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
342 }
342 }
343 else {
343 else {
344 qCWarning(LOG_VariableController())
344 qCWarning(LOG_VariableController())
345 << tr("Aborting progression of inexistant variable detected !!!")
345 << tr("Aborting progression of inexistant variable detected !!!")
346 << QThread::currentThread()->objectName();
346 << QThread::currentThread()->objectName();
347 }
347 }
348 }
348 }
349
349
350 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
350 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
351 {
351 {
352 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
352 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
353 << QThread::currentThread()->objectName()
353 << QThread::currentThread()->objectName()
354 << synchronizationGroupId;
354 << synchronizationGroupId;
355 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
355 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
356 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
356 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
357 std::make_pair(synchronizationGroupId, vSynchroGroup));
357 std::make_pair(synchronizationGroupId, vSynchroGroup));
358 }
358 }
359
359
360 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
360 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
361 {
361 {
362 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
362 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
363 }
363 }
364
364
365 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
365 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
366 QUuid synchronizationGroupId)
366 QUuid synchronizationGroupId)
367
367
368 {
368 {
369 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
369 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
370 << synchronizationGroupId;
370 << synchronizationGroupId;
371 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
371 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
372 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
372 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
373 auto groupIdToVSGIt
373 auto groupIdToVSGIt
374 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
374 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
375 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
375 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
376 impl->m_VariableIdGroupIdMap.insert(
376 impl->m_VariableIdGroupIdMap.insert(
377 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
377 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
378 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
378 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
379 }
379 }
380 else {
380 else {
381 qCCritical(LOG_VariableController())
381 qCCritical(LOG_VariableController())
382 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
382 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
383 << variable->name();
383 << variable->name();
384 }
384 }
385 }
385 }
386 else {
386 else {
387 qCCritical(LOG_VariableController())
387 qCCritical(LOG_VariableController())
388 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
388 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
389 }
389 }
390 }
390 }
391
391
392 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
393 QUuid synchronizationGroupId)
394 {
395 // Gets variable id
396 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
397 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
398 qCCritical(LOG_VariableController())
399 << tr("Can't desynchronize variable %1: variable identifier not found")
400 .arg(variable->name());
401 return;
402 }
403
404 // Gets synchronization group
405 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
406 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
407 qCCritical(LOG_VariableController())
408 << tr("Can't desynchronize variable %1: unknown synchronization group")
409 .arg(variable->name());
410 return;
411 }
412
413 auto variableId = variableIt->second;
414
415 // Removes variable from synchronization group
416 auto synchronizationGroup = groupIt->second;
417 synchronizationGroup->removeVariableId(variableId);
418
419 // Removes link between variable and synchronization group
420 impl->m_VariableIdGroupIdMap.erase(variableId);
421 }
392
422
393 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
423 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
394 const SqpRange &range, const SqpRange &oldRange,
424 const SqpRange &range, const SqpRange &oldRange,
395 bool synchronise)
425 bool synchronise)
396 {
426 {
397 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
427 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
398
428
399 // we want to load data of the variable for the dateTime.
429 // we want to load data of the variable for the dateTime.
400 // First we check if the cache contains some of them.
430 // First we check if the cache contains some of them.
401 // For the other, we ask the provider to give them.
431 // For the other, we ask the provider to give them.
402
432
403 auto varRequestId = QUuid::createUuid();
433 auto varRequestId = QUuid::createUuid();
404 qCInfo(LOG_VariableController()) << "VariableController::onRequestDataLoading"
434 qCInfo(LOG_VariableController()) << "VariableController::onRequestDataLoading"
405 << QThread::currentThread()->objectName() << varRequestId;
435 << QThread::currentThread()->objectName() << varRequestId;
406
436
407 for (const auto &var : variables) {
437 for (const auto &var : variables) {
408 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
438 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
409 impl->processRequest(var, range, varRequestId);
439 impl->processRequest(var, range, varRequestId);
410 }
440 }
411
441
412 if (synchronise) {
442 if (synchronise) {
413 // Get the group ids
443 // Get the group ids
414 qCDebug(LOG_VariableController())
444 qCDebug(LOG_VariableController())
415 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
445 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
416 auto groupIds = std::set<QUuid>{};
446 auto groupIds = std::set<QUuid>{};
417 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
447 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
418 for (const auto &var : variables) {
448 for (const auto &var : variables) {
419 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
449 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
420 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
450 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
421 auto vId = varToVarIdIt->second;
451 auto vId = varToVarIdIt->second;
422 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
452 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
423 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
453 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
424 auto gId = varIdToGroupIdIt->second;
454 auto gId = varIdToGroupIdIt->second;
425 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
455 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
426 if (groupIds.find(gId) == groupIds.cend()) {
456 if (groupIds.find(gId) == groupIds.cend()) {
427 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
457 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
428 groupIds.insert(gId);
458 groupIds.insert(gId);
429 }
459 }
430 }
460 }
431 }
461 }
432 }
462 }
433
463
434 // We assume here all group ids exist
464 // We assume here all group ids exist
435 for (const auto &gId : groupIds) {
465 for (const auto &gId : groupIds) {
436 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
466 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
437 auto vSyncIds = vSynchronizationGroup->getIds();
467 auto vSyncIds = vSynchronizationGroup->getIds();
438 qCDebug(LOG_VariableController()) << "Var in synchro group ";
468 qCDebug(LOG_VariableController()) << "Var in synchro group ";
439 for (auto vId : vSyncIds) {
469 for (auto vId : vSyncIds) {
440 auto var = impl->findVariable(vId);
470 auto var = impl->findVariable(vId);
441
471
442 // Don't process already processed var
472 // Don't process already processed var
443 if (!variables.contains(var)) {
473 if (!variables.contains(var)) {
444 if (var != nullptr) {
474 if (var != nullptr) {
445 qCDebug(LOG_VariableController()) << "processRequest synchro for"
475 qCDebug(LOG_VariableController()) << "processRequest synchro for"
446 << var->name();
476 << var->name();
447 auto vSyncRangeRequested = computeSynchroRangeRequested(
477 auto vSyncRangeRequested = computeSynchroRangeRequested(
448 var->range(), range, groupIdToOldRangeMap.at(gId));
478 var->range(), range, groupIdToOldRangeMap.at(gId));
449 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
479 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
450 impl->processRequest(var, vSyncRangeRequested, varRequestId);
480 impl->processRequest(var, vSyncRangeRequested, varRequestId);
451 }
481 }
452 else {
482 else {
453 qCCritical(LOG_VariableController())
483 qCCritical(LOG_VariableController())
454
484
455 << tr("Impossible to synchronize a null variable");
485 << tr("Impossible to synchronize a null variable");
456 }
486 }
457 }
487 }
458 }
488 }
459 }
489 }
460 }
490 }
461
491
462 impl->updateVariableRequest(varRequestId);
492 impl->updateVariableRequest(varRequestId);
463 }
493 }
464
494
465
495
466 void VariableController::initialize()
496 void VariableController::initialize()
467 {
497 {
468 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
498 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
469 impl->m_WorkingMutex.lock();
499 impl->m_WorkingMutex.lock();
470 qCDebug(LOG_VariableController()) << tr("VariableController init END");
500 qCDebug(LOG_VariableController()) << tr("VariableController init END");
471 }
501 }
472
502
473 void VariableController::finalize()
503 void VariableController::finalize()
474 {
504 {
475 impl->m_WorkingMutex.unlock();
505 impl->m_WorkingMutex.unlock();
476 }
506 }
477
507
478 void VariableController::waitForFinish()
508 void VariableController::waitForFinish()
479 {
509 {
480 QMutexLocker locker{&impl->m_WorkingMutex};
510 QMutexLocker locker{&impl->m_WorkingMutex};
481 }
511 }
482
512
483 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
513 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
484 {
514 {
485 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
515 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
486 auto zoomType = AcquisitionZoomType::Unknown;
516 auto zoomType = AcquisitionZoomType::Unknown;
487 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
517 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
488 zoomType = AcquisitionZoomType::ZoomOut;
518 zoomType = AcquisitionZoomType::ZoomOut;
489 }
519 }
490 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
520 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
491 zoomType = AcquisitionZoomType::PanRight;
521 zoomType = AcquisitionZoomType::PanRight;
492 }
522 }
493 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
523 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
494 zoomType = AcquisitionZoomType::PanLeft;
524 zoomType = AcquisitionZoomType::PanLeft;
495 }
525 }
496 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
526 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
497 zoomType = AcquisitionZoomType::ZoomIn;
527 zoomType = AcquisitionZoomType::ZoomIn;
498 }
528 }
499 else {
529 else {
500 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
530 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
501 }
531 }
502 return zoomType;
532 return zoomType;
503 }
533 }
504
534
505 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
535 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
506 const SqpRange &rangeRequested,
536 const SqpRange &rangeRequested,
507 QUuid varRequestId)
537 QUuid varRequestId)
508 {
538 {
509
539
510 // TODO: protect at
540 // TODO: protect at
511 auto varRequest = VariableRequest{};
541 auto varRequest = VariableRequest{};
512 auto varId = m_VariableToIdentifierMap.at(var);
542 auto varId = m_VariableToIdentifierMap.at(var);
513
543
514 auto varStrategyRangesRequested
544 auto varStrategyRangesRequested
515 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
545 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
516 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
546 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
517 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
547 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
518
548
519 if (!notInCacheRangeList.empty()) {
549 if (!notInCacheRangeList.empty()) {
520 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
550 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
521 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
551 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
522 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest RR ") << rangeRequested;
552 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest RR ") << rangeRequested;
523 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest R ")
553 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest R ")
524 << varStrategyRangesRequested.first;
554 << varStrategyRangesRequested.first;
525 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest CR ")
555 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest CR ")
526 << varStrategyRangesRequested.second;
556 << varStrategyRangesRequested.second;
527 // store VarRequest
557 // store VarRequest
528 storeVariableRequest(varId, varRequestId, varRequest);
558 storeVariableRequest(varId, varRequestId, varRequest);
529
559
530 auto varProvider = m_VariableToProviderMap.at(var);
560 auto varProvider = m_VariableToProviderMap.at(var);
531 if (varProvider != nullptr) {
561 if (varProvider != nullptr) {
532 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
562 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
533 varRequestId, varId, varStrategyRangesRequested.first,
563 varRequestId, varId, varStrategyRangesRequested.first,
534 varStrategyRangesRequested.second,
564 varStrategyRangesRequested.second,
535 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
565 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
536 varProvider);
566 varProvider);
537
567
538 if (!varRequestIdCanceled.isNull()) {
568 if (!varRequestIdCanceled.isNull()) {
539 qCInfo(LOG_VariableAcquisitionWorker()) << tr("varRequestIdCanceled: ")
569 qCInfo(LOG_VariableAcquisitionWorker()) << tr("varRequestIdCanceled: ")
540 << varRequestIdCanceled;
570 << varRequestIdCanceled;
541 cancelVariableRequest(varRequestIdCanceled);
571 cancelVariableRequest(varRequestIdCanceled);
542 }
572 }
543 }
573 }
544 else {
574 else {
545 qCCritical(LOG_VariableController())
575 qCCritical(LOG_VariableController())
546 << "Impossible to provide data with a null provider";
576 << "Impossible to provide data with a null provider";
547 }
577 }
548
578
549 if (!inCacheRangeList.empty()) {
579 if (!inCacheRangeList.empty()) {
550 emit q->updateVarDisplaying(var, inCacheRangeList.first());
580 emit q->updateVarDisplaying(var, inCacheRangeList.first());
551 }
581 }
552 }
582 }
553 else {
583 else {
554
584
555 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
585 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
556 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
586 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
557 // store VarRequest
587 // store VarRequest
558 storeVariableRequest(varId, varRequestId, varRequest);
588 storeVariableRequest(varId, varRequestId, varRequest);
559 acceptVariableRequest(varId,
589 acceptVariableRequest(varId,
560 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
590 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
561 }
591 }
562 }
592 }
563
593
564 std::shared_ptr<Variable>
594 std::shared_ptr<Variable>
565 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
595 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
566 {
596 {
567 std::shared_ptr<Variable> var;
597 std::shared_ptr<Variable> var;
568 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
598 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
569
599
570 auto end = m_VariableToIdentifierMap.cend();
600 auto end = m_VariableToIdentifierMap.cend();
571 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
601 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
572 if (it != end) {
602 if (it != end) {
573 var = it->first;
603 var = it->first;
574 }
604 }
575 else {
605 else {
576 qCCritical(LOG_VariableController())
606 qCCritical(LOG_VariableController())
577 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
607 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
578 }
608 }
579
609
580 return var;
610 return var;
581 }
611 }
582
612
583 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
613 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
584 const QVector<AcquisitionDataPacket> acqDataPacketVector)
614 const QVector<AcquisitionDataPacket> acqDataPacketVector)
585 {
615 {
586 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
616 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
587 << acqDataPacketVector.size();
617 << acqDataPacketVector.size();
588 std::shared_ptr<IDataSeries> dataSeries;
618 std::shared_ptr<IDataSeries> dataSeries;
589 if (!acqDataPacketVector.isEmpty()) {
619 if (!acqDataPacketVector.isEmpty()) {
590 dataSeries = acqDataPacketVector[0].m_DateSeries;
620 dataSeries = acqDataPacketVector[0].m_DateSeries;
591 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
621 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
592 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
622 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
593 }
623 }
594 }
624 }
595 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
625 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
596 << acqDataPacketVector.size();
626 << acqDataPacketVector.size();
597 return dataSeries;
627 return dataSeries;
598 }
628 }
599
629
600 void VariableController::VariableControllerPrivate::registerProvider(
630 void VariableController::VariableControllerPrivate::registerProvider(
601 std::shared_ptr<IDataProvider> provider)
631 std::shared_ptr<IDataProvider> provider)
602 {
632 {
603 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
633 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
604 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
634 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
605 << provider->objectName();
635 << provider->objectName();
606 m_ProviderSet.insert(provider);
636 m_ProviderSet.insert(provider);
607 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
637 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
608 &VariableAcquisitionWorker::onVariableDataAcquired);
638 &VariableAcquisitionWorker::onVariableDataAcquired);
609 connect(provider.get(), &IDataProvider::dataProvidedProgress,
639 connect(provider.get(), &IDataProvider::dataProvidedProgress,
610 m_VariableAcquisitionWorker.get(),
640 m_VariableAcquisitionWorker.get(),
611 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
641 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
612 }
642 }
613 else {
643 else {
614 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
644 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
615 }
645 }
616 }
646 }
617
647
618 void VariableController::VariableControllerPrivate::storeVariableRequest(
648 void VariableController::VariableControllerPrivate::storeVariableRequest(
619 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
649 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
620 {
650 {
621 // First request for the variable. we can create an entry for it
651 // First request for the variable. we can create an entry for it
622 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
652 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
623 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
653 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
624 auto varRequestIdQueue = std::deque<QUuid>{};
654 auto varRequestIdQueue = std::deque<QUuid>{};
625 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
655 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
626 varRequestIdQueue.push_back(varRequestId);
656 varRequestIdQueue.push_back(varRequestId);
627 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
657 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
628 }
658 }
629 else {
659 else {
630 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
660 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
631 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
661 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
632 varRequestIdQueue.push_back(varRequestId);
662 varRequestIdQueue.push_back(varRequestId);
633 }
663 }
634
664
635 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
665 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
636 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
666 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
637 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
667 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
638 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
668 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
639 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
669 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
640 m_VarRequestIdToVarIdVarRequestMap.insert(
670 m_VarRequestIdToVarIdVarRequestMap.insert(
641 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
671 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
642 }
672 }
643 else {
673 else {
644 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
674 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
645 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
675 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
646 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
676 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
647 }
677 }
648 }
678 }
649
679
650 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
680 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
651 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
681 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
652 {
682 {
653 QUuid varRequestId;
683 QUuid varRequestId;
654 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
684 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
655 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
685 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
656 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
686 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
657 varRequestId = varRequestIdQueue.front();
687 varRequestId = varRequestIdQueue.front();
658 auto varRequestIdToVarIdVarRequestMapIt
688 auto varRequestIdToVarIdVarRequestMapIt
659 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
689 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
660 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
690 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
661 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
691 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
662 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
692 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
663 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
693 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
664 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
694 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
665 auto &varRequest = varIdToVarRequestMapIt->second;
695 auto &varRequest = varIdToVarRequestMapIt->second;
666 varRequest.m_DataSeries = dataSeries;
696 varRequest.m_DataSeries = dataSeries;
667 varRequest.m_CanUpdate = true;
697 varRequest.m_CanUpdate = true;
668 }
698 }
669 else {
699 else {
670 qCDebug(LOG_VariableController())
700 qCDebug(LOG_VariableController())
671 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
701 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
672 "to a variableRequestId")
702 "to a variableRequestId")
673 << varRequestId << varId;
703 << varRequestId << varId;
674 }
704 }
675 }
705 }
676 else {
706 else {
677 qCCritical(LOG_VariableController())
707 qCCritical(LOG_VariableController())
678 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
708 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
679 << varRequestId;
709 << varRequestId;
680 }
710 }
681
711
682 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in QUEUE ?")
712 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in QUEUE ?")
683 << varRequestIdQueue.size();
713 << varRequestIdQueue.size();
684 varRequestIdQueue.pop_front();
714 varRequestIdQueue.pop_front();
685 qCDebug(LOG_VariableController()) << tr("2: erase REQUEST in QUEUE ?")
715 qCDebug(LOG_VariableController()) << tr("2: erase REQUEST in QUEUE ?")
686 << varRequestIdQueue.size();
716 << varRequestIdQueue.size();
687 if (varRequestIdQueue.empty()) {
717 if (varRequestIdQueue.empty()) {
688 m_VarIdToVarRequestIdQueueMap.erase(varId);
718 m_VarIdToVarRequestIdQueueMap.erase(varId);
689 }
719 }
690 }
720 }
691 else {
721 else {
692 qCCritical(LOG_VariableController())
722 qCCritical(LOG_VariableController())
693 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
723 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
694 }
724 }
695
725
696 return varRequestId;
726 return varRequestId;
697 }
727 }
698
728
699 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
729 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
700 {
730 {
701
731
702 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
732 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
703 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
733 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
704 bool processVariableUpdate = true;
734 bool processVariableUpdate = true;
705 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
735 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
706 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
736 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
707 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
737 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
708 ++varIdToVarRequestMapIt) {
738 ++varIdToVarRequestMapIt) {
709 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
739 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
710 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
740 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
711 << processVariableUpdate;
741 << processVariableUpdate;
712 }
742 }
713
743
714 if (processVariableUpdate) {
744 if (processVariableUpdate) {
715 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
745 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
716 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
746 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
717 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
747 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
718 auto &varRequest = varIdToVarRequestMapIt->second;
748 auto &varRequest = varIdToVarRequestMapIt->second;
719 var->setRange(varRequest.m_RangeRequested);
749 var->setRange(varRequest.m_RangeRequested);
720 var->setCacheRange(varRequest.m_CacheRangeRequested);
750 var->setCacheRange(varRequest.m_CacheRangeRequested);
721 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
751 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
722 << varRequest.m_RangeRequested;
752 << varRequest.m_RangeRequested;
723 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
753 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
724 << varRequest.m_CacheRangeRequested;
754 << varRequest.m_CacheRangeRequested;
725 var->mergeDataSeries(varRequest.m_DataSeries);
755 var->mergeDataSeries(varRequest.m_DataSeries);
726 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
756 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
727 << varRequest.m_DataSeries->range();
757 << varRequest.m_DataSeries->range();
728 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
758 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
729
759
730 /// @todo MPL: confirm
760 /// @todo MPL: confirm
731 // Variable update is notified only if there is no pending request for it
761 // Variable update is notified only if there is no pending request for it
732 if (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) == 0) {
762 if (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) == 0) {
733 emit var->updated();
763 emit var->updated();
734 }
764 }
735 }
765 }
736 else {
766 else {
737 qCCritical(LOG_VariableController())
767 qCCritical(LOG_VariableController())
738 << tr("Impossible to update data to a null variable");
768 << tr("Impossible to update data to a null variable");
739 }
769 }
740 }
770 }
741
771
742 // cleaning varRequestId
772 // cleaning varRequestId
743 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
773 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
744 << m_VarRequestIdToVarIdVarRequestMap.size();
774 << m_VarRequestIdToVarIdVarRequestMap.size();
745 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
775 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
746 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
776 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
747 << m_VarRequestIdToVarIdVarRequestMap.size();
777 << m_VarRequestIdToVarIdVarRequestMap.size();
748 }
778 }
749 }
779 }
750 else {
780 else {
751 qCCritical(LOG_VariableController())
781 qCCritical(LOG_VariableController())
752 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
782 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
753 }
783 }
754 }
784 }
755
785
756 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
786 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
757 {
787 {
758 // cleaning varRequestId
788 // cleaning varRequestId
759 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
789 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
760
790
761 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
791 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
762 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
792 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
763 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
793 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
764 varRequestIdQueue.erase(
794 varRequestIdQueue.erase(
765 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
795 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
766 varRequestIdQueue.end());
796 varRequestIdQueue.end());
767 if (varRequestIdQueue.empty()) {
797 if (varRequestIdQueue.empty()) {
768 varIdToVarRequestIdQueueMapIt
798 varIdToVarRequestIdQueueMapIt
769 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
799 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
770 }
800 }
771 else {
801 else {
772 ++varIdToVarRequestIdQueueMapIt;
802 ++varIdToVarRequestIdQueueMapIt;
773 }
803 }
774 }
804 }
775 }
805 }
@@ -1,94 +1,98
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QWidget>
7 #include <QWidget>
8
8
9 #include <memory>
9 #include <memory>
10
10
11 #include <Common/spimpl.h>
11 #include <Common/spimpl.h>
12
12
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
14
14
15 class QCPRange;
15 class QCPRange;
16 class QCustomPlot;
16 class QCustomPlot;
17 class SqpRange;
17 class SqpRange;
18 class Variable;
18 class Variable;
19
19
20 namespace Ui {
20 namespace Ui {
21 class VisualizationGraphWidget;
21 class VisualizationGraphWidget;
22 } // namespace Ui
22 } // namespace Ui
23
23
24 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
24 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
25 Q_OBJECT
25 Q_OBJECT
26
26
27 friend class QCustomPlotSynchronizer;
27 friend class QCustomPlotSynchronizer;
28 friend class VisualizationGraphRenderingDelegate;
28 friend class VisualizationGraphRenderingDelegate;
29
29
30 public:
30 public:
31 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
31 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
32 virtual ~VisualizationGraphWidget();
32 virtual ~VisualizationGraphWidget();
33
33
34 /// If acquisition isn't enable, requestDataLoading signal cannot be emit
34 /// If acquisition isn't enable, requestDataLoading signal cannot be emit
35 void enableAcquisition(bool enable);
35 void enableAcquisition(bool enable);
36
36
37 void addVariable(std::shared_ptr<Variable> variable, SqpRange range);
37 void addVariable(std::shared_ptr<Variable> variable, SqpRange range);
38
38
39 /// Removes a variable from the graph
39 /// Removes a variable from the graph
40 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
40 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
41
41
42 void setRange(std::shared_ptr<Variable> variable, const SqpRange &range);
42 void setRange(std::shared_ptr<Variable> variable, const SqpRange &range);
43 void setYRange(const SqpRange &range);
43 void setYRange(const SqpRange &range);
44 SqpRange graphRange() const noexcept;
44 SqpRange graphRange() const noexcept;
45 void setGraphRange(const SqpRange &range);
45 void setGraphRange(const SqpRange &range);
46
46
47 // IVisualizationWidget interface
47 // IVisualizationWidget interface
48 void accept(IVisualizationWidgetVisitor *visitor) override;
48 void accept(IVisualizationWidgetVisitor *visitor) override;
49 bool canDrop(const Variable &variable) const override;
49 bool canDrop(const Variable &variable) const override;
50 bool contains(const Variable &variable) const override;
50 bool contains(const Variable &variable) const override;
51 QString name() const override;
51 QString name() const override;
52
52
53
53
54 signals:
54 signals:
55 void synchronize(const SqpRange &range, const SqpRange &oldRange);
55 void synchronize(const SqpRange &range, const SqpRange &oldRange);
56 void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range,
56 void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range,
57 const SqpRange &oldRange, bool synchronise);
57 const SqpRange &oldRange, bool synchronise);
58
58
59 /// Signal emitted when the variable is about to be removed from the graph
60 void variableAboutToBeRemoved(std::shared_ptr<Variable> var);
61 /// Signal emitted when the variable has been added to the graph
59 void variableAdded(std::shared_ptr<Variable> var);
62 void variableAdded(std::shared_ptr<Variable> var);
60
63
61 protected:
64 protected:
65 void closeEvent(QCloseEvent *event) override;
62 void enterEvent(QEvent *event) override;
66 void enterEvent(QEvent *event) override;
63 void leaveEvent(QEvent *event) override;
67 void leaveEvent(QEvent *event) override;
64
68
65 QCustomPlot &plot() noexcept;
69 QCustomPlot &plot() noexcept;
66
70
67 private:
71 private:
68 Ui::VisualizationGraphWidget *ui;
72 Ui::VisualizationGraphWidget *ui;
69
73
70 class VisualizationGraphWidgetPrivate;
74 class VisualizationGraphWidgetPrivate;
71 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
75 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
72
76
73 private slots:
77 private slots:
74 /// Slot called when right clicking on the graph (displays a menu)
78 /// Slot called when right clicking on the graph (displays a menu)
75 void onGraphMenuRequested(const QPoint &pos) noexcept;
79 void onGraphMenuRequested(const QPoint &pos) noexcept;
76
80
77 /// Rescale the X axe to range parameter
81 /// Rescale the X axe to range parameter
78 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
82 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
79
83
80 /// Slot called when a mouse move was made
84 /// Slot called when a mouse move was made
81 void onMouseMove(QMouseEvent *event) noexcept;
85 void onMouseMove(QMouseEvent *event) noexcept;
82 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
86 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
83 void onMouseWheel(QWheelEvent *event) noexcept;
87 void onMouseWheel(QWheelEvent *event) noexcept;
84 /// Slot called when a mouse press was made, to activate the calibration of a graph
88 /// Slot called when a mouse press was made, to activate the calibration of a graph
85 void onMousePress(QMouseEvent *event) noexcept;
89 void onMousePress(QMouseEvent *event) noexcept;
86 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
90 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
87 void onMouseRelease(QMouseEvent *event) noexcept;
91 void onMouseRelease(QMouseEvent *event) noexcept;
88
92
89 void onDataCacheVariableUpdated();
93 void onDataCacheVariableUpdated();
90
94
91 void onUpdateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
95 void onUpdateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
92 };
96 };
93
97
94 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
98 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,54 +1,57
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <Common/spimpl.h>
6 #include <Common/spimpl.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QWidget>
9 #include <QWidget>
10
10
11 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
11 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
12
12
13 class Variable;
13 class Variable;
14 class VisualizationZoneWidget;
14 class VisualizationZoneWidget;
15
15
16 namespace Ui {
16 namespace Ui {
17 class VisualizationTabWidget;
17 class VisualizationTabWidget;
18 } // namespace Ui
18 } // namespace Ui
19
19
20 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
20 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
21 Q_OBJECT
21 Q_OBJECT
22
22
23 public:
23 public:
24 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
24 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
25 virtual ~VisualizationTabWidget();
25 virtual ~VisualizationTabWidget();
26
26
27 /// Add a zone widget
27 /// Add a zone widget
28 void addZone(VisualizationZoneWidget *zoneWidget);
28 void addZone(VisualizationZoneWidget *zoneWidget);
29
29
30 /**
30 /**
31 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
31 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
32 * zone.
32 * zone.
33 * @param variable the variable for which to create the zone
33 * @param variable the variable for which to create the zone
34 * @return the pointer to the created zone
34 * @return the pointer to the created zone
35 */
35 */
36 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
36 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
37
37
38 // IVisualizationWidget interface
38 // IVisualizationWidget interface
39 void accept(IVisualizationWidgetVisitor *visitor) override;
39 void accept(IVisualizationWidgetVisitor *visitor) override;
40 bool canDrop(const Variable &variable) const override;
40 bool canDrop(const Variable &variable) const override;
41 bool contains(const Variable &variable) const override;
41 bool contains(const Variable &variable) const override;
42 QString name() const override;
42 QString name() const override;
43
43
44 protected:
45 void closeEvent(QCloseEvent *event) override;
46
44 private:
47 private:
45 /// @return the layout of tab in which zones are added
48 /// @return the layout of tab in which zones are added
46 QLayout &tabLayout() const noexcept;
49 QLayout &tabLayout() const noexcept;
47
50
48 Ui::VisualizationTabWidget *ui;
51 Ui::VisualizationTabWidget *ui;
49
52
50 class VisualizationTabWidgetPrivate;
53 class VisualizationTabWidgetPrivate;
51 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
54 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
52 };
55 };
53
56
54 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
57 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
@@ -1,51 +1,54
1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
2 #define SCIQLOP_VISUALIZATIONWIDGET_H
2 #define SCIQLOP_VISUALIZATIONWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5 #include <Data/SqpRange.h>
5 #include <Data/SqpRange.h>
6
6
7 #include <QLoggingCategory>
7 #include <QLoggingCategory>
8 #include <QWidget>
8 #include <QWidget>
9
9
10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
11
11
12 class QMenu;
12 class QMenu;
13 class Variable;
13 class Variable;
14 class VisualizationTabWidget;
14 class VisualizationTabWidget;
15
15
16 namespace Ui {
16 namespace Ui {
17 class VisualizationWidget;
17 class VisualizationWidget;
18 } // namespace Ui
18 } // namespace Ui
19
19
20 class VisualizationWidget : public QWidget, public IVisualizationWidget {
20 class VisualizationWidget : public QWidget, public IVisualizationWidget {
21 Q_OBJECT
21 Q_OBJECT
22
22
23 public:
23 public:
24 explicit VisualizationWidget(QWidget *parent = 0);
24 explicit VisualizationWidget(QWidget *parent = 0);
25 virtual ~VisualizationWidget();
25 virtual ~VisualizationWidget();
26
26
27 // IVisualizationWidget interface
27 // IVisualizationWidget interface
28 void accept(IVisualizationWidgetVisitor *visitor) override;
28 void accept(IVisualizationWidgetVisitor *visitor) override;
29 bool canDrop(const Variable &variable) const override;
29 bool canDrop(const Variable &variable) const override;
30 bool contains(const Variable &variable) const override;
30 bool contains(const Variable &variable) const override;
31 QString name() const override;
31 QString name() const override;
32
32
33 public slots:
33 public slots:
34 /**
34 /**
35 * Attaches to a menu the menu relative to the visualization of variables
35 * Attaches to a menu the menu relative to the visualization of variables
36 * @param menu the parent menu of the generated menu
36 * @param menu the parent menu of the generated menu
37 * @param variables the variables for which to generate the menu
37 * @param variables the variables for which to generate the menu
38 */
38 */
39 void attachVariableMenu(QMenu *menu,
39 void attachVariableMenu(QMenu *menu,
40 const QVector<std::shared_ptr<Variable> > &variables) noexcept;
40 const QVector<std::shared_ptr<Variable> > &variables) noexcept;
41
41
42 /// Slot called when a variable is about to be deleted from SciQlop
42 /// Slot called when a variable is about to be deleted from SciQlop
43 void onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept;
43 void onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept;
44
44
45 void onRangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range) noexcept;
45 void onRangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range) noexcept;
46
46
47 protected:
48 void closeEvent(QCloseEvent *event) override;
49
47 private:
50 private:
48 Ui::VisualizationWidget *ui;
51 Ui::VisualizationWidget *ui;
49 };
52 };
50
53
51 #endif // VISUALIZATIONWIDGET_H
54 #endif // VISUALIZATIONWIDGET_H
@@ -1,55 +1,60
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QWidget>
7 #include <QWidget>
8
8
9 #include <memory>
9 #include <memory>
10
10
11 #include <Common/spimpl.h>
11 #include <Common/spimpl.h>
12
12
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
14
14
15 namespace Ui {
15 namespace Ui {
16 class VisualizationZoneWidget;
16 class VisualizationZoneWidget;
17 } // Ui
17 } // Ui
18
18
19 class Variable;
19 class Variable;
20 class VisualizationGraphWidget;
20 class VisualizationGraphWidget;
21
21
22 class VisualizationZoneWidget : public QWidget, public IVisualizationWidget {
22 class VisualizationZoneWidget : public QWidget, public IVisualizationWidget {
23 Q_OBJECT
23 Q_OBJECT
24
24
25 public:
25 public:
26 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
26 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
27 virtual ~VisualizationZoneWidget();
27 virtual ~VisualizationZoneWidget();
28
28
29 /// Add a graph widget
29 /// Add a graph widget
30 void addGraph(VisualizationGraphWidget *graphWidget);
30 void addGraph(VisualizationGraphWidget *graphWidget);
31
31
32 /**
32 /**
33 * Creates a graph using a variable. The variable will be displayed in the new graph.
33 * Creates a graph using a variable. The variable will be displayed in the new graph.
34 * @param variable the variable for which to create the graph
34 * @param variable the variable for which to create the graph
35 * @return the pointer to the created graph
35 * @return the pointer to the created graph
36 */
36 */
37 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
37 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
38
38
39 // IVisualizationWidget interface
39 // IVisualizationWidget interface
40 void accept(IVisualizationWidgetVisitor *visitor) override;
40 void accept(IVisualizationWidgetVisitor *visitor) override;
41 bool canDrop(const Variable &variable) const override;
41 bool canDrop(const Variable &variable) const override;
42 bool contains(const Variable &variable) const override;
42 bool contains(const Variable &variable) const override;
43 QString name() const override;
43 QString name() const override;
44
44
45 protected:
46 void closeEvent(QCloseEvent *event) override;
47
45 private:
48 private:
46 Ui::VisualizationZoneWidget *ui;
49 Ui::VisualizationZoneWidget *ui;
47
50
48 class VisualizationZoneWidgetPrivate;
51 class VisualizationZoneWidgetPrivate;
49 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
52 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
50
53
51 private slots:
54 private slots:
52 void onVariableAdded(std::shared_ptr<Variable> variable);
55 void onVariableAdded(std::shared_ptr<Variable> variable);
56 /// Slot called when a variable is about to be removed from a graph contained in the zone
57 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
53 };
58 };
54
59
55 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
60 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -1,42 +1,48
1 #ifndef SCIQLOP_GENERATEVARIABLEMENUOPERATION_H
1 #ifndef SCIQLOP_GENERATEVARIABLEMENUOPERATION_H
2 #define SCIQLOP_GENERATEVARIABLEMENUOPERATION_H
2 #define SCIQLOP_GENERATEVARIABLEMENUOPERATION_H
3
3
4 #include "Visualization/IVisualizationWidgetVisitor.h"
4 #include "Visualization/IVisualizationWidgetVisitor.h"
5
5
6 #include <Common/spimpl.h>
6 #include <Common/spimpl.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9
9
10 #include <set>
11
10 class QMenu;
12 class QMenu;
13 class IVisualizationWidget;
11 class Variable;
14 class Variable;
12
15
13 Q_DECLARE_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation)
16 Q_DECLARE_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation)
14
17
15 /**
18 /**
16 * @brief The GenerateVariableMenuOperation class defines an operation that traverses all of
19 * @brief The GenerateVariableMenuOperation class defines an operation that traverses all of
17 * 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
18 * 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.
19 */
22 */
20 class GenerateVariableMenuOperation : public IVisualizationWidgetVisitor {
23 class GenerateVariableMenuOperation : public IVisualizationWidgetVisitor {
21 public:
24 public:
22 /**
25 /**
23 * Ctor
26 * Ctor
24 * @param menu the menu to which to attach the generated menu
27 * @param menu the menu to which to attach the generated menu
25 * @param variable the variable for which to generate the menu
28 * @param variable the variable for which to generate the menu
29 * @param variableContainers the containers that already contain the variable for which to
30 * generate the menu
26 */
31 */
27 explicit GenerateVariableMenuOperation(QMenu *menu, std::shared_ptr<Variable> variable);
32 explicit GenerateVariableMenuOperation(QMenu *menu, std::shared_ptr<Variable> variable,
33 std::set<IVisualizationWidget *> variableContainers);
28
34
29 void visitEnter(VisualizationWidget *widget) override final;
35 void visitEnter(VisualizationWidget *widget) override final;
30 void visitLeave(VisualizationWidget *widget) override final;
36 void visitLeave(VisualizationWidget *widget) override final;
31 void visitEnter(VisualizationTabWidget *tabWidget) override final;
37 void visitEnter(VisualizationTabWidget *tabWidget) override final;
32 void visitLeave(VisualizationTabWidget *tabWidget) override final;
38 void visitLeave(VisualizationTabWidget *tabWidget) override final;
33 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
39 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
34 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
40 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
35 void visit(VisualizationGraphWidget *graphWidget) override final;
41 void visit(VisualizationGraphWidget *graphWidget) override final;
36
42
37 private:
43 private:
38 class GenerateVariableMenuOperationPrivate;
44 class GenerateVariableMenuOperationPrivate;
39 spimpl::unique_impl_ptr<GenerateVariableMenuOperationPrivate> impl;
45 spimpl::unique_impl_ptr<GenerateVariableMenuOperationPrivate> impl;
40 };
46 };
41
47
42 #endif // SCIQLOP_GENERATEVARIABLEMENUOPERATION_H
48 #endif // SCIQLOP_GENERATEVARIABLEMENUOPERATION_H
@@ -1,76 +1,77
1
1
2 gui_moc_headers = [
2 gui_moc_headers = [
3 'include/DataSource/DataSourceWidget.h',
3 'include/DataSource/DataSourceWidget.h',
4 'include/Settings/SqpSettingsDialog.h',
4 'include/Settings/SqpSettingsDialog.h',
5 'include/Settings/SqpSettingsGeneralWidget.h',
5 'include/Settings/SqpSettingsGeneralWidget.h',
6 'include/SidePane/SqpSidePane.h',
6 'include/SidePane/SqpSidePane.h',
7 'include/SqpApplication.h',
7 'include/SqpApplication.h',
8 'include/TimeWidget/TimeWidget.h',
8 'include/TimeWidget/TimeWidget.h',
9 'include/Variable/VariableInspectorWidget.h',
9 'include/Variable/VariableInspectorWidget.h',
10 'include/Visualization/qcustomplot.h',
10 'include/Visualization/qcustomplot.h',
11 'include/Visualization/VisualizationGraphWidget.h',
11 'include/Visualization/VisualizationGraphWidget.h',
12 'include/Visualization/VisualizationTabWidget.h',
12 'include/Visualization/VisualizationTabWidget.h',
13 'include/Visualization/VisualizationWidget.h',
13 'include/Visualization/VisualizationWidget.h',
14 'include/Visualization/VisualizationZoneWidget.h'
14 'include/Visualization/VisualizationZoneWidget.h'
15 ]
15 ]
16
16
17 gui_ui_files = [
17 gui_ui_files = [
18 'ui/DataSource/DataSourceWidget.ui',
18 'ui/DataSource/DataSourceWidget.ui',
19 'ui/Settings/SqpSettingsDialog.ui',
19 'ui/Settings/SqpSettingsDialog.ui',
20 'ui/Settings/SqpSettingsGeneralWidget.ui',
20 'ui/Settings/SqpSettingsGeneralWidget.ui',
21 'ui/SidePane/SqpSidePane.ui',
21 'ui/SidePane/SqpSidePane.ui',
22 'ui/TimeWidget/TimeWidget.ui',
22 'ui/TimeWidget/TimeWidget.ui',
23 'ui/Variable/VariableInspectorWidget.ui',
23 'ui/Variable/VariableInspectorWidget.ui',
24 'ui/Variable/VariableMenuHeaderWidget.ui',
24 'ui/Variable/VariableMenuHeaderWidget.ui',
25 'ui/Visualization/VisualizationGraphWidget.ui',
25 'ui/Visualization/VisualizationGraphWidget.ui',
26 'ui/Visualization/VisualizationTabWidget.ui',
26 'ui/Visualization/VisualizationTabWidget.ui',
27 'ui/Visualization/VisualizationWidget.ui',
27 'ui/Visualization/VisualizationWidget.ui',
28 'ui/Visualization/VisualizationZoneWidget.ui'
28 'ui/Visualization/VisualizationZoneWidget.ui'
29 ]
29 ]
30
30
31 gui_qresources = ['resources/sqpguiresources.qrc']
31 gui_qresources = ['resources/sqpguiresources.qrc']
32
32
33 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
33 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
34 ui_files : gui_ui_files,
34 ui_files : gui_ui_files,
35 qresources : gui_qresources)
35 qresources : gui_qresources)
36
36
37 gui_sources = [
37 gui_sources = [
38 'src/SqpApplication.cpp',
38 'src/SqpApplication.cpp',
39 'src/Common/ColorUtils.cpp',
39 'src/Common/ColorUtils.cpp',
40 'src/DataSource/DataSourceTreeWidgetItem.cpp',
40 'src/DataSource/DataSourceTreeWidgetItem.cpp',
41 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
41 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
42 'src/DataSource/DataSourceWidget.cpp',
42 'src/DataSource/DataSourceWidget.cpp',
43 'src/Settings/SqpSettingsDialog.cpp',
43 'src/Settings/SqpSettingsDialog.cpp',
44 'src/Settings/SqpSettingsGeneralWidget.cpp',
44 'src/Settings/SqpSettingsGeneralWidget.cpp',
45 'src/SidePane/SqpSidePane.cpp',
45 'src/SidePane/SqpSidePane.cpp',
46 'src/TimeWidget/TimeWidget.cpp',
46 'src/TimeWidget/TimeWidget.cpp',
47 'src/Variable/VariableInspectorWidget.cpp',
47 'src/Variable/VariableInspectorWidget.cpp',
48 'src/Variable/VariableMenuHeaderWidget.cpp',
48 'src/Variable/VariableMenuHeaderWidget.cpp',
49 'src/Visualization/VisualizationGraphHelper.cpp',
49 'src/Visualization/VisualizationGraphHelper.cpp',
50 'src/Visualization/VisualizationGraphRenderingDelegate.cpp',
50 'src/Visualization/VisualizationGraphRenderingDelegate.cpp',
51 'src/Visualization/VisualizationGraphWidget.cpp',
51 'src/Visualization/VisualizationGraphWidget.cpp',
52 'src/Visualization/VisualizationTabWidget.cpp',
52 'src/Visualization/VisualizationTabWidget.cpp',
53 'src/Visualization/VisualizationWidget.cpp',
53 'src/Visualization/VisualizationWidget.cpp',
54 'src/Visualization/VisualizationZoneWidget.cpp',
54 'src/Visualization/VisualizationZoneWidget.cpp',
55 'src/Visualization/qcustomplot.cpp',
55 'src/Visualization/qcustomplot.cpp',
56 'src/Visualization/QCustomPlotSynchronizer.cpp',
56 'src/Visualization/QCustomPlotSynchronizer.cpp',
57 'src/Visualization/operations/FindVariableOperation.cpp',
57 'src/Visualization/operations/GenerateVariableMenuOperation.cpp',
58 'src/Visualization/operations/GenerateVariableMenuOperation.cpp',
58 'src/Visualization/operations/MenuBuilder.cpp',
59 'src/Visualization/operations/MenuBuilder.cpp',
59 'src/Visualization/operations/RemoveVariableOperation.cpp',
60 'src/Visualization/operations/RemoveVariableOperation.cpp',
60 'src/Visualization/operations/RescaleAxeOperation.cpp'
61 'src/Visualization/operations/RescaleAxeOperation.cpp'
61 ]
62 ]
62
63
63 gui_inc = include_directories(['include'])
64 gui_inc = include_directories(['include'])
64
65
65 sciqlop_gui_lib = library('sciqlopgui',
66 sciqlop_gui_lib = library('sciqlopgui',
66 gui_sources,
67 gui_sources,
67 gui_moc_files,
68 gui_moc_files,
68 include_directories : [gui_inc],
69 include_directories : [gui_inc],
69 dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core],
70 dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core],
70 install : true
71 install : true
71 )
72 )
72
73
73 sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib,
74 sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib,
74 include_directories : gui_inc,
75 include_directories : gui_inc,
75 dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core])
76 dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core])
76
77
@@ -1,344 +1,356
1 #include "Visualization/VisualizationGraphWidget.h"
1 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationDefs.h"
3 #include "Visualization/VisualizationDefs.h"
4 #include "Visualization/VisualizationGraphHelper.h"
4 #include "Visualization/VisualizationGraphHelper.h"
5 #include "Visualization/VisualizationGraphRenderingDelegate.h"
5 #include "Visualization/VisualizationGraphRenderingDelegate.h"
6 #include "ui_VisualizationGraphWidget.h"
6 #include "ui_VisualizationGraphWidget.h"
7
7
8 #include <Data/ArrayData.h>
8 #include <Data/ArrayData.h>
9 #include <Data/IDataSeries.h>
9 #include <Data/IDataSeries.h>
10 #include <Settings/SqpSettingsDefs.h>
10 #include <Settings/SqpSettingsDefs.h>
11 #include <SqpApplication.h>
11 #include <SqpApplication.h>
12 #include <Variable/Variable.h>
12 #include <Variable/Variable.h>
13 #include <Variable/VariableController.h>
13 #include <Variable/VariableController.h>
14
14
15 #include <unordered_map>
15 #include <unordered_map>
16
16
17 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
17 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
18
18
19 namespace {
19 namespace {
20
20
21 /// Key pressed to enable zoom on horizontal axis
21 /// Key pressed to enable zoom on horizontal axis
22 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
22 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
23
23
24 /// Key pressed to enable zoom on vertical axis
24 /// Key pressed to enable zoom on vertical axis
25 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
25 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
26
26
27 } // namespace
27 } // namespace
28
28
29 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
29 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
30
30
31 explicit VisualizationGraphWidgetPrivate(const QString &name)
31 explicit VisualizationGraphWidgetPrivate(const QString &name)
32 : m_Name{name},
32 : m_Name{name},
33 m_DoAcquisition{true},
33 m_DoAcquisition{true},
34 m_IsCalibration{false},
34 m_IsCalibration{false},
35 m_RenderingDelegate{nullptr}
35 m_RenderingDelegate{nullptr}
36 {
36 {
37 }
37 }
38
38
39 QString m_Name;
39 QString m_Name;
40 // 1 variable -> n qcpplot
40 // 1 variable -> n qcpplot
41 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
41 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
42 bool m_DoAcquisition;
42 bool m_DoAcquisition;
43 bool m_IsCalibration;
43 bool m_IsCalibration;
44 QCPItemTracer *m_TextTracer;
44 QCPItemTracer *m_TextTracer;
45 /// Delegate used to attach rendering features to the plot
45 /// Delegate used to attach rendering features to the plot
46 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
46 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
47 };
47 };
48
48
49 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
49 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
50 : QWidget{parent},
50 : QWidget{parent},
51 ui{new Ui::VisualizationGraphWidget},
51 ui{new Ui::VisualizationGraphWidget},
52 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
52 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
53 {
53 {
54 ui->setupUi(this);
54 ui->setupUi(this);
55
55
56 // 'Close' options : widget is deleted when closed
56 // 'Close' options : widget is deleted when closed
57 setAttribute(Qt::WA_DeleteOnClose);
57 setAttribute(Qt::WA_DeleteOnClose);
58
58
59 // Set qcpplot properties :
59 // Set qcpplot properties :
60 // - Drag (on x-axis) and zoom are enabled
60 // - Drag (on x-axis) and zoom are enabled
61 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
61 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
62 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectItems);
62 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectItems);
63 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
63 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
64
64
65 // The delegate must be initialized after the ui as it uses the plot
65 // The delegate must be initialized after the ui as it uses the plot
66 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this);
66 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this);
67
67
68 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
68 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
69 connect(ui->widget, &QCustomPlot::mouseRelease, this,
69 connect(ui->widget, &QCustomPlot::mouseRelease, this,
70 &VisualizationGraphWidget::onMouseRelease);
70 &VisualizationGraphWidget::onMouseRelease);
71 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
71 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
72 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
72 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
73 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
73 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
74 &QCPAxis::rangeChanged),
74 &QCPAxis::rangeChanged),
75 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
75 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
76
76
77 // Activates menu when right clicking on the graph
77 // Activates menu when right clicking on the graph
78 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
78 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
79 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
79 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
80 &VisualizationGraphWidget::onGraphMenuRequested);
80 &VisualizationGraphWidget::onGraphMenuRequested);
81
81
82 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
82 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
83 &VariableController::onRequestDataLoading);
83 &VariableController::onRequestDataLoading);
84
84
85 connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
85 connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
86 &VisualizationGraphWidget::onUpdateVarDisplaying);
86 &VisualizationGraphWidget::onUpdateVarDisplaying);
87 }
87 }
88
88
89
89
90 VisualizationGraphWidget::~VisualizationGraphWidget()
90 VisualizationGraphWidget::~VisualizationGraphWidget()
91 {
91 {
92 delete ui;
92 delete ui;
93 }
93 }
94
94
95 void VisualizationGraphWidget::enableAcquisition(bool enable)
95 void VisualizationGraphWidget::enableAcquisition(bool enable)
96 {
96 {
97 impl->m_DoAcquisition = enable;
97 impl->m_DoAcquisition = enable;
98 }
98 }
99
99
100 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
100 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
101 {
101 {
102 // Uses delegate to create the qcpplot components according to the variable
102 // Uses delegate to create the qcpplot components according to the variable
103 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
103 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
104 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
104 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
105
105
106 // Set axes properties according to the units of the data series
106 // Set axes properties according to the units of the data series
107 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
107 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
108 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
108 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
109 auto xAxisUnit = Unit{};
109 auto xAxisUnit = Unit{};
110 auto valuesUnit = Unit{};
110 auto valuesUnit = Unit{};
111
111
112 if (auto dataSeries = variable->dataSeries()) {
112 if (auto dataSeries = variable->dataSeries()) {
113 dataSeries->lockRead();
113 dataSeries->lockRead();
114 xAxisUnit = dataSeries->xAxisUnit();
114 xAxisUnit = dataSeries->xAxisUnit();
115 valuesUnit = dataSeries->valuesUnit();
115 valuesUnit = dataSeries->valuesUnit();
116 dataSeries->unlock();
116 dataSeries->unlock();
117 }
117 }
118 impl->m_RenderingDelegate->setAxesProperties(xAxisUnit, valuesUnit);
118 impl->m_RenderingDelegate->setAxesProperties(xAxisUnit, valuesUnit);
119
119
120 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
120 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
121
121
122 auto varRange = variable->range();
122 auto varRange = variable->range();
123
123
124 this->enableAcquisition(false);
124 this->enableAcquisition(false);
125 this->setGraphRange(range);
125 this->setGraphRange(range);
126 this->enableAcquisition(true);
126 this->enableAcquisition(true);
127
127
128 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, varRange,
128 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, varRange,
129 false);
129 false);
130
130
131 emit variableAdded(variable);
131 emit variableAdded(variable);
132 }
132 }
133
133
134 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
134 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
135 {
135 {
136 // Each component associated to the variable :
136 // Each component associated to the variable :
137 // - is removed from qcpplot (which deletes it)
137 // - is removed from qcpplot (which deletes it)
138 // - is no longer referenced in the map
138 // - is no longer referenced in the map
139 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
139 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
140 if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
140 if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
141 emit variableAboutToBeRemoved(variable);
142
141 auto &plottablesMap = variableIt->second;
143 auto &plottablesMap = variableIt->second;
142
144
143 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
145 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
144 plottableIt != plottableEnd;) {
146 plottableIt != plottableEnd;) {
145 ui->widget->removePlottable(plottableIt->second);
147 ui->widget->removePlottable(plottableIt->second);
146 plottableIt = plottablesMap.erase(plottableIt);
148 plottableIt = plottablesMap.erase(plottableIt);
147 }
149 }
148
150
149 impl->m_VariableToPlotMultiMap.erase(variableIt);
151 impl->m_VariableToPlotMultiMap.erase(variableIt);
150 }
152 }
151
153
152 // Updates graph
154 // Updates graph
153 ui->widget->replot();
155 ui->widget->replot();
154 }
156 }
155
157
156 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable, const SqpRange &range)
158 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable, const SqpRange &range)
157 {
159 {
158 // Note: in case of different axes that depends on variable, we could start with a code like
160 // Note: in case of different axes that depends on variable, we could start with a code like
159 // that:
161 // that:
160 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
162 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
161 // for (auto it = componentsIt.first; it != componentsIt.second;) {
163 // for (auto it = componentsIt.first; it != componentsIt.second;) {
162 // }
164 // }
163 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
165 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
164 ui->widget->replot();
166 ui->widget->replot();
165 }
167 }
166
168
167 void VisualizationGraphWidget::setYRange(const SqpRange &range)
169 void VisualizationGraphWidget::setYRange(const SqpRange &range)
168 {
170 {
169 ui->widget->yAxis->setRange(range.m_TStart, range.m_TEnd);
171 ui->widget->yAxis->setRange(range.m_TStart, range.m_TEnd);
170 }
172 }
171
173
172 SqpRange VisualizationGraphWidget::graphRange() const noexcept
174 SqpRange VisualizationGraphWidget::graphRange() const noexcept
173 {
175 {
174 auto graphRange = ui->widget->xAxis->range();
176 auto graphRange = ui->widget->xAxis->range();
175 return SqpRange{graphRange.lower, graphRange.upper};
177 return SqpRange{graphRange.lower, graphRange.upper};
176 }
178 }
177
179
178 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
180 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
179 {
181 {
180 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
182 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
181 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
183 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
182 ui->widget->replot();
184 ui->widget->replot();
183 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
185 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
184 }
186 }
185
187
186 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
188 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
187 {
189 {
188 if (visitor) {
190 if (visitor) {
189 visitor->visit(this);
191 visitor->visit(this);
190 }
192 }
191 else {
193 else {
192 qCCritical(LOG_VisualizationGraphWidget())
194 qCCritical(LOG_VisualizationGraphWidget())
193 << tr("Can't visit widget : the visitor is null");
195 << tr("Can't visit widget : the visitor is null");
194 }
196 }
195 }
197 }
196
198
197 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
199 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
198 {
200 {
199 /// @todo : for the moment, a graph can always accomodate a variable
201 /// @todo : for the moment, a graph can always accomodate a variable
200 Q_UNUSED(variable);
202 Q_UNUSED(variable);
201 return true;
203 return true;
202 }
204 }
203
205
204 bool VisualizationGraphWidget::contains(const Variable &variable) const
206 bool VisualizationGraphWidget::contains(const Variable &variable) const
205 {
207 {
206 // Finds the variable among the keys of the map
208 // Finds the variable among the keys of the map
207 auto variablePtr = &variable;
209 auto variablePtr = &variable;
208 auto findVariable
210 auto findVariable
209 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
211 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
210
212
211 auto end = impl->m_VariableToPlotMultiMap.cend();
213 auto end = impl->m_VariableToPlotMultiMap.cend();
212 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
214 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
213 return it != end;
215 return it != end;
214 }
216 }
215
217
216 QString VisualizationGraphWidget::name() const
218 QString VisualizationGraphWidget::name() const
217 {
219 {
218 return impl->m_Name;
220 return impl->m_Name;
219 }
221 }
220
222
223 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
224 {
225 Q_UNUSED(event);
226
227 // Prevents that all variables will be removed from graph when it will be closed
228 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
229 emit variableAboutToBeRemoved(variableEntry.first);
230 }
231 }
232
221 void VisualizationGraphWidget::enterEvent(QEvent *event)
233 void VisualizationGraphWidget::enterEvent(QEvent *event)
222 {
234 {
223 Q_UNUSED(event);
235 Q_UNUSED(event);
224 impl->m_RenderingDelegate->showGraphOverlay(true);
236 impl->m_RenderingDelegate->showGraphOverlay(true);
225 }
237 }
226
238
227 void VisualizationGraphWidget::leaveEvent(QEvent *event)
239 void VisualizationGraphWidget::leaveEvent(QEvent *event)
228 {
240 {
229 Q_UNUSED(event);
241 Q_UNUSED(event);
230 impl->m_RenderingDelegate->showGraphOverlay(false);
242 impl->m_RenderingDelegate->showGraphOverlay(false);
231 }
243 }
232
244
233 QCustomPlot &VisualizationGraphWidget::plot() noexcept
245 QCustomPlot &VisualizationGraphWidget::plot() noexcept
234 {
246 {
235 return *ui->widget;
247 return *ui->widget;
236 }
248 }
237
249
238 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
250 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
239 {
251 {
240 QMenu graphMenu{};
252 QMenu graphMenu{};
241
253
242 // Iterates on variables (unique keys)
254 // Iterates on variables (unique keys)
243 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
255 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
244 end = impl->m_VariableToPlotMultiMap.cend();
256 end = impl->m_VariableToPlotMultiMap.cend();
245 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
257 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
246 // 'Remove variable' action
258 // 'Remove variable' action
247 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
259 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
248 [ this, var = it->first ]() { removeVariable(var); });
260 [ this, var = it->first ]() { removeVariable(var); });
249 }
261 }
250
262
251 if (!graphMenu.isEmpty()) {
263 if (!graphMenu.isEmpty()) {
252 graphMenu.exec(QCursor::pos());
264 graphMenu.exec(QCursor::pos());
253 }
265 }
254 }
266 }
255
267
256 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
268 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
257 {
269 {
258 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
270 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
259 << QThread::currentThread()->objectName() << "DoAcqui"
271 << QThread::currentThread()->objectName() << "DoAcqui"
260 << impl->m_DoAcquisition;
272 << impl->m_DoAcquisition;
261
273
262 auto graphRange = SqpRange{t1.lower, t1.upper};
274 auto graphRange = SqpRange{t1.lower, t1.upper};
263 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
275 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
264
276
265 if (impl->m_DoAcquisition) {
277 if (impl->m_DoAcquisition) {
266 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
278 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
267
279
268 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
280 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
269 end = impl->m_VariableToPlotMultiMap.end();
281 end = impl->m_VariableToPlotMultiMap.end();
270 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
282 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
271 variableUnderGraphVector.push_back(it->first);
283 variableUnderGraphVector.push_back(it->first);
272 }
284 }
273 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
285 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
274 !impl->m_IsCalibration);
286 !impl->m_IsCalibration);
275
287
276 if (!impl->m_IsCalibration) {
288 if (!impl->m_IsCalibration) {
277 qCDebug(LOG_VisualizationGraphWidget())
289 qCDebug(LOG_VisualizationGraphWidget())
278 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
290 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
279 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
291 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
280 emit synchronize(graphRange, oldGraphRange);
292 emit synchronize(graphRange, oldGraphRange);
281 }
293 }
282 }
294 }
283 }
295 }
284
296
285 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
297 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
286 {
298 {
287 // Handles plot rendering when mouse is moving
299 // Handles plot rendering when mouse is moving
288 impl->m_RenderingDelegate->onMouseMove(event);
300 impl->m_RenderingDelegate->onMouseMove(event);
289 }
301 }
290
302
291 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
303 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
292 {
304 {
293 auto zoomOrientations = QFlags<Qt::Orientation>{};
305 auto zoomOrientations = QFlags<Qt::Orientation>{};
294
306
295 // Lambda that enables a zoom orientation if the key modifier related to this orientation
307 // Lambda that enables a zoom orientation if the key modifier related to this orientation
296 // has
308 // has
297 // been pressed
309 // been pressed
298 auto enableOrientation
310 auto enableOrientation
299 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
311 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
300 auto orientationEnabled = event->modifiers().testFlag(modifier);
312 auto orientationEnabled = event->modifiers().testFlag(modifier);
301 zoomOrientations.setFlag(orientation, orientationEnabled);
313 zoomOrientations.setFlag(orientation, orientationEnabled);
302 };
314 };
303 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
315 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
304 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
316 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
305
317
306 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
318 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
307 }
319 }
308
320
309 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
321 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
310 {
322 {
311 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
323 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
312 }
324 }
313
325
314 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
326 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
315 {
327 {
316 impl->m_IsCalibration = false;
328 impl->m_IsCalibration = false;
317 }
329 }
318
330
319 void VisualizationGraphWidget::onDataCacheVariableUpdated()
331 void VisualizationGraphWidget::onDataCacheVariableUpdated()
320 {
332 {
321 auto graphRange = ui->widget->xAxis->range();
333 auto graphRange = ui->widget->xAxis->range();
322 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
334 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
323
335
324 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
336 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
325 auto variable = variableEntry.first;
337 auto variable = variableEntry.first;
326 qCDebug(LOG_VisualizationGraphWidget())
338 qCDebug(LOG_VisualizationGraphWidget())
327 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
339 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
328 qCDebug(LOG_VisualizationGraphWidget())
340 qCDebug(LOG_VisualizationGraphWidget())
329 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
341 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
330 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
342 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
331 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
343 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
332 variable->range());
344 variable->range());
333 }
345 }
334 }
346 }
335 }
347 }
336
348
337 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
349 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
338 const SqpRange &range)
350 const SqpRange &range)
339 {
351 {
340 auto it = impl->m_VariableToPlotMultiMap.find(variable);
352 auto it = impl->m_VariableToPlotMultiMap.find(variable);
341 if (it != impl->m_VariableToPlotMultiMap.end()) {
353 if (it != impl->m_VariableToPlotMultiMap.end()) {
342 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
354 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
343 }
355 }
344 }
356 }
@@ -1,110 +1,129
1 #include "Visualization/VisualizationTabWidget.h"
1 #include "Visualization/VisualizationTabWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "ui_VisualizationTabWidget.h"
3 #include "ui_VisualizationTabWidget.h"
4
4
5 #include "Visualization/VisualizationZoneWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
6
6
7 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
7 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
8
8
9 namespace {
9 namespace {
10
10
11 /// Generates a default name for a new zone, according to the number of zones already displayed in
11 /// Generates a default name for a new zone, according to the number of zones already displayed in
12 /// the tab
12 /// the tab
13 QString defaultZoneName(const QLayout &layout)
13 QString defaultZoneName(const QLayout &layout)
14 {
14 {
15 auto count = 0;
15 auto count = 0;
16 for (auto i = 0; i < layout.count(); ++i) {
16 for (auto i = 0; i < layout.count(); ++i) {
17 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
17 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
18 count++;
18 count++;
19 }
19 }
20 }
20 }
21
21
22 return QObject::tr("Zone %1").arg(count + 1);
22 return QObject::tr("Zone %1").arg(count + 1);
23 }
23 }
24
24
25 /**
26 * Applies a function to all zones of the tab represented by its layout
27 * @param layout the layout that contains zones
28 * @param fun the function to apply to each zone
29 */
30 template <typename Fun>
31 void processZones(QLayout &layout, Fun fun)
32 {
33 for (auto i = 0; i < layout.count(); ++i) {
34 if (auto item = layout.itemAt(i)) {
35 if (auto visualizationZoneWidget
36 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
37 fun(*visualizationZoneWidget);
38 }
39 }
40 }
41 }
42
25 } // namespace
43 } // namespace
26
44
27 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
45 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
28 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
46 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
29
47
30 QString m_Name;
48 QString m_Name;
31 };
49 };
32
50
33 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
51 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
34 : QWidget{parent},
52 : QWidget{parent},
35 ui{new Ui::VisualizationTabWidget},
53 ui{new Ui::VisualizationTabWidget},
36 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
54 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
37 {
55 {
38 ui->setupUi(this);
56 ui->setupUi(this);
39
57
40 // Widget is deleted when closed
58 // Widget is deleted when closed
41 setAttribute(Qt::WA_DeleteOnClose);
59 setAttribute(Qt::WA_DeleteOnClose);
42 }
60 }
43
61
44 VisualizationTabWidget::~VisualizationTabWidget()
62 VisualizationTabWidget::~VisualizationTabWidget()
45 {
63 {
46 delete ui;
64 delete ui;
47 }
65 }
48
66
49 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
67 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
50 {
68 {
51 tabLayout().addWidget(zoneWidget);
69 tabLayout().addWidget(zoneWidget);
52 }
70 }
53
71
54 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
72 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
55 {
73 {
56 auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(tabLayout()), this};
74 auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(tabLayout()), this};
57 this->addZone(zoneWidget);
75 this->addZone(zoneWidget);
58
76
59 // Creates a new graph into the zone
77 // Creates a new graph into the zone
60 zoneWidget->createGraph(variable);
78 zoneWidget->createGraph(variable);
61
79
62 return zoneWidget;
80 return zoneWidget;
63 }
81 }
64
82
65 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
83 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
66 {
84 {
67 if (visitor) {
85 if (visitor) {
68 visitor->visitEnter(this);
86 visitor->visitEnter(this);
69
87
70 // Apply visitor to zone children
88 // Apply visitor to zone children: widgets different from zones are not visited (no action)
71 auto &layout = tabLayout();
89 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
72 for (auto i = 0; i < layout.count(); ++i) {
90 zoneWidget.accept(visitor);
73 if (auto item = layout.itemAt(i)) {
91 });
74 // Widgets different from zones are not visited (no action)
75 if (auto visualizationZoneWidget
76 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
77 visualizationZoneWidget->accept(visitor);
78 }
79 }
80 }
81
92
82 visitor->visitLeave(this);
93 visitor->visitLeave(this);
83 }
94 }
84 else {
95 else {
85 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
96 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
86 }
97 }
87 }
98 }
88
99
89 bool VisualizationTabWidget::canDrop(const Variable &variable) const
100 bool VisualizationTabWidget::canDrop(const Variable &variable) const
90 {
101 {
91 // A tab can always accomodate a variable
102 // A tab can always accomodate a variable
92 Q_UNUSED(variable);
103 Q_UNUSED(variable);
93 return true;
104 return true;
94 }
105 }
95
106
96 bool VisualizationTabWidget::contains(const Variable &variable) const
107 bool VisualizationTabWidget::contains(const Variable &variable) const
97 {
108 {
98 Q_UNUSED(variable);
109 Q_UNUSED(variable);
99 return false;
110 return false;
100 }
111 }
101
112
102 QString VisualizationTabWidget::name() const
113 QString VisualizationTabWidget::name() const
103 {
114 {
104 return impl->m_Name;
115 return impl->m_Name;
105 }
116 }
106
117
118 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
119 {
120 // Closes zones in the tab
121 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
122
123 QWidget::closeEvent(event);
124 }
125
107 QLayout &VisualizationTabWidget::tabLayout() const noexcept
126 QLayout &VisualizationTabWidget::tabLayout() const noexcept
108 {
127 {
109 return *ui->scrollAreaWidgetContents->layout();
128 return *ui->scrollAreaWidgetContents->layout();
110 }
129 }
@@ -1,152 +1,172
1 #include "Visualization/VisualizationWidget.h"
1 #include "Visualization/VisualizationWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationGraphWidget.h"
3 #include "Visualization/VisualizationGraphWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/operations/FindVariableOperation.h"
6 #include "Visualization/operations/GenerateVariableMenuOperation.h"
7 #include "Visualization/operations/GenerateVariableMenuOperation.h"
7 #include "Visualization/operations/RemoveVariableOperation.h"
8 #include "Visualization/operations/RemoveVariableOperation.h"
8 #include "Visualization/operations/RescaleAxeOperation.h"
9 #include "Visualization/operations/RescaleAxeOperation.h"
9 #include "Visualization/qcustomplot.h"
10 #include "Visualization/qcustomplot.h"
10
11
11 #include "ui_VisualizationWidget.h"
12 #include "ui_VisualizationWidget.h"
12
13
13 #include <QToolButton>
14 #include <QToolButton>
14
15
15 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
16 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
16
17
17 VisualizationWidget::VisualizationWidget(QWidget *parent)
18 VisualizationWidget::VisualizationWidget(QWidget *parent)
18 : QWidget{parent}, ui{new Ui::VisualizationWidget}
19 : QWidget{parent}, ui{new Ui::VisualizationWidget}
19 {
20 {
20 ui->setupUi(this);
21 ui->setupUi(this);
21
22
22 auto addTabViewButton = new QToolButton{ui->tabWidget};
23 auto addTabViewButton = new QToolButton{ui->tabWidget};
23 addTabViewButton->setText(tr("Add View"));
24 addTabViewButton->setText(tr("Add View"));
24 addTabViewButton->setCursor(Qt::ArrowCursor);
25 addTabViewButton->setCursor(Qt::ArrowCursor);
25 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
26 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
26
27
27 auto enableMinimumCornerWidgetSize = [this](bool enable) {
28 auto enableMinimumCornerWidgetSize = [this](bool enable) {
28
29
29 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
30 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
30 auto width = enable ? tabViewCornerWidget->width() : 0;
31 auto width = enable ? tabViewCornerWidget->width() : 0;
31 auto height = enable ? tabViewCornerWidget->height() : 0;
32 auto height = enable ? tabViewCornerWidget->height() : 0;
32 tabViewCornerWidget->setMinimumHeight(height);
33 tabViewCornerWidget->setMinimumHeight(height);
33 tabViewCornerWidget->setMinimumWidth(width);
34 tabViewCornerWidget->setMinimumWidth(width);
34 ui->tabWidget->setMinimumHeight(height);
35 ui->tabWidget->setMinimumHeight(height);
35 ui->tabWidget->setMinimumWidth(width);
36 ui->tabWidget->setMinimumWidth(width);
36 };
37 };
37
38
38 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
39 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
39 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
40 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
40 ui->tabWidget};
41 ui->tabWidget};
41 auto index = ui->tabWidget->addTab(widget, widget->name());
42 auto index = ui->tabWidget->addTab(widget, widget->name());
42 if (ui->tabWidget->count() > 0) {
43 if (ui->tabWidget->count() > 0) {
43 enableMinimumCornerWidgetSize(false);
44 enableMinimumCornerWidgetSize(false);
44 }
45 }
45 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
46 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
46 };
47 };
47
48
48 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
49 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
49 if (ui->tabWidget->count() == 1) {
50 if (ui->tabWidget->count() == 1) {
50 enableMinimumCornerWidgetSize(true);
51 enableMinimumCornerWidgetSize(true);
51 }
52 }
52
53
53 // Removes widget from tab and closes it
54 // Removes widget from tab and closes it
54 auto widget = ui->tabWidget->widget(index);
55 auto widget = ui->tabWidget->widget(index);
55 ui->tabWidget->removeTab(index);
56 ui->tabWidget->removeTab(index);
56 if (widget) {
57 if (widget) {
57 widget->close();
58 widget->close();
58 }
59 }
59
60
60 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
61 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
61
62
62 };
63 };
63
64
64 ui->tabWidget->setTabsClosable(true);
65 ui->tabWidget->setTabsClosable(true);
65
66
66 connect(addTabViewButton, &QToolButton::clicked, addTabView);
67 connect(addTabViewButton, &QToolButton::clicked, addTabView);
67 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
68 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
68
69
69 // Adds default tab
70 // Adds default tab
70 addTabView();
71 addTabView();
71 }
72 }
72
73
73 VisualizationWidget::~VisualizationWidget()
74 VisualizationWidget::~VisualizationWidget()
74 {
75 {
75 delete ui;
76 delete ui;
76 }
77 }
77
78
78 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
79 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
79 {
80 {
80 if (visitor) {
81 if (visitor) {
81 visitor->visitEnter(this);
82 visitor->visitEnter(this);
82
83
83 // Apply visitor for tab children
84 // Apply visitor for tab children
84 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
85 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
85 // Widgets different from tabs are not visited (no action)
86 // Widgets different from tabs are not visited (no action)
86 if (auto visualizationTabWidget
87 if (auto visualizationTabWidget
87 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
88 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
88 visualizationTabWidget->accept(visitor);
89 visualizationTabWidget->accept(visitor);
89 }
90 }
90 }
91 }
91
92
92 visitor->visitLeave(this);
93 visitor->visitLeave(this);
93 }
94 }
94 else {
95 else {
95 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
96 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
96 }
97 }
97 }
98 }
98
99
99 bool VisualizationWidget::canDrop(const Variable &variable) const
100 bool VisualizationWidget::canDrop(const Variable &variable) const
100 {
101 {
101 // The main widget can never accomodate a variable
102 // The main widget can never accomodate a variable
102 Q_UNUSED(variable);
103 Q_UNUSED(variable);
103 return false;
104 return false;
104 }
105 }
105
106
106 bool VisualizationWidget::contains(const Variable &variable) const
107 bool VisualizationWidget::contains(const Variable &variable) const
107 {
108 {
108 Q_UNUSED(variable);
109 Q_UNUSED(variable);
109 return false;
110 return false;
110 }
111 }
111
112
112 QString VisualizationWidget::name() const
113 QString VisualizationWidget::name() const
113 {
114 {
114 return QStringLiteral("MainView");
115 return QStringLiteral("MainView");
115 }
116 }
116
117
117 void VisualizationWidget::attachVariableMenu(
118 void VisualizationWidget::attachVariableMenu(
118 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
119 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
119 {
120 {
120 // Menu is generated only if there is a single variable
121 // Menu is generated only if there is a single variable
121 if (variables.size() == 1) {
122 if (variables.size() == 1) {
122 if (auto variable = variables.first()) {
123 if (auto variable = variables.first()) {
124 // Gets the containers of the variable
125 FindVariableOperation findVariableOperation{variable};
126 accept(&findVariableOperation);
127 auto variableContainers = findVariableOperation.result();
128
123 // Generates the actions that make it possible to visualize the variable
129 // Generates the actions that make it possible to visualize the variable
124 auto generateVariableMenuOperation = GenerateVariableMenuOperation{menu, variable};
130 GenerateVariableMenuOperation generateVariableMenuOperation{
131 menu, variable, std::move(variableContainers)};
125 accept(&generateVariableMenuOperation);
132 accept(&generateVariableMenuOperation);
126 }
133 }
127 else {
134 else {
128 qCCritical(LOG_VisualizationWidget()) << tr(
135 qCCritical(LOG_VisualizationWidget()) << tr(
129 "Can't generate the menu relative to the visualization: the variable is null");
136 "Can't generate the menu relative to the visualization: the variable is null");
130 }
137 }
131 }
138 }
132 else {
139 else {
133 qCDebug(LOG_VisualizationWidget())
140 qCDebug(LOG_VisualizationWidget())
134 << tr("No generation of the menu related to the visualization: several variables are "
141 << tr("No generation of the menu related to the visualization: several variables are "
135 "selected");
142 "selected");
136 }
143 }
137 }
144 }
138
145
139 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
146 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
140 {
147 {
141 // Calls the operation of removing all references to the variable in the visualization
148 // Calls the operation of removing all references to the variable in the visualization
142 auto removeVariableOperation = RemoveVariableOperation{variable};
149 auto removeVariableOperation = RemoveVariableOperation{variable};
143 accept(&removeVariableOperation);
150 accept(&removeVariableOperation);
144 }
151 }
145
152
146 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
153 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
147 const SqpRange &range) noexcept
154 const SqpRange &range) noexcept
148 {
155 {
149 // Calls the operation of rescaling all graph that contrains variable in the visualization
156 // Calls the operation of rescaling all graph that contrains variable in the visualization
150 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
157 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
151 accept(&rescaleVariableOperation);
158 accept(&rescaleVariableOperation);
152 }
159 }
160
161 void VisualizationWidget::closeEvent(QCloseEvent *event)
162 {
163 // Closes tabs in the widget
164 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
165 if (auto visualizationTabWidget
166 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
167 visualizationTabWidget->close();
168 }
169 }
170
171 QWidget::closeEvent(event);
172 }
@@ -1,268 +1,302
1 #include "Visualization/VisualizationZoneWidget.h"
1 #include "Visualization/VisualizationZoneWidget.h"
2
2
3 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/IVisualizationWidgetVisitor.h"
4 #include "Visualization/QCustomPlotSynchronizer.h"
4 #include "Visualization/QCustomPlotSynchronizer.h"
5 #include "Visualization/VisualizationGraphWidget.h"
5 #include "Visualization/VisualizationGraphWidget.h"
6 #include "ui_VisualizationZoneWidget.h"
6 #include "ui_VisualizationZoneWidget.h"
7
7
8 #include <Data/SqpRange.h>
8 #include <Data/SqpRange.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10 #include <Variable/VariableController.h>
10 #include <Variable/VariableController.h>
11
11
12 #include <QUuid>
12 #include <QUuid>
13 #include <SqpApplication.h>
13 #include <SqpApplication.h>
14 #include <cmath>
14 #include <cmath>
15
15
16 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
16 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
17
17
18 namespace {
18 namespace {
19
19
20 /// Minimum height for graph added in zones (in pixels)
20 /// Minimum height for graph added in zones (in pixels)
21 const auto GRAPH_MINIMUM_HEIGHT = 300;
21 const auto GRAPH_MINIMUM_HEIGHT = 300;
22
22
23 /// Generates a default name for a new graph, according to the number of graphs already displayed in
23 /// Generates a default name for a new graph, according to the number of graphs already displayed in
24 /// the zone
24 /// the zone
25 QString defaultGraphName(const QLayout &layout)
25 QString defaultGraphName(const QLayout &layout)
26 {
26 {
27 auto count = 0;
27 auto count = 0;
28 for (auto i = 0; i < layout.count(); ++i) {
28 for (auto i = 0; i < layout.count(); ++i) {
29 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
29 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
30 count++;
30 count++;
31 }
31 }
32 }
32 }
33
33
34 return QObject::tr("Graph %1").arg(count + 1);
34 return QObject::tr("Graph %1").arg(count + 1);
35 }
35 }
36
36
37 /**
38 * Applies a function to all graphs of the zone represented by its layout
39 * @param layout the layout that contains graphs
40 * @param fun the function to apply to each graph
41 */
42 template <typename Fun>
43 void processGraphs(QLayout &layout, Fun fun)
44 {
45 for (auto i = 0; i < layout.count(); ++i) {
46 if (auto item = layout.itemAt(i)) {
47 if (auto visualizationGraphWidget
48 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
49 fun(*visualizationGraphWidget);
50 }
51 }
52 }
53 }
54
37 } // namespace
55 } // namespace
38
56
39 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
57 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
40
58
41 explicit VisualizationZoneWidgetPrivate()
59 explicit VisualizationZoneWidgetPrivate()
42 : m_SynchronisationGroupId{QUuid::createUuid()},
60 : m_SynchronisationGroupId{QUuid::createUuid()},
43 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
61 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
44 {
62 {
45 }
63 }
46 QUuid m_SynchronisationGroupId;
64 QUuid m_SynchronisationGroupId;
47 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
65 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
48 };
66 };
49
67
50 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
68 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
51 : QWidget{parent},
69 : QWidget{parent},
52 ui{new Ui::VisualizationZoneWidget},
70 ui{new Ui::VisualizationZoneWidget},
53 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
71 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
54 {
72 {
55 ui->setupUi(this);
73 ui->setupUi(this);
56
74
57 ui->zoneNameLabel->setText(name);
75 ui->zoneNameLabel->setText(name);
58
76
59 // 'Close' options : widget is deleted when closed
77 // 'Close' options : widget is deleted when closed
60 setAttribute(Qt::WA_DeleteOnClose);
78 setAttribute(Qt::WA_DeleteOnClose);
61 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
79 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
62 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
80 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
63
81
64 // Synchronisation id
82 // Synchronisation id
65 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
83 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
66 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
84 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
67 }
85 }
68
86
69 VisualizationZoneWidget::~VisualizationZoneWidget()
87 VisualizationZoneWidget::~VisualizationZoneWidget()
70 {
88 {
71 delete ui;
89 delete ui;
72 }
90 }
73
91
74 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
92 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
75 {
93 {
76 // Synchronize new graph with others in the zone
94 // Synchronize new graph with others in the zone
77 impl->m_Synchronizer->addGraph(*graphWidget);
95 impl->m_Synchronizer->addGraph(*graphWidget);
78
96
79 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
97 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
80 }
98 }
81
99
82 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
100 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
83 {
101 {
84 auto graphWidget = new VisualizationGraphWidget{
102 auto graphWidget = new VisualizationGraphWidget{
85 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
103 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
86
104
87
105
88 // Set graph properties
106 // Set graph properties
89 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
107 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
90 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
108 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
91
109
92
110
93 // Lambda to synchronize zone widget
111 // Lambda to synchronize zone widget
94 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
112 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
95 const SqpRange &oldGraphRange) {
113 const SqpRange &oldGraphRange) {
96
114
97 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
115 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
98 auto frameLayout = ui->visualizationZoneFrame->layout();
116 auto frameLayout = ui->visualizationZoneFrame->layout();
99 for (auto i = 0; i < frameLayout->count(); ++i) {
117 for (auto i = 0; i < frameLayout->count(); ++i) {
100 auto graphChild
118 auto graphChild
101 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
119 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
102 if (graphChild && (graphChild != graphWidget)) {
120 if (graphChild && (graphChild != graphWidget)) {
103
121
104 auto graphChildRange = graphChild->graphRange();
122 auto graphChildRange = graphChild->graphRange();
105 switch (zoomType) {
123 switch (zoomType) {
106 case AcquisitionZoomType::ZoomIn: {
124 case AcquisitionZoomType::ZoomIn: {
107 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
125 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
108 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
126 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
109 graphChildRange.m_TStart += deltaLeft;
127 graphChildRange.m_TStart += deltaLeft;
110 graphChildRange.m_TEnd -= deltaRight;
128 graphChildRange.m_TEnd -= deltaRight;
111 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
129 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
112 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
130 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
113 << deltaLeft;
131 << deltaLeft;
114 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
132 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
115 << deltaRight;
133 << deltaRight;
116 qCDebug(LOG_VisualizationZoneWidget())
134 qCDebug(LOG_VisualizationZoneWidget())
117 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
135 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
118
136
119 break;
137 break;
120 }
138 }
121
139
122 case AcquisitionZoomType::ZoomOut: {
140 case AcquisitionZoomType::ZoomOut: {
123 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
141 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
124 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
142 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
125 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
143 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
126 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
144 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
127 << deltaLeft;
145 << deltaLeft;
128 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
146 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
129 << deltaRight;
147 << deltaRight;
130 qCDebug(LOG_VisualizationZoneWidget())
148 qCDebug(LOG_VisualizationZoneWidget())
131 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
149 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
132 graphChildRange.m_TStart -= deltaLeft;
150 graphChildRange.m_TStart -= deltaLeft;
133 graphChildRange.m_TEnd += deltaRight;
151 graphChildRange.m_TEnd += deltaRight;
134 break;
152 break;
135 }
153 }
136 case AcquisitionZoomType::PanRight: {
154 case AcquisitionZoomType::PanRight: {
137 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
155 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
138 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
156 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
139 graphChildRange.m_TStart += deltaRight;
157 graphChildRange.m_TStart += deltaRight;
140 graphChildRange.m_TEnd += deltaRight;
158 graphChildRange.m_TEnd += deltaRight;
141 qCDebug(LOG_VisualizationZoneWidget())
159 qCDebug(LOG_VisualizationZoneWidget())
142 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
160 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
143 break;
161 break;
144 }
162 }
145 case AcquisitionZoomType::PanLeft: {
163 case AcquisitionZoomType::PanLeft: {
146 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
164 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
147 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
165 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
148 graphChildRange.m_TStart -= deltaLeft;
166 graphChildRange.m_TStart -= deltaLeft;
149 graphChildRange.m_TEnd -= deltaLeft;
167 graphChildRange.m_TEnd -= deltaLeft;
150 break;
168 break;
151 }
169 }
152 case AcquisitionZoomType::Unknown: {
170 case AcquisitionZoomType::Unknown: {
153 qCDebug(LOG_VisualizationZoneWidget())
171 qCDebug(LOG_VisualizationZoneWidget())
154 << tr("Impossible to synchronize: zoom type unknown");
172 << tr("Impossible to synchronize: zoom type unknown");
155 break;
173 break;
156 }
174 }
157 default:
175 default:
158 qCCritical(LOG_VisualizationZoneWidget())
176 qCCritical(LOG_VisualizationZoneWidget())
159 << tr("Impossible to synchronize: zoom type not take into account");
177 << tr("Impossible to synchronize: zoom type not take into account");
160 // No action
178 // No action
161 break;
179 break;
162 }
180 }
163 graphChild->enableAcquisition(false);
181 graphChild->enableAcquisition(false);
164 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
182 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
165 << graphChild->graphRange();
183 << graphChild->graphRange();
166 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
184 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
167 << graphChildRange;
185 << graphChildRange;
168 qCDebug(LOG_VisualizationZoneWidget())
186 qCDebug(LOG_VisualizationZoneWidget())
169 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
187 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
170 graphChild->setGraphRange(graphChildRange);
188 graphChild->setGraphRange(graphChildRange);
171 graphChild->enableAcquisition(true);
189 graphChild->enableAcquisition(true);
172 }
190 }
173 }
191 }
174 };
192 };
175
193
176 // connection for synchronization
194 // connection for synchronization
177 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
195 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
178 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
196 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
179 &VisualizationZoneWidget::onVariableAdded);
197 &VisualizationZoneWidget::onVariableAdded);
198 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
199 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
180
200
181 auto range = SqpRange{};
201 auto range = SqpRange{};
182
202
183 // Apply visitor to graph children
203 // Apply visitor to graph children
184 auto layout = ui->visualizationZoneFrame->layout();
204 auto layout = ui->visualizationZoneFrame->layout();
185 if (layout->count() > 0) {
205 if (layout->count() > 0) {
186 // Case of a new graph in a existant zone
206 // Case of a new graph in a existant zone
187 if (auto visualizationGraphWidget
207 if (auto visualizationGraphWidget
188 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
208 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
189 range = visualizationGraphWidget->graphRange();
209 range = visualizationGraphWidget->graphRange();
190 }
210 }
191 }
211 }
192 else {
212 else {
193 // Case of a new graph as the first of the zone
213 // Case of a new graph as the first of the zone
194 range = variable->range();
214 range = variable->range();
195 }
215 }
196
216
197 this->addGraph(graphWidget);
217 this->addGraph(graphWidget);
198
218
199 graphWidget->addVariable(variable, range);
219 graphWidget->addVariable(variable, range);
200
220
201 // get y using variable range
221 // get y using variable range
202 if (auto dataSeries = variable->dataSeries()) {
222 if (auto dataSeries = variable->dataSeries()) {
203 dataSeries->lockRead();
223 dataSeries->lockRead();
204 auto valuesBounds
224 auto valuesBounds
205 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
225 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
206 auto end = dataSeries->cend();
226 auto end = dataSeries->cend();
207 if (valuesBounds.first != end && valuesBounds.second != end) {
227 if (valuesBounds.first != end && valuesBounds.second != end) {
208 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
228 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
209
229
210 auto minValue = rangeValue(valuesBounds.first->minValue());
230 auto minValue = rangeValue(valuesBounds.first->minValue());
211 auto maxValue = rangeValue(valuesBounds.second->maxValue());
231 auto maxValue = rangeValue(valuesBounds.second->maxValue());
212
232
213 graphWidget->setYRange(SqpRange{minValue, maxValue});
233 graphWidget->setYRange(SqpRange{minValue, maxValue});
214 }
234 }
215 dataSeries->unlock();
235 dataSeries->unlock();
216 }
236 }
217
237
218 return graphWidget;
238 return graphWidget;
219 }
239 }
220
240
221 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
241 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
222 {
242 {
223 if (visitor) {
243 if (visitor) {
224 visitor->visitEnter(this);
244 visitor->visitEnter(this);
225
245
226 // Apply visitor to graph children
246 // Apply visitor to graph children: widgets different from graphs are not visited (no
227 auto layout = ui->visualizationZoneFrame->layout();
247 // action)
228 for (auto i = 0; i < layout->count(); ++i) {
248 processGraphs(
229 if (auto item = layout->itemAt(i)) {
249 *ui->visualizationZoneFrame->layout(),
230 // Widgets different from graphs are not visited (no action)
250 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
231 if (auto visualizationGraphWidget
232 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
233 visualizationGraphWidget->accept(visitor);
234 }
235 }
236 }
237
251
238 visitor->visitLeave(this);
252 visitor->visitLeave(this);
239 }
253 }
240 else {
254 else {
241 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
255 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
242 }
256 }
243 }
257 }
244
258
245 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
259 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
246 {
260 {
247 // A tab can always accomodate a variable
261 // A tab can always accomodate a variable
248 Q_UNUSED(variable);
262 Q_UNUSED(variable);
249 return true;
263 return true;
250 }
264 }
251
265
252 bool VisualizationZoneWidget::contains(const Variable &variable) const
266 bool VisualizationZoneWidget::contains(const Variable &variable) const
253 {
267 {
254 Q_UNUSED(variable);
268 Q_UNUSED(variable);
255 return false;
269 return false;
256 }
270 }
257
271
258 QString VisualizationZoneWidget::name() const
272 QString VisualizationZoneWidget::name() const
259 {
273 {
260 return ui->zoneNameLabel->text();
274 return ui->zoneNameLabel->text();
261 }
275 }
262
276
277 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
278 {
279 // Closes graphs in the zone
280 processGraphs(*ui->visualizationZoneFrame->layout(),
281 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
282
283 // Delete synchronization group from variable controller
284 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
285 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
286
287 QWidget::closeEvent(event);
288 }
289
263 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
290 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
264 {
291 {
265 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
292 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
266 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
293 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
267 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
294 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
268 }
295 }
296
297 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
298 {
299 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
300 Q_ARG(std::shared_ptr<Variable>, variable),
301 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
302 }
@@ -1,201 +1,216
1 #include "Visualization/operations/GenerateVariableMenuOperation.h"
1 #include "Visualization/operations/GenerateVariableMenuOperation.h"
2 #include "Visualization/operations/MenuBuilder.h"
2 #include "Visualization/operations/MenuBuilder.h"
3
3
4 #include "Visualization/VisualizationGraphWidget.h"
4 #include "Visualization/VisualizationGraphWidget.h"
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/Variable.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(QMenu *menu, std::shared_ptr<Variable> variable)
16 explicit GenerateVariableMenuOperationPrivate(
17 : m_Variable{variable}, m_PlotMenuBuilder{menu}, m_UnplotMenuBuilder{menu}
17 QMenu *menu, std::shared_ptr<Variable> variable,
18 std::set<IVisualizationWidget *> variableContainers)
19 : m_Variable{variable},
20 m_PlotMenuBuilder{menu},
21 m_UnplotMenuBuilder{menu},
22 m_VariableContainers{std::move(variableContainers)}
18 {
23 {
19 }
24 }
20
25
21 void visitRootEnter()
26 void visitRootEnter()
22 {
27 {
23 // Creates the root menu
28 // Creates the root menu
24 if (auto plotMenu
29 if (auto plotMenu
25 = m_PlotMenuBuilder.addMenu(QObject::tr("Plot"), QIcon{":/icones/plot.png"})) {
30 = m_PlotMenuBuilder.addMenu(QObject::tr("Plot"), QIcon{":/icones/plot.png"})) {
26 plotMenu->setEnabled(m_Variable && m_Variable->dataSeries() != nullptr);
31 plotMenu->setEnabled(m_Variable && m_Variable->dataSeries() != nullptr);
27 }
32 }
28
33
29 m_UnplotMenuBuilder.addMenu(QObject::tr("Unplot"), QIcon{":/icones/unplot.png"});
34 m_UnplotMenuBuilder.addMenu(QObject::tr("Unplot"), QIcon{":/icones/unplot.png"});
30 }
35 }
31
36
32 void visitRootLeave()
37 void visitRootLeave()
33 {
38 {
34 // Closes the root menu
39 // Closes the root menu
35 m_PlotMenuBuilder.closeMenu();
40 m_PlotMenuBuilder.closeMenu();
36 m_UnplotMenuBuilder.closeMenu();
41 m_UnplotMenuBuilder.closeMenu();
37 }
42 }
38
43
39 void visitNodeEnter(const IVisualizationWidget &container)
44 void visitNodeEnter(const IVisualizationWidget &container)
40 {
45 {
41 // Opens a new menu associated to the node
46 // Opens a new menu associated to the node
42 m_PlotMenuBuilder.addMenu(container.name());
47 m_PlotMenuBuilder.addMenu(container.name());
43 m_UnplotMenuBuilder.addMenu(container.name());
48 m_UnplotMenuBuilder.addMenu(container.name());
44 }
49 }
45
50
46 template <typename ActionFun>
51 template <typename ActionFun>
47 void visitNodeLeavePlot(const IVisualizationWidget &container, const QString &actionName,
52 void visitNodeLeavePlot(const IVisualizationWidget &container, const QString &actionName,
48 ActionFun actionFunction)
53 ActionFun actionFunction)
49 {
54 {
50 if (m_Variable && container.canDrop(*m_Variable)) {
55 if (isValidContainer(container)) {
51 m_PlotMenuBuilder.addSeparator();
56 m_PlotMenuBuilder.addSeparator();
52 m_PlotMenuBuilder.addAction(actionName, actionFunction);
57 m_PlotMenuBuilder.addAction(actionName, actionFunction);
53 }
58 }
54
59
55 // Closes the menu associated to the node
60 // Closes the menu associated to the node
56 m_PlotMenuBuilder.closeMenu();
61 m_PlotMenuBuilder.closeMenu();
57 }
62 }
58
63
59 void visitNodeLeaveUnplot()
64 void visitNodeLeaveUnplot()
60 {
65 {
61 // Closes the menu associated to the node
66 // Closes the menu associated to the node
62 m_UnplotMenuBuilder.closeMenu();
67 m_UnplotMenuBuilder.closeMenu();
63 }
68 }
64
69
65 template <typename ActionFun>
70 template <typename ActionFun>
66 void visitLeafPlot(const IVisualizationWidget &container, const QString &actionName,
71 void visitLeafPlot(const IVisualizationWidget &container, const QString &actionName,
67 ActionFun actionFunction)
72 ActionFun actionFunction)
68 {
73 {
69 if (m_Variable && container.canDrop(*m_Variable)) {
74 if (isValidContainer(container)) {
70 m_PlotMenuBuilder.addAction(actionName, actionFunction);
75 m_PlotMenuBuilder.addAction(actionName, actionFunction);
71 }
76 }
72 }
77 }
73
78
74 template <typename ActionFun>
79 template <typename ActionFun>
75 void visitLeafUnplot(const IVisualizationWidget &container, const QString &actionName,
80 void visitLeafUnplot(IVisualizationWidget *container, const QString &actionName,
76 ActionFun actionFunction)
81 ActionFun actionFunction)
77 {
82 {
78 if (m_Variable && container.contains(*m_Variable)) {
83 // If the container contains the variable, we generate 'unplot' action
84 if (m_VariableContainers.count(container) == 1) {
79 m_UnplotMenuBuilder.addAction(actionName, actionFunction);
85 m_UnplotMenuBuilder.addAction(actionName, actionFunction);
80 }
86 }
81 }
87 }
82
88
89 bool isValidContainer(const IVisualizationWidget &container) const noexcept
90 {
91 // A container is valid if it can contain the variable and if the variable is not already
92 // contained in another container
93 return m_Variable && m_VariableContainers.size() == 0 && container.canDrop(*m_Variable);
94 }
95
83 std::shared_ptr<Variable> m_Variable;
96 std::shared_ptr<Variable> m_Variable;
97 std::set<IVisualizationWidget *> m_VariableContainers;
84 MenuBuilder m_PlotMenuBuilder; ///< Builder for the 'Plot' menu
98 MenuBuilder m_PlotMenuBuilder; ///< Builder for the 'Plot' menu
85 MenuBuilder m_UnplotMenuBuilder; ///< Builder for the 'Unplot' menu
99 MenuBuilder m_UnplotMenuBuilder; ///< Builder for the 'Unplot' menu
86 };
100 };
87
101
88 GenerateVariableMenuOperation::GenerateVariableMenuOperation(QMenu *menu,
102 GenerateVariableMenuOperation::GenerateVariableMenuOperation(
89 std::shared_ptr<Variable> variable)
103 QMenu *menu, std::shared_ptr<Variable> variable,
90 : impl{spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>(menu, variable)}
104 std::set<IVisualizationWidget *> variableContainers)
105 : impl{spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>(
106 menu, variable, std::move(variableContainers))}
91 {
107 {
92 }
108 }
93
109
94 void GenerateVariableMenuOperation::visitEnter(VisualizationWidget *widget)
110 void GenerateVariableMenuOperation::visitEnter(VisualizationWidget *widget)
95 {
111 {
96 // VisualizationWidget is not intended to accommodate a variable
112 // VisualizationWidget is not intended to accommodate a variable
97 Q_UNUSED(widget)
113 Q_UNUSED(widget)
98
114
99 // 'Plot' and 'Unplot' menus
115 // 'Plot' and 'Unplot' menus
100 impl->visitRootEnter();
116 impl->visitRootEnter();
101 }
117 }
102
118
103 void GenerateVariableMenuOperation::visitLeave(VisualizationWidget *widget)
119 void GenerateVariableMenuOperation::visitLeave(VisualizationWidget *widget)
104 {
120 {
105 // VisualizationWidget is not intended to accommodate a variable
121 // VisualizationWidget is not intended to accommodate a variable
106 Q_UNUSED(widget)
122 Q_UNUSED(widget)
107
123
108 // 'Plot' and 'Unplot' menus
124 // 'Plot' and 'Unplot' menus
109 impl->visitRootLeave();
125 impl->visitRootLeave();
110 }
126 }
111
127
112 void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget *tabWidget)
128 void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget *tabWidget)
113 {
129 {
114 if (tabWidget) {
130 if (tabWidget) {
115 // 'Plot' and 'Unplot' menus
131 // 'Plot' and 'Unplot' menus
116 impl->visitNodeEnter(*tabWidget);
132 impl->visitNodeEnter(*tabWidget);
117 }
133 }
118 else {
134 else {
119 qCCritical(LOG_GenerateVariableMenuOperation(),
135 qCCritical(LOG_GenerateVariableMenuOperation(),
120 "Can't visit enter VisualizationTabWidget : the widget is null");
136 "Can't visit enter VisualizationTabWidget : the widget is null");
121 }
137 }
122 }
138 }
123
139
124 void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget)
140 void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget)
125 {
141 {
126 if (tabWidget) {
142 if (tabWidget) {
127 // 'Plot' menu
143 // 'Plot' menu
128 impl->visitNodeLeavePlot(*tabWidget, QObject::tr("Open in a new zone"),
144 impl->visitNodeLeavePlot(*tabWidget, QObject::tr("Open in a new zone"),
129 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, tabWidget ]() {
145 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, tabWidget ]() {
130 if (auto var = varW.lock()) {
146 if (auto var = varW.lock()) {
131 tabWidget->createZone(var);
147 tabWidget->createZone(var);
132 }
148 }
133 });
149 });
134
150
135 // 'Unplot' menu
151 // 'Unplot' menu
136 impl->visitNodeLeaveUnplot();
152 impl->visitNodeLeaveUnplot();
137 }
153 }
138 else {
154 else {
139 qCCritical(LOG_GenerateVariableMenuOperation(),
155 qCCritical(LOG_GenerateVariableMenuOperation(),
140 "Can't visit leave VisualizationTabWidget : the widget is null");
156 "Can't visit leave VisualizationTabWidget : the widget is null");
141 }
157 }
142 }
158 }
143
159
144 void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
160 void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
145 {
161 {
146 if (zoneWidget) {
162 if (zoneWidget) {
147 // 'Plot' and 'Unplot' menus
163 // 'Plot' and 'Unplot' menus
148 impl->visitNodeEnter(*zoneWidget);
164 impl->visitNodeEnter(*zoneWidget);
149 }
165 }
150 else {
166 else {
151 qCCritical(LOG_GenerateVariableMenuOperation(),
167 qCCritical(LOG_GenerateVariableMenuOperation(),
152 "Can't visit enter VisualizationZoneWidget : the widget is null");
168 "Can't visit enter VisualizationZoneWidget : the widget is null");
153 }
169 }
154 }
170 }
155
171
156 void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
172 void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
157 {
173 {
158 qCCritical(LOG_GenerateVariableMenuOperation(), "Open in a new graph DETECTED !!");
159 if (zoneWidget) {
174 if (zoneWidget) {
160 // 'Plot' menu
175 // 'Plot' menu
161 impl->visitNodeLeavePlot(
176 impl->visitNodeLeavePlot(
162 *zoneWidget, QObject::tr("Open in a new graph"),
177 *zoneWidget, QObject::tr("Open in a new graph"),
163 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, zoneWidget ]() {
178 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, zoneWidget ]() {
164 if (auto var = varW.lock()) {
179 if (auto var = varW.lock()) {
165 zoneWidget->createGraph(var);
180 zoneWidget->createGraph(var);
166 }
181 }
167 });
182 });
168
183
169 // 'Unplot' menu
184 // 'Unplot' menu
170 impl->visitNodeLeaveUnplot();
185 impl->visitNodeLeaveUnplot();
171 }
186 }
172 else {
187 else {
173 qCCritical(LOG_GenerateVariableMenuOperation(),
188 qCCritical(LOG_GenerateVariableMenuOperation(),
174 "Can't visit leave VisualizationZoneWidget : the widget is null");
189 "Can't visit leave VisualizationZoneWidget : the widget is null");
175 }
190 }
176 }
191 }
177
192
178 void GenerateVariableMenuOperation::visit(VisualizationGraphWidget *graphWidget)
193 void GenerateVariableMenuOperation::visit(VisualizationGraphWidget *graphWidget)
179 {
194 {
180 if (graphWidget) {
195 if (graphWidget) {
181 // 'Plot' menu
196 // 'Plot' menu
182 impl->visitLeafPlot(*graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()),
197 impl->visitLeafPlot(*graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()),
183 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, graphWidget ]() {
198 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, graphWidget ]() {
184 if (auto var = varW.lock()) {
199 if (auto var = varW.lock()) {
185 graphWidget->addVariable(var, graphWidget->graphRange());
200 graphWidget->addVariable(var, graphWidget->graphRange());
186 }
201 }
187 });
202 });
188
203
189 // 'Unplot' menu
204 // 'Unplot' menu
190 impl->visitLeafUnplot(*graphWidget, QObject::tr("Remove from %1").arg(graphWidget->name()),
205 impl->visitLeafUnplot(graphWidget, QObject::tr("Remove from %1").arg(graphWidget->name()),
191 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, graphWidget ]() {
206 [ varW = std::weak_ptr<Variable>{impl->m_Variable}, graphWidget ]() {
192 if (auto var = varW.lock()) {
207 if (auto var = varW.lock()) {
193 graphWidget->removeVariable(var);
208 graphWidget->removeVariable(var);
194 }
209 }
195 });
210 });
196 }
211 }
197 else {
212 else {
198 qCCritical(LOG_GenerateVariableMenuOperation(),
213 qCCritical(LOG_GenerateVariableMenuOperation(),
199 "Can't visit VisualizationGraphWidget : the widget is null");
214 "Can't visit VisualizationGraphWidget : the widget is null");
200 }
215 }
201 }
216 }
General Comments 0
You need to be logged in to leave comments. Login now