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