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