##// END OF EJS Templates
Adds variable to model
Alexandre Leroux -
r652:9aa695e50c87
parent child
Show More
@@ -1,81 +1,89
1 #ifndef SCIQLOP_VARIABLEMODEL_H
1 #ifndef SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/SqpRange.h>
6 #include <Data/SqpRange.h>
7
7
8 #include <QAbstractTableModel>
8 #include <QAbstractTableModel>
9 #include <QLoggingCategory>
9 #include <QLoggingCategory>
10
10
11 #include <Common/MetaTypes.h>
11 #include <Common/MetaTypes.h>
12 #include <Common/spimpl.h>
12 #include <Common/spimpl.h>
13
13
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
15
15
16 enum VariableRoles { ProgressRole = Qt::UserRole };
16 enum VariableRoles { ProgressRole = Qt::UserRole };
17
17
18
18
19 class IDataSeries;
19 class IDataSeries;
20 class Variable;
20 class Variable;
21
21
22 /**
22 /**
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
24 */
24 */
25 class SCIQLOP_CORE_EXPORT VariableModel : public QAbstractTableModel {
25 class SCIQLOP_CORE_EXPORT VariableModel : public QAbstractTableModel {
26 Q_OBJECT
26 Q_OBJECT
27 public:
27 public:
28 explicit VariableModel(QObject *parent = nullptr);
28 explicit VariableModel(QObject *parent = nullptr);
29
29
30 /**
30 /**
31 * Adds an existing variable in the model.
32 * @param variable the variable to add.
33 * @remarks the variable's name is modified to avoid name duplicates
34 * @remarks this method does nothing if the variable already exists in the model
35 */
36 void addVariable(std::shared_ptr<Variable> variable) noexcept;
37
38 /**
31 * Creates a new variable in the model
39 * Creates a new variable in the model
32 * @param name the name of the new variable
40 * @param name the name of the new variable
33 * @param dateTime the dateTime of the new variable
41 * @param dateTime the dateTime of the new variable
34 * @param metadata the metadata associated to the new variable
42 * @param metadata the metadata associated to the new variable
35 * @return the pointer to the new variable
43 * @return the pointer to the new variable
36 */
44 */
37 std::shared_ptr<Variable> createVariable(const QString &name, const SqpRange &dateTime,
45 std::shared_ptr<Variable> createVariable(const QString &name, const SqpRange &dateTime,
38 const QVariantHash &metadata) noexcept;
46 const QVariantHash &metadata) noexcept;
39
47
40 /**
48 /**
41 * Deletes a variable from the model, if it exists
49 * Deletes a variable from the model, if it exists
42 * @param variable the variable to delete
50 * @param variable the variable to delete
43 */
51 */
44 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
52 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
45
53
46
54
47 std::shared_ptr<Variable> variable(int index) const;
55 std::shared_ptr<Variable> variable(int index) const;
48 std::vector<std::shared_ptr<Variable> > variables() const;
56 std::vector<std::shared_ptr<Variable> > variables() const;
49
57
50 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
58 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
51
59
52
60
53 // /////////////////////////// //
61 // /////////////////////////// //
54 // QAbstractTableModel methods //
62 // QAbstractTableModel methods //
55 // /////////////////////////// //
63 // /////////////////////////// //
56
64
57 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
65 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
58 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
66 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
59 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
67 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
60 virtual QVariant headerData(int section, Qt::Orientation orientation,
68 virtual QVariant headerData(int section, Qt::Orientation orientation,
61 int role = Qt::DisplayRole) const override;
69 int role = Qt::DisplayRole) const override;
62
70
63
71
64 void abortProgress(const QModelIndex &index);
72 void abortProgress(const QModelIndex &index);
65
73
66 signals:
74 signals:
67 void abortProgessRequested(std::shared_ptr<Variable> variable);
75 void abortProgessRequested(std::shared_ptr<Variable> variable);
68
76
69 private:
77 private:
70 class VariableModelPrivate;
78 class VariableModelPrivate;
71 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
79 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
72
80
73 private slots:
81 private slots:
74 /// Slot called when data of a variable has been updated
82 /// Slot called when data of a variable has been updated
75 void onVariableUpdated() noexcept;
83 void onVariableUpdated() noexcept;
76 };
84 };
77
85
78 // Registers QVector<int> metatype so it can be used in VariableModel::dataChanged() signal
86 // Registers QVector<int> metatype so it can be used in VariableModel::dataChanged() signal
79 SCIQLOP_REGISTER_META_TYPE(QVECTOR_INT_REGISTRY, QVector<int>)
87 SCIQLOP_REGISTER_META_TYPE(QVECTOR_INT_REGISTRY, QVector<int>)
80
88
81 #endif // SCIQLOP_VARIABLEMODEL_H
89 #endif // SCIQLOP_VARIABLEMODEL_H
@@ -1,752 +1,755
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 #include <Variable/VariableAcquisitionWorker.h>
3 #include <Variable/VariableCacheStrategy.h>
3 #include <Variable/VariableCacheStrategy.h>
4 #include <Variable/VariableController.h>
4 #include <Variable/VariableController.h>
5 #include <Variable/VariableModel.h>
5 #include <Variable/VariableModel.h>
6 #include <Variable/VariableSynchronizationGroup.h>
6 #include <Variable/VariableSynchronizationGroup.h>
7
7
8 #include <Data/DataProviderParameters.h>
8 #include <Data/DataProviderParameters.h>
9 #include <Data/IDataProvider.h>
9 #include <Data/IDataProvider.h>
10 #include <Data/IDataSeries.h>
10 #include <Data/IDataSeries.h>
11 #include <Data/VariableRequest.h>
11 #include <Data/VariableRequest.h>
12 #include <Time/TimeController.h>
12 #include <Time/TimeController.h>
13
13
14 #include <QMutex>
14 #include <QMutex>
15 #include <QThread>
15 #include <QThread>
16 #include <QUuid>
16 #include <QUuid>
17 #include <QtCore/QItemSelectionModel>
17 #include <QtCore/QItemSelectionModel>
18
18
19 #include <deque>
19 #include <deque>
20 #include <set>
20 #include <set>
21 #include <unordered_map>
21 #include <unordered_map>
22
22
23 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
23 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
24
24
25 namespace {
25 namespace {
26
26
27 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
27 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
28 const SqpRange &oldGraphRange)
28 const SqpRange &oldGraphRange)
29 {
29 {
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
31
31
32 auto varRangeRequested = varRange;
32 auto varRangeRequested = varRange;
33 switch (zoomType) {
33 switch (zoomType) {
34 case AcquisitionZoomType::ZoomIn: {
34 case AcquisitionZoomType::ZoomIn: {
35 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
35 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
36 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
36 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
37 varRangeRequested.m_TStart += deltaLeft;
37 varRangeRequested.m_TStart += deltaLeft;
38 varRangeRequested.m_TEnd -= deltaRight;
38 varRangeRequested.m_TEnd -= deltaRight;
39 break;
39 break;
40 }
40 }
41
41
42 case AcquisitionZoomType::ZoomOut: {
42 case AcquisitionZoomType::ZoomOut: {
43 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
43 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
44 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
44 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
45 varRangeRequested.m_TStart -= deltaLeft;
45 varRangeRequested.m_TStart -= deltaLeft;
46 varRangeRequested.m_TEnd += deltaRight;
46 varRangeRequested.m_TEnd += deltaRight;
47 break;
47 break;
48 }
48 }
49 case AcquisitionZoomType::PanRight: {
49 case AcquisitionZoomType::PanRight: {
50 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
50 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
51 varRangeRequested.m_TStart += deltaRight;
51 varRangeRequested.m_TStart += deltaRight;
52 varRangeRequested.m_TEnd += deltaRight;
52 varRangeRequested.m_TEnd += deltaRight;
53 break;
53 break;
54 }
54 }
55 case AcquisitionZoomType::PanLeft: {
55 case AcquisitionZoomType::PanLeft: {
56 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
56 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
57 varRangeRequested.m_TStart -= deltaLeft;
57 varRangeRequested.m_TStart -= deltaLeft;
58 varRangeRequested.m_TEnd -= deltaLeft;
58 varRangeRequested.m_TEnd -= deltaLeft;
59 break;
59 break;
60 }
60 }
61 case AcquisitionZoomType::Unknown: {
61 case AcquisitionZoomType::Unknown: {
62 qCCritical(LOG_VariableController())
62 qCCritical(LOG_VariableController())
63 << VariableController::tr("Impossible to synchronize: zoom type unknown");
63 << VariableController::tr("Impossible to synchronize: zoom type unknown");
64 break;
64 break;
65 }
65 }
66 default:
66 default:
67 qCCritical(LOG_VariableController()) << VariableController::tr(
67 qCCritical(LOG_VariableController()) << VariableController::tr(
68 "Impossible to synchronize: zoom type not take into account");
68 "Impossible to synchronize: zoom type not take into account");
69 // No action
69 // No action
70 break;
70 break;
71 }
71 }
72
72
73 return varRangeRequested;
73 return varRangeRequested;
74 }
74 }
75 }
75 }
76
76
77 struct VariableController::VariableControllerPrivate {
77 struct VariableController::VariableControllerPrivate {
78 explicit VariableControllerPrivate(VariableController *parent)
78 explicit VariableControllerPrivate(VariableController *parent)
79 : m_WorkingMutex{},
79 : m_WorkingMutex{},
80 m_VariableModel{new VariableModel{parent}},
80 m_VariableModel{new VariableModel{parent}},
81 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
81 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
84 q{parent}
84 q{parent}
85 {
85 {
86
86
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
89 }
89 }
90
90
91
91
92 virtual ~VariableControllerPrivate()
92 virtual ~VariableControllerPrivate()
93 {
93 {
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
95 m_VariableAcquisitionWorkerThread.quit();
95 m_VariableAcquisitionWorkerThread.quit();
96 m_VariableAcquisitionWorkerThread.wait();
96 m_VariableAcquisitionWorkerThread.wait();
97 }
97 }
98
98
99
99
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
101 QUuid varRequestId);
101 QUuid varRequestId);
102
102
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
104 const SqpRange &dateTime);
104 const SqpRange &dateTime);
105
105
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
107 std::shared_ptr<IDataSeries>
107 std::shared_ptr<IDataSeries>
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
109
109
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
111
111
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
114 void updateVariableRequest(QUuid varRequestId);
114 void updateVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
116
116
117 QMutex m_WorkingMutex;
117 QMutex m_WorkingMutex;
118 /// Variable model. The VariableController has the ownership
118 /// Variable model. The VariableController has the ownership
119 VariableModel *m_VariableModel;
119 VariableModel *m_VariableModel;
120 QItemSelectionModel *m_VariableSelectionModel;
120 QItemSelectionModel *m_VariableSelectionModel;
121
121
122
122
123 TimeController *m_TimeController{nullptr};
123 TimeController *m_TimeController{nullptr};
124 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
124 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
125 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
125 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
126 QThread m_VariableAcquisitionWorkerThread;
126 QThread m_VariableAcquisitionWorkerThread;
127
127
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
129 m_VariableToProviderMap;
129 m_VariableToProviderMap;
130 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
130 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
131 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
131 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
132 m_GroupIdToVariableSynchronizationGroupMap;
132 m_GroupIdToVariableSynchronizationGroupMap;
133 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
133 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
135
135
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
137
137
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
139
139
140
140
141 VariableController *q;
141 VariableController *q;
142 };
142 };
143
143
144
144
145 VariableController::VariableController(QObject *parent)
145 VariableController::VariableController(QObject *parent)
146 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
146 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
147 {
147 {
148 qCDebug(LOG_VariableController()) << tr("VariableController construction")
148 qCDebug(LOG_VariableController()) << tr("VariableController construction")
149 << QThread::currentThread();
149 << QThread::currentThread();
150
150
151 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
151 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
152 &VariableController::onAbortProgressRequested);
152 &VariableController::onAbortProgressRequested);
153
153
154 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
154 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
155 &VariableController::onDataProvided);
155 &VariableController::onDataProvided);
156 connect(impl->m_VariableAcquisitionWorker.get(),
156 connect(impl->m_VariableAcquisitionWorker.get(),
157 &VariableAcquisitionWorker::variableRequestInProgress, this,
157 &VariableAcquisitionWorker::variableRequestInProgress, this,
158 &VariableController::onVariableRetrieveDataInProgress);
158 &VariableController::onVariableRetrieveDataInProgress);
159
159
160 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
160 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
161 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
161 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
162 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
162 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
163 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
163 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
164
164
165
165
166 impl->m_VariableAcquisitionWorkerThread.start();
166 impl->m_VariableAcquisitionWorkerThread.start();
167 }
167 }
168
168
169 VariableController::~VariableController()
169 VariableController::~VariableController()
170 {
170 {
171 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
171 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
172 << QThread::currentThread();
172 << QThread::currentThread();
173 this->waitForFinish();
173 this->waitForFinish();
174 }
174 }
175
175
176 VariableModel *VariableController::variableModel() noexcept
176 VariableModel *VariableController::variableModel() noexcept
177 {
177 {
178 return impl->m_VariableModel;
178 return impl->m_VariableModel;
179 }
179 }
180
180
181 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
181 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
182 {
182 {
183 return impl->m_VariableSelectionModel;
183 return impl->m_VariableSelectionModel;
184 }
184 }
185
185
186 void VariableController::setTimeController(TimeController *timeController) noexcept
186 void VariableController::setTimeController(TimeController *timeController) noexcept
187 {
187 {
188 impl->m_TimeController = timeController;
188 impl->m_TimeController = timeController;
189 }
189 }
190
190
191 std::shared_ptr<Variable>
191 std::shared_ptr<Variable>
192 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
192 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
193 {
193 {
194 // Clones variable
194 // Clones variable
195 auto duplicate = variable->clone();
195 auto duplicate = variable->clone();
196
196
197 // Adds clone to model
198 impl->m_VariableModel->addVariable(duplicate);
199
197 return duplicate;
200 return duplicate;
198 }
201 }
199
202
200 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
203 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
201 {
204 {
202 if (!variable) {
205 if (!variable) {
203 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
206 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
204 return;
207 return;
205 }
208 }
206
209
207 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
210 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
208 // make some treatments before the deletion
211 // make some treatments before the deletion
209 emit variableAboutToBeDeleted(variable);
212 emit variableAboutToBeDeleted(variable);
210
213
211 // Deletes identifier
214 // Deletes identifier
212 impl->m_VariableToIdentifierMap.erase(variable);
215 impl->m_VariableToIdentifierMap.erase(variable);
213
216
214 // Deletes provider
217 // Deletes provider
215 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
218 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
216 qCDebug(LOG_VariableController())
219 qCDebug(LOG_VariableController())
217 << tr("Number of providers deleted for variable %1: %2")
220 << tr("Number of providers deleted for variable %1: %2")
218 .arg(variable->name(), QString::number(nbProvidersDeleted));
221 .arg(variable->name(), QString::number(nbProvidersDeleted));
219
222
220
223
221 // Deletes from model
224 // Deletes from model
222 impl->m_VariableModel->deleteVariable(variable);
225 impl->m_VariableModel->deleteVariable(variable);
223 }
226 }
224
227
225 void VariableController::deleteVariables(
228 void VariableController::deleteVariables(
226 const QVector<std::shared_ptr<Variable> > &variables) noexcept
229 const QVector<std::shared_ptr<Variable> > &variables) noexcept
227 {
230 {
228 for (auto variable : qAsConst(variables)) {
231 for (auto variable : qAsConst(variables)) {
229 deleteVariable(variable);
232 deleteVariable(variable);
230 }
233 }
231 }
234 }
232
235
233 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
236 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
234 {
237 {
235 }
238 }
236
239
237 std::shared_ptr<Variable>
240 std::shared_ptr<Variable>
238 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
241 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
239 std::shared_ptr<IDataProvider> provider) noexcept
242 std::shared_ptr<IDataProvider> provider) noexcept
240 {
243 {
241 if (!impl->m_TimeController) {
244 if (!impl->m_TimeController) {
242 qCCritical(LOG_VariableController())
245 qCCritical(LOG_VariableController())
243 << tr("Impossible to create variable: The time controller is null");
246 << tr("Impossible to create variable: The time controller is null");
244 return nullptr;
247 return nullptr;
245 }
248 }
246
249
247 auto range = impl->m_TimeController->dateTime();
250 auto range = impl->m_TimeController->dateTime();
248
251
249 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
252 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
250 auto identifier = QUuid::createUuid();
253 auto identifier = QUuid::createUuid();
251
254
252 // store the provider
255 // store the provider
253 impl->registerProvider(provider);
256 impl->registerProvider(provider);
254
257
255 // Associate the provider
258 // Associate the provider
256 impl->m_VariableToProviderMap[newVariable] = provider;
259 impl->m_VariableToProviderMap[newVariable] = provider;
257 impl->m_VariableToIdentifierMap[newVariable] = identifier;
260 impl->m_VariableToIdentifierMap[newVariable] = identifier;
258
261
259
262
260 auto varRequestId = QUuid::createUuid();
263 auto varRequestId = QUuid::createUuid();
261 qCInfo(LOG_VariableController()) << "processRequest for" << name << varRequestId;
264 qCInfo(LOG_VariableController()) << "processRequest for" << name << varRequestId;
262 impl->processRequest(newVariable, range, varRequestId);
265 impl->processRequest(newVariable, range, varRequestId);
263 impl->updateVariableRequest(varRequestId);
266 impl->updateVariableRequest(varRequestId);
264
267
265 return newVariable;
268 return newVariable;
266 }
269 }
267 }
270 }
268
271
269 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
272 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
270 {
273 {
271 // TODO check synchronisation and Rescale
274 // TODO check synchronisation and Rescale
272 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
275 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
273 << QThread::currentThread()->objectName();
276 << QThread::currentThread()->objectName();
274 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
277 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
275 auto varRequestId = QUuid::createUuid();
278 auto varRequestId = QUuid::createUuid();
276
279
277 for (const auto &selectedRow : qAsConst(selectedRows)) {
280 for (const auto &selectedRow : qAsConst(selectedRows)) {
278 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
281 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
279 selectedVariable->setRange(dateTime);
282 selectedVariable->setRange(dateTime);
280 impl->processRequest(selectedVariable, dateTime, varRequestId);
283 impl->processRequest(selectedVariable, dateTime, varRequestId);
281
284
282 // notify that rescale operation has to be done
285 // notify that rescale operation has to be done
283 emit rangeChanged(selectedVariable, dateTime);
286 emit rangeChanged(selectedVariable, dateTime);
284 }
287 }
285 }
288 }
286 impl->updateVariableRequest(varRequestId);
289 impl->updateVariableRequest(varRequestId);
287 }
290 }
288
291
289 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
292 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
290 const SqpRange &cacheRangeRequested,
293 const SqpRange &cacheRangeRequested,
291 QVector<AcquisitionDataPacket> dataAcquired)
294 QVector<AcquisitionDataPacket> dataAcquired)
292 {
295 {
293 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
296 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
294 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
297 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
295 if (!varRequestId.isNull()) {
298 if (!varRequestId.isNull()) {
296 impl->updateVariableRequest(varRequestId);
299 impl->updateVariableRequest(varRequestId);
297 }
300 }
298 }
301 }
299
302
300 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
303 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
301 {
304 {
302 if (auto var = impl->findVariable(identifier)) {
305 if (auto var = impl->findVariable(identifier)) {
303 impl->m_VariableModel->setDataProgress(var, progress);
306 impl->m_VariableModel->setDataProgress(var, progress);
304 }
307 }
305 else {
308 else {
306 qCCritical(LOG_VariableController())
309 qCCritical(LOG_VariableController())
307 << tr("Impossible to notify progression of a null variable");
310 << tr("Impossible to notify progression of a null variable");
308 }
311 }
309 }
312 }
310
313
311 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
314 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
312 {
315 {
313 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
316 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
314 << QThread::currentThread()->objectName();
317 << QThread::currentThread()->objectName();
315
318
316 auto it = impl->m_VariableToIdentifierMap.find(variable);
319 auto it = impl->m_VariableToIdentifierMap.find(variable);
317 if (it != impl->m_VariableToIdentifierMap.cend()) {
320 if (it != impl->m_VariableToIdentifierMap.cend()) {
318 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
321 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
319 }
322 }
320 else {
323 else {
321 qCWarning(LOG_VariableController())
324 qCWarning(LOG_VariableController())
322 << tr("Aborting progression of inexistant variable detected !!!")
325 << tr("Aborting progression of inexistant variable detected !!!")
323 << QThread::currentThread()->objectName();
326 << QThread::currentThread()->objectName();
324 }
327 }
325 }
328 }
326
329
327 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
330 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
328 {
331 {
329 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
332 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
330 << QThread::currentThread()->objectName()
333 << QThread::currentThread()->objectName()
331 << synchronizationGroupId;
334 << synchronizationGroupId;
332 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
335 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
333 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
336 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
334 std::make_pair(synchronizationGroupId, vSynchroGroup));
337 std::make_pair(synchronizationGroupId, vSynchroGroup));
335 }
338 }
336
339
337 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
340 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
338 {
341 {
339 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
342 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
340 }
343 }
341
344
342 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
345 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
343 QUuid synchronizationGroupId)
346 QUuid synchronizationGroupId)
344
347
345 {
348 {
346 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
349 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
347 << synchronizationGroupId;
350 << synchronizationGroupId;
348 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
351 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
349 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
352 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
350 auto groupIdToVSGIt
353 auto groupIdToVSGIt
351 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
354 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
352 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
355 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
353 impl->m_VariableIdGroupIdMap.insert(
356 impl->m_VariableIdGroupIdMap.insert(
354 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
357 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
355 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
358 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
356 }
359 }
357 else {
360 else {
358 qCCritical(LOG_VariableController())
361 qCCritical(LOG_VariableController())
359 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
362 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
360 << variable->name();
363 << variable->name();
361 }
364 }
362 }
365 }
363 else {
366 else {
364 qCCritical(LOG_VariableController())
367 qCCritical(LOG_VariableController())
365 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
368 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
366 }
369 }
367 }
370 }
368
371
369
372
370 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
373 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
371 const SqpRange &range, const SqpRange &oldRange,
374 const SqpRange &range, const SqpRange &oldRange,
372 bool synchronise)
375 bool synchronise)
373 {
376 {
374 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
377 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
375
378
376 // we want to load data of the variable for the dateTime.
379 // we want to load data of the variable for the dateTime.
377 // First we check if the cache contains some of them.
380 // First we check if the cache contains some of them.
378 // For the other, we ask the provider to give them.
381 // For the other, we ask the provider to give them.
379
382
380 auto varRequestId = QUuid::createUuid();
383 auto varRequestId = QUuid::createUuid();
381 qCInfo(LOG_VariableController()) << "VariableController::onRequestDataLoading"
384 qCInfo(LOG_VariableController()) << "VariableController::onRequestDataLoading"
382 << QThread::currentThread()->objectName() << varRequestId;
385 << QThread::currentThread()->objectName() << varRequestId;
383
386
384 for (const auto &var : variables) {
387 for (const auto &var : variables) {
385 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
388 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
386 impl->processRequest(var, range, varRequestId);
389 impl->processRequest(var, range, varRequestId);
387 }
390 }
388
391
389 if (synchronise) {
392 if (synchronise) {
390 // Get the group ids
393 // Get the group ids
391 qCDebug(LOG_VariableController())
394 qCDebug(LOG_VariableController())
392 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
395 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
393 auto groupIds = std::set<QUuid>{};
396 auto groupIds = std::set<QUuid>{};
394 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
397 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
395 for (const auto &var : variables) {
398 for (const auto &var : variables) {
396 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
399 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
397 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
400 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
398 auto vId = varToVarIdIt->second;
401 auto vId = varToVarIdIt->second;
399 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
402 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
400 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
403 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
401 auto gId = varIdToGroupIdIt->second;
404 auto gId = varIdToGroupIdIt->second;
402 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
405 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
403 if (groupIds.find(gId) == groupIds.cend()) {
406 if (groupIds.find(gId) == groupIds.cend()) {
404 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
407 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
405 groupIds.insert(gId);
408 groupIds.insert(gId);
406 }
409 }
407 }
410 }
408 }
411 }
409 }
412 }
410
413
411 // We assume here all group ids exist
414 // We assume here all group ids exist
412 for (const auto &gId : groupIds) {
415 for (const auto &gId : groupIds) {
413 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
416 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
414 auto vSyncIds = vSynchronizationGroup->getIds();
417 auto vSyncIds = vSynchronizationGroup->getIds();
415 qCDebug(LOG_VariableController()) << "Var in synchro group ";
418 qCDebug(LOG_VariableController()) << "Var in synchro group ";
416 for (auto vId : vSyncIds) {
419 for (auto vId : vSyncIds) {
417 auto var = impl->findVariable(vId);
420 auto var = impl->findVariable(vId);
418
421
419 // Don't process already processed var
422 // Don't process already processed var
420 if (!variables.contains(var)) {
423 if (!variables.contains(var)) {
421 if (var != nullptr) {
424 if (var != nullptr) {
422 qCDebug(LOG_VariableController()) << "processRequest synchro for"
425 qCDebug(LOG_VariableController()) << "processRequest synchro for"
423 << var->name();
426 << var->name();
424 auto vSyncRangeRequested = computeSynchroRangeRequested(
427 auto vSyncRangeRequested = computeSynchroRangeRequested(
425 var->range(), range, groupIdToOldRangeMap.at(gId));
428 var->range(), range, groupIdToOldRangeMap.at(gId));
426 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
429 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
427 impl->processRequest(var, vSyncRangeRequested, varRequestId);
430 impl->processRequest(var, vSyncRangeRequested, varRequestId);
428 }
431 }
429 else {
432 else {
430 qCCritical(LOG_VariableController())
433 qCCritical(LOG_VariableController())
431
434
432 << tr("Impossible to synchronize a null variable");
435 << tr("Impossible to synchronize a null variable");
433 }
436 }
434 }
437 }
435 }
438 }
436 }
439 }
437 }
440 }
438
441
439 impl->updateVariableRequest(varRequestId);
442 impl->updateVariableRequest(varRequestId);
440 }
443 }
441
444
442
445
443 void VariableController::initialize()
446 void VariableController::initialize()
444 {
447 {
445 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
448 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
446 impl->m_WorkingMutex.lock();
449 impl->m_WorkingMutex.lock();
447 qCDebug(LOG_VariableController()) << tr("VariableController init END");
450 qCDebug(LOG_VariableController()) << tr("VariableController init END");
448 }
451 }
449
452
450 void VariableController::finalize()
453 void VariableController::finalize()
451 {
454 {
452 impl->m_WorkingMutex.unlock();
455 impl->m_WorkingMutex.unlock();
453 }
456 }
454
457
455 void VariableController::waitForFinish()
458 void VariableController::waitForFinish()
456 {
459 {
457 QMutexLocker locker{&impl->m_WorkingMutex};
460 QMutexLocker locker{&impl->m_WorkingMutex};
458 }
461 }
459
462
460 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
463 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
461 {
464 {
462 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
465 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
463 auto zoomType = AcquisitionZoomType::Unknown;
466 auto zoomType = AcquisitionZoomType::Unknown;
464 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
467 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
465 zoomType = AcquisitionZoomType::ZoomOut;
468 zoomType = AcquisitionZoomType::ZoomOut;
466 }
469 }
467 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
470 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
468 zoomType = AcquisitionZoomType::PanRight;
471 zoomType = AcquisitionZoomType::PanRight;
469 }
472 }
470 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
473 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
471 zoomType = AcquisitionZoomType::PanLeft;
474 zoomType = AcquisitionZoomType::PanLeft;
472 }
475 }
473 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
476 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
474 zoomType = AcquisitionZoomType::ZoomIn;
477 zoomType = AcquisitionZoomType::ZoomIn;
475 }
478 }
476 else {
479 else {
477 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
480 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
478 }
481 }
479 return zoomType;
482 return zoomType;
480 }
483 }
481
484
482 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
485 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
483 const SqpRange &rangeRequested,
486 const SqpRange &rangeRequested,
484 QUuid varRequestId)
487 QUuid varRequestId)
485 {
488 {
486
489
487 // TODO: protect at
490 // TODO: protect at
488 auto varRequest = VariableRequest{};
491 auto varRequest = VariableRequest{};
489 auto varId = m_VariableToIdentifierMap.at(var);
492 auto varId = m_VariableToIdentifierMap.at(var);
490
493
491 auto varStrategyRangesRequested
494 auto varStrategyRangesRequested
492 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
495 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
493 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
496 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
494 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
497 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
495
498
496 if (!notInCacheRangeList.empty()) {
499 if (!notInCacheRangeList.empty()) {
497 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
500 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
498 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
501 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
499 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest RR ") << rangeRequested;
502 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest RR ") << rangeRequested;
500 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest R ")
503 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest R ")
501 << varStrategyRangesRequested.first;
504 << varStrategyRangesRequested.first;
502 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest CR ")
505 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest CR ")
503 << varStrategyRangesRequested.second;
506 << varStrategyRangesRequested.second;
504 // store VarRequest
507 // store VarRequest
505 storeVariableRequest(varId, varRequestId, varRequest);
508 storeVariableRequest(varId, varRequestId, varRequest);
506
509
507 auto varProvider = m_VariableToProviderMap.at(var);
510 auto varProvider = m_VariableToProviderMap.at(var);
508 if (varProvider != nullptr) {
511 if (varProvider != nullptr) {
509 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
512 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
510 varRequestId, varId, varStrategyRangesRequested.first,
513 varRequestId, varId, varStrategyRangesRequested.first,
511 varStrategyRangesRequested.second,
514 varStrategyRangesRequested.second,
512 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
515 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
513 varProvider);
516 varProvider);
514
517
515 if (!varRequestIdCanceled.isNull()) {
518 if (!varRequestIdCanceled.isNull()) {
516 qCInfo(LOG_VariableAcquisitionWorker()) << tr("varRequestIdCanceled: ")
519 qCInfo(LOG_VariableAcquisitionWorker()) << tr("varRequestIdCanceled: ")
517 << varRequestIdCanceled;
520 << varRequestIdCanceled;
518 cancelVariableRequest(varRequestIdCanceled);
521 cancelVariableRequest(varRequestIdCanceled);
519 }
522 }
520 }
523 }
521 else {
524 else {
522 qCCritical(LOG_VariableController())
525 qCCritical(LOG_VariableController())
523 << "Impossible to provide data with a null provider";
526 << "Impossible to provide data with a null provider";
524 }
527 }
525
528
526 if (!inCacheRangeList.empty()) {
529 if (!inCacheRangeList.empty()) {
527 emit q->updateVarDisplaying(var, inCacheRangeList.first());
530 emit q->updateVarDisplaying(var, inCacheRangeList.first());
528 }
531 }
529 }
532 }
530 else {
533 else {
531
534
532 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
535 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
533 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
536 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
534 // store VarRequest
537 // store VarRequest
535 storeVariableRequest(varId, varRequestId, varRequest);
538 storeVariableRequest(varId, varRequestId, varRequest);
536 acceptVariableRequest(varId,
539 acceptVariableRequest(varId,
537 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
540 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
538 }
541 }
539 }
542 }
540
543
541 std::shared_ptr<Variable>
544 std::shared_ptr<Variable>
542 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
545 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
543 {
546 {
544 std::shared_ptr<Variable> var;
547 std::shared_ptr<Variable> var;
545 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
548 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
546
549
547 auto end = m_VariableToIdentifierMap.cend();
550 auto end = m_VariableToIdentifierMap.cend();
548 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
551 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
549 if (it != end) {
552 if (it != end) {
550 var = it->first;
553 var = it->first;
551 }
554 }
552 else {
555 else {
553 qCCritical(LOG_VariableController())
556 qCCritical(LOG_VariableController())
554 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
557 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
555 }
558 }
556
559
557 return var;
560 return var;
558 }
561 }
559
562
560 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
563 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
561 const QVector<AcquisitionDataPacket> acqDataPacketVector)
564 const QVector<AcquisitionDataPacket> acqDataPacketVector)
562 {
565 {
563 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
566 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
564 << acqDataPacketVector.size();
567 << acqDataPacketVector.size();
565 std::shared_ptr<IDataSeries> dataSeries;
568 std::shared_ptr<IDataSeries> dataSeries;
566 if (!acqDataPacketVector.isEmpty()) {
569 if (!acqDataPacketVector.isEmpty()) {
567 dataSeries = acqDataPacketVector[0].m_DateSeries;
570 dataSeries = acqDataPacketVector[0].m_DateSeries;
568 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
571 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
569 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
572 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
570 }
573 }
571 }
574 }
572 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
575 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
573 << acqDataPacketVector.size();
576 << acqDataPacketVector.size();
574 return dataSeries;
577 return dataSeries;
575 }
578 }
576
579
577 void VariableController::VariableControllerPrivate::registerProvider(
580 void VariableController::VariableControllerPrivate::registerProvider(
578 std::shared_ptr<IDataProvider> provider)
581 std::shared_ptr<IDataProvider> provider)
579 {
582 {
580 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
583 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
581 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
584 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
582 << provider->objectName();
585 << provider->objectName();
583 m_ProviderSet.insert(provider);
586 m_ProviderSet.insert(provider);
584 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
587 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
585 &VariableAcquisitionWorker::onVariableDataAcquired);
588 &VariableAcquisitionWorker::onVariableDataAcquired);
586 connect(provider.get(), &IDataProvider::dataProvidedProgress,
589 connect(provider.get(), &IDataProvider::dataProvidedProgress,
587 m_VariableAcquisitionWorker.get(),
590 m_VariableAcquisitionWorker.get(),
588 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
591 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
589 }
592 }
590 else {
593 else {
591 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
594 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
592 }
595 }
593 }
596 }
594
597
595 void VariableController::VariableControllerPrivate::storeVariableRequest(
598 void VariableController::VariableControllerPrivate::storeVariableRequest(
596 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
599 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
597 {
600 {
598 // First request for the variable. we can create an entry for it
601 // First request for the variable. we can create an entry for it
599 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
602 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
600 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
603 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
601 auto varRequestIdQueue = std::deque<QUuid>{};
604 auto varRequestIdQueue = std::deque<QUuid>{};
602 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
605 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
603 varRequestIdQueue.push_back(varRequestId);
606 varRequestIdQueue.push_back(varRequestId);
604 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
607 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
605 }
608 }
606 else {
609 else {
607 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
610 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
608 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
611 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
609 varRequestIdQueue.push_back(varRequestId);
612 varRequestIdQueue.push_back(varRequestId);
610 }
613 }
611
614
612 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
615 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
613 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
616 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
614 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
617 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
615 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
618 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
616 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
619 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
617 m_VarRequestIdToVarIdVarRequestMap.insert(
620 m_VarRequestIdToVarIdVarRequestMap.insert(
618 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
621 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
619 }
622 }
620 else {
623 else {
621 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
624 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
622 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
625 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
623 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
626 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
624 }
627 }
625 }
628 }
626
629
627 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
630 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
628 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
631 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
629 {
632 {
630 QUuid varRequestId;
633 QUuid varRequestId;
631 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
634 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
632 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
635 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
633 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
636 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
634 varRequestId = varRequestIdQueue.front();
637 varRequestId = varRequestIdQueue.front();
635 auto varRequestIdToVarIdVarRequestMapIt
638 auto varRequestIdToVarIdVarRequestMapIt
636 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
639 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
637 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
640 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
638 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
641 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
639 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
642 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
640 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
643 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
641 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
644 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
642 auto &varRequest = varIdToVarRequestMapIt->second;
645 auto &varRequest = varIdToVarRequestMapIt->second;
643 varRequest.m_DataSeries = dataSeries;
646 varRequest.m_DataSeries = dataSeries;
644 varRequest.m_CanUpdate = true;
647 varRequest.m_CanUpdate = true;
645 }
648 }
646 else {
649 else {
647 qCDebug(LOG_VariableController())
650 qCDebug(LOG_VariableController())
648 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
651 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
649 "to a variableRequestId")
652 "to a variableRequestId")
650 << varRequestId << varId;
653 << varRequestId << varId;
651 }
654 }
652 }
655 }
653 else {
656 else {
654 qCCritical(LOG_VariableController())
657 qCCritical(LOG_VariableController())
655 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
658 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
656 << varRequestId;
659 << varRequestId;
657 }
660 }
658
661
659 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in QUEUE ?")
662 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in QUEUE ?")
660 << varRequestIdQueue.size();
663 << varRequestIdQueue.size();
661 varRequestIdQueue.pop_front();
664 varRequestIdQueue.pop_front();
662 qCDebug(LOG_VariableController()) << tr("2: erase REQUEST in QUEUE ?")
665 qCDebug(LOG_VariableController()) << tr("2: erase REQUEST in QUEUE ?")
663 << varRequestIdQueue.size();
666 << varRequestIdQueue.size();
664 if (varRequestIdQueue.empty()) {
667 if (varRequestIdQueue.empty()) {
665 m_VarIdToVarRequestIdQueueMap.erase(varId);
668 m_VarIdToVarRequestIdQueueMap.erase(varId);
666 }
669 }
667 }
670 }
668 else {
671 else {
669 qCCritical(LOG_VariableController())
672 qCCritical(LOG_VariableController())
670 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
673 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
671 }
674 }
672
675
673 return varRequestId;
676 return varRequestId;
674 }
677 }
675
678
676 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
679 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
677 {
680 {
678
681
679 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
682 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
680 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
683 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
681 bool processVariableUpdate = true;
684 bool processVariableUpdate = true;
682 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
685 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
683 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
686 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
684 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
687 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
685 ++varIdToVarRequestMapIt) {
688 ++varIdToVarRequestMapIt) {
686 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
689 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
687 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
690 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
688 << processVariableUpdate;
691 << processVariableUpdate;
689 }
692 }
690
693
691 if (processVariableUpdate) {
694 if (processVariableUpdate) {
692 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
695 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
693 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
696 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
694 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
697 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
695 auto &varRequest = varIdToVarRequestMapIt->second;
698 auto &varRequest = varIdToVarRequestMapIt->second;
696 var->setRange(varRequest.m_RangeRequested);
699 var->setRange(varRequest.m_RangeRequested);
697 var->setCacheRange(varRequest.m_CacheRangeRequested);
700 var->setCacheRange(varRequest.m_CacheRangeRequested);
698 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
701 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
699 << varRequest.m_RangeRequested;
702 << varRequest.m_RangeRequested;
700 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
703 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
701 << varRequest.m_CacheRangeRequested;
704 << varRequest.m_CacheRangeRequested;
702 var->mergeDataSeries(varRequest.m_DataSeries);
705 var->mergeDataSeries(varRequest.m_DataSeries);
703 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
706 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
704 << varRequest.m_DataSeries->range();
707 << varRequest.m_DataSeries->range();
705 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
708 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
706
709
707 /// @todo MPL: confirm
710 /// @todo MPL: confirm
708 // Variable update is notified only if there is no pending request for it
711 // Variable update is notified only if there is no pending request for it
709 if (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) == 0) {
712 if (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) == 0) {
710 emit var->updated();
713 emit var->updated();
711 }
714 }
712 }
715 }
713 else {
716 else {
714 qCCritical(LOG_VariableController())
717 qCCritical(LOG_VariableController())
715 << tr("Impossible to update data to a null variable");
718 << tr("Impossible to update data to a null variable");
716 }
719 }
717 }
720 }
718
721
719 // cleaning varRequestId
722 // cleaning varRequestId
720 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
723 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
721 << m_VarRequestIdToVarIdVarRequestMap.size();
724 << m_VarRequestIdToVarIdVarRequestMap.size();
722 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
725 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
723 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
726 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
724 << m_VarRequestIdToVarIdVarRequestMap.size();
727 << m_VarRequestIdToVarIdVarRequestMap.size();
725 }
728 }
726 }
729 }
727 else {
730 else {
728 qCCritical(LOG_VariableController())
731 qCCritical(LOG_VariableController())
729 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
732 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
730 }
733 }
731 }
734 }
732
735
733 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
736 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
734 {
737 {
735 // cleaning varRequestId
738 // cleaning varRequestId
736 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
739 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
737
740
738 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
741 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
739 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
742 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
740 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
743 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
741 varRequestIdQueue.erase(
744 varRequestIdQueue.erase(
742 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
745 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
743 varRequestIdQueue.end());
746 varRequestIdQueue.end());
744 if (varRequestIdQueue.empty()) {
747 if (varRequestIdQueue.empty()) {
745 varIdToVarRequestIdQueueMapIt
748 varIdToVarRequestIdQueueMapIt
746 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
749 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
747 }
750 }
748 else {
751 else {
749 ++varIdToVarRequestIdQueueMapIt;
752 ++varIdToVarRequestIdQueueMapIt;
750 }
753 }
751 }
754 }
752 }
755 }
@@ -1,265 +1,269
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableModel.h>
2 #include <Variable/VariableModel.h>
3
3
4 #include <Common/DateUtils.h>
4 #include <Common/DateUtils.h>
5
5
6 #include <Data/IDataSeries.h>
6 #include <Data/IDataSeries.h>
7
7
8 #include <QSize>
8 #include <QSize>
9 #include <unordered_map>
9 #include <unordered_map>
10
10
11 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
11 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
12
12
13 namespace {
13 namespace {
14
14
15 // Column indexes
15 // Column indexes
16 const auto NAME_COLUMN = 0;
16 const auto NAME_COLUMN = 0;
17 const auto TSTART_COLUMN = 1;
17 const auto TSTART_COLUMN = 1;
18 const auto TEND_COLUMN = 2;
18 const auto TEND_COLUMN = 2;
19 const auto UNIT_COLUMN = 3;
19 const auto UNIT_COLUMN = 3;
20 const auto MISSION_COLUMN = 4;
20 const auto MISSION_COLUMN = 4;
21 const auto PLUGIN_COLUMN = 5;
21 const auto PLUGIN_COLUMN = 5;
22 const auto NB_COLUMNS = 6;
22 const auto NB_COLUMNS = 6;
23
23
24 // Column properties
24 // Column properties
25 const auto DEFAULT_HEIGHT = 25;
25 const auto DEFAULT_HEIGHT = 25;
26 const auto DEFAULT_WIDTH = 100;
26 const auto DEFAULT_WIDTH = 100;
27
27
28 struct ColumnProperties {
28 struct ColumnProperties {
29 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
29 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
30 int height = DEFAULT_HEIGHT)
30 int height = DEFAULT_HEIGHT)
31 : m_Name{name}, m_Width{width}, m_Height{height}
31 : m_Name{name}, m_Width{width}, m_Height{height}
32 {
32 {
33 }
33 }
34
34
35 QString m_Name;
35 QString m_Name;
36 int m_Width;
36 int m_Width;
37 int m_Height;
37 int m_Height;
38 };
38 };
39
39
40 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
40 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
41 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
41 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
42 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {UNIT_COLUMN, {QObject::tr("Unit")}},
42 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {UNIT_COLUMN, {QObject::tr("Unit")}},
43 {MISSION_COLUMN, {QObject::tr("Mission")}}, {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
43 {MISSION_COLUMN, {QObject::tr("Mission")}}, {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
44
44
45 /// Format for datetimes
45 /// Format for datetimes
46 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
46 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
47
47
48
48
49 } // namespace
49 } // namespace
50
50
51 struct VariableModel::VariableModelPrivate {
51 struct VariableModel::VariableModelPrivate {
52 /// Variables created in SciQlop
52 /// Variables created in SciQlop
53 std::vector<std::shared_ptr<Variable> > m_Variables;
53 std::vector<std::shared_ptr<Variable> > m_Variables;
54 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
54 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
55
55
56 /// Return the row index of the variable. -1 if it's not found
56 /// Return the row index of the variable. -1 if it's not found
57 int indexOfVariable(Variable *variable) const noexcept;
57 int indexOfVariable(Variable *variable) const noexcept;
58 };
58 };
59
59
60 VariableModel::VariableModel(QObject *parent)
60 VariableModel::VariableModel(QObject *parent)
61 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
61 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
62 {
62 {
63 }
63 }
64
64
65 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
65 void VariableModel::addVariable(std::shared_ptr<Variable> variable) noexcept
66 const SqpRange &dateTime,
67 const QVariantHash &metadata) noexcept
68 {
66 {
69 auto insertIndex = rowCount();
67 auto insertIndex = rowCount();
70 beginInsertRows({}, insertIndex, insertIndex);
68 beginInsertRows({}, insertIndex, insertIndex);
71
69
72 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
73
74 impl->m_Variables.push_back(variable);
70 impl->m_Variables.push_back(variable);
75 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
71 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
76
72
77 endInsertRows();
73 endInsertRows();
74 }
75
76 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
77 const SqpRange &dateTime,
78 const QVariantHash &metadata) noexcept
79 {
80 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
81 addVariable(variable);
78
82
79 return variable;
83 return variable;
80 }
84 }
81
85
82 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
86 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
83 {
87 {
84 if (!variable) {
88 if (!variable) {
85 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
89 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
86 return;
90 return;
87 }
91 }
88
92
89 // Finds variable in the model
93 // Finds variable in the model
90 auto begin = impl->m_Variables.cbegin();
94 auto begin = impl->m_Variables.cbegin();
91 auto end = impl->m_Variables.cend();
95 auto end = impl->m_Variables.cend();
92 auto it = std::find(begin, end, variable);
96 auto it = std::find(begin, end, variable);
93 if (it != end) {
97 if (it != end) {
94 auto removeIndex = std::distance(begin, it);
98 auto removeIndex = std::distance(begin, it);
95
99
96 // Deletes variable
100 // Deletes variable
97 beginRemoveRows({}, removeIndex, removeIndex);
101 beginRemoveRows({}, removeIndex, removeIndex);
98 impl->m_Variables.erase(it);
102 impl->m_Variables.erase(it);
99 endRemoveRows();
103 endRemoveRows();
100 }
104 }
101 else {
105 else {
102 qCritical(LOG_VariableModel())
106 qCritical(LOG_VariableModel())
103 << tr("Can't delete variable %1 from the model: the variable is not in the model")
107 << tr("Can't delete variable %1 from the model: the variable is not in the model")
104 .arg(variable->name());
108 .arg(variable->name());
105 }
109 }
106
110
107 // Removes variable from progress map
111 // Removes variable from progress map
108 impl->m_VariableToProgress.erase(variable);
112 impl->m_VariableToProgress.erase(variable);
109 }
113 }
110
114
111
115
112 std::shared_ptr<Variable> VariableModel::variable(int index) const
116 std::shared_ptr<Variable> VariableModel::variable(int index) const
113 {
117 {
114 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
118 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
115 }
119 }
116
120
117 std::vector<std::shared_ptr<Variable> > VariableModel::variables() const
121 std::vector<std::shared_ptr<Variable> > VariableModel::variables() const
118 {
122 {
119 return impl->m_Variables;
123 return impl->m_Variables;
120 }
124 }
121
125
122 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
126 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
123 {
127 {
124 if (progress > 0.0) {
128 if (progress > 0.0) {
125 impl->m_VariableToProgress[variable] = progress;
129 impl->m_VariableToProgress[variable] = progress;
126 }
130 }
127 else {
131 else {
128 impl->m_VariableToProgress.erase(variable);
132 impl->m_VariableToProgress.erase(variable);
129 }
133 }
130 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
134 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
131
135
132 emit dataChanged(modelIndex, modelIndex);
136 emit dataChanged(modelIndex, modelIndex);
133 }
137 }
134
138
135 int VariableModel::columnCount(const QModelIndex &parent) const
139 int VariableModel::columnCount(const QModelIndex &parent) const
136 {
140 {
137 Q_UNUSED(parent);
141 Q_UNUSED(parent);
138
142
139 return NB_COLUMNS;
143 return NB_COLUMNS;
140 }
144 }
141
145
142 int VariableModel::rowCount(const QModelIndex &parent) const
146 int VariableModel::rowCount(const QModelIndex &parent) const
143 {
147 {
144 Q_UNUSED(parent);
148 Q_UNUSED(parent);
145
149
146 return impl->m_Variables.size();
150 return impl->m_Variables.size();
147 }
151 }
148
152
149 QVariant VariableModel::data(const QModelIndex &index, int role) const
153 QVariant VariableModel::data(const QModelIndex &index, int role) const
150 {
154 {
151 if (!index.isValid()) {
155 if (!index.isValid()) {
152 return QVariant{};
156 return QVariant{};
153 }
157 }
154
158
155 if (index.row() < 0 || index.row() >= rowCount()) {
159 if (index.row() < 0 || index.row() >= rowCount()) {
156 return QVariant{};
160 return QVariant{};
157 }
161 }
158
162
159 if (role == Qt::DisplayRole) {
163 if (role == Qt::DisplayRole) {
160 if (auto variable = impl->m_Variables.at(index.row()).get()) {
164 if (auto variable = impl->m_Variables.at(index.row()).get()) {
161 switch (index.column()) {
165 switch (index.column()) {
162 case NAME_COLUMN:
166 case NAME_COLUMN:
163 return variable->name();
167 return variable->name();
164 case TSTART_COLUMN: {
168 case TSTART_COLUMN: {
165 auto range = variable->realRange();
169 auto range = variable->realRange();
166 return range != INVALID_RANGE
170 return range != INVALID_RANGE
167 ? DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT)
171 ? DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT)
168 : QVariant{};
172 : QVariant{};
169 }
173 }
170 case TEND_COLUMN: {
174 case TEND_COLUMN: {
171 auto range = variable->realRange();
175 auto range = variable->realRange();
172 return range != INVALID_RANGE
176 return range != INVALID_RANGE
173 ? DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT)
177 ? DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT)
174 : QVariant{};
178 : QVariant{};
175 }
179 }
176 case UNIT_COLUMN:
180 case UNIT_COLUMN:
177 return variable->metadata().value(QStringLiteral("units"));
181 return variable->metadata().value(QStringLiteral("units"));
178 case MISSION_COLUMN:
182 case MISSION_COLUMN:
179 return variable->metadata().value(QStringLiteral("mission"));
183 return variable->metadata().value(QStringLiteral("mission"));
180 case PLUGIN_COLUMN:
184 case PLUGIN_COLUMN:
181 return variable->metadata().value(QStringLiteral("plugin"));
185 return variable->metadata().value(QStringLiteral("plugin"));
182 default:
186 default:
183 // No action
187 // No action
184 break;
188 break;
185 }
189 }
186
190
187 qWarning(LOG_VariableModel())
191 qWarning(LOG_VariableModel())
188 << tr("Can't get data (unknown column %1)").arg(index.column());
192 << tr("Can't get data (unknown column %1)").arg(index.column());
189 }
193 }
190 else {
194 else {
191 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
195 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
192 }
196 }
193 }
197 }
194 else if (role == VariableRoles::ProgressRole) {
198 else if (role == VariableRoles::ProgressRole) {
195 if (auto variable = impl->m_Variables.at(index.row())) {
199 if (auto variable = impl->m_Variables.at(index.row())) {
196
200
197 auto it = impl->m_VariableToProgress.find(variable);
201 auto it = impl->m_VariableToProgress.find(variable);
198 if (it != impl->m_VariableToProgress.cend()) {
202 if (it != impl->m_VariableToProgress.cend()) {
199 return it->second;
203 return it->second;
200 }
204 }
201 }
205 }
202 }
206 }
203
207
204 return QVariant{};
208 return QVariant{};
205 }
209 }
206
210
207 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
211 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
208 {
212 {
209 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
213 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
210 return QVariant{};
214 return QVariant{};
211 }
215 }
212
216
213 if (orientation == Qt::Horizontal) {
217 if (orientation == Qt::Horizontal) {
214 auto propertiesIt = COLUMN_PROPERTIES.find(section);
218 auto propertiesIt = COLUMN_PROPERTIES.find(section);
215 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
219 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
216 // Role is either DisplayRole or SizeHintRole
220 // Role is either DisplayRole or SizeHintRole
217 return (role == Qt::DisplayRole)
221 return (role == Qt::DisplayRole)
218 ? QVariant{propertiesIt->m_Name}
222 ? QVariant{propertiesIt->m_Name}
219 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
223 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
220 }
224 }
221 else {
225 else {
222 qWarning(LOG_VariableModel())
226 qWarning(LOG_VariableModel())
223 << tr("Can't get header data (unknown column %1)").arg(section);
227 << tr("Can't get header data (unknown column %1)").arg(section);
224 }
228 }
225 }
229 }
226
230
227 return QVariant{};
231 return QVariant{};
228 }
232 }
229
233
230 void VariableModel::abortProgress(const QModelIndex &index)
234 void VariableModel::abortProgress(const QModelIndex &index)
231 {
235 {
232 if (auto variable = impl->m_Variables.at(index.row())) {
236 if (auto variable = impl->m_Variables.at(index.row())) {
233 emit abortProgessRequested(variable);
237 emit abortProgessRequested(variable);
234 }
238 }
235 }
239 }
236
240
237 void VariableModel::onVariableUpdated() noexcept
241 void VariableModel::onVariableUpdated() noexcept
238 {
242 {
239 // Finds variable that has been updated in the model
243 // Finds variable that has been updated in the model
240 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
244 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
241 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
245 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
242
246
243 if (updatedVariableIndex > -1) {
247 if (updatedVariableIndex > -1) {
244 emit dataChanged(createIndex(updatedVariableIndex, 0),
248 emit dataChanged(createIndex(updatedVariableIndex, 0),
245 createIndex(updatedVariableIndex, columnCount() - 1));
249 createIndex(updatedVariableIndex, columnCount() - 1));
246 }
250 }
247 }
251 }
248 }
252 }
249
253
250 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
254 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
251 {
255 {
252 auto begin = std::cbegin(m_Variables);
256 auto begin = std::cbegin(m_Variables);
253 auto end = std::cend(m_Variables);
257 auto end = std::cend(m_Variables);
254 auto it
258 auto it
255 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
259 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
256
260
257 if (it != end) {
261 if (it != end) {
258 // Gets the index of the variable in the model: we assume here that views have the same
262 // Gets the index of the variable in the model: we assume here that views have the same
259 // order as the model
263 // order as the model
260 return std::distance(begin, it);
264 return std::distance(begin, it);
261 }
265 }
262 else {
266 else {
263 return -1;
267 return -1;
264 }
268 }
265 }
269 }
General Comments 0
You need to be logged in to leave comments. Login now