##// END OF EJS Templates
add Skeleton for displaying data which are already in cache
perrinel -
r538:ba71c0cdaccd
parent child
Show More
@@ -1,117 +1,120
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
11
12 #include <Common/spimpl.h>
12 #include <Common/spimpl.h>
13
13
14 class IDataProvider;
14 class IDataProvider;
15 class QItemSelectionModel;
15 class QItemSelectionModel;
16 class TimeController;
16 class TimeController;
17 class Variable;
17 class Variable;
18 class VariableModel;
18 class VariableModel;
19
19
20 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
20 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
21
21
22
22
23 /**
23 /**
24 * Possible types of zoom operation
24 * Possible types of zoom operation
25 */
25 */
26 enum class AcquisitionZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
26 enum class AcquisitionZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
27
27
28
28
29 /**
29 /**
30 * @brief The VariableController class aims to handle the variables in SciQlop.
30 * @brief The VariableController class aims to handle the variables in SciQlop.
31 */
31 */
32 class SCIQLOP_CORE_EXPORT VariableController : public QObject {
32 class SCIQLOP_CORE_EXPORT VariableController : public QObject {
33 Q_OBJECT
33 Q_OBJECT
34 public:
34 public:
35 explicit VariableController(QObject *parent = 0);
35 explicit VariableController(QObject *parent = 0);
36 virtual ~VariableController();
36 virtual ~VariableController();
37
37
38 VariableModel *variableModel() noexcept;
38 VariableModel *variableModel() noexcept;
39 QItemSelectionModel *variableSelectionModel() noexcept;
39 QItemSelectionModel *variableSelectionModel() noexcept;
40
40
41 void setTimeController(TimeController *timeController) noexcept;
41 void setTimeController(TimeController *timeController) noexcept;
42
42
43 /**
43 /**
44 * Deletes from the controller the variable passed in parameter.
44 * Deletes from the controller the variable passed in parameter.
45 *
45 *
46 * Delete a variable includes:
46 * Delete a variable includes:
47 * - the deletion of the various references to the variable in SciQlop
47 * - the deletion of the various references to the variable in SciQlop
48 * - the deletion of the model variable
48 * - the deletion of the model variable
49 * - the deletion of the provider associated with the variable
49 * - the deletion of the provider associated with the variable
50 * - removing the cache associated with the variable
50 * - removing the cache associated with the variable
51 *
51 *
52 * @param variable the variable to delete from the controller.
52 * @param variable the variable to delete from the controller.
53 */
53 */
54 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
54 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
55
55
56 /**
56 /**
57 * Deletes from the controller the variables passed in parameter.
57 * Deletes from the controller the variables passed in parameter.
58 * @param variables the variables to delete from the controller.
58 * @param variables the variables to delete from the controller.
59 * @sa deleteVariable()
59 * @sa deleteVariable()
60 */
60 */
61 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
61 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
62
62
63 /**
63 /**
64 * @brief abort the variable retrieve data progression
64 * @brief abort the variable retrieve data progression
65 */
65 */
66 void abortProgress(std::shared_ptr<Variable> variable);
66 void abortProgress(std::shared_ptr<Variable> variable);
67
67
68 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
68 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
69 signals:
69 signals:
70 /// Signal emitted when a variable is about to be deleted from the controller
70 /// Signal emitted when a variable is about to be deleted from the controller
71 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
71 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
72
72
73 /// Signal emitted when a data acquisition is requested on a range for a variable
73 /// Signal emitted when a data acquisition is requested on a range for a variable
74 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
74 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
75
75
76 /// Signal emitted when a sub range of the cacheRange of the variable can be displayed
77 void updateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
78
76 public slots:
79 public slots:
77 /// Request the data loading of the variable whithin range
80 /// Request the data loading of the variable whithin range
78 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
81 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
79 const SqpRange &oldRange, bool synchronise);
82 const SqpRange &oldRange, bool synchronise);
80 /**
83 /**
81 * Creates a new variable and adds it to the model
84 * Creates a new variable and adds it to the model
82 * @param name the name of the new variable
85 * @param name the name of the new variable
83 * @param metadata the metadata of the new variable
86 * @param metadata the metadata of the new variable
84 * @param provider the data provider for the new variable
87 * @param provider the data provider for the new variable
85 */
88 */
86 void createVariable(const QString &name, const QVariantHash &metadata,
89 void createVariable(const QString &name, const QVariantHash &metadata,
87 std::shared_ptr<IDataProvider> provider) noexcept;
90 std::shared_ptr<IDataProvider> provider) noexcept;
88
91
89 /// Update the temporal parameters of every selected variable to dateTime
92 /// Update the temporal parameters of every selected variable to dateTime
90 void onDateTimeOnSelection(const SqpRange &dateTime);
93 void onDateTimeOnSelection(const SqpRange &dateTime);
91
94
92
95
93 void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
96 void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
94 const SqpRange &cacheRangeRequested,
97 const SqpRange &cacheRangeRequested,
95 QVector<AcquisitionDataPacket> dataAcquired);
98 QVector<AcquisitionDataPacket> dataAcquired);
96
99
97 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
100 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
98
101
99 /// Cancel the current request for the variable
102 /// Cancel the current request for the variable
100 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
103 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
101
104
102 /// synchronization group methods
105 /// synchronization group methods
103 void onAddSynchronizationGroupId(QUuid synchronizationGroupId);
106 void onAddSynchronizationGroupId(QUuid synchronizationGroupId);
104 void onRemoveSynchronizationGroupId(QUuid synchronizationGroupId);
107 void onRemoveSynchronizationGroupId(QUuid synchronizationGroupId);
105 void onAddSynchronized(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
108 void onAddSynchronized(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
106
109
107 void initialize();
110 void initialize();
108 void finalize();
111 void finalize();
109
112
110 private:
113 private:
111 void waitForFinish();
114 void waitForFinish();
112
115
113 class VariableControllerPrivate;
116 class VariableControllerPrivate;
114 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
117 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
115 };
118 };
116
119
117 #endif // SCIQLOP_VARIABLECONTROLLER_H
120 #endif // SCIQLOP_VARIABLECONTROLLER_H
@@ -1,541 +1,550
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 #include <Variable/VariableAcquisitionWorker.h>
3 #include <Variable/VariableCacheController.h>
3 #include <Variable/VariableCacheController.h>
4 #include <Variable/VariableCacheStrategy.h>
4 #include <Variable/VariableCacheStrategy.h>
5 #include <Variable/VariableController.h>
5 #include <Variable/VariableController.h>
6 #include <Variable/VariableModel.h>
6 #include <Variable/VariableModel.h>
7 #include <Variable/VariableSynchronizationGroup.h>
7 #include <Variable/VariableSynchronizationGroup.h>
8
8
9 #include <Data/DataProviderParameters.h>
9 #include <Data/DataProviderParameters.h>
10 #include <Data/IDataProvider.h>
10 #include <Data/IDataProvider.h>
11 #include <Data/IDataSeries.h>
11 #include <Data/IDataSeries.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 <set>
19 #include <set>
20 #include <unordered_map>
20 #include <unordered_map>
21
21
22 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
22 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
23
23
24 namespace {
24 namespace {
25
25
26 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
26 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
27 const SqpRange &oldGraphRange)
27 const SqpRange &oldGraphRange)
28 {
28 {
29 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
29 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
30
30
31 auto varRangeRequested = varRange;
31 auto varRangeRequested = varRange;
32 switch (zoomType) {
32 switch (zoomType) {
33 case AcquisitionZoomType::ZoomIn: {
33 case AcquisitionZoomType::ZoomIn: {
34 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
34 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
35 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
35 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
36 varRangeRequested.m_TStart += deltaLeft;
36 varRangeRequested.m_TStart += deltaLeft;
37 varRangeRequested.m_TEnd -= deltaRight;
37 varRangeRequested.m_TEnd -= deltaRight;
38 break;
38 break;
39 }
39 }
40
40
41 case AcquisitionZoomType::ZoomOut: {
41 case AcquisitionZoomType::ZoomOut: {
42 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
42 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
43 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
43 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
44 varRangeRequested.m_TStart -= deltaLeft;
44 varRangeRequested.m_TStart -= deltaLeft;
45 varRangeRequested.m_TEnd += deltaRight;
45 varRangeRequested.m_TEnd += deltaRight;
46 break;
46 break;
47 }
47 }
48 case AcquisitionZoomType::PanRight: {
48 case AcquisitionZoomType::PanRight: {
49 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
49 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
50 varRangeRequested.m_TStart += deltaRight;
50 varRangeRequested.m_TStart += deltaRight;
51 varRangeRequested.m_TEnd += deltaRight;
51 varRangeRequested.m_TEnd += deltaRight;
52 break;
52 break;
53 }
53 }
54 case AcquisitionZoomType::PanLeft: {
54 case AcquisitionZoomType::PanLeft: {
55 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
55 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
56 varRangeRequested.m_TStart -= deltaLeft;
56 varRangeRequested.m_TStart -= deltaLeft;
57 varRangeRequested.m_TEnd -= deltaLeft;
57 varRangeRequested.m_TEnd -= deltaLeft;
58 break;
58 break;
59 }
59 }
60 case AcquisitionZoomType::Unknown: {
60 case AcquisitionZoomType::Unknown: {
61 qCCritical(LOG_VariableController())
61 qCCritical(LOG_VariableController())
62 << VariableController::tr("Impossible to synchronize: zoom type unknown");
62 << VariableController::tr("Impossible to synchronize: zoom type unknown");
63 break;
63 break;
64 }
64 }
65 default:
65 default:
66 qCCritical(LOG_VariableController()) << VariableController::tr(
66 qCCritical(LOG_VariableController()) << VariableController::tr(
67 "Impossible to synchronize: zoom type not take into account");
67 "Impossible to synchronize: zoom type not take into account");
68 // No action
68 // No action
69 break;
69 break;
70 }
70 }
71
71
72 return varRangeRequested;
72 return varRangeRequested;
73 }
73 }
74 }
74 }
75
75
76 struct VariableController::VariableControllerPrivate {
76 struct VariableController::VariableControllerPrivate {
77 explicit VariableControllerPrivate(VariableController *parent)
77 explicit VariableControllerPrivate(VariableController *parent)
78 : m_WorkingMutex{},
78 : m_WorkingMutex{},
79 m_VariableModel{new VariableModel{parent}},
79 m_VariableModel{new VariableModel{parent}},
80 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
80 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
81 m_VariableCacheController{std::make_unique<VariableCacheController>()},
81 m_VariableCacheController{std::make_unique<VariableCacheController>()},
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 {
85 {
85
86
86 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 }
89 }
89
90
90
91
91 virtual ~VariableControllerPrivate()
92 virtual ~VariableControllerPrivate()
92 {
93 {
93 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
94 m_VariableAcquisitionWorkerThread.quit();
95 m_VariableAcquisitionWorkerThread.quit();
95 m_VariableAcquisitionWorkerThread.wait();
96 m_VariableAcquisitionWorkerThread.wait();
96 }
97 }
97
98
98
99
99 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested);
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested);
100
101
101 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
102 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
102 const SqpRange &dateTime);
103 const SqpRange &dateTime);
103
104
104 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
105 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
105 std::shared_ptr<IDataSeries>
106 std::shared_ptr<IDataSeries>
106 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
107 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
107
108
108 void registerProvider(std::shared_ptr<IDataProvider> provider);
109 void registerProvider(std::shared_ptr<IDataProvider> provider);
109
110
110 QMutex m_WorkingMutex;
111 QMutex m_WorkingMutex;
111 /// Variable model. The VariableController has the ownership
112 /// Variable model. The VariableController has the ownership
112 VariableModel *m_VariableModel;
113 VariableModel *m_VariableModel;
113 QItemSelectionModel *m_VariableSelectionModel;
114 QItemSelectionModel *m_VariableSelectionModel;
114
115
115
116
116 TimeController *m_TimeController{nullptr};
117 TimeController *m_TimeController{nullptr};
117 std::unique_ptr<VariableCacheController> m_VariableCacheController;
118 std::unique_ptr<VariableCacheController> m_VariableCacheController;
118 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
119 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
119 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
120 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
120 QThread m_VariableAcquisitionWorkerThread;
121 QThread m_VariableAcquisitionWorkerThread;
121
122
122 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
123 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
123 m_VariableToProviderMap;
124 m_VariableToProviderMap;
124 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
125 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
125 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
126 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
126 m_GroupIdToVariableSynchronizationGroupMap;
127 m_GroupIdToVariableSynchronizationGroupMap;
127 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
128 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
128 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
129 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
130
131
132 VariableController *q;
129 };
133 };
130
134
131
135
132 VariableController::VariableController(QObject *parent)
136 VariableController::VariableController(QObject *parent)
133 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
137 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
134 {
138 {
135 qCDebug(LOG_VariableController()) << tr("VariableController construction")
139 qCDebug(LOG_VariableController()) << tr("VariableController construction")
136 << QThread::currentThread();
140 << QThread::currentThread();
137
141
138 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
142 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
139 &VariableController::onAbortProgressRequested);
143 &VariableController::onAbortProgressRequested);
140
144
141 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
145 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
142 &VariableController::onDataProvided);
146 &VariableController::onDataProvided);
143 connect(impl->m_VariableAcquisitionWorker.get(),
147 connect(impl->m_VariableAcquisitionWorker.get(),
144 &VariableAcquisitionWorker::variableRequestInProgress, this,
148 &VariableAcquisitionWorker::variableRequestInProgress, this,
145 &VariableController::onVariableRetrieveDataInProgress);
149 &VariableController::onVariableRetrieveDataInProgress);
146
150
147 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
151 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
148 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
152 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
149 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
153 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
150 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
154 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
151
155
152
156
153 impl->m_VariableAcquisitionWorkerThread.start();
157 impl->m_VariableAcquisitionWorkerThread.start();
154 }
158 }
155
159
156 VariableController::~VariableController()
160 VariableController::~VariableController()
157 {
161 {
158 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
162 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
159 << QThread::currentThread();
163 << QThread::currentThread();
160 this->waitForFinish();
164 this->waitForFinish();
161 }
165 }
162
166
163 VariableModel *VariableController::variableModel() noexcept
167 VariableModel *VariableController::variableModel() noexcept
164 {
168 {
165 return impl->m_VariableModel;
169 return impl->m_VariableModel;
166 }
170 }
167
171
168 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
172 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
169 {
173 {
170 return impl->m_VariableSelectionModel;
174 return impl->m_VariableSelectionModel;
171 }
175 }
172
176
173 void VariableController::setTimeController(TimeController *timeController) noexcept
177 void VariableController::setTimeController(TimeController *timeController) noexcept
174 {
178 {
175 impl->m_TimeController = timeController;
179 impl->m_TimeController = timeController;
176 }
180 }
177
181
178 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
182 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
179 {
183 {
180 if (!variable) {
184 if (!variable) {
181 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
185 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
182 return;
186 return;
183 }
187 }
184
188
185 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
189 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
186 // make some treatments before the deletion
190 // make some treatments before the deletion
187 emit variableAboutToBeDeleted(variable);
191 emit variableAboutToBeDeleted(variable);
188
192
189 // Deletes identifier
193 // Deletes identifier
190 impl->m_VariableToIdentifierMap.erase(variable);
194 impl->m_VariableToIdentifierMap.erase(variable);
191
195
192 // Deletes provider
196 // Deletes provider
193 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
197 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
194 qCDebug(LOG_VariableController())
198 qCDebug(LOG_VariableController())
195 << tr("Number of providers deleted for variable %1: %2")
199 << tr("Number of providers deleted for variable %1: %2")
196 .arg(variable->name(), QString::number(nbProvidersDeleted));
200 .arg(variable->name(), QString::number(nbProvidersDeleted));
197
201
198 // Clears cache
202 // Clears cache
199 impl->m_VariableCacheController->clear(variable);
203 impl->m_VariableCacheController->clear(variable);
200
204
201 // Deletes from model
205 // Deletes from model
202 impl->m_VariableModel->deleteVariable(variable);
206 impl->m_VariableModel->deleteVariable(variable);
203 }
207 }
204
208
205 void VariableController::deleteVariables(
209 void VariableController::deleteVariables(
206 const QVector<std::shared_ptr<Variable> > &variables) noexcept
210 const QVector<std::shared_ptr<Variable> > &variables) noexcept
207 {
211 {
208 for (auto variable : qAsConst(variables)) {
212 for (auto variable : qAsConst(variables)) {
209 deleteVariable(variable);
213 deleteVariable(variable);
210 }
214 }
211 }
215 }
212
216
213 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
217 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
214 {
218 {
215 }
219 }
216
220
217 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
221 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
218 std::shared_ptr<IDataProvider> provider) noexcept
222 std::shared_ptr<IDataProvider> provider) noexcept
219 {
223 {
220
224
221 if (!impl->m_TimeController) {
225 if (!impl->m_TimeController) {
222 qCCritical(LOG_VariableController())
226 qCCritical(LOG_VariableController())
223 << tr("Impossible to create variable: The time controller is null");
227 << tr("Impossible to create variable: The time controller is null");
224 return;
228 return;
225 }
229 }
226
230
227 auto range = impl->m_TimeController->dateTime();
231 auto range = impl->m_TimeController->dateTime();
228
232
229 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
233 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
230 auto identifier = QUuid::createUuid();
234 auto identifier = QUuid::createUuid();
231
235
232 // store the provider
236 // store the provider
233 impl->registerProvider(provider);
237 impl->registerProvider(provider);
234
238
235 // Associate the provider
239 // Associate the provider
236 impl->m_VariableToProviderMap[newVariable] = provider;
240 impl->m_VariableToProviderMap[newVariable] = provider;
237 impl->m_VariableToIdentifierMap[newVariable] = identifier;
241 impl->m_VariableToIdentifierMap[newVariable] = identifier;
238
242
239
243
240 impl->processRequest(newVariable, range);
244 impl->processRequest(newVariable, range);
241 }
245 }
242 }
246 }
243
247
244 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
248 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
245 {
249 {
246 // TODO check synchronisation
250 // TODO check synchronisation
247 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
251 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
248 << QThread::currentThread()->objectName();
252 << QThread::currentThread()->objectName();
249 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
253 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
250
254
251 for (const auto &selectedRow : qAsConst(selectedRows)) {
255 for (const auto &selectedRow : qAsConst(selectedRows)) {
252 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
256 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
253 selectedVariable->setRange(dateTime);
257 selectedVariable->setRange(dateTime);
254 impl->processRequest(selectedVariable, dateTime);
258 impl->processRequest(selectedVariable, dateTime);
255
259
256 // notify that rescale operation has to be done
260 // notify that rescale operation has to be done
257 emit rangeChanged(selectedVariable, dateTime);
261 emit rangeChanged(selectedVariable, dateTime);
258 }
262 }
259 }
263 }
260 }
264 }
261
265
262 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
266 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
263 const SqpRange &cacheRangeRequested,
267 const SqpRange &cacheRangeRequested,
264 QVector<AcquisitionDataPacket> dataAcquired)
268 QVector<AcquisitionDataPacket> dataAcquired)
265 {
269 {
266 if (auto var = impl->findVariable(vIdentifier)) {
270 if (auto var = impl->findVariable(vIdentifier)) {
267 var->setRange(rangeRequested);
271 var->setRange(rangeRequested);
268 var->setCacheRange(cacheRangeRequested);
272 var->setCacheRange(cacheRangeRequested);
269 qCDebug(LOG_VariableController()) << tr("1: onDataProvided") << rangeRequested;
273 qCDebug(LOG_VariableController()) << tr("1: onDataProvided") << rangeRequested;
270 qCDebug(LOG_VariableController()) << tr("2: onDataProvided") << cacheRangeRequested;
274 qCDebug(LOG_VariableController()) << tr("2: onDataProvided") << cacheRangeRequested;
271
275
272 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
276 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
273 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
277 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
274 << retrievedDataSeries->range();
278 << retrievedDataSeries->range();
275 var->mergeDataSeries(retrievedDataSeries);
279 var->mergeDataSeries(retrievedDataSeries);
276 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
280 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
277 emit var->updated();
281 emit var->updated();
278 }
282 }
279 else {
283 else {
280 qCCritical(LOG_VariableController()) << tr("Impossible to provide data to a null variable");
284 qCCritical(LOG_VariableController()) << tr("Impossible to provide data to a null variable");
281 }
285 }
282 }
286 }
283
287
284 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
288 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
285 {
289 {
286 if (auto var = impl->findVariable(identifier)) {
290 if (auto var = impl->findVariable(identifier)) {
287 impl->m_VariableModel->setDataProgress(var, progress);
291 impl->m_VariableModel->setDataProgress(var, progress);
288 }
292 }
289 else {
293 else {
290 qCCritical(LOG_VariableController())
294 qCCritical(LOG_VariableController())
291 << tr("Impossible to notify progression of a null variable");
295 << tr("Impossible to notify progression of a null variable");
292 }
296 }
293 }
297 }
294
298
295 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
299 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
296 {
300 {
297 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
301 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
298 << QThread::currentThread()->objectName();
302 << QThread::currentThread()->objectName();
299
303
300 auto it = impl->m_VariableToIdentifierMap.find(variable);
304 auto it = impl->m_VariableToIdentifierMap.find(variable);
301 if (it != impl->m_VariableToIdentifierMap.cend()) {
305 if (it != impl->m_VariableToIdentifierMap.cend()) {
302 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
306 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
303 }
307 }
304 else {
308 else {
305 qCWarning(LOG_VariableController())
309 qCWarning(LOG_VariableController())
306 << tr("Aborting progression of inexistant variable detected !!!")
310 << tr("Aborting progression of inexistant variable detected !!!")
307 << QThread::currentThread()->objectName();
311 << QThread::currentThread()->objectName();
308 }
312 }
309 }
313 }
310
314
311 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
315 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
312 {
316 {
313 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
317 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
314 << QThread::currentThread()->objectName()
318 << QThread::currentThread()->objectName()
315 << synchronizationGroupId;
319 << synchronizationGroupId;
316 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
320 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
317 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
321 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
318 std::make_pair(synchronizationGroupId, vSynchroGroup));
322 std::make_pair(synchronizationGroupId, vSynchroGroup));
319 }
323 }
320
324
321 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
325 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
322 {
326 {
323 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
327 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
324 }
328 }
325
329
326 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
330 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
327 QUuid synchronizationGroupId)
331 QUuid synchronizationGroupId)
328
332
329 {
333 {
330 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
334 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
331 << synchronizationGroupId;
335 << synchronizationGroupId;
332 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
336 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
333 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
337 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
334 auto groupIdToVSGIt
338 auto groupIdToVSGIt
335 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
339 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
336 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
340 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
337 impl->m_VariableIdGroupIdMap.insert(
341 impl->m_VariableIdGroupIdMap.insert(
338 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
342 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
339 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
343 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
340 }
344 }
341 else {
345 else {
342 qCCritical(LOG_VariableController())
346 qCCritical(LOG_VariableController())
343 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
347 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
344 << variable->name();
348 << variable->name();
345 }
349 }
346 }
350 }
347 else {
351 else {
348 qCCritical(LOG_VariableController())
352 qCCritical(LOG_VariableController())
349 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
353 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
350 }
354 }
351 }
355 }
352
356
353
357
354 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
358 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
355 const SqpRange &range, const SqpRange &oldRange,
359 const SqpRange &range, const SqpRange &oldRange,
356 bool synchronise)
360 bool synchronise)
357 {
361 {
358 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
362 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
359
363
360 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
364 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
361 << QThread::currentThread()->objectName();
365 << QThread::currentThread()->objectName();
362 // we want to load data of the variable for the dateTime.
366 // we want to load data of the variable for the dateTime.
363 // First we check if the cache contains some of them.
367 // First we check if the cache contains some of them.
364 // For the other, we ask the provider to give them.
368 // For the other, we ask the provider to give them.
365
369
366 for (const auto &var : variables) {
370 for (const auto &var : variables) {
367 qCDebug(LOG_VariableController()) << "processRequest for" << var->name();
371 qCDebug(LOG_VariableController()) << "processRequest for" << var->name();
368 impl->processRequest(var, range);
372 impl->processRequest(var, range);
369 }
373 }
370
374
371 if (synchronise) {
375 if (synchronise) {
372 // Get the group ids
376 // Get the group ids
373 qCDebug(LOG_VariableController())
377 qCDebug(LOG_VariableController())
374 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
378 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
375 auto groupIds = std::set<QUuid>();
379 auto groupIds = std::set<QUuid>();
376 for (const auto &var : variables) {
380 for (const auto &var : variables) {
377 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
381 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
378 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
382 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
379 auto vId = varToVarIdIt->second;
383 auto vId = varToVarIdIt->second;
380 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
384 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
381 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
385 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
382 auto gId = varIdToGroupIdIt->second;
386 auto gId = varIdToGroupIdIt->second;
383 if (groupIds.find(gId) == groupIds.cend()) {
387 if (groupIds.find(gId) == groupIds.cend()) {
384 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
388 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
385 groupIds.insert(gId);
389 groupIds.insert(gId);
386 }
390 }
387 }
391 }
388 }
392 }
389 }
393 }
390
394
391 // We assume here all group ids exist
395 // We assume here all group ids exist
392 for (const auto &gId : groupIds) {
396 for (const auto &gId : groupIds) {
393 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
397 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
394 auto vSyncIds = vSynchronizationGroup->getIds();
398 auto vSyncIds = vSynchronizationGroup->getIds();
395 qCDebug(LOG_VariableController()) << "Var in synchro group ";
399 qCDebug(LOG_VariableController()) << "Var in synchro group ";
396 for (auto vId : vSyncIds) {
400 for (auto vId : vSyncIds) {
397 auto var = impl->findVariable(vId);
401 auto var = impl->findVariable(vId);
398
402
399 // Don't process already processed var
403 // Don't process already processed var
400 if (!variables.contains(var)) {
404 if (!variables.contains(var)) {
401 if (var != nullptr) {
405 if (var != nullptr) {
402 qCDebug(LOG_VariableController()) << "processRequest synchro for"
406 qCDebug(LOG_VariableController()) << "processRequest synchro for"
403 << var->name();
407 << var->name();
404 auto vSyncRangeRequested
408 auto vSyncRangeRequested
405 = computeSynchroRangeRequested(var->range(), range, oldRange);
409 = computeSynchroRangeRequested(var->range(), range, oldRange);
406 impl->processRequest(var, vSyncRangeRequested);
410 impl->processRequest(var, vSyncRangeRequested);
407 }
411 }
408 else {
412 else {
409 qCCritical(LOG_VariableController())
413 qCCritical(LOG_VariableController())
410
414
411 << tr("Impossible to synchronize a null variable");
415 << tr("Impossible to synchronize a null variable");
412 }
416 }
413 }
417 }
414 }
418 }
415 }
419 }
416 }
420 }
417 }
421 }
418
422
419
423
420 void VariableController::initialize()
424 void VariableController::initialize()
421 {
425 {
422 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
426 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
423 impl->m_WorkingMutex.lock();
427 impl->m_WorkingMutex.lock();
424 qCDebug(LOG_VariableController()) << tr("VariableController init END");
428 qCDebug(LOG_VariableController()) << tr("VariableController init END");
425 }
429 }
426
430
427 void VariableController::finalize()
431 void VariableController::finalize()
428 {
432 {
429 impl->m_WorkingMutex.unlock();
433 impl->m_WorkingMutex.unlock();
430 }
434 }
431
435
432 void VariableController::waitForFinish()
436 void VariableController::waitForFinish()
433 {
437 {
434 QMutexLocker locker{&impl->m_WorkingMutex};
438 QMutexLocker locker{&impl->m_WorkingMutex};
435 }
439 }
436
440
437 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
441 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
438 {
442 {
439 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
443 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
440 auto zoomType = AcquisitionZoomType::Unknown;
444 auto zoomType = AcquisitionZoomType::Unknown;
441 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
445 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
442 zoomType = AcquisitionZoomType::ZoomOut;
446 zoomType = AcquisitionZoomType::ZoomOut;
443 }
447 }
444 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
448 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
445 zoomType = AcquisitionZoomType::PanRight;
449 zoomType = AcquisitionZoomType::PanRight;
446 }
450 }
447 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
451 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
448 zoomType = AcquisitionZoomType::PanLeft;
452 zoomType = AcquisitionZoomType::PanLeft;
449 }
453 }
450 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
454 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
451 zoomType = AcquisitionZoomType::ZoomIn;
455 zoomType = AcquisitionZoomType::ZoomIn;
452 }
456 }
453 else {
457 else {
454 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
458 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
455 }
459 }
456 return zoomType;
460 return zoomType;
457 }
461 }
458
462
459 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
463 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
460 const SqpRange &rangeRequested)
464 const SqpRange &rangeRequested)
461 {
465 {
462
466
463 auto varRangesRequested
467 auto varRangesRequested
464 = m_VariableCacheStrategy->computeCacheRange(var->range(), rangeRequested);
468 = m_VariableCacheStrategy->computeCacheRange(var->range(), rangeRequested);
465 auto notInCacheRangeList = var->provideNotInCacheRangeList(varRangesRequested.second);
469 auto notInCacheRangeList = var->provideNotInCacheRangeList(varRangesRequested.second);
470 auto inCacheRangeList = var->provideInCacheRangeList(varRangesRequested.second);
466
471
467 if (!notInCacheRangeList.empty()) {
472 if (!notInCacheRangeList.empty()) {
468 auto identifier = m_VariableToIdentifierMap.at(var);
473 auto identifier = m_VariableToIdentifierMap.at(var);
469 auto varProvider = m_VariableToProviderMap.at(var);
474 auto varProvider = m_VariableToProviderMap.at(var);
470 if (varProvider != nullptr) {
475 if (varProvider != nullptr) {
471 m_VariableAcquisitionWorker->pushVariableRequest(
476 m_VariableAcquisitionWorker->pushVariableRequest(
472 identifier, varRangesRequested.first, varRangesRequested.second,
477 identifier, varRangesRequested.first, varRangesRequested.second,
473 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
478 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
474 varProvider);
479 varProvider);
475 }
480 }
476 else {
481 else {
477 qCCritical(LOG_VariableController())
482 qCCritical(LOG_VariableController())
478 << "Impossible to provide data with a null provider";
483 << "Impossible to provide data with a null provider";
479 }
484 }
485
486 if (!inCacheRangeList.empty()) {
487 emit q->updateVarDisplaying(var, inCacheRangeList.first());
488 }
480 }
489 }
481 else {
490 else {
482 var->setRange(rangeRequested);
491 var->setRange(rangeRequested);
483 var->setCacheRange(varRangesRequested.second);
492 var->setCacheRange(varRangesRequested.second);
484 var->setDataSeries(var->dataSeries()->subDataSeries(varRangesRequested.second));
493 var->setDataSeries(var->dataSeries()->subDataSeries(varRangesRequested.second));
485 emit var->updated();
494 emit var->updated();
486 }
495 }
487 }
496 }
488
497
489 std::shared_ptr<Variable>
498 std::shared_ptr<Variable>
490 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
499 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
491 {
500 {
492 std::shared_ptr<Variable> var;
501 std::shared_ptr<Variable> var;
493 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
502 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
494
503
495 auto end = m_VariableToIdentifierMap.cend();
504 auto end = m_VariableToIdentifierMap.cend();
496 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
505 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
497 if (it != end) {
506 if (it != end) {
498 var = it->first;
507 var = it->first;
499 }
508 }
500 else {
509 else {
501 qCCritical(LOG_VariableController())
510 qCCritical(LOG_VariableController())
502 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
511 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
503 }
512 }
504
513
505 return var;
514 return var;
506 }
515 }
507
516
508 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
517 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
509 const QVector<AcquisitionDataPacket> acqDataPacketVector)
518 const QVector<AcquisitionDataPacket> acqDataPacketVector)
510 {
519 {
511 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
520 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
512 << acqDataPacketVector.size();
521 << acqDataPacketVector.size();
513 std::shared_ptr<IDataSeries> dataSeries;
522 std::shared_ptr<IDataSeries> dataSeries;
514 if (!acqDataPacketVector.isEmpty()) {
523 if (!acqDataPacketVector.isEmpty()) {
515 dataSeries = acqDataPacketVector[0].m_DateSeries;
524 dataSeries = acqDataPacketVector[0].m_DateSeries;
516 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
525 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
517 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
526 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
518 }
527 }
519 }
528 }
520 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
529 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
521 << acqDataPacketVector.size();
530 << acqDataPacketVector.size();
522 return dataSeries;
531 return dataSeries;
523 }
532 }
524
533
525 void VariableController::VariableControllerPrivate::registerProvider(
534 void VariableController::VariableControllerPrivate::registerProvider(
526 std::shared_ptr<IDataProvider> provider)
535 std::shared_ptr<IDataProvider> provider)
527 {
536 {
528 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
537 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
529 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
538 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
530 << provider->objectName();
539 << provider->objectName();
531 m_ProviderSet.insert(provider);
540 m_ProviderSet.insert(provider);
532 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
541 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
533 &VariableAcquisitionWorker::onVariableDataAcquired);
542 &VariableAcquisitionWorker::onVariableDataAcquired);
534 connect(provider.get(), &IDataProvider::dataProvidedProgress,
543 connect(provider.get(), &IDataProvider::dataProvidedProgress,
535 m_VariableAcquisitionWorker.get(),
544 m_VariableAcquisitionWorker.get(),
536 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
545 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
537 }
546 }
538 else {
547 else {
539 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
548 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
540 }
549 }
541 }
550 }
@@ -1,84 +1,86
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 SqpRange;
16 class SqpRange;
17 class Variable;
17 class Variable;
18
18
19 namespace Ui {
19 namespace Ui {
20 class VisualizationGraphWidget;
20 class VisualizationGraphWidget;
21 } // namespace Ui
21 } // namespace Ui
22
22
23 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
23 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
24 Q_OBJECT
24 Q_OBJECT
25
25
26 public:
26 public:
27 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
27 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
28 virtual ~VisualizationGraphWidget();
28 virtual ~VisualizationGraphWidget();
29
29
30 /// If acquisition isn't enable, requestDataLoading signal cannot be emit
30 /// If acquisition isn't enable, requestDataLoading signal cannot be emit
31 void enableAcquisition(bool enable);
31 void enableAcquisition(bool enable);
32
32
33 void addVariable(std::shared_ptr<Variable> variable, SqpRange range);
33 void addVariable(std::shared_ptr<Variable> variable, SqpRange range);
34
34
35 /// Removes a variable from the graph
35 /// Removes a variable from the graph
36 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
36 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
37
37
38 void setRange(std::shared_ptr<Variable> variable, const SqpRange &range);
38 void setRange(std::shared_ptr<Variable> variable, const SqpRange &range);
39 void setYRange(const SqpRange &range);
39 void setYRange(const SqpRange &range);
40 SqpRange graphRange() const noexcept;
40 SqpRange graphRange() const noexcept;
41 void setGraphRange(const SqpRange &range);
41 void setGraphRange(const SqpRange &range);
42
42
43 // IVisualizationWidget interface
43 // IVisualizationWidget interface
44 void accept(IVisualizationWidgetVisitor *visitor) override;
44 void accept(IVisualizationWidgetVisitor *visitor) override;
45 bool canDrop(const Variable &variable) const override;
45 bool canDrop(const Variable &variable) const override;
46 bool contains(const Variable &variable) const override;
46 bool contains(const Variable &variable) const override;
47 QString name() const override;
47 QString name() const override;
48
48
49
49
50 signals:
50 signals:
51 void synchronize(const SqpRange &range, const SqpRange &oldRange);
51 void synchronize(const SqpRange &range, const SqpRange &oldRange);
52 void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range,
52 void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range,
53 const SqpRange &oldRange, bool synchronise);
53 const SqpRange &oldRange, bool synchronise);
54
54
55
55
56 void variableAdded(std::shared_ptr<Variable> var);
56 void variableAdded(std::shared_ptr<Variable> var);
57
57
58
58
59 private:
59 private:
60 Ui::VisualizationGraphWidget *ui;
60 Ui::VisualizationGraphWidget *ui;
61
61
62 class VisualizationGraphWidgetPrivate;
62 class VisualizationGraphWidgetPrivate;
63 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
63 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
64
64
65 private slots:
65 private slots:
66 /// Slot called when right clicking on the graph (displays a menu)
66 /// Slot called when right clicking on the graph (displays a menu)
67 void onGraphMenuRequested(const QPoint &pos) noexcept;
67 void onGraphMenuRequested(const QPoint &pos) noexcept;
68
68
69 /// Rescale the X axe to range parameter
69 /// Rescale the X axe to range parameter
70 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
70 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
71
71
72 /// Slot called when a mouse move was made
72 /// Slot called when a mouse move was made
73 void onMouseMove(QMouseEvent *event) noexcept;
73 void onMouseMove(QMouseEvent *event) noexcept;
74 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
74 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
75 void onMouseWheel(QWheelEvent *event) noexcept;
75 void onMouseWheel(QWheelEvent *event) noexcept;
76 /// Slot called when a mouse press was made, to activate the calibration of a graph
76 /// Slot called when a mouse press was made, to activate the calibration of a graph
77 void onMousePress(QMouseEvent *event) noexcept;
77 void onMousePress(QMouseEvent *event) noexcept;
78 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
78 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
79 void onMouseRelease(QMouseEvent *event) noexcept;
79 void onMouseRelease(QMouseEvent *event) noexcept;
80
80
81 void onDataCacheVariableUpdated();
81 void onDataCacheVariableUpdated();
82
83 void onUpdateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
82 };
84 };
83
85
84 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
86 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,210 +1,211
1 #include "Visualization/VisualizationGraphHelper.h"
1 #include "Visualization/VisualizationGraphHelper.h"
2 #include "Visualization/qcustomplot.h"
2 #include "Visualization/qcustomplot.h"
3
3
4 #include <Data/ScalarSeries.h>
4 #include <Data/ScalarSeries.h>
5
5
6 #include <Variable/Variable.h>
6 #include <Variable/Variable.h>
7
7
8 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
8 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
9
9
10 namespace {
10 namespace {
11
11
12 class SqpDataContainer : public QCPGraphDataContainer {
12 class SqpDataContainer : public QCPGraphDataContainer {
13 public:
13 public:
14 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
14 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
15 };
15 };
16
16
17
17
18 /// Format for datetimes on a axis
18 /// Format for datetimes on a axis
19 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
19 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
20
20
21 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
21 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
22 /// non-time data
22 /// non-time data
23 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
23 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
24 {
24 {
25 if (isTimeAxis) {
25 if (isTimeAxis) {
26 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
26 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
27 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
27 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
28 dateTicker->setDateTimeSpec(Qt::UTC);
28 dateTicker->setDateTimeSpec(Qt::UTC);
29
29
30 return dateTicker;
30 return dateTicker;
31 }
31 }
32 else {
32 else {
33 // default ticker
33 // default ticker
34 return QSharedPointer<QCPAxisTicker>::create();
34 return QSharedPointer<QCPAxisTicker>::create();
35 }
35 }
36 }
36 }
37
37
38 void updateScalarData(QCPAbstractPlottable *component, std::shared_ptr<ScalarSeries> scalarSeries,
38 void updateScalarData(QCPAbstractPlottable *component, std::shared_ptr<ScalarSeries> scalarSeries,
39 const SqpRange &dateTime)
39 const SqpRange &dateTime)
40 {
40 {
41 qCDebug(LOG_VisualizationGraphHelper()) << "TORM: updateScalarData"
41 qCDebug(LOG_VisualizationGraphHelper()) << "TORM: updateScalarData"
42 << QThread::currentThread()->objectName();
42 << QThread::currentThread()->objectName();
43 if (auto qcpGraph = dynamic_cast<QCPGraph *>(component)) {
43 if (auto qcpGraph = dynamic_cast<QCPGraph *>(component)) {
44 scalarSeries->lockRead();
44 scalarSeries->lockRead();
45 {
45 {
46 const auto &xData = scalarSeries->xAxisData()->cdata();
46 // auto bounds = scalarSeries->subData(rang
47 const auto &valuesData = scalarSeries->valuesData()->cdata();
47 // const auto &xData = scalarSeries->xAxisData()->cdata();
48 // const auto &valuesData = scalarSeries->valuesData()->cdata();
48
49
49 auto xDataBegin = xData.cbegin();
50 // auto xDataBegin = xData.cbegin();
50 auto xDataEnd = xData.cend();
51 // auto xDataEnd = xData.cend();
51
52
52 qCInfo(LOG_VisualizationGraphHelper()) << "TODEBUG: Current points in cache"
53 // qCInfo(LOG_VisualizationGraphHelper()) << "TODEBUG: Current points in cache"
53 << xData.count();
54 // << xData.count();
54
55
55 auto sqpDataContainer = QSharedPointer<SqpDataContainer>::create();
56 // auto sqpDataContainer = QSharedPointer<SqpDataContainer>::create();
56 qcpGraph->setData(sqpDataContainer);
57 // qcpGraph->setData(sqpDataContainer);
57
58
58 auto lowerIt = std::lower_bound(xDataBegin, xDataEnd, dateTime.m_TStart);
59 // auto lowerIt = std::lower_bound(xDataBegin, xDataEnd, dateTime.m_TStart);
59 auto upperIt = std::upper_bound(xDataBegin, xDataEnd, dateTime.m_TEnd);
60 // auto upperIt = std::upper_bound(xDataBegin, xDataEnd, dateTime.m_TEnd);
60 auto distance = std::distance(xDataBegin, lowerIt);
61 // auto distance = std::distance(xDataBegin, lowerIt);
61
62
62 auto valuesDataIt = valuesData.cbegin() + distance;
63 // auto valuesDataIt = valuesData.cbegin() + distance;
63 for (auto xAxisDataIt = lowerIt; xAxisDataIt != upperIt;
64 // for (auto xAxisDataIt = lowerIt; xAxisDataIt != upperIt;
64 ++xAxisDataIt, ++valuesDataIt) {
65 // ++xAxisDataIt, ++valuesDataIt) {
65 sqpDataContainer->appendGraphData(QCPGraphData(*xAxisDataIt, *valuesDataIt));
66 // sqpDataContainer->appendGraphData(QCPGraphData(*xAxisDataIt, *valuesDataIt));
66 }
67 // }
67
68
68 qCInfo(LOG_VisualizationGraphHelper()) << "TODEBUG: Current points displayed"
69 qCInfo(LOG_VisualizationGraphHelper()) << "TODEBUG: Current points displayed"
69 << sqpDataContainer->size();
70 << sqpDataContainer->size();
70 }
71 }
71 scalarSeries->unlock();
72 scalarSeries->unlock();
72
73
73
74
74 // Display all data
75 // Display all data
75 component->parentPlot()->replot();
76 component->parentPlot()->replot();
76 }
77 }
77 else {
78 else {
78 /// @todo DEBUG
79 /// @todo DEBUG
79 }
80 }
80 }
81 }
81
82
82 QCPAbstractPlottable *createScalarSeriesComponentV2(std::shared_ptr<ScalarSeries> scalarSeries,
83 QCPAbstractPlottable *createScalarSeriesComponentV2(std::shared_ptr<ScalarSeries> scalarSeries,
83 QCustomPlot &plot)
84 QCustomPlot &plot)
84 {
85 {
85 auto component = plot.addGraph();
86 auto component = plot.addGraph();
86
87
87 if (component) {
88 if (component) {
88 // Axes properties
89 // Axes properties
89 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
90 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
90 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
91 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
91
92
92 auto setAxisProperties = [](auto axis, const auto &unit) {
93 auto setAxisProperties = [](auto axis, const auto &unit) {
93 // label (unit name)
94 // label (unit name)
94 axis->setLabel(unit.m_Name);
95 axis->setLabel(unit.m_Name);
95
96
96 // ticker (depending on the type of unit)
97 // ticker (depending on the type of unit)
97 axis->setTicker(axisTicker(unit.m_TimeUnit));
98 axis->setTicker(axisTicker(unit.m_TimeUnit));
98 };
99 };
99 setAxisProperties(plot.xAxis, scalarSeries->xAxisUnit());
100 setAxisProperties(plot.xAxis, scalarSeries->xAxisUnit());
100 setAxisProperties(plot.yAxis, scalarSeries->valuesUnit());
101 setAxisProperties(plot.yAxis, scalarSeries->valuesUnit());
101 }
102 }
102 return component;
103 return component;
103 }
104 }
104
105
105 QCPAbstractPlottable *createScalarSeriesComponent(std::shared_ptr<ScalarSeries> scalarSeries,
106 QCPAbstractPlottable *createScalarSeriesComponent(std::shared_ptr<ScalarSeries> scalarSeries,
106 QCustomPlot &plot, const SqpRange &dateTime)
107 QCustomPlot &plot, const SqpRange &dateTime)
107 {
108 {
108 auto component = plot.addGraph();
109 auto component = plot.addGraph();
109
110
110 if (component) {
111 if (component) {
111 // // Graph data
112 // // Graph data
112 component->setData(scalarSeries->xAxisData()->data(), scalarSeries->valuesData()->data(),
113 component->setData(scalarSeries->xAxisData()->data(), scalarSeries->valuesData()->data(),
113 true);
114 true);
114
115
115 updateScalarData(component, scalarSeries, dateTime);
116 updateScalarData(component, scalarSeries, dateTime);
116
117
117 // Axes properties
118 // Axes properties
118 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
119 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
119 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
120 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
120
121
121 auto setAxisProperties = [](auto axis, const auto &unit) {
122 auto setAxisProperties = [](auto axis, const auto &unit) {
122 // label (unit name)
123 // label (unit name)
123 axis->setLabel(unit.m_Name);
124 axis->setLabel(unit.m_Name);
124
125
125 // ticker (depending on the type of unit)
126 // ticker (depending on the type of unit)
126 axis->setTicker(axisTicker(unit.m_TimeUnit));
127 axis->setTicker(axisTicker(unit.m_TimeUnit));
127 };
128 };
128 setAxisProperties(plot.xAxis, scalarSeries->xAxisUnit());
129 setAxisProperties(plot.xAxis, scalarSeries->xAxisUnit());
129 setAxisProperties(plot.yAxis, scalarSeries->valuesUnit());
130 setAxisProperties(plot.yAxis, scalarSeries->valuesUnit());
130
131
131 // Display all data
132 // Display all data
132 component->rescaleAxes();
133 component->rescaleAxes();
133 plot.replot();
134 plot.replot();
134 }
135 }
135 else {
136 else {
136 qCDebug(LOG_VisualizationGraphHelper())
137 qCDebug(LOG_VisualizationGraphHelper())
137 << QObject::tr("Can't create graph for the scalar series");
138 << QObject::tr("Can't create graph for the scalar series");
138 }
139 }
139
140
140 return component;
141 return component;
141 }
142 }
142
143
143 } // namespace
144 } // namespace
144
145
145 QVector<QCPAbstractPlottable *>
146 QVector<QCPAbstractPlottable *>
146 VisualizationGraphHelper::createV2(std::shared_ptr<Variable> variable, QCustomPlot &plot) noexcept
147 VisualizationGraphHelper::createV2(std::shared_ptr<Variable> variable, QCustomPlot &plot) noexcept
147 {
148 {
148 auto result = QVector<QCPAbstractPlottable *>{};
149 auto result = QVector<QCPAbstractPlottable *>{};
149
150
150 if (variable) {
151 if (variable) {
151 // Gets the data series of the variable to call the creation of the right components
152 // Gets the data series of the variable to call the creation of the right components
152 // according to its type
153 // according to its type
153 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries())) {
154 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries())) {
154 result.append(createScalarSeriesComponentV2(scalarSeries, plot));
155 result.append(createScalarSeriesComponentV2(scalarSeries, plot));
155 }
156 }
156 else {
157 else {
157 qCDebug(LOG_VisualizationGraphHelper())
158 qCDebug(LOG_VisualizationGraphHelper())
158 << QObject::tr("Can't create graph plottables : unmanaged data series type");
159 << QObject::tr("Can't create graph plottables : unmanaged data series type");
159 }
160 }
160 }
161 }
161 else {
162 else {
162 qCDebug(LOG_VisualizationGraphHelper())
163 qCDebug(LOG_VisualizationGraphHelper())
163 << QObject::tr("Can't create graph plottables : the variable is null");
164 << QObject::tr("Can't create graph plottables : the variable is null");
164 }
165 }
165
166
166 return result;
167 return result;
167 }
168 }
168
169
169 QVector<QCPAbstractPlottable *> VisualizationGraphHelper::create(std::shared_ptr<Variable> variable,
170 QVector<QCPAbstractPlottable *> VisualizationGraphHelper::create(std::shared_ptr<Variable> variable,
170 QCustomPlot &plot) noexcept
171 QCustomPlot &plot) noexcept
171 {
172 {
172 auto result = QVector<QCPAbstractPlottable *>{};
173 auto result = QVector<QCPAbstractPlottable *>{};
173
174
174 if (variable) {
175 if (variable) {
175 // Gets the data series of the variable to call the creation of the right components
176 // Gets the data series of the variable to call the creation of the right components
176 // according to its type
177 // according to its type
177 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries())) {
178 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries())) {
178 result.append(createScalarSeriesComponent(scalarSeries, plot, variable->range()));
179 result.append(createScalarSeriesComponent(scalarSeries, plot, variable->range()));
179 }
180 }
180 else {
181 else {
181 qCDebug(LOG_VisualizationGraphHelper())
182 qCDebug(LOG_VisualizationGraphHelper())
182 << QObject::tr("Can't create graph plottables : unmanaged data series type");
183 << QObject::tr("Can't create graph plottables : unmanaged data series type");
183 }
184 }
184 }
185 }
185 else {
186 else {
186 qCDebug(LOG_VisualizationGraphHelper())
187 qCDebug(LOG_VisualizationGraphHelper())
187 << QObject::tr("Can't create graph plottables : the variable is null");
188 << QObject::tr("Can't create graph plottables : the variable is null");
188 }
189 }
189
190
190 return result;
191 return result;
191 }
192 }
192
193
193 void VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *> plotableVect,
194 void VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *> plotableVect,
194 std::shared_ptr<IDataSeries> dataSeries,
195 std::shared_ptr<IDataSeries> dataSeries,
195 const SqpRange &dateTime)
196 const SqpRange &dateTime)
196 {
197 {
197 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
198 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
198 if (plotableVect.size() == 1) {
199 if (plotableVect.size() == 1) {
199 updateScalarData(plotableVect.at(0), scalarSeries, dateTime);
200 updateScalarData(plotableVect.at(0), scalarSeries, dateTime);
200 }
201 }
201 else {
202 else {
202 qCCritical(LOG_VisualizationGraphHelper()) << QObject::tr(
203 qCCritical(LOG_VisualizationGraphHelper()) << QObject::tr(
203 "Can't update Data of a scalarSeries because there is not only one component "
204 "Can't update Data of a scalarSeries because there is not only one component "
204 "associated");
205 "associated");
205 }
206 }
206 }
207 }
207 else {
208 else {
208 /// @todo DEBUG
209 /// @todo DEBUG
209 }
210 }
210 }
211 }
@@ -1,307 +1,320
1 #include "Visualization/VisualizationGraphWidget.h"
1 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationGraphHelper.h"
3 #include "Visualization/VisualizationGraphHelper.h"
4 #include "Visualization/VisualizationGraphRenderingDelegate.h"
4 #include "Visualization/VisualizationGraphRenderingDelegate.h"
5 #include "ui_VisualizationGraphWidget.h"
5 #include "ui_VisualizationGraphWidget.h"
6
6
7 #include <Data/ArrayData.h>
7 #include <Data/ArrayData.h>
8 #include <Data/IDataSeries.h>
8 #include <Data/IDataSeries.h>
9 #include <Settings/SqpSettingsDefs.h>
9 #include <Settings/SqpSettingsDefs.h>
10 #include <SqpApplication.h>
10 #include <SqpApplication.h>
11 #include <Variable/Variable.h>
11 #include <Variable/Variable.h>
12 #include <Variable/VariableController.h>
12 #include <Variable/VariableController.h>
13
13
14 #include <unordered_map>
14 #include <unordered_map>
15
15
16 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
16 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
17
17
18 namespace {
18 namespace {
19
19
20 /// Key pressed to enable zoom on horizontal axis
20 /// Key pressed to enable zoom on horizontal axis
21 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
21 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
22
22
23 /// Key pressed to enable zoom on vertical axis
23 /// Key pressed to enable zoom on vertical axis
24 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
24 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
25
25
26 } // namespace
26 } // namespace
27
27
28 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
28 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
29
29
30 explicit VisualizationGraphWidgetPrivate()
30 explicit VisualizationGraphWidgetPrivate()
31 : m_DoAcquisition{true}, m_IsCalibration{false}, m_RenderingDelegate{nullptr}
31 : m_DoAcquisition{true}, m_IsCalibration{false}, m_RenderingDelegate{nullptr}
32 {
32 {
33 }
33 }
34
34
35 // 1 variable -> n qcpplot
35 // 1 variable -> n qcpplot
36 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
36 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
37 bool m_DoAcquisition;
37 bool m_DoAcquisition;
38 bool m_IsCalibration;
38 bool m_IsCalibration;
39 QCPItemTracer *m_TextTracer;
39 QCPItemTracer *m_TextTracer;
40 /// Delegate used to attach rendering features to the plot
40 /// Delegate used to attach rendering features to the plot
41 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
41 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
42 };
42 };
43
43
44 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
44 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
45 : QWidget{parent},
45 : QWidget{parent},
46 ui{new Ui::VisualizationGraphWidget},
46 ui{new Ui::VisualizationGraphWidget},
47 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
47 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
48 {
48 {
49 ui->setupUi(this);
49 ui->setupUi(this);
50
50
51 // The delegate must be initialized after the ui as it uses the plot
51 // The delegate must be initialized after the ui as it uses the plot
52 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*ui->widget);
52 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*ui->widget);
53
53
54 ui->graphNameLabel->setText(name);
54 ui->graphNameLabel->setText(name);
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 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
58 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
59 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
59 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
60
60
61 // Set qcpplot properties :
61 // Set qcpplot properties :
62 // - Drag (on x-axis) and zoom are enabled
62 // - Drag (on x-axis) and zoom are enabled
63 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
63 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
64 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
64 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
65 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
65 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
66
66
67 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
67 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
68 connect(ui->widget, &QCustomPlot::mouseRelease, this,
68 connect(ui->widget, &QCustomPlot::mouseRelease, this,
69 &VisualizationGraphWidget::onMouseRelease);
69 &VisualizationGraphWidget::onMouseRelease);
70 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
70 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
71 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
71 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
72 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
72 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
73 &QCPAxis::rangeChanged),
73 &QCPAxis::rangeChanged),
74 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
74 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
75
75
76 // Activates menu when right clicking on the graph
76 // Activates menu when right clicking on the graph
77 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
77 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
78 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
78 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
79 &VisualizationGraphWidget::onGraphMenuRequested);
79 &VisualizationGraphWidget::onGraphMenuRequested);
80
80
81 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
81 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
82 &VariableController::onRequestDataLoading);
82 &VariableController::onRequestDataLoading);
83
84 connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
85 &VisualizationGraphWidget::onUpdateVarDisplaying);
83 }
86 }
84
87
85
88
86 VisualizationGraphWidget::~VisualizationGraphWidget()
89 VisualizationGraphWidget::~VisualizationGraphWidget()
87 {
90 {
88 delete ui;
91 delete ui;
89 }
92 }
90
93
91 void VisualizationGraphWidget::enableAcquisition(bool enable)
94 void VisualizationGraphWidget::enableAcquisition(bool enable)
92 {
95 {
93 impl->m_DoAcquisition = enable;
96 impl->m_DoAcquisition = enable;
94 }
97 }
95
98
96 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
99 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
97 {
100 {
98 // Uses delegate to create the qcpplot components according to the variable
101 // Uses delegate to create the qcpplot components according to the variable
99 auto createdPlottables = VisualizationGraphHelper::createV2(variable, *ui->widget);
102 auto createdPlottables = VisualizationGraphHelper::createV2(variable, *ui->widget);
100
103
101 for (auto createdPlottable : qAsConst(createdPlottables)) {
104 for (auto createdPlottable : qAsConst(createdPlottables)) {
102 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
105 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
103 }
106 }
104
107
105 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
108 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
106
109
107 auto varRange = variable->range();
110 auto varRange = variable->range();
108
111
109 this->enableAcquisition(false);
112 this->enableAcquisition(false);
110 this->setGraphRange(range);
113 this->setGraphRange(range);
111 this->enableAcquisition(true);
114 this->enableAcquisition(true);
112
115
113 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, varRange,
116 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, varRange,
114 false);
117 false);
115
118
116 emit variableAdded(variable);
119 emit variableAdded(variable);
117 }
120 }
118
121
119 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
122 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
120 {
123 {
121 // Each component associated to the variable :
124 // Each component associated to the variable :
122 // - is removed from qcpplot (which deletes it)
125 // - is removed from qcpplot (which deletes it)
123 // - is no longer referenced in the map
126 // - is no longer referenced in the map
124 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
127 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
125 for (auto it = componentsIt.first; it != componentsIt.second;) {
128 for (auto it = componentsIt.first; it != componentsIt.second;) {
126 ui->widget->removePlottable(it->second);
129 ui->widget->removePlottable(it->second);
127 it = impl->m_VariableToPlotMultiMap.erase(it);
130 it = impl->m_VariableToPlotMultiMap.erase(it);
128 }
131 }
129
132
130 // Updates graph
133 // Updates graph
131 ui->widget->replot();
134 ui->widget->replot();
132 }
135 }
133
136
134 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable, const SqpRange &range)
137 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable, const SqpRange &range)
135 {
138 {
136 // Note: in case of different axes that depends on variable, we could start with a code like
139 // Note: in case of different axes that depends on variable, we could start with a code like
137 // that:
140 // that:
138 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
141 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
139 // for (auto it = componentsIt.first; it != componentsIt.second;) {
142 // for (auto it = componentsIt.first; it != componentsIt.second;) {
140 // }
143 // }
141 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
144 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
142 ui->widget->replot();
145 ui->widget->replot();
143 }
146 }
144
147
145 void VisualizationGraphWidget::setYRange(const SqpRange &range)
148 void VisualizationGraphWidget::setYRange(const SqpRange &range)
146 {
149 {
147 ui->widget->yAxis->setRange(range.m_TStart, range.m_TEnd);
150 ui->widget->yAxis->setRange(range.m_TStart, range.m_TEnd);
148 }
151 }
149
152
150 SqpRange VisualizationGraphWidget::graphRange() const noexcept
153 SqpRange VisualizationGraphWidget::graphRange() const noexcept
151 {
154 {
152 auto graphRange = ui->widget->xAxis->range();
155 auto graphRange = ui->widget->xAxis->range();
153 return SqpRange{graphRange.lower, graphRange.upper};
156 return SqpRange{graphRange.lower, graphRange.upper};
154 }
157 }
155
158
156 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
159 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
157 {
160 {
158 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
161 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
159 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
162 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
160 ui->widget->replot();
163 ui->widget->replot();
161 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
164 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
162 }
165 }
163
166
164 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
167 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
165 {
168 {
166 if (visitor) {
169 if (visitor) {
167 visitor->visit(this);
170 visitor->visit(this);
168 }
171 }
169 else {
172 else {
170 qCCritical(LOG_VisualizationGraphWidget())
173 qCCritical(LOG_VisualizationGraphWidget())
171 << tr("Can't visit widget : the visitor is null");
174 << tr("Can't visit widget : the visitor is null");
172 }
175 }
173 }
176 }
174
177
175 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
178 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
176 {
179 {
177 /// @todo : for the moment, a graph can always accomodate a variable
180 /// @todo : for the moment, a graph can always accomodate a variable
178 Q_UNUSED(variable);
181 Q_UNUSED(variable);
179 return true;
182 return true;
180 }
183 }
181
184
182 bool VisualizationGraphWidget::contains(const Variable &variable) const
185 bool VisualizationGraphWidget::contains(const Variable &variable) const
183 {
186 {
184 // Finds the variable among the keys of the map
187 // Finds the variable among the keys of the map
185 auto variablePtr = &variable;
188 auto variablePtr = &variable;
186 auto findVariable
189 auto findVariable
187 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
190 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
188
191
189 auto end = impl->m_VariableToPlotMultiMap.cend();
192 auto end = impl->m_VariableToPlotMultiMap.cend();
190 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
193 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
191 return it != end;
194 return it != end;
192 }
195 }
193
196
194 QString VisualizationGraphWidget::name() const
197 QString VisualizationGraphWidget::name() const
195 {
198 {
196 return ui->graphNameLabel->text();
199 return ui->graphNameLabel->text();
197 }
200 }
198
201
199 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
202 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
200 {
203 {
201 QMenu graphMenu{};
204 QMenu graphMenu{};
202
205
203 // Iterates on variables (unique keys)
206 // Iterates on variables (unique keys)
204 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
207 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
205 end = impl->m_VariableToPlotMultiMap.cend();
208 end = impl->m_VariableToPlotMultiMap.cend();
206 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
209 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
207 // 'Remove variable' action
210 // 'Remove variable' action
208 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
211 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
209 [ this, var = it->first ]() { removeVariable(var); });
212 [ this, var = it->first ]() { removeVariable(var); });
210 }
213 }
211
214
212 if (!graphMenu.isEmpty()) {
215 if (!graphMenu.isEmpty()) {
213 graphMenu.exec(mapToGlobal(pos));
216 graphMenu.exec(mapToGlobal(pos));
214 }
217 }
215 }
218 }
216
219
217 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
220 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
218 {
221 {
219 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
222 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
220 << QThread::currentThread()->objectName() << "DoAcqui"
223 << QThread::currentThread()->objectName() << "DoAcqui"
221 << impl->m_DoAcquisition;
224 << impl->m_DoAcquisition;
222
225
223 auto graphRange = SqpRange{t1.lower, t1.upper};
226 auto graphRange = SqpRange{t1.lower, t1.upper};
224 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
227 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
225
228
226 if (impl->m_DoAcquisition) {
229 if (impl->m_DoAcquisition) {
227 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
230 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
228
231
229 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
232 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
230 end = impl->m_VariableToPlotMultiMap.end();
233 end = impl->m_VariableToPlotMultiMap.end();
231 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
234 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
232 variableUnderGraphVector.push_back(it->first);
235 variableUnderGraphVector.push_back(it->first);
233 }
236 }
234 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
237 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
235 !impl->m_IsCalibration);
238 !impl->m_IsCalibration);
236
239
237 if (!impl->m_IsCalibration) {
240 if (!impl->m_IsCalibration) {
238 qCDebug(LOG_VisualizationGraphWidget())
241 qCDebug(LOG_VisualizationGraphWidget())
239 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
242 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
240 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
243 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
241 emit synchronize(graphRange, oldGraphRange);
244 emit synchronize(graphRange, oldGraphRange);
242 }
245 }
243 }
246 }
244 }
247 }
245
248
246 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
249 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
247 {
250 {
248 // Handles plot rendering when mouse is moving
251 // Handles plot rendering when mouse is moving
249 impl->m_RenderingDelegate->onMouseMove(event);
252 impl->m_RenderingDelegate->onMouseMove(event);
250 }
253 }
251
254
252 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
255 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
253 {
256 {
254 auto zoomOrientations = QFlags<Qt::Orientation>{};
257 auto zoomOrientations = QFlags<Qt::Orientation>{};
255
258
256 // Lambda that enables a zoom orientation if the key modifier related to this orientation
259 // Lambda that enables a zoom orientation if the key modifier related to this orientation
257 // has
260 // has
258 // been pressed
261 // been pressed
259 auto enableOrientation
262 auto enableOrientation
260 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
263 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
261 auto orientationEnabled = event->modifiers().testFlag(modifier);
264 auto orientationEnabled = event->modifiers().testFlag(modifier);
262 zoomOrientations.setFlag(orientation, orientationEnabled);
265 zoomOrientations.setFlag(orientation, orientationEnabled);
263 };
266 };
264 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
267 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
265 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
268 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
266
269
267 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
270 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
268 }
271 }
269
272
270 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
273 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
271 {
274 {
272 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
275 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
273 }
276 }
274
277
275 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
278 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
276 {
279 {
277 impl->m_IsCalibration = false;
280 impl->m_IsCalibration = false;
278 }
281 }
279
282
280 void VisualizationGraphWidget::onDataCacheVariableUpdated()
283 void VisualizationGraphWidget::onDataCacheVariableUpdated()
281 {
284 {
282 // NOTE:
285 // NOTE:
283 // We don't want to call the method for each component of a variable unitarily, but for
286 // We don't want to call the method for each component of a variable unitarily, but for
284 // all
287 // all
285 // its components at once (eg its three components in the case of a vector).
288 // its components at once (eg its three components in the case of a vector).
286
289
287 // The unordered_multimap does not do this easily, so the question is whether to:
290 // The unordered_multimap does not do this easily, so the question is whether to:
288 // - use an ordered_multimap and the algos of std to group the values by key
291 // - use an ordered_multimap and the algos of std to group the values by key
289 // - use a map (unique keys) and store as values directly the list of components
292 // - use a map (unique keys) and store as values directly the list of components
290
293
291 auto graphRange = ui->widget->xAxis->range();
294 auto graphRange = ui->widget->xAxis->range();
292 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
295 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
293
296
294 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
297 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
295 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
298 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
296 auto variable = it->first;
299 auto variable = it->first;
297 qCDebug(LOG_VisualizationGraphWidget())
300 qCDebug(LOG_VisualizationGraphWidget())
298 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
301 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
299 qCDebug(LOG_VisualizationGraphWidget())
302 qCDebug(LOG_VisualizationGraphWidget())
300 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
303 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
301 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
304 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
302
305
303 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
306 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
304 variable->dataSeries(), variable->range());
307 variable->dataSeries(), variable->range());
305 }
308 }
306 }
309 }
307 }
310 }
311
312 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
313 const SqpRange &range)
314 {
315 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
316 for (auto it = componentsIt.first; it != componentsIt.second;) {
317 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
318 variable->dataSeries(), range);
319 }
320 }
General Comments 1
Under Review
author

Auto status change to "Under Review"

You need to be logged in to leave comments. Login now