Make QPen default to 1-width non-cosmetic.
[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->setPen(QPen(Qt::black, 0));
238     item->setRect(itemRect);
239     item->setGraphicsEffect(effect);
240     int margin = effect->margin();
241     QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
242     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
243
244     // Make sure disabling/enabling the effect doesn't change the bounding rect.
245     effect->setEnabled(false);
246     QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
247     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
248     effect->setEnabled(true);
249     QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
250     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
251
252     // Change effect margins.
253     effect->setMargin(margin = 20);
254     QCOMPARE(effect->boundingRect(), itemRect.adjusted(-margin, -margin, margin, margin));
255     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect));
256
257     // Uninstall effect on QGraphicsItem.
258     QPointer<CustomEffect> ptr = effect;
259     item->setGraphicsEffect(0);
260     QVERIFY(!ptr);
261
262     delete item;
263 }
264
265 void tst_QGraphicsEffect::boundingRect2()
266 {
267     CustomEffect *effect = new CustomEffect;
268     QGraphicsRectItem *root = new QGraphicsRectItem;
269     root->setPen(QPen(Qt::black, 0));
270     root->setGraphicsEffect(effect);
271
272     QGraphicsRectItem *child = new QGraphicsRectItem;
273     QRectF childRect(0, 0, 100, 100);
274     child->setPen(QPen(Qt::black, 0));
275     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
276     child->setRect(childRect);
277     child->setParentItem(root);
278
279     QGraphicsRectItem *grandChild = new QGraphicsRectItem;
280     QRectF grandChildRect(0, 0, 200, 200);
281     grandChild->setPen(QPen(Qt::black, 0));
282     grandChild->setRect(grandChildRect);
283     grandChild->setParentItem(child);
284
285     // Make sure the effect's bounding rect is clipped to the child's bounding rect.
286     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
287
288     // Disable ItemClipsChildrenToShape; effect's bounding rect is no longer clipped.
289     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
290     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
291
292     // Add root item to a scene, do the same tests as above. Results should be the same.
293     QGraphicsScene scene;
294     scene.addItem(root);
295
296     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
297     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
298
299     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
300     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
301
302     // Now add the scene to a view, results should be the same.
303     QGraphicsView view(&scene);
304
305     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
306     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect));
307
308     child->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
309     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
310
311     CustomEffect *childEffect = new CustomEffect;
312     child->setGraphicsEffect(childEffect);
313     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childEffect->boundingRectFor(childRect | grandChildRect)));
314
315     child->setGraphicsEffect(0);
316     QCOMPARE(effect->boundingRect(), effect->boundingRectFor(childRect | grandChildRect));
317 }
318
319 void tst_QGraphicsEffect::draw()
320 {
321     QGraphicsScene scene;
322     CustomItem *item = new CustomItem(0, 0, 100, 100);
323     scene.addItem(item);
324
325     QGraphicsView view(&scene);
326     view.show();
327     QVERIFY(QTest::qWaitForWindowActive(&view));
328     QTRY_VERIFY(item->numRepaints > 0);
329     item->reset();
330
331     // Make sure installing the effect triggers a repaint.
332     CustomEffect *effect = new CustomEffect;
333     item->setGraphicsEffect(effect);
334     QTRY_COMPARE(effect->numRepaints, 1);
335     QTRY_COMPARE(item->numRepaints, 1);
336
337     // Make sure QPainter* and QStyleOptionGraphicsItem* stays persistent
338     // during QGraphicsEffect::draw/QGraphicsItem::paint.
339     QVERIFY(effect->m_painter);
340     QCOMPARE(effect->m_painter, item->m_painter);
341     QCOMPARE(effect->m_styleOption, item->m_styleOption);
342     // Make sure QGraphicsEffect::source is persistent.
343     QCOMPARE(effect->m_source, effect->source());
344     effect->reset();
345     item->reset();
346
347     // Make sure updating the source triggers a repaint.
348     item->update();
349     QTRY_COMPARE(effect->numRepaints, 1);
350     QTRY_COMPARE(item->numRepaints, 1);
351     QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceInvalidated);
352     effect->reset();
353     item->reset();
354
355     // Make sure changing the effect's bounding rect triggers a repaint.
356     effect->setMargin(20);
357     QTRY_COMPARE(effect->numRepaints, 1);
358     QTRY_COMPARE(item->numRepaints, 1);
359     effect->reset();
360     item->reset();
361
362     // Make sure change the item's bounding rect triggers a repaint.
363     item->setRect(0, 0, 50, 50);
364     QTRY_COMPARE(effect->numRepaints, 1);
365     QTRY_COMPARE(item->numRepaints, 1);
366     QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceBoundingRectChanged);
367     effect->reset();
368     item->reset();
369
370     // Make sure the effect is the one to issue a repaint of the item.
371     effect->doNothingInDraw = true;
372     item->update();
373     QTRY_COMPARE(effect->numRepaints, 1);
374     QCOMPARE(item->numRepaints, 0);
375     effect->doNothingInDraw = false;
376     effect->reset();
377     item->reset();
378
379     // Make sure we update the source when disabling/enabling the effect.
380     effect->setEnabled(false);
381     QTest::qWait(50);
382     QCOMPARE(effect->numRepaints, 0);
383     QCOMPARE(item->numRepaints, 1);
384     effect->reset();
385     item->reset();
386
387     effect->setEnabled(true);
388     QTRY_COMPARE(effect->numRepaints, 1);
389     QTRY_COMPARE(item->numRepaints, 1);
390     effect->reset();
391     item->reset();
392
393     // Effect is already enabled; nothing should happen.
394     effect->setEnabled(true);
395     QTest::qWait(50);
396     QCOMPARE(effect->numRepaints, 0);
397     QCOMPARE(item->numRepaints, 0);
398
399     // Make sure uninstalling an effect triggers a repaint.
400     QPointer<CustomEffect> ptr = effect;
401     item->setGraphicsEffect(0);
402     QVERIFY(!ptr);
403     QTRY_COMPARE(item->numRepaints, 1);
404 }
405
406 void tst_QGraphicsEffect::opacity()
407 {
408     // Make sure the painter's opacity is correct in QGraphicsEffect::draw.
409     QGraphicsScene scene;
410     CustomItem *item = new CustomItem(0, 0, 100, 100);
411     item->setOpacity(0.5);
412     CustomEffect *effect = new CustomEffect;
413     item->setGraphicsEffect(effect);
414     scene.addItem(item);
415
416     QGraphicsView view(&scene);
417     view.show();
418     QVERIFY(QTest::qWaitForWindowExposed(&view));
419     QTRY_VERIFY(effect->numRepaints > 0);
420     QCOMPARE(effect->m_opacity, qreal(0.5));
421 }
422
423 void tst_QGraphicsEffect::grayscale()
424 {
425     if (qApp->desktop()->depth() < 24)
426         QSKIP("Test only works on 32 bit displays");
427
428     QGraphicsScene scene(0, 0, 100, 100);
429
430     QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
431     item->setPen(Qt::NoPen);
432     item->setBrush(QColor(122, 193, 66)); // Qt light green
433
434     QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
435     effect->setColor(Qt::black);
436     item->setGraphicsEffect(effect);
437
438     QPainter painter;
439     QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
440
441     image.fill(0);
442     painter.begin(&image);
443     painter.setRenderHint(QPainter::Antialiasing);
444     scene.render(&painter);
445     painter.end();
446
447     QCOMPARE(image.pixel(10, 10), qRgb(148, 148, 148));
448
449     effect->setStrength(0.5);
450
451     image.fill(0);
452     painter.begin(&image);
453     painter.setRenderHint(QPainter::Antialiasing);
454     scene.render(&painter);
455     painter.end();
456
457     QCOMPARE(image.pixel(10, 10), qRgb(135, 171, 107));
458
459     effect->setStrength(0.0);
460
461     image.fill(0);
462     painter.begin(&image);
463     painter.setRenderHint(QPainter::Antialiasing);
464     scene.render(&painter);
465     painter.end();
466
467     QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
468 }
469
470 void tst_QGraphicsEffect::colorize()
471 {
472     if (qApp->desktop()->depth() < 24)
473         QSKIP("Test only works on 32 bit displays");
474
475     QGraphicsScene scene(0, 0, 100, 100);
476
477     QGraphicsRectItem *item = scene.addRect(0, 0, 50, 50);
478     item->setPen(Qt::NoPen);
479     item->setBrush(QColor(122, 193, 66)); // Qt light green
480
481     QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect;
482     effect->setColor(QColor(102, 153, 51)); // Qt dark green
483     item->setGraphicsEffect(effect);
484
485     QPainter painter;
486     QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
487
488     image.fill(0);
489     painter.begin(&image);
490     painter.setRenderHint(QPainter::Antialiasing);
491     scene.render(&painter);
492     painter.end();
493
494     QCOMPARE(image.pixel(10, 10), qRgb(191, 212, 169));
495
496     effect->setStrength(0.5);
497
498     image.fill(0);
499     painter.begin(&image);
500     painter.setRenderHint(QPainter::Antialiasing);
501     scene.render(&painter);
502     painter.end();
503
504     QCOMPARE(image.pixel(10, 10), qRgb(156, 203, 117));
505
506     effect->setStrength(0.0);
507
508     image.fill(0);
509     painter.begin(&image);
510     painter.setRenderHint(QPainter::Antialiasing);
511     scene.render(&painter);
512     painter.end();
513
514     QCOMPARE(image.pixel(10, 10), qRgb(122, 193, 66));
515 }
516
517 class PixmapItemEffect : public QGraphicsEffect
518 {
519 public:
520     PixmapItemEffect(const QPixmap &source)
521         : QGraphicsEffect()
522         , pixmap(source)
523         , repaints(0)
524     {}
525
526     QRectF boundingRectFor(const QRectF &rect) const
527     { return rect; }
528
529     void draw(QPainter *painter)
530     {
531         QVERIFY(sourcePixmap(Qt::LogicalCoordinates).handle() == pixmap.handle());
532         QVERIFY((painter->worldTransform().type() <= QTransform::TxTranslate) == (sourcePixmap(Qt::DeviceCoordinates).handle() == pixmap.handle()));
533
534         ++repaints;
535     }
536     QPixmap pixmap;
537     int repaints;
538 };
539
540 void tst_QGraphicsEffect::drawPixmapItem()
541 {
542     QImage image(32, 32, QImage::Format_RGB32);
543     QPainter p(&image);
544     p.fillRect(0, 0, 32, 16, Qt::blue);
545     p.fillRect(0, 16, 32, 16, Qt::red);
546     p.end();
547
548     QGraphicsScene scene;
549     QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap::fromImage(image));
550     scene.addItem(item);
551
552     PixmapItemEffect *effect = new PixmapItemEffect(item->pixmap());
553     item->setGraphicsEffect(effect);
554
555     QGraphicsView view(&scene);
556     view.show();
557     QVERIFY(QTest::qWaitForWindowExposed(&view));
558     QTRY_VERIFY(effect->repaints >= 1);
559
560     item->rotate(180);
561
562     QTRY_VERIFY(effect->repaints >= 2);
563 }
564
565 class DeviceEffect : public QGraphicsEffect
566 {
567 public:
568     QRectF boundingRectFor(const QRectF &rect) const
569     { return rect; }
570
571     void draw(QPainter *painter)
572     {
573         QPoint offset;
574         QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, QGraphicsEffect::NoPad);
575
576         if (pixmap.isNull())
577             return;
578
579         painter->save();
580         painter->setWorldTransform(QTransform());
581         painter->drawPixmap(offset, pixmap);
582         painter->restore();
583     }
584 };
585
586 void tst_QGraphicsEffect::deviceCoordinateTranslateCaching()
587 {
588     QGraphicsScene scene;
589     CustomItem *item = new CustomItem(0, 0, 10, 10);
590     scene.addItem(item);
591     scene.setSceneRect(0, 0, 50, 0);
592
593     item->setGraphicsEffect(new DeviceEffect);
594     item->setPen(Qt::NoPen);
595     item->setBrush(Qt::red);
596
597     QGraphicsView view(&scene);
598     view.show();
599     QVERIFY(QTest::qWaitForWindowExposed(&view));
600
601     QTRY_VERIFY(item->numRepaints >= 1);
602     int numRepaints = item->numRepaints;
603
604     item->translate(10, 0);
605
606     QTRY_VERIFY(item->numRepaints == numRepaints);
607 }
608
609 void tst_QGraphicsEffect::inheritOpacity()
610 {
611     QGraphicsScene scene;
612     QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 10, 10);
613     CustomItem *item = new CustomItem(0, 0, 10, 10, rectItem);
614
615     scene.addItem(rectItem);
616
617     item->setGraphicsEffect(new DeviceEffect);
618     item->setPen(Qt::NoPen);
619     item->setBrush(Qt::red);
620
621     rectItem->setOpacity(0.5);
622
623     QGraphicsView view(&scene);
624     view.show();
625     QVERIFY(QTest::qWaitForWindowExposed(&view));
626
627     QTRY_VERIFY(item->numRepaints >= 1);
628
629     int numRepaints = item->numRepaints;
630
631     rectItem->setOpacity(1);
632
633     // item should have been rerendered due to opacity changing
634     QTRY_VERIFY(item->numRepaints > numRepaints);
635 }
636
637 void tst_QGraphicsEffect::dropShadowClipping()
638 {
639     QImage img(128, 128, QImage::Format_ARGB32_Premultiplied);
640     img.fill(0xffffffff);
641
642     QGraphicsScene scene;
643     QGraphicsRectItem *item = new QGraphicsRectItem(-5, -500, 10, 1000);
644     item->setGraphicsEffect(new QGraphicsDropShadowEffect);
645     item->setPen(Qt::NoPen);
646     item->setBrush(Qt::red);
647
648     scene.addItem(item);
649
650     QPainter p(&img);
651     scene.render(&p, img.rect(), QRect(-64, -64, 128, 128));
652     p.end();
653
654     for (int y = 1; y < img.height(); ++y)
655         for (int x = 0; x < img.width(); ++x)
656             QCOMPARE(img.pixel(x, y), img.pixel(x, y-1));
657 }
658
659 class MyGraphicsItem : public QGraphicsWidget
660 {
661 public:
662     MyGraphicsItem(QGraphicsItem *parent = 0) :
663             QGraphicsWidget(parent), nbPaint(0)
664     {}
665     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
666     {
667         nbPaint++;
668         QGraphicsWidget::paint(painter, option, widget);
669     }
670     int nbPaint;
671 };
672
673 void tst_QGraphicsEffect::childrenVisibilityShouldInvalidateCache()
674 {
675     QGraphicsScene scene;
676     MyGraphicsItem parent;
677     parent.resize(200, 200);
678     QGraphicsWidget child(&parent);
679     child.resize(200, 200);
680     child.setVisible(false);
681     scene.addItem(&parent);
682     QGraphicsView view(&scene);
683     view.show();
684     QApplication::setActiveWindow(&view);
685     QVERIFY(QTest::qWaitForWindowActive(&view));
686     QTRY_VERIFY(parent.nbPaint >= 1);
687     //we set an effect on the parent
688     parent.setGraphicsEffect(new QGraphicsDropShadowEffect(&parent));
689     //flush the events
690     QApplication::processEvents();
691     //new effect applied->repaint
692     QVERIFY(parent.nbPaint >= 2);
693     child.setVisible(true);
694     //flush the events
695     QApplication::processEvents();
696     //a new child appears we need to redraw the effect.
697     QVERIFY(parent.nbPaint >= 3);
698 }
699
700 void tst_QGraphicsEffect::prepareGeometryChangeInvalidateCache()
701 {
702     MyGraphicsItem *item = new MyGraphicsItem;
703     item->resize(200, 200);
704
705     QGraphicsScene scene;
706     scene.addItem(item);
707
708     QGraphicsView view(&scene);
709     view.show();
710     qApp->setActiveWindow(&view);
711     QVERIFY(QTest::qWaitForWindowActive(&view));
712     QTRY_VERIFY(item->nbPaint >= 1);
713
714     item->nbPaint = 0;
715     item->setGraphicsEffect(new QGraphicsDropShadowEffect);
716     QTRY_COMPARE(item->nbPaint, 1);
717
718     item->nbPaint = 0;
719     item->resize(300, 300);
720     QTRY_COMPARE(item->nbPaint, 1);
721
722     item->nbPaint = 0;
723     item->setPos(item->pos() + QPointF(10, 10));
724     QTest::qWait(50);
725     QCOMPARE(item->nbPaint, 0);
726 }
727
728 void tst_QGraphicsEffect::itemHasNoContents()
729 {
730     QGraphicsRectItem *parent = new QGraphicsRectItem;
731     parent->setFlag(QGraphicsItem::ItemHasNoContents);
732
733     MyGraphicsItem *child = new MyGraphicsItem;
734     child->setParentItem(parent);
735     child->resize(200, 200);
736
737     QGraphicsScene scene;
738     scene.addItem(parent);
739
740     QGraphicsView view(&scene);
741     view.show();
742     qApp->setActiveWindow(&view);
743     QVERIFY(QTest::qWaitForWindowActive(&view));
744     QTRY_VERIFY(child->nbPaint >= 1);
745
746     CustomEffect *effect = new CustomEffect;
747     parent->setGraphicsEffect(effect);
748     QTRY_COMPARE(effect->numRepaints, 1);
749
750     for (int i = 0; i < 3; ++i) {
751         effect->reset();
752         effect->update();
753         QTRY_COMPARE(effect->numRepaints, 1);
754     }
755 }
756
757 QTEST_MAIN(tst_QGraphicsEffect)
758 #include "tst_qgraphicseffect.moc"
759