Deactivating an inactive item should do (almost) nothing.
[qt:qt.git] / src / gui / graphicsview / qgraphicsscene.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 /*!
43     \class QGraphicsScene
44     \brief The QGraphicsScene class provides a surface for managing a large
45     number of 2D graphical items.
46     \since 4.2
47     \ingroup graphicsview-api
48
49
50     The class serves as a container for QGraphicsItems. It is used together
51     with QGraphicsView for visualizing graphical items, such as lines,
52     rectangles, text, or even custom items, on a 2D surface. QGraphicsScene is
53     part of the \l{Graphics View Framework}.
54
55     QGraphicsScene also provides functionality that lets you efficiently
56     determine both the location of items, and for determining what items are
57     visible within an arbitrary area on the scene. With the QGraphicsView
58     widget, you can either visualize the whole scene, or zoom in and view only
59     parts of the scene.
60
61     Example:
62
63     \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 0
64
65     Note that QGraphicsScene has no visual appearance of its own; it only
66     manages the items. You need to create a QGraphicsView widget to visualize
67     the scene.
68
69     To add items to a scene, you start off by constructing a QGraphicsScene
70     object. Then, you have two options: either add your existing QGraphicsItem
71     objects by calling addItem(), or you can call one of the convenience
72     functions addEllipse(), addLine(), addPath(), addPixmap(), addPolygon(),
73     addRect(), or addText(), which all return a pointer to the newly added item.
74     The dimensions of the items added with these functions are relative to the
75     item's coordinate system, and the items position is initialized to (0,
76     0) in the scene.
77
78     You can then visualize the scene using QGraphicsView. When the scene
79     changes, (e.g., when an item moves or is transformed) QGraphicsScene
80     emits the changed() signal. To remove an item, call removeItem().
81
82     QGraphicsScene uses an indexing algorithm to manage the location of items
83     efficiently. By default, a BSP (Binary Space Partitioning) tree is used; an
84     algorithm suitable for large scenes where most items remain static (i.e.,
85     do not move around). You can choose to disable this index by calling
86     setItemIndexMethod(). For more information about the available indexing
87     algorithms, see the itemIndexMethod property.
88
89     The scene's bounding rect is set by calling setSceneRect(). Items can be
90     placed at any position on the scene, and the size of the scene is by
91     default unlimited. The scene rect is used only for internal bookkeeping,
92     maintaining the scene's item index. If the scene rect is unset,
93     QGraphicsScene will use the bounding area of all items, as returned by
94     itemsBoundingRect(), as the scene rect. However, itemsBoundingRect() is a
95     relatively time consuming function, as it operates by collecting
96     positional information for every item on the scene. Because of this, you
97     should always set the scene rect when operating on large scenes.
98
99     One of QGraphicsScene's greatest strengths is its ability to efficiently
100     determine the location of items. Even with millions of items on the scene,
101     the items() functions can determine the location of an item within few
102     milliseconds. There are several overloads to items(): one that finds items
103     at a certain position, one that finds items inside or intersecting with a
104     polygon or a rectangle, and more. The list of returned items is sorted by
105     stacking order, with the topmost item being the first item in the list.
106     For convenience, there is also an itemAt() function that returns the
107     topmost item at a given position.
108
109     QGraphicsScene maintains selection information for the scene. To select
110     items, call setSelectionArea(), and to clear the current selection, call
111     clearSelection(). Call selectedItems() to get the list of all selected
112     items.
113
114     \section1 Event Handling and Propagation
115
116     Another responsibility that QGraphicsScene has, is to propagate events
117     from QGraphicsView. To send an event to a scene, you construct an event
118     that inherits QEvent, and then send it using, for example,
119     QApplication::sendEvent(). event() is responsible for dispatching
120     the event to the individual items. Some common events are handled by
121     convenience event handlers. For example, key press events are handled by
122     keyPressEvent(), and mouse press events are handled by mousePressEvent().
123
124     Key events are delivered to the \e {focus item}. To set the focus item,
125     you can either call setFocusItem(), passing an item that accepts focus, or
126     the item itself can call QGraphicsItem::setFocus().  Call focusItem() to
127     get the current focus item. For compatibility with widgets, the scene also
128     maintains its own focus information. By default, the scene does not have
129     focus, and all key events are discarded. If setFocus() is called, or if an
130     item on the scene gains focus, the scene automatically gains focus. If the
131     scene has focus, hasFocus() will return true, and key events will be
132     forwarded to the focus item, if any. If the scene loses focus, (i.e.,
133     someone calls clearFocus()) while an item has focus, the scene will
134     maintain its item focus information, and once the scene regains focus, it
135     will make sure the last focus item regains focus.
136
137     For mouse-over effects, QGraphicsScene dispatches \e {hover
138     events}. If an item accepts hover events (see
139     QGraphicsItem::acceptHoverEvents()), it will receive a \l
140     {QEvent::}{GraphicsSceneHoverEnter} event when the mouse enters
141     its area. As the mouse continues moving inside the item's area,
142     QGraphicsScene will send it \l {QEvent::}{GraphicsSceneHoverMove}
143     events. When the mouse leaves the item's area, the item will
144     receive a \l {QEvent::}{GraphicsSceneHoverLeave} event.
145
146     All mouse events are delivered to the current \e {mouse grabber}
147     item. An item becomes the scene's mouse grabber if it accepts
148     mouse events (see QGraphicsItem::acceptedMouseButtons()) and it
149     receives a mouse press. It stays the mouse grabber until it
150     receives a mouse release when no other mouse buttons are
151     pressed. You can call mouseGrabberItem() to determine what item is
152     currently grabbing the mouse.
153
154     \sa QGraphicsItem, QGraphicsView
155 */
156
157 /*!
158     \enum QGraphicsScene::SceneLayer
159     \since 4.3
160
161     This enum describes the rendering layers in a QGraphicsScene. When
162     QGraphicsScene draws the scene contents, it renders each of these layers
163     separately, in order.
164
165     Each layer represents a flag that can be OR'ed together when calling
166     functions such as invalidate() or QGraphicsView::invalidateScene().
167
168     \value ItemLayer The item layer. QGraphicsScene renders all items are in
169     this layer by calling the virtual function drawItems(). The item layer is
170     drawn after the background layer, but before the foreground layer.
171
172     \value BackgroundLayer The background layer. QGraphicsScene renders the
173     scene's background in this layer by calling the virtual function
174     drawBackground(). The background layer is drawn first of all layers.
175
176     \value ForegroundLayer The foreground layer. QGraphicsScene renders the
177     scene's foreground in this layer by calling the virtual function
178     drawForeground().  The foreground layer is drawn last of all layers.
179
180     \value AllLayers All layers; this value represents a combination of all
181     three layers.
182
183     \sa invalidate(), QGraphicsView::invalidateScene()
184 */
185
186 /*!
187     \enum QGraphicsScene::ItemIndexMethod
188
189     This enum describes the indexing algorithms QGraphicsScene provides for
190     managing positional information about items on the scene.
191
192     \value BspTreeIndex A Binary Space Partitioning tree is applied. All
193     QGraphicsScene's item location algorithms are of an order close to
194     logarithmic complexity, by making use of binary search. Adding, moving and
195     removing items is logarithmic. This approach is best for static scenes
196     (i.e., scenes where most items do not move).
197
198     \value NoIndex No index is applied. Item location is of linear complexity,
199     as all items on the scene are searched. Adding, moving and removing items,
200     however, is done in constant time. This approach is ideal for dynamic
201     scenes, where many items are added, moved or removed continuously.
202
203     \sa setItemIndexMethod(), bspTreeDepth
204 */
205
206 #include "qgraphicsscene.h"
207
208 #ifndef QT_NO_GRAPHICSVIEW
209
210 #include "qgraphicsitem.h"
211 #include "qgraphicsitem_p.h"
212 #include "qgraphicslayout.h"
213 #include "qgraphicsscene_p.h"
214 #include "qgraphicssceneevent.h"
215 #include "qgraphicsview.h"
216 #include "qgraphicsview_p.h"
217 #include "qgraphicswidget.h"
218 #include "qgraphicswidget_p.h"
219 #include "qgraphicssceneindex_p.h"
220 #include "qgraphicsscenebsptreeindex_p.h"
221 #include "qgraphicsscenelinearindex_p.h"
222
223 #include <QtCore/qdebug.h>
224 #include <QtCore/qlist.h>
225 #include <QtCore/qmath.h>
226 #include <QtCore/qrect.h>
227 #include <QtCore/qset.h>
228 #include <QtCore/qstack.h>
229 #include <QtCore/qtimer.h>
230 #include <QtCore/qvarlengtharray.h>
231 #include <QtCore/QMetaMethod>
232 #include <QtGui/qapplication.h>
233 #include <QtGui/qdesktopwidget.h>
234 #include <QtGui/qevent.h>
235 #include <QtGui/qgraphicslayout.h>
236 #include <QtGui/qgraphicsproxywidget.h>
237 #include <QtGui/qgraphicswidget.h>
238 #include <QtGui/qmatrix.h>
239 #include <QtGui/qpaintengine.h>
240 #include <QtGui/qpainter.h>
241 #include <QtGui/qpixmapcache.h>
242 #include <QtGui/qpolygon.h>
243 #include <QtGui/qstyleoption.h>
244 #include <QtGui/qtooltip.h>
245 #include <QtGui/qtransform.h>
246 #include <QtGui/qinputcontext.h>
247 #include <QtGui/qgraphicseffect.h>
248 #ifndef QT_NO_ACCESSIBILITY
249 # include <QtGui/qaccessible.h>
250 #endif
251
252 #include <private/qapplication_p.h>
253 #include <private/qobject_p.h>
254 #ifdef Q_WS_X11
255 #include <private/qt_x11_p.h>
256 #endif
257 #include <private/qgraphicseffect_p.h>
258 #include <private/qgesturemanager_p.h>
259 #include <private/qpathclipper_p.h>
260
261 // #define GESTURE_DEBUG
262 #ifndef GESTURE_DEBUG
263 # define DEBUG if (0) qDebug
264 #else
265 # define DEBUG qDebug
266 #endif
267
268 QT_BEGIN_NAMESPACE
269
270 bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
271
272 static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent)
273 {
274     hover->setWidget(mouseEvent->widget());
275     hover->setPos(mouseEvent->pos());
276     hover->setScenePos(mouseEvent->scenePos());
277     hover->setScreenPos(mouseEvent->screenPos());
278     hover->setLastPos(mouseEvent->lastPos());
279     hover->setLastScenePos(mouseEvent->lastScenePos());
280     hover->setLastScreenPos(mouseEvent->lastScreenPos());
281     hover->setModifiers(mouseEvent->modifiers());
282     hover->setAccepted(mouseEvent->isAccepted());
283 }
284
285 /*!
286     \internal
287 */
288 QGraphicsScenePrivate::QGraphicsScenePrivate()
289     : indexMethod(QGraphicsScene::BspTreeIndex),
290       index(0),
291       lastItemCount(0),
292       hasSceneRect(false),
293       dirtyGrowingItemsBoundingRect(true),
294       updateAll(false),
295       calledEmitUpdated(false),
296       processDirtyItemsEmitted(false),
297       needSortTopLevelItems(true),
298       holesInTopLevelSiblingIndex(false),
299       topLevelSequentialOrdering(true),
300       scenePosDescendantsUpdatePending(false),
301       stickyFocus(false),
302       hasFocus(false),
303       lastMouseGrabberItemHasImplicitMouseGrab(false),
304       allItemsIgnoreHoverEvents(true),
305       allItemsUseDefaultCursor(true),
306       painterStateProtection(true),
307       sortCacheEnabled(false),
308       allItemsIgnoreTouchEvents(true),
309       selectionChanging(0),
310       rectAdjust(2),
311       focusItem(0),
312       lastFocusItem(0),
313       passiveFocusItem(0),
314       tabFocusFirst(0),
315       activePanel(0),
316       lastActivePanel(0),
317       activationRefCount(0),
318       childExplicitActivation(0),
319       lastMouseGrabberItem(0),
320       dragDropItem(0),
321       enterWidget(0),
322       lastDropAction(Qt::IgnoreAction),
323       style(0)
324 {
325 }
326
327 /*!
328     \internal
329 */
330 void QGraphicsScenePrivate::init()
331 {
332     Q_Q(QGraphicsScene);
333
334     index = new QGraphicsSceneBspTreeIndex(q);
335
336     // Keep this index so we can check for connected slots later on.
337     changedSignalIndex = signalIndex("changed(QList<QRectF>)");
338     processDirtyItemsIndex = q->metaObject()->indexOfSlot("_q_processDirtyItems()");
339     polishItemsIndex = q->metaObject()->indexOfSlot("_q_polishItems()");
340
341     qApp->d_func()->scene_list.append(q);
342     q->update();
343 }
344
345 /*!
346     \internal
347 */
348 QGraphicsScenePrivate *QGraphicsScenePrivate::get(QGraphicsScene *q)
349 {
350     return q->d_func();
351 }
352
353 void QGraphicsScenePrivate::_q_emitUpdated()
354 {
355     Q_Q(QGraphicsScene);
356     calledEmitUpdated = false;
357
358     if (dirtyGrowingItemsBoundingRect) {
359         if (!hasSceneRect) {
360             const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
361             growingItemsBoundingRect |= q->itemsBoundingRect();
362             if (oldGrowingItemsBoundingRect != growingItemsBoundingRect)
363                 emit q->sceneRectChanged(growingItemsBoundingRect);
364         }
365         dirtyGrowingItemsBoundingRect = false;
366     }
367
368     // Ensure all views are connected if anything is connected. This disables
369     // the optimization that items send updates directly to the views, but it
370     // needs to happen in order to keep compatibility with the behavior from
371     // Qt 4.4 and backward.
372     if (isSignalConnected(changedSignalIndex)) {
373         for (int i = 0; i < views.size(); ++i) {
374             QGraphicsView *view = views.at(i);
375             if (!view->d_func()->connectedToScene) {
376                 view->d_func()->connectedToScene = true;
377                 q->connect(q, SIGNAL(changed(QList<QRectF>)),
378                            views.at(i), SLOT(updateScene(QList<QRectF>)));
379             }
380         }
381     } else {
382         if (views.isEmpty()) {
383             updateAll = false;
384             return;
385         }
386         for (int i = 0; i < views.size(); ++i)
387             views.at(i)->d_func()->processPendingUpdates();
388         // It's important that we update all views before we dispatch, hence two for-loops.
389         for (int i = 0; i < views.size(); ++i)
390             views.at(i)->d_func()->dispatchPendingUpdateRequests();
391         return;
392     }
393
394     // Notify the changes to anybody interested.
395     QList<QRectF> oldUpdatedRects;
396     oldUpdatedRects = updateAll ? (QList<QRectF>() << q->sceneRect()) : updatedRects;
397     updateAll = false;
398     updatedRects.clear();
399     emit q->changed(oldUpdatedRects);
400 }
401
402 /*!
403     \internal
404
405     ### This function is almost identical to QGraphicsItemPrivate::addChild().
406 */
407 void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item)
408 {
409     item->d_ptr->ensureSequentialSiblingIndex();
410     needSortTopLevelItems = true; // ### maybe false
411     item->d_ptr->siblingIndex = topLevelItems.size();
412     topLevelItems.append(item);
413 }
414
415 /*!
416     \internal
417
418     ### This function is almost identical to QGraphicsItemPrivate::removeChild().
419 */
420 void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
421 {
422     if (!holesInTopLevelSiblingIndex)
423         holesInTopLevelSiblingIndex = item->d_ptr->siblingIndex != topLevelItems.size() - 1;
424     if (topLevelSequentialOrdering && !holesInTopLevelSiblingIndex)
425         topLevelItems.removeAt(item->d_ptr->siblingIndex);
426     else
427         topLevelItems.removeOne(item);
428     // NB! Do not use topLevelItems.removeAt(item->d_ptr->siblingIndex) because
429     // the item is not guaranteed to be at the index after the list is sorted
430     // (see ensureSortedTopLevelItems()).
431     item->d_ptr->siblingIndex = -1;
432     if (topLevelSequentialOrdering)
433         topLevelSequentialOrdering = !holesInTopLevelSiblingIndex;
434 }
435
436 /*!
437     \internal
438 */
439 void QGraphicsScenePrivate::_q_polishItems()
440 {
441     if (unpolishedItems.isEmpty())
442         return;
443
444     const QVariant booleanTrueVariant(true);
445     QGraphicsItem *item = 0;
446     QGraphicsItemPrivate *itemd = 0;
447     const int oldUnpolishedCount = unpolishedItems.count();
448
449     for (int i = 0; i < oldUnpolishedCount; ++i) {
450         item = unpolishedItems.at(i);
451         if (!item)
452             continue;
453         itemd = item->d_ptr.data();
454         itemd->pendingPolish = false;
455         if (!itemd->explicitlyHidden) {
456             item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
457             item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
458         }
459         if (itemd->isWidget) {
460             QEvent event(QEvent::Polish);
461             QApplication::sendEvent((QGraphicsWidget *)item, &event);
462         }
463     }
464
465     if (unpolishedItems.count() == oldUnpolishedCount) {
466         // No new items were added to the vector.
467         unpolishedItems.clear();
468     } else {
469         // New items were appended; keep them and remove the old ones.
470         unpolishedItems.remove(0, oldUnpolishedCount);
471         unpolishedItems.squeeze();
472         QMetaObject::invokeMethod(q_ptr, "_q_polishItems", Qt::QueuedConnection);
473     }
474 }
475
476 void QGraphicsScenePrivate::_q_processDirtyItems()
477 {
478     processDirtyItemsEmitted = false;
479
480     if (updateAll) {
481         Q_ASSERT(calledEmitUpdated);
482         // No need for further processing (except resetting the dirty states).
483         // The growingItemsBoundingRect is updated in _q_emitUpdated.
484         for (int i = 0; i < topLevelItems.size(); ++i)
485             resetDirtyItem(topLevelItems.at(i), /*recursive=*/true);
486         return;
487     }
488
489     const bool wasPendingSceneUpdate = calledEmitUpdated;
490     const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
491
492     // Process items recursively.
493     for (int i = 0; i < topLevelItems.size(); ++i)
494         processDirtyItemsRecursive(topLevelItems.at(i));
495
496     dirtyGrowingItemsBoundingRect = false;
497     if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect)
498         emit q_func()->sceneRectChanged(growingItemsBoundingRect);
499
500     if (wasPendingSceneUpdate)
501         return;
502
503     for (int i = 0; i < views.size(); ++i)
504         views.at(i)->d_func()->processPendingUpdates();
505
506     if (calledEmitUpdated) {
507         // We did a compatibility QGraphicsScene::update in processDirtyItemsRecursive
508         // and we cannot wait for the control to reach the eventloop before the
509         // changed signal is emitted, so we emit it now.
510         _q_emitUpdated();
511     }
512
513     // Immediately dispatch all pending update requests on the views.
514     for (int i = 0; i < views.size(); ++i)
515         views.at(i)->d_func()->dispatchPendingUpdateRequests();
516 }
517
518 /*!
519     \internal
520 */
521 void QGraphicsScenePrivate::setScenePosItemEnabled(QGraphicsItem *item, bool enabled)
522 {
523     QGraphicsItem *p = item->d_ptr->parent;
524     while (p) {
525         p->d_ptr->scenePosDescendants = enabled;
526         p = p->d_ptr->parent;
527     }
528     if (!enabled && !scenePosDescendantsUpdatePending) {
529         scenePosDescendantsUpdatePending = true;
530         QMetaObject::invokeMethod(q_func(), "_q_updateScenePosDescendants", Qt::QueuedConnection);
531     }
532 }
533
534 /*!
535     \internal
536 */
537 void QGraphicsScenePrivate::registerScenePosItem(QGraphicsItem *item)
538 {
539     scenePosItems.insert(item);
540     setScenePosItemEnabled(item, true);
541 }
542
543 /*!
544     \internal
545 */
546 void QGraphicsScenePrivate::unregisterScenePosItem(QGraphicsItem *item)
547 {
548     scenePosItems.remove(item);
549     setScenePosItemEnabled(item, false);
550 }
551
552 /*!
553     \internal
554 */
555 void QGraphicsScenePrivate::_q_updateScenePosDescendants()
556 {
557     foreach (QGraphicsItem *item, scenePosItems) {
558         QGraphicsItem *p = item->d_ptr->parent;
559         while (p) {
560             p->d_ptr->scenePosDescendants = 1;
561             p = p->d_ptr->parent;
562         }
563     }
564     scenePosDescendantsUpdatePending = false;
565 }
566
567 /*!
568     \internal
569
570     Schedules an item for removal. This function leaves some stale indexes
571     around in the BSP tree if called from the item's destructor; these will
572     be cleaned up the next time someone triggers purgeRemovedItems().
573
574     Note: This function might get called from QGraphicsItem's destructor. \a item is
575     being destroyed, so we cannot call any pure virtual functions on it (such
576     as boundingRect()). Also, it is unnecessary to update the item's own state
577     in any way.
578 */
579 void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
580 {
581     Q_Q(QGraphicsScene);
582
583     // Clear focus on the item to remove any reference in the focusWidget chain.
584     item->clearFocus();
585
586     markDirty(item, QRectF(), /*invalidateChildren=*/false, /*force=*/false,
587               /*ignoreOpacity=*/false, /*removingItemFromScene=*/true);
588
589     if (item->d_ptr->inDestructor) {
590         // The item is actually in its destructor, we call the special method in the index.
591         index->deleteItem(item);
592     } else {
593         // Can potentially call item->boundingRect() (virtual function), that's why
594         // we only can call this function if the item is not in its destructor.
595         index->removeItem(item);
596     }
597
598     item->d_ptr->clearSubFocus();
599
600     if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges)
601         unregisterScenePosItem(item);
602
603     QGraphicsScene *oldScene = item->d_func()->scene;
604     item->d_func()->scene = 0;
605
606     //We need to remove all children first because they might use their parent
607     //attributes (e.g. sceneTransform).
608     if (!item->d_ptr->inDestructor) {
609         // Remove all children recursively
610         for (int i = 0; i < item->d_ptr->children.size(); ++i)
611             q->removeItem(item->d_ptr->children.at(i));
612     }
613
614     if (!item->d_ptr->inDestructor && item == tabFocusFirst) {
615         QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
616         widget->d_func()->fixFocusChainBeforeReparenting(0, oldScene, 0);
617     }
618
619     // Unregister focus proxy.
620     item->d_ptr->resetFocusProxy();
621
622     // Remove from parent, or unregister from toplevels.
623     if (QGraphicsItem *parentItem = item->parentItem()) {
624         if (parentItem->scene()) {
625             Q_ASSERT_X(parentItem->scene() == q, "QGraphicsScene::removeItem",
626                        "Parent item's scene is different from this item's scene");
627             item->setParentItem(0);
628         }
629     } else {
630         unregisterTopLevelItem(item);
631     }
632
633     // Reset the mouse grabber and focus item data.
634     if (item == focusItem)
635         focusItem = 0;
636     if (item == lastFocusItem)
637         lastFocusItem = 0;
638     if (item == passiveFocusItem)
639         passiveFocusItem = 0;
640     if (item == activePanel) {
641         // ### deactivate...
642         activePanel = 0;
643     }
644     if (item == lastActivePanel)
645         lastActivePanel = 0;
646
647     // Cancel active touches
648     {
649         QMap<int, QGraphicsItem *>::iterator it = itemForTouchPointId.begin();
650         while (it != itemForTouchPointId.end()) {
651             if (it.value() == item) {
652                 sceneCurrentTouchPoints.remove(it.key());
653                 it = itemForTouchPointId.erase(it);
654             } else {
655                 ++it;
656             }
657         }
658     }
659
660     // Disable selectionChanged() for individual items
661     ++selectionChanging;
662     int oldSelectedItemsSize = selectedItems.size();
663
664     // Update selected & hovered item bookkeeping
665     selectedItems.remove(item);
666     hoverItems.removeAll(item);
667     cachedItemsUnderMouse.removeAll(item);
668     if (item->d_ptr->pendingPolish) {
669         const int unpolishedIndex = unpolishedItems.indexOf(item);
670         if (unpolishedIndex != -1)
671             unpolishedItems[unpolishedIndex] = 0;
672         item->d_ptr->pendingPolish = false;
673     }
674     resetDirtyItem(item);
675
676     //We remove all references of item from the sceneEventFilter arrays
677     QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = sceneEventFilters.begin();
678     while (iterator != sceneEventFilters.end()) {
679         if (iterator.value() == item || iterator.key() == item)
680             iterator = sceneEventFilters.erase(iterator);
681         else
682             ++iterator;
683     }
684
685     if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
686         leaveModal(item);
687
688     // Reset the mouse grabber and focus item data.
689     if (mouseGrabberItems.contains(item))
690         ungrabMouse(item, /* item is dying */ item->d_ptr->inDestructor);
691
692     // Reset the keyboard grabber
693     if (keyboardGrabberItems.contains(item))
694         ungrabKeyboard(item, /* item is dying */ item->d_ptr->inDestructor);
695
696     // Reset the last mouse grabber item
697     if (item == lastMouseGrabberItem)
698         lastMouseGrabberItem = 0;
699
700     // Reset the current drop item
701     if (item == dragDropItem)
702         dragDropItem = 0;
703
704     // Reenable selectionChanged() for individual items
705     --selectionChanging;
706     if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize)
707         emit q->selectionChanged();
708
709 #ifndef QT_NO_GESTURES
710     QHash<QGesture *, QGraphicsObject *>::iterator it;
711     for (it = gestureTargets.begin(); it != gestureTargets.end();) {
712         if (it.value() == item)
713             it = gestureTargets.erase(it);
714         else
715             ++it;
716     }
717
718     QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item);
719     cachedTargetItems.removeOne(dummy);
720     cachedItemGestures.remove(dummy);
721     cachedAlreadyDeliveredGestures.remove(dummy);
722
723     foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
724         ungrabGesture(item, gesture);
725 #endif // QT_NO_GESTURES
726 }
727
728 /*!
729     \internal
730 */
731 void QGraphicsScenePrivate::setActivePanelHelper(QGraphicsItem *item, bool duringActivationEvent)
732 {
733     Q_Q(QGraphicsScene);
734     if (item && item->scene() != q) {
735         qWarning("QGraphicsScene::setActivePanel: item %p must be part of this scene",
736                  item);
737         return;
738     }
739
740     // Ensure the scene has focus when we change panel activation.
741     q->setFocus(Qt::ActiveWindowFocusReason);
742
743     // Find the item's panel.
744     QGraphicsItem *panel = item ? item->panel() : 0;
745     lastActivePanel = panel ? activePanel : 0;
746     if (panel == activePanel || (!q->isActive() && !duringActivationEvent))
747         return;
748
749     // Deactivate the last active panel.
750     if (activePanel) {
751         if (QGraphicsItem *fi = activePanel->focusItem()) {
752             // Remove focus from the current focus item.
753             if (fi == q->focusItem())
754                 q->setFocusItem(0, Qt::ActiveWindowFocusReason);
755         }
756
757         QEvent event(QEvent::WindowDeactivate);
758         q->sendEvent(activePanel, &event);
759     } else if (panel && !duringActivationEvent) {
760         // Deactivate the scene if changing activation to a panel.
761         QEvent event(QEvent::WindowDeactivate);
762         foreach (QGraphicsItem *item, q->items()) {
763             if (item->isVisible() && !item->isPanel() && !item->parentItem())
764                 q->sendEvent(item, &event);
765         }
766     }
767
768     // Update activate state.
769     activePanel = panel;
770     QEvent event(QEvent::ActivationChange);
771     QApplication::sendEvent(q, &event);
772
773     // Activate
774     if (panel) {
775         QEvent event(QEvent::WindowActivate);
776         q->sendEvent(panel, &event);
777
778         // Set focus on the panel's focus item.
779         if (QGraphicsItem *focusItem = panel->focusItem())
780             focusItem->setFocus(Qt::ActiveWindowFocusReason);
781     } else if (q->isActive()) {
782         // Activate the scene
783         QEvent event(QEvent::WindowActivate);
784         foreach (QGraphicsItem *item, q->items()) {
785             if (item->isVisible() && !item->isPanel() && !item->parentItem())
786                 q->sendEvent(item, &event);
787         }
788     }
789 }
790
791 /*!
792     \internal
793 */
794 void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
795                                                Qt::FocusReason focusReason)
796 {
797     Q_Q(QGraphicsScene);
798     if (item == focusItem)
799         return;
800
801     // Clear focus if asked to set focus on something that can't
802     // accept input focus.
803     if (item && (!(item->flags() & QGraphicsItem::ItemIsFocusable)
804                  || !item->isVisible() || !item->isEnabled())) {
805         item = 0;
806     }
807
808     // Set focus on the scene if an item requests focus.
809     if (item) {
810         q->setFocus(focusReason);
811         if (item == focusItem)
812             return;
813     }
814
815     if (focusItem) {
816         lastFocusItem = focusItem;
817
818 #ifndef QT_NO_IM
819         if (lastFocusItem
820             && (lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
821             // Close any external input method panel. This happens
822             // automatically by removing WA_InputMethodEnabled on
823             // the views, but if we are changing focus, we have to
824             // do it ourselves.
825             for (int i = 0; i < views.size(); ++i)
826                 if (views.at(i)->inputContext())
827                     views.at(i)->inputContext()->reset();
828         }
829
830         focusItem = 0;
831         QFocusEvent event(QEvent::FocusOut, focusReason);
832         sendEvent(lastFocusItem, &event);
833 #endif //QT_NO_IM
834     }
835
836     // This handles the case that the item has been removed from the
837     // scene in response to the FocusOut event.
838     if (item && item->scene() != q)
839         item = 0;
840
841     if (item)
842         focusItem = item;
843     updateInputMethodSensitivityInViews();
844
845 #ifndef QT_NO_ACCESSIBILITY
846     if (focusItem) {
847         if (QGraphicsObject *focusObj = focusItem->toGraphicsObject()) {
848             QAccessible::updateAccessibility(focusObj, 0, QAccessible::Focus);
849         }
850     }
851 #endif
852     if (item) {
853         QFocusEvent event(QEvent::FocusIn, focusReason);
854         sendEvent(item, &event);
855     }
856 }
857
858 /*!
859     \internal
860 */
861 void QGraphicsScenePrivate::addPopup(QGraphicsWidget *widget)
862 {
863     Q_ASSERT(widget);
864     Q_ASSERT(!popupWidgets.contains(widget));
865     popupWidgets << widget;
866     if (QGraphicsWidget *focusWidget = widget->focusWidget()) {
867         focusWidget->setFocus(Qt::PopupFocusReason);
868     } else {
869         grabKeyboard((QGraphicsItem *)widget);
870         if (focusItem && popupWidgets.size() == 1) {
871             QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
872             sendEvent(focusItem, &event);
873         }
874     }
875     grabMouse((QGraphicsItem *)widget);
876 }
877
878 /*!
879     \internal
880
881     Remove \a widget from the popup list. Important notes:
882
883     \a widget is guaranteed to be in the list of popups, but it might not be
884     the last entry; you can hide any item in the pop list before the others,
885     and this must cause all later mouse grabbers to lose the grab.
886 */
887 void QGraphicsScenePrivate::removePopup(QGraphicsWidget *widget, bool itemIsDying)
888 {
889     Q_ASSERT(widget);
890     int index = popupWidgets.indexOf(widget);
891     Q_ASSERT(index != -1);
892
893     for (int i = popupWidgets.size() - 1; i >= index; --i) {
894         QGraphicsWidget *widget = popupWidgets.takeLast();
895         ungrabMouse(widget, itemIsDying);
896         if (focusItem && popupWidgets.isEmpty()) {
897             QFocusEvent event(QEvent::FocusIn, Qt::PopupFocusReason);
898             sendEvent(focusItem, &event);
899         } else if (keyboardGrabberItems.contains(static_cast<QGraphicsItem *>(widget))) {
900             ungrabKeyboard(static_cast<QGraphicsItem *>(widget), itemIsDying);
901         }
902         if (!itemIsDying && widget->isVisible()) {
903             widget->QGraphicsItem::d_ptr->setVisibleHelper(false, /* explicit = */ false);
904         }
905     }
906 }
907
908 /*!
909     \internal
910 */
911 void QGraphicsScenePrivate::grabMouse(QGraphicsItem *item, bool implicit)
912 {
913     // Append to list of mouse grabber items, and send a mouse grab event.
914     if (mouseGrabberItems.contains(item)) {
915         if (mouseGrabberItems.last() == item) {
916             Q_ASSERT(!implicit);
917             if (!lastMouseGrabberItemHasImplicitMouseGrab) {
918                 qWarning("QGraphicsItem::grabMouse: already a mouse grabber");
919             } else {
920                 // Upgrade to an explicit mouse grab
921                 lastMouseGrabberItemHasImplicitMouseGrab = false;
922             }
923         } else {
924             qWarning("QGraphicsItem::grabMouse: already blocked by mouse grabber: %p",
925                      mouseGrabberItems.last());
926         }
927         return;
928     }
929
930     // Send ungrab event to the last grabber.
931     if (!mouseGrabberItems.isEmpty()) {
932         QGraphicsItem *last = mouseGrabberItems.last();
933         if (lastMouseGrabberItemHasImplicitMouseGrab) {
934             // Implicit mouse grab is immediately lost.
935             last->ungrabMouse();
936         } else {
937             // Just send ungrab event to current grabber.
938             QEvent ungrabEvent(QEvent::UngrabMouse);
939             sendEvent(last, &ungrabEvent);
940         }
941     }
942
943     mouseGrabberItems << item;
944     lastMouseGrabberItemHasImplicitMouseGrab = implicit;
945
946     // Send grab event to current grabber.
947     QEvent grabEvent(QEvent::GrabMouse);
948     sendEvent(item, &grabEvent);
949 }
950
951 /*!
952     \internal
953 */
954 void QGraphicsScenePrivate::ungrabMouse(QGraphicsItem *item, bool itemIsDying)
955 {
956     int index = mouseGrabberItems.indexOf(item);
957     if (index == -1) {
958         qWarning("QGraphicsItem::ungrabMouse: not a mouse grabber");
959         return;
960     }
961
962     if (item != mouseGrabberItems.last()) {
963         // Recursively ungrab the next mouse grabber until we reach this item
964         // to ensure state consistency.
965         ungrabMouse(mouseGrabberItems.at(index + 1), itemIsDying);
966     }
967     if (!popupWidgets.isEmpty() && item == popupWidgets.last()) {
968         // If the item is a popup, go via removePopup to ensure state
969         // consistency and that it gets hidden correctly - beware that
970         // removePopup() reenters this function to continue removing the grab.
971         removePopup((QGraphicsWidget *)item, itemIsDying);
972         return;
973     }
974
975     // Send notification about mouse ungrab.
976     if (!itemIsDying) {
977         QEvent event(QEvent::UngrabMouse);
978         sendEvent(item, &event);
979     }
980
981     // Remove the item from the list of grabbers. Whenever this happens, we
982     // reset the implicitGrab (there can be only ever be one implicit grabber
983     // in a scene, and it is always the latest grabber; if the implicit grab
984     // is lost, it is not automatically regained.
985     mouseGrabberItems.takeLast();
986     lastMouseGrabberItemHasImplicitMouseGrab = false;
987
988     // Send notification about mouse regrab. ### It's unfortunate that all the
989     // items get a GrabMouse event, but this is a rare case with a simple
990     // implementation and it does ensure a consistent state.
991     if (!itemIsDying && !mouseGrabberItems.isEmpty()) {
992         QGraphicsItem *last = mouseGrabberItems.last();
993         QEvent event(QEvent::GrabMouse);
994         sendEvent(last, &event);
995     }
996 }
997
998 /*!
999     \internal
1000 */
1001 void QGraphicsScenePrivate::clearMouseGrabber()
1002 {
1003     if (!mouseGrabberItems.isEmpty())
1004         mouseGrabberItems.first()->ungrabMouse();
1005     lastMouseGrabberItem = 0;
1006 }
1007
1008 /*!
1009     \internal
1010 */
1011 void QGraphicsScenePrivate::grabKeyboard(QGraphicsItem *item)
1012 {
1013     if (keyboardGrabberItems.contains(item)) {
1014         if (keyboardGrabberItems.last() == item)
1015             qWarning("QGraphicsItem::grabKeyboard: already a keyboard grabber");
1016         else
1017             qWarning("QGraphicsItem::grabKeyboard: already blocked by keyboard grabber: %p",
1018                      keyboardGrabberItems.last());
1019         return;
1020     }
1021
1022     // Send ungrab event to the last grabber.
1023     if (!keyboardGrabberItems.isEmpty()) {
1024         // Just send ungrab event to current grabber.
1025         QEvent ungrabEvent(QEvent::UngrabKeyboard);
1026         sendEvent(keyboardGrabberItems.last(), &ungrabEvent);
1027     }
1028
1029     keyboardGrabberItems << item;
1030
1031     // Send grab event to current grabber.
1032     QEvent grabEvent(QEvent::GrabKeyboard);
1033     sendEvent(item, &grabEvent);
1034 }
1035
1036 /*!
1037     \internal
1038 */
1039 void QGraphicsScenePrivate::ungrabKeyboard(QGraphicsItem *item, bool itemIsDying)
1040 {
1041     int index = keyboardGrabberItems.lastIndexOf(item);
1042     if (index == -1) {
1043         qWarning("QGraphicsItem::ungrabKeyboard: not a keyboard grabber");
1044         return;
1045     }
1046     if (item != keyboardGrabberItems.last()) {
1047         // Recursively ungrab the topmost keyboard grabber until we reach this
1048         // item to ensure state consistency.
1049         ungrabKeyboard(keyboardGrabberItems.at(index + 1), itemIsDying);
1050     }
1051
1052     // Send notification about keyboard ungrab.
1053     if (!itemIsDying) {
1054         QEvent event(QEvent::UngrabKeyboard);
1055         sendEvent(item, &event);
1056     }
1057
1058     // Remove the item from the list of grabbers.
1059     keyboardGrabberItems.takeLast();
1060
1061     // Send notification about mouse regrab.
1062     if (!itemIsDying && !keyboardGrabberItems.isEmpty()) {
1063         QGraphicsItem *last = keyboardGrabberItems.last();
1064         QEvent event(QEvent::GrabKeyboard);
1065         sendEvent(last, &event);
1066     }
1067 }
1068
1069 /*!
1070     \internal
1071 */
1072 void QGraphicsScenePrivate::clearKeyboardGrabber()
1073 {
1074     if (!keyboardGrabberItems.isEmpty())
1075         ungrabKeyboard(keyboardGrabberItems.first());
1076 }
1077
1078 void QGraphicsScenePrivate::enableMouseTrackingOnViews()
1079 {
1080     foreach (QGraphicsView *view, views)
1081         view->viewport()->setMouseTracking(true);
1082 }
1083
1084 /*!
1085     Returns all items for the screen position in \a event.
1086 */
1087 QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &/*screenPos*/,
1088                                                               const QPointF &scenePos,
1089                                                               QWidget *widget) const
1090 {
1091     Q_Q(const QGraphicsScene);
1092     QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
1093     if (!view)
1094         return q->items(scenePos, Qt::IntersectsItemShape, Qt::DescendingOrder, QTransform());
1095
1096     const QRectF pointRect(scenePos, QSizeF(1, 1));
1097     if (!view->isTransformed())
1098         return q->items(pointRect, Qt::IntersectsItemShape, Qt::DescendingOrder);
1099
1100     const QTransform viewTransform = view->viewportTransform();
1101     return q->items(pointRect, Qt::IntersectsItemShape,
1102                     Qt::DescendingOrder, viewTransform);
1103 }
1104
1105 /*!
1106     \internal
1107 */
1108 void QGraphicsScenePrivate::storeMouseButtonsForMouseGrabber(QGraphicsSceneMouseEvent *event)
1109 {
1110     for (int i = 0x1; i <= 0x10; i <<= 1) {
1111         if (event->buttons() & i) {
1112             mouseGrabberButtonDownPos.insert(Qt::MouseButton(i),
1113                                              mouseGrabberItems.last()->d_ptr->genericMapFromScene(event->scenePos(),
1114                                                                                                   event->widget()));
1115             mouseGrabberButtonDownScenePos.insert(Qt::MouseButton(i), event->scenePos());
1116             mouseGrabberButtonDownScreenPos.insert(Qt::MouseButton(i), event->screenPos());
1117         }
1118     }
1119 }
1120
1121 /*!
1122     \internal
1123 */
1124 void QGraphicsScenePrivate::installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter)
1125 {
1126     sceneEventFilters.insert(watched, filter);
1127 }
1128
1129 /*!
1130     \internal
1131 */
1132 void QGraphicsScenePrivate::removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter)
1133 {
1134     if (!sceneEventFilters.contains(watched))
1135         return;
1136
1137     QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator it = sceneEventFilters.lowerBound(watched);
1138     QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator end = sceneEventFilters.upperBound(watched);
1139     do {
1140         if (it.value() == filter)
1141             it = sceneEventFilters.erase(it);
1142         else
1143             ++it;
1144     } while (it != end);
1145 }
1146
1147 /*!
1148   \internal
1149 */
1150 bool QGraphicsScenePrivate::filterDescendantEvent(QGraphicsItem *item, QEvent *event)
1151 {
1152     if (item && (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents)) {
1153         QGraphicsItem *parent = item->parentItem();
1154         while (parent) {
1155             if (parent->d_ptr->filtersDescendantEvents && parent->sceneEventFilter(item, event))
1156                 return true;
1157             if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents))
1158                 return false;
1159             parent = parent->parentItem();
1160         }
1161     }
1162     return false;
1163 }
1164
1165 /*!
1166     \internal
1167 */
1168 bool QGraphicsScenePrivate::filterEvent(QGraphicsItem *item, QEvent *event)
1169 {
1170     if (item && !sceneEventFilters.contains(item))
1171         return false;
1172
1173     QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator it = sceneEventFilters.lowerBound(item);
1174     QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator end = sceneEventFilters.upperBound(item);
1175     while (it != end) {
1176         // ### The filterer and filteree might both be deleted.
1177         if (it.value()->sceneEventFilter(it.key(), event))
1178             return true;
1179         ++it;
1180     }
1181     return false;
1182 }
1183
1184 /*!
1185     \internal
1186
1187     This is the final dispatch point for any events from the scene to the
1188     item. It filters the event first - if the filter returns true, the event
1189     is considered to have been eaten by the filter, and is therefore stopped
1190     (the default filter returns false). Then/otherwise, if the item is
1191     enabled, the event is sent; otherwise it is stopped.
1192 */
1193 bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event)
1194 {
1195     if (QGraphicsObject *object = item->toGraphicsObject()) {
1196 #ifndef QT_NO_GESTURES
1197         QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager;
1198         if (gestureManager) {
1199             if (gestureManager->filterEvent(object, event))
1200                 return true;
1201         }
1202 #endif // QT_NO_GESTURES
1203     }
1204
1205     if (filterEvent(item, event))
1206         return false;
1207     if (filterDescendantEvent(item, event))
1208         return false;
1209     if (!item || !item->isEnabled())
1210         return false;
1211     if (QGraphicsObject *o = item->toGraphicsObject()) {
1212         bool spont = event->spontaneous();
1213         if (spont ? qt_sendSpontaneousEvent(o, event) : QApplication::sendEvent(o, event))
1214             return true;
1215         event->spont = spont;
1216     }
1217     return item->sceneEvent(event);
1218 }
1219
1220 /*!
1221     \internal
1222 */
1223 void QGraphicsScenePrivate::cloneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
1224                                                QGraphicsSceneDragDropEvent *source)
1225 {
1226     dest->setWidget(source->widget());
1227     dest->setPos(source->pos());
1228     dest->setScenePos(source->scenePos());
1229     dest->setScreenPos(source->screenPos());
1230     dest->setButtons(source->buttons());
1231     dest->setModifiers(source->modifiers());
1232     dest->setPossibleActions(source->possibleActions());
1233     dest->setProposedAction(source->proposedAction());
1234     dest->setDropAction(source->dropAction());
1235     dest->setSource(source->source());
1236     dest->setMimeData(source->mimeData());
1237 }
1238
1239 /*!
1240     \internal
1241 */
1242 void QGraphicsScenePrivate::sendDragDropEvent(QGraphicsItem *item,
1243                                               QGraphicsSceneDragDropEvent *dragDropEvent)
1244 {
1245     dragDropEvent->setPos(item->d_ptr->genericMapFromScene(dragDropEvent->scenePos(), dragDropEvent->widget()));
1246     sendEvent(item, dragDropEvent);
1247 }
1248
1249 /*!
1250     \internal
1251 */
1252 void QGraphicsScenePrivate::sendHoverEvent(QEvent::Type type, QGraphicsItem *item,
1253                                            QGraphicsSceneHoverEvent *hoverEvent)
1254 {
1255     QGraphicsSceneHoverEvent event(type);
1256     event.setWidget(hoverEvent->widget());
1257     event.setPos(item->d_ptr->genericMapFromScene(hoverEvent->scenePos(), hoverEvent->widget()));
1258     event.setScenePos(hoverEvent->scenePos());
1259     event.setScreenPos(hoverEvent->screenPos());
1260     event.setLastPos(item->d_ptr->genericMapFromScene(hoverEvent->lastScenePos(), hoverEvent->widget()));
1261     event.setLastScenePos(hoverEvent->lastScenePos());
1262     event.setLastScreenPos(hoverEvent->lastScreenPos());
1263     event.setModifiers(hoverEvent->modifiers());
1264     sendEvent(item, &event);
1265 }
1266
1267 /*!
1268     \internal
1269 */
1270 void QGraphicsScenePrivate::sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent)
1271 {
1272     if (mouseEvent->button() == 0 && mouseEvent->buttons() == 0 && lastMouseGrabberItemHasImplicitMouseGrab) {
1273         // ### This is a temporary fix for until we get proper mouse
1274         // grab events.
1275         clearMouseGrabber();
1276         return;
1277     }
1278
1279     QGraphicsItem *item = mouseGrabberItems.last();
1280     if (item->isBlockedByModalPanel())
1281         return;
1282
1283     for (int i = 0x1; i <= 0x10; i <<= 1) {
1284         Qt::MouseButton button = Qt::MouseButton(i);
1285         mouseEvent->setButtonDownPos(button, mouseGrabberButtonDownPos.value(button, item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget())));
1286         mouseEvent->setButtonDownScenePos(button, mouseGrabberButtonDownScenePos.value(button, mouseEvent->scenePos()));
1287         mouseEvent->setButtonDownScreenPos(button, mouseGrabberButtonDownScreenPos.value(button, mouseEvent->screenPos()));
1288     }
1289     mouseEvent->setPos(item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget()));
1290     mouseEvent->setLastPos(item->d_ptr->genericMapFromScene(mouseEvent->lastScenePos(), mouseEvent->widget()));
1291     sendEvent(item, mouseEvent);
1292 }
1293
1294 /*!
1295     \internal
1296 */
1297 void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent)
1298 {
1299     Q_Q(QGraphicsScene);
1300
1301     // Ignore by default, unless we find a mouse grabber that accepts it.
1302     mouseEvent->ignore();
1303
1304     // Deliver to any existing mouse grabber.
1305     if (!mouseGrabberItems.isEmpty()) {
1306         if (mouseGrabberItems.last()->isBlockedByModalPanel())
1307             return;
1308         // The event is ignored by default, but we disregard the event's
1309         // accepted state after delivery; the mouse is grabbed, after all.
1310         sendMouseEvent(mouseEvent);
1311         return;
1312     }
1313
1314     // Start by determining the number of items at the current position.
1315     // Reuse value from earlier calculations if possible.
1316     if (cachedItemsUnderMouse.isEmpty()) {
1317         cachedItemsUnderMouse = itemsAtPosition(mouseEvent->screenPos(),
1318                                                 mouseEvent->scenePos(),
1319                                                 mouseEvent->widget());
1320     }
1321
1322     // Update window activation.
1323     QGraphicsItem *topItem = cachedItemsUnderMouse.value(0);
1324     QGraphicsWidget *newActiveWindow = topItem ? topItem->window() : 0;
1325     if (newActiveWindow && newActiveWindow->isBlockedByModalPanel(&topItem)) {
1326         // pass activation to the blocking modal window
1327         newActiveWindow = topItem ? topItem->window() : 0;
1328     }
1329
1330     if (newActiveWindow != q->activeWindow())
1331         q->setActiveWindow(newActiveWindow);
1332
1333     // Set focus on the topmost enabled item that can take focus.
1334     bool setFocus = false;
1335
1336     foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
1337         if (item->isBlockedByModalPanel()
1338             || (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling)) {
1339             // Make sure we don't clear focus.
1340             setFocus = true;
1341             break;
1342         }
1343         if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable))) {
1344             if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
1345                 setFocus = true;
1346                 if (item != q->focusItem() && item->d_ptr->mouseSetsFocus)
1347                     q->setFocusItem(item, Qt::MouseFocusReason);
1348                 break;
1349             }
1350         }
1351         if (item->isPanel())
1352             break;
1353         if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
1354             break;
1355     }
1356
1357     // Check for scene modality.
1358     bool sceneModality = false;
1359     for (int i = 0; i < modalPanels.size(); ++i) {
1360         if (modalPanels.at(i)->panelModality() == QGraphicsItem::SceneModal) {
1361             sceneModality = true;
1362             break;
1363         }
1364     }
1365
1366     // If nobody could take focus, clear it.
1367     if (!stickyFocus && !setFocus && !sceneModality)
1368         q->setFocusItem(0, Qt::MouseFocusReason);
1369
1370     // Any item will do.
1371     if (sceneModality && cachedItemsUnderMouse.isEmpty())
1372         cachedItemsUnderMouse << modalPanels.first();
1373
1374     // Find a mouse grabber by sending mouse press events to all mouse grabber
1375     // candidates one at a time, until the event is accepted. It's accepted by
1376     // default, so the receiver has to explicitly ignore it for it to pass
1377     // through.
1378     foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
1379         if (!(item->acceptedMouseButtons() & mouseEvent->button())) {
1380             // Skip items that don't accept the event's mouse button.
1381             continue;
1382         }
1383
1384         // Check if this item is blocked by a modal panel and deliver the mouse event to the
1385         // blocking panel instead of this item if blocked.
1386         (void) item->isBlockedByModalPanel(&item);
1387
1388         grabMouse(item, /* implicit = */ true);
1389         mouseEvent->accept();
1390
1391         // check if the item we are sending to are disabled (before we send the event)
1392         bool disabled = !item->isEnabled();
1393         bool isPanel = item->isPanel();
1394         if (mouseEvent->type() == QEvent::GraphicsSceneMouseDoubleClick
1395             && item != lastMouseGrabberItem && lastMouseGrabberItem) {
1396             // If this item is different from the item that received the last
1397             // mouse event, and mouseEvent is a doubleclick event, then the
1398             // event is converted to a press. Known limitation:
1399             // Triple-clicking will not generate a doubleclick, though.
1400             QGraphicsSceneMouseEvent mousePress(QEvent::GraphicsSceneMousePress);
1401             mousePress.spont = mouseEvent->spont;
1402             mousePress.accept();
1403             mousePress.setButton(mouseEvent->button());
1404             mousePress.setButtons(mouseEvent->buttons());
1405             mousePress.setScreenPos(mouseEvent->screenPos());
1406             mousePress.setScenePos(mouseEvent->scenePos());
1407             mousePress.setModifiers(mouseEvent->modifiers());
1408             mousePress.setWidget(mouseEvent->widget());
1409             mousePress.setButtonDownPos(mouseEvent->button(),
1410                                         mouseEvent->buttonDownPos(mouseEvent->button()));
1411             mousePress.setButtonDownScenePos(mouseEvent->button(),
1412                                              mouseEvent->buttonDownScenePos(mouseEvent->button()));
1413             mousePress.setButtonDownScreenPos(mouseEvent->button(),
1414                                               mouseEvent->buttonDownScreenPos(mouseEvent->button()));
1415             sendMouseEvent(&mousePress);
1416             mouseEvent->setAccepted(mousePress.isAccepted());
1417         } else {
1418             sendMouseEvent(mouseEvent);
1419         }
1420
1421         bool dontSendUngrabEvents = mouseGrabberItems.isEmpty() || mouseGrabberItems.last() != item;
1422         if (disabled) {
1423             ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
1424             break;
1425         }
1426         if (mouseEvent->isAccepted()) {
1427             if (!mouseGrabberItems.isEmpty())
1428                 storeMouseButtonsForMouseGrabber(mouseEvent);
1429             lastMouseGrabberItem = item;
1430             return;
1431         }
1432         ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
1433
1434         // Don't propagate through panels.
1435         if (isPanel)
1436             break;
1437     }
1438
1439     // Is the event still ignored? Then the mouse press goes to the scene.
1440     // Reset the mouse grabber, clear the selection, clear focus, and leave
1441     // the event ignored so that it can propagate through the originating
1442     // view.
1443     if (!mouseEvent->isAccepted()) {
1444         clearMouseGrabber();
1445
1446         QGraphicsView *view = mouseEvent->widget() ? qobject_cast<QGraphicsView *>(mouseEvent->widget()->parentWidget()) : 0;
1447         bool dontClearSelection = view && view->dragMode() == QGraphicsView::ScrollHandDrag;
1448         if (!dontClearSelection) {
1449             // Clear the selection if the originating view isn't in scroll
1450             // hand drag mode. The view will clear the selection if no drag
1451             // happened.
1452             q->clearSelection();
1453         }
1454     }
1455 }
1456
1457 /*!
1458     \internal
1459
1460     Ensures that the list of toplevels is sorted by insertion order, and that
1461     the siblingIndexes are packed (no gaps), and start at 0.
1462
1463     ### This function is almost identical to
1464     QGraphicsItemPrivate::ensureSequentialSiblingIndex().
1465 */
1466 void QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes()
1467 {
1468     if (!topLevelSequentialOrdering) {
1469         qSort(topLevelItems.begin(), topLevelItems.end(), QGraphicsItemPrivate::insertionOrder);
1470         topLevelSequentialOrdering = true;
1471         needSortTopLevelItems = 1;
1472     }
1473     if (holesInTopLevelSiblingIndex) {
1474         holesInTopLevelSiblingIndex = 0;
1475         for (int i = 0; i < topLevelItems.size(); ++i)
1476             topLevelItems[i]->d_ptr->siblingIndex = i;
1477     }
1478 }
1479
1480 /*!
1481     \internal
1482
1483     Set the font and propagate the changes if the font is different from the
1484     current font.
1485 */
1486 void QGraphicsScenePrivate::setFont_helper(const QFont &font)
1487 {
1488     if (this->font == font && this->font.resolve() == font.resolve())
1489         return;
1490     updateFont(font);
1491 }
1492
1493 /*!
1494     \internal
1495
1496     Resolve the scene's font against the application font, and propagate the
1497     changes too all items in the scene.
1498 */
1499 void QGraphicsScenePrivate::resolveFont()
1500 {
1501     QFont naturalFont = QApplication::font();
1502     naturalFont.resolve(0);
1503     QFont resolvedFont = font.resolve(naturalFont);
1504     updateFont(resolvedFont);
1505 }
1506
1507 /*!
1508     \internal
1509
1510     Update the font, and whether or not it has changed, reresolve all fonts in
1511     the scene.
1512 */
1513 void QGraphicsScenePrivate::updateFont(const QFont &font)
1514 {
1515     Q_Q(QGraphicsScene);
1516
1517     // Update local font setting.
1518     this->font = font;
1519
1520     // Resolve the fonts of all top-level widget items, or widget items
1521     // whose parent is not a widget.
1522     foreach (QGraphicsItem *item, q->items()) {
1523         if (!item->parentItem()) {
1524             // Resolvefont for an item is a noop operation, but
1525             // every item can be a widget, or can have a widget
1526             // childre.
1527             item->d_ptr->resolveFont(font.resolve());
1528         }
1529     }
1530
1531     // Send the scene a FontChange event.
1532     QEvent event(QEvent::FontChange);
1533     QApplication::sendEvent(q, &event);
1534 }
1535
1536 /*!
1537     \internal
1538
1539     Set the palette and propagate the changes if the palette is different from
1540     the current palette.
1541 */
1542 void QGraphicsScenePrivate::setPalette_helper(const QPalette &palette)
1543 {
1544     if (this->palette == palette && this->palette.resolve() == palette.resolve())
1545         return;
1546     updatePalette(palette);
1547 }
1548
1549 /*!
1550     \internal
1551
1552     Resolve the scene's palette against the application palette, and propagate
1553     the changes too all items in the scene.
1554 */
1555 void QGraphicsScenePrivate::resolvePalette()
1556 {
1557     QPalette naturalPalette = QApplication::palette();
1558     naturalPalette.resolve(0);
1559     QPalette resolvedPalette = palette.resolve(naturalPalette);
1560     updatePalette(resolvedPalette);
1561 }
1562
1563 /*!
1564     \internal
1565
1566     Update the palette, and whether or not it has changed, reresolve all
1567     palettes in the scene.
1568 */
1569 void QGraphicsScenePrivate::updatePalette(const QPalette &palette)
1570 {
1571     Q_Q(QGraphicsScene);
1572
1573     // Update local palette setting.
1574     this->palette = palette;
1575
1576     // Resolve the palettes of all top-level widget items, or widget items
1577     // whose parent is not a widget.
1578     foreach (QGraphicsItem *item, q->items()) {
1579         if (!item->parentItem()) {
1580             // Resolvefont for an item is a noop operation, but
1581             // every item can be a widget, or can have a widget
1582             // childre.
1583             item->d_ptr->resolvePalette(palette.resolve());
1584         }
1585     }
1586
1587     // Send the scene a PaletteChange event.
1588     QEvent event(QEvent::PaletteChange);
1589     QApplication::sendEvent(q, &event);
1590 }
1591
1592 /*!
1593     Constructs a QGraphicsScene object. The \a parent parameter is
1594     passed to QObject's constructor.
1595 */
1596 QGraphicsScene::QGraphicsScene(QObject *parent)
1597     : QObject(*new QGraphicsScenePrivate, parent)
1598 {
1599     d_func()->init();
1600 }
1601
1602 /*!
1603     Constructs a QGraphicsScene object, using \a sceneRect for its
1604     scene rectangle. The \a parent parameter is passed to QObject's
1605     constructor.
1606
1607     \sa sceneRect
1608 */
1609 QGraphicsScene::QGraphicsScene(const QRectF &sceneRect, QObject *parent)
1610     : QObject(*new QGraphicsScenePrivate, parent)
1611 {
1612     d_func()->init();
1613     setSceneRect(sceneRect);
1614 }
1615
1616 /*!
1617     Constructs a QGraphicsScene object, using the rectangle specified
1618     by (\a x, \a y), and the given \a width and \a height for its
1619     scene rectangle. The \a parent parameter is passed to QObject's
1620     constructor.
1621
1622     \sa sceneRect
1623 */
1624 QGraphicsScene::QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent)
1625     : QObject(*new QGraphicsScenePrivate, parent)
1626 {
1627     d_func()->init();
1628     setSceneRect(x, y, width, height);
1629 }
1630
1631 /*!
1632   Removes and deletes all items from the scene object
1633   before destroying the scene object. The scene object
1634   is removed from the application's global scene list,
1635   and it is removed from all associated views.
1636 */
1637 QGraphicsScene::~QGraphicsScene()
1638 {
1639     Q_D(QGraphicsScene);
1640
1641     // Remove this scene from qApp's global scene list.
1642     if (!QApplicationPrivate::is_app_closing)
1643         qApp->d_func()->scene_list.removeAll(this);
1644
1645     clear();
1646
1647     // Remove this scene from all associated views.
1648     for (int j = 0; j < d->views.size(); ++j)
1649         d->views.at(j)->setScene(0);
1650 }
1651
1652 /*!
1653     \property QGraphicsScene::sceneRect
1654     \brief the scene rectangle; the bounding rectangle of the scene
1655
1656     The scene rectangle defines the extent of the scene. It is
1657     primarily used by QGraphicsView to determine the view's default
1658     scrollable area, and by QGraphicsScene to manage item indexing.
1659
1660     If unset, or if set to a null QRectF, sceneRect() will return the largest
1661     bounding rect of all items on the scene since the scene was created (i.e.,
1662     a rectangle that grows when items are added to or moved in the scene, but
1663     never shrinks).
1664
1665     \sa width(), height(), QGraphicsView::sceneRect
1666 */
1667 QRectF QGraphicsScene::sceneRect() const
1668 {
1669     Q_D(const QGraphicsScene);
1670     if (d->hasSceneRect)
1671         return d->sceneRect;
1672
1673     if (d->dirtyGrowingItemsBoundingRect) {
1674         // Lazily update the growing items bounding rect
1675         QGraphicsScenePrivate *thatd = const_cast<QGraphicsScenePrivate *>(d);
1676         QRectF oldGrowingBoundingRect = thatd->growingItemsBoundingRect;
1677         thatd->growingItemsBoundingRect |= itemsBoundingRect();
1678         thatd->dirtyGrowingItemsBoundingRect = false;
1679         if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect)
1680             emit const_cast<QGraphicsScene *>(this)->sceneRectChanged(thatd->growingItemsBoundingRect);
1681     }
1682     return d->growingItemsBoundingRect;
1683 }
1684 void QGraphicsScene::setSceneRect(const QRectF &rect)
1685 {
1686     Q_D(QGraphicsScene);
1687     if (rect != d->sceneRect) {
1688         d->hasSceneRect = !rect.isNull();
1689         d->sceneRect = rect;
1690         emit sceneRectChanged(d->hasSceneRect ? rect : d->growingItemsBoundingRect);
1691     }
1692 }
1693
1694 /*!
1695      \fn qreal QGraphicsScene::width() const
1696
1697      This convenience function is equivalent to calling sceneRect().width().
1698
1699      \sa height()
1700 */
1701
1702 /*!
1703      \fn qreal QGraphicsScene::height() const
1704
1705      This convenience function is equivalent to calling \c sceneRect().height().
1706
1707      \sa width()
1708 */
1709
1710 /*!
1711     Renders the \a source rect from scene into \a target, using \a painter. This
1712     function is useful for capturing the contents of the scene onto a paint
1713     device, such as a QImage (e.g., to take a screenshot), or for printing
1714     with QPrinter. For example:
1715
1716     \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 1
1717
1718     If \a source is a null rect, this function will use sceneRect() to
1719     determine what to render. If \a target is a null rect, the dimensions of \a
1720     painter's paint device will be used.
1721
1722     The source rect contents will be transformed according to \a
1723     aspectRatioMode to fit into the target rect. By default, the aspect ratio
1724     is kept, and \a source is scaled to fit in \a target.
1725
1726     \sa QGraphicsView::render()
1727 */
1728 void QGraphicsScene::render(QPainter *painter, const QRectF &target, const QRectF &source,
1729                             Qt::AspectRatioMode aspectRatioMode)
1730 {
1731     // ### Switch to using the recursive rendering algorithm instead.
1732
1733     // Default source rect = scene rect
1734     QRectF sourceRect = source;
1735     if (sourceRect.isNull())
1736         sourceRect = sceneRect();
1737
1738     // Default target rect = device rect
1739     QRectF targetRect = target;
1740     if (targetRect.isNull()) {
1741         if (painter->device()->devType() == QInternal::Picture)
1742             targetRect = sourceRect;
1743         else
1744             targetRect.setRect(0, 0, painter->device()->width(), painter->device()->height());
1745     }
1746
1747     // Find the ideal x / y scaling ratio to fit \a source into \a target.
1748     qreal xratio = targetRect.width() / sourceRect.width();
1749     qreal yratio = targetRect.height() / sourceRect.height();
1750
1751     // Scale according to the aspect ratio mode.
1752     switch (aspectRatioMode) {
1753     case Qt::KeepAspectRatio:
1754         xratio = yratio = qMin(xratio, yratio);
1755         break;
1756     case Qt::KeepAspectRatioByExpanding:
1757         xratio = yratio = qMax(xratio, yratio);
1758         break;
1759     case Qt::IgnoreAspectRatio:
1760         break;
1761     }
1762
1763     // Find all items to draw, and reverse the list (we want to draw
1764     // in reverse order).
1765     QList<QGraphicsItem *> itemList = items(sourceRect, Qt::IntersectsItemBoundingRect);
1766     QGraphicsItem **itemArray = new QGraphicsItem *[itemList.size()];
1767     int numItems = itemList.size();
1768     for (int i = 0; i < numItems; ++i)
1769         itemArray[numItems - i - 1] = itemList.at(i);
1770     itemList.clear();
1771
1772     painter->save();
1773
1774     // Transform the painter.
1775     painter->setClipRect(targetRect, Qt::IntersectClip);
1776     QTransform painterTransform;
1777     painterTransform *= QTransform()
1778                         .translate(targetRect.left(), targetRect.top())
1779                         .scale(xratio, yratio)
1780                         .translate(-sourceRect.left(), -sourceRect.top());
1781     painter->setWorldTransform(painterTransform, true);
1782
1783     // Two unit vectors.
1784     QLineF v1(0, 0, 1, 0);
1785     QLineF v2(0, 0, 0, 1);
1786
1787     // Generate the style options
1788     QStyleOptionGraphicsItem *styleOptionArray = new QStyleOptionGraphicsItem[numItems];
1789     for (int i = 0; i < numItems; ++i)
1790         itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], painterTransform, targetRect.toRect());
1791
1792     // Render the scene.
1793     drawBackground(painter, sourceRect);
1794     drawItems(painter, numItems, itemArray, styleOptionArray);
1795     drawForeground(painter, sourceRect);
1796
1797     delete [] itemArray;
1798     delete [] styleOptionArray;
1799
1800     painter->restore();
1801 }
1802
1803 /*!
1804     \property QGraphicsScene::itemIndexMethod
1805     \brief the item indexing method.
1806
1807     QGraphicsScene applies an indexing algorithm to the scene, to speed up
1808     item discovery functions like items() and itemAt(). Indexing is most
1809     efficient for static scenes (i.e., where items don't move around). For
1810     dynamic scenes, or scenes with many animated items, the index bookkeeping
1811     can outweight the fast lookup speeds.
1812
1813     For the common case, the default index method BspTreeIndex works fine.  If
1814     your scene uses many animations and you are experiencing slowness, you can
1815     disable indexing by calling \c setItemIndexMethod(NoIndex).
1816
1817     \sa bspTreeDepth
1818 */
1819 QGraphicsScene::ItemIndexMethod QGraphicsScene::itemIndexMethod() const
1820 {
1821     Q_D(const QGraphicsScene);
1822     return d->indexMethod;
1823 }
1824 void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method)
1825 {
1826     Q_D(QGraphicsScene);
1827     if (d->indexMethod == method)
1828         return;
1829
1830     d->indexMethod = method;
1831
1832     QList<QGraphicsItem *> oldItems = d->index->items(Qt::DescendingOrder);
1833     delete d->index;
1834     if (method == BspTreeIndex)
1835         d->index = new QGraphicsSceneBspTreeIndex(this);
1836     else
1837         d->index = new QGraphicsSceneLinearIndex(this);
1838     for (int i = oldItems.size() - 1; i >= 0; --i)
1839         d->index->addItem(oldItems.at(i));
1840 }
1841
1842 /*!
1843     \property QGraphicsScene::bspTreeDepth
1844     \brief the depth of QGraphicsScene's BSP index tree
1845     \since 4.3
1846
1847     This property has no effect when NoIndex is used.
1848
1849     This value determines the depth of QGraphicsScene's BSP tree. The depth
1850     directly affects QGraphicsScene's performance and memory usage; the latter
1851     growing exponentially with the depth of the tree. With an optimal tree
1852     depth, QGraphicsScene can instantly determine the locality of items, even
1853     for scenes with thousands or millions of items. This also greatly improves
1854     rendering performance.
1855
1856     By default, the value is 0, in which case Qt will guess a reasonable
1857     default depth based on the size, location and number of items in the
1858     scene. If these parameters change frequently, however, you may experience
1859     slowdowns as QGraphicsScene retunes the depth internally. You can avoid
1860     potential slowdowns by fixating the tree depth through setting this
1861     property.
1862
1863     The depth of the tree and the size of the scene rectangle decide the
1864     granularity of the scene's partitioning. The size of each scene segment is
1865     determined by the following algorithm:
1866
1867     \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 2
1868
1869     The BSP tree has an optimal size when each segment contains between 0 and
1870     10 items.
1871
1872     \sa itemIndexMethod
1873 */
1874 int QGraphicsScene::bspTreeDepth() const
1875 {
1876     Q_D(const QGraphicsScene);
1877     QGraphicsSceneBspTreeIndex *bspTree = qobject_cast<QGraphicsSceneBspTreeIndex *>(d->index);
1878     return bspTree ? bspTree->bspTreeDepth() : 0;
1879 }
1880 void QGraphicsScene::setBspTreeDepth(int depth)
1881 {
1882     Q_D(QGraphicsScene);
1883     if (depth < 0) {
1884         qWarning("QGraphicsScene::setBspTreeDepth: invalid depth %d ignored; must be >= 0", depth);
1885         return;
1886     }
1887
1888     QGraphicsSceneBspTreeIndex *bspTree = qobject_cast<QGraphicsSceneBspTreeIndex *>(d->index);
1889     if (!bspTree) {
1890         qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP");
1891         return;
1892     }
1893     bspTree->setBspTreeDepth(depth);
1894 }
1895
1896 /*!
1897     \property QGraphicsScene::sortCacheEnabled
1898     \brief whether sort caching is enabled
1899     \since 4.5
1900     \obsolete
1901
1902     Since Qt 4.6, this property has no effect.
1903 */
1904 bool QGraphicsScene::isSortCacheEnabled() const
1905 {
1906     Q_D(const QGraphicsScene);
1907     return d->sortCacheEnabled;
1908 }
1909 void QGraphicsScene::setSortCacheEnabled(bool enabled)
1910 {
1911     Q_D(QGraphicsScene);
1912     if (d->sortCacheEnabled == enabled)
1913         return;
1914     d->sortCacheEnabled = enabled;
1915 }
1916
1917 /*!
1918     Calculates and returns the bounding rect of all items on the scene. This
1919     function works by iterating over all items, and because if this, it can
1920     be slow for large scenes.
1921
1922     \sa sceneRect()
1923 */
1924 QRectF QGraphicsScene::itemsBoundingRect() const
1925 {
1926     // Does not take untransformable items into account.
1927     QRectF boundingRect;
1928     foreach (QGraphicsItem *item, items())
1929         boundingRect |= item->sceneBoundingRect();
1930     return boundingRect;
1931 }
1932
1933 /*!
1934     Returns a list of all items in the scene in descending stacking order.
1935
1936     \sa addItem(), removeItem(), {QGraphicsItem#Sorting}{Sorting}
1937 */
1938 QList<QGraphicsItem *> QGraphicsScene::items() const
1939 {
1940     Q_D(const QGraphicsScene);
1941     return d->index->items(Qt::DescendingOrder);
1942 }
1943
1944 /*!
1945     Returns an ordered list of all items on the scene. \a order decides the
1946     stacking order.
1947
1948     \sa addItem(), removeItem(), {QGraphicsItem#Sorting}{Sorting}
1949 */
1950 QList<QGraphicsItem *> QGraphicsScene::items(Qt::SortOrder order) const
1951 {
1952     Q_D(const QGraphicsScene);
1953     return d->index->items(order);
1954 }
1955
1956 /*!
1957     \obsolete
1958
1959     Returns all visible items at position \a pos in the scene. The items are
1960     listed in descending stacking order (i.e., the first item in the list is the
1961     top-most item, and the last item is the bottom-most item).
1962
1963     This function is deprecated and returns incorrect results if the scene
1964     contains items that ignore transformations. Use the overload that takes
1965     a QTransform instead.
1966
1967     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
1968 */
1969 QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos) const
1970 {
1971     Q_D(const QGraphicsScene);
1972     return d->index->items(pos, Qt::IntersectsItemShape, Qt::DescendingOrder);
1973 }
1974
1975 /*!
1976     \overload
1977     \obsolete
1978
1979     Returns all visible items that, depending on \a mode, are either inside or
1980     intersect with the specified \a rectangle.
1981
1982     The default value for \a mode is Qt::IntersectsItemShape; all items whose
1983     exact shape intersects with or is contained by \a rectangle are returned.
1984
1985     This function is deprecated and returns incorrect results if the scene
1986     contains items that ignore transformations. Use the overload that takes
1987     a QTransform instead.
1988
1989     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
1990 */
1991 QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rectangle, Qt::ItemSelectionMode mode) const
1992 {
1993     Q_D(const QGraphicsScene);
1994     return d->index->items(rectangle, mode, Qt::DescendingOrder);
1995 }
1996
1997 /*!
1998     \fn QList<QGraphicsItem *> QGraphicsScene::items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode) const
1999     \obsolete
2000     \since 4.3
2001
2002     This convenience function is equivalent to calling items(QRectF(\a x, \a y, \a w, \a h), \a mode).
2003
2004     This function is deprecated and returns incorrect results if the scene
2005     contains items that ignore transformations. Use the overload that takes
2006     a QTransform instead.
2007 */
2008
2009 /*!
2010     \fn QList<QGraphicsItem *> QGraphicsScene::items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
2011     \overload
2012     \since 4.6
2013
2014     \brief Returns all visible items that, depending on \a mode, are
2015     either inside or intersect with the rectangle defined by \a x, \a y,
2016     \a w and \a h, in a list sorted using \a order.
2017
2018     \a deviceTransform is the transformation that applies to the view, and needs to
2019     be provided if the scene contains items that ignore transformations.
2020 */
2021
2022 /*!
2023     \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode) const
2024     \overload
2025     \obsolete
2026
2027     Returns all visible items that, depending on \a mode, are either inside or
2028     intersect with the polygon \a polygon.
2029
2030     The default value for \a mode is Qt::IntersectsItemShape; all items whose
2031     exact shape intersects with or is contained by \a polygon are returned.
2032
2033     This function is deprecated and returns incorrect results if the scene
2034     contains items that ignore transformations. Use the overload that takes
2035     a QTransform instead.
2036
2037     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
2038 */
2039 QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode) const
2040 {
2041     Q_D(const QGraphicsScene);
2042     return d->index->items(polygon, mode, Qt::DescendingOrder);
2043 }
2044
2045 /*!
2046     \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
2047     \overload
2048     \obsolete
2049
2050     Returns all visible items that, depending on \a path, are either inside or
2051     intersect with the path \a path.
2052
2053     The default value for \a mode is Qt::IntersectsItemShape; all items whose
2054     exact shape intersects with or is contained by \a path are returned.
2055
2056     This function is deprecated and returns incorrect results if the scene
2057     contains items that ignore transformations. Use the overload that takes
2058     a QTransform instead.
2059
2060     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
2061 */
2062 QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
2063 {
2064     Q_D(const QGraphicsScene);
2065     return d->index->items(path, mode, Qt::DescendingOrder);
2066 }
2067
2068 /*!
2069     \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
2070     \since 4.6
2071
2072     \brief Returns all visible items that, depending on \a mode, are at
2073     the specified \a pos in a list sorted using \a order.
2074
2075     The default value for \a mode is Qt::IntersectsItemShape; all items whose
2076     exact shape intersects with \a pos are returned.
2077
2078     \a deviceTransform is the transformation that applies to the view, and needs to
2079     be provided if the scene contains items that ignore transformations.
2080
2081     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
2082 */
2083 QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode,
2084                                              Qt::SortOrder order, const QTransform &deviceTransform) const
2085 {
2086     Q_D(const QGraphicsScene);
2087     return d->index->items(pos, mode, order, deviceTransform);
2088 }
2089
2090 /*!
2091     \fn QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
2092     \overload
2093     \since 4.6
2094
2095     \brief Returns all visible items that, depending on \a mode, are
2096     either inside or intersect with the specified \a rect and return a
2097     list sorted using \a order.
2098
2099     The default value for \a mode is Qt::IntersectsItemShape; all items whose
2100     exact shape intersects with or is contained by \a rect are returned.
2101
2102     \a deviceTransform is the transformation that applies to the view, and needs to
2103     be provided if the scene contains items that ignore transformations.
2104
2105     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
2106 */
2107 QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode,
2108                                              Qt::SortOrder order, const QTransform &deviceTransform) const
2109 {
2110     Q_D(const QGraphicsScene);
2111     return d->index->items(rect, mode, order, deviceTransform);
2112 }
2113
2114 /*!
2115     \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
2116     \overload
2117     \since 4.6
2118
2119     \brief Returns all visible items that, depending on \a mode, are
2120     either inside or intersect with the specified \a polygon and return
2121     a list sorted using \a order.
2122
2123     The default value for \a mode is Qt::IntersectsItemShape; all items whose
2124     exact shape intersects with or is contained by \a polygon are returned.
2125
2126     \a deviceTransform is the transformation that applies to the view, and needs to
2127     be provided if the scene contains items that ignore transformations.
2128
2129     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
2130 */
2131 QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode,
2132                                              Qt::SortOrder order, const QTransform &deviceTransform) const
2133 {
2134     Q_D(const QGraphicsScene);
2135     return d->index->items(polygon, mode, order, deviceTransform);
2136 }
2137
2138 /*!
2139     \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
2140     \overload
2141     \since 4.6
2142
2143     \brief Returns all visible items that, depending on \a mode, are
2144     either inside or intersect with the specified \a path and return a
2145     list sorted using \a order.
2146
2147     The default value for \a mode is Qt::IntersectsItemShape; all items whose
2148     exact shape intersects with or is contained by \a path are returned.
2149
2150     \a deviceTransform is the transformation that applies to the view, and needs to
2151     be provided if the scene contains items that ignore transformations.
2152
2153     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
2154 */
2155 QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode,
2156                                              Qt::SortOrder order, const QTransform &deviceTransform) const
2157 {
2158     Q_D(const QGraphicsScene);
2159     return d->index->items(path, mode, order, deviceTransform);
2160 }
2161
2162 /*!
2163     Returns a list of all items that collide with \a item. Collisions are
2164     determined by calling QGraphicsItem::collidesWithItem(); the collision
2165     detection is determined by \a mode. By default, all items whose shape
2166     intersects \a item or is contained inside \a item's shape are returned.
2167
2168     The items are returned in descending stacking order (i.e., the first item
2169     in the list is the uppermost item, and the last item is the lowermost
2170     item).
2171
2172     \sa items(), itemAt(), QGraphicsItem::collidesWithItem(), {QGraphicsItem#Sorting}{Sorting}
2173 */
2174 QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item,
2175                                                       Qt::ItemSelectionMode mode) const
2176 {
2177     Q_D(const QGraphicsScene);
2178     if (!item) {
2179         qWarning("QGraphicsScene::collidingItems: cannot find collisions for null item");
2180         return QList<QGraphicsItem *>();
2181     }
2182
2183     // Does not support ItemIgnoresTransformations.
2184     QList<QGraphicsItem *> tmp;
2185     foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::DescendingOrder)) {
2186         if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode))
2187             tmp << itemInVicinity;
2188     }
2189     return tmp;
2190 }
2191
2192 /*!
2193     \overload
2194     \obsolete
2195
2196     Returns the topmost visible item at the specified \a position, or 0 if
2197     there are no items at this position.
2198
2199     This function is deprecated and returns incorrect results if the scene
2200     contains items that ignore transformations. Use the overload that takes
2201     a QTransform instead.
2202
2203     \sa items(), collidingItems(), {QGraphicsItem#Sorting}{Sorting}
2204 */
2205 QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position) const
2206 {
2207     QList<QGraphicsItem *> itemsAtPoint = items(position);
2208     return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
2209 }
2210
2211 /*!
2212     \since 4.6
2213
2214     Returns the topmost visible item at the specified \a position, or 0
2215     if there are no items at this position.
2216
2217     \a deviceTransform is the transformation that applies to the view, and needs to
2218     be provided if the scene contains items that ignore transformations.
2219
2220     \sa items(), collidingItems(), {QGraphicsItem#Sorting}{Sorting}
2221 */
2222 QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform &deviceTransform) const
2223 {
2224     QList<QGraphicsItem *> itemsAtPoint = items(position, Qt::IntersectsItemShape,
2225                                                 Qt::DescendingOrder, deviceTransform);
2226     return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
2227 }
2228
2229 /*!
2230     \fn QGraphicsScene::itemAt(qreal x, qreal y, const QTransform &deviceTransform) const
2231     \overload
2232     \since 4.6
2233
2234     Returns the topmost item at the position specified by (\a x, \a
2235     y), or 0 if there are no items at this position.
2236
2237     \a deviceTransform is the transformation that applies to the view, and needs to
2238     be provided if the scene contains items that ignore transformations.
2239
2240     This convenience function is equivalent to calling \c
2241     {itemAt(QPointF(x, y), deviceTransform)}.
2242 */
2243
2244 /*!
2245     \fn QGraphicsScene::itemAt(qreal x, qreal y) const
2246     \overload
2247     \obsolete
2248
2249     Returns the topmost item at the position specified by (\a x, \a
2250     y), or 0 if there are no items at this position.
2251
2252     This convenience function is equivalent to calling \c
2253     {itemAt(QPointF(x, y))}.
2254
2255     This function is deprecated and returns incorrect results if the scene
2256     contains items that ignore transformations. Use the overload that takes
2257     a QTransform instead.
2258 */
2259
2260 /*!
2261     Returns a list of all currently selected items. The items are
2262     returned in no particular order.
2263
2264     \sa setSelectionArea()
2265 */
2266 QList<QGraphicsItem *> QGraphicsScene::selectedItems() const
2267 {
2268     Q_D(const QGraphicsScene);
2269
2270     // Optimization: Lazily removes items that are not selected.
2271     QGraphicsScene *that = const_cast<QGraphicsScene *>(this);
2272     QSet<QGraphicsItem *> actuallySelectedSet;
2273     foreach (QGraphicsItem *item, that->d_func()->selectedItems) {
2274         if (item->isSelected())
2275             actuallySelectedSet << item;
2276     }
2277
2278     that->d_func()->selectedItems = actuallySelectedSet;
2279
2280     return d->selectedItems.values();
2281 }
2282
2283 /*!
2284     Returns the selection area that was previously set with
2285     setSelectionArea(), or an empty QPainterPath if no selection area has been
2286     set.
2287
2288     \sa setSelectionArea()
2289 */
2290 QPainterPath QGraphicsScene::selectionArea() const
2291 {
2292     Q_D(const QGraphicsScene);
2293     return d->selectionArea;
2294 }
2295
2296 /*!
2297     \since 4.6
2298
2299     Sets the selection area to \a path. All items within this area are
2300     immediately selected, and all items outside are unselected. You can get
2301     the list of all selected items by calling selectedItems().
2302
2303     \a deviceTransform is the transformation that applies to the view, and needs to
2304     be provided if the scene contains items that ignore transformations.
2305
2306     For an item to be selected, it must be marked as \e selectable
2307     (QGraphicsItem::ItemIsSelectable).
2308
2309     \sa clearSelection(), selectionArea()
2310 */
2311 void QGraphicsScene::setSelectionArea(const QPainterPath &path, const QTransform &deviceTransform)
2312 {
2313     setSelectionArea(path, Qt::IntersectsItemShape, deviceTransform);
2314 }
2315
2316 /*!
2317     \obsolete
2318     \overload
2319
2320     Sets the selection area to \a path.
2321
2322     This function is deprecated and leads to incorrect results if the scene
2323     contains items that ignore transformations. Use the overload that takes
2324     a QTransform instead.
2325 */
2326 void QGraphicsScene::setSelectionArea(const QPainterPath &path)
2327 {
2328     setSelectionArea(path, Qt::IntersectsItemShape, QTransform());
2329 }
2330
2331 /*!
2332     \obsolete
2333     \overload
2334     \since 4.3
2335
2336     Sets the selection area to \a path using \a mode to determine if items are
2337     included in the selection area.
2338
2339     \sa clearSelection(), selectionArea()
2340 */
2341 void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode)
2342 {
2343     setSelectionArea(path, mode, QTransform());
2344 }
2345
2346 /*!
2347     \overload
2348     \since 4.6
2349
2350     Sets the selection area to \a path using \a mode to determine if items are
2351     included in the selection area.
2352
2353     \a deviceTransform is the transformation that applies to the view, and needs to
2354     be provided if the scene contains items that ignore transformations.
2355
2356     \sa clearSelection(), selectionArea()
2357 */
2358 void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode,
2359                                       const QTransform &deviceTransform)
2360 {
2361     Q_D(QGraphicsScene);
2362
2363     // Note: with boolean path operations, we can improve performance here
2364     // quite a lot by "growing" the old path instead of replacing it. That
2365     // allows us to only check the intersect area for changes, instead of
2366     // reevaluating the whole path over again.
2367     d->selectionArea = path;
2368
2369     QSet<QGraphicsItem *> unselectItems = d->selectedItems;
2370
2371     // Disable emitting selectionChanged() for individual items.
2372     ++d->selectionChanging;
2373     bool changed = false;
2374
2375     // Set all items in path to selected.
2376     foreach (QGraphicsItem *item, items(path, mode, Qt::DescendingOrder, deviceTransform)) {
2377         if (item->flags() & QGraphicsItem::ItemIsSelectable) {
2378             if (!item->isSelected())
2379                 changed = true;
2380             unselectItems.remove(item);
2381             item->setSelected(true);
2382         }
2383     }
2384
2385     // Unselect all items outside path.
2386     foreach (QGraphicsItem *item, unselectItems) {
2387         item->setSelected(false);
2388         changed = true;
2389     }
2390
2391     // Reenable emitting selectionChanged() for individual items.
2392     --d->selectionChanging;
2393
2394     if (!d->selectionChanging && changed)
2395         emit selectionChanged();
2396 }
2397
2398 /*!
2399    Clears the current selection.
2400
2401    \sa setSelectionArea(), selectedItems()
2402 */
2403 void QGraphicsScene::clearSelection()
2404 {
2405     Q_D(QGraphicsScene);
2406
2407     // Disable emitting selectionChanged
2408     ++d->selectionChanging;
2409     bool changed = !d->selectedItems.isEmpty();
2410
2411     foreach (QGraphicsItem *item, d->selectedItems)
2412         item->setSelected(false);
2413     d->selectedItems.clear();
2414
2415     // Reenable emitting selectionChanged() for individual items.
2416     --d->selectionChanging;
2417
2418     if (!d->selectionChanging && changed)
2419         emit selectionChanged();
2420 }
2421
2422 /*!
2423     \since 4.4
2424
2425     Removes and deletes all items from the scene, but otherwise leaves the
2426     state of the scene unchanged.
2427
2428     \sa addItem()
2429 */
2430 void QGraphicsScene::clear()
2431 {
2432     Q_D(QGraphicsScene);
2433     // NB! We have to clear the index before deleting items; otherwise the
2434     // index might try to access dangling item pointers.
2435     d->index->clear();
2436     // NB! QGraphicsScenePrivate::unregisterTopLevelItem() removes items
2437     while (!d->topLevelItems.isEmpty())
2438         delete d->topLevelItems.first();
2439     Q_ASSERT(d->topLevelItems.isEmpty());
2440     d->lastItemCount = 0;
2441     d->allItemsIgnoreHoverEvents = true;
2442     d->allItemsUseDefaultCursor = true;
2443     d->allItemsIgnoreTouchEvents = true;
2444 }
2445
2446 /*!
2447     Groups all items in \a items into a new QGraphicsItemGroup, and returns a
2448     pointer to the group. The group is created with the common ancestor of \a
2449     items as its parent, and with position (0, 0). The items are all
2450     reparented to the group, and their positions and transformations are
2451     mapped to the group. If \a items is empty, this function will return an
2452     empty top-level QGraphicsItemGroup.
2453
2454     QGraphicsScene has ownership of the group item; you do not need to delete
2455     it. To dismantle (ungroup) a group, call destroyItemGroup().
2456
2457     \sa destroyItemGroup(), QGraphicsItemGroup::addToGroup()
2458 */
2459 QGraphicsItemGroup *QGraphicsScene::createItemGroup(const QList<QGraphicsItem *> &items)
2460 {
2461     // Build a list of the first item's ancestors
2462     QList<QGraphicsItem *> ancestors;
2463     int n = 0;
2464     if (!items.isEmpty()) {
2465         QGraphicsItem *parent = items.at(n++);
2466         while ((parent = parent->parentItem()))
2467             ancestors.append(parent);
2468     }
2469
2470     // Find the common ancestor for all items
2471     QGraphicsItem *commonAncestor = 0;
2472     if (!ancestors.isEmpty()) {
2473         while (n < items.size()) {
2474             int commonIndex = -1;
2475             QGraphicsItem *parent = items.at(n++);
2476             do {
2477                 int index = ancestors.indexOf(parent, qMax(0, commonIndex));
2478                 if (index != -1) {
2479                     commonIndex = index;
2480                     break;
2481                 }
2482             } while ((parent = parent->parentItem()));
2483
2484             if (commonIndex == -1) {
2485                 commonAncestor = 0;
2486                 break;
2487             }
2488
2489             commonAncestor = ancestors.at(commonIndex);
2490         }
2491     }
2492
2493     // Create a new group at that level
2494     QGraphicsItemGroup *group = new QGraphicsItemGroup(commonAncestor);
2495     if (!commonAncestor)
2496         addItem(group);
2497     foreach (QGraphicsItem *item, items)
2498         group->addToGroup(item);
2499     return group;
2500 }
2501
2502 /*!
2503     Reparents all items in \a group to \a group's parent item, then removes \a
2504     group from the scene, and finally deletes it. The items' positions and
2505     transformations are mapped from the group to the group's parent.
2506
2507     \sa createItemGroup(), QGraphicsItemGroup::removeFromGroup()
2508 */
2509 void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)
2510 {
2511     foreach (QGraphicsItem *item, group->children())
2512         group->removeFromGroup(item);
2513     removeItem(group);
2514     delete group;
2515 }
2516
2517 /*!
2518     Adds or moves the \a item and all its childen to this scene.
2519     This scene takes ownership of the \a item.
2520
2521     If the item is visible (i.e., QGraphicsItem::isVisible() returns
2522     true), QGraphicsScene will emit changed() once control goes back
2523     to the event loop.
2524
2525     If the item is already in a different scene, it will first be
2526     removed from its old scene, and then added to this scene as a
2527     top-level.
2528
2529     QGraphicsScene will send ItemSceneChange notifications to \a item
2530     while it is added to the scene. If item does not currently belong
2531     to a scene, only one notification is sent. If it does belong to
2532     scene already (i.e., it is moved to this scene), QGraphicsScene
2533     will send an addition notification as the item is removed from its
2534     previous scene.
2535
2536     If the item is a panel, the scene is active, and there is no
2537     active panel in the scene, then the item will be activated.
2538
2539     \sa removeItem(), addEllipse(), addLine(), addPath(), addPixmap(),
2540     addRect(), addText(), addWidget(), {QGraphicsItem#Sorting}{Sorting}
2541 */
2542 void QGraphicsScene::addItem(QGraphicsItem *item)
2543 {
2544     Q_D(QGraphicsScene);
2545     if (!item) {
2546         qWarning("QGraphicsScene::addItem: cannot add null item");
2547         return;
2548     }
2549     if (item->d_ptr->scene == this) {
2550         qWarning("QGraphicsScene::addItem: item has already been added to this scene");
2551         return;
2552     }
2553     // Remove this item from its existing scene
2554     if (QGraphicsScene *oldScene = item->d_ptr->scene)
2555         oldScene->removeItem(item);
2556
2557     // Notify the item that its scene is changing, and allow the item to
2558     // react.
2559     const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
2560                                                     QVariant::fromValue<QGraphicsScene *>(this)));
2561     QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
2562     if (targetScene != this) {
2563         if (targetScene && item->d_ptr->scene != targetScene)
2564             targetScene->addItem(item);
2565         return;
2566     }
2567
2568     // QDeclarativeItems do not rely on initial itemChanged message, as the componentComplete
2569     // function allows far more opportunity for delayed-construction optimization.
2570     if (!item->d_ptr->isDeclarativeItem) {
2571         if (d->unpolishedItems.isEmpty()) {
2572             QMetaMethod method = metaObject()->method(d->polishItemsIndex);
2573             method.invoke(this, Qt::QueuedConnection);
2574         }
2575         d->unpolishedItems.append(item);
2576         item->d_ptr->pendingPolish = true;
2577     }
2578
2579     // Detach this item from its parent if the parent's scene is different
2580     // from this scene.
2581     if (QGraphicsItem *itemParent = item->d_ptr->parent) {
2582         if (itemParent->d_ptr->scene != this)
2583             item->setParentItem(0);
2584     }
2585
2586     // Add the item to this scene
2587     item->d_func()->scene = targetScene;
2588
2589     // Add the item in the index
2590     d->index->addItem(item);
2591
2592     // Add to list of toplevels if this item is a toplevel.
2593     if (!item->d_ptr->parent)
2594         d->registerTopLevelItem(item);
2595
2596     // Add to list of items that require an update. We cannot assume that the
2597     // item is fully constructed, so calling item->update() can lead to a pure
2598     // virtual function call to boundingRect().
2599     d->markDirty(item);
2600     d->dirtyGrowingItemsBoundingRect = true;
2601
2602     // Disable selectionChanged() for individual items
2603     ++d->selectionChanging;
2604     int oldSelectedItemSize = d->selectedItems.size();
2605
2606     // Enable mouse tracking if the item accepts hover events or has a cursor set.
2607     if (d->allItemsIgnoreHoverEvents && d->itemAcceptsHoverEvents_helper(item)) {
2608         d->allItemsIgnoreHoverEvents = false;
2609         d->enableMouseTrackingOnViews();
2610     }
2611 #ifndef QT_NO_CURSOR
2612     if (d->allItemsUseDefaultCursor && item->d_ptr->hasCursor) {
2613         d->allItemsUseDefaultCursor = false;
2614         if (d->allItemsIgnoreHoverEvents) // already enabled otherwise
2615             d->enableMouseTrackingOnViews();
2616     }
2617 #endif //QT_NO_CURSOR
2618
2619     // Enable touch events if the item accepts touch events.
2620     if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) {
2621         d->allItemsIgnoreTouchEvents = false;
2622         d->enableTouchEventsOnViews();
2623     }
2624
2625 #ifndef QT_NO_GESTURES
2626     foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
2627         d->grabGesture(item, gesture);
2628 #endif
2629
2630     // Update selection lists
2631     if (item->isSelected())
2632         d->selectedItems << item;
2633     if (item->isWidget() && item->isVisible() && static_cast<QGraphicsWidget *>(item)->windowType() == Qt::Popup)
2634         d->addPopup(static_cast<QGraphicsWidget *>(item));
2635     if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
2636         d->enterModal(item);
2637
2638     // Update creation order focus chain. Make sure to leave the widget's
2639     // internal tab order intact.
2640     if (item->isWidget()) {
2641         QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
2642         if (!d->tabFocusFirst) {
2643             // No first tab focus widget - make this the first tab focus
2644             // widget.
2645             d->tabFocusFirst = widget;
2646         } else if (!widget->parentWidget()) {
2647             // Adding a widget that is not part of a tab focus chain.
2648             QGraphicsWidget *last = d->tabFocusFirst->d_func()->focusPrev;
2649             QGraphicsWidget *lastNew = widget->d_func()->focusPrev;
2650             last->d_func()->focusNext = widget;
2651             widget->d_func()->focusPrev = last;
2652             d->tabFocusFirst->d_func()->focusPrev = lastNew;
2653             lastNew->d_func()->focusNext = d->tabFocusFirst;
2654         }
2655     }
2656
2657     // Add all children recursively
2658     item->d_ptr->ensureSortedChildren();
2659     for (int i = 0; i < item->d_ptr->children.size(); ++i)
2660         addItem(item->d_ptr->children.at(i));
2661
2662     // Resolve font and palette.
2663     item->d_ptr->resolveFont(d->font.resolve());
2664     item->d_ptr->resolvePalette(d->palette.resolve());
2665
2666
2667     // Reenable selectionChanged() for individual items
2668     --d->selectionChanging;
2669     if (!d->selectionChanging && d->selectedItems.size() != oldSelectedItemSize)
2670         emit selectionChanged();
2671
2672     // Deliver post-change notification
2673     item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
2674
2675     // Update explicit activation
2676     bool autoActivate = true;
2677     if (!d->childExplicitActivation && item->d_ptr->explicitActivate)
2678         d->childExplicitActivation = item->d_ptr->wantsActive ? 1 : 2;
2679     if (d->childExplicitActivation && item->isPanel()) {
2680         if (d->childExplicitActivation == 1)
2681             setActivePanel(item);
2682         else
2683             autoActivate = false;
2684         d->childExplicitActivation = 0;
2685     } else if (!item->d_ptr->parent) {
2686         d->childExplicitActivation = 0;
2687     }
2688
2689     // Auto-activate this item's panel if nothing else has been activated
2690     if (autoActivate) {
2691         if (!d->lastActivePanel && !d->activePanel && item->isPanel()) {
2692             if (isActive())
2693                 setActivePanel(item);
2694             else
2695                 d->lastActivePanel = item;
2696         }
2697     }
2698
2699     if (item->d_ptr->flags & QGraphicsItem::ItemSendsScenePositionChanges)
2700         d->registerScenePosItem(item);
2701
2702     // Ensure that newly added items that have subfocus set, gain
2703     // focus automatically if there isn't a focus item already.
2704     if (!d->focusItem && item != d->lastFocusItem && item->focusItem() == item)
2705         item->focusItem()->setFocus();
2706
2707     d->updateInputMethodSensitivityInViews();
2708 }
2709
2710 /*!
2711     Creates and adds an ellipse item to the scene, and returns the item
2712     pointer. The geometry of the ellipse is defined by \a rect, and its pen
2713     and brush are initialized to \a pen and \a brush.
2714
2715     Note that the item's geometry is provided in item coordinates, and its
2716     position is initialized to (0, 0).
2717
2718     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2719     QGraphicsScene will emit changed() once control goes back to the event
2720     loop.
2721
2722     \sa addLine(), addPath(), addPixmap(), addRect(), addText(), addItem(),
2723     addWidget()
2724 */
2725 QGraphicsEllipseItem *QGraphicsScene::addEllipse(const QRectF &rect, const QPen &pen, const QBrush &brush)
2726 {
2727     QGraphicsEllipseItem *item = new QGraphicsEllipseItem(rect);
2728     item->setPen(pen);
2729     item->setBrush(brush);
2730     addItem(item);
2731     return item;
2732 }
2733
2734 /*!
2735     \fn QGraphicsEllipseItem *QGraphicsScene::addEllipse(qreal x, qreal y, qreal w, qreal h, const QPen &pen, const QBrush &brush)
2736     \since 4.3
2737
2738     This convenience function is equivalent to calling addEllipse(QRectF(\a x,
2739     \a y, \a w, \a h), \a pen, \a brush).
2740 */
2741
2742 /*!
2743     Creates and adds a line item to the scene, and returns the item
2744     pointer. The geometry of the line is defined by \a line, and its pen
2745     is initialized to \a pen.
2746
2747     Note that the item's geometry is provided in item coordinates, and its
2748     position is initialized to (0, 0).
2749
2750     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2751     QGraphicsScene will emit changed() once control goes back to the event
2752     loop.
2753
2754     \sa addEllipse(), addPath(), addPixmap(), addRect(), addText(), addItem(),
2755     addWidget()
2756 */
2757 QGraphicsLineItem *QGraphicsScene::addLine(const QLineF &line, const QPen &pen)
2758 {
2759     QGraphicsLineItem *item = new QGraphicsLineItem(line);
2760     item->setPen(pen);
2761     addItem(item);
2762     return item;
2763 }
2764
2765 /*!
2766     \fn QGraphicsLineItem *QGraphicsScene::addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen)
2767     \since 4.3
2768
2769     This convenience function is equivalent to calling addLine(QLineF(\a x1,
2770     \a y1, \a x2, \a y2), \a pen).
2771 */
2772
2773 /*!
2774     Creates and adds a path item to the scene, and returns the item
2775     pointer. The geometry of the path is defined by \a path, and its pen and
2776     brush are initialized to \a pen and \a brush.
2777
2778     Note that the item's geometry is provided in item coordinates, and its
2779     position is initialized to (0, 0).
2780
2781     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2782     QGraphicsScene will emit changed() once control goes back to the event
2783     loop.
2784
2785     \sa addEllipse(), addLine(), addPixmap(), addRect(), addText(), addItem(),
2786     addWidget()
2787 */
2788 QGraphicsPathItem *QGraphicsScene::addPath(const QPainterPath &path, const QPen &pen, const QBrush &brush)
2789 {
2790     QGraphicsPathItem *item = new QGraphicsPathItem(path);
2791     item->setPen(pen);
2792     item->setBrush(brush);
2793     addItem(item);
2794     return item;
2795 }
2796
2797 /*!
2798     Creates and adds a pixmap item to the scene, and returns the item
2799     pointer. The pixmap is defined by \a pixmap.
2800
2801     Note that the item's geometry is provided in item coordinates, and its
2802     position is initialized to (0, 0).
2803
2804     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2805     QGraphicsScene will emit changed() once control goes back to the event
2806     loop.
2807
2808     \sa addEllipse(), addLine(), addPath(), addRect(), addText(), addItem(),
2809     addWidget()
2810 */
2811 QGraphicsPixmapItem *QGraphicsScene::addPixmap(const QPixmap &pixmap)
2812 {
2813     QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
2814     addItem(item);
2815     return item;
2816 }
2817
2818 /*!
2819     Creates and adds a polygon item to the scene, and returns the item
2820     pointer. The polygon is defined by \a polygon, and its pen and
2821     brush are initialized to \a pen and \a brush.
2822
2823     Note that the item's geometry is provided in item coordinates, and its
2824     position is initialized to (0, 0).
2825
2826     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2827     QGraphicsScene will emit changed() once control goes back to the event
2828     loop.
2829
2830     \sa addEllipse(), addLine(), addPath(), addRect(), addText(), addItem(),
2831     addWidget()
2832 */
2833 QGraphicsPolygonItem *QGraphicsScene::addPolygon(const QPolygonF &polygon,
2834                                                  const QPen &pen, const QBrush &brush)
2835 {
2836     QGraphicsPolygonItem *item = new QGraphicsPolygonItem(polygon);
2837     item->setPen(pen);
2838     item->setBrush(brush);
2839     addItem(item);
2840     return item;
2841 }
2842
2843 /*!
2844     Creates and adds a rectangle item to the scene, and returns the item
2845     pointer. The geometry of the rectangle is defined by \a rect, and its pen
2846     and brush are initialized to \a pen and \a brush.
2847
2848     Note that the item's geometry is provided in item coordinates, and its
2849     position is initialized to (0, 0). For example, if a QRect(50, 50, 100,
2850     100) is added, its top-left corner will be at (50, 50) relative to the
2851     origin in the items coordinate system.
2852
2853     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2854     QGraphicsScene will emit changed() once control goes back to the event
2855     loop.
2856
2857     \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addText(),
2858     addItem(), addWidget()
2859 */
2860 QGraphicsRectItem *QGraphicsScene::addRect(const QRectF &rect, const QPen &pen, const QBrush &brush)
2861 {
2862     QGraphicsRectItem *item = new QGraphicsRectItem(rect);
2863     item->setPen(pen);
2864     item->setBrush(brush);
2865     addItem(item);
2866     return item;
2867 }
2868
2869 /*!
2870     \fn QGraphicsRectItem *QGraphicsScene::addRect(qreal x, qreal y, qreal w, qreal h, const QPen &pen, const QBrush &brush)
2871     \since 4.3
2872
2873     This convenience function is equivalent to calling addRect(QRectF(\a x,
2874     \a y, \a w, \a h), \a pen, \a brush).
2875 */
2876
2877 /*!
2878     Creates and adds a text item to the scene, and returns the item
2879     pointer. The text string is initialized to \a text, and its font
2880     is initialized to \a font.
2881
2882     The item's position is initialized to (0, 0).
2883
2884     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2885     QGraphicsScene will emit changed() once control goes back to the event
2886     loop.
2887
2888     \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
2889     addItem(), addWidget()
2890 */
2891 QGraphicsTextItem *QGraphicsScene::addText(const QString &text, const QFont &font)
2892 {
2893     QGraphicsTextItem *item = new QGraphicsTextItem(text);
2894     item->setFont(font);
2895     addItem(item);
2896     return item;
2897 }
2898
2899 /*!
2900     Creates and adds a QGraphicsSimpleTextItem to the scene, and returns the
2901     item pointer. The text string is initialized to \a text, and its font is
2902     initialized to \a font.
2903
2904     The item's position is initialized to (0, 0).
2905
2906     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2907     QGraphicsScene will emit changed() once control goes back to the event
2908     loop.
2909
2910     \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
2911     addItem(), addWidget()
2912 */
2913 QGraphicsSimpleTextItem *QGraphicsScene::addSimpleText(const QString &text, const QFont &font)
2914 {
2915     QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem(text);
2916     item->setFont(font);
2917     addItem(item);
2918     return item;
2919 }
2920
2921 /*!
2922     Creates a new QGraphicsProxyWidget for \a widget, adds it to the scene,
2923     and returns a pointer to the proxy. \a wFlags set the default window flags
2924     for the embedding proxy widget.
2925
2926     The item's position is initialized to (0, 0).
2927
2928     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2929     QGraphicsScene will emit changed() once control goes back to the event
2930     loop.
2931
2932     Note that widgets with the Qt::WA_PaintOnScreen widget attribute
2933     set and widgets that wrap an external application or controller
2934     are not supported. Examples are QGLWidget and QAxWidget.
2935
2936     \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
2937     addText(), addSimpleText(), addItem()
2938 */
2939 QGraphicsProxyWidget *QGraphicsScene::addWidget(QWidget *widget, Qt::WindowFlags wFlags)
2940 {
2941     QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(0, wFlags);
2942     proxy->setWidget(widget);
2943     addItem(proxy);
2944     return proxy;
2945 }
2946
2947 /*!
2948     Removes the item \a item and all its children from the scene.  The
2949     ownership of \a item is passed on to the caller (i.e.,
2950     QGraphicsScene will no longer delete \a item when destroyed).
2951
2952     \sa addItem()
2953 */
2954 void QGraphicsScene::removeItem(QGraphicsItem *item)
2955 {
2956     // ### Refactoring: This function shares much functionality with _q_removeItemLater()
2957     Q_D(QGraphicsScene);
2958     if (!item) {
2959         qWarning("QGraphicsScene::removeItem: cannot remove 0-item");
2960         return;
2961     }
2962     if (item->scene() != this) {
2963         qWarning("QGraphicsScene::removeItem: item %p's scene (%p)"
2964                  " is different from this scene (%p)",
2965                  item, item->scene(), this);
2966         return;
2967     }
2968
2969     // Notify the item that it's scene is changing to 0, allowing the item to
2970     // react.
2971     const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
2972                                                     QVariant::fromValue<QGraphicsScene *>(0)));
2973     QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
2974     if (targetScene != 0 && targetScene != this) {
2975         targetScene->addItem(item);
2976         return;
2977     }
2978
2979     d->removeItemHelper(item);
2980
2981     // Deliver post-change notification
2982     item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
2983
2984     d->updateInputMethodSensitivityInViews();
2985 }
2986
2987 /*!