a63403a039aee44d5547176cbb211b2f1cb276a4
[profile/ivi/qtbase.git] / src / widgets / graphicsview / qgraphicsscene.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
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     \inmodule QtWidgets
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 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 <QtWidgets/qapplication.h>
233 #include <QtWidgets/qdesktopwidget.h>
234 #include <QtGui/qevent.h>
235 #include <QtWidgets/qgraphicslayout.h>
236 #include <QtWidgets/qgraphicsproxywidget.h>
237 #include <QtWidgets/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 <QtWidgets/qstyleoption.h>
244 #include <QtWidgets/qtooltip.h>
245 #include <QtGui/qtransform.h>
246 #include <QtGui/qinputmethod.h>
247 #include <QtWidgets/qgraphicseffect.h>
248 #ifndef QT_NO_ACCESSIBILITY
249 # include <QtGui/qaccessible.h>
250 #endif
251 #include <private/qapplication_p.h>
252 #include <private/qobject_p.h>
253 #ifdef Q_WS_X11
254 #include <private/qt_x11_p.h>
255 #endif
256 #include <private/qgraphicseffect_p.h>
257 #include <private/qgesturemanager_p.h>
258 #include <private/qpathclipper_p.h>
259
260 // #define GESTURE_DEBUG
261 #ifndef GESTURE_DEBUG
262 # define DEBUG if (0) qDebug
263 #else
264 # define DEBUG qDebug
265 #endif
266
267 QT_BEGIN_NAMESPACE
268
269 bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
270
271 static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent)
272 {
273     hover->setWidget(mouseEvent->widget());
274     hover->setPos(mouseEvent->pos());
275     hover->setScenePos(mouseEvent->scenePos());
276     hover->setScreenPos(mouseEvent->screenPos());
277     hover->setLastPos(mouseEvent->lastPos());
278     hover->setLastScenePos(mouseEvent->lastScenePos());
279     hover->setLastScreenPos(mouseEvent->lastScreenPos());
280     hover->setModifiers(mouseEvent->modifiers());
281     hover->setAccepted(mouseEvent->isAccepted());
282 }
283
284 /*!
285     \internal
286 */
287 QGraphicsScenePrivate::QGraphicsScenePrivate()
288     : indexMethod(QGraphicsScene::BspTreeIndex),
289       index(0),
290       lastItemCount(0),
291       hasSceneRect(false),
292       dirtyGrowingItemsBoundingRect(true),
293       updateAll(false),
294       calledEmitUpdated(false),
295       processDirtyItemsEmitted(false),
296       needSortTopLevelItems(true),
297       holesInTopLevelSiblingIndex(false),
298       topLevelSequentialOrdering(true),
299       scenePosDescendantsUpdatePending(false),
300       stickyFocus(false),
301       hasFocus(false),
302       lastMouseGrabberItemHasImplicitMouseGrab(false),
303       allItemsIgnoreHoverEvents(true),
304       allItemsUseDefaultCursor(true),
305       painterStateProtection(true),
306       sortCacheEnabled(false),
307       allItemsIgnoreTouchEvents(true),
308       selectionChanging(0),
309       rectAdjust(2),
310       focusItem(0),
311       lastFocusItem(0),
312       passiveFocusItem(0),
313       tabFocusFirst(0),
314       activePanel(0),
315       lastActivePanel(0),
316       activationRefCount(0),
317       childExplicitActivation(0),
318       lastMouseGrabberItem(0),
319       dragDropItem(0),
320       enterWidget(0),
321       lastDropAction(Qt::IgnoreAction),
322       style(0)
323 {
324 }
325
326 /*!
327     \internal
328 */
329 void QGraphicsScenePrivate::init()
330 {
331     Q_Q(QGraphicsScene);
332
333     index = new QGraphicsSceneBspTreeIndex(q);
334
335     // Keep this index so we can check for connected slots later on.
336     changedSignalIndex = signalIndex("changed(QList<QRectF>)");
337     processDirtyItemsIndex = q->metaObject()->indexOfSlot("_q_processDirtyItems()");
338     polishItemsIndex = q->metaObject()->indexOfSlot("_q_polishItems()");
339
340     qApp->d_func()->scene_list.append(q);
341     q->update();
342 }
343
344 /*!
345     \internal
346 */
347 QGraphicsScenePrivate *QGraphicsScenePrivate::get(QGraphicsScene *q)
348 {
349     return q->d_func();
350 }
351
352 void QGraphicsScenePrivate::_q_emitUpdated()
353 {
354     Q_Q(QGraphicsScene);
355     calledEmitUpdated = false;
356
357     if (dirtyGrowingItemsBoundingRect) {
358         if (!hasSceneRect) {
359             const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
360             growingItemsBoundingRect |= q->itemsBoundingRect();
361             if (oldGrowingItemsBoundingRect != growingItemsBoundingRect)
362                 emit q->sceneRectChanged(growingItemsBoundingRect);
363         }
364         dirtyGrowingItemsBoundingRect = false;
365     }
366
367     // Ensure all views are connected if anything is connected. This disables
368     // the optimization that items send updates directly to the views, but it
369     // needs to happen in order to keep compatibility with the behavior from
370     // Qt 4.4 and backward.
371     if (isSignalConnected(changedSignalIndex)) {
372         for (int i = 0; i < views.size(); ++i) {
373             QGraphicsView *view = views.at(i);
374             if (!view->d_func()->connectedToScene) {
375                 view->d_func()->connectedToScene = true;
376                 q->connect(q, SIGNAL(changed(QList<QRectF>)),
377                            views.at(i), SLOT(updateScene(QList<QRectF>)));
378             }
379         }
380     } else {
381         if (views.isEmpty()) {
382             updateAll = false;
383             return;
384         }
385         for (int i = 0; i < views.size(); ++i)
386             views.at(i)->d_func()->processPendingUpdates();
387         // It's important that we update all views before we dispatch, hence two for-loops.
388         for (int i = 0; i < views.size(); ++i)
389             views.at(i)->d_func()->dispatchPendingUpdateRequests();
390         return;
391     }
392
393     // Notify the changes to anybody interested.
394     QList<QRectF> oldUpdatedRects;
395     oldUpdatedRects = updateAll ? (QList<QRectF>() << q->sceneRect()) : updatedRects;
396     updateAll = false;
397     updatedRects.clear();
398     emit q->changed(oldUpdatedRects);
399 }
400
401 /*!
402     \internal
403
404     ### This function is almost identical to QGraphicsItemPrivate::addChild().
405 */
406 void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item)
407 {
408     item->d_ptr->ensureSequentialSiblingIndex();
409     needSortTopLevelItems = true; // ### maybe false
410     item->d_ptr->siblingIndex = topLevelItems.size();
411     topLevelItems.append(item);
412 }
413
414 /*!
415     \internal
416
417     ### This function is almost identical to QGraphicsItemPrivate::removeChild().
418 */
419 void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
420 {
421     if (!holesInTopLevelSiblingIndex)
422         holesInTopLevelSiblingIndex = item->d_ptr->siblingIndex != topLevelItems.size() - 1;
423     if (topLevelSequentialOrdering && !holesInTopLevelSiblingIndex)
424         topLevelItems.removeAt(item->d_ptr->siblingIndex);
425     else
426         topLevelItems.removeOne(item);
427     // NB! Do not use topLevelItems.removeAt(item->d_ptr->siblingIndex) because
428     // the item is not guaranteed to be at the index after the list is sorted
429     // (see ensureSortedTopLevelItems()).
430     item->d_ptr->siblingIndex = -1;
431     if (topLevelSequentialOrdering)
432         topLevelSequentialOrdering = !holesInTopLevelSiblingIndex;
433 }
434
435 /*!
436     \internal
437 */
438 void QGraphicsScenePrivate::_q_polishItems()
439 {
440     if (unpolishedItems.isEmpty())
441         return;
442
443     const QVariant booleanTrueVariant(true);
444     QGraphicsItem *item = 0;
445     QGraphicsItemPrivate *itemd = 0;
446     const int oldUnpolishedCount = unpolishedItems.count();
447
448     for (int i = 0; i < oldUnpolishedCount; ++i) {
449         item = unpolishedItems.at(i);
450         if (!item)
451             continue;
452         itemd = item->d_ptr.data();
453         itemd->pendingPolish = false;
454         if (!itemd->explicitlyHidden) {
455             item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
456             item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
457         }
458         if (itemd->isWidget) {
459             QEvent event(QEvent::Polish);
460             QApplication::sendEvent((QGraphicsWidget *)item, &event);
461         }
462     }
463
464     if (unpolishedItems.count() == oldUnpolishedCount) {
465         // No new items were added to the vector.
466         unpolishedItems.clear();
467     } else {
468         // New items were appended; keep them and remove the old ones.
469         unpolishedItems.remove(0, oldUnpolishedCount);
470         unpolishedItems.squeeze();
471         QMetaObject::invokeMethod(q_ptr, "_q_polishItems", Qt::QueuedConnection);
472     }
473 }
474
475 void QGraphicsScenePrivate::_q_processDirtyItems()
476 {
477     processDirtyItemsEmitted = false;
478
479     if (updateAll) {
480         Q_ASSERT(calledEmitUpdated);
481         // No need for further processing (except resetting the dirty states).
482         // The growingItemsBoundingRect is updated in _q_emitUpdated.
483         for (int i = 0; i < topLevelItems.size(); ++i)
484             resetDirtyItem(topLevelItems.at(i), /*recursive=*/true);
485         return;
486     }
487
488     const bool wasPendingSceneUpdate = calledEmitUpdated;
489     const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
490
491     // Process items recursively.
492     for (int i = 0; i < topLevelItems.size(); ++i)
493         processDirtyItemsRecursive(topLevelItems.at(i));
494
495     dirtyGrowingItemsBoundingRect = false;
496     if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect)
497         emit q_func()->sceneRectChanged(growingItemsBoundingRect);
498
499     if (wasPendingSceneUpdate)
500         return;
501
502     for (int i = 0; i < views.size(); ++i)
503         views.at(i)->d_func()->processPendingUpdates();
504
505     if (calledEmitUpdated) {
506         // We did a compatibility QGraphicsScene::update in processDirtyItemsRecursive
507         // and we cannot wait for the control to reach the eventloop before the
508         // changed signal is emitted, so we emit it now.
509         _q_emitUpdated();
510     }
511
512     // Immediately dispatch all pending update requests on the views.
513     for (int i = 0; i < views.size(); ++i)
514         views.at(i)->d_func()->dispatchPendingUpdateRequests();
515 }
516
517 /*!
518     \internal
519 */
520 void QGraphicsScenePrivate::setScenePosItemEnabled(QGraphicsItem *item, bool enabled)
521 {
522     QGraphicsItem *p = item->d_ptr->parent;
523     while (p) {
524         p->d_ptr->scenePosDescendants = enabled;
525         p = p->d_ptr->parent;
526     }
527     if (!enabled && !scenePosDescendantsUpdatePending) {
528         scenePosDescendantsUpdatePending = true;
529         QMetaObject::invokeMethod(q_func(), "_q_updateScenePosDescendants", Qt::QueuedConnection);
530     }
531 }
532
533 /*!
534     \internal
535 */
536 void QGraphicsScenePrivate::registerScenePosItem(QGraphicsItem *item)
537 {
538     scenePosItems.insert(item);
539     setScenePosItemEnabled(item, true);
540 }
541
542 /*!
543     \internal
544 */
545 void QGraphicsScenePrivate::unregisterScenePosItem(QGraphicsItem *item)
546 {
547     scenePosItems.remove(item);
548     setScenePosItemEnabled(item, false);
549 }
550
551 /*!
552     \internal
553 */
554 void QGraphicsScenePrivate::_q_updateScenePosDescendants()
555 {
556     foreach (QGraphicsItem *item, scenePosItems) {
557         QGraphicsItem *p = item->d_ptr->parent;
558         while (p) {
559             p->d_ptr->scenePosDescendants = 1;
560             p = p->d_ptr->parent;
561         }
562     }
563     scenePosDescendantsUpdatePending = false;
564 }
565
566 /*!
567     \internal
568
569     Schedules an item for removal. This function leaves some stale indexes
570     around in the BSP tree if called from the item's destructor; these will
571     be cleaned up the next time someone triggers purgeRemovedItems().
572
573     Note: This function might get called from QGraphicsItem's destructor. \a item is
574     being destroyed, so we cannot call any pure virtual functions on it (such
575     as boundingRect()). Also, it is unnecessary to update the item's own state
576     in any way.
577 */
578 void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
579 {
580     Q_Q(QGraphicsScene);
581
582     // Clear focus on the item to remove any reference in the focusWidget chain.
583     item->clearFocus();
584
585     markDirty(item, QRectF(), /*invalidateChildren=*/false, /*force=*/false,
586               /*ignoreOpacity=*/false, /*removingItemFromScene=*/true);
587
588     if (item->d_ptr->inDestructor) {
589         // The item is actually in its destructor, we call the special method in the index.
590         index->deleteItem(item);
591     } else {
592         // Can potentially call item->boundingRect() (virtual function), that's why
593         // we only can call this function if the item is not in its destructor.
594         index->removeItem(item);
595     }
596
597     item->d_ptr->clearSubFocus();
598
599     if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges)
600         unregisterScenePosItem(item);
601
602     QGraphicsScene *oldScene = item->d_func()->scene;
603     item->d_func()->scene = 0;
604
605     //We need to remove all children first because they might use their parent
606     //attributes (e.g. sceneTransform).
607     if (!item->d_ptr->inDestructor) {
608         // Remove all children recursively
609         for (int i = 0; i < item->d_ptr->children.size(); ++i)
610             q->removeItem(item->d_ptr->children.at(i));
611     }
612
613     if (!item->d_ptr->inDestructor && item == tabFocusFirst) {
614         QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
615         widget->d_func()->fixFocusChainBeforeReparenting(0, oldScene, 0);
616     }
617
618     // Unregister focus proxy.
619     item->d_ptr->resetFocusProxy();
620
621     // Remove from parent, or unregister from toplevels.
622     if (QGraphicsItem *parentItem = item->parentItem()) {
623         if (parentItem->scene()) {
624             Q_ASSERT_X(parentItem->scene() == q, "QGraphicsScene::removeItem",
625                        "Parent item's scene is different from this item's scene");
626             item->setParentItem(0);
627         }
628     } else {
629         unregisterTopLevelItem(item);
630     }
631
632     // Reset the mouse grabber and focus item data.
633     if (item == focusItem)
634         focusItem = 0;
635     if (item == lastFocusItem)
636         lastFocusItem = 0;
637     if (item == passiveFocusItem)
638         passiveFocusItem = 0;
639     if (item == activePanel) {
640         // ### deactivate...
641         activePanel = 0;
642     }
643     if (item == lastActivePanel)
644         lastActivePanel = 0;
645
646     // Cancel active touches
647     {
648         QMap<int, QGraphicsItem *>::iterator it = itemForTouchPointId.begin();
649         while (it != itemForTouchPointId.end()) {
650             if (it.value() == item) {
651                 sceneCurrentTouchPoints.remove(it.key());
652                 it = itemForTouchPointId.erase(it);
653             } else {
654                 ++it;
655             }
656         }
657     }
658
659     // Disable selectionChanged() for individual items
660     ++selectionChanging;
661     int oldSelectedItemsSize = selectedItems.size();
662
663     // Update selected & hovered item bookkeeping
664     selectedItems.remove(item);
665     hoverItems.removeAll(item);
666     cachedItemsUnderMouse.removeAll(item);
667     if (item->d_ptr->pendingPolish) {
668         const int unpolishedIndex = unpolishedItems.indexOf(item);
669         if (unpolishedIndex != -1)
670             unpolishedItems[unpolishedIndex] = 0;
671         item->d_ptr->pendingPolish = false;
672     }
673     resetDirtyItem(item);
674
675     //We remove all references of item from the sceneEventFilter arrays
676     QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = sceneEventFilters.begin();
677     while (iterator != sceneEventFilters.end()) {
678         if (iterator.value() == item || iterator.key() == item)
679             iterator = sceneEventFilters.erase(iterator);
680         else
681             ++iterator;
682     }
683
684     if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
685         leaveModal(item);
686
687     // Reset the mouse grabber and focus item data.
688     if (mouseGrabberItems.contains(item))
689         ungrabMouse(item, /* item is dying */ item->d_ptr->inDestructor);
690
691     // Reset the keyboard grabber
692     if (keyboardGrabberItems.contains(item))
693         ungrabKeyboard(item, /* item is dying */ item->d_ptr->inDestructor);
694
695     // Reset the last mouse grabber item
696     if (item == lastMouseGrabberItem)
697         lastMouseGrabberItem = 0;
698
699     // Reset the current drop item
700     if (item == dragDropItem)
701         dragDropItem = 0;
702
703     // Reenable selectionChanged() for individual items
704     --selectionChanging;
705     if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize)
706         emit q->selectionChanged();
707
708 #ifndef QT_NO_GESTURES
709     QHash<QGesture *, QGraphicsObject *>::iterator it;
710     for (it = gestureTargets.begin(); it != gestureTargets.end();) {
711         if (it.value() == item)
712             it = gestureTargets.erase(it);
713         else
714             ++it;
715     }
716
717     QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item);
718     cachedTargetItems.removeOne(dummy);
719     cachedItemGestures.remove(dummy);
720     cachedAlreadyDeliveredGestures.remove(dummy);
721
722     foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
723         ungrabGesture(item, gesture);
724 #endif // QT_NO_GESTURES
725 }
726
727 /*!
728     \internal
729 */
730 void QGraphicsScenePrivate::setActivePanelHelper(QGraphicsItem *item, bool duringActivationEvent)
731 {
732     Q_Q(QGraphicsScene);
733     if (item && item->scene() != q) {
734         qWarning("QGraphicsScene::setActivePanel: item %p must be part of this scene",
735                  item);
736         return;
737     }
738
739     // Ensure the scene has focus when we change panel activation.
740     q->setFocus(Qt::ActiveWindowFocusReason);
741
742     // Find the item's panel.
743     QGraphicsItem *panel = item ? item->panel() : 0;
744     lastActivePanel = panel ? activePanel : 0;
745     if (panel == activePanel || (!q->isActive() && !duringActivationEvent))
746         return;
747
748     // Deactivate the last active panel.
749     if (activePanel) {
750         if (QGraphicsItem *fi = activePanel->focusItem()) {
751             // Remove focus from the current focus item.
752             if (fi == q->focusItem())
753                 q->setFocusItem(0, Qt::ActiveWindowFocusReason);
754         }
755
756         QEvent event(QEvent::WindowDeactivate);
757         q->sendEvent(activePanel, &event);
758     } else if (panel && !duringActivationEvent) {
759         // Deactivate the scene if changing activation to a panel.
760         QEvent event(QEvent::WindowDeactivate);
761         foreach (QGraphicsItem *item, q->items()) {
762             if (item->isVisible() && !item->isPanel() && !item->parentItem())
763                 q->sendEvent(item, &event);
764         }
765     }
766
767     // Update activate state.
768     activePanel = panel;
769     QEvent event(QEvent::ActivationChange);
770     QApplication::sendEvent(q, &event);
771
772     // Activate
773     if (panel) {
774         QEvent event(QEvent::WindowActivate);
775         q->sendEvent(panel, &event);
776
777         // Set focus on the panel's focus item.
778         if (QGraphicsItem *focusItem = panel->focusItem())
779             focusItem->setFocus(Qt::ActiveWindowFocusReason);
780     } else if (q->isActive()) {
781         // Activate the scene
782         QEvent event(QEvent::WindowActivate);
783         foreach (QGraphicsItem *item, q->items()) {
784             if (item->isVisible() && !item->isPanel() && !item->parentItem())
785                 q->sendEvent(item, &event);
786         }
787     }
788 }
789
790 /*!
791     \internal
792 */
793 void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
794                                                Qt::FocusReason focusReason)
795 {
796     Q_Q(QGraphicsScene);
797     if (item == focusItem)
798         return;
799
800     // Clear focus if asked to set focus on something that can't
801     // accept input focus.
802     if (item && (!(item->flags() & QGraphicsItem::ItemIsFocusable)
803                  || !item->isVisible() || !item->isEnabled())) {
804         item = 0;
805     }
806
807     // Set focus on the scene if an item requests focus.
808     if (item) {
809         q->setFocus(focusReason);
810         if (item == focusItem)
811             return;
812     }
813
814     if (focusItem) {
815         lastFocusItem = focusItem;
816
817 #ifndef QT_NO_IM
818         if (lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod) {
819             // Close any external input method panel. This happens
820             // automatically by removing WA_InputMethodEnabled on
821             // the views, but if we are changing focus, we have to
822             // do it ourselves.
823             if (qApp)
824                 qApp->inputMethod()->commit();
825         }
826 #endif //QT_NO_IM
827
828         focusItem = 0;
829         QFocusEvent event(QEvent::FocusOut, focusReason);
830         sendEvent(lastFocusItem, &event);
831     }
832
833     // This handles the case that the item has been removed from the
834     // scene in response to the FocusOut event.
835     if (item && item->scene() != q)
836         item = 0;
837
838     if (item)
839         focusItem = item;
840     updateInputMethodSensitivityInViews();
841
842 #ifndef QT_NO_ACCESSIBILITY
843     if (focusItem) {
844         if (QGraphicsObject *focusObj = focusItem->toGraphicsObject()) {
845             QAccessibleEvent event(focusObj, QAccessible::Focus);
846             QAccessible::updateAccessibility(&event);
847         }
848     }
849 #endif
850     if (item) {
851         QFocusEvent event(QEvent::FocusIn, focusReason);
852         sendEvent(item, &event);
853     }
854 }
855
856 /*!
857     \internal
858 */
859 void QGraphicsScenePrivate::addPopup(QGraphicsWidget *widget)
860 {
861     Q_ASSERT(widget);
862     Q_ASSERT(!popupWidgets.contains(widget));
863     popupWidgets << widget;
864     if (QGraphicsWidget *focusWidget = widget->focusWidget()) {
865         focusWidget->setFocus(Qt::PopupFocusReason);
866     } else {
867         grabKeyboard((QGraphicsItem *)widget);
868         if (focusItem && popupWidgets.size() == 1) {
869             QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
870             sendEvent(focusItem, &event);
871         }
872     }
873     grabMouse((QGraphicsItem *)widget);
874 }
875
876 /*!
877     \internal
878
879     Remove \a widget from the popup list. Important notes:
880
881     \a widget is guaranteed to be in the list of popups, but it might not be
882     the last entry; you can hide any item in the pop list before the others,
883     and this must cause all later mouse grabbers to lose the grab.
884 */
885 void QGraphicsScenePrivate::removePopup(QGraphicsWidget *widget, bool itemIsDying)
886 {
887     Q_ASSERT(widget);
888     int index = popupWidgets.indexOf(widget);
889     Q_ASSERT(index != -1);
890
891     for (int i = popupWidgets.size() - 1; i >= index; --i) {
892         QGraphicsWidget *widget = popupWidgets.takeLast();
893         ungrabMouse(widget, itemIsDying);
894         if (focusItem && popupWidgets.isEmpty()) {
895             QFocusEvent event(QEvent::FocusIn, Qt::PopupFocusReason);
896             sendEvent(focusItem, &event);
897         } else if (keyboardGrabberItems.contains(static_cast<QGraphicsItem *>(widget))) {
898             ungrabKeyboard(static_cast<QGraphicsItem *>(widget), itemIsDying);
899         }
900         if (!itemIsDying && widget->isVisible()) {
901             widget->QGraphicsItem::d_ptr->setVisibleHelper(false, /* explicit = */ false);
902         }
903     }
904 }
905
906 /*!
907     \internal
908 */
909 void QGraphicsScenePrivate::grabMouse(QGraphicsItem *item, bool implicit)
910 {
911     // Append to list of mouse grabber items, and send a mouse grab event.
912     if (mouseGrabberItems.contains(item)) {
913         if (mouseGrabberItems.last() == item) {
914             Q_ASSERT(!implicit);
915             if (!lastMouseGrabberItemHasImplicitMouseGrab) {
916                 qWarning("QGraphicsItem::grabMouse: already a mouse grabber");
917             } else {
918                 // Upgrade to an explicit mouse grab
919                 lastMouseGrabberItemHasImplicitMouseGrab = false;
920             }
921         } else {
922             qWarning("QGraphicsItem::grabMouse: already blocked by mouse grabber: %p",
923                      mouseGrabberItems.last());
924         }
925         return;
926     }
927
928     // Send ungrab event to the last grabber.
929     if (!mouseGrabberItems.isEmpty()) {
930         QGraphicsItem *last = mouseGrabberItems.last();
931         if (lastMouseGrabberItemHasImplicitMouseGrab) {
932             // Implicit mouse grab is immediately lost.
933             last->ungrabMouse();
934         } else {
935             // Just send ungrab event to current grabber.
936             QEvent ungrabEvent(QEvent::UngrabMouse);
937             sendEvent(last, &ungrabEvent);
938         }
939     }
940
941     mouseGrabberItems << item;
942     lastMouseGrabberItemHasImplicitMouseGrab = implicit;
943
944     // Send grab event to current grabber.
945     QEvent grabEvent(QEvent::GrabMouse);
946     sendEvent(item, &grabEvent);
947 }
948
949 /*!
950     \internal
951 */
952 void QGraphicsScenePrivate::ungrabMouse(QGraphicsItem *item, bool itemIsDying)
953 {
954     int index = mouseGrabberItems.indexOf(item);
955     if (index == -1) {
956         qWarning("QGraphicsItem::ungrabMouse: not a mouse grabber");
957         return;
958     }
959
960     if (item != mouseGrabberItems.last()) {
961         // Recursively ungrab the next mouse grabber until we reach this item
962         // to ensure state consistency.
963         ungrabMouse(mouseGrabberItems.at(index + 1), itemIsDying);
964     }
965     if (!popupWidgets.isEmpty() && item == popupWidgets.last()) {
966         // If the item is a popup, go via removePopup to ensure state
967         // consistency and that it gets hidden correctly - beware that
968         // removePopup() reenters this function to continue removing the grab.
969         removePopup((QGraphicsWidget *)item, itemIsDying);
970         return;
971     }
972
973     // Send notification about mouse ungrab.
974     if (!itemIsDying) {
975         QEvent event(QEvent::UngrabMouse);
976         sendEvent(item, &event);
977     }
978
979     // Remove the item from the list of grabbers. Whenever this happens, we
980     // reset the implicitGrab (there can be only ever be one implicit grabber
981     // in a scene, and it is always the latest grabber; if the implicit grab
982     // is lost, it is not automatically regained.
983     mouseGrabberItems.takeLast();
984     lastMouseGrabberItemHasImplicitMouseGrab = false;
985
986     // Send notification about mouse regrab. ### It's unfortunate that all the
987     // items get a GrabMouse event, but this is a rare case with a simple
988     // implementation and it does ensure a consistent state.
989     if (!itemIsDying && !mouseGrabberItems.isEmpty()) {
990         QGraphicsItem *last = mouseGrabberItems.last();
991         QEvent event(QEvent::GrabMouse);
992         sendEvent(last, &event);
993     }
994 }
995
996 /*!
997     \internal
998 */
999 void QGraphicsScenePrivate::clearMouseGrabber()
1000 {
1001     if (!mouseGrabberItems.isEmpty())
1002         mouseGrabberItems.first()->ungrabMouse();
1003     lastMouseGrabberItem = 0;
1004 }
1005
1006 /*!
1007     \internal
1008 */
1009 void QGraphicsScenePrivate::grabKeyboard(QGraphicsItem *item)
1010 {
1011     if (keyboardGrabberItems.contains(item)) {
1012         if (keyboardGrabberItems.last() == item)
1013             qWarning("QGraphicsItem::grabKeyboard: already a keyboard grabber");
1014         else
1015             qWarning("QGraphicsItem::grabKeyboard: already blocked by keyboard grabber: %p",
1016                      keyboardGrabberItems.last());
1017         return;
1018     }
1019
1020     // Send ungrab event to the last grabber.
1021     if (!keyboardGrabberItems.isEmpty()) {
1022         // Just send ungrab event to current grabber.
1023         QEvent ungrabEvent(QEvent::UngrabKeyboard);
1024         sendEvent(keyboardGrabberItems.last(), &ungrabEvent);
1025     }
1026
1027     keyboardGrabberItems << item;
1028
1029     // Send grab event to current grabber.
1030     QEvent grabEvent(QEvent::GrabKeyboard);
1031     sendEvent(item, &grabEvent);
1032 }
1033
1034 /*!
1035     \internal
1036 */
1037 void QGraphicsScenePrivate::ungrabKeyboard(QGraphicsItem *item, bool itemIsDying)
1038 {
1039     int index = keyboardGrabberItems.lastIndexOf(item);
1040     if (index == -1) {
1041         qWarning("QGraphicsItem::ungrabKeyboard: not a keyboard grabber");
1042         return;
1043     }
1044     if (item != keyboardGrabberItems.last()) {
1045         // Recursively ungrab the topmost keyboard grabber until we reach this
1046         // item to ensure state consistency.
1047         ungrabKeyboard(keyboardGrabberItems.at(index + 1), itemIsDying);
1048     }
1049
1050     // Send notification about keyboard ungrab.
1051     if (!itemIsDying) {
1052         QEvent event(QEvent::UngrabKeyboard);
1053         sendEvent(item, &event);
1054     }
1055
1056     // Remove the item from the list of grabbers.
1057     keyboardGrabberItems.takeLast();
1058
1059     // Send notification about mouse regrab.
1060     if (!itemIsDying && !keyboardGrabberItems.isEmpty()) {
1061         QGraphicsItem *last = keyboardGrabberItems.last();
1062         QEvent event(QEvent::GrabKeyboard);
1063         sendEvent(last, &event);
1064     }
1065 }
1066
1067 /*!
1068     \internal
1069 */
1070 void QGraphicsScenePrivate::clearKeyboardGrabber()
1071 {
1072     if (!keyboardGrabberItems.isEmpty())
1073         ungrabKeyboard(keyboardGrabberItems.first());
1074 }
1075
1076 void QGraphicsScenePrivate::enableMouseTrackingOnViews()
1077 {
1078     foreach (QGraphicsView *view, views)
1079         view->viewport()->setMouseTracking(true);
1080 }
1081
1082 /*!
1083     Returns all items for the screen position in \a event.
1084 */
1085 QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &screenPos,
1086                                                               const QPointF &scenePos,
1087                                                               QWidget *widget) const
1088 {
1089     Q_Q(const QGraphicsScene);
1090     QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
1091     if (!view)
1092         return q->items(scenePos, Qt::IntersectsItemShape, Qt::DescendingOrder, QTransform());
1093
1094     const QRectF pointRect(QPointF(widget->mapFromGlobal(screenPos)), QSizeF(1, 1));
1095     if (!view->isTransformed())
1096         return q->items(pointRect, Qt::IntersectsItemShape, Qt::DescendingOrder);
1097
1098     const QTransform viewTransform = view->viewportTransform();
1099     if (viewTransform.type() <= QTransform::TxScale) {
1100         return q->items(viewTransform.inverted().mapRect(pointRect), Qt::IntersectsItemShape,
1101                         Qt::DescendingOrder, viewTransform);
1102     }
1103     return q->items(viewTransform.inverted().map(pointRect), Qt::IntersectsItemShape,
1104                     Qt::DescendingOrder, viewTransform);
1105 }
1106
1107 /*!
1108     \internal
1109 */
1110 void QGraphicsScenePrivate::storeMouseButtonsForMouseGrabber(QGraphicsSceneMouseEvent *event)
1111 {
1112     for (int i = 0x1; i <= 0x10; i <<= 1) {
1113         if (event->buttons() & i) {
1114             mouseGrabberButtonDownPos.insert(Qt::MouseButton(i),
1115                                              mouseGrabberItems.last()->d_ptr->genericMapFromScene(event->scenePos(),
1116                                                                                                   event->widget()));
1117             mouseGrabberButtonDownScenePos.insert(Qt::MouseButton(i), event->scenePos());
1118             mouseGrabberButtonDownScreenPos.insert(Qt::MouseButton(i), event->screenPos());
1119         }
1120     }
1121 }
1122
1123 /*!
1124     \internal
1125 */
1126 void QGraphicsScenePrivate::installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter)
1127 {
1128     sceneEventFilters.insert(watched, filter);
1129 }
1130
1131 /*!
1132     \internal
1133 */
1134 void QGraphicsScenePrivate::removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter)
1135 {
1136     if (!sceneEventFilters.contains(watched))
1137         return;
1138
1139     QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator it = sceneEventFilters.lowerBound(watched);
1140     QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator end = sceneEventFilters.upperBound(watched);
1141     do {
1142         if (it.value() == filter)
1143             it = sceneEventFilters.erase(it);
1144         else
1145             ++it;
1146     } while (it != end);
1147 }
1148
1149 /*!
1150   \internal
1151 */
1152 bool QGraphicsScenePrivate::filterDescendantEvent(QGraphicsItem *item, QEvent *event)
1153 {
1154     if (item && (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents)) {
1155         QGraphicsItem *parent = item->parentItem();
1156         while (parent) {
1157             if (parent->d_ptr->filtersDescendantEvents && parent->sceneEventFilter(item, event))
1158                 return true;
1159             if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents))
1160                 return false;
1161             parent = parent->parentItem();
1162         }
1163     }
1164     return false;
1165 }
1166
1167 /*!
1168     \internal
1169 */
1170 bool QGraphicsScenePrivate::filterEvent(QGraphicsItem *item, QEvent *event)
1171 {
1172     if (item && !sceneEventFilters.contains(item))
1173         return false;
1174
1175     QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator it = sceneEventFilters.lowerBound(item);
1176     QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator end = sceneEventFilters.upperBound(item);
1177     while (it != end) {
1178         // ### The filterer and filteree might both be deleted.
1179         if (it.value()->sceneEventFilter(it.key(), event))
1180             return true;
1181         ++it;
1182     }
1183     return false;
1184 }
1185
1186 /*!
1187     \internal
1188
1189     This is the final dispatch point for any events from the scene to the
1190     item. It filters the event first - if the filter returns true, the event
1191     is considered to have been eaten by the filter, and is therefore stopped
1192     (the default filter returns false). Then/otherwise, if the item is
1193     enabled, the event is sent; otherwise it is stopped.
1194 */
1195 bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event)
1196 {
1197     if (QGraphicsObject *object = item->toGraphicsObject()) {
1198 #ifndef QT_NO_GESTURES
1199         QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager;
1200         if (gestureManager) {
1201             if (gestureManager->filterEvent(object, event))
1202                 return true;
1203         }
1204 #endif // QT_NO_GESTURES
1205     }
1206
1207     if (filterEvent(item, event))
1208         return false;
1209     if (filterDescendantEvent(item, event))
1210         return false;
1211     if (!item || !item->isEnabled())
1212         return false;
1213     if (QGraphicsObject *o = item->toGraphicsObject()) {
1214         bool spont = event->spontaneous();
1215         if (spont ? qt_sendSpontaneousEvent(o, event) : QApplication::sendEvent(o, event))
1216             return true;
1217         event->spont = spont;
1218     }
1219     return item->sceneEvent(event);
1220 }
1221
1222 /*!
1223     \internal
1224 */
1225 void QGraphicsScenePrivate::cloneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
1226                                                QGraphicsSceneDragDropEvent *source)
1227 {
1228     dest->setWidget(source->widget());
1229     dest->setPos(source->pos());
1230     dest->setScenePos(source->scenePos());
1231     dest->setScreenPos(source->screenPos());
1232     dest->setButtons(source->buttons());
1233     dest->setModifiers(source->modifiers());
1234     dest->setPossibleActions(source->possibleActions());
1235     dest->setProposedAction(source->proposedAction());
1236     dest->setDropAction(source->dropAction());
1237     dest->setSource(source->source());
1238     dest->setMimeData(source->mimeData());
1239 }
1240
1241 /*!
1242     \internal
1243 */
1244 void QGraphicsScenePrivate::sendDragDropEvent(QGraphicsItem *item,
1245                                               QGraphicsSceneDragDropEvent *dragDropEvent)
1246 {
1247     dragDropEvent->setPos(item->d_ptr->genericMapFromScene(dragDropEvent->scenePos(), dragDropEvent->widget()));
1248     sendEvent(item, dragDropEvent);
1249 }
1250
1251 /*!
1252     \internal
1253 */
1254 void QGraphicsScenePrivate::sendHoverEvent(QEvent::Type type, QGraphicsItem *item,
1255                                            QGraphicsSceneHoverEvent *hoverEvent)
1256 {
1257     QGraphicsSceneHoverEvent event(type);
1258     event.setWidget(hoverEvent->widget());
1259     event.setPos(item->d_ptr->genericMapFromScene(hoverEvent->scenePos(), hoverEvent->widget()));
1260     event.setScenePos(hoverEvent->scenePos());
1261     event.setScreenPos(hoverEvent->screenPos());
1262     event.setLastPos(item->d_ptr->genericMapFromScene(hoverEvent->lastScenePos(), hoverEvent->widget()));
1263     event.setLastScenePos(hoverEvent->lastScenePos());
1264     event.setLastScreenPos(hoverEvent->lastScreenPos());
1265     event.setModifiers(hoverEvent->modifiers());
1266     sendEvent(item, &event);
1267 }
1268
1269 /*!
1270     \internal
1271 */
1272 void QGraphicsScenePrivate::sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent)
1273 {
1274     if (mouseEvent->button() == 0 && mouseEvent->buttons() == 0 && lastMouseGrabberItemHasImplicitMouseGrab) {
1275         // ### This is a temporary fix for until we get proper mouse
1276         // grab events.
1277         clearMouseGrabber();
1278         return;
1279     }
1280
1281     QGraphicsItem *item = mouseGrabberItems.last();
1282     if (item->isBlockedByModalPanel())
1283         return;
1284
1285     for (int i = 0x1; i <= 0x10; i <<= 1) {
1286         Qt::MouseButton button = Qt::MouseButton(i);
1287         mouseEvent->setButtonDownPos(button, mouseGrabberButtonDownPos.value(button, item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget())));
1288         mouseEvent->setButtonDownScenePos(button, mouseGrabberButtonDownScenePos.value(button, mouseEvent->scenePos()));
1289         mouseEvent->setButtonDownScreenPos(button, mouseGrabberButtonDownScreenPos.value(button, mouseEvent->screenPos()));
1290     }
1291     mouseEvent->setPos(item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget()));
1292     mouseEvent->setLastPos(item->d_ptr->genericMapFromScene(mouseEvent->lastScenePos(), mouseEvent->widget()));
1293     sendEvent(item, mouseEvent);
1294 }
1295
1296 /*!
1297     \internal
1298 */
1299 void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent)
1300 {
1301     Q_Q(QGraphicsScene);
1302
1303     // Ignore by default, unless we find a mouse grabber that accepts it.
1304     mouseEvent->ignore();
1305
1306     // Deliver to any existing mouse grabber.
1307     if (!mouseGrabberItems.isEmpty()) {
1308         if (mouseGrabberItems.last()->isBlockedByModalPanel())
1309             return;
1310         // The event is ignored by default, but we disregard the event's
1311         // accepted state after delivery; the mouse is grabbed, after all.
1312         sendMouseEvent(mouseEvent);
1313         return;
1314     }
1315
1316     // Start by determining the number of items at the current position.
1317     // Reuse value from earlier calculations if possible.
1318     if (cachedItemsUnderMouse.isEmpty()) {
1319         cachedItemsUnderMouse = itemsAtPosition(mouseEvent->screenPos(),
1320                                                 mouseEvent->scenePos(),
1321                                                 mouseEvent->widget());
1322     }
1323
1324     // Update window activation.
1325     QGraphicsItem *topItem = cachedItemsUnderMouse.value(0);
1326     QGraphicsWidget *newActiveWindow = topItem ? topItem->window() : 0;
1327     if (newActiveWindow && newActiveWindow->isBlockedByModalPanel(&topItem)) {
1328         // pass activation to the blocking modal window
1329         newActiveWindow = topItem ? topItem->window() : 0;
1330     }
1331
1332     if (newActiveWindow != q->activeWindow())
1333         q->setActiveWindow(newActiveWindow);
1334
1335     // Set focus on the topmost enabled item that can take focus.
1336     bool setFocus = false;
1337
1338     foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
1339         if (item->isBlockedByModalPanel()
1340             || (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling)) {
1341             // Make sure we don't clear focus.
1342             setFocus = true;
1343             break;
1344         }
1345         if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable))) {
1346             if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
1347                 setFocus = true;
1348                 if (item != q->focusItem() && item->d_ptr->mouseSetsFocus)
1349                     q->setFocusItem(item, Qt::MouseFocusReason);
1350                 break;
1351             }
1352         }
1353         if (item->isPanel())
1354             break;
1355         if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
1356             break;
1357     }
1358
1359     // Check for scene modality.
1360     bool sceneModality = false;
1361     for (int i = 0; i < modalPanels.size(); ++i) {
1362         if (modalPanels.at(i)->panelModality() == QGraphicsItem::SceneModal) {
1363             sceneModality = true;
1364             break;
1365         }
1366     }
1367
1368     // If nobody could take focus, clear it.
1369     if (!stickyFocus && !setFocus && !sceneModality)
1370         q->setFocusItem(0, Qt::MouseFocusReason);
1371
1372     // Any item will do.
1373     if (sceneModality && cachedItemsUnderMouse.isEmpty())
1374         cachedItemsUnderMouse << modalPanels.first();
1375
1376     // Find a mouse grabber by sending mouse press events to all mouse grabber
1377     // candidates one at a time, until the event is accepted. It's accepted by
1378     // default, so the receiver has to explicitly ignore it for it to pass
1379     // through.
1380     foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
1381         if (!(item->acceptedMouseButtons() & mouseEvent->button())) {
1382             // Skip items that don't accept the event's mouse button.
1383             continue;
1384         }
1385
1386         // Check if this item is blocked by a modal panel and deliver the mouse event to the
1387         // blocking panel instead of this item if blocked.
1388         (void) item->isBlockedByModalPanel(&item);
1389
1390         grabMouse(item, /* implicit = */ true);
1391         mouseEvent->accept();
1392
1393         // check if the item we are sending to are disabled (before we send the event)
1394         bool disabled = !item->isEnabled();
1395         bool isPanel = item->isPanel();
1396         if (mouseEvent->type() == QEvent::GraphicsSceneMouseDoubleClick
1397             && item != lastMouseGrabberItem && lastMouseGrabberItem) {
1398             // If this item is different from the item that received the last
1399             // mouse event, and mouseEvent is a doubleclick event, then the
1400             // event is converted to a press. Known limitation:
1401             // Triple-clicking will not generate a doubleclick, though.
1402             QGraphicsSceneMouseEvent mousePress(QEvent::GraphicsSceneMousePress);
1403             mousePress.spont = mouseEvent->spont;
1404             mousePress.accept();
1405             mousePress.setButton(mouseEvent->button());
1406             mousePress.setButtons(mouseEvent->buttons());
1407             mousePress.setScreenPos(mouseEvent->screenPos());
1408             mousePress.setScenePos(mouseEvent->scenePos());
1409             mousePress.setModifiers(mouseEvent->modifiers());
1410             mousePress.setWidget(mouseEvent->widget());
1411             mousePress.setButtonDownPos(mouseEvent->button(),
1412                                         mouseEvent->buttonDownPos(mouseEvent->button()));
1413             mousePress.setButtonDownScenePos(mouseEvent->button(),
1414                                              mouseEvent->buttonDownScenePos(mouseEvent->button()));
1415             mousePress.setButtonDownScreenPos(mouseEvent->button(),
1416                                               mouseEvent->buttonDownScreenPos(mouseEvent->button()));
1417             sendMouseEvent(&mousePress);
1418             mouseEvent->setAccepted(mousePress.isAccepted());
1419         } else {
1420             sendMouseEvent(mouseEvent);
1421         }
1422
1423         bool dontSendUngrabEvents = mouseGrabberItems.isEmpty() || mouseGrabberItems.last() != item;
1424         if (disabled) {
1425             ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
1426             break;
1427         }
1428         if (mouseEvent->isAccepted()) {
1429             if (!mouseGrabberItems.isEmpty())
1430                 storeMouseButtonsForMouseGrabber(mouseEvent);
1431             lastMouseGrabberItem = item;
1432             return;
1433         }
1434         ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
1435
1436         // Don't propagate through panels.
1437         if (isPanel)
1438             break;
1439     }
1440
1441     // Is the event still ignored? Then the mouse press goes to the scene.
1442     // Reset the mouse grabber, clear the selection, clear focus, and leave
1443     // the event ignored so that it can propagate through the originating
1444     // view.
1445     if (!mouseEvent->isAccepted()) {
1446         clearMouseGrabber();
1447
1448         QGraphicsView *view = mouseEvent->widget() ? qobject_cast<QGraphicsView *>(mouseEvent->widget()->parentWidget()) : 0;
1449         bool dontClearSelection = view && view->dragMode() == QGraphicsView::ScrollHandDrag;
1450         if (!dontClearSelection) {
1451             // Clear the selection if the originating view isn't in scroll
1452             // hand drag mode. The view will clear the selection if no drag
1453             // happened.
1454             q->clearSelection();
1455         }
1456     }
1457 }
1458
1459 /*!
1460     \internal
1461
1462     Ensures that the list of toplevels is sorted by insertion order, and that
1463     the siblingIndexes are packed (no gaps), and start at 0.
1464
1465     ### This function is almost identical to
1466     QGraphicsItemPrivate::ensureSequentialSiblingIndex().
1467 */
1468 void QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes()
1469 {
1470     if (!topLevelSequentialOrdering) {
1471         qSort(topLevelItems.begin(), topLevelItems.end(), QGraphicsItemPrivate::insertionOrder);
1472         topLevelSequentialOrdering = true;
1473         needSortTopLevelItems = 1;
1474     }
1475     if (holesInTopLevelSiblingIndex) {
1476         holesInTopLevelSiblingIndex = 0;
1477         for (int i = 0; i < topLevelItems.size(); ++i)
1478             topLevelItems[i]->d_ptr->siblingIndex = i;
1479     }
1480 }
1481
1482 /*!
1483     \internal
1484
1485     Set the font and propagate the changes if the font is different from the
1486     current font.
1487 */
1488 void QGraphicsScenePrivate::setFont_helper(const QFont &font)
1489 {
1490     if (this->font == font && this->font.resolve() == font.resolve())
1491         return;
1492     updateFont(font);
1493 }
1494
1495 /*!
1496     \internal
1497
1498     Resolve the scene's font against the application font, and propagate the
1499     changes too all items in the scene.
1500 */
1501 void QGraphicsScenePrivate::resolveFont()
1502 {
1503     QFont naturalFont = QApplication::font();
1504     naturalFont.resolve(0);
1505     QFont resolvedFont = font.resolve(naturalFont);
1506     updateFont(resolvedFont);
1507 }
1508
1509 /*!
1510     \internal
1511
1512     Update the font, and whether or not it has changed, reresolve all fonts in
1513     the scene.
1514 */
1515 void QGraphicsScenePrivate::updateFont(const QFont &font)
1516 {
1517     Q_Q(QGraphicsScene);
1518
1519     // Update local font setting.
1520     this->font = font;
1521
1522     // Resolve the fonts of all top-level widget items, or widget items
1523     // whose parent is not a widget.
1524     foreach (QGraphicsItem *item, q->items()) {
1525         if (!item->parentItem()) {
1526             // Resolvefont for an item is a noop operation, but
1527             // every item can be a widget, or can have a widget
1528             // childre.
1529             item->d_ptr->resolveFont(font.resolve());
1530         }
1531     }
1532
1533     // Send the scene a FontChange event.
1534     QEvent event(QEvent::FontChange);
1535     QApplication::sendEvent(q, &event);
1536 }
1537
1538 /*!
1539     \internal
1540
1541     Set the palette and propagate the changes if the palette is different from
1542     the current palette.
1543 */
1544 void QGraphicsScenePrivate::setPalette_helper(const QPalette &palette)
1545 {
1546     if (this->palette == palette && this->palette.resolve() == palette.resolve())
1547         return;
1548     updatePalette(palette);
1549 }
1550
1551 /*!
1552     \internal
1553
1554     Resolve the scene's palette against the application palette, and propagate
1555     the changes too all items in the scene.
1556 */
1557 void QGraphicsScenePrivate::resolvePalette()
1558 {
1559     QPalette naturalPalette = QApplication::palette();
1560     naturalPalette.resolve(0);
1561     QPalette resolvedPalette = palette.resolve(naturalPalette);
1562     updatePalette(resolvedPalette);
1563 }
1564
1565 /*!
1566     \internal
1567
1568     Update the palette, and whether or not it has changed, reresolve all
1569     palettes in the scene.
1570 */
1571 void QGraphicsScenePrivate::updatePalette(const QPalette &palette)
1572 {
1573     Q_Q(QGraphicsScene);
1574
1575     // Update local palette setting.
1576     this->palette = palette;
1577
1578     // Resolve the palettes of all top-level widget items, or widget items
1579     // whose parent is not a widget.
1580     foreach (QGraphicsItem *item, q->items()) {
1581         if (!item->parentItem()) {
1582             // Resolvefont for an item is a noop operation, but
1583             // every item can be a widget, or can have a widget
1584             // childre.
1585             item->d_ptr->resolvePalette(palette.resolve());
1586         }
1587     }
1588
1589     // Send the scene a PaletteChange event.
1590     QEvent event(QEvent::PaletteChange);
1591     QApplication::sendEvent(q, &event);
1592 }
1593
1594 /*!
1595     Constructs a QGraphicsScene object. The \a parent parameter is
1596     passed to QObject's constructor.
1597 */
1598 QGraphicsScene::QGraphicsScene(QObject *parent)
1599     : QObject(*new QGraphicsScenePrivate, parent)
1600 {
1601     d_func()->init();
1602 }
1603
1604 /*!
1605     Constructs a QGraphicsScene object, using \a sceneRect for its
1606     scene rectangle. The \a parent parameter is passed to QObject's
1607     constructor.
1608
1609     \sa sceneRect
1610 */
1611 QGraphicsScene::QGraphicsScene(const QRectF &sceneRect, QObject *parent)
1612     : QObject(*new QGraphicsScenePrivate, parent)
1613 {
1614     d_func()->init();
1615     setSceneRect(sceneRect);
1616 }
1617
1618 /*!
1619     Constructs a QGraphicsScene object, using the rectangle specified
1620     by (\a x, \a y), and the given \a width and \a height for its
1621     scene rectangle. The \a parent parameter is passed to QObject's
1622     constructor.
1623
1624     \sa sceneRect
1625 */
1626 QGraphicsScene::QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent)
1627     : QObject(*new QGraphicsScenePrivate, parent)
1628 {
1629     d_func()->init();
1630     setSceneRect(x, y, width, height);
1631 }
1632
1633 /*!
1634   Removes and deletes all items from the scene object
1635   before destroying the scene object. The scene object
1636   is removed from the application's global scene list,
1637   and it is removed from all associated views.
1638 */
1639 QGraphicsScene::~QGraphicsScene()
1640 {
1641     Q_D(QGraphicsScene);
1642
1643     // Remove this scene from qApp's global scene list.
1644     if (!QApplicationPrivate::is_app_closing)
1645         qApp->d_func()->scene_list.removeAll(this);
1646
1647     clear();
1648
1649     // Remove this scene from all associated views.
1650     for (int j = 0; j < d->views.size(); ++j)
1651         d->views.at(j)->setScene(0);
1652 }
1653
1654 /*!
1655     \property QGraphicsScene::sceneRect
1656     \brief the scene rectangle; the bounding rectangle of the scene
1657
1658     The scene rectangle defines the extent of the scene. It is
1659     primarily used by QGraphicsView to determine the view's default
1660     scrollable area, and by QGraphicsScene to manage item indexing.
1661
1662     If unset, or if set to a null QRectF, sceneRect() will return the largest
1663     bounding rect of all items on the scene since the scene was created (i.e.,
1664     a rectangle that grows when items are added to or moved in the scene, but
1665     never shrinks).
1666
1667     \sa width(), height(), QGraphicsView::sceneRect
1668 */
1669 QRectF QGraphicsScene::sceneRect() const
1670 {
1671     Q_D(const QGraphicsScene);
1672     if (d->hasSceneRect)
1673         return d->sceneRect;
1674
1675     if (d->dirtyGrowingItemsBoundingRect) {
1676         // Lazily update the growing items bounding rect
1677         QGraphicsScenePrivate *thatd = const_cast<QGraphicsScenePrivate *>(d);
1678         QRectF oldGrowingBoundingRect = thatd->growingItemsBoundingRect;
1679         thatd->growingItemsBoundingRect |= itemsBoundingRect();
1680         thatd->dirtyGrowingItemsBoundingRect = false;
1681         if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect)
1682             emit const_cast<QGraphicsScene *>(this)->sceneRectChanged(thatd->growingItemsBoundingRect);
1683     }
1684     return d->growingItemsBoundingRect;
1685 }
1686 void QGraphicsScene::setSceneRect(const QRectF &rect)
1687 {
1688     Q_D(QGraphicsScene);
1689     if (rect != d->sceneRect) {
1690         d->hasSceneRect = !rect.isNull();
1691         d->sceneRect = rect;
1692         emit sceneRectChanged(d->hasSceneRect ? rect : d->growingItemsBoundingRect);
1693     }
1694 }
1695
1696 /*!
1697      \fn qreal QGraphicsScene::width() const
1698
1699      This convenience function is equivalent to calling sceneRect().width().
1700
1701      \sa height()
1702 */
1703
1704 /*!
1705      \fn qreal QGraphicsScene::height() const
1706
1707      This convenience function is equivalent to calling \c sceneRect().height().
1708
1709      \sa width()
1710 */
1711
1712 /*!
1713     Renders the \a source rect from scene into \a target, using \a painter. This
1714     function is useful for capturing the contents of the scene onto a paint
1715     device, such as a QImage (e.g., to take a screenshot), or for printing
1716     with QPrinter. For example:
1717
1718     \snippet code/src_gui_graphicsview_qgraphicsscene.cpp 1
1719
1720     If \a source is a null rect, this function will use sceneRect() to
1721     determine what to render. If \a target is a null rect, the dimensions of \a
1722     painter's paint device will be used.
1723
1724     The source rect contents will be transformed according to \a
1725     aspectRatioMode to fit into the target rect. By default, the aspect ratio
1726     is kept, and \a source is scaled to fit in \a target.
1727
1728     \sa QGraphicsView::render()
1729 */
1730 void QGraphicsScene::render(QPainter *painter, const QRectF &target, const QRectF &source,
1731                             Qt::AspectRatioMode aspectRatioMode)
1732 {
1733     // ### Switch to using the recursive rendering algorithm instead.
1734
1735     // Default source rect = scene rect
1736     QRectF sourceRect = source;
1737     if (sourceRect.isNull())
1738         sourceRect = sceneRect();
1739
1740     // Default target rect = device rect
1741     QRectF targetRect = target;
1742     if (targetRect.isNull()) {
1743         if (painter->device()->devType() == QInternal::Picture)
1744             targetRect = sourceRect;
1745         else
1746             targetRect.setRect(0, 0, painter->device()->width(), painter->device()->height());
1747     }
1748
1749     // Find the ideal x / y scaling ratio to fit \a source into \a target.
1750     qreal xratio = targetRect.width() / sourceRect.width();
1751     qreal yratio = targetRect.height() / sourceRect.height();
1752
1753     // Scale according to the aspect ratio mode.
1754     switch (aspectRatioMode) {
1755     case Qt::KeepAspectRatio:
1756         xratio = yratio = qMin(xratio, yratio);
1757         break;
1758     case Qt::KeepAspectRatioByExpanding:
1759         xratio = yratio = qMax(xratio, yratio);
1760         break;
1761     case Qt::IgnoreAspectRatio:
1762         break;
1763     }
1764
1765     // Find all items to draw, and reverse the list (we want to draw
1766     // in reverse order).
1767     QList<QGraphicsItem *> itemList = items(sourceRect, Qt::IntersectsItemBoundingRect);
1768     QGraphicsItem **itemArray = new QGraphicsItem *[itemList.size()];
1769     int numItems = itemList.size();
1770     for (int i = 0; i < numItems; ++i)
1771         itemArray[numItems - i - 1] = itemList.at(i);
1772     itemList.clear();
1773
1774     painter->save();
1775
1776     // Transform the painter.
1777     painter->setClipRect(targetRect, Qt::IntersectClip);
1778     QTransform painterTransform;
1779     painterTransform *= QTransform()
1780                         .translate(targetRect.left(), targetRect.top())
1781                         .scale(xratio, yratio)
1782                         .translate(-sourceRect.left(), -sourceRect.top());
1783     painter->setWorldTransform(painterTransform, true);
1784
1785     // Two unit vectors.
1786     QLineF v1(0, 0, 1, 0);
1787     QLineF v2(0, 0, 0, 1);
1788
1789     // Generate the style options
1790     QStyleOptionGraphicsItem *styleOptionArray = new QStyleOptionGraphicsItem[numItems];
1791     for (int i = 0; i < numItems; ++i)
1792         itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], painterTransform, targetRect.toRect());
1793
1794     // Render the scene.
1795     drawBackground(painter, sourceRect);
1796     drawItems(painter, numItems, itemArray, styleOptionArray);
1797     drawForeground(painter, sourceRect);
1798
1799     delete [] itemArray;
1800     delete [] styleOptionArray;
1801
1802     painter->restore();
1803 }
1804
1805 /*!
1806     \property QGraphicsScene::itemIndexMethod
1807     \brief the item indexing method.
1808
1809     QGraphicsScene applies an indexing algorithm to the scene, to speed up
1810     item discovery functions like items() and itemAt(). Indexing is most
1811     efficient for static scenes (i.e., where items don't move around). For
1812     dynamic scenes, or scenes with many animated items, the index bookkeeping
1813     can outweight the fast lookup speeds.
1814
1815     For the common case, the default index method BspTreeIndex works fine.  If
1816     your scene uses many animations and you are experiencing slowness, you can
1817     disable indexing by calling \c setItemIndexMethod(NoIndex).
1818
1819     \sa bspTreeDepth
1820 */
1821 QGraphicsScene::ItemIndexMethod QGraphicsScene::itemIndexMethod() const
1822 {
1823     Q_D(const QGraphicsScene);
1824     return d->indexMethod;
1825 }
1826 void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method)
1827 {
1828     Q_D(QGraphicsScene);
1829     if (d->indexMethod == method)
1830         return;
1831
1832     d->indexMethod = method;
1833
1834     QList<QGraphicsItem *> oldItems = d->index->items(Qt::DescendingOrder);
1835     delete d->index;
1836     if (method == BspTreeIndex)
1837         d->index = new QGraphicsSceneBspTreeIndex(this);
1838     else
1839         d->index = new QGraphicsSceneLinearIndex(this);
1840     for (int i = oldItems.size() - 1; i >= 0; --i)
1841         d->index->addItem(oldItems.at(i));
1842 }
1843
1844 /*!
1845     \property QGraphicsScene::bspTreeDepth
1846     \brief the depth of QGraphicsScene's BSP index tree
1847     \since 4.3
1848
1849     This property has no effect when NoIndex is used.
1850
1851     This value determines the depth of QGraphicsScene's BSP tree. The depth
1852     directly affects QGraphicsScene's performance and memory usage; the latter
1853     growing exponentially with the depth of the tree. With an optimal tree
1854     depth, QGraphicsScene can instantly determine the locality of items, even
1855     for scenes with thousands or millions of items. This also greatly improves
1856     rendering performance.
1857
1858     By default, the value is 0, in which case Qt will guess a reasonable
1859     default depth based on the size, location and number of items in the
1860     scene. If these parameters change frequently, however, you may experience
1861     slowdowns as QGraphicsScene retunes the depth internally. You can avoid
1862     potential slowdowns by fixating the tree depth through setting this
1863     property.
1864
1865     The depth of the tree and the size of the scene rectangle decide the
1866     granularity of the scene's partitioning. The size of each scene segment is
1867     determined by the following algorithm:
1868
1869     \snippet code/src_gui_graphicsview_qgraphicsscene.cpp 2
1870
1871     The BSP tree has an optimal size when each segment contains between 0 and
1872     10 items.
1873
1874     \sa itemIndexMethod
1875 */
1876 int QGraphicsScene::bspTreeDepth() const
1877 {
1878     Q_D(const QGraphicsScene);
1879     QGraphicsSceneBspTreeIndex *bspTree = qobject_cast<QGraphicsSceneBspTreeIndex *>(d->index);
1880     return bspTree ? bspTree->bspTreeDepth() : 0;
1881 }
1882 void QGraphicsScene::setBspTreeDepth(int depth)
1883 {
1884     Q_D(QGraphicsScene);
1885     if (depth < 0) {
1886         qWarning("QGraphicsScene::setBspTreeDepth: invalid depth %d ignored; must be >= 0", depth);
1887         return;
1888     }
1889
1890     QGraphicsSceneBspTreeIndex *bspTree = qobject_cast<QGraphicsSceneBspTreeIndex *>(d->index);
1891     if (!bspTree) {
1892         qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP");
1893         return;
1894     }
1895     bspTree->setBspTreeDepth(depth);
1896 }
1897
1898 /*!
1899     \property QGraphicsScene::sortCacheEnabled
1900     \brief whether sort caching is enabled
1901     \since 4.5
1902     \obsolete
1903
1904     Since Qt 4.6, this property has no effect.
1905 */
1906 bool QGraphicsScene::isSortCacheEnabled() const
1907 {
1908     Q_D(const QGraphicsScene);
1909     return d->sortCacheEnabled;
1910 }
1911 void QGraphicsScene::setSortCacheEnabled(bool enabled)
1912 {
1913     Q_D(QGraphicsScene);
1914     if (d->sortCacheEnabled == enabled)
1915         return;
1916     d->sortCacheEnabled = enabled;
1917 }
1918
1919 /*!
1920     Calculates and returns the bounding rect of all items on the scene. This
1921     function works by iterating over all items, and because if this, it can
1922     be slow for large scenes.
1923
1924     \sa sceneRect()
1925 */
1926 QRectF QGraphicsScene::itemsBoundingRect() const
1927 {
1928     // Does not take untransformable items into account.
1929     QRectF boundingRect;
1930     foreach (QGraphicsItem *item, items())
1931         boundingRect |= item->sceneBoundingRect();
1932     return boundingRect;
1933 }
1934
1935 /*!
1936     Returns an ordered list of all items on the scene. \a order decides the
1937     stacking order.
1938
1939     \sa addItem(), removeItem(), {QGraphicsItem#Sorting}{Sorting}
1940 */
1941 QList<QGraphicsItem *> QGraphicsScene::items(Qt::SortOrder order) const
1942 {
1943     Q_D(const QGraphicsScene);
1944     return d->index->items(order);
1945 }
1946
1947 /*!
1948     \fn QList<QGraphicsItem *> QGraphicsScene::items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode) const
1949     \obsolete
1950     \since 4.3
1951
1952     This convenience function is equivalent to calling items(QRectF(\a x, \a y, \a w, \a h), \a mode).
1953
1954     This function is deprecated and returns incorrect results if the scene
1955     contains items that ignore transformations. Use the overload that takes
1956     a QTransform instead.
1957 */
1958
1959 /*!
1960     \fn QList<QGraphicsItem *> QGraphicsScene::items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
1961     \overload
1962     \since 4.6
1963
1964     \brief Returns all visible items that, depending on \a mode, are
1965     either inside or intersect with the rectangle defined by \a x, \a y,
1966     \a w and \a h, in a list sorted using \a order.
1967
1968     \a deviceTransform is the transformation that applies to the view, and needs to
1969     be provided if the scene contains items that ignore transformations.
1970 */
1971
1972 /*!
1973     \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
1974     \since 4.6
1975
1976     \brief Returns all visible items that, depending on \a mode, are at
1977     the specified \a pos in a list sorted using \a order.
1978
1979     The default value for \a mode is Qt::IntersectsItemShape; all items whose
1980     exact shape intersects with \a pos are returned.
1981
1982     \a deviceTransform is the transformation that applies to the view, and needs to
1983     be provided if the scene contains items that ignore transformations.
1984
1985     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
1986 */
1987 QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode,
1988                                              Qt::SortOrder order, const QTransform &deviceTransform) const
1989 {
1990     Q_D(const QGraphicsScene);
1991     return d->index->items(pos, mode, order, deviceTransform);
1992 }
1993
1994 /*!
1995     \fn QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
1996     \overload
1997     \since 4.6
1998
1999     \brief Returns all visible items that, depending on \a mode, are
2000     either inside or intersect with the specified \a rect and return a
2001     list sorted using \a order.
2002
2003     The default value for \a mode is Qt::IntersectsItemShape; all items whose
2004     exact shape intersects with or is contained by \a rect are returned.
2005
2006     \a deviceTransform is the transformation that applies to the view, and needs to
2007     be provided if the scene contains items that ignore transformations.
2008
2009     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
2010 */
2011 QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode,
2012                                              Qt::SortOrder order, const QTransform &deviceTransform) const
2013 {
2014     Q_D(const QGraphicsScene);
2015     return d->index->items(rect, mode, order, deviceTransform);
2016 }
2017
2018 /*!
2019     \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
2020     \overload
2021     \since 4.6
2022
2023     \brief Returns all visible items that, depending on \a mode, are
2024     either inside or intersect with the specified \a polygon and return
2025     a list sorted using \a order.
2026
2027     The default value for \a mode is Qt::IntersectsItemShape; all items whose
2028     exact shape intersects with or is contained by \a polygon are returned.
2029
2030     \a deviceTransform is the transformation that applies to the view, and needs to
2031     be provided if the scene contains items that ignore transformations.
2032
2033     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
2034 */
2035 QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode,
2036                                              Qt::SortOrder order, const QTransform &deviceTransform) const
2037 {
2038     Q_D(const QGraphicsScene);
2039     return d->index->items(polygon, mode, order, deviceTransform);
2040 }
2041
2042 /*!
2043     \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
2044     \overload
2045     \since 4.6
2046
2047     \brief Returns all visible items that, depending on \a mode, are
2048     either inside or intersect with the specified \a path and return a
2049     list sorted using \a order.
2050
2051     The default value for \a mode is Qt::IntersectsItemShape; all items whose
2052     exact shape intersects with or is contained by \a path are returned.
2053
2054     \a deviceTransform is the transformation that applies to the view, and needs to
2055     be provided if the scene contains items that ignore transformations.
2056
2057     \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
2058 */
2059 QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode,
2060                                              Qt::SortOrder order, const QTransform &deviceTransform) const
2061 {
2062     Q_D(const QGraphicsScene);
2063     return d->index->items(path, mode, order, deviceTransform);
2064 }
2065
2066 /*!
2067     Returns a list of all items that collide with \a item. Collisions are
2068     determined by calling QGraphicsItem::collidesWithItem(); the collision
2069     detection is determined by \a mode. By default, all items whose shape
2070     intersects \a item or is contained inside \a item's shape are returned.
2071
2072     The items are returned in descending stacking order (i.e., the first item
2073     in the list is the uppermost item, and the last item is the lowermost
2074     item).
2075
2076     \sa items(), itemAt(), QGraphicsItem::collidesWithItem(), {QGraphicsItem#Sorting}{Sorting}
2077 */
2078 QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item,
2079                                                       Qt::ItemSelectionMode mode) const
2080 {
2081     Q_D(const QGraphicsScene);
2082     if (!item) {
2083         qWarning("QGraphicsScene::collidingItems: cannot find collisions for null item");
2084         return QList<QGraphicsItem *>();
2085     }
2086
2087     // Does not support ItemIgnoresTransformations.
2088     QList<QGraphicsItem *> tmp;
2089     foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::DescendingOrder)) {
2090         if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode))
2091             tmp << itemInVicinity;
2092     }
2093     return tmp;
2094 }
2095
2096 /*!
2097     \fn QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position) const
2098     \overload
2099     \obsolete
2100
2101     Returns the topmost visible item at the specified \a position, or 0 if
2102     there are no items at this position.
2103
2104     This function is deprecated and returns incorrect results if the scene
2105     contains items that ignore transformations. Use the overload that takes
2106     a QTransform instead.
2107
2108     \sa items(), collidingItems(), {QGraphicsItem#Sorting}{Sorting}
2109 */
2110
2111 /*!
2112     \since 4.6
2113
2114     Returns the topmost visible item at the specified \a position, or 0
2115     if there are no items at this position.
2116
2117     \a deviceTransform is the transformation that applies to the view, and needs to
2118     be provided if the scene contains items that ignore transformations.
2119
2120     \sa items(), collidingItems(), {QGraphicsItem#Sorting}{Sorting}
2121 */
2122 QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform &deviceTransform) const
2123 {
2124     QList<QGraphicsItem *> itemsAtPoint = items(position, Qt::IntersectsItemShape,
2125                                                 Qt::DescendingOrder, deviceTransform);
2126     return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
2127 }
2128
2129 /*!
2130     \fn QGraphicsScene::itemAt(qreal x, qreal y, const QTransform &deviceTransform) const
2131     \overload
2132     \since 4.6
2133
2134     Returns the topmost item at the position specified by (\a x, \a
2135     y), or 0 if there are no items at this position.
2136
2137     \a deviceTransform is the transformation that applies to the view, and needs to
2138     be provided if the scene contains items that ignore transformations.
2139
2140     This convenience function is equivalent to calling \c
2141     {itemAt(QPointF(x, y), deviceTransform)}.
2142 */
2143
2144 /*!
2145     \fn QGraphicsScene::itemAt(qreal x, qreal y) const
2146     \overload
2147     \obsolete
2148
2149     Returns the topmost item at the position specified by (\a x, \a
2150     y), or 0 if there are no items at this position.
2151
2152     This convenience function is equivalent to calling \c
2153     {itemAt(QPointF(x, y))}.
2154
2155     This function is deprecated and returns incorrect results if the scene
2156     contains items that ignore transformations. Use the overload that takes
2157     a QTransform instead.
2158 */
2159
2160 /*!
2161     Returns a list of all currently selected items. The items are
2162     returned in no particular order.
2163
2164     \sa setSelectionArea()
2165 */
2166 QList<QGraphicsItem *> QGraphicsScene::selectedItems() const
2167 {
2168     Q_D(const QGraphicsScene);
2169
2170     // Optimization: Lazily removes items that are not selected.
2171     QGraphicsScene *that = const_cast<QGraphicsScene *>(this);
2172     QSet<QGraphicsItem *> actuallySelectedSet;
2173     foreach (QGraphicsItem *item, that->d_func()->selectedItems) {
2174         if (item->isSelected())
2175             actuallySelectedSet << item;
2176     }
2177
2178     that->d_func()->selectedItems = actuallySelectedSet;
2179
2180     return d->selectedItems.values();
2181 }
2182
2183 /*!
2184     Returns the selection area that was previously set with
2185     setSelectionArea(), or an empty QPainterPath if no selection area has been
2186     set.
2187
2188     \sa setSelectionArea()
2189 */
2190 QPainterPath QGraphicsScene::selectionArea() const
2191 {
2192     Q_D(const QGraphicsScene);
2193     return d->selectionArea;
2194 }
2195
2196 /*!
2197     \since 4.6
2198
2199     Sets the selection area to \a path. All items within this area are
2200     immediately selected, and all items outside are unselected. You can get
2201     the list of all selected items by calling selectedItems().
2202
2203     \a deviceTransform is the transformation that applies to the view, and needs to
2204     be provided if the scene contains items that ignore transformations.
2205
2206     For an item to be selected, it must be marked as \e selectable
2207     (QGraphicsItem::ItemIsSelectable).
2208
2209     \sa clearSelection(), selectionArea()
2210 */
2211 void QGraphicsScene::setSelectionArea(const QPainterPath &path, const QTransform &deviceTransform)
2212 {
2213     setSelectionArea(path, Qt::IntersectsItemShape, deviceTransform);
2214 }
2215
2216 /*!
2217     \overload
2218     \since 4.6
2219
2220     Sets the selection area to \a path using \a mode to determine if items are
2221     included in the selection area.
2222
2223     \a deviceTransform is the transformation that applies to the view, and needs to
2224     be provided if the scene contains items that ignore transformations.
2225
2226     \sa clearSelection(), selectionArea()
2227 */
2228 void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode,
2229                                       const QTransform &deviceTransform)
2230 {
2231     Q_D(QGraphicsScene);
2232
2233     // Note: with boolean path operations, we can improve performance here
2234     // quite a lot by "growing" the old path instead of replacing it. That
2235     // allows us to only check the intersect area for changes, instead of
2236     // reevaluating the whole path over again.
2237     d->selectionArea = path;
2238
2239     QSet<QGraphicsItem *> unselectItems = d->selectedItems;
2240
2241     // Disable emitting selectionChanged() for individual items.
2242     ++d->selectionChanging;
2243     bool changed = false;
2244
2245     // Set all items in path to selected.
2246     foreach (QGraphicsItem *item, items(path, mode, Qt::DescendingOrder, deviceTransform)) {
2247         if (item->flags() & QGraphicsItem::ItemIsSelectable) {
2248             if (!item->isSelected())
2249                 changed = true;
2250             unselectItems.remove(item);
2251             item->setSelected(true);
2252         }
2253     }
2254
2255     // Unselect all items outside path.
2256     foreach (QGraphicsItem *item, unselectItems) {
2257         item->setSelected(false);
2258         changed = true;
2259     }
2260
2261     // Reenable emitting selectionChanged() for individual items.
2262     --d->selectionChanging;
2263
2264     if (!d->selectionChanging && changed)
2265         emit selectionChanged();
2266 }
2267
2268 /*!
2269    Clears the current selection.
2270
2271    \sa setSelectionArea(), selectedItems()
2272 */
2273 void QGraphicsScene::clearSelection()
2274 {
2275     Q_D(QGraphicsScene);
2276
2277     // Disable emitting selectionChanged
2278     ++d->selectionChanging;
2279     bool changed = !d->selectedItems.isEmpty();
2280
2281     foreach (QGraphicsItem *item, d->selectedItems)
2282         item->setSelected(false);
2283     d->selectedItems.clear();
2284
2285     // Reenable emitting selectionChanged() for individual items.
2286     --d->selectionChanging;
2287
2288     if (!d->selectionChanging && changed)
2289         emit selectionChanged();
2290 }
2291
2292 /*!
2293     \since 4.4
2294
2295     Removes and deletes all items from the scene, but otherwise leaves the
2296     state of the scene unchanged.
2297
2298     \sa addItem()
2299 */
2300 void QGraphicsScene::clear()
2301 {
2302     Q_D(QGraphicsScene);
2303     // NB! We have to clear the index before deleting items; otherwise the
2304     // index might try to access dangling item pointers.
2305     d->index->clear();
2306     // NB! QGraphicsScenePrivate::unregisterTopLevelItem() removes items
2307     while (!d->topLevelItems.isEmpty())
2308         delete d->topLevelItems.first();
2309     Q_ASSERT(d->topLevelItems.isEmpty());
2310     d->lastItemCount = 0;
2311     d->allItemsIgnoreHoverEvents = true;
2312     d->allItemsUseDefaultCursor = true;
2313     d->allItemsIgnoreTouchEvents = true;
2314 }
2315
2316 /*!
2317     Groups all items in \a items into a new QGraphicsItemGroup, and returns a
2318     pointer to the group. The group is created with the common ancestor of \a
2319     items as its parent, and with position (0, 0). The items are all
2320     reparented to the group, and their positions and transformations are
2321     mapped to the group. If \a items is empty, this function will return an
2322     empty top-level QGraphicsItemGroup.
2323
2324     QGraphicsScene has ownership of the group item; you do not need to delete
2325     it. To dismantle (ungroup) a group, call destroyItemGroup().
2326
2327     \sa destroyItemGroup(), QGraphicsItemGroup::addToGroup()
2328 */
2329 QGraphicsItemGroup *QGraphicsScene::createItemGroup(const QList<QGraphicsItem *> &items)
2330 {
2331     // Build a list of the first item's ancestors
2332     QList<QGraphicsItem *> ancestors;
2333     int n = 0;
2334     if (!items.isEmpty()) {
2335         QGraphicsItem *parent = items.at(n++);
2336         while ((parent = parent->parentItem()))
2337             ancestors.append(parent);
2338     }
2339
2340     // Find the common ancestor for all items
2341     QGraphicsItem *commonAncestor = 0;
2342     if (!ancestors.isEmpty()) {
2343         while (n < items.size()) {
2344             int commonIndex = -1;
2345             QGraphicsItem *parent = items.at(n++);
2346             do {
2347                 int index = ancestors.indexOf(parent, qMax(0, commonIndex));
2348                 if (index != -1) {
2349                     commonIndex = index;
2350                     break;
2351                 }
2352             } while ((parent = parent->parentItem()));
2353
2354             if (commonIndex == -1) {
2355                 commonAncestor = 0;
2356                 break;
2357             }
2358
2359             commonAncestor = ancestors.at(commonIndex);
2360         }
2361     }
2362
2363     // Create a new group at that level
2364     QGraphicsItemGroup *group = new QGraphicsItemGroup(commonAncestor);
2365     if (!commonAncestor)
2366         addItem(group);
2367     foreach (QGraphicsItem *item, items)
2368         group->addToGroup(item);
2369     return group;
2370 }
2371
2372 /*!
2373     Reparents all items in \a group to \a group's parent item, then removes \a
2374     group from the scene, and finally deletes it. The items' positions and
2375     transformations are mapped from the group to the group's parent.
2376
2377     \sa createItemGroup(), QGraphicsItemGroup::removeFromGroup()
2378 */
2379 void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)
2380 {
2381     foreach (QGraphicsItem *item, group->children())
2382         group->removeFromGroup(item);
2383     removeItem(group);
2384     delete group;
2385 }
2386
2387 /*!
2388     Adds or moves the \a item and all its childen to this scene.
2389     This scene takes ownership of the \a item.
2390
2391     If the item is visible (i.e., QGraphicsItem::isVisible() returns
2392     true), QGraphicsScene will emit changed() once control goes back
2393     to the event loop.
2394
2395     If the item is already in a different scene, it will first be
2396     removed from its old scene, and then added to this scene as a
2397     top-level.
2398
2399     QGraphicsScene will send ItemSceneChange notifications to \a item
2400     while it is added to the scene. If item does not currently belong
2401     to a scene, only one notification is sent. If it does belong to
2402     scene already (i.e., it is moved to this scene), QGraphicsScene
2403     will send an addition notification as the item is removed from its
2404     previous scene.
2405
2406     If the item is a panel, the scene is active, and there is no
2407     active panel in the scene, then the item will be activated.
2408
2409     \sa removeItem(), addEllipse(), addLine(), addPath(), addPixmap(),
2410     addRect(), addText(), addWidget(), {QGraphicsItem#Sorting}{Sorting}
2411 */
2412 void QGraphicsScene::addItem(QGraphicsItem *item)
2413 {
2414     Q_D(QGraphicsScene);
2415     if (!item) {
2416         qWarning("QGraphicsScene::addItem: cannot add null item");
2417         return;
2418     }
2419     if (item->d_ptr->scene == this) {
2420         qWarning("QGraphicsScene::addItem: item has already been added to this scene");
2421         return;
2422     }
2423     // Remove this item from its existing scene
2424     if (QGraphicsScene *oldScene = item->d_ptr->scene)
2425         oldScene->removeItem(item);
2426
2427     // Notify the item that its scene is changing, and allow the item to
2428     // react.
2429     const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
2430                                                     QVariant::fromValue<QGraphicsScene *>(this)));
2431     QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
2432     if (targetScene != this) {
2433         if (targetScene && item->d_ptr->scene != targetScene)
2434             targetScene->addItem(item);
2435         return;
2436     }
2437
2438     // QDeclarativeItems do not rely on initial itemChanged message, as the componentComplete
2439     // function allows far more opportunity for delayed-construction optimization.
2440     if (!item->d_ptr->isDeclarativeItem) {
2441         if (d->unpolishedItems.isEmpty()) {
2442             QMetaMethod method = metaObject()->method(d->polishItemsIndex);
2443             method.invoke(this, Qt::QueuedConnection);
2444         }
2445         d->unpolishedItems.append(item);
2446         item->d_ptr->pendingPolish = true;
2447     }
2448
2449     // Detach this item from its parent if the parent's scene is different
2450     // from this scene.
2451     if (QGraphicsItem *itemParent = item->d_ptr->parent) {
2452         if (itemParent->d_ptr->scene != this)
2453             item->setParentItem(0);
2454     }
2455
2456     // Add the item to this scene
2457     item->d_func()->scene = targetScene;
2458
2459     // Add the item in the index
2460     d->index->addItem(item);
2461
2462     // Add to list of toplevels if this item is a toplevel.
2463     if (!item->d_ptr->parent)
2464         d->registerTopLevelItem(item);
2465
2466     // Add to list of items that require an update. We cannot assume that the
2467     // item is fully constructed, so calling item->update() can lead to a pure
2468     // virtual function call to boundingRect().
2469     d->markDirty(item);
2470     d->dirtyGrowingItemsBoundingRect = true;
2471
2472     // Disable selectionChanged() for individual items
2473     ++d->selectionChanging;
2474     int oldSelectedItemSize = d->selectedItems.size();
2475
2476     // Enable mouse tracking if the item accepts hover events or has a cursor set.
2477     if (d->allItemsIgnoreHoverEvents && d->itemAcceptsHoverEvents_helper(item)) {
2478         d->allItemsIgnoreHoverEvents = false;
2479         d->enableMouseTrackingOnViews();
2480     }
2481 #ifndef QT_NO_CURSOR
2482     if (d->allItemsUseDefaultCursor && item->d_ptr->hasCursor) {
2483         d->allItemsUseDefaultCursor = false;
2484         if (d->allItemsIgnoreHoverEvents) // already enabled otherwise
2485             d->enableMouseTrackingOnViews();
2486     }
2487 #endif //QT_NO_CURSOR
2488
2489     // Enable touch events if the item accepts touch events.
2490     if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) {
2491         d->allItemsIgnoreTouchEvents = false;
2492         d->enableTouchEventsOnViews();
2493     }
2494
2495 #ifndef QT_NO_GESTURES
2496     foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
2497         d->grabGesture(item, gesture);
2498 #endif
2499
2500     // Update selection lists
2501     if (item->isSelected())
2502         d->selectedItems << item;
2503     if (item->isWidget() && item->isVisible() && static_cast<QGraphicsWidget *>(item)->windowType() == Qt::Popup)
2504         d->addPopup(static_cast<QGraphicsWidget *>(item));
2505     if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
2506         d->enterModal(item);
2507
2508     // Update creation order focus chain. Make sure to leave the widget's
2509     // internal tab order intact.
2510     if (item->isWidget()) {
2511         QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
2512         if (!d->tabFocusFirst) {
2513             // No first tab focus widget - make this the first tab focus
2514             // widget.
2515             d->tabFocusFirst = widget;
2516         } else if (!widget->parentWidget()) {
2517             // Adding a widget that is not part of a tab focus chain.
2518             QGraphicsWidget *last = d->tabFocusFirst->d_func()->focusPrev;
2519             QGraphicsWidget *lastNew = widget->d_func()->focusPrev;
2520             last->d_func()->focusNext = widget;
2521             widget->d_func()->focusPrev = last;
2522             d->tabFocusFirst->d_func()->focusPrev = lastNew;
2523             lastNew->d_func()->focusNext = d->tabFocusFirst;
2524         }
2525     }
2526
2527     // Add all children recursively
2528     item->d_ptr->ensureSortedChildren();
2529     for (int i = 0; i < item->d_ptr->children.size(); ++i)
2530         addItem(item->d_ptr->children.at(i));
2531
2532     // Resolve font and palette.
2533     item->d_ptr->resolveFont(d->font.resolve());
2534     item->d_ptr->resolvePalette(d->palette.resolve());
2535
2536
2537     // Reenable selectionChanged() for individual items
2538     --d->selectionChanging;
2539     if (!d->selectionChanging && d->selectedItems.size() != oldSelectedItemSize)
2540         emit selectionChanged();
2541
2542     // Deliver post-change notification
2543     item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
2544
2545     // Update explicit activation
2546     bool autoActivate = true;
2547     if (!d->childExplicitActivation && item->d_ptr->explicitActivate)
2548         d->childExplicitActivation = item->d_ptr->wantsActive ? 1 : 2;
2549     if (d->childExplicitActivation && item->isPanel()) {
2550         if (d->childExplicitActivation == 1)
2551             setActivePanel(item);
2552         else
2553             autoActivate = false;
2554         d->childExplicitActivation = 0;
2555     } else if (!item->d_ptr->parent) {
2556         d->childExplicitActivation = 0;
2557     }
2558
2559     // Auto-activate this item's panel if nothing else has been activated
2560     if (autoActivate) {
2561         if (!d->lastActivePanel && !d->activePanel && item->isPanel()) {
2562             if (isActive())
2563                 setActivePanel(item);
2564             else
2565                 d->lastActivePanel = item;
2566         }
2567     }
2568
2569     if (item->d_ptr->flags & QGraphicsItem::ItemSendsScenePositionChanges)
2570         d->registerScenePosItem(item);
2571
2572     // Ensure that newly added items that have subfocus set, gain
2573     // focus automatically if there isn't a focus item already.
2574     if (!d->focusItem && item != d->lastFocusItem && item->focusItem() == item)
2575         item->focusItem()->setFocus();
2576
2577     d->updateInputMethodSensitivityInViews();
2578 }
2579
2580 /*!
2581     Creates and adds an ellipse item to the scene, and returns the item
2582     pointer. The geometry of the ellipse is defined by \a rect, and its pen
2583     and brush are initialized to \a pen and \a brush.
2584
2585     Note that the item's geometry is provided in item coordinates, and its
2586     position is initialized to (0, 0).
2587
2588     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2589     QGraphicsScene will emit changed() once control goes back to the event
2590     loop.
2591
2592     \sa addLine(), addPath(), addPixmap(), addRect(), addText(), addItem(),
2593     addWidget()
2594 */
2595 QGraphicsEllipseItem *QGraphicsScene::addEllipse(const QRectF &rect, const QPen &pen, const QBrush &brush)
2596 {
2597     QGraphicsEllipseItem *item = new QGraphicsEllipseItem(rect);
2598     item->setPen(pen);
2599     item->setBrush(brush);
2600     addItem(item);
2601     return item;
2602 }
2603
2604 /*!
2605     \fn QGraphicsEllipseItem *QGraphicsScene::addEllipse(qreal x, qreal y, qreal w, qreal h, const QPen &pen, const QBrush &brush)
2606     \since 4.3
2607
2608     This convenience function is equivalent to calling addEllipse(QRectF(\a x,
2609     \a y, \a w, \a h), \a pen, \a brush).
2610 */
2611
2612 /*!
2613     Creates and adds a line item to the scene, and returns the item
2614     pointer. The geometry of the line is defined by \a line, and its pen
2615     is initialized to \a pen.
2616
2617     Note that the item's geometry is provided in item coordinates, and its
2618     position is initialized to (0, 0).
2619
2620     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2621     QGraphicsScene will emit changed() once control goes back to the event
2622     loop.
2623
2624     \sa addEllipse(), addPath(), addPixmap(), addRect(), addText(), addItem(),
2625     addWidget()
2626 */
2627 QGraphicsLineItem *QGraphicsScene::addLine(const QLineF &line, const QPen &pen)
2628 {
2629     QGraphicsLineItem *item = new QGraphicsLineItem(line);
2630     item->setPen(pen);
2631     addItem(item);
2632     return item;
2633 }
2634
2635 /*!
2636     \fn QGraphicsLineItem *QGraphicsScene::addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen)
2637     \since 4.3
2638
2639     This convenience function is equivalent to calling addLine(QLineF(\a x1,
2640     \a y1, \a x2, \a y2), \a pen).
2641 */
2642
2643 /*!
2644     Creates and adds a path item to the scene, and returns the item
2645     pointer. The geometry of the path is defined by \a path, and its pen and
2646     brush are initialized to \a pen and \a brush.
2647
2648     Note that the item's geometry is provided in item coordinates, and its
2649     position is initialized to (0, 0).
2650
2651     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2652     QGraphicsScene will emit changed() once control goes back to the event
2653     loop.
2654
2655     \sa addEllipse(), addLine(), addPixmap(), addRect(), addText(), addItem(),
2656     addWidget()
2657 */
2658 QGraphicsPathItem *QGraphicsScene::addPath(const QPainterPath &path, const QPen &pen, const QBrush &brush)
2659 {
2660     QGraphicsPathItem *item = new QGraphicsPathItem(path);
2661     item->setPen(pen);
2662     item->setBrush(brush);
2663     addItem(item);
2664     return item;
2665 }
2666
2667 /*!
2668     Creates and adds a pixmap item to the scene, and returns the item
2669     pointer. The pixmap is defined by \a pixmap.
2670
2671     Note that the item's geometry is provided in item coordinates, and its
2672     position is initialized to (0, 0).
2673
2674     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2675     QGraphicsScene will emit changed() once control goes back to the event
2676     loop.
2677
2678     \sa addEllipse(), addLine(), addPath(), addRect(), addText(), addItem(),
2679     addWidget()
2680 */
2681 QGraphicsPixmapItem *QGraphicsScene::addPixmap(const QPixmap &pixmap)
2682 {
2683     QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
2684     addItem(item);
2685     return item;
2686 }
2687
2688 /*!
2689     Creates and adds a polygon item to the scene, and returns the item
2690     pointer. The polygon is defined by \a polygon, and its pen and
2691     brush are initialized to \a pen and \a brush.
2692
2693     Note that the item's geometry is provided in item coordinates, and its
2694     position is initialized to (0, 0).
2695
2696     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2697     QGraphicsScene will emit changed() once control goes back to the event
2698     loop.
2699
2700     \sa addEllipse(), addLine(), addPath(), addRect(), addText(), addItem(),
2701     addWidget()
2702 */
2703 QGraphicsPolygonItem *QGraphicsScene::addPolygon(const QPolygonF &polygon,
2704                                                  const QPen &pen, const QBrush &brush)
2705 {
2706     QGraphicsPolygonItem *item = new QGraphicsPolygonItem(polygon);
2707     item->setPen(pen);
2708     item->setBrush(brush);
2709     addItem(item);
2710     return item;
2711 }
2712
2713 /*!
2714     Creates and adds a rectangle item to the scene, and returns the item
2715     pointer. The geometry of the rectangle is defined by \a rect, and its pen
2716     and brush are initialized to \a pen and \a brush.
2717
2718     Note that the item's geometry is provided in item coordinates, and its
2719     position is initialized to (0, 0). For example, if a QRect(50, 50, 100,
2720     100) is added, its top-left corner will be at (50, 50) relative to the
2721     origin in the items coordinate system.
2722
2723     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2724     QGraphicsScene will emit changed() once control goes back to the event
2725     loop.
2726
2727     \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addText(),
2728     addItem(), addWidget()
2729 */
2730 QGraphicsRectItem *QGraphicsScene::addRect(const QRectF &rect, const QPen &pen, const QBrush &brush)
2731 {
2732     QGraphicsRectItem *item = new QGraphicsRectItem(rect);
2733     item->setPen(pen);
2734     item->setBrush(brush);
2735     addItem(item);
2736     return item;
2737 }
2738
2739 /*!
2740     \fn QGraphicsRectItem *QGraphicsScene::addRect(qreal x, qreal y, qreal w, qreal h, const QPen &pen, const QBrush &brush)
2741     \since 4.3
2742
2743     This convenience function is equivalent to calling addRect(QRectF(\a x,
2744     \a y, \a w, \a h), \a pen, \a brush).
2745 */
2746
2747 /*!
2748     Creates and adds a text item to the scene, and returns the item
2749     pointer. The text string is initialized to \a text, and its font
2750     is initialized to \a font.
2751
2752     The item's position is initialized to (0, 0).
2753
2754     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2755     QGraphicsScene will emit changed() once control goes back to the event
2756     loop.
2757
2758     \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
2759     addItem(), addWidget()
2760 */
2761 QGraphicsTextItem *QGraphicsScene::addText(const QString &text, const QFont &font)
2762 {
2763     QGraphicsTextItem *item = new QGraphicsTextItem(text);
2764     item->setFont(font);
2765     addItem(item);
2766     return item;
2767 }
2768
2769 /*!
2770     Creates and adds a QGraphicsSimpleTextItem to the scene, and returns the
2771     item pointer. The text string is initialized to \a text, and its font is
2772     initialized to \a font.
2773
2774     The item's position is initialized to (0, 0).
2775
2776     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2777     QGraphicsScene will emit changed() once control goes back to the event
2778     loop.
2779
2780     \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
2781     addItem(), addWidget()
2782 */
2783 QGraphicsSimpleTextItem *QGraphicsScene::addSimpleText(const QString &text, const QFont &font)
2784 {
2785     QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem(text);
2786     item->setFont(font);
2787     addItem(item);
2788     return item;
2789 }
2790
2791 /*!
2792     Creates a new QGraphicsProxyWidget for \a widget, adds it to the scene,
2793     and returns a pointer to the proxy. \a wFlags set the default window flags
2794     for the embedding proxy widget.
2795
2796     The item's position is initialized to (0, 0).
2797
2798     If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
2799     QGraphicsScene will emit changed() once control goes back to the event
2800     loop.
2801
2802     Note that widgets with the Qt::WA_PaintOnScreen widget attribute
2803     set and widgets that wrap an external application or controller
2804     are not supported. Examples are QGLWidget and QAxWidget.
2805
2806     \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
2807     addText(), addSimpleText(), addItem()
2808 */
2809 QGraphicsProxyWidget *QGraphicsScene::addWidget(QWidget *widget, Qt::WindowFlags wFlags)
2810 {
2811     QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(0, wFlags);
2812     proxy->setWidget(widget);
2813     addItem(proxy);
2814     return proxy;
2815 }
2816
2817 /*!
2818     Removes the item \a item and all its children from the scene.  The
2819     ownership of \a item is passed on to the caller (i.e.,
2820     QGraphicsScene will no longer delete \a item when destroyed).
2821
2822     \sa addItem()
2823 */
2824 void QGraphicsScene::removeItem(QGraphicsItem *item)
2825 {
2826     // ### Refactoring: This function shares much functionality with _q_removeItemLater()
2827     Q_D(QGraphicsScene);
2828     if (!item) {
2829         qWarning("QGraphicsScene::removeItem: cannot remove 0-item");
2830         return;
2831     }
2832     if (item->scene() != this) {
2833         qWarning("QGraphicsScene::removeItem: item %p's scene (%p)"
2834                  " is different from this scene (%p)",
2835                  item, item->scene(), this);
2836         return;
2837     }
2838
2839     // Notify the item that it's scene is changing to 0, allowing the item to
2840     // react.
2841     const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
2842                                                     QVariant::fromValue<QGraphicsScene *>(0)));
2843     QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
2844     if (targetScene != 0 && targetScene != this) {
2845         targetScene->addItem(item);
2846         return;
2847     }
2848
2849     d->removeItemHelper(item);
2850
2851     // Deliver post-change notification
2852     item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
2853
2854     d->updateInputMethodSensitivityInViews();
2855 }
2856
2857 /*!
2858     When the scene is active, this functions returns the scene's current focus
2859     item, or 0 if no item currently has focus. When the scene is inactive, this
2860     functions returns the item that will gain input focus when the scene becomes
2861     active.
2862
2863     The focus item receives keyboard input when the scene receives a
2864     key event.
2865
2866     \sa setFocusItem(), QGraphicsItem::hasFocus(), isActive()
2867 */
2868 QGraphicsItem *QGraphicsScene::focusItem() const
2869 {
2870     Q_D(const QGraphicsScene);
2871     return isActive() ? d->focusItem : d->passiveFocusItem;
2872 }
2873
2874 /*!
2875     Sets the scene's focus item to \a item, with the focus reason \a
2876     focusReason, after removing focus from any previous item that may have had
2877     focus.
2878
2879     If \a item is 0, or if it either does not accept focus (i.e., it does not
2880     have the QGraphicsItem::ItemIsFocusable flag enabled), or is not visible
2881     or not enabled, this function only removes focus from any previous
2882     focusitem.
2883
2884     If item is not 0, and the scene does not currently have focus (i.e.,
2885     hasFocus() returns false), this function will call setFocus()
2886     automatically.
2887
2888     \sa focusItem(), hasFocus(), setFocus()
2889 */
2890 void QGraphicsScene::setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReason)
2891 {
2892     Q_D(QGraphicsScene);
2893     if (item)
2894         item->setFocus(focusReason);
2895     else
2896         d->setFocusItemHelper(item, focusReason);
2897 }
2898
2899 /*!
2900     Returns true if the scene has focus; otherwise returns false. If the scene
2901     has focus, it will will forward key events from QKeyEvent to any item that
2902     has focus.
2903
2904     \sa setFocus(), setFocusItem()
2905 */
2906 bool QGraphicsScene::hasFocus() const
2907 {
2908     Q_D(const QGraphicsScene);
2909     return d->hasFocus;
2910 }
2911
2912 /*!
2913     Sets focus on the scene by sending a QFocusEvent to the scene, passing \a
2914     focusReason as the reason. If the scene regains focus after having
2915     previously lost it while an item had focus, the last focus item will
2916     receive focus with \a focusReason as the reason.
2917
2918     If the scene already has focus, this function does nothing.
2919
2920     \sa hasFocus(), clearFocus(), setFocusItem()
2921 */
2922 void QGraphicsScene::setFocus(Qt::FocusReason focusReason)
2923 {
2924     Q_D(QGraphicsScene);
2925     if (d->hasFocus || !isActive())
2926         return;
2927     QFocusEvent event(QEvent::FocusIn, focusReason);
2928     QCoreApplication::sendEvent(this, &event);
2929 }
2930
2931 /*!
2932     Clears focus from the scene. If any item has focus when this function is
2933     called, it will lose focus, and regain focus again once the scene regains
2934     focus.
2935
2936     A scene that does not have focus ignores key events.
2937
2938     \sa hasFocus(), setFocus(), setFocusItem()
2939 */
2940 void QGraphicsScene::clearFocus()
2941 {
2942     Q_D(QGraphicsScene);
2943     if (d->hasFocus) {
2944         d->hasFocus = false;
2945         d->passiveFocusItem = d->focusItem;
2946         setFocusItem(0, Qt::OtherFocusReason);
2947     }
2948 }
2949
2950 /*!
2951     \property QGraphicsScene::stickyFocus
2952     \brief whether clicking into the scene background will clear focus
2953
2954     \since 4.6
2955
2956     In a QGraphicsScene with stickyFocus set to true, focus will remain
2957     unchanged when the user clicks into the scene background or on an item
2958     that does not accept focus. Otherwise, focus will be cleared.
2959
2960     By default, this property is false.
2961
2962     Focus changes in response to a mouse press. You can reimplement
2963     mousePressEvent() in a subclass of QGraphicsScene to toggle this property
2964     based on where the user has clicked.
2965
2966     \sa clearFocus(), setFocusItem()
2967 */
2968 void QGraphicsScene::setStickyFocus(bool enabled)
2969 {
2970     Q_D(QGraphicsScene);
2971     d->stickyFocus = enabled;
2972 }
2973 bool QGraphicsScene::stickyFocus() const
2974 {
2975     Q_D(const QGraphicsScene);
2976     return d->stickyFocus;
2977 }
2978
2979 /*!
2980     Returns the current mouse grabber item, or 0 if no item is currently
2981     grabbing the mouse. The mouse grabber item is the item that receives all
2982     mouse events sent to the scene.
2983
2984     An item becomes a mouse grabber when it receives and accepts a
2985     mouse press event, and it stays the mouse grabber until either of
2986     the following events occur:
2987
2988     \list
2989     \li If the item receives a mouse release event when there are no other
2990     buttons pressed, it loses the mouse grab.
2991     \li If the item becomes invisible (i.e., someone calls \c {item->setVisible(false)}),
2992     or if it becomes disabled (i.e., someone calls \c {item->setEnabled(false)}),
2993     it loses the mouse grab.
2994     \li If the item is removed from the scene, it loses the mouse grab.
2995     \endlist
2996
2997     If the item loses its mouse grab, the scene will ignore all mouse events
2998     until a new item grabs the mouse (i.e., until a new item receives a mouse
2999     press event).
3000 */
3001 QGraphicsItem *QGraphicsScene::mouseGrabberItem() const
3002 {
3003     Q_D(const QGraphicsScene);
3004     return !d->mouseGrabberItems.isEmpty() ? d->mouseGrabberItems.last() : 0;
3005 }
3006
3007 /*!
3008     \property QGraphicsScene::backgroundBrush
3009     \brief the background brush of the scene.
3010
3011     Set this property to changes the scene's background to a different color,
3012     gradient or texture. The default background brush is Qt::NoBrush. The
3013     background is drawn before (behind) the items.
3014
3015     Example:
3016
3017     \snippet code/src_gui_graphicsview_qgraphicsscene.cpp 3
3018
3019     QGraphicsScene::render() calls drawBackground() to draw the scene
3020     background. For more detailed control over how the background is drawn,
3021     you can reimplement drawBackground() in a subclass of QGraphicsScene.
3022 */
3023 QBrush QGraphicsScene::backgroundBrush() const
3024 {
3025     Q_D(const QGraphicsScene);
3026     return d->backgroundBrush;
3027 }
3028 void QGraphicsScene::setBackgroundBrush(const QBrush &brush)
3029 {
3030     Q_D(QGraphicsScene);
3031     d->backgroundBrush = brush;
3032     foreach (QGraphicsView *view, d->views) {
3033         view->resetCachedContent();
3034         view->viewport()->update();
3035     }
3036     update();
3037 }
3038
3039 /*!
3040     \property QGraphicsScene::foregroundBrush
3041     \brief the foreground brush of the scene.
3042
3043     Change this property to set the scene's foreground to a different
3044     color, gradient or texture.
3045
3046     The foreground is drawn after (on top of) the items. The default
3047     foreground brush is Qt::NoBrush ( i.e. the foreground is not
3048     drawn).
3049
3050     Example:
3051
3052     \snippet code/src_gui_graphicsview_qgraphicsscene.cpp 4
3053
3054     QGraphicsScene::render() calls drawForeground() to draw the scene
3055     foreground. For more detailed control over how the foreground is
3056     drawn, you can reimplement the drawForeground() function in a
3057     QGraphicsScene subclass.
3058 */
3059 QBrush QGraphicsScene::foregroundBrush() const
3060 {
3061     Q_D(const QGraphicsScene);
3062     return d->foregroundBrush;
3063 }
3064 void QGraphicsScene::setForegroundBrush(const QBrush &brush)
3065 {
3066     Q_D(QGraphicsScene);
3067     d->foregroundBrush = brush;
3068     foreach (QGraphicsView *view, views())
3069         view->viewport()->update();
3070     update();
3071 }
3072
3073 /*!
3074     This method is used by input methods to query a set of properties of
3075     the scene to be able to support complex input method operations as support
3076     for surrounding text and reconversions.
3077
3078     The \a query parameter specifies which property is queried.
3079
3080     \sa QWidget::inputMethodQuery()
3081 */
3082 QVariant QGraphicsScene::inputMethodQuery(Qt::InputMethodQuery query) const
3083 {
3084     Q_D(const QGraphicsScene);
3085     if (!d->focusItem || !(d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod))
3086         return QVariant();
3087     const QTransform matrix = d->focusItem->sceneTransform();
3088     QVariant value = d->focusItem->inputMethodQuery(query);
3089     if (value.type() == QVariant::RectF)
3090         value = matrix.mapRect(value.toRectF());
3091     else if (value.type() == QVariant::PointF)
3092         value = matrix.map(value.toPointF());
3093     else if (value.type() == QVariant::Rect)
3094         value = matrix.mapRect(value.toRect());
3095     else if (value.type() == QVariant::Point)
3096         value = matrix.map(value.toPoint());
3097     return value;
3098 }
3099
3100 /*!
3101     \fn void QGraphicsScene::update(const QRectF &rect)
3102     Schedules a redraw of the area \a rect on the scene.
3103
3104     \sa sceneRect(), changed()
3105 */
3106 void QGraphicsScene::update(const QRectF &rect)
3107 {
3108     Q_D(QGraphicsScene);
3109     if (d->updateAll || (rect.isEmpty() && !rect.isNull()))
3110         return;
3111
3112     // Check if anyone's connected; if not, we can send updates directly to
3113     // the views. Otherwise or if there are no views, use old behavior.
3114     bool directUpdates = !(d->isSignalConnected(d->changedSignalIndex)) && !d->views.isEmpty();
3115     if (rect.isNull()) {
3116         d->updateAll = true;
3117         d->updatedRects.clear();
3118         if (directUpdates) {
3119             // Update all views.
3120             for (int i = 0; i < d->views.size(); ++i)
3121                 d->views.at(i)->d_func()->fullUpdatePending = true;
3122         }
3123     } else {
3124         if (directUpdates) {
3125             // Update all views.
3126             for (int i = 0; i < d->views.size(); ++i) {
3127                 QGraphicsView *view = d->views.at(i);
3128                 if (view->isTransformed())
3129                     view->d_func()->updateRectF(view->viewportTransform().mapRect(rect));
3130                 else
3131                     view->d_func()->updateRectF(rect);
3132             }
3133         } else {
3134             d->updatedRects << rect;
3135         }
3136     }
3137
3138     if (!d->calledEmitUpdated) {
3139         d->calledEmitUpdated = true;
3140         QMetaObject::invokeMethod(this, "_q_emitUpdated", Qt::QueuedConnection);
3141     }
3142 }
3143
3144 /*!
3145     \fn void QGraphicsScene::update(qreal x, qreal y, qreal w, qreal h)
3146     \overload
3147     \since 4.3
3148
3149     This function is equivalent to calling update(QRectF(\a x, \a y, \a w,
3150     \a h));
3151 */
3152
3153 /*!
3154     Invalidates and schedules a redraw of the \a layers in \a rect on the
3155     scene. Any cached content in \a layers is unconditionally invalidated and
3156     redrawn.
3157
3158     You can use this function overload to notify QGraphicsScene of changes to
3159     the background or the foreground of the scene. This function is commonly
3160     used for scenes with tile-based backgrounds to notify changes when
3161     QGraphicsView has enabled
3162     \l{QGraphicsView::CacheBackground}{CacheBackground}.
3163
3164     Example:
3165
3166     \snippet code/src_gui_graphicsview_qgraphicsscene.cpp 5
3167
3168     Note that QGraphicsView currently supports background caching only (see
3169     QGraphicsView::CacheBackground). This function is equivalent to calling
3170     update() if any layer but BackgroundLayer is passed.
3171
3172     \sa QGraphicsView::resetCachedContent()
3173 */
3174 void QGraphicsScene::invalidate(const QRectF &rect, SceneLayers layers)
3175 {
3176     foreach (QGraphicsView *view, views())
3177         view->invalidateScene(rect, layers);
3178     update(rect);
3179 }
3180
3181 /*!
3182     \fn void QGraphicsScene::invalidate(qreal x, qreal y, qreal w, qreal h, SceneLayers layers)
3183     \overload
3184     \since 4.3
3185
3186     This convenience function is equivalent to calling invalidate(QRectF(\a x, \a
3187     y, \a w, \a h), \a layers);
3188 */
3189
3190 /*!
3191     Returns a list of all the views that display this scene.
3192
3193     \sa QGraphicsView::scene()
3194 */
3195 QList <QGraphicsView *> QGraphicsScene::views() const
3196 {
3197     Q_D(const QGraphicsScene);
3198     return d->views;
3199 }
3200
3201 /*!
3202     This slot \e advances the scene by one step, by calling
3203     QGraphicsItem::advance() for all items on the scene. This is done in two
3204     phases: in the first phase, all items are notified that the scene is about
3205     to change, and in the second phase all items are notified that they can
3206     move. In the first phase, QGraphicsItem::advance() is called passing a
3207     value of 0 as an argument, and 1 is passed in the second phase.
3208
3209     \sa QGraphicsItem::advance(), QGraphicsItemAnimation, QTimeLine
3210 */
3211 void QGraphicsScene::advance()
3212 {
3213     for (int i = 0; i < 2; ++i) {
3214         foreach (QGraphicsItem *item, items())
3215             item->advance(i);
3216     }
3217 }
3218
3219 /*!
3220     Processes the event \a event, and dispatches it to the respective
3221     event handlers.
3222
3223     In addition to calling the convenience event handlers, this
3224     function is responsible for converting mouse move events to hover
3225     events for when there is no mouse grabber item. Hover events are
3226     delivered directly to items; there is no convenience function for
3227     them.
3228
3229     Unlike QWidget, QGraphicsScene does not have the convenience functions
3230     \l{QWidget::}{enterEvent()} and \l{QWidget::}{leaveEvent()}. Use this
3231     function to obtain those events instead.
3232
3233     \sa contextMenuEvent(), keyPressEvent(), keyReleaseEvent(),
3234     mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(),
3235     mouseDoubleClickEvent(), focusInEvent(), focusOutEvent()
3236 */
3237 bool QGraphicsScene::event(QEvent *event)
3238 {
3239     Q_D(QGraphicsScene);
3240
3241     switch (event->type()) {
3242     case QEvent::GraphicsSceneMousePress:
3243     case QEvent::GraphicsSceneMouseMove:
3244     case QEvent::GraphicsSceneMouseRelease:
3245     case QEvent::GraphicsSceneMouseDoubleClick:
3246     case QEvent::GraphicsSceneHoverEnter:
3247     case QEvent::GraphicsSceneHoverLeave:
3248     case QEvent::GraphicsSceneHoverMove:
3249     case QEvent::TouchBegin:
3250     case QEvent::TouchUpdate:
3251     case QEvent::TouchEnd:
3252         // Reset the under-mouse list to ensure that this event gets fresh
3253         // item-under-mouse data. Be careful about this list; if people delete
3254         // items from inside event handlers, this list can quickly end up
3255         // having stale pointers in it. We need to clear it before dispatching
3256         // events that use it.
3257         // ### this should only be cleared if we received a new mouse move event,
3258         // which relies on us fixing the replay mechanism in QGraphicsView.
3259         d->cachedItemsUnderMouse.clear();
3260     default:
3261         break;
3262     }
3263
3264     switch (event->type()) {
3265     case QEvent::GraphicsSceneDragEnter:
3266         dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
3267         break;
3268     case QEvent::GraphicsSceneDragMove:
3269         dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
3270         break;
3271     case QEvent::GraphicsSceneDragLeave:
3272         dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
3273         break;
3274     case QEvent::GraphicsSceneDrop:
3275         dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
3276         break;
3277     case QEvent::GraphicsSceneContextMenu:
3278         contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event));
3279         break;
3280     case QEvent::KeyPress:
3281         if (!d->focusItem) {
3282             QKeyEvent *k = static_cast<QKeyEvent *>(event);
3283             if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
3284                 if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) {  //### Add MetaModifier?
3285                     bool res = false;
3286                     if (k->key() == Qt::Key_Backtab
3287                         || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
3288                         res = focusNextPrevChild(false);
3289                     } else if (k->key() == Qt::Key_Tab) {
3290                         res = focusNextPrevChild(true);
3291                     }
3292                     if (!res)
3293                         event->ignore();
3294                     return true;
3295                 }
3296             }
3297         }
3298         keyPressEvent(static_cast<QKeyEvent *>(event));
3299         break;
3300     case QEvent::KeyRelease:
3301         keyReleaseEvent(static_cast<QKeyEvent *>(event));
3302         break;
3303     case QEvent::ShortcutOverride: {
3304             QGraphicsItem *parent = focusItem();
3305             while (parent) {
3306                 d->sendEvent(parent, event);
3307                 if (event->isAccepted())
3308                     return true;
3309                 parent = parent->parentItem();
3310             }
3311         }
3312         return false;
3313     case QEvent::GraphicsSceneMouseMove:
3314     {
3315         QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
3316         d->lastSceneMousePos = mouseEvent->scenePos();
3317         mouseMoveEvent(mouseEvent);
3318         break;
3319     }
3320     case QEvent::GraphicsSceneMousePress:
3321         mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
3322         break;
3323     case QEvent::GraphicsSceneMouseRelease:
3324         mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
3325         break;
3326     case QEvent::GraphicsSceneMouseDoubleClick:
3327         mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
3328         break;
3329     case QEvent::GraphicsSceneWheel:
3330         wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
3331         break;
3332     case QEvent::FocusIn:
3333         focusInEvent(static_cast<QFocusEvent *>(event));
3334         break;
3335     case QEvent::FocusOut:
3336         focusOutEvent(static_cast<QFocusEvent *>(event));
3337         break;
3338     case QEvent::GraphicsSceneHoverEnter:
3339     case QEvent::GraphicsSceneHoverLeave:
3340     case QEvent::GraphicsSceneHoverMove:
3341     {
3342         QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
3343         d->lastSceneMousePos = hoverEvent->scenePos();
3344         d->dispatchHoverEvent(hoverEvent);
3345         break;
3346     }
3347     case QEvent::Leave:
3348         // hackieshly unpacking the viewport pointer from the leave event.
3349         d->leaveScene(reinterpret_cast<QWidget *>(event->d));
3350         break;
3351     case QEvent::GraphicsSceneHelp:
3352         helpEvent(static_cast<QGraphicsSceneHelpEvent *>(event));
3353         break;
3354     case QEvent::InputMethod:
3355         inputMethodEvent(static_cast<QInputMethodEvent *>(event));
3356         break;
3357     case QEvent::WindowActivate:
3358         if (!d->activationRefCount++) {
3359             if (d->lastActivePanel) {
3360                 // Activate the last panel.
3361                 d->setActivePanelHelper(d->lastActivePanel, true);
3362             } else if (d->tabFocusFirst && d->tabFocusFirst->isPanel()) {
3363                 // Activate the panel of the first item in the tab focus
3364                 // chain.
3365                 d->setActivePanelHelper(d->tabFocusFirst, true);
3366             } else {
3367                 // Activate all toplevel items.
3368                 QEvent event(QEvent::WindowActivate);
3369                 foreach (QGraphicsItem *item, items()) {
3370                     if (item->isVisible() && !item->isPanel() && !item->parentItem())
3371                         sendEvent(item, &event);
3372                 }
3373             }
3374         }
3375         break;
3376     case QEvent::WindowDeactivate:
3377         if (!--d->activationRefCount) {
3378             if (d->activePanel) {
3379                 // Deactivate the active panel (but keep it so we can
3380                 // reactivate it later).
3381                 QGraphicsItem *lastActivePanel = d->activePanel;
3382                 d->setActivePanelHelper(0, true);
3383                 d->lastActivePanel = lastActivePanel;
3384             } else {
3385                 // Activate all toplevel items.
3386                 QEvent event(QEvent::WindowDeactivate);
3387                 foreach (QGraphicsItem *item, items()) {
3388                     if (item->isVisible() && !item->isPanel() && !item->parentItem())
3389                         sendEvent(item, &event);
3390                 }
3391             }
3392         }
3393         break;
3394     case QEvent::ApplicationFontChange: {
3395         // Resolve the existing scene font.
3396         d->resolveFont();
3397         break;
3398     }
3399     case QEvent::FontChange:
3400         // Update the entire scene when the font changes.
3401         update();
3402         break;
3403     case QEvent::ApplicationPaletteChange: {
3404         // Resolve the existing scene palette.
3405         d->resolvePalette();
3406         break;
3407     }
3408     case QEvent::PaletteChange:
3409         // Update the entire scene when the palette changes.
3410         update();
3411         break;
3412     case QEvent::StyleChange:
3413         // Reresolve all widgets' styles. Update all top-level widgets'
3414         // geometries that do not have an explicit style set.
3415         update();
3416         break;
3417     case QEvent::TouchBegin:
3418     case QEvent::TouchUpdate:
3419     case QEvent::TouchEnd:
3420         d->touchEventHandler(static_cast<QTouchEvent *>(event));
3421         break;
3422 #ifndef QT_NO_GESTURES
3423     case QEvent::Gesture:
3424     case QEvent::GestureOverride:
3425         d->gestureEventHandler(static_cast<QGestureEvent *>(event));
3426         break;
3427 #endif // QT_NO_GESTURES
3428     default:
3429         return QObject::event(event);
3430     }
3431     return true;
3432 }
3433
3434 /*!
3435     \reimp
3436
3437     QGraphicsScene filters QApplication's events to detect palette and font
3438     changes.
3439 */
3440 bool QGraphicsScene::eventFilter(QObject *watched, QEvent *event)
3441 {
3442     if (watched != qApp)
3443         return false;
3444
3445     switch (event->type()) {
3446     case QEvent::ApplicationPaletteChange:
3447         QApplication::postEvent(this, new QEvent(QEvent::ApplicationPaletteChange));
3448         break;
3449     case QEvent::ApplicationFontChange:
3450         QApplication::postEvent(this, new QEvent(QEvent::ApplicationFontChange));
3451         break;
3452     default:
3453         break;
3454     }
3455     return false;
3456 }
3457
3458 /*!
3459     This event handler, for event \a contextMenuEvent, can be reimplemented in
3460     a subclass to receive context menu events. The default implementation
3461     forwards the event to the topmost item that accepts context menu events at
3462     the position of the event. If no items accept context menu events at this
3463     position, the event is ignored.
3464
3465     \sa QGraphicsItem::contextMenuEvent()
3466 */
3467 void QGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent)
3468 {
3469     Q_D(QGraphicsScene);
3470     // Ignore by default.
3471     contextMenuEvent->ignore();
3472
3473     // Send the event to all items at this position until one item accepts the
3474     // event.
3475     foreach (QGraphicsItem *item, d->itemsAtPosition(contextMenuEvent->screenPos(),
3476                                                      contextMenuEvent->scenePos(),
3477                                                      contextMenuEvent->widget())) {
3478         contextMenuEvent->setPos(item->d_ptr->genericMapFromScene(contextMenuEvent->scenePos(),
3479                                                                   contextMenuEvent->widget()));
3480         contextMenuEvent->accept();
3481         if (!d->sendEvent(item, contextMenuEvent))
3482             break;
3483
3484         if (contextMenuEvent->isAccepted())
3485             break;
3486     }
3487 }
3488
3489 /*!
3490     This event handler, for event \a event, can be reimplemented in a subclass
3491     to receive drag enter events for the scene.
3492
3493     The default implementation accepts the event and prepares the scene to
3494     accept drag move events.
3495
3496     \sa QGraphicsItem::dragEnterEvent(), dragMoveEvent(), dragLeaveEvent(),
3497     dropEvent()
3498 */
3499 void QGraphicsScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
3500 {
3501     Q_D(QGraphicsScene);
3502     d->dragDropItem = 0;
3503     d->lastDropAction = Qt::IgnoreAction;
3504     event->accept();
3505 }
3506
3507 /*!
3508     This event handler, for event \a event, can be reimplemented in a subclass
3509     to receive drag move events for the scene.
3510
3511     \sa QGraphicsItem::dragMoveEvent(), dragEnterEvent(), dragLeaveEvent(),
3512     dropEvent()
3513 */
3514 void QGraphicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
3515 {
3516     Q_D(QGraphicsScene);
3517     event->ignore();
3518
3519     if (!d->mouseGrabberItems.isEmpty()) {
3520         // Mouse grabbers that start drag events lose the mouse grab.
3521         d->clearMouseGrabber();
3522         d->mouseGrabberButtonDownPos.clear();
3523         d->mouseGrabberButtonDownScenePos.clear();
3524         d->mouseGrabberButtonDownScreenPos.clear();
3525     }
3526
3527     bool eventDelivered = false;
3528
3529     // Find the topmost enabled items under the cursor. They are all
3530     // candidates for accepting drag & drop events.
3531     foreach (QGraphicsItem *item, d->itemsAtPosition(event->screenPos(),
3532                                                      event->scenePos(),
3533                                                      event->widget())) {
3534         if (!item->isEnabled() || !item->acceptDrops())
3535             continue;
3536
3537         if (item != d->dragDropItem) {
3538             // Enter the new drag drop item. If it accepts the event, we send
3539             // the leave to the parent item.
3540             QGraphicsSceneDragDropEvent dragEnter(QEvent::GraphicsSceneDragEnter);
3541             d->cloneDragDropEvent(&dragEnter, event);
3542             dragEnter.setDropAction(event->proposedAction());
3543             d->sendDragDropEvent(item, &dragEnter);
3544             event->setAccepted(dragEnter.isAccepted());
3545             event->setDropAction(dragEnter.dropAction());
3546             if (!event->isAccepted()) {
3547                 // Propagate to the item under
3548                 continue;
3549             }
3550
3551             d->lastDropAction = event->dropAction();
3552
3553             if (d->dragDropItem) {
3554                 // Leave the last drag drop item. A perfect implementation
3555                 // would set the position of this event to the point where
3556                 // this event and the last event intersect with the item's
3557                 // shape, but that's not easy to do. :-)
3558                 QGraphicsSceneDragDropEvent dragLeave(QEvent::GraphicsSceneDragLeave);
3559                 d->cloneDragDropEvent(&dragLeave, event);
3560                 d->sendDragDropEvent(d->dragDropItem, &dragLeave);
3561             }
3562
3563             // We've got a new drag & drop item
3564             d->dragDropItem = item;
3565         }
3566
3567         // Send the move event.
3568         event->setDropAction(d->lastDropAction);
3569         event->accept();
3570         d->sendDragDropEvent(item, event);
3571         if (event->isAccepted())
3572             d->lastDropAction = event->dropAction();
3573         eventDelivered = true;
3574         break;
3575     }
3576
3577     if (!eventDelivered) {
3578         if (d->dragDropItem) {
3579             // Leave the last drag drop item
3580             QGraphicsSceneDragDropEvent dragLeave(QEvent::GraphicsSceneDragLeave);
3581             d->cloneDragDropEvent(&dragLeave, event);
3582             d->sendDragDropEvent(d->dragDropItem, &dragLeave);
3583             d->dragDropItem = 0;
3584         }
3585         // Propagate
3586         event->setDropAction(Qt::IgnoreAction);
3587     }
3588 }
3589
3590 /*!
3591     This event handler, for event \a event, can be reimplemented in a subclass
3592     to receive drag leave events for the scene.
3593
3594     \sa QGraphicsItem::dragLeaveEvent(), dragEnterEvent(), dragMoveEvent(),
3595     dropEvent()
3596 */
3597 void QGraphicsScene::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
3598 {
3599     Q_D(QGraphicsScene);
3600     if (d->dragDropItem) {
3601         // Leave the last drag drop item
3602         d->sendDragDropEvent(d->dragDropItem, event);
3603         d->dragDropItem = 0;
3604     }
3605 }
3606
3607 /*!
3608     This event handler, for event \a event, can be reimplemented in a subclass
3609     to receive drop events for the scene.
3610
3611     \sa QGraphicsItem::dropEvent(), dragEnterEvent(), dragMoveEvent(),
3612     dragLeaveEvent()
3613 */
3614 void QGraphicsScene::dropEvent(QGraphicsSceneDragDropEvent *event)
3615 {
3616     Q_UNUSED(event);
3617     Q_D(QGraphicsScene);
3618     if (d->dragDropItem) {
3619         // Drop on the last drag drop item
3620         d->sendDragDropEvent(d->dragDropItem, event);
3621         d->dragDropItem = 0;
3622     }
3623 }
3624
3625 /*!
3626     This event handler, for event \a focusEvent, can be reimplemented in a
3627     subclass to receive focus in events.
3628
3629     The default implementation sets focus on the scene, and then on the last
3630     focus item.
3631
3632     \sa QGraphicsItem::focusOutEvent()
3633 */
3634 void QGraphicsScene::focusInEvent(QFocusEvent *focusEvent)
3635 {
3636     Q_D(QGraphicsScene);
3637
3638     d->hasFocus = true;
3639     switch (focusEvent->reason()) {
3640     case Qt::TabFocusReason:
3641         if (!focusNextPrevChild(true))
3642             focusEvent->ignore();
3643         break;
3644     case Qt::BacktabFocusReason:
3645         if (!focusNextPrevChild(false))
3646             focusEvent->ignore();
3647         break;
3648     default:
3649         if (d->passiveFocusItem) {
3650             // Set focus on the last focus item
3651             setFocusItem(d->passiveFocusItem, focusEvent->reason());
3652         }
3653         break;
3654     }
3655 }
3656
3657 /*!
3658     This event handler, for event \a focusEvent, can be reimplemented in a
3659     subclass to receive focus out events.
3660
3661     The default implementation removes focus from any focus item, then removes
3662     focus from the scene.
3663
3664     \sa QGraphicsItem::focusInEvent()
3665 */
3666 void QGraphicsScene::focusOutEvent(QFocusEvent *focusEvent)
3667 {
3668     Q_D(QGraphicsScene);
3669     d->hasFocus = false;
3670     d->passiveFocusItem = d->focusItem;
3671     setFocusItem(0, focusEvent->reason());
3672
3673     // Remove all popups when the scene loses focus.
3674     if (!d->popupWidgets.isEmpty())
3675         d->removePopup(d->popupWidgets.first());
3676 }
3677
3678 /*!
3679     This event handler, for event \a helpEvent, can be
3680     reimplemented in a subclass to receive help events. The events
3681     are of type QEvent::ToolTip, which are created when a tooltip is
3682     requested.
3683
3684     The default implementation shows the tooltip of the topmost
3685     item, i.e., the item with the highest z-value, at the mouse
3686     cursor position. If no item has a tooltip set, this function
3687     does nothing.
3688
3689    \sa QGraphicsItem::toolTip(), QGraphicsSceneHelpEvent
3690 */
3691 void QGraphicsScene::helpEvent(QGraphicsSceneHelpEvent *helpEvent)
3692 {
3693 #ifdef QT_NO_TOOLTIP
3694     Q_UNUSED(helpEvent);
3695 #else
3696     // Find the first item that does tooltips
3697     Q_D(QGraphicsScene);
3698     QList<QGraphicsItem *> itemsAtPos = d->itemsAtPosition(helpEvent->screenPos(),
3699                                                            helpEvent->scenePos(),
3700                                                            helpEvent->widget());
3701     QGraphicsItem *toolTipItem = 0;
3702     for (int i = 0; i < itemsAtPos.size(); ++i) {
3703         QGraphicsItem *tmp = itemsAtPos.at(i);
3704         if (tmp->d_func()->isProxyWidget()) {
3705             // if the item is a proxy widget, the event is forwarded to it
3706             sendEvent(tmp, helpEvent);
3707             if (helpEvent->isAccepted())
3708                 return;
3709         }
3710         if (!tmp->toolTip().isEmpty()) {
3711             toolTipItem = tmp;
3712             break;
3713         }
3714     }
3715
3716     // Show or hide the tooltip
3717     QString text;
3718     QPoint point;
3719     if (toolTipItem && !toolTipItem->toolTip().isEmpty()) {
3720         text = toolTipItem->toolTip();
3721         point = helpEvent->screenPos();
3722     }
3723     QToolTip::showText(point, text, helpEvent->widget());
3724     helpEvent->setAccepted(!text.isEmpty());
3725 #endif
3726 }
3727
3728 bool QGraphicsScenePrivate::itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const
3729 {
3730     return (item->d_ptr->acceptsHover
3731             || (item->d_ptr->isWidget
3732                 && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration()))
3733            && !item->isBlockedByModalPanel();
3734 }
3735
3736 /*!
3737     This event handler, for event \a hoverEvent, can be reimplemented in a
3738     subclass to receive hover enter events. The default implementation
3739     forwards the event to the topmost item that accepts hover events at the
3740     scene position from the event.
3741
3742     \sa QGraphicsItem::hoverEvent(), QGraphicsItem::setAcceptHoverEvents()
3743 */
3744 bool QGraphicsScenePrivate::dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEvent)
3745 {
3746     if (allItemsIgnoreHoverEvents)
3747         return false;
3748
3749     // Find the first item that accepts hover events, reusing earlier
3750     // calculated data is possible.
3751     if (cachedItemsUnderMouse.isEmpty()) {
3752         cachedItemsUnderMouse = itemsAtPosition(hoverEvent->screenPos(),
3753                                                 hoverEvent->scenePos(),
3754                                                 hoverEvent->widget());
3755     }
3756
3757     QGraphicsItem *item = 0;
3758     for (int i = 0; i < cachedItemsUnderMouse.size(); ++i) {
3759         QGraphicsItem *tmp = cachedItemsUnderMouse.at(i);
3760         if (itemAcceptsHoverEvents_helper(tmp)) {
3761             item = tmp;
3762             break;
3763         }
3764     }
3765
3766     // Find the common ancestor item for the new topmost hoverItem and the
3767     // last item in the hoverItem list.
3768     QGraphicsItem *commonAncestorItem = (item && !hoverItems.isEmpty()) ? item->commonAncestorItem(hoverItems.last()) : 0;
3769     while (commonAncestorItem && !itemAcceptsHoverEvents_helper(commonAncestorItem))
3770         commonAncestorItem = commonAncestorItem->parentItem();
3771     if (commonAncestorItem && commonAncestorItem->panel() != item->panel()) {
3772         // The common ancestor isn't in the same panel as the two hovered
3773         // items.
3774         commonAncestorItem = 0;
3775     }
3776
3777     // Check if the common ancestor item is known.
3778     int index = commonAncestorItem ? hoverItems.indexOf(commonAncestorItem) : -1;
3779     // Send hover leaves to any existing hovered children of the common
3780     // ancestor item.
3781     for (int i = hoverItems.size() - 1; i > index; --i) {
3782         QGraphicsItem *lastItem = hoverItems.takeLast();
3783         if (itemAcceptsHoverEvents_helper(lastItem))
3784             sendHoverEvent(QEvent::GraphicsSceneHoverLeave, lastItem, hoverEvent);
3785     }
3786
3787     // Item is a child of a known item. Generate enter events for the
3788     // missing links.
3789     QList<QGraphicsItem *> parents;
3790     QGraphicsItem *parent = item;
3791     while (parent && parent != commonAncestorItem) {
3792         parents.prepend(parent);
3793         if (parent->isPanel()) {
3794             // Stop at the panel - we don't deliver beyond this point.
3795             break;
3796         }
3797         parent = parent->parentItem();
3798     }
3799     for (int i = 0; i < parents.size(); ++i) {
3800         parent = parents.at(i);
3801         hoverItems << parent;
3802         if (itemAcceptsHoverEvents_helper(parent))
3803             sendHoverEvent(QEvent::GraphicsSceneHoverEnter, parent, hoverEvent);
3804     }
3805
3806     // Generate a move event for the item itself
3807     if (item
3808         && !hoverItems.isEmpty()
3809         && item == hoverItems.last()) {
3810         sendHoverEvent(QEvent::GraphicsSceneHoverMove, item, hoverEvent);
3811         return true;
3812     }
3813     return false;
3814 }
3815
3816 /*!
3817     \internal
3818
3819     Handles all actions necessary to clean up the scene when the mouse leaves
3820     the view.
3821 */
3822 void QGraphicsScenePrivate::leaveScene(QWidget *viewport)
3823 {
3824 #ifndef QT_NO_TOOLTIP
3825     QToolTip::hideText();
3826 #endif
3827     QGraphicsView *view = qobject_cast<QGraphicsView *>(viewport->parent());
3828     // Send HoverLeave events to all existing hover items, topmost first.
3829     QGraphicsSceneHoverEvent hoverEvent;
3830     hoverEvent.setWidget(viewport);
3831
3832     if (view) {
3833         QPoint cursorPos = QCursor::pos();
3834         hoverEvent.setScenePos(view->mapToScene(viewport->mapFromGlobal(cursorPos)));
3835         hoverEvent.setLastScenePos(hoverEvent.scenePos());
3836         hoverEvent.setScreenPos(cursorPos);
3837         hoverEvent.setLastScreenPos(hoverEvent.screenPos());
3838     }
3839
3840     while (!hoverItems.isEmpty()) {
3841         QGraphicsItem *lastItem = hoverItems.takeLast();
3842         if (itemAcceptsHoverEvents_helper(lastItem))
3843             sendHoverEvent(QEvent::GraphicsSceneHoverLeave, lastItem, &hoverEvent);
3844     }
3845 }
3846
3847 /*!
3848     This event handler, for event \a keyEvent, can be reimplemented in a
3849     subclass to receive keypress events. The default implementation forwards
3850     the event to current focus item.
3851
3852     \sa QGraphicsItem::keyPressEvent(), focusItem()
3853 */
3854 void QGraphicsScene::keyPressEvent(QKeyEvent *keyEvent)
3855 {
3856     // ### Merge this function with keyReleaseEvent; they are identical
3857     // ### (except this comment).
3858     Q_D(QGraphicsScene);
3859     QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.last() : 0;
3860     if (!item)
3861         item = focusItem();
3862     if (item) {
3863         QGraphicsItem *p = item;
3864         do {
3865             // Accept the event by default
3866             keyEvent->accept();
3867             // Send it; QGraphicsItem::keyPressEvent ignores it.  If the event
3868             // is filtered out, stop propagating it.
3869             if (p->isBlockedByModalPanel())
3870                 break;
3871             if (!d->sendEvent(p, keyEvent))
3872                 break;
3873         } while (!keyEvent->isAccepted() && !p->isPanel() && (p = p->parentItem()));
3874     } else {
3875         keyEvent->ignore();
3876     }
3877 }
3878
3879 /*!
3880     This event handler, for event \a keyEvent, can be reimplemented in a
3881     subclass to receive key release events. The default implementation
3882     forwards the event to current focus item.
3883
3884     \sa QGraphicsItem::keyReleaseEvent(), focusItem()
3885 */
3886 void QGraphicsScene::keyReleaseEvent(QKeyEvent *keyEvent)
3887 {
3888     // ### Merge this function with keyPressEvent; they are identical (except
3889     // ### this comment).
3890     Q_D(QGraphicsScene);
3891     QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.last() : 0;
3892     if (!item)
3893         item = focusItem();
3894     if (item) {
3895         QGraphicsItem *p = item;
3896         do {
3897             // Accept the event by default
3898             keyEvent->accept();
3899             // Send it; QGraphicsItem::keyPressEvent ignores it.  If the event
3900             // is filtered out, stop propagating it.
3901             if (p->isBlockedByModalPanel())
3902                 break;
3903             if (!d->sendEvent(p, keyEvent))
3904                 break;
3905         } while (!keyEvent->isAccepted() && !p->isPanel() && (p = p->parentItem()));
3906     } else {
3907         keyEvent->ignore();
3908     }
3909 }
3910
3911 /*!
3912     This event handler, for event \a mouseEvent, can be reimplemented
3913     in a subclass to receive mouse press events for the scene.
3914
3915     The default implementation depends on the state of the scene. If
3916     there is a mouse grabber item, then the event is sent to the mouse
3917     grabber. Otherwise, it is forwarded to the topmost item that
3918     accepts mouse events at the scene position from the event, and
3919     that item promptly becomes the mouse grabber item.
3920
3921     If there is no item at the given position on the scene, the
3922     selection area is reset, any focus item loses its input focus, and
3923     the event is then ignored.
3924
3925     \sa QGraphicsItem::mousePressEvent(),
3926     QGraphicsItem::setAcceptedMouseButtons()
3927 */
3928 void QGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
3929 {
3930     Q_D(QGraphicsScene);
3931     if (d->mouseGrabberItems.isEmpty()) {
3932         // Dispatch hover events
3933         QGraphicsSceneHoverEvent hover;
3934         _q_hoverFromMouseEvent(&hover, mouseEvent);
3935         d->dispatchHoverEvent(&hover);
3936     }
3937
3938     d->mousePressEventHandler(mouseEvent);
3939 }
3940
3941 /*!
3942     This event handler, for event \a mouseEvent, can be reimplemented
3943     in a subclass to receive mouse move events for the scene.
3944
3945     The default implementation depends on the mouse grabber state. If there is
3946     a mouse grabber item, the event is sent to the mouse grabber.  If there
3947     are any items that accept hover events at the current position, the event
3948     is translated into a hover event and accepted; otherwise it's ignored.
3949
3950     \sa QGraphicsItem::mousePressEvent(), QGraphicsItem::mouseReleaseEvent(),
3951     QGraphicsItem::mouseDoubleClickEvent(), QGraphicsItem::setAcceptedMouseButtons()
3952 */
3953 void QGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
3954 {
3955     Q_D(QGraphicsScene);
3956     if (d->mouseGrabberItems.isEmpty()) {
3957         if (mouseEvent->buttons())
3958             return;
3959         QGraphicsSceneHoverEvent hover;
3960         _q_hoverFromMouseEvent(&hover, mouseEvent);
3961         mouseEvent->setAccepted(d->dispatchHoverEvent(&hover));
3962         return;
3963     }
3964
3965     // Forward the event to the mouse grabber
3966     d->sendMouseEvent(mouseEvent);
3967     mouseEvent->accept();
3968 }
3969
3970 /*!
3971     This event handler, for event \a mouseEvent, can be reimplemented
3972     in a subclass to receive mouse release events for the scene.
3973
3974     The default implementation depends on the mouse grabber state.  If
3975     there is no mouse grabber, the event is ignored.  Otherwise, if
3976     there is a mouse grabber item, the event is sent to the mouse
3977     grabber. If this mouse release represents the last pressed button
3978     on the mouse, the mouse grabber item then loses the mouse grab.
3979
3980     \sa QGraphicsItem::mousePressEvent(), QGraphicsItem::mouseMoveEvent(),
3981     QGraphicsItem::mouseDoubleClickEvent(), QGraphicsItem::setAcceptedMouseButtons()
3982 */
3983 void QGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
3984 {
3985     Q_D(QGraphicsScene);
3986     if (d->mouseGrabberItems.isEmpty()) {
3987         mouseEvent->ignore();
3988         return;
3989     }
3990
3991     // Forward the event to the mouse grabber
3992     d->sendMouseEvent(mouseEvent);
3993     mouseEvent->accept();
3994
3995     // Reset the mouse grabber when the last mouse button has been released.
3996     if (!mouseEvent->buttons()) {
3997         if (!d->mouseGrabberItems.isEmpty()) {
3998             d->lastMouseGrabberItem = d->mouseGrabberItems.last();
3999             if (d->lastMouseGrabberItemHasImplicitMouseGrab)
4000                 d->mouseGrabberItems.last()->ungrabMouse();
4001         } else {
4002             d->lastMouseGrabberItem = 0;
4003         }
4004
4005         // Generate a hoverevent
4006         QGraphicsSceneHoverEvent hoverEvent;
4007         _q_hoverFromMouseEvent(&hoverEvent, mouseEvent);
4008         d->dispatchHoverEvent(&hoverEvent);
4009     }
4010 }
4011
4012 /*!
4013     This event handler, for event \a mouseEvent, can be reimplemented
4014     in a subclass to receive mouse doubleclick events for the scene.
4015
4016     If someone doubleclicks on the scene, the scene will first receive
4017     a mouse press event, followed by a release event (i.e., a click),
4018     then a doubleclick event, and finally a release event. If the
4019     doubleclick event is delivered to a different item than the one
4020     that received the first press and release, it will be delivered as
4021     a press event. However, tripleclick events are not delivered as
4022     doubleclick events in this case.
4023
4024     The default implementation is similar to mousePressEvent().
4025
4026     \sa QGraphicsItem::mousePressEvent(), QGraphicsItem::mouseMoveEvent(),
4027     QGraphicsItem::mouseReleaseEvent(), QGraphicsItem::setAcceptedMouseButtons()
4028 */
4029 void QGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
4030 {
4031     Q_D(QGraphicsScene);
4032     d->mousePressEventHandler(mouseEvent);
4033 }
4034
4035 /*!
4036     This event handler, for event \a wheelEvent, can be reimplemented in a
4037     subclass to receive mouse wheel events for the scene.
4038
4039     By default, the event is delivered to the topmost visible item under the
4040     cursor. If ignored, the event propagates to the item beneath, and again
4041     until the event is accepted, or it reaches the scene. If no items accept
4042     the event, it is ignored.
4043
4044     \sa QGraphicsItem::wheelEvent()
4045 */
4046 void QGraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent)
4047 {
4048     Q_D(QGraphicsScene);
4049     QList<QGraphicsItem *> wheelCandidates = d->itemsAtPosition(wheelEvent->screenPos(),
4050                                                                 wheelEvent->scenePos(),
4051                                                                 wheelEvent->widget());
4052
4053 #ifdef Q_WS_MAC
4054     // On Mac, ignore the event if the first item under the mouse is not the last opened
4055     // popup (or one of its descendant)
4056     if (!d->popupWidgets.isEmpty() && !wheelCandidates.isEmpty() && wheelCandidates.first() != d->popupWidgets.back() && !d->popupWidgets.back()->isAncestorOf(wheelCandidates.first())) {
4057         wheelEvent->accept();
4058         return;
4059     }
4060 #else
4061     // Find the first popup under the mouse (including the popup's descendants) starting from the last.
4062     // Remove all popups after the one found, or all or them if no popup is under the mouse.
4063     // Then continue with the event.
4064     QList<QGraphicsWidget *>::const_iterator iter = d->popupWidgets.constEnd();
4065     while (--iter >= d->popupWidgets.constBegin() && !wheelCandidates.isEmpty()) {
4066         if (wheelCandidates.first() == *iter || (*iter)->isAncestorOf(wheelCandidates.first()))
4067             break;
4068         d->removePopup(*iter);
4069     }
4070 #endif
4071
4072     bool hasSetFocus = false;
4073     foreach (QGraphicsItem *item, wheelCandidates) {
4074         if (!hasSetFocus && item->isEnabled()
4075             && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
4076             if (item->isWidget() && static_cast<QGraphicsWidget *>(item)->focusPolicy() == Qt::WheelFocus) {
4077                 hasSetFocus = true;
4078                 if (item != focusItem())
4079                     setFocusItem(item, Qt::MouseFocusReason);
4080             }
4081         }
4082
4083         wheelEvent->setPos(item->d_ptr->genericMapFromScene(wheelEvent->scenePos(),
4084                                                             wheelEvent->widget()));
4085         wheelEvent->accept();
4086         bool isPanel = item->isPanel();
4087         d->sendEvent(item, wheelEvent);
4088         if (isPanel || wheelEvent->isAccepted())
4089             break;
4090     }
4091 }
4092
4093 /*!
4094     This event handler, for event \a event, can be reimplemented in a
4095     subclass to receive input method events for the scene.
4096
4097     The default implementation forwards the event to the focusItem().
4098     If no item currently has focus or the current focus item does not
4099     accept input methods, this function does nothing.
4100
4101     \sa QGraphicsItem::inputMethodEvent()
4102 */
4103 void QGraphicsScene::inputMethodEvent(QInputMethodEvent *event)
4104 {
4105     Q_D(QGraphicsScene);
4106     if (d->focusItem && (d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod))
4107         d->sendEvent(d->focusItem, event);
4108 }
4109
4110 /*!
4111     Draws the background of the scene using \a painter, before any items and
4112     the foreground are drawn. Reimplement this function to provide a custom
4113     background for the scene.
4114
4115     All painting is done in \e scene coordinates. The \a rect
4116     parameter is the exposed rectangle.
4117
4118     If all you want is to define a color, texture, or gradient for the
4119     background, you can call setBackgroundBrush() instead.
4120
4121     \sa drawForeground(), drawItems()
4122 */
4123 void QGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
4124 {
4125     Q_D(QGraphicsScene);
4126
4127     if (d->backgroundBrush.style() != Qt::NoBrush) {
4128         if (d->painterStateProtection)
4129             painter->save();
4130         painter->setBrushOrigin(0, 0);
4131         painter->fillRect(rect, backgroundBrush());
4132         if (d->painterStateProtection)
4133             painter->restore();
4134     }
4135 }
4136
4137 /*!
4138     Draws the foreground of the scene using \a painter, after the background
4139     and all items have been drawn. Reimplement this function to provide a
4140     custom foreground for the scene.
4141
4142     All painting is done in \e scene coordinates. The \a rect
4143     parameter is the exposed rectangle.
4144
4145     If all you want is to define a color, texture or gradient for the
4146     foreground, you can call setForegroundBrush() instead.
4147
4148     \sa drawBackground(), drawItems()
4149 */
4150 void QGraphicsScene::drawForeground(QPainter *painter, const QRectF &rect)
4151 {
4152     Q_D(QGraphicsScene);
4153
4154     if (d->foregroundBrush.style() != Qt::NoBrush) {
4155         if (d->painterStateProtection)
4156             painter->save();
4157         painter->setBrushOrigin(0, 0);
4158         painter->fillRect(rect, foregroundBrush());
4159         if (d->painterStateProtection)
4160             painter->restore();
4161     }
4162 }
4163
4164 static void _q_paintItem(QGraphicsItem *item, QPainter *painter,
4165                          const QStyleOptionGraphicsItem *option, QWidget *widget,
4166                          bool useWindowOpacity, bool painterStateProtection)
4167 {
4168     if (!item->isWidget()) {
4169         item->paint(painter, option, widget);
4170         return;
4171     }
4172     QGraphicsWidget *widgetItem = static_cast<QGraphicsWidget *>(item);
4173     QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(widgetItem);
4174     const qreal windowOpacity = (proxy && proxy->widget() && useWindowOpacity)
4175                                 ? proxy->widget()->windowOpacity() : 1.0;
4176     const qreal oldPainterOpacity = painter->opacity();
4177
4178     if (qFuzzyIsNull(windowOpacity))
4179         return;
4180     // Set new painter opacity.
4181     if (windowOpacity < 1.0)
4182         painter->setOpacity(oldPainterOpacity * windowOpacity);
4183
4184     // set layoutdirection on the painter
4185     Qt::LayoutDirection oldLayoutDirection = painter->layoutDirection();
4186     painter->setLayoutDirection(widgetItem->layoutDirection());
4187
4188     if (widgetItem->isWindow() && widgetItem->windowType() != Qt::Popup && widgetItem->windowType() != Qt::ToolTip
4189         && !(widgetItem->windowFlags() & Qt::FramelessWindowHint)) {
4190         if (painterStateProtection)
4191             painter->save();
4192         widgetItem->paintWindowFrame(painter, option, widget);
4193         if (painterStateProtection)
4194             painter->restore();
4195     } else if (widgetItem->autoFillBackground()) {
4196         painter->fillRect(option->exposedRect, widgetItem->palette().window());
4197     }
4198
4199     widgetItem->paint(painter, option, widget);
4200
4201     // Restore layoutdirection on the painter.
4202     painter->setLayoutDirection(oldLayoutDirection);
4203     // Restore painter opacity.
4204     if (windowOpacity < 1.0)
4205         painter->setOpacity(oldPainterOpacity);
4206 }
4207
4208 static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion &pixmapExposed,
4209                               const QTransform &itemToPixmap, QPainter::RenderHints renderHints,
4210                               const QStyleOptionGraphicsItem *option, bool painterStateProtection)
4211 {
4212     QPixmap subPix;
4213     QPainter pixmapPainter;
4214     QRect br = pixmapExposed.boundingRect();
4215
4216     // Don't use subpixmap if we get a full update.
4217     if (pixmapExposed.isEmpty() || (pixmapExposed.rectCount() == 1 && br.contains(pix->rect()))) {
4218         pix->fill(Qt::transparent);
4219         pixmapPainter.begin(pix);
4220     } else {
4221         subPix = QPixmap(br.size());
4222         subPix.fill(Qt::transparent);
4223         pixmapPainter.begin(&subPix);
4224         pixmapPainter.translate(-br.topLeft());
4225         if (!pixmapExposed.isEmpty()) {
4226             // Applied to subPix; paint is adjusted to the coordinate space is
4227             // correct.
4228             pixmapPainter.setClipRegion(pixmapExposed);
4229         }
4230     }
4231
4232     pixmapPainter.setRenderHints(pixmapPainter.renderHints(), false);
4233     pixmapPainter.setRenderHints(renderHints, true);
4234     pixmapPainter.setWorldTransform(itemToPixmap, true);
4235
4236     // Render.
4237     _q_paintItem(item, &pixmapPainter, option, 0, false, painterStateProtection);
4238     pixmapPainter.end();
4239
4240     if (!subPix.isNull()) {
4241         // Blit the subpixmap into the main pixmap.
4242         pixmapPainter.begin(pix);
4243         pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
4244         pixmapPainter.setClipRegion(pixmapExposed);
4245         pixmapPainter.drawPixmap(br.topLeft(), subPix);
4246         pixmapPainter.end();
4247     }
4248 }
4249
4250 // Copied from qpaintengine_vg.cpp
4251 // Returns true for 90, 180, and 270 degree rotations.
4252 static inline bool transformIsSimple(const QTransform& transform)
4253 {
4254     QTransform::TransformationType type = transform.type();
4255     if (type <= QTransform::TxScale) {
4256         return true;
4257     } else if (type == QTransform::TxRotate) {
4258         // Check for 90, and 270 degree rotations.
4259         qreal m11 = transform.m11();
4260         qreal m12 = transform.m12();
4261         qreal m21 = transform.m21();
4262         qreal m22 = transform.m22();
4263         if (m11 == 0.0f && m22 == 0.0f) {
4264             if (m12 == 1.0f && m21 == -1.0f)
4265                 return true; // 90 degrees.
4266             else if (m12 == -1.0f && m21 == 1.0f)
4267                 return true; // 270 degrees.
4268             else if (m12 == -1.0f && m21 == -1.0f)
4269                 return true; // 90 degrees inverted y.
4270             else if (m12 == 1.0f && m21 == 1.0f)
4271                 return true; // 270 degrees inverted y.
4272         }
4273     }
4274     return false;
4275 }
4276
4277 /*!
4278     \internal
4279
4280     Draws items directly, or using cache.
4281 */
4282 void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painter,
4283                                            const QStyleOptionGraphicsItem *option, QWidget *widget,
4284                                            bool painterStateProtection)
4285 {
4286     QGraphicsItemPrivate *itemd = item->d_ptr.data();
4287     QGraphicsItem::CacheMode cacheMode = QGraphicsItem::CacheMode(itemd->cacheMode);
4288
4289     // Render directly, using no cache.
4290     if (cacheMode == QGraphicsItem::NoCache
4291 #ifdef Q_WS_X11
4292         || !X11->use_xrender
4293 #endif
4294         ) {
4295         _q_paintItem(static_cast<QGraphicsWidget *>(item), painter, option, widget, true, painterStateProtection);
4296         return;
4297     }
4298
4299     const qreal oldPainterOpacity = painter->opacity();
4300     qreal newPainterOpacity = oldPainterOpacity;
4301     QGraphicsProxyWidget *proxy = item->isWidget() ? qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(item)) : 0;
4302     if (proxy && proxy->widget()) {
4303         const qreal windowOpacity = proxy->widget()->windowOpacity();
4304         if (windowOpacity < 1.0)
4305             newPainterOpacity *= windowOpacity;
4306     }
4307
4308     // Item's (local) bounding rect
4309     QRectF brect = item->boundingRect();
4310     QRectF adjustedBrect(brect);
4311     _q_adjustRect(&adjustedBrect);
4312     if (adjustedBrect.isEmpty())
4313         return;
4314
4315     // Fetch the off-screen transparent buffer and exposed area info.
4316     QPixmapCache::Key pixmapKey;
4317     QPixmap pix;
4318     bool pixmapFound;
4319     QGraphicsItemCache *itemCache = itemd->extraItemCache();
4320     if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
4321         pixmapKey = itemCache->key;
4322     } else {
4323         pixmapKey = itemCache->deviceData.value(widget).key;
4324     }
4325
4326     // Find pixmap in cache.
4327     pixmapFound = QPixmapCache::find(pixmapKey, &pix);
4328
4329     // Render using item coordinate cache mode.
4330     if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
4331         QSize pixmapSize;
4332         bool fixedCacheSize = false;
4333         QRect br = brect.toAlignedRect();
4334         if ((fixedCacheSize = itemCache->fixedSize.isValid())) {
4335             pixmapSize = itemCache->fixedSize;
4336         } else {
4337             pixmapSize = br.size();
4338         }
4339
4340         // Create or recreate the pixmap.
4341         int adjust = itemCache->fixedSize.isValid() ? 0 : 2;
4342         QSize adjustSize(adjust*2, adjust*2);
4343         br.adjust(-adjust, -adjust, adjust, adjust);
4344         if (pix.isNull() || (!fixedCacheSize && (pixmapSize + adjustSize) != pix.size())) {
4345             pix = QPixmap(pixmapSize + adjustSize);
4346             itemCache->boundingRect = br;
4347             itemCache->exposed.clear();
4348             itemCache->allExposed = true;
4349         } else if (itemCache->boundingRect != br) {
4350             itemCache->boundingRect = br;
4351             itemCache->exposed.clear();
4352             itemCache->allExposed = true;
4353         }
4354
4355         // Redraw any newly exposed areas.
4356         if (itemCache->allExposed || !itemCache->exposed.isEmpty()) {
4357
4358             //We know that we will modify the pixmap, removing it from the cache
4359             //will detach the one we have and avoid a deep copy
4360             if (pixmapFound)
4361                 QPixmapCache::remove(pixmapKey);
4362
4363             // Fit the item's bounding rect into the pixmap's coordinates.
4364             QTransform itemToPixmap;
4365             if (fixedCacheSize) {
4366                 const QPointF scale(pixmapSize.width() / brect.width(), pixmapSize.height() / brect.height());
4367                 itemToPixmap.scale(scale.x(), scale.y());
4368             }
4369             itemToPixmap.translate(-br.x(), -br.y());
4370
4371             // Generate the item's exposedRect and map its list of expose
4372             // rects to device coordinates.
4373             styleOptionTmp = *option;
4374             QRegion pixmapExposed;
4375             QRectF exposedRect;
4376             if (!itemCache->allExposed) {
4377                 for (int i = 0; i < itemCache->exposed.size(); ++i) {
4378                     QRectF r = itemCache->exposed.at(i);
4379                     exposedRect |= r;
4380                     pixmapExposed += itemToPixmap.mapRect(r).toAlignedRect();
4381                 }
4382             } else {
4383                 exposedRect = brect;
4384             }
4385             styleOptionTmp.exposedRect = exposedRect;
4386
4387             // Render.
4388             _q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
4389                               &styleOptionTmp, painterStateProtection);
4390
4391             // insert this pixmap into the cache.
4392             itemCache->key = QPixmapCache::insert(pix);
4393
4394             // Reset expose data.
4395             itemCache->allExposed = false;
4396             itemCache->exposed.clear();
4397         }
4398
4399         // Redraw the exposed area using the transformed painter. Depending on
4400         // the hardware, this may be a server-side operation, or an expensive
4401         // qpixmap-image-transform-pixmap roundtrip.
4402         if (newPainterOpacity != oldPainterOpacity) {
4403             painter->setOpacity(newPainterOpacity);
4404             painter->drawPixmap(br.topLeft(), pix);
4405             painter->setOpacity(oldPainterOpacity);
4406         } else {
4407             painter->drawPixmap(br.topLeft(), pix);
4408         }
4409         return;
4410     }
4411
4412     // Render using device coordinate cache mode.
4413     if (cacheMode == QGraphicsItem::DeviceCoordinateCache) {
4414         // Find the item's bounds in device coordinates.
4415         QRectF deviceBounds = painter->worldTransform().mapRect(brect);
4416         QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
4417         if (deviceRect.isEmpty())
4418             return;
4419         QRect viewRect = widget ? widget->rect() : QRect();
4420         if (widget && !viewRect.intersects(deviceRect))
4421             return;
4422
4423         // Resort to direct rendering if the device rect exceeds the
4424         // (optional) maximum bounds. (QGraphicsSvgItem uses this).
4425         QSize maximumCacheSize =
4426             itemd->extra(QGraphicsItemPrivate::ExtraMaxDeviceCoordCacheSize).toSize();
4427         if (!maximumCacheSize.isEmpty()
4428             && (deviceRect.width() > maximumCacheSize.width()
4429                 || deviceRect.height() > maximumCacheSize.height())) {
4430             _q_paintItem(static_cast<QGraphicsWidget *>(item), painter, option, widget,
4431                          oldPainterOpacity != newPainterOpacity, painterStateProtection);
4432             return;
4433         }
4434
4435         // Create or reuse offscreen pixmap, possibly scroll/blit from the old one.
4436         // If the world transform is rotated we always recreate the cache to avoid
4437         // wrong blending.
4438         bool pixModified = false;
4439         QGraphicsItemCache::DeviceData *deviceData = &itemCache->deviceData[widget];
4440         bool invertable = true;
4441         QTransform diff = deviceData->lastTransform.inverted(&invertable);
4442         if (invertable)
4443             diff *= painter->worldTransform();
4444         deviceData->lastTransform = painter->worldTransform();
4445         bool allowPartialCacheExposure = false;
4446         bool simpleTransform = invertable && diff.type() <= QTransform::TxTranslate
4447                                && transformIsSimple(painter->worldTransform());
4448         if (!simpleTransform) {
4449             pixModified = true;
4450             itemCache->allExposed = true;
4451             itemCache->exposed.clear();
4452             deviceData->cacheIndent = QPoint();
4453             pix = QPixmap();
4454         } else if (!viewRect.isNull()) {
4455             allowPartialCacheExposure = deviceData->cacheIndent != QPoint();
4456         }
4457
4458         // Allow partial cache exposure if the device rect isn't fully contained and
4459         // deviceRect is 20% taller or wider than the viewRect.
4460         if (!allowPartialCacheExposure && !viewRect.isNull() && !viewRect.contains(deviceRect)) {
4461             allowPartialCacheExposure = (viewRect.width() * 1.2 < deviceRect.width())
4462                                          || (viewRect.height() * 1.2 < deviceRect.height());
4463         }
4464
4465         QRegion scrollExposure;
4466         if (allowPartialCacheExposure) {
4467             // Part of pixmap is drawn. Either device contains viewrect (big
4468             // item covers whole screen) or parts of device are outside the
4469             // viewport. In either case the device rect must be the intersect
4470             // between the two.
4471             int dx = deviceRect.left() < viewRect.left() ? viewRect.left() - deviceRect.left() : 0;
4472             int dy = deviceRect.top() < viewRect.top() ? viewRect.top() - deviceRect.top() : 0;
4473             QPoint newCacheIndent(dx, dy);
4474             deviceRect &= viewRect;
4475
4476             if (pix.isNull()) {
4477                 deviceData->cacheIndent = QPoint();
4478                 itemCache->allExposed = true;
4479                 itemCache->exposed.clear();
4480                 pixModified = true;
4481             }
4482
4483             // Copy / "scroll" the old pixmap onto the new ole and calculate
4484             // scrolled exposure.
4485             if (newCacheIndent != deviceData->cacheIndent || deviceRect.size() != pix.size()) {
4486                 QPoint diff = newCacheIndent - deviceData->cacheIndent;
4487                 QPixmap newPix(deviceRect.size());
4488                 // ### Investigate removing this fill (test with Plasma and
4489                 // graphicssystem raster).
4490                 newPix.fill(Qt::transparent);
4491                 if (!pix.isNull()) {
4492                     QPainter newPixPainter(&newPix);
4493                     newPixPainter.drawPixmap(-diff, pix);
4494                     newPixPainter.end();
4495                 }
4496                 QRegion exposed;
4497                 exposed += newPix.rect();
4498                 if (!pix.isNull())
4499                     exposed -= QRect(-diff, pix.size());
4500                 scrollExposure = exposed;
4501
4502                 pix = newPix;
4503                 pixModified = true;
4504             }
4505             deviceData->cacheIndent = newCacheIndent;
4506         } else {
4507             // Full pixmap is drawn.
4508             deviceData->cacheIndent = QPoint();
4509
4510             // Auto-adjust the pixmap size.
4511             if (deviceRect.size() != pix.size()) {
4512                 // exposed needs to cover the whole pixmap
4513                 pix = QPixmap(deviceRect.size());
4514                 pixModified = true;
4515                 itemCache->allExposed = true;
4516                 itemCache->exposed.clear();
4517             }
4518         }
4519
4520         // Check for newly invalidated areas.
4521         if (itemCache->allExposed || !itemCache->exposed.isEmpty() || !scrollExposure.isEmpty()) {
4522             //We know that we will modify the pixmap, removing it from the cache
4523             //will detach the one we have and avoid a deep copy
4524             if (pixmapFound)
4525                 QPixmapCache::remove(pixmapKey);
4526
4527             // Construct an item-to-pixmap transform.
4528             QPointF p = deviceRect.topLeft();
4529             QTransform itemToPixmap = painter->worldTransform();
4530             if (!p.isNull())
4531                 itemToPixmap *= QTransform::fromTranslate(-p.x(), -p.y());
4532
4533             // Map the item's logical expose to pixmap coordinates.
4534             QRegion pixmapExposed = scrollExposure;
4535             if (!itemCache->allExposed) {
4536                 const QVector<QRectF> &exposed = itemCache->exposed;
4537                 for (int i = 0; i < exposed.size(); ++i)
4538                     pixmapExposed += itemToPixmap.mapRect(exposed.at(i)).toRect().adjusted(-1, -1, 1, 1);
4539             }
4540
4541             // Calculate the style option's exposedRect.
4542             QRectF br;
4543             if (itemCache->allExposed) {
4544                 br = item->boundingRect();
4545             } else {
4546                 const QVector<QRectF> &exposed = itemCache->exposed;
4547                 for (int i = 0; i < exposed.size(); ++i)
4548                     br |= exposed.at(i);
4549                 QTransform pixmapToItem = itemToPixmap.inverted();
4550                 foreach (QRect r, scrollExposure.rects())
4551                     br |= pixmapToItem.mapRect(r);
4552             }
4553             styleOptionTmp = *option;
4554             styleOptionTmp.exposedRect = br.adjusted(-1, -1, 1, 1);
4555
4556             // Render the exposed areas.
4557             _q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
4558                               &styleOptionTmp, painterStateProtection);
4559
4560             // Reset expose data.
4561             pixModified = true;
4562             itemCache->allExposed = false;
4563             itemCache->exposed.clear();
4564         }
4565
4566         if (pixModified) {
4567             // Insert this pixmap into the cache.
4568             deviceData->key = QPixmapCache::insert(pix);
4569         }
4570
4571         // Redraw the exposed area using an untransformed painter. This
4572         // effectively becomes a bitblit that does not transform the cache.
4573         QTransform restoreTransform = painter->worldTransform();
4574         painter->setWorldTransform(QTransform());
4575         if (newPainterOpacity != oldPainterOpacity) {
4576             painter->setOpacity(newPainterOpacity);
4577             painter->drawPixmap(deviceRect.topLeft(), pix);
4578             painter->setOpacity(oldPainterOpacity);
4579         } else {
4580             painter->drawPixmap(deviceRect.topLeft(), pix);
4581         }
4582         painter->setWorldTransform(restoreTransform);
4583         return;
4584     }
4585 }
4586
4587 void QGraphicsScenePrivate::drawItems(QPainter *painter, const QTransform *const viewTransform,
4588                                       QRegion *exposedRegion, QWidget *widget)
4589 {
4590     // Make sure we don't have unpolished items before we draw.
4591     if (!unpolishedItems.isEmpty())
4592         _q_polishItems();
4593
4594     updateAll = false;
4595     QRectF exposedSceneRect;
4596     if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) {
4597         exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1);
4598         if (viewTransform)
4599             exposedSceneRect = viewTransform->inverted().mapRect(exposedSceneRect);
4600     }
4601     const QList<QGraphicsItem *> tli = index->estimateTopLevelItems(exposedSceneRect, Qt::AscendingOrder);
4602     for (int i = 0; i < tli.size(); ++i)
4603         drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget);
4604 }
4605
4606 void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter,
4607                                                  const QTransform *const viewTransform,
4608                                                  QRegion *exposedRegion, QWidget *widget,
4609                                                  qreal parentOpacity, const QTransform *const effectTransform)
4610 {
4611     Q_ASSERT(item);
4612
4613     if (!item->d_ptr->visible)
4614         return;
4615
4616     const bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents);
4617     const bool itemHasChildren = !item->d_ptr->children.isEmpty();
4618     if (!itemHasContents && !itemHasChildren)
4619         return; // Item has neither contents nor children!(?)
4620
4621     const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
4622     const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
4623     if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
4624         return;
4625
4626     QTransform transform(Qt::Uninitialized);
4627     QTransform *transformPtr = 0;
4628     bool translateOnlyTransform = false;
4629 #define ENSURE_TRANSFORM_PTR \
4630     if (!transformPtr) { \
4631         Q_ASSERT(!itemIsUntransformable); \
4632         if (viewTransform) { \
4633             transform = item->d_ptr->sceneTransform; \
4634             transform *= *viewTransform; \
4635             transformPtr = &transform; \
4636         } else { \
4637             transformPtr = &item->d_ptr->sceneTransform; \
4638             translateOnlyTransform = item->d_ptr->sceneTransformTranslateOnly; \
4639         } \
4640     }
4641
4642     // Update the item's scene transform if the item is transformable;
4643     // otherwise calculate the full transform,
4644     bool wasDirtyParentSceneTransform = false;
4645     const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
4646     if (itemIsUntransformable) {
4647         transform = item->deviceTransform(viewTransform ? *viewTransform : QTransform());
4648         transformPtr = &transform;
4649     } else if (item->d_ptr->dirtySceneTransform) {
4650         item->d_ptr->updateSceneTransformFromParent();
4651         Q_ASSERT(!item->d_ptr->dirtySceneTransform);
4652         wasDirtyParentSceneTransform = true;
4653     }
4654
4655     const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
4656     bool drawItem = itemHasContents && !itemIsFullyTransparent;
4657     if (drawItem) {
4658         const QRectF brect = adjustedItemEffectiveBoundingRect(item);
4659         ENSURE_TRANSFORM_PTR
4660         QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toAlignedRect()
4661                                                         : transformPtr->mapRect(brect).toAlignedRect();
4662         viewBoundingRect.adjust(-int(rectAdjust), -int(rectAdjust), rectAdjust, rectAdjust);
4663         if (widget)
4664             item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
4665         drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect)
4666                                  : !viewBoundingRect.normalized().isEmpty();
4667         if (!drawItem) {
4668             if (!itemHasChildren)
4669                 return;
4670             if (itemClipsChildrenToShape) {
4671                 if (wasDirtyParentSceneTransform)
4672                     item->d_ptr->invalidateChildrenSceneTransform();
4673                 return;
4674             }
4675         }
4676     } // else we know for sure this item has children we must process.
4677
4678     if (itemHasChildren && itemClipsChildrenToShape)
4679         ENSURE_TRANSFORM_PTR;
4680
4681 #ifndef QT_NO_GRAPHICSEFFECT
4682     if (item->d_ptr->graphicsEffect && item->d_ptr->graphicsEffect->isEnabled()) {
4683         ENSURE_TRANSFORM_PTR;
4684         QGraphicsItemPaintInfo info(viewTransform, transformPtr, effectTransform, exposedRegion, widget, &styleOptionTmp,
4685                                     painter, opacity, wasDirtyParentSceneTransform, itemHasContents && !itemIsFullyTransparent);
4686         QGraphicsEffectSource *source = item->d_ptr->graphicsEffect->d_func()->source;
4687         QGraphicsItemEffectSourcePrivate *sourced = static_cast<QGraphicsItemEffectSourcePrivate *>
4688                                                     (source->d_func());
4689         sourced->info = &info;
4690         const QTransform restoreTransform = painter->worldTransform();
4691         if (effectTransform)
4692             painter->setWorldTransform(*transformPtr * *effectTransform);
4693         else
4694             painter->setWorldTransform(*transformPtr);
4695         painter->setOpacity(opacity);
4696
4697         if (sourced->currentCachedSystem() != Qt::LogicalCoordinates
4698             && sourced->lastEffectTransform != painter->worldTransform())
4699         {
4700             if (sourced->lastEffectTransform.type() <= QTransform::TxTranslate
4701                 && painter->worldTransform().type() <= QTransform::TxTranslate)
4702             {
4703                 QRectF sourceRect = sourced->boundingRect(Qt::DeviceCoordinates);
4704                 QRect effectRect = sourced->paddedEffectRect(Qt::DeviceCoordinates, sourced->currentCachedMode(), sourceRect);
4705
4706                 sourced->setCachedOffset(effectRect.topLeft());
4707             } else {
4708                 sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
4709             }
4710
4711             sourced->lastEffectTransform = painter->worldTransform();
4712         }
4713
4714         item->d_ptr->graphicsEffect->draw(painter);
4715         painter->setWorldTransform(restoreTransform);
4716         sourced->info = 0;
4717     } else
4718 #endif //QT_NO_GRAPHICSEFFECT
4719     {
4720         draw(item, painter, viewTransform, transformPtr, exposedRegion, widget, opacity,
4721              effectTransform, wasDirtyParentSceneTransform, drawItem);
4722     }
4723 }
4724
4725 static inline void setClip(QPainter *painter, QGraphicsItem *item)
4726 {
4727     painter->save();
4728     QRectF clipRect;
4729     const QPainterPath clipPath(item->shape());
4730     if (QPathClipper::pathToRect(clipPath, &clipRect))
4731         painter->setClipRect(clipRect, Qt::IntersectClip);
4732     else
4733         painter->setClipPath(clipPath, Qt::IntersectClip);
4734 }
4735
4736 static inline void setWorldTransform(QPainter *painter, const QTransform *const transformPtr,
4737                                      const QTransform *effectTransform)
4738 {
4739     Q_ASSERT(transformPtr);
4740     if (effectTransform)
4741         painter->setWorldTransform(*transformPtr * *effectTransform);
4742     else
4743         painter->setWorldTransform(*transformPtr);
4744 }
4745
4746 void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const QTransform *const viewTransform,
4747                                  const QTransform *const transformPtr, QRegion *exposedRegion, QWidget *widget,
4748                                  qreal opacity, const QTransform *effectTransform,
4749                                  bool wasDirtyParentSceneTransform, bool drawItem)
4750 {
4751     const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
4752     const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
4753     const bool itemHasChildren = !item->d_ptr->children.isEmpty();
4754     bool setChildClip = itemClipsChildrenToShape;
4755     bool itemHasChildrenStackedBehind = false;
4756
4757     int i = 0;
4758     if (itemHasChildren) {
4759         if (itemClipsChildrenToShape)
4760             setWorldTransform(painter, transformPtr, effectTransform);
4761
4762         item->d_ptr->ensureSortedChildren();
4763         // Items with the 'ItemStacksBehindParent' flag are put in front of the list
4764         // so all we have to do is to check the first item.
4765         itemHasChildrenStackedBehind = (item->d_ptr->children.at(0)->d_ptr->flags
4766                                         & QGraphicsItem::ItemStacksBehindParent);
4767
4768         if (itemHasChildrenStackedBehind) {
4769             if (itemClipsChildrenToShape) {
4770                 setClip(painter, item);
4771                 setChildClip = false;
4772             }
4773
4774             // Draw children behind
4775             for (i = 0; i < item->d_ptr->children.size(); ++i) {
4776                 QGraphicsItem *child = item->d_ptr->children.at(i);
4777                 if (wasDirtyParentSceneTransform)
4778                     child->d_ptr->dirtySceneTransform = 1;
4779                 if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
4780                     break;
4781                 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
4782                     continue;
4783                 drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform);
4784             }
4785         }
4786     }
4787
4788     // Draw item
4789     if (drawItem) {
4790         Q_ASSERT(!itemIsFullyTransparent);
4791         Q_ASSERT(!(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents));
4792         Q_ASSERT(transformPtr);
4793         item->d_ptr->initStyleOption(&styleOptionTmp, *transformPtr, exposedRegion
4794                                      ? *exposedRegion : QRegion(), exposedRegion == 0);
4795
4796         const bool itemClipsToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsToShape;
4797         bool restorePainterClip = false;
4798
4799         if (!itemHasChildren || !itemClipsChildrenToShape) {
4800             // Item does not have children or clip children to shape.
4801             setWorldTransform(painter, transformPtr, effectTransform);
4802             if ((restorePainterClip = itemClipsToShape))
4803                 setClip(painter, item);
4804         } else if (itemHasChildrenStackedBehind){
4805             // Item clips children to shape and has children stacked behind, which means
4806             // the painter is already clipped to the item's shape.
4807             if (itemClipsToShape) {
4808                 // The clip is already correct. Ensure correct world transform.
4809                 setWorldTransform(painter, transformPtr, effectTransform);
4810             } else {
4811                 // Remove clip (this also ensures correct world transform).
4812                 painter->restore();
4813                 setChildClip = true;
4814             }
4815         } else if (itemClipsToShape) {
4816             // Item clips children and itself to shape. It does not have hildren stacked
4817             // behind, which means the clip has not yet been set. We set it now and re-use it
4818             // for the children.
4819             setClip(painter, item);
4820             setChildClip = false;
4821         }
4822
4823         if (painterStateProtection && !restorePainterClip)
4824             painter->save();
4825
4826         painter->setOpacity(opacity);
4827         if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget)
4828             item->paint(painter, &styleOptionTmp, widget);
4829         else
4830             drawItemHelper(item, painter, &styleOptionTmp, widget, painterStateProtection);
4831
4832         if (painterStateProtection || restorePainterClip)
4833             painter->restore();
4834
4835         static int drawRect = qgetenv("QT_DRAW_SCENE_ITEM_RECTS").toInt();
4836         if (drawRect) {
4837             QPen oldPen = painter->pen();
4838             QBrush oldBrush = painter->brush();
4839             quintptr ptr = reinterpret_cast<quintptr>(item);
4840             const QColor color = QColor::fromHsv(ptr % 255, 255, 255);
4841             painter->setPen(color);
4842             painter->setBrush(Qt::NoBrush);
4843             painter->drawRect(adjustedItemBoundingRect(item));
4844             painter->setPen(oldPen);
4845             painter->setBrush(oldBrush);
4846         }
4847     }
4848
4849     // Draw children in front
4850     if (itemHasChildren) {
4851         if (setChildClip)
4852             setClip(painter, item);
4853
4854         for (; i < item->d_ptr->children.size(); ++i) {
4855             QGraphicsItem *child = item->d_ptr->children.at(i);
4856             if (wasDirtyParentSceneTransform)
4857                 child->d_ptr->dirtySceneTransform = 1;
4858             if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
4859                 continue;
4860             drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform);
4861         }
4862
4863         // Restore child clip
4864         if (itemClipsChildrenToShape)
4865             painter->restore();
4866     }
4867 }
4868
4869 void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren,
4870                                       bool force, bool ignoreOpacity, bool removingItemFromScene,
4871                                       bool updateBoundingRect)
4872 {
4873     Q_ASSERT(item);
4874     if (updateAll)
4875         return;
4876
4877     if (removingItemFromScene && !ignoreOpacity && !item->d_ptr->ignoreOpacity) {
4878         // If any of the item's ancestors ignore opacity, it means that the opacity
4879         // was set to 0 (and the update request has not yet been processed). That
4880         // also means that we have to ignore the opacity for the item itself; otherwise
4881         // things like: parent->setOpacity(0); scene->removeItem(child) won't work.
4882         // Note that we only do this when removing items from the scene. In all other
4883         // cases the ignoreOpacity bit propagates properly in processDirtyItems, but
4884         // since the item is removed immediately it won't be processed there.
4885         QGraphicsItem *p = item->d_ptr->parent;
4886         while (p) {
4887             if (p->d_ptr->ignoreOpacity) {
4888                 item->d_ptr->ignoreOpacity = true;
4889                 break;
4890             }
4891             p = p->d_ptr->parent;
4892         }
4893     }
4894
4895     if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force,
4896                                           /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren,
4897                                           /*ignoreOpacity=*/ignoreOpacity)) {
4898         if (item->d_ptr->dirty) {
4899             // The item is already marked as dirty and will be processed later. However,
4900             // we have to make sure ignoreVisible and ignoreOpacity are set properly;
4901             // otherwise things like: item->update(); item->hide() (force is now true)
4902             // won't work as expected.
4903             if (force)
4904                 item->d_ptr->ignoreVisible = 1;
4905             if (ignoreOpacity)
4906                 item->d_ptr->ignoreOpacity = 1;
4907         }
4908         return;
4909     }
4910
4911     const bool fullItemUpdate = rect.isNull();
4912     if (!fullItemUpdate && rect.isEmpty())
4913         return;
4914
4915     if (!processDirtyItemsEmitted) {
4916         QMetaMethod method = q_ptr->metaObject()->method(processDirtyItemsIndex);
4917         method.invoke(q_ptr, Qt::QueuedConnection);
4918 //        QMetaObject::invokeMethod(q_ptr, "_q_processDirtyItems", Qt::QueuedConnection);
4919         processDirtyItemsEmitted = true;
4920     }
4921
4922     if (removingItemFromScene) {
4923         // Note that this function can be called from the item's destructor, so
4924         // do NOT call any virtual functions on it within this block.
4925         if (isSignalConnected(changedSignalIndex) || views.isEmpty()) {
4926             // This block of code is kept for compatibility. Since 4.5, by default
4927             // QGraphicsView does not connect the signal and we use the below
4928             // method of delivering updates.
4929             q_func()->update();
4930             return;
4931         }
4932
4933         for (int i = 0; i < views.size(); ++i) {
4934             QGraphicsViewPrivate *viewPrivate = views.at(i)->d_func();
4935             QRect rect = item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport);
4936             rect.translate(viewPrivate->dirtyScrollOffset);
4937             viewPrivate->updateRect(rect);
4938         }
4939         return;
4940     }
4941
4942     bool hasNoContents = item->d_ptr->flags & QGraphicsItem::ItemHasNoContents;
4943     if (!hasNoContents) {
4944         item->d_ptr->dirty = 1;
4945         if (fullItemUpdate)
4946             item->d_ptr->fullUpdatePending = 1;
4947         else if (!item->d_ptr->fullUpdatePending)
4948             item->d_ptr->needsRepaint |= rect;
4949     } else if (item->d_ptr->graphicsEffect) {
4950         invalidateChildren = true;
4951     }
4952
4953     if (invalidateChildren) {
4954         item->d_ptr->allChildrenDirty = 1;
4955         item->d_ptr->dirtyChildren = 1;
4956     }
4957
4958     if (force)
4959         item->d_ptr->ignoreVisible = 1;
4960     if (ignoreOpacity)
4961         item->d_ptr->ignoreOpacity = 1;
4962
4963     if (!updateBoundingRect)
4964         item->d_ptr->markParentDirty();
4965 }
4966
4967 static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item,
4968                                 const QRectF &rect, bool itemIsUntransformable)
4969 {
4970     Q_ASSERT(view);
4971     Q_ASSERT(item);
4972
4973     QGraphicsItem *itemq = static_cast<QGraphicsItem *>(item->q_ptr);
4974     QGraphicsView *viewq = static_cast<QGraphicsView *>(view->q_ptr);
4975
4976     if (itemIsUntransformable) {
4977         const QTransform xform = itemq->deviceTransform(viewq->viewportTransform());
4978         if (!item->hasBoundingRegionGranularity)
4979             return view->updateRectF(xform.mapRect(rect));
4980         return view->updateRegion(rect, xform);
4981     }
4982
4983     if (item->sceneTransformTranslateOnly && view->identityMatrix) {
4984         const qreal dx = item->sceneTransform.dx();
4985         const qreal dy = item->sceneTransform.dy();
4986         QRectF r(rect);
4987         r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll());
4988         return view->updateRectF(r);
4989     }
4990
4991     if (!viewq->isTransformed()) {
4992         if (!item->hasBoundingRegionGranularity)
4993             return view->updateRectF(item->sceneTransform.mapRect(rect));
4994         return view->updateRegion(rect, item->sceneTransform);
4995     }
4996
4997     QTransform xform = item->sceneTransform;
4998     xform *= viewq->viewportTransform();
4999     if (!item->hasBoundingRegionGranularity)
5000         return view->updateRectF(xform.mapRect(rect));
5001     return view->updateRegion(rect, xform);
5002 }
5003
5004 void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren,
5005                                                        qreal parentOpacity)
5006 {
5007     Q_Q(QGraphicsScene);
5008     Q_ASSERT(item);
5009     Q_ASSERT(!updateAll);
5010
5011     if (!item->d_ptr->dirty && !item->d_ptr->dirtyChildren) {
5012         resetDirtyItem(item);
5013         return;
5014     }
5015
5016     const bool itemIsHidden = !item->d_ptr->ignoreVisible && !item->d_ptr->visible;
5017     if (itemIsHidden) {
5018         resetDirtyItem(item, /*recursive=*/true);
5019         return;
5020     }
5021
5022     bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents);
5023     const bool itemHasChildren = !item->d_ptr->children.isEmpty();
5024     if (!itemHasContents) {
5025         if (!itemHasChildren) {
5026             resetDirtyItem(item);
5027             return; // Item has neither contents nor children!(?)
5028         }
5029         if (item->d_ptr->graphicsEffect)
5030             itemHasContents = true;
5031     }
5032
5033     const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
5034     const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity
5035                                         && QGraphicsItemPrivate::isOpacityNull(opacity);
5036     if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) {
5037         resetDirtyItem(item, /*recursive=*/itemHasChildren);
5038         return;
5039     }
5040
5041     bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform;
5042     const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
5043     if (wasDirtyParentSceneTransform && !itemIsUntransformable) {
5044         item->d_ptr->updateSceneTransformFromParent();
5045         Q_ASSERT(!item->d_ptr->dirtySceneTransform);
5046     }
5047
5048     const bool wasDirtyParentViewBoundingRects = item->d_ptr->paintedViewBoundingRectsNeedRepaint;
5049     if (itemIsFullyTransparent || !itemHasContents || dirtyAncestorContainsChildren) {
5050         // Make sure we don't process invisible items or items with no content.
5051         item->d_ptr->dirty = 0;
5052         item->d_ptr->fullUpdatePending = 0;
5053         // Might have a dirty view bounding rect otherwise.
5054         if (itemIsFullyTransparent || !itemHasContents)
5055             item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
5056     }
5057
5058     if (!hasSceneRect && item->d_ptr->geometryChanged && item->d_ptr->visible) {
5059         // Update growingItemsBoundingRect.
5060         if (item->d_ptr->sceneTransformTranslateOnly) {
5061             growingItemsBoundingRect |= item->boundingRect().translated(item->d_ptr->sceneTransform.dx(),
5062                                                                         item->d_ptr->sceneTransform.dy());
5063         } else {
5064             growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect());
5065         }
5066     }
5067
5068     // Process item.
5069     if (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
5070         const bool useCompatUpdate = views.isEmpty() || isSignalConnected(changedSignalIndex);
5071         const QRectF itemBoundingRect = adjustedItemEffectiveBoundingRect(item);
5072
5073         if (useCompatUpdate && !itemIsUntransformable && qFuzzyIsNull(item->boundingRegionGranularity())) {
5074             // This block of code is kept for compatibility. Since 4.5, by default
5075             // QGraphicsView does not connect the signal and we use the below
5076             // method of delivering updates.
5077             if (item->d_ptr->sceneTransformTranslateOnly) {
5078                 q->update(itemBoundingRect.translated(item->d_ptr->sceneTransform.dx(),
5079                                                       item->d_ptr->sceneTransform.dy()));
5080             } else {
5081                 QRectF rect = item->d_ptr->sceneTransform.mapRect(itemBoundingRect);
5082                 if (!rect.isEmpty())
5083                     q->update(rect);
5084             }
5085         } else {
5086             QRectF dirtyRect;
5087             bool uninitializedDirtyRect = true;
5088
5089             for (int j = 0; j < views.size(); ++j) {
5090                 QGraphicsView *view = views.at(j);
5091                 QGraphicsViewPrivate *viewPrivate = view->d_func();
5092                 QRect &paintedViewBoundingRect = item->d_ptr->paintedViewBoundingRects[viewPrivate->viewport];
5093                 if (viewPrivate->fullUpdatePending
5094                     || viewPrivate->viewportUpdateMode == QGraphicsView::NoViewportUpdate) {
5095                     // Okay, if we have a full update pending or no viewport update, this item's
5096                     // paintedViewBoundingRect  will be updated correctly in the next paintEvent if
5097                     // it is inside the viewport, but for now we can pretend that it is outside.
5098                     paintedViewBoundingRect = QRect(-1, -1, -1, -1);
5099                     continue;
5100                 }
5101
5102                 if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
5103                     paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset);
5104                     if (!viewPrivate->updateRect(paintedViewBoundingRect))
5105                         paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport.
5106                 }
5107
5108                 if (!item->d_ptr->dirty)
5109                     continue;
5110
5111                 if (!item->d_ptr->paintedViewBoundingRectsNeedRepaint
5112                     && paintedViewBoundingRect.x() == -1 && paintedViewBoundingRect.y() == -1
5113                     && paintedViewBoundingRect.width() == -1 && paintedViewBoundingRect.height() == -1) {
5114                     continue; // Outside viewport.
5115                 }
5116
5117                 if (uninitializedDirtyRect) {
5118                     dirtyRect = itemBoundingRect;
5119                     if (!item->d_ptr->fullUpdatePending) {
5120                         _q_adjustRect(&item->d_ptr->needsRepaint);
5121                         dirtyRect &= item->d_ptr->needsRepaint;
5122                     }
5123                     uninitializedDirtyRect = false;
5124                 }
5125
5126                 if (dirtyRect.isEmpty())
5127                     continue; // Discard updates outside the bounding rect.
5128
5129                 if (!updateHelper(viewPrivate, item->d_ptr.data(), dirtyRect, itemIsUntransformable)
5130                     && item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
5131                     paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport.
5132                 }
5133             }
5134         }
5135     }
5136
5137     // Process children.
5138     if (itemHasChildren && item->d_ptr->dirtyChildren) {
5139         const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape;
5140         // Items with no content are threated as 'dummy' items which means they are never drawn and
5141         // 'processed', so the painted view bounding rect is never up-to-date. This means that whenever
5142         // such an item changes geometry, its children have to take care of the update regardless
5143         // of whether the item clips children to shape or not.
5144         const bool bypassUpdateClip = !itemHasContents && wasDirtyParentViewBoundingRects;
5145         if (itemClipsChildrenToShape && !bypassUpdateClip) {
5146             // Make sure child updates are clipped to the item's bounding rect.
5147             for (int i = 0; i < views.size(); ++i)
5148                 views.at(i)->d_func()->setUpdateClip(item);
5149         }
5150         if (!dirtyAncestorContainsChildren) {
5151             dirtyAncestorContainsChildren = item->d_ptr->fullUpdatePending
5152                                             && itemClipsChildrenToShape;
5153         }
5154         const bool allChildrenDirty = item->d_ptr->allChildrenDirty;
5155         const bool parentIgnoresVisible = item->d_ptr->ignoreVisible;
5156         const bool parentIgnoresOpacity = item->d_ptr->ignoreOpacity;
5157         for (int i = 0; i < item->d_ptr->children.size(); ++i) {
5158             QGraphicsItem *child = item->d_ptr->children.at(i);
5159             if (wasDirtyParentSceneTransform)
5160                 child->d_ptr->dirtySceneTransform = 1;
5161             if (wasDirtyParentViewBoundingRects)
5162                 child->d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
5163             if (parentIgnoresVisible)
5164                 child->d_ptr->ignoreVisible = 1;
5165             if (parentIgnoresOpacity)
5166                 child->d_ptr->ignoreOpacity = 1;
5167             if (allChildrenDirty) {
5168                 child->d_ptr->dirty = 1;
5169                 child->d_ptr->fullUpdatePending = 1;
5170                 child->d_ptr->dirtyChildren = 1;
5171                 child->d_ptr->allChildrenDirty = 1;
5172             }
5173             processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity);
5174         }
5175
5176         if (itemClipsChildrenToShape) {
5177             // Reset updateClip.
5178             for (int i = 0; i < views.size(); ++i)
5179                 views.at(i)->d_func()->setUpdateClip(0);
5180         }
5181     } else if (wasDirtyParentSceneTransform) {
5182         item->d_ptr->invalidateChildrenSceneTransform();
5183     }
5184
5185     resetDirtyItem(item);
5186 }
5187
5188 /*!
5189     \obsolete
5190
5191     Paints the given \a items using the provided \a painter, after the
5192     background has been drawn, and before the foreground has been
5193     drawn.  All painting is done in \e scene coordinates. Before
5194     drawing each item, the painter must be transformed using
5195     QGraphicsItem::sceneTransform().
5196
5197     The \a options parameter is the list of style option objects for
5198     each item in \a items. The \a numItems parameter is the number of
5199     items in \a items and options in \a options. The \a widget
5200     parameter is optional; if specified, it should point to the widget
5201     that is being painted on.
5202
5203     The default implementation prepares the painter matrix, and calls
5204     QGraphicsItem::paint() on all items. Reimplement this function to
5205     provide custom painting of all items for the scene; gaining
5206     complete control over how each item is drawn. In some cases this
5207     can increase drawing performance significantly.
5208
5209     Example:
5210
5211     \snippet graphicssceneadditemsnippet.cpp 0
5212
5213     Since Qt 4.6, this function is not called anymore unless
5214     the QGraphicsView::IndirectPainting flag is given as an Optimization
5215     flag.
5216
5217     \sa drawBackground(), drawForeground()
5218 */
5219 void QGraphicsScene::drawItems(QPainter *painter,
5220                                int numItems,
5221                                QGraphicsItem *items[],
5222                                const QStyleOptionGraphicsItem options[], QWidget *widget)
5223 {
5224     Q_D(QGraphicsScene);
5225     // Make sure we don't have unpolished items before we draw.
5226     if (!d->unpolishedItems.isEmpty())
5227         d->_q_polishItems();
5228
5229     const qreal opacity = painter->opacity();
5230     QTransform viewTransform = painter->worldTransform();
5231     Q_UNUSED(options);
5232
5233     // Determine view, expose and flags.
5234     QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
5235     QRegion *expose = 0;
5236     const quint32 oldRectAdjust = d->rectAdjust;
5237     if (view) {
5238         d->updateAll = false;
5239         expose = &view->d_func()->exposedRegion;
5240         if (view->d_func()->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
5241             d->rectAdjust = 1;
5242         else
5243             d->rectAdjust = 2;
5244     }
5245
5246     // Find all toplevels, they are already sorted.
5247     QList<QGraphicsItem *> topLevelItems;
5248     for (int i = 0; i < numItems; ++i) {
5249         QGraphicsItem *item = items[i]->topLevelItem();
5250         if (!item->d_ptr->itemDiscovered) {
5251             topLevelItems << item;
5252             item->d_ptr->itemDiscovered = 1;
5253             d->drawSubtreeRecursive(item, painter, &viewTransform, expose, widget);
5254         }
5255     }
5256
5257     d->rectAdjust = oldRectAdjust;
5258     // Reset discovery bits.
5259     for (int i = 0; i < topLevelItems.size(); ++i)
5260         topLevelItems.at(i)->d_ptr->itemDiscovered = 0;
5261
5262     painter->setWorldTransform(viewTransform);
5263     painter->setOpacity(opacity);
5264 }
5265
5266 /*!
5267     \since 4.4
5268
5269     Finds a new widget to give the keyboard focus to, as appropriate for Tab
5270     and Shift+Tab, and returns true if it can find a new widget, or false if
5271     it cannot. If \a next is true, this function searches forward; if \a next
5272     is false, it searches backward.
5273
5274     You can reimplement this function in a subclass of QGraphicsScene to
5275     provide fine-grained control over how tab focus passes inside your
5276     scene. The default implementation is based on the tab focus chain defined
5277     by QGraphicsWidget::setTabOrder().
5278 */
5279 bool QGraphicsScene::focusNextPrevChild(bool next)
5280 {
5281     Q_D(QGraphicsScene);
5282
5283     QGraphicsItem *item = focusItem();
5284     if (item && !item->isWidget()) {
5285         // Tab out of the scene.
5286         return false;
5287     }
5288     if (!item) {
5289         if (d->lastFocusItem && !d->lastFocusItem->isWidget()) {
5290             // Restore focus to the last focusable non-widget item that had
5291             // focus.
5292             setFocusItem(d->lastFocusItem, next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
5293             return true;
5294         }
5295     }
5296     if (!d->tabFocusFirst) {
5297         // No widgets...
5298         return false;
5299     }
5300
5301     // The item must be a widget.
5302     QGraphicsWidget *widget = 0;
5303     if (!item) {
5304         widget = next ? d->tabFocusFirst : d->tabFocusFirst->d_func()->focusPrev;
5305     } else {
5306         QGraphicsWidget *test = static_cast<QGraphicsWidget *>(item);
5307         widget = next ? test->d_func()->focusNext : test->d_func()->focusPrev;
5308         if ((next && widget == d->tabFocusFirst) || (!next && widget == d->tabFocusFirst->d_func()->focusPrev))
5309             return false;
5310     }
5311     QGraphicsWidget *widgetThatHadFocus = widget;
5312
5313     // Run around the focus chain until we find a widget that can take tab focus.
5314     do {
5315         if (widget->flags() & QGraphicsItem::ItemIsFocusable
5316             && widget->isEnabled() && widget->isVisibleTo(0)
5317             && (widget->focusPolicy() & Qt::TabFocus)
5318             && (!item || !item->isPanel() || item->isAncestorOf(widget))
5319             ) {
5320             setFocusItem(widget, next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
5321             return true;
5322         }
5323         widget = next ? widget->d_func()->focusNext : widget->d_func()->focusPrev;
5324         if ((next && widget == d->tabFocusFirst) || (!next && widget == d->tabFocusFirst->d_func()->focusPrev))
5325             return false;
5326     } while (widget != widgetThatHadFocus);
5327
5328     return false;
5329 }
5330
5331 /*!
5332     \fn QGraphicsScene::changed(const QList<QRectF> &region)
5333
5334     This signal is emitted by QGraphicsScene when control reaches the
5335     event loop, if the scene content changes. The \a region parameter
5336     contains a list of scene rectangles that indicate the area that
5337     has been changed.
5338
5339     \sa QGraphicsView::updateScene()
5340 */
5341
5342 /*!
5343     \fn QGraphicsScene::sceneRectChanged(const QRectF &rect)
5344
5345     This signal is emitted by QGraphicsScene whenever the scene rect changes.
5346     The \a rect parameter is the new scene rectangle.
5347
5348     \sa QGraphicsView::updateSceneRect()
5349 */
5350
5351 /*!
5352     \fn QGraphicsScene::selectionChanged()
5353     \since 4.3
5354
5355     This signal is emitted by QGraphicsScene whenever the selection
5356     changes. You can call selectedItems() to get the new list of selected
5357     items.
5358
5359     The selection changes whenever an item is selected or unselected, a
5360     selection area is set, cleared or otherwise changed, if a preselected item
5361     is added to the scene, or if a selected item is removed from the scene.
5362
5363     QGraphicsScene emits this signal only once for group selection operations.
5364     For example, if you set a selection area, select or unselect a
5365     QGraphicsItemGroup, or if you add or remove from the scene a parent item
5366     that contains several selected items, selectionChanged() is emitted only
5367     once after the operation has completed (instead of once for each item).
5368
5369     \sa setSelectionArea(), selectedItems(), QGraphicsItem::setSelected()
5370 */
5371
5372 /*!
5373     \since 4.4
5374
5375     Returns the scene's style, or the same as QApplication::style() if the
5376     scene has not been explicitly assigned a style.
5377
5378     \sa setStyle()
5379 */
5380 QStyle *QGraphicsScene::style() const
5381 {
5382     Q_D(const QGraphicsScene);
5383     // ### This function, and the use of styles in general, is non-reentrant.
5384     return d->style ? d->style : QApplication::style();
5385 }
5386
5387 /*!
5388     \since 4.4
5389
5390     Sets or replaces the style of the scene to \a style, and reparents the
5391     style to this scene. Any previously assigned style is deleted. The scene's
5392     style defaults to QApplication::style(), and serves as the default for all
5393     QGraphicsWidget items in the scene.
5394
5395     Changing the style, either directly by calling this function, or
5396     indirectly by calling QApplication::setStyle(), will automatically update
5397     the style for all widgets in the scene that do not have a style explicitly
5398     assigned to them.
5399
5400     If \a style is 0, QGraphicsScene will revert to QApplication::style().
5401
5402     \sa style()
5403 */
5404 void QGraphicsScene::setStyle(QStyle *style)
5405 {
5406     Q_D(QGraphicsScene);
5407     // ### This function, and the use of styles in general, is non-reentrant.
5408     if (style == d->style)
5409         return;
5410
5411     // Delete the old style,
5412     delete d->style;
5413     if ((d->style = style))
5414         d->style->setParent(this);
5415
5416     // Notify the scene.
5417     QEvent event(QEvent::StyleChange);
5418     QApplication::sendEvent(this, &event);
5419
5420     // Notify all widgets that don't have a style explicitly set.
5421     foreach (QGraphicsItem *item, items()) {
5422         if (item->isWidget()) {
5423             QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
5424             if (!widget->testAttribute(Qt::WA_SetStyle))
5425                 QApplication::sendEvent(widget, &event);
5426         }
5427     }
5428 }
5429
5430 /*!
5431     \property QGraphicsScene::font
5432     \since 4.4
5433     \brief the scene's default font
5434
5435     This property provides the scene's font. The scene font defaults to,
5436     and resolves all its entries from, QApplication::font.
5437
5438     If the scene's font changes, either directly through setFont() or
5439     indirectly when the application font changes, QGraphicsScene first
5440     sends itself a \l{QEvent::FontChange}{FontChange} event, and it then
5441     sends \l{QEvent::FontChange}{FontChange} events to all top-level
5442     widget items in the scene. These items respond by resolving their own
5443     fonts to the scene, and they then notify their children, who again
5444     notify their children, and so on, until all widget items have updated
5445     their fonts.
5446
5447     Changing the scene font, (directly or indirectly through
5448     QApplication::setFont(),) automatically schedules a redraw the entire
5449     scene.
5450
5451     \sa QWidget::font, QApplication::setFont(), palette, style()
5452 */
5453 QFont QGraphicsScene::font() const
5454 {
5455     Q_D(const QGraphicsScene);
5456     return d->font;
5457 }
5458 void QGraphicsScene::setFont(const QFont &font)
5459 {
5460     Q_D(QGraphicsScene);
5461     QFont naturalFont = QApplication::font();
5462     naturalFont.resolve(0);
5463     QFont resolvedFont = font.resolve(naturalFont);
5464     d->setFont_helper(resolvedFont);
5465 }
5466
5467 /*!
5468     \property QGraphicsScene::palette
5469     \since 4.4
5470     \brief the scene's default palette
5471
5472     This property provides the scene's palette. The scene palette defaults to,
5473     and resolves all its entries from, QApplication::palette.
5474
5475     If the scene's palette changes, either directly through setPalette() or
5476     indirectly when the application palette changes, QGraphicsScene first
5477     sends itself a \l{QEvent::PaletteChange}{PaletteChange} event, and it then
5478     sends \l{QEvent::PaletteChange}{PaletteChange} events to all top-level
5479     widget items in the scene. These items respond by resolving their own
5480     palettes to the scene, and they then notify their children, who again
5481     notify their children, and so on, until all widget items have updated
5482     their palettes.
5483
5484     Changing the scene palette, (directly or indirectly through
5485     QApplication::setPalette(),) automatically schedules a redraw the entire
5486     scene.
5487
5488     \sa QWidget::palette, QApplication::setPalette(), font, style()
5489 */
5490 QPalette QGraphicsScene::palette() const
5491 {
5492     Q_D(const QGraphicsScene);
5493     return d->palette;
5494 }
5495 void QGraphicsScene::setPalette(const QPalette &palette)
5496 {
5497     Q_D(QGraphicsScene);
5498     QPalette naturalPalette = QApplication::palette();
5499     naturalPalette.resolve(0);
5500     QPalette resolvedPalette = palette.resolve(naturalPalette);
5501     d->setPalette_helper(resolvedPalette);
5502 }
5503
5504 /*!
5505     \since 4.6
5506
5507     Returns true if the scene is active (e.g., it's viewed by
5508     at least one QGraphicsView that is active); otherwise returns false.
5509
5510     \sa QGraphicsItem::isActive(), QWidget::isActiveWindow()
5511 */
5512 bool QGraphicsScene::isActive() const
5513 {
5514     Q_D(const QGraphicsScene);
5515     return d->activationRefCount > 0;
5516 }
5517
5518 /*!
5519     \since 4.6
5520     Returns the current active panel, or 0 if no panel is currently active.
5521
5522     \sa QGraphicsScene::setActivePanel()
5523 */
5524 QGraphicsItem *QGraphicsScene::activePanel() const
5525 {
5526     Q_D(const QGraphicsScene);
5527     return d->activePanel;
5528 }
5529
5530 /*!
5531     \since 4.6
5532     Activates \a item, which must be an item in this scene. You
5533     can also pass 0 for \a item, in which case QGraphicsScene will
5534     deactivate any currently active panel.
5535
5536     If the scene is currently inactive, \a item remains inactive until the
5537     scene becomes active (or, ir \a item is 0, no item will be activated).
5538
5539     \sa activePanel(), isActive(), QGraphicsItem::isActive()
5540 */
5541 void QGraphicsScene::setActivePanel(QGraphicsItem *item)
5542 {
5543     Q_D(QGraphicsScene);
5544     d->setActivePanelHelper(item, false);
5545 }
5546
5547 /*!
5548     \since 4.4
5549
5550     Returns the current active window, or 0 if no window is currently
5551     active.
5552
5553     \sa QGraphicsScene::setActiveWindow()
5554 */
5555 QGraphicsWidget *QGraphicsScene::activeWindow() const
5556 {
5557     Q_D(const QGraphicsScene);
5558     if (d->activePanel && d->activePanel->isWindow())
5559         return static_cast<QGraphicsWidget *>(d->activePanel);
5560     return 0;
5561 }
5562
5563 /*!
5564     \since 4.4
5565     Activates \a widget, which must be a widget in this scene. You can also
5566     pass 0 for \a widget, in which case QGraphicsScene will deactivate any
5567     currently active window.
5568
5569     \sa activeWindow(), QGraphicsWidget::isActiveWindow()
5570 */
5571 void QGraphicsScene::setActiveWindow(QGraphicsWidget *widget)
5572 {
5573     if (widget && widget->scene() != this) {
5574         qWarning("QGraphicsScene::setActiveWindow: widget %p must be part of this scene",
5575                  widget);
5576         return;
5577     }
5578
5579     // Activate the widget's panel (all windows are panels).
5580     QGraphicsItem *panel = widget ? widget->panel() : 0;
5581     setActivePanel(panel);
5582
5583     // Raise
5584     if (panel) {
5585         QList<QGraphicsItem *> siblingWindows;
5586         QGraphicsItem *parent = panel->parentItem();
5587         // Raise ### inefficient for toplevels
5588         foreach (QGraphicsItem *sibling, parent ? parent->children() : items()) {
5589             if (sibling != panel && sibling->isWindow())
5590                 siblingWindows << sibling;
5591         }
5592
5593         // Find the highest z value.
5594         qreal z = panel->zValue();
5595         for (int i = 0; i < siblingWindows.size(); ++i)
5596             z = qMax(z, siblingWindows.at(i)->zValue());
5597
5598         // This will probably never overflow.
5599         const qreal litt = qreal(0.001);
5600         panel->setZValue(z + litt);
5601     }
5602 }
5603
5604 /*!
5605     \since 4.6
5606
5607     Sends event \a event to item \a item through possible event filters.
5608
5609     The event is sent only if the item is enabled.
5610
5611     Returns \c false if the event was filtered or if the item is disabled.
5612     Otherwise returns the value that was returned from the event handler.
5613
5614     \sa QGraphicsItem::sceneEvent(), QGraphicsItem::sceneEventFilter()
5615 */
5616 bool QGraphicsScene::sendEvent(QGraphicsItem *item, QEvent *event)
5617 {
5618     Q_D(QGraphicsScene);
5619     if (!item) {
5620         qWarning("QGraphicsScene::sendEvent: cannot send event to a null item");
5621         return false;
5622     }
5623     if (item->scene() != this) {
5624         qWarning("QGraphicsScene::sendEvent: item %p's scene (%p)"
5625                  " is different from this scene (%p)",
5626                  item, item->scene(), this);
5627         return false;
5628     }
5629     return d->sendEvent(item, event);
5630 }
5631
5632 void QGraphicsScenePrivate::addView(QGraphicsView *view)
5633 {
5634     views << view;
5635 #ifndef QT_NO_GESTURES
5636     foreach (Qt::GestureType gesture, grabbedGestures.keys())
5637         view->viewport()->grabGesture(gesture);
5638 #endif
5639 }
5640
5641 void QGraphicsScenePrivate::removeView(QGraphicsView *view)
5642 {
5643     views.removeAll(view);
5644 }
5645
5646 void QGraphicsScenePrivate::updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent)
5647 {
5648     QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
5649     for (int i = 0; i < touchPoints.count(); ++i) {
5650         QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
5651         touchPoint.setRect(item->mapFromScene(touchPoint.sceneRect()).boundingRect());
5652         touchPoint.setStartPos(item->d_ptr->genericMapFromScene(touchPoint.startScenePos(), static_cast<QWidget *>(touchEvent->target())));
5653         touchPoint.setLastPos(item->d_ptr->genericMapFromScene(touchPoint.lastScenePos(), static_cast<QWidget *>(touchEvent->target())));
5654     }
5655     touchEvent->setTouchPoints(touchPoints);
5656 }
5657
5658 int QGraphicsScenePrivate::findClosestTouchPointId(const QPointF &scenePos)
5659 {
5660     int closestTouchPointId = -1;
5661     qreal closestDistance = qreal(0.);
5662     foreach (const QTouchEvent::TouchPoint &touchPoint, sceneCurrentTouchPoints) {
5663         qreal distance = QLineF(scenePos, touchPoint.scenePos()).length();
5664         if (closestTouchPointId == -1|| distance < closestDistance) {
5665             closestTouchPointId = touchPoint.id();
5666             closestDistance = distance;
5667         }
5668     }
5669     return closestTouchPointId;
5670 }
5671
5672 void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
5673 {
5674     typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
5675     QHash<QGraphicsItem *, StatesAndTouchPoints> itemsNeedingEvents;
5676
5677     for (int i = 0; i < sceneTouchEvent->touchPoints().count(); ++i) {
5678         const QTouchEvent::TouchPoint &touchPoint = sceneTouchEvent->touchPoints().at(i);
5679
5680         // update state
5681         QGraphicsItem *item = 0;
5682         if (touchPoint.state() == Qt::TouchPointPressed) {
5683             if (sceneTouchEvent->device()->type() == QTouchDevice::TouchPad) {
5684                 // on touch-pad devices, send all touch points to the same item
5685                 item = itemForTouchPointId.isEmpty()
5686                        ? 0
5687                        : itemForTouchPointId.constBegin().value();
5688             }
5689
5690             if (!item) {
5691                 // determine which item this touch point will go to
5692                 cachedItemsUnderMouse = itemsAtPosition(touchPoint.screenPos().toPoint(),
5693                                                         touchPoint.scenePos(),
5694                                                         static_cast<QWidget *>(sceneTouchEvent->target()));
5695                 item = cachedItemsUnderMouse.isEmpty() ? 0 : cachedItemsUnderMouse.first();
5696             }
5697
5698             if (sceneTouchEvent->device()->type() == QTouchDevice::TouchScreen) {
5699                 // on touch-screens, combine this touch point with the closest one we find
5700                 int closestTouchPointId = findClosestTouchPointId(touchPoint.scenePos());
5701                 QGraphicsItem *closestItem = itemForTouchPointId.value(closestTouchPointId);
5702                 if (!item || (closestItem && cachedItemsUnderMouse.contains(closestItem)))
5703                     item = closestItem;
5704             }
5705             if (!item)
5706                 continue;
5707
5708             itemForTouchPointId.insert(touchPoint.id(), item);
5709             sceneCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
5710         } else if (touchPoint.state() == Qt::TouchPointReleased) {
5711             item = itemForTouchPointId.take(touchPoint.id());
5712             if (!item)
5713                 continue;
5714
5715             sceneCurrentTouchPoints.remove(touchPoint.id());
5716         } else {
5717             item = itemForTouchPointId.value(touchPoint.id());
5718             if (!item)
5719                 continue;
5720             Q_ASSERT(sceneCurrentTouchPoints.contains(touchPoint.id()));
5721             sceneCurrentTouchPoints[touchPoint.id()] = touchPoint;
5722         }
5723
5724         StatesAndTouchPoints &statesAndTouchPoints = itemsNeedingEvents[item];
5725         statesAndTouchPoints.first |= touchPoint.state();
5726         statesAndTouchPoints.second.append(touchPoint);
5727     }
5728
5729     if (itemsNeedingEvents.isEmpty()) {
5730         sceneTouchEvent->accept();
5731         return;
5732     }
5733
5734     bool ignoreSceneTouchEvent = true;
5735     QHash<QGraphicsItem *, StatesAndTouchPoints>::ConstIterator it = itemsNeedingEvents.constBegin();
5736     const QHash<QGraphicsItem *, StatesAndTouchPoints>::ConstIterator end = itemsNeedingEvents.constEnd();
5737     for (; it != end; ++it) {
5738         QGraphicsItem *item = it.key();
5739
5740         (void) item->isBlockedByModalPanel(&item);
5741
5742         // determine event type from the state mask
5743         QEvent::Type eventType;
5744         switch (it.value().first) {
5745         case Qt::TouchPointPressed:
5746             // all touch points have pressed state
5747             eventType = QEvent::TouchBegin;
5748             break;
5749         case Qt::TouchPointReleased:
5750             // all touch points have released state
5751             eventType = QEvent::TouchEnd;
5752             break;
5753         case Qt::TouchPointStationary:
5754             // don't send the event if nothing changed
5755             continue;
5756         default:
5757             // all other combinations
5758             eventType = QEvent::TouchUpdate;
5759             break;
5760         }
5761
5762         QTouchEvent touchEvent(eventType);
5763         touchEvent.setWindow(sceneTouchEvent->window());
5764         touchEvent.setTarget(sceneTouchEvent->target());
5765         touchEvent.setDevice(sceneTouchEvent->device());
5766         touchEvent.setModifiers(sceneTouchEvent->modifiers());
5767         touchEvent.setTouchPointStates(it.value().first);
5768         touchEvent.setTouchPoints(it.value().second);
5769         touchEvent.setTimestamp(sceneTouchEvent->timestamp());
5770
5771         switch (touchEvent.type()) {
5772         case QEvent::TouchBegin:
5773         {
5774             // if the TouchBegin handler recurses, we assume that means the event
5775             // has been implicitly accepted and continue to send touch events
5776             item->d_ptr->acceptedTouchBeginEvent = true;
5777             bool res = sendTouchBeginEvent(item, &touchEvent)
5778                        && touchEvent.isAccepted();
5779             if (!res) {
5780                 // forget about these touch points, we didn't handle them
5781                 for (int i = 0; i < touchEvent.touchPoints().count(); ++i) {
5782                     const QTouchEvent::TouchPoint &touchPoint = touchEvent.touchPoints().at(i);
5783                     itemForTouchPointId.remove(touchPoint.id());
5784                     sceneCurrentTouchPoints.remove(touchPoint.id());
5785                 }
5786                 ignoreSceneTouchEvent = false;
5787             }
5788             break;
5789         }
5790         default:
5791             if (item->d_ptr->acceptedTouchBeginEvent) {
5792                 updateTouchPointsForItem(item, &touchEvent);
5793                 (void) sendEvent(item, &touchEvent);
5794                 ignoreSceneTouchEvent = false;
5795             }
5796             break;
5797         }
5798     }
5799     sceneTouchEvent->setAccepted(ignoreSceneTouchEvent);
5800 }
5801
5802 bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEvent *touchEvent)
5803 {
5804     Q_Q(QGraphicsScene);
5805
5806     if (cachedItemsUnderMouse.isEmpty() || cachedItemsUnderMouse.first() != origin) {
5807         const QTouchEvent::TouchPoint &firstTouchPoint = touchEvent->touchPoints().first();
5808         cachedItemsUnderMouse = itemsAtPosition(firstTouchPoint.screenPos().toPoint(),
5809                                                 firstTouchPoint.scenePos(),
5810                                                 static_cast<QWidget *>(touchEvent->target()));
5811     }
5812     Q_ASSERT(cachedItemsUnderMouse.first() == origin);
5813
5814     // Set focus on the topmost enabled item that can take focus.
5815     bool setFocus = false;
5816
5817     foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
5818         if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
5819             if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
5820                 setFocus = true;
5821                 if (item != q->focusItem())
5822                     q->setFocusItem(item, Qt::MouseFocusReason);
5823                 break;
5824             }
5825         }
5826         if (item->isPanel())
5827             break;
5828         if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
5829             break;
5830         if (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling) {
5831             // Make sure we don't clear focus.
5832             setFocus = true;
5833             break;
5834         }
5835     }
5836
5837     // If nobody could take focus, clear it.
5838     if (!stickyFocus && !setFocus)
5839         q->setFocusItem(0, Qt::MouseFocusReason);
5840
5841     bool res = false;
5842     bool eventAccepted = touchEvent->isAccepted();
5843     foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
5844         // first, try to deliver the touch event
5845         updateTouchPointsForItem(item, touchEvent);
5846         bool acceptTouchEvents = item->acceptTouchEvents();
5847         touchEvent->setAccepted(acceptTouchEvents);
5848         res = acceptTouchEvents && sendEvent(item, touchEvent);
5849         eventAccepted = touchEvent->isAccepted();
5850         if (itemForTouchPointId.value(touchEvent->touchPoints().first().id()) == 0) {
5851             // item was deleted
5852             item = 0;
5853         } else {
5854             item->d_ptr->acceptedTouchBeginEvent = (res && eventAccepted);
5855         }
5856         touchEvent->spont = false;
5857         if (res && eventAccepted) {
5858             // the first item to accept the TouchBegin gets an implicit grab.
5859             for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
5860                 const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
5861                 itemForTouchPointId[touchPoint.id()] = item; // can be zero
5862             }
5863             break;
5864         }
5865         if (item && item->isPanel())
5866             break;
5867     }
5868
5869     touchEvent->setAccepted(eventAccepted);
5870     return res;
5871 }
5872
5873 void QGraphicsScenePrivate::enableTouchEventsOnViews()
5874 {
5875     foreach (QGraphicsView *view, views)
5876         view->viewport()->setAttribute(Qt::WA_AcceptTouchEvents, true);
5877 }
5878
5879 void QGraphicsScenePrivate::updateInputMethodSensitivityInViews()
5880 {
5881     for (int i = 0; i < views.size(); ++i)
5882         views.at(i)->d_func()->updateInputMethodSensitivity();
5883 }
5884
5885 void QGraphicsScenePrivate::enterModal(QGraphicsItem *panel, QGraphicsItem::PanelModality previousModality)
5886 {
5887     Q_Q(QGraphicsScene);
5888     Q_ASSERT(panel && panel->isPanel());
5889
5890     QGraphicsItem::PanelModality panelModality = panel->d_ptr->panelModality;
5891     if (previousModality != QGraphicsItem::NonModal) {
5892         // the panel is changing from one modality type to another... temporarily set it back so
5893         // that blockedPanels is populated correctly
5894         panel->d_ptr->panelModality = previousModality;
5895     }
5896
5897     QSet<QGraphicsItem *> blockedPanels;
5898     QList<QGraphicsItem *> items = q->items(); // ### store panels separately
5899     for (int i = 0; i < items.count(); ++i) {
5900         QGraphicsItem *item = items.at(i);
5901         if (item->isPanel() && item->isBlockedByModalPanel())
5902             blockedPanels.insert(item);
5903     }
5904     // blockedPanels contains all currently blocked panels
5905
5906     if (previousModality != QGraphicsItem::NonModal) {
5907         // reset the modality to the proper value, since we changed it above
5908         panel->d_ptr->panelModality = panelModality;
5909         // remove this panel so that it will be reinserted at the front of the stack
5910         modalPanels.removeAll(panel);
5911     }
5912
5913     modalPanels.prepend(panel);
5914
5915     if (!hoverItems.isEmpty()) {
5916         // send GraphicsSceneHoverLeave events to newly blocked hoverItems
5917         QGraphicsSceneHoverEvent hoverEvent;
5918         hoverEvent.setScenePos(lastSceneMousePos);
5919         dispatchHoverEvent(&hoverEvent);
5920     }
5921
5922     if (!mouseGrabberItems.isEmpty() && lastMouseGrabberItemHasImplicitMouseGrab) {
5923         QGraphicsItem *item = mouseGrabberItems.last();
5924         if (item->isBlockedByModalPanel())
5925             ungrabMouse(item, /*itemIsDying =*/ false);
5926     }
5927
5928     QEvent windowBlockedEvent(QEvent::WindowBlocked);
5929     QEvent windowUnblockedEvent(QEvent::WindowUnblocked);
5930     for (int i = 0; i < items.count(); ++i) {
5931         QGraphicsItem *item = items.at(i);
5932         if (item->isPanel()) {
5933             if (!blockedPanels.contains(item) && item->isBlockedByModalPanel()) {
5934                 // send QEvent::WindowBlocked to newly blocked panels
5935                 sendEvent(item, &windowBlockedEvent);
5936             } else if (blockedPanels.contains(item) && !item->isBlockedByModalPanel()) {
5937                 // send QEvent::WindowUnblocked to unblocked panels when downgrading
5938                 // a panel from SceneModal to PanelModal
5939                 sendEvent(item, &windowUnblockedEvent);
5940             }
5941         }
5942     }
5943 }
5944
5945 void QGraphicsScenePrivate::leaveModal(QGraphicsItem *panel)
5946 {
5947     Q_Q(QGraphicsScene);
5948     Q_ASSERT(panel && panel->isPanel());
5949
5950     QSet<QGraphicsItem *> blockedPanels;
5951     QList<QGraphicsItem *> items = q->items(); // ### same as above
5952     for (int i = 0; i < items.count(); ++i) {
5953         QGraphicsItem *item = items.at(i);
5954         if (item->isPanel() && item->isBlockedByModalPanel())
5955             blockedPanels.insert(item);
5956     }
5957
5958     modalPanels.removeAll(panel);
5959
5960     QEvent e(QEvent::WindowUnblocked);
5961     for (int i = 0; i < items.count(); ++i) {
5962         QGraphicsItem *item = items.at(i);
5963         if (item->isPanel() && blockedPanels.contains(item) && !item->isBlockedByModalPanel())
5964             sendEvent(item, &e);
5965     }
5966
5967     // send GraphicsSceneHoverEnter events to newly unblocked items
5968     QGraphicsSceneHoverEvent hoverEvent;
5969     hoverEvent.setScenePos(lastSceneMousePos);
5970     dispatchHoverEvent(&hoverEvent);
5971 }
5972
5973 #ifndef QT_NO_GESTURES
5974 void QGraphicsScenePrivate::gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures,
5975                                               Qt::GestureFlag flag,
5976                                               QHash<QGraphicsObject *, QSet<QGesture *> > *targets,
5977                                               QSet<QGraphicsObject *> *itemsSet,
5978                                               QSet<QGesture *> *normal,
5979                                               QSet<QGesture *> *conflicts)
5980 {
5981     QSet<QGesture *> normalGestures; // that are not in conflicted state.
5982     foreach (QGesture *gesture, gestures) {
5983         if (!gesture->hasHotSpot())
5984             continue;
5985         const Qt::GestureType gestureType = gesture->gestureType();
5986         QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), gesture->d_func()->sceneHotSpot, 0);
5987         for (int j = 0; j < items.size(); ++j) {
5988             QGraphicsItem *item = items.at(j);
5989
5990             // Check if the item is blocked by a modal panel and use it as
5991             // a target instead of this item.
5992             (void) item->isBlockedByModalPanel(&item);
5993
5994             if (QGraphicsObject *itemobj = item->toGraphicsObject()) {
5995                 QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
5996                 QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator it =
5997                         d->gestureContext.constFind(gestureType);
5998                 if (it != d->gestureContext.constEnd() && (!flag || (it.value() & flag))) {
5999                     if (normalGestures.contains(gesture)) {
6000                         normalGestures.remove(gesture);
6001                         if (conflicts)
6002                             conflicts->insert(gesture);
6003                     } else {
6004                         normalGestures.insert(gesture);
6005                     }
6006                     if (targets)
6007                         (*targets)[itemobj].insert(gesture);
6008                     if (itemsSet)
6009                         (*itemsSet).insert(itemobj);
6010                 }
6011             }
6012             // Don't propagate through panels.
6013             if (item->isPanel())
6014                 break;
6015         }
6016     }
6017     if (normal)
6018         *normal = normalGestures;
6019 }
6020
6021 void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
6022 {
6023     QWidget *viewport = event->widget();
6024     if (!viewport)
6025         return;
6026     QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(viewport->parent());
6027     if (!graphicsView)
6028         return;
6029
6030     QList<QGesture *> allGestures = event->gestures();
6031     DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6032             << "Gestures:" <<  allGestures;
6033
6034     QSet<QGesture *> startedGestures;
6035     QPoint delta = viewport->mapFromGlobal(QPoint());
6036     QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y())
6037                          * graphicsView->viewportTransform().inverted();
6038     foreach (QGesture *gesture, allGestures) {
6039         // cache scene coordinates of the hot spot
6040         if (gesture->hasHotSpot()) {
6041             gesture->d_func()->sceneHotSpot = toScene.map(gesture->hotSpot());
6042         } else {
6043             gesture->d_func()->sceneHotSpot = QPointF();
6044         }
6045
6046         QGraphicsObject *target = gestureTargets.value(gesture, 0);
6047         if (!target) {
6048             // when we are not in started mode but don't have a target
6049             // then the only one interested in gesture is the view/scene
6050             if (gesture->state() == Qt::GestureStarted)
6051                 startedGestures.insert(gesture);
6052         }
6053     }
6054
6055     if (!startedGestures.isEmpty()) {
6056         QSet<QGesture *> normalGestures; // that have just one target
6057         QSet<QGesture *> conflictedGestures; // that have multiple possible targets
6058         gestureTargetsAtHotSpots(startedGestures, Qt::GestureFlag(0), &cachedItemGestures, 0,
6059                                  &normalGestures, &conflictedGestures);
6060         cachedTargetItems = cachedItemGestures.keys();
6061         qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
6062         DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6063                 << "Normal gestures:" << normalGestures
6064                 << "Conflicting gestures:" << conflictedGestures;
6065
6066         // deliver conflicted gestures as override events AND remember
6067         // initial gesture targets
6068         if (!conflictedGestures.isEmpty()) {
6069             for (int i = 0; i < cachedTargetItems.size(); ++i) {
6070                 QWeakPointer<QGraphicsObject> item = cachedTargetItems.at(i);
6071
6072                 // get gestures to deliver to the current item
6073                 QSet<QGesture *> gestures = conflictedGestures & cachedItemGestures.value(item.data());
6074                 if (gestures.isEmpty())
6075                     continue;
6076
6077                 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6078                         << "delivering override to"
6079                         << item.data() << gestures;
6080                 // send gesture override
6081                 QGestureEvent ev(gestures.toList());
6082                 ev.t = QEvent::GestureOverride;
6083                 ev.setWidget(event->widget());
6084                 // mark event and individual gestures as ignored
6085                 ev.ignore();
6086                 foreach(QGesture *g, gestures)
6087                     ev.setAccepted(g, false);
6088                 sendEvent(item.data(), &ev);
6089                 // mark all accepted gestures to deliver them as normal gesture events
6090                 foreach (QGesture *g, gestures) {
6091                     if (ev.isAccepted() || ev.isAccepted(g)) {
6092                         conflictedGestures.remove(g);
6093                         // mark the item as a gesture target
6094                         if (item) {
6095                             gestureTargets.insert(g, item.data());
6096                             QHash<QGraphicsObject *, QSet<QGesture *> >::iterator it, e;
6097                             it = cachedItemGestures.begin();
6098                             e = cachedItemGestures.end();
6099                             for(; it != e; ++it)
6100                                 it.value().remove(g);
6101                             cachedItemGestures[item.data()].insert(g);
6102                         }
6103                         DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6104                                 << "override was accepted:"
6105                                 << g << item.data();
6106                     }
6107                     // remember the first item that received the override event
6108                     // as it most likely become a target if no one else accepts
6109                     // the override event
6110                     if (!gestureTargets.contains(g) && item)
6111                         gestureTargets.insert(g, item.data());
6112
6113                 }
6114                 if (conflictedGestures.isEmpty())
6115                     break;
6116             }
6117         }
6118         // remember the initial target item for each gesture that was not in
6119         // the conflicted state.
6120         if (!normalGestures.isEmpty()) {
6121             for (int i = 0; i < cachedTargetItems.size() && !normalGestures.isEmpty(); ++i) {
6122                 QGraphicsObject *item = cachedTargetItems.at(i);
6123
6124                 // get gestures to deliver to the current item
6125                 foreach (QGesture *g, cachedItemGestures.value(item)) {
6126                     if (!gestureTargets.contains(g)) {
6127                         gestureTargets.insert(g, item);
6128                         normalGestures.remove(g);
6129                     }
6130                 }
6131             }
6132         }
6133     }
6134
6135
6136     // deliver all gesture events
6137     QSet<QGesture *> undeliveredGestures;
6138     QSet<QGesture *> parentPropagatedGestures;
6139     foreach (QGesture *gesture, allGestures) {
6140         if (QGraphicsObject *target = gestureTargets.value(gesture, 0)) {
6141             cachedItemGestures[target].insert(gesture);
6142             cachedTargetItems.append(target);
6143             undeliveredGestures.insert(gesture);
6144             QGraphicsItemPrivate *d = target->QGraphicsItem::d_func();
6145             const Qt::GestureFlags flags = d->gestureContext.value(gesture->gestureType());
6146             if (flags & Qt::IgnoredGesturesPropagateToParent)
6147                 parentPropagatedGestures.insert(gesture);
6148         } else {
6149             DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6150                     << "no target for" << gesture << "at"
6151                     << gesture->hotSpot() << gesture->d_func()->sceneHotSpot;
6152         }
6153     }
6154     qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
6155     for (int i = 0; i < cachedTargetItems.size(); ++i) {
6156         QWeakPointer<QGraphicsObject> receiver = cachedTargetItems.at(i);
6157         QSet<QGesture *> gestures =
6158                 undeliveredGestures & cachedItemGestures.value(receiver.data());
6159         gestures -= cachedAlreadyDeliveredGestures.value(receiver.data());
6160
6161         if (gestures.isEmpty())
6162             continue;
6163
6164         cachedAlreadyDeliveredGestures[receiver.data()] += gestures;
6165         const bool isPanel = receiver.data()->isPanel();
6166
6167         DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6168                 << "delivering to"
6169                 << receiver.data() << gestures;
6170         QGestureEvent ev(gestures.toList());
6171         ev.setWidget(event->widget());
6172         sendEvent(receiver.data(), &ev);
6173         QSet<QGesture *> ignoredGestures;
6174         foreach (QGesture *g, gestures) {
6175             if (!ev.isAccepted() && !ev.isAccepted(g)) {
6176                 // if the gesture was ignored by its target, we will update the
6177                 // targetItems list with a possible target items (items that
6178                 // want to receive partial gestures).
6179                 // ### wont' work if the target was destroyed in the event
6180                 //     we will just stop delivering it.
6181                 if (receiver && receiver.data() == gestureTargets.value(g, 0))
6182                     ignoredGestures.insert(g);
6183             } else {
6184                 if (receiver && g->state() == Qt::GestureStarted) {
6185                     // someone accepted the propagated initial GestureStarted
6186                     // event, let it be the new target for all following events.
6187                     gestureTargets[g] = receiver.data();
6188                 }
6189                 undeliveredGestures.remove(g);
6190             }
6191         }
6192         if (undeliveredGestures.isEmpty())
6193             break;
6194
6195         // ignoredGestures list is only filled when delivering to the gesture
6196         // target item, so it is safe to assume item == target.
6197         if (!ignoredGestures.isEmpty() && !isPanel) {
6198             // look for new potential targets for gestures that were ignored
6199             // and should be propagated.
6200
6201             QSet<QGraphicsObject *> targetsSet = cachedTargetItems.toSet();
6202
6203             if (receiver) {
6204                 // first if the gesture should be propagated to parents only
6205                 for (QSet<QGesture *>::iterator it = ignoredGestures.begin();
6206                      it != ignoredGestures.end();) {
6207                     if (parentPropagatedGestures.contains(*it)) {
6208                         QGesture *gesture = *it;
6209                         const Qt::GestureType gestureType = gesture->gestureType();
6210                         QGraphicsItem *item = receiver.data();
6211                         while (item) {
6212                             if (QGraphicsObject *obj = item->toGraphicsObject()) {
6213                                 if (item->d_func()->gestureContext.contains(gestureType)) {
6214                                     targetsSet.insert(obj);
6215                                     cachedItemGestures[obj].insert(gesture);
6216                                 }
6217                             }
6218                             if (item->isPanel())
6219                                 break;
6220                             item = item->parentItem();
6221                         }
6222
6223                         it = ignoredGestures.erase(it);
6224                         continue;
6225                     }
6226                     ++it;
6227                 }
6228             }
6229
6230             gestureTargetsAtHotSpots(ignoredGestures, Qt::ReceivePartialGestures,
6231                                      &cachedItemGestures, &targetsSet, 0, 0);
6232
6233             cachedTargetItems = targetsSet.toList();
6234             qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
6235             DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
6236                     << "new targets:" << cachedTargetItems;
6237             i = -1; // start delivery again
6238             continue;
6239         }
6240     }
6241
6242     foreach (QGesture *g, startedGestures) {
6243         if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) {
6244             DEBUG() << "lets try to cancel some";
6245             // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
6246             cancelGesturesForChildren(g);
6247         }
6248     }
6249
6250     // forget about targets for gestures that have ended
6251     foreach (QGesture *g, allGestures) {
6252         switch (g->state()) {
6253         case Qt::GestureFinished:
6254         case Qt::GestureCanceled:
6255             gestureTargets.remove(g);
6256             break;
6257         default:
6258             break;
6259         }
6260     }
6261
6262     cachedTargetItems.clear();
6263     cachedItemGestures.clear();
6264     cachedAlreadyDeliveredGestures.clear();
6265 }
6266
6267 void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original)
6268 {
6269     Q_ASSERT(original);
6270     QGraphicsItem *originalItem = gestureTargets.value(original);
6271     if (originalItem == 0) // we only act on accepted gestures, which implies it has a target.
6272         return;
6273
6274     // iterate over all active gestures and for each find the owner
6275     // if the owner is part of our sub-hierarchy, cancel it.
6276
6277     QSet<QGesture *> canceledGestures;
6278     QHash<QGesture *, QGraphicsObject *>::Iterator iter = gestureTargets.begin();
6279     while (iter != gestureTargets.end()) {
6280         QGraphicsObject *item = iter.value();
6281         // note that we don't touch the gestures for our originalItem
6282         if (item != originalItem && originalItem->isAncestorOf(item)) {
6283             DEBUG() << "  found a gesture to cancel" << iter.key();
6284             iter.key()->d_func()->state = Qt::GestureCanceled;
6285             canceledGestures << iter.key();
6286         }
6287         ++iter;
6288     }
6289
6290     // sort them per target item by cherry picking from almostCanceledGestures and delivering
6291     QSet<QGesture *> almostCanceledGestures = canceledGestures;
6292     QSet<QGesture *>::Iterator setIter;
6293     while (!almostCanceledGestures.isEmpty()) {
6294         QGraphicsObject *target = 0;
6295         QSet<QGesture*> gestures;
6296         setIter = almostCanceledGestures.begin();
6297         // sort per target item
6298         while (setIter != almostCanceledGestures.end()) {
6299             QGraphicsObject *item = gestureTargets.value(*setIter);
6300             if (target == 0)
6301                 target = item;
6302             if (target == item) {
6303                 gestures << *setIter;
6304                 setIter = almostCanceledGestures.erase(setIter);
6305             } else {
6306                 ++setIter;
6307             }
6308         }
6309         Q_ASSERT(target);
6310
6311         QList<QGesture *> list = gestures.toList();
6312         QGestureEvent ev(list);
6313         sendEvent(target, &ev);
6314
6315         foreach (QGesture *g, list) {
6316             if (ev.isAccepted() || ev.isAccepted(g))
6317                 gestures.remove(g);
6318         }
6319
6320         foreach (QGesture *g, gestures) {
6321             if (!g->hasHotSpot())
6322                 continue;
6323
6324             QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), g->d_func()->sceneHotSpot, 0);
6325             for (int j = 0; j < items.size(); ++j) {
6326                 QGraphicsObject *item = items.at(j)->toGraphicsObject();
6327                 if (!item)
6328                     continue;
6329                 QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
6330                 if (d->gestureContext.contains(g->gestureType())) {
6331                     QList<QGesture *> list;
6332                     list << g;
6333                     QGestureEvent ev(list);
6334                     sendEvent(item, &ev);
6335                     if (ev.isAccepted() || ev.isAccepted(g))
6336                         break; // successfully delivered
6337                 }
6338             }
6339         }
6340     }
6341
6342     QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager;
6343     Q_ASSERT(gestureManager); // it would be very odd if we got called without a manager.
6344     for (setIter = canceledGestures.begin(); setIter != canceledGestures.end(); ++setIter) {
6345         gestureManager->recycle(*setIter);
6346         gestureTargets.remove(*setIter);
6347     }
6348 }
6349
6350 void QGraphicsScenePrivate::grabGesture(QGraphicsItem *, Qt::GestureType gesture)
6351 {
6352     (void)QGestureManager::instance(); // create a gesture manager
6353     if (!grabbedGestures[gesture]++) {
6354         foreach (QGraphicsView *view, views)
6355             view->viewport()->grabGesture(gesture);
6356     }
6357 }
6358
6359 void QGraphicsScenePrivate::ungrabGesture(QGraphicsItem *item, Qt::GestureType gesture)
6360 {
6361     // we know this can only be an object
6362     Q_ASSERT(item->d_ptr->isObject);
6363     QGraphicsObject *obj = static_cast<QGraphicsObject *>(item);
6364     QGestureManager::instance()->cleanupCachedGestures(obj, gesture);
6365     if (!--grabbedGestures[gesture]) {
6366         foreach (QGraphicsView *view, views)
6367             view->viewport()->ungrabGesture(gesture);
6368     }
6369 }
6370 #endif // QT_NO_GESTURES
6371
6372 QT_END_NAMESPACE
6373
6374 #include "moc_qgraphicsscene.cpp"
6375
6376 #endif // QT_NO_GRAPHICSVIEW