##// END OF EJS Templates
Model mappers now connected to series and model destroy signals
Marek Rosa -
r1656:449d9eb6f2f2
parent child
Show More
@@ -1,556 +1,568
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qbarmodelmapper.h"
22 22 #include "qbarmodelmapper_p.h"
23 23 #include "qabstractbarseries.h"
24 24 #include "qbarset.h"
25 25 #include "qchart.h"
26 26 #include <QAbstractItemModel>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 QBarModelMapper::QBarModelMapper(QObject *parent) :
31 31 QObject(parent),
32 32 d_ptr(new QBarModelMapperPrivate(this))
33 33 {
34 34 }
35 35
36 36 QAbstractItemModel* QBarModelMapper::model() const
37 37 {
38 38 Q_D(const QBarModelMapper);
39 39 return d->m_model;
40 40 }
41 41
42 42 void QBarModelMapper::setModel(QAbstractItemModel *model)
43 43 {
44 44 if (model == 0)
45 45 return;
46 46
47 47 Q_D(QBarModelMapper);
48 48 if (d->m_model) {
49 49 disconnect(d->m_model, 0, d, 0);
50 50 }
51 51
52 52 d->m_model = model;
53 53 d->initializeBarFromModel();
54 54 // connect signals from the model
55 55 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
56 56 connect(d->m_model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), d, SLOT(modelHeaderDataUpdated(Qt::Orientation,int,int)));
57 57 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
58 58 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
59 59 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
60 60 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
61 connect(d->m_model, SIGNAL(destroyed()), d, SLOT(handleModelDestroyed()));
61 62 }
62 63
63 64 QAbstractBarSeries* QBarModelMapper::series() const
64 65 {
65 66 Q_D(const QBarModelMapper);
66 67 return d->m_series;
67 68 }
68 69
69 70 void QBarModelMapper::setSeries(QAbstractBarSeries *series)
70 71 {
71 72 Q_D(QBarModelMapper);
72 73 if (d->m_series) {
73 74 disconnect(d->m_series, 0, d, 0);
74 75 }
75 76
76 77 if (series == 0)
77 78 return;
78 79
79 80 d->m_series = series;
80 81 d->initializeBarFromModel();
81 82 // connect the signals from the series
82 83 connect(d->m_series, SIGNAL(barsetsAdded(QList<QBarSet*>)), d, SLOT(barSetsAdded(QList<QBarSet*>)));
83 84 connect(d->m_series, SIGNAL(barsetsRemoved(QList<QBarSet*>)), d, SLOT(barSetsRemoved(QList<QBarSet*>)));
85 connect(d->m_series, SIGNAL(destroyed()), d, SLOT(handleSeriesDestroyed()));
84 86 }
85 87
86 88 /*!
87 89 Returns which row/column of the model contains the first values of the QBarSets in the series.
88 90 The default value is 0.
89 91 */
90 92 int QBarModelMapper::first() const
91 93 {
92 94 Q_D(const QBarModelMapper);
93 95 return d->m_first;
94 96 }
95 97
96 98 /*!
97 99 Sets which row of the model contains the \a first values of the QBarSets in the series.
98 100 The default value is 0.
99 101 */
100 102 void QBarModelMapper::setFirst(int first)
101 103 {
102 104 Q_D(QBarModelMapper);
103 105 d->m_first = qMax(first, 0);
104 106 d->initializeBarFromModel();
105 107 }
106 108
107 109 /*!
108 110 Returns the number of rows/columns of the model that are mapped as the data for QAbstractBarSeries
109 111 Minimal and default value is: -1 (count limited by the number of rows/columns in the model)
110 112 */
111 113 int QBarModelMapper::count() const
112 114 {
113 115 Q_D(const QBarModelMapper);
114 116 return d->m_count;
115 117 }
116 118
117 119 /*!
118 120 Sets the \a count of rows/columns of the model that are mapped as the data for QAbstractBarSeries
119 121 Minimal and default value is: -1 (count limited by the number of rows/columns in the model)
120 122 */
121 123 void QBarModelMapper::setCount(int count)
122 124 {
123 125 Q_D(QBarModelMapper);
124 126 d->m_count = qMax(count, -1);
125 127 d->initializeBarFromModel();
126 128 }
127 129
128 130 /*!
129 131 Returns the orientation that is used when QBarModelMapper accesses the model.
130 132 This mean whether the consecutive values of the bar set are read from row (Qt::Horizontal)
131 133 or from columns (Qt::Vertical)
132 134 */
133 135 Qt::Orientation QBarModelMapper::orientation() const
134 136 {
135 137 Q_D(const QBarModelMapper);
136 138 return d->m_orientation;
137 139 }
138 140
139 141 /*!
140 142 Returns the \a orientation that is used when QBarModelMapper accesses the model.
141 143 This mean whether the consecutive values of the pie are read from row (Qt::Horizontal)
142 144 or from columns (Qt::Vertical)
143 145 */
144 146 void QBarModelMapper::setOrientation(Qt::Orientation orientation)
145 147 {
146 148 Q_D(QBarModelMapper);
147 149 d->m_orientation = orientation;
148 150 d->initializeBarFromModel();
149 151 }
150 152
151 153 /*!
152 154 Returns which section of the model is used as the data source for the first bar set
153 155 */
154 156 int QBarModelMapper::firstBarSetSection() const
155 157 {
156 158 Q_D(const QBarModelMapper);
157 159 return d->m_firstBarSetSection;
158 160 }
159 161
160 162 /*!
161 163 Sets the model section that is used as the data source for the first bar set
162 164 Parameter \a firstBarSetSection specifies the section of the model.
163 165 */
164 166 void QBarModelMapper::setFirstBarSetSection(int firstBarSetSection)
165 167 {
166 168 Q_D(QBarModelMapper);
167 169 d->m_firstBarSetSection = qMax(-1, firstBarSetSection);
168 170 d->initializeBarFromModel();
169 171 }
170 172
171 173 /*!
172 174 Returns which section of the model is used as the data source for the last bar set
173 175 */
174 176 int QBarModelMapper::lastBarSetSection() const
175 177 {
176 178 Q_D(const QBarModelMapper);
177 179 return d->m_lastBarSetSection;
178 180 }
179 181
180 182 /*!
181 183 Sets the model section that is used as the data source for the last bar set
182 184 Parameter \a lastBarSetSection specifies the section of the model.
183 185 */
184 186 void QBarModelMapper::setLastBarSetSection(int lastBarSetSection)
185 187 {
186 188 Q_D(QBarModelMapper);
187 189 d->m_lastBarSetSection = qMax(-1, lastBarSetSection);
188 190 d->initializeBarFromModel();
189 191 }
190 192
191 193 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
192 194
193 195 QBarModelMapperPrivate::QBarModelMapperPrivate(QBarModelMapper *q) :
194 196 m_series(0),
195 197 m_model(0),
196 198 m_first(0),
197 199 m_count(-1),
198 200 m_orientation(Qt::Vertical),
199 201 m_firstBarSetSection(-1),
200 202 m_lastBarSetSection(-1),
201 203 m_seriesSignalsBlock(false),
202 204 m_modelSignalsBlock(false),
203 205 q_ptr(q)
204 206 {
205 207 }
206 208
207 209 void QBarModelMapperPrivate::blockModelSignals(bool block)
208 210 {
209 211 m_modelSignalsBlock = block;
210 212 }
211 213
212 214 void QBarModelMapperPrivate::blockSeriesSignals(bool block)
213 215 {
214 216 m_seriesSignalsBlock = block;
215 217 }
216 218
217 219 QBarSet* QBarModelMapperPrivate::barSet(QModelIndex index)
218 220 {
219 221 if (!index.isValid())
220 222 return 0;
221 223
222 224 if (m_orientation == Qt::Vertical && index.column() >= m_firstBarSetSection && index.column() <= m_lastBarSetSection) {
223 225 if (index.row() >= m_first && (m_count == - 1 || index.row() < m_first + m_count)) {
224 226 // if (m_model->index(index.row(), m_valuesSection).isValid() && m_model->index(index.row(), m_labelsSection).isValid())
225 227 return m_series->barSets().at(index.column() - m_firstBarSetSection);
226 228 // else
227 229 // return 0;
228 230 }
229 231 } else if (m_orientation == Qt::Horizontal && index.row() >= m_firstBarSetSection && index.row() <= m_lastBarSetSection) {
230 232 if (index.column() >= m_first && (m_count == - 1 || index.column() < m_first + m_count))
231 233 return m_series->barSets().at(index.row() - m_firstBarSetSection);
232 234 }
233 235 return 0; // This part of model has not been mapped to any slice
234 236 }
235 237
236 238 QModelIndex QBarModelMapperPrivate::barModelIndex(int barSection, int posInBar)
237 239 {
238 240 if (m_count != -1 && posInBar >= m_count)
239 241 return QModelIndex(); // invalid
240 242
241 243 if (barSection < m_firstBarSetSection || barSection > m_lastBarSetSection)
242 244 return QModelIndex(); // invalid
243 245
244 246 if (m_orientation == Qt::Vertical)
245 247 return m_model->index(posInBar + m_first, barSection);
246 248 else
247 249 return m_model->index(barSection, posInBar + m_first);
248 250 }
249 251
252 void QBarModelMapperPrivate::handleSeriesDestroyed()
253 {
254 m_series = 0;
255 }
256
250 257 void QBarModelMapperPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
251 258 {
252 259 Q_UNUSED(topLeft)
253 260 Q_UNUSED(bottomRight)
254 261
255 262 if (m_model == 0 || m_series == 0)
256 263 return;
257 264
258 265 if (m_modelSignalsBlock)
259 266 return;
260 267
261 268 blockSeriesSignals();
262 269 QModelIndex index;
263 270 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
264 271 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
265 272 index = topLeft.sibling(row, column);
266 273 QBarSet* bar = barSet(index);
267 274 if (bar) {
268 275 if (m_orientation == Qt::Vertical)
269 276 bar->replace(row - m_first, m_model->data(index).toReal());
270 277 else
271 278 bar->replace(column - m_first, m_model->data(index).toReal());
272 279 }
273 280 }
274 281 }
275 282 blockSeriesSignals(false);
276 283 }
277 284
278 285 void QBarModelMapperPrivate::modelHeaderDataUpdated(Qt::Orientation orientation, int first, int last)
279 286 {
280 287 if (m_model == 0 || m_series == 0)
281 288 return;
282 289
283 290 if (m_modelSignalsBlock)
284 291 return;
285 292
286 293 blockSeriesSignals();
287 294 if (orientation != m_orientation) {
288 295 for (int section = first; section <= last; section++) {
289 296 if (section >= m_firstBarSetSection && section <= m_lastBarSetSection) {
290 297 QBarSet* bar = m_series->barSets().at(section - m_firstBarSetSection);
291 298 if (bar)
292 299 bar->setLabel(m_model->headerData(section, orientation).toString());
293 300 }
294 301 }
295 302 }
296 303 blockSeriesSignals(false);
297 304 }
298 305
299 306 void QBarModelMapperPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
300 307 {
301 308 Q_UNUSED(parent);
302 309 Q_UNUSED(end)
303 310 if (m_modelSignalsBlock)
304 311 return;
305 312
306 313 blockSeriesSignals();
307 314 if (m_orientation == Qt::Vertical)
308 315 // insertData(start, end);
309 316 initializeBarFromModel();
310 317 else if (start <= m_firstBarSetSection || start <= m_lastBarSetSection) // if the changes affect the map - reinitialize
311 318 initializeBarFromModel();
312 319 blockSeriesSignals(false);
313 320 }
314 321
315 322 void QBarModelMapperPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
316 323 {
317 324 Q_UNUSED(parent);
318 325 Q_UNUSED(end)
319 326 if (m_modelSignalsBlock)
320 327 return;
321 328
322 329 blockSeriesSignals();
323 330 if (m_orientation == Qt::Vertical)
324 331 // removeData(start, end);
325 332 initializeBarFromModel();
326 333 else if (start <= m_firstBarSetSection || start <= m_lastBarSetSection) // if the changes affect the map - reinitialize
327 334 initializeBarFromModel();
328 335 blockSeriesSignals(false);
329 336 }
330 337
331 338 void QBarModelMapperPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
332 339 {
333 340 Q_UNUSED(parent);
334 341 Q_UNUSED(end)
335 342 if (m_modelSignalsBlock)
336 343 return;
337 344
338 345 blockSeriesSignals();
339 346 if (m_orientation == Qt::Horizontal)
340 347 // insertData(start, end);
341 348 initializeBarFromModel();
342 349 else if (start <= m_firstBarSetSection || start <= m_lastBarSetSection) // if the changes affect the map - reinitialize
343 350 initializeBarFromModel();
344 351 blockSeriesSignals(false);
345 352 }
346 353
347 354 void QBarModelMapperPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
348 355 {
349 356 Q_UNUSED(parent);
350 357 Q_UNUSED(end)
351 358 if (m_modelSignalsBlock)
352 359 return;
353 360
354 361 blockSeriesSignals();
355 362 if (m_orientation == Qt::Horizontal)
356 363 // removeData(start, end);
357 364 initializeBarFromModel();
358 365 else if (start <= m_firstBarSetSection || start <= m_lastBarSetSection) // if the changes affect the map - reinitialize
359 366 initializeBarFromModel();
360 367 blockSeriesSignals(false);
361 368 }
362 369
370 void QBarModelMapperPrivate::handleModelDestroyed()
371 {
372 m_model = 0;
373 }
374
363 375 void QBarModelMapperPrivate::insertData(int start, int end)
364 376 {
365 377 Q_UNUSED(end)
366 378 Q_UNUSED(start)
367 379 Q_UNUSED(end)
368 380 // To be implemented
369 381 }
370 382
371 383 void QBarModelMapperPrivate::removeData(int start, int end)
372 384 {
373 385 Q_UNUSED(end)
374 386 Q_UNUSED(start)
375 387 Q_UNUSED(end)
376 388 // To be implemented
377 389 }
378 390
379 391 void QBarModelMapperPrivate::barSetsAdded(QList<QBarSet*> sets)
380 392 {
381 393 if (m_seriesSignalsBlock)
382 394 return;
383 395
384 396 if (sets.count() == 0)
385 397 return;
386 398
387 399 int firstIndex = m_series->barSets().indexOf(sets.at(0));
388 400 if (firstIndex == -1)
389 401 return;
390 402
391 403 int maxCount = 0;
392 404 for(int i = 0; i < sets.count(); i++)
393 405 if (sets.at(i)->count() > m_count)
394 406 maxCount = sets.at(i)->count();
395 407
396 408 if (m_count != -1 && m_count < maxCount)
397 409 m_count = maxCount;
398 410
399 411 m_lastBarSetSection += sets.count();
400 412
401 413 blockModelSignals();
402 414 int modelCapacity = m_orientation == Qt::Vertical ? m_model->rowCount() - m_first : m_model->columnCount() - m_first;
403 415 if (maxCount > modelCapacity) {
404 416 if (m_orientation == Qt::Vertical)
405 417 m_model->insertRows(m_model->rowCount(), maxCount - modelCapacity);
406 418 else
407 419 m_model->insertColumns(m_model->columnCount(), maxCount - modelCapacity);
408 420 }
409 421
410 422 if (m_orientation == Qt::Vertical)
411 423 m_model->insertColumns(firstIndex + m_firstBarSetSection, sets.count());
412 424 else
413 425 m_model->insertRows(firstIndex + m_firstBarSetSection, sets.count());
414 426
415 427
416 428 for(int i = firstIndex + m_firstBarSetSection; i < firstIndex + m_firstBarSetSection + sets.count(); i++) {
417 429 m_model->setHeaderData(i, m_orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical, sets.at(i - firstIndex - m_firstBarSetSection)->label());
418 430 for (int j = 0; j < sets.at(i - firstIndex - m_firstBarSetSection)->count(); j++)
419 431 m_model->setData(barModelIndex(i, j), sets.at(i - firstIndex - m_firstBarSetSection)->at(j));
420 432 }
421 433 blockModelSignals(false);
422 434 initializeBarFromModel();
423 435 }
424 436
425 437 void QBarModelMapperPrivate::barSetsRemoved(QList<QBarSet*> sets)
426 438 {
427 439 if (m_seriesSignalsBlock)
428 440 return;
429 441
430 442 if (sets.count() == 0)
431 443 return;
432 444
433 445 int firstIndex = m_barSets.indexOf(sets.at(0));
434 446 if (firstIndex == -1)
435 447 return;
436 448
437 449 m_lastBarSetSection -= sets.count();
438 450
439 451 for (int i = firstIndex + sets.count() - 1; i >= firstIndex; i--)
440 452 m_barSets.removeAt(i);
441 453
442 454 blockModelSignals();
443 455 if (m_orientation == Qt::Vertical)
444 456 m_model->removeColumns(firstIndex + m_firstBarSetSection, sets.count());
445 457 else
446 458 m_model->removeRows(firstIndex + m_firstBarSetSection, sets.count());
447 459 blockModelSignals(false);
448 460 initializeBarFromModel();
449 461 }
450 462
451 463 void QBarModelMapperPrivate::valuesAdded(int index, int count)
452 464 {
453 465 if (m_seriesSignalsBlock)
454 466 return;
455 467
456 468 if (m_count != -1)
457 469 m_count += count;
458 470
459 471 int barSetIndex = m_barSets.indexOf(qobject_cast<QBarSet *>(QObject::sender()));
460 472
461 473 blockModelSignals();
462 474 if (m_orientation == Qt::Vertical)
463 475 m_model->insertRows(index + m_first, count);
464 476 else
465 477 m_model->insertColumns(index + m_first, count);
466 478
467 479 for (int j = index; j < index + count; j++)
468 480 m_model->setData(barModelIndex(barSetIndex + m_firstBarSetSection, j), m_barSets.at(barSetIndex)->at(j));
469 481
470 482 blockModelSignals(false);
471 483 initializeBarFromModel();
472 484 }
473 485
474 486 void QBarModelMapperPrivate::valuesRemoved(int index, int count)
475 487 {
476 488 if (m_seriesSignalsBlock)
477 489 return;
478 490
479 491 if (m_count != -1)
480 492 m_count -= count;
481 493
482 494 blockModelSignals();
483 495 if (m_orientation == Qt::Vertical)
484 496 m_model->removeRows(index + m_first, count);
485 497 else
486 498 m_model->removeColumns(index + m_first, count);
487 499
488 500 blockModelSignals(false);
489 501 initializeBarFromModel();
490 502 }
491 503
492 504 void QBarModelMapperPrivate::barLabelChanged()
493 505 {
494 506 if (m_seriesSignalsBlock)
495 507 return;
496 508
497 509 int barSetIndex = m_barSets.indexOf(qobject_cast<QBarSet *>(QObject::sender()));
498 510
499 511 blockModelSignals();
500 512 m_model->setHeaderData(barSetIndex + m_firstBarSetSection, m_orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical, m_barSets.at(barSetIndex)->label());
501 513 blockModelSignals(false);
502 514 initializeBarFromModel();
503 515 }
504 516
505 517 void QBarModelMapperPrivate::barValueChanged(int index)
506 518 {
507 519 if (m_seriesSignalsBlock)
508 520 return;
509 521
510 522 int barSetIndex = m_barSets.indexOf(qobject_cast<QBarSet *>(QObject::sender()));
511 523
512 524 blockModelSignals();
513 525 m_model->setData(barModelIndex(barSetIndex + m_firstBarSetSection, index), m_barSets.at(barSetIndex)->at(index));
514 526 blockModelSignals(false);
515 527 initializeBarFromModel();
516 528 }
517 529
518 530 void QBarModelMapperPrivate::initializeBarFromModel()
519 531 {
520 532 if (m_model == 0 || m_series == 0)
521 533 return;
522 534
523 535 blockSeriesSignals();
524 536 // clear current content
525 537 m_series->clear();
526 538 m_barSets.clear();
527 539
528 540 // create the initial bar sets
529 541 for (int i = m_firstBarSetSection; i <= m_lastBarSetSection; i++) {
530 542 int posInBar = 0;
531 543 QModelIndex barIndex = barModelIndex(i, posInBar);
532 544 // check if there is such model index
533 545 if (barIndex.isValid()) {
534 546 QBarSet *barSet = new QBarSet(m_model->headerData(i, m_orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical).toString());
535 547 while (barIndex.isValid()) {
536 548 barSet->append(m_model->data(barIndex, Qt::DisplayRole).toDouble());
537 549 posInBar++;
538 550 barIndex = barModelIndex(i, posInBar);
539 551 }
540 552 connect(barSet, SIGNAL(valuesAdded(int, int)), this, SLOT(valuesAdded(int, int)));
541 553 connect(barSet, SIGNAL(valuesRemoved(int, int)), this, SLOT(valuesRemoved(int, int)));
542 554 connect(barSet, SIGNAL(valueChanged(int)), this, SLOT(barValueChanged(int)));
543 555 connect(barSet, SIGNAL(labelChanged()), this, SLOT(barLabelChanged()));
544 556 m_series->append(barSet);
545 557 m_barSets.append(barSet);
546 558 } else {
547 559 break;
548 560 }
549 561 }
550 562 blockSeriesSignals(false);
551 563 }
552 564
553 565 #include "moc_qbarmodelmapper.cpp"
554 566 #include "moc_qbarmodelmapper_p.cpp"
555 567
556 568 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,95 +1,97
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QBARMODELMAPPER_P_H
31 31 #define QBARMODELMAPPER_P_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include <QObject>
35 35 #include "qbarmodelmapper.h"
36 36
37 37 class QModelIndex;
38 38
39 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 40
41 41 class QBarSet;
42 42
43 43 class QBarModelMapperPrivate : public QObject
44 44 {
45 45 Q_OBJECT
46 46 public:
47 47 explicit QBarModelMapperPrivate(QBarModelMapper *q);
48 48
49 49 public Q_SLOTS:
50 50 // for the model
51 51 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
52 52 void modelHeaderDataUpdated(Qt::Orientation orientation, int first, int last);
53 53 void modelRowsAdded(QModelIndex parent, int start, int end);
54 54 void modelRowsRemoved(QModelIndex parent, int start, int end);
55 55 void modelColumnsAdded(QModelIndex parent, int start, int end);
56 56 void modelColumnsRemoved(QModelIndex parent, int start, int end);
57 void handleModelDestroyed();
57 58
58 59 // for the series
59 60 void barSetsAdded(QList<QBarSet*> sets);
60 61 void barSetsRemoved(QList<QBarSet*> sets);
61 62 void valuesAdded(int index, int count);
62 63 void valuesRemoved(int index, int count);
63 64 void barLabelChanged();
64 65 void barValueChanged(int index);
66 void handleSeriesDestroyed();
65 67
66 68 void initializeBarFromModel();
67 69
68 70 private:
69 71 QBarSet* barSet(QModelIndex index);
70 72 QModelIndex barModelIndex(int barSection, int posInBar);
71 73 void insertData(int start, int end);
72 74 void removeData(int start, int end);
73 75 void blockModelSignals(bool block = true);
74 76 void blockSeriesSignals(bool block = true);
75 77
76 78 private:
77 79 QAbstractBarSeries *m_series;
78 80 QList<QBarSet*> m_barSets;
79 81 QAbstractItemModel *m_model;
80 82 int m_first;
81 83 int m_count;
82 84 Qt::Orientation m_orientation;
83 85 int m_firstBarSetSection;
84 86 int m_lastBarSetSection;
85 87 bool m_seriesSignalsBlock;
86 88 bool m_modelSignalsBlock;
87 89
88 90 private:
89 91 QBarModelMapper *q_ptr;
90 92 Q_DECLARE_PUBLIC(QBarModelMapper)
91 93 };
92 94
93 95 QTCOMMERCIALCHART_END_NAMESPACE
94 96
95 97 #endif // QBARMODELMAPPER_P_H
@@ -1,555 +1,567
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qpiemodelmapper_p.h"
22 22 #include "qpiemodelmapper.h"
23 23 #include "qpieseries.h"
24 24 #include "qpieslice.h"
25 25 #include <QAbstractItemModel>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 QPieModelMapper::QPieModelMapper(QObject *parent) :
30 30 QObject(parent),
31 31 d_ptr(new QPieModelMapperPrivate(this))
32 32 {
33 33 }
34 34
35 35 QAbstractItemModel* QPieModelMapper::model() const
36 36 {
37 37 Q_D(const QPieModelMapper);
38 38 return d->m_model;
39 39 }
40 40
41 41 void QPieModelMapper::setModel(QAbstractItemModel *model)
42 42 {
43 43 if (model == 0)
44 44 return;
45 45
46 46 Q_D(QPieModelMapper);
47 47 if (d->m_model) {
48 48 disconnect(d->m_model, 0, d, 0);
49 49 }
50 50
51 51 d->m_model = model;
52 52 d->initializePieFromModel();
53 53 // connect signals from the model
54 54 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
55 55 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
56 56 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
57 57 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
58 58 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
59 connect(d->m_model, SIGNAL(destroyed()), d, SLOT(handleModelDestroyed()));
59 60 }
60 61
61 62 QPieSeries* QPieModelMapper::series() const
62 63 {
63 64 Q_D(const QPieModelMapper);
64 65 return d->m_series;
65 66 }
66 67
67 68 void QPieModelMapper::setSeries(QPieSeries *series)
68 69 {
69 70 Q_D(QPieModelMapper);
70 71 if (d->m_series) {
71 72 disconnect(d->m_series, 0, d, 0);
72 73 }
73 74
74 75 if (series == 0)
75 76 return;
76 77
77 78 d->m_series = series;
78 79 d->initializePieFromModel();
79 80 // connect the signals from the series
80 81 connect(d->m_series, SIGNAL(added(QList<QPieSlice*>)), d, SLOT(slicesAdded(QList<QPieSlice*>)));
81 82 connect(d->m_series, SIGNAL(removed(QList<QPieSlice*>)), d, SLOT(slicesRemoved(QList<QPieSlice*>)));
83 connect(d->m_series, SIGNAL(destroyed()), d, SLOT(handleSeriesDestroyed()));
82 84 }
83 85
84 86 /*!
85 87 Defines which row/column of the model contains the first slice value.
86 88 Minimal and default value is: 0
87 89 */
88 90 int QPieModelMapper::first() const
89 91 {
90 92 Q_D(const QPieModelMapper);
91 93 return d->m_first;
92 94 }
93 95
94 96 /*!
95 97 Sets which row/column of the model contains the \a first slice value.
96 98 Minimal and default value is: 0
97 99 */
98 100 void QPieModelMapper::setFirst(int first)
99 101 {
100 102 Q_D(QPieModelMapper);
101 103 d->m_first = qMax(first, 0);
102 104 d->initializePieFromModel();
103 105 }
104 106
105 107 /*!
106 108 Defines the number of rows/columns of the model that are mapped as the data for QPieSeries
107 109 Minimal and default value is: -1 (count limited by the number of rows/columns in the model)
108 110 */
109 111 int QPieModelMapper::count() const
110 112 {
111 113 Q_D(const QPieModelMapper);
112 114 return d->m_count;
113 115 }
114 116
115 117 /*!
116 118 Defines the \a count of rows/columns of the model that are mapped as the data for QPieSeries
117 119 Minimal and default value is: -1 (count limited by the number of rows/columns in the model)
118 120 */
119 121 void QPieModelMapper::setCount(int count)
120 122 {
121 123 Q_D(QPieModelMapper);
122 124 d->m_count = qMax(count, -1);
123 125 d->initializePieFromModel();
124 126 }
125 127
126 128 /*!
127 129 Returns the orientation that is used when QPieModelMapper accesses the model.
128 130 This mean whether the consecutive values/labels of the pie are read from row (Qt::Horizontal)
129 131 or from columns (Qt::Vertical)
130 132 */
131 133 Qt::Orientation QPieModelMapper::orientation() const
132 134 {
133 135 Q_D(const QPieModelMapper);
134 136 return d->m_orientation;
135 137 }
136 138
137 139 /*!
138 140 Returns the \a orientation that is used when QPieModelMapper accesses the model.
139 141 This mean whether the consecutive values/labels of the pie are read from row (Qt::Horizontal)
140 142 or from columns (Qt::Vertical)
141 143 */
142 144 void QPieModelMapper::setOrientation(Qt::Orientation orientation)
143 145 {
144 146 Q_D(QPieModelMapper);
145 147 d->m_orientation = orientation;
146 148 d->initializePieFromModel();
147 149 }
148 150
149 151 /*!
150 152 Returns which section of the model is kept in sync with the values of the pie's slices
151 153 */
152 154 int QPieModelMapper::valuesSection() const
153 155 {
154 156 Q_D(const QPieModelMapper);
155 157 return d->m_valuesSection;
156 158 }
157 159
158 160 /*!
159 161 Sets the model section that is kept in sync with the pie slices values.
160 162 Parameter \a valuesSection specifies the section of the model.
161 163 */
162 164 void QPieModelMapper::setValuesSection(int valuesSection)
163 165 {
164 166 Q_D(QPieModelMapper);
165 167 d->m_valuesSection = qMax(-1, valuesSection);
166 168 d->initializePieFromModel();
167 169 }
168 170
169 171 /*!
170 172 Returns which section of the model is kept in sync with the labels of the pie's slices
171 173 */
172 174 int QPieModelMapper::labelsSection() const
173 175 {
174 176 Q_D(const QPieModelMapper);
175 177 return d->m_labelsSection;
176 178 }
177 179
178 180 /*!
179 181 Sets the model section that is kept in sync with the pie slices labels.
180 182 Parameter \a labelsSection specifies the section of the model.
181 183 */
182 184 void QPieModelMapper::setLabelsSection(int labelsSection)
183 185 {
184 186 Q_D(QPieModelMapper);
185 187 d->m_labelsSection = qMax(-1, labelsSection);
186 188 d->initializePieFromModel();
187 189 }
188 190
189 191 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
190 192
191 193 QPieModelMapperPrivate::QPieModelMapperPrivate(QPieModelMapper *q) :
192 194 m_series(0),
193 195 m_model(0),
194 196 m_first(0),
195 197 m_count(-1),
196 198 m_orientation(Qt::Vertical),
197 199 m_valuesSection(-1),
198 200 m_labelsSection(-1),
199 201 m_seriesSignalsBlock(false),
200 202 m_modelSignalsBlock(false),
201 203 q_ptr(q)
202 204 {
203 205 }
204 206
205 207 void QPieModelMapperPrivate::blockModelSignals(bool block)
206 208 {
207 209 m_modelSignalsBlock = block;
208 210 }
209 211
210 212 void QPieModelMapperPrivate::blockSeriesSignals(bool block)
211 213 {
212 214 m_seriesSignalsBlock = block;
213 215 }
214 216
215 217
216 218 QPieSlice* QPieModelMapperPrivate::pieSlice(QModelIndex index) const
217 219 {
218 220 if (!index.isValid())
219 221 return 0; // index is invalid
220 222
221 223 if (m_orientation == Qt::Vertical && (index.column() == m_valuesSection || index.column() == m_labelsSection)) {
222 224 if (index.row() >= m_first && (m_count == - 1 || index.row() < m_first + m_count)) {
223 225 if (m_model->index(index.row(), m_valuesSection).isValid() && m_model->index(index.row(), m_labelsSection).isValid())
224 226 return m_series->slices().at(index.row() - m_first);
225 227 else
226 228 return 0;
227 229 }
228 230 } else if (m_orientation == Qt::Horizontal && (index.row() == m_valuesSection || index.row() == m_labelsSection)) {
229 231 if (index.column() >= m_first && (m_count == - 1 || index.column() < m_first + m_count)) {
230 232 if (m_model->index(m_valuesSection, index.column()).isValid() && m_model->index(m_labelsSection, index.column()).isValid())
231 233 return m_series->slices().at(index.column() - m_first);
232 234 else
233 235 return 0;
234 236 }
235 237 }
236 238 return 0; // This part of model has not been mapped to any slice
237 239 }
238 240
239 241 QModelIndex QPieModelMapperPrivate::valueModelIndex(int slicePos)
240 242 {
241 243 if (m_count != -1 && slicePos >= m_count)
242 244 return QModelIndex(); // invalid
243 245
244 246 if (m_orientation == Qt::Vertical)
245 247 return m_model->index(slicePos + m_first, m_valuesSection);
246 248 else
247 249 return m_model->index(m_valuesSection, slicePos + m_first);
248 250 }
249 251
250 252 QModelIndex QPieModelMapperPrivate::labelModelIndex(int slicePos)
251 253 {
252 254 if (m_count != -1 && slicePos >= m_count)
253 255 return QModelIndex(); // invalid
254 256
255 257 if (m_orientation == Qt::Vertical)
256 258 return m_model->index(slicePos + m_first, m_labelsSection);
257 259 else
258 260 return m_model->index(m_labelsSection, slicePos + m_first);
259 261 }
260 262
261 263 bool QPieModelMapperPrivate::isLabelIndex(QModelIndex index) const
262 264 {
263 265 if (m_orientation == Qt::Vertical && index.column() == m_labelsSection)
264 266 return true;
265 267 else if (m_orientation == Qt::Horizontal && index.row() == m_labelsSection)
266 268 return true;
267 269
268 270 return false;
269 271 }
270 272
271 273 bool QPieModelMapperPrivate::isValueIndex(QModelIndex index) const
272 274 {
273 275 if (m_orientation == Qt::Vertical && index.column() == m_valuesSection)
274 276 return true;
275 277 else if (m_orientation == Qt::Horizontal && index.row() == m_valuesSection)
276 278 return true;
277 279
278 280 return false;
279 281 }
280 282
281 283 void QPieModelMapperPrivate::slicesAdded(QList<QPieSlice*> slices)
282 284 {
283 285 if (m_seriesSignalsBlock)
284 286 return;
285 287
286 288 if (slices.count() == 0)
287 289 return;
288 290
289 291 int firstIndex = m_series->slices().indexOf(slices.at(0));
290 292 if (firstIndex == -1)
291 293 return;
292 294
293 295 if (m_count != -1)
294 296 m_count += slices.count();
295 297
296 298 for (int i = firstIndex; i < firstIndex + slices.count(); i++) {
297 299 m_slices.insert(i, slices.at(i - firstIndex));
298 300 connect(slices.at(i - firstIndex), SIGNAL(labelChanged()), this, SLOT(sliceLabelChanged()));
299 301 connect(slices.at(i - firstIndex), SIGNAL(valueChanged()), this, SLOT(sliceValueChanged()));
300 302 }
301 303
302 304 blockModelSignals();
303 305 if (m_orientation == Qt::Vertical)
304 306 m_model->insertRows(firstIndex + m_first, slices.count());
305 307 else
306 308 m_model->insertColumns(firstIndex + m_first, slices.count());
307 309
308 310 for(int i = firstIndex; i < firstIndex + slices.count(); i++) {
309 311 m_model->setData(valueModelIndex(i), slices.at(i - firstIndex)->value());
310 312 m_model->setData(labelModelIndex(i), slices.at(i - firstIndex)->label());
311 313 }
312 314 blockModelSignals(false);
313 315 }
314 316
315 317 void QPieModelMapperPrivate::slicesRemoved(QList<QPieSlice*> slices)
316 318 {
317 319 if (m_seriesSignalsBlock)
318 320 return;
319 321
320 322 if (slices.count() == 0)
321 323 return;
322 324
323 325 int firstIndex = m_slices.indexOf(slices.at(0));
324 326 if (firstIndex == -1)
325 327 return;
326 328
327 329 if (m_count != -1)
328 330 m_count -= slices.count();
329 331
330 332 for (int i = firstIndex + slices.count() - 1; i >= firstIndex; i--)
331 333 m_slices.removeAt(i);
332 334
333 335 blockModelSignals();
334 336 if (m_orientation == Qt::Vertical)
335 337 m_model->removeRows(firstIndex + m_first, slices.count());
336 338 else
337 339 m_model->removeColumns(firstIndex + m_first, slices.count());
338 340 blockModelSignals(false);
339 341 }
340 342
341 343 void QPieModelMapperPrivate::sliceLabelChanged()
342 344 {
343 345 if (m_seriesSignalsBlock)
344 346 return;
345 347
346 348 blockModelSignals();
347 349 QPieSlice *slice = qobject_cast<QPieSlice *>(QObject::sender());
348 350 m_model->setData(labelModelIndex(m_series->slices().indexOf(slice)), slice->label());
349 351 blockModelSignals(false);
350 352 }
351 353
352 354 void QPieModelMapperPrivate::sliceValueChanged()
353 355 {
354 356 if (m_seriesSignalsBlock)
355 357 return;
356 358
357 359 blockModelSignals();
358 360 QPieSlice *slice = qobject_cast<QPieSlice *>(QObject::sender());
359 361 m_model->setData(valueModelIndex(m_series->slices().indexOf(slice)), slice->value());
360 362 blockModelSignals(false);
361 363 }
362 364
365 void QPieModelMapperPrivate::handleSeriesDestroyed()
366 {
367 m_series = 0;
368 }
369
363 370 void QPieModelMapperPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
364 371 {
365 372 if (m_model == 0 || m_series == 0)
366 373 return;
367 374
368 375 if (m_modelSignalsBlock)
369 376 return;
370 377
371 378 blockSeriesSignals();
372 379 QModelIndex index;
373 380 QPieSlice *slice;
374 381 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
375 382 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
376 383 index = topLeft.sibling(row, column);
377 384 slice = pieSlice(index);
378 385 if (slice) {
379 386 if (isValueIndex(index))
380 387 slice->setValue(m_model->data(index, Qt::DisplayRole).toReal());
381 388 if (isLabelIndex(index))
382 389 slice->setLabel(m_model->data(index, Qt::DisplayRole).toString());
383 390 }
384 391 }
385 392 }
386 393 blockSeriesSignals(false);
387 394 }
388 395
389 396
390 397 void QPieModelMapperPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
391 398 {
392 399 Q_UNUSED(parent);
393 400 if (m_modelSignalsBlock)
394 401 return;
395 402
396 403 blockSeriesSignals();
397 404 if (m_orientation == Qt::Vertical)
398 405 insertData(start, end);
399 406 else if (start <= m_valuesSection || start <= m_labelsSection) // if the changes affect the map - reinitialize the pie
400 407 initializePieFromModel();
401 408 blockSeriesSignals(false);
402 409 }
403 410
404 411 void QPieModelMapperPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
405 412 {
406 413 Q_UNUSED(parent);
407 414 if (m_modelSignalsBlock)
408 415 return;
409 416
410 417 blockSeriesSignals();
411 418 if (m_orientation == Qt::Vertical)
412 419 removeData(start, end);
413 420 else if (start <= m_valuesSection || start <= m_labelsSection) // if the changes affect the map - reinitialize the pie
414 421 initializePieFromModel();
415 422 blockSeriesSignals(false);
416 423 }
417 424
418 425 void QPieModelMapperPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
419 426 {
420 427 Q_UNUSED(parent);
421 428 if (m_modelSignalsBlock)
422 429 return;
423 430
424 431 blockSeriesSignals();
425 432 if (m_orientation == Qt::Horizontal)
426 433 insertData(start, end);
427 434 else if (start <= m_valuesSection || start <= m_labelsSection) // if the changes affect the map - reinitialize the pie
428 435 initializePieFromModel();
429 436 blockSeriesSignals(false);
430 437 }
431 438
432 439 void QPieModelMapperPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
433 440 {
434 441 Q_UNUSED(parent);
435 442 if (m_modelSignalsBlock)
436 443 return;
437 444
438 445 blockSeriesSignals();
439 446 if (m_orientation == Qt::Horizontal)
440 447 removeData(start, end);
441 448 else if (start <= m_valuesSection || start <= m_labelsSection) // if the changes affect the map - reinitialize the pie
442 449 initializePieFromModel();
443 450 blockSeriesSignals(false);
444 451 }
445 452
453 void QPieModelMapperPrivate::handleModelDestroyed()
454 {
455 m_model = 0;
456 }
457
446 458 void QPieModelMapperPrivate::insertData(int start, int end)
447 459 {
448 460 if (m_model == 0 || m_series == 0)
449 461 return;
450 462
451 463 if (m_count != -1 && start >= m_first + m_count) {
452 464 return;
453 465 } else {
454 466 int addedCount = end - start + 1;
455 467 if (m_count != -1 && addedCount > m_count)
456 468 addedCount = m_count;
457 469 int first = qMax(start, m_first);
458 470 int last = qMin(first + addedCount - 1, m_orientation == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
459 471 for (int i = first; i <= last; i++) {
460 472 QModelIndex valueIndex = valueModelIndex(i - m_first);
461 473 QModelIndex labelIndex = labelModelIndex(i - m_first);
462 474 if (valueIndex.isValid() && labelIndex.isValid()) {
463 475 QPieSlice *slice = new QPieSlice;
464 476 slice->setValue(m_model->data(valueIndex, Qt::DisplayRole).toDouble());
465 477 slice->setLabel(m_model->data(labelIndex, Qt::DisplayRole).toString());
466 478 connect(slice, SIGNAL(labelChanged()), this, SLOT(sliceLabelChanged()));
467 479 connect(slice, SIGNAL(valueChanged()), this, SLOT(sliceValueChanged()));
468 480 m_series->insert(i - m_first, slice);
469 481 m_slices.insert(i - m_first, slice);
470 482 }
471 483 }
472 484
473 485 // remove excess of slices (abouve m_count)
474 486 if (m_count != -1 && m_series->slices().size() > m_count)
475 487 for (int i = m_series->slices().size() - 1; i >= m_count; i--) {
476 488 m_series->remove(m_series->slices().at(i));
477 489 m_slices.removeAt(i);
478 490 }
479 491 }
480 492 }
481 493
482 494 void QPieModelMapperPrivate::removeData(int start, int end)
483 495 {
484 496 if (m_model == 0 || m_series == 0)
485 497 return;
486 498
487 499 int removedCount = end - start + 1;
488 500 if (m_count != -1 && start >= m_first + m_count) {
489 501 return;
490 502 } else {
491 503 int toRemove = qMin(m_series->slices().size(), removedCount); // first find how many items can actually be removed
492 504 int first = qMax(start, m_first); // get the index of the first item that will be removed.
493 505 int last = qMin(first + toRemove - 1, m_series->slices().size() + m_first - 1); // get the index of the last item that will be removed.
494 506 for (int i = last; i >= first; i--) {
495 507 m_series->remove(m_series->slices().at(i - m_first));
496 508 m_slices.removeAt(i - m_first);
497 509 }
498 510
499 511 if (m_count != -1) {
500 512 int itemsAvailable; // check how many are available to be added
501 513 if (m_orientation == Qt::Vertical)
502 514 itemsAvailable = m_model->rowCount() - m_first - m_series->slices().size();
503 515 else
504 516 itemsAvailable = m_model->columnCount() - m_first - m_series->slices().size();
505 517 int toBeAdded = qMin(itemsAvailable, m_count - m_series->slices().size()); // add not more items than there is space left to be filled.
506 518 int currentSize = m_series->slices().size();
507 519 if (toBeAdded > 0)
508 520 for (int i = m_series->slices().size(); i < currentSize + toBeAdded; i++) {
509 521 QModelIndex valueIndex = valueModelIndex(i - m_first);
510 522 QModelIndex labelIndex = labelModelIndex(i - m_first);
511 523 if (valueIndex.isValid() && labelIndex.isValid()) {
512 524 QPieSlice *slice = new QPieSlice;
513 525 slice->setValue(m_model->data(valueIndex, Qt::DisplayRole).toDouble());
514 526 slice->setLabel(m_model->data(labelIndex, Qt::DisplayRole).toString());
515 527 m_series->insert(i, slice);
516 528 m_slices.insert(i, slice);
517 529 }
518 530 }
519 531 }
520 532 }
521 533 }
522 534
523 535 void QPieModelMapperPrivate::initializePieFromModel()
524 536 {
525 537 if (m_model == 0 || m_series == 0)
526 538 return;
527 539
528 540 blockSeriesSignals();
529 541 // clear current content
530 542 m_series->clear();
531 543 m_slices.clear();
532 544
533 545 // create the initial slices set
534 546 int slicePos = 0;
535 547 QModelIndex valueIndex = valueModelIndex(slicePos);
536 548 QModelIndex labelIndex = labelModelIndex(slicePos);
537 549 while (valueIndex.isValid() && labelIndex.isValid()) {
538 550 QPieSlice *slice = new QPieSlice;
539 551 slice->setLabel(m_model->data(labelIndex, Qt::DisplayRole).toString());
540 552 slice->setValue(m_model->data(valueIndex, Qt::DisplayRole).toDouble());
541 553 connect(slice, SIGNAL(labelChanged()), this, SLOT(sliceLabelChanged()));
542 554 connect(slice, SIGNAL(valueChanged()), this, SLOT(sliceValueChanged()));
543 555 m_series->append(slice);
544 556 m_slices.append(slice);
545 557 slicePos++;
546 558 valueIndex = valueModelIndex(slicePos);
547 559 labelIndex = labelModelIndex(slicePos);
548 560 }
549 561 blockSeriesSignals(false);
550 562 }
551 563
552 564 #include "moc_qpiemodelmapper_p.cpp"
553 565 #include "moc_qpiemodelmapper.cpp"
554 566
555 567 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,101 +1,103
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QPIEMODELMAPPER_P_H
31 31 #define QPIEMODELMAPPER_P_H
32 32
33 33 #include "qpiemodelmapper.h"
34 34 #include <QObject>
35 35
36 36 class QModelIndex;
37 37 class QAbstractItemModel;
38 38
39 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 40
41 41 class QPieModelMapper;
42 42 class QPieSeries;
43 43 class QPieSlice;
44 44
45 45 class QPieModelMapperPrivate : public QObject
46 46 {
47 47 Q_OBJECT
48 48
49 49 public:
50 50 QPieModelMapperPrivate(QPieModelMapper *q);
51 51
52 52 public Q_SLOTS:
53 53 // for the model
54 54 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
55 55 void modelRowsAdded(QModelIndex parent, int start, int end);
56 56 void modelRowsRemoved(QModelIndex parent, int start, int end);
57 57 void modelColumnsAdded(QModelIndex parent, int start, int end);
58 58 void modelColumnsRemoved(QModelIndex parent, int start, int end);
59 void handleModelDestroyed();
59 60
60 61 // for the series
61 62 void slicesAdded(QList<QPieSlice*> slices);
62 63 void slicesRemoved(QList<QPieSlice*> slices);
63 64 void sliceLabelChanged();
64 65 void sliceValueChanged();
66 void handleSeriesDestroyed();
65 67
66 68 void initializePieFromModel();
67 69
68 70 private:
69 71 QPieSlice* pieSlice(QModelIndex index) const;
70 72 bool isLabelIndex(QModelIndex index) const;
71 73 bool isValueIndex(QModelIndex index) const;
72 74 QModelIndex valueModelIndex(int slicePos);
73 75 QModelIndex labelModelIndex(int slicePos);
74 76 void insertData(int start, int end);
75 77 void removeData(int start, int end);
76 78
77 79 void blockModelSignals(bool block = true);
78 80 void blockSeriesSignals(bool block = true);
79 81
80 82 private:
81 83 QPieSeries *m_series;
82 84 QList<QPieSlice*> m_slices;
83 85 QAbstractItemModel *m_model;
84 86 int m_first;
85 87 int m_count;
86 88 Qt::Orientation m_orientation;
87 89 int m_valuesSection;
88 90 int m_labelsSection;
89 91 bool m_seriesSignalsBlock;
90 92 bool m_modelSignalsBlock;
91 93
92 94 private:
93 95
94 96 QPieModelMapper *q_ptr;
95 97 Q_DECLARE_PUBLIC(QPieModelMapper)
96 98 friend class QPieSeriesPrivate;
97 99 };
98 100
99 101 QTCOMMERCIALCHART_END_NAMESPACE
100 102
101 103 #endif // QPIEMODELMAPPER_P_H
@@ -1,493 +1,505
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qxymodelmapper.h"
22 22 #include "qxymodelmapper_p.h"
23 23 #include "qxyseries.h"
24 24 #include <QAbstractItemModel>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 /*!
29 29 Constructs a mapper object which is a child of \a parent.
30 30 */
31 31 QXYModelMapper::QXYModelMapper(QObject *parent):
32 32 QObject(parent),
33 33 d_ptr(new QXYModelMapperPrivate(this))
34 34 {
35 35 }
36 36
37 37 /*!
38 38 \internal
39 39 */
40 40 QAbstractItemModel* QXYModelMapper::model() const
41 41 {
42 42 Q_D(const QXYModelMapper);
43 43 return d->m_model;
44 44 }
45 45
46 46 /*!
47 47 \internal
48 48 */
49 49 void QXYModelMapper::setModel(QAbstractItemModel *model)
50 50 {
51 51 if (model == 0)
52 52 return;
53 53
54 54 Q_D(QXYModelMapper);
55 55 if (d->m_model) {
56 56 disconnect(d->m_model, 0, d, 0);
57 57 }
58 58
59 59 d->m_model = model;
60 60 d->initializeXYFromModel();
61 61 // connect signals from the model
62 62 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
63 63 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
64 64 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
65 65 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
66 66 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
67 connect(d->m_model, SIGNAL(destroyed()), d, SLOT(handleModelDestroyed()));
67 68 }
68 69
69 70 /*!
70 71 \internal
71 72 */
72 73 QXYSeries* QXYModelMapper::series() const
73 74 {
74 75 Q_D(const QXYModelMapper);
75 76 return d->m_series;
76 77 }
77 78
78 79 /*!
79 80 \internal
80 81 */
81 82 void QXYModelMapper::setSeries(QXYSeries *series)
82 83 {
83 84 Q_D(QXYModelMapper);
84 85 if (d->m_series) {
85 86 disconnect(d->m_series, 0, d, 0);
86 87 }
87 88
88 89 if (series == 0)
89 90 return;
90 91
91 92 d->m_series = series;
92 93 d->initializeXYFromModel();
93 94 // connect the signals from the series
94 95 connect(d->m_series, SIGNAL(pointAdded(int)), d, SLOT(handlePointAdded(int)));
95 96 connect(d->m_series, SIGNAL(pointRemoved(int)), d, SLOT(handlePointRemoved(int)));
96 97 connect(d->m_series, SIGNAL(pointReplaced(int)), d, SLOT(handlePointReplaced(int)));
98 connect(d->m_series, SIGNAL(destroyed()), d, SLOT(handleSeriesDestroyed()));
97 99 }
98 100
99 101 /*!
100 102 \internal
101 103 */
102 104 int QXYModelMapper::first() const
103 105 {
104 106 Q_D(const QXYModelMapper);
105 107 return d->m_first;
106 108 }
107 109
108 110 /*!
109 111 \internal
110 112 */
111 113 void QXYModelMapper::setFirst(int first)
112 114 {
113 115 Q_D(QXYModelMapper);
114 116 d->m_first = qMax(first, 0);
115 117 d->initializeXYFromModel();
116 118 }
117 119
118 120 /*!
119 121 \internal
120 122 */
121 123 int QXYModelMapper::count() const
122 124 {
123 125 Q_D(const QXYModelMapper);
124 126 return d->m_count;
125 127 }
126 128
127 129 /*!
128 130 \internal
129 131 */
130 132 void QXYModelMapper::setCount(int count)
131 133 {
132 134 Q_D(QXYModelMapper);
133 135 d->m_count = qMax(count, -1);
134 136 d->initializeXYFromModel();
135 137 }
136 138
137 139 /*!
138 140 Returns the orientation that is used when QXYModelMapper accesses the model.
139 141 This mean whether the consecutive x/y values of the QXYSeries are read from rows (Qt::Horizontal)
140 142 or from columns (Qt::Vertical)
141 143 */
142 144 Qt::Orientation QXYModelMapper::orientation() const
143 145 {
144 146 Q_D(const QXYModelMapper);
145 147 return d->m_orientation;
146 148 }
147 149
148 150 /*!
149 151 Returns the \a orientation that is used when QXYModelMapper accesses the model.
150 152 This mean whether the consecutive x/y values of the QXYSeries are read from rows (Qt::Horizontal)
151 153 or from columns (Qt::Vertical)
152 154 */
153 155 void QXYModelMapper::setOrientation(Qt::Orientation orientation)
154 156 {
155 157 Q_D(QXYModelMapper);
156 158 d->m_orientation = orientation;
157 159 d->initializeXYFromModel();
158 160 }
159 161
160 162 /*!
161 163 Returns which section of the model is kept in sync with the x values of the QXYSeries
162 164 */
163 165 int QXYModelMapper::xSection() const
164 166 {
165 167 Q_D(const QXYModelMapper);
166 168 return d->m_xSection;
167 169 }
168 170
169 171 /*!
170 172 Sets the model section that is kept in sync with the x values of the QXYSeries.
171 173 Parameter \a xSection specifies the section of the model.
172 174 */
173 175 void QXYModelMapper::setXSection(int xSection)
174 176 {
175 177 Q_D(QXYModelMapper);
176 178 d->m_xSection = qMax(-1, xSection);
177 179 d->initializeXYFromModel();
178 180 }
179 181
180 182 /*!
181 183 Returns which section of the model is kept in sync with the y values of the QXYSeries
182 184 */
183 185 int QXYModelMapper::ySection() const
184 186 {
185 187 Q_D(const QXYModelMapper);
186 188 return d->m_ySection;
187 189 }
188 190
189 191 /*!
190 192 Sets the model section that is kept in sync with the y values of the QXYSeries.
191 193 Parameter \a ySection specifies the section of the model.
192 194 */
193 195 void QXYModelMapper::setYSection(int ySection)
194 196 {
195 197 Q_D(QXYModelMapper);
196 198 d->m_ySection = qMax(-1, ySection);
197 199 d->initializeXYFromModel();
198 200 }
199 201
200 202 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
201 203
202 204 QXYModelMapperPrivate::QXYModelMapperPrivate(QXYModelMapper *q) :
203 205 m_series(0),
204 206 m_model(0),
205 207 m_first(0),
206 208 m_count(-1),
207 209 m_orientation(Qt::Vertical),
208 210 m_xSection(-1),
209 211 m_ySection(-1),
210 212 m_seriesSignalsBlock(false),
211 213 m_modelSignalsBlock(false),
212 214 q_ptr(q)
213 215 {
214 216 }
215 217
216 218 void QXYModelMapperPrivate::blockModelSignals(bool block)
217 219 {
218 220 m_modelSignalsBlock = block;
219 221 }
220 222
221 223 void QXYModelMapperPrivate::blockSeriesSignals(bool block)
222 224 {
223 225 m_seriesSignalsBlock = block;
224 226 }
225 227
226 228 QModelIndex QXYModelMapperPrivate::xModelIndex(int xPos)
227 229 {
228 230 if (m_count != -1 && xPos >= m_count)
229 231 return QModelIndex(); // invalid
230 232
231 233 if (m_orientation == Qt::Vertical)
232 234 return m_model->index(xPos + m_first, m_xSection);
233 235 else
234 236 return m_model->index(m_xSection, xPos + m_first);
235 237 }
236 238
237 239 QModelIndex QXYModelMapperPrivate::yModelIndex(int yPos)
238 240 {
239 241 if (m_count != -1 && yPos >= m_count)
240 242 return QModelIndex(); // invalid
241 243
242 244 if (m_orientation == Qt::Vertical)
243 245 return m_model->index(yPos + m_first, m_ySection);
244 246 else
245 247 return m_model->index(m_ySection, yPos + m_first);
246 248 }
247 249
248 250 void QXYModelMapperPrivate::handlePointAdded(int pointPos)
249 251 {
250 252 if (m_seriesSignalsBlock)
251 253 return;
252 254
253 255 if (m_count != -1)
254 256 m_count += 1;
255 257
256 258 blockModelSignals();
257 259 if (m_orientation == Qt::Vertical)
258 260 m_model->insertRows(pointPos + m_first, 1);
259 261 else
260 262 m_model->insertColumns(pointPos + m_first, 1);
261 263
262 264 m_model->setData(xModelIndex(pointPos), m_series->points().at(pointPos).x());
263 265 m_model->setData(yModelIndex(pointPos), m_series->points().at(pointPos).y());
264 266 blockModelSignals(false);
265 267 }
266 268
267 269 void QXYModelMapperPrivate::handlePointRemoved(int pointPos)
268 270 {
269 271 if (m_seriesSignalsBlock)
270 272 return;
271 273
272 274 if (m_count != -1)
273 275 m_count -= 1;
274 276
275 277 blockModelSignals();
276 278 if (m_orientation == Qt::Vertical)
277 279 m_model->removeRow(pointPos + m_first);
278 280 else
279 281 m_model->removeColumn(pointPos + m_first);
280 282 blockModelSignals(false);
281 283 }
282 284
283 285 void QXYModelMapperPrivate::handlePointReplaced(int pointPos)
284 286 {
285 287 if (m_seriesSignalsBlock)
286 288 return;
287 289
288 290 blockModelSignals();
289 291 m_model->setData(xModelIndex(pointPos), m_series->points().at(pointPos).x());
290 292 m_model->setData(yModelIndex(pointPos), m_series->points().at(pointPos).y());
291 293 blockModelSignals(false);
292 294 }
293 295
296 void QXYModelMapperPrivate::handleSeriesDestroyed()
297 {
298 m_series = 0;
299 }
300
294 301 void QXYModelMapperPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
295 302 {
296 303 if (m_model == 0 || m_series == 0)
297 304 return;
298 305
299 306 if (m_modelSignalsBlock)
300 307 return;
301 308
302 309 blockSeriesSignals();
303 310 QModelIndex index;
304 311 QPointF oldPoint;
305 312 QPointF newPoint;
306 313 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
307 314 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
308 315 index = topLeft.sibling(row, column);
309 316 if (m_orientation == Qt::Vertical && (index.column() == m_xSection || index.column() == m_ySection)) {
310 317 if (index.row() >= m_first && (m_count == - 1 || index.row() < m_first + m_count)) {
311 318 QModelIndex xIndex = xModelIndex(index.row() - m_first);
312 319 QModelIndex yIndex = yModelIndex(index.row() - m_first);
313 320 if (xIndex.isValid() && yIndex.isValid()) {
314 321 oldPoint = m_series->points().at(index.row() - m_first);
315 322 newPoint.setX(m_model->data(xIndex).toReal());
316 323 newPoint.setY(m_model->data(yIndex).toReal());
317 324 }
318 325 }
319 326 } else if (m_orientation == Qt::Horizontal && (index.row() == m_xSection || index.row() == m_ySection)) {
320 327 if (index.column() >= m_first && (m_count == - 1 || index.column() < m_first + m_count)) {
321 328 QModelIndex xIndex = xModelIndex(index.column() - m_first);
322 329 QModelIndex yIndex = yModelIndex(index.column() - m_first);
323 330 if (xIndex.isValid() && yIndex.isValid()) {
324 331 oldPoint = m_series->points().at(index.column() - m_first);
325 332 newPoint.setX(m_model->data(xIndex).toReal());
326 333 newPoint.setY(m_model->data(yIndex).toReal());
327 334 }
328 335 }
329 336 } else {
330 337 continue;
331 338 }
332 339 m_series->replace(oldPoint, newPoint);
333 340 }
334 341 }
335 342 blockSeriesSignals(false);
336 343 }
337 344
338 345 void QXYModelMapperPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
339 346 {
340 347 Q_UNUSED(parent);
341 348 if (m_modelSignalsBlock)
342 349 return;
343 350
344 351 blockSeriesSignals();
345 352 if (m_orientation == Qt::Vertical)
346 353 insertData(start, end);
347 354 else if (start <= m_xSection || start <= m_ySection) // if the changes affect the map - reinitialize the xy
348 355 initializeXYFromModel();
349 356 blockSeriesSignals(false);
350 357 }
351 358
352 359 void QXYModelMapperPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
353 360 {
354 361 Q_UNUSED(parent);
355 362 if (m_modelSignalsBlock)
356 363 return;
357 364
358 365 blockSeriesSignals();
359 366 if (m_orientation == Qt::Vertical)
360 367 removeData(start, end);
361 368 else if (start <= m_xSection || start <= m_ySection) // if the changes affect the map - reinitialize the xy
362 369 initializeXYFromModel();
363 370 blockSeriesSignals(false);
364 371 }
365 372
366 373 void QXYModelMapperPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
367 374 {
368 375 Q_UNUSED(parent);
369 376 if (m_modelSignalsBlock)
370 377 return;
371 378
372 379 blockSeriesSignals();
373 380 if (m_orientation == Qt::Horizontal)
374 381 insertData(start, end);
375 382 else if (start <= m_xSection || start <= m_ySection) // if the changes affect the map - reinitialize the xy
376 383 initializeXYFromModel();
377 384 blockSeriesSignals(false);
378 385 }
379 386
380 387 void QXYModelMapperPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
381 388 {
382 389 Q_UNUSED(parent);
383 390 if (m_modelSignalsBlock)
384 391 return;
385 392
386 393 blockSeriesSignals();
387 394 if (m_orientation == Qt::Horizontal)
388 395 removeData(start, end);
389 396 else if (start <= m_xSection || start <= m_ySection) // if the changes affect the map - reinitialize the xy
390 397 initializeXYFromModel();
391 398 blockSeriesSignals(false);
392 399 }
393 400
401 void QXYModelMapperPrivate::handleModelDestroyed()
402 {
403 m_model = 0;
404 }
405
394 406 void QXYModelMapperPrivate::insertData(int start, int end)
395 407 {
396 408 if (m_model == 0 || m_series == 0)
397 409 return;
398 410
399 411 if (m_count != -1 && start >= m_first + m_count) {
400 412 return;
401 413 } else {
402 414 int addedCount = end - start + 1;
403 415 if (m_count != -1 && addedCount > m_count)
404 416 addedCount = m_count;
405 417 int first = qMax(start, m_first);
406 418 int last = qMin(first + addedCount - 1, m_orientation == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
407 419 for (int i = first; i <= last; i++) {
408 420 QPointF point;
409 421 QModelIndex xIndex = xModelIndex(i - m_first);
410 422 QModelIndex yIndex = yModelIndex(i - m_first);
411 423 if (xIndex.isValid() && yIndex.isValid()) {
412 424 point.setX(m_model->data(xIndex, Qt::DisplayRole).toDouble());
413 425 point.setY(m_model->data(yIndex, Qt::DisplayRole).toDouble());
414 426 m_series->insert(i - m_first, point);
415 427 }
416 428 }
417 429
418 430 // remove excess of slices (abouve m_count)
419 431 if (m_count != -1 && m_series->points().size() > m_count)
420 432 for (int i = m_series->points().size() - 1; i >= m_count; i--) {
421 433 m_series->remove(m_series->points().at(i));
422 434 }
423 435 }
424 436 }
425 437
426 438 void QXYModelMapperPrivate::removeData(int start, int end)
427 439 {
428 440 if (m_model == 0 || m_series == 0)
429 441 return;
430 442
431 443 int removedCount = end - start + 1;
432 444 if (m_count != -1 && start >= m_first + m_count) {
433 445 return;
434 446 } else {
435 447 int toRemove = qMin(m_series->count(), removedCount); // first find how many items can actually be removed
436 448 int first = qMax(start, m_first); // get the index of the first item that will be removed.
437 449 int last = qMin(first + toRemove - 1, m_series->count() + m_first - 1); // get the index of the last item that will be removed.
438 450 for (int i = last; i >= first; i--) {
439 451 m_series->remove(m_series->points().at(i - m_first));
440 452 }
441 453
442 454 if (m_count != -1) {
443 455 int itemsAvailable; // check how many are available to be added
444 456 if (m_orientation == Qt::Vertical)
445 457 itemsAvailable = m_model->rowCount() - m_first - m_series->count();
446 458 else
447 459 itemsAvailable = m_model->columnCount() - m_first - m_series->count();
448 460 int toBeAdded = qMin(itemsAvailable, m_count - m_series->count()); // add not more items than there is space left to be filled.
449 461 int currentSize = m_series->count();
450 462 if (toBeAdded > 0)
451 463 for (int i = m_series->count(); i < currentSize + toBeAdded; i++) {
452 464 QPointF point;
453 465 QModelIndex xIndex = xModelIndex(i);
454 466 QModelIndex yIndex = yModelIndex(i);
455 467 if (xIndex.isValid() && yIndex.isValid()) {
456 468 point.setX(m_model->data(xIndex, Qt::DisplayRole).toDouble());
457 469 point.setY(m_model->data(yIndex, Qt::DisplayRole).toDouble());
458 470 m_series->insert(i, point);
459 471 }
460 472 }
461 473 }
462 474 }
463 475 }
464 476
465 477 void QXYModelMapperPrivate::initializeXYFromModel()
466 478 {
467 479 if (m_model == 0 || m_series == 0)
468 480 return;
469 481
470 482 blockSeriesSignals();
471 483 // clear current content
472 484 m_series->clear();
473 485
474 486 // create the initial slices set
475 487 int pointPos = 0;
476 488 QModelIndex xIndex = xModelIndex(pointPos);
477 489 QModelIndex yIndex = yModelIndex(pointPos);
478 490 while (xIndex.isValid() && yIndex.isValid()) {
479 491 QPointF point;
480 492 point.setX(m_model->data(xIndex, Qt::DisplayRole).toDouble());
481 493 point.setY(m_model->data(yIndex, Qt::DisplayRole).toDouble());
482 494 m_series->append(point);
483 495 pointPos++;
484 496 xIndex = xModelIndex(pointPos);
485 497 yIndex = yModelIndex(pointPos);
486 498 }
487 499 blockSeriesSignals(false);
488 500 }
489 501
490 502 #include "moc_qxymodelmapper.cpp"
491 503 #include "moc_qxymodelmapper_p.cpp"
492 504
493 505 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,93 +1,95
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QXYMODELMAPPER_P_H
31 31 #define QXYMODELMAPPER_P_H
32 32
33 33 #include "qxymodelmapper.h"
34 34 #include <QObject>
35 35
36 36 class QModelIndex;
37 37 class QAbstractItemModel;
38 38 class QPointF;
39 39
40 40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41 41
42 42 class QXYModelMapper;
43 43 class QXYSeries;
44 44
45 45 class QXYModelMapperPrivate : public QObject
46 46 {
47 47 Q_OBJECT
48 48
49 49 public:
50 50 QXYModelMapperPrivate(QXYModelMapper *q);
51 51
52 52 public Q_SLOTS:
53 53 // for the model
54 54 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
55 55 void modelRowsAdded(QModelIndex parent, int start, int end);
56 56 void modelRowsRemoved(QModelIndex parent, int start, int end);
57 57 void modelColumnsAdded(QModelIndex parent, int start, int end);
58 58 void modelColumnsRemoved(QModelIndex parent, int start, int end);
59 void handleModelDestroyed();
59 60
60 61 // for the series
61 62 void handlePointAdded(int pointPos);
62 63 void handlePointRemoved(int pointPos);
63 64 void handlePointReplaced(int pointPos);
65 void handleSeriesDestroyed();
64 66
65 67 void initializeXYFromModel();
66 68
67 69 private:
68 70 QModelIndex xModelIndex(int xPos);
69 71 QModelIndex yModelIndex(int yPos);
70 72 void insertData(int start, int end);
71 73 void removeData(int start, int end);
72 74 void blockModelSignals(bool block = true);
73 75 void blockSeriesSignals(bool block = true);
74 76
75 77 private:
76 78 QXYSeries *m_series;
77 79 QAbstractItemModel *m_model;
78 80 int m_first;
79 81 int m_count;
80 82 Qt::Orientation m_orientation;
81 83 int m_xSection;
82 84 int m_ySection;
83 85 bool m_seriesSignalsBlock;
84 86 bool m_modelSignalsBlock;
85 87
86 88 private:
87 89 QXYModelMapper *q_ptr;
88 90 Q_DECLARE_PUBLIC(QXYModelMapper)
89 91 };
90 92
91 93 QTCOMMERCIALCHART_END_NAMESPACE
92 94
93 95 #endif // QXYMODELMAPPER_P_H
General Comments 0
You need to be logged in to leave comments. Login now