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