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