##// END OF EJS Templates
Merge pull request 292 from SCIQLOP-Initialisation develop...
leroux -
r765:a6dacc853f4a merge
parent child
Show More
@@ -1,108 +1,112
1 1 #ifndef SCIQLOP_SQPITERATOR_H
2 2 #define SCIQLOP_SQPITERATOR_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 /**
7 7 * @brief The SqpIterator class represents an iterator used in SciQlop. It defines all operators
8 8 * needed for a standard forward iterator
9 9 * @tparam T the type of object handled in iterator
10 10 * @sa http://www.cplusplus.com/reference/iterator/
11 11 */
12 12 template <typename T>
13 13 class SCIQLOP_CORE_EXPORT SqpIterator {
14 14 public:
15 15 using iterator_category = std::random_access_iterator_tag;
16 16 using value_type = const T;
17 17 using difference_type = std::ptrdiff_t;
18 18 using pointer = value_type *;
19 19 using reference = value_type &;
20 20
21 21 explicit SqpIterator(T value) : m_CurrentValue{std::move(value)} {}
22 22
23 23 virtual ~SqpIterator() noexcept = default;
24 24 SqpIterator(const SqpIterator &) = default;
25 SqpIterator &operator=(SqpIterator other) { swap(m_CurrentValue, other.m_CurrentValue); }
25 SqpIterator &operator=(SqpIterator other)
26 {
27 swap(m_CurrentValue, other.m_CurrentValue);
28 return *this;
29 }
26 30
27 31 SqpIterator &operator++()
28 32 {
29 33 m_CurrentValue.next();
30 34 return *this;
31 35 }
32 36
33 37 SqpIterator &operator--()
34 38 {
35 39 m_CurrentValue.prev();
36 40 return *this;
37 41 }
38 42
39 43 SqpIterator operator++(int)const
40 44 {
41 45 auto result = *this;
42 46 this->operator++();
43 47 return result;
44 48 }
45 49 SqpIterator operator--(int)const
46 50 {
47 51 auto result = *this;
48 52 this->operator--();
49 53 return result;
50 54 }
51 55
52 56 SqpIterator &operator+=(int offset)
53 57 {
54 58 if (offset >= 0) {
55 59 m_CurrentValue.next(offset);
56 60 }
57 61 else {
58 62 while (offset++) {
59 63 m_CurrentValue.prev();
60 64 }
61 65 }
62 66
63 67 return *this;
64 68 }
65 69 SqpIterator &operator-=(int offset) { return *this += -offset; }
66 70
67 71 SqpIterator operator+(int offset) const
68 72 {
69 73 auto result = *this;
70 74 result += offset;
71 75 return result;
72 76 }
73 77 SqpIterator operator-(int offset) const
74 78 {
75 79 auto result = *this;
76 80 result -= offset;
77 81 return result;
78 82 }
79 83
80 84 int operator-(const SqpIterator &other) const
81 85 {
82 86 return m_CurrentValue.distance(other.m_CurrentValue);
83 87 }
84 88
85 89 const T *operator->() const { return &m_CurrentValue; }
86 90 const T &operator*() const { return m_CurrentValue; }
87 91 T *operator->() { return &m_CurrentValue; }
88 92 T &operator*() { return m_CurrentValue; }
89 93 T &operator[](int offset) const { return m_CurrentValue.advance(offset); }
90 94
91 95 bool operator==(const SqpIterator &other) const
92 96 {
93 97 return m_CurrentValue.equals(other.m_CurrentValue);
94 98 }
95 99 bool operator!=(const SqpIterator &other) const { return !(*this == other); }
96 100 bool operator>(const SqpIterator &other) const { return other.m_CurrentValue.lowerThan(*this); }
97 101 bool operator<(const SqpIterator &other) const
98 102 {
99 103 return m_CurrentValue.lowerThan(other.m_CurrentValue);
100 104 }
101 105 bool operator>=(const SqpIterator &other) const { return !(*this < other); }
102 106 bool operator<=(const SqpIterator &other) const { return !(*this > other); }
103 107
104 108 private:
105 109 T m_CurrentValue;
106 110 };
107 111
108 112 #endif // SCIQLOP_SQPITERATOR_H
@@ -1,84 +1,83
1 1 #include "Data/DataSeriesIterator.h"
2 2
3 3 DataSeriesIteratorValue::DataSeriesIteratorValue(
4 4 std::unique_ptr<DataSeriesIteratorValue::Impl> impl)
5 5 : m_Impl{std::move(impl)}
6 6 {
7 7 }
8 8
9 9 DataSeriesIteratorValue::DataSeriesIteratorValue(const DataSeriesIteratorValue &other)
10 10 : m_Impl{other.m_Impl->clone()}
11 11 {
12 12 }
13 13
14 14 DataSeriesIteratorValue &DataSeriesIteratorValue::operator=(DataSeriesIteratorValue other)
15 15 {
16 16 m_Impl->swap(*other.m_Impl);
17 17 return *this;
18 18 }
19 19
20 20 int DataSeriesIteratorValue::distance(const DataSeriesIteratorValue &other) const
21 21 {
22 auto dist = m_Impl->distance(*other.m_Impl);
23 22 return m_Impl->distance(*other.m_Impl);
24 23 }
25 24
26 25 bool DataSeriesIteratorValue::equals(const DataSeriesIteratorValue &other) const
27 26 {
28 27 return m_Impl->equals(*other.m_Impl);
29 28 }
30 29
31 30 bool DataSeriesIteratorValue::lowerThan(const DataSeriesIteratorValue &other) const
32 31 {
33 32 return m_Impl->lowerThan(*other.m_Impl);
34 33 }
35 34
36 35 DataSeriesIteratorValue DataSeriesIteratorValue::advance(int offset) const
37 36 {
38 37 return DataSeriesIteratorValue{m_Impl->advance(offset)};
39 38 }
40 39
41 40 void DataSeriesIteratorValue::next(int offset)
42 41 {
43 42 m_Impl->next(offset);
44 43 }
45 44
46 45 void DataSeriesIteratorValue::prev()
47 46 {
48 47 m_Impl->prev();
49 48 }
50 49
51 50 double DataSeriesIteratorValue::x() const
52 51 {
53 52 return m_Impl->x();
54 53 }
55 54
56 55 double DataSeriesIteratorValue::value() const
57 56 {
58 57 return m_Impl->value();
59 58 }
60 59
61 60 double DataSeriesIteratorValue::value(int componentIndex) const
62 61 {
63 62 return m_Impl->value(componentIndex);
64 63 }
65 64
66 65 double DataSeriesIteratorValue::minValue() const
67 66 {
68 67 return m_Impl->minValue();
69 68 }
70 69
71 70 double DataSeriesIteratorValue::maxValue() const
72 71 {
73 72 return m_Impl->maxValue();
74 73 }
75 74
76 75 QVector<double> DataSeriesIteratorValue::values() const
77 76 {
78 77 return m_Impl->values();
79 78 }
80 79
81 80 DataSeriesIteratorValue::Impl *DataSeriesIteratorValue::impl()
82 81 {
83 82 return m_Impl.get();
84 83 }
@@ -1,834 +1,839
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(),
155 155 &VariableAcquisitionWorker::variableCanceledRequested, this,
156 156 &VariableController::onAbortAcquisitionRequested);
157 157
158 158 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
159 159 &VariableController::onDataProvided);
160 160 connect(impl->m_VariableAcquisitionWorker.get(),
161 161 &VariableAcquisitionWorker::variableRequestInProgress, this,
162 162 &VariableController::onVariableRetrieveDataInProgress);
163 163
164 164
165 165 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
166 166 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
167 167 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
168 168 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
169 169
170 170
171 171 impl->m_VariableAcquisitionWorkerThread.start();
172 172 }
173 173
174 174 VariableController::~VariableController()
175 175 {
176 176 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
177 177 << QThread::currentThread();
178 178 this->waitForFinish();
179 179 }
180 180
181 181 VariableModel *VariableController::variableModel() noexcept
182 182 {
183 183 return impl->m_VariableModel;
184 184 }
185 185
186 186 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
187 187 {
188 188 return impl->m_VariableSelectionModel;
189 189 }
190 190
191 191 void VariableController::setTimeController(TimeController *timeController) noexcept
192 192 {
193 193 impl->m_TimeController = timeController;
194 194 }
195 195
196 196 std::shared_ptr<Variable>
197 197 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
198 198 {
199 199 if (impl->m_VariableModel->containsVariable(variable)) {
200 200 // Clones variable
201 201 auto duplicate = variable->clone();
202 202
203 203 // Adds clone to model
204 204 impl->m_VariableModel->addVariable(duplicate);
205 205
206 206 // Generates clone identifier
207 207 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
208 208
209 209 // Registers provider
210 210 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
211 211 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
212 212
213 213 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
214 214 if (duplicateProvider) {
215 215 impl->registerProvider(duplicateProvider);
216 216 }
217 217
218 218 return duplicate;
219 219 }
220 220 else {
221 221 qCCritical(LOG_VariableController())
222 222 << tr("Can't create duplicate of variable %1: variable not registered in the model")
223 223 .arg(variable->name());
224 224 return nullptr;
225 225 }
226 226 }
227 227
228 228 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
229 229 {
230 230 if (!variable) {
231 231 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
232 232 return;
233 233 }
234 234
235 235 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
236 236 // make some treatments before the deletion
237 237 emit variableAboutToBeDeleted(variable);
238 238
239 239 // Deletes identifier
240 240 impl->m_VariableToIdentifierMap.erase(variable);
241 241
242 242 // Deletes provider
243 243 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
244 244 qCDebug(LOG_VariableController())
245 245 << tr("Number of providers deleted for variable %1: %2")
246 246 .arg(variable->name(), QString::number(nbProvidersDeleted));
247 247
248 248
249 249 // Deletes from model
250 250 impl->m_VariableModel->deleteVariable(variable);
251 251 }
252 252
253 253 void VariableController::deleteVariables(
254 254 const QVector<std::shared_ptr<Variable> > &variables) noexcept
255 255 {
256 256 for (auto variable : qAsConst(variables)) {
257 257 deleteVariable(variable);
258 258 }
259 259 }
260 260
261 261 std::shared_ptr<Variable>
262 262 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
263 263 std::shared_ptr<IDataProvider> provider) noexcept
264 264 {
265 265 if (!impl->m_TimeController) {
266 266 qCCritical(LOG_VariableController())
267 267 << tr("Impossible to create variable: The time controller is null");
268 268 return nullptr;
269 269 }
270 270
271 271 auto range = impl->m_TimeController->dateTime();
272 272
273 273 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
274 274 auto identifier = QUuid::createUuid();
275 275
276 276 // store the provider
277 277 impl->registerProvider(provider);
278 278
279 279 // Associate the provider
280 280 impl->m_VariableToProviderMap[newVariable] = provider;
281 281 qCInfo(LOG_VariableController()) << "createVariable: " << identifier;
282 282 impl->m_VariableToIdentifierMap[newVariable] = identifier;
283 283
284 284
285 285 auto varRequestId = QUuid::createUuid();
286 286 impl->processRequest(newVariable, range, varRequestId);
287 287 impl->updateVariableRequest(varRequestId);
288 288
289 289 return newVariable;
290 290 }
291 291 }
292 292
293 293 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
294 294 {
295 295 // TODO check synchronisation and Rescale
296 296 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
297 297 << QThread::currentThread()->objectName();
298 298 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
299 299 auto varRequestId = QUuid::createUuid();
300 300
301 301 for (const auto &selectedRow : qAsConst(selectedRows)) {
302 302 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
303 303 selectedVariable->setRange(dateTime);
304 304 impl->processRequest(selectedVariable, dateTime, varRequestId);
305 305
306 306 // notify that rescale operation has to be done
307 307 emit rangeChanged(selectedVariable, dateTime);
308 308 }
309 309 }
310 310 impl->updateVariableRequest(varRequestId);
311 311 }
312 312
313 313 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
314 314 const SqpRange &cacheRangeRequested,
315 315 QVector<AcquisitionDataPacket> dataAcquired)
316 316 {
317 317 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
318 318 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
319 319 if (!varRequestId.isNull()) {
320 320 impl->updateVariableRequest(varRequestId);
321 321 }
322 322 }
323 323
324 324 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
325 325 {
326 326 qCDebug(LOG_VariableController())
327 327 << "TORM: variableController::onVariableRetrieveDataInProgress"
328 328 << QThread::currentThread()->objectName() << progress;
329 329 if (auto var = impl->findVariable(identifier)) {
330 330 impl->m_VariableModel->setDataProgress(var, progress);
331 331 }
332 332 else {
333 333 qCCritical(LOG_VariableController())
334 334 << tr("Impossible to notify progression of a null variable");
335 335 }
336 336 }
337 337
338 338 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
339 339 {
340 340 auto it = impl->m_VariableToIdentifierMap.find(variable);
341 341 if (it != impl->m_VariableToIdentifierMap.cend()) {
342 342 impl->m_VariableAcquisitionWorker->abortProgressRequested(it->second);
343 343
344 344 QUuid varRequestId;
345 345 auto varIdToVarRequestIdQueueMapIt = impl->m_VarIdToVarRequestIdQueueMap.find(it->second);
346 346 if (varIdToVarRequestIdQueueMapIt != impl->m_VarIdToVarRequestIdQueueMap.cend()) {
347 347 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
348 348 varRequestId = varRequestIdQueue.front();
349 349 impl->cancelVariableRequest(varRequestId);
350 350
351 351 // Finish the progression for the request
352 352 impl->m_VariableModel->setDataProgress(variable, 0.0);
353 353 }
354 354 else {
355 355 qCWarning(LOG_VariableController())
356 356 << tr("Aborting progression of inexistant variable request detected !!!")
357 357 << QThread::currentThread()->objectName();
358 358 }
359 359 }
360 360 else {
361 361 qCWarning(LOG_VariableController())
362 362 << tr("Aborting progression of inexistant variable detected !!!")
363 363 << QThread::currentThread()->objectName();
364 364 }
365 365 }
366 366
367 367 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
368 368 {
369 369 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
370 370 << QThread::currentThread()->objectName() << vIdentifier;
371 371
372 372 if (auto var = impl->findVariable(vIdentifier)) {
373 373 this->onAbortProgressRequested(var);
374 374 }
375 375 else {
376 376 qCCritical(LOG_VariableController())
377 377 << tr("Impossible to abort Acquisition Requestof a null variable");
378 378 }
379 379 }
380 380
381 381 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
382 382 {
383 383 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
384 384 << QThread::currentThread()->objectName()
385 385 << synchronizationGroupId;
386 386 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
387 387 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
388 388 std::make_pair(synchronizationGroupId, vSynchroGroup));
389 389 }
390 390
391 391 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
392 392 {
393 393 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
394 394 }
395 395
396 396 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
397 397 QUuid synchronizationGroupId)
398 398
399 399 {
400 400 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
401 401 << synchronizationGroupId;
402 402 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
403 403 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
404 404 auto groupIdToVSGIt
405 405 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
406 406 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
407 407 impl->m_VariableIdGroupIdMap.insert(
408 408 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
409 409 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
410 410 }
411 411 else {
412 412 qCCritical(LOG_VariableController())
413 413 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
414 414 << variable->name();
415 415 }
416 416 }
417 417 else {
418 418 qCCritical(LOG_VariableController())
419 419 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
420 420 }
421 421 }
422 422
423 423 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
424 424 QUuid synchronizationGroupId)
425 425 {
426 426 // Gets variable id
427 427 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
428 428 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
429 429 qCCritical(LOG_VariableController())
430 430 << tr("Can't desynchronize variable %1: variable identifier not found")
431 431 .arg(variable->name());
432 432 return;
433 433 }
434 434
435 435 // Gets synchronization group
436 436 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
437 437 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
438 438 qCCritical(LOG_VariableController())
439 439 << tr("Can't desynchronize variable %1: unknown synchronization group")
440 440 .arg(variable->name());
441 441 return;
442 442 }
443 443
444 444 auto variableId = variableIt->second;
445 445
446 446 // Removes variable from synchronization group
447 447 auto synchronizationGroup = groupIt->second;
448 448 synchronizationGroup->removeVariableId(variableId);
449 449
450 450 // Removes link between variable and synchronization group
451 451 impl->m_VariableIdGroupIdMap.erase(variableId);
452 452 }
453 453
454 454 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
455 455 const SqpRange &range, const SqpRange &oldRange,
456 456 bool synchronise)
457 457 {
458 458 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
459 459
460 460 // we want to load data of the variable for the dateTime.
461 461 // First we check if the cache contains some of them.
462 462 // For the other, we ask the provider to give them.
463 463
464 464 auto varRequestId = QUuid::createUuid();
465 465 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
466 466 << QThread::currentThread()->objectName() << varRequestId;
467 467
468 468 for (const auto &var : variables) {
469 469 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
470 470 impl->processRequest(var, range, varRequestId);
471 471 }
472 472
473 473 if (synchronise) {
474 474 // Get the group ids
475 475 qCDebug(LOG_VariableController())
476 476 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
477 477 auto groupIds = std::set<QUuid>{};
478 478 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
479 479 for (const auto &var : variables) {
480 480 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
481 481 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
482 482 auto vId = varToVarIdIt->second;
483 483 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
484 484 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
485 485 auto gId = varIdToGroupIdIt->second;
486 486 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
487 487 if (groupIds.find(gId) == groupIds.cend()) {
488 488 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
489 489 groupIds.insert(gId);
490 490 }
491 491 }
492 492 }
493 493 }
494 494
495 495 // We assume here all group ids exist
496 496 for (const auto &gId : groupIds) {
497 497 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
498 498 auto vSyncIds = vSynchronizationGroup->getIds();
499 499 qCDebug(LOG_VariableController()) << "Var in synchro group ";
500 500 for (auto vId : vSyncIds) {
501 501 auto var = impl->findVariable(vId);
502 502
503 503 // Don't process already processed var
504 504 if (!variables.contains(var)) {
505 505 if (var != nullptr) {
506 506 qCDebug(LOG_VariableController()) << "processRequest synchro for"
507 507 << var->name();
508 508 auto vSyncRangeRequested = computeSynchroRangeRequested(
509 509 var->range(), range, groupIdToOldRangeMap.at(gId));
510 510 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
511 511 impl->processRequest(var, vSyncRangeRequested, varRequestId);
512 512 }
513 513 else {
514 514 qCCritical(LOG_VariableController())
515 515
516 516 << tr("Impossible to synchronize a null variable");
517 517 }
518 518 }
519 519 }
520 520 }
521 521 }
522 522
523 523 impl->updateVariableRequest(varRequestId);
524 524 }
525 525
526 526
527 527 void VariableController::initialize()
528 528 {
529 529 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
530 530 impl->m_WorkingMutex.lock();
531 531 qCDebug(LOG_VariableController()) << tr("VariableController init END");
532 532 }
533 533
534 534 void VariableController::finalize()
535 535 {
536 536 impl->m_WorkingMutex.unlock();
537 537 }
538 538
539 539 void VariableController::waitForFinish()
540 540 {
541 541 QMutexLocker locker{&impl->m_WorkingMutex};
542 542 }
543 543
544 544 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
545 545 {
546 546 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
547 547 auto zoomType = AcquisitionZoomType::Unknown;
548 548 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
549 549 zoomType = AcquisitionZoomType::ZoomOut;
550 550 }
551 551 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
552 552 zoomType = AcquisitionZoomType::PanRight;
553 553 }
554 554 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
555 555 zoomType = AcquisitionZoomType::PanLeft;
556 556 }
557 557 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
558 558 zoomType = AcquisitionZoomType::ZoomIn;
559 559 }
560 560 else {
561 561 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
562 562 }
563 563 return zoomType;
564 564 }
565 565
566 566 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
567 567 const SqpRange &rangeRequested,
568 568 QUuid varRequestId)
569 569 {
570 570
571 571 // TODO: protect at
572 572 auto varRequest = VariableRequest{};
573 573 auto varId = m_VariableToIdentifierMap.at(var);
574 574
575 575 auto varStrategyRangesRequested
576 576 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
577 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
578 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
577
578 auto notInCacheRangeList = QVector<SqpRange>{varStrategyRangesRequested.second};
579 auto inCacheRangeList = QVector<SqpRange>{};
580 if (m_VarIdToVarRequestIdQueueMap.find(varId) == m_VarIdToVarRequestIdQueueMap.cend()) {
581 notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
582 inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
583 }
579 584
580 585 if (!notInCacheRangeList.empty()) {
581 586 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
582 587 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
583 588
584 589 // store VarRequest
585 590 storeVariableRequest(varId, varRequestId, varRequest);
586 591
587 592 auto varProvider = m_VariableToProviderMap.at(var);
588 593 if (varProvider != nullptr) {
589 594 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
590 595 varRequestId, varId, varStrategyRangesRequested.first,
591 596 varStrategyRangesRequested.second,
592 597 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
593 598 varProvider);
594 599
595 600 if (!varRequestIdCanceled.isNull()) {
596 601 qCDebug(LOG_VariableAcquisitionWorker()) << tr("vsarRequestIdCanceled: ")
597 602 << varRequestIdCanceled;
598 603 cancelVariableRequest(varRequestIdCanceled);
599 604 }
600 605 }
601 606 else {
602 607 qCCritical(LOG_VariableController())
603 608 << "Impossible to provide data with a null provider";
604 609 }
605 610
606 611 if (!inCacheRangeList.empty()) {
607 612 emit q->updateVarDisplaying(var, inCacheRangeList.first());
608 613 }
609 614 }
610 615 else {
611 616 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
612 617 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
613 618 // store VarRequest
614 619 storeVariableRequest(varId, varRequestId, varRequest);
615 620 acceptVariableRequest(varId,
616 621 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
617 622 }
618 623 }
619 624
620 625 std::shared_ptr<Variable>
621 626 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
622 627 {
623 628 std::shared_ptr<Variable> var;
624 629 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
625 630
626 631 auto end = m_VariableToIdentifierMap.cend();
627 632 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
628 633 if (it != end) {
629 634 var = it->first;
630 635 }
631 636 else {
632 637 qCCritical(LOG_VariableController())
633 638 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
634 639 }
635 640
636 641 return var;
637 642 }
638 643
639 644 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
640 645 const QVector<AcquisitionDataPacket> acqDataPacketVector)
641 646 {
642 647 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
643 648 << acqDataPacketVector.size();
644 649 std::shared_ptr<IDataSeries> dataSeries;
645 650 if (!acqDataPacketVector.isEmpty()) {
646 651 dataSeries = acqDataPacketVector[0].m_DateSeries;
647 652 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
648 653 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
649 654 }
650 655 }
651 656 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
652 657 << acqDataPacketVector.size();
653 658 return dataSeries;
654 659 }
655 660
656 661 void VariableController::VariableControllerPrivate::registerProvider(
657 662 std::shared_ptr<IDataProvider> provider)
658 663 {
659 664 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
660 665 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
661 666 << provider->objectName();
662 667 m_ProviderSet.insert(provider);
663 668 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
664 669 &VariableAcquisitionWorker::onVariableDataAcquired);
665 670 connect(provider.get(), &IDataProvider::dataProvidedProgress,
666 671 m_VariableAcquisitionWorker.get(),
667 672 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
668 673 connect(provider.get(), &IDataProvider::dataProvidedFailed,
669 674 m_VariableAcquisitionWorker.get(),
670 675 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
671 676 }
672 677 else {
673 678 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
674 679 }
675 680 }
676 681
677 682 void VariableController::VariableControllerPrivate::storeVariableRequest(
678 683 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
679 684 {
680 685 // First request for the variable. we can create an entry for it
681 686 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
682 687 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
683 688 auto varRequestIdQueue = std::deque<QUuid>{};
684 689 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
685 690 varRequestIdQueue.push_back(varRequestId);
686 691 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
687 692 }
688 693 else {
689 694 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
690 695 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
691 696 varRequestIdQueue.push_back(varRequestId);
692 697 }
693 698
694 699 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
695 700 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
696 701 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
697 702 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
698 703 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
699 704 m_VarRequestIdToVarIdVarRequestMap.insert(
700 705 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
701 706 }
702 707 else {
703 708 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
704 709 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
705 710 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
706 711 }
707 712 }
708 713
709 714 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
710 715 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
711 716 {
712 717 QUuid varRequestId;
713 718 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
714 719 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
715 720 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
716 721 varRequestId = varRequestIdQueue.front();
717 722 auto varRequestIdToVarIdVarRequestMapIt
718 723 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
719 724 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
720 725 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
721 726 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
722 727 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
723 728 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
724 729 auto &varRequest = varIdToVarRequestMapIt->second;
725 730 varRequest.m_DataSeries = dataSeries;
726 731 varRequest.m_CanUpdate = true;
727 732 }
728 733 else {
729 734 qCDebug(LOG_VariableController())
730 735 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
731 736 "to a variableRequestId")
732 737 << varRequestId << varId;
733 738 }
734 739 }
735 740 else {
736 741 qCCritical(LOG_VariableController())
737 742 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
738 743 << varRequestId;
739 744 }
740 745
741 746 varRequestIdQueue.pop_front();
742 747 if (varRequestIdQueue.empty()) {
743 748 qCDebug(LOG_VariableController())
744 749 << tr("TORM Erase REQUEST because it has been accepted") << varId;
745 750 m_VarIdToVarRequestIdQueueMap.erase(varId);
746 751 }
747 752 }
748 753 else {
749 754 qCCritical(LOG_VariableController())
750 755 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
751 756 }
752 757
753 758 return varRequestId;
754 759 }
755 760
756 761 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
757 762 {
758 763
759 764 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
760 765 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
761 766 bool processVariableUpdate = true;
762 767 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
763 768 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
764 769 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
765 770 ++varIdToVarRequestMapIt) {
766 771 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
767 772 qCDebug(LOG_VariableController()) << tr("updateVariableRequest")
768 773 << processVariableUpdate;
769 774 }
770 775
771 776 if (processVariableUpdate) {
772 777 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
773 778 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
774 779 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
775 780 auto &varRequest = varIdToVarRequestMapIt->second;
776 781 var->setRange(varRequest.m_RangeRequested);
777 782 var->setCacheRange(varRequest.m_CacheRangeRequested);
778 783 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
779 784 << varRequest.m_RangeRequested;
780 785 qCDebug(LOG_VariableController()) << tr("2: onDataProvided")
781 786 << varRequest.m_CacheRangeRequested;
782 787 var->mergeDataSeries(varRequest.m_DataSeries);
783 788 qCDebug(LOG_VariableController()) << tr("3: onDataProvided")
784 789 << varRequest.m_DataSeries->range();
785 790 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
786 791
787 792 /// @todo MPL: confirm
788 793 // Variable update is notified only if there is no pending request for it
789 794 // if
790 795 // (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first)
791 796 // == 0) {
792 797 emit var->updated();
793 798 // }
794 799 }
795 800 else {
796 801 qCCritical(LOG_VariableController())
797 802 << tr("Impossible to update data to a null variable");
798 803 }
799 804 }
800 805
801 806 // cleaning varRequestId
802 807 qCDebug(LOG_VariableController()) << tr("0: erase REQUEST in MAP ?")
803 808 << m_VarRequestIdToVarIdVarRequestMap.size();
804 809 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
805 810 qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in MAP ?")
806 811 << m_VarRequestIdToVarIdVarRequestMap.size();
807 812 }
808 813 }
809 814 else {
810 815 qCCritical(LOG_VariableController())
811 816 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
812 817 }
813 818 }
814 819
815 820 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
816 821 {
817 822 // cleaning varRequestId
818 823 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
819 824
820 825 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
821 826 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
822 827 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
823 828 varRequestIdQueue.erase(
824 829 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
825 830 varRequestIdQueue.end());
826 831 if (varRequestIdQueue.empty()) {
827 832 varIdToVarRequestIdQueueMapIt
828 833 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
829 834 }
830 835 else {
831 836 ++varIdToVarRequestIdQueueMapIt;
832 837 }
833 838 }
834 839 }
@@ -1,228 +1,232
1 1 #include <Variable/RenameVariableDialog.h>
2 2 #include <Variable/Variable.h>
3 3 #include <Variable/VariableController.h>
4 4 #include <Variable/VariableInspectorWidget.h>
5 5 #include <Variable/VariableMenuHeaderWidget.h>
6 6 #include <Variable/VariableModel.h>
7 7
8 8 #include <ui_VariableInspectorWidget.h>
9 9
10 10 #include <QMouseEvent>
11 11 #include <QSortFilterProxyModel>
12 12 #include <QStyledItemDelegate>
13 13 #include <QWidgetAction>
14 14
15 15 #include <SqpApplication.h>
16 16
17 17 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
18 18
19 19
20 20 class QProgressBarItemDelegate : public QStyledItemDelegate {
21 21
22 22 public:
23 23 QProgressBarItemDelegate(QObject *parent) : QStyledItemDelegate{parent} {}
24 24
25 25 void paint(QPainter *painter, const QStyleOptionViewItem &option,
26 26 const QModelIndex &index) const
27 27 {
28 28 auto data = index.data(Qt::DisplayRole);
29 29 auto progressData = index.data(VariableRoles::ProgressRole);
30 30 if (data.isValid() && progressData.isValid()) {
31 31 auto name = data.value<QString>();
32 32 auto progress = progressData.value<double>();
33 33 if (progress > 0) {
34 34 auto cancelButtonWidth = 20;
35 35 auto progressBarOption = QStyleOptionProgressBar{};
36 36 auto progressRect = option.rect;
37 37 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
38 38 progressBarOption.rect = progressRect;
39 39 progressBarOption.minimum = 0;
40 40 progressBarOption.maximum = 100;
41 41 progressBarOption.progress = progress;
42 42 progressBarOption.text
43 43 = QString("%1 %2").arg(name).arg(QString::number(progress, 'f', 2) + "%");
44 44 progressBarOption.textVisible = true;
45 45 progressBarOption.textAlignment = Qt::AlignCenter;
46 46
47 47
48 48 QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption,
49 49 painter);
50 50
51 51 // Cancel button
52 52 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
53 53 option.rect.height());
54 54 auto buttonOption = QStyleOptionButton{};
55 55 buttonOption.rect = buttonRect;
56 56 buttonOption.text = "X";
57 57
58 58 QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
59 59 }
60 60 else {
61 61 QStyledItemDelegate::paint(painter, option, index);
62 62 }
63 63 }
64 64 else {
65 65 QStyledItemDelegate::paint(painter, option, index);
66 66 }
67 67 }
68 68
69 69 bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
70 70 const QModelIndex &index)
71 71 {
72 72 if (event->type() == QEvent::MouseButtonRelease) {
73 73 auto data = index.data(Qt::DisplayRole);
74 74 auto progressData = index.data(VariableRoles::ProgressRole);
75 75 if (data.isValid() && progressData.isValid()) {
76 76 auto cancelButtonWidth = 20;
77 77 auto progressRect = option.rect;
78 78 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
79 79 // Cancel button
80 80 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
81 81 option.rect.height());
82 82
83 83 auto e = (QMouseEvent *)event;
84 84 auto clickX = e->x();
85 85 auto clickY = e->y();
86 86
87 87 auto x = buttonRect.left(); // the X coordinate
88 88 auto y = buttonRect.top(); // the Y coordinate
89 89 auto w = buttonRect.width(); // button width
90 90 auto h = buttonRect.height(); // button height
91 91
92 92 if (clickX > x && clickX < x + w) {
93 93 if (clickY > y && clickY < y + h) {
94 94 auto variableModel = sqpApp->variableController().variableModel();
95 95 variableModel->abortProgress(index);
96 96 }
97 return true;
97 98 }
98 99 else {
99 QStyledItemDelegate::editorEvent(event, model, option, index);
100 return QStyledItemDelegate::editorEvent(event, model, option, index);
100 101 }
101 102 }
102 103 else {
103 QStyledItemDelegate::editorEvent(event, model, option, index);
104 return QStyledItemDelegate::editorEvent(event, model, option, index);
104 105 }
105 106 }
106 107 else {
107 QStyledItemDelegate::editorEvent(event, model, option, index);
108 return QStyledItemDelegate::editorEvent(event, model, option, index);
108 109 }
110
111
112 return QStyledItemDelegate::editorEvent(event, model, option, index);
109 113 }
110 114 };
111 115
112 116 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
113 117 : QWidget{parent},
114 118 ui{new Ui::VariableInspectorWidget},
115 119 m_ProgressBarItemDelegate{new QProgressBarItemDelegate{this}}
116 120 {
117 121 ui->setupUi(this);
118 122
119 123 // Sets model for table
120 124 // auto sortFilterModel = new QSortFilterProxyModel{this};
121 125 // sortFilterModel->setSourceModel(sqpApp->variableController().variableModel());
122 126
123 127 auto variableModel = sqpApp->variableController().variableModel();
124 128 ui->tableView->setModel(variableModel);
125 129
126 130 // Adds extra signal/slot between view and model, so the view can be updated instantly when
127 131 // there is a change of data in the model
128 132 connect(variableModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this,
129 133 SLOT(refresh()));
130 134
131 135 ui->tableView->setSelectionModel(sqpApp->variableController().variableSelectionModel());
132 136 ui->tableView->setItemDelegateForColumn(0, m_ProgressBarItemDelegate);
133 137
134 138 // Fixes column sizes
135 139 auto model = ui->tableView->model();
136 140 const auto count = model->columnCount();
137 141 for (auto i = 0; i < count; ++i) {
138 142 ui->tableView->setColumnWidth(
139 143 i, model->headerData(i, Qt::Horizontal, Qt::SizeHintRole).toSize().width());
140 144 }
141 145
142 146 // Sets selection options
143 147 ui->tableView->setSelectionBehavior(QTableView::SelectRows);
144 148 ui->tableView->setSelectionMode(QTableView::ExtendedSelection);
145 149
146 150 // Connection to show a menu when right clicking on the tree
147 151 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
148 152 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
149 153 &VariableInspectorWidget::onTableMenuRequested);
150 154 }
151 155
152 156 VariableInspectorWidget::~VariableInspectorWidget()
153 157 {
154 158 delete ui;
155 159 }
156 160
157 161 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
158 162 {
159 163 auto selectedRows = ui->tableView->selectionModel()->selectedRows();
160 164
161 165 // Gets the model to retrieve the underlying selected variables
162 166 auto model = sqpApp->variableController().variableModel();
163 167 auto selectedVariables = QVector<std::shared_ptr<Variable> >{};
164 168 for (const auto &selectedRow : qAsConst(selectedRows)) {
165 169 if (auto selectedVariable = model->variable(selectedRow.row())) {
166 170 selectedVariables.push_back(selectedVariable);
167 171 }
168 172 }
169 173
170 174 QMenu tableMenu{};
171 175
172 176 // Emits a signal so that potential receivers can populate the menu before displaying it
173 177 emit tableMenuAboutToBeDisplayed(&tableMenu, selectedVariables);
174 178
175 179 // Adds menu-specific actions
176 180 if (!selectedVariables.isEmpty()) {
177 181 tableMenu.addSeparator();
178 182
179 183 // 'Rename' and 'Duplicate' actions (only if one variable selected)
180 184 if (selectedVariables.size() == 1) {
181 185 auto selectedVariable = selectedVariables.front();
182 186
183 187 auto duplicateFun = [&selectedVariable]() {
184 188 sqpApp->variableController().cloneVariable(selectedVariable);
185 189 };
186 190
187 191 tableMenu.addAction(tr("Duplicate"), duplicateFun);
188 192
189 193 auto renameFun = [&selectedVariable, &model, this]() {
190 194 // Generates forbidden names (names associated to existing variables)
191 195 auto allVariables = model->variables();
192 196 auto forbiddenNames = QVector<QString>(allVariables.size());
193 197 std::transform(allVariables.cbegin(), allVariables.cend(), forbiddenNames.begin(),
194 198 [](const auto &variable) { return variable->name(); });
195 199
196 200 RenameVariableDialog dialog{selectedVariable->name(), forbiddenNames, this};
197 201 if (dialog.exec() == QDialog::Accepted) {
198 202 selectedVariable->setName(dialog.name());
199 203 }
200 204 };
201 205
202 206 tableMenu.addAction(tr("Rename..."), renameFun);
203 207 }
204 208
205 209 // 'Delete' action
206 210 auto deleteFun = [&selectedVariables]() {
207 211 sqpApp->variableController().deleteVariables(selectedVariables);
208 212 };
209 213
210 214 tableMenu.addAction(QIcon{":/icones/delete.png"}, tr("Delete"), deleteFun);
211 215 }
212 216
213 217 if (!tableMenu.isEmpty()) {
214 218 // Generates menu header (inserted before first action)
215 219 auto firstAction = tableMenu.actions().first();
216 220 auto headerAction = new QWidgetAction{&tableMenu};
217 221 headerAction->setDefaultWidget(new VariableMenuHeaderWidget{selectedVariables, &tableMenu});
218 222 tableMenu.insertAction(firstAction, headerAction);
219 223
220 224 // Displays menu
221 225 tableMenu.exec(QCursor::pos());
222 226 }
223 227 }
224 228
225 229 void VariableInspectorWidget::refresh() noexcept
226 230 {
227 231 ui->tableView->viewport()->update();
228 232 }
General Comments 0
You need to be logged in to leave comments. Login now