1ddee7714ae11a72e3f0b81864573df840fc270d
[profile/ivi/qtbase.git] / tests / auto / widgets / effects / qgraphicseffect / tst_qgraphicseffect.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
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 Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43 #include <QtTest/QtTestWidgets>
44 #include <QtWidgets/qdesktopwidget.h>
45 #include <QtWidgets/qgraphicseffect.h>
46 #include <QtWidgets/qgraphicsview.h>
47 #include <QtWidgets/qgraphicsscene.h>
48 #include <QtWidgets/qgraphicsitem.h>
49 #include <QtWidgets/qgraphicswidget.h>
50 #include <QtWidgets/qstyleoption.h>
51
52 #include <private/qgraphicseffect_p.h>
53
54 class tst_QGraphicsEffect : public QObject
55 {
56     Q_OBJECT
57 public slots:
58     void initTestCase();
59
60 private slots:
61     void setEnabled();
62     void source();
63     void boundingRectFor();
64     void boundingRect();
65     void boundingRect2();
66     void draw();
67     void opacity();
68     void grayscale();
69     void colorize();
70     void drawPixmapItem();
71     void deviceCoordinateTranslateCaching();
72     void inheritOpacity();
73     void dropShadowClipping();
74     void childrenVisibilityShouldInvalidateCache();
75     void prepareGeometryChangeInvalidateCache();
76     void itemHasNoContents();
77 };
78
79 void tst_QGraphicsEffect::initTestCase()
80 {}
81
82 class CustomItem : public QGraphicsRectItem
83 {
84 public:
85     CustomItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = 0)
86         : QGraphicsRectItem(x, y, width, height, parent), numRepaints(0),
87           m_painter(0), m_styleOption(0)
88     {}
89
90     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
91     {
92         m_painter = painter;
93         m_styleOption = option;
94         ++numRepaints;
95         QGraphicsRectItem::paint(painter, option, widget);
96     }
97
98     void reset()
99     {
100         numRepaints = 0;
101         m_painter = 0;
102         m_styleOption = 0;
103     }
104
105     int numRepaints;
106     QPainter *m_painter;
107     const QStyleOption *m_styleOption;
108 };
109
110 class CustomEffect : public QGraphicsEffect
111 {
112 public:
113     CustomEffect()
114         : QGraphicsEffect(), numRepaints(0), m_margin(10),
115           doNothingInDraw(false), m_painter(0), m_styleOption(0), m_source(0), m_opacity(1.0)
116     {}
117
118     QRectF boundingRectFor(const QRectF &rect) const
119     { return rect.adjusted(-m_margin, -m_margin, m_margin, m_margin); }
120
121     void reset()
122     {
123         numRepaints = 0;
124         m_sourceChangedFlags = QGraphicsEffect::ChangeFlags();
125         m_painter = 0;
126         m_styleOption = 0;
127         m_source = 0;
128         m_opacity = 1.0;
129     }
130
131     void setMargin(int margin)
132     {
133         m_margin = margin;
134         updateBoundingRect();
135     }
136
137     int margin() const
138     { return m_margin; }
139
140     void draw(QPainter *painter)
141     {
142         ++numRepaints;
143         if (doNothingInDraw)
144             return;
145         m_source = source();
146         m_painter = painter;
147         m_styleOption = source()->styleOption();
148         m_opacity = painter->opacity();
149         drawSource(painter);
150     }
151
152     void sourceChanged(QGraphicsEffect::ChangeFlags flags)
153     { m_sourceChangedFlags |= flags; }
154
155     int numRepaints;
156     int m_margin;
157     QGraphicsEffect::ChangeFlags m_sourceChangedFlags;
158     bool doNothingInDraw;
159     QPainter *m_painter;
160     const QStyleOption *m_styleOption;
161     QGraphicsEffectSource *m_source;
162     qreal m_opacity;
163 };
164
165 void tst_QGraphicsEffect::setEnabled()
166 {
167     CustomEffect effect;
168     QVERIFY(effect.isEnabled());
169
170     effect.setEnabled(false);
171     QVERIFY(!effect.isEnabled());
172 }
173
174 void tst_QGraphicsEffect::source()
175 {
176     QPointer<CustomEffect> effect = new CustomEffect;
177     QVERIFY(!effect->source());
178     QVERIFY(!effect->m_sourceChangedFlags);
179
180     // Install effect on QGraphicsItem.
181     QGraphicsItem *item = new QGraphicsRectItem(0, 0, 10, 10);
182     item->setGraphicsEffect(effect);
183     QVERIFY(effect->source());
184     QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
185     QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceAttached);
186     effect->reset();
187
188     // Make sure disabling/enabling the effect doesn't change the source.
189     effect->setEnabled(false);
190     QVERIFY(effect->source());
191     QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
192     QVERIFY(!effect->m_sourceChangedFlags);
193     effect->reset();
194
195     effect->setEnabled(true);
196     QVERIFY(effect->source());
197     QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
198     QVERIFY(!effect->m_sourceChangedFlags);
199     effect->reset();
200
201     // Uninstall effect on QGraphicsItem.
202     effect->reset();
203     item->setGraphicsEffect(0);
204     QVERIFY(!effect);
205     effect = new CustomEffect;
206
207     // The item takes ownership and should delete the effect when destroyed.
208     item->setGraphicsEffect(effect);
209     QPointer<QGraphicsEffectSource> source = effect->source();
210     QVERIFY(source);
211     QCOMPARE(source->graphicsItem(), (const QGraphicsItem*)item);
212     delete item;
213     QVERIFY(!effect);
214     QVERIFY(!source);
215 }
216
217 void tst_QGraphicsEffect::boundingRectFor()
218 {
219     CustomEffect effect;
220     int margin = effect.margin();
221     const QRectF source(0, 0, 100, 100);
222     QCOMPARE(effect.boundingRectFor(source), source.adjusted(-margin, -margin, margin, margin));
223
224     effect.setMargin(margin = 20);
225     QCOMPARE(effect.boundingRectFor(source), source.adjusted(-margin, -margin, margin, margin));
226 }
227
228 void tst_QGraphicsEffect::boundingRect()
229 {
230     // No source; empty bounding rect.
231     CustomEffect *effect = new CustomEffect;
232     QCOMPARE(effect->boundingRect(), QRectF());
233
234     // Install effect on QGraphicsItem.
235     QRectF itemRect(0, 0, 100, 100);
236     QGraphicsRectItem *item = new QGraphicsRectItem;
237     item->setRect(itemRect);
238     item->setGraphicsEffect(effect);
239     int margin = effect->margin();
240     QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
241     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
242
243     // Make sure disabling/enabling the effect doesn't change the bounding rect.
244     effect->setEnabled(false);
245     QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
246     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
247     effect->setEnabled(true);
248     QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
249     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
250
251     // Change effect margins.
252     effect->setMargin(margin = 20);
253     QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
254     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
255
256     // Uninstall effect on QGraphicsItem.
257     QPointer<CustomEffect> ptr = effect;
258     item->setGraphicsEffect(0);
259     QVERIFY(!ptr);
260
261     delete item;
262 }
263
264 void tst_QGraphicsEffect::boundingRect2()
265 {
266     CustomEffect *effect = new CustomEffect;
267     QGraphicsRectItem *root = new QGraphicsRectItem;
268     root->setGraphicsEffect(effect);
269
270     QGraphicsRectItem *child = new QGraphicsRectItem;
271     QRectF childRect(0, 0, 100, 100);
272     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
273     child->setRect(childRect);
274     child->setParentItem(root);
275
276     QGraphicsRectItem *grandChild = new QGraphicsRectItem;
277     QRectF grandChildRect(0, 0, 200, 200);
278     grandChild->setRect(grandChildRect);
279     grandChild->setParentItem(child);
280
281     // Make sure the effect's bounding rect is clipped to the child's bounding rect.
282     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
283
284     // Disable ItemClipsChildrenToShape; effect's bounding rect is no longer clipped.
285     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
286     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
287
288     // Add root item to a scene, do the same tests as above. Results should be the same.
289     QGraphicsScene scene;
290     scene.addItem(root);
291
292     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
293     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
294
295     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
296     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
297
298     // Now add the scene to a view, results should be the same.
299     QGraphicsView view(&scene);
300
301     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
302     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
303
304     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
305     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
306
307     CustomEffect *childEffect = new CustomEffect;
308     child->setGraphicsEffect(childEffect);
309     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childEffect->boundingRectFor(childRect | grandChildRect)));
310
311     child->setGraphicsEffect(0);
312     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
313 }
314
315 void tst_QGraphicsEffect::draw()
316 {
317     QGraphicsScene scene;
318     CustomItem *item = new CustomItem(0, 0, 100, 100);
319     scene.addItem(item);
320
321     QGraphicsView view(&scene);
322     view.show();
323     QVERIFY(QTest::qWaitForWindowActive(&view));
324     QTRY_VERIFY(item->numRepaints > 0);
325     item->reset();
326
327     // Make sure installing the effect triggers a repaint.
328     CustomEffect *effect = new CustomEffect;
329     item->setGraphicsEffect(effect);
330     QTRY_COMPARE(effect->numRepaints, 1);
331     QTRY_COMPARE(item->numRepaints, 1);
332
333     // Make sure QPainter* and QStyleOptionGraphicsItem* stays persistent
334     // during QGraphicsEffect::draw/QGraphicsItem::paint.
335     QVERIFY(effect->m_painter);
336     QCOMPARE(effect->m_painter, item->m_painter);
337     QCOMPARE(effect->m_styleOption, item->m_styleOption);
338     // Make sure QGraphicsEffect::source is persistent.
339     QCOMPARE(effect->m_source, effect->source());
340     effect->reset();
341     item->reset();
342
343     // Make sure updating the source triggers a repaint.
344     item->update();
345     QTRY_COMPARE(effect->numRepaints, 1);
346     QTRY_COMPARE(item->numRepaints, 1);
347     QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceInvalidated);
348     effect->reset();
349     item->reset();
350
351     // Make sure changing the effect's bounding rect triggers a repaint.
352     effect->setMargin(20);
353     QTRY_COMPARE(effect->numRepaints, 1);
354     QTRY_COMPARE(item->numRepaints, 1);
355     effect->reset();
356     item->reset();
357
358     // Make sure change the item's bounding rect triggers a repaint.
359     item->setRect(0, 0, 50, 50);
360     QTRY_COMPARE(effect->numRepaints, 1);
361     QTRY_COMPARE(item->numRepaints, 1);
362     QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceBoundingRectChanged);
363     effect->reset();
364     item->reset();
365
366     // Make sure the effect is the one to issue a repaint of the item.
367     effect->doNothingInDraw = true;
368     item->update();
369     QTRY_COMPARE(effect->numRepaints, 1);
370     QCOMPARE(item->numRepaints, 0);
371     effect->doNothingInDraw = false;
372     effect->reset();
373     item->reset();
374
375     // Make sure we update the source when disabling/enabling the effect.
376     effect->setEnabled(false);
377     QTest::qWait(50);
378     QCOMPARE(effect->numRepaints, 0);
379     QCOMPARE(item->numRepaints, 1);
380     effect->reset();
381     item->reset();
382
383     effect->setEnabled(true);
384     QTRY_COMPARE(effect->numRepaints, 1);
385     QTRY_COMPARE(item->numRepaints, 1);
386     effect->reset();
387     item->reset();
388
389     // Effect is already enabled; nothing should happen.
390     effect->setEnabled(true);
391     QTest::qWait(50);
392     QCOMPARE(effect->numRepaints, 0);
393     QCOMPARE(item->numRepaints, 0);
394
395     // Make sure uninstalling an effect triggers a repaint.
396     QPointer<CustomEffect> ptr = effect;
397     item->setGraphicsEffect(0);
398     QVERIFY(!ptr);
399     QTRY_COMPARE(item->numRepaints, 1);
400 }
401
402 void tst_QGraphicsEffect::opacity()
403 {
404     // Make sure the painter's opacity is correct in QGraphicsEffect::draw.
405     QGraphicsScene scene;
406     CustomItem *item = new CustomItem(0, 0, 100, 100);
407     item->setOpacity(0.5);
408     CustomEffect *effect = new CustomEffect;
409     item->setGraphicsEffect(effect);
410     scene.addItem(item);
411
412     QGraphicsView view(&scene);
413     view.show();
414     QVERIFY(QTest::qWaitForWindowExposed(&view));
415     QTRY_VERIFY(effect->numRepaints > 0);
416     QCOMPARE(effect->m_opacity, qreal(0.5));
417 }
418
419 void tst_QGraphicsEffect::grayscale()
420 {
421     if (qApp->desktop()->depth() < 24)
422         QSKIP("Test only works on 32 bit displays");
423
424     QGraphicsScene scene(0, 0, 100, 100);
425
426     QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
427     item->setPen(Qt::NoPen);
428     item->setBrush(QColor(122, 193, 66)); // Qt light green
429
430     QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
431     effect->setColor(Qt::black);
432     item->setGraphicsEffect(effect);
433
434     QPainter painter;
435     QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
436
437     image.fill(0);
438     painter.begin(&image);
439     painter.setRenderHint(QPainter::Antialiasing);
440     scene.render(&painter);
441     painter.end();
442
443     QCOMPARE(image.pixel(10, 10), qRgb(148, 148, 148));
444
445     effect->setStrength(0.5);
446
447     image.fill(0);
448     painter.begin(&image);
449     painter.setRenderHint(QPainter::Antialiasing);
450     scene.render(&painter);
451     painter.end();
452
453     QCOMPARE(image.pixel(10, 10), qRgb(135, 171, 107));
454
455     effect->setStrength(0.0);
456
457     image.fill(0);
458     painter.begin(&image);
459     painter.setRenderHint(QPainter::Antialiasing);
460     scene.render(&painter);
461     painter.end();
462
463     QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
464 }
465
466 void tst_QGraphicsEffect::colorize()
467 {
468     if (qApp->desktop()->depth() < 24)
469         QSKIP("Test only works on 32 bit displays");
470
471     QGraphicsScene scene(0, 0, 100, 100);
472
473     QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
474     item->setPen(Qt::NoPen);
475     item->setBrush(QColor(122, 193, 66)); // Qt light green
476
477     QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
478     effect->setColor(QColor(102, 153, 51)); // Qt dark green
479     item->setGraphicsEffect(effect);
480
481     QPainter painter;
482     QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
483
484     image.fill(0);
485     painter.begin(&image);
486     painter.setRenderHint(QPainter::Antialiasing);
487     scene.render(&painter);
488     painter.end();
489
490     QCOMPARE(image.pixel(10, 10), qRgb(191, 212, 169));
491
492     effect->setStrength(0.5);
493
494     image.fill(0);
495     painter.begin(&image);
496     painter.setRenderHint(QPainter::Antialiasing);
497     scene.render(&painter);
498     painter.end();
499
500     QCOMPARE(image.pixel(10, 10), qRgb(156, 203, 117));
501
502     effect->setStrength(0.0);
503
504     image.fill(0);
505     painter.begin(&image);
506     painter.setRenderHint(QPainter::Antialiasing);
507     scene.render(&painter);
508     painter.end();
509
510     QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
511 }
512
513 class PixmapItemEffect : public QGraphicsEffect
514 {
515 public:
516     PixmapItemEffect(const QPixmap &source)
517         : QGraphicsEffect()
518         , pixmap(source)
519         , repaints(0)
520     {}
521
522     QRectF boundingRectFor(const QRectF &rect) const
523     { return rect; }
524
525     void draw(QPainter *painter)
526     {
527         QVERIFY(sourcePixmap(Qt::LogicalCoordinates).handle() == pixmap.handle());
528         QVERIFY((painter->worldTransform().type() <= QTransform::TxTranslate) == (sourcePixmap(Qt::DeviceCoordinates).handle() == pixmap.handle()));
529
530         ++repaints;
531     }
532     QPixmap pixmap;
533     int repaints;
534 };
535
536 void tst_QGraphicsEffect::drawPixmapItem()
537 {
538     QImage image(32, 32, QImage::Format_RGB32);
539     QPainter p(&image);
540     p.fillRect(0, 0, 32, 16, Qt::blue);
541     p.fillRect(0, 16, 32, 16, Qt::red);
542     p.end();
543
544     QGraphicsScene scene;
545     QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap::fromImage(image));
546     scene.addItem(item);
547
548     PixmapItemEffect *effect = new PixmapItemEffect(item->pixmap());
549     item->setGraphicsEffect(effect);
550
551     QGraphicsView view(&scene);
552     view.show();
553     QVERIFY(QTest::qWaitForWindowExposed(&view));
554     QTRY_VERIFY(effect->repaints >= 1);
555
556     item->rotate(180);
557
558     QTRY_VERIFY(effect->repaints >= 2);
559 }
560
561 class DeviceEffect : public QGraphicsEffect
562 {
563 public:
564     QRectF boundingRectFor(const QRectF &rect) const
565     { return rect; }
566
567     void draw(QPainter *painter)
568     {
569         QPoint offset;
570         QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, QGraphicsEffect::NoPad);
571
572         if (pixmap.isNull())
573             return;
574
575         painter->save();
576         painter->setWorldTransform(QTransform());
577         painter->drawPixmap(offset, pixmap);
578         painter->restore();
579     }
580 };
581
582 void tst_QGraphicsEffect::deviceCoordinateTranslateCaching()
583 {
584     QGraphicsScene scene;
585     CustomItem *item = new CustomItem(0, 0, 10, 10);
586     scene.addItem(item);
587     scene.setSceneRect(0, 0, 50, 0);
588
589     item->setGraphicsEffect(new DeviceEffect);
590     item->setPen(Qt::NoPen);
591     item->setBrush(Qt::red);
592
593     QGraphicsView view(&scene);
594     view.show();
595     QVERIFY(QTest::qWaitForWindowExposed(&view));
596
597     QTRY_VERIFY(item->numRepaints >= 1);
598     int numRepaints = item->numRepaints;
599
600     item->translate(10, 0);
601
602     QTRY_VERIFY(item->numRepaints == numRepaints);
603 }
604
605 void tst_QGraphicsEffect::inheritOpacity()
606 {
607     QGraphicsScene scene;
608     QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 10, 10);
609     CustomItem *item = new CustomItem(0, 0, 10, 10, rectItem);
610
611     scene.addItem(rectItem);
612
613     item->setGraphicsEffect(new DeviceEffect);
614     item->setPen(Qt::NoPen);
615     item->setBrush(Qt::red);
616
617     rectItem->setOpacity(0.5);
618
619     QGraphicsView view(&scene);
620     view.show();
621     QVERIFY(QTest::qWaitForWindowExposed(&view));
622
623     QTRY_VERIFY(item->numRepaints >= 1);
624
625     int numRepaints = item->numRepaints;
626
627     rectItem->setOpacity(1);
628
629     // item should have been rerendered due to opacity changing
630     QTRY_VERIFY(item->numRepaints > numRepaints);
631 }
632
633 void tst_QGraphicsEffect::dropShadowClipping()
634 {
635     QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
636     img.fill(0xffffffff);
637
638     QGraphicsScene scene;
639     QGraphicsRectItem *item = new QGraphicsRectItem(-5, -500, 10, 1000);
640     item->setGraphicsEffect(new QGraphicsDropShadowEffect);
641     item->setPen(Qt::NoPen);
642     item->setBrush(Qt::red);
643
644     scene.addItem(item);
645
646     QPainter p(&img);
647     scene.render(&p, img.rect(), QRect(-64, -64, 128, 128));
648     p.end();
649
650     for (int y = 1; y < img.height(); ++y)
651         for (int x = 0; x < img.width(); ++x)
652             QCOMPARE(img.pixel(x, y), img.pixel(x, y-1));
653 }
654
655 class MyGraphicsItem : public QGraphicsWidget
656 {
657 public:
658     MyGraphicsItem(QGraphicsItem *parent = 0) :
659             QGraphicsWidget(parent), nbPaint(0)
660     {}
661     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
662     {
663         nbPaint++;
664         QGraphicsWidget::paint(painter, option, widget);
665     }
666     int nbPaint;
667 };
668
669 void tst_QGraphicsEffect::childrenVisibilityShouldInvalidateCache()
670 {
671     QGraphicsScene scene;
672     MyGraphicsItem parent;
673     parent.resize(200, 200);
674     QGraphicsWidget child(&parent);
675     child.resize(200, 200);
676     child.setVisible(false);
677     scene.addItem(&parent);
678     QGraphicsView view(&scene);
679     view.show();
680     QApplication::setActiveWindow(&view);
681     QVERIFY(QTest::qWaitForWindowActive(&view));
682     QTRY_VERIFY(parent.nbPaint >= 1);
683     //we set an effect on the parent
684     parent.setGraphicsEffect(new QGraphicsDropShadowEffect(&parent));
685     //flush the events
686     QApplication::processEvents();
687     //new effect applied->repaint
688     QVERIFY(parent.nbPaint >= 2);
689     child.setVisible(true);
690     //flush the events
691     QApplication::processEvents();
692     //a new child appears we need to redraw the effect.
693     QVERIFY(parent.nbPaint >= 3);
694 }
695
696 void tst_QGraphicsEffect::prepareGeometryChangeInvalidateCache()
697 {
698     MyGraphicsItem *item = new MyGraphicsItem;
699     item->resize(200, 200);
700
701     QGraphicsScene scene;
702     scene.addItem(item);
703
704     QGraphicsView view(&scene);
705     view.show();
706     qApp->setActiveWindow(&view);
707     QVERIFY(QTest::qWaitForWindowActive(&view));
708     QTRY_VERIFY(item->nbPaint >= 1);
709
710     item->nbPaint = 0;
711     item->setGraphicsEffect(new QGraphicsDropShadowEffect);
712     QTRY_COMPARE(item->nbPaint, 1);
713
714     item->nbPaint = 0;
715     item->resize(300, 300);
716     QTRY_COMPARE(item->nbPaint, 1);
717
718     item->nbPaint = 0;
719     item->setPos(item->pos() + QPointF(10, 10));
720     QTest::qWait(50);
721     QCOMPARE(item->nbPaint, 0);
722 }
723
724 void tst_QGraphicsEffect::itemHasNoContents()
725 {
726     QGraphicsRectItem *parent = new QGraphicsRectItem;
727     parent->setFlag(QGraphicsItem::ItemHasNoContents);
728
729     MyGraphicsItem *child = new MyGraphicsItem;
730     child->setParentItem(parent);
731     child->resize(200, 200);
732
733     QGraphicsScene scene;
734     scene.addItem(parent);
735
736     QGraphicsView view(&scene);
737     view.show();
738     qApp->setActiveWindow(&view);
739     QVERIFY(QTest::qWaitForWindowActive(&view));
740     QTRY_VERIFY(child->nbPaint >= 1);
741
742     CustomEffect *effect = new CustomEffect;
743     parent->setGraphicsEffect(effect);
744     QTRY_COMPARE(effect->numRepaints, 1);
745
746     for (int i = 0; i < 3; ++i) {
747         effect->reset();
748         effect->update();
749         QTRY_COMPARE(effect->numRepaints, 1);
750     }
751 }
752
753 QTEST_MAIN(tst_QGraphicsEffect)
754 #include "tst_qgraphicseffect.moc"
755