70ebd3c8a789f510cc2e16e27d89d3c219ac719a
[profile/ivi/qtbase.git] / tests / auto / widgets / graphicsview / qgraphicssceneindex / tst_qgraphicssceneindex.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/QtTest>
44 #include <QtWidgets/qgraphicsscene.h>
45 #include <private/qgraphicsscenebsptreeindex_p.h>
46 #include <private/qgraphicssceneindex_p.h>
47 #include <private/qgraphicsscenelinearindex_p.h>
48
49 class tst_QGraphicsSceneIndex : public QObject
50 {
51     Q_OBJECT
52 public slots:
53     void initTestCase();
54
55 private slots:
56     void scatteredItems_data();
57     void scatteredItems();
58     void overlappedItems_data();
59     void overlappedItems();
60     void movingItems_data();
61     void movingItems();
62     void connectedToSceneRectChanged();
63     void items();
64     void removeItems();
65     void clear();
66
67 private:
68     void common_data();
69     QGraphicsSceneIndex *createIndex(const QString &name);
70 };
71
72 void tst_QGraphicsSceneIndex::initTestCase()
73 {
74 }
75
76 void tst_QGraphicsSceneIndex::common_data()
77 {
78     QTest::addColumn<QString>("indexMethod");
79
80     QTest::newRow("BSP") << QString("bsp");
81     QTest::newRow("Linear") << QString("linear");
82 }
83
84 QGraphicsSceneIndex *tst_QGraphicsSceneIndex::createIndex(const QString &indexMethod)
85 {
86     QGraphicsSceneIndex *index = 0;
87     QGraphicsScene *scene = new QGraphicsScene();
88     if (indexMethod == "bsp")
89         index = new QGraphicsSceneBspTreeIndex(scene);
90
91     if (indexMethod == "linear")
92         index = new QGraphicsSceneLinearIndex(scene);
93
94     return index;
95 }
96
97 void tst_QGraphicsSceneIndex::scatteredItems_data()
98 {
99     common_data();
100 }
101
102 void tst_QGraphicsSceneIndex::scatteredItems()
103 {
104     QFETCH(QString, indexMethod);
105
106     QGraphicsScene scene;
107     scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
108
109     for (int i = 0; i < 10; ++i)
110         scene.addRect(i*50, i*50, 40, 35);
111
112     QCOMPARE(scene.items(QPointF(5, 5)).count(), 1);
113     QCOMPARE(scene.items(QPointF(55, 55)).count(), 1);
114     QCOMPARE(scene.items(QPointF(-100, -100)).count(), 0);
115
116     QCOMPARE(scene.items(QRectF(0, 0, 10, 10)).count(), 1);
117     QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 10);
118     QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).count(), 0);
119 }
120
121 void tst_QGraphicsSceneIndex::overlappedItems_data()
122 {
123     common_data();
124 }
125
126 void tst_QGraphicsSceneIndex::overlappedItems()
127 {
128     QFETCH(QString, indexMethod);
129
130     QGraphicsScene scene;
131     scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
132
133     for (int i = 0; i < 10; ++i)
134         for (int j = 0; j < 10; ++j)
135             scene.addRect(i*50, j*50, 200, 200);
136
137     QCOMPARE(scene.items(QPointF(5, 5)).count(), 1);
138     QCOMPARE(scene.items(QPointF(55, 55)).count(), 4);
139     QCOMPARE(scene.items(QPointF(105, 105)).count(), 9);
140     QCOMPARE(scene.items(QPointF(-100, -100)).count(), 0);
141
142     QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 100);
143     QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).count(), 0);
144     QCOMPARE(scene.items(QRectF(0, 0, 200, 200)).count(), 16);
145     QCOMPARE(scene.items(QRectF(0, 0, 100, 100)).count(), 4);
146     QCOMPARE(scene.items(QRectF(0, 0, 1, 100)).count(), 2);
147     QCOMPARE(scene.items(QRectF(0, 0, 1, 1000)).count(), 10);
148 }
149
150 void tst_QGraphicsSceneIndex::movingItems_data()
151 {
152     common_data();
153 }
154
155 void tst_QGraphicsSceneIndex::movingItems()
156 {
157     QFETCH(QString, indexMethod);
158
159     QGraphicsScene scene;
160     scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
161
162     for (int i = 0; i < 10; ++i)
163         scene.addRect(i*50, i*50, 40, 35);
164
165     QGraphicsRectItem *box = scene.addRect(0, 0, 10, 10);
166     QCOMPARE(scene.items(QPointF(5, 5)).count(), 2);
167     QCOMPARE(scene.items(QPointF(-1, -1)).count(), 0);
168     QCOMPARE(scene.items(QRectF(0, 0, 5, 5)).count(), 2);
169
170     box->setPos(10, 10);
171     QCOMPARE(scene.items(QPointF(9, 9)).count(), 1);
172     QCOMPARE(scene.items(QPointF(15, 15)).count(), 2);
173     QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).count(), 1);
174
175     box->setPos(-5, -5);
176     QCOMPARE(scene.items(QPointF(-1, -1)).count(), 1);
177     QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).count(), 2);
178
179     QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 11);
180 }
181
182 void tst_QGraphicsSceneIndex::connectedToSceneRectChanged()
183 {
184
185     class MyScene : public QGraphicsScene
186     {
187     public:
188         using QGraphicsScene::receivers;
189     };
190
191     MyScene scene; // Uses QGraphicsSceneBspTreeIndex by default.
192     QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(QRectF))), 1);
193
194     scene.setItemIndexMethod(QGraphicsScene::NoIndex); // QGraphicsSceneLinearIndex
195     QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(QRectF))), 1);
196 }
197
198 void tst_QGraphicsSceneIndex::items()
199 {
200     QGraphicsScene scene;
201     QGraphicsItem *item1 = scene.addRect(0, 0, 10, 10);
202     QGraphicsItem *item2 = scene.addRect(10, 10, 10, 10);
203     QCOMPARE(scene.items().size(), 2);
204
205     // Move from unindexed items into bsp tree.
206     QTest::qWait(50);
207     QCOMPARE(scene.items().size(), 2);
208
209     // Add untransformable item.
210     QGraphicsItem *item3 = new QGraphicsRectItem(QRectF(20, 20, 10, 10));
211     item3->setFlag(QGraphicsItem::ItemIgnoresTransformations);
212     scene.addItem(item3);
213     QCOMPARE(scene.items().size(), 3);
214
215     // Move from unindexed items into untransformable items.
216     QTest::qWait(50);
217     QCOMPARE(scene.items().size(), 3);
218
219     // Move from untransformable items into unindexed items.
220     item3->setFlag(QGraphicsItem::ItemIgnoresTransformations, false);
221     QCOMPARE(scene.items().size(), 3);
222     QTest::qWait(50);
223     QCOMPARE(scene.items().size(), 3);
224
225     // Make all items untransformable.
226     item1->setFlag(QGraphicsItem::ItemIgnoresTransformations);
227     item2->setParentItem(item1);
228     item3->setParentItem(item2);
229     QCOMPARE(scene.items().size(), 3);
230
231     // Move from unindexed items into untransformable items.
232     QTest::qWait(50);
233     QCOMPARE(scene.items().size(), 3);
234 }
235
236 class RectWidget : public QGraphicsWidget
237 {
238     Q_OBJECT
239 public:
240     RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent)
241     {
242     }
243
244     void paint(QPainter *painter, const QStyleOptionGraphicsItem * /* option */, QWidget * /* widget */)
245     {
246         painter->setBrush(brush);
247         painter->drawRect(boundingRect());
248     }
249 public:
250     QBrush brush;
251 };
252
253 void tst_QGraphicsSceneIndex::removeItems()
254 {
255      QGraphicsScene scene;
256
257     RectWidget *parent = new RectWidget;
258     parent->brush = QBrush(QColor(Qt::magenta));
259     parent->setGeometry(250, 250, 400, 400);
260
261     RectWidget *widget = new RectWidget(parent);
262     widget->brush = QBrush(QColor(Qt::blue));
263     widget->setGeometry(10, 10, 200, 200);
264
265     RectWidget *widgetChild1 = new RectWidget(widget);
266     widgetChild1->brush = QBrush(QColor(Qt::green));
267     widgetChild1->setGeometry(20, 20, 100, 100);
268
269     RectWidget *widgetChild2 = new RectWidget(widgetChild1);
270     widgetChild2->brush = QBrush(QColor(Qt::yellow));
271     widgetChild2->setGeometry(25, 25, 50, 50);
272
273     scene.addItem(parent);
274
275     QGraphicsView view(&scene);
276     view.resize(600, 600);
277     view.show();
278     QApplication::setActiveWindow(&view);
279     QVERIFY(QTest::qWaitForWindowActive(&view));
280
281     scene.removeItem(widgetChild1);
282
283     delete widgetChild1;
284
285     //We move the parent
286     scene.items(295, 295, 50, 50);
287
288     //This should not crash
289 }
290
291 void tst_QGraphicsSceneIndex::clear()
292 {
293     class MyItem : public QGraphicsItem
294     {
295     public:
296         MyItem(QGraphicsItem *parent = 0) : QGraphicsItem(parent), numPaints(0) {}
297         int numPaints;
298     protected:
299         QRectF boundingRect() const { return QRectF(0, 0, 10, 10); }
300         void paint(QPainter * /* painter */, const QStyleOptionGraphicsItem *, QWidget *)
301         { ++numPaints; }
302     };
303
304     QGraphicsScene scene;
305     scene.setSceneRect(0, 0, 100, 100);
306     scene.addItem(new MyItem);
307
308     QGraphicsView view(&scene);
309     view.show();
310     QVERIFY(QTest::qWaitForWindowActive(&view));
311     qApp->setActiveWindow(&view);
312     scene.clear();
313
314     // Make sure the index is re-generated after QGraphicsScene::clear();
315     // otherwise no items will be painted.
316     MyItem *item = new MyItem;
317     scene.addItem(item);
318     qApp->processEvents();
319     QTRY_COMPARE(item->numPaints, 1);
320 }
321
322 QTEST_MAIN(tst_QGraphicsSceneIndex)
323 #include "tst_qgraphicssceneindex.moc"