1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include <QtCharts/QCandlestickModelMapper> |
5 | #include <QtCharts/QCandlestickSeries> |
6 | #include <QtCharts/QCandlestickSet> |
7 | #include <QtCore/QAbstractItemModel> |
8 | #include <private/qcandlestickmodelmapper_p.h> |
9 | |
10 | #include <algorithm> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | /*! |
15 | \class QCandlestickModelMapper |
16 | \since 5.8 |
17 | \inmodule QtCharts |
18 | \brief Abstract model mapper class for candlestick series. |
19 | |
20 | Model mappers allow the use of a QAbstractItemModel-derived model as a data source for a chart |
21 | series, creating a connection between a QCandlestickSeries and the model object. A model mapper |
22 | maintains an equal size across all \l {QCandlestickSet} {QCandlestickSets}. |
23 | |
24 | \note The model used must support adding and removing rows/columns and modifying the data of the |
25 | cells. |
26 | */ |
27 | |
28 | /*! |
29 | \property QCandlestickModelMapper::model |
30 | \brief Defines the model that is used by the mapper. |
31 | */ |
32 | |
33 | /*! |
34 | \property QCandlestickModelMapper::series |
35 | \brief Defines the QCandlestickSeries object that is used by the mapper. |
36 | |
37 | \note All data in the series is discarded when it is set to the mapper. When a new series is |
38 | specified, the old series is disconnected (preserving its data). |
39 | */ |
40 | |
41 | /*! |
42 | \fn Qt::Orientation QCandlestickModelMapper::orientation() const |
43 | Returns the orientation that is used when QCandlestickModelMapper accesses the model. This |
44 | determines whether the consecutive values of the set are read from rows (Qt::Horizontal) or from |
45 | columns (Qt::Vertical). |
46 | */ |
47 | |
48 | /*! |
49 | \fn void QCandlestickModelMapper::modelReplaced() |
50 | \brief Emitted when the model, to which the mapper is connected, has changed. |
51 | \sa model |
52 | */ |
53 | |
54 | /*! |
55 | \fn void QCandlestickModelMapper::seriesReplaced() |
56 | \brief Emitted when the series to which mapper is connected to has changed. |
57 | \sa series |
58 | */ |
59 | |
60 | /*! |
61 | Constructs a model mapper object as a child of \a parent. |
62 | */ |
63 | QCandlestickModelMapper::QCandlestickModelMapper(QObject *parent) |
64 | : QObject(parent), |
65 | d_ptr(new QCandlestickModelMapperPrivate(this)) |
66 | { |
67 | } |
68 | |
69 | void QCandlestickModelMapper::setModel(QAbstractItemModel *model) |
70 | { |
71 | Q_D(QCandlestickModelMapper); |
72 | |
73 | if (d->m_model == model) |
74 | return; |
75 | |
76 | if (d->m_model) |
77 | disconnect(sender: d->m_model, signal: 0, receiver: d, member: 0); |
78 | |
79 | d->m_model = model; |
80 | emit modelReplaced(); |
81 | |
82 | if (!d->m_model) |
83 | return; |
84 | |
85 | d->initializeCandlestickFromModel(); |
86 | // connect signals from the model |
87 | connect(sender: d->m_model, SIGNAL(modelReset()), receiver: d, SLOT(initializeCandlestickFromModel())); |
88 | connect(sender: d->m_model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), |
89 | receiver: d, SLOT(modelDataUpdated(QModelIndex, QModelIndex))); |
90 | connect(sender: d->m_model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)), |
91 | receiver: d, SLOT(modelHeaderDataUpdated(Qt::Orientation, int, int))); |
92 | connect(sender: d->m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), |
93 | receiver: d, SLOT(modelRowsInserted(QModelIndex, int, int))); |
94 | connect(sender: d->m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), |
95 | receiver: d, SLOT(modelRowsRemoved(QModelIndex, int, int))); |
96 | connect(sender: d->m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), |
97 | receiver: d, SLOT(modelColumnsInserted(QModelIndex, int, int))); |
98 | connect(sender: d->m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), |
99 | receiver: d, SLOT(modelColumnsRemoved(QModelIndex, int, int))); |
100 | connect(sender: d->m_model, SIGNAL(destroyed()), receiver: d, SLOT(modelDestroyed())); |
101 | } |
102 | |
103 | QAbstractItemModel *QCandlestickModelMapper::model() const |
104 | { |
105 | Q_D(const QCandlestickModelMapper); |
106 | |
107 | return d->m_model; |
108 | } |
109 | |
110 | void QCandlestickModelMapper::setSeries(QCandlestickSeries *series) |
111 | { |
112 | Q_D(QCandlestickModelMapper); |
113 | |
114 | if (d->m_series == series) |
115 | return; |
116 | |
117 | if (d->m_series) |
118 | disconnect(sender: d->m_series, signal: 0, receiver: d, member: 0); |
119 | |
120 | d->m_series = series; |
121 | emit seriesReplaced(); |
122 | |
123 | if (!d->m_series) |
124 | return; |
125 | |
126 | d->initializeCandlestickFromModel(); |
127 | // connect the signals from the series |
128 | connect(sender: d->m_series, SIGNAL(candlestickSetsAdded(QList<QCandlestickSet *>)), |
129 | receiver: d, SLOT(candlestickSetsAdded(QList<QCandlestickSet *>))); |
130 | connect(sender: d->m_series, SIGNAL(candlestickSetsRemoved(QList<QCandlestickSet*>)), |
131 | receiver: d, SLOT(candlestickSetsRemoved(QList<QCandlestickSet *>))); |
132 | connect(sender: d->m_series, SIGNAL(destroyed()), receiver: d, SLOT(seriesDestroyed())); |
133 | } |
134 | |
135 | QCandlestickSeries *QCandlestickModelMapper::series() const |
136 | { |
137 | Q_D(const QCandlestickModelMapper); |
138 | |
139 | return d->m_series; |
140 | } |
141 | |
142 | /*! |
143 | Sets the row/column of the model that contains the \a timestamp values of the sets in the |
144 | series. Default value is -1 (invalid mapping). |
145 | */ |
146 | void QCandlestickModelMapper::setTimestamp(int timestamp) |
147 | { |
148 | Q_D(QCandlestickModelMapper); |
149 | |
150 | timestamp = qMax(a: timestamp, b: -1); |
151 | |
152 | if (d->m_timestamp == timestamp) |
153 | return; |
154 | |
155 | d->m_timestamp = timestamp; |
156 | emit d->timestampChanged(); |
157 | d->initializeCandlestickFromModel(); |
158 | } |
159 | |
160 | /*! |
161 | Returns the row/column of the model that contains the timestamp values of the sets in the |
162 | series. Default value is -1 (invalid mapping). |
163 | */ |
164 | int QCandlestickModelMapper::timestamp() const |
165 | { |
166 | Q_D(const QCandlestickModelMapper); |
167 | |
168 | return d->m_timestamp; |
169 | } |
170 | |
171 | /*! |
172 | Sets the row/column of the model that contains the \a open values of the sets in the series. |
173 | Default value is -1 (invalid mapping). |
174 | */ |
175 | void QCandlestickModelMapper::setOpen(int open) |
176 | { |
177 | Q_D(QCandlestickModelMapper); |
178 | |
179 | open = qMax(a: open, b: -1); |
180 | |
181 | if (d->m_open == open) |
182 | return; |
183 | |
184 | d->m_open = open; |
185 | emit d->openChanged(); |
186 | d->initializeCandlestickFromModel(); |
187 | } |
188 | |
189 | /*! |
190 | Returns the row/column of the model that contains the open values of the sets in the series. |
191 | Default value is -1 (invalid mapping). |
192 | */ |
193 | int QCandlestickModelMapper::open() const |
194 | { |
195 | Q_D(const QCandlestickModelMapper); |
196 | |
197 | return d->m_open; |
198 | } |
199 | |
200 | /*! |
201 | Sets the row/column of the model that contains the \a high values of the sets in the series. |
202 | Default value is -1 (invalid mapping). |
203 | */ |
204 | void QCandlestickModelMapper::setHigh(int high) |
205 | { |
206 | Q_D(QCandlestickModelMapper); |
207 | |
208 | high = qMax(a: high, b: -1); |
209 | |
210 | if (d->m_high == high) |
211 | return; |
212 | |
213 | d->m_high = high; |
214 | emit d->highChanged(); |
215 | d->initializeCandlestickFromModel(); |
216 | } |
217 | |
218 | /*! |
219 | Returns the row/column of the model that contains the high values of the sets in the series. |
220 | Default value is -1 (invalid mapping). |
221 | */ |
222 | int QCandlestickModelMapper::high() const |
223 | { |
224 | Q_D(const QCandlestickModelMapper); |
225 | |
226 | return d->m_high; |
227 | } |
228 | |
229 | /*! |
230 | Sets the row/column of the model that contains the \a low values of the sets in the series. |
231 | Default value is -1 (invalid mapping). |
232 | */ |
233 | void QCandlestickModelMapper::setLow(int low) |
234 | { |
235 | Q_D(QCandlestickModelMapper); |
236 | |
237 | low = qMax(a: low, b: -1); |
238 | |
239 | if (d->m_low == low) |
240 | return; |
241 | |
242 | d->m_low = low; |
243 | emit d->lowChanged(); |
244 | d->initializeCandlestickFromModel(); |
245 | } |
246 | |
247 | /*! |
248 | Returns the row/column of the model that contains the low values of the sets in the series. |
249 | Default value is -1 (invalid mapping). |
250 | */ |
251 | int QCandlestickModelMapper::low() const |
252 | { |
253 | Q_D(const QCandlestickModelMapper); |
254 | |
255 | return d->m_low; |
256 | } |
257 | |
258 | /*! |
259 | Sets the row/column of the model that contains the \a close values of the sets in the series. |
260 | Default value is -1 (invalid mapping). |
261 | */ |
262 | void QCandlestickModelMapper::setClose(int close) |
263 | { |
264 | Q_D(QCandlestickModelMapper); |
265 | |
266 | close = qMax(a: close, b: -1); |
267 | |
268 | if (d->m_close == close) |
269 | return; |
270 | |
271 | d->m_close = close; |
272 | emit d->closeChanged(); |
273 | d->initializeCandlestickFromModel(); |
274 | } |
275 | |
276 | /*! |
277 | Returns the row/column of the model that contains the close values of the sets in the series. |
278 | Default value is -1 (invalid mapping). |
279 | */ |
280 | int QCandlestickModelMapper::close() const |
281 | { |
282 | Q_D(const QCandlestickModelMapper); |
283 | |
284 | return d->m_close; |
285 | } |
286 | |
287 | /*! |
288 | Sets the section of the model that is used as the data source for the first candlestick set. |
289 | Parameter \a firstSetSection specifies the section of the model. Default value is -1. |
290 | */ |
291 | void QCandlestickModelMapper::setFirstSetSection(int firstSetSection) |
292 | { |
293 | Q_D(QCandlestickModelMapper); |
294 | |
295 | firstSetSection = qMax(a: firstSetSection, b: -1); |
296 | |
297 | if (d->m_firstSetSection == firstSetSection) |
298 | return; |
299 | |
300 | d->m_firstSetSection = firstSetSection; |
301 | emit d->firstSetSectionChanged(); |
302 | d->initializeCandlestickFromModel(); |
303 | } |
304 | |
305 | /*! |
306 | Returns the section of the model that is used as the data source for the first candlestick set. |
307 | Default value is -1 (invalid mapping). |
308 | */ |
309 | int QCandlestickModelMapper::firstSetSection() const |
310 | { |
311 | Q_D(const QCandlestickModelMapper); |
312 | |
313 | return d->m_firstSetSection; |
314 | } |
315 | |
316 | /*! |
317 | Sets the section of the model that is used as the data source for the last candlestick set. |
318 | Parameter \a lastSetSection specifies the section of the model. Default value is -1. |
319 | */ |
320 | void QCandlestickModelMapper::setLastSetSection(int lastSetSection) |
321 | { |
322 | Q_D(QCandlestickModelMapper); |
323 | |
324 | lastSetSection = qMax(a: lastSetSection, b: -1); |
325 | |
326 | if (d->m_lastSetSection == lastSetSection) |
327 | return; |
328 | |
329 | d->m_lastSetSection = lastSetSection; |
330 | emit d->lastSetSectionChanged(); |
331 | d->initializeCandlestickFromModel(); |
332 | } |
333 | |
334 | /*! |
335 | Returns the section of the model that is used as the data source for the last candlestick set. |
336 | Default value is -1 (invalid mapping). |
337 | */ |
338 | int QCandlestickModelMapper::lastSetSection() const |
339 | { |
340 | Q_D(const QCandlestickModelMapper); |
341 | |
342 | return d->m_lastSetSection; |
343 | } |
344 | |
345 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
346 | |
347 | QCandlestickModelMapperPrivate::QCandlestickModelMapperPrivate(QCandlestickModelMapper *q) |
348 | : QObject(q), |
349 | m_model(nullptr), |
350 | m_series(nullptr), |
351 | m_timestamp(-1), |
352 | m_open(-1), |
353 | m_high(-1), |
354 | m_low(-1), |
355 | m_close(-1), |
356 | m_firstSetSection(-1), |
357 | m_lastSetSection(-1), |
358 | m_modelSignalsBlock(false), |
359 | m_seriesSignalsBlock(false), |
360 | q_ptr(q) |
361 | { |
362 | } |
363 | |
364 | void QCandlestickModelMapperPrivate::initializeCandlestickFromModel() |
365 | { |
366 | if (!m_model || !m_series) |
367 | return; |
368 | |
369 | blockSeriesSignals(); |
370 | // clear current content |
371 | m_series->clear(); |
372 | m_sets.clear(); |
373 | |
374 | // create the initial candlestick sets |
375 | QList<QCandlestickSet *> sets; |
376 | for (int i = m_firstSetSection; i <= m_lastSetSection; ++i) { |
377 | QModelIndex timestampIndex = candlestickModelIndex(section: i, pos: m_timestamp); |
378 | QModelIndex openIndex = candlestickModelIndex(section: i, pos: m_open); |
379 | QModelIndex highIndex = candlestickModelIndex(section: i, pos: m_high); |
380 | QModelIndex lowIndex = candlestickModelIndex(section: i, pos: m_low); |
381 | QModelIndex closeIndex = candlestickModelIndex(section: i, pos: m_close); |
382 | if (timestampIndex.isValid() |
383 | && openIndex.isValid() |
384 | && highIndex.isValid() |
385 | && lowIndex.isValid() |
386 | && closeIndex.isValid()) { |
387 | QCandlestickSet *set = new QCandlestickSet(); |
388 | set->setTimestamp(m_model->data(index: timestampIndex, role: Qt::DisplayRole).toReal()); |
389 | set->setOpen(m_model->data(index: openIndex, role: Qt::DisplayRole).toReal()); |
390 | set->setHigh(m_model->data(index: highIndex, role: Qt::DisplayRole).toReal()); |
391 | set->setLow(m_model->data(index: lowIndex, role: Qt::DisplayRole).toReal()); |
392 | set->setClose(m_model->data(index: closeIndex, role: Qt::DisplayRole).toReal()); |
393 | |
394 | connect(sender: set, SIGNAL(timestampChanged()), receiver: this, SLOT(candlestickSetChanged())); |
395 | connect(sender: set, SIGNAL(openChanged()), receiver: this, SLOT(candlestickSetChanged())); |
396 | connect(sender: set, SIGNAL(highChanged()), receiver: this, SLOT(candlestickSetChanged())); |
397 | connect(sender: set, SIGNAL(lowChanged()), receiver: this, SLOT(candlestickSetChanged())); |
398 | connect(sender: set, SIGNAL(closeChanged()), receiver: this, SLOT(candlestickSetChanged())); |
399 | |
400 | sets.append(t: set); |
401 | } else { |
402 | break; |
403 | } |
404 | } |
405 | m_series->append(sets); |
406 | m_sets.append(l: sets); |
407 | blockSeriesSignals(block: false); |
408 | } |
409 | |
410 | void QCandlestickModelMapperPrivate::modelDataUpdated(QModelIndex topLeft, QModelIndex bottomRight) |
411 | { |
412 | Q_Q(QCandlestickModelMapper); |
413 | |
414 | if (!m_model || !m_series) |
415 | return; |
416 | |
417 | if (m_modelSignalsBlock) |
418 | return; |
419 | |
420 | blockSeriesSignals(); |
421 | QModelIndex index; |
422 | for (int row = topLeft.row(); row <= bottomRight.row(); ++row) { |
423 | for (int column = topLeft.column(); column <= bottomRight.column(); ++column) { |
424 | index = topLeft.sibling(arow: row, acolumn: column); |
425 | QCandlestickSet *set = candlestickSet(index); |
426 | if (set) { |
427 | int pos = (q->orientation() == Qt::Vertical) ? row : column; |
428 | if (pos == m_timestamp) |
429 | set->setTimestamp(m_model->data(index).toReal()); |
430 | else if (pos == m_open) |
431 | set->setOpen(m_model->data(index).toReal()); |
432 | else if (pos == m_high) |
433 | set->setHigh(m_model->data(index).toReal()); |
434 | else if (pos == m_low) |
435 | set->setLow(m_model->data(index).toReal()); |
436 | else if (pos == m_close) |
437 | set->setClose(m_model->data(index).toReal()); |
438 | } |
439 | } |
440 | } |
441 | blockSeriesSignals(block: false); |
442 | } |
443 | |
444 | void QCandlestickModelMapperPrivate::modelHeaderDataUpdated(Qt::Orientation orientation, int first, |
445 | int last) |
446 | { |
447 | Q_UNUSED(orientation); |
448 | Q_UNUSED(first); |
449 | Q_UNUSED(last); |
450 | } |
451 | |
452 | void QCandlestickModelMapperPrivate::modelRowsInserted(QModelIndex parent, int start, int end) |
453 | { |
454 | Q_UNUSED(parent); |
455 | |
456 | Q_Q(QCandlestickModelMapper); |
457 | |
458 | if (m_modelSignalsBlock) |
459 | return; |
460 | |
461 | blockSeriesSignals(); |
462 | if (q->orientation() == Qt::Vertical) |
463 | insertData(start, end); |
464 | else if (start <= m_firstSetSection || start <= m_lastSetSection) |
465 | initializeCandlestickFromModel(); // if the changes affect the map - reinitialize |
466 | blockSeriesSignals(block: false); |
467 | } |
468 | |
469 | void QCandlestickModelMapperPrivate::modelRowsRemoved(QModelIndex parent, int start, int end) |
470 | { |
471 | Q_UNUSED(parent); |
472 | |
473 | Q_Q(QCandlestickModelMapper); |
474 | |
475 | if (m_modelSignalsBlock) |
476 | return; |
477 | |
478 | blockSeriesSignals(); |
479 | if (q->orientation() == Qt::Vertical) |
480 | removeData(start, end); |
481 | else if (start <= m_firstSetSection || start <= m_lastSetSection) |
482 | initializeCandlestickFromModel(); // if the changes affect the map - reinitialize |
483 | blockSeriesSignals(block: false); |
484 | } |
485 | |
486 | void QCandlestickModelMapperPrivate::modelColumnsInserted(QModelIndex parent, int start, int end) |
487 | { |
488 | Q_UNUSED(parent); |
489 | |
490 | Q_Q(QCandlestickModelMapper); |
491 | |
492 | if (m_modelSignalsBlock) |
493 | return; |
494 | |
495 | blockSeriesSignals(); |
496 | if (q->orientation() == Qt::Horizontal) |
497 | insertData(start, end); |
498 | else if (start <= m_firstSetSection || start <= m_lastSetSection) |
499 | initializeCandlestickFromModel(); // if the changes affect the map - reinitialize |
500 | blockSeriesSignals(block: false); |
501 | } |
502 | |
503 | void QCandlestickModelMapperPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end) |
504 | { |
505 | Q_UNUSED(parent); |
506 | |
507 | Q_Q(QCandlestickModelMapper); |
508 | |
509 | if (m_modelSignalsBlock) |
510 | return; |
511 | |
512 | blockSeriesSignals(); |
513 | if (q->orientation() == Qt::Horizontal) |
514 | removeData(start, end); |
515 | else if (start <= m_firstSetSection || start <= m_lastSetSection) |
516 | initializeCandlestickFromModel(); // if the changes affect the map - reinitialize |
517 | blockSeriesSignals(block: false); |
518 | } |
519 | |
520 | void QCandlestickModelMapperPrivate::modelDestroyed() |
521 | { |
522 | m_model = 0; |
523 | } |
524 | |
525 | void QCandlestickModelMapperPrivate::candlestickSetsAdded(const QList<QCandlestickSet *> &sets) |
526 | { |
527 | Q_Q(QCandlestickModelMapper); |
528 | |
529 | if (m_seriesSignalsBlock) |
530 | return; |
531 | |
532 | if (sets.isEmpty()) |
533 | return; |
534 | |
535 | int firstIndex = m_series->sets().indexOf(t: sets.at(i: 0)); |
536 | if (firstIndex == -1) |
537 | return; |
538 | |
539 | m_lastSetSection += sets.size(); |
540 | |
541 | blockModelSignals(); |
542 | if (q->orientation() == Qt::Vertical) |
543 | m_model->insertColumns(column: firstIndex + m_firstSetSection, count: sets.size()); |
544 | else |
545 | m_model->insertRows(row: firstIndex + m_firstSetSection, count: sets.size()); |
546 | |
547 | for (int i = 0; i < sets.size(); ++i) { |
548 | int section = i + firstIndex + m_firstSetSection; |
549 | m_model->setData(index: candlestickModelIndex(section, pos: m_timestamp), value: sets.at(i)->timestamp()); |
550 | m_model->setData(index: candlestickModelIndex(section, pos: m_open), value: sets.at(i)->open()); |
551 | m_model->setData(index: candlestickModelIndex(section, pos: m_high), value: sets.at(i)->high()); |
552 | m_model->setData(index: candlestickModelIndex(section, pos: m_low), value: sets.at(i)->low()); |
553 | m_model->setData(index: candlestickModelIndex(section, pos: m_close), value: sets.at(i)->close()); |
554 | } |
555 | blockModelSignals(block: false); |
556 | initializeCandlestickFromModel(); |
557 | } |
558 | |
559 | void QCandlestickModelMapperPrivate::candlestickSetsRemoved(const QList<QCandlestickSet *> &sets) |
560 | { |
561 | Q_Q(QCandlestickModelMapper); |
562 | |
563 | if (m_seriesSignalsBlock) |
564 | return; |
565 | |
566 | if (sets.isEmpty()) |
567 | return; |
568 | |
569 | QList<int> removedIndices; |
570 | for (auto &set : sets) { |
571 | int index = m_sets.indexOf(t: set); |
572 | if (index != -1) |
573 | removedIndices << index; |
574 | } |
575 | |
576 | if (removedIndices.isEmpty()) |
577 | return; |
578 | |
579 | std::sort(first: removedIndices.begin(), last: removedIndices.end()); |
580 | |
581 | for (int i = removedIndices.size() - 1; i >= 0; --i) { |
582 | m_sets.removeAt(i: removedIndices[i]); |
583 | --m_lastSetSection; |
584 | } |
585 | |
586 | blockModelSignals(); |
587 | |
588 | // There is no guarantee removed sets are continuous, so remove them one by one |
589 | for (int i = removedIndices.size() - 1; i >= 0; --i) { |
590 | if (q->orientation() == Qt::Vertical) |
591 | m_model->removeColumns(column: removedIndices[i] + m_firstSetSection, count: 1); |
592 | else |
593 | m_model->removeRows(row: removedIndices[i] + m_firstSetSection, count: 1); |
594 | } |
595 | |
596 | blockModelSignals(block: false); |
597 | initializeCandlestickFromModel(); |
598 | } |
599 | |
600 | void QCandlestickModelMapperPrivate::candlestickSetChanged() |
601 | { |
602 | if (m_seriesSignalsBlock) |
603 | return; |
604 | |
605 | QCandlestickSet *set = qobject_cast<QCandlestickSet *>(object: QObject::sender()); |
606 | if (!set) |
607 | return; |
608 | |
609 | int section = m_series->sets().indexOf(t: set); |
610 | if (section < 0) |
611 | return; |
612 | |
613 | section += m_firstSetSection; |
614 | |
615 | blockModelSignals(); |
616 | m_model->setData(index: candlestickModelIndex(section, pos: m_timestamp), value: set->timestamp()); |
617 | m_model->setData(index: candlestickModelIndex(section, pos: m_open), value: set->open()); |
618 | m_model->setData(index: candlestickModelIndex(section, pos: m_high), value: set->high()); |
619 | m_model->setData(index: candlestickModelIndex(section, pos: m_low), value: set->low()); |
620 | m_model->setData(index: candlestickModelIndex(section, pos: m_close), value: set->close()); |
621 | blockModelSignals(block: false); |
622 | } |
623 | |
624 | void QCandlestickModelMapperPrivate::seriesDestroyed() |
625 | { |
626 | m_series = 0; |
627 | } |
628 | |
629 | QCandlestickSet *QCandlestickModelMapperPrivate::candlestickSet(QModelIndex index) |
630 | { |
631 | Q_Q(QCandlestickModelMapper); |
632 | |
633 | if (!index.isValid()) |
634 | return 0; |
635 | |
636 | int section = (q->orientation() == Qt::Vertical) ? index.column() : index.row(); |
637 | int pos = (q->orientation() == Qt::Vertical) ? index.row() : index.column(); |
638 | |
639 | if (section < m_firstSetSection || section > m_lastSetSection) |
640 | return 0; // This part of model has not been mapped to any candlestick set. |
641 | |
642 | if (pos != m_timestamp && pos != m_open && pos != m_high && pos != m_low && pos != m_close) |
643 | return 0; // This part of model has not been mapped to any candlestick set. |
644 | |
645 | return m_series->sets().at(i: section - m_firstSetSection); |
646 | } |
647 | |
648 | QModelIndex QCandlestickModelMapperPrivate::candlestickModelIndex(int section, int pos) |
649 | { |
650 | Q_Q(QCandlestickModelMapper); |
651 | |
652 | if (section < m_firstSetSection || section > m_lastSetSection) |
653 | return QModelIndex(); // invalid |
654 | |
655 | if (pos != m_timestamp && pos != m_open && pos != m_high && pos != m_low && pos != m_close) |
656 | return QModelIndex(); // invalid |
657 | |
658 | if (q->orientation() == Qt::Vertical) |
659 | return m_model->index(row: pos, column: section); |
660 | else |
661 | return m_model->index(row: section, column: pos); |
662 | } |
663 | |
664 | void QCandlestickModelMapperPrivate::insertData(int start, int end) |
665 | { |
666 | Q_UNUSED(start); |
667 | Q_UNUSED(end); |
668 | |
669 | // Currently candlestickchart needs to be fully recalculated when change is made. |
670 | initializeCandlestickFromModel(); |
671 | } |
672 | |
673 | void QCandlestickModelMapperPrivate::removeData(int start, int end) |
674 | { |
675 | Q_UNUSED(start); |
676 | Q_UNUSED(end); |
677 | |
678 | // Currently candlestickchart needs to be fully recalculated when change is made. |
679 | initializeCandlestickFromModel(); |
680 | } |
681 | |
682 | void QCandlestickModelMapperPrivate::blockModelSignals(bool block) |
683 | { |
684 | m_modelSignalsBlock = block; |
685 | } |
686 | |
687 | void QCandlestickModelMapperPrivate::blockSeriesSignals(bool block) |
688 | { |
689 | m_seriesSignalsBlock = block; |
690 | } |
691 | |
692 | QT_END_NAMESPACE |
693 | |
694 | #include "moc_qcandlestickmodelmapper.cpp" |
695 | #include "moc_qcandlestickmodelmapper_p.cpp" |
696 | |