1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Charts module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 or (at your option) any later version
20** approved by the KDE Free Qt Foundation. The licenses are as published by
21** the Free Software Foundation and appearing in the file LICENSE.GPL3
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include <QtTest/QtTest>
31#include <QtCharts/QChartView>
32#include <QtCharts/QChart>
33#include <QtCharts/QPieSeries>
34#include <QtCharts/QPieSlice>
35#include <QtCharts/QPieModelMapper>
36#include <QtGui/QStandardItemModel>
37#include <tst_definitions.h>
38
39QT_CHARTS_USE_NAMESPACE
40
41Q_DECLARE_METATYPE(QPieSlice*)
42Q_DECLARE_METATYPE(QList<QPieSlice*>)
43
44class tst_qpieseries : public QObject
45{
46 Q_OBJECT
47
48public slots:
49 void initTestCase();
50 void cleanupTestCase();
51 void init();
52 void cleanup();
53
54private slots:
55 void properties();
56 void append();
57 void appendAnimated();
58 void insert();
59 void insertAnimated();
60 void remove();
61 void removeAnimated();
62 void take();
63 void takeAnimated();
64 void calculatedValues();
65 void clickedSignal();
66 void hoverSignal();
67 void sliceSeries();
68 void destruction();
69 void pressedSignal();
70 void releasedSignal();
71 void doubleClickedSignal();
72
73private:
74 void verifyCalculatedData(const QPieSeries &series, bool *ok);
75 QList<QPoint> slicePoints(QRectF rect);
76
77private:
78 QChartView *m_view;
79 QPieSeries *m_series;
80};
81
82void tst_qpieseries::initTestCase()
83{
84 qRegisterMetaType<QPieSlice*>(typeName: "QPieSlice*");
85 qRegisterMetaType<QList<QPieSlice*> >(typeName: "QList<QPieSlice*>");
86}
87
88void tst_qpieseries::cleanupTestCase()
89{
90 QTest::qWait(ms: 1); // Allow final deleteLaters to run
91}
92
93void tst_qpieseries::init()
94{
95 m_view = new QChartView();
96 m_view->resize(w: 200, h: 200);
97 m_series = new QPieSeries(m_view);
98 m_view->show();
99 QVERIFY(QTest::qWaitForWindowExposed(m_view));
100
101}
102
103void tst_qpieseries::cleanup()
104{
105 delete m_view;
106 m_view = 0;
107 m_series = 0;
108}
109
110void tst_qpieseries::properties()
111{
112 QSignalSpy countSpy(m_series, SIGNAL(countChanged()));
113 QSignalSpy sumSpy(m_series, SIGNAL(sumChanged()));
114 QSignalSpy opacitySpy(m_series, SIGNAL(opacityChanged()));
115
116 QVERIFY(m_series->type() == QAbstractSeries::SeriesTypePie);
117 QVERIFY(m_series->count() == 0);
118 QVERIFY(m_series->isEmpty());
119 QCOMPARE(m_series->sum(), 0.0);
120 QCOMPARE(m_series->horizontalPosition(), 0.5);
121 QCOMPARE(m_series->verticalPosition(), 0.5);
122 QCOMPARE(m_series->pieSize(), 0.7);
123 QCOMPARE(m_series->pieStartAngle(), 0.0);
124 QCOMPARE(m_series->pieEndAngle(), 360.0);
125 QCOMPARE(m_series->opacity(), 1.0);
126
127 m_series->append(label: "s1", value: 1);
128 m_series->append(label: "s2", value: 1);
129 m_series->append(label: "s3", value: 1);
130 m_series->insert(index: 1, slice: new QPieSlice("s4", 1));
131 m_series->remove(slice: m_series->slices().first());
132 QCOMPARE(m_series->count(), 3);
133 QCOMPARE(m_series->sum(), 3.0);
134 m_series->clear();
135 QCOMPARE(m_series->count(), 0);
136 QCOMPARE(m_series->sum(), 0.0);
137 QCOMPARE(countSpy.count(), 6);
138 QCOMPARE(sumSpy.count(), 6);
139
140 m_series->setPieSize(-1.0);
141 QCOMPARE(m_series->pieSize(), 0.0);
142 m_series->setPieSize(0.0);
143 m_series->setPieSize(0.9);
144 m_series->setPieSize(2.0);
145 QCOMPARE(m_series->pieSize(), 1.0);
146
147 m_series->setPieSize(0.7);
148 QCOMPARE(m_series->pieSize(), 0.7);
149
150 m_series->setHoleSize(-1.0);
151 QCOMPARE(m_series->holeSize(), 0.0);
152 m_series->setHoleSize(0.5);
153 QCOMPARE(m_series->holeSize(), 0.5);
154
155 m_series->setHoleSize(0.8);
156 QCOMPARE(m_series->holeSize(), 0.8);
157 QCOMPARE(m_series->pieSize(), 0.8);
158
159 m_series->setPieSize(0.4);
160 QCOMPARE(m_series->pieSize(), 0.4);
161 QCOMPARE(m_series->holeSize(), 0.4);
162
163 m_series->setPieStartAngle(0);
164 m_series->setPieStartAngle(-180);
165 m_series->setPieStartAngle(180);
166 QCOMPARE(m_series->pieStartAngle(), 180.0);
167
168 m_series->setPieEndAngle(360);
169 m_series->setPieEndAngle(-180);
170 m_series->setPieEndAngle(180);
171 QCOMPARE(m_series->pieEndAngle(), 180.0);
172
173 m_series->setHorizontalPosition(0.5);
174 m_series->setHorizontalPosition(-1.0);
175 QCOMPARE(m_series->horizontalPosition(), 0.0);
176 m_series->setHorizontalPosition(1.0);
177 m_series->setHorizontalPosition(2.0);
178 QCOMPARE(m_series->horizontalPosition(), 1.0);
179
180 m_series->setVerticalPosition(0.5);
181 m_series->setVerticalPosition(-1.0);
182 QCOMPARE(m_series->verticalPosition(), 0.0);
183 m_series->setVerticalPosition(1.0);
184 m_series->setVerticalPosition(2.0);
185 QCOMPARE(m_series->verticalPosition(), 1.0);
186
187 m_series->setOpacity(0.5);
188 QCOMPARE(m_series->opacity(), 0.5);
189 QCOMPARE(opacitySpy.count(), 1);
190 m_series->setOpacity(0.0);
191 QCOMPARE(m_series->opacity(), 0.0);
192 QCOMPARE(opacitySpy.count(), 2);
193 m_series->setOpacity(1.0);
194 QCOMPARE(m_series->opacity(), 1.0);
195 QCOMPARE(opacitySpy.count(), 3);
196}
197
198void tst_qpieseries::append()
199{
200 m_view->chart()->addSeries(series: m_series);
201 QSignalSpy addedSpy(m_series, SIGNAL(added(QList<QPieSlice*>)));
202
203 // append pointer
204 QPieSlice *slice1 = 0;
205 QVERIFY(!m_series->append(slice1));
206 slice1 = new QPieSlice("slice 1", 1);
207 QVERIFY(m_series->append(slice1));
208 QVERIFY(!m_series->append(slice1));
209 QCOMPARE(m_series->count(), 1);
210 QCOMPARE(addedSpy.count(), 1);
211 QList<QPieSlice*> added = qvariant_cast<QList<QPieSlice*> >(v: addedSpy.at(i: 0).at(i: 0));
212 QCOMPARE(added.count(), 1);
213 QCOMPARE(added.first(), slice1);
214
215 // try to append same slice to another series
216 QPieSeries series2;
217 QVERIFY(!series2.append(slice1));
218
219 // append pointer list
220 QList<QPieSlice *> list;
221 QVERIFY(!m_series->append(list));
222 list << (QPieSlice *) 0;
223 QVERIFY(!m_series->append(list));
224 list.clear();
225 list << new QPieSlice("slice 2", 2);
226 list << new QPieSlice("slice 3", 3);
227 QVERIFY(m_series->append(list));
228 QVERIFY(!m_series->append(list));
229 QCOMPARE(m_series->count(), 3);
230 QCOMPARE(addedSpy.count(), 2);
231 added = qvariant_cast<QList<QPieSlice*> >(v: addedSpy.at(i: 1).at(i: 0));
232 QCOMPARE(added.count(), 2);
233 QCOMPARE(added, list);
234
235 // append operator
236 QPieSlice *slice4 = new QPieSlice("slice 4", 4);
237 *m_series << slice4;
238 *m_series << slice1; // fails because already added
239 QCOMPARE(m_series->count(), 4);
240 QCOMPARE(addedSpy.count(), 3);
241 added = qvariant_cast<QList<QPieSlice*> >(v: addedSpy.at(i: 2).at(i: 0));
242 QCOMPARE(added.count(), 1);
243 QCOMPARE(added.first(), slice4);
244
245 // append with params
246 QPieSlice *slice5 = m_series->append(label: "slice 5", value: 5);
247 QVERIFY(slice5 != 0);
248 QCOMPARE(slice5->value(), 5.0);
249 QCOMPARE(slice5->label(), QString("slice 5"));
250 QCOMPARE(m_series->count(), 5);
251 QCOMPARE(addedSpy.count(), 4);
252 added = qvariant_cast<QList<QPieSlice*> >(v: addedSpy.at(i: 3).at(i: 0));
253 QCOMPARE(added.count(), 1);
254 QCOMPARE(added.first(), slice5);
255
256 // check slices
257 QVERIFY(!m_series->isEmpty());
258 for (int i=0; i<m_series->count(); i++) {
259 QCOMPARE(m_series->slices().at(i)->value(), (qreal) i+1);
260 QCOMPARE(m_series->slices().at(i)->label(), QString("slice ") + QString::number(i+1));
261 }
262}
263
264void tst_qpieseries::appendAnimated()
265{
266 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
267 append();
268}
269
270void tst_qpieseries::insert()
271{
272 m_view->chart()->addSeries(series: m_series);
273 QSignalSpy addedSpy(m_series, SIGNAL(added(QList<QPieSlice*>)));
274
275 // insert one slice
276 QPieSlice *slice1 = 0;
277 QVERIFY(!m_series->insert(0, slice1));
278 slice1 = new QPieSlice("slice 1", 1);
279 QVERIFY(!m_series->insert(-1, slice1));
280 QVERIFY(!m_series->insert(5, slice1));
281 QVERIFY(m_series->insert(0, slice1));
282 QVERIFY(!m_series->insert(0, slice1));
283 QCOMPARE(m_series->count(), 1);
284 QCOMPARE(addedSpy.count(), 1);
285 QList<QPieSlice*> added = qvariant_cast<QList<QPieSlice*> >(v: addedSpy.at(i: 0).at(i: 0));
286 QCOMPARE(added.count(), 1);
287 QCOMPARE(added.first(), slice1);
288
289 // try to insert same slice to another series
290 QPieSeries series2;
291 QVERIFY(!series2.insert(0, slice1));
292
293 // add some more slices
294 QPieSlice *slice2 = m_series->append(label: "slice 2", value: 2);
295 QPieSlice *slice4 = m_series->append(label: "slice 4", value: 4);
296 QCOMPARE(m_series->count(), 3);
297 QCOMPARE(addedSpy.count(), 3);
298 added = qvariant_cast<QList<QPieSlice*> >(v: addedSpy.at(i: 1).at(i: 0));
299 QCOMPARE(added.count(), 1);
300 QCOMPARE(added.first(), slice2);
301 added = qvariant_cast<QList<QPieSlice*> >(v: addedSpy.at(i: 2).at(i: 0));
302 QCOMPARE(added.count(), 1);
303 QCOMPARE(added.first(), slice4);
304
305 // insert between slices
306 QPieSlice *slice3 = new QPieSlice("slice 3", 3);
307 m_series->insert(index: 2, slice: slice3);
308 QCOMPARE(m_series->count(), 4);
309 QCOMPARE(addedSpy.count(), 4);
310 added = qvariant_cast<QList<QPieSlice*> >(v: addedSpy.at(i: 3).at(i: 0));
311 QCOMPARE(added.count(), 1);
312 QCOMPARE(added.first(), slice3);
313
314 // check slices
315 for (int i=0; i<m_series->count(); i++) {
316 QCOMPARE(m_series->slices().at(i)->value(), (qreal) i+1);
317 QCOMPARE(m_series->slices().at(i)->label(), QString("slice ") + QString::number(i+1));
318 QVERIFY(m_series->slices().at(i)->parent() == m_series);
319 }
320}
321
322void tst_qpieseries::insertAnimated()
323{
324 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
325 insert();
326}
327
328void tst_qpieseries::remove()
329{
330 m_view->chart()->addSeries(series: m_series);
331 QSignalSpy removedSpy(m_series, SIGNAL(removed(QList<QPieSlice*>)));
332
333 // add some slices
334 QPieSlice *slice1 = m_series->append(label: "slice 1", value: 1);
335 QPieSlice *slice2 = m_series->append(label: "slice 2", value: 2);
336 QPieSlice *slice3 = m_series->append(label: "slice 3", value: 3);
337 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
338 QSignalSpy spy2(slice2, SIGNAL(destroyed()));
339 QSignalSpy spy3(slice3, SIGNAL(destroyed()));
340 QCOMPARE(m_series->count(), 3);
341
342 // null pointer remove
343 QVERIFY(!m_series->remove(0));
344
345 // remove first
346 QVERIFY(m_series->remove(slice1));
347 QVERIFY(!m_series->remove(slice1));
348 QCOMPARE(m_series->count(), 2);
349 QCOMPARE(m_series->slices().at(0)->label(), slice2->label());
350 QCOMPARE(removedSpy.count(), 1);
351 QList<QPieSlice*> removed = qvariant_cast<QList<QPieSlice*> >(v: removedSpy.at(i: 0).at(i: 0));
352 QCOMPARE(removed.count(), 1);
353 QCOMPARE(removed.first(), slice1);
354
355 // remove all
356 m_series->clear();
357 QVERIFY(m_series->isEmpty());
358 QVERIFY(m_series->slices().isEmpty());
359 QCOMPARE(m_series->count(), 0);
360 QCOMPARE(removedSpy.count(), 2);
361 removed = qvariant_cast<QList<QPieSlice*> >(v: removedSpy.at(i: 1).at(i: 0));
362 QCOMPARE(removed.count(), 2);
363 QCOMPARE(removed.first(), slice2);
364 QCOMPARE(removed.last(), slice3);
365
366 // check that slices were actually destroyed
367 TRY_COMPARE(spy1.count(), 1);
368 TRY_COMPARE(spy2.count(), 1);
369 TRY_COMPARE(spy3.count(), 1);
370}
371
372void tst_qpieseries::removeAnimated()
373{
374 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
375 remove();
376}
377
378void tst_qpieseries::take()
379{
380 m_view->chart()->addSeries(series: m_series);
381 QSignalSpy removedSpy(m_series, SIGNAL(removed(QList<QPieSlice*>)));
382
383 // add some slices
384 QPieSlice *slice1 = m_series->append(label: "slice 1", value: 1);
385 QPieSlice *slice2 = m_series->append(label: "slice 2", value: 2);
386 m_series->append(label: "slice 3", value: 3);
387 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
388 QCOMPARE(m_series->count(), 3);
389
390 // null pointer remove
391 QVERIFY(!m_series->take(0));
392
393 // take first
394 QVERIFY(m_series->take(slice1));
395 TRY_COMPARE(spy1.count(), 0);
396 QVERIFY(slice1->parent() == m_series); // series is still the parent object
397 QVERIFY(!m_series->take(slice1));
398 QCOMPARE(m_series->count(), 2);
399 QCOMPARE(m_series->slices().at(0)->label(), slice2->label());
400 QCOMPARE(removedSpy.count(), 1);
401 QList<QPieSlice*> removed = qvariant_cast<QList<QPieSlice*> >(v: removedSpy.at(i: 0).at(i: 0));
402 QCOMPARE(removed.count(), 1);
403 QCOMPARE(removed.first(), slice1);
404}
405
406void tst_qpieseries::takeAnimated()
407{
408 m_view->chart()->setAnimationOptions(QChart::AllAnimations);
409 take();
410}
411
412void tst_qpieseries::calculatedValues()
413{
414 m_view->chart()->addSeries(series: m_series);
415
416 QPieSlice *slice1 = new QPieSlice("slice 1", 1);
417 QSignalSpy percentageSpy(slice1, SIGNAL(percentageChanged()));
418 QSignalSpy startAngleSpy(slice1, SIGNAL(startAngleChanged()));
419 QSignalSpy angleSpanSpy(slice1, SIGNAL(angleSpanChanged()));
420
421 // add a slice
422 m_series->append(slice: slice1);
423 bool ok;
424 verifyCalculatedData(series: *m_series, ok: &ok);
425 if (!ok)
426 return;
427 QCOMPARE(percentageSpy.count(), 1);
428 QCOMPARE(startAngleSpy.count(), 0);
429 QCOMPARE(angleSpanSpy.count(), 1);
430
431 // add some more slices
432 QList<QPieSlice *> list;
433 list << new QPieSlice("slice 2", 2);
434 list << new QPieSlice("slice 3", 3);
435 m_series->append(slices: list);
436 verifyCalculatedData(series: *m_series, ok: &ok);
437 if (!ok)
438 return;
439 QCOMPARE(percentageSpy.count(), 2);
440 QCOMPARE(startAngleSpy.count(), 0);
441 QCOMPARE(angleSpanSpy.count(), 2);
442
443 // remove a slice
444 m_series->remove(slice: list.first()); // remove slice 2
445 verifyCalculatedData(series: *m_series, ok: &ok);
446 if (!ok)
447 return;
448 QCOMPARE(percentageSpy.count(), 3);
449 QCOMPARE(startAngleSpy.count(), 0);
450 QCOMPARE(angleSpanSpy.count(), 3);
451
452 // insert a slice
453 m_series->insert(index: 0, slice: new QPieSlice("Slice 4", 4));
454 verifyCalculatedData(series: *m_series, ok: &ok);
455 if (!ok)
456 return;
457 QCOMPARE(percentageSpy.count(), 4);
458 QCOMPARE(startAngleSpy.count(), 1);
459 QCOMPARE(angleSpanSpy.count(), 4);
460
461 // modify pie angles
462 m_series->setPieStartAngle(-90);
463 m_series->setPieEndAngle(90);
464 verifyCalculatedData(series: *m_series, ok: &ok);
465 if (!ok)
466 return;
467 QCOMPARE(percentageSpy.count(), 4);
468 QCOMPARE(startAngleSpy.count(), 3);
469 QCOMPARE(angleSpanSpy.count(), 6);
470
471 // clear all
472 m_series->clear();
473 verifyCalculatedData(series: *m_series, ok: &ok);
474 if (!ok)
475 return;
476 QCOMPARE(percentageSpy.count(), 4);
477 QCOMPARE(startAngleSpy.count(), 3);
478 QCOMPARE(angleSpanSpy.count(), 6);
479}
480
481void tst_qpieseries::verifyCalculatedData(const QPieSeries &series, bool *ok)
482{
483 *ok = false;
484
485 qreal sum = 0;
486 foreach (const QPieSlice *slice, series.slices())
487 sum += slice->value();
488 QCOMPARE(series.sum(), sum);
489
490 qreal startAngle = series.pieStartAngle();
491 qreal pieAngleSpan = series.pieEndAngle() - series.pieStartAngle();
492 foreach (const QPieSlice *slice, series.slices()) {
493 qreal ratio = slice->value() / sum;
494 qreal sliceSpan = pieAngleSpan * ratio;
495 QCOMPARE(slice->startAngle(), startAngle);
496 QCOMPARE(slice->angleSpan(), sliceSpan);
497 QCOMPARE(slice->percentage(), ratio);
498 startAngle += sliceSpan;
499 }
500
501 if (!series.isEmpty())
502 QCOMPARE(series.slices().last()->startAngle() + series.slices().last()->angleSpan(), series.pieEndAngle());
503
504 *ok = true;
505}
506
507void tst_qpieseries::clickedSignal()
508{
509 // NOTE:
510 // This test is the same as tst_qpieslice::clickedSignal()
511 // Just for different signals.
512
513 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
514
515 // add some slices
516 QPieSlice *s1 = m_series->append(label: "slice 1", value: 1);
517 QPieSlice *s2 = m_series->append(label: "slice 2", value: 1);
518 QPieSlice *s3 = m_series->append(label: "slice 3", value: 1);
519 QPieSlice *s4 = m_series->append(label: "slice 4", value: 1);
520 QSignalSpy clickSpy(m_series, SIGNAL(clicked(QPieSlice*)));
521
522 // add series to the chart
523 m_view->chart()->legend()->setVisible(false);
524 m_view->chart()->addSeries(series: m_series);
525 m_view->show();
526 QVERIFY(QTest::qWaitForWindowExposed(m_view));
527
528 // test maximum size
529 m_series->setPieSize(1.0);
530 QRectF pieRect = m_view->chart()->plotArea();
531 QList<QPoint> points = slicePoints(rect: pieRect);
532 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 0));
533 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 1));
534 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 2));
535 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 3));
536 TRY_COMPARE(clickSpy.count(), 4);
537 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(0).at(0)), s1);
538 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(1).at(0)), s2);
539 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(2).at(0)), s3);
540 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(3).at(0)), s4);
541 clickSpy.clear();
542
543 // test half size
544 m_series->setPieSize(0.5);
545 m_series->setVerticalPosition(0.25);
546 m_series->setHorizontalPosition(0.25);
547 pieRect = QRectF(m_view->chart()->plotArea().topLeft(), m_view->chart()->plotArea().center());
548 points = slicePoints(rect: pieRect);
549 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 0));
550 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 1));
551 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 2));
552 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 3));
553 TRY_COMPARE(clickSpy.count(), 4);
554 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(0).at(0)), s1);
555 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(1).at(0)), s2);
556 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(2).at(0)), s3);
557 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(3).at(0)), s4);
558}
559
560void tst_qpieseries::hoverSignal()
561{
562 // NOTE:
563 // This test is the same as tst_qpieslice::hoverSignal()
564 // Just for different signals.
565
566 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
567 SKIP_IF_FLAKY_MOUSE_MOVE();
568
569 // add some slices
570 m_series->append(label: "slice 1", value: 1);
571 m_series->append(label: "slice 2", value: 1);
572 m_series->append(label: "slice 3", value: 1);
573 m_series->append(label: "slice 4", value: 1);
574
575 // add series to the chart
576 m_view->chart()->legend()->setVisible(false);
577 m_view->chart()->addSeries(series: m_series);
578 m_view->show();
579 QVERIFY(QTest::qWaitForWindowExposed(m_view));
580
581 // move inside the slices
582 m_series->setPieSize(1.0);
583 QRectF pieRect = m_view->chart()->plotArea();
584 QList<QPoint> points = slicePoints(rect: pieRect);
585 QTest::mouseMove(widget: m_view->viewport(), pos: pieRect.topRight().toPoint(), delay: 100);
586 QSignalSpy hoverSpy(m_series, SIGNAL(hovered(QPieSlice*,bool)));
587 QTest::mouseMove(widget: m_view->viewport(), pos: points.at(i: 0), delay: 100);
588 QTest::mouseMove(widget: m_view->viewport(), pos: points.at(i: 1), delay: 100);
589 QTest::mouseMove(widget: m_view->viewport(), pos: points.at(i: 2), delay: 100);
590 QTest::mouseMove(widget: m_view->viewport(), pos: points.at(i: 3), delay: 100);
591 QTest::mouseMove(widget: m_view->viewport(), pos: pieRect.topLeft().toPoint(), delay: 100);
592 // Final hoverevent can take few milliseconds to appear in some environments, so wait a bit
593 QTest::qWait(ms: 100);
594
595 // check
596 QCOMPARE(hoverSpy.count(), 8);
597 int i = 0;
598 foreach (QPieSlice *s, m_series->slices()) {
599 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(i).at(0)), s);
600 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(i).at(1)), true);
601 i++;
602 QCOMPARE(qvariant_cast<QPieSlice*>(hoverSpy.at(i).at(0)), s);
603 QCOMPARE(qvariant_cast<bool>(hoverSpy.at(i).at(1)), false);
604 i++;
605 }
606}
607
608void tst_qpieseries::sliceSeries()
609{
610 QPieSlice *slice = new QPieSlice();
611 QVERIFY(!slice->series());
612 delete slice;
613
614 slice = new QPieSlice(m_series);
615 QVERIFY(!slice->series());
616
617 m_series->append(slice);
618 QCOMPARE(slice->series(), m_series);
619
620 slice = new QPieSlice();
621 m_series->insert(index: 0, slice);
622 QCOMPARE(slice->series(), m_series);
623
624 m_series->take(slice);
625 QCOMPARE(slice->series(), (QPieSeries*) 0);
626}
627
628void tst_qpieseries::destruction()
629{
630 // add some slices
631 QPieSlice *slice1 = m_series->append(label: "slice 1", value: 1);
632 QPieSlice *slice2 = m_series->append(label: "slice 2", value: 2);
633 QPieSlice *slice3 = m_series->append(label: "slice 3", value: 3);
634 QSignalSpy spy1(slice1, SIGNAL(destroyed()));
635 QSignalSpy spy2(slice2, SIGNAL(destroyed()));
636 QSignalSpy spy3(slice3, SIGNAL(destroyed()));
637
638 // destroy series
639 delete m_series;
640 m_series = 0;
641
642 // check that series has destroyed its slices
643 QCOMPARE(spy1.count(), 1);
644 QCOMPARE(spy2.count(), 1);
645 QCOMPARE(spy3.count(), 1);
646}
647
648QList<QPoint> tst_qpieseries::slicePoints(QRectF rect)
649{
650 qreal x1 = rect.topLeft().x() + (rect.width() / 4);
651 qreal x2 = rect.topLeft().x() + (rect.width() / 4) * 3;
652 qreal y1 = rect.topLeft().y() + (rect.height() / 4);
653 qreal y2 = rect.topLeft().y() + (rect.height() / 4) * 3;
654 QList<QPoint> points;
655 points << QPoint(x2, y1);
656 points << QPoint(x2, y2);
657 points << QPoint(x1, y2);
658 points << QPoint(x1, y1);
659 return points;
660}
661
662void tst_qpieseries::pressedSignal()
663{
664 // NOTE:
665 // This test is the same as tst_qpieslice::pressedSignal()
666 // Just for different signals.
667
668 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
669
670 // add some slices
671 QPieSlice *s1 = m_series->append(label: "slice 1", value: 1);
672 QPieSlice *s2 = m_series->append(label: "slice 2", value: 1);
673 QPieSlice *s3 = m_series->append(label: "slice 3", value: 1);
674 QPieSlice *s4 = m_series->append(label: "slice 4", value: 1);
675 QSignalSpy clickSpy(m_series, SIGNAL(pressed(QPieSlice*)));
676
677 // add series to the chart
678 m_view->chart()->legend()->setVisible(false);
679 m_view->chart()->addSeries(series: m_series);
680 m_view->show();
681 QVERIFY(QTest::qWaitForWindowExposed(m_view));
682
683 // test maximum size
684 m_series->setPieSize(1.0);
685 QRectF pieRect = m_view->chart()->plotArea();
686 QList<QPoint> points = slicePoints(rect: pieRect);
687 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 0));
688 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 1));
689 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 2));
690 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 3));
691 TRY_COMPARE(clickSpy.count(), 4);
692 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(0).at(0)), s1);
693 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(1).at(0)), s2);
694 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(2).at(0)), s3);
695 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(3).at(0)), s4);
696 clickSpy.clear();
697
698 // test half size
699 m_series->setPieSize(0.5);
700 m_series->setVerticalPosition(0.25);
701 m_series->setHorizontalPosition(0.25);
702 pieRect = QRectF(m_view->chart()->plotArea().topLeft(), m_view->chart()->plotArea().center());
703 points = slicePoints(rect: pieRect);
704 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 0));
705 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 1));
706 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 2));
707 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 3));
708 TRY_COMPARE(clickSpy.count(), 4);
709 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(0).at(0)), s1);
710 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(1).at(0)), s2);
711 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(2).at(0)), s3);
712 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(3).at(0)), s4);
713}
714
715void tst_qpieseries::releasedSignal()
716{
717 // NOTE:
718 // This test is the same as tst_qpieslice::pressedSignal()
719 // Just for different signals.
720
721 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
722
723 // add some slices
724 QPieSlice *s1 = m_series->append(label: "slice 1", value: 1);
725 QPieSlice *s2 = m_series->append(label: "slice 2", value: 1);
726 QPieSlice *s3 = m_series->append(label: "slice 3", value: 1);
727 QPieSlice *s4 = m_series->append(label: "slice 4", value: 1);
728 QSignalSpy clickSpy(m_series, SIGNAL(released(QPieSlice*)));
729
730 // add series to the chart
731 m_view->chart()->legend()->setVisible(false);
732 m_view->chart()->addSeries(series: m_series);
733 m_view->show();
734 QVERIFY(QTest::qWaitForWindowExposed(m_view));
735
736 // test maximum size
737 m_series->setPieSize(1.0);
738 QRectF pieRect = m_view->chart()->plotArea();
739 QList<QPoint> points = slicePoints(rect: pieRect);
740 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 0));
741 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 1));
742 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 2));
743 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 3));
744 TRY_COMPARE(clickSpy.count(), 4);
745 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(0).at(0)), s1);
746 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(1).at(0)), s2);
747 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(2).at(0)), s3);
748 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(3).at(0)), s4);
749 clickSpy.clear();
750
751 // test half size
752 m_series->setPieSize(0.5);
753 m_series->setVerticalPosition(0.25);
754 m_series->setHorizontalPosition(0.25);
755 pieRect = QRectF(m_view->chart()->plotArea().topLeft(), m_view->chart()->plotArea().center());
756 points = slicePoints(rect: pieRect);
757 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 0));
758 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 1));
759 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 2));
760 QTest::mouseClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 3));
761 TRY_COMPARE(clickSpy.count(), 4);
762 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(0).at(0)), s1);
763 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(1).at(0)), s2);
764 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(2).at(0)), s3);
765 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(3).at(0)), s4);
766}
767
768void tst_qpieseries::doubleClickedSignal()
769{
770 // NOTE:
771 // This test is the same as tst_qpieslice::pressedSignal()
772 // Just for different signals.
773
774 SKIP_IF_CANNOT_TEST_MOUSE_EVENTS();
775
776 // add some slices
777 QPieSlice *s1 = m_series->append(label: "slice 1", value: 1);
778 QSignalSpy clickSpy(m_series, SIGNAL(doubleClicked(QPieSlice*)));
779
780 // add series to the chart
781 m_view->chart()->legend()->setVisible(false);
782 m_view->chart()->addSeries(series: m_series);
783 m_view->show();
784 QVERIFY(QTest::qWaitForWindowExposed(m_view));
785
786 // test maximum size
787 m_series->setPieSize(1.0);
788 QRectF pieRect = m_view->chart()->plotArea();
789 QList<QPoint> points = slicePoints(rect: pieRect);
790 QTest::mouseDClick(widget: m_view->viewport(), button: Qt::LeftButton, stateKey: {}, pos: points.at(i: 0));
791 TRY_COMPARE(clickSpy.count(), 1);
792 QCOMPARE(qvariant_cast<QPieSlice*>(clickSpy.at(0).at(0)), s1);
793}
794
795QTEST_MAIN(tst_qpieseries)
796
797#include "tst_qpieseries.moc"
798
799

source code of qtcharts/tests/auto/qpieseries/tst_qpieseries.cpp