##// END OF EJS Templates
Handles desynchronisation when removing variable from a graph (1)...
Alexandre Leroux -
r737:e5aabf0f62fb
parent child
Show More
@@ -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,97
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:
62 void enterEvent(QEvent *event) override;
65 void enterEvent(QEvent *event) override;
63 void leaveEvent(QEvent *event) override;
66 void leaveEvent(QEvent *event) override;
64
67
65 QCustomPlot &plot() noexcept;
68 QCustomPlot &plot() noexcept;
66
69
67 private:
70 private:
68 Ui::VisualizationGraphWidget *ui;
71 Ui::VisualizationGraphWidget *ui;
69
72
70 class VisualizationGraphWidgetPrivate;
73 class VisualizationGraphWidgetPrivate;
71 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
74 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
72
75
73 private slots:
76 private slots:
74 /// Slot called when right clicking on the graph (displays a menu)
77 /// Slot called when right clicking on the graph (displays a menu)
75 void onGraphMenuRequested(const QPoint &pos) noexcept;
78 void onGraphMenuRequested(const QPoint &pos) noexcept;
76
79
77 /// Rescale the X axe to range parameter
80 /// Rescale the X axe to range parameter
78 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
81 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
79
82
80 /// Slot called when a mouse move was made
83 /// Slot called when a mouse move was made
81 void onMouseMove(QMouseEvent *event) noexcept;
84 void onMouseMove(QMouseEvent *event) noexcept;
82 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
85 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
83 void onMouseWheel(QWheelEvent *event) noexcept;
86 void onMouseWheel(QWheelEvent *event) noexcept;
84 /// Slot called when a mouse press was made, to activate the calibration of a graph
87 /// Slot called when a mouse press was made, to activate the calibration of a graph
85 void onMousePress(QMouseEvent *event) noexcept;
88 void onMousePress(QMouseEvent *event) noexcept;
86 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
89 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
87 void onMouseRelease(QMouseEvent *event) noexcept;
90 void onMouseRelease(QMouseEvent *event) noexcept;
88
91
89 void onDataCacheVariableUpdated();
92 void onDataCacheVariableUpdated();
90
93
91 void onUpdateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
94 void onUpdateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
92 };
95 };
93
96
94 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
97 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,55 +1,57
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 private:
45 private:
46 Ui::VisualizationZoneWidget *ui;
46 Ui::VisualizationZoneWidget *ui;
47
47
48 class VisualizationZoneWidgetPrivate;
48 class VisualizationZoneWidgetPrivate;
49 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
49 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
50
50
51 private slots:
51 private slots:
52 void onVariableAdded(std::shared_ptr<Variable> variable);
52 void onVariableAdded(std::shared_ptr<Variable> variable);
53 /// Slot called when a variable is about to be removed from a graph contained in the zone
54 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
53 };
55 };
54
56
55 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
57 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -1,344 +1,346
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
221 void VisualizationGraphWidget::enterEvent(QEvent *event)
223 void VisualizationGraphWidget::enterEvent(QEvent *event)
222 {
224 {
223 Q_UNUSED(event);
225 Q_UNUSED(event);
224 impl->m_RenderingDelegate->showGraphOverlay(true);
226 impl->m_RenderingDelegate->showGraphOverlay(true);
225 }
227 }
226
228
227 void VisualizationGraphWidget::leaveEvent(QEvent *event)
229 void VisualizationGraphWidget::leaveEvent(QEvent *event)
228 {
230 {
229 Q_UNUSED(event);
231 Q_UNUSED(event);
230 impl->m_RenderingDelegate->showGraphOverlay(false);
232 impl->m_RenderingDelegate->showGraphOverlay(false);
231 }
233 }
232
234
233 QCustomPlot &VisualizationGraphWidget::plot() noexcept
235 QCustomPlot &VisualizationGraphWidget::plot() noexcept
234 {
236 {
235 return *ui->widget;
237 return *ui->widget;
236 }
238 }
237
239
238 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
240 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
239 {
241 {
240 QMenu graphMenu{};
242 QMenu graphMenu{};
241
243
242 // Iterates on variables (unique keys)
244 // Iterates on variables (unique keys)
243 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
245 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
244 end = impl->m_VariableToPlotMultiMap.cend();
246 end = impl->m_VariableToPlotMultiMap.cend();
245 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
247 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
246 // 'Remove variable' action
248 // 'Remove variable' action
247 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
249 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
248 [ this, var = it->first ]() { removeVariable(var); });
250 [ this, var = it->first ]() { removeVariable(var); });
249 }
251 }
250
252
251 if (!graphMenu.isEmpty()) {
253 if (!graphMenu.isEmpty()) {
252 graphMenu.exec(QCursor::pos());
254 graphMenu.exec(QCursor::pos());
253 }
255 }
254 }
256 }
255
257
256 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
258 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
257 {
259 {
258 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
260 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
259 << QThread::currentThread()->objectName() << "DoAcqui"
261 << QThread::currentThread()->objectName() << "DoAcqui"
260 << impl->m_DoAcquisition;
262 << impl->m_DoAcquisition;
261
263
262 auto graphRange = SqpRange{t1.lower, t1.upper};
264 auto graphRange = SqpRange{t1.lower, t1.upper};
263 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
265 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
264
266
265 if (impl->m_DoAcquisition) {
267 if (impl->m_DoAcquisition) {
266 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
268 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
267
269
268 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
270 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
269 end = impl->m_VariableToPlotMultiMap.end();
271 end = impl->m_VariableToPlotMultiMap.end();
270 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
272 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
271 variableUnderGraphVector.push_back(it->first);
273 variableUnderGraphVector.push_back(it->first);
272 }
274 }
273 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
275 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
274 !impl->m_IsCalibration);
276 !impl->m_IsCalibration);
275
277
276 if (!impl->m_IsCalibration) {
278 if (!impl->m_IsCalibration) {
277 qCDebug(LOG_VisualizationGraphWidget())
279 qCDebug(LOG_VisualizationGraphWidget())
278 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
280 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
279 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
281 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
280 emit synchronize(graphRange, oldGraphRange);
282 emit synchronize(graphRange, oldGraphRange);
281 }
283 }
282 }
284 }
283 }
285 }
284
286
285 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
287 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
286 {
288 {
287 // Handles plot rendering when mouse is moving
289 // Handles plot rendering when mouse is moving
288 impl->m_RenderingDelegate->onMouseMove(event);
290 impl->m_RenderingDelegate->onMouseMove(event);
289 }
291 }
290
292
291 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
293 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
292 {
294 {
293 auto zoomOrientations = QFlags<Qt::Orientation>{};
295 auto zoomOrientations = QFlags<Qt::Orientation>{};
294
296
295 // Lambda that enables a zoom orientation if the key modifier related to this orientation
297 // Lambda that enables a zoom orientation if the key modifier related to this orientation
296 // has
298 // has
297 // been pressed
299 // been pressed
298 auto enableOrientation
300 auto enableOrientation
299 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
301 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
300 auto orientationEnabled = event->modifiers().testFlag(modifier);
302 auto orientationEnabled = event->modifiers().testFlag(modifier);
301 zoomOrientations.setFlag(orientation, orientationEnabled);
303 zoomOrientations.setFlag(orientation, orientationEnabled);
302 };
304 };
303 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
305 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
304 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
306 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
305
307
306 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
308 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
307 }
309 }
308
310
309 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
311 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
310 {
312 {
311 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
313 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
312 }
314 }
313
315
314 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
316 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
315 {
317 {
316 impl->m_IsCalibration = false;
318 impl->m_IsCalibration = false;
317 }
319 }
318
320
319 void VisualizationGraphWidget::onDataCacheVariableUpdated()
321 void VisualizationGraphWidget::onDataCacheVariableUpdated()
320 {
322 {
321 auto graphRange = ui->widget->xAxis->range();
323 auto graphRange = ui->widget->xAxis->range();
322 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
324 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
323
325
324 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
326 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
325 auto variable = variableEntry.first;
327 auto variable = variableEntry.first;
326 qCDebug(LOG_VisualizationGraphWidget())
328 qCDebug(LOG_VisualizationGraphWidget())
327 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
329 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
328 qCDebug(LOG_VisualizationGraphWidget())
330 qCDebug(LOG_VisualizationGraphWidget())
329 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
331 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
330 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
332 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
331 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
333 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
332 variable->range());
334 variable->range());
333 }
335 }
334 }
336 }
335 }
337 }
336
338
337 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
339 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
338 const SqpRange &range)
340 const SqpRange &range)
339 {
341 {
340 auto it = impl->m_VariableToPlotMultiMap.find(variable);
342 auto it = impl->m_VariableToPlotMultiMap.find(variable);
341 if (it != impl->m_VariableToPlotMultiMap.end()) {
343 if (it != impl->m_VariableToPlotMultiMap.end()) {
342 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
344 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
343 }
345 }
344 }
346 }
@@ -1,268 +1,277
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 } // namespace
37 } // namespace
38
38
39 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
39 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
40
40
41 explicit VisualizationZoneWidgetPrivate()
41 explicit VisualizationZoneWidgetPrivate()
42 : m_SynchronisationGroupId{QUuid::createUuid()},
42 : m_SynchronisationGroupId{QUuid::createUuid()},
43 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
43 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
44 {
44 {
45 }
45 }
46 QUuid m_SynchronisationGroupId;
46 QUuid m_SynchronisationGroupId;
47 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
47 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
48 };
48 };
49
49
50 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
50 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
51 : QWidget{parent},
51 : QWidget{parent},
52 ui{new Ui::VisualizationZoneWidget},
52 ui{new Ui::VisualizationZoneWidget},
53 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
53 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
54 {
54 {
55 ui->setupUi(this);
55 ui->setupUi(this);
56
56
57 ui->zoneNameLabel->setText(name);
57 ui->zoneNameLabel->setText(name);
58
58
59 // 'Close' options : widget is deleted when closed
59 // 'Close' options : widget is deleted when closed
60 setAttribute(Qt::WA_DeleteOnClose);
60 setAttribute(Qt::WA_DeleteOnClose);
61 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
61 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
62 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
62 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
63
63
64 // Synchronisation id
64 // Synchronisation id
65 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
65 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
66 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
66 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
67 }
67 }
68
68
69 VisualizationZoneWidget::~VisualizationZoneWidget()
69 VisualizationZoneWidget::~VisualizationZoneWidget()
70 {
70 {
71 delete ui;
71 delete ui;
72 }
72 }
73
73
74 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
74 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
75 {
75 {
76 // Synchronize new graph with others in the zone
76 // Synchronize new graph with others in the zone
77 impl->m_Synchronizer->addGraph(*graphWidget);
77 impl->m_Synchronizer->addGraph(*graphWidget);
78
78
79 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
79 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
80 }
80 }
81
81
82 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
82 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
83 {
83 {
84 auto graphWidget = new VisualizationGraphWidget{
84 auto graphWidget = new VisualizationGraphWidget{
85 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
85 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
86
86
87
87
88 // Set graph properties
88 // Set graph properties
89 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
89 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
90 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
90 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
91
91
92
92
93 // Lambda to synchronize zone widget
93 // Lambda to synchronize zone widget
94 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
94 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
95 const SqpRange &oldGraphRange) {
95 const SqpRange &oldGraphRange) {
96
96
97 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
97 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
98 auto frameLayout = ui->visualizationZoneFrame->layout();
98 auto frameLayout = ui->visualizationZoneFrame->layout();
99 for (auto i = 0; i < frameLayout->count(); ++i) {
99 for (auto i = 0; i < frameLayout->count(); ++i) {
100 auto graphChild
100 auto graphChild
101 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
101 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
102 if (graphChild && (graphChild != graphWidget)) {
102 if (graphChild && (graphChild != graphWidget)) {
103
103
104 auto graphChildRange = graphChild->graphRange();
104 auto graphChildRange = graphChild->graphRange();
105 switch (zoomType) {
105 switch (zoomType) {
106 case AcquisitionZoomType::ZoomIn: {
106 case AcquisitionZoomType::ZoomIn: {
107 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
107 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
108 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
108 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
109 graphChildRange.m_TStart += deltaLeft;
109 graphChildRange.m_TStart += deltaLeft;
110 graphChildRange.m_TEnd -= deltaRight;
110 graphChildRange.m_TEnd -= deltaRight;
111 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
111 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
112 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
112 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
113 << deltaLeft;
113 << deltaLeft;
114 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
114 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
115 << deltaRight;
115 << deltaRight;
116 qCDebug(LOG_VisualizationZoneWidget())
116 qCDebug(LOG_VisualizationZoneWidget())
117 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
117 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
118
118
119 break;
119 break;
120 }
120 }
121
121
122 case AcquisitionZoomType::ZoomOut: {
122 case AcquisitionZoomType::ZoomOut: {
123 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
123 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
124 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
124 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
125 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
125 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
126 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
126 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
127 << deltaLeft;
127 << deltaLeft;
128 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
128 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
129 << deltaRight;
129 << deltaRight;
130 qCDebug(LOG_VisualizationZoneWidget())
130 qCDebug(LOG_VisualizationZoneWidget())
131 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
131 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
132 graphChildRange.m_TStart -= deltaLeft;
132 graphChildRange.m_TStart -= deltaLeft;
133 graphChildRange.m_TEnd += deltaRight;
133 graphChildRange.m_TEnd += deltaRight;
134 break;
134 break;
135 }
135 }
136 case AcquisitionZoomType::PanRight: {
136 case AcquisitionZoomType::PanRight: {
137 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
137 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
138 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
138 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
139 graphChildRange.m_TStart += deltaRight;
139 graphChildRange.m_TStart += deltaRight;
140 graphChildRange.m_TEnd += deltaRight;
140 graphChildRange.m_TEnd += deltaRight;
141 qCDebug(LOG_VisualizationZoneWidget())
141 qCDebug(LOG_VisualizationZoneWidget())
142 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
142 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
143 break;
143 break;
144 }
144 }
145 case AcquisitionZoomType::PanLeft: {
145 case AcquisitionZoomType::PanLeft: {
146 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
146 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
147 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
147 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
148 graphChildRange.m_TStart -= deltaLeft;
148 graphChildRange.m_TStart -= deltaLeft;
149 graphChildRange.m_TEnd -= deltaLeft;
149 graphChildRange.m_TEnd -= deltaLeft;
150 break;
150 break;
151 }
151 }
152 case AcquisitionZoomType::Unknown: {
152 case AcquisitionZoomType::Unknown: {
153 qCDebug(LOG_VisualizationZoneWidget())
153 qCDebug(LOG_VisualizationZoneWidget())
154 << tr("Impossible to synchronize: zoom type unknown");
154 << tr("Impossible to synchronize: zoom type unknown");
155 break;
155 break;
156 }
156 }
157 default:
157 default:
158 qCCritical(LOG_VisualizationZoneWidget())
158 qCCritical(LOG_VisualizationZoneWidget())
159 << tr("Impossible to synchronize: zoom type not take into account");
159 << tr("Impossible to synchronize: zoom type not take into account");
160 // No action
160 // No action
161 break;
161 break;
162 }
162 }
163 graphChild->enableAcquisition(false);
163 graphChild->enableAcquisition(false);
164 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
164 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
165 << graphChild->graphRange();
165 << graphChild->graphRange();
166 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
166 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
167 << graphChildRange;
167 << graphChildRange;
168 qCDebug(LOG_VisualizationZoneWidget())
168 qCDebug(LOG_VisualizationZoneWidget())
169 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
169 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
170 graphChild->setGraphRange(graphChildRange);
170 graphChild->setGraphRange(graphChildRange);
171 graphChild->enableAcquisition(true);
171 graphChild->enableAcquisition(true);
172 }
172 }
173 }
173 }
174 };
174 };
175
175
176 // connection for synchronization
176 // connection for synchronization
177 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
177 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
178 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
178 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
179 &VisualizationZoneWidget::onVariableAdded);
179 &VisualizationZoneWidget::onVariableAdded);
180 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
181 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
180
182
181 auto range = SqpRange{};
183 auto range = SqpRange{};
182
184
183 // Apply visitor to graph children
185 // Apply visitor to graph children
184 auto layout = ui->visualizationZoneFrame->layout();
186 auto layout = ui->visualizationZoneFrame->layout();
185 if (layout->count() > 0) {
187 if (layout->count() > 0) {
186 // Case of a new graph in a existant zone
188 // Case of a new graph in a existant zone
187 if (auto visualizationGraphWidget
189 if (auto visualizationGraphWidget
188 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
190 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
189 range = visualizationGraphWidget->graphRange();
191 range = visualizationGraphWidget->graphRange();
190 }
192 }
191 }
193 }
192 else {
194 else {
193 // Case of a new graph as the first of the zone
195 // Case of a new graph as the first of the zone
194 range = variable->range();
196 range = variable->range();
195 }
197 }
196
198
197 this->addGraph(graphWidget);
199 this->addGraph(graphWidget);
198
200
199 graphWidget->addVariable(variable, range);
201 graphWidget->addVariable(variable, range);
200
202
201 // get y using variable range
203 // get y using variable range
202 if (auto dataSeries = variable->dataSeries()) {
204 if (auto dataSeries = variable->dataSeries()) {
203 dataSeries->lockRead();
205 dataSeries->lockRead();
204 auto valuesBounds
206 auto valuesBounds
205 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
207 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
206 auto end = dataSeries->cend();
208 auto end = dataSeries->cend();
207 if (valuesBounds.first != end && valuesBounds.second != end) {
209 if (valuesBounds.first != end && valuesBounds.second != end) {
208 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
210 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
209
211
210 auto minValue = rangeValue(valuesBounds.first->minValue());
212 auto minValue = rangeValue(valuesBounds.first->minValue());
211 auto maxValue = rangeValue(valuesBounds.second->maxValue());
213 auto maxValue = rangeValue(valuesBounds.second->maxValue());
212
214
213 graphWidget->setYRange(SqpRange{minValue, maxValue});
215 graphWidget->setYRange(SqpRange{minValue, maxValue});
214 }
216 }
215 dataSeries->unlock();
217 dataSeries->unlock();
216 }
218 }
217
219
218 return graphWidget;
220 return graphWidget;
219 }
221 }
220
222
221 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
223 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
222 {
224 {
223 if (visitor) {
225 if (visitor) {
224 visitor->visitEnter(this);
226 visitor->visitEnter(this);
225
227
226 // Apply visitor to graph children
228 // Apply visitor to graph children
227 auto layout = ui->visualizationZoneFrame->layout();
229 auto layout = ui->visualizationZoneFrame->layout();
228 for (auto i = 0; i < layout->count(); ++i) {
230 for (auto i = 0; i < layout->count(); ++i) {
229 if (auto item = layout->itemAt(i)) {
231 if (auto item = layout->itemAt(i)) {
230 // Widgets different from graphs are not visited (no action)
232 // Widgets different from graphs are not visited (no action)
231 if (auto visualizationGraphWidget
233 if (auto visualizationGraphWidget
232 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
234 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
233 visualizationGraphWidget->accept(visitor);
235 visualizationGraphWidget->accept(visitor);
234 }
236 }
235 }
237 }
236 }
238 }
237
239
238 visitor->visitLeave(this);
240 visitor->visitLeave(this);
239 }
241 }
240 else {
242 else {
241 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
243 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
242 }
244 }
243 }
245 }
244
246
245 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
247 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
246 {
248 {
247 // A tab can always accomodate a variable
249 // A tab can always accomodate a variable
248 Q_UNUSED(variable);
250 Q_UNUSED(variable);
249 return true;
251 return true;
250 }
252 }
251
253
252 bool VisualizationZoneWidget::contains(const Variable &variable) const
254 bool VisualizationZoneWidget::contains(const Variable &variable) const
253 {
255 {
254 Q_UNUSED(variable);
256 Q_UNUSED(variable);
255 return false;
257 return false;
256 }
258 }
257
259
258 QString VisualizationZoneWidget::name() const
260 QString VisualizationZoneWidget::name() const
259 {
261 {
260 return ui->zoneNameLabel->text();
262 return ui->zoneNameLabel->text();
261 }
263 }
262
264
263 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
265 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
264 {
266 {
265 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
267 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
266 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
268 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
267 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
269 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
268 }
270 }
271
272 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
273 {
274 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
275 Q_ARG(std::shared_ptr<Variable>, variable),
276 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
277 }
General Comments 0
You need to be logged in to leave comments. Login now