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