56ea4f986c17869ed682f2c146818f235eaa2e03
[profile/ivi/qtbase.git] / src / widgets / graphicsview / qgraphicsitem.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 QGraphicsItem
44     \brief The QGraphicsItem class is the base class for all graphical
45     items in a QGraphicsScene.
46     \since 4.2
47
48     \ingroup graphicsview-api
49     \inmodule QtWidgets
50
51     It provides a light-weight foundation for writing your own custom items.
52     This includes defining the item's geometry, collision detection, its
53     painting implementation and item interaction through its event handlers.
54     QGraphicsItem is part of the \l{Graphics View Framework}
55
56     \image graphicsview-items.png
57
58     For convenience, Qt provides a set of standard graphics items for the most
59     common shapes. These are:
60
61     \list
62     \li QGraphicsEllipseItem provides an ellipse item
63     \li QGraphicsLineItem provides a line item
64     \li QGraphicsPathItem provides an arbitrary path item
65     \li QGraphicsPixmapItem provides a pixmap item
66     \li QGraphicsPolygonItem provides a polygon item
67     \li QGraphicsRectItem provides a rectangular item
68     \li QGraphicsSimpleTextItem provides a simple text label item
69     \li QGraphicsTextItem provides an advanced text browser item
70     \endlist
71
72     All of an item's geometric information is based on its local coordinate
73     system. The item's position, pos(), is the only function that does not
74     operate in local coordinates, as it returns a position in parent
75     coordinates. \l {The Graphics View Coordinate System} describes the coordinate
76     system in detail.
77
78     You can set whether an item should be visible (i.e., drawn, and accepting
79     events), by calling setVisible(). Hiding an item will also hide its
80     children. Similarly, you can enable or disable an item by calling
81     setEnabled(). If you disable an item, all its children will also be
82     disabled. By default, items are both visible and enabled. To toggle
83     whether an item is selected or not, first enable selection by setting
84     the ItemIsSelectable flag, and then call setSelected(). Normally,
85     selection is toggled by the scene, as a result of user interaction.
86
87     To write your own graphics item, you first create a subclass of
88     QGraphicsItem, and then start by implementing its two pure virtual public
89     functions: boundingRect(), which returns an estimate of the area painted
90     by the item, and paint(), which implements the actual painting. For
91     example:
92
93     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 0
94
95     The boundingRect() function has many different purposes.
96     QGraphicsScene bases its item index on boundingRect(), and
97     QGraphicsView uses it both for culling invisible items, and for
98     determining the area that needs to be recomposed when drawing
99     overlapping items. In addition, QGraphicsItem's collision
100     detection mechanisms use boundingRect() to provide an efficient
101     cut-off. The fine grained collision algorithm in
102     collidesWithItem() is based on calling shape(), which returns an
103     accurate outline of the item's shape as a QPainterPath.
104
105     QGraphicsScene expects all items boundingRect() and shape() to
106     remain unchanged unless it is notified. If you want to change an
107     item's geometry in any way, you must first call
108     prepareGeometryChange() to allow QGraphicsScene to update its
109     bookkeeping.
110
111     Collision detection can be done in two ways:
112
113     \list 1
114
115     \li Reimplement shape() to return an accurate shape for your item,
116     and rely on the default implementation of collidesWithItem() to do
117     shape-shape intersection. This can be rather expensive if the
118     shapes are complex.
119
120     \li Reimplement collidesWithItem() to provide your own custom item
121     and shape collision algorithm.
122
123     \endlist
124
125     The contains() function can be called to determine whether the item \e
126     contains a point or not. This function can also be reimplemented by the
127     item. The default behavior of contains() is based on calling shape().
128
129     Items can contain other items, and also be contained by other items. All
130     items can have a parent item and a list of children. Unless the item has
131     no parent, its position is in \e parent coordinates (i.e., the parent's
132     local coordinates). Parent items propagate both their position and their
133     transformation to all children.
134
135     \img graphicsview-parentchild.png
136
137     \target Transformations
138     \section1 Transformations
139
140     QGraphicsItem supports projective transformations in addition to its base
141     position, pos(). There are several ways to change an item's transformation.
142     For simple transformations, you can call either of the convenience
143     functions setRotation() or setScale(), or you can pass any transformation
144     matrix to setTransform(). For advanced transformation control you also have
145     the option of setting several combined transformations by calling
146     setTransformations().
147
148     Item transformations accumulate from parent to child, so if both a parent
149     and child item are rotated 90 degrees, the child's total transformation
150     will be 180 degrees. Similarly, if the item's parent is scaled to 2x its
151     original size, its children will also be twice as large. An item's
152     transformation does not affect its own local geometry; all geometry
153     functions (e.g., contains(), update(), and all the mapping functions) still
154     operate in local coordinates. For convenience, QGraphicsItem provides the
155     functions sceneTransform(), which returns the item's total transformation
156     matrix (including its position and all parents' positions and
157     transformations), and scenePos(), which returns its position in scene
158     coordinates. To reset an item's matrix, call resetTransform().
159
160     Certain transformation operations produce a different outcome depending on
161     the order in which they are applied. For example, if you scale an
162     transform, and then rotate it, you may get a different result than if the
163     transform was rotated first. However, the order you set the transformation
164     properties on QGraphicsItem does not affect the resulting transformation;
165     QGraphicsItem always applies the properties in a fixed, defined order:
166
167     \list
168     \li The item's base transform is applied (transform())
169     \li The item's transformations list is applied in order (transformations())
170     \li The item is rotated relative to its transform origin point (rotation(), transformOriginPoint())
171     \li The item is scaled relative to its transform origin point (scale(), transformOriginPoint())
172     \endlist
173
174     \section1 Painting
175
176     The paint() function is called by QGraphicsView to paint the item's
177     contents. The item has no background or default fill of its own; whatever
178     is behind the item will shine through all areas that are not explicitly
179     painted in this function.  You can call update() to schedule a repaint,
180     optionally passing the rectangle that needs a repaint. Depending on
181     whether or not the item is visible in a view, the item may or may not be
182     repainted; there is no equivalent to QWidget::repaint() in QGraphicsItem.
183
184     Items are painted by the view, starting with the parent items and then
185     drawing children, in ascending stacking order. You can set an item's
186     stacking order by calling setZValue(), and test it by calling
187     zValue(), where items with low z-values are painted before items with
188     high z-values. Stacking order applies to sibling items; parents are always
189     drawn before their children.
190
191     \section1 Sorting
192
193     All items are drawn in a defined, stable order, and this same order decides
194     which items will receive mouse input first when you click on the scene.
195     Normally you don't have to worry about sorting, as the items follow a
196     "natural order", following the logical structure of the scene.
197
198     An item's children are stacked on top of the parent, and sibling items are
199     stacked by insertion order (i.e., in the same order that they were either
200     added to the scene, or added to the same parent). If you add item A, and
201     then B, then B will be on top of A. If you then add C, the items' stacking
202     order will be A, then B, then C.
203
204     \image graphicsview-zorder.png
205
206     This example shows the stacking order of all limbs of the robot from the
207     \l{graphicsview/dragdroprobot}{Drag and Drop Robot} example. The torso is
208     the root item (all other items are children or descendants of the torso),
209     so it is drawn first. Next, the head is drawn, as it is the first item in
210     the torso's list of children. Then the upper left arm is drawn. As the
211     lower arm is a child of the upper arm, the lower arm is then drawn,
212     followed by the upper arm's next sibling, which is the upper right arm, and
213     so on.
214
215     For advanced users, there are ways to alter how your items are sorted:
216
217     \list
218     \li You can call setZValue() on an item to explicitly stack it on top of, or
219     under, other sibling items. The default Z value for an item is 0. Items
220     with the same Z value are stacked by insertion order.
221
222     \li You can call stackBefore() to reorder the list of children. This will
223     directly modify the insertion order.
224
225     \li You can set the ItemStacksBehindParent flag to stack a child item behind
226     its parent.
227     \endlist
228
229     The stacking order of two sibling items also counts for each item's
230     children and descendant items. So if one item is on top of another, then
231     all its children will also be on top of all the other item's children as
232     well.
233
234     \section1 Events
235
236     QGraphicsItem receives events from QGraphicsScene through the virtual
237     function sceneEvent(). This function distributes the most common events
238     to a set of convenience event handlers:
239
240     \list
241     \li contextMenuEvent() handles context menu events
242     \li focusInEvent() and focusOutEvent() handle focus in and out events
243     \li hoverEnterEvent(), hoverMoveEvent(), and hoverLeaveEvent() handles
244     hover enter, move and leave events
245     \li inputMethodEvent() handles input events, for accessibility support
246     \li keyPressEvent() and keyReleaseEvent() handle key press and release events
247     \li mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), and
248     mouseDoubleClickEvent() handles mouse press, move, release, click and
249     doubleclick events
250     \endlist
251
252     You can filter events for any other item by installing event filters. This
253     functionality is separate from Qt's regular event filters (see
254     QObject::installEventFilter()), which only work on subclasses of QObject. After
255     installing your item as an event filter for another item by calling
256     installSceneEventFilter(), the filtered events will be received by the virtual
257     function sceneEventFilter(). You can remove item event filters by calling
258     removeSceneEventFilter().
259
260     \section1 Custom Data
261
262     Sometimes it's useful to register custom data with an item, be it a custom
263     item, or a standard item. You can call setData() on any item to store data
264     in it using a key-value pair (the key being an integer, and the value is a
265     QVariant). To get custom data from an item, call data(). This
266     functionality is completely untouched by Qt itself; it is provided for the
267     user's convenience.
268
269     \sa QGraphicsScene, QGraphicsView, {Graphics View Framework}
270 */
271
272 /*!
273     \variable QGraphicsItem::Type
274
275     The type value returned by the virtual type() function in standard
276     graphics item classes in Qt. All such standard graphics item
277     classes in Qt are associated with a unique value for Type,
278     e.g. the value returned by QGraphicsPathItem::type() is 2.
279
280     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 18
281 */
282
283 /*!
284     \variable QGraphicsItem::UserType
285
286     The lowest permitted type value for custom items (subclasses
287     of QGraphicsItem or any of the standard items). This value is
288     used in conjunction with a reimplementation of QGraphicsItem::type()
289     and declaring a Type enum value. Example:
290
291     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 1
292
293     \note UserType = 65536
294 */
295
296 /*!
297     \enum QGraphicsItem::GraphicsItemFlag
298
299     This enum describes different flags that you can set on an item to
300     toggle different features in the item's behavior.
301
302     All flags are disabled by default.
303
304     \value ItemIsMovable The item supports interactive movement using
305     the mouse. By clicking on the item and then dragging, the item
306     will move together with the mouse cursor. If the item has
307     children, all children are also moved. If the item is part of a
308     selection, all selected items are also moved. This feature is
309     provided as a convenience through the base implementation of
310     QGraphicsItem's mouse event handlers.
311
312     \value ItemIsSelectable The item supports selection. Enabling this
313     feature will enable setSelected() to toggle selection for the
314     item. It will also let the item be selected automatically as a
315     result of calling QGraphicsScene::setSelectionArea(), by clicking
316     on an item, or by using rubber band selection in QGraphicsView.
317
318     \value ItemIsFocusable The item supports keyboard input focus (i.e., it is
319     an input item). Enabling this flag will allow the item to accept focus,
320     which again allows the delivery of key events to
321     QGraphicsItem::keyPressEvent() and QGraphicsItem::keyReleaseEvent().
322
323     \value ItemClipsToShape The item clips to its own shape. The item cannot
324     draw or receive mouse, tablet, drag and drop or hover events outside its
325     shape. It is disabled by default. This behavior is enforced by
326     QGraphicsView::drawItems() or QGraphicsScene::drawItems(). This flag was
327     introduced in Qt 4.3.
328
329     \value ItemClipsChildrenToShape The item clips the painting of all its
330     descendants to its own shape. Items that are either direct or indirect
331     children of this item cannot draw outside this item's shape. By default,
332     this flag is disabled; children can draw anywhere. This behavior is
333     enforced by QGraphicsView::drawItems() or
334     QGraphicsScene::drawItems(). This flag was introduced in Qt 4.3.
335
336     \value ItemIgnoresTransformations The item ignores inherited
337     transformations (i.e., its position is still anchored to its parent, but
338     the parent or view rotation, zoom or shear transformations are ignored).
339     This flag is useful for keeping text label items horizontal and unscaled,
340     so they will still be readable if the view is transformed.  When set, the
341     item's view geometry and scene geometry will be maintained separately. You
342     must call deviceTransform() to map coordinates and detect collisions in
343     the view. By default, this flag is disabled. This flag was introduced in
344     Qt 4.3. \note With this flag set you can still scale the item itself, and
345     that scale transformation will influence the item's children.
346
347     \value ItemIgnoresParentOpacity The item ignores its parent's opacity. The
348     item's effective opacity is the same as its own; it does not combine with
349     the parent's opacity. This flags allows your item to keep its absolute
350     opacity even if the parent is semitransparent. This flag was introduced in
351     Qt 4.5.
352
353     \value ItemDoesntPropagateOpacityToChildren The item doesn't propagate its
354     opacity to its children. This flag allows you to create a semitransparent
355     item that does not affect the opacity of its children. This flag was
356     introduced in Qt 4.5.
357
358     \value ItemStacksBehindParent The item is stacked behind its parent. By
359     default, child items are stacked on top of the parent item. But setting
360     this flag, the child will be stacked behind it. This flag is useful for
361     drop shadow effects and for decoration objects that follow the parent
362     item's geometry without drawing on top of it. This flag was introduced
363     in Qt 4.5.
364
365     \value ItemUsesExtendedStyleOption The item makes use of either
366     \l{QStyleOptionGraphicsItem::} {exposedRect} or
367     \l{QStyleOptionGraphicsItem::} {matrix} in
368     QStyleOptionGraphicsItem. By default, the
369     \l{QStyleOptionGraphicsItem::} {exposedRect} is initialized to the
370     item's boundingRect() and the
371     \l{QStyleOptionGraphicsItem::}{matrix} is untransformed.  You can
372     enable this flag for the style options to be set up with more
373     fine-grained values.  Note that
374     QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag
375     and always initialized to 1. Use
376     QStyleOptionGraphicsItem::levelOfDetailFromTransform() if you need
377     a higher value. This flag was introduced in Qt 4.6.
378
379     \value ItemHasNoContents The item does not paint anything (i.e., calling
380     paint() on the item has no effect). You should set this flag on items that
381     do not need to be painted to ensure that Graphics View avoids unnecessary
382     painting preparations. This flag was introduced in Qt 4.6.
383
384     \value ItemSendsGeometryChanges The item enables itemChange()
385     notifications for ItemPositionChange, ItemPositionHasChanged,
386     ItemMatrixChange, ItemTransformChange, ItemTransformHasChanged,
387     ItemRotationChange, ItemRotationHasChanged, ItemScaleChange, ItemScaleHasChanged,
388     ItemTransformOriginPointChange, and ItemTransformOriginPointHasChanged. For
389     performance reasons, these notifications are disabled by default. You must
390     enable this flag to receive notifications for position and transform
391     changes. This flag was introduced in Qt 4.6.
392
393     \value ItemAcceptsInputMethod The item supports input methods typically
394     used for Asian languages.
395     This flag was introduced in Qt 4.6.
396
397     \value ItemNegativeZStacksBehindParent The item automatically
398     stacks behind it's parent if it's z-value is negative. This flag
399     enables setZValue() to toggle ItemStacksBehindParent. This flag
400     was introduced in Qt 4.6.
401
402     \value ItemIsPanel The item is a panel. A panel provides activation and
403     contained focus handling. Only one panel can be active at a time (see
404     QGraphicsItem::isActive()). When no panel is active, QGraphicsScene
405     activates all non-panel items. Window items (i.e.,
406     QGraphicsItem::isWindow() returns true) are panels. This flag was
407     introduced in Qt 4.6.
408
409     \omitvalue ItemIsFocusScope \omit Internal only (for now). \endomit
410
411     \value ItemSendsScenePositionChanges The item enables itemChange()
412     notifications for ItemScenePositionHasChanged. For performance reasons,
413     these notifications are disabled by default. You must enable this flag
414     to receive notifications for scene position changes. This flag was
415     introduced in Qt 4.6.
416
417     \omitvalue ItemStopsClickFocusPropagation \omit The item stops propagating
418     click focus to items underneath when being clicked on. This flag
419     allows you create a non-focusable item that can be clicked on without
420     changing the focus. \endomit
421
422     \omitvalue ItemStopsFocusHandling \omit Same as
423     ItemStopsClickFocusPropagation, but also suppresses focus-out. This flag
424     allows you to completely take over focus handling.
425     This flag was introduced in Qt 4.7. \endomit
426 */
427
428 /*!
429     \enum QGraphicsItem::GraphicsItemChange
430
431     This enum describes the state changes that are notified by
432     QGraphicsItem::itemChange(). The notifications are sent as the state
433     changes, and in some cases, adjustments can be made (see the documentation
434     for each change for details).
435
436     Note: Be careful with calling functions on the QGraphicsItem itself inside
437     itemChange(), as certain function calls can lead to unwanted
438     recursion. For example, you cannot call setPos() in itemChange() on an
439     ItemPositionChange notification, as the setPos() function will again call
440     itemChange(ItemPositionChange). Instead, you can return the new, adjusted
441     position from itemChange().
442
443     \value ItemEnabledChange The item's enabled state changes. If the item is
444     presently enabled, it will become disabled, and vice verca. The value
445     argument is the new enabled state (i.e., true or false). Do not call
446     setEnabled() in itemChange() as this notification is delivered. Instead,
447     you can return the new state from itemChange().
448
449     \value ItemEnabledHasChanged The item's enabled state has changed. The
450     value argument is the new enabled state (i.e., true or false). Do not call
451     setEnabled() in itemChange() as this notification is delivered. The return
452     value is ignored.
453
454     \value ItemMatrixChange The item's affine transformation matrix is
455     changing. This value is obsolete; you can use ItemTransformChange instead.
456
457     \value ItemPositionChange The item's position changes. This notification
458     is sent if the ItemSendsGeometryChanges flag is enabled, and when the
459     item's local position changes, relative to its parent (i.e., as a result
460     of calling setPos() or moveBy()). The value argument is the new position
461     (i.e., a QPointF).  You can call pos() to get the original position. Do
462     not call setPos() or moveBy() in itemChange() as this notification is
463     delivered; instead, you can return the new, adjusted position from
464     itemChange(). After this notification, QGraphicsItem immediately sends the
465     ItemPositionHasChanged notification if the position changed.
466
467     \value ItemPositionHasChanged The item's position has changed. This
468     notification is sent if the ItemSendsGeometryChanges flag is enabled, and
469     after the item's local position, relative to its parent, has changed. The
470     value argument is the new position (the same as pos()), and QGraphicsItem
471     ignores the return value for this notification (i.e., a read-only
472     notification).
473
474     \value ItemTransformChange The item's transformation matrix changes. This
475     notification is send if the ItemSendsGeometryChanges flag is enabled, and
476     when the item's local transformation matrix changes (i.e., as a result of
477     calling setTransform(). The value argument is the new matrix (i.e., a
478     QTransform); to get the old matrix, call transform(). Do not call
479     setTransform() or set any of the transformation properties in itemChange()
480     as this notification is delivered; instead, you can return the new matrix
481     from itemChange().  This notification is not sent if you change the
482     transformation properties.
483
484     \value ItemTransformHasChanged The item's transformation matrix has
485     changed either because setTransform is called, or one of the
486     transformation properties is changed. This notification is sent if the
487     ItemSendsGeometryChanges flag is enabled, and after the item's local
488     transformation matrix has changed. The value argument is the new matrix
489     (same as transform()), and QGraphicsItem ignores the return value for this
490     notification (i.e., a read-only notification).
491
492     \value ItemRotationChange The item's rotation property changes. This
493     notification is sent if the ItemSendsGeometryChanges flag is enabled, and
494     when the item's rotation property changes (i.e., as a result of calling
495     setRotation()). The value argument is the new rotation (i.e., a double);
496     to get the old rotation, call rotation(). Do not call setRotation() in
497     itemChange() as this notification is delivered; instead, you can return
498     the new rotation from itemChange().
499
500     \value ItemRotationHasChanged The item's rotation property has changed.
501     This notification is sent if the ItemSendsGeometryChanges flag is enabled,
502     and after the item's rotation property has changed. The value argument is
503     the new rotation (i.e., a double), and QGraphicsItem ignores the return
504     value for this notification (i.e., a read-only notification). Do not call
505     setRotation() in itemChange() as this notification is delivered.
506
507     \value ItemScaleChange The item's scale property changes. This notification
508     is sent if the ItemSendsGeometryChanges flag is enabled, and when the item's
509     scale property changes (i.e., as a result of calling setScale()). The value
510     argument is the new scale (i.e., a double); to get the old scale, call
511     scale(). Do not call setScale() in itemChange() as this notification is
512     delivered; instead, you can return the new scale from itemChange().
513
514     \value ItemScaleHasChanged The item's scale property has changed. This
515     notification is sent if the ItemSendsGeometryChanges flag is enabled, and
516     after the item's scale property has changed. The value argument is the new
517     scale (i.e., a double), and QGraphicsItem ignores the return value for this
518     notification (i.e., a read-only notification). Do not call setScale() in
519     itemChange() as this notification is delivered.
520
521     \value ItemTransformOriginPointChange The item's transform origin point
522     property changes. This notification is sent if the ItemSendsGeometryChanges
523     flag is enabled, and when the item's transform origin point property changes
524     (i.e., as a result of calling setTransformOriginPoint()). The value argument
525     is the new origin point (i.e., a QPointF); to get the old origin point, call
526     transformOriginPoint(). Do not call setTransformOriginPoint() in itemChange()
527     as this notification is delivered; instead, you can return the new transform
528     origin point from itemChange().
529
530     \value ItemTransformOriginPointHasChanged The item's transform origin point
531     property has changed. This notification is sent if the ItemSendsGeometryChanges
532     flag is enabled, and after the item's transform origin point property has
533     changed. The value argument is the new origin point (i.e., a QPointF), and
534     QGraphicsItem ignores the return value for this notification (i.e., a read-only
535     notification). Do not call setTransformOriginPoint() in itemChange() as this
536     notification is delivered.
537
538     \value ItemSelectedChange The item's selected state changes. If the item is
539     presently selected, it will become unselected, and vice verca. The value
540     argument is the new selected state (i.e., true or false). Do not call
541     setSelected() in itemChange() as this notification is delivered; instead, you
542     can return the new selected state from itemChange().
543
544     \value ItemSelectedHasChanged The item's selected state has changed. The
545     value argument is the new selected state (i.e., true or false). Do not
546     call setSelected() in itemChange() as this notification is delivered. The
547     return value is ignored.
548
549     \value ItemVisibleChange The item's visible state changes. If the item is
550     presently visible, it will become invisible, and vice verca. The value
551     argument is the new visible state (i.e., true or false). Do not call
552     setVisible() in itemChange() as this notification is delivered; instead,
553     you can return the new visible state from itemChange().
554
555     \value ItemVisibleHasChanged The item's visible state has changed. The
556     value argument is the new visible state (i.e., true or false). Do not call
557     setVisible() in itemChange() as this notification is delivered. The return
558     value is ignored.
559
560     \value ItemParentChange The item's parent changes. The value argument is
561     the new parent item (i.e., a QGraphicsItem pointer).  Do not call
562     setParentItem() in itemChange() as this notification is delivered;
563     instead, you can return the new parent from itemChange().
564
565     \value ItemParentHasChanged The item's parent has changed. The value
566     argument is the new parent (i.e., a pointer to a QGraphicsItem). Do not
567     call setParentItem() in itemChange() as this notification is
568     delivered. The return value is ignored.
569
570     \value ItemChildAddedChange A child is added to this item. The value
571     argument is the new child item (i.e., a QGraphicsItem pointer). Do not
572     pass this item to any item's setParentItem() function as this notification
573     is delivered. The return value is unused; you cannot adjust anything in
574     this notification. Note that the new child might not be fully constructed
575     when this notification is sent; calling pure virtual functions on
576     the child can lead to a crash.
577
578     \value ItemChildRemovedChange A child is removed from this item. The value
579     argument is the child item that is about to be removed (i.e., a
580     QGraphicsItem pointer). The return value is unused; you cannot adjust
581     anything in this notification.
582
583     \value ItemSceneChange The item is moved to a new scene. This notification is
584     also sent when the item is added to its initial scene, and when it is removed.
585     The item's scene() is the old scene (or 0 if the item has not been added to a
586     scene yet). The value argument is the new scene (i.e., a QGraphicsScene
587     pointer), or a null pointer if the item is removed from a scene. Do not
588     override this change by passing this item to QGraphicsScene::addItem() as this
589     notification is delivered; instead, you can return the new scene from
590     itemChange(). Use this feature with caution; objecting to a scene change can
591     quickly lead to unwanted recursion.
592
593     \value ItemSceneHasChanged The item's scene has changed. The item's scene() is
594     the new scene. This notification is also sent when the item is added to its
595     initial scene, and when it is removed.The value argument is the new scene
596     (i.e., a pointer to a QGraphicsScene). Do not call setScene() in itemChange()
597     as this notification is delivered. The return value is ignored.
598
599     \value ItemCursorChange The item's cursor changes. The value argument is
600     the new cursor (i.e., a QCursor). Do not call setCursor() in itemChange()
601     as this notification is delivered. Instead, you can return a new cursor
602     from itemChange().
603
604     \value ItemCursorHasChanged The item's cursor has changed. The value
605     argument is the new cursor (i.e., a QCursor). Do not call setCursor() as
606     this notification is delivered. The return value is ignored.
607
608     \value ItemToolTipChange The item's tooltip changes. The value argument is
609     the new tooltip (i.e., a QToolTip). Do not call setToolTip() in
610     itemChange() as this notification is delivered. Instead, you can return a
611     new tooltip from itemChange().
612
613     \value ItemToolTipHasChanged The item's tooltip has changed. The value
614     argument is the new tooltip (i.e., a QToolTip). Do not call setToolTip()
615     as this notification is delivered. The return value is ignored.
616
617     \value ItemFlagsChange The item's flags change. The value argument is the
618     new flags (i.e., a quint32). Do not call setFlags() in itemChange() as
619     this notification is delivered. Instead, you can return the new flags from
620     itemChange().
621
622     \value ItemFlagsHaveChanged The item's flags have changed. The value
623     argument is the new flags (i.e., a quint32). Do not call setFlags() in
624     itemChange() as this notification is delivered. The return value is
625     ignored.
626
627     \value ItemZValueChange The item's Z-value changes. The value argument is
628     the new Z-value (i.e., a double). Do not call setZValue() in itemChange()
629     as this notification is delivered. Instead, you can return a new Z-value
630     from itemChange().
631
632     \value ItemZValueHasChanged The item's Z-value has changed. The value
633     argument is the new Z-value (i.e., a double). Do not call setZValue() as
634     this notification is delivered. The return value is ignored.
635
636     \value ItemOpacityChange The item's opacity changes. The value argument is
637     the new opacity (i.e., a double). Do not call setOpacity() in itemChange()
638     as this notification is delivered. Instead, you can return a new opacity
639     from itemChange().
640
641     \value ItemOpacityHasChanged The item's opacity has changed. The value
642     argument is the new opacity (i.e., a double). Do not call setOpacity() as
643     this notification is delivered. The return value is ignored.
644
645     \value ItemScenePositionHasChanged The item's scene position has changed.
646     This notification is sent if the ItemSendsScenePositionChanges flag is
647     enabled, and after the item's scene position has changed (i.e., the
648     position or transformation of the item itself or the position or
649     transformation of any ancestor has changed). The value argument is the
650     new scene position (the same as scenePos()), and QGraphicsItem ignores
651     the return value for this notification (i.e., a read-only notification).
652 */
653
654 /*!
655     \enum QGraphicsItem::CacheMode
656     \since 4.4
657
658     This enum describes QGraphicsItem's cache modes. Caching is used to speed
659     up rendering by allocating and rendering to an off-screen pixel buffer,
660     which can be reused when the item requires redrawing. For some paint
661     devices, the cache is stored directly in graphics memory, which makes
662     rendering very quick.
663
664     \value NoCache The default; all item caching is
665     disabled. QGraphicsItem::paint() is called every time the item needs
666     redrawing.
667
668     \value ItemCoordinateCache Caching is enabled for the item's logical
669     (local) coordinate system. QGraphicsItem creates an off-screen pixel
670     buffer with a configurable size / resolution that you can pass to
671     QGraphicsItem::setCacheMode(). Rendering quality will typically degrade,
672     depending on the resolution of the cache and the item transformation.  The
673     first time the item is redrawn, it will render itself into the cache, and
674     the cache is then reused for every subsequent expose. The cache is also
675     reused as the item is transformed. To adjust the resolution of the cache,
676     you can call setCacheMode() again.
677
678     \value DeviceCoordinateCache Caching is enabled at the paint device level,
679     in device coordinates. This mode is for items that can move, but are not
680     rotated, scaled or sheared. If the item is transformed directly or
681     indirectly, the cache will be regenerated automatically. Unlike
682     ItemCoordinateCacheMode, DeviceCoordinateCache always renders at maximum
683     quality.
684
685     \sa QGraphicsItem::setCacheMode()
686 */
687
688 /*!
689     \enum QGraphicsItem::Extension
690     \internal
691
692     Note: This is provided as a hook to avoid future problems related
693     to adding virtual functions. See also extension(),
694     supportsExtension() and setExtension().
695 */
696
697 /*!
698     \enum QGraphicsItem::PanelModality
699     \since 4.6
700
701     This enum specifies the behavior of a modal panel. A modal panel
702     is one that blocks input to other panels. Note that items that
703     are children of a modal panel are not blocked.
704
705     The values are:
706
707     \value NonModal The panel is not modal and does not block input to
708     other panels. This is the default value for panels.
709
710     \value PanelModal The panel is modal to a single item hierarchy
711     and blocks input to its parent pane, all grandparent panels, and
712     all siblings of its parent and grandparent panels.
713
714     \value SceneModal The window is modal to the entire scene and
715     blocks input to all panels.
716
717     \sa QGraphicsItem::setPanelModality(), QGraphicsItem::panelModality(), QGraphicsItem::ItemIsPanel
718 */
719
720 #include "qgraphicsitem.h"
721
722 #ifndef QT_NO_GRAPHICSVIEW
723
724 #include "qgraphicsscene.h"
725 #include "qgraphicsscene_p.h"
726 #include "qgraphicssceneevent.h"
727 #include "qgraphicsview.h"
728 #include "qgraphicswidget.h"
729 #include "qgraphicsproxywidget.h"
730 #include "qgraphicsscenebsptreeindex_p.h"
731 #include <QtCore/qbitarray.h>
732 #include <QtCore/qdebug.h>
733 #include <QtCore/qpoint.h>
734 #include <QtCore/qstack.h>
735 #include <QtCore/qtimer.h>
736 #include <QtCore/qvariant.h>
737 #include <QtCore/qvarlengtharray.h>
738 #include <QtCore/qnumeric.h>
739 #include <QtWidgets/qapplication.h>
740 #include <QtGui/qbitmap.h>
741 #include <QtGui/qpainter.h>
742 #include <QtGui/qpainterpath.h>
743 #include <QtGui/qpixmapcache.h>
744 #include <QtWidgets/qstyleoption.h>
745 #include <QtGui/qevent.h>
746 #include <QtGui/qinputmethod.h>
747 #include <QtWidgets/qgraphicseffect.h>
748 #ifndef QT_NO_ACCESSIBILITY
749 # include "qaccessible.h"
750 #endif
751
752 #include <private/qgraphicsitem_p.h>
753 #include <private/qgraphicswidget_p.h>
754 #include <private/qwidgettextcontrol_p.h>
755 #include <private/qtextdocumentlayout_p.h>
756 #include <private/qtextengine_p.h>
757 #include <private/qwidget_p.h>
758 #include <private/qapplication_p.h>
759
760 #ifdef Q_WS_X11
761 #include <private/qt_x11_p.h>
762 #include <private/qpixmap_x11_p.h>
763 #endif
764
765 #include <private/qgesturemanager_p.h>
766
767 #include <math.h>
768
769 QT_BEGIN_NAMESPACE
770
771 static inline void _q_adjustRect(QRect *rect)
772 {
773     Q_ASSERT(rect);
774     if (!rect->width())
775         rect->adjust(0, 0, 1, 0);
776     if (!rect->height())
777         rect->adjust(0, 0, 0, 1);
778 }
779
780 /*
781     ### Move this into QGraphicsItemPrivate
782  */
783 class QGraphicsItemCustomDataStore
784 {
785 public:
786     QHash<const QGraphicsItem *, QMap<int, QVariant> > data;
787 };
788 Q_GLOBAL_STATIC(QGraphicsItemCustomDataStore, qt_dataStore)
789
790 /*!
791     \internal
792
793     Returns a QPainterPath of \a path when stroked with the \a pen.
794     Ignoring dash pattern.
795 */
796 static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)
797 {
798     // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
799     // if we pass a value of 0.0 to QPainterPathStroker::setWidth()
800     const qreal penWidthZero = qreal(0.00000001);
801
802     if (path == QPainterPath())
803         return path;
804     QPainterPathStroker ps;
805     ps.setCapStyle(pen.capStyle());
806     if (pen.widthF() <= 0.0)
807         ps.setWidth(penWidthZero);
808     else
809         ps.setWidth(pen.widthF());
810     ps.setJoinStyle(pen.joinStyle());
811     ps.setMiterLimit(pen.miterLimit());
812     QPainterPath p = ps.createStroke(path);
813     p.addPath(path);
814     return p;
815 }
816
817 /*!
818     \internal
819
820     Propagates the ancestor flag \a flag with value \a enabled to all this
821     item's children. If \a root is false, the flag is also set on this item
822     (default is true).
823 */
824 void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
825                                            AncestorFlag flag, bool enabled, bool root)
826 {
827     Q_Q(QGraphicsItem);
828     if (root) {
829         // For root items only. This is the item that has either enabled or
830         // disabled \a childFlag, or has been reparented.
831         switch (int(childFlag)) {
832         case -2:
833             flag = AncestorFiltersChildEvents;
834             enabled = q->filtersChildEvents();
835             break;
836         case -1:
837             flag = AncestorHandlesChildEvents;
838             enabled = q->handlesChildEvents();
839             break;
840         case QGraphicsItem::ItemClipsChildrenToShape:
841             flag = AncestorClipsChildren;
842             enabled = flags & QGraphicsItem::ItemClipsChildrenToShape;
843             break;
844         case QGraphicsItem::ItemIgnoresTransformations:
845             flag = AncestorIgnoresTransformations;
846             enabled = flags & QGraphicsItem::ItemIgnoresTransformations;
847             break;
848         default:
849             return;
850         }
851
852         if (parent) {
853             // Inherit the enabled-state from our parents.
854             if ((parent->d_ptr->ancestorFlags & flag)
855                     || (int(parent->d_ptr->flags & childFlag) == childFlag)
856                         || (childFlag == -1 && parent->d_ptr->handlesChildEvents)
857                         || (childFlag == -2 && parent->d_ptr->filtersDescendantEvents)) {
858                 enabled = true;
859                 ancestorFlags |= flag;
860             } else {
861                 ancestorFlags &= ~flag;
862             }
863         } else {
864             // Top-level root items don't have any ancestors, so there are no
865             // ancestor flags either.
866             ancestorFlags = 0;
867         }
868     } else {
869         // Don't set or propagate the ancestor flag if it's already correct.
870         if (((ancestorFlags & flag) && enabled) || (!(ancestorFlags & flag) && !enabled))
871             return;
872
873         // Set the flag.
874         if (enabled)
875             ancestorFlags |= flag;
876         else
877             ancestorFlags &= ~flag;
878
879         // Don't process children if the item has the main flag set on itself.
880         if ((childFlag != -1 &&  int(flags & childFlag) == childFlag)
881             || (int(childFlag) == -1 && handlesChildEvents)
882             || (int(childFlag) == -2 && filtersDescendantEvents))
883             return;
884     }
885
886     for (int i = 0; i < children.size(); ++i)
887         children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
888 }
889
890 void QGraphicsItemPrivate::updateAncestorFlags()
891 {
892     int flags = 0;
893     if (parent) {
894         // Inherit the parent's ancestor flags.
895         QGraphicsItemPrivate *pd = parent->d_ptr.data();
896         flags = pd->ancestorFlags;
897
898         // Add in flags from the parent.
899         if (pd->filtersDescendantEvents)
900             flags |= AncestorFiltersChildEvents;
901         if (pd->handlesChildEvents)
902             flags |= AncestorHandlesChildEvents;
903         if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape)
904             flags |= AncestorClipsChildren;
905         if (pd->flags & QGraphicsItem::ItemIgnoresTransformations)
906             flags |= AncestorIgnoresTransformations;
907     }
908
909     if (ancestorFlags == flags)
910         return; // No change; stop propagation.
911     ancestorFlags = flags;
912
913     // Propagate to children recursively.
914     for (int i = 0; i < children.size(); ++i)
915         children.at(i)->d_ptr->updateAncestorFlags();
916 }
917
918 /*!
919     \internal
920
921     Propagates item group membership.
922 */
923 void QGraphicsItemPrivate::setIsMemberOfGroup(bool enabled)
924 {
925     Q_Q(QGraphicsItem);
926     isMemberOfGroup = enabled;
927     if (!qgraphicsitem_cast<QGraphicsItemGroup *>(q)) {
928         foreach (QGraphicsItem *child, children)
929             child->d_func()->setIsMemberOfGroup(enabled);
930     }
931 }
932
933 /*!
934     \internal
935
936     Maps any item pos properties of \a event to \a item's coordinate system.
937 */
938 void QGraphicsItemPrivate::remapItemPos(QEvent *event, QGraphicsItem *item)
939 {
940     Q_Q(QGraphicsItem);
941     switch (event->type()) {
942     case QEvent::GraphicsSceneMouseMove:
943     case QEvent::GraphicsSceneMousePress:
944     case QEvent::GraphicsSceneMouseRelease:
945     case QEvent::GraphicsSceneMouseDoubleClick: {
946         QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
947         mouseEvent->setPos(item->mapFromItem(q, mouseEvent->pos()));
948         mouseEvent->setLastPos(item->mapFromItem(q, mouseEvent->pos()));
949         for (int i = 0x1; i <= 0x10; i <<= 1) {
950             if (mouseEvent->buttons() & i) {
951                 Qt::MouseButton button = Qt::MouseButton(i);
952                 mouseEvent->setButtonDownPos(button, item->mapFromItem(q, mouseEvent->buttonDownPos(button)));
953             }
954         }
955         break;
956     }
957     case QEvent::GraphicsSceneWheel: {
958         QGraphicsSceneWheelEvent *wheelEvent = static_cast<QGraphicsSceneWheelEvent *>(event);
959         wheelEvent->setPos(item->mapFromItem(q, wheelEvent->pos()));
960         break;
961     }
962     case QEvent::GraphicsSceneContextMenu: {
963         QGraphicsSceneContextMenuEvent *contextEvent = static_cast<QGraphicsSceneContextMenuEvent *>(event);
964         contextEvent->setPos(item->mapFromItem(q, contextEvent->pos()));
965         break;
966     }
967     case QEvent::GraphicsSceneHoverMove: {
968         QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
969         hoverEvent->setPos(item->mapFromItem(q, hoverEvent->pos()));
970         break;
971     }
972     default:
973         break;
974     }
975 }
976
977 /*!
978     \internal
979
980     Maps the point \a pos from scene to item coordinates. If \a view is passed and the item
981     is untransformable, this function will correctly map \a pos from the scene using the
982     view's transformation.
983 */
984 QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos,
985                                                   const QWidget *viewport) const
986 {
987     Q_Q(const QGraphicsItem);
988     if (!itemIsUntransformable())
989         return q->mapFromScene(pos);
990     QGraphicsView *view = 0;
991     if (viewport)
992         view = qobject_cast<QGraphicsView *>(viewport->parentWidget());
993     if (!view)
994         return q->mapFromScene(pos);
995     // ### More ping pong than needed.
996     return q->deviceTransform(view->viewportTransform()).inverted().map(view->mapFromScene(pos));
997 }
998
999 /*!
1000     \internal
1001
1002     Combines this item's position and transform onto \a transform.
1003
1004     If you need to change this function (e.g., adding more transformation
1005     modes / options), make sure to change all places marked with COMBINE.
1006 */
1007 void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransform *viewTransform) const
1008 {
1009     // COMBINE
1010     if (viewTransform && itemIsUntransformable()) {
1011         *x = q_ptr->deviceTransform(*viewTransform);
1012     } else {
1013         if (transformData)
1014             *x *= transformData->computedFullTransform();
1015         if (!pos.isNull())
1016             *x *= QTransform::fromTranslate(pos.x(), pos.y());
1017     }
1018 }
1019
1020 /*!
1021     \internal
1022
1023     Combines this item's position and transform onto \a transform.
1024
1025     If you need to change this function (e.g., adding more transformation
1026     modes / options), make sure to change QGraphicsItem::deviceTransform() as
1027     well.
1028 */
1029 void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTransform *viewTransform) const
1030 {
1031     // COMBINE
1032     if (viewTransform && itemIsUntransformable()) {
1033         *x = q_ptr->deviceTransform(*viewTransform);
1034     } else {
1035         x->translate(pos.x(), pos.y());
1036         if (transformData)
1037             *x = transformData->computedFullTransform(x);
1038     }
1039 }
1040
1041 void QGraphicsItemPrivate::updateSceneTransformFromParent()
1042 {
1043     if (parent) {
1044         Q_ASSERT(!parent->d_ptr->dirtySceneTransform);
1045         if (parent->d_ptr->sceneTransformTranslateOnly) {
1046             sceneTransform = QTransform::fromTranslate(parent->d_ptr->sceneTransform.dx() + pos.x(),
1047                                                        parent->d_ptr->sceneTransform.dy() + pos.y());
1048         } else {
1049             sceneTransform = parent->d_ptr->sceneTransform;
1050             sceneTransform.translate(pos.x(), pos.y());
1051         }
1052         if (transformData) {
1053             sceneTransform = transformData->computedFullTransform(&sceneTransform);
1054             sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1055         } else {
1056             sceneTransformTranslateOnly = parent->d_ptr->sceneTransformTranslateOnly;
1057         }
1058     } else if (!transformData) {
1059         sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
1060         sceneTransformTranslateOnly = 1;
1061     } else if (transformData->onlyTransform) {
1062         sceneTransform = transformData->transform;
1063         if (!pos.isNull())
1064             sceneTransform *= QTransform::fromTranslate(pos.x(), pos.y());
1065         sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1066     } else if (pos.isNull()) {
1067         sceneTransform = transformData->computedFullTransform();
1068         sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1069     } else {
1070         sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
1071         sceneTransform = transformData->computedFullTransform(&sceneTransform);
1072         sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1073     }
1074     dirtySceneTransform = 0;
1075 }
1076
1077 /*!
1078     \internal
1079
1080     This helper function helped us add input method query support in
1081     Qt 4.4.1 without having to reimplement the inputMethodQuery()
1082     function in QGraphicsProxyWidget. ### Qt 5: Remove. We cannot
1083     remove it in 4.5+ even if we do reimplement the function properly,
1084     because apps compiled with 4.4 will not be able to call the
1085     reimplementation.
1086 */
1087 QVariant QGraphicsItemPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query) const
1088 {
1089     Q_UNUSED(query);
1090     return QVariant();
1091 }
1092
1093 /*!
1094     \internal
1095
1096     Make sure not to trigger any pure virtual function calls (e.g.,
1097     prepareGeometryChange) if the item is in its destructor, i.e.
1098     inDestructor is 1.
1099 */
1100 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant,
1101                                                const QVariant *thisPointerVariant)
1102 {
1103     Q_Q(QGraphicsItem);
1104     if (newParent == parent)
1105         return;
1106
1107     if (isWidget)
1108         static_cast<QGraphicsWidgetPrivate *>(this)->fixFocusChainBeforeReparenting((newParent &&
1109                                                         newParent->isWidget()) ? static_cast<QGraphicsWidget *>(newParent) : 0,
1110                                                         scene);
1111     if (scene) {
1112         // Deliver the change to the index
1113         if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
1114             scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
1115
1116         // Disable scene pos notifications for old ancestors
1117         if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
1118             scene->d_func()->setScenePosItemEnabled(q, false);
1119     }
1120
1121     if (subFocusItem && parent) {
1122         // Make sure none of the old parents point to this guy.
1123         subFocusItem->d_ptr->clearSubFocus(parent);
1124     }
1125
1126     // We anticipate geometry changes. If the item is deleted, it will be
1127     // removed from the index at a later stage, and the whole scene will be
1128     // updated.
1129     if (!inDestructor)
1130         q_ptr->prepareGeometryChange();
1131
1132     if (parent) {
1133         // Remove from current parent
1134         parent->d_ptr->removeChild(q);
1135         if (thisPointerVariant)
1136             parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant);
1137     }
1138
1139     // Update toplevelitem list. If this item is being deleted, its parent
1140     // will be 0 but we don't want to register/unregister it in the TLI list.
1141     if (scene && !inDestructor) {
1142         if (parent && !newParent) {
1143             scene->d_func()->registerTopLevelItem(q);
1144         } else if (!parent && newParent) {
1145             scene->d_func()->unregisterTopLevelItem(q);
1146         }
1147     }
1148
1149     // Ensure any last parent focus scope does not point to this item or any of
1150     // its descendents.
1151     QGraphicsItem *p = parent;
1152     QGraphicsItem *parentFocusScopeItem = 0;
1153     while (p) {
1154         if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
1155             // If this item's focus scope's focus scope item points
1156             // to this item or a descendent, then clear it.
1157             QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
1158             if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
1159                 parentFocusScopeItem = fsi;
1160                 p->d_ptr->focusScopeItem = 0;
1161                 fsi->d_ptr->focusScopeItemChange(false);
1162             }
1163             break;
1164         }
1165         p = p->d_ptr->parent;
1166     }
1167
1168     // Update graphics effect optimization flag
1169     if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect))
1170         newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
1171
1172     // Update focus scope item ptr in new scope.
1173     QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
1174     if (newFocusScopeItem && newParent) {
1175         QGraphicsItem *p = newParent;
1176         while (p) {
1177             if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
1178                 if (subFocusItem && subFocusItem != q_ptr) {
1179                     // Find the subFocusItem's topmost focus scope within the new parent's focusscope
1180                     QGraphicsItem *ancestorScope = 0;
1181                     QGraphicsItem *p2 = subFocusItem->d_ptr->parent;
1182                     while (p2 && p2 != p) {
1183                         if (p2->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
1184                             ancestorScope = p2;
1185                         if (p2->d_ptr->flags & QGraphicsItem::ItemIsPanel)
1186                             break;
1187                         if (p2 == q_ptr)
1188                             break;
1189                         p2 = p2->d_ptr->parent;
1190                     }
1191                     if (ancestorScope)
1192                         newFocusScopeItem = ancestorScope;
1193                 }
1194
1195                 p->d_ptr->focusScopeItem = newFocusScopeItem;
1196                 newFocusScopeItem->d_ptr->focusScopeItemChange(true);
1197                 // Ensure the new item is no longer the subFocusItem. The
1198                 // only way to set focus on a child of a focus scope is
1199                 // by setting focus on the scope itself.
1200                 if (subFocusItem && !p->focusItem())
1201                     subFocusItem->d_ptr->clearSubFocus();
1202                 break;
1203             }
1204             p = p->d_ptr->parent;
1205         }
1206     }
1207
1208     // Resolve depth.
1209     invalidateDepthRecursively();
1210
1211     if ((parent = newParent)) {
1212         if (parent->d_func()->scene && parent->d_func()->scene != scene) {
1213             // Move this item to its new parent's scene
1214             parent->d_func()->scene->addItem(q);
1215         } else if (!parent->d_func()->scene && scene) {
1216             // Remove this item from its former scene
1217             scene->removeItem(q);
1218         }
1219
1220         parent->d_ptr->addChild(q);
1221         if (thisPointerVariant)
1222             parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant);
1223         if (scene) {
1224             // Re-enable scene pos notifications for new ancestors
1225             if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
1226                 scene->d_func()->setScenePosItemEnabled(q, true);
1227         }
1228
1229         // Propagate dirty flags to the new parent
1230         markParentDirty(/*updateBoundingRect=*/true);
1231
1232         // Inherit ancestor flags from the new parent.
1233         updateAncestorFlags();
1234
1235         // Update item visible / enabled.
1236         if (parent->d_ptr->visible != visible) {
1237             if (!parent->d_ptr->visible || !explicitlyHidden)
1238                 setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false);
1239         }
1240         if (parent->isEnabled() != enabled) {
1241             if (!parent->d_ptr->enabled || !explicitlyDisabled)
1242                 setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false);
1243         }
1244
1245         // Auto-activate if visible and the parent is active.
1246         if (visible && parent->isActive())
1247             q->setActive(true);
1248     } else {
1249         // Inherit ancestor flags from the new parent.
1250         updateAncestorFlags();
1251
1252         if (!inDestructor) {
1253             // Update item visible / enabled.
1254             if (!visible && !explicitlyHidden)
1255                 setVisibleHelper(true, /* explicit = */ false);
1256             if (!enabled && !explicitlyDisabled)
1257                 setEnabledHelper(true, /* explicit = */ false);
1258         }
1259     }
1260
1261     dirtySceneTransform = 1;
1262     if (!inDestructor && (transformData || (newParent && newParent->d_ptr->transformData)))
1263         transformChanged();
1264
1265     // Restore the sub focus chain.
1266     if (subFocusItem) {
1267         subFocusItem->d_ptr->setSubFocus(newParent);
1268         if (parent && parent->isActive())
1269             subFocusItem->setFocus();
1270     }
1271
1272     // Deliver post-change notification
1273     if (newParentVariant)
1274         q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant);
1275
1276     if (isObject)
1277         emit static_cast<QGraphicsObject *>(q)->parentChanged();
1278 }
1279
1280 /*!
1281     \internal
1282
1283     Returns the bounding rect of this item's children (excluding itself).
1284 */
1285 void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem)
1286 {
1287     Q_Q(QGraphicsItem);
1288
1289     QRectF childrenRect;
1290     QRectF *result = rect;
1291     rect = &childrenRect;
1292     const bool setTopMostEffectItem = !topMostEffectItem;
1293
1294     for (int i = 0; i < children.size(); ++i) {
1295         QGraphicsItem *child = children.at(i);
1296         QGraphicsItemPrivate *childd = child->d_ptr.data();
1297         if (setTopMostEffectItem)
1298             topMostEffectItem = child;
1299         bool hasPos = !childd->pos.isNull();
1300         if (hasPos || childd->transformData) {
1301             // COMBINE
1302             QTransform matrix = childd->transformToParent();
1303             if (x)
1304                 matrix *= *x;
1305             *rect |= matrix.mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
1306             if (!childd->children.isEmpty())
1307                 childd->childrenBoundingRectHelper(&matrix, rect, topMostEffectItem);
1308         } else {
1309             if (x)
1310                 *rect |= x->mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
1311             else
1312                 *rect |= child->d_ptr->effectiveBoundingRect(topMostEffectItem);
1313             if (!childd->children.isEmpty())
1314                 childd->childrenBoundingRectHelper(x, rect, topMostEffectItem);
1315         }
1316     }
1317
1318     if (flags & QGraphicsItem::ItemClipsChildrenToShape){
1319         if (x)
1320             *rect &= x->mapRect(q->boundingRect());
1321         else
1322             *rect &= q->boundingRect();
1323     }
1324
1325     *result |= *rect;
1326 }
1327
1328 void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
1329                                            const QRegion &exposedRegion, bool allItems) const
1330 {
1331     Q_ASSERT(option);
1332     Q_Q(const QGraphicsItem);
1333
1334     // Initialize standard QStyleOption values.
1335     const QRectF brect = q->boundingRect();
1336     option->state = QStyle::State_None;
1337     option->rect = brect.toRect();
1338     option->levelOfDetail = 1;
1339     option->exposedRect = brect;
1340     if (selected)
1341         option->state |= QStyle::State_Selected;
1342     if (enabled)
1343         option->state |= QStyle::State_Enabled;
1344     if (q->hasFocus())
1345         option->state |= QStyle::State_HasFocus;
1346     if (scene) {
1347         if (scene->d_func()->hoverItems.contains(q_ptr))
1348             option->state |= QStyle::State_MouseOver;
1349         if (q == scene->mouseGrabberItem())
1350             option->state |= QStyle::State_Sunken;
1351     }
1352
1353     if (!(flags & QGraphicsItem::ItemUsesExtendedStyleOption))
1354         return;
1355
1356     // Initialize QStyleOptionGraphicsItem specific values (matrix, exposedRect).
1357     option->matrix = worldTransform.toAffine(); //### discards perspective
1358
1359     if (!allItems) {
1360         // Determine the item's exposed area
1361         option->exposedRect = QRectF();
1362         const QTransform reverseMap = worldTransform.inverted();
1363         const QVector<QRect> exposedRects(exposedRegion.rects());
1364         for (int i = 0; i < exposedRects.size(); ++i) {
1365             option->exposedRect |= reverseMap.mapRect(QRectF(exposedRects.at(i)));
1366             if (option->exposedRect.contains(brect))
1367                 break;
1368         }
1369         option->exposedRect &= brect;
1370     }
1371 }
1372
1373 /*!
1374     \internal
1375
1376     Empty all cached pixmaps from the pixmap cache.
1377 */
1378 void QGraphicsItemCache::purge()
1379 {
1380     QPixmapCache::remove(key);
1381     key = QPixmapCache::Key();
1382     QMutableHashIterator<QPaintDevice *, DeviceData> it(deviceData);
1383     while (it.hasNext()) {
1384         DeviceData &data = it.next().value();
1385         QPixmapCache::remove(data.key);
1386         data.cacheIndent = QPoint();
1387     }
1388     deviceData.clear();
1389     allExposed = true;
1390     exposed.clear();
1391 }
1392
1393 /*!
1394     Constructs a QGraphicsItem with the given \a parent item.
1395     It does not modify the parent object returned by QObject::parent().
1396
1397     If \a parent is 0, you can add the item to a scene by calling
1398     QGraphicsScene::addItem(). The item will then become a top-level item.
1399
1400     \sa QGraphicsScene::addItem(), setParentItem()
1401 */
1402 QGraphicsItem::QGraphicsItem(QGraphicsItem *parent
1403 #ifndef Q_QDOC
1404                              // obsolete argument
1405                              , QGraphicsScene *scene
1406 #endif
1407     )
1408     : d_ptr(new QGraphicsItemPrivate)
1409 {
1410     d_ptr->q_ptr = this;
1411     setParentItem(parent);
1412
1413     if (scene && parent && parent->scene() != scene) {
1414         qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
1415                  " different from parent's scene (%p)",
1416                  scene, parent->scene());
1417         return;
1418     }
1419     if (scene && !parent)
1420         scene->addItem(this);
1421 }
1422
1423 /*!
1424     \internal
1425 */
1426 QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent,
1427                              QGraphicsScene *scene)
1428     : d_ptr(&dd)
1429 {
1430     d_ptr->q_ptr = this;
1431     setParentItem(parent);
1432
1433     if (scene && parent && parent->scene() != scene) {
1434         qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
1435                  " different from parent's scene (%p)",
1436                  scene, parent->scene());
1437         return;
1438     }
1439     if (scene && !parent)
1440         scene->addItem(this);
1441 }
1442
1443 /*!
1444     Destroys the QGraphicsItem and all its children. If this item is currently
1445     associated with a scene, the item will be removed from the scene before it
1446     is deleted.
1447
1448     \note It is more efficient to remove the item from the QGraphicsScene before
1449     destroying the item.
1450 */
1451 QGraphicsItem::~QGraphicsItem()
1452 {
1453     if (d_ptr->isObject) {
1454         QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
1455         QObjectPrivate *p = QObjectPrivate::get(o);
1456         p->wasDeleted = true;
1457         if (p->declarativeData) {
1458             QAbstractDeclarativeData::destroyed(p->declarativeData, o);
1459             p->declarativeData = 0;
1460         }
1461     }
1462
1463     d_ptr->inDestructor = 1;
1464     d_ptr->removeExtraItemCache();
1465
1466 #ifndef QT_NO_GESTURES
1467     if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) {
1468         QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
1469         if (QGestureManager *manager = QGestureManager::instance()) {
1470             foreach (Qt::GestureType type, d_ptr->gestureContext.keys())
1471                 manager->cleanupCachedGestures(o, type);
1472         }
1473     }
1474 #endif
1475
1476     clearFocus();
1477
1478     // Update focus scope item ptr.
1479     QGraphicsItem *p = d_ptr->parent;
1480     while (p) {
1481         if (p->flags() & ItemIsFocusScope) {
1482             if (p->d_ptr->focusScopeItem == this)
1483                 p->d_ptr->focusScopeItem = 0;
1484             break;
1485         }
1486         p = p->d_ptr->parent;
1487     }
1488
1489     if (!d_ptr->children.isEmpty()) {
1490         while (!d_ptr->children.isEmpty())
1491             delete d_ptr->children.first();
1492         Q_ASSERT(d_ptr->children.isEmpty());
1493     }
1494
1495     if (d_ptr->scene) {
1496         d_ptr->scene->d_func()->removeItemHelper(this);
1497     } else {
1498         d_ptr->resetFocusProxy();
1499         setParentItem(0);
1500     }
1501
1502 #ifndef QT_NO_GRAPHICSEFFECT
1503     delete d_ptr->graphicsEffect;
1504 #endif //QT_NO_GRAPHICSEFFECT
1505     if (d_ptr->transformData) {
1506         for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) {
1507             QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i);
1508             static_cast<QGraphicsTransformPrivate *>(t->d_ptr.data())->item = 0;
1509             delete t;
1510         }
1511     }
1512     delete d_ptr->transformData;
1513
1514     if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore())
1515         dataStore->data.remove(this);
1516 }
1517
1518 /*!
1519     Returns the current scene for the item, or 0 if the item is not stored in
1520     a scene.
1521
1522     To add or move an item to a scene, call QGraphicsScene::addItem().
1523 */
1524 QGraphicsScene *QGraphicsItem::scene() const
1525 {
1526     return d_ptr->scene;
1527 }
1528
1529 /*!
1530     Returns a pointer to this item's item group, or 0 if this item is not
1531     member of a group.
1532
1533     \sa QGraphicsItemGroup, QGraphicsScene::createItemGroup()
1534 */
1535 QGraphicsItemGroup *QGraphicsItem::group() const
1536 {
1537     if (!d_ptr->isMemberOfGroup)
1538         return 0;
1539     QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
1540     while ((parent = parent->d_ptr->parent)) {
1541         if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(parent))
1542             return group;
1543     }
1544     // Unreachable; if d_ptr->isMemberOfGroup is != 0, then one parent of this
1545     // item is a group item.
1546     return 0;
1547 }
1548
1549 /*!
1550     Adds this item to the item group \a group. If \a group is 0, this item is
1551     removed from any current group and added as a child of the previous
1552     group's parent.
1553
1554     \sa group(), QGraphicsScene::createItemGroup()
1555 */
1556 void QGraphicsItem::setGroup(QGraphicsItemGroup *group)
1557 {
1558     if (!group) {
1559         if (QGraphicsItemGroup *group = this->group())
1560             group->removeFromGroup(this);
1561     } else {
1562         group->addToGroup(this);
1563     }
1564 }
1565
1566 /*!
1567     Returns a pointer to this item's parent item. If this item does not have a
1568     parent, 0 is returned.
1569
1570     \sa setParentItem(), childItems()
1571 */
1572 QGraphicsItem *QGraphicsItem::parentItem() const
1573 {
1574     return d_ptr->parent;
1575 }
1576
1577 /*!
1578     Returns this item's top-level item. The top-level item is the item's
1579     topmost ancestor item whose parent is 0. If an item has no parent, its own
1580     pointer is returned (i.e., a top-level item is its own top-level item).
1581
1582     \sa parentItem()
1583 */
1584 QGraphicsItem *QGraphicsItem::topLevelItem() const
1585 {
1586     QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
1587     while (QGraphicsItem *grandPa = parent->parentItem())
1588         parent = grandPa;
1589     return parent;
1590 }
1591
1592 /*!
1593     \since 4.6
1594
1595     Returns a pointer to the item's parent, cast to a QGraphicsObject. returns 0 if the parent item
1596     is not a QGraphicsObject.
1597
1598     \sa parentItem(), childItems()
1599 */
1600 QGraphicsObject *QGraphicsItem::parentObject() const
1601 {
1602     QGraphicsItem *p = d_ptr->parent;
1603     return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : 0;
1604 }
1605
1606 /*!
1607     \since 4.4
1608
1609     Returns a pointer to the item's parent widget. The item's parent widget is
1610     the closest parent item that is a widget.
1611
1612     \sa parentItem(), childItems()
1613 */
1614 QGraphicsWidget *QGraphicsItem::parentWidget() const
1615 {
1616     QGraphicsItem *p = parentItem();
1617     while (p && !p->isWidget())
1618         p = p->parentItem();
1619     return (p && p->isWidget()) ? static_cast<QGraphicsWidget *>(p) : 0;
1620 }
1621
1622 /*!
1623     \since 4.4
1624
1625     Returns a pointer to the item's top level widget (i.e., the item's
1626     ancestor whose parent is 0, or whose parent is not a widget), or 0 if this
1627     item does not have a top level widget. If the item is its own top level
1628     widget, this function returns a pointer to the item itself.
1629 */
1630 QGraphicsWidget *QGraphicsItem::topLevelWidget() const
1631 {
1632     if (const QGraphicsWidget *p = parentWidget())
1633         return p->topLevelWidget();
1634     return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : 0;
1635 }
1636
1637 /*!
1638     \since 4.4
1639
1640     Returns the item's window, or 0 if this item does not have a window. If
1641     the item is a window, it will return itself.  Otherwise it will return the
1642     closest ancestor that is a window.
1643
1644     \sa QGraphicsWidget::isWindow()
1645 */
1646 QGraphicsWidget *QGraphicsItem::window() const
1647 {
1648     QGraphicsItem *p = panel();
1649     if (p && p->isWindow())
1650         return static_cast<QGraphicsWidget *>(p);
1651     return 0;
1652 }
1653
1654 /*!
1655     \since 4.6
1656
1657     Returns the item's panel, or 0 if this item does not have a panel. If the
1658     item is a panel, it will return itself. Otherwise it will return the
1659     closest ancestor that is a panel.
1660
1661     \sa isPanel(), ItemIsPanel
1662 */
1663 QGraphicsItem *QGraphicsItem::panel() const
1664 {
1665     if (d_ptr->flags & ItemIsPanel)
1666         return const_cast<QGraphicsItem *>(this);
1667     return d_ptr->parent ? d_ptr->parent->panel() : 0;
1668 }
1669
1670 /*!
1671   \since 4.6
1672
1673   Return the graphics item cast to a QGraphicsObject, if the class is actually a
1674   graphics object, 0 otherwise.
1675 */
1676 QGraphicsObject *QGraphicsItem::toGraphicsObject()
1677 {
1678     return d_ptr->isObject ? static_cast<QGraphicsObject *>(this) : 0;
1679 }
1680
1681 /*!
1682   \since 4.6
1683
1684   Return the graphics item cast to a QGraphicsObject, if the class is actually a
1685   graphics object, 0 otherwise.
1686 */
1687 const QGraphicsObject *QGraphicsItem::toGraphicsObject() const
1688 {
1689     return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0;
1690 }
1691
1692 /*!
1693   Sets this item's parent item to \a newParent. If this item already
1694   has a parent, it is first removed from the previous parent. If \a
1695   newParent is 0, this item will become a top-level item.
1696
1697   Note that this implicitly adds this graphics item to the scene of
1698   the parent. You should not \l{QGraphicsScene::addItem()}{add} the
1699   item to the scene yourself.
1700
1701   Calling this function on an item that is an ancestor of \a newParent
1702   have undefined behaviour.
1703
1704   \sa parentItem(), childItems()
1705 */
1706 void QGraphicsItem::setParentItem(QGraphicsItem *newParent)
1707 {
1708     if (newParent == this) {
1709         qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
1710         return;
1711     }
1712     if (newParent == d_ptr->parent)
1713         return;
1714
1715     const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange,
1716                                                QVariant::fromValue<QGraphicsItem *>(newParent)));
1717     newParent = qvariant_cast<QGraphicsItem *>(newParentVariant);
1718     if (newParent == d_ptr->parent)
1719         return;
1720
1721     const QVariant thisPointerVariant(QVariant::fromValue<QGraphicsItem *>(this));
1722     d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant);
1723 }
1724
1725 /*!
1726     \obsolete
1727
1728     Use childItems() instead.
1729
1730     \sa setParentItem()
1731 */
1732 QList<QGraphicsItem *> QGraphicsItem::children() const
1733 {
1734     return childItems();
1735 }
1736
1737 /*!
1738     \since 4.4
1739
1740     Returns a list of this item's children.
1741
1742     The items are sorted by stacking order. This takes into account both the
1743     items' insertion order and their Z-values.
1744
1745     \sa setParentItem(), zValue(), {QGraphicsItem#Sorting}{Sorting}
1746 */
1747 QList<QGraphicsItem *> QGraphicsItem::childItems() const
1748 {
1749     const_cast<QGraphicsItem *>(this)->d_ptr->ensureSortedChildren();
1750     return d_ptr->children;
1751 }
1752
1753 /*!
1754     \since 4.4
1755     Returns true if this item is a widget (i.e., QGraphicsWidget); otherwise,
1756     returns false.
1757 */
1758 bool QGraphicsItem::isWidget() const
1759 {
1760     return d_ptr->isWidget;
1761 }
1762
1763 /*!
1764     \since 4.4
1765     Returns true if the item is a QGraphicsWidget window, otherwise returns
1766     false.
1767
1768     \sa QGraphicsWidget::windowFlags()
1769 */
1770 bool QGraphicsItem::isWindow() const
1771 {
1772     return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
1773 }
1774
1775 /*!
1776     \since 4.6
1777     Returns true if the item is a panel; otherwise returns false.
1778
1779     \sa QGraphicsItem::panel(), ItemIsPanel
1780 */
1781 bool QGraphicsItem::isPanel() const
1782 {
1783     return d_ptr->flags & ItemIsPanel;
1784 }
1785
1786 /*!
1787     Returns this item's flags. The flags describe what configurable features
1788     of the item are enabled and not. For example, if the flags include
1789     ItemIsFocusable, the item can accept input focus.
1790
1791     By default, no flags are enabled.
1792
1793     \sa setFlags(), setFlag()
1794 */
1795 QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const
1796 {
1797     return GraphicsItemFlags(d_ptr->flags);
1798 }
1799
1800 /*!
1801     If \a enabled is true, the item flag \a flag is enabled; otherwise, it is
1802     disabled.
1803
1804     \sa flags(), setFlags()
1805 */
1806 void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled)
1807 {
1808     if (enabled)
1809         setFlags(GraphicsItemFlags(d_ptr->flags) | flag);
1810     else
1811         setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag);
1812 }
1813
1814 /*!
1815     \internal
1816
1817     Sets the flag \a flag on \a item and all its children, to \a enabled.
1818 */
1819 static void _q_qgraphicsItemSetFlag(QGraphicsItem *item, QGraphicsItem::GraphicsItemFlag flag,
1820                                     bool enabled)
1821 {
1822     if (item->flags() & flag) {
1823         // If this item already has the correct flag set, we don't have to
1824         // propagate it.
1825         return;
1826     }
1827     item->setFlag(flag, enabled);
1828     foreach (QGraphicsItem *child, item->children())
1829         _q_qgraphicsItemSetFlag(child, flag, enabled);
1830 }
1831
1832 /*!
1833     Sets the item flags to \a flags. All flags in \a flags are enabled; all
1834     flags not in \a flags are disabled.
1835
1836     If the item had focus and \a flags does not enable ItemIsFocusable, the
1837     item loses focus as a result of calling this function. Similarly, if the
1838     item was selected, and \a flags does not enabled ItemIsSelectable, the
1839     item is automatically unselected.
1840
1841     By default, no flags are enabled. (QGraphicsWidget enables the
1842     ItemSendsGeometryChanges flag by default in order to track position
1843     changes.)
1844
1845     \sa flags(), setFlag()
1846 */
1847 void QGraphicsItem::setFlags(GraphicsItemFlags flags)
1848 {
1849     // Notify change and check for adjustment.
1850     if (quint32(d_ptr->flags) == quint32(flags))
1851         return;
1852     flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
1853     if (quint32(d_ptr->flags) == quint32(flags))
1854         return;
1855     if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
1856         d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags);
1857
1858     // Flags that alter the geometry of the item (or its children).
1859     const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
1860     bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
1861     if (fullUpdate)
1862         d_ptr->updatePaintedViewBoundingRects(/*children=*/true);
1863
1864     // Keep the old flags to compare the diff.
1865     GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
1866
1867     // Update flags.
1868     d_ptr->flags = flags;
1869
1870     if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
1871         // Clear focus on the item if it has focus when the focusable flag
1872         // is unset.
1873         clearFocus();
1874     }
1875
1876     if (!(d_ptr->flags & ItemIsSelectable) && isSelected()) {
1877         // Unselect the item if it is selected when the selectable flag is
1878         // unset.
1879         setSelected(false);
1880     }
1881
1882     if ((flags & ItemClipsChildrenToShape) != (oldFlags & ItemClipsChildrenToShape)) {
1883         // Item children clipping changes. Propagate the ancestor flag to
1884         // all children.
1885         d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
1886         // The childrenBoundingRect is clipped to the boundingRect in case of ItemClipsChildrenToShape,
1887         // which means we have to invalidate the cached childrenBoundingRect whenever this flag changes.
1888         d_ptr->dirtyChildrenBoundingRect = 1;
1889         d_ptr->markParentDirty(true);
1890     }
1891
1892     if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
1893         // Item children clipping changes. Propagate the ancestor flag to
1894         // all children.
1895         d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
1896     }
1897
1898     if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
1899         // NB! We change the flags directly here, so we must also update d_ptr->flags.
1900         // Note that this has do be done before the ItemStacksBehindParent check
1901         // below; otherwise we will loose the change.
1902
1903         // Update stack-behind.
1904         if (d_ptr->z < qreal(0.0))
1905             flags |= ItemStacksBehindParent;
1906         else
1907             flags &= ~ItemStacksBehindParent;
1908         d_ptr->flags = flags;
1909     }
1910
1911     if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
1912         // NB! This check has to come after the ItemNegativeZStacksBehindParent
1913         // check above. Be careful.
1914
1915         // Ensure child item sorting is up to date when toggling this flag.
1916         if (d_ptr->parent)
1917             d_ptr->parent->d_ptr->needSortChildren = 1;
1918         else if (d_ptr->scene)
1919             d_ptr->scene->d_func()->needSortTopLevelItems = 1;
1920     }
1921
1922     if ((flags & ItemAcceptsInputMethod) != (oldFlags & ItemAcceptsInputMethod)) {
1923         // Update input method sensitivity in any views.
1924         if (d_ptr->scene)
1925             d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
1926     }
1927
1928
1929     if ((d_ptr->panelModality != NonModal)
1930         && d_ptr->scene
1931         && (flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
1932         // update the panel's modal state
1933         if (flags & ItemIsPanel)
1934             d_ptr->scene->d_func()->enterModal(this);
1935         else
1936             d_ptr->scene->d_func()->leaveModal(this);
1937     }
1938
1939     if (d_ptr->scene) {
1940         if ((flags & ItemSendsScenePositionChanges) != (oldFlags & ItemSendsScenePositionChanges)) {
1941             if (flags & ItemSendsScenePositionChanges)
1942                 d_ptr->scene->d_func()->registerScenePosItem(this);
1943             else
1944                 d_ptr->scene->d_func()->unregisterScenePosItem(this);
1945         }
1946         d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
1947     }
1948
1949     // Notify change.
1950     itemChange(ItemFlagsHaveChanged, quint32(flags));
1951 }
1952
1953 /*!
1954     \since 4.4
1955     Returns the cache mode for this item. The default mode is NoCache (i.e.,
1956     cache is disabled and all painting is immediate).
1957
1958     \sa setCacheMode()
1959 */
1960 QGraphicsItem::CacheMode QGraphicsItem::cacheMode() const
1961 {
1962     return QGraphicsItem::CacheMode(d_ptr->cacheMode);
1963 }
1964
1965 /*!
1966     \since 4.4
1967     Sets the item's cache mode to \a mode.
1968
1969     The optional \a logicalCacheSize argument is used only by
1970     ItemCoordinateCache mode, and describes the resolution of the cache
1971     buffer; if \a logicalCacheSize is (100, 100), QGraphicsItem will fit the
1972     item into 100x100 pixels in graphics memory, regardless of the logical
1973     size of the item itself. By default QGraphicsItem uses the size of
1974     boundingRect(). For all other cache modes than ItemCoordinateCache, \a
1975     logicalCacheSize is ignored.
1976
1977     Caching can speed up rendering if your item spends a significant time
1978     redrawing itself. In some cases the cache can also slow down rendering, in
1979     particular when the item spends less time redrawing than QGraphicsItem
1980     spends redrawing from the cache. When enabled, the item's paint() function
1981     will be called only once for each call to update(); for any subsequent
1982     repaint requests, the Graphics View framework will redraw from the
1983     cache. This approach works particularly well with QGLWidget, which stores
1984     all the cache as OpenGL textures.
1985
1986     Be aware that QPixmapCache's cache limit may need to be changed to obtain
1987     optimal performance.
1988
1989     You can read more about the different cache modes in the CacheMode
1990     documentation.
1991
1992     \sa CacheMode, QPixmapCache::setCacheLimit()
1993 */
1994 void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize)
1995 {
1996     CacheMode lastMode = CacheMode(d_ptr->cacheMode);
1997     d_ptr->cacheMode = mode;
1998     bool noVisualChange = (mode == NoCache && lastMode == NoCache)
1999                           || (mode == NoCache && lastMode == DeviceCoordinateCache)
2000                           || (mode == DeviceCoordinateCache && lastMode == NoCache)
2001                           || (mode == DeviceCoordinateCache && lastMode == DeviceCoordinateCache);
2002     if (mode == NoCache) {
2003         d_ptr->removeExtraItemCache();
2004     } else {
2005         QGraphicsItemCache *cache = d_ptr->extraItemCache();
2006
2007         // Reset old cache
2008         cache->purge();
2009
2010         if (mode == ItemCoordinateCache) {
2011             if (lastMode == mode && cache->fixedSize == logicalCacheSize)
2012                 noVisualChange = true;
2013             cache->fixedSize = logicalCacheSize;
2014         }
2015     }
2016     if (!noVisualChange)
2017         update();
2018 }
2019
2020 /*!
2021     \since 4.6
2022
2023     Returns the modality for this item.
2024 */
2025 QGraphicsItem::PanelModality QGraphicsItem::panelModality() const
2026 {
2027     return d_ptr->panelModality;
2028 }
2029
2030 /*!
2031     \since 4.6
2032
2033     Sets the modality for this item to \a panelModality.
2034
2035     Changing the modality of a visible item takes effect immediately.
2036 */
2037 void QGraphicsItem::setPanelModality(PanelModality panelModality)
2038 {
2039     if (d_ptr->panelModality == panelModality)
2040         return;
2041
2042     PanelModality previousModality = d_ptr->panelModality;
2043     bool enterLeaveModal = (isPanel() && d_ptr->scene && isVisible());
2044     if (enterLeaveModal && panelModality == NonModal)
2045         d_ptr->scene->d_func()->leaveModal(this);
2046     d_ptr->panelModality = panelModality;
2047     if (enterLeaveModal && d_ptr->panelModality != NonModal)
2048         d_ptr->scene->d_func()->enterModal(this, previousModality);
2049 }
2050
2051 /*!
2052     \since 4.6
2053
2054     Returns true if this item is blocked by a modal panel, false otherwise. If \a blockingPanel is
2055     non-zero, \a blockingPanel will be set to the modal panel that is blocking this item. If this
2056     item is not blocked, \a blockingPanel will not be set by this function.
2057
2058     This function always returns false for items not in a scene.
2059
2060     \sa panelModality(), setPanelModality(), PanelModality
2061 */
2062 bool QGraphicsItem::isBlockedByModalPanel(QGraphicsItem **blockingPanel) const
2063 {
2064     if (!d_ptr->scene)
2065         return false;
2066
2067
2068     QGraphicsItem *dummy = 0;
2069     if (!blockingPanel)
2070         blockingPanel = &dummy;
2071
2072     QGraphicsScenePrivate *scene_d = d_ptr->scene->d_func();
2073     if (scene_d->modalPanels.isEmpty())
2074         return false;
2075
2076     // ###
2077     if (!scene_d->popupWidgets.isEmpty() && scene_d->popupWidgets.first() == this)
2078         return false;
2079
2080     for (int i = 0; i < scene_d->modalPanels.count(); ++i) {
2081         QGraphicsItem *modalPanel = scene_d->modalPanels.at(i);
2082         if (modalPanel->panelModality() == QGraphicsItem::SceneModal) {
2083             // Scene modal panels block all non-descendents.
2084             if (modalPanel != this && !modalPanel->isAncestorOf(this)) {
2085                 *blockingPanel = modalPanel;
2086                 return true;
2087             }
2088         } else {
2089             // Window modal panels block ancestors and siblings/cousins.
2090             if (modalPanel != this
2091                 && !modalPanel->isAncestorOf(this)
2092                 && commonAncestorItem(modalPanel)) {
2093                 *blockingPanel = modalPanel;
2094                 return true;
2095             }
2096         }
2097     }
2098     return false;
2099 }
2100
2101 #ifndef QT_NO_TOOLTIP
2102 /*!
2103     Returns the item's tool tip, or an empty QString if no tool tip has been
2104     set.
2105
2106     \sa setToolTip(), QToolTip
2107 */
2108 QString QGraphicsItem::toolTip() const
2109 {
2110     return d_ptr->extra(QGraphicsItemPrivate::ExtraToolTip).toString();
2111 }
2112
2113 /*!
2114     Sets the item's tool tip to \a toolTip. If \a toolTip is empty, the item's
2115     tool tip is cleared.
2116
2117     \sa toolTip(), QToolTip
2118 */
2119 void QGraphicsItem::setToolTip(const QString &toolTip)
2120 {
2121     const QVariant toolTipVariant(itemChange(ItemToolTipChange, toolTip));
2122     d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTipVariant.toString());
2123     itemChange(ItemToolTipHasChanged, toolTipVariant);
2124 }
2125 #endif // QT_NO_TOOLTIP
2126
2127 #ifndef QT_NO_CURSOR
2128 /*!
2129     Returns the current cursor shape for the item. The mouse cursor
2130     will assume this shape when it's over this item. See the \link
2131     Qt::CursorShape list of predefined cursor objects\endlink for a
2132     range of useful shapes.
2133
2134     An editor item might want to use an I-beam cursor:
2135
2136     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 2
2137
2138     If no cursor has been set, the cursor of the item beneath is used.
2139
2140     \sa setCursor(), hasCursor(), unsetCursor(), QWidget::cursor,
2141     QApplication::overrideCursor()
2142 */
2143 QCursor QGraphicsItem::cursor() const
2144 {
2145     return qvariant_cast<QCursor>(d_ptr->extra(QGraphicsItemPrivate::ExtraCursor));
2146 }
2147
2148 /*!
2149     Sets the current cursor shape for the item to \a cursor. The mouse cursor
2150     will assume this shape when it's over this item. See the \link
2151     Qt::CursorShape list of predefined cursor objects\endlink for a range of
2152     useful shapes.
2153
2154     An editor item might want to use an I-beam cursor:
2155
2156     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 3
2157
2158     If no cursor has been set, the cursor of the item beneath is used.
2159
2160     \sa cursor(), hasCursor(), unsetCursor(), QWidget::cursor,
2161     QApplication::overrideCursor()
2162 */
2163 void QGraphicsItem::setCursor(const QCursor &cursor)
2164 {
2165     const QVariant cursorVariant(itemChange(ItemCursorChange, QVariant::fromValue<QCursor>(cursor)));
2166     d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qvariant_cast<QCursor>(cursorVariant));
2167     d_ptr->hasCursor = 1;
2168     if (d_ptr->scene) {
2169         d_ptr->scene->d_func()->allItemsUseDefaultCursor = false;
2170         foreach (QGraphicsView *view, d_ptr->scene->views()) {
2171             view->viewport()->setMouseTracking(true);
2172             // Note: Some of this logic is duplicated in QGraphicsView's mouse events.
2173             if (view->underMouse()) {
2174                 foreach (QGraphicsItem *itemUnderCursor, view->items(view->mapFromGlobal(QCursor::pos()))) {
2175                     if (itemUnderCursor->hasCursor()) {
2176                         QMetaObject::invokeMethod(view, "_q_setViewportCursor",
2177                                                   Q_ARG(QCursor, itemUnderCursor->cursor()));
2178                         break;
2179                     }
2180                 }
2181                 break;
2182             }
2183         }
2184     }
2185     itemChange(ItemCursorHasChanged, cursorVariant);
2186 }
2187
2188 /*!
2189     Returns true if this item has a cursor set; otherwise, false is returned.
2190
2191     By default, items don't have any cursor set. cursor() will return a
2192     standard pointing arrow cursor.
2193
2194     \sa unsetCursor()
2195 */
2196 bool QGraphicsItem::hasCursor() const
2197 {
2198     return d_ptr->hasCursor;
2199 }
2200
2201 /*!
2202     Clears the cursor from this item.
2203
2204     \sa hasCursor(), setCursor()
2205 */
2206 void QGraphicsItem::unsetCursor()
2207 {
2208     d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraCursor);
2209     d_ptr->hasCursor = 0;
2210     if (d_ptr->scene) {
2211         foreach (QGraphicsView *view, d_ptr->scene->views()) {
2212             if (view->underMouse() && view->itemAt(view->mapFromGlobal(QCursor::pos())) == this) {
2213                 QMetaObject::invokeMethod(view, "_q_unsetViewportCursor");
2214                 break;
2215             }
2216         }
2217     }
2218 }
2219
2220 #endif // QT_NO_CURSOR
2221
2222 /*!
2223    Returns true if the item is visible; otherwise, false is returned.
2224
2225    Note that the item's general visibility is unrelated to whether or not it
2226    is actually being visualized by a QGraphicsView.
2227
2228    \sa setVisible()
2229 */
2230 bool QGraphicsItem::isVisible() const
2231 {
2232     return d_ptr->visible;
2233 }
2234
2235 /*!
2236     \since 4.4
2237     Returns true if the item is visible to \a parent; otherwise, false is
2238     returned. \a parent can be 0, in which case this function will return
2239     whether the item is visible to the scene or not.
2240
2241     An item may not be visible to its ancestors even if isVisible() is true. It
2242     may also be visible to its ancestors even if isVisible() is false. If
2243     any ancestor is hidden, the item itself will be implicitly hidden, in which
2244     case this function will return false.
2245
2246     \sa isVisible(), setVisible()
2247 */
2248 bool QGraphicsItem::isVisibleTo(const QGraphicsItem *parent) const
2249 {
2250     const QGraphicsItem *p = this;
2251     if (d_ptr->explicitlyHidden)
2252         return false;
2253     do {
2254         if (p == parent)
2255             return true;
2256         if (p->d_ptr->explicitlyHidden)
2257             return false;
2258     } while ((p = p->d_ptr->parent));
2259     return parent == 0;
2260 }
2261
2262 /*!
2263     \internal
2264
2265     Sets this item's visibility to \a newVisible. If \a explicitly is true,
2266     this item will be "explicitly" \a newVisible; otherwise, it.. will not be.
2267 */
2268 void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bool update)
2269 {
2270     Q_Q(QGraphicsItem);
2271
2272     // Update explicit bit.
2273     if (explicitly)
2274         explicitlyHidden = newVisible ? 0 : 1;
2275
2276     // Check if there's nothing to do.
2277     if (visible == quint32(newVisible))
2278         return;
2279
2280     // Don't show child if parent is not visible
2281     if (parent && newVisible && !parent->d_ptr->visible)
2282         return;
2283
2284     // Modify the property.
2285     const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange,
2286                                                        quint32(newVisible)));
2287     newVisible = newVisibleVariant.toBool();
2288     if (visible == quint32(newVisible))
2289         return;
2290     visible = newVisible;
2291
2292     // Schedule redrawing
2293     if (update) {
2294         QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
2295         if (c)
2296             c->purge();
2297         if (scene) {
2298 #ifndef QT_NO_GRAPHICSEFFECT
2299             invalidateParentGraphicsEffectsRecursively();
2300 #endif //QT_NO_GRAPHICSEFFECT
2301             scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
2302         }
2303     }
2304
2305     // Certain properties are dropped as an item becomes invisible.
2306     bool hasFocus = q_ptr->hasFocus();
2307     if (!newVisible) {
2308         if (scene) {
2309             if (scene->d_func()->mouseGrabberItems.contains(q))
2310                 q->ungrabMouse();
2311             if (scene->d_func()->keyboardGrabberItems.contains(q))
2312                 q->ungrabKeyboard();
2313             if (q->isPanel() && panelModality != QGraphicsItem::NonModal)
2314                 scene->d_func()->leaveModal(q_ptr);
2315         }
2316         if (hasFocus && scene) {
2317             // Hiding the closest non-panel ancestor of the focus item
2318             QGraphicsItem *focusItem = scene->focusItem();
2319             bool clear = true;
2320             if (isWidget && !focusItem->isPanel()) {
2321                 do {
2322                     if (focusItem == q_ptr) {
2323                         clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
2324                         break;
2325                     }
2326                 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
2327             }
2328             if (clear)
2329                 clearFocusHelper(/* giveFocusToParent = */ false);
2330         }
2331         if (q_ptr->isSelected())
2332             q_ptr->setSelected(false);
2333     } else {
2334         geometryChanged = 1;
2335         paintedViewBoundingRectsNeedRepaint = 1;
2336         if (scene) {
2337             if (isWidget) {
2338                 QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
2339                 if (widget->windowType() == Qt::Popup)
2340                     scene->d_func()->addPopup(widget);
2341             }
2342             if (q->isPanel() && panelModality != QGraphicsItem::NonModal) {
2343                 scene->d_func()->enterModal(q_ptr);
2344             }
2345         }
2346     }
2347
2348     // Update children with explicitly = false.
2349     const bool updateChildren = update && !(flags & QGraphicsItem::ItemClipsChildrenToShape);
2350     foreach (QGraphicsItem *child, children) {
2351         if (!newVisible || !child->d_ptr->explicitlyHidden)
2352             child->d_ptr->setVisibleHelper(newVisible, false, updateChildren);
2353     }
2354
2355     // Update activation
2356     if (scene && q->isPanel()) {
2357         if (newVisible) {
2358             if (parent && parent->isActive())
2359                 q->setActive(true);
2360         } else {
2361             if (q->isActive())
2362                 scene->setActivePanel(parent);
2363         }
2364     }
2365
2366     // Enable subfocus
2367     if (scene) {
2368         if (newVisible) {
2369             // Item is shown
2370             QGraphicsItem *p = parent;
2371             bool done = false;
2372             while (p) {
2373                 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
2374                     QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
2375                     if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
2376                         done = true;
2377                         while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
2378                             fsi = fsi->d_ptr->focusScopeItem;
2379                         fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
2380                                                    /* focusFromHide = */ false);
2381                     }
2382                     break;
2383                 }
2384                 p = p->d_ptr->parent;
2385             }
2386             if (!done) {
2387                 QGraphicsItem *fi = subFocusItem;
2388                 if (fi && fi != scene->focusItem()) {
2389                     scene->setFocusItem(fi);
2390                 } else if (flags & QGraphicsItem::ItemIsFocusScope &&
2391                            !scene->focusItem() &&
2392                            q->isAncestorOf(scene->d_func()->lastFocusItem)) {
2393                     q_ptr->setFocus();
2394                 }
2395             }
2396         } else {
2397             // Item is hidden
2398             if (hasFocus) {
2399                 QGraphicsItem *p = parent;
2400                 while (p) {
2401                     if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
2402                         if (p->d_ptr->visible) {
2403                             p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
2404                                                      /* focusFromHide = */ true);
2405                         }
2406                         break;
2407                     }
2408                     p = p->d_ptr->parent;
2409                 }
2410             }
2411         }
2412     }
2413
2414     // Deliver post-change notification.
2415     q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, newVisibleVariant);
2416
2417     if (isObject)
2418         emit static_cast<QGraphicsObject *>(q_ptr)->visibleChanged();
2419 }
2420
2421 /*!
2422     If \a visible is true, the item is made visible. Otherwise, the item is
2423     made invisible. Invisible items are not painted, nor do they receive any
2424     events. In particular, mouse events pass right through invisible items,
2425     and are delivered to any item that may be behind. Invisible items are also
2426     unselectable, they cannot take input focus, and are not detected by
2427     QGraphicsScene's item location functions.
2428
2429     If an item becomes invisible while grabbing the mouse, (i.e., while it is
2430     receiving mouse events,) it will automatically lose the mouse grab, and
2431     the grab is not regained by making the item visible again; it must receive
2432     a new mouse press to regain the mouse grab.
2433
2434     Similarly, an invisible item cannot have focus, so if the item has focus
2435     when it becomes invisible, it will lose focus, and the focus is not
2436     regained by simply making the item visible again.
2437
2438     If you hide a parent item, all its children will also be hidden. If you
2439     show a parent item, all children will be shown, unless they have been
2440     explicitly hidden (i.e., if you call setVisible(false) on a child, it will
2441     not be reshown even if its parent is hidden, and then shown again).
2442
2443     Items are visible by default; it is unnecessary to call
2444     setVisible() on a new item.
2445
2446     \sa isVisible(), show(), hide()
2447 */
2448 void QGraphicsItem::setVisible(bool visible)
2449 {
2450     d_ptr->setVisibleHelper(visible, /* explicit = */ true);
2451 }
2452
2453 /*!
2454     \fn void QGraphicsItem::hide()
2455
2456     Hides the item. (Items are visible by default.)
2457
2458     This convenience function is equivalent to calling \c setVisible(false).
2459
2460     \sa show(), setVisible()
2461 */
2462
2463 /*!
2464     \fn void QGraphicsItem::show()
2465
2466     Shows the item. (Items are visible by default.)
2467
2468     This convenience function is equivalent to calling \c setVisible(true).
2469
2470     \sa hide(), setVisible()
2471 */
2472
2473 /*!
2474     Returns true if the item is enabled; otherwise, false is returned.
2475
2476     \sa setEnabled()
2477 */
2478 bool QGraphicsItem::isEnabled() const
2479 {
2480     return d_ptr->enabled;
2481 }
2482
2483 /*!
2484     \internal
2485
2486     Sets this item's visibility to \a newEnabled. If \a explicitly is true,
2487     this item will be "explicitly" \a newEnabled; otherwise, it.. will not be.
2488 */
2489 void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bool update)
2490 {
2491     // Update explicit bit.
2492     if (explicitly)
2493         explicitlyDisabled = newEnabled ? 0 : 1;
2494
2495     // Check if there's nothing to do.
2496     if (enabled == quint32(newEnabled))
2497         return;
2498
2499     // Certain properties are dropped when an item is disabled.
2500     if (!newEnabled) {
2501         if (scene && scene->mouseGrabberItem() == q_ptr)
2502             q_ptr->ungrabMouse();
2503         if (q_ptr->hasFocus()) {
2504             // Disabling the closest non-panel ancestor of the focus item
2505             // causes focus to pop to the next item, otherwise it's cleared.
2506             QGraphicsItem *focusItem = scene->focusItem();
2507             bool clear = true;
2508             if (isWidget && !focusItem->isPanel() && q_ptr->isAncestorOf(focusItem)) {
2509                 do {
2510                     if (focusItem == q_ptr) {
2511                         clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
2512                         break;
2513                     }
2514                 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
2515             }
2516             if (clear)
2517                 q_ptr->clearFocus();
2518         }
2519         if (q_ptr->isSelected())
2520             q_ptr->setSelected(false);
2521     }
2522
2523     // Modify the property.
2524     const QVariant newEnabledVariant(q_ptr->itemChange(QGraphicsItem::ItemEnabledChange,
2525                                                        quint32(newEnabled)));
2526     enabled = newEnabledVariant.toBool();
2527
2528     // Schedule redraw.
2529     if (update)
2530         q_ptr->update();
2531
2532     foreach (QGraphicsItem *child, children) {
2533         if (!newEnabled || !child->d_ptr->explicitlyDisabled)
2534             child->d_ptr->setEnabledHelper(newEnabled, /* explicitly = */ false);
2535     }
2536
2537     // Deliver post-change notification.
2538     q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, newEnabledVariant);
2539
2540     if (isObject)
2541         emit static_cast<QGraphicsObject *>(q_ptr)->enabledChanged();
2542 }
2543
2544 /*!
2545     If \a enabled is true, the item is enabled; otherwise, it is disabled.
2546
2547     Disabled items are visible, but they do not receive any events, and cannot
2548     take focus nor be selected. Mouse events are discarded; they are not
2549     propagated unless the item is also invisible, or if it does not accept
2550     mouse events (see acceptedMouseButtons()). A disabled item cannot become the
2551     mouse grabber, and as a result of this, an item loses the grab if it
2552     becomes disabled when grabbing the mouse, just like it loses focus if it
2553     had focus when it was disabled.
2554
2555     Disabled items are traditionally drawn using grayed-out colors (see \l
2556     QPalette::Disabled).
2557
2558     If you disable a parent item, all its children will also be disabled. If
2559     you enable a parent item, all children will be enabled, unless they have
2560     been explicitly disabled (i.e., if you call setEnabled(false) on a child,
2561     it will not be reenabled if its parent is disabled, and then enabled
2562     again).
2563
2564     Items are enabled by default.
2565
2566     \note If you install an event filter, you can still intercept events
2567     before they are delivered to items; this mechanism disregards the item's
2568     enabled state.
2569
2570     \sa isEnabled()
2571 */
2572 void QGraphicsItem::setEnabled(bool enabled)
2573 {
2574     d_ptr->setEnabledHelper(enabled, /* explicitly = */ true);
2575 }
2576
2577 /*!
2578     Returns true if this item is selected; otherwise, false is returned.
2579
2580     Items that are in a group inherit the group's selected state.
2581
2582     Items are not selected by default.
2583
2584     \sa setSelected(), QGraphicsScene::setSelectionArea()
2585 */
2586 bool QGraphicsItem::isSelected() const
2587 {
2588     if (QGraphicsItemGroup *group = this->group())
2589         return group->isSelected();
2590     return d_ptr->selected;
2591 }
2592
2593 /*!
2594     If \a selected is true and this item is selectable, this item is selected;
2595     otherwise, it is unselected.
2596
2597     If the item is in a group, the whole group's selected state is toggled by
2598     this function. If the group is selected, all items in the group are also
2599     selected, and if the group is not selected, no item in the group is
2600     selected.
2601
2602     Only visible, enabled, selectable items can be selected.  If \a selected
2603     is true and this item is either invisible or disabled or unselectable,
2604     this function does nothing.
2605
2606     By default, items cannot be selected. To enable selection, set the
2607     ItemIsSelectable flag.
2608
2609     This function is provided for convenience, allowing individual toggling of
2610     the selected state of an item. However, a more common way of selecting
2611     items is to call QGraphicsScene::setSelectionArea(), which will call this
2612     function for all visible, enabled, and selectable items within a specified
2613     area on the scene.
2614
2615     \sa isSelected(), QGraphicsScene::selectedItems()
2616 */
2617 void QGraphicsItem::setSelected(bool selected)
2618 {
2619     if (QGraphicsItemGroup *group = this->group()) {
2620         group->setSelected(selected);
2621         return;
2622     }
2623
2624     if (!(d_ptr->flags & ItemIsSelectable) || !d_ptr->enabled || !d_ptr->visible)
2625         selected = false;
2626     if (d_ptr->selected == selected)
2627         return;
2628     const QVariant newSelectedVariant(itemChange(ItemSelectedChange, quint32(selected)));
2629     bool newSelected = newSelectedVariant.toBool();
2630     if (d_ptr->selected == newSelected)
2631         return;
2632     d_ptr->selected = newSelected;
2633
2634     update();
2635     if (d_ptr->scene) {
2636         QGraphicsScenePrivate *sceneD = d_ptr->scene->d_func();
2637         if (selected) {
2638             sceneD->selectedItems << this;
2639         } else {
2640             // QGraphicsScene::selectedItems() lazily pulls out all items that are
2641             // no longer selected.
2642         }
2643         if (!sceneD->selectionChanging)
2644             emit d_ptr->scene->selectionChanged();
2645     }
2646
2647     // Deliver post-change notification.
2648     itemChange(QGraphicsItem::ItemSelectedHasChanged, newSelectedVariant);
2649 }
2650
2651 /*!
2652     \since 4.5
2653
2654     Returns this item's local opacity, which is between 0.0 (transparent) and
2655     1.0 (opaque). This value is combined with parent and ancestor values into
2656     the effectiveOpacity(). The effective opacity decides how the item is
2657     rendered.
2658
2659     The opacity property decides the state of the painter passed to the
2660     paint() function. If the item is cached, i.e., ItemCoordinateCache or
2661     DeviceCoordinateCache, the effective property will be applied to the item's
2662     cache as it is rendered.
2663
2664     The default opacity is 1.0; fully opaque.
2665
2666     \sa setOpacity(), paint(), ItemIgnoresParentOpacity,
2667     ItemDoesntPropagateOpacityToChildren
2668 */
2669 qreal QGraphicsItem::opacity() const
2670 {
2671     return d_ptr->opacity;
2672 }
2673
2674 /*!
2675     \since 4.5
2676
2677     Returns this item's \e effective opacity, which is between 0.0
2678     (transparent) and 1.0 (opaque). This value is a combination of this item's
2679     local opacity, and its parent and ancestors' opacities. The effective
2680     opacity decides how the item is rendered.
2681
2682     \sa opacity(), setOpacity(), paint(), ItemIgnoresParentOpacity,
2683     ItemDoesntPropagateOpacityToChildren
2684 */
2685 qreal QGraphicsItem::effectiveOpacity() const
2686 {
2687     return d_ptr->effectiveOpacity();
2688 }
2689
2690 /*!
2691     \since 4.5
2692
2693     Sets this item's local \a opacity, between 0.0 (transparent) and 1.0
2694     (opaque). The item's local opacity is combined with parent and ancestor
2695     opacities into the effectiveOpacity().
2696
2697     By default, opacity propagates from parent to child, so if a parent's
2698     opacity is 0.5 and the child is also 0.5, the child's effective opacity
2699     will be 0.25.
2700
2701     The opacity property decides the state of the painter passed to the
2702     paint() function. If the item is cached, i.e., ItemCoordinateCache or
2703     DeviceCoordinateCache, the effective property will be applied to the
2704     item's cache as it is rendered.
2705
2706     There are two item flags that affect how the item's opacity is combined
2707     with the parent: ItemIgnoresParentOpacity and
2708     ItemDoesntPropagateOpacityToChildren.
2709
2710     \sa opacity(), effectiveOpacity()
2711 */
2712 void QGraphicsItem::setOpacity(qreal opacity)
2713 {
2714     // Notify change.
2715     const QVariant newOpacityVariant(itemChange(ItemOpacityChange, opacity));
2716
2717     // Normalized opacity
2718     qreal newOpacity = qBound(qreal(0), newOpacityVariant.toReal(), qreal(1));
2719
2720     // No change? Done.
2721     if (newOpacity == d_ptr->opacity)
2722         return;
2723
2724     bool wasFullyTransparent = d_ptr->isOpacityNull();
2725     d_ptr->opacity = newOpacity;
2726
2727     // Notify change.
2728     itemChange(ItemOpacityHasChanged, newOpacityVariant);
2729
2730     // Update.
2731     if (d_ptr->scene) {
2732 #ifndef QT_NO_GRAPHICSEFFECT
2733         d_ptr->invalidateParentGraphicsEffectsRecursively();
2734         if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren))
2735             d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged);
2736 #endif //QT_NO_GRAPHICSEFFECT
2737         d_ptr->scene->d_func()->markDirty(this, QRectF(),
2738                                           /*invalidateChildren=*/true,
2739                                           /*force=*/false,
2740                                           /*ignoreOpacity=*/d_ptr->isOpacityNull());
2741         if (wasFullyTransparent)
2742             d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
2743     }
2744
2745     if (d_ptr->isObject)
2746         emit static_cast<QGraphicsObject *>(this)->opacityChanged();
2747 }
2748
2749 /*!
2750     Returns a pointer to this item's effect if it has one; otherwise 0.
2751
2752     \since 4.6
2753 */
2754 #ifndef QT_NO_GRAPHICSEFFECT
2755 QGraphicsEffect *QGraphicsItem::graphicsEffect() const
2756 {
2757     return d_ptr->graphicsEffect;
2758 }
2759
2760 /*!
2761     Sets \a effect as the item's effect. If there already is an effect installed
2762     on this item, QGraphicsItem will delete the existing effect before installing
2763     the new \a effect.
2764
2765     If \a effect is the installed on a different item, setGraphicsEffect() will remove
2766     the effect from the item and install it on this item.
2767
2768     QGraphicsItem takes ownership of \a effect.
2769
2770     \note This function will apply the effect on itself and all its children.
2771
2772     \since 4.6
2773 */
2774 void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
2775 {
2776     if (d_ptr->graphicsEffect == effect)
2777         return;
2778
2779     if (d_ptr->graphicsEffect) {
2780         delete d_ptr->graphicsEffect;
2781         d_ptr->graphicsEffect = 0;
2782     } else if (d_ptr->parent) {
2783         d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
2784     }
2785
2786     if (effect) {
2787         // Set new effect.
2788         QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
2789         QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
2790         d_ptr->graphicsEffect = effect;
2791         effect->d_func()->setGraphicsEffectSource(source);
2792         prepareGeometryChange();
2793     }
2794 }
2795 #endif //QT_NO_GRAPHICSEFFECT
2796
2797 void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively()
2798 {
2799 #ifndef QT_NO_GRAPHICSEFFECT
2800     QGraphicsItemPrivate *itemPrivate = this;
2801     do {
2802         // parent chain already notified?
2803         if (itemPrivate->mayHaveChildWithGraphicsEffect)
2804             return;
2805         itemPrivate->mayHaveChildWithGraphicsEffect = 1;
2806     } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
2807 #endif
2808 }
2809
2810 /*!
2811     \internal
2812     \since 4.6
2813     Returns the effective bounding rect of the given item space rect.
2814     If the item has no effect, the rect is returned unmodified.
2815     If the item has an effect, the effective rect can be extend beyond the
2816     item's bounding rect, depending on the effect.
2817
2818     \sa boundingRect()
2819 */
2820 QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
2821 {
2822 #ifndef QT_NO_GRAPHICSEFFECT
2823     Q_Q(const QGraphicsItem);
2824     QGraphicsEffect *effect = graphicsEffect;
2825     if (scene && effect && effect->isEnabled()) {
2826         if (scene->d_func()->views.isEmpty())
2827             return effect->boundingRectFor(rect);
2828         QRectF sceneRect = q->mapRectToScene(rect);
2829         QRectF sceneEffectRect;
2830         foreach (QGraphicsView *view, scene->views()) {
2831             QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect);
2832             QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect();
2833             sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect);
2834         }
2835         return q->mapRectFromScene(sceneEffectRect);
2836     }
2837 #endif //QT_NO_GRAPHICSEFFECT
2838     return rect;
2839 }
2840
2841 /*!
2842     \internal
2843     \since 4.6
2844     Returns the effective bounding rect of the item.
2845     If the item has no effect, this is the same as the item's bounding rect.
2846     If the item has an effect, the effective rect can be larger than the item's
2847     bouding rect, depending on the effect.
2848
2849     \sa boundingRect()
2850 */
2851 QRectF QGraphicsItemPrivate::effectiveBoundingRect(QGraphicsItem *topMostEffectItem) const
2852 {
2853 #ifndef QT_NO_GRAPHICSEFFECT
2854     Q_Q(const QGraphicsItem);
2855     QRectF brect = effectiveBoundingRect(q_ptr->boundingRect());
2856     if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren || topMostEffectItem == q)
2857         return brect;
2858
2859     const QGraphicsItem *effectParent = parent;
2860     while (effectParent) {
2861         QGraphicsEffect *effect = effectParent->d_ptr->graphicsEffect;
2862         if (scene && effect && effect->isEnabled()) {
2863             const QRectF brectInParentSpace = q->mapRectToItem(effectParent, brect);
2864             const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace);
2865             brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
2866         }
2867         if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
2868             || topMostEffectItem == effectParent) {
2869             return brect;
2870         }
2871         effectParent = effectParent->d_ptr->parent;
2872     }
2873
2874     return brect;
2875 #else //QT_NO_GRAPHICSEFFECT
2876     return q_ptr->boundingRect();
2877 #endif //QT_NO_GRAPHICSEFFECT
2878
2879 }
2880
2881 /*!
2882     \internal
2883     \since 4.6
2884     Returns the effective bounding rect of this item in scene coordinates,
2885     by combining sceneTransform() with boundingRect(), taking into account
2886     the effect that the item might have.
2887
2888     If the item has no effect, this is the same as sceneBoundingRect().
2889
2890     \sa effectiveBoundingRect(), sceneBoundingRect()
2891 */
2892 QRectF QGraphicsItemPrivate::sceneEffectiveBoundingRect() const
2893 {
2894     // Find translate-only offset
2895     // COMBINE
2896     QPointF offset;
2897     const QGraphicsItem *parentItem = q_ptr;
2898     const QGraphicsItemPrivate *itemd;
2899     do {
2900         itemd = parentItem->d_ptr.data();
2901         if (itemd->transformData)
2902             break;
2903         offset += itemd->pos;
2904     } while ((parentItem = itemd->parent));
2905
2906     QRectF br = effectiveBoundingRect();
2907     br.translate(offset);
2908     return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
2909 }
2910
2911 /*!
2912    Returns true if this item can accept drag and drop events; otherwise,
2913    returns false. By default, items do not accept drag and drop events; items
2914    are transparent to drag and drop.
2915
2916    \sa setAcceptDrops()
2917 */
2918 bool QGraphicsItem::acceptDrops() const
2919 {
2920     return d_ptr->acceptDrops;
2921 }
2922
2923 /*!
2924     If \a on is true, this item will accept drag and drop events; otherwise,
2925     it is transparent for drag and drop events. By default, items do not
2926     accept drag and drop events.
2927
2928     \sa acceptDrops()
2929 */
2930 void QGraphicsItem::setAcceptDrops(bool on)
2931 {
2932     d_ptr->acceptDrops = on;
2933 }
2934
2935 /*!
2936     Returns the mouse buttons that this item accepts mouse events for.  By
2937     default, all mouse buttons are accepted.
2938
2939     If an item accepts a mouse button, it will become the mouse
2940     grabber item when a mouse press event is delivered for that mouse
2941     button. However, if the item does not accept the button,
2942     QGraphicsScene will forward the mouse events to the first item
2943     beneath it that does.
2944
2945     \sa setAcceptedMouseButtons(), mousePressEvent()
2946 */
2947 Qt::MouseButtons QGraphicsItem::acceptedMouseButtons() const
2948 {
2949     return Qt::MouseButtons(d_ptr->acceptedMouseButtons);
2950 }
2951
2952 /*!
2953     Sets the mouse \a buttons that this item accepts mouse events for.
2954
2955     By default, all mouse buttons are accepted. If an item accepts a
2956     mouse button, it will become the mouse grabber item when a mouse
2957     press event is delivered for that button. However, if the item
2958     does not accept the mouse button, QGraphicsScene will forward the
2959     mouse events to the first item beneath it that does.
2960
2961     To disable mouse events for an item (i.e., make it transparent for mouse
2962     events), call setAcceptedMouseButtons(0).
2963
2964     \sa acceptedMouseButtons(), mousePressEvent()
2965 */
2966 void QGraphicsItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
2967 {
2968     if (Qt::MouseButtons(d_ptr->acceptedMouseButtons) != buttons) {
2969         if (buttons == 0 && d_ptr->scene && d_ptr->scene->mouseGrabberItem() == this
2970             && d_ptr->scene->d_func()->lastMouseGrabberItemHasImplicitMouseGrab) {
2971             ungrabMouse();
2972         }
2973         d_ptr->acceptedMouseButtons = quint32(buttons);
2974     }
2975 }
2976
2977 /*!
2978     \since 4.4
2979
2980     Returns true if an item accepts hover events
2981     (QGraphicsSceneHoverEvent); otherwise, returns false. By default,
2982     items do not accept hover events.
2983
2984     \sa setAcceptedMouseButtons()
2985 */
2986 bool QGraphicsItem::acceptHoverEvents() const
2987 {
2988     return d_ptr->acceptsHover;
2989 }
2990
2991 /*!
2992     \obsolete
2993
2994     Call acceptHoverEvents() instead.
2995 */
2996 bool QGraphicsItem::acceptsHoverEvents() const
2997 {
2998     return d_ptr->acceptsHover;
2999 }
3000
3001 /*!
3002     \since 4.4
3003
3004     If \a enabled is true, this item will accept hover events;
3005     otherwise, it will ignore them. By default, items do not accept
3006     hover events.
3007
3008     Hover events are delivered when there is no current mouse grabber
3009     item.  They are sent when the mouse cursor enters an item, when it
3010     moves around inside the item, and when the cursor leaves an
3011     item. Hover events are commonly used to highlight an item when
3012     it's entered, and for tracking the mouse cursor as it hovers over
3013     the item (equivalent to QWidget::mouseTracking).
3014
3015     Parent items receive hover enter events before their children, and
3016     leave events after their children. The parent does not receive a
3017     hover leave event if the cursor enters a child, though; the parent
3018     stays "hovered" until the cursor leaves its area, including its
3019     children's areas.
3020
3021     If a parent item handles child events, it will receive hover move,
3022     drag move, and drop events as the cursor passes through its
3023     children, but it does not receive hover enter and hover leave, nor
3024     drag enter and drag leave events on behalf of its children.
3025
3026     A QGraphicsWidget with window decorations will accept hover events
3027     regardless of the value of acceptHoverEvents().
3028
3029     \sa acceptHoverEvents(), hoverEnterEvent(), hoverMoveEvent(),
3030     hoverLeaveEvent()
3031 */
3032 void QGraphicsItem::setAcceptHoverEvents(bool enabled)
3033 {
3034     if (d_ptr->acceptsHover == quint32(enabled))
3035         return;
3036     d_ptr->acceptsHover = quint32(enabled);
3037     if (d_ptr->acceptsHover && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreHoverEvents) {
3038         d_ptr->scene->d_func()->allItemsIgnoreHoverEvents = false;
3039         d_ptr->scene->d_func()->enableMouseTrackingOnViews();
3040     }
3041 }
3042
3043 /*!
3044     \obsolete
3045
3046     Use setAcceptHoverEvents(\a enabled) instead.
3047 */
3048 void QGraphicsItem::setAcceptsHoverEvents(bool enabled)
3049 {
3050     setAcceptHoverEvents(enabled);
3051 }
3052
3053 /*! \since 4.6
3054
3055     Returns true if an item accepts \l{QTouchEvent}{touch events};
3056     otherwise, returns false. By default, items do not accept touch events.
3057
3058     \sa setAcceptTouchEvents()
3059 */
3060 bool QGraphicsItem::acceptTouchEvents() const
3061 {
3062     return d_ptr->acceptTouchEvents;
3063 }
3064
3065 /*!
3066     \since 4.6
3067
3068     If \a enabled is true, this item will accept \l{QTouchEvent}{touch events};
3069     otherwise, it will ignore them. By default, items do not accept
3070     touch events.
3071 */
3072 void QGraphicsItem::setAcceptTouchEvents(bool enabled)
3073 {
3074     if (d_ptr->acceptTouchEvents == quint32(enabled))
3075         return;
3076     d_ptr->acceptTouchEvents = quint32(enabled);
3077     if (d_ptr->acceptTouchEvents && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreTouchEvents) {
3078         d_ptr->scene->d_func()->allItemsIgnoreTouchEvents = false;
3079         d_ptr->scene->d_func()->enableTouchEventsOnViews();
3080     }
3081 }
3082
3083 /*!
3084     \since 4.6
3085
3086     Returns true if this item filters child events (i.e., all events
3087     intended for any of its children are instead sent to this item);
3088     otherwise, false is returned.
3089
3090     The default value is false; child events are not filtered.
3091
3092     \sa setFiltersChildEvents()
3093 */
3094 bool QGraphicsItem::filtersChildEvents() const
3095 {
3096     return d_ptr->filtersDescendantEvents;
3097 }
3098
3099 /*!
3100     \since 4.6
3101
3102     If \a enabled is true, this item is set to filter all events for
3103     all its children (i.e., all events intented for any of its
3104     children are instead sent to this item); otherwise, if \a enabled
3105     is false, this item will only handle its own events. The default
3106     value is false.
3107
3108     \sa filtersChildEvents()
3109 */
3110 void QGraphicsItem::setFiltersChildEvents(bool enabled)
3111 {
3112     if (d_ptr->filtersDescendantEvents == enabled)
3113         return;
3114
3115     d_ptr->filtersDescendantEvents = enabled;
3116     d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
3117 }
3118
3119 /*!
3120     \obsolete
3121
3122     Returns true if this item handles child events (i.e., all events
3123     intended for any of its children are instead sent to this item);
3124     otherwise, false is returned.
3125
3126     This property is useful for item groups; it allows one item to
3127     handle events on behalf of its children, as opposed to its
3128     children handling their events individually.
3129
3130     The default is to return false; children handle their own events.
3131     The exception for this is if the item is a QGraphicsItemGroup, then
3132     it defaults to return true.
3133
3134     \sa setHandlesChildEvents()
3135 */
3136 bool QGraphicsItem::handlesChildEvents() const
3137 {
3138     return d_ptr->handlesChildEvents;
3139 }
3140
3141 /*!
3142     \obsolete
3143
3144     If \a enabled is true, this item is set to handle all events for
3145     all its children (i.e., all events intented for any of its
3146     children are instead sent to this item); otherwise, if \a enabled
3147     is false, this item will only handle its own events. The default
3148     value is false.
3149
3150     This property is useful for item groups; it allows one item to
3151     handle events on behalf of its children, as opposed to its
3152     children handling their events individually.
3153
3154     If a child item accepts hover events, its parent will receive
3155     hover move events as the cursor passes through the child, but it
3156     does not receive hover enter and hover leave events on behalf of
3157     its child.
3158
3159     \sa handlesChildEvents()
3160 */
3161 void QGraphicsItem::setHandlesChildEvents(bool enabled)
3162 {
3163     if (d_ptr->handlesChildEvents == enabled)
3164         return;
3165
3166     d_ptr->handlesChildEvents = enabled;
3167     d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
3168 }
3169 /*!
3170     \since 4.6
3171     Returns true if this item is active; otherwise returns false.
3172
3173     An item can only be active if the scene is active. An item is active
3174     if it is, or is a descendent of, an active panel. Items in non-active
3175     panels are not active.
3176
3177     Items that are not part of a panel follow scene activation when the
3178     scene has no active panel.
3179
3180     Only active items can gain input focus.
3181
3182     \sa QGraphicsScene::isActive(), QGraphicsScene::activePanel(), panel(), isPanel()
3183 */
3184 bool QGraphicsItem::isActive() const
3185 {
3186     if (!d_ptr->scene || !d_ptr->scene->isActive())
3187         return false;
3188     return panel() == d_ptr->scene->activePanel();
3189 }
3190
3191 /*!
3192     \since 4.6
3193
3194     If \a active is true, and the scene is active, this item's panel will be
3195     activated. Otherwise, the panel is deactivated.
3196
3197     If the item is not part of an active scene, \a active will decide what
3198     happens to the panel when the scene becomes active or the item is added to
3199     the scene. If true, the item's panel will be activated when the item is
3200     either added to the scene or the scene is activated. Otherwise, the item
3201     will stay inactive independent of the scene's activated state.
3202
3203     \sa isPanel(), QGraphicsScene::setActivePanel(), QGraphicsScene::isActive()
3204 */
3205 void QGraphicsItem::setActive(bool active)
3206 {
3207     d_ptr->explicitActivate = 1;
3208     d_ptr->wantsActive = active;
3209     if (d_ptr->scene) {
3210         if (active) {
3211             // Activate this item.
3212             d_ptr->scene->setActivePanel(this);
3213         } else {
3214             // Deactivate this item, and reactivate the last active item
3215             // (if any).
3216             QGraphicsItem *lastActive = d_ptr->scene->d_func()->lastActivePanel;
3217             d_ptr->scene->setActivePanel(lastActive != this ? lastActive : 0);
3218         }
3219     }
3220 }
3221
3222 /*!
3223     Returns true if this item is active, and it or its \l{focusProxy()}{focus
3224     proxy} has keyboard input focus; otherwise, returns false.
3225
3226     \sa focusItem(), setFocus(), QGraphicsScene::setFocusItem(), isActive()
3227 */
3228 bool QGraphicsItem::hasFocus() const
3229 {
3230     if (!d_ptr->scene || !d_ptr->scene->isActive())
3231         return false;
3232
3233     if (d_ptr->focusProxy)
3234         return d_ptr->focusProxy->hasFocus();
3235
3236     if (d_ptr->scene->d_func()->focusItem != this)
3237         return false;
3238
3239     return panel() == d_ptr->scene->d_func()->activePanel;
3240 }
3241
3242 /*!
3243     Gives keyboard input focus to this item. The \a focusReason argument will
3244     be passed into any \l{QFocusEvent}{focus event} generated by this function;
3245     it is used to give an explanation of what caused the item to get focus.
3246
3247     Only enabled items that set the ItemIsFocusable flag can accept keyboard
3248     focus.
3249
3250     If this item is not visible, not active, or not associated with a scene,
3251     it will not gain immediate input focus. However, it will be registered as
3252     the preferred focus item for its subtree of items, should it later become
3253     visible.
3254
3255     As a result of calling this function, this item will receive a
3256     \l{focusInEvent()}{focus in event} with \a focusReason. If another item
3257     already has focus, that item will first receive a \l{focusOutEvent()}
3258     {focus out event} indicating that it has lost input focus.
3259
3260     \sa clearFocus(), hasFocus(), focusItem(), focusProxy()
3261 */
3262 void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
3263 {
3264     d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromHide = */ false);
3265 }
3266
3267 /*!
3268     \internal
3269 */
3270 void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide)
3271 {
3272     // Disabled / unfocusable items cannot accept focus.
3273     if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
3274         return;
3275
3276     // Find focus proxy.
3277     QGraphicsItem *f = q_ptr;
3278     while (f->d_ptr->focusProxy)
3279         f = f->d_ptr->focusProxy;
3280
3281     // Return if it already has focus.
3282     if (scene && scene->focusItem() == f)
3283         return;
3284
3285     // Update focus scope item ptr.
3286     QGraphicsItem *p = parent;
3287     while (p) {
3288         if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3289             QGraphicsItem *oldFocusScopeItem = p->d_ptr->focusScopeItem;
3290             p->d_ptr->focusScopeItem = q_ptr;
3291             if (!p->focusItem() && !focusFromHide) {
3292                 if (oldFocusScopeItem)
3293                     oldFocusScopeItem->d_ptr->focusScopeItemChange(false);
3294                 focusScopeItemChange(true);
3295                 // If you call setFocus on a child of a focus scope that
3296                 // doesn't currently have a focus item, then stop.
3297                 return;
3298             }
3299             break;
3300         }
3301         p = p->d_ptr->parent;
3302     }
3303
3304     if (climb) {
3305         while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible())
3306             f = f->d_ptr->focusScopeItem;
3307     }
3308
3309     // Update the child focus chain.
3310     QGraphicsItem *commonAncestor = 0;
3311     if (scene && scene->focusItem()) {
3312         commonAncestor = scene->focusItem()->commonAncestorItem(f);
3313         scene->focusItem()->d_ptr->clearSubFocus(scene->focusItem(), commonAncestor);
3314     }
3315
3316     f->d_ptr->setSubFocus(f, commonAncestor);
3317
3318     // Update the scene's focus item.
3319     if (scene) {
3320         QGraphicsItem *p = q_ptr->panel();
3321         if ((!p && scene->isActive()) || (p && p->isActive())) {
3322             // Visible items immediately gain focus from scene.
3323             scene->d_func()->setFocusItemHelper(f, focusReason);
3324         }
3325     }
3326 }
3327
3328 /*!
3329     Takes keyboard input focus from the item.
3330
3331     If it has focus, a \l{focusOutEvent()}{focus out event} is sent to this
3332     item to tell it that it is about to lose the focus.
3333
3334     Only items that set the ItemIsFocusable flag, or widgets that set an
3335     appropriate focus policy, can accept keyboard focus.
3336
3337     \sa setFocus(), hasFocus(), QGraphicsWidget::focusPolicy
3338 */
3339 void QGraphicsItem::clearFocus()
3340 {
3341     d_ptr->clearFocusHelper(/* giveFocusToParent = */ true);
3342 }
3343
3344 /*!
3345     \internal
3346 */
3347 void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent)
3348 {
3349     if (giveFocusToParent) {
3350         // Pass focus to the closest parent focus scope
3351         if (!inDestructor) {
3352             QGraphicsItem *p = parent;
3353             while (p) {
3354                 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3355                     if (p->d_ptr->focusScopeItem == q_ptr) {
3356                         p->d_ptr->focusScopeItem = 0;
3357                         if (!q_ptr->hasFocus()) //if it has focus, focusScopeItemChange is called elsewhere
3358                             focusScopeItemChange(false);
3359                     }
3360                     if (q_ptr->hasFocus())
3361                         p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false,
3362                                                  /* focusFromHide = */ false);
3363                     return;
3364                 }
3365                 p = p->d_ptr->parent;
3366             }
3367         }
3368     }
3369
3370     if (q_ptr->hasFocus()) {
3371         // Invisible items with focus must explicitly clear subfocus.
3372         clearSubFocus(q_ptr);
3373
3374         // If this item has the scene's input focus, clear it.
3375         scene->setFocusItem(0);
3376     }
3377 }
3378
3379 /*!
3380     \since 4.6
3381
3382     Returns this item's focus proxy, or 0 if this item has no
3383     focus proxy.
3384
3385     \sa setFocusProxy(), setFocus(), hasFocus()
3386 */
3387 QGraphicsItem *QGraphicsItem::focusProxy() const
3388 {
3389     return d_ptr->focusProxy;
3390 }
3391
3392 /*!
3393     \since 4.6
3394
3395     Sets the item's focus proxy to \a item.
3396
3397     If an item has a focus proxy, the focus proxy will receive
3398     input focus when the item gains input focus. The item itself
3399     will still have focus (i.e., hasFocus() will return true),
3400     but only the focus proxy will receive the keyboard input.
3401
3402     A focus proxy can itself have a focus proxy, and so on. In
3403     such case, keyboard input will be handled by the outermost
3404     focus proxy.
3405
3406     The focus proxy \a item must belong to the same scene as
3407     this item.
3408
3409     \sa focusProxy(), setFocus(), hasFocus()
3410 */
3411 void QGraphicsItem::setFocusProxy(QGraphicsItem *item)
3412 {
3413     if (item == d_ptr->focusProxy)
3414         return;
3415     if (item == this) {
3416         qWarning("QGraphicsItem::setFocusProxy: cannot assign self as focus proxy");
3417         return;
3418     }
3419     if (item) {
3420         if (item->d_ptr->scene != d_ptr->scene) {
3421             qWarning("QGraphicsItem::setFocusProxy: focus proxy must be in same scene");
3422             return;
3423         }
3424         for (QGraphicsItem *f = item->focusProxy(); f != 0; f = f->focusProxy()) {
3425             if (f == this) {
3426                 qWarning("QGraphicsItem::setFocusProxy: %p is already in the focus proxy chain", item);
3427                 return;
3428             }
3429         }
3430     }
3431
3432     QGraphicsItem *lastFocusProxy = d_ptr->focusProxy;
3433     if (lastFocusProxy)
3434         lastFocusProxy->d_ptr->focusProxyRefs.removeOne(&d_ptr->focusProxy);
3435     d_ptr->focusProxy = item;
3436     if (item)
3437         item->d_ptr->focusProxyRefs << &d_ptr->focusProxy;
3438 }
3439
3440 /*!
3441     \since 4.6
3442
3443     If this item, a child or descendant of this item currently has input
3444     focus, this function will return a pointer to that item. If
3445     no descendant has input focus, 0 is returned.
3446
3447     \sa hasFocus(), setFocus(), QWidget::focusWidget()
3448 */
3449 QGraphicsItem *QGraphicsItem::focusItem() const
3450 {
3451     return d_ptr->subFocusItem;
3452 }
3453
3454 /*!
3455     \internal
3456
3457     Returns this item's focus scope item.
3458 */
3459 QGraphicsItem *QGraphicsItem::focusScopeItem() const
3460 {
3461     return d_ptr->focusScopeItem;
3462 }
3463
3464 /*!
3465     \since 4.4
3466     Grabs the mouse input.
3467
3468     This item will receive all mouse events for the scene until any of the
3469     following events occurs:
3470
3471     \list
3472     \li The item becomes invisible
3473     \li The item is removed from the scene
3474     \li The item is deleted
3475     \li The item call ungrabMouse()
3476     \li Another item calls grabMouse(); the item will regain the mouse grab
3477     when the other item calls ungrabMouse().
3478     \endlist
3479
3480     When an item gains the mouse grab, it receives a QEvent::GrabMouse
3481     event. When it loses the mouse grab, it receives a QEvent::UngrabMouse
3482     event. These events can be used to detect when your item gains or loses
3483     the mouse grab through other means than receiving mouse button events.
3484
3485     It is almost never necessary to explicitly grab the mouse in Qt, as Qt
3486     grabs and releases it sensibly. In particular, Qt grabs the mouse when you
3487     press a mouse button, and keeps the mouse grabbed until you release the
3488     last mouse button. Also, Qt::Popup widgets implicitly call grabMouse()
3489     when shown, and ungrabMouse() when hidden.
3490
3491     Note that only visible items can grab mouse input. Calling grabMouse() on
3492     an invisible item has no effect.
3493
3494     Keyboard events are not affected.
3495
3496     \sa QGraphicsScene::mouseGrabberItem(), ungrabMouse(), grabKeyboard()
3497 */
3498 void QGraphicsItem::grabMouse()
3499 {
3500     if (!d_ptr->scene) {
3501         qWarning("QGraphicsItem::grabMouse: cannot grab mouse without scene");
3502         return;
3503     }
3504     if (!d_ptr->visible) {
3505         qWarning("QGraphicsItem::grabMouse: cannot grab mouse while invisible");
3506         return;
3507     }
3508     d_ptr->scene->d_func()->grabMouse(this);
3509 }
3510
3511 /*!
3512     \since 4.4
3513     Releases the mouse grab.
3514
3515     \sa grabMouse(), ungrabKeyboard()
3516 */
3517 void QGraphicsItem::ungrabMouse()
3518 {
3519     if (!d_ptr->scene) {
3520         qWarning("QGraphicsItem::ungrabMouse: cannot ungrab mouse without scene");
3521         return;
3522     }
3523     d_ptr->scene->d_func()->ungrabMouse(this);
3524 }
3525
3526 /*!
3527     \since 4.4
3528     Grabs the keyboard input.
3529
3530     The item will receive all keyboard input to the scene until one of the
3531     following events occur:
3532
3533     \list
3534     \li The item becomes invisible
3535     \li The item is removed from the scene
3536     \li The item is deleted
3537     \li The item calls ungrabKeyboard()
3538     \li Another item calls grabKeyboard(); the item will regain the keyboard grab
3539     when the other item calls ungrabKeyboard().
3540     \endlist
3541
3542     When an item gains the keyboard grab, it receives a QEvent::GrabKeyboard
3543     event. When it loses the keyboard grab, it receives a
3544     QEvent::UngrabKeyboard event. These events can be used to detect when your
3545     item gains or loses the keyboard grab through other means than gaining
3546     input focus.
3547
3548     It is almost never necessary to explicitly grab the keyboard in Qt, as Qt
3549     grabs and releases it sensibly. In particular, Qt grabs the keyboard when
3550     your item gains input focus, and releases it when your item loses input
3551     focus, or when the item is hidden.
3552
3553     Note that only visible items can grab keyboard input. Calling
3554     grabKeyboard() on an invisible item has no effect.
3555
3556     Keyboard events are not affected.
3557
3558     \sa ungrabKeyboard(), grabMouse(), setFocus()
3559 */
3560 void QGraphicsItem::grabKeyboard()
3561 {
3562     if (!d_ptr->scene) {
3563         qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard without scene");
3564         return;
3565     }
3566     if (!d_ptr->visible) {
3567         qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard while invisible");
3568         return;
3569     }
3570     d_ptr->scene->d_func()->grabKeyboard(this);
3571 }
3572
3573 /*!
3574     \since 4.4
3575     Releases the keyboard grab.
3576
3577     \sa grabKeyboard(), ungrabMouse()
3578 */
3579 void QGraphicsItem::ungrabKeyboard()
3580 {
3581     if (!d_ptr->scene) {
3582         qWarning("QGraphicsItem::ungrabKeyboard: cannot ungrab keyboard without scene");
3583         return;
3584     }
3585     d_ptr->scene->d_func()->ungrabKeyboard(this);
3586 }
3587
3588 /*!
3589     Returns the position of the item in parent coordinates. If the item has no
3590     parent, its position is given in scene coordinates.
3591
3592     The position of the item describes its origin (local coordinate
3593     (0, 0)) in parent coordinates; this function returns the same as
3594     mapToParent(0, 0).
3595
3596     For convenience, you can also call scenePos() to determine the
3597     item's position in scene coordinates, regardless of its parent.
3598
3599     \sa x(), y(), setPos(), transform(), {The Graphics View Coordinate System}
3600 */
3601 QPointF QGraphicsItem::pos() const
3602 {
3603     return d_ptr->pos;
3604 }
3605
3606 /*!
3607     \fn QGraphicsItem::x() const
3608
3609     This convenience function is equivalent to calling pos().x().
3610
3611     \sa y()
3612 */
3613
3614 /*!
3615     \since 4.6
3616
3617     Set's the \a x coordinate of the item's position. Equivalent to
3618     calling setPos(x, y()).
3619
3620     \sa x(), setPos()
3621 */
3622 void QGraphicsItem::setX(qreal x)
3623 {
3624     if (d_ptr->inDestructor)
3625         return;
3626
3627     if (qIsNaN(x))
3628         return;
3629
3630     setPos(QPointF(x, d_ptr->pos.y()));
3631 }
3632
3633 /*!
3634     \fn QGraphicsItem::y() const
3635
3636     This convenience function is equivalent to calling pos().y().
3637
3638     \sa x()
3639 */
3640
3641 /*!
3642     \since 4.6
3643
3644     Set's the \a y coordinate of the item's position. Equivalent to
3645     calling setPos(x(), y).
3646
3647     \sa x(), setPos()
3648 */
3649 void QGraphicsItem::setY(qreal y)
3650 {
3651     if (d_ptr->inDestructor)
3652         return;
3653
3654     if (qIsNaN(y))
3655         return;
3656
3657     setPos(QPointF(d_ptr->pos.x(), y));
3658 }
3659
3660 /*!
3661     Returns the item's position in scene coordinates. This is
3662     equivalent to calling \c mapToScene(0, 0).
3663
3664     \sa pos(), sceneTransform(), {The Graphics View Coordinate System}
3665 */
3666 QPointF QGraphicsItem::scenePos() const
3667 {
3668     return mapToScene(0, 0);
3669 }
3670
3671 /*!
3672     \internal
3673
3674     Sets the position \a pos.
3675 */
3676 void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
3677 {
3678     Q_Q(QGraphicsItem);
3679     inSetPosHelper = 1;
3680     if (scene)
3681         q->prepareGeometryChange();
3682     QPointF oldPos = this->pos;
3683     this->pos = pos;
3684     dirtySceneTransform = 1;
3685     inSetPosHelper = 0;
3686     if (isObject) {
3687         if (pos.x() != oldPos.x())
3688             emit static_cast<QGraphicsObject *>(q_ptr)->xChanged();
3689         if (pos.y() != oldPos.y())
3690             emit static_cast<QGraphicsObject *>(q_ptr)->yChanged();
3691     }
3692 }
3693
3694 /*!
3695     \internal
3696
3697     Sets the transform \a transform.
3698 */
3699 void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
3700 {
3701     q_ptr->prepareGeometryChange();
3702     transformData->transform = transform;
3703     dirtySceneTransform = 1;
3704     transformChanged();
3705 }
3706
3707 /*!
3708     Sets the position of the item to \a pos, which is in parent
3709     coordinates.  For items with no parent, \a pos is in scene
3710     coordinates.
3711
3712     The position of the item describes its origin (local coordinate
3713     (0, 0)) in parent coordinates.
3714
3715     \sa pos(), scenePos(), {The Graphics View Coordinate System}
3716 */
3717 void QGraphicsItem::setPos(const QPointF &pos)
3718 {
3719     if (d_ptr->pos == pos)
3720         return;
3721
3722     if (d_ptr->inDestructor)
3723         return;
3724
3725     // Update and repositition.
3726     if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
3727         d_ptr->setPosHelper(pos);
3728         if (d_ptr->isWidget)
3729             static_cast<QGraphicsWidget *>(this)->d_func()->setGeometryFromSetPos();
3730         if (d_ptr->scenePosDescendants)
3731             d_ptr->sendScenePosChange();
3732         return;
3733     }
3734
3735     // Notify the item that the position is changing.
3736     const QVariant newPosVariant(itemChange(ItemPositionChange, QVariant::fromValue<QPointF>(pos)));
3737     QPointF newPos = newPosVariant.toPointF();
3738     if (newPos == d_ptr->pos)
3739         return;
3740
3741     // Update and repositition.
3742     d_ptr->setPosHelper(newPos);
3743
3744     // Send post-notification.
3745     itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
3746     d_ptr->sendScenePosChange();
3747 }
3748
3749 /*!
3750     \fn void QGraphicsItem::setPos(qreal x, qreal y)
3751     \overload
3752
3753     This convenience function is equivalent to calling setPos(QPointF(\a x, \a
3754     y)).
3755 */
3756
3757 /*!
3758     \fn void QGraphicsItem::moveBy(qreal dx, qreal dy)
3759
3760     Moves the item by \a dx points horizontally, and \a dy point
3761     vertically. This function is equivalent to calling setPos(pos() +
3762     QPointF(\a dx, \a dy)).
3763 */
3764
3765 /*!
3766     If this item is part of a scene that is viewed by a QGraphicsView, this
3767     convenience function will attempt to scroll the view to ensure that \a
3768     rect is visible inside the view's viewport. If \a rect is a null rect (the
3769     default), QGraphicsItem will default to the item's bounding rect. \a xmargin
3770     and \a ymargin are the number of pixels the view should use for margins.
3771
3772     If the specified rect cannot be reached, the contents are scrolled to the
3773     nearest valid position.
3774
3775     If this item is not viewed by a QGraphicsView, this function does nothing.
3776
3777     \sa QGraphicsView::ensureVisible()
3778 */
3779 void QGraphicsItem::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
3780 {
3781     if (d_ptr->scene) {
3782         QRectF sceneRect;
3783         if (!rect.isNull())
3784             sceneRect = sceneTransform().mapRect(rect);
3785         else
3786             sceneRect = sceneBoundingRect();
3787         foreach (QGraphicsView *view, d_ptr->scene->d_func()->views)
3788             view->ensureVisible(sceneRect, xmargin, ymargin);
3789     }
3790 }
3791
3792 /*!
3793     \fn void QGraphicsItem::ensureVisible(qreal x, qreal y, qreal w, qreal h,
3794     int xmargin = 50, int ymargin = 50)
3795
3796     This convenience function is equivalent to calling
3797     ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin):
3798 */
3799
3800 /*!
3801     \obsolete
3802
3803     Returns the item's affine transformation matrix. This is a subset or the
3804     item's full transformation matrix, and might not represent the item's full
3805     transformation.
3806
3807     Use transform() instead.
3808
3809     \sa setTransform(), sceneTransform()
3810 */
3811 QMatrix QGraphicsItem::matrix() const
3812 {
3813     return transform().toAffine();
3814 }
3815
3816 /*!
3817     \since 4.3
3818
3819     Returns this item's transformation matrix.
3820
3821     The transformation matrix is combined with the item's rotation(), scale()
3822     and transformations() into a combined transformations for the item.
3823
3824     The default transformation matrix is an identity matrix.
3825
3826     \sa setTransform(), sceneTransform()
3827 */
3828 QTransform QGraphicsItem::transform() const
3829 {
3830     if (!d_ptr->transformData)
3831         return QTransform();
3832     return d_ptr->transformData->transform;
3833 }
3834
3835 /*!
3836     \since 4.6
3837
3838     Returns the clockwise rotation, in degrees, around the Z axis. The default
3839     value is 0 (i.e., the item is not rotated).
3840
3841     The rotation is combined with the item's scale(), transform() and
3842     transformations() to map the item's coordinate system to the parent item.
3843
3844     \sa setRotation(), transformOriginPoint(), {Transformations}
3845 */
3846 qreal QGraphicsItem::rotation() const
3847 {
3848     if (!d_ptr->transformData)
3849         return 0;
3850     return d_ptr->transformData->rotation;
3851 }
3852
3853 /*!
3854     \since 4.6
3855
3856     Sets the clockwise rotation \a angle, in degrees, around the Z axis. The
3857     default value is 0 (i.e., the item is not rotated). Assigning a negative
3858     value will rotate the item counter-clockwise. Normally the rotation angle
3859     is in the range (-360, 360), but it's also possible to assign values
3860     outside of this range (e.g., a rotation of 370 degrees is the same as a
3861     rotation of 10 degrees).
3862
3863     The item is rotated around its transform origin point, which by default
3864     is (0, 0). You can select a different transformation origin by calling
3865     setTransformOriginPoint().
3866
3867     The rotation is combined with the item's scale(), transform() and
3868     transformations() to map the item's coordinate system to the parent item.
3869
3870     \sa rotation(), setTransformOriginPoint(), {Transformations}
3871 */
3872 void QGraphicsItem::setRotation(qreal angle)
3873 {
3874     prepareGeometryChange();
3875     qreal newRotation = angle;
3876
3877     if (d_ptr->flags & ItemSendsGeometryChanges) {
3878         // Notify the item that the rotation is changing.
3879         const QVariant newRotationVariant(itemChange(ItemRotationChange, angle));
3880         newRotation = newRotationVariant.toReal();
3881     }
3882
3883     if (!d_ptr->transformData)
3884         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
3885
3886     if (d_ptr->transformData->rotation == newRotation)
3887         return;
3888
3889     d_ptr->transformData->rotation = newRotation;
3890     d_ptr->transformData->onlyTransform = false;
3891     d_ptr->dirtySceneTransform = 1;
3892
3893     // Send post-notification.
3894     if (d_ptr->flags & ItemSendsGeometryChanges)
3895         itemChange(ItemRotationHasChanged, newRotation);
3896
3897     if (d_ptr->isObject)
3898         emit static_cast<QGraphicsObject *>(this)->rotationChanged();
3899
3900     d_ptr->transformChanged();
3901 }
3902
3903 /*!
3904     \since 4.6
3905
3906     Returns the scale factor of the item. The default scale factor is 1.0
3907     (i.e., the item is not scaled).
3908
3909     The scale is combined with the item's rotation(), transform() and
3910     transformations() to map the item's coordinate system to the parent item.
3911
3912     \sa setScale(), rotation(), {Transformations}
3913 */
3914 qreal QGraphicsItem::scale() const
3915 {
3916     if (!d_ptr->transformData)
3917         return 1.;
3918     return d_ptr->transformData->scale;
3919 }
3920
3921 /*!
3922     \since 4.6
3923
3924     Sets the scale \a factor of the item. The default scale factor is 1.0
3925     (i.e., the item is not scaled). A scale factor of 0.0 will collapse the
3926     item to a single point. If you provide a negative scale factor, the
3927     item will be flipped and mirrored (i.e., rotated 180 degrees).
3928
3929     The item is scaled around its transform origin point, which by default
3930     is (0, 0). You can select a different transformation origin by calling
3931     setTransformOriginPoint().
3932
3933     The scale is combined with the item's rotation(), transform() and
3934     transformations() to map the item's coordinate system to the parent item.
3935
3936     \sa scale(), setTransformOriginPoint(), {Transformations Example}
3937 */
3938 void QGraphicsItem::setScale(qreal factor)
3939 {
3940     prepareGeometryChange();
3941     qreal newScale = factor;
3942
3943     if (d_ptr->flags & ItemSendsGeometryChanges) {
3944         // Notify the item that the scale is changing.
3945         const QVariant newScaleVariant(itemChange(ItemScaleChange, factor));
3946         newScale = newScaleVariant.toReal();
3947     }
3948
3949     if (!d_ptr->transformData)
3950         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
3951
3952     if (d_ptr->transformData->scale == newScale)
3953         return;
3954
3955     d_ptr->transformData->scale = newScale;
3956     d_ptr->transformData->onlyTransform = false;
3957     d_ptr->dirtySceneTransform = 1;
3958
3959     // Send post-notification.
3960     if (d_ptr->flags & ItemSendsGeometryChanges)
3961         itemChange(ItemScaleHasChanged, newScale);
3962
3963     if (d_ptr->isObject)
3964         emit static_cast<QGraphicsObject *>(this)->scaleChanged();
3965
3966     d_ptr->transformChanged();
3967 }
3968
3969
3970 /*!
3971     \since 4.6
3972
3973     Returns a list of graphics transforms that currently apply to this item.
3974
3975     QGraphicsTransform is for applying and controlling a chain of individual
3976     transformation operations on an item. It's particularly useful in
3977     animations, where each transform operation needs to be interpolated
3978     independently, or differently.
3979
3980     The transformations are combined with the item's rotation(), scale() and
3981     transform() to map the item's coordinate system to the parent item.
3982
3983     \sa scale(), rotation(), transformOriginPoint(), {Transformations}
3984 */
3985 QList<QGraphicsTransform *> QGraphicsItem::transformations() const
3986 {
3987     if (!d_ptr->transformData)
3988         return QList<QGraphicsTransform *>();
3989     return d_ptr->transformData->graphicsTransforms;
3990 }
3991
3992 /*!
3993     \since 4.6
3994
3995     Sets a list of graphics \a transformations (QGraphicsTransform) that
3996     currently apply to this item.
3997
3998     If all you want is to rotate or scale an item, you should call setRotation()
3999     or setScale() instead. If you want to set an arbitrary transformation on
4000     an item, you can call setTransform().
4001
4002     QGraphicsTransform is for applying and controlling a chain of individual
4003     transformation operations on an item. It's particularly useful in
4004     animations, where each transform operation needs to be interpolated
4005     independently, or differently.
4006
4007     The transformations are combined with the item's rotation(), scale() and
4008     transform() to map the item's coordinate system to the parent item.
4009
4010     \sa scale(), setTransformOriginPoint(), {Transformations}
4011 */
4012 void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transformations)
4013 {
4014     prepareGeometryChange();
4015     if (!d_ptr->transformData)
4016         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4017     d_ptr->transformData->graphicsTransforms = transformations;
4018     for (int i = 0; i < transformations.size(); ++i)
4019         transformations.at(i)->d_func()->setItem(this);
4020     d_ptr->transformData->onlyTransform = false;
4021     d_ptr->dirtySceneTransform = 1;
4022     d_ptr->transformChanged();
4023 }
4024
4025 /*!
4026     \internal
4027 */
4028 void QGraphicsItemPrivate::prependGraphicsTransform(QGraphicsTransform *t)
4029 {
4030     if (!transformData)
4031         transformData = new QGraphicsItemPrivate::TransformData;
4032     if (!transformData->graphicsTransforms.contains(t))
4033         transformData->graphicsTransforms.prepend(t);
4034
4035     Q_Q(QGraphicsItem);
4036     t->d_func()->setItem(q);
4037     transformData->onlyTransform = false;
4038     dirtySceneTransform = 1;
4039     transformChanged();
4040 }
4041
4042 /*!
4043     \internal
4044 */
4045 void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t)
4046 {
4047     if (!transformData)
4048         transformData = new QGraphicsItemPrivate::TransformData;
4049     if (!transformData->graphicsTransforms.contains(t))
4050         transformData->graphicsTransforms.append(t);
4051
4052     Q_Q(QGraphicsItem);
4053     t->d_func()->setItem(q);
4054     transformData->onlyTransform = false;
4055     dirtySceneTransform = 1;
4056     transformChanged();
4057 }
4058
4059 /*!
4060     \since 4.6
4061
4062     Returns the origin point for the transformation in item coordinates.
4063
4064     The default is QPointF(0,0).
4065
4066     \sa setTransformOriginPoint(), {Transformations}
4067 */
4068 QPointF QGraphicsItem::transformOriginPoint() const
4069 {
4070     if (!d_ptr->transformData)
4071         return QPointF(0,0);
4072     return QPointF(d_ptr->transformData->xOrigin, d_ptr->transformData->yOrigin);
4073 }
4074
4075 /*!
4076     \since 4.6
4077
4078     Sets the \a origin point for the transformation in item coordinates.
4079
4080     \sa transformOriginPoint(), {Transformations}
4081 */
4082 void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
4083 {
4084     prepareGeometryChange();
4085     QPointF newOrigin = origin;
4086
4087     if (d_ptr->flags & ItemSendsGeometryChanges) {
4088         // Notify the item that the origin point is changing.
4089         const QVariant newOriginVariant(itemChange(ItemTransformOriginPointChange,
4090                                                    QVariant::fromValue<QPointF>(origin)));
4091         newOrigin = newOriginVariant.toPointF();
4092     }
4093
4094     if (!d_ptr->transformData)
4095         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4096
4097     if (d_ptr->transformData->xOrigin == newOrigin.x()
4098         && d_ptr->transformData->yOrigin == newOrigin.y()) {
4099         return;
4100     }
4101
4102     d_ptr->transformData->xOrigin = newOrigin.x();
4103     d_ptr->transformData->yOrigin = newOrigin.y();
4104     d_ptr->transformData->onlyTransform = false;
4105     d_ptr->dirtySceneTransform = 1;
4106
4107     // Send post-notification.
4108     if (d_ptr->flags & ItemSendsGeometryChanges)
4109         itemChange(ItemTransformOriginPointHasChanged, QVariant::fromValue<QPointF>(newOrigin));
4110 }
4111
4112 /*!
4113     \fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y)
4114
4115     \since 4.6
4116     \overload
4117
4118     Sets the origin point for the transformation in item coordinates.
4119     This is equivalent to calling setTransformOriginPoint(QPointF(\a x, \a y)).
4120
4121     \sa setTransformOriginPoint(), {Transformations}
4122 */
4123
4124
4125 /*!
4126     \obsolete
4127
4128     Use sceneTransform() instead.
4129
4130     \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}
4131 */
4132 QMatrix QGraphicsItem::sceneMatrix() const
4133 {
4134     d_ptr->ensureSceneTransform();
4135     return d_ptr->sceneTransform.toAffine();
4136 }
4137
4138
4139 /*!
4140     \since 4.3
4141
4142     Returns this item's scene transformation matrix. This matrix can be used
4143     to map coordinates and geometrical shapes from this item's local
4144     coordinate system to the scene's coordinate system. To map coordinates
4145     from the scene, you must first invert the returned matrix.
4146
4147     Example:
4148
4149     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 4
4150
4151     Unlike transform(), which returns only an item's local transformation, this
4152     function includes the item's (and any parents') position, and all the transfomation properties.
4153
4154     \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}, {Transformations}
4155 */
4156 QTransform QGraphicsItem::sceneTransform() const
4157 {
4158     d_ptr->ensureSceneTransform();
4159     return d_ptr->sceneTransform;
4160 }
4161
4162 /*!
4163     \since 4.3
4164
4165     Returns this item's device transformation matrix, using \a
4166     viewportTransform to map from scene to device coordinates. This matrix can
4167     be used to map coordinates and geometrical shapes from this item's local
4168     coordinate system to the viewport's (or any device's) coordinate
4169     system. To map coordinates from the viewport, you must first invert the
4170     returned matrix.
4171
4172     Example:
4173
4174     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 5
4175
4176     This function is the same as combining this item's scene transform with
4177     the view's viewport transform, but it also understands the
4178     ItemIgnoresTransformations flag. The device transform can be used to do
4179     accurate coordinate mapping (and collision detection) for untransformable
4180     items.
4181
4182     \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate
4183     System}, itemTransform()
4184 */
4185 QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) const
4186 {
4187     // Ensure we return the standard transform if we're not untransformable.
4188     if (!d_ptr->itemIsUntransformable()) {
4189         d_ptr->ensureSceneTransform();
4190         return d_ptr->sceneTransform * viewportTransform;
4191     }
4192
4193     // Find the topmost item that ignores view transformations.
4194     const QGraphicsItem *untransformedAncestor = this;
4195     QList<const QGraphicsItem *> parents;
4196     while (untransformedAncestor && ((untransformedAncestor->d_ptr->ancestorFlags
4197                                      & QGraphicsItemPrivate::AncestorIgnoresTransformations))) {
4198         parents.prepend(untransformedAncestor);
4199         untransformedAncestor = untransformedAncestor->parentItem();
4200     }
4201
4202     if (!untransformedAncestor) {
4203         // Assert in debug mode, continue in release.
4204         Q_ASSERT_X(untransformedAncestor, "QGraphicsItem::deviceTransform",
4205                    "Invalid object structure!");
4206         return QTransform();
4207     }
4208
4209     // First translate the base untransformable item.
4210     untransformedAncestor->d_ptr->ensureSceneTransform();
4211     QPointF mappedPoint = (untransformedAncestor->d_ptr->sceneTransform * viewportTransform).map(QPointF(0, 0));
4212
4213     // COMBINE
4214     QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y());
4215     if (untransformedAncestor->d_ptr->transformData)
4216         matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform(&matrix);
4217
4218     // Then transform and translate all children.
4219     for (int i = 0; i < parents.size(); ++i) {
4220         const QGraphicsItem *parent = parents.at(i);
4221         parent->d_ptr->combineTransformFromParent(&matrix);
4222     }
4223
4224     return matrix;
4225 }
4226
4227 /*!
4228     \since 4.5
4229
4230     Returns a QTransform that maps coordinates from this item to \a other. If
4231     \a ok is not null, and if there is no such transform, the boolean pointed
4232     to by \a ok will be set to false; otherwise it will be set to true.
4233
4234     This transform provides an alternative to the mapToItem() or mapFromItem()
4235     functions, by returning the appropriate transform so that you can map
4236     shapes and coordinates yourself. It also helps you write more efficient
4237     code when repeatedly mapping between the same two items.
4238
4239     \note In rare circumstances, there is no transform that maps between two
4240     items.
4241
4242     \sa mapToItem(), mapFromItem(), deviceTransform()
4243 */
4244 QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) const
4245 {
4246     // Catch simple cases first.
4247     if (other == 0) {
4248         qWarning("QGraphicsItem::itemTransform: null pointer passed");
4249         return QTransform();
4250     }
4251     if (other == this) {
4252         if (ok)
4253             *ok = true;
4254         return QTransform();
4255     }
4256
4257     QGraphicsItem *parent = d_ptr->parent;
4258     const QGraphicsItem *otherParent = other->d_ptr->parent;
4259
4260     // This is other's child
4261     if (parent == other) {
4262         if (ok)
4263             *ok = true;
4264         QTransform x;
4265         d_ptr->combineTransformFromParent(&x);
4266         return x;
4267     }
4268
4269     // This is other's parent
4270     if (otherParent == this) {
4271         const QPointF &otherPos = other->d_ptr->pos;
4272         if (other->d_ptr->transformData) {
4273             QTransform otherToParent;
4274             other->d_ptr->combineTransformFromParent(&otherToParent);
4275             return otherToParent.inverted(ok);
4276         }
4277         if (ok)
4278             *ok = true;
4279         return QTransform::fromTranslate(-otherPos.x(), -otherPos.y());
4280     }
4281
4282     // Siblings
4283     if (parent == otherParent) {
4284         // COMBINE
4285         const QPointF &itemPos = d_ptr->pos;
4286         const QPointF &otherPos = other->d_ptr->pos;
4287         if (!d_ptr->transformData && !other->d_ptr->transformData) {
4288             QPointF delta = itemPos - otherPos;
4289             if (ok)
4290                 *ok = true;
4291             return QTransform::fromTranslate(delta.x(), delta.y());
4292         }
4293
4294         QTransform itemToParent;
4295         d_ptr->combineTransformFromParent(&itemToParent);
4296         QTransform otherToParent;
4297         other->d_ptr->combineTransformFromParent(&otherToParent);
4298         return itemToParent * otherToParent.inverted(ok);
4299     }
4300
4301     // Find the closest common ancestor. If the two items don't share an
4302     // ancestor, then the only way is to combine their scene transforms.
4303     const QGraphicsItem *commonAncestor = commonAncestorItem(other);
4304     if (!commonAncestor) {
4305         d_ptr->ensureSceneTransform();
4306         other->d_ptr->ensureSceneTransform();
4307         return d_ptr->sceneTransform * other->d_ptr->sceneTransform.inverted(ok);
4308     }
4309
4310     // If the two items are cousins (in sibling branches), map both to the
4311     // common ancestor, and combine the two transforms.
4312     bool cousins = other != commonAncestor && this != commonAncestor;
4313     if (cousins) {
4314         bool good = false;
4315         QTransform thisToScene = itemTransform(commonAncestor, &good);
4316         QTransform otherToScene(Qt::Uninitialized);
4317         if (good)
4318             otherToScene = other->itemTransform(commonAncestor, &good);
4319         if (!good) {
4320             if (ok)
4321                 *ok = false;
4322             return QTransform();
4323         }
4324         return thisToScene * otherToScene.inverted(ok);
4325     }
4326
4327     // One is an ancestor of the other; walk the chain.
4328     bool parentOfOther = isAncestorOf(other);
4329     const QGraphicsItem *child = parentOfOther ? other : this;
4330     const QGraphicsItem *root = parentOfOther ? this : other;
4331
4332     QTransform x;
4333     const QGraphicsItem *p = child;
4334     do {
4335         p->d_ptr.data()->combineTransformToParent(&x);
4336     } while ((p = p->d_ptr->parent) && p != root);
4337     if (parentOfOther)
4338         return x.inverted(ok);
4339     if (ok)
4340         *ok = true;
4341     return x;
4342 }
4343
4344 /*!
4345     \obsolete
4346
4347     Sets the item's affine transformation matrix. This is a subset or the
4348     item's full transformation matrix, and might not represent the item's full
4349     transformation.
4350
4351     Use setTransform() instead.
4352
4353     \sa transform(), {The Graphics View Coordinate System}
4354 */
4355 void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
4356 {
4357     if (!d_ptr->transformData)
4358         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4359
4360     QTransform newTransform(combine ? QTransform(matrix) * d_ptr->transformData->transform : QTransform(matrix));
4361     if (d_ptr->transformData->transform == newTransform)
4362         return;
4363
4364     // Update and set the new transformation.
4365     if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
4366         d_ptr->setTransformHelper(newTransform);
4367         return;
4368     }
4369
4370     // Notify the item that the transformation matrix is changing.
4371     const QVariant newMatrixVariant = QVariant::fromValue<QMatrix>(newTransform.toAffine());
4372     newTransform = QTransform(qvariant_cast<QMatrix>(itemChange(ItemMatrixChange, newMatrixVariant)));
4373     if (d_ptr->transformData->transform == newTransform)
4374         return;
4375
4376     // Update and set the new transformation.
4377     d_ptr->setTransformHelper(newTransform);
4378
4379     // Send post-notification.
4380     itemChange(ItemTransformHasChanged, QVariant::fromValue<QTransform>(newTransform));
4381 }
4382
4383 /*!
4384     \since 4.3
4385
4386     Sets the item's current transformation matrix to \a matrix.
4387
4388     If \a combine is true, then \a matrix is combined with the current matrix;
4389     otherwise, \a matrix \e replaces the current matrix. \a combine is false
4390     by default.
4391
4392     To simplify interation with items using a transformed view, QGraphicsItem
4393     provides mapTo... and mapFrom... functions that can translate between
4394     items' and the scene's coordinates. For example, you can call mapToScene()
4395     to map an item coordiate to a scene coordinate, or mapFromScene() to map
4396     from scene coordinates to item coordinates.
4397
4398     The transformation matrix is combined with the item's rotation(), scale()
4399     and transformations() into a combined transformation that maps the item's
4400     coordinate system to its parent.
4401
4402     \sa transform(), setRotation(), setScale(), setTransformOriginPoint(), {The Graphics View Coordinate System}, {Transformations}
4403 */
4404 void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
4405 {
4406     if (!d_ptr->transformData)
4407         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4408
4409     QTransform newTransform(combine ? matrix * d_ptr->transformData->transform : matrix);
4410     if (d_ptr->transformData->transform == newTransform)
4411         return;
4412
4413     // Update and set the new transformation.
4414     if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
4415         d_ptr->setTransformHelper(newTransform);
4416         if (d_ptr->scenePosDescendants)
4417             d_ptr->sendScenePosChange();
4418         return;
4419     }
4420
4421     // Notify the item that the transformation matrix is changing.
4422     const QVariant newTransformVariant(itemChange(ItemTransformChange,
4423                                                   QVariant::fromValue<QTransform>(newTransform)));
4424     newTransform = qvariant_cast<QTransform>(newTransformVariant);
4425     if (d_ptr->transformData->transform == newTransform)
4426         return;
4427
4428     // Update and set the new transformation.
4429     d_ptr->setTransformHelper(newTransform);
4430
4431     // Send post-notification.
4432     itemChange(ItemTransformHasChanged, newTransformVariant);
4433     d_ptr->sendScenePosChange();
4434 }
4435
4436 /*!
4437     \obsolete
4438
4439     Use resetTransform() instead.
4440 */
4441 void QGraphicsItem::resetMatrix()
4442 {
4443     resetTransform();
4444 }
4445
4446 /*!
4447     \since 4.3
4448
4449     Resets this item's transformation matrix to the identity matrix or
4450     all the transformation properties to their default values.
4451     This is equivalent to calling \c setTransform(QTransform()).
4452
4453     \sa setTransform(), transform()
4454 */
4455 void QGraphicsItem::resetTransform()
4456 {
4457     setTransform(QTransform(), false);
4458 }
4459
4460 /*!
4461     \obsolete
4462
4463     Use
4464
4465     \code
4466     setRotation(rotation() + angle);
4467     \endcode
4468
4469     instead.
4470
4471     Rotates the current item transformation \a angle degrees clockwise around
4472     its origin. To translate around an arbitrary point (x, y), you need to
4473     combine translation and rotation with setTransform().
4474
4475     Example:
4476
4477     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 6
4478
4479     \sa setTransform(), transform(), scale(), shear(), translate()
4480 */
4481 void QGraphicsItem::rotate(qreal angle)
4482 {
4483     setTransform(QTransform().rotate(angle), true);
4484 }
4485
4486 /*!
4487     \obsolete
4488
4489     Use
4490
4491     \code
4492     setTransform(QTransform::fromScale(sx, sy), true);
4493     \endcode
4494
4495     instead.
4496
4497     Scales the current item transformation by (\a sx, \a sy) around its
4498     origin. To scale from an arbitrary point (x, y), you need to combine
4499     translation and scaling with setTransform().
4500
4501     Example:
4502
4503     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 7
4504
4505     \sa setTransform(), transform()
4506 */
4507 void QGraphicsItem::scale(qreal sx, qreal sy)
4508 {
4509     setTransform(QTransform::fromScale(sx, sy), true);
4510 }
4511
4512 /*!
4513     \obsolete
4514
4515     Use
4516
4517     \code
4518     setTransform(QTransform().shear(sh, sv), true);
4519     \endcode
4520
4521     instead.
4522
4523     Shears the current item transformation by (\a sh, \a sv).
4524
4525     \sa setTransform(), transform()
4526 */
4527 void QGraphicsItem::shear(qreal sh, qreal sv)
4528 {
4529     setTransform(QTransform().shear(sh, sv), true);
4530 }
4531
4532 /*!
4533     \obsolete
4534
4535     Use setPos() or setTransformOriginPoint() instead. For identical
4536     behavior, use
4537
4538     \code
4539     setTransform(QTransform::fromTranslate(dx, dy), true);
4540     \endcode
4541
4542     Translates the current item transformation by (\a dx, \a dy).
4543
4544     If all you want is to move an item, you should call moveBy() or
4545     setPos() instead; this function changes the item's translation,
4546     which is conceptually separate from its position.
4547
4548     \sa setTransform(), transform()
4549 */
4550 void QGraphicsItem::translate(qreal dx, qreal dy)
4551 {
4552     setTransform(QTransform::fromTranslate(dx, dy), true);
4553 }
4554
4555 /*!
4556     This virtual function is called twice for all items by the
4557     QGraphicsScene::advance() slot. In the first phase, all items are called
4558     with \a phase == 0, indicating that items on the scene are about to
4559     advance, and then all items are called with \a phase == 1. Reimplement
4560     this function to update your item if you need simple scene-controlled
4561     animation.
4562
4563     The default implementation does nothing.
4564
4565     For individual item animation, an alternative to this function is to
4566     either use QGraphicsItemAnimation, or to multiple-inherit from QObject and
4567     QGraphicsItem, and animate your item using QObject::startTimer() and
4568     QObject::timerEvent().
4569
4570     \sa QGraphicsItemAnimation, QTimeLine
4571 */
4572 void QGraphicsItem::advance(int phase)
4573 {
4574     Q_UNUSED(phase);
4575 }
4576
4577 /*!
4578     Returns the Z-value of the item. The Z-value affects the stacking order of
4579     sibling (neighboring) items.
4580
4581     The default Z-value is 0.
4582
4583     \sa setZValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
4584 */
4585 qreal QGraphicsItem::zValue() const
4586 {
4587     return d_ptr->z;
4588 }
4589
4590 /*!
4591     Sets the Z-value of the item to \a z. The Z value decides the stacking
4592     order of sibling (neighboring) items. A sibling item of high Z value will
4593     always be drawn on top of another sibling item with a lower Z value.
4594
4595     If you restore the Z value, the item's insertion order will decide its
4596     stacking order.
4597
4598     The Z-value does not affect the item's size in any way.
4599
4600     The default Z-value is 0.
4601
4602     \sa zValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
4603 */
4604 void QGraphicsItem::setZValue(qreal z)
4605 {
4606     const QVariant newZVariant(itemChange(ItemZValueChange, z));
4607     qreal newZ = newZVariant.toReal();
4608     if (newZ == d_ptr->z)
4609         return;
4610
4611     if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
4612         // Z Value has changed, we have to notify the index.
4613         d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
4614     }
4615
4616     d_ptr->z = newZ;
4617     if (d_ptr->parent)
4618         d_ptr->parent->d_ptr->needSortChildren = 1;
4619     else if (d_ptr->scene)
4620         d_ptr->scene->d_func()->needSortTopLevelItems = 1;
4621
4622     if (d_ptr->scene)
4623         d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
4624
4625     itemChange(ItemZValueHasChanged, newZVariant);
4626
4627     if (d_ptr->flags & ItemNegativeZStacksBehindParent)
4628         setFlag(QGraphicsItem::ItemStacksBehindParent, z < qreal(0.0));
4629
4630     if (d_ptr->isObject)
4631         emit static_cast<QGraphicsObject *>(this)->zChanged();
4632 }
4633
4634 /*!
4635     \internal
4636
4637     Ensures that the list of children is sorted by insertion order, and that
4638     the siblingIndexes are packed (no gaps), and start at 0.
4639
4640     ### This function is almost identical to
4641     QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes().
4642 */
4643 void QGraphicsItemPrivate::ensureSequentialSiblingIndex()
4644 {
4645     if (!sequentialOrdering) {
4646         qSort(children.begin(), children.end(), insertionOrder);
4647         sequentialOrdering = 1;
4648         needSortChildren = 1;
4649     }
4650     if (holesInSiblingIndex) {
4651         holesInSiblingIndex = 0;
4652         for (int i = 0; i < children.size(); ++i)
4653             children[i]->d_ptr->siblingIndex = i;
4654     }
4655 }
4656
4657 /*!
4658     \internal
4659 */
4660 inline void QGraphicsItemPrivate::sendScenePosChange()
4661 {
4662     Q_Q(QGraphicsItem);
4663     if (scene) {
4664         if (flags & QGraphicsItem::ItemSendsScenePositionChanges)
4665             q->itemChange(QGraphicsItem::ItemScenePositionHasChanged, q->scenePos());
4666         if (scenePosDescendants) {
4667             foreach (QGraphicsItem *item, scene->d_func()->scenePosItems) {
4668                 if (q->isAncestorOf(item))
4669                     item->itemChange(QGraphicsItem::ItemScenePositionHasChanged, item->scenePos());
4670             }
4671         }
4672     }
4673 }
4674
4675 /*!
4676     \since 4.6
4677
4678     Stacks this item before \a sibling, which must be a sibling item (i.e., the
4679     two items must share the same parent item, or must both be toplevel items).
4680     The \a sibling must have the same Z value as this item, otherwise calling
4681     this function will have no effect.
4682
4683     By default, all sibling items are stacked by insertion order (i.e., the
4684     first item you add is drawn before the next item you add). If two items' Z
4685     values are different, then the item with the highest Z value is drawn on
4686     top. When the Z values are the same, the insertion order will decide the
4687     stacking order.
4688
4689     \sa setZValue(), ItemStacksBehindParent, {QGraphicsItem#Sorting}{Sorting}
4690 */
4691 void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
4692 {
4693     if (sibling == this)
4694         return;
4695     if (!sibling || d_ptr->parent != sibling->parentItem()) {
4696         qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
4697         return;
4698     }
4699     QList<QGraphicsItem *> *siblings = d_ptr->parent
4700                                        ? &d_ptr->parent->d_ptr->children
4701                                        : (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0);
4702     if (!siblings) {
4703         qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
4704         return;
4705     }
4706
4707     // First, make sure that the sibling indexes have no holes. This also
4708     // marks the children list for sorting.
4709     if (d_ptr->parent)
4710         d_ptr->parent->d_ptr->ensureSequentialSiblingIndex();
4711     else
4712         d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
4713
4714     // Only move items with the same Z value, and that need moving.
4715     int siblingIndex = sibling->d_ptr->siblingIndex;
4716     int myIndex = d_ptr->siblingIndex;
4717     if (myIndex >= siblingIndex) {
4718         siblings->move(myIndex, siblingIndex);
4719         // Fixup the insertion ordering.
4720         for (int i = 0; i < siblings->size(); ++i) {
4721             int &index = siblings->at(i)->d_ptr->siblingIndex;
4722             if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
4723                 ++index;
4724         }
4725         d_ptr->siblingIndex = siblingIndex;
4726         for (int i = 0; i < siblings->size(); ++i) {
4727             int &index = siblings->at(i)->d_ptr->siblingIndex;
4728             if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
4729                 siblings->at(i)->d_ptr->siblingOrderChange();
4730         }
4731         d_ptr->siblingOrderChange();
4732     }
4733 }
4734
4735 /*!
4736     Returns the bounding rect of this item's descendants (i.e., its
4737     children, their children, etc.) in local coordinates. The
4738     rectangle will contain all descendants after they have been mapped
4739     to local coordinates. If the item has no children, this function
4740     returns an empty QRectF.
4741
4742     This does not include this item's own bounding rect; it only returns
4743     its descendants' accumulated bounding rect. If you need to include this
4744     item's bounding rect, you can add boundingRect() to childrenBoundingRect()
4745     using QRectF::operator|().
4746
4747     This function is linear in complexity; it determines the size of the
4748     returned bounding rect by iterating through all descendants.
4749
4750     \sa boundingRect(), sceneBoundingRect()
4751 */
4752 QRectF QGraphicsItem::childrenBoundingRect() const
4753 {
4754     if (!d_ptr->dirtyChildrenBoundingRect)
4755         return d_ptr->childrenBoundingRect;
4756
4757     d_ptr->childrenBoundingRect = QRectF();
4758     d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect, 0);
4759     d_ptr->dirtyChildrenBoundingRect = 0;
4760     return d_ptr->childrenBoundingRect;
4761 }
4762
4763 /*!
4764     \fn virtual QRectF QGraphicsItem::boundingRect() const = 0
4765
4766     This pure virtual function defines the outer bounds of the item as
4767     a rectangle; all painting must be restricted to inside an item's
4768     bounding rect. QGraphicsView uses this to determine whether the
4769     item requires redrawing.
4770
4771     Although the item's shape can be arbitrary, the bounding rect is
4772     always rectangular, and it is unaffected by the items'
4773     transformation.
4774
4775     If you want to change the item's bounding rectangle, you must first call
4776     prepareGeometryChange(). This notifies the scene of the imminent change,
4777     so that its can update its item geometry index; otherwise, the scene will
4778     be unaware of the item's new geometry, and the results are undefined
4779     (typically, rendering artifacts are left around in the view).
4780
4781     Reimplement this function to let QGraphicsView determine what
4782     parts of the widget, if any, need to be redrawn.
4783
4784     Note: For shapes that paint an outline / stroke, it is important
4785     to include half the pen width in the bounding rect. It is not
4786     necessary to compensate for antialiasing, though.
4787
4788     Example:
4789
4790     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 8
4791
4792     \sa boundingRegion(), shape(), contains(), {The Graphics View Coordinate
4793     System}, prepareGeometryChange()
4794 */
4795
4796 /*!
4797     Returns the bounding rect of this item in scene coordinates, by combining
4798     sceneTransform() with boundingRect().
4799
4800     \sa boundingRect(), {The Graphics View Coordinate System}
4801 */
4802 QRectF QGraphicsItem::sceneBoundingRect() const
4803 {
4804     // Find translate-only offset
4805     // COMBINE
4806     QPointF offset;
4807     const QGraphicsItem *parentItem = this;
4808     const QGraphicsItemPrivate *itemd;
4809     do {
4810         itemd = parentItem->d_ptr.data();
4811         if (itemd->transformData)
4812             break;
4813         offset += itemd->pos;
4814     } while ((parentItem = itemd->parent));
4815
4816     QRectF br = boundingRect();
4817     br.translate(offset);
4818     if (!parentItem)
4819         return br;
4820     if (parentItem->d_ptr->hasTranslateOnlySceneTransform()) {
4821         br.translate(parentItem->d_ptr->sceneTransform.dx(), parentItem->d_ptr->sceneTransform.dy());
4822         return br;
4823     }
4824     return parentItem->d_ptr->sceneTransform.mapRect(br);
4825 }
4826
4827 /*!
4828     Returns the shape of this item as a QPainterPath in local
4829     coordinates. The shape is used for many things, including collision
4830     detection, hit tests, and for the QGraphicsScene::items() functions.
4831
4832     The default implementation calls boundingRect() to return a simple
4833     rectangular shape, but subclasses can reimplement this function to return
4834     a more accurate shape for non-rectangular items. For example, a round item
4835     may choose to return an elliptic shape for better collision detection. For
4836     example:
4837
4838     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 9
4839
4840     The outline of a shape can vary depending on the width and style of the
4841     pen used when drawing. If you want to include this outline in the item's
4842     shape, you can create a shape from the stroke using QPainterPathStroker.
4843
4844     This function is called by the default implementations of contains() and
4845     collidesWithPath().
4846
4847     \sa boundingRect(), contains(), prepareGeometryChange(), QPainterPathStroker
4848 */
4849 QPainterPath QGraphicsItem::shape() const
4850 {
4851     QPainterPath path;
4852     path.addRect(boundingRect());
4853     return path;
4854 }
4855
4856 /*!
4857     Returns true if this item is clipped. An item is clipped if it has either
4858     set the \l ItemClipsToShape flag, or if it or any of its ancestors has set
4859     the \l ItemClipsChildrenToShape flag.
4860
4861     Clipping affects the item's appearance (i.e., painting), as well as mouse
4862     and hover event delivery.
4863
4864     \sa clipPath(), shape(), setFlags()
4865 */
4866 bool QGraphicsItem::isClipped() const
4867 {
4868     Q_D(const QGraphicsItem);
4869     return (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
4870         || (d->flags & QGraphicsItem::ItemClipsToShape);
4871 }
4872
4873 /*!
4874     \since 4.5
4875
4876     Returns this item's clip path, or an empty QPainterPath if this item is
4877     not clipped. The clip path constrains the item's appearance and
4878     interaction (i.e., restricts the area the item can draw, and it also
4879     restricts the area that the item receives events).
4880
4881     You can enable clipping by setting the ItemClipsToShape or
4882     ItemClipsChildrenToShape flags. The item's clip path is calculated by
4883     intersecting all clipping ancestors' shapes. If the item sets
4884     ItemClipsToShape, the final clip is intersected with the item's own shape.
4885
4886     \note Clipping introduces a performance penalty for all items involved;
4887     you should generally avoid using clipping if you can (e.g., if your items
4888     always draw inside boundingRect() or shape() boundaries, clipping is not
4889     necessary).
4890
4891     \sa isClipped(), shape(), setFlags()
4892 */
4893 QPainterPath QGraphicsItem::clipPath() const
4894 {
4895     Q_D(const QGraphicsItem);
4896     if (!isClipped())
4897         return QPainterPath();
4898
4899     const QRectF thisBoundingRect(boundingRect());
4900     if (thisBoundingRect.isEmpty())
4901         return QPainterPath();
4902
4903     QPainterPath clip;
4904     // Start with the item's bounding rect.
4905     clip.addRect(thisBoundingRect);
4906
4907     if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
4908         const QGraphicsItem *parent = this;
4909         const QGraphicsItem *lastParent = this;
4910
4911         // Intersect any in-between clips starting at the top and moving downwards.
4912         while ((parent = parent->d_ptr->parent)) {
4913             if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
4914                 // Map clip to the current parent and intersect with its shape/clipPath
4915                 clip = lastParent->itemTransform(parent).map(clip);
4916                 clip = clip.intersected(parent->shape());
4917                 if (clip.isEmpty())
4918                     return clip;
4919                 lastParent = parent;
4920             }
4921
4922             if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
4923                 break;
4924         }
4925
4926         if (lastParent != this) {
4927             // Map clip back to the item's transform.
4928             // ### what if itemtransform fails
4929             clip = lastParent->itemTransform(this).map(clip);
4930         }
4931     }
4932
4933     if (d->flags & ItemClipsToShape)
4934         clip = clip.intersected(shape());
4935
4936     return clip;
4937 }
4938
4939 /*!
4940     Returns true if this item contains \a point, which is in local
4941     coordinates; otherwise, false is returned. It is most often called from
4942     QGraphicsView to determine what item is under the cursor, and for that
4943     reason, the implementation of this function should be as light-weight as
4944     possible.
4945
4946     By default, this function calls shape(), but you can reimplement it in a
4947     subclass to provide a (perhaps more efficient) implementation.
4948
4949     \sa shape(), boundingRect(), collidesWithPath()
4950 */
4951 bool QGraphicsItem::contains(const QPointF &point) const
4952 {
4953     return isClipped() ? clipPath().contains(point) : shape().contains(point);
4954 }
4955
4956 /*!
4957
4958     Returns true if this item collides with \a other; otherwise
4959     returns false.
4960
4961     The \a mode is applied to \a other, and the resulting shape or
4962     bounding rectangle is then compared to this item's shape. The
4963     default value for \a mode is Qt::IntersectsItemShape; \a other
4964     collides with this item if it either intersects, contains, or is
4965     contained by this item's shape (see Qt::ItemSelectionMode for
4966     details).
4967
4968     The default implementation is based on shape intersection, and it calls
4969     shape() on both items. Because the complexity of arbitrary shape-shape
4970     intersection grows with an order of magnitude when the shapes are complex,
4971     this operation can be noticably time consuming. You have the option of
4972     reimplementing this function in a subclass of QGraphicsItem to provide a
4973     custom algorithm. This allows you to make use of natural constraints in
4974     the shapes of your own items, in order to improve the performance of the
4975     collision detection. For instance, two untransformed perfectly circular
4976     items' collision can be determined very efficiently by comparing their
4977     positions and radii.
4978
4979     Keep in mind that when reimplementing this function and calling shape() or
4980     boundingRect() on \a other, the returned coordinates must be mapped to
4981     this item's coordinate system before any intersection can take place.
4982
4983     \sa contains(), shape()
4984 */
4985 bool QGraphicsItem::collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode) const
4986 {
4987     if (other == this)
4988         return true;
4989     if (!other)
4990         return false;
4991     // The items share the same clip if their closest clipper is the same, or
4992     // if one clips the other.
4993     bool clips = (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
4994     bool otherClips = (other->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
4995     if (clips || otherClips) {
4996         const QGraphicsItem *closestClipper = isAncestorOf(other) ? this : parentItem();
4997         while (closestClipper && !(closestClipper->flags() & ItemClipsChildrenToShape))
4998             closestClipper = closestClipper->parentItem();
4999         const QGraphicsItem *otherClosestClipper = other->isAncestorOf(this) ? other : other->parentItem();
5000         while (otherClosestClipper && !(otherClosestClipper->flags() & ItemClipsChildrenToShape))
5001             otherClosestClipper = otherClosestClipper->parentItem();
5002         if (closestClipper == otherClosestClipper) {
5003             d_ptr->localCollisionHack = 1;
5004             bool res = collidesWithPath(mapFromItem(other, other->shape()), mode);
5005             d_ptr->localCollisionHack = 0;
5006             return res;
5007         }
5008     }
5009
5010     QPainterPath otherShape = other->isClipped() ? other->clipPath() : other->shape();
5011     return collidesWithPath(mapFromItem(other, otherShape), mode);
5012 }
5013
5014 /*!
5015     Returns true if this item collides with \a path.
5016
5017     The collision is determined by \a mode. The default value for \a mode is
5018     Qt::IntersectsItemShape; \a path collides with this item if it either
5019     intersects, contains, or is contained by this item's shape.
5020
5021     Note that this function checks whether the item's shape or
5022     bounding rectangle (depending on \a mode) is contained within \a
5023     path, and not whether \a path is contained within the items shape
5024     or bounding rectangle.
5025
5026     \sa collidesWithItem(), contains(), shape()
5027 */
5028 bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelectionMode mode) const
5029 {
5030     if (path.isEmpty()) {
5031         // No collision with empty paths.
5032         return false;
5033     }
5034
5035     QRectF rectA(boundingRect());
5036     _q_adjustRect(&rectA);
5037     QRectF rectB(path.controlPointRect());
5038     _q_adjustRect(&rectB);
5039     if (!rectA.intersects(rectB)) {
5040         // This we can determine efficiently. If the two rects neither
5041         // intersect nor contain eachother, then the two items do not collide.
5042         return false;
5043     }
5044
5045     // For further testing, we need this item's shape or bounding rect.
5046     QPainterPath thisShape;
5047     if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape)
5048         thisShape = (isClipped() && !d_ptr->localCollisionHack) ? clipPath() : shape();
5049     else
5050         thisShape.addRect(rectA);
5051
5052     if (thisShape == QPainterPath()) {
5053         // Empty shape? No collision.
5054         return false;
5055     }
5056
5057     // Use QPainterPath boolean operations to determine the collision, O(N*logN).
5058     if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
5059         return path.intersects(thisShape);
5060     return path.contains(thisShape);
5061 }
5062
5063 /*!
5064     Returns a list of all items that collide with this item.
5065
5066     The way collisions are detected is determined by applying \a mode
5067     to items that are compared to this item, i.e., each item's shape
5068     or bounding rectangle is checked against this item's shape. The
5069     default value for \a mode is Qt::IntersectsItemShape.
5070
5071     \sa collidesWithItem()
5072 */
5073 QList<QGraphicsItem *> QGraphicsItem::collidingItems(Qt::ItemSelectionMode mode) const
5074 {
5075     if (d_ptr->scene)
5076         return d_ptr->scene->collidingItems(this, mode);
5077     return QList<QGraphicsItem *>();
5078 }
5079
5080 /*!
5081     Returns true if this item's bounding rect is completely obscured by the
5082     opaque shape of any of colliding items above it (i.e., with a higher Z
5083     value than this item).
5084
5085     Its implementation is based on calling isObscuredBy(), which you can
5086     reimplement to provide a custom obscurity algorithm.
5087
5088   \sa opaqueArea()
5089 */
5090 bool QGraphicsItem::isObscured() const
5091 {
5092     return isObscured(QRectF());
5093 }
5094
5095 /*!
5096     \internal
5097
5098     Item obscurity helper function.
5099
5100     Returns true if the subrect \a rect of \a item's bounding rect is obscured
5101     by \a other (i.e., \a other's opaque area covers \a item's \a rect
5102     completely. \a other is assumed to already be "on top of" \a item
5103     wrt. stacking order.
5104 */
5105 static bool qt_QGraphicsItem_isObscured(const QGraphicsItem *item,
5106                                         const QGraphicsItem *other,
5107                                         const QRectF &rect)
5108 {
5109     return other->mapToItem(item, other->opaqueArea()).contains(rect);
5110 }
5111
5112 /*!
5113     \overload
5114     \since 4.3
5115
5116     Returns true if \a rect is completely obscured by the opaque shape of any
5117     of colliding items above it (i.e., with a higher Z value than this item).
5118
5119     Unlike the default isObscured() function, this function does not call
5120     isObscuredBy().
5121
5122     \sa opaqueArea()
5123 */
5124 bool QGraphicsItem::isObscured(const QRectF &rect) const
5125 {
5126     Q_D(const QGraphicsItem);
5127     if (!d->scene)
5128         return false;
5129
5130     QRectF br = boundingRect();
5131     QRectF testRect = rect.isNull() ? br : rect;
5132
5133     foreach (QGraphicsItem *item, d->scene->items(mapToScene(br), Qt::IntersectsItemBoundingRect)) {
5134         if (item == this)
5135             break;
5136         if (qt_QGraphicsItem_isObscured(this, item, testRect))
5137             return true;
5138     }
5139     return false;
5140 }
5141
5142 /*!
5143     \fn bool QGraphicsItem::isObscured(qreal x, qreal y, qreal w, qreal h) const
5144     \since 4.3
5145
5146     This convenience function is equivalent to calling isObscured(QRectF(\a x, \a y, \a w, \a h)).
5147 */
5148
5149 /*!
5150     Returns true if this item's bounding rect is completely obscured by the
5151     opaque shape of \a item.
5152
5153     The base implementation maps \a item's opaqueArea() to this item's
5154     coordinate system, and then checks if this item's boundingRect() is fully
5155     contained within the mapped shape.
5156
5157     You can reimplement this function to provide a custom algorithm for
5158     determining whether this item is obscured by \a item.
5159
5160     \sa opaqueArea(), isObscured()
5161 */
5162 bool QGraphicsItem::isObscuredBy(const QGraphicsItem *item) const
5163 {
5164     if (!item)
5165         return false;
5166     return qt_closestItemFirst(item, this)
5167         && qt_QGraphicsItem_isObscured(this, item, boundingRect());
5168 }
5169
5170 /*!
5171     This virtual function returns a shape representing the area where this
5172     item is opaque. An area is opaque if it is filled using an opaque brush or
5173     color (i.e., not transparent).
5174
5175     This function is used by isObscuredBy(), which is called by underlying
5176     items to determine if they are obscured by this item.
5177
5178     The default implementation returns an empty QPainterPath, indicating that
5179     this item is completely transparent and does not obscure any other items.
5180
5181     \sa isObscuredBy(), isObscured(), shape()
5182 */
5183 QPainterPath QGraphicsItem::opaqueArea() const
5184 {
5185     return QPainterPath();
5186 }
5187
5188 /*!
5189     \since 4.4
5190
5191     Returns the bounding region for this item. The coordinate space of the
5192     returned region depends on \a itemToDeviceTransform. If you pass an
5193     identity QTransform as a parameter, this function will return a local
5194     coordinate region.
5195
5196     The bounding region describes a coarse outline of the item's visual
5197     contents. Although it's expensive to calculate, it's also more precise
5198     than boundingRect(), and it can help to avoid unnecessary repainting when
5199     an item is updated. This is particularly efficient for thin items (e.g.,
5200     lines or simple polygons). You can tune the granularity for the bounding
5201     region by calling setBoundingRegionGranularity(). The default granularity
5202     is 0; in which the item's bounding region is the same as its bounding
5203     rect.
5204
5205     \a itemToDeviceTransform is the transformation from item coordinates to
5206     device coordinates. If you want this function to return a QRegion in scene
5207     coordinates, you can pass sceneTransform() as an argument.
5208
5209     \sa boundingRegionGranularity()
5210 */
5211 QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) const
5212 {
5213     // ### Ideally we would have a better way to generate this region,
5214     // preferably something in the lines of QPainterPath::toRegion(QTransform)
5215     // coupled with a way to generate a painter path from a set of painter
5216     // operations (e.g., QPicture::toPainterPath() or so). The current
5217     // approach generates a bitmap with the size of the item's bounding rect
5218     // in device coordinates, scaled by b.r.granularity, then paints the item
5219     // into the bitmap, converts the result to a QRegion and scales the region
5220     // back to device space with inverse granularity.
5221     qreal granularity = boundingRegionGranularity();
5222     QRect deviceRect = itemToDeviceTransform.mapRect(boundingRect()).toRect();
5223     _q_adjustRect(&deviceRect);
5224     if (granularity == 0.0)
5225         return QRegion(deviceRect);
5226
5227     int pad = 1;
5228     QSize bitmapSize(qMax(1, int(deviceRect.width() * granularity) + pad * 2),
5229                      qMax(1, int(deviceRect.height() * granularity) + pad * 2));
5230     QImage mask(bitmapSize, QImage::Format_ARGB32_Premultiplied);
5231     mask.fill(0);
5232     QPainter p(&mask);
5233     p.setRenderHints(QPainter::Antialiasing);
5234
5235     // Transform painter (### this code is from QGraphicsScene::drawItemHelper
5236     // and doesn't work properly with perspective transformations).
5237     QPointF viewOrigo = itemToDeviceTransform.map(QPointF(0,  0));
5238     QPointF offset = viewOrigo - deviceRect.topLeft();
5239     p.scale(granularity, granularity);
5240     p.translate(offset);
5241     p.translate(pad, pad);
5242     p.setWorldTransform(itemToDeviceTransform, true);
5243     p.translate(itemToDeviceTransform.inverted().map(QPointF(0, 0)));
5244
5245     // Render
5246     QStyleOptionGraphicsItem option;
5247     const_cast<QGraphicsItem *>(this)->paint(&p, &option, 0);
5248     p.end();
5249
5250     // Transform QRegion back to device space
5251     QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity);
5252     QRegion r;
5253     QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0));
5254     foreach (const QRect &rect, QRegion( colorMask ).rects()) {
5255         QRect xrect = unscale.mapRect(rect).translated(deviceRect.topLeft() - QPoint(pad, pad));
5256         r += xrect.adjusted(-1, -1, 1, 1) & deviceRect;
5257     }
5258     return r;
5259 }
5260
5261 /*!
5262     \since 4.4
5263
5264     Returns the item's bounding region granularity; a value between and
5265     including 0 and 1. The default value is 0 (i.e., the lowest granularity,
5266     where the bounding region corresponds to the item's bounding rectangle).
5267
5268 \omit
5269 ### NOTE
5270 \endomit
5271
5272     \sa setBoundingRegionGranularity()
5273 */
5274 qreal QGraphicsItem::boundingRegionGranularity() const
5275 {
5276     return d_ptr->hasBoundingRegionGranularity
5277         ? qvariant_cast<qreal>(d_ptr->extra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity))
5278         : 0;
5279 }
5280
5281 /*!
5282     \since 4.4
5283     Sets the bounding region granularity to \a granularity; a value between
5284     and including 0 and 1. The default value is 0 (i.e., the lowest
5285     granularity, where the bounding region corresponds to the item's bounding
5286     rectangle).
5287
5288     The granularity is used by boundingRegion() to calculate how fine the
5289     bounding region of the item should be. The highest achievable granularity
5290     is 1, where boundingRegion() will return the finest outline possible for
5291     the respective device (e.g., for a QGraphicsView viewport, this gives you
5292     a pixel-perfect bounding region). The lowest possible granularity is
5293     0. The value of \a granularity describes the ratio between device
5294     resolution and the resolution of the bounding region (e.g., a value of
5295     0.25 will provide a region where each chunk corresponds to 4x4 device
5296     units / pixels).
5297
5298     \sa boundingRegionGranularity()
5299 */
5300 void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
5301 {
5302     if (granularity < 0.0 || granularity > 1.0) {
5303         qWarning("QGraphicsItem::setBoundingRegionGranularity: invalid granularity %g", granularity);
5304         return;
5305     }
5306     if (granularity == 0.0) {
5307         d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity);
5308         d_ptr->hasBoundingRegionGranularity = 0;
5309         return;
5310     }
5311     d_ptr->hasBoundingRegionGranularity = 1;
5312     d_ptr->setExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity,
5313                     QVariant::fromValue<qreal>(granularity));
5314 }
5315
5316 /*!
5317     \fn virtual void QGraphicsItem::paint(QPainter *painter, const
5318     QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0
5319
5320     This function, which is usually called by QGraphicsView, paints the
5321     contents of an item in local coordinates.
5322
5323     Reimplement this function in a QGraphicsItem subclass to provide the
5324     item's painting implementation, using \a painter. The \a option parameter
5325     provides style options for the item, such as its state, exposed area and
5326     its level-of-detail hints. The \a widget argument is optional. If
5327     provided, it points to the widget that is being painted on; otherwise, it
5328     is 0. For cached painting, \a widget is always 0.
5329
5330     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 10
5331
5332     The painter's pen is 0-width by default, and its pen is initialized to the
5333     QPalette::Text brush from the paint device's palette. The brush is
5334     initialized to QPalette::Window.
5335
5336     Make sure to constrain all painting inside the boundaries of
5337     boundingRect() to avoid rendering artifacts (as QGraphicsView does not
5338     clip the painter for you). In particular, when QPainter renders the
5339     outline of a shape using an assigned QPen, half of the outline will be
5340     drawn outside, and half inside, the shape you're rendering (e.g., with a
5341     pen width of 2 units, you must draw outlines 1 unit inside
5342     boundingRect()). QGraphicsItem does not support use of cosmetic pens with
5343     a non-zero width.
5344
5345     All painting is done in local coordinates.
5346
5347     \sa setCacheMode(), QPen::width(), {Item Coordinates}, ItemUsesExtendedStyleOption
5348 */
5349
5350 /*!
5351     \internal
5352     Returns true if we can discard an update request; otherwise false.
5353 */
5354 bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreVisibleBit, bool ignoreDirtyBit,
5355                                                 bool ignoreOpacity) const
5356 {
5357     // No scene, or if the scene is updating everything, means we have nothing
5358     // to do. The only exception is if the scene tracks the growing scene rect.
5359     return !scene
5360            || (!visible && !ignoreVisibleBit && !this->ignoreVisible)
5361            || (!ignoreDirtyBit && fullUpdatePending)
5362            || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent());
5363 }
5364
5365 /*!
5366     \internal
5367 */
5368 int QGraphicsItemPrivate::depth() const
5369 {
5370     if (itemDepth == -1)
5371         const_cast<QGraphicsItemPrivate *>(this)->resolveDepth();
5372
5373     return itemDepth;
5374 }
5375
5376 /*!
5377     \internal
5378 */
5379 #ifndef QT_NO_GRAPHICSEFFECT
5380 void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
5381 {
5382     QGraphicsItemPrivate *itemPrivate = this;
5383     do {
5384         if (itemPrivate->graphicsEffect) {
5385             itemPrivate->notifyInvalidated = 1;
5386
5387             if (!itemPrivate->updateDueToGraphicsEffect)
5388                 static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
5389         }
5390     } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
5391 }
5392
5393 void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason)
5394 {
5395     if (!mayHaveChildWithGraphicsEffect)
5396         return;
5397
5398     for (int i = 0; i < children.size(); ++i) {
5399         QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data();
5400         if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity))
5401             continue;
5402         if (childPrivate->graphicsEffect) {
5403             childPrivate->notifyInvalidated = 1;
5404             static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
5405         }
5406
5407         childPrivate->invalidateChildGraphicsEffectsRecursively(reason);
5408     }
5409 }
5410 #endif //QT_NO_GRAPHICSEFFECT
5411
5412 /*!
5413     \internal
5414 */
5415 void QGraphicsItemPrivate::invalidateDepthRecursively()
5416 {
5417     if (itemDepth == -1)
5418         return;
5419
5420     itemDepth = -1;
5421     for (int i = 0; i < children.size(); ++i)
5422         children.at(i)->d_ptr->invalidateDepthRecursively();
5423 }
5424
5425 /*!
5426     \internal
5427
5428     Resolves the stacking depth of this object and all its ancestors.
5429 */
5430 void QGraphicsItemPrivate::resolveDepth()
5431 {
5432     if (!parent)
5433         itemDepth = 0;
5434     else {
5435         if (parent->d_ptr->itemDepth == -1)
5436             parent->d_ptr->resolveDepth();
5437         itemDepth = parent->d_ptr->itemDepth + 1;
5438     }
5439 }
5440
5441 /*!
5442     \internal
5443
5444     ### This function is almost identical to
5445     QGraphicsScenePrivate::registerTopLevelItem().
5446 */
5447 void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
5448 {
5449     // Remove all holes from the sibling index list. Now the max index
5450     // number is equal to the size of the children list.
5451     ensureSequentialSiblingIndex();
5452     needSortChildren = 1; // ### maybe 0
5453     child->d_ptr->siblingIndex = children.size();
5454     children.append(child);
5455     if (isObject)
5456         emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
5457 }
5458
5459 /*!
5460     \internal
5461
5462     ### This function is almost identical to
5463     QGraphicsScenePrivate::unregisterTopLevelItem().
5464 */
5465 void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
5466 {
5467     // When removing elements in the middle of the children list,
5468     // there will be a "gap" in the list of sibling indexes (0,1,3,4).
5469     if (!holesInSiblingIndex)
5470         holesInSiblingIndex = child->d_ptr->siblingIndex != children.size() - 1;
5471     if (sequentialOrdering && !holesInSiblingIndex)
5472         children.removeAt(child->d_ptr->siblingIndex);
5473     else
5474         children.removeOne(child);
5475     // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
5476     // the child is not guaranteed to be at the index after the list is sorted.
5477     // (see ensureSortedChildren()).
5478     child->d_ptr->siblingIndex = -1;
5479     if (isObject)
5480         emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
5481 }
5482
5483 /*!
5484     \internal
5485 */
5486 QGraphicsItemCache *QGraphicsItemPrivate::maybeExtraItemCache() const
5487 {
5488     return (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5489 }
5490
5491 /*!
5492     \internal
5493 */
5494 QGraphicsItemCache *QGraphicsItemPrivate::extraItemCache() const
5495 {
5496     QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5497     if (!c) {
5498         QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this);
5499         c = new QGraphicsItemCache;
5500         that->setExtra(ExtraCacheData, QVariant::fromValue<void *>(c));
5501     }
5502     return c;
5503 }
5504
5505 /*!
5506     \internal
5507 */
5508 void QGraphicsItemPrivate::removeExtraItemCache()
5509 {
5510     QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5511     if (c) {
5512         c->purge();
5513         delete c;
5514     }
5515     unsetExtra(ExtraCacheData);
5516 }
5517
5518 void QGraphicsItemPrivate::updatePaintedViewBoundingRects(bool updateChildren)
5519 {
5520     if (!scene)
5521         return;
5522
5523     for (int i = 0; i < scene->d_func()->views.size(); ++i) {
5524         QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func();
5525         QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport);
5526         rect.translate(viewPrivate->dirtyScrollOffset);
5527         viewPrivate->updateRect(rect);
5528     }
5529
5530     if (updateChildren) {
5531         for (int i = 0; i < children.size(); ++i)
5532             children.at(i)->d_ptr->updatePaintedViewBoundingRects(true);
5533     }
5534 }
5535
5536 // Traverses all the ancestors up to the top-level and updates the pointer to
5537 // always point to the top-most item that has a dirty scene transform.
5538 // It then backtracks to the top-most dirty item and start calculating the
5539 // scene transform by combining the item's transform (+pos) with the parent's
5540 // cached scene transform (which we at this point know for sure is valid).
5541 void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem)
5542 {
5543     Q_ASSERT(topMostDirtyItem);
5544
5545     if (dirtySceneTransform)
5546         *topMostDirtyItem = q_ptr;
5547
5548     if (parent)
5549         parent->d_ptr->ensureSceneTransformRecursive(topMostDirtyItem);
5550
5551     if (*topMostDirtyItem == q_ptr) {
5552         if (!dirtySceneTransform)
5553             return; // OK, neither my ancestors nor I have dirty scene transforms.
5554         *topMostDirtyItem = 0;
5555     } else if (*topMostDirtyItem) {
5556         return; // Continue backtrack.
5557     }
5558
5559     // This item and all its descendants have dirty scene transforms.
5560     // We're about to validate this item's scene transform, so we have to
5561     // invalidate all the children; otherwise there's no way for the descendants
5562     // to detect that the ancestor has changed.
5563     invalidateChildrenSceneTransform();
5564
5565     // COMBINE my transform with the parent's scene transform.
5566     updateSceneTransformFromParent();
5567     Q_ASSERT(!dirtySceneTransform);
5568 }
5569
5570 /*!
5571     \internal
5572 */
5573 void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
5574 {
5575     // Update focus child chain. Stop at panels, or if this item
5576     // is hidden, stop at the first item with a visible parent.
5577     QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
5578     if (parent->panel() != q_ptr->panel())
5579         return;
5580
5581     do {
5582         // Clear any existing ancestor's subFocusItem.
5583         if (parent != q_ptr && parent->d_ptr->subFocusItem) {
5584             if (parent->d_ptr->subFocusItem == q_ptr)
5585                 break;
5586             parent->d_ptr->subFocusItem->d_ptr->clearSubFocus(0, stopItem);
5587         }
5588         parent->d_ptr->subFocusItem = q_ptr;
5589         parent->d_ptr->subFocusItemChange();
5590     } while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
5591
5592     if (scene && !scene->isActive()) {
5593         scene->d_func()->passiveFocusItem = subFocusItem;
5594         scene->d_func()->lastFocusItem = subFocusItem;
5595     }
5596 }
5597
5598 /*!
5599     \internal
5600 */
5601 void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
5602 {
5603     // Reset sub focus chain.
5604     QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
5605     do {
5606         if (parent->d_ptr->subFocusItem != q_ptr)
5607             break;
5608         parent->d_ptr->subFocusItem = 0;
5609         if (parent != stopItem && !parent->isAncestorOf(stopItem))
5610             parent->d_ptr->subFocusItemChange();
5611     } while (!parent->isPanel() && (parent = parent->d_ptr->parent));
5612 }
5613
5614 /*!
5615     \internal
5616
5617     Sets the focusProxy pointer to 0 for all items that have this item as their
5618     focusProxy. ### Qt 5: Use QPointer instead.
5619 */
5620 void QGraphicsItemPrivate::resetFocusProxy()
5621 {
5622     for (int i = 0; i < focusProxyRefs.size(); ++i)
5623         *focusProxyRefs.at(i) = 0;
5624     focusProxyRefs.clear();
5625 }
5626
5627 /*!
5628     \internal
5629
5630     Subclasses can reimplement this function to be notified when subFocusItem
5631     changes.
5632 */
5633 void QGraphicsItemPrivate::subFocusItemChange()
5634 {
5635 }
5636
5637 /*!
5638     \internal
5639
5640     Subclasses can reimplement this function to be notified when an item
5641     becomes a focusScopeItem (or is no longer a focusScopeItem).
5642 */
5643 void QGraphicsItemPrivate::focusScopeItemChange(bool isSubFocusItem)
5644 {
5645     Q_UNUSED(isSubFocusItem);
5646 }
5647
5648 /*!
5649     \internal
5650
5651     Subclasses can reimplement this function to be notified when its
5652     siblingIndex order is changed.
5653 */
5654 void QGraphicsItemPrivate::siblingOrderChange()
5655 {
5656 }
5657
5658 /*!
5659     \internal
5660
5661     Tells us if it is a proxy widget
5662 */
5663 bool QGraphicsItemPrivate::isProxyWidget() const
5664 {
5665     return false;
5666 }
5667
5668 /*!
5669     Schedules a redraw of the area covered by \a rect in this item. You can
5670     call this function whenever your item needs to be redrawn, such as if it
5671     changes appearance or size.
5672
5673     This function does not cause an immediate paint; instead it schedules a
5674     paint request that is processed by QGraphicsView after control reaches the
5675     event loop. The item will only be redrawn if it is visible in any
5676     associated view.
5677
5678     As a side effect of the item being repainted, other items that overlap the
5679     area \a rect may also be repainted.
5680
5681     If the item is invisible (i.e., isVisible() returns false), this function
5682     does nothing.
5683
5684     \sa paint(), boundingRect()
5685 */
5686 void QGraphicsItem::update(const QRectF &rect)
5687 {
5688     if (rect.isEmpty() && !rect.isNull())
5689         return;
5690
5691     // Make sure we notify effects about invalidated source.
5692 #ifndef QT_NO_GRAPHICSEFFECT
5693     d_ptr->invalidateParentGraphicsEffectsRecursively();
5694 #endif //QT_NO_GRAPHICSEFFECT
5695
5696     if (CacheMode(d_ptr->cacheMode) != NoCache) {
5697         // Invalidate cache.
5698         QGraphicsItemCache *cache = d_ptr->extraItemCache();
5699         if (!cache->allExposed) {
5700             if (rect.isNull()) {
5701                 cache->allExposed = true;
5702                 cache->exposed.clear();
5703             } else {
5704                 cache->exposed.append(rect);
5705             }
5706         }
5707         // Only invalidate cache; item is already dirty.
5708         if (d_ptr->fullUpdatePending)
5709             return;
5710     }
5711
5712     if (d_ptr->scene)
5713         d_ptr->scene->d_func()->markDirty(this, rect);
5714 }
5715
5716 /*!
5717     \since 4.4
5718     Scrolls the contents of \a rect by \a dx, \a dy. If \a rect is a null rect
5719     (the default), the item's bounding rect is scrolled.
5720
5721     Scrolling provides a fast alternative to simply redrawing when the
5722     contents of the item (or parts of the item) are shifted vertically or
5723     horizontally. Depending on the current transformation and the capabilities
5724     of the paint device (i.e., the viewport), this operation may consist of
5725     simply moving pixels from one location to another using memmove(). In most
5726     cases this is faster than rerendering the entire area.
5727
5728     After scrolling, the item will issue an update for the newly exposed
5729     areas. If scrolling is not supported (e.g., you are rendering to an OpenGL
5730     viewport, which does not benefit from scroll optimizations), this function
5731     is equivalent to calling update(\a rect).
5732
5733     \b{Note:} Scrolling is only supported when QGraphicsItem::ItemCoordinateCache
5734     is enabled; in all other cases calling this function is equivalent to calling
5735     update(\a rect). If you for sure know that the item is opaque and not overlapped
5736     by other items, you can map the \a rect to viewport coordinates and scroll the
5737     viewport.
5738
5739     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 19
5740
5741     \sa boundingRect()
5742 */
5743 void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
5744 {
5745     Q_D(QGraphicsItem);
5746     if (dx == 0.0 && dy == 0.0)
5747         return;
5748     if (!d->scene)
5749         return;
5750
5751     // Accelerated scrolling means moving pixels from one location to another
5752     // and only redraw the newly exposed area. The following requirements must
5753     // be fulfilled in order to do that:
5754     //
5755     // 1) Item is opaque.
5756     // 2) Item is not overlapped by other items.
5757     //
5758     // There's (yet) no way to detect whether an item is opaque or not, which means
5759     // we cannot do accelerated scrolling unless the cache is enabled. In case of using
5760     // DeviceCoordinate cache we also have to take the device transform into account in
5761     // order to determine whether we can do accelerated scrolling or not. That's left out
5762     // for simplicity here, but it is definitely something we can consider in the future
5763     // as a performance improvement.
5764     if (d->cacheMode != QGraphicsItem::ItemCoordinateCache
5765         || !qFuzzyIsNull(dx - int(dx)) || !qFuzzyIsNull(dy - int(dy))) {
5766         update(rect);
5767         return;
5768     }
5769
5770     QGraphicsItemCache *cache = d->extraItemCache();
5771     if (cache->allExposed || cache->fixedSize.isValid()) {
5772         // Cache is either invalidated or item is scaled (see QGraphicsItem::setCacheMode).
5773         update(rect);
5774         return;
5775     }
5776
5777     // Find pixmap in cache.
5778     QPixmap cachedPixmap;
5779     if (!QPixmapCache::find(cache->key, &cachedPixmap)) {
5780         update(rect);
5781         return;
5782     }
5783
5784     QRect scrollRect = (rect.isNull() ? boundingRect() : rect).toAlignedRect();
5785     if (!scrollRect.intersects(cache->boundingRect))
5786         return; // Nothing to scroll.
5787
5788     // Remove from cache to avoid deep copy when modifying.
5789     QPixmapCache::remove(cache->key);
5790
5791     QRegion exposed;
5792     cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed);
5793
5794     // Reinsert into cache.
5795     cache->key = QPixmapCache::insert(cachedPixmap);
5796
5797     // Translate the existing expose.
5798     for (int i = 0; i < cache->exposed.size(); ++i) {
5799         QRectF &e = cache->exposed[i];
5800         if (!rect.isNull() && !e.intersects(rect))
5801             continue;
5802         e.translate(dx, dy);
5803     }
5804
5805     // Append newly exposed areas. Note that the exposed region is currently
5806     // in pixmap coordinates, so we have to translate it to item coordinates.
5807     exposed.translate(cache->boundingRect.topLeft());
5808     const QVector<QRect> exposedRects = exposed.rects();
5809     for (int i = 0; i < exposedRects.size(); ++i)
5810         cache->exposed += exposedRects.at(i);
5811
5812     // Trigger update. This will redraw the newly exposed area and make sure
5813     // the pixmap is re-blitted in case there are overlapping items.
5814     d->scene->d_func()->markDirty(this, rect);
5815 }
5816
5817 /*!
5818     \fn void QGraphicsItem::update(qreal x, qreal y, qreal width, qreal height)
5819     \overload
5820
5821     This convenience function is equivalent to calling update(QRectF(\a x, \a
5822     y, \a width, \a height)).
5823 */
5824
5825 /*!
5826     Maps the point \a point, which is in this item's coordinate system, to \a
5827     item's coordinate system, and returns the mapped coordinate.
5828
5829     If \a item is 0, this function returns the same as mapToScene().
5830
5831     \sa itemTransform(), mapToParent(), mapToScene(), transform(), mapFromItem(), {The Graphics
5832     View Coordinate System}
5833 */
5834 QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF &point) const
5835 {
5836     if (item)
5837         return itemTransform(item).map(point);
5838     return mapToScene(point);
5839 }
5840
5841 /*!
5842     \fn QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y) const
5843     \overload
5844
5845     This convenience function is equivalent to calling mapToItem(\a item,
5846     QPointF(\a x, \a y)).
5847 */
5848
5849 /*!
5850     Maps the point \a point, which is in this item's coordinate system, to its
5851     parent's coordinate system, and returns the mapped coordinate. If the item
5852     has no parent, \a point will be mapped to the scene's coordinate system.
5853
5854     \sa mapToItem(), mapToScene(), transform(), mapFromParent(), {The Graphics
5855     View Coordinate System}
5856 */
5857 QPointF QGraphicsItem::mapToParent(const QPointF &point) const
5858 {
5859     // COMBINE
5860     if (!d_ptr->transformData)
5861         return point + d_ptr->pos;
5862     return d_ptr->transformToParent().map(point);
5863 }
5864
5865 /*!
5866     \fn QPointF QGraphicsItem::mapToParent(qreal x, qreal y) const
5867     \overload
5868
5869     This convenience function is equivalent to calling mapToParent(QPointF(\a
5870     x, \a y)).
5871 */
5872
5873 /*!
5874     Maps the point \a point, which is in this item's coordinate system, to the
5875     scene's coordinate system, and returns the mapped coordinate.
5876
5877     \sa mapToItem(), mapToParent(), transform(), mapFromScene(), {The Graphics
5878     View Coordinate System}
5879 */
5880 QPointF QGraphicsItem::mapToScene(const QPointF &point) const
5881 {
5882     if (d_ptr->hasTranslateOnlySceneTransform())
5883         return QPointF(point.x() + d_ptr->sceneTransform.dx(), point.y() + d_ptr->sceneTransform.dy());
5884     return d_ptr->sceneTransform.map(point);
5885 }
5886
5887 /*!
5888     \fn QPointF QGraphicsItem::mapToScene(qreal x, qreal y) const
5889     \overload
5890
5891     This convenience function is equivalent to calling mapToScene(QPointF(\a
5892     x, \a y)).
5893 */
5894
5895 /*!
5896     Maps the rectangle \a rect, which is in this item's coordinate system, to
5897     \a item's coordinate system, and returns the mapped rectangle as a polygon.
5898
5899     If \a item is 0, this function returns the same as mapToScene().
5900
5901     \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5902     Graphics View Coordinate System}
5903 */
5904 QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect) const
5905 {
5906     if (item)
5907         return itemTransform(item).map(rect);
5908     return mapToScene(rect);
5909 }
5910
5911 /*!
5912     \fn QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
5913     \since 4.3
5914
5915     This convenience function is equivalent to calling mapToItem(item, QRectF(\a x, \a y, \a w, \a h)).
5916 */
5917
5918 /*!
5919     Maps the rectangle \a rect, which is in this item's coordinate system, to
5920     its parent's coordinate system, and returns the mapped rectangle as a
5921     polygon. If the item has no parent, \a rect will be mapped to the scene's
5922     coordinate system.
5923
5924     \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
5925     Coordinate System}
5926 */
5927 QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
5928 {
5929     // COMBINE
5930     if (!d_ptr->transformData)
5931         return rect.translated(d_ptr->pos);
5932     return d_ptr->transformToParent().map(rect);
5933 }
5934
5935 /*!
5936     \fn QPolygonF QGraphicsItem::mapToParent(qreal x, qreal y, qreal w, qreal h) const
5937     \since 4.3
5938
5939     This convenience function is equivalent to calling mapToParent(QRectF(\a x, \a y, \a w, \a h)).
5940 */
5941
5942 /*!
5943     Maps the rectangle \a rect, which is in this item's coordinate system, to
5944     the scene's coordinate system, and returns the mapped rectangle as a polygon.
5945
5946     \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
5947     Coordinate System}
5948 */
5949 QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const
5950 {
5951     if (d_ptr->hasTranslateOnlySceneTransform())
5952         return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
5953     return d_ptr->sceneTransform.map(rect);
5954 }
5955
5956 /*!
5957     \fn QPolygonF QGraphicsItem::mapToScene(qreal x, qreal y, qreal w, qreal h) const
5958     \since 4.3
5959
5960     This convenience function is equivalent to calling mapToScene(QRectF(\a x, \a y, \a w, \a h)).
5961 */
5962
5963 /*!
5964     \since 4.5
5965
5966     Maps the rectangle \a rect, which is in this item's coordinate system, to
5967     \a item's coordinate system, and returns the mapped rectangle as a new
5968     rectangle (i.e., the bounding rectangle of the resulting polygon).
5969
5970     If \a item is 0, this function returns the same as mapRectToScene().
5971
5972     \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5973     Graphics View Coordinate System}
5974 */
5975 QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, const QRectF &rect) const
5976 {
5977     if (item)
5978         return itemTransform(item).mapRect(rect);
5979     return mapRectToScene(rect);
5980 }
5981
5982 /*!
5983     \fn QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
5984     \since 4.5
5985
5986     This convenience function is equivalent to calling mapRectToItem(item, QRectF(\a x, \a y, \a w, \a h)).
5987 */
5988
5989 /*!
5990     \since 4.5
5991
5992     Maps the rectangle \a rect, which is in this item's coordinate system, to
5993     its parent's coordinate system, and returns the mapped rectangle as a new
5994     rectangle (i.e., the bounding rectangle of the resulting polygon).
5995
5996     \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5997     Graphics View Coordinate System}
5998 */
5999 QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const
6000 {
6001     // COMBINE
6002     if (!d_ptr->transformData)
6003         return rect.translated(d_ptr->pos);
6004     return d_ptr->transformToParent().mapRect(rect);
6005 }
6006
6007 /*!
6008     \fn QRectF QGraphicsItem::mapRectToParent(qreal x, qreal y, qreal w, qreal h) const
6009     \since 4.5
6010
6011     This convenience function is equivalent to calling mapRectToParent(QRectF(\a x, \a y, \a w, \a h)).
6012 */
6013
6014 /*!
6015     \since 4.5
6016
6017     Maps the rectangle \a rect, which is in this item's coordinate system, to
6018     the scene coordinate system, and returns the mapped rectangle as a new
6019     rectangle (i.e., the bounding rectangle of the resulting polygon).
6020
6021     \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6022     Graphics View Coordinate System}
6023 */
6024 QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const
6025 {
6026     if (d_ptr->hasTranslateOnlySceneTransform())
6027         return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6028     return d_ptr->sceneTransform.mapRect(rect);
6029 }
6030
6031 /*!
6032     \fn QRectF QGraphicsItem::mapRectToScene(qreal x, qreal y, qreal w, qreal h) const
6033     \since 4.5
6034
6035     This convenience function is equivalent to calling mapRectToScene(QRectF(\a x, \a y, \a w, \a h)).
6036 */
6037
6038 /*!
6039     \since 4.5
6040
6041     Maps the rectangle \a rect, which is in \a item's coordinate system, to
6042     this item's coordinate system, and returns the mapped rectangle as a new
6043     rectangle (i.e., the bounding rectangle of the resulting polygon).
6044
6045     If \a item is 0, this function returns the same as mapRectFromScene().
6046
6047     \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6048     Graphics View Coordinate System}
6049 */
6050 QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, const QRectF &rect) const
6051 {
6052     if (item)
6053         return item->itemTransform(this).mapRect(rect);
6054     return mapRectFromScene(rect);
6055 }
6056
6057 /*!
6058     \fn QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
6059     \since 4.5
6060
6061     This convenience function is equivalent to calling mapRectFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
6062 */
6063
6064 /*!
6065     \since 4.5
6066
6067     Maps the rectangle \a rect, which is in this item's parent's coordinate
6068     system, to this item's coordinate system, and returns the mapped rectangle
6069     as a new rectangle (i.e., the bounding rectangle of the resulting
6070     polygon).
6071
6072     \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6073     Graphics View Coordinate System}
6074 */
6075 QRectF QGraphicsItem::mapRectFromParent(const QRectF &rect) const
6076 {
6077     // COMBINE
6078     if (!d_ptr->transformData)
6079         return rect.translated(-d_ptr->pos);
6080     return d_ptr->transformToParent().inverted().mapRect(rect);
6081 }
6082
6083 /*!
6084     \fn QRectF QGraphicsItem::mapRectFromParent(qreal x, qreal y, qreal w, qreal h) const
6085     \since 4.5
6086
6087     This convenience function is equivalent to calling mapRectFromParent(QRectF(\a x, \a y, \a w, \a h)).
6088 */
6089
6090 /*!
6091     \since 4.5
6092
6093     Maps the rectangle \a rect, which is in scene coordinates, to this item's
6094     coordinate system, and returns the mapped rectangle as a new rectangle
6095     (i.e., the bounding rectangle of the resulting polygon).
6096
6097     \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6098     Graphics View Coordinate System}
6099 */
6100 QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const
6101 {
6102     if (d_ptr->hasTranslateOnlySceneTransform())
6103         return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6104     return d_ptr->sceneTransform.inverted().mapRect(rect);
6105 }
6106
6107 /*!
6108     \fn QRectF QGraphicsItem::mapRectFromScene(qreal x, qreal y, qreal w, qreal h) const
6109     \since 4.5
6110
6111     This convenience function is equivalent to calling mapRectFromScene(QRectF(\a x, \a y, \a w, \a h)).
6112 */
6113
6114 /*!
6115     Maps the polygon \a polygon, which is in this item's coordinate system, to
6116     \a item's coordinate system, and returns the mapped polygon.
6117
6118     If \a item is 0, this function returns the same as mapToScene().
6119
6120     \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6121     Graphics View Coordinate System}
6122 */
6123 QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &polygon) const
6124 {
6125     if (item)
6126         return itemTransform(item).map(polygon);
6127     return mapToScene(polygon);
6128 }
6129
6130 /*!
6131     Maps the polygon \a polygon, which is in this item's coordinate system, to
6132     its parent's coordinate system, and returns the mapped polygon. If the
6133     item has no parent, \a polygon will be mapped to the scene's coordinate
6134     system.
6135
6136     \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
6137     Coordinate System}
6138 */
6139 QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
6140 {
6141     // COMBINE
6142     if (!d_ptr->transformData)
6143         return polygon.translated(d_ptr->pos);
6144     return d_ptr->transformToParent().map(polygon);
6145 }
6146
6147 /*!
6148     Maps the polygon \a polygon, which is in this item's coordinate system, to
6149     the scene's coordinate system, and returns the mapped polygon.
6150
6151     \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
6152     Coordinate System}
6153 */
6154 QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const
6155 {
6156     if (d_ptr->hasTranslateOnlySceneTransform())
6157         return polygon.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6158     return d_ptr->sceneTransform.map(polygon);
6159 }
6160
6161 /*!
6162     Maps the path \a path, which is in this item's coordinate system, to
6163     \a item's coordinate system, and returns the mapped path.
6164
6165     If \a item is 0, this function returns the same as mapToScene().
6166
6167     \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6168     Graphics View Coordinate System}
6169 */
6170 QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterPath &path) const
6171 {
6172     if (item)
6173         return itemTransform(item).map(path);
6174     return mapToScene(path);
6175 }
6176
6177 /*!
6178     Maps the path \a path, which is in this item's coordinate system, to
6179     its parent's coordinate system, and returns the mapped path. If the
6180     item has no parent, \a path will be mapped to the scene's coordinate
6181     system.
6182
6183     \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
6184     Coordinate System}
6185 */
6186 QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
6187 {
6188     // COMBINE
6189     if (!d_ptr->transformData)
6190         return path.translated(d_ptr->pos);
6191     return d_ptr->transformToParent().map(path);
6192 }
6193
6194 /*!
6195     Maps the path \a path, which is in this item's coordinate system, to
6196     the scene's coordinate system, and returns the mapped path.
6197
6198     \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
6199     Coordinate System}
6200 */
6201 QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const
6202 {
6203     if (d_ptr->hasTranslateOnlySceneTransform())
6204         return path.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6205     return d_ptr->sceneTransform.map(path);
6206 }
6207
6208 /*!
6209     Maps the point \a point, which is in \a item's coordinate system, to this
6210     item's coordinate system, and returns the mapped coordinate.
6211
6212     If \a item is 0, this function returns the same as mapFromScene().
6213
6214     \sa itemTransform(), mapFromParent(), mapFromScene(), transform(), mapToItem(), {The Graphics
6215     View Coordinate System}
6216 */
6217 QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &point) const
6218 {
6219     if (item)
6220         return item->itemTransform(this).map(point);
6221     return mapFromScene(point);
6222 }
6223
6224 /*!
6225     \fn QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y) const
6226     \overload
6227
6228     This convenience function is equivalent to calling mapFromItem(\a item,
6229     QPointF(\a x, \a y)).
6230 */
6231
6232 /*!
6233     Maps the point \a point, which is in this item's parent's coordinate
6234     system, to this item's coordinate system, and returns the mapped
6235     coordinate.
6236
6237     \sa mapFromItem(), mapFromScene(), transform(), mapToParent(), {The Graphics
6238     View Coordinate System}
6239 */
6240 QPointF QGraphicsItem::mapFromParent(const QPointF &point) const
6241 {
6242     // COMBINE
6243     if (d_ptr->transformData)
6244         return d_ptr->transformToParent().inverted().map(point);
6245     return point - d_ptr->pos;
6246 }
6247
6248 /*!
6249     \fn QPointF QGraphicsItem::mapFromParent(qreal x, qreal y) const
6250     \overload
6251
6252     This convenience function is equivalent to calling
6253     mapFromParent(QPointF(\a x, \a y)).
6254 */
6255
6256 /*!
6257     Maps the point \a point, which is in this item's scene's coordinate
6258     system, to this item's coordinate system, and returns the mapped
6259     coordinate.
6260
6261     \sa mapFromItem(), mapFromParent(), transform(), mapToScene(), {The Graphics
6262     View Coordinate System}
6263 */
6264 QPointF QGraphicsItem::mapFromScene(const QPointF &point) const
6265 {
6266     if (d_ptr->hasTranslateOnlySceneTransform())
6267         return QPointF(point.x() - d_ptr->sceneTransform.dx(), point.y() - d_ptr->sceneTransform.dy());
6268     return d_ptr->sceneTransform.inverted().map(point);
6269 }
6270
6271 /*!
6272     \fn QPointF QGraphicsItem::mapFromScene(qreal x, qreal y) const
6273     \overload
6274
6275     This convenience function is equivalent to calling mapFromScene(QPointF(\a
6276     x, \a y)).
6277 */
6278
6279 /*!
6280     Maps the rectangle \a rect, which is in \a item's coordinate system, to
6281     this item's coordinate system, and returns the mapped rectangle as a
6282     polygon.
6283
6284     If \a item is 0, this function returns the same as mapFromScene()
6285
6286     \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The Graphics View Coordinate
6287     System}
6288 */
6289 QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QRectF &rect) const
6290 {
6291     if (item)
6292         return item->itemTransform(this).map(rect);
6293     return mapFromScene(rect);
6294 }
6295
6296 /*!
6297     \fn QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
6298     \since 4.3
6299
6300     This convenience function is equivalent to calling mapFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
6301 */
6302
6303 /*!
6304     Maps the rectangle \a rect, which is in this item's parent's coordinate
6305     system, to this item's coordinate system, and returns the mapped rectangle
6306     as a polygon.
6307
6308     \sa mapToParent(), mapFromItem(), transform(), {The Graphics View Coordinate
6309     System}
6310 */
6311 QPolygonF QGraphicsItem::mapFromParent(const QRectF &rect) const
6312 {
6313     // COMBINE
6314     if (!d_ptr->transformData)
6315         return rect.translated(-d_ptr->pos);
6316     return d_ptr->transformToParent().inverted().map(rect);
6317 }
6318
6319 /*!
6320     \fn QPolygonF QGraphicsItem::mapFromParent(qreal x, qreal y, qreal w, qreal h) const
6321     \since 4.3
6322
6323     This convenience function is equivalent to calling mapFromItem(QRectF(\a x, \a y, \a w, \a h)).
6324 */
6325
6326 /*!
6327     Maps the rectangle \a rect, which is in this item's scene's coordinate
6328     system, to this item's coordinate system, and returns the mapped rectangle
6329     as a polygon.
6330
6331     \sa mapToScene(), mapFromItem(), transform(), {The Graphics View Coordinate
6332     System}
6333 */
6334 QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const
6335 {
6336     if (d_ptr->hasTranslateOnlySceneTransform())
6337         return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6338     return d_ptr->sceneTransform.inverted().map(rect);
6339 }
6340
6341 /*!
6342     \fn QPolygonF QGraphicsItem::mapFromScene(qreal x, qreal y, qreal w, qreal h) const
6343     \since 4.3
6344
6345     This convenience function is equivalent to calling mapFromScene(QRectF(\a x, \a y, \a w, \a h)).
6346 */
6347
6348 /*!
6349     Maps the polygon \a polygon, which is in \a item's coordinate system, to
6350     this item's coordinate system, and returns the mapped polygon.
6351
6352     If \a item is 0, this function returns the same as mapFromScene().
6353
6354     \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The
6355     Graphics View Coordinate System}
6356 */
6357 QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPolygonF &polygon) const
6358 {
6359     if (item)
6360         return item->itemTransform(this).map(polygon);
6361     return mapFromScene(polygon);
6362 }
6363
6364 /*!
6365     Maps the polygon \a polygon, which is in this item's parent's coordinate
6366     system, to this item's coordinate system, and returns the mapped polygon.
6367
6368     \sa mapToParent(), mapToItem(), transform(), {The Graphics View Coordinate
6369     System}
6370 */
6371 QPolygonF QGraphicsItem::mapFromParent(const QPolygonF &polygon) const
6372 {
6373     // COMBINE
6374     if (!d_ptr->transformData)
6375         return polygon.translated(-d_ptr->pos);
6376     return d_ptr->transformToParent().inverted().map(polygon);
6377 }
6378
6379 /*!
6380     Maps the polygon \a polygon, which is in this item's scene's coordinate
6381     system, to this item's coordinate system, and returns the mapped polygon.
6382
6383     \sa mapToScene(), mapFromParent(), transform(), {The Graphics View Coordinate
6384     System}
6385 */
6386 QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const
6387 {
6388     if (d_ptr->hasTranslateOnlySceneTransform())
6389         return polygon.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6390     return d_ptr->sceneTransform.inverted().map(polygon);
6391 }
6392
6393 /*!
6394     Maps the path \a path, which is in \a item's coordinate system, to
6395     this item's coordinate system, and returns the mapped path.
6396
6397     If \a item is 0, this function returns the same as mapFromScene().
6398
6399     \sa itemTransform(), mapFromParent(), mapFromScene(), mapToItem(), {The
6400     Graphics View Coordinate System}
6401 */
6402 QPainterPath QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPainterPath &path) const
6403 {
6404     if (item)
6405         return item->itemTransform(this).map(path);
6406     return mapFromScene(path);
6407 }
6408
6409 /*!
6410     Maps the path \a path, which is in this item's parent's coordinate
6411     system, to this item's coordinate system, and returns the mapped path.
6412
6413     \sa mapFromScene(), mapFromItem(), mapToParent(), {The Graphics View
6414     Coordinate System}
6415 */
6416 QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const
6417 {
6418     // COMBINE
6419     if (!d_ptr->transformData)
6420             return path.translated(-d_ptr->pos);
6421     return d_ptr->transformToParent().inverted().map(path);
6422 }
6423
6424 /*!
6425     Maps the path \a path, which is in this item's scene's coordinate
6426     system, to this item's coordinate system, and returns the mapped path.
6427
6428     \sa mapFromParent(), mapFromItem(), mapToScene(), {The Graphics View
6429     Coordinate System}
6430 */
6431 QPainterPath QGraphicsItem::mapFromScene(const QPainterPath &path) const
6432 {
6433     if (d_ptr->hasTranslateOnlySceneTransform())
6434         return path.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6435     return d_ptr->sceneTransform.inverted().map(path);
6436 }
6437
6438 /*!
6439     Returns true if this item is an ancestor of \a child (i.e., if this item
6440     is \a child's parent, or one of \a child's parent's ancestors).
6441
6442     \sa parentItem()
6443 */
6444 bool QGraphicsItem::isAncestorOf(const QGraphicsItem *child) const
6445 {
6446     if (!child || child == this)
6447         return false;
6448     if (child->d_ptr->depth() < d_ptr->depth())
6449         return false;
6450     const QGraphicsItem *ancestor = child;
6451     while ((ancestor = ancestor->d_ptr->parent)) {
6452         if (ancestor == this)
6453             return true;
6454     }
6455     return false;
6456 }
6457
6458 /*!
6459     \since 4.4
6460
6461     Returns the closest common ancestor item of this item and \a other, or 0
6462     if either \a other is 0, or there is no common ancestor.
6463
6464     \sa isAncestorOf()
6465 */
6466 QGraphicsItem *QGraphicsItem::commonAncestorItem(const QGraphicsItem *other) const
6467 {
6468     if (!other)
6469         return 0;
6470     if (other == this)
6471         return const_cast<QGraphicsItem *>(this);
6472     const QGraphicsItem *thisw = this;
6473     const QGraphicsItem *otherw = other;
6474     int thisDepth = d_ptr->depth();
6475     int otherDepth = other->d_ptr->depth();
6476     while (thisDepth > otherDepth) {
6477         thisw = thisw->d_ptr->parent;
6478         --thisDepth;
6479     }
6480     while (otherDepth > thisDepth) {
6481         otherw = otherw->d_ptr->parent;
6482         --otherDepth;
6483     }
6484     while (thisw && thisw != otherw) {
6485         thisw = thisw->d_ptr->parent;
6486         otherw = otherw->d_ptr->parent;
6487     }
6488     return const_cast<QGraphicsItem *>(thisw);
6489 }
6490
6491 /*!
6492     \since 4,4
6493     Returns true if this item is currently under the mouse cursor in one of
6494     the views; otherwise, false is returned.
6495
6496     \sa QGraphicsScene::views(), QCursor::pos()
6497 */
6498 bool QGraphicsItem::isUnderMouse() const
6499 {
6500     Q_D(const QGraphicsItem);
6501     if (!d->scene)
6502         return false;
6503
6504     QPoint cursorPos = QCursor::pos();
6505     foreach (QGraphicsView *view, d->scene->views()) {
6506         if (contains(mapFromScene(view->mapToScene(view->mapFromGlobal(cursorPos)))))
6507             return true;
6508     }
6509     return false;
6510 }
6511
6512 /*!
6513     Returns this item's custom data for the key \a key as a QVariant.
6514
6515     Custom item data is useful for storing arbitrary properties in any
6516     item. Example:
6517
6518     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 11
6519
6520     Qt does not use this feature for storing data; it is provided solely
6521     for the convenience of the user.
6522
6523     \sa setData()
6524 */
6525 QVariant QGraphicsItem::data(int key) const
6526 {
6527     QGraphicsItemCustomDataStore *store = qt_dataStore();
6528     if (!store->data.contains(this))
6529         return QVariant();
6530     return store->data.value(this).value(key);
6531 }
6532
6533 /*!
6534     Sets this item's custom data for the key \a key to \a value.
6535
6536     Custom item data is useful for storing arbitrary properties for any
6537     item. Qt does not use this feature for storing data; it is provided solely
6538     for the convenience of the user.
6539
6540     \sa data()
6541 */
6542 void QGraphicsItem::setData(int key, const QVariant &value)
6543 {
6544     qt_dataStore()->data[this][key] = value;
6545 }
6546
6547 /*!
6548     \fn T qgraphicsitem_cast(QGraphicsItem *item)
6549     \relates QGraphicsItem
6550     \since 4.2
6551
6552     Returns the given \a item cast to type T if \a item is of type T;
6553     otherwise, 0 is returned.
6554
6555     \note To make this function work correctly with custom items, reimplement
6556     the \l{QGraphicsItem::}{type()} function for each custom QGraphicsItem
6557     subclass.
6558
6559     \sa QGraphicsItem::type(), QGraphicsItem::UserType
6560 */
6561
6562 /*!
6563     Returns the type of an item as an int. All standard graphicsitem classes
6564     are associated with a unique value; see QGraphicsItem::Type. This type
6565     information is used by qgraphicsitem_cast() to distinguish between types.
6566
6567     The default implementation (in QGraphicsItem) returns UserType.
6568
6569     To enable use of qgraphicsitem_cast() with a custom item, reimplement this
6570     function and declare a Type enum value equal to your custom item's type.
6571     Custom items must return a value larger than or equal to UserType (65536).
6572
6573     For example:
6574
6575     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp QGraphicsItem type
6576
6577     \sa UserType
6578 */
6579 int QGraphicsItem::type() const
6580 {
6581     return (int)UserType;
6582 }
6583
6584 /*!
6585     Installs an event filter for this item on \a filterItem, causing
6586     all events for this item to first pass through \a filterItem's
6587     sceneEventFilter() function.
6588
6589     To filter another item's events, install this item as an event filter
6590     for the other item. Example:
6591
6592     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 12
6593
6594     An item can only filter events for other items in the same
6595     scene. Also, an item cannot filter its own events; instead, you
6596     can reimplement sceneEvent() directly.
6597
6598     Items must belong to a scene for scene event filters to be installed and
6599     used.
6600
6601     \sa removeSceneEventFilter(), sceneEventFilter(), sceneEvent()
6602 */
6603 void QGraphicsItem::installSceneEventFilter(QGraphicsItem *filterItem)
6604 {
6605     if (!d_ptr->scene) {
6606         qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
6607                  " on items in a scene.");
6608         return;
6609     }
6610     if (d_ptr->scene != filterItem->scene()) {
6611         qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
6612                  " on items in the same scene.");
6613         return;
6614     }
6615     d_ptr->scene->d_func()->installSceneEventFilter(this, filterItem);
6616 }
6617
6618 /*!
6619     Removes an event filter on this item from \a filterItem.
6620
6621     \sa installSceneEventFilter()
6622 */
6623 void QGraphicsItem::removeSceneEventFilter(QGraphicsItem *filterItem)
6624 {
6625     if (!d_ptr->scene || d_ptr->scene != filterItem->scene())
6626         return;
6627     d_ptr->scene->d_func()->removeSceneEventFilter(this, filterItem);
6628 }
6629
6630 /*!
6631     Filters events for the item \a watched. \a event is the filtered
6632     event.
6633
6634     Reimplementing this function in a subclass makes it possible
6635     for the item to be used as an event filter for other items,
6636     intercepting all the events send to those items before they are
6637     able to respond.
6638
6639     Reimplementations must return true to prevent further processing of
6640     a given event, ensuring that it will not be delivered to the watched
6641     item, or return false to indicate that the event should be propagated
6642     further by the event system.
6643
6644     \sa installSceneEventFilter()
6645 */
6646 bool QGraphicsItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
6647 {
6648     Q_UNUSED(watched);
6649     Q_UNUSED(event);
6650     return false;
6651 }
6652
6653 /*!
6654     This virtual function receives events to this item. Reimplement
6655     this function to intercept events before they are dispatched to
6656     the specialized event handlers contextMenuEvent(), focusInEvent(),
6657     focusOutEvent(), hoverEnterEvent(), hoverMoveEvent(),
6658     hoverLeaveEvent(), keyPressEvent(), keyReleaseEvent(),
6659     mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent(), and
6660     mouseDoubleClickEvent().
6661
6662     Returns true if the event was recognized and handled; otherwise, (e.g., if
6663     the event type was not recognized,) false is returned.
6664
6665     \a event is the intercepted event.
6666 */
6667 bool QGraphicsItem::sceneEvent(QEvent *event)
6668 {
6669     if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents) {
6670         if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverLeave
6671             || event->type() == QEvent::DragEnter || event->type() == QEvent::DragLeave) {
6672             // Hover enter and hover leave events for children are ignored;
6673             // hover move events are forwarded.
6674             return true;
6675         }
6676
6677         QGraphicsItem *handler = this;
6678         do {
6679             handler = handler->d_ptr->parent;
6680             Q_ASSERT(handler);
6681         } while (handler->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents);
6682         // Forward the event to the closest parent that handles child
6683         // events, mapping existing item-local coordinates to its
6684         // coordinate system.
6685         d_ptr->remapItemPos(event, handler);
6686         handler->sceneEvent(event);
6687         return true;
6688     }
6689
6690     if (event->type() == QEvent::FocusOut) {
6691         focusOutEvent(static_cast<QFocusEvent *>(event));
6692         return true;
6693     }
6694
6695     if (!d_ptr->visible) {
6696         // Eaten
6697         return true;
6698     }
6699
6700     switch (event->type()) {
6701     case QEvent::FocusIn:
6702         focusInEvent(static_cast<QFocusEvent *>(event));
6703         break;
6704     case QEvent::GraphicsSceneContextMenu:
6705         contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event));
6706         break;
6707     case QEvent::GraphicsSceneDragEnter:
6708         dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6709         break;
6710     case QEvent::GraphicsSceneDragMove:
6711         dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6712         break;
6713     case QEvent::GraphicsSceneDragLeave:
6714         dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6715         break;
6716     case QEvent::GraphicsSceneDrop:
6717         dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6718         break;
6719     case QEvent::GraphicsSceneHoverEnter:
6720         hoverEnterEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6721         break;
6722     case QEvent::GraphicsSceneHoverMove:
6723         hoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6724         break;
6725     case QEvent::GraphicsSceneHoverLeave:
6726         hoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6727         break;
6728     case QEvent::GraphicsSceneMouseMove:
6729         mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6730         break;
6731     case QEvent::GraphicsSceneMousePress:
6732         mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6733         break;
6734     case QEvent::GraphicsSceneMouseRelease:
6735         mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6736         break;
6737     case QEvent::GraphicsSceneMouseDoubleClick:
6738         mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6739         break;
6740     case QEvent::GraphicsSceneWheel:
6741         wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
6742         break;
6743     case QEvent::KeyPress: {
6744         QKeyEvent *k = static_cast<QKeyEvent *>(event);
6745         if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
6746             if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) {  //### Add MetaModifier?
6747                 bool res = false;
6748                 if (k->key() == Qt::Key_Backtab
6749                     || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
6750                     if (d_ptr->isWidget) {
6751                         res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(false);
6752                     } else if (d_ptr->scene) {
6753                         res = d_ptr->scene->focusNextPrevChild(false);
6754                     }
6755                 } else if (k->key() == Qt::Key_Tab) {
6756                     if (d_ptr->isWidget) {
6757                         res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(true);
6758                     } else if (d_ptr->scene) {
6759                         res = d_ptr->scene->focusNextPrevChild(true);
6760                     }
6761                 }
6762                 if (!res)
6763                     event->ignore();
6764                 return true;
6765             }
6766         }
6767         keyPressEvent(static_cast<QKeyEvent *>(event));
6768         break;
6769     }
6770     case QEvent::KeyRelease:
6771         keyReleaseEvent(static_cast<QKeyEvent *>(event));
6772         break;
6773     case QEvent::InputMethod:
6774         inputMethodEvent(static_cast<QInputMethodEvent *>(event));
6775         break;
6776     case QEvent::WindowActivate:
6777     case QEvent::WindowDeactivate:
6778         // Propagate panel activation.
6779         if (d_ptr->scene) {
6780             for (int i = 0; i < d_ptr->children.size(); ++i) {
6781                 QGraphicsItem *child = d_ptr->children.at(i);
6782                 if (child->isVisible() && !child->isPanel()) {
6783                     if (!(child->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents))
6784                         d_ptr->scene->sendEvent(child, event);
6785                 }
6786             }
6787         }
6788         break;
6789     default:
6790         return false;
6791     }
6792
6793     return true;
6794 }
6795
6796 /*!
6797     This event handler can be reimplemented in a subclass to process context
6798     menu events. The \a event parameter contains details about the event to
6799     be handled.
6800
6801     If you ignore the event, (i.e., by calling QEvent::ignore(),) \a event
6802     will propagate to any item beneath this item. If no items accept the
6803     event, it will be ignored by the scene, and propagate to the view.
6804
6805     It's common to open a QMenu in response to receiving a context menu
6806     event. Example:
6807
6808     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 13
6809
6810     The default implementation ignores the event.
6811
6812     \sa sceneEvent()
6813 */
6814 void QGraphicsItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
6815 {
6816     event->ignore();
6817 }
6818
6819 /*!
6820     This event handler, for event \a event, can be reimplemented to receive
6821     drag enter events for this item. Drag enter events are generated as the
6822     cursor enters the item's area.
6823
6824     By accepting the event, (i.e., by calling QEvent::accept(),) the item will
6825     accept drop events, in addition to receiving drag move and drag
6826     leave. Otherwise, the event will be ignored and propagate to the item
6827     beneath. If the event is accepted, the item will receive a drag move event
6828     before control goes back to the event loop.
6829
6830     A common implementation of dragEnterEvent accepts or ignores \a event
6831     depending on the associated mime data in \a event. Example:
6832
6833     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 14
6834
6835     Items do not receive drag and drop events by default; to enable this
6836     feature, call \c setAcceptDrops(true).
6837
6838     The default implementation does nothing.
6839
6840     \sa dropEvent(), dragMoveEvent(), dragLeaveEvent()
6841 */
6842 void QGraphicsItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
6843 {
6844     Q_D(QGraphicsItem);
6845     // binary compatibility workaround between 4.4 and 4.5
6846     if (d->isProxyWidget())
6847         static_cast<QGraphicsProxyWidget*>(this)->dragEnterEvent(event);
6848 }
6849
6850 /*!
6851     This event handler, for event \a event, can be reimplemented to receive
6852     drag leave events for this item. Drag leave events are generated as the
6853     cursor leaves the item's area. Most often you will not need to reimplement
6854     this function, but it can be useful for resetting state in your item
6855     (e.g., highlighting).
6856
6857     Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6858
6859     Items do not receive drag and drop events by default; to enable this
6860     feature, call \c setAcceptDrops(true).
6861
6862     The default implementation does nothing.
6863
6864     \sa dragEnterEvent(), dropEvent(), dragMoveEvent()
6865 */
6866 void QGraphicsItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
6867 {
6868     Q_D(QGraphicsItem);
6869     // binary compatibility workaround between 4.4 and 4.5
6870     if (d->isProxyWidget())
6871         static_cast<QGraphicsProxyWidget*>(this)->dragLeaveEvent(event);
6872 }
6873
6874 /*!
6875     This event handler, for event \a event, can be reimplemented to receive
6876     drag move events for this item. Drag move events are generated as the
6877     cursor moves around inside the item's area. Most often you will not need
6878     to reimplement this function; it is used to indicate that only parts of
6879     the item can accept drops.
6880
6881     Calling QEvent::ignore() or QEvent::accept() on \a event toggles whether
6882     or not the item will accept drops at the position from the event. By
6883     default, \a event is accepted, indicating that the item allows drops at
6884     the specified position.
6885
6886     Items do not receive drag and drop events by default; to enable this
6887     feature, call \c setAcceptDrops(true).
6888
6889     The default implementation does nothing.
6890
6891     \sa dropEvent(), dragEnterEvent(), dragLeaveEvent()
6892 */
6893 void QGraphicsItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
6894 {
6895     Q_D(QGraphicsItem);
6896     // binary compatibility workaround between 4.4 and 4.5
6897     if (d->isProxyWidget())
6898         static_cast<QGraphicsProxyWidget*>(this)->dragMoveEvent(event);
6899 }
6900
6901 /*!
6902     This event handler, for event \a event, can be reimplemented to receive
6903     drop events for this item. Items can only receive drop events if the last
6904     drag move event was accepted.
6905
6906     Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6907
6908     Items do not receive drag and drop events by default; to enable this
6909     feature, call \c setAcceptDrops(true).
6910
6911     The default implementation does nothing.
6912
6913     \sa dragEnterEvent(), dragMoveEvent(), dragLeaveEvent()
6914 */
6915 void QGraphicsItem::dropEvent(QGraphicsSceneDragDropEvent *event)
6916 {
6917     Q_D(QGraphicsItem);
6918     // binary compatibility workaround between 4.4 and 4.5
6919     if (d->isProxyWidget())
6920         static_cast<QGraphicsProxyWidget*>(this)->dropEvent(event);
6921 }
6922
6923 /*!
6924     This event handler, for event \a event, can be reimplemented to receive
6925     focus in events for this item. The default implementation calls
6926     ensureVisible().
6927
6928     \sa focusOutEvent(), sceneEvent(), setFocus()
6929 */
6930 void QGraphicsItem::focusInEvent(QFocusEvent *event)
6931 {
6932     Q_UNUSED(event);
6933     update();
6934 }
6935
6936 /*!
6937     This event handler, for event \a event, can be reimplemented to receive
6938     focus out events for this item. The default implementation does nothing.
6939
6940     \sa focusInEvent(), sceneEvent(), setFocus()
6941 */
6942 void QGraphicsItem::focusOutEvent(QFocusEvent *event)
6943 {
6944     Q_UNUSED(event);
6945     update();
6946 }
6947
6948 /*!
6949     This event handler, for event \a event, can be reimplemented to receive
6950     hover enter events for this item. The default implementation calls
6951     update(); otherwise it does nothing.
6952
6953     Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6954
6955     \sa hoverMoveEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
6956 */
6957 void QGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
6958 {
6959     Q_UNUSED(event);
6960     update();
6961 }
6962
6963 /*!
6964     This event handler, for event \a event, can be reimplemented to receive
6965     hover move events for this item. The default implementation does nothing.
6966
6967     Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6968
6969     \sa hoverEnterEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
6970 */
6971 void QGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
6972 {
6973     Q_UNUSED(event);
6974 }
6975
6976 /*!
6977     This event handler, for event \a event, can be reimplemented to receive
6978     hover leave events for this item. The default implementation calls
6979     update(); otherwise it does nothing.
6980
6981     Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6982
6983     \sa hoverEnterEvent(), hoverMoveEvent(), sceneEvent(), setAcceptHoverEvents()
6984 */
6985 void QGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
6986 {
6987     Q_UNUSED(event);
6988     update();
6989 }
6990
6991 /*!
6992     This event handler, for event \a event, can be reimplemented to
6993     receive key press events for this item. The default implementation
6994     ignores the event. If you reimplement this handler, the event will by
6995     default be accepted.
6996
6997     Note that key events are only received for items that set the
6998     ItemIsFocusable flag, and that have keyboard input focus.
6999
7000     \sa keyReleaseEvent(), setFocus(), QGraphicsScene::setFocusItem(),
7001     sceneEvent()
7002 */
7003 void QGraphicsItem::keyPressEvent(QKeyEvent *event)
7004 {
7005     event->ignore();
7006 }
7007
7008 /*!
7009     This event handler, for event \a event, can be reimplemented to receive
7010     key release events for this item. The default implementation
7011     ignores the event. If you reimplement this handler, the event will by
7012     default be accepted.
7013
7014     Note that key events are only received for items that set the
7015     ItemIsFocusable flag, and that have keyboard input focus.
7016
7017     \sa keyPressEvent(), setFocus(), QGraphicsScene::setFocusItem(),
7018     sceneEvent()
7019 */
7020 void QGraphicsItem::keyReleaseEvent(QKeyEvent *event)
7021 {
7022     event->ignore();
7023 }
7024
7025 /*!
7026     This event handler, for event \a event, can be reimplemented to
7027     receive mouse press events for this item. Mouse press events are
7028     only delivered to items that accept the mouse button that is
7029     pressed. By default, an item accepts all mouse buttons, but you
7030     can change this by calling setAcceptedMouseButtons().
7031
7032     The mouse press event decides which item should become the mouse
7033     grabber (see QGraphicsScene::mouseGrabberItem()). If you do not
7034     reimplement this function, the press event will propagate to any
7035     topmost item beneath this item, and no other mouse events will be
7036     delivered to this item.
7037
7038     If you do reimplement this function, \a event will by default be
7039     accepted (see QEvent::accept()), and this item is then the mouse
7040     grabber. This allows the item to receive future move, release and
7041     doubleclick events. If you call QEvent::ignore() on \a event, this
7042     item will lose the mouse grab, and \a event will propagate to any
7043     topmost item beneath. No further mouse events will be delivered to
7044     this item unless a new mouse press event is received.
7045
7046     The default implementation handles basic item interaction, such as
7047     selection and moving. If you want to keep the base implementation
7048     when reimplementing this function, call
7049     QGraphicsItem::mousePressEvent() in your reimplementation.
7050
7051     The event is \l{QEvent::ignore()}d for items that are neither
7052     \l{QGraphicsItem::ItemIsMovable}{movable} nor
7053     \l{QGraphicsItem::ItemIsSelectable}{selectable}.
7054
7055     \sa mouseMoveEvent(), mouseReleaseEvent(),
7056     mouseDoubleClickEvent(), sceneEvent()
7057 */
7058 void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
7059 {
7060     if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
7061         bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
7062         if (!multiSelect) {
7063             if (!d_ptr->selected) {
7064                 if (QGraphicsScene *scene = d_ptr->scene) {
7065                     ++scene->d_func()->selectionChanging;
7066                     scene->clearSelection();
7067                     --scene->d_func()->selectionChanging;
7068                 }
7069                 setSelected(true);
7070             }
7071         }
7072     } else if (!(flags() & ItemIsMovable)) {
7073         event->ignore();
7074     }
7075     if (d_ptr->isWidget) {
7076         // Qt::Popup closes when you click outside.
7077         QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
7078         if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
7079             event->accept();
7080             if (!w->rect().contains(event->pos()))
7081                 w->close();
7082         }
7083     }
7084 }
7085
7086 /*!
7087     obsolete
7088 */
7089 bool _qt_movableAncestorIsSelected(const QGraphicsItem *item)
7090 {
7091     const QGraphicsItem *parent = item->parentItem();
7092     return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
7093 }
7094
7095 bool QGraphicsItemPrivate::movableAncestorIsSelected(const QGraphicsItem *item)
7096 {
7097     const QGraphicsItem *parent = item->d_ptr->parent;
7098     return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
7099 }
7100
7101 /*!
7102     This event handler, for event \a event, can be reimplemented to
7103     receive mouse move events for this item. If you do receive this
7104     event, you can be certain that this item also received a mouse
7105     press event, and that this item is the current mouse grabber.
7106
7107     Calling QEvent::ignore() or QEvent::accept() on \a event has no
7108     effect.
7109
7110     The default implementation handles basic item interaction, such as
7111     selection and moving. If you want to keep the base implementation
7112     when reimplementing this function, call
7113     QGraphicsItem::mouseMoveEvent() in your reimplementation.
7114
7115     Please note that mousePressEvent() decides which graphics item it
7116     is that receives mouse events. See the mousePressEvent()
7117     description for details.
7118
7119     \sa mousePressEvent(), mouseReleaseEvent(),
7120     mouseDoubleClickEvent(), sceneEvent()
7121 */
7122 void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
7123 {
7124     if ((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) {
7125         // Determine the list of items that need to be moved.
7126         QList<QGraphicsItem *> selectedItems;
7127         QHash<QGraphicsItem *, QPointF> initialPositions;
7128         if (d_ptr->scene) {
7129             selectedItems = d_ptr->scene->selectedItems();
7130             initialPositions = d_ptr->scene->d_func()->movingItemsInitialPositions;
7131             if (initialPositions.isEmpty()) {
7132                 foreach (QGraphicsItem *item, selectedItems)
7133                     initialPositions[item] = item->pos();
7134                 initialPositions[this] = pos();
7135             }
7136             d_ptr->scene->d_func()->movingItemsInitialPositions = initialPositions;
7137         }
7138
7139         // Find the active view.
7140         QGraphicsView *view = 0;
7141         if (event->widget())
7142             view = qobject_cast<QGraphicsView *>(event->widget()->parentWidget());
7143
7144         // Move all selected items
7145         int i = 0;
7146         bool movedMe = false;
7147         while (i <= selectedItems.size()) {
7148             QGraphicsItem *item = 0;
7149             if (i < selectedItems.size())
7150                 item = selectedItems.at(i);
7151             else
7152                 item = this;
7153             if (item == this) {
7154                 // Slightly clumsy-looking way to ensure that "this" is part
7155                 // of the list of items to move, this is to avoid allocations
7156                 // (appending this item to the list of selected items causes a
7157                 // detach).
7158                 if (movedMe)
7159                     break;
7160                 movedMe = true;
7161             }
7162
7163             if ((item->flags() & ItemIsMovable) && !QGraphicsItemPrivate::movableAncestorIsSelected(item)) {
7164                 QPointF currentParentPos;
7165                 QPointF buttonDownParentPos;
7166                 if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorIgnoresTransformations) {
7167                     // Items whose ancestors ignore transformations need to
7168                     // map screen coordinates to local coordinates, then map
7169                     // those to the parent.
7170                     QTransform viewToItemTransform = (item->deviceTransform(view->viewportTransform())).inverted();
7171                     currentParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))));
7172                     buttonDownParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))));
7173                 } else if (item->flags() & ItemIgnoresTransformations) {
7174                     // Root items that ignore transformations need to
7175                     // calculate their diff by mapping viewport coordinates
7176                     // directly to parent coordinates.
7177                     // COMBINE
7178                     QTransform itemTransform;
7179                     if (item->d_ptr->transformData)
7180                         itemTransform = item->d_ptr->transformData->computedFullTransform();
7181                     itemTransform.translate(item->d_ptr->pos.x(), item->d_ptr->pos.y());
7182                     QTransform viewToParentTransform = itemTransform
7183                                                        * (item->sceneTransform() * view->viewportTransform()).inverted();
7184                     currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos())));
7185                     buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton))));
7186                 } else {
7187                     // All other items simply map from the scene.
7188                     currentParentPos = item->mapToParent(item->mapFromScene(event->scenePos()));
7189                     buttonDownParentPos = item->mapToParent(item->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)));
7190                 }
7191
7192                 item->setPos(initialPositions.value(item) + currentParentPos - buttonDownParentPos);
7193
7194                 if (item->flags() & ItemIsSelectable)
7195                     item->setSelected(true);
7196             }
7197             ++i;
7198         }
7199
7200     } else {
7201         event->ignore();
7202     }
7203 }
7204
7205 /*!
7206     This event handler, for event \a event, can be reimplemented to
7207     receive mouse release events for this item.
7208
7209     Calling QEvent::ignore() or QEvent::accept() on \a event has no
7210     effect.
7211
7212     The default implementation handles basic item interaction, such as
7213     selection and moving. If you want to keep the base implementation
7214     when reimplementing this function, call
7215     QGraphicsItem::mouseReleaseEvent() in your reimplementation.
7216
7217     Please note that mousePressEvent() decides which graphics item it
7218     is that receives mouse events. See the mousePressEvent()
7219     description for details.
7220
7221     \sa mousePressEvent(), mouseMoveEvent(), mouseDoubleClickEvent(),
7222     sceneEvent()
7223 */
7224 void QGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
7225 {
7226     if (flags() & ItemIsSelectable) {
7227         bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
7228         if (event->scenePos() == event->buttonDownScenePos(Qt::LeftButton)) {
7229             // The item didn't move
7230             if (multiSelect) {
7231                 setSelected(!isSelected());
7232             } else {
7233                 bool selectionChanged = false;
7234                 if (QGraphicsScene *scene = d_ptr->scene) {
7235                     ++scene->d_func()->selectionChanging;
7236                     // Clear everything but this item. Bypass
7237                     // QGraphicsScene::clearSelection()'s default behavior by
7238                     // temporarily removing this item from the selection list.
7239                     if (d_ptr->selected) {
7240                         scene->d_func()->selectedItems.remove(this);
7241                         foreach (QGraphicsItem *item, scene->d_func()->selectedItems) {
7242                             if (item->isSelected()) {
7243                                 selectionChanged = true;
7244                                 break;
7245                             }
7246                         }
7247                     }
7248                     scene->clearSelection();
7249                     if (d_ptr->selected)
7250                         scene->d_func()->selectedItems.insert(this);
7251                     --scene->d_func()->selectionChanging;
7252                     if (selectionChanged)
7253                         emit d_ptr->scene->selectionChanged();
7254                 }
7255                 setSelected(true);
7256             }
7257         }
7258     }
7259     if (d_ptr->scene && !event->buttons())
7260         d_ptr->scene->d_func()->movingItemsInitialPositions.clear();
7261 }
7262
7263 /*!
7264     This event handler, for event \a event, can be reimplemented to
7265     receive mouse doubleclick events for this item.
7266
7267     When doubleclicking an item, the item will first receive a mouse
7268     press event, followed by a release event (i.e., a click), then a
7269     doubleclick event, and finally a release event.
7270
7271     Calling QEvent::ignore() or QEvent::accept() on \a event has no
7272     effect.
7273
7274     The default implementation calls mousePressEvent(). If you want to
7275     keep the base implementation when reimplementing this function,
7276     call QGraphicsItem::mouseDoubleClickEvent() in your
7277     reimplementation.
7278
7279     Note that an item will not receive double click events if it is
7280     neither \l {QGraphicsItem::ItemIsSelectable}{selectable} nor
7281     \l{QGraphicsItem::ItemIsMovable}{movable} (single mouse clicks are
7282     ignored in this case, and that stops the generation of double
7283     clicks).
7284
7285     \sa mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), sceneEvent()
7286 */
7287 void QGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
7288 {
7289     mousePressEvent(event);
7290 }
7291
7292 /*!
7293     This event handler, for event \a event, can be reimplemented to receive
7294     wheel events for this item. If you reimplement this function, \a event
7295     will be accepted by default.
7296
7297     If you ignore the event, (i.e., by calling QEvent::ignore(),) it will
7298     propagate to any item beneath this item. If no items accept the event, it
7299     will be ignored by the scene, and propagate to the view (e.g., the view's
7300     vertical scroll bar).
7301
7302     The default implementation ignores the event.
7303
7304     \sa sceneEvent()
7305 */
7306 void QGraphicsItem::wheelEvent(QGraphicsSceneWheelEvent *event)
7307 {
7308     event->ignore();
7309 }
7310
7311 /*!
7312     This event handler, for event \a event, can be reimplemented to receive
7313     input method events for this item. The default implementation ignores the
7314     event.
7315
7316     \sa inputMethodQuery(), sceneEvent()
7317 */
7318 void QGraphicsItem::inputMethodEvent(QInputMethodEvent *event)
7319 {
7320     event->ignore();
7321 }
7322
7323 /*!
7324     This method is only relevant for input items. It is used by the
7325     input method to query a set of properties of the item to be able
7326     to support complex input method operations, such as support for
7327     surrounding text and reconversions. \a query specifies which
7328     property is queried.
7329
7330     \sa inputMethodEvent(), QInputMethodEvent
7331 */
7332 QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const
7333 {
7334     if (isWidget()) {
7335         // ### Qt 5: Remove. The reimplementation in
7336         // QGraphicsProxyWidget solves this problem (but requires a
7337         // recompile to take effect).
7338         return d_ptr->inputMethodQueryHelper(query);
7339     }
7340
7341     Q_UNUSED(query);
7342     return QVariant();
7343 }
7344
7345 /*!
7346     Returns the current input method hints of this item.
7347
7348     Input method hints are only relevant for input items.
7349     The hints are used by the input method to indicate how it should operate.
7350     For example, if the Qt::ImhNumbersOnly flag is set, the input method may change
7351     its visual components to reflect that only numbers can be entered.
7352
7353     The effect may vary between input method implementations.
7354
7355     \since 4.6
7356
7357     \sa setInputMethodHints(), inputMethodQuery()
7358 */
7359 Qt::InputMethodHints QGraphicsItem::inputMethodHints() const
7360 {
7361     Q_D(const QGraphicsItem);
7362     return d->imHints;
7363 }
7364
7365 /*!
7366     Sets the current input method hints of this item to \a hints.
7367
7368     \since 4.6
7369
7370     \sa inputMethodHints(), inputMethodQuery()
7371 */
7372 void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
7373 {
7374     Q_D(QGraphicsItem);
7375     d->imHints = hints;
7376     if (!hasFocus())
7377         return;
7378     d->scene->d_func()->updateInputMethodSensitivityInViews();
7379     QWidget *fw = QApplication::focusWidget();
7380     if (!fw)
7381         return;
7382     qApp->inputMethod()->update(Qt::ImHints);
7383 }
7384
7385 /*!
7386     Updates the item's micro focus.
7387
7388     \since 4.7
7389
7390     \sa QInputMethod
7391 */
7392 void QGraphicsItem::updateMicroFocus()
7393 {
7394 #if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS))
7395     if (QWidget *fw = QApplication::focusWidget()) {
7396         if (scene()) {
7397             for (int i = 0 ; i < scene()->views().count() ; ++i) {
7398                 if (scene()->views().at(i) == fw) {
7399                     if (qApp)
7400                         qApp->inputMethod()->update(Qt::ImQueryAll);
7401
7402 #ifndef QT_NO_ACCESSIBILITY
7403                     // ##### is this correct
7404                     if (toGraphicsObject())
7405                         QAccessible::updateAccessibility(toGraphicsObject(), 0, QAccessible::StateChanged);
7406 #endif
7407                     break;
7408                     }
7409                 }
7410             }
7411         }
7412     }
7413 #endif
7414 }
7415
7416 /*!
7417     This virtual function is called by QGraphicsItem to notify custom items
7418     that some part of the item's state changes. By reimplementing this
7419     function, your can react to a change, and in some cases, (depending on \a
7420     change,) adjustments can be made.
7421
7422     \a change is the parameter of the item that is changing. \a value is the
7423     new value; the type of the value depends on \a change.
7424
7425     Example:
7426
7427     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 15
7428
7429     The default implementation does nothing, and returns \a value.
7430
7431     Note: Certain QGraphicsItem functions cannot be called in a
7432     reimplementation of this function; see the GraphicsItemChange
7433     documentation for details.
7434
7435     \sa GraphicsItemChange
7436 */
7437 QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value)
7438 {
7439     Q_UNUSED(change);
7440     return value;
7441 }
7442
7443 /*!
7444     \internal
7445
7446     Note: This is provided as a hook to avoid future problems related
7447     to adding virtual functions.
7448 */
7449 bool QGraphicsItem::supportsExtension(Extension extension) const
7450 {
7451     Q_UNUSED(extension);
7452     return false;
7453 }
7454
7455 /*!
7456     \internal
7457
7458     Note: This is provided as a hook to avoid future problems related
7459     to adding virtual functions.
7460 */
7461 void QGraphicsItem::setExtension(Extension extension, const QVariant &variant)
7462 {
7463     Q_UNUSED(extension);
7464     Q_UNUSED(variant);
7465 }
7466
7467 /*!
7468     \internal
7469
7470     Note: This is provided as a hook to avoid future problems related
7471     to adding virtual functions.
7472 */
7473 QVariant QGraphicsItem::extension(const QVariant &variant) const
7474 {
7475     Q_UNUSED(variant);
7476     return QVariant();
7477 }
7478
7479 /*!
7480     \internal
7481
7482     Adds this item to the scene's index. Called in conjunction with
7483     removeFromIndex() to ensure the index bookkeeping is correct when
7484     the item's position, transformation or shape changes.
7485 */
7486 void QGraphicsItem::addToIndex()
7487 {
7488     if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
7489         // ### add to child index only if applicable
7490         return;
7491     }
7492     if (d_ptr->scene)
7493         d_ptr->scene->d_func()->index->addItem(this);
7494 }
7495
7496 /*!
7497     \internal
7498
7499     Removes this item from the scene's index. Called in conjunction
7500     with addToIndex() to ensure the index bookkeeping is correct when
7501     the item's position, transformation or shape changes.
7502 */
7503 void QGraphicsItem::removeFromIndex()
7504 {
7505     if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
7506         // ### remove from child index only if applicable
7507         return;
7508     }
7509     if (d_ptr->scene)
7510         d_ptr->scene->d_func()->index->removeItem(this);
7511 }
7512
7513 /*!
7514     Prepares the item for a geometry change. Call this function before
7515     changing the bounding rect of an item to keep QGraphicsScene's index up to
7516     date.
7517
7518     prepareGeometryChange() will call update() if this is necessary.
7519
7520     Example:
7521
7522     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 16
7523
7524     \sa boundingRect()
7525 */
7526 void QGraphicsItem::prepareGeometryChange()
7527 {
7528     if (d_ptr->inDestructor)
7529         return;
7530     if (d_ptr->scene) {
7531         d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true;
7532         d_ptr->geometryChanged = 1;
7533         d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
7534         d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper;
7535
7536         QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
7537         scenePrivate->index->prepareBoundingRectChange(this);
7538         scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false,
7539                                 /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false,
7540                                 /*updateBoundingRect=*/true);
7541
7542         // For compatibility reasons, we have to update the item's old geometry
7543         // if someone is connected to the changed signal or the scene has no views.
7544         // Note that this has to be done *after* markDirty to ensure that
7545         // _q_processDirtyItems is called before _q_emitUpdated.
7546         if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
7547             || scenePrivate->views.isEmpty()) {
7548             if (d_ptr->hasTranslateOnlySceneTransform()) {
7549                 d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
7550                                                                d_ptr->sceneTransform.dy()));
7551             } else {
7552                 d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect()));
7553             }
7554         }
7555     }
7556
7557     d_ptr->markParentDirty(/*updateBoundingRect=*/true);
7558 }
7559
7560 /*!
7561     \internal
7562
7563     Highlights \a item as selected.
7564
7565     NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in
7566           qgraphicssvgitem.cpp!
7567 */
7568 static void qt_graphicsItem_highlightSelected(
7569     QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option)
7570 {
7571     const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1));
7572     if (qFuzzyIsNull(qMax(murect.width(), murect.height())))
7573         return;
7574
7575     const QRectF mbrect = painter->transform().mapRect(item->boundingRect());
7576     if (qMin(mbrect.width(), mbrect.height()) < qreal(1.0))
7577         return;
7578
7579     qreal itemPenWidth;
7580     switch (item->type()) {
7581         case QGraphicsEllipseItem::Type:
7582             itemPenWidth = static_cast<QGraphicsEllipseItem *>(item)->pen().widthF();
7583             break;
7584         case QGraphicsPathItem::Type:
7585             itemPenWidth = static_cast<QGraphicsPathItem *>(item)->pen().widthF();
7586             break;
7587         case QGraphicsPolygonItem::Type:
7588             itemPenWidth = static_cast<QGraphicsPolygonItem *>(item)->pen().widthF();
7589             break;
7590         case QGraphicsRectItem::Type:
7591             itemPenWidth = static_cast<QGraphicsRectItem *>(item)->pen().widthF();
7592             break;
7593         case QGraphicsSimpleTextItem::Type:
7594             itemPenWidth = static_cast<QGraphicsSimpleTextItem *>(item)->pen().widthF();
7595             break;
7596         case QGraphicsLineItem::Type:
7597             itemPenWidth = static_cast<QGraphicsLineItem *>(item)->pen().widthF();
7598             break;
7599         default:
7600             itemPenWidth = 1.0;
7601     }
7602     const qreal pad = itemPenWidth / 2;
7603
7604     const qreal penWidth = 0; // cosmetic pen
7605
7606     const QColor fgcolor = option->palette.windowText().color();
7607     const QColor bgcolor( // ensure good contrast against fgcolor
7608         fgcolor.red()   > 127 ? 0 : 255,
7609         fgcolor.green() > 127 ? 0 : 255,
7610         fgcolor.blue()  > 127 ? 0 : 255);
7611
7612     painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
7613     painter->setBrush(Qt::NoBrush);
7614     painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
7615
7616     painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
7617     painter->setBrush(Qt::NoBrush);
7618     painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
7619 }
7620
7621 /*!
7622     \class QGraphicsObject
7623     \brief The QGraphicsObject class provides a base class for all graphics items that
7624     require signals, slots and properties.
7625     \since 4.6
7626     \ingroup graphicsview-api
7627     \inmodule QtWidgets
7628
7629     The class extends a QGraphicsItem with QObject's signal/slot and property mechanisms.
7630     It maps many of QGraphicsItem's basic setters and getters to properties and adds notification
7631     signals for many of them.
7632
7633     \section1 Parents and Children
7634
7635     Each graphics object can be constructed with a parent item. This ensures that the
7636     item will be destroyed when its parent item is destroyed. Although QGraphicsObject
7637     inherits from both QObject and QGraphicsItem, you should use the functions provided
7638     by QGraphicsItem, \e not QObject, to manage the relationships between parent and
7639     child items.
7640
7641     The relationships between items can be explored using the parentItem() and childItems()
7642     functions. In the hierarchy of items in a scene, the parentObject() and parentWidget()
7643     functions are the equivalent of the QWidget::parent() and QWidget::parentWidget()
7644     functions for QWidget subclasses.
7645
7646     \sa QGraphicsWidget
7647 */
7648
7649 /*!
7650     Constructs a QGraphicsObject with \a parent.
7651 */
7652 QGraphicsObject::QGraphicsObject(QGraphicsItem *parent)
7653         : QGraphicsItem(parent)
7654 {
7655     QGraphicsItem::d_ptr->isObject = true;
7656 }
7657
7658 /*!
7659   \internal
7660 */
7661 QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene)
7662     : QGraphicsItem(dd, parent, scene)
7663 {
7664     QGraphicsItem::d_ptr->isObject = true;
7665 }
7666
7667 #ifndef QT_NO_GESTURES
7668 /*!
7669     Subscribes the graphics object to the given \a gesture with specific \a flags.
7670
7671     \sa ungrabGesture(), QGestureEvent
7672 */
7673 void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
7674 {
7675     bool contains = QGraphicsItem::d_ptr->gestureContext.contains(gesture);
7676     QGraphicsItem::d_ptr->gestureContext.insert(gesture, flags);
7677     if (!contains && QGraphicsItem::d_ptr->scene)
7678         QGraphicsItem::d_ptr->scene->d_func()->grabGesture(this, gesture);
7679 }
7680
7681 /*!
7682     Unsubscribes the graphics object from the given \a gesture.
7683
7684     \sa grabGesture(), QGestureEvent
7685 */
7686 void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
7687 {
7688     if (QGraphicsItem::d_ptr->gestureContext.remove(gesture) && QGraphicsItem::d_ptr->scene)
7689         QGraphicsItem::d_ptr->scene->d_func()->ungrabGesture(this, gesture);
7690 }
7691 #endif // QT_NO_GESTURES
7692
7693 /*!
7694     Updates the item's micro focus. This is slot for convenience.
7695
7696     \since 4.7
7697
7698     \sa QInputMethod
7699 */
7700 void QGraphicsObject::updateMicroFocus()
7701 {
7702     QGraphicsItem::updateMicroFocus();
7703 }
7704
7705 void QGraphicsItemPrivate::children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item)
7706 {
7707     if (item) {
7708         QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(list->object);
7709         if (QGraphicsItemPrivate::get(graphicsObject)->sendParentChangeNotification) {
7710             item->setParentItem(graphicsObject);
7711         } else {
7712             QGraphicsItemPrivate::get(item)->setParentItemHelper(graphicsObject, 0, 0);
7713         }
7714     }
7715 }
7716
7717 int QGraphicsItemPrivate::children_count(QDeclarativeListProperty<QGraphicsObject> *list)
7718 {
7719     QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7720     return d->children.count();
7721 }
7722
7723 QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGraphicsObject> *list, int index)
7724 {
7725     QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7726     if (index >= 0 && index < d->children.count())
7727         return d->children.at(index)->toGraphicsObject();
7728     else
7729         return 0;
7730 }
7731
7732 void QGraphicsItemPrivate::children_clear(QDeclarativeListProperty<QGraphicsObject> *list)
7733 {
7734     QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7735     int childCount = d->children.count();
7736     if (d->sendParentChangeNotification) {
7737         for (int index = 0; index < childCount; index++)
7738             d->children.at(0)->setParentItem(0);
7739     } else {
7740         for (int index = 0; index < childCount; index++)
7741             QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, 0, 0);
7742     }
7743 }
7744
7745 /*!
7746     Returns a list of this item's children.
7747
7748     The items are sorted by stacking order. This takes into account both the
7749     items' insertion order and their Z-values.
7750
7751 */
7752 QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList()
7753 {
7754     Q_Q(QGraphicsItem);
7755     if (isObject) {
7756         QGraphicsObject *that = static_cast<QGraphicsObject *>(q);
7757         return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append,
7758                                                          children_count, children_at, children_clear);
7759     } else {
7760         //QGraphicsItem is not supported for this property
7761         return QDeclarativeListProperty<QGraphicsObject>();
7762     }
7763 }
7764
7765 /*!
7766   \internal
7767   Returns the width of the item
7768   Reimplemented by QGraphicsWidget
7769 */
7770 qreal QGraphicsItemPrivate::width() const
7771 {
7772     return 0;
7773 }
7774
7775 /*!
7776   \internal
7777   Set the width of the item
7778   Reimplemented by QGraphicsWidget
7779 */
7780 void QGraphicsItemPrivate::setWidth(qreal w)
7781 {
7782     Q_UNUSED(w);
7783 }
7784
7785 /*!
7786   \internal
7787   Reset the width of the item
7788   Reimplemented by QGraphicsWidget
7789 */
7790 void QGraphicsItemPrivate::resetWidth()
7791 {
7792 }
7793
7794 /*!
7795   \internal
7796   Returns the height of the item
7797   Reimplemented by QGraphicsWidget
7798 */
7799 qreal QGraphicsItemPrivate::height() const
7800 {
7801     return 0;
7802 }
7803
7804 /*!
7805   \internal
7806   Set the height of the item
7807   Reimplemented by QGraphicsWidget
7808 */
7809 void QGraphicsItemPrivate::setHeight(qreal h)
7810 {
7811     Q_UNUSED(h);
7812 }
7813
7814 /*!
7815   \internal
7816   Reset the height of the item
7817   Reimplemented by QGraphicsWidget
7818 */
7819 void QGraphicsItemPrivate::resetHeight()
7820 {
7821 }
7822
7823 /*!
7824     \property QGraphicsObject::children
7825     \since 4.7
7826     \internal
7827 */
7828
7829 /*!
7830     \property QGraphicsObject::width
7831     \since 4.7
7832     \internal
7833 */
7834
7835 /*!
7836     \property QGraphicsObject::height
7837     \since 4.7
7838     \internal
7839 */
7840
7841 /*!
7842   \property QGraphicsObject::parent
7843   \brief the parent of the item
7844
7845   \note The item's parent is set independently of the parent object returned
7846   by QObject::parent().
7847
7848   \sa QGraphicsItem::setParentItem(), QGraphicsItem::parentObject()
7849 */
7850
7851 /*!
7852   \property QGraphicsObject::opacity
7853   \brief the opacity of the item
7854
7855   \sa QGraphicsItem::setOpacity(), QGraphicsItem::opacity()
7856 */
7857
7858 /*!
7859   \fn QGraphicsObject::opacityChanged()
7860
7861   This signal gets emitted whenever the opacity of the item changes
7862
7863   \sa QGraphicsItem::opacity()
7864 */
7865
7866 /*!
7867   \fn QGraphicsObject::parentChanged()
7868
7869   This signal gets emitted whenever the parent of the item changes
7870 */
7871
7872 /*!
7873   \property QGraphicsObject::pos
7874   \brief the position of the item
7875
7876   Describes the items position.
7877
7878   \sa QGraphicsItem::setPos(), QGraphicsItem::pos()
7879 */
7880
7881 /*!
7882   \property QGraphicsObject::x
7883   \brief the x position of the item
7884
7885   Describes the items x position.
7886
7887   \sa QGraphicsItem::setX(), setPos(), xChanged()
7888 */
7889
7890 /*!
7891   \fn QGraphicsObject::xChanged()
7892
7893   This signal gets emitted whenever the x position of the item changes
7894
7895   \sa pos()
7896 */
7897
7898 /*!
7899   \property QGraphicsObject::y
7900   \brief the y position of the item
7901
7902   Describes the items y position.
7903
7904   \sa QGraphicsItem::setY(), setPos(), yChanged()
7905 */
7906
7907 /*!
7908   \fn QGraphicsObject::yChanged()
7909
7910   This signal gets emitted whenever the y position of the item changes.
7911
7912   \sa pos()
7913 */
7914
7915 /*!
7916   \property QGraphicsObject::z
7917   \brief the z value of the item
7918
7919   Describes the items z value.
7920
7921   \sa QGraphicsItem::setZValue(), zValue(), zChanged()
7922 */
7923
7924 /*!
7925   \fn QGraphicsObject::zChanged()
7926
7927   This signal gets emitted whenever the z value of the item changes.
7928
7929   \sa pos()
7930 */
7931
7932 /*!
7933   \property QGraphicsObject::rotation
7934   This property holds the rotation of the item in degrees.
7935
7936   This specifies how many degrees to rotate the item around its transformOrigin.
7937   The default rotation is 0 degrees (i.e. not rotated at all).
7938 */
7939
7940 /*!
7941   \fn QGraphicsObject::rotationChanged()
7942
7943   This signal gets emitted whenever the roation of the item changes.
7944 */
7945
7946 /*!
7947   \property QGraphicsObject::scale
7948   This property holds the scale of the item.
7949
7950   A scale of less than 1 means the item will be displayed smaller than
7951   normal, and a scale of greater than 1 means the item will be
7952   displayed larger than normal.  A negative scale means the item will
7953   be mirrored.
7954
7955   By default, items are displayed at a scale of 1 (i.e. at their
7956   normal size).
7957
7958   Scaling is from the item's transformOrigin.
7959 */
7960
7961 /*!
7962   \fn void QGraphicsObject::scaleChanged()
7963
7964   This signal is emitted when the scale of the item changes.
7965 */
7966
7967
7968 /*!
7969   \property QGraphicsObject::enabled
7970   \brief whether the item is enabled or not
7971
7972   This property is declared in QGraphicsItem.
7973
7974   By default, this property is true.
7975
7976   \sa QGraphicsItem::isEnabled(), QGraphicsItem::setEnabled()
7977   \sa QGraphicsObject::enabledChanged()
7978 */
7979
7980 /*!
7981   \fn void QGraphicsObject::enabledChanged()
7982
7983   This signal gets emitted whenever the item get's enabled or disabled.
7984
7985   \sa isEnabled()
7986 */
7987
7988 /*!
7989   \property QGraphicsObject::visible
7990   \brief whether the item is visible or not
7991
7992   This property is declared in QGraphicsItem.
7993
7994   By default, this property is true.
7995
7996   \sa QGraphicsItem::isVisible(), QGraphicsItem::setVisible(), visibleChanged()
7997 */
7998
7999 /*!
8000   \fn QGraphicsObject::visibleChanged()
8001
8002   This signal gets emitted whenever the visibility of the item changes
8003
8004   \sa visible
8005 */
8006
8007 /*!
8008   \fn const QObjectList &QGraphicsObject::children() const
8009   \internal
8010
8011   This function returns the same value as QObject::children(). It's
8012   provided to differentiate between the obsolete member
8013   QGraphicsItem::children() and QObject::children(). QGraphicsItem now
8014   provides childItems() instead.
8015 */
8016
8017 /*!
8018   \property QGraphicsObject::transformOriginPoint
8019   \brief the transformation origin
8020
8021   This property sets a specific point in the items coordiante system as the
8022   origin for scale and rotation.
8023
8024   \sa scale, rotation, QGraphicsItem::transformOriginPoint()
8025 */
8026
8027 /*!
8028     \fn void QGraphicsObject::widthChanged()
8029     \internal
8030 */
8031
8032 /*!
8033     \fn void QGraphicsObject::heightChanged()
8034     \internal
8035 */
8036
8037 /*!
8038
8039   \fn QGraphicsObject::childrenChanged()
8040
8041   This signal gets emitted whenever the children list changes
8042   \internal
8043 */
8044
8045 /*!
8046   \property QGraphicsObject::effect
8047   \since 4.7
8048   \brief the effect attached to this item
8049
8050   \sa QGraphicsItem::setGraphicsEffect(), QGraphicsItem::graphicsEffect()
8051 */
8052
8053 /*!
8054     \class QAbstractGraphicsShapeItem
8055     \brief The QAbstractGraphicsShapeItem class provides a common base for
8056     all path items.
8057     \since 4.2
8058     \ingroup graphicsview-api
8059     \inmodule QtWidgets
8060
8061     This class does not fully implement an item by itself; in particular, it
8062     does not implement boundingRect() and paint(), which are inherited by
8063     QGraphicsItem.
8064
8065     You can subclass this item to provide a simple base implementation of
8066     accessors for the item's pen and brush.
8067
8068     \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPathItem,
8069     QGraphicsPolygonItem, QGraphicsTextItem, QGraphicsLineItem,
8070     QGraphicsPixmapItem, {Graphics View Framework}
8071 */
8072
8073 class QAbstractGraphicsShapeItemPrivate : public QGraphicsItemPrivate
8074 {
8075     Q_DECLARE_PUBLIC(QAbstractGraphicsShapeItem)
8076 public:
8077
8078     QBrush brush;
8079     QPen pen;
8080
8081     // Cached bounding rectangle
8082     mutable QRectF boundingRect;
8083 };
8084
8085 /*!
8086     Constructs a QAbstractGraphicsShapeItem. \a parent is passed to
8087     QGraphicsItem's constructor.
8088 */
8089 QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QGraphicsItem *parent
8090 #ifndef Q_QDOC
8091                                                        // obsolete argument
8092                                                        , QGraphicsScene *scene
8093 #endif
8094     )
8095     : QGraphicsItem(*new QAbstractGraphicsShapeItemPrivate, parent, scene)
8096 {
8097 }
8098
8099 /*!
8100     \internal
8101 */
8102 QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QAbstractGraphicsShapeItemPrivate &dd,
8103                                                      QGraphicsItem *parent,
8104                                                      QGraphicsScene *scene)
8105     : QGraphicsItem(dd, parent, scene)
8106 {
8107 }
8108
8109 /*!
8110     Destroys a QAbstractGraphicsShapeItem.
8111 */
8112 QAbstractGraphicsShapeItem::~QAbstractGraphicsShapeItem()
8113 {
8114 }
8115
8116 /*!
8117     Returns the item's pen. If no pen has been set, this function returns
8118     QPen(), a default black solid line pen with 0 width.
8119 */
8120 QPen QAbstractGraphicsShapeItem::pen() const
8121 {
8122     Q_D(const QAbstractGraphicsShapeItem);
8123     return d->pen;
8124 }
8125
8126 /*!
8127     Sets the pen for this item to \a pen.
8128
8129     The pen is used to draw the item's outline.
8130
8131     \sa pen()
8132 */
8133 void QAbstractGraphicsShapeItem::setPen(const QPen &pen)
8134 {
8135     Q_D(QAbstractGraphicsShapeItem);
8136     if (d->pen == pen)
8137         return;
8138     prepareGeometryChange();
8139     d->pen = pen;
8140     d->boundingRect = QRectF();
8141     update();
8142 }
8143
8144 /*!
8145     Returns the item's brush, or an empty brush if no brush has been set.
8146
8147     \sa setBrush()
8148 */
8149 QBrush QAbstractGraphicsShapeItem::brush() const
8150 {
8151     Q_D(const QAbstractGraphicsShapeItem);
8152     return d->brush;
8153 }
8154
8155 /*!
8156     Sets the item's brush to \a brush.
8157
8158     The item's brush is used to fill the item.
8159
8160     If you use a brush with a QGradient, the gradient
8161     is relative to the item's coordinate system.
8162
8163     \sa brush()
8164 */
8165 void QAbstractGraphicsShapeItem::setBrush(const QBrush &brush)
8166 {
8167     Q_D(QAbstractGraphicsShapeItem);
8168     if (d->brush == brush)
8169         return;
8170     d->brush = brush;
8171     update();
8172 }
8173
8174 /*!
8175     \reimp
8176 */
8177 bool QAbstractGraphicsShapeItem::isObscuredBy(const QGraphicsItem *item) const
8178 {
8179     return QGraphicsItem::isObscuredBy(item);
8180 }
8181
8182 /*!
8183     \reimp
8184 */
8185 QPainterPath QAbstractGraphicsShapeItem::opaqueArea() const
8186 {
8187     Q_D(const QAbstractGraphicsShapeItem);
8188     if (d->brush.isOpaque())
8189         return isClipped() ? clipPath() : shape();
8190     return QGraphicsItem::opaqueArea();
8191 }
8192
8193 /*!
8194     \class QGraphicsPathItem
8195     \brief The QGraphicsPathItem class provides a path item that you
8196     can add to a QGraphicsScene.
8197     \since 4.2
8198     \ingroup graphicsview-api
8199     \inmodule QtWidgets
8200
8201     To set the item's path, pass a QPainterPath to QGraphicsPathItem's
8202     constructor, or call the setPath() function. The path() function
8203     returns the current path.
8204
8205     \image graphicsview-pathitem.png
8206
8207     QGraphicsPathItem uses the path to provide a reasonable
8208     implementation of boundingRect(), shape(), and contains(). The
8209     paint() function draws the path using the item's associated pen
8210     and brush, which you can set by calling the setPen() and
8211     setBrush() functions.
8212
8213     \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
8214     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8215     View Framework}
8216 */
8217
8218 class QGraphicsPathItemPrivate : public QAbstractGraphicsShapeItemPrivate
8219 {
8220     Q_DECLARE_PUBLIC(QGraphicsPathItem)
8221 public:
8222     QPainterPath path;
8223 };
8224
8225 /*!
8226     Constructs a QGraphicsPath item using \a path as the default path. \a
8227     parent is passed to QAbstractGraphicsShapeItem's constructor.
8228
8229     \sa QGraphicsScene::addItem()
8230 */
8231 QGraphicsPathItem::QGraphicsPathItem(const QPainterPath &path,
8232                                      QGraphicsItem *parent
8233 #ifndef Q_QDOC
8234                                      // obsolete argument
8235                                      , QGraphicsScene *scene
8236 #endif
8237     )
8238     : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
8239 {
8240     if (!path.isEmpty())
8241         setPath(path);
8242 }
8243
8244 /*!
8245     Constructs a QGraphicsPath. \a parent is passed to
8246     QAbstractGraphicsShapeItem's constructor.
8247
8248     \sa QGraphicsScene::addItem()
8249 */
8250 QGraphicsPathItem::QGraphicsPathItem(QGraphicsItem *parent
8251 #ifndef Q_QDOC
8252                                      // obsolete argument
8253                                      , QGraphicsScene *scene
8254 #endif
8255     )
8256     : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
8257 {
8258 }
8259
8260 /*!
8261     Destroys the QGraphicsPathItem.
8262 */
8263 QGraphicsPathItem::~QGraphicsPathItem()
8264 {
8265 }
8266
8267 /*!
8268     Returns the item's path as a QPainterPath. If no item has been set, an
8269     empty QPainterPath is returned.
8270
8271     \sa setPath()
8272 */
8273 QPainterPath QGraphicsPathItem::path() const
8274 {
8275     Q_D(const QGraphicsPathItem);
8276     return d->path;
8277 }
8278
8279 /*!
8280     Sets the item's path to be the given \a path.
8281
8282     \sa path()
8283 */
8284 void QGraphicsPathItem::setPath(const QPainterPath &path)
8285 {
8286     Q_D(QGraphicsPathItem);
8287     if (d->path == path)
8288         return;
8289     prepareGeometryChange();
8290     d->path = path;
8291     d->boundingRect = QRectF();
8292     update();
8293 }
8294
8295 /*!
8296     \reimp
8297 */
8298 QRectF QGraphicsPathItem::boundingRect() const
8299 {
8300     Q_D(const QGraphicsPathItem);
8301     if (d->boundingRect.isNull()) {
8302         qreal pw = pen().widthF();
8303         if (pw == 0.0)
8304             d->boundingRect = d->path.controlPointRect();
8305         else {
8306             d->boundingRect = shape().controlPointRect();
8307         }
8308     }
8309     return d->boundingRect;
8310 }
8311
8312 /*!
8313     \reimp
8314 */
8315 QPainterPath QGraphicsPathItem::shape() const
8316 {
8317     Q_D(const QGraphicsPathItem);
8318     return qt_graphicsItem_shapeFromPath(d->path, d->pen);
8319 }
8320
8321 /*!
8322     \reimp
8323 */
8324 bool QGraphicsPathItem::contains(const QPointF &point) const
8325 {
8326     return QAbstractGraphicsShapeItem::contains(point);
8327 }
8328
8329 /*!
8330     \reimp
8331 */
8332 void QGraphicsPathItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8333                               QWidget *widget)
8334 {
8335     Q_D(QGraphicsPathItem);
8336     Q_UNUSED(widget);
8337     painter->setPen(d->pen);
8338     painter->setBrush(d->brush);
8339     painter->drawPath(d->path);
8340
8341     if (option->state & QStyle::State_Selected)
8342         qt_graphicsItem_highlightSelected(this, painter, option);
8343 }
8344
8345 /*!
8346     \reimp
8347 */
8348 bool QGraphicsPathItem::isObscuredBy(const QGraphicsItem *item) const
8349 {
8350     return QAbstractGraphicsShapeItem::isObscuredBy(item);
8351 }
8352
8353 /*!
8354     \reimp
8355 */
8356 QPainterPath QGraphicsPathItem::opaqueArea() const
8357 {
8358     return QAbstractGraphicsShapeItem::opaqueArea();
8359 }
8360
8361 /*!
8362     \reimp
8363 */
8364 int QGraphicsPathItem::type() const
8365 {
8366     return Type;
8367 }
8368
8369 /*!
8370     \internal
8371 */
8372 bool QGraphicsPathItem::supportsExtension(Extension extension) const
8373 {
8374     Q_UNUSED(extension);
8375     return false;
8376 }
8377
8378 /*!
8379     \internal
8380 */
8381 void QGraphicsPathItem::setExtension(Extension extension, const QVariant &variant)
8382 {
8383     Q_UNUSED(extension);
8384     Q_UNUSED(variant);
8385 }
8386
8387 /*!
8388     \internal
8389 */
8390 QVariant QGraphicsPathItem::extension(const QVariant &variant) const
8391 {
8392     Q_UNUSED(variant);
8393     return QVariant();
8394 }
8395
8396 /*!
8397     \class QGraphicsRectItem
8398     \brief The QGraphicsRectItem class provides a rectangle item that you
8399     can add to a QGraphicsScene.
8400     \since 4.2
8401     \ingroup graphicsview-api
8402     \inmodule QtWidgets
8403
8404     To set the item's rectangle, pass a QRectF to QGraphicsRectItem's
8405     constructor, or call the setRect() function. The rect() function
8406     returns the current rectangle.
8407
8408     \image graphicsview-rectitem.png
8409
8410     QGraphicsRectItem uses the rectangle and the pen width to provide
8411     a reasonable implementation of boundingRect(), shape(), and
8412     contains(). The paint() function draws the rectangle using the
8413     item's associated pen and brush, which you can set by calling the
8414     setPen() and setBrush() functions.
8415
8416     \note The rendering of invalid rectangles, such as those with negative
8417     widths or heights, is undefined. If you cannot be sure that you are
8418     using valid rectangles (for example, if you are creating
8419     rectangles using data from an unreliable source) then you should
8420     use QRectF::normalized() to create normalized rectangles, and use
8421     those instead.
8422
8423     \sa QGraphicsPathItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
8424     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8425     View Framework}
8426 */
8427
8428 class QGraphicsRectItemPrivate : public QAbstractGraphicsShapeItemPrivate
8429 {
8430     Q_DECLARE_PUBLIC(QGraphicsRectItem)
8431 public:
8432     QRectF rect;
8433 };
8434
8435 /*!
8436     Constructs a QGraphicsRectItem, using \a rect as the default rectangle.
8437     \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8438
8439     \sa QGraphicsScene::addItem()
8440 */
8441 QGraphicsRectItem::QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent
8442 #ifndef Q_QDOC
8443                                      // obsolete argument
8444                                      , QGraphicsScene *scene
8445 #endif
8446     )
8447     : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
8448 {
8449     setRect(rect);
8450 }
8451
8452 /*!
8453     \fn QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal width, qreal height,
8454                                      QGraphicsItem *parent)
8455
8456     Constructs a QGraphicsRectItem with a default rectangle defined
8457     by (\a x, \a y) and the given \a width and \a height.
8458
8459     \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8460
8461     \sa QGraphicsScene::addItem()
8462 */
8463 QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h,
8464                                      QGraphicsItem *parent
8465 #ifndef Q_QDOC
8466                                      // obsolete argument
8467                                      , QGraphicsScene *scene
8468 #endif
8469     )
8470     : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
8471 {
8472     setRect(QRectF(x, y, w, h));
8473 }
8474
8475 /*!
8476     Constructs a QGraphicsRectItem. \a parent is passed to
8477     QAbstractGraphicsShapeItem's constructor.
8478
8479     \sa QGraphicsScene::addItem()
8480 */
8481 QGraphicsRectItem::QGraphicsRectItem(QGraphicsItem *parent
8482 #ifndef Q_QDOC
8483                                      // obsolete argument
8484                                      , QGraphicsScene *scene
8485 #endif
8486     )
8487     : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
8488 {
8489 }
8490
8491 /*!
8492     Destroys the QGraphicsRectItem.
8493 */
8494 QGraphicsRectItem::~QGraphicsRectItem()
8495 {
8496 }
8497
8498 /*!
8499     Returns the item's rectangle.
8500
8501     \sa setRect()
8502 */
8503 QRectF QGraphicsRectItem::rect() const
8504 {
8505     Q_D(const QGraphicsRectItem);
8506     return d->rect;
8507 }
8508
8509 /*!
8510     \fn void QGraphicsRectItem::setRect(const QRectF &rectangle)
8511
8512     Sets the item's rectangle to be the given \a rectangle.
8513
8514     \sa rect()
8515 */
8516 void QGraphicsRectItem::setRect(const QRectF &rect)
8517 {
8518     Q_D(QGraphicsRectItem);
8519     if (d->rect == rect)
8520         return;
8521     prepareGeometryChange();
8522     d->rect = rect;
8523     d->boundingRect = QRectF();
8524     update();
8525 }
8526
8527 /*!
8528     \fn void QGraphicsRectItem::setRect(qreal x, qreal y, qreal width, qreal height)
8529     \fn void QGraphicsEllipseItem::setRect(qreal x, qreal y, qreal width, qreal height)
8530
8531     Sets the item's rectangle to the rectangle defined by (\a x, \a y)
8532     and the given \a width and \a height.
8533
8534     This convenience function is equivalent to calling \c
8535     {setRect(QRectF(x, y, width, height))}
8536
8537     \sa rect()
8538 */
8539
8540 /*!
8541     \reimp
8542 */
8543 QRectF QGraphicsRectItem::boundingRect() const
8544 {
8545     Q_D(const QGraphicsRectItem);
8546     if (d->boundingRect.isNull()) {
8547         qreal halfpw = pen().widthF() / 2;
8548         d->boundingRect = d->rect;
8549         if (halfpw > 0.0)
8550             d->boundingRect.adjust(-halfpw, -halfpw, halfpw, halfpw);
8551     }
8552     return d->boundingRect;
8553 }
8554
8555 /*!
8556     \reimp
8557 */
8558 QPainterPath QGraphicsRectItem::shape() const
8559 {
8560     Q_D(const QGraphicsRectItem);
8561     QPainterPath path;
8562     path.addRect(d->rect);
8563     return qt_graphicsItem_shapeFromPath(path, d->pen);
8564 }
8565
8566 /*!
8567     \reimp
8568 */
8569 bool QGraphicsRectItem::contains(const QPointF &point) const
8570 {
8571     return QAbstractGraphicsShapeItem::contains(point);
8572 }
8573
8574 /*!
8575     \reimp
8576 */
8577 void QGraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8578                               QWidget *widget)
8579 {
8580     Q_D(QGraphicsRectItem);
8581     Q_UNUSED(widget);
8582     painter->setPen(d->pen);
8583     painter->setBrush(d->brush);
8584     painter->drawRect(d->rect);
8585
8586     if (option->state & QStyle::State_Selected)
8587         qt_graphicsItem_highlightSelected(this, painter, option);
8588 }
8589
8590 /*!
8591     \reimp
8592 */
8593 bool QGraphicsRectItem::isObscuredBy(const QGraphicsItem *item) const
8594 {
8595     return QAbstractGraphicsShapeItem::isObscuredBy(item);
8596 }
8597
8598 /*!
8599     \reimp
8600 */
8601 QPainterPath QGraphicsRectItem::opaqueArea() const
8602 {
8603     return QAbstractGraphicsShapeItem::opaqueArea();
8604 }
8605
8606 /*!
8607     \reimp
8608 */
8609 int QGraphicsRectItem::type() const
8610 {
8611     return Type;
8612 }
8613
8614 /*!
8615     \internal
8616 */
8617 bool QGraphicsRectItem::supportsExtension(Extension extension) const
8618 {
8619     Q_UNUSED(extension);
8620     return false;
8621 }
8622
8623 /*!
8624     \internal
8625 */
8626 void QGraphicsRectItem::setExtension(Extension extension, const QVariant &variant)
8627 {
8628     Q_UNUSED(extension);
8629     Q_UNUSED(variant);
8630 }
8631
8632 /*!
8633     \internal
8634 */
8635 QVariant QGraphicsRectItem::extension(const QVariant &variant) const
8636 {
8637     Q_UNUSED(variant);
8638     return QVariant();
8639 }
8640
8641 /*!
8642     \class QGraphicsEllipseItem
8643     \brief The QGraphicsEllipseItem class provides an ellipse item that you
8644     can add to a QGraphicsScene.
8645     \since 4.2
8646     \ingroup graphicsview-api
8647     \inmodule QtWidgets
8648
8649     QGraphicsEllipseItem respresents an ellipse with a fill and an outline,
8650     and you can also use it for ellipse segments (see startAngle(),
8651     spanAngle()).
8652
8653     \table
8654         \row
8655             \li \inlineimage graphicsview-ellipseitem.png
8656             \li \inlineimage graphicsview-ellipseitem-pie.png
8657     \endtable
8658
8659     To set the item's ellipse, pass a QRectF to QGraphicsEllipseItem's
8660     constructor, or call setRect(). The rect() function returns the
8661     current ellipse geometry.
8662
8663     QGraphicsEllipseItem uses the rect and the pen width to provide a
8664     reasonable implementation of boundingRect(), shape(), and contains(). The
8665     paint() function draws the ellipse using the item's associated pen and
8666     brush, which you can set by calling setPen() and setBrush().
8667
8668     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsPolygonItem,
8669     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8670     View Framework}
8671 */
8672
8673 class QGraphicsEllipseItemPrivate : public QAbstractGraphicsShapeItemPrivate
8674 {
8675     Q_DECLARE_PUBLIC(QGraphicsEllipseItem)
8676 public:
8677     inline QGraphicsEllipseItemPrivate()
8678         : startAngle(0), spanAngle(360 * 16)
8679     { }
8680
8681     QRectF rect;
8682     int startAngle;
8683     int spanAngle;
8684 };
8685
8686 /*!
8687     Constructs a QGraphicsEllipseItem using \a rect as the default rectangle.
8688     \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8689
8690     \sa QGraphicsScene::addItem()
8691 */
8692 QGraphicsEllipseItem::QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent
8693 #ifndef Q_QDOC
8694                                            // obsolete argument
8695                                            , QGraphicsScene *scene
8696 #endif
8697     )
8698     : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
8699 {
8700     setRect(rect);
8701 }
8702
8703 /*!
8704     \fn QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent)
8705     \since 4.3
8706
8707     Constructs a QGraphicsEllipseItem using the rectangle defined by (\a x, \a
8708     y) and the given \a width and \a height, as the default rectangle. \a
8709     parent is passed to QAbstractGraphicsShapeItem's constructor.
8710
8711     \sa QGraphicsScene::addItem()
8712 */
8713 QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h,
8714                                            QGraphicsItem *parent
8715 #ifndef Q_QDOC
8716                                            // obsolete argument
8717                                            , QGraphicsScene *scene
8718 #endif
8719     )
8720     : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
8721 {
8722     setRect(x,y,w,h);
8723 }
8724
8725
8726
8727 /*!
8728     Constructs a QGraphicsEllipseItem. \a parent is passed to
8729     QAbstractGraphicsShapeItem's constructor.
8730
8731     \sa QGraphicsScene::addItem()
8732 */
8733 QGraphicsEllipseItem::QGraphicsEllipseItem(QGraphicsItem *parent
8734 #ifndef Q_QDOC
8735                                            // obsolete argument
8736                                            , QGraphicsScene *scene
8737 #endif
8738     )
8739     : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
8740 {
8741 }
8742
8743 /*!
8744     Destroys the QGraphicsEllipseItem.
8745 */
8746 QGraphicsEllipseItem::~QGraphicsEllipseItem()
8747 {
8748 }
8749
8750 /*!
8751     Returns the item's ellipse geometry as a QRectF.
8752
8753     \sa setRect(), QPainter::drawEllipse()
8754 */
8755 QRectF QGraphicsEllipseItem::rect() const
8756 {
8757     Q_D(const QGraphicsEllipseItem);
8758     return d->rect;
8759 }
8760
8761 /*!
8762     Sets the item's ellipse geometry to \a rect. The rectangle's left edge
8763     defines the left edge of the ellipse, and the rectangle's top edge
8764     describes the top of the ellipse. The height and width of the rectangle
8765     describe the height and width of the ellipse.
8766
8767     \sa rect(), QPainter::drawEllipse()
8768 */
8769 void QGraphicsEllipseItem::setRect(const QRectF &rect)
8770 {
8771     Q_D(QGraphicsEllipseItem);
8772     if (d->rect == rect)
8773         return;
8774     prepareGeometryChange();
8775     d->rect = rect;
8776     d->boundingRect = QRectF();
8777     update();
8778 }
8779
8780 /*!
8781     Returns the start angle for an ellipse segment in 16ths of a degree. This
8782     angle is used together with spanAngle() for representing an ellipse
8783     segment (a pie). By default, the start angle is 0.
8784
8785     \sa setStartAngle(), spanAngle()
8786 */
8787 int QGraphicsEllipseItem::startAngle() const
8788 {
8789     Q_D(const QGraphicsEllipseItem);
8790     return d->startAngle;
8791 }
8792
8793 /*!
8794     Sets the start angle for an ellipse segment to \a angle, which is in 16ths
8795     of a degree. This angle is used together with spanAngle() for representing
8796     an ellipse segment (a pie). By default, the start angle is 0.
8797
8798     \sa startAngle(), setSpanAngle(), QPainter::drawPie()
8799 */
8800 void QGraphicsEllipseItem::setStartAngle(int angle)
8801 {
8802     Q_D(QGraphicsEllipseItem);
8803     if (angle != d->startAngle) {
8804         prepareGeometryChange();
8805         d->boundingRect = QRectF();
8806         d->startAngle = angle;
8807         update();
8808     }
8809 }
8810
8811 /*!
8812     Returns the span angle of an ellipse segment in 16ths of a degree. This
8813     angle is used together with startAngle() for representing an ellipse
8814     segment (a pie). By default, this function returns 5760 (360 * 16, a full
8815     ellipse).
8816
8817     \sa setSpanAngle(), startAngle()
8818 */
8819 int QGraphicsEllipseItem::spanAngle() const
8820 {
8821     Q_D(const QGraphicsEllipseItem);
8822     return d->spanAngle;
8823 }
8824
8825 /*!
8826     Sets the span angle for an ellipse segment to \a angle, which is in 16ths
8827     of a degree. This angle is used together with startAngle() to represent an
8828     ellipse segment (a pie). By default, the span angle is 5760 (360 * 16, a
8829     full ellipse).
8830
8831     \sa spanAngle(), setStartAngle(), QPainter::drawPie()
8832 */
8833 void QGraphicsEllipseItem::setSpanAngle(int angle)
8834 {
8835     Q_D(QGraphicsEllipseItem);
8836     if (angle != d->spanAngle) {
8837         prepareGeometryChange();
8838         d->boundingRect = QRectF();
8839         d->spanAngle = angle;
8840         update();
8841     }
8842 }
8843
8844 /*!
8845     \reimp
8846 */
8847 QRectF QGraphicsEllipseItem::boundingRect() const
8848 {
8849     Q_D(const QGraphicsEllipseItem);
8850     if (d->boundingRect.isNull()) {
8851         qreal pw = pen().widthF();
8852         if (pw == 0.0 && d->spanAngle == 360 * 16)
8853             d->boundingRect = d->rect;
8854         else
8855             d->boundingRect = shape().controlPointRect();
8856     }
8857     return d->boundingRect;
8858 }
8859
8860 /*!
8861     \reimp
8862 */
8863 QPainterPath QGraphicsEllipseItem::shape() const
8864 {
8865     Q_D(const QGraphicsEllipseItem);
8866     QPainterPath path;
8867     if (d->rect.isNull())
8868         return path;
8869     if (d->spanAngle != 360 * 16) {
8870         path.moveTo(d->rect.center());
8871         path.arcTo(d->rect, d->startAngle / 16.0, d->spanAngle / 16.0);
8872     } else {
8873         path.addEllipse(d->rect);
8874     }
8875
8876     return qt_graphicsItem_shapeFromPath(path, d->pen);
8877 }
8878
8879 /*!
8880     \reimp
8881 */
8882 bool QGraphicsEllipseItem::contains(const QPointF &point) const
8883 {
8884     return QAbstractGraphicsShapeItem::contains(point);
8885 }
8886
8887 /*!
8888     \reimp
8889 */
8890 void QGraphicsEllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8891                                  QWidget *widget)
8892 {
8893     Q_D(QGraphicsEllipseItem);
8894     Q_UNUSED(widget);
8895     painter->setPen(d->pen);
8896     painter->setBrush(d->brush);
8897     if ((d->spanAngle != 0) && (qAbs(d->spanAngle) % (360 * 16) == 0))
8898         painter->drawEllipse(d->rect);
8899     else
8900         painter->drawPie(d->rect, d->startAngle, d->spanAngle);
8901
8902     if (option->state & QStyle::State_Selected)
8903         qt_graphicsItem_highlightSelected(this, painter, option);
8904 }
8905
8906 /*!
8907     \reimp
8908 */
8909 bool QGraphicsEllipseItem::isObscuredBy(const QGraphicsItem *item) const
8910 {
8911     return QAbstractGraphicsShapeItem::isObscuredBy(item);
8912 }
8913
8914 /*!
8915     \reimp
8916 */
8917 QPainterPath QGraphicsEllipseItem::opaqueArea() const
8918 {
8919     return QAbstractGraphicsShapeItem::opaqueArea();
8920 }
8921
8922 /*!
8923     \reimp
8924 */
8925 int QGraphicsEllipseItem::type() const
8926 {
8927     return Type;
8928 }
8929
8930
8931 /*!
8932     \internal
8933 */
8934 bool QGraphicsEllipseItem::supportsExtension(Extension extension) const
8935 {
8936     Q_UNUSED(extension);
8937     return false;
8938 }
8939
8940 /*!
8941     \internal
8942 */
8943 void QGraphicsEllipseItem::setExtension(Extension extension, const QVariant &variant)
8944 {
8945     Q_UNUSED(extension);
8946     Q_UNUSED(variant);
8947 }
8948
8949 /*!
8950     \internal
8951 */
8952 QVariant QGraphicsEllipseItem::extension(const QVariant &variant) const
8953 {
8954     Q_UNUSED(variant);
8955     return QVariant();
8956 }
8957
8958 /*!
8959     \class QGraphicsPolygonItem
8960     \brief The QGraphicsPolygonItem class provides a polygon item that you
8961     can add to a QGraphicsScene.
8962     \since 4.2
8963     \ingroup graphicsview-api
8964     \inmodule QtWidgets
8965
8966     To set the item's polygon, pass a QPolygonF to
8967     QGraphicsPolygonItem's constructor, or call the setPolygon()
8968     function. The polygon() function returns the current polygon.
8969
8970     \image graphicsview-polygonitem.png
8971
8972     QGraphicsPolygonItem uses the polygon and the pen width to provide
8973     a reasonable implementation of boundingRect(), shape(), and
8974     contains(). The paint() function draws the polygon using the
8975     item's associated pen and brush, which you can set by calling the
8976     setPen() and setBrush() functions.
8977
8978     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
8979     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8980     View Framework}
8981 */
8982
8983 class QGraphicsPolygonItemPrivate : public QAbstractGraphicsShapeItemPrivate
8984 {
8985     Q_DECLARE_PUBLIC(QGraphicsPolygonItem)
8986 public:
8987     inline QGraphicsPolygonItemPrivate()
8988         : fillRule(Qt::OddEvenFill)
8989     { }
8990
8991     QPolygonF polygon;
8992     Qt::FillRule fillRule;
8993 };
8994
8995 /*!
8996     Constructs a QGraphicsPolygonItem with \a polygon as the default
8997     polygon. \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8998
8999     \sa QGraphicsScene::addItem()
9000 */
9001 QGraphicsPolygonItem::QGraphicsPolygonItem(const QPolygonF &polygon,
9002                                            QGraphicsItem *parent
9003 #ifndef Q_QDOC
9004                                            // obsolete argument
9005                                            , QGraphicsScene *scene
9006 #endif
9007     )
9008     : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
9009 {
9010     setPolygon(polygon);
9011 }
9012
9013 /*!
9014     Constructs a QGraphicsPolygonItem. \a parent is passed to
9015     QAbstractGraphicsShapeItem's constructor.
9016
9017     \sa QGraphicsScene::addItem()
9018 */
9019 QGraphicsPolygonItem::QGraphicsPolygonItem(QGraphicsItem *parent
9020 #ifndef Q_QDOC
9021                                            // obsolete argument
9022                                            , QGraphicsScene *scene
9023 #endif
9024     )
9025     : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
9026 {
9027 }
9028
9029 /*!
9030     Destroys the QGraphicsPolygonItem.
9031 */
9032 QGraphicsPolygonItem::~QGraphicsPolygonItem()
9033 {
9034 }
9035
9036 /*!
9037     Returns the item's polygon, or an empty polygon if no polygon
9038     has been set.
9039
9040     \sa setPolygon()
9041 */
9042 QPolygonF QGraphicsPolygonItem::polygon() const
9043 {
9044     Q_D(const QGraphicsPolygonItem);
9045     return d->polygon;
9046 }
9047
9048 /*!
9049     Sets the item's polygon to be the given \a polygon.
9050
9051     \sa polygon()
9052 */
9053 void QGraphicsPolygonItem::setPolygon(const QPolygonF &polygon)
9054 {
9055     Q_D(QGraphicsPolygonItem);
9056     if (d->polygon == polygon)
9057         return;
9058     prepareGeometryChange();
9059     d->polygon = polygon;
9060     d->boundingRect = QRectF();
9061     update();
9062 }
9063
9064 /*!
9065      Returns the fill rule of the polygon. The default fill rule is
9066      Qt::OddEvenFill.
9067
9068      \sa setFillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
9069 */
9070 Qt::FillRule QGraphicsPolygonItem::fillRule() const
9071 {
9072      Q_D(const QGraphicsPolygonItem);
9073      return d->fillRule;
9074 }
9075
9076 /*!
9077      Sets the fill rule of the polygon to \a rule. The default fill rule is
9078      Qt::OddEvenFill.
9079
9080      \sa fillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
9081 */
9082 void QGraphicsPolygonItem::setFillRule(Qt::FillRule rule)
9083 {
9084      Q_D(QGraphicsPolygonItem);
9085      if (rule != d->fillRule) {
9086          d->fillRule = rule;
9087          update();
9088      }
9089 }
9090
9091 /*!
9092     \reimp
9093 */
9094 QRectF QGraphicsPolygonItem::boundingRect() const
9095 {
9096     Q_D(const QGraphicsPolygonItem);
9097     if (d->boundingRect.isNull()) {
9098         qreal pw = pen().widthF();
9099         if (pw == 0.0)
9100             d->boundingRect = d->polygon.boundingRect();
9101         else
9102             d->boundingRect = shape().controlPointRect();
9103     }
9104     return d->boundingRect;
9105 }
9106
9107 /*!
9108     \reimp
9109 */
9110 QPainterPath QGraphicsPolygonItem::shape() const
9111 {
9112     Q_D(const QGraphicsPolygonItem);
9113     QPainterPath path;
9114     path.addPolygon(d->polygon);
9115     return qt_graphicsItem_shapeFromPath(path, d->pen);
9116 }
9117
9118 /*!
9119     \reimp
9120 */
9121 bool QGraphicsPolygonItem::contains(const QPointF &point) const
9122 {
9123     return QAbstractGraphicsShapeItem::contains(point);
9124 }
9125
9126 /*!
9127     \reimp
9128 */
9129 void QGraphicsPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
9130 {
9131     Q_D(QGraphicsPolygonItem);
9132     Q_UNUSED(widget);
9133     painter->setPen(d->pen);
9134     painter->setBrush(d->brush);
9135     painter->drawPolygon(d->polygon, d->fillRule);
9136
9137     if (option->state & QStyle::State_Selected)
9138         qt_graphicsItem_highlightSelected(this, painter, option);
9139 }
9140
9141 /*!
9142     \reimp
9143 */
9144 bool QGraphicsPolygonItem::isObscuredBy(const QGraphicsItem *item) const
9145 {
9146     return QAbstractGraphicsShapeItem::isObscuredBy(item);
9147 }
9148
9149 /*!
9150     \reimp
9151 */
9152 QPainterPath QGraphicsPolygonItem::opaqueArea() const
9153 {
9154     return QAbstractGraphicsShapeItem::opaqueArea();
9155 }
9156
9157 /*!
9158     \reimp
9159 */
9160 int QGraphicsPolygonItem::type() const
9161 {
9162     return Type;
9163 }
9164
9165 /*!
9166     \internal
9167 */
9168 bool QGraphicsPolygonItem::supportsExtension(Extension extension) const
9169 {
9170     Q_UNUSED(extension);
9171     return false;
9172 }
9173
9174 /*!
9175     \internal
9176 */
9177 void QGraphicsPolygonItem::setExtension(Extension extension, const QVariant &variant)
9178 {
9179     Q_UNUSED(extension);
9180     Q_UNUSED(variant);
9181 }
9182
9183 /*!
9184     \internal
9185 */
9186 QVariant QGraphicsPolygonItem::extension(const QVariant &variant) const
9187 {
9188     Q_UNUSED(variant);
9189     return QVariant();
9190 }
9191
9192 /*!
9193     \class QGraphicsLineItem
9194     \brief The QGraphicsLineItem class provides a line item that you can add to a
9195     QGraphicsScene.
9196     \since 4.2
9197     \ingroup graphicsview-api
9198     \inmodule QtWidgets
9199
9200     To set the item's line, pass a QLineF to QGraphicsLineItem's
9201     constructor, or call the setLine() function. The line() function
9202     returns the current line. By default the line is black with a
9203     width of 0, but you can change this by calling setPen().
9204
9205     \img graphicsview-lineitem.png
9206
9207     QGraphicsLineItem uses the line and the pen width to provide a reasonable
9208     implementation of boundingRect(), shape(), and contains(). The paint()
9209     function draws the line using the item's associated pen.
9210
9211     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
9212     QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsPixmapItem,
9213     {Graphics View Framework}
9214 */
9215
9216 class QGraphicsLineItemPrivate : public QGraphicsItemPrivate
9217 {
9218     Q_DECLARE_PUBLIC(QGraphicsLineItem)
9219 public:
9220     QLineF line;
9221     QPen pen;
9222 };
9223
9224 /*!
9225     Constructs a QGraphicsLineItem, using \a line as the default line. \a
9226     parent is passed to QGraphicsItem's constructor.
9227
9228     \sa QGraphicsScene::addItem()
9229 */
9230 QGraphicsLineItem::QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent
9231 #ifndef Q_QDOC
9232                                      // obsolete argument
9233                                      , QGraphicsScene *scene
9234 #endif
9235     )
9236     : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
9237 {
9238     setLine(line);
9239 }
9240
9241 /*!
9242     Constructs a QGraphicsLineItem, using the line between (\a x1, \a y1) and
9243     (\a x2, \a y2) as the default line.  \a parent is passed to
9244     QGraphicsItem's constructor.
9245
9246     \sa QGraphicsScene::addItem()
9247 */
9248 QGraphicsLineItem::QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent
9249 #ifndef Q_QDOC
9250                                      // obsolete argument
9251                                      , QGraphicsScene *scene
9252 #endif
9253     )
9254     : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
9255 {
9256     setLine(x1, y1, x2, y2);
9257 }
9258
9259
9260
9261 /*!
9262     Constructs a QGraphicsLineItem. \a parent is passed to QGraphicsItem's
9263     constructor.
9264
9265     \sa QGraphicsScene::addItem()
9266 */
9267 QGraphicsLineItem::QGraphicsLineItem(QGraphicsItem *parent
9268 #ifndef Q_QDOC
9269                                      // obsolete argument
9270                                      , QGraphicsScene *scene
9271 #endif
9272     )
9273     : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
9274 {
9275 }
9276
9277 /*!
9278     Destroys the QGraphicsLineItem.
9279 */
9280 QGraphicsLineItem::~QGraphicsLineItem()
9281 {
9282 }
9283
9284 /*!
9285     Returns the item's pen, or a black solid 0-width pen if no pen has
9286     been set.
9287
9288     \sa setPen()
9289 */
9290 QPen QGraphicsLineItem::pen() const
9291 {
9292     Q_D(const QGraphicsLineItem);
9293     return d->pen;
9294 }
9295
9296 /*!
9297     Sets the item's pen to \a pen. If no pen is set, the line will be painted
9298     using a black solid 0-width pen.
9299
9300     \sa pen()
9301 */
9302 void QGraphicsLineItem::setPen(const QPen &pen)
9303 {
9304     Q_D(QGraphicsLineItem);
9305     if (d->pen == pen)
9306         return;
9307     prepareGeometryChange();
9308     d->pen = pen;
9309     update();
9310 }
9311
9312 /*!
9313     Returns the item's line, or a null line if no line has been set.
9314
9315     \sa setLine()
9316 */
9317 QLineF QGraphicsLineItem::line() const
9318 {
9319     Q_D(const QGraphicsLineItem);
9320     return d->line;
9321 }
9322
9323 /*!
9324     Sets the item's line to be the given \a line.
9325
9326     \sa line()
9327 */
9328 void QGraphicsLineItem::setLine(const QLineF &line)
9329 {
9330     Q_D(QGraphicsLineItem);
9331     if (d->line == line)
9332         return;
9333     prepareGeometryChange();
9334     d->line = line;
9335     update();
9336 }
9337
9338 /*!
9339     \fn void QGraphicsLineItem::setLine(qreal x1, qreal y1, qreal x2, qreal y2)
9340     \overload
9341
9342     Sets the item's line to be the line between (\a x1, \a y1) and (\a
9343     x2, \a y2).
9344
9345     This is the same as calling \c {setLine(QLineF(x1, y1, x2, y2))}.
9346 */
9347
9348 /*!
9349     \reimp
9350 */
9351 QRectF QGraphicsLineItem::boundingRect() const
9352 {
9353     Q_D(const QGraphicsLineItem);
9354     if (d->pen.widthF() == 0.0) {
9355         const qreal x1 = d->line.p1().x();
9356         const qreal x2 = d->line.p2().x();
9357         const qreal y1 = d->line.p1().y();
9358         const qreal y2 = d->line.p2().y();
9359         qreal lx = qMin(x1, x2);
9360         qreal rx = qMax(x1, x2);
9361         qreal ty = qMin(y1, y2);
9362         qreal by = qMax(y1, y2);
9363         return QRectF(lx, ty, rx - lx, by - ty);
9364     }
9365     return shape().controlPointRect();
9366 }
9367
9368 /*!
9369     \reimp
9370 */
9371 QPainterPath QGraphicsLineItem::shape() const
9372 {
9373     Q_D(const QGraphicsLineItem);
9374     QPainterPath path;
9375     if (d->line == QLineF())
9376         return path;
9377
9378     path.moveTo(d->line.p1());
9379     path.lineTo(d->line.p2());
9380     return qt_graphicsItem_shapeFromPath(path, d->pen);
9381 }
9382
9383 /*!
9384     \reimp
9385 */
9386 bool QGraphicsLineItem::contains(const QPointF &point) const
9387 {
9388     return QGraphicsItem::contains(point);
9389 }
9390
9391 /*!
9392     \reimp
9393 */
9394 void QGraphicsLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
9395 {
9396     Q_D(QGraphicsLineItem);
9397     Q_UNUSED(widget);
9398     painter->setPen(d->pen);
9399     painter->drawLine(d->line);
9400
9401     if (option->state & QStyle::State_Selected)
9402         qt_graphicsItem_highlightSelected(this, painter, option);
9403 }
9404
9405 /*!
9406     \reimp
9407 */
9408 bool QGraphicsLineItem::isObscuredBy(const QGraphicsItem *item) const
9409 {
9410     return QGraphicsItem::isObscuredBy(item);
9411 }
9412
9413 /*!
9414     \reimp
9415 */
9416 QPainterPath QGraphicsLineItem::opaqueArea() const
9417 {
9418     return QGraphicsItem::opaqueArea();
9419 }
9420
9421 /*!
9422     \reimp
9423 */
9424 int QGraphicsLineItem::type() const
9425 {
9426     return Type;
9427 }
9428
9429 /*!
9430     \internal
9431 */
9432 bool QGraphicsLineItem::supportsExtension(Extension extension) const
9433 {
9434     Q_UNUSED(extension);
9435     return false;
9436 }
9437
9438 /*!
9439     \internal
9440 */
9441 void QGraphicsLineItem::setExtension(Extension extension, const QVariant &variant)
9442 {
9443     Q_UNUSED(extension);
9444     Q_UNUSED(variant);
9445 }
9446
9447 /*!
9448     \internal
9449 */
9450 QVariant QGraphicsLineItem::extension(const QVariant &variant) const
9451 {
9452     Q_UNUSED(variant);
9453     return QVariant();
9454 }
9455
9456 /*!
9457     \class QGraphicsPixmapItem
9458     \brief The QGraphicsPixmapItem class provides a pixmap item that you can add to
9459     a QGraphicsScene.
9460     \since 4.2
9461     \ingroup graphicsview-api
9462     \inmodule QtWidgets
9463
9464     To set the item's pixmap, pass a QPixmap to QGraphicsPixmapItem's
9465     constructor, or call the setPixmap() function. The pixmap()
9466     function returns the current pixmap.
9467
9468     QGraphicsPixmapItem uses pixmap's optional alpha mask to provide a
9469     reasonable implementation of boundingRect(), shape(), and contains().
9470
9471     \image graphicsview-pixmapitem.png
9472
9473     The pixmap is drawn at the item's (0, 0) coordinate, as returned by
9474     offset(). You can change the drawing offset by calling setOffset().
9475
9476     You can set the pixmap's transformation mode by calling
9477     setTransformationMode(). By default, Qt::FastTransformation is used, which
9478     provides fast, non-smooth scaling. Qt::SmoothTransformation enables
9479     QPainter::SmoothPixmapTransform on the painter, and the quality depends on
9480     the platform and viewport. The result is usually not as good as calling
9481     QPixmap::scale() directly. Call transformationMode() to get the current
9482     transformation mode for the item.
9483
9484     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
9485     QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsLineItem,
9486     {Graphics View Framework}
9487 */
9488
9489 /*!
9490     \enum QGraphicsPixmapItem::ShapeMode
9491
9492     This enum describes how QGraphicsPixmapItem calculates its shape and
9493     opaque area.
9494
9495     The default value is MaskShape.
9496
9497     \value MaskShape The shape is determined by calling QPixmap::mask().
9498     This shape includes only the opaque pixels of the pixmap.
9499     Because the shape is more complex, however, it can be slower than the other modes,
9500     and uses more memory.
9501
9502     \value BoundingRectShape The shape is determined by tracing the outline of
9503     the pixmap. This is the fastest shape mode, but it does not take into account
9504     any transparent areas on the pixmap.
9505
9506     \value HeuristicMaskShape The shape is determine by calling
9507     QPixmap::createHeuristicMask().  The performance and memory consumption
9508     is similar to MaskShape.
9509 */
9510 extern QPainterPath qt_regionToPath(const QRegion &region);
9511
9512 class QGraphicsPixmapItemPrivate : public QGraphicsItemPrivate
9513 {
9514     Q_DECLARE_PUBLIC(QGraphicsPixmapItem)
9515 public:
9516     QGraphicsPixmapItemPrivate()
9517         : transformationMode(Qt::FastTransformation),
9518         shapeMode(QGraphicsPixmapItem::MaskShape),
9519         hasShape(false)
9520     {}
9521
9522     QPixmap pixmap;
9523     Qt::TransformationMode transformationMode;
9524     QPointF offset;
9525     QGraphicsPixmapItem::ShapeMode shapeMode;
9526     QPainterPath shape;
9527     bool hasShape;
9528
9529     void updateShape()
9530     {
9531         shape = QPainterPath();
9532         switch (shapeMode) {
9533         case QGraphicsPixmapItem::MaskShape: {
9534             QBitmap mask = pixmap.mask();
9535             if (!mask.isNull()) {
9536                 shape = qt_regionToPath(QRegion(mask).translated(offset.toPoint()));
9537                 break;
9538             }
9539             // FALL THROUGH
9540         }
9541         case QGraphicsPixmapItem::BoundingRectShape:
9542             shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
9543             break;
9544         case QGraphicsPixmapItem::HeuristicMaskShape:
9545 #ifndef QT_NO_IMAGE_HEURISTIC_MASK
9546             shape = qt_regionToPath(QRegion(pixmap.createHeuristicMask()).translated(offset.toPoint()));
9547 #else
9548             shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
9549 #endif
9550             break;
9551         }
9552     }
9553 };
9554
9555 /*!
9556     Constructs a QGraphicsPixmapItem, using \a pixmap as the default pixmap.
9557     \a parent is passed to QGraphicsItem's constructor.
9558
9559     \sa QGraphicsScene::addItem()
9560 */
9561 QGraphicsPixmapItem::QGraphicsPixmapItem(const QPixmap &pixmap,
9562                                          QGraphicsItem *parent
9563 #ifndef Q_QDOC
9564                                          // obsolete argument
9565                                          , QGraphicsScene *scene
9566 #endif
9567     )
9568     : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
9569 {
9570     setPixmap(pixmap);
9571 }
9572
9573 /*!
9574     Constructs a QGraphicsPixmapItem. \a parent is passed to QGraphicsItem's
9575     constructor.
9576
9577     \sa QGraphicsScene::addItem()
9578 */
9579 QGraphicsPixmapItem::QGraphicsPixmapItem(QGraphicsItem *parent
9580 #ifndef Q_QDOC
9581                                          // obsolete argument
9582                                          , QGraphicsScene *scene
9583 #endif
9584     )
9585     : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
9586 {
9587 }
9588
9589 /*!
9590     Destroys the QGraphicsPixmapItem.
9591 */
9592 QGraphicsPixmapItem::~QGraphicsPixmapItem()
9593 {
9594 }
9595
9596 /*!
9597     Sets the item's pixmap to \a pixmap.
9598
9599     \sa pixmap()
9600 */
9601 void QGraphicsPixmapItem::setPixmap(const QPixmap &pixmap)
9602 {
9603     Q_D(QGraphicsPixmapItem);
9604     prepareGeometryChange();
9605     d->pixmap = pixmap;
9606     d->hasShape = false;
9607     update();
9608 }
9609
9610 /*!
9611     Returns the item's pixmap, or an invalid QPixmap if no pixmap has been
9612     set.
9613
9614     \sa setPixmap()
9615 */
9616 QPixmap QGraphicsPixmapItem::pixmap() const
9617 {
9618     Q_D(const QGraphicsPixmapItem);
9619     return d->pixmap;
9620 }
9621
9622 /*!
9623     Returns the transformation mode of the pixmap. The default mode is
9624     Qt::FastTransformation, which provides quick transformation with no
9625     smoothing.
9626
9627     \sa setTransformationMode()
9628 */
9629 Qt::TransformationMode QGraphicsPixmapItem::transformationMode() const
9630 {
9631     Q_D(const QGraphicsPixmapItem);
9632     return d->transformationMode;
9633 }
9634
9635 /*!
9636     Sets the pixmap item's transformation mode to \a mode, and toggles an
9637     update of the item. The default mode is Qt::FastTransformation, which
9638     provides quick transformation with no smoothing.
9639
9640     Qt::SmoothTransformation enables QPainter::SmoothPixmapTransform on the
9641     painter, and the quality depends on the platform and viewport. The result
9642     is usually not as good as calling QPixmap::scale() directly.
9643
9644     \sa transformationMode()
9645 */
9646 void QGraphicsPixmapItem::setTransformationMode(Qt::TransformationMode mode)
9647 {
9648     Q_D(QGraphicsPixmapItem);
9649     if (mode != d->transformationMode) {
9650         d->transformationMode = mode;
9651         update();
9652     }
9653 }
9654
9655 /*!
9656     Returns the pixmap item's \e offset, which defines the point of the
9657     top-left corner of the pixmap, in local coordinates.
9658
9659     \sa setOffset()
9660 */
9661 QPointF QGraphicsPixmapItem::offset() const
9662 {
9663     Q_D(const QGraphicsPixmapItem);
9664     return d->offset;
9665 }
9666
9667 /*!
9668     Sets the pixmap item's offset to \a offset. QGraphicsPixmapItem will draw
9669     its pixmap using \a offset for its top-left corner.
9670
9671     \sa offset()
9672 */
9673 void QGraphicsPixmapItem::setOffset(const QPointF &offset)
9674 {
9675     Q_D(QGraphicsPixmapItem);
9676     if (d->offset == offset)
9677         return;
9678     prepareGeometryChange();
9679     d->offset = offset;
9680     d->hasShape = false;
9681     update();
9682 }
9683
9684 /*!
9685     \fn void QGraphicsPixmapItem::setOffset(qreal x, qreal y)
9686     \since 4.3
9687
9688     This convenience function is equivalent to calling setOffset(QPointF(\a x, \a y)).
9689 */
9690
9691 /*!
9692     \reimp
9693 */
9694 QRectF QGraphicsPixmapItem::boundingRect() const
9695 {
9696     Q_D(const QGraphicsPixmapItem);
9697     if (d->pixmap.isNull())
9698         return QRectF();
9699     if (d->flags & ItemIsSelectable) {
9700         qreal pw = 1.0;
9701         return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
9702     } else {
9703         return QRectF(d->offset, d->pixmap.size());
9704     }
9705 }
9706
9707 /*!
9708     \reimp
9709 */
9710 QPainterPath QGraphicsPixmapItem::shape() const
9711 {
9712     Q_D(const QGraphicsPixmapItem);
9713     if (!d->hasShape) {
9714         QGraphicsPixmapItemPrivate *thatD = const_cast<QGraphicsPixmapItemPrivate *>(d);
9715         thatD->updateShape();
9716         thatD->hasShape = true;
9717     }
9718     return d_func()->shape;
9719 }
9720
9721 /*!
9722     \reimp
9723 */
9724 bool QGraphicsPixmapItem::contains(const QPointF &point) const
9725 {
9726     return QGraphicsItem::contains(point);
9727 }
9728
9729 /*!
9730     \reimp
9731 */
9732 void QGraphicsPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
9733                                 QWidget *widget)
9734 {
9735     Q_D(QGraphicsPixmapItem);
9736     Q_UNUSED(widget);
9737
9738     painter->setRenderHint(QPainter::SmoothPixmapTransform,
9739                            (d->transformationMode == Qt::SmoothTransformation));
9740
9741     painter->drawPixmap(d->offset, d->pixmap);
9742
9743     if (option->state & QStyle::State_Selected)
9744         qt_graphicsItem_highlightSelected(this, painter, option);
9745 }
9746
9747 /*!
9748     \reimp
9749 */
9750 bool QGraphicsPixmapItem::isObscuredBy(const QGraphicsItem *item) const
9751 {
9752     return QGraphicsItem::isObscuredBy(item);
9753 }
9754
9755 /*!
9756     \reimp
9757 */
9758 QPainterPath QGraphicsPixmapItem::opaqueArea() const
9759 {
9760     return shape();
9761 }
9762
9763 /*!
9764     \reimp
9765 */
9766 int QGraphicsPixmapItem::type() const
9767 {
9768     return Type;
9769 }
9770
9771 /*!
9772     Returns the item's shape mode. The shape mode describes how
9773     QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
9774
9775     \sa setShapeMode(), ShapeMode
9776 */
9777 QGraphicsPixmapItem::ShapeMode QGraphicsPixmapItem::shapeMode() const
9778 {
9779     return d_func()->shapeMode;
9780 }
9781
9782 /*!
9783     Sets the item's shape mode to \a mode. The shape mode describes how
9784     QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
9785
9786     \sa shapeMode(), ShapeMode
9787 */
9788 void QGraphicsPixmapItem::setShapeMode(ShapeMode mode)
9789 {
9790     Q_D(QGraphicsPixmapItem);
9791     if (d->shapeMode == mode)
9792         return;
9793     d->shapeMode = mode;
9794     d->hasShape = false;
9795 }
9796
9797 /*!
9798     \internal
9799 */
9800 bool QGraphicsPixmapItem::supportsExtension(Extension extension) const
9801 {
9802     Q_UNUSED(extension);
9803     return false;
9804 }
9805
9806 /*!
9807     \internal
9808 */
9809 void QGraphicsPixmapItem::setExtension(Extension extension, const QVariant &variant)
9810 {
9811     Q_UNUSED(extension);
9812     Q_UNUSED(variant);
9813 }
9814
9815 /*!
9816     \internal
9817 */
9818 QVariant QGraphicsPixmapItem::extension(const QVariant &variant) const
9819 {
9820     Q_UNUSED(variant);
9821     return QVariant();
9822 }
9823
9824 /*!
9825     \class QGraphicsTextItem
9826     \brief The QGraphicsTextItem class provides a text item that you can add to
9827     a QGraphicsScene to display formatted text.
9828     \since 4.2
9829     \ingroup graphicsview-api
9830     \inmodule QtWidgets
9831
9832     If you only need to show plain text in an item, consider using QGraphicsSimpleTextItem
9833     instead.
9834
9835     To set the item's text, pass a QString to QGraphicsTextItem's
9836     constructor, or call setHtml()/setPlainText().
9837
9838     QGraphicsTextItem uses the text's formatted size and the associated font
9839     to provide a reasonable implementation of boundingRect(), shape(),
9840     and contains(). You can set the font by calling setFont().
9841
9842     It is possible to make the item editable by setting the Qt::TextEditorInteraction flag
9843     using setTextInteractionFlags().
9844
9845     The item's preferred text width can be set using setTextWidth() and obtained
9846     using textWidth().
9847
9848     \note In order to align HTML text in the center, the item's text width must be set.
9849
9850     \img graphicsview-textitem.png
9851
9852     \note QGraphicsTextItem accepts \l{QGraphicsItem::acceptHoverEvents()}{hover events}
9853           by default. You can change this with \l{QGraphicsItem::}{setAcceptHoverEvents()}.
9854
9855     \sa QGraphicsSimpleTextItem, QGraphicsPathItem, QGraphicsRectItem,
9856         QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
9857         QGraphicsLineItem, {Graphics View Framework}
9858 */
9859
9860 class QGraphicsTextItemPrivate
9861 {
9862 public:
9863     QGraphicsTextItemPrivate()
9864         : control(0), pageNumber(0), useDefaultImpl(false), tabChangesFocus(false), clickCausedFocus(0)
9865     { }
9866
9867     mutable QWidgetTextControl *control;
9868     QWidgetTextControl *textControl() const;
9869
9870     inline QPointF controlOffset() const
9871     { return QPointF(0., pageNumber * control->document()->pageSize().height()); }
9872     inline void sendControlEvent(QEvent *e)
9873     { if (control) control->processEvent(e, controlOffset()); }
9874
9875     void _q_updateBoundingRect(const QSizeF &);
9876     void _q_update(QRectF);
9877     void _q_ensureVisible(QRectF);
9878     bool _q_mouseOnEdge(QGraphicsSceneMouseEvent *);
9879
9880     QRectF boundingRect;
9881     int pageNumber;
9882     bool useDefaultImpl;
9883     bool tabChangesFocus;
9884
9885     uint clickCausedFocus : 1;
9886
9887     QGraphicsTextItem *qq;
9888 };
9889
9890
9891 /*!
9892     Constructs a QGraphicsTextItem, using \a text as the default plain
9893     text. \a parent is passed to QGraphicsItem's constructor.
9894
9895     \sa QGraphicsScene::addItem()
9896 */
9897 QGraphicsTextItem::QGraphicsTextItem(const QString &text, QGraphicsItem *parent
9898 #ifndef Q_QDOC
9899                                      // obsolete argument
9900                                      , QGraphicsScene *scene
9901 #endif
9902     )
9903     : QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
9904 {
9905     dd->qq = this;
9906     if (!text.isEmpty())
9907         setPlainText(text);
9908     setAcceptDrops(true);
9909     setAcceptHoverEvents(true);
9910     setFlags(ItemUsesExtendedStyleOption);
9911 }
9912
9913 /*!
9914     Constructs a QGraphicsTextItem. \a parent is passed to QGraphicsItem's
9915     constructor.
9916
9917     \sa QGraphicsScene::addItem()
9918 */
9919 QGraphicsTextItem::QGraphicsTextItem(QGraphicsItem *parent
9920 #ifndef Q_QDOC
9921                                      // obsolete argument
9922                                      , QGraphicsScene *scene
9923 #endif
9924     )
9925     : QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
9926 {
9927     dd->qq = this;
9928     setAcceptDrops(true);
9929     setAcceptHoverEvents(true);
9930     setFlag(ItemUsesExtendedStyleOption);
9931 }
9932
9933 /*!
9934     Destroys the QGraphicsTextItem.
9935 */
9936 QGraphicsTextItem::~QGraphicsTextItem()
9937 {
9938     delete dd;
9939 }
9940
9941 /*!
9942     Returns the item's text converted to HTML, or an empty QString if no text has been set.
9943
9944     \sa setHtml()
9945 */
9946 QString QGraphicsTextItem::toHtml() const
9947 {
9948 #ifndef QT_NO_TEXTHTMLPARSER
9949     if (dd->control)
9950         return dd->control->toHtml();
9951 #endif
9952     return QString();
9953 }
9954
9955 /*!
9956     Sets the item's text to \a text, assuming that text is HTML formatted. If
9957     the item has keyboard input focus, this function will also call
9958     ensureVisible() to ensure that the text is visible in all viewports.
9959
9960     \sa toHtml(), hasFocus(), QGraphicsSimpleTextItem
9961 */
9962 void QGraphicsTextItem::setHtml(const QString &text)
9963 {
9964     dd->textControl()->setHtml(text);
9965 }
9966
9967 /*!
9968     Returns the item's text converted to plain text, or an empty QString if no text has been set.
9969
9970     \sa setPlainText()
9971 */
9972 QString QGraphicsTextItem::toPlainText() const
9973 {
9974     if (dd->control)
9975         return dd->control->toPlainText();
9976     return QString();
9977 }
9978
9979 /*!
9980     Sets the item's text to \a text. If the item has keyboard input focus,
9981     this function will also call ensureVisible() to ensure that the text is
9982     visible in all viewports.
9983
9984     \sa toHtml(), hasFocus()
9985 */
9986 void QGraphicsTextItem::setPlainText(const QString &text)
9987 {
9988     dd->textControl()->setPlainText(text);
9989 }
9990
9991 /*!
9992     Returns the item's font, which is used to render the text.
9993
9994     \sa setFont()
9995 */
9996 QFont QGraphicsTextItem::font() const
9997 {
9998     if (!dd->control)
9999         return QFont();
10000     return dd->control->document()->defaultFont();
10001 }
10002
10003 /*!
10004     Sets the font used to render the text item to \a font.
10005
10006     \sa font()
10007 */
10008 void QGraphicsTextItem::setFont(const QFont &font)
10009 {
10010     dd->textControl()->document()->setDefaultFont(font);
10011 }
10012
10013 /*!
10014     Sets the color for unformatted text to \a col.
10015 */
10016 void QGraphicsTextItem::setDefaultTextColor(const QColor &col)
10017 {
10018     QWidgetTextControl *c = dd->textControl();
10019     QPalette pal = c->palette();
10020     QColor old = pal.color(QPalette::Text);
10021     pal.setColor(QPalette::Text, col);
10022     c->setPalette(pal);
10023     if (old != col)
10024         update();
10025 }
10026
10027 /*!
10028     Returns the default text color that is used to for unformatted text.
10029 */
10030 QColor QGraphicsTextItem::defaultTextColor() const
10031 {
10032     return dd->textControl()->palette().color(QPalette::Text);
10033 }
10034
10035 /*!
10036     \reimp
10037 */
10038 QRectF QGraphicsTextItem::boundingRect() const
10039 {
10040     return dd->boundingRect;
10041 }
10042
10043 /*!
10044     \reimp
10045 */
10046 QPainterPath QGraphicsTextItem::shape() const
10047 {
10048     if (!dd->control)
10049         return QPainterPath();
10050     QPainterPath path;
10051     path.addRect(dd->boundingRect);
10052     return path;
10053 }
10054
10055 /*!
10056     \reimp
10057 */
10058 bool QGraphicsTextItem::contains(const QPointF &point) const
10059 {
10060     return dd->boundingRect.contains(point);
10061 }
10062
10063 /*!
10064     \reimp
10065 */
10066 void QGraphicsTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
10067                               QWidget *widget)
10068 {
10069     Q_UNUSED(widget);
10070     if (dd->control) {
10071         painter->save();
10072         QRectF r = option->exposedRect;
10073         painter->translate(-dd->controlOffset());
10074         r.translate(dd->controlOffset());
10075
10076         QTextDocument *doc = dd->control->document();
10077         QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
10078
10079         // the layout might need to expand the root frame to
10080         // the viewport if NoWrap is set
10081         if (layout)
10082             layout->setViewport(dd->boundingRect);
10083
10084         dd->control->drawContents(painter, r);
10085
10086         if (layout)
10087             layout->setViewport(QRect());
10088
10089         painter->restore();
10090     }
10091
10092     if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
10093         qt_graphicsItem_highlightSelected(this, painter, option);
10094 }
10095
10096 /*!
10097     \reimp
10098 */
10099 bool QGraphicsTextItem::isObscuredBy(const QGraphicsItem *item) const
10100 {
10101     return QGraphicsItem::isObscuredBy(item);
10102 }
10103
10104 /*!
10105     \reimp
10106 */
10107 QPainterPath QGraphicsTextItem::opaqueArea() const
10108 {
10109     return QGraphicsItem::opaqueArea();
10110 }
10111
10112 /*!
10113     \reimp
10114 */
10115 int QGraphicsTextItem::type() const
10116 {
10117     return Type;
10118 }
10119
10120 /*!
10121     Sets the preferred width for the item's text. If the actual text
10122     is wider than the specified width then it will be broken into
10123     multiple lines.
10124
10125     If \a width is set to -1 then the text will not be broken into
10126     multiple lines unless it is enforced through an explicit line
10127     break or a new paragraph.
10128
10129     The default value is -1.
10130
10131     Note that QGraphicsTextItem keeps a QTextDocument internally,
10132     which is used to calculate the text width.
10133
10134     \sa textWidth(), QTextDocument::setTextWidth()
10135 */
10136 void QGraphicsTextItem::setTextWidth(qreal width)
10137 {
10138     dd->textControl()->setTextWidth(width);
10139 }
10140
10141 /*!
10142     Returns the text width.
10143
10144     The width is calculated with the QTextDocument that
10145     QGraphicsTextItem keeps internally.
10146
10147     \sa setTextWidth(), QTextDocument::textWidth()
10148 */
10149 qreal QGraphicsTextItem::textWidth() const
10150 {
10151     if (!dd->control)
10152         return -1;
10153     return dd->control->textWidth();
10154 }
10155
10156 /*!
10157     Adjusts the text item to a reasonable size.
10158 */
10159 void QGraphicsTextItem::adjustSize()
10160 {
10161     if (dd->control)
10162         dd->control->adjustSize();
10163 }
10164
10165 /*!
10166     Sets the text document \a document on the item.
10167 */
10168 void QGraphicsTextItem::setDocument(QTextDocument *document)
10169 {
10170     dd->textControl()->setDocument(document);
10171     dd->_q_updateBoundingRect(dd->control->size());
10172 }
10173
10174 /*!
10175     Returns the item's text document.
10176 */
10177 QTextDocument *QGraphicsTextItem::document() const
10178 {
10179     return dd->textControl()->document();
10180 }
10181
10182 /*!
10183     \reimp
10184 */
10185 bool QGraphicsTextItem::sceneEvent(QEvent *event)
10186 {
10187     QEvent::Type t = event->type();
10188     if (!dd->tabChangesFocus && (t == QEvent::KeyPress || t == QEvent::KeyRelease)) {
10189         int k = ((QKeyEvent *)event)->key();
10190         if (k == Qt::Key_Tab || k == Qt::Key_Backtab) {
10191             dd->sendControlEvent(event);
10192             return true;
10193         }
10194     }
10195     bool result = QGraphicsItem::sceneEvent(event);
10196
10197     // Ensure input context is updated.
10198     switch (event->type()) {
10199     case QEvent::ContextMenu:
10200     case QEvent::FocusIn:
10201     case QEvent::FocusOut:
10202     case QEvent::GraphicsSceneDragEnter:
10203     case QEvent::GraphicsSceneDragLeave:
10204     case QEvent::GraphicsSceneDragMove:
10205     case QEvent::GraphicsSceneDrop:
10206     case QEvent::GraphicsSceneHoverEnter:
10207     case QEvent::GraphicsSceneHoverLeave:
10208     case QEvent::GraphicsSceneHoverMove:
10209     case QEvent::GraphicsSceneMouseDoubleClick:
10210     case QEvent::GraphicsSceneMousePress:
10211     case QEvent::GraphicsSceneMouseMove:
10212     case QEvent::GraphicsSceneMouseRelease:
10213     case QEvent::KeyPress:
10214     case QEvent::KeyRelease:
10215         // Reset the focus widget's input context, regardless
10216         // of how this item gained or lost focus.
10217         if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) {
10218             qApp->inputMethod()->reset();
10219         } else {
10220             qApp->inputMethod()->update(Qt::ImQueryInput);
10221         }
10222         break;
10223     case QEvent::ShortcutOverride:
10224         dd->sendControlEvent(event);
10225         return true;
10226     default:
10227         break;
10228     }
10229
10230     return result;
10231 }
10232
10233 /*!
10234     \reimp
10235 */
10236 void QGraphicsTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
10237 {
10238     if ((QGraphicsItem::d_ptr->flags & (ItemIsSelectable | ItemIsMovable))
10239         && (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) {
10240         // User left-pressed on edge of selectable/movable item, use
10241         // base impl.
10242         dd->useDefaultImpl = true;
10243     } else if (event->buttons() == event->button()
10244                && dd->control->textInteractionFlags() == Qt::NoTextInteraction) {
10245         // User pressed first button on non-interactive item.
10246         dd->useDefaultImpl = true;
10247     }
10248     if (dd->useDefaultImpl) {
10249         QGraphicsItem::mousePressEvent(event);
10250         if (!event->isAccepted())
10251             dd->useDefaultImpl = false;
10252         return;
10253     }
10254
10255     dd->sendControlEvent(event);
10256 }
10257
10258 /*!
10259     \reimp
10260 */
10261 void QGraphicsTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
10262 {
10263     if (dd->useDefaultImpl) {
10264         QGraphicsItem::mouseMoveEvent(event);
10265         return;
10266     }
10267
10268     dd->sendControlEvent(event);
10269 }
10270
10271 /*!
10272     \reimp
10273 */
10274 void QGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
10275 {
10276     if (dd->useDefaultImpl) {
10277         QGraphicsItem::mouseReleaseEvent(event);
10278         if (dd->control->textInteractionFlags() == Qt::NoTextInteraction
10279             && !event->buttons()) {
10280             // User released last button on non-interactive item.
10281             dd->useDefaultImpl = false;
10282         } else  if ((event->buttons() & Qt::LeftButton) == 0) {
10283             // User released the left button on an interactive item.
10284             dd->useDefaultImpl = false;
10285         }
10286         return;
10287     }
10288
10289     QWidget *widget = event->widget();
10290     if (widget && (dd->control->textInteractionFlags() & Qt::TextEditable) && boundingRect().contains(event->pos())) {
10291         qt_widget_private(widget)->handleSoftwareInputPanel(event->button(), dd->clickCausedFocus);
10292     }
10293     dd->clickCausedFocus = 0;
10294     dd->sendControlEvent(event);
10295 }
10296
10297 /*!
10298     \reimp
10299 */
10300 void QGraphicsTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
10301 {
10302     if (dd->useDefaultImpl) {
10303         QGraphicsItem::mouseDoubleClickEvent(event);
10304         return;
10305     }
10306
10307     if (!hasFocus()) {
10308         QGraphicsItem::mouseDoubleClickEvent(event);
10309         return;
10310     }
10311
10312     dd->sendControlEvent(event);
10313 }
10314
10315 /*!
10316     \reimp
10317 */
10318 void QGraphicsTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
10319 {
10320     dd->sendControlEvent(event);
10321 }
10322
10323 /*!
10324     \reimp
10325 */
10326 void QGraphicsTextItem::keyPressEvent(QKeyEvent *event)
10327 {
10328     dd->sendControlEvent(event);
10329 }
10330
10331 /*!
10332     \reimp
10333 */
10334 void QGraphicsTextItem::keyReleaseEvent(QKeyEvent *event)
10335 {
10336     dd->sendControlEvent(event);
10337 }
10338
10339 /*!
10340     \reimp
10341 */
10342 void QGraphicsTextItem::focusInEvent(QFocusEvent *event)
10343 {
10344     dd->sendControlEvent(event);
10345     if (event->reason() == Qt::MouseFocusReason) {
10346         dd->clickCausedFocus = 1;
10347     }
10348     update();
10349 }
10350
10351 /*!
10352     \reimp
10353 */
10354 void QGraphicsTextItem::focusOutEvent(QFocusEvent *event)
10355 {
10356     dd->sendControlEvent(event);
10357     update();
10358 }
10359
10360 /*!
10361     \reimp
10362 */
10363 void QGraphicsTextItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
10364 {
10365     dd->sendControlEvent(event);
10366 }
10367
10368 /*!
10369     \reimp
10370 */
10371 void QGraphicsTextItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
10372 {
10373     dd->sendControlEvent(event);
10374 }
10375
10376 /*!
10377     \reimp
10378 */
10379 void QGraphicsTextItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
10380 {
10381     dd->sendControlEvent(event);
10382 }
10383
10384 /*!
10385     \reimp
10386 */
10387 void QGraphicsTextItem::dropEvent(QGraphicsSceneDragDropEvent *event)
10388 {
10389     dd->sendControlEvent(event);
10390 }
10391
10392 /*!
10393     \reimp
10394 */
10395 void QGraphicsTextItem::inputMethodEvent(QInputMethodEvent *event)
10396 {
10397     dd->sendControlEvent(event);
10398 }
10399
10400 /*!
10401     \reimp
10402 */
10403 void QGraphicsTextItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
10404 {
10405     dd->sendControlEvent(event);
10406 }
10407
10408 /*!
10409     \reimp
10410 */
10411 void QGraphicsTextItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
10412 {
10413     dd->sendControlEvent(event);
10414 }
10415
10416 /*!
10417     \reimp
10418 */
10419 void QGraphicsTextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
10420 {
10421     dd->sendControlEvent(event);
10422 }
10423
10424 /*!
10425     \reimp
10426 */
10427 QVariant QGraphicsTextItem::inputMethodQuery(Qt::InputMethodQuery query) const
10428 {
10429     QVariant v;
10430     if (dd->control)
10431         v = dd->control->inputMethodQuery(query);
10432     if (v.type() == QVariant::RectF)
10433         v = v.toRectF().translated(-dd->controlOffset());
10434     else if (v.type() == QVariant::PointF)
10435         v = v.toPointF() - dd->controlOffset();
10436     else if (v.type() == QVariant::Rect)
10437         v = v.toRect().translated(-dd->controlOffset().toPoint());
10438     else if (v.type() == QVariant::Point)
10439         v = v.toPoint() - dd->controlOffset().toPoint();
10440     return v;
10441 }
10442
10443 /*!
10444     \internal
10445 */
10446 bool QGraphicsTextItem::supportsExtension(Extension extension) const
10447 {
10448     Q_UNUSED(extension);
10449     return false;
10450 }
10451
10452 /*!
10453     \internal
10454 */
10455 void QGraphicsTextItem::setExtension(Extension extension, const QVariant &variant)
10456 {
10457     Q_UNUSED(extension);
10458     Q_UNUSED(variant);
10459 }
10460
10461 /*!
10462     \internal
10463 */
10464 QVariant QGraphicsTextItem::extension(const QVariant &variant) const
10465 {
10466     Q_UNUSED(variant);
10467     return QVariant();
10468 }
10469
10470 /*!
10471     \internal
10472 */
10473 void QGraphicsTextItemPrivate::_q_update(QRectF rect)
10474 {
10475     if (rect.isValid()) {
10476         rect.translate(-controlOffset());
10477     } else {
10478         rect = boundingRect;
10479     }
10480     if (rect.intersects(boundingRect))
10481         qq->update(rect);
10482 }
10483
10484 /*!
10485     \internal
10486 */
10487 void QGraphicsTextItemPrivate::_q_updateBoundingRect(const QSizeF &size)
10488 {
10489     if (!control) return; // can't happen
10490     const QSizeF pageSize = control->document()->pageSize();
10491     // paged items have a constant (page) size
10492     if (size == boundingRect.size() || pageSize.height() != -1)
10493         return;
10494     qq->prepareGeometryChange();
10495     boundingRect.setSize(size);
10496     qq->update();
10497 }
10498
10499 /*!
10500     \internal
10501 */
10502 void QGraphicsTextItemPrivate::_q_ensureVisible(QRectF rect)
10503 {
10504     if (qq->hasFocus()) {
10505         rect.translate(-controlOffset());
10506         qq->ensureVisible(rect, /*xmargin=*/0, /*ymargin=*/0);
10507     }
10508 }
10509
10510 QWidgetTextControl *QGraphicsTextItemPrivate::textControl() const
10511 {
10512     if (!control) {
10513         QGraphicsTextItem *that = const_cast<QGraphicsTextItem *>(qq);
10514         control = new QWidgetTextControl(that);
10515         control->setTextInteractionFlags(Qt::NoTextInteraction);
10516
10517         QObject::connect(control, SIGNAL(updateRequest(QRectF)),
10518                          qq, SLOT(_q_update(QRectF)));
10519         QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)),
10520                          qq, SLOT(_q_updateBoundingRect(QSizeF)));
10521         QObject::connect(control, SIGNAL(visibilityRequest(QRectF)),
10522                          qq, SLOT(_q_ensureVisible(QRectF)));
10523         QObject::connect(control, SIGNAL(linkActivated(QString)),
10524                          qq, SIGNAL(linkActivated(QString)));
10525         QObject::connect(control, SIGNAL(linkHovered(QString)),
10526                          qq, SIGNAL(linkHovered(QString)));
10527
10528         const QSizeF pgSize = control->document()->pageSize();
10529         if (pgSize.height() != -1) {
10530             qq->prepareGeometryChange();
10531             that->dd->boundingRect.setSize(pgSize);
10532             qq->update();
10533         } else {
10534             that->dd->_q_updateBoundingRect(control->size());
10535         }
10536     }
10537     return control;
10538 }
10539
10540 /*!
10541     \internal
10542 */
10543 bool QGraphicsTextItemPrivate::_q_mouseOnEdge(QGraphicsSceneMouseEvent *event)
10544 {
10545     QPainterPath path;
10546     path.addRect(qq->boundingRect());
10547
10548     QPainterPath docPath;
10549     const QTextFrameFormat format = control->document()->rootFrame()->frameFormat();
10550     docPath.addRect(
10551         qq->boundingRect().adjusted(
10552             format.leftMargin(),
10553             format.topMargin(),
10554             -format.rightMargin(),
10555             -format.bottomMargin()));
10556
10557     return path.subtracted(docPath).contains(event->pos());
10558 }
10559
10560 /*!
10561     \fn QGraphicsTextItem::linkActivated(const QString &link)
10562
10563     This signal is emitted when the user clicks on a link on a text item
10564     that enables Qt::LinksAccessibleByMouse or Qt::LinksAccessibleByKeyboard.
10565     \a link is the link that was clicked.
10566
10567     \sa setTextInteractionFlags()
10568 */
10569
10570 /*!
10571     \fn QGraphicsTextItem::linkHovered(const QString &link)
10572
10573     This signal is emitted when the user hovers over a link on a text item
10574     that enables Qt::LinksAccessibleByMouse. \a link is
10575     the link that was hovered over.
10576
10577     \sa setTextInteractionFlags()
10578 */
10579
10580 /*!
10581     Sets the flags \a flags to specify how the text item should react to user
10582     input.
10583
10584     The default for a QGraphicsTextItem is Qt::NoTextInteraction. This function
10585     also affects the ItemIsFocusable QGraphicsItem flag by setting it if \a flags
10586     is different from Qt::NoTextInteraction and clearing it otherwise.
10587
10588     By default, the text is read-only. To transform the item into an editor,
10589     set the Qt::TextEditable flag.
10590 */
10591 void QGraphicsTextItem::setTextInteractionFlags(Qt::TextInteractionFlags flags)
10592 {
10593     if (flags == Qt::NoTextInteraction)
10594         setFlags(this->flags() & ~(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod));
10595     else
10596         setFlags(this->flags() | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod);
10597
10598     dd->textControl()->setTextInteractionFlags(flags);
10599 }
10600
10601 /*!
10602     Returns the current text interaction flags.
10603
10604     \sa setTextInteractionFlags()
10605 */
10606 Qt::TextInteractionFlags QGraphicsTextItem::textInteractionFlags() const
10607 {
10608     if (!dd->control)
10609         return Qt::NoTextInteraction;
10610     return dd->control->textInteractionFlags();
10611 }
10612
10613 /*!
10614     \since 4.5
10615
10616     If \a b is true, the \uicontrol Tab key will cause the widget to change focus;
10617     otherwise, the tab key will insert a tab into the document.
10618
10619     In some occasions text edits should not allow the user to input tabulators
10620     or change indentation using the \uicontrol Tab key, as this breaks the focus
10621     chain. The default is false.
10622
10623     \sa tabChangesFocus(), ItemIsFocusable, textInteractionFlags()
10624 */
10625 void QGraphicsTextItem::setTabChangesFocus(bool b)
10626 {
10627     dd->tabChangesFocus = b;
10628 }
10629
10630 /*!
10631     \since 4.5
10632
10633     Returns true if the \uicontrol Tab key will cause the widget to change focus;
10634     otherwise, false is returned.
10635
10636     By default, this behavior is disabled, and this function will return false.
10637
10638     \sa setTabChangesFocus()
10639 */
10640 bool QGraphicsTextItem::tabChangesFocus() const
10641 {
10642     return dd->tabChangesFocus;
10643 }
10644
10645 /*!
10646     \property QGraphicsTextItem::openExternalLinks
10647
10648     Specifies whether QGraphicsTextItem should automatically open links using
10649     QDesktopServices::openUrl() instead of emitting the
10650     linkActivated signal.
10651
10652     The default value is false.
10653 */
10654 void QGraphicsTextItem::setOpenExternalLinks(bool open)
10655 {
10656     dd->textControl()->setOpenExternalLinks(open);
10657 }
10658
10659 bool QGraphicsTextItem::openExternalLinks() const
10660 {
10661     if (!dd->control)
10662         return false;
10663     return dd->control->openExternalLinks();
10664 }
10665
10666 /*!
10667     \property QGraphicsTextItem::textCursor
10668
10669     This property represents the visible text cursor in an editable
10670     text item.
10671
10672     By default, if the item's text has not been set, this property
10673     contains a null text cursor; otherwise it contains a text cursor
10674     placed at the start of the item's document.
10675 */
10676 void QGraphicsTextItem::setTextCursor(const QTextCursor &cursor)
10677 {
10678     dd->textControl()->setTextCursor(cursor);
10679 }
10680
10681 QTextCursor QGraphicsTextItem::textCursor() const
10682 {
10683     if (!dd->control)
10684         return QTextCursor();
10685     return dd->control->textCursor();
10686 }
10687
10688 class QGraphicsSimpleTextItemPrivate : public QAbstractGraphicsShapeItemPrivate
10689 {
10690     Q_DECLARE_PUBLIC(QGraphicsSimpleTextItem)
10691 public:
10692     inline QGraphicsSimpleTextItemPrivate() {
10693         pen.setStyle(Qt::NoPen);
10694         brush.setStyle(Qt::SolidPattern);
10695     }
10696     QString text;
10697     QFont font;
10698     QRectF boundingRect;
10699
10700     void updateBoundingRect();
10701 };
10702
10703 static QRectF setupTextLayout(QTextLayout *layout)
10704 {
10705     layout->setCacheEnabled(true);
10706     layout->beginLayout();
10707     while (layout->createLine().isValid())
10708         ;
10709     layout->endLayout();
10710     qreal maxWidth = 0;
10711     qreal y = 0;
10712     for (int i = 0; i < layout->lineCount(); ++i) {
10713         QTextLine line = layout->lineAt(i);
10714         maxWidth = qMax(maxWidth, line.naturalTextWidth());
10715         line.setPosition(QPointF(0, y));
10716         y += line.height();
10717     }
10718     return QRectF(0, 0, maxWidth, y);
10719 }
10720
10721 void QGraphicsSimpleTextItemPrivate::updateBoundingRect()
10722 {
10723     Q_Q(QGraphicsSimpleTextItem);
10724     QRectF br;
10725     if (text.isEmpty()) {
10726         br = QRectF();
10727     } else {
10728         QString tmp = text;
10729         tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
10730         QStackTextEngine engine(tmp, font);
10731         QTextLayout layout(&engine);
10732         br = setupTextLayout(&layout);
10733     }
10734     if (br != boundingRect) {
10735         q->prepareGeometryChange();
10736         boundingRect = br;
10737         q->update();
10738     }
10739 }
10740
10741 /*!
10742     \class QGraphicsSimpleTextItem
10743     \brief The QGraphicsSimpleTextItem class provides a simple text path item
10744     that you can add to a QGraphicsScene.
10745     \since 4.2
10746     \ingroup graphicsview-api
10747     \inmodule QtWidgets
10748
10749     To set the item's text, you can either pass a QString to
10750     QGraphicsSimpleTextItem's constructor, or call setText() to change the
10751     text later. To set the text fill color, call setBrush().
10752
10753     The simple text item can have both a fill and an outline; setBrush() will
10754     set the text fill (i.e., text color), and setPen() sets the pen that will
10755     be used to draw the text outline. (The latter can be slow, especially for
10756     complex pens, and items with long text content.) If all you want is to
10757     draw a simple line of text, you should call setBrush() only, and leave the
10758     pen unset; QGraphicsSimpleTextItem's pen is by default Qt::NoPen.
10759
10760     QGraphicsSimpleTextItem uses the text's formatted size and the associated
10761     font to provide a reasonable implementation of boundingRect(), shape(),
10762     and contains(). You can set the font by calling setFont().
10763
10764     QGraphicsSimpleText does not display rich text; instead, you can use
10765     QGraphicsTextItem, which provides full text control capabilities.
10766
10767     \img graphicsview-simpletextitem.png
10768
10769     \sa QGraphicsTextItem, QGraphicsPathItem, QGraphicsRectItem,
10770     QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
10771     QGraphicsLineItem, {Graphics View Framework}
10772 */
10773
10774 /*!
10775     Constructs a QGraphicsSimpleTextItem.
10776
10777     \a parent is passed to QGraphicsItem's constructor.
10778
10779     \sa QGraphicsScene::addItem()
10780 */
10781 QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(QGraphicsItem *parent
10782 #ifndef Q_QDOC
10783                                                  // obsolete argument
10784                                                  , QGraphicsScene *scene
10785 #endif
10786     )
10787     : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
10788 {
10789 }
10790
10791 /*!
10792     Constructs a QGraphicsSimpleTextItem, using \a text as the default plain text.
10793
10794     \a parent is passed to QGraphicsItem's constructor.
10795
10796     \sa QGraphicsScene::addItem()
10797 */
10798 QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent
10799 #ifndef Q_QDOC
10800                                                  // obsolete argument
10801                                                  , QGraphicsScene *scene
10802 #endif
10803     )
10804     : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
10805 {
10806     setText(text);
10807 }
10808
10809 /*!
10810     Destroys the QGraphicsSimpleTextItem.
10811 */
10812 QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem()
10813 {
10814 }
10815
10816 /*!
10817     Sets the item's text to \a text. The text will be displayed as
10818     plain text. Newline characters ('\n') as well as characters of
10819     type QChar::LineSeparator will cause item to break the text into
10820     multiple lines.
10821 */
10822 void QGraphicsSimpleTextItem::setText(const QString &text)
10823 {
10824     Q_D(QGraphicsSimpleTextItem);
10825     if (d->text == text)
10826         return;
10827     d->text = text;
10828     d->updateBoundingRect();
10829     update();
10830 }
10831
10832 /*!
10833     Returns the item's text.
10834 */
10835 QString QGraphicsSimpleTextItem::text() const
10836 {
10837     Q_D(const QGraphicsSimpleTextItem);
10838     return d->text;
10839 }
10840
10841 /*!
10842     Sets the font that is used to draw the item's text to \a font.
10843 */
10844 void QGraphicsSimpleTextItem::setFont(const QFont &font)
10845 {
10846     Q_D(QGraphicsSimpleTextItem);
10847     d->font = font;
10848     d->updateBoundingRect();
10849 }
10850
10851 /*!
10852     Returns the font that is used to draw the item's text.
10853 */
10854 QFont QGraphicsSimpleTextItem::font() const
10855 {
10856     Q_D(const QGraphicsSimpleTextItem);
10857     return d->font;
10858 }
10859
10860 /*!
10861     \reimp
10862 */
10863 QRectF QGraphicsSimpleTextItem::boundingRect() const
10864 {
10865     Q_D(const QGraphicsSimpleTextItem);
10866     return d->boundingRect;
10867 }
10868
10869 /*!
10870     \reimp
10871 */
10872 QPainterPath QGraphicsSimpleTextItem::shape() const
10873 {
10874     Q_D(const QGraphicsSimpleTextItem);
10875     QPainterPath path;
10876     path.addRect(d->boundingRect);
10877     return path;
10878 }
10879
10880 /*!
10881     \reimp
10882 */
10883 bool QGraphicsSimpleTextItem::contains(const QPointF &point) const
10884 {
10885     Q_D(const QGraphicsSimpleTextItem);
10886     return d->boundingRect.contains(point);
10887 }
10888
10889 /*!
10890     \reimp
10891 */
10892 void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
10893 {
10894     Q_UNUSED(widget);
10895     Q_D(QGraphicsSimpleTextItem);
10896
10897     painter->setFont(d->font);
10898
10899     QString tmp = d->text;
10900     tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
10901     QStackTextEngine engine(tmp, d->font);
10902     QTextLayout layout(&engine);
10903     setupTextLayout(&layout);
10904
10905     QPen p;
10906     p.setBrush(d->brush);
10907     painter->setPen(p);
10908     if (d->pen.style() == Qt::NoPen && d->brush.style() == Qt::SolidPattern) {
10909         painter->setBrush(Qt::NoBrush);
10910     } else {
10911         QTextLayout::FormatRange range;
10912         range.start = 0;
10913         range.length = layout.text().length();
10914         range.format.setTextOutline(d->pen);
10915         QList<QTextLayout::FormatRange> formats;
10916         formats.append(range);
10917         layout.setAdditionalFormats(formats);
10918     }
10919
10920     layout.draw(painter, QPointF(0, 0));
10921
10922     if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
10923         qt_graphicsItem_highlightSelected(this, painter, option);
10924 }
10925
10926 /*!
10927     \reimp
10928 */
10929 bool QGraphicsSimpleTextItem::isObscuredBy(const QGraphicsItem *item) const
10930 {
10931     return QAbstractGraphicsShapeItem::isObscuredBy(item);
10932 }
10933
10934 /*!
10935     \reimp
10936 */
10937 QPainterPath QGraphicsSimpleTextItem::opaqueArea() const
10938 {
10939     return QAbstractGraphicsShapeItem::opaqueArea();
10940 }
10941
10942 /*!
10943     \reimp
10944 */
10945 int QGraphicsSimpleTextItem::type() const
10946 {
10947     return Type;
10948 }
10949
10950 /*!
10951     \internal
10952 */
10953 bool QGraphicsSimpleTextItem::supportsExtension(Extension extension) const
10954 {
10955     Q_UNUSED(extension);
10956     return false;
10957 }
10958
10959 /*!
10960     \internal
10961 */
10962 void QGraphicsSimpleTextItem::setExtension(Extension extension, const QVariant &variant)
10963 {
10964     Q_UNUSED(extension);
10965     Q_UNUSED(variant);
10966 }
10967
10968 /*!
10969     \internal
10970 */
10971 QVariant QGraphicsSimpleTextItem::extension(const QVariant &variant) const
10972 {
10973     Q_UNUSED(variant);
10974     return QVariant();
10975 }
10976
10977 /*!
10978     \class QGraphicsItemGroup
10979     \brief The QGraphicsItemGroup class provides a container that treats
10980     a group of items as a single item.
10981     \since 4.2
10982     \ingroup graphicsview-api
10983     \inmodule QtWidgets
10984
10985     A QGraphicsItemGroup is a special type of compound item that
10986     treats itself and all its children as one item (i.e., all events
10987     and geometries for all children are merged together). It's common
10988     to use item groups in presentation tools, when the user wants to
10989     group several smaller items into one big item in order to simplify
10990     moving and copying of items.
10991
10992     If all you want is to store items inside other items, you can use
10993     any QGraphicsItem directly by passing a suitable parent to
10994     setParentItem().
10995
10996     The boundingRect() function of QGraphicsItemGroup returns the
10997     bounding rectangle of all items in the item group.
10998     QGraphicsItemGroup ignores the ItemIgnoresTransformations flag on
10999     its children (i.e., with respect to the geometry of the group
11000     item, the children are treated as if they were transformable).
11001
11002     There are two ways to construct an item group. The easiest and
11003     most common approach is to pass a list of items (e.g., all
11004     selected items) to QGraphicsScene::createItemGroup(), which
11005     returns a new QGraphicsItemGroup item. The other approach is to
11006     manually construct a QGraphicsItemGroup item, add it to the scene
11007     calling QGraphicsScene::addItem(), and then add items to the group
11008     manually, one at a time by calling addToGroup(). To dismantle
11009     ("ungroup") an item group, you can either call
11010     QGraphicsScene::destroyItemGroup(), or you can manually remove all
11011     items from the group by calling removeFromGroup().
11012
11013     \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 17
11014
11015     The operation of adding and removing items preserves the items'
11016     scene-relative position and transformation, as opposed to calling
11017     setParentItem(), where only the child item's parent-relative
11018     position and transformation are kept.
11019
11020     The addtoGroup() function reparents the target item to this item
11021     group, keeping the item's position and transformation intact
11022     relative to the scene. Visually, this means that items added via
11023     addToGroup() will remain completely unchanged as a result of this
11024     operation, regardless of the item or the group's current position
11025     or transformation; although the item's position and matrix are
11026     likely to change.
11027
11028     The removeFromGroup() function has similar semantics to
11029     setParentItem(); it reparents the item to the parent item of the
11030     item group. As with addToGroup(), the item's scene-relative
11031     position and transformation remain intact.
11032
11033     \sa QGraphicsItem, {Graphics View Framework}
11034 */
11035
11036 class QGraphicsItemGroupPrivate : public QGraphicsItemPrivate
11037 {
11038 public:
11039     QRectF itemsBoundingRect;
11040 };
11041
11042 /*!
11043     Constructs a QGraphicsItemGroup. \a parent is passed to QGraphicsItem's
11044     constructor.
11045
11046     \sa QGraphicsScene::addItem()
11047 */
11048 QGraphicsItemGroup::QGraphicsItemGroup(QGraphicsItem *parent
11049 #ifndef Q_QDOC
11050                                        // obsolete argument
11051                                        , QGraphicsScene *scene
11052 #endif
11053     )
11054     : QGraphicsItem(*new QGraphicsItemGroupPrivate, parent, scene)
11055 {
11056     setHandlesChildEvents(true);
11057 }
11058
11059 /*!
11060     Destroys the QGraphicsItemGroup.
11061 */
11062 QGraphicsItemGroup::~QGraphicsItemGroup()
11063 {
11064 }
11065
11066 /*!
11067     Adds the given \a item and item's child items to this item group.
11068     The item and child items will be reparented to this group, but its
11069     position and transformation relative to the scene will stay intact.
11070
11071     \sa removeFromGroup(), QGraphicsScene::createItemGroup()
11072 */
11073 void QGraphicsItemGroup::addToGroup(QGraphicsItem *item)
11074 {
11075     Q_D(QGraphicsItemGroup);
11076     if (!item) {
11077         qWarning("QGraphicsItemGroup::addToGroup: cannot add null item");
11078         return;
11079     }
11080     if (item == this) {
11081         qWarning("QGraphicsItemGroup::addToGroup: cannot add a group to itself");
11082         return;
11083     }
11084
11085     // COMBINE
11086     bool ok;
11087     QTransform itemTransform = item->itemTransform(this, &ok);
11088
11089     if (!ok) {
11090         qWarning("QGraphicsItemGroup::addToGroup: could not find a valid transformation from item to group coordinates");
11091         return;
11092     }
11093
11094     QTransform newItemTransform(itemTransform);
11095     item->setPos(mapFromItem(item, 0, 0));
11096     item->setParentItem(this);
11097
11098     // removing position from translation component of the new transform
11099     if (!item->pos().isNull())
11100         newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
11101
11102     // removing additional transformations properties applied with itemTransform()
11103     QPointF origin = item->transformOriginPoint();
11104     QMatrix4x4 m;
11105     QList<QGraphicsTransform*> transformList = item->transformations();
11106     for (int i = 0; i < transformList.size(); ++i)
11107         transformList.at(i)->applyTo(&m);
11108     newItemTransform *= m.toTransform().inverted();
11109     newItemTransform.translate(origin.x(), origin.y());
11110     newItemTransform.rotate(-item->rotation());
11111     newItemTransform.scale(1/item->scale(), 1/item->scale());
11112     newItemTransform.translate(-origin.x(), -origin.y());
11113
11114     // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
11115
11116     item->setTransform(newItemTransform);
11117     item->d_func()->setIsMemberOfGroup(true);
11118     prepareGeometryChange();
11119     d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
11120     update();
11121 }
11122
11123 /*!
11124     Removes the specified \a item from this group. The item will be
11125     reparented to this group's parent item, or to 0 if this group has
11126     no parent.  Its position and transformation relative to the scene
11127     will stay intact.
11128
11129     \sa addToGroup(), QGraphicsScene::destroyItemGroup()
11130 */
11131 void QGraphicsItemGroup::removeFromGroup(QGraphicsItem *item)
11132 {
11133     Q_D(QGraphicsItemGroup);
11134     if (!item) {
11135         qWarning("QGraphicsItemGroup::removeFromGroup: cannot remove null item");
11136         return;
11137     }
11138
11139     QGraphicsItem *newParent = d_ptr->parent;
11140
11141     // COMBINE
11142     bool ok;
11143     QTransform itemTransform;
11144     if (newParent)
11145         itemTransform = item->itemTransform(newParent, &ok);
11146     else
11147         itemTransform = item->sceneTransform();
11148
11149     QPointF oldPos = item->mapToItem(newParent, 0, 0);
11150     item->setParentItem(newParent);
11151     item->setPos(oldPos);
11152
11153     // removing position from translation component of the new transform
11154     if (!item->pos().isNull())
11155         itemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
11156
11157     // removing additional transformations properties applied
11158     // with itemTransform() or sceneTransform()
11159     QPointF origin = item->transformOriginPoint();
11160     QMatrix4x4 m;
11161     QList<QGraphicsTransform*> transformList = item->transformations();
11162     for (int i = 0; i < transformList.size(); ++i)
11163         transformList.at(i)->applyTo(&m);
11164     itemTransform *= m.toTransform().inverted();
11165     itemTransform.translate(origin.x(), origin.y());
11166     itemTransform.rotate(-item->rotation());
11167     itemTransform.scale(1 / item->scale(), 1 / item->scale());
11168     itemTransform.translate(-origin.x(), -origin.y());
11169
11170     // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
11171
11172     item->setTransform(itemTransform);
11173     item->d_func()->setIsMemberOfGroup(item->group() != 0);
11174
11175     // ### Quite expensive. But removeFromGroup() isn't called very often.
11176     prepareGeometryChange();
11177     d->itemsBoundingRect = childrenBoundingRect();
11178 }
11179
11180 /*!
11181     \reimp
11182
11183     Returns the bounding rect of this group item, and all its children.
11184 */
11185 QRectF QGraphicsItemGroup::boundingRect() const
11186 {
11187     Q_D(const QGraphicsItemGroup);
11188     return d->itemsBoundingRect;
11189 }
11190
11191 /*!
11192     \reimp
11193 */
11194 void QGraphicsItemGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
11195                                QWidget *widget)
11196 {
11197     Q_UNUSED(widget);
11198     if (option->state & QStyle::State_Selected) {
11199         Q_D(QGraphicsItemGroup);
11200         painter->setBrush(Qt::NoBrush);
11201         painter->drawRect(d->itemsBoundingRect);
11202     }
11203 }
11204
11205 /*!
11206     \reimp
11207 */
11208 bool QGraphicsItemGroup::isObscuredBy(const QGraphicsItem *item) const
11209 {
11210     return QGraphicsItem::isObscuredBy(item);
11211 }
11212
11213 /*!
11214     \reimp
11215 */
11216 QPainterPath QGraphicsItemGroup::opaqueArea() const
11217 {
11218     return QGraphicsItem::opaqueArea();
11219 }
11220
11221 /*!
11222     \reimp
11223 */
11224 int QGraphicsItemGroup::type() const
11225 {
11226     return Type;
11227 }
11228
11229 #ifndef QT_NO_GRAPHICSEFFECT
11230 QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
11231 {
11232     const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
11233     if (!info && deviceCoordinates) {
11234         // Device coordinates without info not yet supported.
11235         qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
11236         return QRectF();
11237     }
11238
11239     QRectF rect = item->boundingRect();
11240     if (!item->d_ptr->children.isEmpty())
11241         rect |= item->childrenBoundingRect();
11242
11243     if (deviceCoordinates) {
11244         Q_ASSERT(info->painter);
11245         rect = info->painter->worldTransform().mapRect(rect);
11246     }
11247
11248     return rect;
11249 }
11250
11251 void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter)
11252 {
11253     if (!info) {
11254         qWarning("QGraphicsEffectSource::draw: Can only begin as a result of QGraphicsEffect::draw");
11255         return;
11256     }
11257
11258     Q_ASSERT(item->d_ptr->scene);
11259     QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
11260     if (painter == info->painter) {
11261         scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
11262                      info->widget, info->opacity, info->effectTransform, info->wasDirtySceneTransform,
11263                      info->drawItem);
11264     } else {
11265         QTransform effectTransform = info->painter->worldTransform().inverted();
11266         effectTransform *= painter->worldTransform();
11267         scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
11268                      info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
11269                      info->drawItem);
11270     }
11271 }
11272
11273 // sourceRect must be in the given coordinate system
11274 QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
11275 {
11276     QRectF effectRectF;
11277
11278     if (unpadded)
11279         *unpadded = false;
11280
11281     if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
11282         if (info) {
11283             QRectF deviceRect = system == Qt::DeviceCoordinates ? sourceRect : info->painter->worldTransform().mapRect(sourceRect);
11284             effectRectF = item->graphicsEffect()->boundingRectFor(deviceRect);
11285             if (unpadded)
11286                 *unpadded = (effectRectF.size() == sourceRect.size());
11287             if (info && system == Qt::LogicalCoordinates)
11288                 effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
11289         } else {
11290             // no choice but to send a logical coordinate bounding rect to boundingRectFor
11291             effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect);
11292         }
11293     } else if (mode == QGraphicsEffect::PadToTransparentBorder) {
11294         // adjust by 1.5 to account for cosmetic pens
11295         effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
11296     } else {
11297         effectRectF = sourceRect;
11298         if (unpadded)
11299             *unpadded = true;
11300     }
11301
11302     return effectRectF.toAlignedRect();
11303 }
11304
11305 QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
11306                                                  QGraphicsEffect::PixmapPadMode mode) const
11307 {
11308     const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
11309     if (!info && deviceCoordinates) {
11310         // Device coordinates without info not yet supported.
11311         qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
11312         return QPixmap();
11313     }
11314     if (!item->d_ptr->scene)
11315         return QPixmap();
11316     QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
11317
11318     bool unpadded;
11319     const QRectF sourceRect = boundingRect(system);
11320     QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded);
11321
11322     if (offset)
11323         *offset = effectRect.topLeft();
11324
11325     bool untransformed = !deviceCoordinates
11326             || info->painter->worldTransform().type() <= QTransform::TxTranslate;
11327     if (untransformed && unpadded && isPixmap()) {
11328         if (offset)
11329             *offset = boundingRect(system).topLeft().toPoint();
11330         return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
11331     }
11332
11333     if (effectRect.isEmpty())
11334         return QPixmap();
11335
11336     QPixmap pixmap(effectRect.size());
11337     pixmap.fill(Qt::transparent);
11338     QPainter pixmapPainter(&pixmap);
11339     pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing);
11340
11341     QTransform effectTransform = QTransform::fromTranslate(-effectRect.x(), -effectRect.y());
11342     if (deviceCoordinates && info->effectTransform)
11343         effectTransform *= *info->effectTransform;
11344
11345     if (!info) {
11346         // Logical coordinates without info.
11347         QTransform sceneTransform = item->sceneTransform();
11348         QTransform newEffectTransform = sceneTransform.inverted();
11349         newEffectTransform *= effectTransform;
11350         scened->draw(item, &pixmapPainter, 0, &sceneTransform, 0, 0, qreal(1.0),
11351                      &newEffectTransform, false, true);
11352     } else if (deviceCoordinates) {
11353         // Device coordinates with info.
11354         scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
11355                      info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
11356                      info->drawItem);
11357     } else {
11358         // Item coordinates with info.
11359         QTransform newEffectTransform = info->transformPtr->inverted();
11360         newEffectTransform *= effectTransform;
11361         scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
11362                      info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform,
11363                      info->drawItem);
11364     }
11365
11366     pixmapPainter.end();
11367
11368     return pixmap;
11369 }
11370 #endif //QT_NO_GRAPHICSEFFECT
11371
11372 #ifndef QT_NO_DEBUG_STREAM
11373 QDebug operator<<(QDebug debug, QGraphicsItem *item)
11374 {
11375     if (!item) {
11376         debug << "QGraphicsItem(0)";
11377         return debug;
11378     }
11379
11380     if (QGraphicsObject *o = item->toGraphicsObject())
11381         debug << o->metaObject()->className();
11382     else
11383         debug << "QGraphicsItem";
11384     debug << "(this =" << (void*)item
11385           << ", parent =" << (void*)item->parentItem()
11386           << ", pos =" << item->pos()
11387           << ", z =" << item->zValue() << ", flags = "
11388           << item->flags() << ")";
11389     return debug;
11390 }
11391
11392 QDebug operator<<(QDebug debug, QGraphicsObject *item)
11393 {
11394     if (!item) {
11395         debug << "QGraphicsObject(0)";
11396         return debug;
11397     }
11398
11399     debug.nospace() << item->metaObject()->className() << '(' << (void*)item;
11400     if (!item->objectName().isEmpty())
11401         debug << ", name = " << item->objectName();
11402     debug.nospace() << ", parent = " << ((void*)item->parentItem())
11403           << ", pos = " << item->pos()
11404           << ", z = " << item->zValue() << ", flags = "
11405           << item->flags() << ')';
11406     return debug.space();
11407 }
11408
11409 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change)
11410 {
11411     const char *str = "UnknownChange";
11412     switch (change) {
11413     case QGraphicsItem::ItemChildAddedChange:
11414         str = "ItemChildAddedChange";
11415         break;
11416     case QGraphicsItem::ItemChildRemovedChange:
11417         str = "ItemChildRemovedChange";
11418         break;
11419     case QGraphicsItem::ItemCursorChange:
11420         str = "ItemCursorChange";
11421         break;
11422     case QGraphicsItem::ItemCursorHasChanged:
11423         str = "ItemCursorHasChanged";
11424         break;
11425     case QGraphicsItem::ItemEnabledChange:
11426         str = "ItemEnabledChange";
11427         break;
11428     case QGraphicsItem::ItemEnabledHasChanged:
11429         str = "ItemEnabledHasChanged";
11430         break;
11431     case QGraphicsItem::ItemFlagsChange:
11432         str = "ItemFlagsChange";
11433         break;
11434     case QGraphicsItem::ItemFlagsHaveChanged:
11435         str = "ItemFlagsHaveChanged";
11436         break;
11437     case QGraphicsItem::ItemMatrixChange:
11438         str = "ItemMatrixChange";
11439         break;
11440     case QGraphicsItem::ItemParentChange:
11441         str = "ItemParentChange";
11442         break;
11443     case QGraphicsItem::ItemParentHasChanged:
11444         str = "ItemParentHasChanged";
11445         break;
11446     case QGraphicsItem::ItemPositionChange:
11447         str = "ItemPositionChange";
11448         break;
11449     case QGraphicsItem::ItemPositionHasChanged:
11450         str = "ItemPositionHasChanged";
11451         break;
11452     case QGraphicsItem::ItemSceneChange:
11453         str = "ItemSceneChange";
11454         break;
11455     case QGraphicsItem::ItemSceneHasChanged:
11456         str = "ItemSceneHasChanged";
11457         break;
11458     case QGraphicsItem::ItemSelectedChange:
11459         str = "ItemSelectedChange";
11460         break;
11461     case QGraphicsItem::ItemSelectedHasChanged:
11462         str = "ItemSelectedHasChanged";
11463         break;
11464     case QGraphicsItem::ItemToolTipChange:
11465         str = "ItemToolTipChange";
11466         break;
11467     case QGraphicsItem::ItemToolTipHasChanged:
11468         str = "ItemToolTipHasChanged";
11469         break;
11470     case QGraphicsItem::ItemTransformChange:
11471         str = "ItemTransformChange";
11472         break;
11473     case QGraphicsItem::ItemTransformHasChanged:
11474         str = "ItemTransformHasChanged";
11475         break;
11476     case QGraphicsItem::ItemVisibleChange:
11477         str = "ItemVisibleChange";
11478         break;
11479     case QGraphicsItem::ItemVisibleHasChanged:
11480         str = "ItemVisibleHasChanged";
11481         break;
11482     case QGraphicsItem::ItemZValueChange:
11483         str = "ItemZValueChange";
11484         break;
11485     case QGraphicsItem::ItemZValueHasChanged:
11486         str = "ItemZValueHasChanged";
11487         break;
11488     case QGraphicsItem::ItemOpacityChange:
11489         str = "ItemOpacityChange";
11490         break;
11491     case QGraphicsItem::ItemOpacityHasChanged:
11492         str = "ItemOpacityHasChanged";
11493         break;
11494     case QGraphicsItem::ItemScenePositionHasChanged:
11495         str = "ItemScenePositionHasChanged";
11496         break;
11497     case QGraphicsItem::ItemRotationChange:
11498         str = "ItemRotationChange";
11499         break;
11500     case QGraphicsItem::ItemRotationHasChanged:
11501         str = "ItemRotationHasChanged";
11502         break;
11503     case QGraphicsItem::ItemScaleChange:
11504         str = "ItemScaleChange";
11505         break;
11506     case QGraphicsItem::ItemScaleHasChanged:
11507         str = "ItemScaleHasChanged";
11508         break;
11509     case QGraphicsItem::ItemTransformOriginPointChange:
11510         str = "ItemTransformOriginPointChange";
11511         break;
11512     case QGraphicsItem::ItemTransformOriginPointHasChanged:
11513         str = "ItemTransformOriginPointHasChanged";
11514         break;
11515     }
11516     debug << str;
11517     return debug;
11518 }
11519
11520 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
11521 {
11522     const char *str = "UnknownFlag";
11523     switch (flag) {
11524     case QGraphicsItem::ItemIsMovable:
11525         str = "ItemIsMovable";
11526         break;
11527     case QGraphicsItem::ItemIsSelectable:
11528         str = "ItemIsSelectable";
11529         break;
11530     case QGraphicsItem::ItemIsFocusable:
11531         str = "ItemIsFocusable";
11532         break;
11533     case QGraphicsItem::ItemClipsToShape:
11534         str = "ItemClipsToShape";
11535         break;
11536     case QGraphicsItem::ItemClipsChildrenToShape:
11537         str = "ItemClipsChildrenToShape";
11538         break;
11539     case QGraphicsItem::ItemIgnoresTransformations:
11540         str = "ItemIgnoresTransformations";
11541         break;
11542     case QGraphicsItem::ItemIgnoresParentOpacity:
11543         str = "ItemIgnoresParentOpacity";
11544         break;
11545     case QGraphicsItem::ItemDoesntPropagateOpacityToChildren:
11546         str = "ItemDoesntPropagateOpacityToChildren";
11547         break;
11548     case QGraphicsItem::ItemStacksBehindParent:
11549         str = "ItemStacksBehindParent";
11550         break;
11551     case QGraphicsItem::ItemUsesExtendedStyleOption:
11552         str = "ItemUsesExtendedStyleOption";
11553         break;
11554     case QGraphicsItem::ItemHasNoContents:
11555         str = "ItemHasNoContents";
11556         break;
11557     case QGraphicsItem::ItemSendsGeometryChanges:
11558         str = "ItemSendsGeometryChanges";
11559         break;
11560     case QGraphicsItem::ItemAcceptsInputMethod:
11561         str = "ItemAcceptsInputMethod";
11562         break;
11563     case QGraphicsItem::ItemNegativeZStacksBehindParent:
11564         str = "ItemNegativeZStacksBehindParent";
11565         break;
11566     case QGraphicsItem::ItemIsPanel:
11567         str = "ItemIsPanel";
11568         break;
11569     case QGraphicsItem::ItemIsFocusScope:
11570         str = "ItemIsFocusScope";
11571         break;
11572     case QGraphicsItem::ItemSendsScenePositionChanges:
11573         str = "ItemSendsScenePositionChanges";
11574         break;
11575     case QGraphicsItem::ItemStopsClickFocusPropagation:
11576         str = "ItemStopsClickFocusPropagation";
11577         break;
11578     case QGraphicsItem::ItemStopsFocusHandling:
11579         str = "ItemStopsFocusHandling";
11580         break;
11581     }
11582     debug << str;
11583     return debug;
11584 }
11585
11586 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags)
11587 {
11588     debug << '(';
11589     bool f = false;
11590     for (int i = 0; i < 17; ++i) {
11591         if (flags & (1 << i)) {
11592             if (f)
11593                 debug << '|';
11594             f = true;
11595             debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i)));
11596         }
11597     }
11598     debug << ')';
11599     return debug;
11600 }
11601
11602 #endif
11603
11604 QT_END_NAMESPACE
11605
11606 #include "moc_qgraphicsitem.cpp"
11607
11608 #endif // QT_NO_GRAPHICSVIEW