##// END OF EJS Templates
Add synchronization part of v5 acquisition
perrinel -
r540:bf486b19bffa
parent child
Show More
@@ -1,116 +1,117
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 public slots:
76 public slots:
77 /// Request the data loading of the variable whithin range
77 /// Request the data loading of the variable whithin range
78 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
78 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
79 const SqpRange &oldRange, bool synchronise);
79 const SqpRange &oldRange, bool synchronise);
80 /**
80 /**
81 * Creates a new variable and adds it to the model
81 * Creates a new variable and adds it to the model
82 * @param name the name of the new variable
82 * @param name the name of the new variable
83 * @param metadata the metadata of the new variable
83 * @param metadata the metadata of the new variable
84 * @param provider the data provider for the new variable
84 * @param provider the data provider for the new variable
85 */
85 */
86 void createVariable(const QString &name, const QVariantHash &metadata,
86 void createVariable(const QString &name, const QVariantHash &metadata,
87 std::shared_ptr<IDataProvider> provider) noexcept;
87 std::shared_ptr<IDataProvider> provider) noexcept;
88
88
89 /// Update the temporal parameters of every selected variable to dateTime
89 /// Update the temporal parameters of every selected variable to dateTime
90 void onDateTimeOnSelection(const SqpRange &dateTime);
90 void onDateTimeOnSelection(const SqpRange &dateTime);
91
91
92
92
93 void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
93 void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
94 const SqpRange &cacheRangeRequested,
94 const SqpRange &cacheRangeRequested,
95 QVector<AcquisitionDataPacket> dataAcquired);
95 QVector<AcquisitionDataPacket> dataAcquired);
96
96
97 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
97 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
98
98
99 /// Cancel the current request for the variable
99 /// Cancel the current request for the variable
100 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
100 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
101
101
102 /// synchronization group methods
102 /// synchronization group methods
103 void onAddSynchronizationGroupId(QUuid synchronizationGroupId);
103 void onAddSynchronizationGroupId(QUuid synchronizationGroupId);
104 void onRemoveSynchronizationGroupId(QUuid synchronizationGroupId);
104 void onRemoveSynchronizationGroupId(QUuid synchronizationGroupId);
105 void onAddSynchronized(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
105
106
106 void initialize();
107 void initialize();
107 void finalize();
108 void finalize();
108
109
109 private:
110 private:
110 void waitForFinish();
111 void waitForFinish();
111
112
112 class VariableControllerPrivate;
113 class VariableControllerPrivate;
113 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
114 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
114 };
115 };
115
116
116 #endif // SCIQLOP_VARIABLECONTROLLER_H
117 #endif // SCIQLOP_VARIABLECONTROLLER_H
@@ -1,508 +1,543
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 &grapheRange,
26 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &grapheRange,
27 const SqpRange &oldGraphRange)
27 const SqpRange &oldGraphRange)
28 {
28 {
29 auto zoomType = VariableController::getZoomType(grapheRange, oldGraphRange);
29 auto zoomType = VariableController::getZoomType(grapheRange, 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 = grapheRange.m_TStart - oldGraphRange.m_TStart;
34 auto deltaLeft = grapheRange.m_TStart - oldGraphRange.m_TStart;
35 auto deltaRight = oldGraphRange.m_TEnd - grapheRange.m_TEnd;
35 auto deltaRight = oldGraphRange.m_TEnd - grapheRange.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 - grapheRange.m_TStart;
42 auto deltaLeft = oldGraphRange.m_TStart - grapheRange.m_TStart;
43 auto deltaRight = grapheRange.m_TEnd - oldGraphRange.m_TEnd;
43 auto deltaRight = grapheRange.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 = grapheRange.m_TEnd - oldGraphRange.m_TEnd;
49 auto deltaRight = grapheRange.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 - grapheRange.m_TStart;
55 auto deltaLeft = oldGraphRange.m_TStart - grapheRange.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 {
84 {
85
85
86 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
86 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
87 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 }
88 }
89
89
90
90
91 virtual ~VariableControllerPrivate()
91 virtual ~VariableControllerPrivate()
92 {
92 {
93 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
93 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
94 m_VariableAcquisitionWorkerThread.quit();
94 m_VariableAcquisitionWorkerThread.quit();
95 m_VariableAcquisitionWorkerThread.wait();
95 m_VariableAcquisitionWorkerThread.wait();
96 }
96 }
97
97
98
98
99 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested);
99 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested);
100
100
101 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
101 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
102 const SqpRange &dateTime);
102 const SqpRange &dateTime);
103
103
104 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
104 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
105 std::shared_ptr<IDataSeries>
105 std::shared_ptr<IDataSeries>
106 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
106 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
107
107
108 void registerProvider(std::shared_ptr<IDataProvider> provider);
108 void registerProvider(std::shared_ptr<IDataProvider> provider);
109
109
110 QMutex m_WorkingMutex;
110 QMutex m_WorkingMutex;
111 /// Variable model. The VariableController has the ownership
111 /// Variable model. The VariableController has the ownership
112 VariableModel *m_VariableModel;
112 VariableModel *m_VariableModel;
113 QItemSelectionModel *m_VariableSelectionModel;
113 QItemSelectionModel *m_VariableSelectionModel;
114
114
115
115
116 TimeController *m_TimeController{nullptr};
116 TimeController *m_TimeController{nullptr};
117 std::unique_ptr<VariableCacheController> m_VariableCacheController;
117 std::unique_ptr<VariableCacheController> m_VariableCacheController;
118 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
118 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
119 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
119 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
120 QThread m_VariableAcquisitionWorkerThread;
120 QThread m_VariableAcquisitionWorkerThread;
121
121
122 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
122 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
123 m_VariableToProviderMap;
123 m_VariableToProviderMap;
124 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
124 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
125 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
125 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
126 m_GroupIdToVariableSynchronizationGroupMap;
126 m_GroupIdToVariableSynchronizationGroupMap;
127 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
127 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
128 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
128 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
129 };
129 };
130
130
131
131
132 VariableController::VariableController(QObject *parent)
132 VariableController::VariableController(QObject *parent)
133 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
133 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
134 {
134 {
135 qCDebug(LOG_VariableController()) << tr("VariableController construction")
135 qCDebug(LOG_VariableController()) << tr("VariableController construction")
136 << QThread::currentThread();
136 << QThread::currentThread();
137
137
138 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
138 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
139 &VariableController::onAbortProgressRequested);
139 &VariableController::onAbortProgressRequested);
140
140
141 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
141 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
142 &VariableController::onDataProvided);
142 &VariableController::onDataProvided);
143 connect(impl->m_VariableAcquisitionWorker.get(),
143 connect(impl->m_VariableAcquisitionWorker.get(),
144 &VariableAcquisitionWorker::variableRequestInProgress, this,
144 &VariableAcquisitionWorker::variableRequestInProgress, this,
145 &VariableController::onVariableRetrieveDataInProgress);
145 &VariableController::onVariableRetrieveDataInProgress);
146
146
147 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
147 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
148 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
148 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
149 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
149 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
150 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
150 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
151
151
152
152
153 impl->m_VariableAcquisitionWorkerThread.start();
153 impl->m_VariableAcquisitionWorkerThread.start();
154 }
154 }
155
155
156 VariableController::~VariableController()
156 VariableController::~VariableController()
157 {
157 {
158 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
158 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
159 << QThread::currentThread();
159 << QThread::currentThread();
160 this->waitForFinish();
160 this->waitForFinish();
161 }
161 }
162
162
163 VariableModel *VariableController::variableModel() noexcept
163 VariableModel *VariableController::variableModel() noexcept
164 {
164 {
165 return impl->m_VariableModel;
165 return impl->m_VariableModel;
166 }
166 }
167
167
168 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
168 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
169 {
169 {
170 return impl->m_VariableSelectionModel;
170 return impl->m_VariableSelectionModel;
171 }
171 }
172
172
173 void VariableController::setTimeController(TimeController *timeController) noexcept
173 void VariableController::setTimeController(TimeController *timeController) noexcept
174 {
174 {
175 impl->m_TimeController = timeController;
175 impl->m_TimeController = timeController;
176 }
176 }
177
177
178 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
178 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
179 {
179 {
180 if (!variable) {
180 if (!variable) {
181 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
181 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
182 return;
182 return;
183 }
183 }
184
184
185 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
185 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
186 // make some treatments before the deletion
186 // make some treatments before the deletion
187 emit variableAboutToBeDeleted(variable);
187 emit variableAboutToBeDeleted(variable);
188
188
189 // Deletes identifier
189 // Deletes identifier
190 impl->m_VariableToIdentifierMap.erase(variable);
190 impl->m_VariableToIdentifierMap.erase(variable);
191
191
192 // Deletes provider
192 // Deletes provider
193 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
193 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
194 qCDebug(LOG_VariableController())
194 qCDebug(LOG_VariableController())
195 << tr("Number of providers deleted for variable %1: %2")
195 << tr("Number of providers deleted for variable %1: %2")
196 .arg(variable->name(), QString::number(nbProvidersDeleted));
196 .arg(variable->name(), QString::number(nbProvidersDeleted));
197
197
198 // Clears cache
198 // Clears cache
199 impl->m_VariableCacheController->clear(variable);
199 impl->m_VariableCacheController->clear(variable);
200
200
201 // Deletes from model
201 // Deletes from model
202 impl->m_VariableModel->deleteVariable(variable);
202 impl->m_VariableModel->deleteVariable(variable);
203 }
203 }
204
204
205 void VariableController::deleteVariables(
205 void VariableController::deleteVariables(
206 const QVector<std::shared_ptr<Variable> > &variables) noexcept
206 const QVector<std::shared_ptr<Variable> > &variables) noexcept
207 {
207 {
208 for (auto variable : qAsConst(variables)) {
208 for (auto variable : qAsConst(variables)) {
209 deleteVariable(variable);
209 deleteVariable(variable);
210 }
210 }
211 }
211 }
212
212
213 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
213 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
214 {
214 {
215 }
215 }
216
216
217 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
217 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
218 std::shared_ptr<IDataProvider> provider) noexcept
218 std::shared_ptr<IDataProvider> provider) noexcept
219 {
219 {
220
220
221 if (!impl->m_TimeController) {
221 if (!impl->m_TimeController) {
222 qCCritical(LOG_VariableController())
222 qCCritical(LOG_VariableController())
223 << tr("Impossible to create variable: The time controller is null");
223 << tr("Impossible to create variable: The time controller is null");
224 return;
224 return;
225 }
225 }
226
226
227 auto range = impl->m_TimeController->dateTime();
227 auto range = impl->m_TimeController->dateTime();
228
228
229 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
229 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
230 auto identifier = QUuid::createUuid();
230 auto identifier = QUuid::createUuid();
231
231
232 // store the provider
232 // store the provider
233 impl->registerProvider(provider);
233 impl->registerProvider(provider);
234
234
235 // Associate the provider
235 // Associate the provider
236 impl->m_VariableToProviderMap[newVariable] = provider;
236 impl->m_VariableToProviderMap[newVariable] = provider;
237 impl->m_VariableToIdentifierMap[newVariable] = identifier;
237 impl->m_VariableToIdentifierMap[newVariable] = identifier;
238
238
239
239
240 impl->processRequest(newVariable, range);
240 impl->processRequest(newVariable, range);
241 }
241 }
242 }
242 }
243
243
244 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
244 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
245 {
245 {
246 // TODO check synchronisation
246 // TODO check synchronisation
247 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
247 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
248 << QThread::currentThread()->objectName();
248 << QThread::currentThread()->objectName();
249 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
249 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
250
250
251 for (const auto &selectedRow : qAsConst(selectedRows)) {
251 for (const auto &selectedRow : qAsConst(selectedRows)) {
252 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
252 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
253 selectedVariable->setRange(dateTime);
253 selectedVariable->setRange(dateTime);
254 impl->processRequest(selectedVariable, dateTime);
254 impl->processRequest(selectedVariable, dateTime);
255
255
256 // notify that rescale operation has to be done
256 // notify that rescale operation has to be done
257 emit rangeChanged(selectedVariable, dateTime);
257 emit rangeChanged(selectedVariable, dateTime);
258 }
258 }
259 }
259 }
260 }
260 }
261
261
262 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
262 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
263 const SqpRange &cacheRangeRequested,
263 const SqpRange &cacheRangeRequested,
264 QVector<AcquisitionDataPacket> dataAcquired)
264 QVector<AcquisitionDataPacket> dataAcquired)
265 {
265 {
266 qCCritical(LOG_VariableController()) << tr("onDataProvided") << dataAcquired.isEmpty();
267
268 auto var = impl->findVariable(vIdentifier);
266 auto var = impl->findVariable(vIdentifier);
269 if (var != nullptr) {
267 if (var != nullptr) {
270 var->setRange(rangeRequested);
268 var->setRange(rangeRequested);
271 var->setCacheRange(cacheRangeRequested);
269 var->setCacheRange(cacheRangeRequested);
272 qCCritical(LOG_VariableController()) << tr("1: onDataProvided") << rangeRequested;
270 qCDebug(LOG_VariableController()) << tr("1: onDataProvided") << rangeRequested;
273 qCCritical(LOG_VariableController()) << tr("2: onDataProvided") << cacheRangeRequested;
271 qCDebug(LOG_VariableController()) << tr("2: onDataProvided") << cacheRangeRequested;
274
272
275 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
273 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
276 qCCritical(LOG_VariableController()) << tr("3: onDataProvided")
274 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
277 << retrievedDataSeries->range();
275 << retrievedDataSeries->range();
278 var->mergeDataSeries(retrievedDataSeries);
276 var->mergeDataSeries(retrievedDataSeries);
279 emit var->updated();
277 emit var->updated();
280 }
278 }
281 else {
279 else {
282 qCCritical(LOG_VariableController()) << tr("Impossible to provide data to a null variable");
280 qCCritical(LOG_VariableController()) << tr("Impossible to provide data to a null variable");
283 }
281 }
284 }
282 }
285
283
286 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
284 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
287 {
285 {
288 auto var = impl->findVariable(identifier);
286 auto var = impl->findVariable(identifier);
289 if (var != nullptr) {
287 if (var != nullptr) {
290 impl->m_VariableModel->setDataProgress(var, progress);
288 impl->m_VariableModel->setDataProgress(var, progress);
291 }
289 }
292 else {
290 else {
293 qCCritical(LOG_VariableController())
291 qCCritical(LOG_VariableController())
294 << tr("Impossible to notify progression of a null variable");
292 << tr("Impossible to notify progression of a null variable");
295 }
293 }
296 }
294 }
297
295
298 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
296 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
299 {
297 {
300 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
298 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
301 << QThread::currentThread()->objectName();
299 << QThread::currentThread()->objectName();
302
300
303 auto it = impl->m_VariableToIdentifierMap.find(variable);
301 auto it = impl->m_VariableToIdentifierMap.find(variable);
304 if (it != impl->m_VariableToIdentifierMap.cend()) {
302 if (it != impl->m_VariableToIdentifierMap.cend()) {
305 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
303 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
306 }
304 }
307 else {
305 else {
308 qCWarning(LOG_VariableController())
306 qCWarning(LOG_VariableController())
309 << tr("Aborting progression of inexistant variable detected !!!")
307 << tr("Aborting progression of inexistant variable detected !!!")
310 << QThread::currentThread()->objectName();
308 << QThread::currentThread()->objectName();
311 }
309 }
312 }
310 }
313
311
314 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
312 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
315 {
313 {
314 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
315 << QThread::currentThread()->objectName()
316 << synchronizationGroupId;
316 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
317 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
317 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
318 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
318 std::make_pair(synchronizationGroupId, vSynchroGroup));
319 std::make_pair(synchronizationGroupId, vSynchroGroup));
319 }
320 }
320
321
321 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
322 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
322 {
323 {
323 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
324 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
324 }
325 }
325
326
327 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
328 QUuid synchronizationGroupId)
329
330 {
331 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
332 << synchronizationGroupId;
333 auto vToVIdit = impl->m_VariableToIdentifierMap.find(variable);
334 if (vToVIdit != impl->m_VariableToIdentifierMap.cend()) {
335 auto itSynchroGroup
336 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
337 if (itSynchroGroup != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
338 impl->m_VariableIdGroupIdMap.insert(
339 std::make_pair(vToVIdit->second, synchronizationGroupId));
340 itSynchroGroup->second->addVariableId(vToVIdit->second);
341 }
342 else {
343 qCCritical(LOG_VariableController())
344 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
345 << variable->name();
346 }
347 }
348 else {
349 qCCritical(LOG_VariableController())
350 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
351 }
352 }
353
326
354
327 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
355 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
328 const SqpRange &range, const SqpRange &oldRange,
356 const SqpRange &range, const SqpRange &oldRange,
329 bool synchronise)
357 bool synchronise)
330 {
358 {
331 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
359 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
332
360
333 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
361 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
334 << QThread::currentThread()->objectName();
362 << QThread::currentThread()->objectName();
335 // we want to load data of the variable for the dateTime.
363 // we want to load data of the variable for the dateTime.
336 // First we check if the cache contains some of them.
364 // First we check if the cache contains some of them.
337 // For the other, we ask the provider to give them.
365 // For the other, we ask the provider to give them.
338
366
339 foreach (auto var, variables) {
367 foreach (auto var, variables) {
340 qCInfo(LOG_VariableController()) << "processRequest for" << var->name();
368 qCDebug(LOG_VariableController()) << "processRequest for" << var->name();
341 impl->processRequest(var, range);
369 impl->processRequest(var, range);
342 }
370 }
343
371
344 if (synchronise) {
372 if (synchronise) {
345 // Get the group ids
373 // Get the group ids
346 qCInfo(LOG_VariableController())
374 qCDebug(LOG_VariableController())
347 << "VariableController::onRequestDataLoading for synchro var ENABLE";
375 << "VariableController::onRequestDataLoading for synchro var ENABLE";
348 auto groupIds = std::set<QUuid>();
376 auto groupIds = std::set<QUuid>();
349 foreach (auto var, variables) {
377 foreach (auto var, variables) {
350 auto vToVIdit = impl->m_VariableToIdentifierMap.find(var);
378 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
351 if (vToVIdit != impl->m_VariableToIdentifierMap.cend()) {
379 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
352 auto vId = vToVIdit->second;
380 auto vId = varToVarIdIt->second;
353
381 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
354 auto vIdToGIdit = impl->m_VariableIdGroupIdMap.find(vId);
382 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
355 if (vIdToGIdit != impl->m_VariableIdGroupIdMap.cend()) {
383 auto gId = varIdToGroupIdIt->second;
356 auto gId = vToVIdit->second;
357 if (groupIds.find(gId) == groupIds.cend()) {
384 if (groupIds.find(gId) == groupIds.cend()) {
385 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
358 groupIds.insert(gId);
386 groupIds.insert(gId);
359 }
387 }
360 }
388 }
361 }
389 }
362 }
390 }
363
391
364 // We assume here all group ids exist
392 // We assume here all group ids exist
365 foreach (auto gId, groupIds) {
393 foreach (auto gId, groupIds) {
366 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
394 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
367 auto vSyncIds = vSynchronizationGroup->getIds();
395 auto vSyncIds = vSynchronizationGroup->getIds();
396 qCDebug(LOG_VariableController()) << "Var in synchro group ";
368 for (auto vId : vSyncIds) {
397 for (auto vId : vSyncIds) {
369 auto var = impl->findVariable(vId);
398 auto var = impl->findVariable(vId);
370 if (var != nullptr) {
399
371 qCInfo(LOG_VariableController()) << "processRequest synchro for" << var->name();
400 // Don't process already processed var
372 auto vSyncRangeRequested
401 if (!variables.contains(var)) {
373 = computeSynchroRangeRequested(var->range(), range, oldRange);
402 if (var != nullptr) {
374 impl->processRequest(var, vSyncRangeRequested);
403 qCDebug(LOG_VariableController()) << "processRequest synchro for"
375 }
404 << var->name();
376 else {
405 auto vSyncRangeRequested
377 qCCritical(LOG_VariableController())
406 = computeSynchroRangeRequested(var->range(), range, oldRange);
378 << tr("Impossible to synchronize a null variable");
407 impl->processRequest(var, vSyncRangeRequested);
408 }
409 else {
410 qCCritical(LOG_VariableController())
411
412 << tr("Impossible to synchronize a null variable");
413 }
379 }
414 }
380 }
415 }
381 }
416 }
382 }
417 }
383 }
418 }
384
419
385
420
386 void VariableController::initialize()
421 void VariableController::initialize()
387 {
422 {
388 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
423 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
389 impl->m_WorkingMutex.lock();
424 impl->m_WorkingMutex.lock();
390 qCDebug(LOG_VariableController()) << tr("VariableController init END");
425 qCDebug(LOG_VariableController()) << tr("VariableController init END");
391 }
426 }
392
427
393 void VariableController::finalize()
428 void VariableController::finalize()
394 {
429 {
395 impl->m_WorkingMutex.unlock();
430 impl->m_WorkingMutex.unlock();
396 }
431 }
397
432
398 void VariableController::waitForFinish()
433 void VariableController::waitForFinish()
399 {
434 {
400 QMutexLocker locker{&impl->m_WorkingMutex};
435 QMutexLocker locker{&impl->m_WorkingMutex};
401 }
436 }
402
437
403 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
438 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
404 {
439 {
405 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
440 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
406 auto zoomType = AcquisitionZoomType::Unknown;
441 auto zoomType = AcquisitionZoomType::Unknown;
407 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
442 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
408 zoomType = AcquisitionZoomType::ZoomOut;
443 zoomType = AcquisitionZoomType::ZoomOut;
409 }
444 }
410 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
445 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
411 zoomType = AcquisitionZoomType::PanRight;
446 zoomType = AcquisitionZoomType::PanRight;
412 }
447 }
413 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) {
414 zoomType = AcquisitionZoomType::PanLeft;
449 zoomType = AcquisitionZoomType::PanLeft;
415 }
450 }
416 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
451 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
417 zoomType = AcquisitionZoomType::ZoomIn;
452 zoomType = AcquisitionZoomType::ZoomIn;
418 }
453 }
419 else {
454 else {
420 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
455 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
421 }
456 }
422 return zoomType;
457 return zoomType;
423 }
458 }
424
459
425 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
460 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
426 const SqpRange &rangeRequested)
461 const SqpRange &rangeRequested)
427 {
462 {
428
463
429 auto varRangesRequested
464 auto varRangesRequested
430 = m_VariableCacheStrategy->computeCacheRange(var->range(), rangeRequested);
465 = m_VariableCacheStrategy->computeCacheRange(var->range(), rangeRequested);
431 auto notInCacheRangeList = var->provideNotInCacheRangeList(varRangesRequested.second);
466 auto notInCacheRangeList = var->provideNotInCacheRangeList(varRangesRequested.second);
432
467
433 if (!notInCacheRangeList.empty()) {
468 if (!notInCacheRangeList.empty()) {
434 // Display part of data which are already there
469 // Display part of data which are already there
435 // Ask the provider for each data on the dateTimeListNotInCache
470 // Ask the provider for each data on the dateTimeListNotInCache
436 auto identifier = m_VariableToIdentifierMap.at(var);
471 auto identifier = m_VariableToIdentifierMap.at(var);
437 auto varProvider = m_VariableToProviderMap.at(var);
472 auto varProvider = m_VariableToProviderMap.at(var);
438 if (varProvider != nullptr) {
473 if (varProvider != nullptr) {
439 m_VariableAcquisitionWorker->pushVariableRequest(
474 m_VariableAcquisitionWorker->pushVariableRequest(
440 identifier, varRangesRequested.first, varRangesRequested.second,
475 identifier, varRangesRequested.first, varRangesRequested.second,
441 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
476 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
442 varProvider);
477 varProvider);
443 }
478 }
444 else {
479 else {
445 qCCritical(LOG_VariableController())
480 qCCritical(LOG_VariableController())
446 << "Impossible to provide data with a null provider";
481 << "Impossible to provide data with a null provider";
447 }
482 }
448 }
483 }
449 else {
484 else {
450 var->setRange(rangeRequested);
485 var->setRange(rangeRequested);
451 var->setCacheRange(varRangesRequested.second);
486 var->setCacheRange(varRangesRequested.second);
452 var->setDataSeries(var->dataSeries()->subData(varRangesRequested.second));
487 var->setDataSeries(var->dataSeries()->subData(varRangesRequested.second));
453 emit var->updated();
488 emit var->updated();
454 }
489 }
455 }
490 }
456
491
457 std::shared_ptr<Variable>
492 std::shared_ptr<Variable>
458 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
493 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
459 {
494 {
460 std::shared_ptr<Variable> var;
495 std::shared_ptr<Variable> var;
461 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
496 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
462
497
463 auto end = m_VariableToIdentifierMap.cend();
498 auto end = m_VariableToIdentifierMap.cend();
464 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
499 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
465 if (it != end) {
500 if (it != end) {
466 var = it->first;
501 var = it->first;
467 }
502 }
468 else {
503 else {
469 qCCritical(LOG_VariableController())
504 qCCritical(LOG_VariableController())
470 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
505 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
471 }
506 }
472
507
473 return var;
508 return var;
474 }
509 }
475
510
476 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
511 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
477 const QVector<AcquisitionDataPacket> acqDataPacketVector)
512 const QVector<AcquisitionDataPacket> acqDataPacketVector)
478 {
513 {
479 qCInfo(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
514 qCInfo(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
480 << acqDataPacketVector.size();
515 << acqDataPacketVector.size();
481 std::shared_ptr<IDataSeries> dataSeries;
516 std::shared_ptr<IDataSeries> dataSeries;
482 if (!acqDataPacketVector.isEmpty()) {
517 if (!acqDataPacketVector.isEmpty()) {
483 dataSeries = acqDataPacketVector[0].m_DateSeries;
518 dataSeries = acqDataPacketVector[0].m_DateSeries;
484 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
519 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
485 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
520 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
486 }
521 }
487 }
522 }
488
523
489 return dataSeries;
524 return dataSeries;
490 }
525 }
491
526
492 void VariableController::VariableControllerPrivate::registerProvider(
527 void VariableController::VariableControllerPrivate::registerProvider(
493 std::shared_ptr<IDataProvider> provider)
528 std::shared_ptr<IDataProvider> provider)
494 {
529 {
495 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
530 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
496 qCInfo(LOG_VariableController()) << tr("Registering of a new provider")
531 qCInfo(LOG_VariableController()) << tr("Registering of a new provider")
497 << provider->objectName();
532 << provider->objectName();
498 m_ProviderSet.insert(provider);
533 m_ProviderSet.insert(provider);
499 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
534 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
500 &VariableAcquisitionWorker::onVariableDataAcquired);
535 &VariableAcquisitionWorker::onVariableDataAcquired);
501 connect(provider.get(), &IDataProvider::dataProvidedProgress,
536 connect(provider.get(), &IDataProvider::dataProvidedProgress,
502 m_VariableAcquisitionWorker.get(),
537 m_VariableAcquisitionWorker.get(),
503 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
538 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
504 }
539 }
505 else {
540 else {
506 qCInfo(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
541 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
507 }
542 }
508 }
543 }
@@ -1,199 +1,199
1 #include "Data/ArrayData.h"
1 #include "Data/ArrayData.h"
2 #include <QObject>
2 #include <QObject>
3 #include <QtTest>
3 #include <QtTest>
4
4
5 class TestOneDimArrayData : public QObject {
5 class TestOneDimArrayData : public QObject {
6 Q_OBJECT
6 Q_OBJECT
7 private slots:
7 private slots:
8 /// Tests @sa ArrayData::data()
8 /// Tests @sa ArrayData::data()
9 void testData_data();
9 void testData_data();
10 void testData();
10 void testData();
11
11
12 /// Tests @sa ArrayData::data(int componentIndex)
12 /// Tests @sa ArrayData::data(int componentIndex)
13 void testDataByComponentIndex_data();
13 void testDataByComponentIndex_data();
14 void testDataByComponentIndex();
14 void testDataByComponentIndex();
15
15
16 /// Tests @sa ArrayData::add()
16 /// Tests @sa ArrayData::add()
17 void testAdd_data();
17 void testAdd_data();
18 void testAdd();
18 void testAdd();
19
19
20 /// Tests @sa ArrayData::at(int index)
20 /// Tests @sa ArrayData::at(int index)
21 void testAt_data();
21 void testAt_data();
22 void testAt();
22 void testAt();
23
23
24 /// Tests @sa ArrayData::clear()
24 /// Tests @sa ArrayData::clear()
25 void testClear_data();
25 void testClear_data();
26 void testClear();
26 void testClear();
27
27
28 /// Tests @sa ArrayData::size()
28 /// Tests @sa ArrayData::size()
29 void testSize_data();
29 void testSize_data();
30 void testSize();
30 void testSize();
31
31
32 /// Tests @sa ArrayData::sort()
32 /// Tests @sa ArrayData::sort()
33 void testSort_data();
33 void testSort_data();
34 void testSort();
34 void testSort();
35 };
35 };
36
36
37 void TestOneDimArrayData::testData_data()
37 void TestOneDimArrayData::testData_data()
38 {
38 {
39 // Test structure
39 // Test structure
40 QTest::addColumn<QVector<double> >("inputData"); // array's data input
40 QTest::addColumn<QVector<double> >("inputData"); // array's data input
41 QTest::addColumn<QVector<double> >("expectedData"); // expected data
41 QTest::addColumn<QVector<double> >("expectedData"); // expected data
42
42
43 // Test cases
43 // Test cases
44 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.}
44 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.}
45 << QVector<double>{1., 2., 3., 4., 5.};
45 << QVector<double>{1., 2., 3., 4., 5.};
46 }
46 }
47
47
48 void TestOneDimArrayData::testData()
48 void TestOneDimArrayData::testData()
49 {
49 {
50 QFETCH(QVector<double>, inputData);
50 QFETCH(QVector<double>, inputData);
51 QFETCH(QVector<double>, expectedData);
51 QFETCH(QVector<double>, expectedData);
52
52
53 ArrayData<1> arrayData{inputData};
53 ArrayData<1> arrayData{inputData};
54 QVERIFY(arrayData.data() == expectedData);
54 QVERIFY(arrayData.data() == expectedData);
55 }
55 }
56
56
57 void TestOneDimArrayData::testDataByComponentIndex_data()
57 void TestOneDimArrayData::testDataByComponentIndex_data()
58 {
58 {
59 // Test structure
59 // Test structure
60 QTest::addColumn<QVector<double> >("inputData"); // array data's input
60 QTest::addColumn<QVector<double> >("inputData"); // array data's input
61 QTest::addColumn<int>("componentIndex"); // component index to test
61 QTest::addColumn<int>("componentIndex"); // component index to test
62 QTest::addColumn<QVector<double> >("expectedData"); // expected data
62 QTest::addColumn<QVector<double> >("expectedData"); // expected data
63
63
64 // Test cases
64 // Test cases
65 QTest::newRow("validIndex") << QVector<double>{1., 2., 3., 4., 5.} << 0
65 QTest::newRow("validIndex") << QVector<double>{1., 2., 3., 4., 5.} << 0
66 << QVector<double>{1., 2., 3., 4., 5.};
66 << QVector<double>{1., 2., 3., 4., 5.};
67 QTest::newRow("invalidIndex1")
67 QTest::newRow("invalidIndex1") << QVector<double>{1., 2., 3., 4., 5.} << -1
68 << QVector<double>{1., 2., 3., 4., 5.} << -1 << QVector<double>{};
68 << QVector<double>{};
69 QTest::newRow("invalidIndex2") << QVector<double>{1., 2., 3., 4., 5.} << 1 << QVector<double>{};
69 QTest::newRow("invalidIndex2") << QVector<double>{1., 2., 3., 4., 5.} << 1 << QVector<double>{};
70 }
70 }
71
71
72 void TestOneDimArrayData::testDataByComponentIndex()
72 void TestOneDimArrayData::testDataByComponentIndex()
73 {
73 {
74 QFETCH(QVector<double>, inputData);
74 QFETCH(QVector<double>, inputData);
75 QFETCH(int, componentIndex);
75 QFETCH(int, componentIndex);
76 QFETCH(QVector<double>, expectedData);
76 QFETCH(QVector<double>, expectedData);
77
77
78 ArrayData<1> arrayData{inputData};
78 ArrayData<1> arrayData{inputData};
79 QVERIFY(arrayData.data(componentIndex) == expectedData);
79 QVERIFY(arrayData.data(componentIndex) == expectedData);
80 }
80 }
81
81
82 void TestOneDimArrayData::testAdd_data()
82 void TestOneDimArrayData::testAdd_data()
83 {
83 {
84 // Test structure
84 // Test structure
85 QTest::addColumn<QVector<double> >("inputData"); // array's data input
85 QTest::addColumn<QVector<double> >("inputData"); // array's data input
86 QTest::addColumn<QVector<double> >("otherData"); // array data's input to merge with
86 QTest::addColumn<QVector<double> >("otherData"); // array data's input to merge with
87 QTest::addColumn<bool>("prepend"); // prepend or append merge
87 QTest::addColumn<bool>("prepend"); // prepend or append merge
88 QTest::addColumn<QVector<double> >("expectedData"); // expected data after merge
88 QTest::addColumn<QVector<double> >("expectedData"); // expected data after merge
89
89
90 // Test cases
90 // Test cases
91 QTest::newRow("appendMerge") << QVector<double>{1., 2., 3., 4., 5.}
91 QTest::newRow("appendMerge") << QVector<double>{1., 2., 3., 4., 5.}
92 << QVector<double>{6., 7., 8.} << false
92 << QVector<double>{6., 7., 8.} << false
93 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8.};
93 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8.};
94 QTest::newRow("prependMerge") << QVector<double>{1., 2., 3., 4., 5.}
94 QTest::newRow("prependMerge") << QVector<double>{1., 2., 3., 4., 5.}
95 << QVector<double>{6., 7., 8.} << true
95 << QVector<double>{6., 7., 8.} << true
96 << QVector<double>{6., 7., 8., 1., 2., 3., 4., 5.};
96 << QVector<double>{6., 7., 8., 1., 2., 3., 4., 5.};
97 }
97 }
98
98
99 void TestOneDimArrayData::testAdd()
99 void TestOneDimArrayData::testAdd()
100 {
100 {
101 QFETCH(QVector<double>, inputData);
101 QFETCH(QVector<double>, inputData);
102 QFETCH(QVector<double>, otherData);
102 QFETCH(QVector<double>, otherData);
103 QFETCH(bool, prepend);
103 QFETCH(bool, prepend);
104 QFETCH(QVector<double>, expectedData);
104 QFETCH(QVector<double>, expectedData);
105
105
106 ArrayData<1> arrayData{inputData};
106 ArrayData<1> arrayData{inputData};
107 ArrayData<1> other{otherData};
107 ArrayData<1> other{otherData};
108
108
109 arrayData.add(other, prepend);
109 arrayData.add(other, prepend);
110 QVERIFY(arrayData.data() == expectedData);
110 QVERIFY(arrayData.data() == expectedData);
111 }
111 }
112
112
113 void TestOneDimArrayData::testAt_data()
113 void TestOneDimArrayData::testAt_data()
114 {
114 {
115 // Test structure
115 // Test structure
116 QTest::addColumn<QVector<double> >("inputData"); // array data's input
116 QTest::addColumn<QVector<double> >("inputData"); // array data's input
117 QTest::addColumn<int>("index"); // index to retrieve data
117 QTest::addColumn<int>("index"); // index to retrieve data
118 QTest::addColumn<double>("expectedData"); // expected data at index
118 QTest::addColumn<double>("expectedData"); // expected data at index
119
119
120 // Test cases
120 // Test cases
121 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << 0 << 1.;
121 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << 0 << 1.;
122 QTest::newRow("data2") << QVector<double>{1., 2., 3., 4., 5.} << 3 << 4.;
122 QTest::newRow("data2") << QVector<double>{1., 2., 3., 4., 5.} << 3 << 4.;
123 }
123 }
124
124
125 void TestOneDimArrayData::testAt()
125 void TestOneDimArrayData::testAt()
126 {
126 {
127 QFETCH(QVector<double>, inputData);
127 QFETCH(QVector<double>, inputData);
128 QFETCH(int, index);
128 QFETCH(int, index);
129 QFETCH(double, expectedData);
129 QFETCH(double, expectedData);
130
130
131 ArrayData<1> arrayData{inputData};
131 ArrayData<1> arrayData{inputData};
132 QVERIFY(arrayData.at(index) == expectedData);
132 QVERIFY(arrayData.at(index) == expectedData);
133 }
133 }
134
134
135 void TestOneDimArrayData::testClear_data()
135 void TestOneDimArrayData::testClear_data()
136 {
136 {
137 // Test structure
137 // Test structure
138 QTest::addColumn<QVector<double> >("inputData"); // array data's input
138 QTest::addColumn<QVector<double> >("inputData"); // array data's input
139
139
140 // Test cases
140 // Test cases
141 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.};
141 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.};
142 }
142 }
143
143
144 void TestOneDimArrayData::testClear()
144 void TestOneDimArrayData::testClear()
145 {
145 {
146 QFETCH(QVector<double>, inputData);
146 QFETCH(QVector<double>, inputData);
147
147
148 ArrayData<1> arrayData{inputData};
148 ArrayData<1> arrayData{inputData};
149 arrayData.clear();
149 arrayData.clear();
150 QVERIFY(arrayData.data() == QVector<double>{});
150 QVERIFY(arrayData.data() == QVector<double>{});
151 }
151 }
152
152
153 void TestOneDimArrayData::testSize_data()
153 void TestOneDimArrayData::testSize_data()
154 {
154 {
155 // Test structure
155 // Test structure
156 QTest::addColumn<QVector<double> >("inputData"); // array data's input
156 QTest::addColumn<QVector<double> >("inputData"); // array data's input
157 QTest::addColumn<int>("expectedSize"); // expected array data size
157 QTest::addColumn<int>("expectedSize"); // expected array data size
158
158
159 // Test cases
159 // Test cases
160 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << 5;
160 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << 5;
161 }
161 }
162
162
163 void TestOneDimArrayData::testSize()
163 void TestOneDimArrayData::testSize()
164 {
164 {
165 QFETCH(QVector<double>, inputData);
165 QFETCH(QVector<double>, inputData);
166 QFETCH(int, expectedSize);
166 QFETCH(int, expectedSize);
167
167
168 ArrayData<1> arrayData{inputData};
168 ArrayData<1> arrayData{inputData};
169 QVERIFY(arrayData.size() == expectedSize);
169 QVERIFY(arrayData.size() == expectedSize);
170 }
170 }
171
171
172 void TestOneDimArrayData::testSort_data()
172 void TestOneDimArrayData::testSort_data()
173 {
173 {
174 // Test structure
174 // Test structure
175 QTest::addColumn<QVector<double> >("inputData"); // array data's input
175 QTest::addColumn<QVector<double> >("inputData"); // array data's input
176 QTest::addColumn<std::vector<int> >("sortPermutation"); // permutation used to sort data
176 QTest::addColumn<std::vector<int> >("sortPermutation"); // permutation used to sort data
177 QTest::addColumn<QVector<double> >("expectedData"); // expected data after sorting
177 QTest::addColumn<QVector<double> >("expectedData"); // expected data after sorting
178
178
179 // Test cases
179 // Test cases
180 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << std::vector<int>{0, 2, 3, 1, 4}
180 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << std::vector<int>{0, 2, 3, 1, 4}
181 << QVector<double>{1., 3., 4., 2., 5.};
181 << QVector<double>{1., 3., 4., 2., 5.};
182 QTest::newRow("data2") << QVector<double>{1., 2., 3., 4., 5.} << std::vector<int>{4, 1, 2, 3, 0}
182 QTest::newRow("data2") << QVector<double>{1., 2., 3., 4., 5.} << std::vector<int>{4, 1, 2, 3, 0}
183 << QVector<double>{5., 2., 3., 4., 1.};
183 << QVector<double>{5., 2., 3., 4., 1.};
184 }
184 }
185
185
186 void TestOneDimArrayData::testSort()
186 void TestOneDimArrayData::testSort()
187 {
187 {
188 QFETCH(QVector<double>, inputData);
188 QFETCH(QVector<double>, inputData);
189 QFETCH(std::vector<int>, sortPermutation);
189 QFETCH(std::vector<int>, sortPermutation);
190 QFETCH(QVector<double>, expectedData);
190 QFETCH(QVector<double>, expectedData);
191
191
192 ArrayData<1> arrayData{inputData};
192 ArrayData<1> arrayData{inputData};
193 auto sortedArrayData = arrayData.sort(sortPermutation);
193 auto sortedArrayData = arrayData.sort(sortPermutation);
194 QVERIFY(sortedArrayData != nullptr);
194 QVERIFY(sortedArrayData != nullptr);
195 QVERIFY(sortedArrayData->data() == expectedData);
195 QVERIFY(sortedArrayData->data() == expectedData);
196 }
196 }
197
197
198 QTEST_MAIN(TestOneDimArrayData)
198 QTEST_MAIN(TestOneDimArrayData)
199 #include "TestOneDimArrayData.moc"
199 #include "TestOneDimArrayData.moc"
@@ -1,224 +1,224
1 #include "Data/ArrayData.h"
1 #include "Data/ArrayData.h"
2 #include <QObject>
2 #include <QObject>
3 #include <QtTest>
3 #include <QtTest>
4
4
5 using DataContainer = QVector<QVector<double> >;
5 using DataContainer = QVector<QVector<double> >;
6
6
7 class TestTwoDimArrayData : public QObject {
7 class TestTwoDimArrayData : public QObject {
8 Q_OBJECT
8 Q_OBJECT
9 private slots:
9 private slots:
10 /// Tests @sa ArrayData::data(int componentIndex)
10 /// Tests @sa ArrayData::data(int componentIndex)
11 void testDataByComponentIndex_data();
11 void testDataByComponentIndex_data();
12 void testDataByComponentIndex();
12 void testDataByComponentIndex();
13
13
14 /// Tests @sa ArrayData ctor
14 /// Tests @sa ArrayData ctor
15 void testCtor_data();
15 void testCtor_data();
16 void testCtor();
16 void testCtor();
17
17
18 /// Tests @sa ArrayData::add()
18 /// Tests @sa ArrayData::add()
19 void testAdd_data();
19 void testAdd_data();
20 void testAdd();
20 void testAdd();
21
21
22 /// Tests @sa ArrayData::clear()
22 /// Tests @sa ArrayData::clear()
23 void testClear_data();
23 void testClear_data();
24 void testClear();
24 void testClear();
25
25
26 /// Tests @sa ArrayData::size()
26 /// Tests @sa ArrayData::size()
27 void testSize_data();
27 void testSize_data();
28 void testSize();
28 void testSize();
29
29
30 /// Tests @sa ArrayData::sort()
30 /// Tests @sa ArrayData::sort()
31 void testSort_data();
31 void testSort_data();
32 void testSort();
32 void testSort();
33 };
33 };
34
34
35 void TestTwoDimArrayData::testDataByComponentIndex_data()
35 void TestTwoDimArrayData::testDataByComponentIndex_data()
36 {
36 {
37 // Test structure
37 // Test structure
38 QTest::addColumn<DataContainer>("inputData"); // array data's input
38 QTest::addColumn<DataContainer>("inputData"); // array data's input
39 QTest::addColumn<int>("componentIndex"); // component index to test
39 QTest::addColumn<int>("componentIndex"); // component index to test
40 QTest::addColumn<QVector<double> >("expectedData"); // expected data
40 QTest::addColumn<QVector<double> >("expectedData"); // expected data
41
41
42 // Test cases
42 // Test cases
43 auto inputData
43 auto inputData
44 = DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}};
44 = DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}};
45
45
46 QTest::newRow("validIndex1") << inputData << 0 << QVector<double>{1., 2., 3., 4., 5.};
46 QTest::newRow("validIndex1") << inputData << 0 << QVector<double>{1., 2., 3., 4., 5.};
47 QTest::newRow("validIndex2") << inputData << 1 << QVector<double>{6., 7., 8., 9., 10.};
47 QTest::newRow("validIndex2") << inputData << 1 << QVector<double>{6., 7., 8., 9., 10.};
48 QTest::newRow("validIndex3") << inputData << 2 << QVector<double>{11., 12., 13., 14., 15.};
48 QTest::newRow("validIndex3") << inputData << 2 << QVector<double>{11., 12., 13., 14., 15.};
49 QTest::newRow("invalidIndex1") << inputData << -1 << QVector<double>{};
49 QTest::newRow("invalidIndex1") << inputData << -1 << QVector<double>{};
50 QTest::newRow("invalidIndex2") << inputData << 3 << QVector<double>{};
50 QTest::newRow("invalidIndex2") << inputData << 3 << QVector<double>{};
51 }
51 }
52
52
53 void TestTwoDimArrayData::testDataByComponentIndex()
53 void TestTwoDimArrayData::testDataByComponentIndex()
54 {
54 {
55 QFETCH(DataContainer, inputData);
55 QFETCH(DataContainer, inputData);
56 QFETCH(int, componentIndex);
56 QFETCH(int, componentIndex);
57 QFETCH(QVector<double>, expectedData);
57 QFETCH(QVector<double>, expectedData);
58
58
59 ArrayData<2> arrayData{inputData};
59 ArrayData<2> arrayData{inputData};
60 QVERIFY(arrayData.data(componentIndex) == expectedData);
60 QVERIFY(arrayData.data(componentIndex) == expectedData);
61 }
61 }
62
62
63 void TestTwoDimArrayData::testCtor_data()
63 void TestTwoDimArrayData::testCtor_data()
64 {
64 {
65 // Test structure
65 // Test structure
66 QTest::addColumn<DataContainer>("inputData"); // array data's input
66 QTest::addColumn<DataContainer>("inputData"); // array data's input
67 QTest::addColumn<bool>("success"); // array data has been successfully constructed
67 QTest::addColumn<bool>("success"); // array data has been successfully constructed
68 QTest::addColumn<DataContainer>("expectedData"); // expected array data (when success)
68 QTest::addColumn<DataContainer>("expectedData"); // expected array data (when success)
69
69
70 // Test cases
70 // Test cases
71 QTest::newRow("validInput")
71 QTest::newRow("validInput")
72 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}}
72 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}}
73 << true
73 << true
74 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}};
74 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}};
75 QTest::newRow("malformedInput (components of the array data haven't the same size")
75 QTest::newRow("malformedInput (components of the array data haven't the same size")
76 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8.}, {11., 12.}} << true
76 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8.}, {11., 12.}} << true
77 << DataContainer{{}, {}, {}};
77 << DataContainer{{}, {}, {}};
78 QTest::newRow("invalidInput (less than tow components")
78 QTest::newRow("invalidInput (less than tow components") << DataContainer{{1., 2., 3., 4., 5.}}
79 << DataContainer{{1., 2., 3., 4., 5.}} << false << DataContainer{{}, {}, {}};
79 << false << DataContainer{{}, {}, {}};
80 }
80 }
81
81
82 void TestTwoDimArrayData::testCtor()
82 void TestTwoDimArrayData::testCtor()
83 {
83 {
84 QFETCH(DataContainer, inputData);
84 QFETCH(DataContainer, inputData);
85 QFETCH(bool, success);
85 QFETCH(bool, success);
86
86
87 if (success) {
87 if (success) {
88 QFETCH(DataContainer, expectedData);
88 QFETCH(DataContainer, expectedData);
89
89
90 ArrayData<2> arrayData{inputData};
90 ArrayData<2> arrayData{inputData};
91
91
92 for (auto i = 0; i < expectedData.size(); ++i) {
92 for (auto i = 0; i < expectedData.size(); ++i) {
93 QVERIFY(arrayData.data(i) == expectedData.at(i));
93 QVERIFY(arrayData.data(i) == expectedData.at(i));
94 }
94 }
95 }
95 }
96 else {
96 else {
97 QVERIFY_EXCEPTION_THROWN(ArrayData<2> arrayData{inputData}, std::invalid_argument);
97 QVERIFY_EXCEPTION_THROWN(ArrayData<2> arrayData{inputData}, std::invalid_argument);
98 }
98 }
99 }
99 }
100
100
101 void TestTwoDimArrayData::testAdd_data()
101 void TestTwoDimArrayData::testAdd_data()
102 {
102 {
103 // Test structure
103 // Test structure
104 QTest::addColumn<DataContainer>("inputData"); // array's data input
104 QTest::addColumn<DataContainer>("inputData"); // array's data input
105 QTest::addColumn<DataContainer>("otherData"); // array data's input to merge with
105 QTest::addColumn<DataContainer>("otherData"); // array data's input to merge with
106 QTest::addColumn<bool>("prepend"); // prepend or append merge
106 QTest::addColumn<bool>("prepend"); // prepend or append merge
107 QTest::addColumn<DataContainer>("expectedData"); // expected data after merge
107 QTest::addColumn<DataContainer>("expectedData"); // expected data after merge
108
108
109 // Test cases
109 // Test cases
110 auto inputData
110 auto inputData
111 = DataContainer{{1., 2., 3., 4., 5.}, {11., 12., 13., 14., 15.}, {21., 22., 23., 24., 25.}};
111 = DataContainer{{1., 2., 3., 4., 5.}, {11., 12., 13., 14., 15.}, {21., 22., 23., 24., 25.}};
112
112
113 auto vectorContainer = DataContainer{{6., 7., 8.}, {16., 17., 18.}, {26., 27., 28}};
113 auto vectorContainer = DataContainer{{6., 7., 8.}, {16., 17., 18.}, {26., 27., 28}};
114 auto tensorContainer = DataContainer{{6., 7., 8.}, {16., 17., 18.}, {26., 27., 28},
114 auto tensorContainer = DataContainer{{6., 7., 8.}, {16., 17., 18.}, {26., 27., 28},
115 {36., 37., 38.}, {46., 47., 48.}, {56., 57., 58}};
115 {36., 37., 38.}, {46., 47., 48.}, {56., 57., 58}};
116
116
117 QTest::newRow("appendMerge") << inputData << vectorContainer << false
117 QTest::newRow("appendMerge") << inputData << vectorContainer << false
118 << DataContainer{{1., 2., 3., 4., 5., 6., 7., 8.},
118 << DataContainer{{1., 2., 3., 4., 5., 6., 7., 8.},
119 {11., 12., 13., 14., 15., 16., 17., 18.},
119 {11., 12., 13., 14., 15., 16., 17., 18.},
120 {21., 22., 23., 24., 25., 26., 27., 28}};
120 {21., 22., 23., 24., 25., 26., 27., 28}};
121 QTest::newRow("prependMerge") << inputData << vectorContainer << true
121 QTest::newRow("prependMerge") << inputData << vectorContainer << true
122 << DataContainer{{6., 7., 8., 1., 2., 3., 4., 5.},
122 << DataContainer{{6., 7., 8., 1., 2., 3., 4., 5.},
123 {16., 17., 18., 11., 12., 13., 14., 15.},
123 {16., 17., 18., 11., 12., 13., 14., 15.},
124 {26., 27., 28, 21., 22., 23., 24., 25.}};
124 {26., 27., 28, 21., 22., 23., 24., 25.}};
125 QTest::newRow("invalidMerge") << inputData << tensorContainer << false << inputData;
125 QTest::newRow("invalidMerge") << inputData << tensorContainer << false << inputData;
126 }
126 }
127
127
128 void TestTwoDimArrayData::testAdd()
128 void TestTwoDimArrayData::testAdd()
129 {
129 {
130 QFETCH(DataContainer, inputData);
130 QFETCH(DataContainer, inputData);
131 QFETCH(DataContainer, otherData);
131 QFETCH(DataContainer, otherData);
132 QFETCH(bool, prepend);
132 QFETCH(bool, prepend);
133 QFETCH(DataContainer, expectedData);
133 QFETCH(DataContainer, expectedData);
134
134
135 ArrayData<2> arrayData{inputData};
135 ArrayData<2> arrayData{inputData};
136 ArrayData<2> other{otherData};
136 ArrayData<2> other{otherData};
137
137
138 arrayData.add(other, prepend);
138 arrayData.add(other, prepend);
139
139
140 for (auto i = 0; i < expectedData.size(); ++i) {
140 for (auto i = 0; i < expectedData.size(); ++i) {
141 QVERIFY(arrayData.data(i) == expectedData.at(i));
141 QVERIFY(arrayData.data(i) == expectedData.at(i));
142 }
142 }
143 }
143 }
144
144
145 void TestTwoDimArrayData::testClear_data()
145 void TestTwoDimArrayData::testClear_data()
146 {
146 {
147 // Test structure
147 // Test structure
148 QTest::addColumn<DataContainer>("inputData"); // array data's input
148 QTest::addColumn<DataContainer>("inputData"); // array data's input
149
149
150 // Test cases
150 // Test cases
151 QTest::newRow("data1") << DataContainer{
151 QTest::newRow("data1") << DataContainer{
152 {1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}};
152 {1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}};
153 }
153 }
154
154
155 void TestTwoDimArrayData::testClear()
155 void TestTwoDimArrayData::testClear()
156 {
156 {
157 QFETCH(DataContainer, inputData);
157 QFETCH(DataContainer, inputData);
158
158
159 ArrayData<2> arrayData{inputData};
159 ArrayData<2> arrayData{inputData};
160 arrayData.clear();
160 arrayData.clear();
161
161
162 for (auto i = 0; i < inputData.size(); ++i) {
162 for (auto i = 0; i < inputData.size(); ++i) {
163 QVERIFY(arrayData.data(i) == QVector<double>{});
163 QVERIFY(arrayData.data(i) == QVector<double>{});
164 }
164 }
165 }
165 }
166
166
167 void TestTwoDimArrayData::testSize_data()
167 void TestTwoDimArrayData::testSize_data()
168 {
168 {
169 // Test structure
169 // Test structure
170 QTest::addColumn<QVector<QVector<double> > >("inputData"); // array data's input
170 QTest::addColumn<QVector<QVector<double> > >("inputData"); // array data's input
171 QTest::addColumn<int>("expectedSize"); // expected array data size
171 QTest::addColumn<int>("expectedSize"); // expected array data size
172
172
173 // Test cases
173 // Test cases
174 QTest::newRow("data1") << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}} << 5;
174 QTest::newRow("data1") << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}} << 5;
175 QTest::newRow("data2") << DataContainer{{1., 2., 3., 4., 5.},
175 QTest::newRow("data2") << DataContainer{{1., 2., 3., 4., 5.},
176 {6., 7., 8., 9., 10.},
176 {6., 7., 8., 9., 10.},
177 {11., 12., 13., 14., 15.}}
177 {11., 12., 13., 14., 15.}}
178 << 5;
178 << 5;
179 }
179 }
180
180
181 void TestTwoDimArrayData::testSize()
181 void TestTwoDimArrayData::testSize()
182 {
182 {
183 QFETCH(DataContainer, inputData);
183 QFETCH(DataContainer, inputData);
184 QFETCH(int, expectedSize);
184 QFETCH(int, expectedSize);
185
185
186 ArrayData<2> arrayData{inputData};
186 ArrayData<2> arrayData{inputData};
187 QVERIFY(arrayData.size() == expectedSize);
187 QVERIFY(arrayData.size() == expectedSize);
188 }
188 }
189
189
190 void TestTwoDimArrayData::testSort_data()
190 void TestTwoDimArrayData::testSort_data()
191 {
191 {
192 // Test structure
192 // Test structure
193 QTest::addColumn<DataContainer>("inputData"); // array data's input
193 QTest::addColumn<DataContainer>("inputData"); // array data's input
194 QTest::addColumn<std::vector<int> >("sortPermutation"); // permutation used to sort data
194 QTest::addColumn<std::vector<int> >("sortPermutation"); // permutation used to sort data
195 QTest::addColumn<DataContainer>("expectedData"); // expected data after sorting
195 QTest::addColumn<DataContainer>("expectedData"); // expected data after sorting
196
196
197 // Test cases
197 // Test cases
198 QTest::newRow("data1")
198 QTest::newRow("data1")
199 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}}
199 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}}
200 << std::vector<int>{0, 2, 3, 1, 4}
200 << std::vector<int>{0, 2, 3, 1, 4}
201 << DataContainer{{1., 3., 4., 2., 5.}, {6., 8., 9., 7., 10.}, {11., 13., 14., 12., 15.}};
201 << DataContainer{{1., 3., 4., 2., 5.}, {6., 8., 9., 7., 10.}, {11., 13., 14., 12., 15.}};
202 QTest::newRow("data2")
202 QTest::newRow("data2")
203 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}}
203 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}}
204 << std::vector<int>{2, 4, 3, 0, 1}
204 << std::vector<int>{2, 4, 3, 0, 1}
205 << DataContainer{{3., 5., 4., 1., 2.}, {8., 10., 9., 6., 7.}, {13., 15., 14., 11., 12.}};
205 << DataContainer{{3., 5., 4., 1., 2.}, {8., 10., 9., 6., 7.}, {13., 15., 14., 11., 12.}};
206 }
206 }
207
207
208 void TestTwoDimArrayData::testSort()
208 void TestTwoDimArrayData::testSort()
209 {
209 {
210 QFETCH(DataContainer, inputData);
210 QFETCH(DataContainer, inputData);
211 QFETCH(std::vector<int>, sortPermutation);
211 QFETCH(std::vector<int>, sortPermutation);
212 QFETCH(DataContainer, expectedData);
212 QFETCH(DataContainer, expectedData);
213
213
214 ArrayData<2> arrayData{inputData};
214 ArrayData<2> arrayData{inputData};
215 auto sortedArrayData = arrayData.sort(sortPermutation);
215 auto sortedArrayData = arrayData.sort(sortPermutation);
216 QVERIFY(sortedArrayData != nullptr);
216 QVERIFY(sortedArrayData != nullptr);
217
217
218 for (auto i = 0; i < expectedData.size(); ++i) {
218 for (auto i = 0; i < expectedData.size(); ++i) {
219 QVERIFY(sortedArrayData->data(i) == expectedData.at(i));
219 QVERIFY(sortedArrayData->data(i) == expectedData.at(i));
220 }
220 }
221 }
221 }
222
222
223 QTEST_MAIN(TestTwoDimArrayData)
223 QTEST_MAIN(TestTwoDimArrayData)
224 #include "TestTwoDimArrayData.moc"
224 #include "TestTwoDimArrayData.moc"
@@ -1,80 +1,83
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);
33 void addVariable(std::shared_ptr<Variable> variable);
34 void addVariableUsingGraph(std::shared_ptr<Variable> variable);
34 void addVariableUsingGraph(std::shared_ptr<Variable> variable);
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 SqpRange graphRange() const noexcept;
39 SqpRange graphRange() const noexcept;
40 void setGraphRange(const SqpRange &range);
40 void setGraphRange(const SqpRange &range);
41
41
42 // IVisualizationWidget interface
42 // IVisualizationWidget interface
43 void accept(IVisualizationWidgetVisitor *visitor) override;
43 void accept(IVisualizationWidgetVisitor *visitor) override;
44 bool canDrop(const Variable &variable) const override;
44 bool canDrop(const Variable &variable) const override;
45 bool contains(const Variable &variable) const override;
45 bool contains(const Variable &variable) const override;
46 QString name() const override;
46 QString name() const override;
47
47
48
48
49 signals:
49 signals:
50 void synchronize(const SqpRange &range, const SqpRange &oldRange);
50 void synchronize(const SqpRange &range, const SqpRange &oldRange);
51 void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range,
51 void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range,
52 const SqpRange &oldRange, bool synchronise);
52 const SqpRange &oldRange, bool synchronise);
53
53
54
54
55 void variableAdded(std::shared_ptr<Variable> var);
56
57
55 private:
58 private:
56 Ui::VisualizationGraphWidget *ui;
59 Ui::VisualizationGraphWidget *ui;
57
60
58 class VisualizationGraphWidgetPrivate;
61 class VisualizationGraphWidgetPrivate;
59 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
62 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
60
63
61 private slots:
64 private slots:
62 /// Slot called when right clicking on the graph (displays a menu)
65 /// Slot called when right clicking on the graph (displays a menu)
63 void onGraphMenuRequested(const QPoint &pos) noexcept;
66 void onGraphMenuRequested(const QPoint &pos) noexcept;
64
67
65 /// Rescale the X axe to range parameter
68 /// Rescale the X axe to range parameter
66 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
69 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
67
70
68 /// Slot called when a mouse move was made
71 /// Slot called when a mouse move was made
69 void onMouseMove(QMouseEvent *event) noexcept;
72 void onMouseMove(QMouseEvent *event) noexcept;
70 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
73 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
71 void onMouseWheel(QWheelEvent *event) noexcept;
74 void onMouseWheel(QWheelEvent *event) noexcept;
72 /// Slot called when a mouse press was made, to activate the calibration of a graph
75 /// Slot called when a mouse press was made, to activate the calibration of a graph
73 void onMousePress(QMouseEvent *event) noexcept;
76 void onMousePress(QMouseEvent *event) noexcept;
74 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
77 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
75 void onMouseRelease(QMouseEvent *event) noexcept;
78 void onMouseRelease(QMouseEvent *event) noexcept;
76
79
77 void onDataCacheVariableUpdated();
80 void onDataCacheVariableUpdated();
78 };
81 };
79
82
80 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
83 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,52 +1,56
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
46 private slots:
47 void onVariableAdded(std::shared_ptr<Variable> variable);
48
45 private:
49 private:
46 Ui::VisualizationZoneWidget *ui;
50 Ui::VisualizationZoneWidget *ui;
47
51
48 class VisualizationZoneWidgetPrivate;
52 class VisualizationZoneWidgetPrivate;
49 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
53 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
50 };
54 };
51
55
52 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
56 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -1,321 +1,307
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 }
83 }
84
84
85
85
86 VisualizationGraphWidget::~VisualizationGraphWidget()
86 VisualizationGraphWidget::~VisualizationGraphWidget()
87 {
87 {
88 delete ui;
88 delete ui;
89 }
89 }
90
90
91 void VisualizationGraphWidget::enableAcquisition(bool enable)
91 void VisualizationGraphWidget::enableAcquisition(bool enable)
92 {
92 {
93 impl->m_DoAcquisition = enable;
93 impl->m_DoAcquisition = enable;
94 }
94 }
95
95
96 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
96 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
97 {
97 {
98 auto calibrationState = impl->m_IsCalibration;
99 impl->m_IsCalibration = true;
98 // Uses delegate to create the qcpplot components according to the variable
100 // Uses delegate to create the qcpplot components according to the variable
99 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
101 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
102 impl->m_IsCalibration = calibrationState;
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()));
109
110 emit variableAdded(variable);
106 }
111 }
107 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
112 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
108 {
113 {
109 // TODO
114 // Uses delegate to create the qcpplot components according to the variable
110 // // when adding a variable, we need to set its time range to the current graph range
115 this->addVariable(variable);
111 // auto grapheRange = ui->widget->xAxis->range();
112 // auto dateTime = SqpRange{grapheRange.lower, grapheRange.upper};
113 // variable->setDateTime(dateTime);
114
115 // auto variableDateTimeWithTolerance = dateTime;
116
117 // // add tolerance for each side
118 // auto toleranceFactor
119 // = toleranceValue(GENERAL_TOLERANCE_AT_INIT_KEY,
120 // GENERAL_TOLERANCE_AT_INIT_DEFAULT_VALUE);
121 // auto tolerance = toleranceFactor * (dateTime.m_TEnd - dateTime.m_TStart);
122 // variableDateTimeWithTolerance.m_TStart -= tolerance;
123 // variableDateTimeWithTolerance.m_TEnd += tolerance;
124
125 // // Uses delegate to create the qcpplot components according to the variable
126 // auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
127
128 // for (auto createdPlottable : qAsConst(createdPlottables)) {
129 // impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
130 // }
131
116
132 // connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
117 // Request range for the variable
118 auto graphRange = ui->widget->xAxis->range();
133
119
134 // // CHangement detected, we need to ask controller to request data loading
120 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable,
135 // emit requestDataLoading(variable, variableDateTimeWithTolerance);
121 SqpRange{graphRange.lower, graphRange.upper}, variable->range(), false);
136 }
122 }
137
123
138 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
124 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
139 {
125 {
140 // Each component associated to the variable :
126 // Each component associated to the variable :
141 // - is removed from qcpplot (which deletes it)
127 // - is removed from qcpplot (which deletes it)
142 // - is no longer referenced in the map
128 // - is no longer referenced in the map
143 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
129 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
144 for (auto it = componentsIt.first; it != componentsIt.second;) {
130 for (auto it = componentsIt.first; it != componentsIt.second;) {
145 ui->widget->removePlottable(it->second);
131 ui->widget->removePlottable(it->second);
146 it = impl->m_VariableToPlotMultiMap.erase(it);
132 it = impl->m_VariableToPlotMultiMap.erase(it);
147 }
133 }
148
134
149 // Updates graph
135 // Updates graph
150 ui->widget->replot();
136 ui->widget->replot();
151 }
137 }
152
138
153 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable, const SqpRange &range)
139 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable, const SqpRange &range)
154 {
140 {
155 // Note: in case of different axes that depends on variable, we could start with a code like
141 // Note: in case of different axes that depends on variable, we could start with a code like
156 // that:
142 // that:
157 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
143 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
158 // for (auto it = componentsIt.first; it != componentsIt.second;) {
144 // for (auto it = componentsIt.first; it != componentsIt.second;) {
159 // }
145 // }
160 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
146 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
161 ui->widget->replot();
147 ui->widget->replot();
162 }
148 }
163
149
164 SqpRange VisualizationGraphWidget::graphRange() const noexcept
150 SqpRange VisualizationGraphWidget::graphRange() const noexcept
165 {
151 {
166 auto grapheRange = ui->widget->xAxis->range();
152 auto grapheRange = ui->widget->xAxis->range();
167 return SqpRange{grapheRange.lower, grapheRange.upper};
153 return SqpRange{grapheRange.lower, grapheRange.upper};
168 }
154 }
169
155
170 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
156 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
171 {
157 {
172 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
158 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
173 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
159 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
174 ui->widget->replot();
160 ui->widget->replot();
175 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
161 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
176 }
162 }
177
163
178 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
164 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
179 {
165 {
180 if (visitor) {
166 if (visitor) {
181 visitor->visit(this);
167 visitor->visit(this);
182 }
168 }
183 else {
169 else {
184 qCCritical(LOG_VisualizationGraphWidget())
170 qCCritical(LOG_VisualizationGraphWidget())
185 << tr("Can't visit widget : the visitor is null");
171 << tr("Can't visit widget : the visitor is null");
186 }
172 }
187 }
173 }
188
174
189 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
175 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
190 {
176 {
191 /// @todo : for the moment, a graph can always accomodate a variable
177 /// @todo : for the moment, a graph can always accomodate a variable
192 Q_UNUSED(variable);
178 Q_UNUSED(variable);
193 return true;
179 return true;
194 }
180 }
195
181
196 bool VisualizationGraphWidget::contains(const Variable &variable) const
182 bool VisualizationGraphWidget::contains(const Variable &variable) const
197 {
183 {
198 // Finds the variable among the keys of the map
184 // Finds the variable among the keys of the map
199 auto variablePtr = &variable;
185 auto variablePtr = &variable;
200 auto findVariable
186 auto findVariable
201 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
187 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
202
188
203 auto end = impl->m_VariableToPlotMultiMap.cend();
189 auto end = impl->m_VariableToPlotMultiMap.cend();
204 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
190 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
205 return it != end;
191 return it != end;
206 }
192 }
207
193
208 QString VisualizationGraphWidget::name() const
194 QString VisualizationGraphWidget::name() const
209 {
195 {
210 return ui->graphNameLabel->text();
196 return ui->graphNameLabel->text();
211 }
197 }
212
198
213 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
199 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
214 {
200 {
215 QMenu graphMenu{};
201 QMenu graphMenu{};
216
202
217 // Iterates on variables (unique keys)
203 // Iterates on variables (unique keys)
218 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
204 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
219 end = impl->m_VariableToPlotMultiMap.cend();
205 end = impl->m_VariableToPlotMultiMap.cend();
220 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
206 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
221 // 'Remove variable' action
207 // 'Remove variable' action
222 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
208 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
223 [ this, var = it->first ]() { removeVariable(var); });
209 [ this, var = it->first ]() { removeVariable(var); });
224 }
210 }
225
211
226 if (!graphMenu.isEmpty()) {
212 if (!graphMenu.isEmpty()) {
227 graphMenu.exec(mapToGlobal(pos));
213 graphMenu.exec(mapToGlobal(pos));
228 }
214 }
229 }
215 }
230
216
231 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
217 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
232 {
218 {
233 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
219 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
234 << QThread::currentThread()->objectName() << "DoAcqui"
220 << QThread::currentThread()->objectName() << "DoAcqui"
235 << impl->m_DoAcquisition;
221 << impl->m_DoAcquisition;
236
222
237 auto graphRange = SqpRange{t1.lower, t1.upper};
223 auto graphRange = SqpRange{t1.lower, t1.upper};
238 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
224 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
239
225
240 if (impl->m_DoAcquisition) {
226 if (impl->m_DoAcquisition) {
241 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
227 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
242
228
243 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
229 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
244 end = impl->m_VariableToPlotMultiMap.end();
230 end = impl->m_VariableToPlotMultiMap.end();
245 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
231 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
246 variableUnderGraphVector.push_back(it->first);
232 variableUnderGraphVector.push_back(it->first);
247 }
233 }
248 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
234 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
249 !impl->m_IsCalibration);
235 !impl->m_IsCalibration);
250
236
251 if (!impl->m_IsCalibration) {
237 if (!impl->m_IsCalibration) {
252 qCDebug(LOG_VisualizationGraphWidget())
238 qCInfo(LOG_VisualizationGraphWidget())
253 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
239 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
254 << QThread::currentThread()->objectName();
240 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
255 emit synchronize(graphRange, oldGraphRange);
241 emit synchronize(graphRange, oldGraphRange);
256 }
242 }
257 }
243 }
258 }
244 }
259
245
260 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
246 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
261 {
247 {
262 // Handles plot rendering when mouse is moving
248 // Handles plot rendering when mouse is moving
263 impl->m_RenderingDelegate->onMouseMove(event);
249 impl->m_RenderingDelegate->onMouseMove(event);
264 }
250 }
265
251
266 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
252 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
267 {
253 {
268 auto zoomOrientations = QFlags<Qt::Orientation>{};
254 auto zoomOrientations = QFlags<Qt::Orientation>{};
269
255
270 // Lambda that enables a zoom orientation if the key modifier related to this orientation
256 // Lambda that enables a zoom orientation if the key modifier related to this orientation
271 // has
257 // has
272 // been pressed
258 // been pressed
273 auto enableOrientation
259 auto enableOrientation
274 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
260 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
275 auto orientationEnabled = event->modifiers().testFlag(modifier);
261 auto orientationEnabled = event->modifiers().testFlag(modifier);
276 zoomOrientations.setFlag(orientation, orientationEnabled);
262 zoomOrientations.setFlag(orientation, orientationEnabled);
277 };
263 };
278 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
264 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
279 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
265 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
280
266
281 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
267 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
282 }
268 }
283
269
284 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
270 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
285 {
271 {
286 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
272 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
287 }
273 }
288
274
289 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
275 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
290 {
276 {
291 impl->m_IsCalibration = false;
277 impl->m_IsCalibration = false;
292 }
278 }
293
279
294 void VisualizationGraphWidget::onDataCacheVariableUpdated()
280 void VisualizationGraphWidget::onDataCacheVariableUpdated()
295 {
281 {
296 // NOTE:
282 // NOTE:
297 // We don't want to call the method for each component of a variable unitarily, but for
283 // We don't want to call the method for each component of a variable unitarily, but for
298 // all
284 // all
299 // its components at once (eg its three components in the case of a vector).
285 // its components at once (eg its three components in the case of a vector).
300
286
301 // The unordered_multimap does not do this easily, so the question is whether to:
287 // The unordered_multimap does not do this easily, so the question is whether to:
302 // - use an ordered_multimap and the algos of std to group the values by key
288 // - use an ordered_multimap and the algos of std to group the values by key
303 // - use a map (unique keys) and store as values directly the list of components
289 // - use a map (unique keys) and store as values directly the list of components
304
290
305 auto grapheRange = ui->widget->xAxis->range();
291 auto grapheRange = ui->widget->xAxis->range();
306 auto dateTime = SqpRange{grapheRange.lower, grapheRange.upper};
292 auto dateTime = SqpRange{grapheRange.lower, grapheRange.upper};
307
293
308 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
294 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
309 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
295 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
310 auto variable = it->first;
296 auto variable = it->first;
311 qCDebug(LOG_VisualizationGraphWidget())
297 qCDebug(LOG_VisualizationGraphWidget())
312 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
298 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
313 qCDebug(LOG_VisualizationGraphWidget())
299 qCDebug(LOG_VisualizationGraphWidget())
314 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
300 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
315 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
301 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
316
302
317 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
303 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
318 variable->dataSeries(), variable->range());
304 variable->dataSeries(), variable->range());
319 }
305 }
320 }
306 }
321 }
307 }
@@ -1,215 +1,225
1 #include "Visualization/VisualizationZoneWidget.h"
1 #include "Visualization/VisualizationZoneWidget.h"
2
2
3
3
4 #include "Visualization/IVisualizationWidgetVisitor.h"
4 #include "Visualization/IVisualizationWidgetVisitor.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/VariableController.h>
9 #include <Variable/VariableController.h>
10
10
11 #include <QUuid>
11 #include <QUuid>
12 #include <SqpApplication.h>
12 #include <SqpApplication.h>
13
13
14 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
14 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
15
15
16 namespace {
16 namespace {
17
17
18 /// Minimum height for graph added in zones (in pixels)
18 /// Minimum height for graph added in zones (in pixels)
19 const auto GRAPH_MINIMUM_HEIGHT = 300;
19 const auto GRAPH_MINIMUM_HEIGHT = 300;
20
20
21 /// Generates a default name for a new graph, according to the number of graphs already displayed in
21 /// Generates a default name for a new graph, according to the number of graphs already displayed in
22 /// the zone
22 /// the zone
23 QString defaultGraphName(const QLayout &layout)
23 QString defaultGraphName(const QLayout &layout)
24 {
24 {
25 auto count = 0;
25 auto count = 0;
26 for (auto i = 0; i < layout.count(); ++i) {
26 for (auto i = 0; i < layout.count(); ++i) {
27 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
27 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
28 count++;
28 count++;
29 }
29 }
30 }
30 }
31
31
32 return QObject::tr("Graph %1").arg(count + 1);
32 return QObject::tr("Graph %1").arg(count + 1);
33 }
33 }
34
34
35 } // namespace
35 } // namespace
36
36
37 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
37 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
38
38
39 explicit VisualizationZoneWidgetPrivate() : m_SynchronisationGroupId{QUuid::createUuid()} {}
39 explicit VisualizationZoneWidgetPrivate() : m_SynchronisationGroupId{QUuid::createUuid()} {}
40 QUuid m_SynchronisationGroupId;
40 QUuid m_SynchronisationGroupId;
41 };
41 };
42
42
43 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
43 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
44 : QWidget{parent},
44 : QWidget{parent},
45 ui{new Ui::VisualizationZoneWidget},
45 ui{new Ui::VisualizationZoneWidget},
46 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
46 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
47 {
47 {
48 ui->setupUi(this);
48 ui->setupUi(this);
49
49
50 ui->zoneNameLabel->setText(name);
50 ui->zoneNameLabel->setText(name);
51
51
52 // 'Close' options : widget is deleted when closed
52 // 'Close' options : widget is deleted when closed
53 setAttribute(Qt::WA_DeleteOnClose);
53 setAttribute(Qt::WA_DeleteOnClose);
54 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
54 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
55 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
55 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
56
56
57 // Synchronisation id
57 // Synchronisation id
58 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
58 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
59 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
59 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
60 }
60 }
61
61
62 VisualizationZoneWidget::~VisualizationZoneWidget()
62 VisualizationZoneWidget::~VisualizationZoneWidget()
63 {
63 {
64 delete ui;
64 delete ui;
65 }
65 }
66
66
67 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
67 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
68 {
68 {
69 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
69 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
70 }
70 }
71
71
72 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
72 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
73 {
73 {
74 auto graphWidget = new VisualizationGraphWidget{
74 auto graphWidget = new VisualizationGraphWidget{
75 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
75 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
76
76
77
77
78 // Set graph properties
78 // Set graph properties
79 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
79 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
80 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
80 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
81
81
82 this->addGraph(graphWidget);
83
84 graphWidget->addVariable(variable);
85
82
86 // Lambda to synchronize zone widget
83 // Lambda to synchronize zone widget
87 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &grapheRange,
84 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &grapheRange,
88 const SqpRange &oldGraphRange) {
85 const SqpRange &oldGraphRange) {
89
86
90 auto zoomType = VariableController::getZoomType(grapheRange, oldGraphRange);
87 auto zoomType = VariableController::getZoomType(grapheRange, oldGraphRange);
91 auto frameLayout = ui->visualizationZoneFrame->layout();
88 auto frameLayout = ui->visualizationZoneFrame->layout();
92 for (auto i = 0; i < frameLayout->count(); ++i) {
89 for (auto i = 0; i < frameLayout->count(); ++i) {
93 auto graphChild
90 auto graphChild
94 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
91 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
95 if (graphChild && (graphChild != graphWidget)) {
92 if (graphChild && (graphChild != graphWidget)) {
96
93
97 auto graphChildRange = graphChild->graphRange();
94 auto graphChildRange = graphChild->graphRange();
98 switch (zoomType) {
95 switch (zoomType) {
99 case AcquisitionZoomType::ZoomIn: {
96 case AcquisitionZoomType::ZoomIn: {
100 auto deltaLeft = grapheRange.m_TStart - oldGraphRange.m_TStart;
97 auto deltaLeft = grapheRange.m_TStart - oldGraphRange.m_TStart;
101 auto deltaRight = oldGraphRange.m_TEnd - grapheRange.m_TEnd;
98 auto deltaRight = oldGraphRange.m_TEnd - grapheRange.m_TEnd;
102 graphChildRange.m_TStart += deltaLeft;
99 graphChildRange.m_TStart += deltaLeft;
103 graphChildRange.m_TEnd -= deltaRight;
100 graphChildRange.m_TEnd -= deltaRight;
104 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
101 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
105 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
102 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
106 << deltaLeft;
103 << deltaLeft;
107 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
104 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
108 << deltaRight;
105 << deltaRight;
109 qCCritical(LOG_VisualizationZoneWidget())
106 qCCritical(LOG_VisualizationZoneWidget())
110 << tr("TORM: dt") << grapheRange.m_TEnd - grapheRange.m_TStart;
107 << tr("TORM: dt") << grapheRange.m_TEnd - grapheRange.m_TStart;
111
108
112 break;
109 break;
113 }
110 }
114
111
115 case AcquisitionZoomType::ZoomOut: {
112 case AcquisitionZoomType::ZoomOut: {
116 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
113 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
117 auto deltaLeft = oldGraphRange.m_TStart - grapheRange.m_TStart;
114 auto deltaLeft = oldGraphRange.m_TStart - grapheRange.m_TStart;
118 auto deltaRight = grapheRange.m_TEnd - oldGraphRange.m_TEnd;
115 auto deltaRight = grapheRange.m_TEnd - oldGraphRange.m_TEnd;
119 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
116 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
120 << deltaLeft;
117 << deltaLeft;
121 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
118 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
122 << deltaRight;
119 << deltaRight;
123 qCCritical(LOG_VisualizationZoneWidget())
120 qCCritical(LOG_VisualizationZoneWidget())
124 << tr("TORM: dt") << grapheRange.m_TEnd - grapheRange.m_TStart;
121 << tr("TORM: dt") << grapheRange.m_TEnd - grapheRange.m_TStart;
125 graphChildRange.m_TStart -= deltaLeft;
122 graphChildRange.m_TStart -= deltaLeft;
126 graphChildRange.m_TEnd += deltaRight;
123 graphChildRange.m_TEnd += deltaRight;
127 break;
124 break;
128 }
125 }
129 case AcquisitionZoomType::PanRight: {
126 case AcquisitionZoomType::PanRight: {
130 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
127 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
131 auto deltaRight = grapheRange.m_TEnd - oldGraphRange.m_TEnd;
128 auto deltaRight = grapheRange.m_TEnd - oldGraphRange.m_TEnd;
132 graphChildRange.m_TStart += deltaRight;
129 graphChildRange.m_TStart += deltaRight;
133 graphChildRange.m_TEnd += deltaRight;
130 graphChildRange.m_TEnd += deltaRight;
134 qCCritical(LOG_VisualizationZoneWidget())
131 qCCritical(LOG_VisualizationZoneWidget())
135 << tr("TORM: dt") << grapheRange.m_TEnd - grapheRange.m_TStart;
132 << tr("TORM: dt") << grapheRange.m_TEnd - grapheRange.m_TStart;
136 break;
133 break;
137 }
134 }
138 case AcquisitionZoomType::PanLeft: {
135 case AcquisitionZoomType::PanLeft: {
139 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
136 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
140 auto deltaLeft = oldGraphRange.m_TStart - grapheRange.m_TStart;
137 auto deltaLeft = oldGraphRange.m_TStart - grapheRange.m_TStart;
141 graphChildRange.m_TStart -= deltaLeft;
138 graphChildRange.m_TStart -= deltaLeft;
142 graphChildRange.m_TEnd -= deltaLeft;
139 graphChildRange.m_TEnd -= deltaLeft;
143 break;
140 break;
144 }
141 }
145 case AcquisitionZoomType::Unknown: {
142 case AcquisitionZoomType::Unknown: {
146 qCCritical(LOG_VisualizationZoneWidget())
143 qCCritical(LOG_VisualizationZoneWidget())
147 << tr("Impossible to synchronize: zoom type unknown");
144 << tr("Impossible to synchronize: zoom type unknown");
148 break;
145 break;
149 }
146 }
150 default:
147 default:
151 qCCritical(LOG_VisualizationZoneWidget())
148 qCCritical(LOG_VisualizationZoneWidget())
152 << tr("Impossible to synchronize: zoom type not take into account");
149 << tr("Impossible to synchronize: zoom type not take into account");
153 // No action
150 // No action
154 break;
151 break;
155 }
152 }
156 graphChild->enableAcquisition(false);
153 graphChild->enableAcquisition(false);
157 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
154 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
158 << graphChild->graphRange();
155 << graphChild->graphRange();
159 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
156 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
160 << graphChildRange;
157 << graphChildRange;
161 qCCritical(LOG_VisualizationZoneWidget())
158 qCCritical(LOG_VisualizationZoneWidget())
162 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
159 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
163 graphChild->setGraphRange(graphChildRange);
160 graphChild->setGraphRange(graphChildRange);
164 graphChild->enableAcquisition(true);
161 graphChild->enableAcquisition(true);
165 }
162 }
166 }
163 }
167 };
164 };
168
165
169 // connection for synchronization
166 // connection for synchronization
170 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
167 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
168 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
169 &VisualizationZoneWidget::onVariableAdded);
170
171 this->addGraph(graphWidget);
172
173 graphWidget->addVariable(variable);
171
174
172 return graphWidget;
175 return graphWidget;
173 }
176 }
174
177
175 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
178 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
176 {
179 {
177 if (visitor) {
180 if (visitor) {
178 visitor->visitEnter(this);
181 visitor->visitEnter(this);
179
182
180 // Apply visitor to graph children
183 // Apply visitor to graph children
181 auto layout = ui->visualizationZoneFrame->layout();
184 auto layout = ui->visualizationZoneFrame->layout();
182 for (auto i = 0; i < layout->count(); ++i) {
185 for (auto i = 0; i < layout->count(); ++i) {
183 if (auto item = layout->itemAt(i)) {
186 if (auto item = layout->itemAt(i)) {
184 // Widgets different from graphs are not visited (no action)
187 // Widgets different from graphs are not visited (no action)
185 if (auto visualizationGraphWidget
188 if (auto visualizationGraphWidget
186 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
189 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
187 visualizationGraphWidget->accept(visitor);
190 visualizationGraphWidget->accept(visitor);
188 }
191 }
189 }
192 }
190 }
193 }
191
194
192 visitor->visitLeave(this);
195 visitor->visitLeave(this);
193 }
196 }
194 else {
197 else {
195 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
198 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
196 }
199 }
197 }
200 }
198
201
199 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
202 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
200 {
203 {
201 // A tab can always accomodate a variable
204 // A tab can always accomodate a variable
202 Q_UNUSED(variable);
205 Q_UNUSED(variable);
203 return true;
206 return true;
204 }
207 }
205
208
206 bool VisualizationZoneWidget::contains(const Variable &variable) const
209 bool VisualizationZoneWidget::contains(const Variable &variable) const
207 {
210 {
208 Q_UNUSED(variable);
211 Q_UNUSED(variable);
209 return false;
212 return false;
210 }
213 }
211
214
212 QString VisualizationZoneWidget::name() const
215 QString VisualizationZoneWidget::name() const
213 {
216 {
214 return ui->zoneNameLabel->text();
217 return ui->zoneNameLabel->text();
215 }
218 }
219
220 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
221 {
222 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
223 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
224 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
225 }
@@ -1,147 +1,148
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaDefs.h"
2 #include "AmdaDefs.h"
3 #include "AmdaResultParser.h"
3 #include "AmdaResultParser.h"
4
4
5 #include <Common/DateUtils.h>
5 #include <Common/DateUtils.h>
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10
10
11 #include <QNetworkAccessManager>
11 #include <QNetworkAccessManager>
12 #include <QNetworkReply>
12 #include <QNetworkReply>
13 #include <QTemporaryFile>
13 #include <QTemporaryFile>
14 #include <QThread>
14 #include <QThread>
15
15
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
17
17
18 namespace {
18 namespace {
19
19
20 /// URL format for a request on AMDA server. The parameters are as follows:
20 /// URL format for a request on AMDA server. The parameters are as follows:
21 /// - %1: start date
21 /// - %1: start date
22 /// - %2: end date
22 /// - %2: end date
23 /// - %3: parameter id
23 /// - %3: parameter id
24 const auto AMDA_URL_FORMAT = QStringLiteral(
24 const auto AMDA_URL_FORMAT = QStringLiteral(
25 "http://amda.irap.omp.eu/php/rest/"
25 "http://amda.irap.omp.eu/php/rest/"
26 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
26 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
27 "timeFormat=ISO8601&gzip=0");
27 "timeFormat=ISO8601&gzip=0");
28
28
29 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
29 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
30 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
30 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
31
31
32 /// Formats a time to a date that can be passed in URL
32 /// Formats a time to a date that can be passed in URL
33 QString dateFormat(double sqpRange) noexcept
33 QString dateFormat(double sqpRange) noexcept
34 {
34 {
35 auto dateTime = DateUtils::dateTime(sqpRange);
35 auto dateTime = DateUtils::dateTime(sqpRange);
36 return dateTime.toString(AMDA_TIME_FORMAT);
36 return dateTime.toString(AMDA_TIME_FORMAT);
37 }
37 }
38
38
39 } // namespace
39 } // namespace
40
40
41 AmdaProvider::AmdaProvider()
41 AmdaProvider::AmdaProvider()
42 {
42 {
43 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
43 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
44 if (auto app = sqpApp) {
44 if (auto app = sqpApp) {
45 auto &networkController = app->networkController();
45 auto &networkController = app->networkController();
46 connect(this, SIGNAL(requestConstructed(QNetworkRequest, QUuid,
46 connect(this, SIGNAL(requestConstructed(QNetworkRequest, QUuid,
47 std::function<void(QNetworkReply *, QUuid)>)),
47 std::function<void(QNetworkReply *, QUuid)>)),
48 &networkController,
48 &networkController,
49 SLOT(onProcessRequested(QNetworkRequest, QUuid,
49 SLOT(onProcessRequested(QNetworkRequest, QUuid,
50 std::function<void(QNetworkReply *, QUuid)>)));
50 std::function<void(QNetworkReply *, QUuid)>)));
51
51
52
52
53 connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this,
53 connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this,
54 SIGNAL(dataProvidedProgress(QUuid, double)));
54 SIGNAL(dataProvidedProgress(QUuid, double)));
55 }
55 }
56 }
56 }
57
57
58 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
58 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
59 {
59 {
60 // NOTE: Try to use multithread if possible
60 // NOTE: Try to use multithread if possible
61 const auto times = parameters.m_Times;
61 const auto times = parameters.m_Times;
62 const auto data = parameters.m_Data;
62 const auto data = parameters.m_Data;
63 for (const auto &dateTime : qAsConst(times)) {
63 for (const auto &dateTime : qAsConst(times)) {
64 retrieveData(acqIdentifier, dateTime, data);
64 this->retrieveData(acqIdentifier, dateTime, data);
65 QThread::msleep(200);
65 }
66 }
66 }
67 }
67
68
68 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
69 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
69 {
70 {
70 if (auto app = sqpApp) {
71 if (auto app = sqpApp) {
71 auto &networkController = app->networkController();
72 auto &networkController = app->networkController();
72 networkController.onReplyCanceled(acqIdentifier);
73 networkController.onReplyCanceled(acqIdentifier);
73 }
74 }
74 }
75 }
75
76
76 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
77 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
77 {
78 {
78 // Retrieves product ID from data: if the value is invalid, no request is made
79 // Retrieves product ID from data: if the value is invalid, no request is made
79 auto productId = data.value(AMDA_XML_ID_KEY).toString();
80 auto productId = data.value(AMDA_XML_ID_KEY).toString();
80 if (productId.isNull()) {
81 if (productId.isNull()) {
81 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
82 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
82 return;
83 return;
83 }
84 }
84 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
85 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
85
86
86 // /////////// //
87 // /////////// //
87 // Creates URL //
88 // Creates URL //
88 // /////////// //
89 // /////////// //
89
90
90 auto startDate = dateFormat(dateTime.m_TStart);
91 auto startDate = dateFormat(dateTime.m_TStart);
91 auto endDate = dateFormat(dateTime.m_TEnd);
92 auto endDate = dateFormat(dateTime.m_TEnd);
92
93
93 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
94 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
94 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData url:") << url;
95 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData url:") << url;
95 auto tempFile = std::make_shared<QTemporaryFile>();
96 auto tempFile = std::make_shared<QTemporaryFile>();
96
97
97 // LAMBDA
98 // LAMBDA
98 auto httpDownloadFinished
99 auto httpDownloadFinished
99 = [this, dateTime, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
100 = [this, dateTime, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
100
101
101 // Don't do anything if the reply was abort
102 // Don't do anything if the reply was abort
102 if (reply->error() != QNetworkReply::OperationCanceledError) {
103 if (reply->error() != QNetworkReply::OperationCanceledError) {
103
104
104 if (tempFile) {
105 if (tempFile) {
105 auto replyReadAll = reply->readAll();
106 auto replyReadAll = reply->readAll();
106 if (!replyReadAll.isEmpty()) {
107 if (!replyReadAll.isEmpty()) {
107 tempFile->write(replyReadAll);
108 tempFile->write(replyReadAll);
108 }
109 }
109 tempFile->close();
110 tempFile->close();
110
111
111 // Parse results file
112 // Parse results file
112 if (auto dataSeries = AmdaResultParser::readTxt(tempFile->fileName())) {
113 if (auto dataSeries = AmdaResultParser::readTxt(tempFile->fileName())) {
113 emit dataProvided(dataId, dataSeries, dateTime);
114 emit dataProvided(dataId, dataSeries, dateTime);
114 }
115 }
115 else {
116 else {
116 /// @todo ALX : debug
117 /// @todo ALX : debug
117 }
118 }
118 }
119 }
119 }
120 }
120
121
121 };
122 };
122 auto httpFinishedLambda
123 auto httpFinishedLambda
123 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
124 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
124
125
125 // Don't do anything if the reply was abort
126 // Don't do anything if the reply was abort
126 if (reply->error() != QNetworkReply::OperationCanceledError) {
127 if (reply->error() != QNetworkReply::OperationCanceledError) {
127 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
128 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
128
129
129
130
130 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData downloadFileUrl:")
131 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData downloadFileUrl:")
131 << downloadFileUrl;
132 << downloadFileUrl;
132 // Executes request for downloading file //
133 // Executes request for downloading file //
133
134
134 // Creates destination file
135 // Creates destination file
135 if (tempFile->open()) {
136 if (tempFile->open()) {
136 // Executes request
137 // Executes request
137 emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId,
138 emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId,
138 httpDownloadFinished);
139 httpDownloadFinished);
139 }
140 }
140 }
141 }
141 };
142 };
142
143
143 // //////////////// //
144 // //////////////// //
144 // Executes request //
145 // Executes request //
145 // //////////////// //
146 // //////////////// //
146 emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda);
147 emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda);
147 }
148 }
General Comments 0
You need to be logged in to leave comments. Login now