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