##// END OF EJS Templates
Added docs for NOTIFY signals of the PieModelMapper
Marek Rosa -
r1476:ef9c1b689dd4
parent child
Show More
@@ -1,101 +1,113
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 "qhpiemodelmapper.h"
22 22
23 23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 24
25 25 /*!
26 26 \class QHPieModelMapper
27 27 \brief part of QtCommercial chart API.
28 28 \mainclass
29 29
30 30 Model mappers allow you to use QAbstractItemModel derived models as a data source for a chart series.
31 31 Horizontal model mapper is used to create a connection between QPieSeries and QAbstractItemModel derived model object that keeps the consecutive pie slices data in rows.
32 32 It is possible to use both QAbstractItemModel and QPieSeries model API. QHPieModelMapper makes sure that Pie and the model are kept in sync.
33 33 NOTE: used model has to support adding/removing rows/columns and modifying the data of the cells.
34 34 */
35 35
36 36 /*!
37 37 \property QHPieModelMapper::valuesRow
38 38 \brief Defines which row of the model is kept in sync with the values of the pie's slices
39 39
40 40 Default value is: -1 (invalid mapping)
41 41 */
42 42
43 43 /*!
44 44 \property QHPieModelMapper::labelsRow
45 45 \brief Defines which row of the model is kept in sync with the labels of the pie's slices
46 46
47 47 Default value is: -1 (invalid mapping)
48 48 */
49 49
50 50 /*!
51 \fn void QHPieModelMapper::valuesRowChanged()
52
53 Emitted when the valuesRow has changed.
54 */
55
56 /*!
57 \fn void QHPieModelMapper::labelsRowChanged()
58
59 Emitted when the labelsRow has changed.
60 */
61
62 /*!
51 63 Constructs a mapper object which is a child of \a parent.
52 64 */
53 65 QHPieModelMapper::QHPieModelMapper(QObject *parent) :
54 66 QPieModelMapper(parent)
55 67 {
56 68 QPieModelMapper::setOrientation(Qt::Horizontal);
57 69 }
58 70
59 71 /*!
60 72 Returns which row of the model is kept in sync with the values of the pie's slices
61 73 */
62 74 int QHPieModelMapper::valuesRow() const
63 75 {
64 76 return QPieModelMapper::valuesSection();
65 77 }
66 78
67 79 /*!
68 80 Sets the model row that is kept in sync with the pie slices values.
69 81 Parameter \a valuesRow specifies the row of the model.
70 82 */
71 83 void QHPieModelMapper::setValuesRow(int valuesRow)
72 84 {
73 85 if (valuesRow != valuesSection()) {
74 86 QPieModelMapper::setValuesSection(valuesRow);
75 87 emit valuesRowChanged();
76 88 }
77 89 }
78 90
79 91 /*!
80 92 Returns which row of the model is kept in sync with the labels of the pie's slices
81 93 */
82 94 int QHPieModelMapper::labelsRow() const
83 95 {
84 96 return QPieModelMapper::labelsSection();
85 97 }
86 98
87 99 /*!
88 100 Sets the model row that is kept in sync with the pie's slices labels.
89 101 Parameter \a labelsRow specifies the row of the model.
90 102 */
91 103 void QHPieModelMapper::setLabelsRow(int labelsRow)
92 104 {
93 105 if (labelsRow != labelsSection()) {
94 106 QPieModelMapper::setLabelsSection(labelsRow);
95 107 emit labelsRowChanged();
96 108 }
97 109 }
98 110
99 111 #include "moc_qhpiemodelmapper.cpp"
100 112
101 113 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,605 +1,629
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 /*!
30 30 \class QPieModelMapper
31 31 \brief part of QtCommercial chart API.
32 32 \mainclass
33 33
34 34 Model mappers allow you to use QAbstractItemModel derived models as a data source for a chart series.
35 35 The instance of this class cannot be created directly. QHPieModelMapper of QVPieModelMapper should be used instead. This class is used to create a connection between QPieSeries and QAbstractItemModel derived model object.
36 36 It is possible to use both QAbstractItemModel and QPieSeries model API. QPieModelMapper makes sure that Pie and the model are kept in sync.
37 37 NOTE: used model has to support adding/removing rows/columns and modifying the data of the cells.
38 38 */
39 39
40 40 /*!
41 41 \property QPieModelMapper::series
42 42 \brief Defines the QPieSeries object that is used by the mapper.
43 43
44 44 All the data in the series is discarded when it is set to the mapper.
45 45 When new series is specified the old series is disconnected (it preserves its data)
46 46 */
47 47
48 48 /*!
49 49 \property QPieModelMapper::model
50 50 \brief Defines the model that is used by the mapper.
51 51 */
52 52
53 53 /*!
54 54 \property QPieModelMapper::first
55 55 \brief Defines which item of the model's row/column should be mapped as the value/label of the first slice of the pie
56 56
57 57 Minimal and default value is: 0
58 58 */
59 59
60 60 /*!
61 61 \property QPieModelMapper::count
62 62 \brief Defines the number of rows/columns of the model that are mapped as the data for the pie.
63 63
64 64 Minimal and default value is: -1 (count limited by the number of rows/columns in the model)
65 65 */
66 66
67 67 /*!
68 \fn void QPieModelMapper::seriesReplaced()
69
70 Emitted when the series to which mapper is connected to has changed.
71 */
72
73 /*!
74 \fn void QPieModelMapper::modelReplaced()
75
76 Emitted when the model to which mapper is connected to has changed.
77 */
78
79 /*!
80 \fn void QPieModelMapper::firstChanged()
81
82 Emitted when the value for the first has changed.
83 */
84
85 /*!
86 \fn void QPieModelMapper::countChanged()
87
88 Emitted when the value for the count has changed.
89 */
90
91 /*!
68 92 Constructs a mapper object which is a child of \a parent.
69 93 */
70 94 QPieModelMapper::QPieModelMapper(QObject *parent) :
71 95 QObject(parent),
72 96 d_ptr(new QPieModelMapperPrivate(this))
73 97 {
74 98 }
75 99
76 100 QAbstractItemModel* QPieModelMapper::model() const
77 101 {
78 102 Q_D(const QPieModelMapper);
79 103 return d->m_model;
80 104 }
81 105
82 106 void QPieModelMapper::setModel(QAbstractItemModel *model)
83 107 {
84 108 if (model == 0)
85 109 return;
86 110
87 111 Q_D(QPieModelMapper);
88 112 if (d->m_model) {
89 113 disconnect(d->m_model, 0, d, 0);
90 114 }
91 115
92 116 d->m_model = model;
93 117 d->initializePieFromModel();
94 118 // connect signals from the model
95 119 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
96 120 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
97 121 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
98 122 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
99 123 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
100 124
101 125 emit modelReplaced();
102 126 }
103 127
104 128 QPieSeries* QPieModelMapper::series() const
105 129 {
106 130 Q_D(const QPieModelMapper);
107 131 return d->m_series;
108 132 }
109 133
110 134 void QPieModelMapper::setSeries(QPieSeries *series)
111 135 {
112 136 Q_D(QPieModelMapper);
113 137 if (d->m_series) {
114 138 disconnect(d->m_series, 0, d, 0);
115 139 }
116 140
117 141 if (series == 0)
118 142 return;
119 143
120 144 d->m_series = series;
121 145 d->initializePieFromModel();
122 146 // connect the signals from the series
123 147 connect(d->m_series, SIGNAL(added(QList<QPieSlice*>)), d, SLOT(slicesAdded(QList<QPieSlice*>)));
124 148 connect(d->m_series, SIGNAL(removed(QList<QPieSlice*>)), d, SLOT(slicesRemoved(QList<QPieSlice*>)));
125 149
126 150 emit seriesReplaced();
127 151 }
128 152
129 153 int QPieModelMapper::first() const
130 154 {
131 155 Q_D(const QPieModelMapper);
132 156 return d->m_first;
133 157 }
134 158
135 159 void QPieModelMapper::setFirst(int first)
136 160 {
137 161 Q_D(QPieModelMapper);
138 162 if (first != d->m_first) {
139 163 d->m_first = qMax(first, 0);
140 164 d->initializePieFromModel();
141 165
142 166 emit firstChanged();
143 167 }
144 168 }
145 169
146 170 int QPieModelMapper::count() const
147 171 {
148 172 Q_D(const QPieModelMapper);
149 173 return d->m_count;
150 174 }
151 175
152 176 void QPieModelMapper::setCount(int count)
153 177 {
154 178 Q_D(QPieModelMapper);
155 179 if (count != d->m_count) {
156 180 d->m_count = qMax(count, -1);
157 181 d->initializePieFromModel();
158 182
159 183 emit countChanged();
160 184 }
161 185 }
162 186
163 187 /*!
164 188 Returns the orientation that is used when QPieModelMapper accesses the model.
165 189 This mean whether the consecutive values/labels of the pie are read from row (Qt::Horizontal)
166 190 or from columns (Qt::Vertical)
167 191 */
168 192 Qt::Orientation QPieModelMapper::orientation() const
169 193 {
170 194 Q_D(const QPieModelMapper);
171 195 return d->m_orientation;
172 196 }
173 197
174 198 /*!
175 199 Returns the \a orientation that is used when QPieModelMapper accesses the model.
176 200 This mean whether the consecutive values/labels of the pie are read from row (Qt::Horizontal)
177 201 or from columns (Qt::Vertical)
178 202 */
179 203 void QPieModelMapper::setOrientation(Qt::Orientation orientation)
180 204 {
181 205 Q_D(QPieModelMapper);
182 206 d->m_orientation = orientation;
183 207 d->initializePieFromModel();
184 208 }
185 209
186 210 /*!
187 211 Returns which section of the model is kept in sync with the values of the pie's slices
188 212 */
189 213 int QPieModelMapper::valuesSection() const
190 214 {
191 215 Q_D(const QPieModelMapper);
192 216 return d->m_valuesSection;
193 217 }
194 218
195 219 /*!
196 220 Sets the model section that is kept in sync with the pie slices values.
197 221 Parameter \a valuesSection specifies the section of the model.
198 222 */
199 223 void QPieModelMapper::setValuesSection(int valuesSection)
200 224 {
201 225 Q_D(QPieModelMapper);
202 226 d->m_valuesSection = qMax(-1, valuesSection);
203 227 d->initializePieFromModel();
204 228 }
205 229
206 230 /*!
207 231 Returns which section of the model is kept in sync with the labels of the pie's slices
208 232 */
209 233 int QPieModelMapper::labelsSection() const
210 234 {
211 235 Q_D(const QPieModelMapper);
212 236 return d->m_labelsSection;
213 237 }
214 238
215 239 /*!
216 240 Sets the model section that is kept in sync with the pie slices labels.
217 241 Parameter \a labelsSection specifies the section of the model.
218 242 */
219 243 void QPieModelMapper::setLabelsSection(int labelsSection)
220 244 {
221 245 Q_D(QPieModelMapper);
222 246 d->m_labelsSection = qMax(-1, labelsSection);
223 247 d->initializePieFromModel();
224 248 }
225 249
226 250 /*!
227 251 Resets the QPieModelMapper to the default state.
228 252 first: 0; count: -1; valuesSection: -1; labelsSection: -1;
229 253 */
230 254 void QPieModelMapper::reset()
231 255 {
232 256 Q_D(QPieModelMapper);
233 257 d->m_first = 0;
234 258 d->m_count = -1;
235 259 d->m_valuesSection = -1;
236 260 d->m_labelsSection = -1;
237 261 }
238 262
239 263 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
240 264
241 265 QPieModelMapperPrivate::QPieModelMapperPrivate(QPieModelMapper *q) :
242 266 m_series(0),
243 267 m_model(0),
244 268 m_first(0),
245 269 m_count(-1),
246 270 m_orientation(Qt::Vertical),
247 271 m_valuesSection(-1),
248 272 m_labelsSection(-1),
249 273 m_seriesSignalsBlock(false),
250 274 m_modelSignalsBlock(false),
251 275 q_ptr(q)
252 276 {
253 277 }
254 278
255 279 void QPieModelMapperPrivate::blockModelSignals(bool block)
256 280 {
257 281 m_modelSignalsBlock = block;
258 282 }
259 283
260 284 void QPieModelMapperPrivate::blockSeriesSignals(bool block)
261 285 {
262 286 m_seriesSignalsBlock = block;
263 287 }
264 288
265 289
266 290 QPieSlice* QPieModelMapperPrivate::pieSlice(QModelIndex index) const
267 291 {
268 292 if (!index.isValid())
269 293 return 0; // index is invalid
270 294
271 295 if (m_orientation == Qt::Vertical && (index.column() == m_valuesSection || index.column() == m_labelsSection)) {
272 296 if (index.row() >= m_first && (m_count == - 1 || index.row() < m_first + m_count)) {
273 297 if (m_model->index(index.row(), m_valuesSection).isValid() && m_model->index(index.row(), m_labelsSection).isValid())
274 298 return m_series->slices().at(index.row() - m_first);
275 299 else
276 300 return 0;
277 301 }
278 302 } else if (m_orientation == Qt::Horizontal && (index.row() == m_valuesSection || index.row() == m_labelsSection)) {
279 303 if (index.column() >= m_first && (m_count == - 1 || index.column() < m_first + m_count)) {
280 304 if (m_model->index(m_valuesSection, index.column()).isValid() && m_model->index(m_labelsSection, index.column()).isValid())
281 305 return m_series->slices().at(index.column() - m_first);
282 306 else
283 307 return 0;
284 308 }
285 309 }
286 310 return 0; // This part of model has not been mapped to any slice
287 311 }
288 312
289 313 QModelIndex QPieModelMapperPrivate::valueModelIndex(int slicePos)
290 314 {
291 315 if (m_count != -1 && slicePos >= m_count)
292 316 return QModelIndex(); // invalid
293 317
294 318 if (m_orientation == Qt::Vertical)
295 319 return m_model->index(slicePos + m_first, m_valuesSection);
296 320 else
297 321 return m_model->index(m_valuesSection, slicePos + m_first);
298 322 }
299 323
300 324 QModelIndex QPieModelMapperPrivate::labelModelIndex(int slicePos)
301 325 {
302 326 if (m_count != -1 && slicePos >= m_count)
303 327 return QModelIndex(); // invalid
304 328
305 329 if (m_orientation == Qt::Vertical)
306 330 return m_model->index(slicePos + m_first, m_labelsSection);
307 331 else
308 332 return m_model->index(m_labelsSection, slicePos + m_first);
309 333 }
310 334
311 335 bool QPieModelMapperPrivate::isLabelIndex(QModelIndex index) const
312 336 {
313 337 if (m_orientation == Qt::Vertical && index.column() == m_labelsSection)
314 338 return true;
315 339 else if (m_orientation == Qt::Horizontal && index.row() == m_labelsSection)
316 340 return true;
317 341
318 342 return false;
319 343 }
320 344
321 345 bool QPieModelMapperPrivate::isValueIndex(QModelIndex index) const
322 346 {
323 347 if (m_orientation == Qt::Vertical && index.column() == m_valuesSection)
324 348 return true;
325 349 else if (m_orientation == Qt::Horizontal && index.row() == m_valuesSection)
326 350 return true;
327 351
328 352 return false;
329 353 }
330 354
331 355 void QPieModelMapperPrivate::slicesAdded(QList<QPieSlice*> slices)
332 356 {
333 357 if (m_seriesSignalsBlock)
334 358 return;
335 359
336 360 if (slices.count() == 0)
337 361 return;
338 362
339 363 int firstIndex = m_series->slices().indexOf(slices.at(0));
340 364 if (firstIndex == -1)
341 365 return;
342 366
343 367 if (m_count != -1)
344 368 m_count += slices.count();
345 369
346 370 for (int i = firstIndex; i < firstIndex + slices.count(); i++) {
347 371 m_slices.insert(i, slices.at(i - firstIndex));
348 372 connect(slices.at(i - firstIndex), SIGNAL(labelChanged()), this, SLOT(sliceLabelChanged()));
349 373 connect(slices.at(i - firstIndex), SIGNAL(valueChanged()), this, SLOT(sliceValueChanged()));
350 374 }
351 375
352 376 blockModelSignals();
353 377 if (m_orientation == Qt::Vertical)
354 378 m_model->insertRows(firstIndex + m_first, slices.count());
355 379 else
356 380 m_model->insertColumns(firstIndex + m_first, slices.count());
357 381
358 382 for(int i = firstIndex; i < firstIndex + slices.count(); i++) {
359 383 m_model->setData(valueModelIndex(i), slices.at(i - firstIndex)->value());
360 384 m_model->setData(labelModelIndex(i), slices.at(i - firstIndex)->label());
361 385 }
362 386 blockModelSignals(false);
363 387 }
364 388
365 389 void QPieModelMapperPrivate::slicesRemoved(QList<QPieSlice*> slices)
366 390 {
367 391 if (m_seriesSignalsBlock)
368 392 return;
369 393
370 394 if (slices.count() == 0)
371 395 return;
372 396
373 397 int firstIndex = m_slices.indexOf(slices.at(0));
374 398 if (firstIndex == -1)
375 399 return;
376 400
377 401 if (m_count != -1)
378 402 m_count -= slices.count();
379 403
380 404 for (int i = firstIndex + slices.count() - 1; i >= firstIndex; i--)
381 405 m_slices.removeAt(i);
382 406
383 407 blockModelSignals();
384 408 if (m_orientation == Qt::Vertical)
385 409 m_model->removeRows(firstIndex + m_first, slices.count());
386 410 else
387 411 m_model->removeColumns(firstIndex + m_first, slices.count());
388 412 blockModelSignals(false);
389 413 }
390 414
391 415 void QPieModelMapperPrivate::sliceLabelChanged()
392 416 {
393 417 if (m_seriesSignalsBlock)
394 418 return;
395 419
396 420 blockModelSignals();
397 421 QPieSlice *slice = qobject_cast<QPieSlice *>(QObject::sender());
398 422 m_model->setData(labelModelIndex(m_series->slices().indexOf(slice)), slice->label());
399 423 blockModelSignals(false);
400 424 }
401 425
402 426 void QPieModelMapperPrivate::sliceValueChanged()
403 427 {
404 428 if (m_seriesSignalsBlock)
405 429 return;
406 430
407 431 blockModelSignals();
408 432 QPieSlice *slice = qobject_cast<QPieSlice *>(QObject::sender());
409 433 m_model->setData(valueModelIndex(m_series->slices().indexOf(slice)), slice->value());
410 434 blockModelSignals(false);
411 435 }
412 436
413 437 void QPieModelMapperPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
414 438 {
415 439 if (m_model == 0 || m_series == 0)
416 440 return;
417 441
418 442 if (m_modelSignalsBlock)
419 443 return;
420 444
421 445 blockSeriesSignals();
422 446 QModelIndex index;
423 447 QPieSlice *slice;
424 448 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
425 449 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
426 450 index = topLeft.sibling(row, column);
427 451 slice = pieSlice(index);
428 452 if (slice) {
429 453 if (isValueIndex(index))
430 454 slice->setValue(m_model->data(index, Qt::DisplayRole).toReal());
431 455 if (isLabelIndex(index))
432 456 slice->setLabel(m_model->data(index, Qt::DisplayRole).toString());
433 457 }
434 458 }
435 459 }
436 460 blockSeriesSignals(false);
437 461 }
438 462
439 463
440 464 void QPieModelMapperPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
441 465 {
442 466 Q_UNUSED(parent);
443 467 if (m_modelSignalsBlock)
444 468 return;
445 469
446 470 blockSeriesSignals();
447 471 if (m_orientation == Qt::Vertical)
448 472 insertData(start, end);
449 473 else if (start <= m_valuesSection || start <= m_labelsSection) // if the changes affect the map - reinitialize the pie
450 474 initializePieFromModel();
451 475 blockSeriesSignals(false);
452 476 }
453 477
454 478 void QPieModelMapperPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
455 479 {
456 480 Q_UNUSED(parent);
457 481 if (m_modelSignalsBlock)
458 482 return;
459 483
460 484 blockSeriesSignals();
461 485 if (m_orientation == Qt::Vertical)
462 486 removeData(start, end);
463 487 else if (start <= m_valuesSection || start <= m_labelsSection) // if the changes affect the map - reinitialize the pie
464 488 initializePieFromModel();
465 489 blockSeriesSignals(false);
466 490 }
467 491
468 492 void QPieModelMapperPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
469 493 {
470 494 Q_UNUSED(parent);
471 495 if (m_modelSignalsBlock)
472 496 return;
473 497
474 498 blockSeriesSignals();
475 499 if (m_orientation == Qt::Horizontal)
476 500 insertData(start, end);
477 501 else if (start <= m_valuesSection || start <= m_labelsSection) // if the changes affect the map - reinitialize the pie
478 502 initializePieFromModel();
479 503 blockSeriesSignals(false);
480 504 }
481 505
482 506 void QPieModelMapperPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
483 507 {
484 508 Q_UNUSED(parent);
485 509 if (m_modelSignalsBlock)
486 510 return;
487 511
488 512 blockSeriesSignals();
489 513 if (m_orientation == Qt::Horizontal)
490 514 removeData(start, end);
491 515 else if (start <= m_valuesSection || start <= m_labelsSection) // if the changes affect the map - reinitialize the pie
492 516 initializePieFromModel();
493 517 blockSeriesSignals(false);
494 518 }
495 519
496 520 void QPieModelMapperPrivate::insertData(int start, int end)
497 521 {
498 522 if (m_model == 0 || m_series == 0)
499 523 return;
500 524
501 525 if (m_count != -1 && start >= m_first + m_count) {
502 526 return;
503 527 } else {
504 528 int addedCount = end - start + 1;
505 529 if (m_count != -1 && addedCount > m_count)
506 530 addedCount = m_count;
507 531 int first = qMax(start, m_first);
508 532 int last = qMin(first + addedCount - 1, m_orientation == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
509 533 for (int i = first; i <= last; i++) {
510 534 QModelIndex valueIndex = valueModelIndex(i - m_first);
511 535 QModelIndex labelIndex = labelModelIndex(i - m_first);
512 536 if (valueIndex.isValid() && labelIndex.isValid()) {
513 537 QPieSlice *slice = new QPieSlice;
514 538 slice->setValue(m_model->data(valueIndex, Qt::DisplayRole).toDouble());
515 539 slice->setLabel(m_model->data(labelIndex, Qt::DisplayRole).toString());
516 540 connect(slice, SIGNAL(labelChanged()), this, SLOT(sliceLabelChanged()));
517 541 connect(slice, SIGNAL(valueChanged()), this, SLOT(sliceValueChanged()));
518 542 m_series->insert(i - m_first, slice);
519 543 m_slices.insert(i - m_first, slice);
520 544 }
521 545 }
522 546
523 547 // remove excess of slices (abouve m_count)
524 548 if (m_count != -1 && m_series->slices().size() > m_count)
525 549 for (int i = m_series->slices().size() - 1; i >= m_count; i--) {
526 550 m_series->remove(m_series->slices().at(i));
527 551 m_slices.removeAt(i);
528 552 }
529 553 }
530 554 }
531 555
532 556 void QPieModelMapperPrivate::removeData(int start, int end)
533 557 {
534 558 if (m_model == 0 || m_series == 0)
535 559 return;
536 560
537 561 int removedCount = end - start + 1;
538 562 if (m_count != -1 && start >= m_first + m_count) {
539 563 return;
540 564 } else {
541 565 int toRemove = qMin(m_series->slices().size(), removedCount); // first find how many items can actually be removed
542 566 int first = qMax(start, m_first); // get the index of the first item that will be removed.
543 567 int last = qMin(first + toRemove - 1, m_series->slices().size() + m_first - 1); // get the index of the last item that will be removed.
544 568 for (int i = last; i >= first; i--) {
545 569 m_series->remove(m_series->slices().at(i - m_first));
546 570 m_slices.removeAt(i - m_first);
547 571 }
548 572
549 573 if (m_count != -1) {
550 574 int itemsAvailable; // check how many are available to be added
551 575 if (m_orientation == Qt::Vertical)
552 576 itemsAvailable = m_model->rowCount() - m_first - m_series->slices().size();
553 577 else
554 578 itemsAvailable = m_model->columnCount() - m_first - m_series->slices().size();
555 579 int toBeAdded = qMin(itemsAvailable, m_count - m_series->slices().size()); // add not more items than there is space left to be filled.
556 580 int currentSize = m_series->slices().size();
557 581 if (toBeAdded > 0)
558 582 for (int i = m_series->slices().size(); i < currentSize + toBeAdded; i++) {
559 583 QModelIndex valueIndex = valueModelIndex(i - m_first);
560 584 QModelIndex labelIndex = labelModelIndex(i - m_first);
561 585 if (valueIndex.isValid() && labelIndex.isValid()) {
562 586 QPieSlice *slice = new QPieSlice;
563 587 slice->setValue(m_model->data(valueIndex, Qt::DisplayRole).toDouble());
564 588 slice->setLabel(m_model->data(labelIndex, Qt::DisplayRole).toString());
565 589 m_series->insert(i, slice);
566 590 m_slices.insert(i, slice);
567 591 }
568 592 }
569 593 }
570 594 }
571 595 }
572 596
573 597 void QPieModelMapperPrivate::initializePieFromModel()
574 598 {
575 599 if (m_model == 0 || m_series == 0)
576 600 return;
577 601
578 602 blockSeriesSignals();
579 603 // clear current content
580 604 m_series->clear();
581 605 m_slices.clear();
582 606
583 607 // create the initial slices set
584 608 int slicePos = 0;
585 609 QModelIndex valueIndex = valueModelIndex(slicePos);
586 610 QModelIndex labelIndex = labelModelIndex(slicePos);
587 611 while (valueIndex.isValid() && labelIndex.isValid()) {
588 612 QPieSlice *slice = new QPieSlice;
589 613 slice->setLabel(m_model->data(labelIndex, Qt::DisplayRole).toString());
590 614 slice->setValue(m_model->data(valueIndex, Qt::DisplayRole).toDouble());
591 615 connect(slice, SIGNAL(labelChanged()), this, SLOT(sliceLabelChanged()));
592 616 connect(slice, SIGNAL(valueChanged()), this, SLOT(sliceValueChanged()));
593 617 m_series->append(slice);
594 618 m_slices.append(slice);
595 619 slicePos++;
596 620 valueIndex = valueModelIndex(slicePos);
597 621 labelIndex = labelModelIndex(slicePos);
598 622 }
599 623 blockSeriesSignals(false);
600 624 }
601 625
602 626 #include "moc_qpiemodelmapper_p.cpp"
603 627 #include "moc_qpiemodelmapper.cpp"
604 628
605 629 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,101 +1,113
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 "qvpiemodelmapper.h"
22 22
23 23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 24
25 25 /*!
26 26 \class QVPieModelMapper
27 27 \brief part of QtCommercial chart API.
28 28 \mainclass
29 29
30 30 Model mappers allow you to use QAbstractItemModel derived models as a data source for a chart series.
31 31 Vertical model mapper is used to create a connection between QPieSeries and QAbstractItemModel derived model object that keeps the consecutive pie slices data in columns.
32 32 It is possible to use both QAbstractItemModel and QPieSeries model API. QVPieModelMapper makes sure that Pie and the model are kept in sync.
33 33 NOTE: used model has to support adding/removing rows/columns and modifying the data of the cells.
34 34 */
35 35
36 36 /*!
37 37 \property QVPieModelMapper::valuesColumn
38 38 \brief Defines which column of the model is kept in sync with the values of the pie's slices
39 39
40 40 Default value is: -1 (invalid mapping)
41 41 */
42 42
43 43 /*!
44 44 \property QVPieModelMapper::labelsColumn
45 45 \brief Defines which column of the model is kept in sync with the labels of the pie's slices
46 46
47 47 Default value is: -1 (invalid mapping)
48 48 */
49 49
50 50 /*!
51 \fn void QVPieModelMapper::valuesColumnChanged()
52
53 Emitted when the valuesColumn has changed.
54 */
55
56 /*!
57 \fn void QVPieModelMapper::labelsColumnChanged()
58
59 Emitted when the labelsColumn has changed.
60 */
61
62 /*!
51 63 Constructs a mapper object which is a child of \a parent.
52 64 */
53 65 QVPieModelMapper::QVPieModelMapper(QObject *parent) :
54 66 QPieModelMapper(parent)
55 67 {
56 68 QPieModelMapper::setOrientation(Qt::Vertical);
57 69 }
58 70
59 71 /*!
60 72 Returns which column of the model is kept in sync with the values of the pie's slices
61 73 */
62 74 int QVPieModelMapper::valuesColumn() const
63 75 {
64 76 return QPieModelMapper::valuesSection();
65 77 }
66 78
67 79 /*!
68 80 Sets the model column that is kept in sync with the pie slices values.
69 81 Parameter \a valuesColumn specifies the row of the model.
70 82 */
71 83 void QVPieModelMapper::setValuesColumn(int valuesColumn)
72 84 {
73 85 if (valuesColumn != valuesSection()) {
74 86 QPieModelMapper::setValuesSection(valuesColumn);
75 87 emit valuesColumnChanged();
76 88 }
77 89 }
78 90
79 91 /*!
80 92 Returns which column of the model is kept in sync with the labels of the pie's slices
81 93 */
82 94 int QVPieModelMapper::labelsColumn() const
83 95 {
84 96 return QPieModelMapper::labelsSection();
85 97 }
86 98
87 99 /*!
88 100 Sets the model column that is kept in sync with the pie's slices labels.
89 101 Parameter \a labelsColumn specifies the row of the model.
90 102 */
91 103 void QVPieModelMapper::setLabelsColumn(int labelsColumn)
92 104 {
93 105 if (labelsColumn != labelsSection()) {
94 106 QPieModelMapper::setLabelsSection(labelsColumn);
95 107 emit labelsColumnChanged();
96 108 }
97 109 }
98 110
99 111 #include "moc_qvpiemodelmapper.cpp"
100 112
101 113 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now