##// END OF EJS Templates
Added tests for XYModelMapper
Marek Rosa -
r1352:6d51f9f77c12
parent child
Show More
@@ -0,0 +1,8
1 !include( ../auto.pri ) {
2 error( "Couldn't find the auto.pri file!" )
3 }
4
5 SOURCES += \
6 tst_qxymodelmapper.cpp
7
8 !system_build:mac: QMAKE_POST_LINK += "$$MAC_POST_LINK_PREFIX $$MAC_AUTOTESTS_BIN_DIR"
@@ -0,0 +1,273
1 #include <QtCore/QString>
2 #include <QtTest/QtTest>
3
4 #include <qchart.h>
5 #include <qchartview.h>
6 #include <qxyseries.h>
7 #include <qlineseries.h>
8 #include <qvxymodelmapper.h>
9 #include <qhxymodelmapper.h>
10 #include <QStandardItemModel>
11
12 QTCOMMERCIALCHART_USE_NAMESPACE
13
14 class tst_qxymodelmapper : public QObject
15 {
16 Q_OBJECT
17
18 public:
19 tst_qxymodelmapper();
20
21 private Q_SLOTS:
22 void initTestCase();
23 void cleanupTestCase();
24 void init();
25 void cleanup();
26 void verticalMapper_data();
27 void verticalMapper();
28 void verticalMapperCustomMapping_data();
29 void verticalMapperCustomMapping();
30 void horizontalMapper_data();
31 void horizontalMapper();
32 void horizontalMapperCustomMapping_data();
33 void horizontalMapperCustomMapping();
34 void seriesUpdated();
35
36 private:
37 QStandardItemModel *m_model;
38 int m_modelRowCount;
39 int m_modelColumnCount;
40
41 QXYSeries *m_series;
42 QChart *m_chart;
43 };
44
45 tst_qxymodelmapper::tst_qxymodelmapper():
46 m_model(0),
47 m_modelRowCount(10),
48 m_modelColumnCount(8)
49 {
50 }
51
52 void tst_qxymodelmapper::init()
53 {
54 m_series = new QLineSeries;
55 m_chart->addSeries(m_series);
56 }
57
58 void tst_qxymodelmapper::cleanup()
59 {
60 m_chart->removeSeries(m_series);
61 delete m_series;
62 m_series = 0;
63 }
64
65 void tst_qxymodelmapper::initTestCase()
66 {
67 m_chart = new QChart;
68 QChartView *chartView = new QChartView(m_chart);
69 chartView->show();
70
71 m_model = new QStandardItemModel(this);
72 for (int row = 0; row < m_modelRowCount; ++row) {
73 for (int column = 0; column < m_modelColumnCount; column++) {
74 QStandardItem *item = new QStandardItem(row * column);
75 m_model->setItem(row, column, item);
76 }
77 }
78 }
79
80 void tst_qxymodelmapper::cleanupTestCase()
81 {
82 m_model->clear();
83 }
84
85 void tst_qxymodelmapper::verticalMapper_data()
86 {
87 QTest::addColumn<int>("xColumn");
88 QTest::addColumn<int>("yColumn");
89 QTest::addColumn<int>("expectedCount");
90 QTest::newRow("different x and y columns") << 0 << 1 << m_modelRowCount;
91 QTest::newRow("same x and y columns") << 1 << 1 << m_modelRowCount;
92 QTest::newRow("invalid x column and correct y column") << -3 << 1 << 0;
93 QTest::newRow("x column beyond the size of model and correct y column") << m_modelColumnCount << 1 << 0;
94 QTest::newRow("x column beyond the size of model and invalid y column") << m_modelColumnCount << -1 << 0;
95 }
96
97 void tst_qxymodelmapper::verticalMapper()
98 {
99 QFETCH(int, xColumn);
100 QFETCH(int, yColumn);
101 QFETCH(int, expectedCount);
102
103 QVXYModelMapper *mapper = new QVXYModelMapper;
104 mapper->setXColumn(xColumn);
105 mapper->setYColumn(yColumn);
106 mapper->setModel(m_model);
107 mapper->setSeries(m_series);
108
109 QCOMPARE(m_series->count(), expectedCount);
110 QCOMPARE(mapper->xColumn(), qMax(-1, xColumn));
111 QCOMPARE(mapper->yColumn(), qMax(-1, yColumn));
112
113 delete mapper;
114 mapper = 0;
115 }
116
117 void tst_qxymodelmapper::verticalMapperCustomMapping_data()
118 {
119 QTest::addColumn<int>("first");
120 QTest::addColumn<int>("countLimit");
121 QTest::addColumn<int>("expectedCount");
122 QTest::newRow("first: 0, unlimited count") << 0 << -1 << m_modelRowCount;
123 QTest::newRow("first: 3, unlimited count") << 3 << -1 << m_modelRowCount - 3;
124 QTest::newRow("first: 0, count: 5") << 0 << 5 << qMin(5, m_modelRowCount);
125 QTest::newRow("first: 3, count: 5") << 3 << 5 << qMin(5, m_modelRowCount - 3);
126 QTest::newRow("first: +1 greater then the number of rows in the model, unlimited count") << m_modelRowCount + 1 << -1 << 0;
127 QTest::newRow("first: +1 greater then the number of rows in the model, count: 5") << m_modelRowCount + 1 << 5 << 0;
128 QTest::newRow("first: 0, count: +3 greater than the number of rows in the model (should limit to the size of model)") << 0 << m_modelRowCount + 3 << m_modelRowCount;
129 QTest::newRow("first: -3(invalid - should default to 0), unlimited count") << -3 << -1 << m_modelRowCount;
130 QTest::newRow("first: 0, count: -3 (invalid - shlould default to -1)") << 0 << -3 << m_modelRowCount;
131 QTest::newRow("first: -3(invalid - should default to 0), count: -3 (invalid - shlould default to -1)") << -3 << -3 << m_modelRowCount;
132
133 }
134
135 void tst_qxymodelmapper::verticalMapperCustomMapping()
136 {
137 QFETCH(int, first);
138 QFETCH(int, countLimit);
139 QFETCH(int, expectedCount);
140
141 QCOMPARE(m_series->count(), 0);
142
143 QVXYModelMapper *mapper = new QVXYModelMapper;
144 mapper->setXColumn(0);
145 mapper->setYColumn(1);
146 mapper->setModel(m_model);
147 mapper->setSeries(m_series);
148 mapper->setFirst(first);
149 mapper->setCount(countLimit);
150
151 QCOMPARE(m_series->count(), expectedCount);
152
153 // change values column mapping to invalid
154 mapper->setXColumn(-1);
155 mapper->setYColumn(1);
156
157 QCOMPARE(m_series->count(), 0);
158
159 delete mapper;
160 mapper = 0;
161 }
162
163 void tst_qxymodelmapper::horizontalMapper_data()
164 {
165 QTest::addColumn<int>("xRow");
166 QTest::addColumn<int>("yRow");
167 QTest::addColumn<int>("expectedCount");
168 QTest::newRow("different x and y rows") << 0 << 1 << m_modelColumnCount;
169 QTest::newRow("same x and y rows") << 1 << 1 << m_modelColumnCount;
170 QTest::newRow("invalid x row and correct y row") << -3 << 1 << 0;
171 QTest::newRow("x row beyond the size of model and correct y row") << m_modelRowCount << 1 << 0;
172 QTest::newRow("x row beyond the size of model and invalid y row") << m_modelRowCount << -1 << 0;
173 }
174
175 void tst_qxymodelmapper::horizontalMapper()
176 {
177 QFETCH(int, xRow);
178 QFETCH(int, yRow);
179 QFETCH(int, expectedCount);
180
181 QHXYModelMapper *mapper = new QHXYModelMapper;
182 mapper->setXRow(xRow);
183 mapper->setYRow(yRow);
184 mapper->setModel(m_model);
185 mapper->setSeries(m_series);
186
187 QCOMPARE(m_series->count(), expectedCount);
188 QCOMPARE(mapper->xRow(), qMax(-1, xRow));
189 QCOMPARE(mapper->yRow(), qMax(-1, yRow));
190
191 delete mapper;
192 mapper = 0;
193 }
194
195 void tst_qxymodelmapper::horizontalMapperCustomMapping_data()
196 {
197 QTest::addColumn<int>("first");
198 QTest::addColumn<int>("countLimit");
199 QTest::addColumn<int>("expectedCount");
200 QTest::newRow("first: 0, unlimited count") << 0 << -1 << m_modelColumnCount;
201 QTest::newRow("first: 3, unlimited count") << 3 << -1 << m_modelColumnCount - 3;
202 QTest::newRow("first: 0, count: 5") << 0 << 5 << qMin(5, m_modelColumnCount);
203 QTest::newRow("first: 3, count: 5") << 3 << 5 << qMin(5, m_modelColumnCount - 3);
204 QTest::newRow("first: +1 greater then the number of columns in the model, unlimited count") << m_modelColumnCount + 1 << -1 << 0;
205 QTest::newRow("first: +1 greater then the number of columns in the model, count: 5") << m_modelColumnCount + 1 << 5 << 0;
206 QTest::newRow("first: 0, count: +3 greater than the number of columns in the model (should limit to the size of model)") << 0 << m_modelColumnCount + 3 << m_modelColumnCount;
207 QTest::newRow("first: -3(invalid - should default to 0), unlimited count") << -3 << -1 << m_modelColumnCount;
208 QTest::newRow("first: 0, count: -3 (invalid - shlould default to -1)") << 0 << -3 << m_modelColumnCount;
209 QTest::newRow("first: -3(invalid - should default to 0), count: -3 (invalid - shlould default to -1)") << -3 << -3 << m_modelColumnCount;
210 }
211
212 void tst_qxymodelmapper::horizontalMapperCustomMapping()
213 {
214 QFETCH(int, first);
215 QFETCH(int, countLimit);
216 QFETCH(int, expectedCount);
217
218 QCOMPARE(m_series->count(), 0);
219
220 QHXYModelMapper *mapper = new QHXYModelMapper;
221 mapper->setXRow(0);
222 mapper->setYRow(1);
223 mapper->setModel(m_model);
224 mapper->setSeries(m_series);
225 mapper->setFirst(first);
226 mapper->setCount(countLimit);
227
228 QCOMPARE(m_series->count(), expectedCount);
229
230 // change values row mapping to invalid
231 mapper->setXRow(-1);
232 mapper->setYRow(1);
233
234 QCOMPARE(m_series->count(), 0);
235
236 delete mapper;
237 mapper = 0;
238 }
239
240 void tst_qxymodelmapper::seriesUpdated()
241 {
242 QStandardItemModel *otherModel = new QStandardItemModel;
243 for (int row = 0; row < m_modelRowCount; ++row) {
244 for (int column = 0; column < m_modelColumnCount; column++) {
245 QStandardItem *item = new QStandardItem(row * column);
246 otherModel->setItem(row, column, item);
247 }
248 }
249
250 QVXYModelMapper *mapper = new QVXYModelMapper;
251 mapper->setXColumn(0);
252 mapper->setYColumn(1);
253 mapper->setModel(otherModel);
254 mapper->setSeries(m_series);
255 QCOMPARE(m_series->count(), m_modelRowCount);
256 QCOMPARE(mapper->count(), -1);
257
258 m_series->append(QPointF(100, 100));
259 QCOMPARE(m_series->count(), m_modelRowCount + 1);
260 QCOMPARE(mapper->count(), -1); // the value should not change as it indicates 'all' items there are in the model
261
262 m_series->remove(m_series->points().last());
263 QCOMPARE(m_series->count(), m_modelRowCount);
264 QCOMPARE(mapper->count(), -1); // the value should not change as it indicates 'all' items there are in the model
265
266 otherModel->clear();
267 delete otherModel;
268 otherModel = 0;
269 }
270
271 QTEST_MAIN(tst_qxymodelmapper)
272
273 #include "tst_qxymodelmapper.moc"
@@ -1,501 +1,501
1 1 #include "qxymodelmapper.h"
2 2 #include "qxymodelmapper_p.h"
3 3 #include "qxyseries.h"
4 4 #include <QAbstractItemModel>
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 /*!
9 9 \property QXYModelMapper::series
10 10 \brief Defines the QPieSeries object that is used by the mapper.
11 11
12 12 All the data in the series in the series is discarded when it is set to the mapper.
13 13 When new series is specified the old series is disconnected (it preserves its data)
14 14 */
15 15
16 16 /*!
17 17 \property QXYModelMapper::model
18 18 \brief Defines the model that is used by the mapper.
19 19 */
20 20
21 21 /*!
22 22 \property QXYModelMapper::first
23 23 \brief Defines which item of the model's row/column should be mapped as the first x/y pair
24 24
25 25 Minimal and default value is: 0
26 26 */
27 27
28 28 /*!
29 29 \property QXYModelMapper::count
30 30 \brief Defines the number of rows/columns of the model that are mapped as the data for QXYSeries
31 31
32 32 Minimal and default value is: -1 (count limited by the number of rows/columns in the model)
33 33 */
34 34
35 35 /*!
36 36 \class QXYModelMapper
37 37 \brief part of QtCommercial chart API.
38 38 \mainclass
39 39
40 40 The instance of this class cannot be created directly. QHXYModelMapper of QVXYModelMapper should be used instead. This class is used to create a connection between QXYSeries and QAbstractItemModel derived model object.
41 41 It is possible to use both QAbstractItemModel and QXYSeries model API. QXYModelMapper makes sure that QXYSeries and the model are kept in sync.
42 42 NOTE: used model has to support adding/removing rows/columns and modifying the data of the cells.
43 43 */
44 44
45 45 /*!
46 46 Constructs a mapper object which is a child of \a parent.
47 47 */
48 48 QXYModelMapper::QXYModelMapper(QObject *parent):
49 49 QObject(parent),
50 50 d_ptr(new QXYModelMapperPrivate(this))
51 51 {
52 52 }
53 53
54 54 QAbstractItemModel* QXYModelMapper::model() const
55 55 {
56 56 Q_D(const QXYModelMapper);
57 57 return d->m_model;
58 58 }
59 59
60 60 void QXYModelMapper::setModel(QAbstractItemModel *model)
61 61 {
62 62 if (model == 0)
63 63 return;
64 64
65 65 Q_D(QXYModelMapper);
66 66 if (d->m_model) {
67 67 disconnect(d->m_model, 0, d, 0);
68 68 }
69 69
70 70 d->m_model = model;
71 71 d->initializeXYFromModel();
72 72 // connect signals from the model
73 73 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
74 74 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
75 75 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
76 76 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
77 77 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
78 78 }
79 79
80 80 QXYSeries* QXYModelMapper::series() const
81 81 {
82 82 Q_D(const QXYModelMapper);
83 83 return d->m_series;
84 84 }
85 85
86 86 void QXYModelMapper::setSeries(QXYSeries *series)
87 87 {
88 88 Q_D(QXYModelMapper);
89 89 if (d->m_series) {
90 90 disconnect(d->m_series, 0, d, 0);
91 91 }
92 92
93 93 if (series == 0)
94 94 return;
95 95
96 96 d->m_series = series;
97 97 d->initializeXYFromModel();
98 98 // connect the signals from the series
99 99 connect(d->m_series, SIGNAL(pointAdded(int)), d, SLOT(handlePointAdded(int)));
100 100 connect(d->m_series, SIGNAL(pointRemoved(int)), d, SLOT(handlePointRemoved(int)));
101 101 connect(d->m_series, SIGNAL(pointReplaced(int)), d, SLOT(handlePointReplaced(int)));
102 102 }
103 103
104 104 int QXYModelMapper::first() const
105 105 {
106 106 Q_D(const QXYModelMapper);
107 107 return d->m_first;
108 108 }
109 109
110 110 void QXYModelMapper::setFirst(int first)
111 111 {
112 112 Q_D(QXYModelMapper);
113 113 d->m_first = qMax(first, 0);
114 114 d->initializeXYFromModel();
115 115 }
116 116
117 117 int QXYModelMapper::count() const
118 118 {
119 119 Q_D(const QXYModelMapper);
120 120 return d->m_count;
121 121 }
122 122
123 123 void QXYModelMapper::setCount(int count)
124 124 {
125 125 Q_D(QXYModelMapper);
126 126 d->m_count = qMax(count, -1);
127 127 d->initializeXYFromModel();
128 128 }
129 129
130 130 /*!
131 131 Returns the orientation that is used when QXYModelMapper accesses the model.
132 132 This mean whether the consecutive x/y values of the QXYSeries are read from rows (Qt::Horizontal)
133 133 or from columns (Qt::Vertical)
134 134 */
135 135 Qt::Orientation QXYModelMapper::orientation() const
136 136 {
137 137 Q_D(const QXYModelMapper);
138 138 return d->m_orientation;
139 139 }
140 140
141 141 /*!
142 142 Returns the \a orientation that is used when QXYModelMapper accesses the model.
143 143 This mean whether the consecutive x/y values of the QXYSeries are read from rows (Qt::Horizontal)
144 144 or from columns (Qt::Vertical)
145 145 */
146 146 void QXYModelMapper::setOrientation(Qt::Orientation orientation)
147 147 {
148 148 Q_D(QXYModelMapper);
149 149 d->m_orientation = orientation;
150 150 d->initializeXYFromModel();
151 151 }
152 152
153 153 /*!
154 154 Returns which section of the model is kept in sync with the x values of the QXYSeries
155 155 */
156 156 int QXYModelMapper::xSection() const
157 157 {
158 158 Q_D(const QXYModelMapper);
159 159 return d->m_xSection;
160 160 }
161 161
162 162 /*!
163 163 Sets the model section that is kept in sync with the x values of the QXYSeries.
164 164 Parameter \a xSection specifies the section of the model.
165 165 */
166 166 void QXYModelMapper::setXSection(int xSection)
167 167 {
168 168 Q_D(QXYModelMapper);
169 d->m_xSection = xSection;
169 d->m_xSection = qMax(-1, xSection);
170 170 d->initializeXYFromModel();
171 171 }
172 172
173 173 /*!
174 174 Returns which section of the model is kept in sync with the y values of the QXYSeries
175 175 */
176 176 int QXYModelMapper::ySection() const
177 177 {
178 178 Q_D(const QXYModelMapper);
179 179 return d->m_ySection;
180 180 }
181 181
182 182 /*!
183 183 Sets the model section that is kept in sync with the y values of the QXYSeries.
184 184 Parameter \a ySection specifies the section of the model.
185 185 */
186 186 void QXYModelMapper::setYSection(int ySection)
187 187 {
188 188 Q_D(QXYModelMapper);
189 d->m_ySection = ySection;
189 d->m_ySection = qMax(-1, ySection);
190 190 d->initializeXYFromModel();
191 191 }
192 192
193 193 /*!
194 194 Resets the QXYModelMapper to the default state.
195 195 first: 0; count: -1; xSection: -1; ySection: -1;
196 196 */
197 197 void QXYModelMapper::reset()
198 198 {
199 199 Q_D(QXYModelMapper);
200 200 d->m_first = 0;
201 201 d->m_count = -1;
202 202 d->m_orientation = Qt::Vertical;
203 203 d->m_xSection = -1;
204 204 d->m_ySection = -1;
205 205 d->initializeXYFromModel();
206 206 }
207 207
208 208 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
209 209
210 210 QXYModelMapperPrivate::QXYModelMapperPrivate(QXYModelMapper *q) :
211 211 m_series(0),
212 212 m_model(0),
213 213 m_first(0),
214 214 m_count(-1),
215 215 m_orientation(Qt::Vertical),
216 216 m_xSection(-1),
217 217 m_ySection(-1),
218 218 m_seriesSignalsBlock(false),
219 219 m_modelSignalsBlock(false),
220 220 q_ptr(q)
221 221 {
222 222 }
223 223
224 224 void QXYModelMapperPrivate::blockModelSignals(bool block)
225 225 {
226 226 m_modelSignalsBlock = block;
227 227 }
228 228
229 229 void QXYModelMapperPrivate::blockSeriesSignals(bool block)
230 230 {
231 231 m_seriesSignalsBlock = block;
232 232 }
233 233
234 234 QModelIndex QXYModelMapperPrivate::xModelIndex(int xPos)
235 235 {
236 236 if (m_count != -1 && xPos >= m_count)
237 237 return QModelIndex(); // invalid
238 238
239 239 if (m_orientation == Qt::Vertical)
240 240 return m_model->index(xPos + m_first, m_xSection);
241 241 else
242 242 return m_model->index(m_xSection, xPos + m_first);
243 243 }
244 244
245 245 QModelIndex QXYModelMapperPrivate::yModelIndex(int yPos)
246 246 {
247 247 if (m_count != -1 && yPos >= m_count)
248 248 return QModelIndex(); // invalid
249 249
250 250 if (m_orientation == Qt::Vertical)
251 251 return m_model->index(yPos + m_first, m_ySection);
252 252 else
253 253 return m_model->index(m_ySection, yPos + m_first);
254 254 }
255 255
256 256 void QXYModelMapperPrivate::handlePointAdded(int pointPos)
257 257 {
258 258 if (m_seriesSignalsBlock)
259 259 return;
260 260
261 261 if (m_count != -1)
262 262 m_count += 1;
263 263
264 264 blockModelSignals();
265 265 if (m_orientation == Qt::Vertical)
266 266 m_model->insertRows(pointPos + m_first, 1);
267 267 else
268 268 m_model->insertColumns(pointPos + m_first, 1);
269 269
270 270 m_model->setData(xModelIndex(pointPos), m_series->points().at(pointPos).x());
271 271 m_model->setData(yModelIndex(pointPos), m_series->points().at(pointPos).y());
272 272 blockModelSignals(false);
273 273 }
274 274
275 275 void QXYModelMapperPrivate::handlePointRemoved(int pointPos)
276 276 {
277 277 if (m_seriesSignalsBlock)
278 278 return;
279 279
280 280 if (m_count != -1)
281 281 m_count -= 1;
282 282
283 283 blockModelSignals();
284 284 if (m_orientation == Qt::Vertical)
285 285 m_model->removeRow(pointPos + m_first);
286 286 else
287 287 m_model->removeColumn(pointPos + m_first);
288 288 blockModelSignals(false);
289 289 }
290 290
291 291 void QXYModelMapperPrivate::handlePointReplaced(int pointPos)
292 292 {
293 293 if (m_seriesSignalsBlock)
294 294 return;
295 295
296 296 blockModelSignals();
297 297 m_model->setData(xModelIndex(pointPos), m_series->points().at(pointPos).x());
298 298 m_model->setData(yModelIndex(pointPos), m_series->points().at(pointPos).y());
299 299 blockModelSignals(false);
300 300 }
301 301
302 302 void QXYModelMapperPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
303 303 {
304 304 if (m_model == 0 || m_series == 0)
305 305 return;
306 306
307 307 if (m_modelSignalsBlock)
308 308 return;
309 309
310 310 blockSeriesSignals();
311 311 QModelIndex index;
312 312 QPointF oldPoint;
313 313 QPointF newPoint;
314 314 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
315 315 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
316 316 index = topLeft.sibling(row, column);
317 317 if (m_orientation == Qt::Vertical && (index.column() == m_xSection || index.column() == m_ySection)) {
318 318 if (index.row() >= m_first && (m_count == - 1 || index.row() < m_first + m_count)) {
319 319 QModelIndex xIndex = xModelIndex(index.row() - m_first);
320 320 QModelIndex yIndex = yModelIndex(index.row() - m_first);
321 321 if (xIndex.isValid() && yIndex.isValid()) {
322 322 oldPoint = m_series->points().at(index.row() - m_first);
323 323 newPoint.setX(m_model->data(xIndex).toReal());
324 324 newPoint.setY(m_model->data(yIndex).toReal());
325 325 }
326 326 }
327 327 } else if (m_orientation == Qt::Horizontal && (index.row() == m_xSection || index.row() == m_ySection)) {
328 328 if (index.column() >= m_first && (m_count == - 1 || index.column() < m_first + m_count)) {
329 329 QModelIndex xIndex = xModelIndex(index.column() - m_first);
330 330 QModelIndex yIndex = yModelIndex(index.column() - m_first);
331 331 if (xIndex.isValid() && yIndex.isValid()) {
332 332 oldPoint = m_series->points().at(index.column() - m_first);
333 333 newPoint.setX(m_model->data(xIndex).toReal());
334 334 newPoint.setY(m_model->data(yIndex).toReal());
335 335 }
336 336 }
337 337 } else {
338 338 continue;
339 339 }
340 340 m_series->replace(oldPoint, newPoint);
341 341 }
342 342 }
343 343 blockSeriesSignals(false);
344 344 }
345 345
346 346 void QXYModelMapperPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
347 347 {
348 348 Q_UNUSED(parent);
349 349 if (m_modelSignalsBlock)
350 350 return;
351 351
352 352 blockSeriesSignals();
353 353 if (m_orientation == Qt::Vertical)
354 354 insertData(start, end);
355 355 else if (start <= m_xSection || start <= m_ySection) // if the changes affect the map - reinitialize the xy
356 356 initializeXYFromModel();
357 357 blockSeriesSignals(false);
358 358 }
359 359
360 360 void QXYModelMapperPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
361 361 {
362 362 Q_UNUSED(parent);
363 363 if (m_modelSignalsBlock)
364 364 return;
365 365
366 366 blockSeriesSignals();
367 367 if (m_orientation == Qt::Vertical)
368 368 removeData(start, end);
369 369 else if (start <= m_xSection || start <= m_ySection) // if the changes affect the map - reinitialize the xy
370 370 initializeXYFromModel();
371 371 blockSeriesSignals(false);
372 372 }
373 373
374 374 void QXYModelMapperPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
375 375 {
376 376 Q_UNUSED(parent);
377 377 if (m_modelSignalsBlock)
378 378 return;
379 379
380 380 blockSeriesSignals();
381 381 if (m_orientation == Qt::Horizontal)
382 382 insertData(start, end);
383 383 else if (start <= m_xSection || start <= m_ySection) // if the changes affect the map - reinitialize the xy
384 384 initializeXYFromModel();
385 385 blockSeriesSignals(false);
386 386 }
387 387
388 388 void QXYModelMapperPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
389 389 {
390 390 Q_UNUSED(parent);
391 391 if (m_modelSignalsBlock)
392 392 return;
393 393
394 394 blockSeriesSignals();
395 395 if (m_orientation == Qt::Horizontal)
396 396 removeData(start, end);
397 397 else if (start <= m_xSection || start <= m_ySection) // if the changes affect the map - reinitialize the xy
398 398 initializeXYFromModel();
399 399 blockSeriesSignals(false);
400 400 }
401 401
402 402 void QXYModelMapperPrivate::insertData(int start, int end)
403 403 {
404 404 if (m_model == 0 || m_series == 0)
405 405 return;
406 406
407 407 if (m_count != -1 && start >= m_first + m_count) {
408 408 return;
409 409 } else {
410 410 int addedCount = end - start + 1;
411 411 if (m_count != -1 && addedCount > m_count)
412 412 addedCount = m_count;
413 413 int first = qMax(start, m_first);
414 414 int last = qMin(first + addedCount - 1, m_orientation == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
415 415 for (int i = first; i <= last; i++) {
416 416 QPointF point;
417 417 QModelIndex xIndex = xModelIndex(i - m_first);
418 418 QModelIndex yIndex = yModelIndex(i - m_first);
419 419 if (xIndex.isValid() && yIndex.isValid()) {
420 420 point.setX(m_model->data(xIndex, Qt::DisplayRole).toDouble());
421 421 point.setY(m_model->data(yIndex, Qt::DisplayRole).toDouble());
422 422 m_series->insert(i - m_first, point);
423 423 }
424 424 }
425 425
426 426 // remove excess of slices (abouve m_count)
427 427 if (m_count != -1 && m_series->points().size() > m_count)
428 428 for (int i = m_series->points().size() - 1; i >= m_count; i--) {
429 429 m_series->remove(m_series->points().at(i));
430 430 }
431 431 }
432 432 }
433 433
434 434 void QXYModelMapperPrivate::removeData(int start, int end)
435 435 {
436 436 if (m_model == 0 || m_series == 0)
437 437 return;
438 438
439 439 int removedCount = end - start + 1;
440 440 if (m_count != -1 && start >= m_first + m_count) {
441 441 return;
442 442 } else {
443 443 int toRemove = qMin(m_series->count(), removedCount); // first find how many items can actually be removed
444 444 int first = qMax(start, m_first); // get the index of the first item that will be removed.
445 445 int last = qMin(first + toRemove - 1, m_series->count() + m_first - 1); // get the index of the last item that will be removed.
446 446 for (int i = last; i >= first; i--) {
447 447 m_series->remove(m_series->points().at(i - m_first));
448 448 }
449 449
450 450 if (m_count != -1) {
451 451 int itemsAvailable; // check how many are available to be added
452 452 if (m_orientation == Qt::Vertical)
453 453 itemsAvailable = m_model->rowCount() - m_first - m_series->count();
454 454 else
455 455 itemsAvailable = m_model->columnCount() - m_first - m_series->count();
456 456 int toBeAdded = qMin(itemsAvailable, m_count - m_series->count()); // add not more items than there is space left to be filled.
457 457 int currentSize = m_series->count();
458 458 if (toBeAdded > 0)
459 459 for (int i = m_series->count(); i < currentSize + toBeAdded; i++) {
460 460 QPointF point;
461 461 QModelIndex xIndex = xModelIndex(i);
462 462 QModelIndex yIndex = yModelIndex(i);
463 463 if (xIndex.isValid() && yIndex.isValid()) {
464 464 point.setX(m_model->data(xIndex, Qt::DisplayRole).toDouble());
465 465 point.setY(m_model->data(yIndex, Qt::DisplayRole).toDouble());
466 466 m_series->insert(i, point);
467 467 }
468 468 }
469 469 }
470 470 }
471 471 }
472 472
473 473 void QXYModelMapperPrivate::initializeXYFromModel()
474 474 {
475 475 if (m_model == 0 || m_series == 0)
476 476 return;
477 477
478 478 blockSeriesSignals();
479 479 // clear current content
480 480 m_series->clear();
481 481
482 482 // create the initial slices set
483 483 int pointPos = 0;
484 484 QModelIndex xIndex = xModelIndex(pointPos);
485 485 QModelIndex yIndex = yModelIndex(pointPos);
486 486 while (xIndex.isValid() && yIndex.isValid()) {
487 487 QPointF point;
488 488 point.setX(m_model->data(xIndex, Qt::DisplayRole).toDouble());
489 489 point.setY(m_model->data(yIndex, Qt::DisplayRole).toDouble());
490 490 m_series->append(point);
491 491 pointPos++;
492 492 xIndex = xModelIndex(pointPos);
493 493 yIndex = yModelIndex(pointPos);
494 494 }
495 495 blockSeriesSignals(false);
496 496 }
497 497
498 498 #include "moc_qxymodelmapper.cpp"
499 499 #include "moc_qxymodelmapper_p.cpp"
500 500
501 501 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,10 +1,10
1 1 !include( ../tests.pri ) {
2 2 error( "Couldn't find the tests.pri file!" )
3 3 }
4 4
5 5 TEMPLATE = subdirs
6 SUBDIRS += qchartview qchart qlineseries qbarset qbarseries qstackedbarseries qpercentbarseries qgroupedbarseries qpieslice qpieseries qpiemodelmapper qsplineseries qscatterseries
6 SUBDIRS += qchartview qchart qlineseries qbarset qbarseries qstackedbarseries qpercentbarseries qgroupedbarseries qpieslice qpieseries qpiemodelmapper qsplineseries qscatterseries qxymodelmapper
7 7
8 8 test_private:{
9 9 SUBDIRS += chartdataset domain
10 10 }
@@ -1,273 +1,273
1 1 #include <QtCore/QString>
2 2 #include <QtTest/QtTest>
3 3
4 4 #include <qchart.h>
5 5 #include <qchartview.h>
6 6 #include <qpieseries.h>
7 7 #include <qvpiemodelmapper.h>
8 8 #include <qhpiemodelmapper.h>
9 9 #include <QStandardItemModel>
10 10
11 11 QTCOMMERCIALCHART_USE_NAMESPACE
12 12
13 class tst_piemodelmapper : public QObject
13 class tst_qpiemodelmapper : public QObject
14 14 {
15 15 Q_OBJECT
16 16
17 17 public:
18 tst_piemodelmapper();
18 tst_qpiemodelmapper();
19 19
20 20 private Q_SLOTS:
21 21 void initTestCase();
22 22 void cleanupTestCase();
23 23 void init();
24 24 void cleanup();
25 25 void verticalMapper_data();
26 26 void verticalMapper();
27 27 void verticalMapperCustomMapping_data();
28 28 void verticalMapperCustomMapping();
29 29 void horizontalMapper_data();
30 30 void horizontalMapper();
31 31 void horizontalMapperCustomMapping_data();
32 32 void horizontalMapperCustomMapping();
33 33 void seriesUpdated();
34 34
35 35
36 36 private:
37 37 QStandardItemModel *m_model;
38 38 int m_modelRowCount;
39 39 int m_modelColumnCount;
40 40
41 41 QPieSeries *m_series;
42 42 QChart *m_chart;
43 43 };
44 44
45 tst_piemodelmapper::tst_piemodelmapper():
45 tst_qpiemodelmapper::tst_qpiemodelmapper():
46 46 m_model(0),
47 47 m_modelRowCount(10),
48 48 m_modelColumnCount(8)
49 49 {
50 50 }
51 51
52 void tst_piemodelmapper::init()
52 void tst_qpiemodelmapper::init()
53 53 {
54 54 m_series = new QPieSeries;
55 55 m_chart->addSeries(m_series);
56 56 }
57 57
58 void tst_piemodelmapper::cleanup()
58 void tst_qpiemodelmapper::cleanup()
59 59 {
60 60 m_chart->removeSeries(m_series);
61 61 delete m_series;
62 62 m_series = 0;
63 63 }
64 64
65 void tst_piemodelmapper::initTestCase()
65 void tst_qpiemodelmapper::initTestCase()
66 66 {
67 67 m_chart = new QChart;
68 68 QChartView *chartView = new QChartView(m_chart);
69 69 chartView->show();
70 70
71 71 m_model = new QStandardItemModel(this);
72 72 for (int row = 0; row < m_modelRowCount; ++row) {
73 73 for (int column = 0; column < m_modelColumnCount; column++) {
74 74 QStandardItem *item = new QStandardItem(row * column);
75 75 m_model->setItem(row, column, item);
76 76 }
77 77 }
78 78 }
79 79
80 void tst_piemodelmapper::cleanupTestCase()
80 void tst_qpiemodelmapper::cleanupTestCase()
81 81 {
82 82 m_model->clear();
83 83 }
84 84
85 void tst_piemodelmapper::verticalMapper_data()
85 void tst_qpiemodelmapper::verticalMapper_data()
86 86 {
87 87 QTest::addColumn<int>("valuesColumn");
88 88 QTest::addColumn<int>("labelsColumn");
89 89 QTest::addColumn<int>("expectedCount");
90 90 QTest::newRow("different values and labels columns") << 0 << 1 << m_modelRowCount;
91 91 QTest::newRow("same values and labels columns") << 1 << 1 << m_modelRowCount;
92 92 QTest::newRow("invalid values column and correct labels column") << -3 << 1 << 0;
93 93 QTest::newRow("values column beyond the size of model and correct labels column") << m_modelColumnCount << 1 << 0;
94 QTest::newRow("values column beyond the size of model and correct labels column") << m_modelColumnCount << -1 << 0;
94 QTest::newRow("values column beyond the size of model and invalid labels column") << m_modelColumnCount << -1 << 0;
95 95 }
96 96
97 void tst_piemodelmapper::verticalMapper()
97 void tst_qpiemodelmapper::verticalMapper()
98 98 {
99 99 QFETCH(int, valuesColumn);
100 100 QFETCH(int, labelsColumn);
101 101 QFETCH(int, expectedCount);
102 102
103 103 QVPieModelMapper *mapper = new QVPieModelMapper;
104 104 mapper->setValuesColumn(valuesColumn);
105 105 mapper->setLabelsColumn(labelsColumn);
106 106 mapper->setModel(m_model);
107 107 mapper->setSeries(m_series);
108 108
109 109 QCOMPARE(m_series->count(), expectedCount);
110 110 QCOMPARE(mapper->valuesColumn(), qMax(-1, valuesColumn));
111 111 QCOMPARE(mapper->labelsColumn(), qMax(-1, labelsColumn));
112 112
113 113 delete mapper;
114 114 mapper = 0;
115 115 }
116 116
117 void tst_piemodelmapper::verticalMapperCustomMapping_data()
117 void tst_qpiemodelmapper::verticalMapperCustomMapping_data()
118 118 {
119 119 QTest::addColumn<int>("first");
120 120 QTest::addColumn<int>("countLimit");
121 121 QTest::addColumn<int>("expectedCount");
122 122 QTest::newRow("first: 0, unlimited count") << 0 << -1 << m_modelRowCount;
123 123 QTest::newRow("first: 3, unlimited count") << 3 << -1 << m_modelRowCount - 3;
124 124 QTest::newRow("first: 0, count: 5") << 0 << 5 << qMin(5, m_modelRowCount);
125 125 QTest::newRow("first: 3, count: 5") << 3 << 5 << qMin(5, m_modelRowCount - 3);
126 126 QTest::newRow("first: +1 greater then the number of rows in the model, unlimited count") << m_modelRowCount + 1 << -1 << 0;
127 127 QTest::newRow("first: +1 greater then the number of rows in the model, count: 5") << m_modelRowCount + 1 << 5 << 0;
128 128 QTest::newRow("first: 0, count: +3 greater than the number of rows in the model (should limit to the size of model)") << 0 << m_modelRowCount + 3 << m_modelRowCount;
129 129 QTest::newRow("first: -3(invalid - should default to 0), unlimited count") << -3 << -1 << m_modelRowCount;
130 130 QTest::newRow("first: 0, count: -3 (invalid - shlould default to -1)") << 0 << -3 << m_modelRowCount;
131 131 QTest::newRow("first: -3(invalid - should default to 0), count: -3 (invalid - shlould default to -1)") << -3 << -3 << m_modelRowCount;
132 132
133 133 }
134 134
135 void tst_piemodelmapper::verticalMapperCustomMapping()
135 void tst_qpiemodelmapper::verticalMapperCustomMapping()
136 136 {
137 137 QFETCH(int, first);
138 138 QFETCH(int, countLimit);
139 139 QFETCH(int, expectedCount);
140 140
141 141 QCOMPARE(m_series->count(), 0);
142 142
143 143 QVPieModelMapper *mapper = new QVPieModelMapper;
144 144 mapper->setValuesColumn(0);
145 145 mapper->setLabelsColumn(1);
146 146 mapper->setModel(m_model);
147 147 mapper->setSeries(m_series);
148 148 mapper->setFirst(first);
149 149 mapper->setCount(countLimit);
150 150
151 151 QCOMPARE(m_series->count(), expectedCount);
152 152
153 153 // change values column mapping to invalid
154 154 mapper->setValuesColumn(-1);
155 155 mapper->setLabelsColumn(1);
156 156
157 157 QCOMPARE(m_series->count(), 0);
158 158
159 159 delete mapper;
160 160 mapper = 0;
161 161 }
162 162
163 void tst_piemodelmapper::horizontalMapper_data()
163 void tst_qpiemodelmapper::horizontalMapper_data()
164 164 {
165 165 QTest::addColumn<int>("valuesRow");
166 166 QTest::addColumn<int>("labelsRow");
167 167 QTest::addColumn<int>("expectedCount");
168 168 QTest::newRow("different values and labels rows") << 0 << 1 << m_modelColumnCount;
169 169 QTest::newRow("same values and labels rows") << 1 << 1 << m_modelColumnCount;
170 170 QTest::newRow("invalid values row and correct labels row") << -3 << 1 << 0;
171 171 QTest::newRow("values row beyond the size of model and correct labels row") << m_modelRowCount << 1 << 0;
172 172 QTest::newRow("values row beyond the size of model and invalid labels row") << m_modelRowCount << -1 << 0;
173 173 }
174 174
175 void tst_piemodelmapper::horizontalMapper()
175 void tst_qpiemodelmapper::horizontalMapper()
176 176 {
177 177 QFETCH(int, valuesRow);
178 178 QFETCH(int, labelsRow);
179 179 QFETCH(int, expectedCount);
180 180
181 181 QHPieModelMapper *mapper = new QHPieModelMapper;
182 182 mapper->setValuesRow(valuesRow);
183 183 mapper->setLabelsRow(labelsRow);
184 184 mapper->setModel(m_model);
185 185 mapper->setSeries(m_series);
186 186
187 187 QCOMPARE(m_series->count(), expectedCount);
188 188 QCOMPARE(mapper->valuesRow(), qMax(-1, valuesRow));
189 189 QCOMPARE(mapper->labelsRow(), qMax(-1, labelsRow));
190 190
191 191 delete mapper;
192 192 mapper = 0;
193 193 }
194 194
195 void tst_piemodelmapper::horizontalMapperCustomMapping_data()
195 void tst_qpiemodelmapper::horizontalMapperCustomMapping_data()
196 196 {
197 197 QTest::addColumn<int>("first");
198 198 QTest::addColumn<int>("countLimit");
199 199 QTest::addColumn<int>("expectedCount");
200 200 QTest::newRow("first: 0, unlimited count") << 0 << -1 << m_modelColumnCount;
201 201 QTest::newRow("first: 3, unlimited count") << 3 << -1 << m_modelColumnCount - 3;
202 202 QTest::newRow("first: 0, count: 5") << 0 << 5 << qMin(5, m_modelColumnCount);
203 203 QTest::newRow("first: 3, count: 5") << 3 << 5 << qMin(5, m_modelColumnCount - 3);
204 204 QTest::newRow("first: +1 greater then the number of columns in the model, unlimited count") << m_modelColumnCount + 1 << -1 << 0;
205 205 QTest::newRow("first: +1 greater then the number of columns in the model, count: 5") << m_modelColumnCount + 1 << 5 << 0;
206 206 QTest::newRow("first: 0, count: +3 greater than the number of columns in the model (should limit to the size of model)") << 0 << m_modelColumnCount + 3 << m_modelColumnCount;
207 207 QTest::newRow("first: -3(invalid - should default to 0), unlimited count") << -3 << -1 << m_modelColumnCount;
208 208 QTest::newRow("first: 0, count: -3 (invalid - shlould default to -1)") << 0 << -3 << m_modelColumnCount;
209 209 QTest::newRow("first: -3(invalid - should default to 0), count: -3 (invalid - shlould default to -1)") << -3 << -3 << m_modelColumnCount;
210 210 }
211 211
212 void tst_piemodelmapper::horizontalMapperCustomMapping()
212 void tst_qpiemodelmapper::horizontalMapperCustomMapping()
213 213 {
214 214 QFETCH(int, first);
215 215 QFETCH(int, countLimit);
216 216 QFETCH(int, expectedCount);
217 217
218 218 QCOMPARE(m_series->count(), 0);
219 219
220 220 QHPieModelMapper *mapper = new QHPieModelMapper;
221 221 mapper->setValuesRow(0);
222 222 mapper->setLabelsRow(1);
223 223 mapper->setModel(m_model);
224 224 mapper->setSeries(m_series);
225 225 mapper->setFirst(first);
226 226 mapper->setCount(countLimit);
227 227
228 228 QCOMPARE(m_series->count(), expectedCount);
229 229
230 230 // change values row mapping to invalid
231 231 mapper->setValuesRow(-1);
232 232 mapper->setLabelsRow(1);
233 233
234 234 QCOMPARE(m_series->count(), 0);
235 235
236 236 delete mapper;
237 237 mapper = 0;
238 238 }
239 239
240 void tst_piemodelmapper::seriesUpdated()
240 void tst_qpiemodelmapper::seriesUpdated()
241 241 {
242 242 QStandardItemModel *otherModel = new QStandardItemModel;
243 243 for (int row = 0; row < m_modelRowCount; ++row) {
244 244 for (int column = 0; column < m_modelColumnCount; column++) {
245 245 QStandardItem *item = new QStandardItem(row * column);
246 246 otherModel->setItem(row, column, item);
247 247 }
248 248 }
249 249
250 250 QVPieModelMapper *mapper = new QVPieModelMapper;
251 251 mapper->setValuesColumn(0);
252 252 mapper->setLabelsColumn(1);
253 253 mapper->setModel(otherModel);
254 254 mapper->setSeries(m_series);
255 255 QCOMPARE(m_series->count(), m_modelRowCount);
256 256 QCOMPARE(mapper->count(), -1);
257 257
258 258 m_series->append("1000", 1000);
259 259 QCOMPARE(m_series->count(), m_modelRowCount + 1);
260 260 QCOMPARE(mapper->count(), -1); // the value should not change as it indicates 'all' items there are in the model
261 261
262 262 m_series->remove(m_series->slices().last());
263 263 QCOMPARE(m_series->count(), m_modelRowCount);
264 264 QCOMPARE(mapper->count(), -1); // the value should not change as it indicates 'all' items there are in the model
265 265
266 266 otherModel->clear();
267 267 delete otherModel;
268 268 otherModel = 0;
269 269 }
270 270
271 QTEST_MAIN(tst_piemodelmapper)
271 QTEST_MAIN(tst_qpiemodelmapper)
272 272
273 273 #include "tst_qpiemodelmapper.moc"
General Comments 0
You need to be logged in to leave comments. Login now