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