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