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