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