Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/graphicsview/qgraphicsitem.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information ([email protected])
     4** All rights reserved.
     5** Contact: Nokia Corporation ([email protected])
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you
     37** @nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4545    items in a QGraphicsScene.
    4646    \since 4.2
    47     \ingroup multimedia
     47
    4848    \ingroup graphicsview-api
    4949
     
    5353    QGraphicsItem is part of \l{The Graphics View Framework}
    5454
    55     \img graphicsview-items.png
     55    \im graphicsview-items.png
    5656
    5757    For convenience, Qt provides a set of standard graphics items for the most
     
    9292    \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 0
    9393
    94     The boundingRect() function has many different purposes. QGraphicsScene
    95     bases its item index on boundingRect(), and QGraphicsView uses it both for
    96     culling invisible items, and for determining the area that needs to be
    97     recomposed when drawing overlapping items. In addition, QGraphicsItem's
    98     collision detection mechanisms use boundingRect() to provide an efficient
    99     cut-off. The fine grained collision algorithm in collidesWithItem() is based
    100     on calling shape(), which returns an accurate outline of the item's shape
    101     as a QPainterPath.
    102 
    103     QGraphicsScene expects all items boundingRect() and shape() to remain
    104     unchanged unless it is notified. If you want to change an item's geometry
    105     in any way, you must first call prepareGeometryChange() to allow
    106     QGraphicsScene to update its bookkeeping.
     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.
    107109
    108110    Collision detection can be done in two ways:
     
    110112    \list 1
    111113
    112     \o Reimplement shape() to return an accurate shape for your item, and rely
    113     on the default implementation of collidesWithItem() to do shape-shape
    114     intersection. This can be rather expensive if the shapes are complex.
    115 
    116     \o Reimplement collidesWithItem() to provide your own custom item and shape
    117     collision algorithm.
     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.
    118121
    119122    \endlist
     
    131134    \img graphicsview-parentchild.png
    132135
    133     QGraphicsItem supports affine transformations in addition to its base
    134     position, pos(). To change the item's transformation, you can either pass
    135     a transformation matrix to setTransform(), or call one of the convenience
    136     functions rotate(), scale(), translate(), or shear(). Item transformations
    137     accumulate from parent to child, so if both a parent and child item are
    138     rotated 90 degrees, the child's total transformation will be 180 degrees.
    139     Similarly, if the item's parent is scaled to 2x its original size, its
    140     children will also be twice as large. An item's transformation does not
    141     affect its own local geometry; all geometry functions (e.g., contains(),
    142     update(), and all the mapping functions) still operate in local
    143     coordinates. For convenience, QGraphicsItem provides the functions
    144     sceneTransform(), which returns the item's total transformation matrix
    145     (including its position and all parents' positions and transformations),
    146     and scenePos(), which returns its position in scene coordinates. To reset
    147     an item's matrix, call resetTransform().
     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
    148173
    149174    The paint() function is called by QGraphicsView to paint the item's
     
    162187    drawn before their children.
    163188
     189
     190
     191
     192
     193
     194
     195
     196
     197
     198
     199
     200
     201
     202
     203
     204
     205
     206
     207
     208
     209
     210
     211
     212
     213
     214
     215
     216
     217
     218
     219
     220
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230
     231
     232
     233
    164234    QGraphicsItem receives events from QGraphicsScene through the virtual
    165235    function sceneEvent(). This function distributes the most common events
     
    172242    hover enter, move and leave events
    173243    \o inputMethodEvent() handles input events, for accessibility support
    174     \o keyPressEvent() and keyReleaseEvent handle key press and release events
     244    \o keyPressEvent() and keyReleaseEvent handle key press and release events
    175245    \o mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), and
    176246    mouseDoubleClickEvent() handles mouse press, move, release, click and
     
    178248    \endlist
    179249
    180     You can filter events for any other item by installing event
    181     filters. This functionaly is separate from from Qt's regular
    182     event filters (see QObject::installEventFilter()), which only
    183     work on subclasses of QObject. After installing your item as an
    184     event filter for another item by calling
    185     installSceneEventFilter(), the filtered events will be received
    186     by the virtual function sceneEventFilter(). You can remove item
    187     event filters by calling removeSceneEventFilter().
     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
    188259
    189260    Sometimes it's useful to register custom data with an item, be it a custom
     
    275346    drop shadow effects and for decoration objects that follow the parent
    276347    item's geometry without drawing on top of it.
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
     362
     363
     364
     365
     366
     367
     368
     369
     370
     371
     372
     373
     374
     375
     376
     377
     378
     379
     380
     381
     382
     383
     384
     385
     386
     387
     388
     389
     390
     391
     392
     393
     394
    277395*/
    278396
     
    313431
    314432    \value ItemPositionChange The item's position changes. This notification
    315     is only sent when the item's local position changes, relative to its
    316     parent, has changed (i.e., as a result of calling setPos() or
    317     moveBy()). The value argument is the new position (i.e., a QPointF).  You
    318     can call pos() to get the original position. Do not call setPos() or
    319     moveBy() in itemChange() as this notification is delivered; instead, you
    320     can return the new, adjusted position from itemChange(). After this
    321     notification, QGraphicsItem immediately sends the ItemPositionHasChanged
    322     notification if the position changed.
     433    is
     434   
     435   
     436   
     437   
     438   
     439   
     440    notification if the position changed.
    323441
    324442    \value ItemPositionHasChanged The item's position has changed. This
    325     notification is only sent after the item's local position, relative to its
    326     parent, has changed. The value argument is the new position (the same as
    327     pos()), and QGraphicsItem ignores the return value for this notification
    328     (i.e., a read-only notification).
     443    notification is sent if the ItemSendsGeometryChanges flag is enabled, and
     444    after the item's local position, relative to its parent, has changed. The
     445    value argument is the new position (the same as pos()), and QGraphicsItem
     446    ignores the return value for this notification (i.e., a read-only
     447    notification).
    329448
    330449    \value ItemTransformChange The item's transformation matrix changes. This
    331     notification is only sent when the item's local transformation matrix
    332     changes (i.e., as a result of calling setTransform(), or one of the
    333     convenience transformation functions, such as rotate()). The value
    334     argument is the new matrix (i.e., a QTransform); to get the old matrix,
    335     call transform(). Do not call setTransform() or any of the transformation
    336     convenience functions in itemChange() as this notification is delivered;
    337     instead, you can return the new matrix from itemChange().
     450    notification is send if the ItemSendsGeometryChanges flag is enabled, and
     451    when the item's local transformation matrix changes (i.e., as a result of
     452    calling setTransform(). The value argument is the new matrix (i.e., a
     453    QTransform); to get the old matrix, call transform(). Do not call
     454    setTransform() or set any of the transformation properties in itemChange()
     455    as this notification is delivered; instead, you can return the new matrix
     456    from itemChange().  This notification is not sent if you change the
     457    transformation properties.
    338458
    339459    \value ItemTransformHasChanged The item's transformation matrix has
    340     changed.  This notification is only sent after the item's local
    341     trasformation matrix has changed. The value argument is the new matrix
     460    changed either because setTransform is called, or one of the
     461    transformation properties is changed. This notification is sent if the
     462    ItemSendsGeometryChanges flag is enabled, and after the item's local
     463    transformation matrix has changed. The value argument is the new matrix
    342464    (same as transform()), and QGraphicsItem ignores the return value for this
    343465    notification (i.e., a read-only notification).
    344466
    345     \value ItemSelectedChange The item's selected state changes. If the item
    346     is presently selected, it will become unselected, and vice verca. The
    347     value argument is the new selected state (i.e., true or false). Do not
    348     call setSelected() in itemChange() as this notification is delivered();
    349     instead, you can return the new selected state from itemChange().
     467    \value ItemSelectedChange The item's selected state changes. If the item
     468    e
     469   
     470   
     471    can return the new selected state from itemChange().
    350472
    351473    \value ItemSelectedHasChanged The item's selected state has changed. The
     
    447569    argument is the new opacity (i.e., a double). Do not call setOpacity() as
    448570    this notification is delivered. The return value is ignored.
     571
     572
     573
     574
     575
     576
     577
     578
    449579*/
    450580
     
    492622*/
    493623
     624
     625
     626
     627
     628
     629
     630
     631
     632
     633
     634
     635
     636
     637
     638
     639
    494640#include "qgraphicsitem.h"
    495641
     
    502648#include "qgraphicswidget.h"
    503649#include "qgraphicsproxywidget.h"
     650
    504651#include <QtCore/qbitarray.h>
    505652#include <QtCore/qdebug.h>
     
    516663#include <QtGui/qstyleoption.h>
    517664#include <QtGui/qevent.h>
     665
     666
    518667
    519668#include <private/qgraphicsitem_p.h>
     
    522671#include <private/qtextdocumentlayout_p.h>
    523672#include <private/qtextengine_p.h>
     673
     674
     675
     676
     677
     678
     679
     680
    524681
    525682#include <math.h>
    526683
    527684QT_BEGIN_NAMESPACE
    528 
    529 // QRectF::intersects() returns false always if either the source or target
    530 // rectangle's width or height are 0. This works around that problem.
    531 static inline void _q_adjustRect(QRectF *rect)
    532 {
    533     Q_ASSERT(rect);
    534     if (!rect->width())
    535         rect->adjust(-0.00001, 0, 0.00001, 0);
    536     if (!rect->height())
    537         rect->adjust(0, -0.00001, 0, 0.00001);
    538 }
    539685
    540686static inline void _q_adjustRect(QRect *rect)
     
    556702};
    557703Q_GLOBAL_STATIC(QGraphicsItemCustomDataStore, qt_dataStore)
    558 
    559 /*!
    560     \internal
    561 
    562     Removes the first instance of \a child from \a children. This is a
    563     heuristic approach that assumes that it's common to remove items from the
    564     start or end of the list.
    565 */
    566 static void qt_graphicsitem_removeChild(QGraphicsItem *child, QList<QGraphicsItem *> *children)
    567 {
    568     const int n = children->size();
    569     for (int i = 0; i < (n + 1) / 2; ++i) {
    570         if (children->at(i) == child) {
    571             children->removeAt(i);
    572             return;
    573         }
    574         int j = n - i - 1;
    575         if (children->at(j) == child) {
    576             children->removeAt(j);
    577             return;
    578         }
    579     }
    580 }
    581704
    582705/*!
     
    622745        // disabled \a childFlag, or has been reparented.
    623746        switch (int(childFlag)) {
     747
     748
     749
     750
    624751        case -1:
    625752            flag = AncestorHandlesChildEvents;
     
    629756            flag = AncestorClipsChildren;
    630757            enabled = flags & QGraphicsItem::ItemClipsChildrenToShape;
    631             invalidateCachedClipPathRecursively(/*childrenOnly=*/true);
    632758            break;
    633759        case QGraphicsItem::ItemIgnoresTransformations:
     
    639765        }
    640766
    641         // Inherit the enabled-state from our parents.
    642         if ((parent && ((parent->d_ptr->ancestorFlags & flag)
    643                         || (int(parent->d_ptr->flags & childFlag) == childFlag)
    644                         || (childFlag == -1 && parent->d_ptr->handlesChildEvents)))) {
    645             enabled = true;
    646             ancestorFlags |= flag;
     767        if (parent) {
     768            // Inherit the enabled-state from our parents.
     769            if ((parent->d_ptr->ancestorFlags & flag)
     770                    || (int(parent->d_ptr->flags & childFlag) == childFlag)
     771                        || (childFlag == -1 && parent->d_ptr->handlesChildEvents)
     772                        || (childFlag == -2 && parent->d_ptr->filtersDescendantEvents)) {
     773                enabled = true;
     774                ancestorFlags |= flag;
     775            } else {
     776                ancestorFlags &= ~flag;
     777            }
     778        } else {
     779            // Top-level root items don't have any ancestors, so there are no
     780            // ancestor flags either.
     781            ancestorFlags = 0;
    647782        }
    648 
    649         // Top-level root items don't have any ancestors, so there are no
    650         // ancestor flags either.
    651         if (!parent)
    652             ancestorFlags = 0;
    653783    } else {
    654784        // Don't set or propagate the ancestor flag if it's already correct.
     
    663793
    664794        // Don't process children if the item has the main flag set on itself.
    665         if ((childFlag != -1 &&  int(flags & childFlag) == childFlag) || (int(childFlag) == -1 && handlesChildEvents))
     795        if ((childFlag != -1 &&  int(flags & childFlag) == childFlag)
     796            || (int(childFlag) == -1 && handlesChildEvents)
     797            || (int(childFlag) == -2 && filtersDescendantEvents))
    666798            return;
    667799    }
     
    755887    \internal
    756888
    757     Returns true if this item or any of its ancestors are untransformable.
    758 */
    759 bool QGraphicsItemPrivate::itemIsUntransformable() const
    760 {
    761     return (flags & QGraphicsItem::ItemIgnoresTransformations)
    762         || (ancestorFlags & AncestorIgnoresTransformations);
     889    Combines this item's position and transform onto \a transform.
     890
     891    If you need to change this function (e.g., adding more transformation
     892    modes / options), make sure to change all places marked with COMBINE.
     893*/
     894void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransform *viewTransform) const
     895{
     896    // COMBINE
     897    if (viewTransform && itemIsUntransformable()) {
     898        *x = q_ptr->deviceTransform(*viewTransform);
     899    } else {
     900        if (transformData)
     901            *x *= transformData->computedFullTransform();
     902        if (!pos.isNull())
     903            *x *= QTransform::fromTranslate(pos.x(), pos.y());
     904    }
     905}
     906
     907/*!
     908    \internal
     909
     910    Combines this item's position and transform onto \a transform.
     911
     912    If you need to change this function (e.g., adding more transformation
     913    modes / options), make sure to change QGraphicsItem::deviceTransform() as
     914    well.
     915*/
     916void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTransform *viewTransform) const
     917{
     918    // COMBINE
     919    if (viewTransform && itemIsUntransformable()) {
     920        *x = q_ptr->deviceTransform(*viewTransform);
     921    } else {
     922        x->translate(pos.x(), pos.y());
     923        if (transformData)
     924            *x = transformData->computedFullTransform(x);
     925    }
     926}
     927
     928void QGraphicsItemPrivate::updateSceneTransformFromParent()
     929{
     930    if (parent) {
     931        Q_ASSERT(!parent->d_ptr->dirtySceneTransform);
     932        if (parent->d_ptr->sceneTransformTranslateOnly) {
     933            sceneTransform = QTransform::fromTranslate(parent->d_ptr->sceneTransform.dx() + pos.x(),
     934                                                       parent->d_ptr->sceneTransform.dy() + pos.y());
     935        } else {
     936            sceneTransform = parent->d_ptr->sceneTransform;
     937            sceneTransform.translate(pos.x(), pos.y());
     938        }
     939        if (transformData) {
     940            sceneTransform = transformData->computedFullTransform(&sceneTransform);
     941            sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
     942        } else {
     943            sceneTransformTranslateOnly = parent->d_ptr->sceneTransformTranslateOnly;
     944        }
     945    } else if (!transformData) {
     946        sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
     947        sceneTransformTranslateOnly = 1;
     948    } else if (transformData->onlyTransform) {
     949        sceneTransform = transformData->transform;
     950        if (!pos.isNull())
     951            sceneTransform *= QTransform::fromTranslate(pos.x(), pos.y());
     952        sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
     953    } else if (pos.isNull()) {
     954        sceneTransform = transformData->computedFullTransform();
     955        sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
     956    } else {
     957        sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
     958        sceneTransform = transformData->computedFullTransform(&sceneTransform);
     959        sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
     960    }
     961    dirtySceneTransform = 0;
    763962}
    764963
     
    782981    \internal
    783982
     983
     984
     985
     986
     987
     988
     989
     990
     991
     992
     993
     994
     995
     996
     997
     998
     999
     1000
     1001
     1002
     1003
     1004
     1005
     1006
     1007
     1008
     1009
     1010
     1011
     1012
     1013
     1014
     1015
     1016
     1017
     1018
     1019
     1020
     1021
     1022
     1023
     1024
     1025
     1026
     1027
     1028
     1029
     1030
     1031
     1032
     1033
     1034
     1035
     1036
     1037
     1038
     1039
     1040
     1041
     1042
     1043
     1044
     1045
     1046
     1047
     1048
     1049
     1050
     1051
     1052
     1053
     1054
     1055
     1056
     1057
     1058
     1059
     1060
     1061
     1062
     1063
     1064
     1065
     1066
     1067
     1068
     1069
     1070
     1071
     1072
     1073
     1074
     1075
     1076
     1077
     1078
     1079
     1080
     1081
     1082
     1083
     1084
     1085
     1086
     1087
     1088
     1089
     1090
     1091
     1092
     1093
     1094
     1095
     1096
     1097
     1098
     1099
     1100
     1101
     1102
     1103
     1104
     1105
     1106
     1107
     1108
     1109
     1110
     1111
     1112
     1113
     1114
     1115
     1116
     1117
     1118
     1119
     1120
     1121
     1122
     1123
     1124
     1125
     1126
     1127
     1128
     1129
     1130
     1131
     1132
     1133
     1134
     1135
     1136
     1137
     1138
     1139
     1140
     1141
     1142
     1143
     1144
     1145
     1146
     1147
     1148
     1149
     1150
     1151
     1152
     1153
     1154
     1155
     1156
     1157
     1158
     1159
     1160
     1161
     1162
     1163
     1164
     1165
     1166
     1167
     1168
     1169
     1170
     1171
     1172
     1173
     1174
     1175
     1176
     1177
     1178
     1179
     1180
     1181
     1182
     1183
     1184
     1185
     1186
     1187
     1188
     1189
     1190
     1191
     1192
     1193
     1194
     1195
     1196
     1197
     1198
     1199
     1200
     1201
     1202
     1203
     1204
     1205
     1206
     1207
     1208
     1209
     1210
     1211
     1212
     1213
     1214
     1215
     1216
     1217
     1218
     1219
     1220
     1221
     1222
     1223
     1224
     1225
     1226
     1227
     1228
     1229
     1230
     1231
     1232
     1233
     1234
     1235
     1236
     1237
     1238
     1239
     1240
     1241
     1242
     1243
     1244
     1245
     1246
     1247
    7841248    Empty all cached pixmaps from the pixmap cache.
    7851249*/
     
    7871251{
    7881252    QPixmapCache::remove(key);
     1253
    7891254    QMutableMapIterator<QPaintDevice *, DeviceData> it(deviceData);
    7901255    while (it.hasNext()) {
     
    7991264
    8001265/*!
    801     Constructs a QGraphicsItem with the given \a parent.
     1266    Constructs a QGraphicsItem with the given \a parent item.
     1267    It does not modify the parent object returned by QObject::parent().
    8021268
    8031269    If \a parent is 0, you can add the item to a scene by calling
     
    8511317    associated with a scene, the item will be removed from the scene before it
    8521318    is deleted.
     1319
     1320
     1321
    8531322*/
    8541323QGraphicsItem::~QGraphicsItem()
    8551324{
     1325
     1326
     1327
     1328
     1329
    8561330    clearFocus();
    857     d_ptr->removeExtraItemCache();
    858 
    859     QVariant variant;
    860     foreach (QGraphicsItem *child, d_ptr->children) {
    861         if (QGraphicsItem *parent = child->parentItem()) {
    862             qVariantSetValue<QGraphicsItem *>(variant, child);
    863             parent->itemChange(ItemChildRemovedChange, variant);
     1331
     1332    // Update focus scope item ptr.
     1333    QGraphicsItem *p = d_ptr->parent;
     1334    while (p) {
     1335        if (p->flags() & ItemIsFocusScope) {
     1336            if (p->d_ptr->focusScopeItem == this)
     1337                p->d_ptr->focusScopeItem = 0;
     1338            break;
    8641339        }
    865         delete child;
    866     }
    867     d_ptr->children.clear();
    868 
    869     if (QGraphicsItem *parent = parentItem()) {
    870         qVariantSetValue<QGraphicsItem *>(variant, this);
    871         parent->itemChange(ItemChildRemovedChange, variant);
    872         qt_graphicsitem_removeChild(this, &parent->d_func()->children);
    873     }
    874     if (d_ptr->scene)
    875         d_ptr->scene->d_func()->_q_removeItemLater(this);
    876 
    877     delete d_ptr;
     1340        p = p->d_ptr->parent;
     1341    }
     1342
     1343    if (!d_ptr->children.isEmpty()) {
     1344        while (!d_ptr->children.isEmpty())
     1345            delete d_ptr->children.first();
     1346        Q_ASSERT(d_ptr->children.isEmpty());
     1347    }
     1348
     1349    if (d_ptr->scene) {
     1350        d_ptr->scene->d_func()->removeItemHelper(this);
     1351    } else {
     1352        d_ptr->resetFocusProxy();
     1353        d_ptr->setParentItemHelper(0);
     1354    }
     1355
     1356#ifndef QT_NO_GRAPHICSEFFECT
     1357    delete d_ptr->graphicsEffect;
     1358#endif //QT_NO_GRAPHICSEFFECT
     1359    if (d_ptr->transformData) {
     1360        for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) {
     1361            QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i);
     1362            static_cast<QGraphicsTransformPrivate *>(t->d_ptr.data())->item = 0;
     1363            delete t;
     1364        }
     1365    }
     1366    delete d_ptr->transformData;
    8781367
    8791368    qt_dataStore()->data.remove(this);
     
    9321421    parent, 0 is returned.
    9331422
    934     \sa setParentItem(), children()
     1423    \sa setParentItem(), child()
    9351424*/
    9361425QGraphicsItem *QGraphicsItem::parentItem() const
     
    9551444
    9561445/*!
     1446
     1447
     1448
     1449
     1450
     1451
     1452
     1453
     1454
     1455
     1456
     1457
     1458
     1459
    9571460    \since 4.4
    9581461
     
    9961499QGraphicsWidget *QGraphicsItem::window() const
    9971500{
    998     if (isWidget() && static_cast<const QGraphicsWidget *>(this)->isWindow())
    999         return static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this));
    1000     if (QGraphicsWidget *parent = parentWidget())
    1001         return parent->window();
     1501    QGraphicsItem *p = panel();
     1502    if (p && p->isWindow())
     1503        return static_cast<QGraphicsWidget *>(p);
    10021504    return 0;
     1505
     1506
     1507
     1508
     1509
     1510
     1511
     1512
     1513
     1514
     1515
     1516
     1517
     1518
     1519
     1520
     1521
     1522
     1523
     1524
     1525
     1526
     1527
     1528
     1529
     1530
     1531
     1532
     1533
     1534
     1535
     1536
     1537
     1538
     1539
     1540
     1541
     1542
    10031543}
    10041544
     
    10121552    item to the scene yourself.
    10131553
    1014     \sa parentItem(), children()
     1554    Calling this function on an item that is an ancestor of \a parent have undefined behaviour.
     1555
     1556    \sa parentItem(), childItems()
    10151557*/
    10161558void QGraphicsItem::setParentItem(QGraphicsItem *parent)
    10171559{
    1018     if (parent == this) {
    1019         qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
    1020         return;
    1021     }
    1022     if (parent == d_ptr->parent)
    1023         return;
    1024     const QVariant newParentVariant(itemChange(ItemParentChange, qVariantFromValue<QGraphicsItem *>(parent)));
    1025     parent = qVariantValue<QGraphicsItem *>(newParentVariant);
    1026     if (parent == d_ptr->parent)
    1027         return;
    1028 
    1029     if (QGraphicsWidget *w = d_ptr->isWidget ? static_cast<QGraphicsWidget *>(this) : parentWidget()) {
    1030         // Update the child focus chain; when reparenting a widget that has a
    1031         // focus child, ensure that that focus child clears its focus child
    1032         // chain from our parents before it's reparented.
    1033         if (QGraphicsWidget *focusChild = w->focusWidget())
    1034             focusChild->clearFocus();
    1035     }
    1036 
    1037     // We anticipate geometry changes
    1038     prepareGeometryChange();
    1039 
    1040     const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this));
    1041     if (d_ptr->parent) {
    1042         // Remove from current parent
    1043         qt_graphicsitem_removeChild(this, &d_ptr->parent->d_func()->children);
    1044         d_ptr->parent->itemChange(ItemChildRemovedChange, thisPointerVariant);
    1045     }
    1046 
    1047     if ((d_ptr->parent = parent)) {
    1048         bool implicitUpdate = false;
    1049         if (parent->d_func()->scene && parent->d_func()->scene != d_ptr->scene) {
    1050             // Move this item to its new parent's scene
    1051             parent->d_func()->scene->addItem(this);
    1052             implicitUpdate = true;
    1053         } else if (!parent->d_func()->scene && d_ptr->scene) {
    1054             // Remove this item from its former scene
    1055             d_ptr->scene->removeItem(this);
    1056         }
    1057 
    1058         d_ptr->parent->d_func()->children << this;
    1059         d_ptr->parent->itemChange(ItemChildAddedChange, thisPointerVariant);
    1060         if (!implicitUpdate)
    1061             d_ptr->updateHelper(QRectF(), false, true);
    1062 
    1063         // Inherit ancestor flags from the new parent.
    1064         d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
    1065         d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
    1066         d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
    1067 
    1068         // Update item visible / enabled.
    1069         if (d_ptr->parent->isVisible() != d_ptr->visible) {
    1070             if (!d_ptr->parent->isVisible() || !d_ptr->explicitlyHidden)
    1071                 d_ptr->setVisibleHelper(d_ptr->parent->isVisible(), /* explicit = */ false, /* update = */ !implicitUpdate);
    1072         }
    1073         if (d_ptr->parent->isEnabled() != d_ptr->enabled) {
    1074             if (!d_ptr->parent->isEnabled() || !d_ptr->explicitlyDisabled)
    1075                 d_ptr->setEnabledHelper(d_ptr->parent->isEnabled(), /* explicit = */ false, /* update = */ !implicitUpdate);
    1076         }
    1077 
    1078     } else {
    1079         // Inherit ancestor flags from the new parent.
    1080         d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
    1081         d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
    1082         d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
    1083 
    1084         // Update item visible / enabled.
    1085         if (!d_ptr->visible && !d_ptr->explicitlyHidden)
    1086             d_ptr->setVisibleHelper(true, /* explicit = */ false);
    1087         if (!d_ptr->enabled && !d_ptr->explicitlyDisabled)
    1088             d_ptr->setEnabledHelper(true, /* explicit = */ false);
    1089 
    1090         d_ptr->updateHelper(QRectF(), false, true);
    1091     }
    1092 
    1093     if (d_ptr->scene) {
    1094         // Invalidate any sort caching; arrival of a new item means we need to
    1095         // resort.
    1096         d_ptr->scene->d_func()->invalidateSortCache();
    1097     }
    1098 
    1099     // Resolve opacity.
    1100     d_ptr->updateEffectiveOpacity();
    1101 
    1102     // Resolve depth.
    1103     d_ptr->resolveDepth(parent ? parent->d_ptr->depth : -1);
    1104 
    1105     // Invalidate transform cache.
    1106     d_ptr->invalidateSceneTransformCache();
    1107 
    1108     // Deliver post-change notification
    1109     itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant);
     1560    d_ptr->setParentItemHelper(parent);
    11101561}
    11111562
     
    11251576    \since 4.4
    11261577
    1127     Returns a list of this item's children. The items are returned in no
    1128     particular order.
    1129 
    1130     \sa setParentItem()
     1578    Returns a list of this item's children.
     1579
     1580    The items are sorted by stacking order. This takes into account both the
     1581    items' insertion order and their Z-values.
     1582
     1583    \sa setParentItem(), zValue(), {QGraphicsItem#Sorting}{Sorting}
    11311584*/
    11321585QList<QGraphicsItem *> QGraphicsItem::childItems() const
    11331586{
     1587
    11341588    return d_ptr->children;
    11351589}
     
    11551609{
    11561610    return isWidget() && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
     1611
     1612
     1613
     1614
     1615
     1616
     1617
     1618
     1619
     1620
     1621
    11571622}
    11581623
     
    12121677    item is automatically unselected.
    12131678
    1214     By default, no flags are enabled.
     1679    By default, no flags are enabled. (QGraphicsWidget enables the
     1680    ItemSendsGeometryChanges flag by default in order to track position
     1681    changes.)
    12151682
    12161683    \sa flags(), setFlag()
     
    12181685void QGraphicsItem::setFlags(GraphicsItemFlags flags)
    12191686{
     1687
     1688
     1689
    12201690    // Notify change and check for adjustment.
    12211691    if (quint32(d_ptr->flags) == quint32(flags))
     
    12241694    if (quint32(d_ptr->flags) == quint32(flags))
    12251695        return;
     1696
     1697
    12261698
    12271699    // Flags that alter the geometry of the item (or its children).
    1228     int geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations);
    1229     bool fullUpdate = (flags & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
     1700    );
     1701    bool fullUpdate = ( & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
    12301702    if (fullUpdate)
    1231         d_ptr->fullUpdateHelper(false, true);
     1703        d_ptr->;
    12321704
    12331705    // Keep the old flags to compare the diff.
     
    12361708    // Update flags.
    12371709    d_ptr->flags = flags;
    1238 
    1239     // Reresolve effective opacity if the opacity flags change.
    1240     static const quint32 opacityFlagsMask = ItemIgnoresParentOpacity | ItemDoesntPropagateOpacityToChildren;
    1241     if ((flags & opacityFlagsMask) != (oldFlags & opacityFlagsMask))
    1242         d_ptr->updateEffectiveOpacity();
    12431710
    12441711    if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
     
    12601727    }
    12611728
    1262     if ((flags & ItemClipsToShape) != (oldFlags & ItemClipsToShape))
    1263         d_ptr->invalidateCachedClipPath();
    1264 
    12651729    if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
    12661730        // Item children clipping changes. Propagate the ancestor flag to
     
    12691733    }
    12701734
    1271     // ### Why updateHelper?
    1272     d_ptr->updateHelper(QRectF(), false, true);
     1735    if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
     1736        // Ensure child item sorting is up to date when toggling this flag.
     1737        if (d_ptr->parent)
     1738            d_ptr->parent->d_ptr->needSortChildren = 1;
     1739        else if (d_ptr->scene)
     1740            d_ptr->scene->d_func()->needSortTopLevelItems = 1;
     1741    }
     1742
     1743    if ((flags & ItemAcceptsInputMethod) != (oldFlags & ItemAcceptsInputMethod)) {
     1744        // Update input method sensitivity in any views.
     1745        if (d_ptr->scene)
     1746            d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
     1747    }
     1748
     1749    if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
     1750        // Update stack-behind.
     1751        setFlag(ItemStacksBehindParent, d_ptr->z < qreal(0.0));
     1752    }
     1753
     1754    if ((d_ptr->panelModality != NonModal)
     1755        && d_ptr->scene
     1756        && (flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
     1757        // update the panel's modal state
     1758        if (flags & ItemIsPanel)
     1759            d_ptr->scene->d_func()->enterModal(this);
     1760        else
     1761            d_ptr->scene->d_func()->leaveModal(this);
     1762    }
     1763
     1764    if (d_ptr->scene) {
     1765        if ((flags & ItemSendsScenePositionChanges) != (oldFlags & ItemSendsScenePositionChanges)) {
     1766            if (flags & ItemSendsScenePositionChanges)
     1767                d_ptr->scene->d_func()->registerScenePosItem(this);
     1768            else
     1769                d_ptr->scene->d_func()->unregisterScenePosItem(this);
     1770        }
     1771        d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
     1772    }
    12731773
    12741774    // Notify change.
     
    13331833
    13341834        if (mode == ItemCoordinateCache) {
    1335             if (cache->key.isEmpty()) {
    1336                 // Generate new simple pixmap cache key.
    1337                 QString tmp;
    1338                 tmp.sprintf("qgv-%p", this);
    1339                 cache->key = tmp;
    1340             }
    13411835            if (lastMode == mode && cache->fixedSize == logicalCacheSize)
    13421836                noVisualChange = true;
     
    13481842}
    13491843
     1844
     1845
     1846
     1847
     1848
     1849
     1850
     1851
     1852
     1853
     1854
     1855
     1856
     1857
     1858
     1859
     1860
     1861
     1862
     1863
     1864
     1865
     1866
     1867
     1868
     1869
     1870
     1871
     1872
     1873
     1874
     1875
     1876
     1877
     1878
     1879
     1880
     1881
     1882
     1883
     1884
     1885
     1886
     1887
     1888
     1889
     1890
     1891
     1892
     1893
     1894
     1895
     1896
     1897
     1898
     1899
     1900
     1901
     1902
     1903
     1904
     1905
     1906
     1907
     1908
     1909
     1910
     1911
     1912
     1913
     1914
     1915
     1916
     1917
     1918
     1919
     1920
     1921
     1922
     1923
     1924
    13501925#ifndef QT_NO_TOOLTIP
    13511926/*!
     
    14161991    d_ptr->hasCursor = 1;
    14171992    if (d_ptr->scene) {
     1993
    14181994        foreach (QGraphicsView *view, d_ptr->scene->views()) {
     1995
    14191996            // Note: Some of this logic is duplicated in QGraphicsView's mouse events.
    14201997            if (view->underMouse()) {
     
    15232100        return;
    15242101
     2102
     2103
     2104
     2105
    15252106    // Modify the property.
    15262107    const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange,
     
    15362117        if (c)
    15372118            c->purge();
    1538         updateHelper(QRectF(), /* force = */ true);
     2119        if (scene)
     2120            scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
    15392121    }
    15402122
     
    15462128            if (scene->d_func()->keyboardGrabberItems.contains(q))
    15472129                q->ungrabKeyboard();
     2130
     2131
    15482132        }
    15492133        if (q_ptr->hasFocus() && scene) {
    1550             // Hiding the closest non-window ancestor of the focus item
     2134            // Hiding the closest non- ancestor of the focus item
    15512135            QGraphicsItem *focusItem = scene->focusItem();
    15522136            bool clear = true;
    1553             if (isWidget && !focusItem->isWindow()) {
     2137            if (isWidget && !focusItem->is()) {
    15542138                do {
    15552139                    if (focusItem == q_ptr) {
     
    15572141                        break;
    15582142                    }
    1559                 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isWindow());
     2143                } while ((focusItem = focusItem->parentWidget()) && !focusItem->is());
    15602144            }
    15612145            if (clear)
     
    15652149            q_ptr->setSelected(false);
    15662150    } else {
    1567         if (isWidget && scene) {
    1568             QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
    1569             if (widget->windowType() == Qt::Popup)
    1570                 scene->d_func()->addPopup(widget);
     2151        geometryChanged = 1;
     2152        paintedViewBoundingRectsNeedRepaint = 1;
     2153        if (scene) {
     2154            if (isWidget) {
     2155                QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
     2156                if (widget->windowType() == Qt::Popup)
     2157                    scene->d_func()->addPopup(widget);
     2158            }
     2159            if (q->isPanel() && panelModality != QGraphicsItem::NonModal) {
     2160                scene->d_func()->enterModal(q_ptr);
     2161            }
    15712162        }
    15722163    }
     
    15792170    }
    15802171
     2172
     2173
     2174
     2175
     2176
     2177
     2178
     2179
     2180
     2181
     2182
    15812183    // Enable subfocus
    1582     if (newVisible && isWidget) {
    1583         QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
    1584         QGraphicsWidget *fw = widget->focusWidget();
    1585         if (fw && fw != scene->focusItem())
    1586             scene->setFocusItem(fw);
     2184    if (scene && newVisible) {
     2185        QGraphicsItem *p = parent;
     2186        bool done = false;
     2187        while (p) {
     2188            if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
     2189                QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
     2190                if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
     2191                    done = true;
     2192                    while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
     2193                        fsi = fsi->d_ptr->focusScopeItem;
     2194                    scene->setFocusItem(fsi);
     2195                }
     2196                break;
     2197            }
     2198            p = p->d_ptr->parent;
     2199        }
     2200        if (!done) {
     2201            QGraphicsItem *fi = subFocusItem;
     2202            if (fi && fi != scene->focusItem()) {
     2203                scene->setFocusItem(fi);
     2204            }
     2205        }
    15872206    }
    15882207
    15892208    // Deliver post-change notification.
    15902209    q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, newVisibleVariant);
     2210
     2211
     2212
    15912213}
    15922214
     
    16742296            q_ptr->ungrabMouse();
    16752297        if (q_ptr->hasFocus()) {
    1676             // Disabling the closest non-window ancestor of the focus item
     2298            // Disabling the closest non- ancestor of the focus item
    16772299            // causes focus to pop to the next item, otherwise it's cleared.
    16782300            QGraphicsItem *focusItem = scene->focusItem();
    16792301            bool clear = true;
    1680             if (isWidget && !focusItem->isWindow() && q_ptr->isAncestorOf(focusItem)) {
     2302            if (isWidget && !focusItem->is() && q_ptr->isAncestorOf(focusItem)) {
    16812303                do {
    16822304                    if (focusItem == q_ptr) {
     
    16842306                        break;
    16852307                    }
    1686                 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isWindow());
     2308                } while ((focusItem = focusItem->parentWidget()) && !focusItem->is());
    16872309            }
    16882310            if (clear)
     
    17002322    // Schedule redraw.
    17012323    if (update)
    1702         updateHelper();
     2324        ();
    17032325
    17042326    foreach (QGraphicsItem *child, children) {
     
    17092331    // Deliver post-change notification.
    17102332    q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, newEnabledVariant);
     2333
     2334
     2335
    17112336}
    17122337
     
    18012426    d_ptr->selected = newSelected;
    18022427
    1803     d_ptr->updateHelper();
    1804 
     2428    update();
    18052429    if (d_ptr->scene) {
    18062430        QGraphicsScenePrivate *sceneD = d_ptr->scene->d_func();
     
    18392463qreal QGraphicsItem::opacity() const
    18402464{
    1841     if (d_ptr->hasOpacity) {
    1842         QVariant o = d_ptr->extra(QGraphicsItemPrivate::ExtraOpacity);
    1843         if (!o.isNull())
    1844             return o.toDouble();
    1845     }
    1846     return qreal(1.0);
     2465    return d_ptr->opacity;
    18472466}
    18482467
     
    18602479qreal QGraphicsItem::effectiveOpacity() const
    18612480{
    1862     if (!d_ptr->hasEffectiveOpacity)
    1863         return qreal(1.0);
    1864 
    1865     QVariant effectiveOpacity = d_ptr->extra(QGraphicsItemPrivate::ExtraEffectiveOpacity);
    1866     return effectiveOpacity.isNull() ? qreal(1.0) : qreal(effectiveOpacity.toDouble());
     2481    return d_ptr->effectiveOpacity();
    18672482}
    18682483
     
    18922507{
    18932508    // Notify change.
    1894     const QVariant newOpacityVariant(itemChange(ItemOpacityChange, double(opacity)));
    1895     qreal newOpacity = newOpacityVariant.toDouble();
    1896 
    1897     // Normalize.
    1898     newOpacity = qBound<qreal>(0.0, newOpacity, 1.0);
     2509    const QVariant newOpacityVariant(itemChange(ItemOpacityChange, opacity));
     2510
     2511    // Normalized opacity
     2512    qreal newOpacity = qBound(qreal(0), newOpacityVariant.toReal(), qreal(1));
    18992513
    19002514    // No change? Done.
    1901     if (qFuzzyCompare(newOpacity, this->opacity()))
     2515    if ()
    19022516        return;
    19032517
    1904     // Assign local opacity.
    1905     if (qFuzzyCompare(newOpacity, qreal(1.0))) {
    1906         // Opaque, unset opacity.
    1907         d_ptr->hasOpacity = 0;
    1908         d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraOpacity);
    1909     } else {
    1910         d_ptr->hasOpacity = 1;
    1911         d_ptr->setExtra(QGraphicsItemPrivate::ExtraOpacity, double(newOpacity));
    1912     }
    1913 
    1914     // Resolve effective opacity.
    1915     if (QGraphicsItem *p = d_ptr->parent)
    1916         d_ptr->resolveEffectiveOpacity(p->effectiveOpacity());
    1917     else
    1918         d_ptr->resolveEffectiveOpacity(1.0);
     2518    d_ptr->opacity = newOpacity;
    19192519
    19202520    // Notify change.
    1921     itemChange(ItemOpacityHasChanged, newOpacity);
     2521    itemChange(ItemOpacityHasChanged, newOpacity);
    19222522
    19232523    // Update.
    1924     d_ptr->fullUpdateHelper();
     2524    if (d_ptr->scene) {
     2525#ifndef QT_NO_GRAPHICSEFFECT
     2526        d_ptr->invalidateGraphicsEffectsRecursively();
     2527#endif //QT_NO_GRAPHICSEFFECT
     2528        d_ptr->scene->d_func()->markDirty(this, QRectF(),
     2529                                          /*invalidateChildren=*/true,
     2530                                          /*force=*/false,
     2531                                          /*ignoreOpacity=*/true);
     2532    }
     2533
     2534    if (d_ptr->isObject)
     2535        emit static_cast<QGraphicsObject *>(this)->opacityChanged();
     2536}
     2537
     2538/*!
     2539    Returns a pointer to this item's effect if it has one; otherwise 0.
     2540
     2541    \since 4.6
     2542*/
     2543#ifndef QT_NO_GRAPHICSEFFECT
     2544QGraphicsEffect *QGraphicsItem::graphicsEffect() const
     2545{
     2546    return d_ptr->graphicsEffect;
     2547}
     2548
     2549/*!
     2550    Sets \a effect as the item's effect. If there already is an effect installed
     2551    on this item, QGraphicsItem will delete the existing effect before installing
     2552    the new \a effect.
     2553
     2554    If \a effect is the installed on a different item, setGraphicsEffect() will remove
     2555    the effect from the item and install it on this item.
     2556
     2557    QGraphicsItem takes ownership of \a effect.
     2558
     2559    \note This function will apply the effect on itself and all its children.
     2560
     2561    \since 4.6
     2562*/
     2563void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
     2564{
     2565    if (d_ptr->graphicsEffect == effect)
     2566        return;
     2567
     2568    if (d_ptr->graphicsEffect) {
     2569        delete d_ptr->graphicsEffect;
     2570        d_ptr->graphicsEffect = 0;
     2571    }
     2572
     2573    if (effect) {
     2574        // Set new effect.
     2575        QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
     2576        QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
     2577        d_ptr->graphicsEffect = effect;
     2578        effect->d_func()->setGraphicsEffectSource(source);
     2579        prepareGeometryChange();
     2580    }
     2581}
     2582#endif //QT_NO_GRAPHICSEFFECT
     2583
     2584/*!
     2585    \internal
     2586    \since 4.6
     2587    Returns the effective bounding rect of the given item space rect.
     2588    If the item has no effect, the rect is returned unmodified.
     2589    If the item has an effect, the effective rect can be extend beyond the
     2590    item's bounding rect, depending on the effect.
     2591
     2592    \sa boundingRect()
     2593*/
     2594QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
     2595{
     2596#ifndef QT_NO_GRAPHICSEFFECT
     2597    Q_Q(const QGraphicsItem);
     2598    QGraphicsEffect *effect = graphicsEffect;
     2599    if (scene && effect && effect->isEnabled()) {
     2600        QRectF sceneRect = q->mapRectToScene(rect);
     2601        QRectF sceneEffectRect;
     2602        foreach (QGraphicsView *view, scene->views()) {
     2603            QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect);
     2604            QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect();
     2605            sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect);
     2606        }
     2607        return q->mapRectFromScene(sceneEffectRect);
     2608    }
     2609#endif //QT_NO_GRAPHICSEFFECT
     2610    return rect;
     2611}
     2612
     2613/*!
     2614    \internal
     2615    \since 4.6
     2616    Returns the effective bounding rect of the item.
     2617    If the item has no effect, this is the same as the item's bounding rect.
     2618    If the item has an effect, the effective rect can be larger than the item's
     2619    bouding rect, depending on the effect.
     2620
     2621    \sa boundingRect()
     2622*/
     2623QRectF QGraphicsItemPrivate::effectiveBoundingRect() const
     2624{
     2625#ifndef QT_NO_GRAPHICSEFFECT
     2626    Q_Q(const QGraphicsItem);
     2627    QRectF brect = effectiveBoundingRect(q_ptr->boundingRect());
     2628    if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
     2629        return brect;
     2630
     2631    const QGraphicsItem *effectParent = parent;
     2632    while (effectParent) {
     2633        QGraphicsEffect *effect = effectParent->d_ptr->graphicsEffect;
     2634        if (scene && effect && effect->isEnabled()) {
     2635            const QRectF brectInParentSpace = q->mapRectToItem(effectParent, brect);
     2636            const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace);
     2637            brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
     2638        }
     2639        if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
     2640            return brect;
     2641        effectParent = effectParent->d_ptr->parent;
     2642    }
     2643
     2644    return brect;
     2645#else //QT_NO_GRAPHICSEFFECT
     2646    return q_ptr->boundingRect();
     2647#endif //QT_NO_GRAPHICSEFFECT
     2648
     2649}
     2650
     2651/*!
     2652    \internal
     2653    \since 4.6
     2654    Returns the effective bounding rect of this item in scene coordinates,
     2655    by combining sceneTransform() with boundingRect(), taking into account
     2656    the effect that the item might have.
     2657
     2658    If the item has no effect, this is the same as sceneBoundingRect().
     2659
     2660    \sa effectiveBoundingRect(), sceneBoundingRect()
     2661*/
     2662QRectF QGraphicsItemPrivate::sceneEffectiveBoundingRect() const
     2663{
     2664    // Find translate-only offset
     2665    // COMBINE
     2666    QPointF offset;
     2667    const QGraphicsItem *parentItem = q_ptr;
     2668    const QGraphicsItemPrivate *itemd;
     2669    do {
     2670        itemd = parentItem->d_ptr.data();
     2671        if (itemd->transformData)
     2672            break;
     2673        offset += itemd->pos;
     2674    } while ((parentItem = itemd->parent));
     2675
     2676    QRectF br = effectiveBoundingRect();
     2677    br.translate(offset);
     2678    return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
    19252679}
    19262680
     
    20352789    children's areas.
    20362790
    2037     If a parent item handles child events (setHandlesChildEvents()), it will
    2038     receive hover move, drag move, and drop events as the cursor passes
    2039     through its children, but it does not receive hover enter and hover leave,
    2040     nor drag enter and drag leave events on behalf of its children.
     2791    If a parent item handles child events
     2792    s
     2793   
     2794    drag enter and drag leave events on behalf of its children.
    20412795
    20422796    A QGraphicsWidget with window decorations will accept hover events
     
    20482802void QGraphicsItem::setAcceptHoverEvents(bool enabled)
    20492803{
     2804
     2805
    20502806    d_ptr->acceptsHover = quint32(enabled);
     2807
     2808
     2809
     2810
    20512811}
    20522812
     
    20582818void QGraphicsItem::setAcceptsHoverEvents(bool enabled)
    20592819{
    2060     d_ptr->acceptsHover = quint32(enabled);
    2061 }
    2062 
    2063 /*!
     2820    setAcceptHoverEvents(enabled);
     2821}
     2822
     2823/*! \since 4.6
     2824
     2825    Returns true if an item accepts \l{QTouchEvent}{touch events};
     2826    otherwise, returns false. By default, items do not accept touch events.
     2827
     2828    \sa setAcceptTouchEvents()
     2829*/
     2830bool QGraphicsItem::acceptTouchEvents() const
     2831{
     2832    return d_ptr->acceptTouchEvents;
     2833}
     2834
     2835/*!
     2836    \since 4.6
     2837
     2838    If \a enabled is true, this item will accept \l{QTouchEvent}{touch events};
     2839    otherwise, it will ignore them. By default, items do not accept
     2840    touch events.
     2841*/
     2842void QGraphicsItem::setAcceptTouchEvents(bool enabled)
     2843{
     2844    if (d_ptr->acceptTouchEvents == quint32(enabled))
     2845        return;
     2846    d_ptr->acceptTouchEvents = quint32(enabled);
     2847    if (d_ptr->acceptTouchEvents && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreTouchEvents) {
     2848        d_ptr->scene->d_func()->allItemsIgnoreTouchEvents = false;
     2849        d_ptr->scene->d_func()->enableTouchEventsOnViews();
     2850    }
     2851}
     2852
     2853/*!
     2854    \since 4.6
     2855
     2856    Returns true if this item filters child events (i.e., all events
     2857    intended for any of its children are instead sent to this item);
     2858    otherwise, false is returned.
     2859
     2860    The default value is false; child events are not filtered.
     2861
     2862    \sa setFiltersChildEvents()
     2863*/
     2864bool QGraphicsItem::filtersChildEvents() const
     2865{
     2866    return d_ptr->filtersDescendantEvents;
     2867}
     2868
     2869/*!
     2870    \since 4.6
     2871
     2872    If \a enabled is true, this item is set to filter all events for
     2873    all its children (i.e., all events intented for any of its
     2874    children are instead sent to this item); otherwise, if \a enabled
     2875    is false, this item will only handle its own events. The default
     2876    value is false.
     2877
     2878    \sa filtersChildEvents()
     2879*/
     2880void QGraphicsItem::setFiltersChildEvents(bool enabled)
     2881{
     2882    if (d_ptr->filtersDescendantEvents == enabled)
     2883        return;
     2884
     2885    d_ptr->filtersDescendantEvents = enabled;
     2886    d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
     2887}
     2888
     2889/*!
     2890    \obsolete
     2891
    20642892    Returns true if this item handles child events (i.e., all events
    20652893    intended for any of its children are instead sent to this item);
     
    20822910
    20832911/*!
     2912
     2913
    20842914    If \a enabled is true, this item is set to handle all events for
    20852915    all its children (i.e., all events intented for any of its
     
    21072937    d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
    21082938}
    2109 
    2110 /*!
    2111     Returns true if this item has keyboard input focus; otherwise, returns
    2112     false.
    2113 
    2114     \sa QGraphicsScene::focusItem(), setFocus(), QGraphicsScene::setFocusItem()
     2939/*!
     2940    \since 4.6
     2941    Returns true if this item is active; otherwise returns false.
     2942
     2943    An item can only be active if the scene is active. An item is active
     2944    if it is, or is a descendent of, an active panel. Items in non-active
     2945    panels are not active.
     2946
     2947    Items that are not part of a panel follow scene activation when the
     2948    scene has no active panel.
     2949
     2950    Only active items can gain input focus.
     2951
     2952    \sa QGraphicsScene::isActive(), QGraphicsScene::activePanel(), panel(), isPanel()
     2953*/
     2954bool QGraphicsItem::isActive() const
     2955{
     2956    if (!d_ptr->scene || !d_ptr->scene->isActive())
     2957        return false;
     2958    return panel() == d_ptr->scene->activePanel();
     2959}
     2960
     2961/*!
     2962    \since 4.6
     2963
     2964    If \a active is true, and the scene is active, this item's panel will be
     2965    activated. Otherwise, the panel is deactivated.
     2966
     2967    If the item is not part of an active scene, \a active will decide what
     2968    happens to the panel when the scene becomes active or the item is added to
     2969    the scene. If true, the item's panel will be activated when the item is
     2970    either added to the scene or the scene is activated. Otherwise, the item
     2971    will stay inactive independent of the scene's activated state.
     2972
     2973    \sa isPanel(), QGraphicsScene::setActivePanel(), QGraphicsScene::isActive()
     2974*/
     2975void QGraphicsItem::setActive(bool active)
     2976{
     2977    d_ptr->explicitActivate = 1;
     2978    d_ptr->wantsActive = active;
     2979    if (d_ptr->scene) {
     2980        if (active) {
     2981            // Activate this item.
     2982            d_ptr->scene->setActivePanel(this);
     2983        } else {
     2984            // Deactivate this item, and reactivate the last active item
     2985            // (if any).
     2986            QGraphicsItem *lastActive = d_ptr->scene->d_func()->lastActivePanel;
     2987            d_ptr->scene->setActivePanel(lastActive != this ? lastActive : 0);
     2988        }
     2989    }
     2990}
     2991
     2992/*!
     2993    Returns true if this item is active, and it or its \l{focusProxy()}{focus
     2994    proxy} has keyboard input focus; otherwise, returns false.
     2995
     2996    \sa focusItem(), setFocus(), QGraphicsScene::setFocusItem(), isActive()
    21152997*/
    21162998bool QGraphicsItem::hasFocus() const
    21172999{
    2118     return (d_ptr->scene && d_ptr->scene->focusItem() == this);
     3000    if (d_ptr->focusProxy)
     3001        return d_ptr->focusProxy->hasFocus();
     3002    return isActive() && (d_ptr->scene && d_ptr->scene->focusItem() == this);
    21193003}
    21203004
    21213005/*!
    21223006    Gives keyboard input focus to this item. The \a focusReason argument will
    2123     be passed into any focus event generated by this function; it is used to
    2124     give an explanation of what caused the item to get focus.
    2125 
    2126     Only items that set the ItemIsFocusable flag can accept keyboard focus.
    2127 
    2128     If this item is not visible (i.e., isVisible() returns false), not
    2129     enabled, not associated with a scene, or if it already has input focus,
    2130     this function will do nothing.
    2131 
    2132     As a result of calling this function, this item will receive a focus in
    2133     event with \a focusReason. If another item already has focus, that item
    2134     will first receive a focus out event indicating that it has lost input
     3007    be passed into any \l{QFocusEvent}{focus event} generated by this function;
     3008    it is used to give an explanation of what caused the item to get focus.
     3009
     3010    Only enabled items that set the ItemIsFocusable flag can accept keyboard
    21353011    focus.
    21363012
    2137     \sa clearFocus(), hasFocus()
     3013    If this item is not visible, not active, or not associated with a scene,
     3014    it will not gain immediate input focus. However, it will be registered as
     3015    the preferred focus item for its subtree of items, should it later become
     3016    visible.
     3017
     3018    As a result of calling this function, this item will receive a
     3019    \l{focusInEvent()}{focus in event} with \a focusReason. If another item
     3020    already has focus, that item will first receive a \l{focusOutEvent()}
     3021    {focus out event} indicating that it has lost input focus.
     3022
     3023    \sa clearFocus(), hasFocus(), focusItem(), focusProxy()
    21383024*/
    21393025void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
    21403026{
    2141     if (!d_ptr->scene || !isEnabled() || hasFocus() || !(d_ptr->flags & ItemIsFocusable))
     3027    d_ptr->setFocusHelper(focusReason, /* climb = */ true);
     3028}
     3029
     3030/*!
     3031    \internal
     3032*/
     3033void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb)
     3034{
     3035    // Disabled / unfocusable items cannot accept focus.
     3036    if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
    21423037        return;
    2143     if (isVisible()) {
    2144         // Visible items immediately gain focus from scene.
    2145         d_ptr->scene->setFocusItem(this, focusReason);
    2146     } else if (d_ptr->isWidget) {
    2147         // Just set up subfocus.
    2148         static_cast<QGraphicsWidget *>(this)->d_func()->setFocusWidget();
     3038
     3039    // Find focus proxy.
     3040    QGraphicsItem *f = q_ptr;
     3041    while (f->d_ptr->focusProxy)
     3042        f = f->d_ptr->focusProxy;
     3043
     3044    // Return if it already has focus.
     3045    if (scene && scene->focusItem() == f)
     3046        return;
     3047
     3048    // Update focus scope item ptr.
     3049    QGraphicsItem *p = parent;
     3050    while (p) {
     3051        if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
     3052            p->d_ptr->focusScopeItem = q_ptr;
     3053            if (!p->focusItem()) {
     3054                // If you call setFocus on a child of a focus scope that
     3055                // doesn't currently have a focus item, then stop.
     3056                return;
     3057            }
     3058            break;
     3059        }
     3060        p = p->d_ptr->parent;
     3061    }
     3062
     3063    if (climb) {
     3064        while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible())
     3065            f = f->d_ptr->focusScopeItem;
     3066    }
     3067
     3068    // Update the child focus chain.
     3069    f->d_ptr->setSubFocus();
     3070
     3071    // Update the scene's focus item.
     3072    if (scene) {
     3073        QGraphicsItem *p = q_ptr->panel();
     3074        if ((!p && scene->isActive()) || (p && p->isActive())) {
     3075            // Visible items immediately gain focus from scene.
     3076            scene->d_func()->setFocusItemHelper(f, focusReason);
     3077        }
    21493078    }
    21503079}
     
    21533082    Takes keyboard input focus from the item.
    21543083
    2155     If it has focus, a focus out event is sent to this item to tell it that it
    2156     is about to lose the focus.
     3084    If it has focus, a
     3085    is about to lose the focus.
    21573086
    21583087    Only items that set the ItemIsFocusable flag, or widgets that set an
    21593088    appropriate focus policy, can accept keyboard focus.
    21603089
    2161     \sa setFocus(), QGraphicsWidget::focusPolicy
     3090    \sa setFocus(), QGraphicsWidget::focusPolicy
    21623091*/
    21633092void QGraphicsItem::clearFocus()
    21643093{
    2165     if (!d_ptr->scene)
    2166         return;
    2167     if (d_ptr->isWidget) {
    2168         // Invisible widget items with focus must explicitly clear subfocus.
    2169         static_cast<QGraphicsWidget *>(this)->d_func()->clearFocusWidget();
    2170     }
    2171     if (d_ptr->scene->focusItem() == this) {
     3094    // Pass focus to the closest parent focus scope.
     3095    if (!d_ptr->inDestructor) {
     3096        QGraphicsItem *p = d_ptr->parent;
     3097        while (p) {
     3098            if (p->flags() & ItemIsFocusScope) {
     3099                p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false);
     3100                return;
     3101            }
     3102            p = p->d_ptr->parent;
     3103        }
     3104    }
     3105
     3106    // Invisible items with focus must explicitly clear subfocus.
     3107    d_ptr->clearSubFocus(this);
     3108
     3109    if (hasFocus()) {
    21723110        // If this item has the scene's input focus, clear it.
    21733111        d_ptr->scene->setFocusItem(0);
    21743112    }
     3113
     3114
     3115
     3116
     3117
     3118
     3119
     3120
     3121
     3122
     3123
     3124
     3125
     3126
     3127
     3128
     3129
     3130
     3131
     3132
     3133
     3134
     3135
     3136
     3137
     3138
     3139
     3140
     3141
     3142
     3143
     3144
     3145
     3146
     3147
     3148
     3149
     3150
     3151
     3152
     3153
     3154
     3155
     3156
     3157
     3158
     3159
     3160
     3161
     3162
     3163
     3164
     3165
     3166
     3167
     3168
     3169
     3170
     3171
     3172
     3173
     3174
     3175
     3176
     3177
     3178
     3179
     3180
     3181
     3182
     3183
     3184
     3185
     3186
     3187
     3188
     3189
     3190
     3191
     3192
     3193
     3194
     3195
     3196
     3197
    21753198}
    21763199
     
    23103333    item's position in scene coordinates, regardless of its parent.
    23113334
    2312     \sa x(), y(), setPos(), matrix(), {The Graphics View Coordinate System}
     3335    \sa x(), y(), setPos(), (), {The Graphics View Coordinate System}
    23133336*/
    23143337QPointF QGraphicsItem::pos() const
     
    23263349
    23273350/*!
     3351
     3352
     3353
     3354
     3355
     3356
     3357
     3358
     3359
     3360
     3361
     3362
     3363
     3364
     3365
     3366
    23283367    \fn QGraphicsItem::y() const
    23293368
     
    23323371    \sa x()
    23333372*/
     3373
     3374
     3375
     3376
     3377
     3378
     3379
     3380
     3381
     3382
     3383
     3384
     3385
     3386
     3387
     3388
    23343389
    23353390/*!
     
    23473402    \internal
    23483403
    2349     Sets the position \a pos and notifies the change. If \a update is true,
    2350     the item is also updated; otherwise it is not updated before and after the
    2351     change.
     3404    Sets the position \a pos.
    23523405*/
    23533406void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
    23543407{
    23553408    Q_Q(QGraphicsItem);
    2356     if (this->pos == pos)
    2357         return;
    2358 
    2359     // Notify the item that the position is changing.
    2360     const QVariant newPosVariant(q->itemChange(QGraphicsItem::ItemPositionChange, pos));
    2361     QPointF newPos = newPosVariant.toPointF();
    2362     if (newPos == this->pos)
    2363         return;
    2364 
    2365     // Update and repositition.
    23663409    inSetPosHelper = 1;
    2367     updateCachedClipPathFromSetPosHelper(newPos);
    2368     if (scene) {
    2369         fullUpdateHelper(true);
     3410    if (scene)
    23703411        q->prepareGeometryChange();
    2371     }
    2372     this->pos = newPos;
    2373     invalidateSceneTransformCache();
    2374 
    2375     // Send post-notification.
    2376     q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
     3412    QPointF oldPos = this->pos;
     3413    this->pos = pos;
     3414    dirtySceneTransform = 1;
    23773415    inSetPosHelper = 0;
     3416
     3417
     3418
     3419
     3420
     3421
     3422
     3423
     3424
     3425
     3426
     3427
     3428
     3429
     3430
     3431
     3432
     3433
    23783434}
    23793435
     
    23903446void QGraphicsItem::setPos(const QPointF &pos)
    23913447{
    2392     d_ptr->setPosHelper(pos);
     3448    if (d_ptr->pos == pos)
     3449        return;
     3450
     3451    if (d_ptr->inDestructor)
     3452        return;
     3453
     3454    // Update and repositition.
     3455    if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
     3456        d_ptr->setPosHelper(pos);
     3457        return;
     3458    }
     3459
     3460    // Notify the item that the position is changing.
     3461    const QVariant newPosVariant(itemChange(ItemPositionChange, qVariantFromValue<QPointF>(pos)));
     3462    QPointF newPos = newPosVariant.toPointF();
     3463    if (newPos == d_ptr->pos)
     3464        return;
     3465
     3466    // Update and repositition.
     3467    d_ptr->setPosHelper(newPos);
     3468
     3469    // Send post-notification.
     3470    itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
     3471    d_ptr->sendScenePosChange();
    23933472}
    23943473
     
    24633542    \since 4.3
    24643543
    2465     Returns this item's transformation matrix. If no matrix has been set, the
    2466     identity matrix is returned.
     3544    Returns this item's transformation matrix.
     3545
     3546    The transformation matrix is combined with the item's rotation(), scale()
     3547    and transformations() into a combined transformations for the item.
     3548
     3549    The default transformation matrix is an identity matrix.
    24673550
    24683551    \sa setTransform(), sceneTransform()
     
    24703553QTransform QGraphicsItem::transform() const
    24713554{
    2472     if (!d_ptr->hasTransform)
     3555    if (!d_ptr->)
    24733556        return QTransform();
    2474     return qVariantValue<QTransform>(d_ptr->extra(QGraphicsItemPrivate::ExtraTransform));
    2475 }
     3557    return d_ptr->transformData->transform;
     3558}
     3559
     3560/*!
     3561    \since 4.6
     3562
     3563    Returns the clockwise rotation, in degrees, around the Z axis. The default
     3564    value is 0 (i.e., the item is not rotated).
     3565
     3566    The rotation is combined with the item's scale(), transform() and
     3567    transformations() to map the item's coordinate system to the parent item.
     3568
     3569    \sa setRotation(), transformOriginPoint(), {Transformations}
     3570*/
     3571qreal QGraphicsItem::rotation() const
     3572{
     3573    if (!d_ptr->transformData)
     3574        return 0;
     3575    return d_ptr->transformData->rotation;
     3576}
     3577
     3578/*!
     3579    \since 4.6
     3580
     3581    Sets the clockwise rotation \a angle, in degrees, around the Z axis. The
     3582    default value is 0 (i.e., the item is not rotated). Assigning a negative
     3583    value will rotate the item counter-clockwise. Normally the rotation angle
     3584    is in the range (-360, 360), but it's also possible to assign values
     3585    outside of this range (e.g., a rotation of 370 degrees is the same as a
     3586    rotation of 10 degrees).
     3587
     3588    The item is rotated around its transform origin point, which by default
     3589    is (0, 0). You can select a different transformation origin by calling
     3590    setTransformOriginPoint().
     3591
     3592    The rotation is combined with the item's scale(), transform() and
     3593    transformations() to map the item's coordinate system to the parent item.
     3594
     3595    \sa rotation(), setTransformOriginPoint(), {Transformations}
     3596*/
     3597void QGraphicsItem::setRotation(qreal angle)
     3598{
     3599    prepareGeometryChange();
     3600    if (!d_ptr->transformData)
     3601        d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
     3602    d_ptr->transformData->rotation = angle;
     3603    d_ptr->transformData->onlyTransform = false;
     3604    d_ptr->dirtySceneTransform = 1;
     3605
     3606    if (d_ptr->isObject)
     3607        emit static_cast<QGraphicsObject *>(this)->rotationChanged();
     3608}
     3609
     3610/*!
     3611    \since 4.6
     3612
     3613    Returns the scale factor of the item. The default scale factor is 1.0
     3614    (i.e., the item is not scaled).
     3615
     3616    The scale is combined with the item's rotation(), transform() and
     3617    transformations() to map the item's coordinate system to the parent item.
     3618
     3619    \sa setScale(), rotation(), {Transformations}
     3620*/
     3621qreal QGraphicsItem::scale() const
     3622{
     3623    if (!d_ptr->transformData)
     3624        return 1.;
     3625    return d_ptr->transformData->scale;
     3626}
     3627
     3628/*!
     3629    \since 4.6
     3630
     3631    Sets the scale \a factor of the item. The default scale factor is 1.0
     3632    (i.e., the item is not scaled). A scale factor of 0.0 will collapse the
     3633    item to a single point. If you provide a negative scale factor, the
     3634    item will be flipped and mirrored (i.e., rotated 180 degrees).
     3635
     3636    The item is scaled around its transform origin point, which by default
     3637    is (0, 0). You can select a different transformation origin by calling
     3638    setTransformOriginPoint().
     3639
     3640    The scale is combined with the item's rotation(), transform() and
     3641    transformations() to map the item's coordinate system to the parent item.
     3642
     3643    \sa scale(), setTransformOriginPoint(), {Transformations}
     3644*/
     3645void QGraphicsItem::setScale(qreal factor)
     3646{
     3647    prepareGeometryChange();
     3648    if (!d_ptr->transformData)
     3649        d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
     3650    d_ptr->transformData->scale = factor;
     3651    d_ptr->transformData->onlyTransform = false;
     3652    d_ptr->dirtySceneTransform = 1;
     3653
     3654    if (d_ptr->isObject)
     3655        emit static_cast<QGraphicsObject *>(this)->scaleChanged();
     3656}
     3657
     3658
     3659/*!
     3660    \since 4.6
     3661
     3662    Returns a list of graphics transforms that currently apply to this item.
     3663
     3664    QGraphicsTransform is for applying and controlling a chain of individual
     3665    transformation operations on an item. It's particularily useful in
     3666    animations, where each transform operation needs to be interpolated
     3667    independently, or differently.
     3668
     3669    The transformations are combined with the item's rotation(), scale() and
     3670    transform() to map the item's coordinate system to the parent item.
     3671
     3672    \sa scale(), rotation(), transformOriginPoint(), {Transformations}
     3673*/
     3674QList<QGraphicsTransform *> QGraphicsItem::transformations() const
     3675{
     3676    if (!d_ptr->transformData)
     3677        return QList<QGraphicsTransform *>();
     3678    return d_ptr->transformData->graphicsTransforms;
     3679}
     3680
     3681/*!
     3682    \since 4.6
     3683
     3684    Sets a list of graphics \a transformations (QGraphicsTransform) that
     3685    currently apply to this item.
     3686
     3687    If all you want is to rotate or scale an item, you should call setRotation()
     3688    or setScale() instead. If you want to set an arbitrary transformation on
     3689    an item, you can call setTransform().
     3690
     3691    QGraphicsTransform is for applying and controlling a chain of individual
     3692    transformation operations on an item. It's particularily useful in
     3693    animations, where each transform operation needs to be interpolated
     3694    independently, or differently.
     3695
     3696    The transformations are combined with the item's rotation(), scale() and
     3697    transform() to map the item's coordinate system to the parent item.
     3698
     3699    \sa scale(), setTransformOriginPoint(), {Transformations}
     3700*/
     3701void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transformations)
     3702{
     3703    prepareGeometryChange();
     3704    if (!d_ptr->transformData)
     3705        d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
     3706    d_ptr->transformData->graphicsTransforms = transformations;
     3707    for (int i = 0; i < transformations.size(); ++i)
     3708        transformations.at(i)->d_func()->setItem(this);
     3709    d_ptr->transformData->onlyTransform = false;
     3710    d_ptr->dirtySceneTransform = 1;
     3711}
     3712
     3713/*!
     3714    \internal
     3715*/
     3716void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t)
     3717{
     3718    if (!transformData)
     3719        transformData = new QGraphicsItemPrivate::TransformData;
     3720    if (!transformData->graphicsTransforms.contains(t))
     3721        transformData->graphicsTransforms.append(t);
     3722
     3723    Q_Q(QGraphicsItem);
     3724    t->d_func()->setItem(q);
     3725    transformData->onlyTransform = false;
     3726    dirtySceneTransform = 1;
     3727}
     3728
     3729/*!
     3730    \since 4.6
     3731
     3732    Returns the origin point for the transformation in item coordinates.
     3733
     3734    The default is QPointF(0,0).
     3735
     3736    \sa setTransformOriginPoint(), {Transformations}
     3737*/
     3738QPointF QGraphicsItem::transformOriginPoint() const
     3739{
     3740    if (!d_ptr->transformData)
     3741        return QPointF(0,0);
     3742    return QPointF(d_ptr->transformData->xOrigin, d_ptr->transformData->yOrigin);
     3743}
     3744
     3745/*!
     3746    \since 4.6
     3747
     3748    Sets the \a origin point for the transformation in item coordinates.
     3749
     3750    \sa transformOriginPoint(), {Transformations}
     3751*/
     3752void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
     3753{
     3754    prepareGeometryChange();
     3755    if (!d_ptr->transformData)
     3756        d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
     3757    d_ptr->transformData->xOrigin = origin.x();
     3758    d_ptr->transformData->yOrigin = origin.y();
     3759    d_ptr->transformData->onlyTransform = false;
     3760    d_ptr->dirtySceneTransform = 1;
     3761}
     3762
     3763/*!
     3764    \fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y)
     3765
     3766    \since 4.6
     3767    \overload
     3768
     3769    Sets the origin point for the transformation in item coordinates.
     3770    This is equivalent to calling setTransformOriginPoint(QPointF(\a x, \a y)).
     3771
     3772    \sa setTransformOriginPoint(), {Transformations}
     3773*/
     3774
    24763775
    24773776/*!
     
    24843783QMatrix QGraphicsItem::sceneMatrix() const
    24853784{
    2486     return sceneTransform().toAffine();
     3785    d_ptr->ensureSceneTransform();
     3786    return d_ptr->sceneTransform.toAffine();
    24873787}
    24883788
     
    25013801
    25023802    Unlike transform(), which returns only an item's local transformation, this
    2503     function includes the item's (and any parents') position.
    2504 
    2505     \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}
     3803    function includes the item's (and any parents') position.
     3804
     3805    \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}
    25063806*/
    25073807QTransform QGraphicsItem::sceneTransform() const
    25083808{
    2509     // Check if there's any entry in the transform cache.
    2510     QGraphicsScenePrivate *sd = d_ptr->scene ? d_ptr->scene->d_func() : 0;
    2511     int index = d_ptr->sceneTransformIndex;
    2512     if (sd && index != -1 && sd->validTransforms.testBit(index))
    2513         return sd->sceneTransformCache[index];
    2514 
    2515     // Calculate local transform.
    2516     QTransform m;
    2517     if (d_ptr->hasTransform) {
    2518         m = transform();
    2519         if (!d_ptr->pos.isNull())
    2520             m *= QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y());
    2521     } else if (!d_ptr->pos.isNull()) {
    2522         m = QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y());
    2523     }
    2524 
    2525     // Combine with parent and add to cache.
    2526     if (d_ptr->parent) {
    2527         m *= d_ptr->parent->sceneTransform();
    2528         // Don't cache toplevels
    2529         if (sd) {
    2530             if (index == -1) {
    2531                 if (!sd->freeSceneTransformSlots.isEmpty()) {
    2532                     index = sd->freeSceneTransformSlots.last();
    2533                     sd->freeSceneTransformSlots.pop_back();
    2534                 } else {
    2535                     index = sd->sceneTransformCache.size();
    2536                 }
    2537                 d_ptr->sceneTransformIndex = index;
    2538                 if (index >= sd->validTransforms.size()) {
    2539                     sd->validTransforms.resize(index + 1);
    2540                     sd->sceneTransformCache.resize(index + 1);
    2541                 }
    2542             }
    2543             sd->validTransforms.setBit(index, 1);
    2544             sd->sceneTransformCache[index] = m;
    2545         }
    2546     }
    2547     return m;
     3809    d_ptr->ensureSceneTransform();
     3810    return d_ptr->sceneTransform;
    25483811}
    25493812
     
    25733836QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) const
    25743837{
     3838
     3839
     3840
     3841
     3842
     3843
    25753844    // Find the topmost item that ignores view transformations.
    25763845    const QGraphicsItem *untransformedAncestor = this;
     
    25903859
    25913860    // First translate the base untransformable item.
    2592     QPointF mappedPoint = (untransformedAncestor->sceneTransform() * viewportTransform).map(QPointF(0, 0));
    2593     QTransform matrix;
    2594     matrix.translate(mappedPoint.x(), mappedPoint.y());
    2595     matrix = untransformedAncestor->transform() * matrix;
     3861    untransformedAncestor->d_ptr->ensureSceneTransform();
     3862    QPointF mappedPoint = (untransformedAncestor->d_ptr->sceneTransform * viewportTransform).map(QPointF(0, 0));
     3863
     3864    // COMBINE
     3865    QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y());
     3866    if (untransformedAncestor->d_ptr->transformData)
     3867        matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform(&matrix);
    25963868
    25973869    // Then transform and translate all children.
    25983870    for (int i = 0; i < parents.size(); ++i) {
    25993871        const QGraphicsItem *parent = parents.at(i);
    2600         QPointF pos = parent->pos();
    2601         QTransform moveMatrix;
    2602         moveMatrix.translate(pos.x(), pos.y());
    2603         matrix = (parent->transform() * moveMatrix) * matrix;
     3872        parent->d_ptr->combineTransformFromParent(&matrix);
    26043873    }
    26053874
     
    26443913        if (ok)
    26453914            *ok = true;
    2646         const QPointF &itemPos = d_ptr->pos;
    2647         if (itemPos.isNull())
    2648             return d_ptr->hasTransform ? transform() : QTransform();
    2649         if (d_ptr->hasTransform)
    2650             return transform() * QTransform::fromTranslate(itemPos.x(), itemPos.y());
    2651         return QTransform::fromTranslate(itemPos.x(), itemPos.y());
     3915        QTransform x;
     3916        d_ptr->combineTransformFromParent(&x);
     3917        return x;
    26523918    }
    26533919
     
    26553921    if (otherParent == this) {
    26563922        const QPointF &otherPos = other->d_ptr->pos;
    2657         if (other->d_ptr->hasTransform) {
    2658             QTransform otherToParent = other->transform();
    2659             if (!otherPos.isNull())
    2660                 otherToParent *= QTransform::fromTranslate(otherPos.x(), otherPos.y());
     3923        if (other->d_ptr->transformData) {
     3924            QTransform otherToParent;
     3925            other->d_ptr->combineTransformFromParent(&otherToParent);
    26613926            return otherToParent.inverted(ok);
    2662         } else {
    2663             if (ok)
    2664                 *ok = true;
    2665             return QTransform::fromTranslate(-otherPos.x(), -otherPos.y());
    26663927        }
     3928
     3929
     3930
    26673931    }
    26683932
    26693933    // Siblings
    26703934    if (parent == otherParent) {
    2671         bool hasTr = d_ptr->hasTransform;
    2672         bool otherHasTr = other->d_ptr->hasTransform;
     3935        // COMBINE
    26733936        const QPointF &itemPos = d_ptr->pos;
    26743937        const QPointF &otherPos = other->d_ptr->pos;
    2675 
    2676         if (!hasTr && !otherHasTr) {
     3938        if (!d_ptr->transformData && !other->d_ptr->transformData) {
    26773939            QPointF delta = itemPos - otherPos;
    26783940            if (ok)
     
    26813943        }
    26823944
    2683         QTransform itemToParent = QTransform::fromTranslate(itemPos.x(), itemPos.y());
    2684         if (hasTr)
    2685             itemToParent = itemPos.isNull() ? transform() : transform() * itemToParent;
    2686 
    2687         QTransform otherToParent = QTransform::fromTranslate(otherPos.x(), otherPos.y());
    2688         if (otherHasTr)
    2689             otherToParent = otherPos.isNull() ? other->transform() : other->transform() * otherToParent;
    2690 
     3945        QTransform itemToParent;
     3946        d_ptr->combineTransformFromParent(&itemToParent);
     3947        QTransform otherToParent;
     3948        other->d_ptr->combineTransformFromParent(&otherToParent);
    26913949        return itemToParent * otherToParent.inverted(ok);
    26923950    }
     
    26953953    // ancestor, then the only way is to combine their scene transforms.
    26963954    const QGraphicsItem *commonAncestor = commonAncestorItem(other);
    2697     if (!commonAncestor)
    2698         return sceneTransform() * other->sceneTransform().inverted(ok);
     3955    if (!commonAncestor) {
     3956        d_ptr->ensureSceneTransform();
     3957        other->d_ptr->ensureSceneTransform();
     3958        return d_ptr->sceneTransform * other->d_ptr->sceneTransform.inverted(ok);
     3959    }
    26993960
    27003961    // If the two items are cousins (in sibling branches), map both to the
     
    27033964    if (cousins) {
    27043965        bool good = false;
    2705         QTransform thisToScene;
    2706         QTransform otherToScene;
    2707         thisToScene = itemTransform(commonAncestor, &good);
     3966        QTransform thisToScene = itemTransform(commonAncestor, &good);
     3967        QTransform otherToScene(Qt::Uninitialized);
    27083968        if (good)
    27093969            otherToScene = other->itemTransform(commonAncestor, &good);
     
    27243984    const QGraphicsItem *p = child;
    27253985    do {
    2726         const QGraphicsItemPrivate *pd = p->d_ptr;
    2727         if (pd->hasTransform)
    2728             x *= p->transform();
    2729         if (!pd->pos.isNull())
    2730             x *= QTransform::fromTranslate(pd->pos.x(), pd->pos.y());
     3986        p->d_ptr.data()->combineTransformToParent(&x);
    27313987    } while ((p = p->d_ptr->parent) && p != root);
    27323988    if (parentOfOther)
     
    27464002    Use setTransform() instead.
    27474003
    2748     \sa transform(), rotate(), scale(), shear(), translate(), {The Graphics View Coordinate System}
     4004    \sa transform(), {The Graphics View Coordinate System}
    27494005*/
    27504006void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
    27514007{
    2752     QTransform oldTransform = this->transform();
    2753     QTransform newTransform;
    2754     if (!combine)
    2755         newTransform = QTransform(matrix);
    2756     else
    2757         newTransform = QTransform(matrix) * oldTransform;
    2758     if (oldTransform == newTransform)
     4008    if (!d_ptr->transformData)
     4009        d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
     4010
     4011    QTransform newTransform(combine ? QTransform(matrix) * d_ptr->transformData->transform : QTransform(matrix));
     4012    if (d_ptr->transformData->transform == newTransform)
    27594013        return;
    27604014
    2761     // Notify the item that the matrix is changing.
    2762     QVariant newTransformVariant(itemChange(ItemMatrixChange,
    2763                                             qVariantFromValue<QMatrix>(newTransform.toAffine())));
    2764     newTransform = QTransform(qVariantValue<QMatrix>(newTransformVariant));
    2765     if (oldTransform == newTransform)
     4015    // Update and set the new transformation.
     4016    if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
     4017        d_ptr->setTransformHelper(newTransform);
    27664018        return;
     4019
     4020
     4021
     4022
     4023
     4024
     4025
    27674026
    27684027    // Update and set the new transformation.
    2769     d_ptr->fullUpdateHelper(true, true);
    2770     prepareGeometryChange();
    2771     d_ptr->hasTransform = !newTransform.isIdentity();
    2772     d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform);
    2773     d_ptr->invalidateSceneTransformCache();
     4028    d_ptr->setTransformHelper(newTransform);
    27744029
    27754030    // Send post-notification.
    2776     // NB! We have to change the value from QMatrix to QTransform.
    2777     qVariantSetValue<QTransform>(newTransformVariant, newTransform);
    2778     itemChange(ItemTransformHasChanged, newTransformVariant);
     4031    itemChange(ItemTransformHasChanged, qVariantFromValue<QTransform>(newTransform));
    27794032}
    27804033
     
    27944047    from scene coordinates to item coordinates.
    27954048
    2796     \sa transform(), rotate(), scale(), shear(), translate(), {The Graphics View Coordinate System}
     4049    The transformation matrix is combined with the item's rotation(), scale()
     4050    and transformations() into a combined transformation that maps the item's
     4051    coordinate system to its parent.
     4052
     4053    \sa transform(), setRotation(), setScale(), setTransformOriginPoint(), {The Graphics View Coordinate System}, {Transformations}
    27974054*/
    27984055void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
    27994056{
    2800     QTransform oldTransform = this->transform();
    2801     QTransform newTransform;
    2802     if (!combine)
    2803         newTransform = matrix;
    2804     else
    2805         newTransform = matrix * oldTransform;
    2806     if (oldTransform == newTransform)
     4057    if (!d_ptr->transformData)
     4058        d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
     4059
     4060    QTransform newTransform(combine ? matrix * d_ptr->transformData->transform : matrix);
     4061    if (d_ptr->transformData->transform == newTransform)
    28074062        return;
     4063
     4064
     4065
     4066
     4067
     4068
    28084069
    28094070    // Notify the item that the transformation matrix is changing.
     
    28114072                                                  qVariantFromValue<QTransform>(newTransform)));
    28124073    newTransform = qVariantValue<QTransform>(newTransformVariant);
    2813     if (oldTransform == newTransform)
     4074    if (ransform == newTransform)
    28144075        return;
    28154076
    28164077    // Update and set the new transformation.
    2817     d_ptr->fullUpdateHelper(true, true);
    2818     prepareGeometryChange();
    2819     d_ptr->hasTransform = !newTransform.isIdentity();
    2820     d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform);
    2821     d_ptr->invalidateSceneTransformCache();
     4078    d_ptr->setTransformHelper(newTransform);
    28224079
    28234080    // Send post-notification.
    28244081    itemChange(ItemTransformHasChanged, newTransformVariant);
     4082
    28254083}
    28264084
     
    28384096    \since 4.3
    28394097
    2840     Resets this item's transformation matrix to the identity matrix. This is
    2841     equivalent to calling \c setTransform(QTransform()).
     4098    Resets this item's transformation matrix to the identity matrix or
     4099    all the transformation properties to their default values.
     4100    This is equivalent to calling \c setTransform(QTransform()).
    28424101
    28434102    \sa setTransform(), transform()
     
    28494108
    28504109/*!
     4110
     4111
     4112
     4113
     4114
     4115
     4116
     4117
     4118
     4119
    28514120    Rotates the current item transformation \a angle degrees clockwise around
    28524121    its origin. To translate around an arbitrary point (x, y), you need to
     
    28654134
    28664135/*!
     4136
     4137
     4138
     4139
     4140
     4141
     4142
     4143
     4144
     4145
    28674146    Scales the current item transformation by (\a sx, \a sy) around its
    28684147    origin. To scale from an arbitrary point (x, y), you need to combine
     
    28734152    \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 7
    28744153
    2875     \sa setTransform(), transform(), rotate(), shear(), translate()
     4154    \sa setTransform(), transform()
    28764155*/
    28774156void QGraphicsItem::scale(qreal sx, qreal sy)
     
    28814160
    28824161/*!
     4162
     4163
     4164
     4165
     4166
     4167
     4168
     4169
     4170
     4171
    28834172    Shears the current item transformation by (\a sh, \a sv).
    28844173
    2885     \sa setTransform(), transform(), rotate(), scale(), translate()
     4174    \sa setTransform(), transform()
    28864175*/
    28874176void QGraphicsItem::shear(qreal sh, qreal sv)
     
    28914180
    28924181/*!
     4182
     4183
     4184
     4185
     4186
     4187
     4188
     4189
     4190
    28934191    Translates the current item transformation by (\a dx, \a dy).
    28944192
     
    28974195    which is conceptually separate from its position.
    28984196
    2899     \sa setTransform(), transform(), rotate(), scale(), shear()
     4197    \sa setTransform(), transform()
    29004198*/
    29014199void QGraphicsItem::translate(qreal dx, qreal dy)
     
    29274225
    29284226/*!
    2929     Returns the Z-value, or the elevation, of the item. The Z-value decides
    2930     the stacking order of sibling (neighboring) items.
     4227    Returns the Z-value
     4228    sibling (neighboring) items.
    29314229
    29324230    The default Z-value is 0.
    29334231
    2934     \sa setZValue()
     4232    \sa setZValue()
    29354233*/
    29364234qreal QGraphicsItem::zValue() const
     
    29404238
    29414239/*!
    2942     Sets the Z-value, or the elevation, of the item, to \a z. The elevation
    2943     decides the stacking order of sibling (neighboring) items. An item of high
    2944     Z-value will be drawn on top of an item with a lower Z-value if they
    2945     share the same parent item. In addition, children of an item will always be drawn
    2946     on top of the parent, regardless of the child's Z-value. Sibling items
    2947     that share the same Z-value will be drawn in an undefined order, although
    2948     the order will stay the same for as long as the items live.
    2949 
    2950     \img graphicsview-zorder.png
    2951 
    2952     Children of different parents are stacked according to the Z-value of
    2953     each item's ancestor item which is an immediate child of the two
    2954     items' closest common ancestor. For example, a robot item might
    2955     define a torso item as the parent of a head item, two arm items,
    2956     and two upper-leg items. The upper-leg items would each be parents
    2957     of one lower-leg item, and each lower-leg item would be parents of
    2958     one foot item.  The stacking order of the feet is the same as the
    2959     stacking order of each foot's ancestor that is an immediate child
    2960     of the two feet's common ancestor (i.e., the torso item); so the
    2961     feet are stacked in the same order as the upper-leg items,
    2962     regardless of each foot's Z-value.
     4240    Sets the Z-value of the item to \a z. The Z value decides the stacking
     4241    order of sibling (neighboring) items. A sibling item of high Z value will
     4242    always be drawn on top of another sibling item with a lower Z value.
     4243
     4244    If you restore the Z value, the item's insertion order will decide its
     4245    stacking order.
    29634246
    29644247    The Z-value does not affect the item's size in any way.
     
    29664249    The default Z-value is 0.
    29674250
    2968     \sa zValue()
     4251    \sa zValue()
    29694252*/
    29704253void QGraphicsItem::setZValue(qreal z)
    29714254{
    2972     const QVariant newZVariant(itemChange(ItemZValueChange, double(z)));
    2973     qreal newZ = qreal(newZVariant.toDouble());
     4255    const QVariant newZVariant(itemChange(ItemZValueChange, ));
     4256    qreal newZ = );
    29744257    if (newZ == d_ptr->z)
    29754258        return;
    2976     d_ptr->z = z;
    2977     d_ptr->fullUpdateHelper();
    29784259
    29794260    if (d_ptr->scene) {
    2980         // Invalidate any sort caching; arrival of a new item means we need to
    2981         // resort.
    2982         d_ptr->scene->d_func()->invalidateSortCache();
    2983     }
     4261        // Z Value has changed, we have to notify the index.
     4262        d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant);
     4263    }
     4264
     4265    d_ptr->z = newZ;
     4266    if (d_ptr->parent)
     4267        d_ptr->parent->d_ptr->needSortChildren = 1;
     4268    else if (d_ptr->scene)
     4269        d_ptr->scene->d_func()->needSortTopLevelItems = 1;
     4270
     4271    if (d_ptr->scene)
     4272        d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
    29844273
    29854274    itemChange(ItemZValueHasChanged, newZVariant);
     4275
     4276
     4277
     4278
     4279
     4280
     4281
     4282
     4283
     4284
     4285
     4286
     4287
     4288
     4289
     4290
     4291
     4292
     4293
     4294
     4295
     4296
     4297
     4298
     4299
     4300
     4301
     4302
     4303
     4304
     4305
     4306
     4307
     4308
     4309
     4310
     4311
     4312
     4313
     4314
     4315
     4316
     4317
     4318
     4319
     4320
     4321
     4322
     4323
     4324
     4325
     4326
     4327
     4328
     4329
     4330
     4331
     4332
     4333
     4334
     4335
     4336
     4337
     4338
     4339
     4340
     4341
     4342
     4343
     4344
     4345
     4346
     4347
     4348
     4349
     4350
     4351
     4352
     4353
     4354
     4355
     4356
     4357
     4358
     4359
     4360
     4361
     4362
     4363
     4364
     4365
     4366
     4367
     4368
     4369
     4370
     4371
     4372
     4373
     4374
     4375
     4376
     4377
     4378
     4379
     4380
     4381
    29864382}
    29874383
     
    30054401QRectF QGraphicsItem::childrenBoundingRect() const
    30064402{
    3007     QRectF childRect;
    3008     foreach (QGraphicsItem *child, children()) {
    3009         QPointF childPos = child->pos();
    3010         QTransform matrix = child->transform();
    3011         if (!childPos.isNull())
    3012             matrix *= QTransform::fromTranslate(childPos.x(), childPos.y());
    3013         childRect |= matrix.mapRect(child->boundingRect() | child->childrenBoundingRect());
    3014     }
    3015     return childRect;
     4403    if (!d_ptr->dirtyChildrenBoundingRect)
     4404        return d_ptr->childrenBoundingRect;
     4405
     4406    d_ptr->childrenBoundingRect = QRectF();
     4407    d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect);
     4408    d_ptr->dirtyChildrenBoundingRect = 0;
     4409    return d_ptr->childrenBoundingRect;
    30164410}
    30174411
     
    30264420    Although the item's shape can be arbitrary, the bounding rect is
    30274421    always rectangular, and it is unaffected by the items'
    3028     transformation (scale(), rotate(), etc.).
     4422    transformation.
    30294423
    30304424    If you want to change the item's bounding rectangle, you must first call
     
    30584452{
    30594453    // Find translate-only offset
     4454
    30604455    QPointF offset;
    30614456    const QGraphicsItem *parentItem = this;
    30624457    const QGraphicsItemPrivate *itemd;
    30634458    do {
    3064         itemd = parentItem->d_ptr;
    3065         if (itemd->hasTransform)
     4459        itemd = parentItem->d_ptr;
     4460        if (itemd->)
    30664461            break;
    30674462        offset += itemd->pos;
     
    30704465    QRectF br = boundingRect();
    30714466    br.translate(offset);
    3072     return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
     4467    if (!parentItem)
     4468        return br;
     4469    if (parentItem->d_ptr->hasTranslateOnlySceneTransform()) {
     4470        br.translate(parentItem->d_ptr->sceneTransform.dx(), parentItem->d_ptr->sceneTransform.dy());
     4471        return br;
     4472    }
     4473    return parentItem->d_ptr->sceneTransform.mapRect(br);
    30734474}
    30744475
     
    31424543{
    31434544    Q_D(const QGraphicsItem);
    3144     if (!d->dirtyClipPath)
    3145         return d->emptyClipPath ? QPainterPath() : d->cachedClipPath;
    3146 
    3147     if (!isClipped()) {
    3148         d_ptr->setCachedClipPath(QPainterPath());
    3149         return d->cachedClipPath;
    3150     }
     4545    if (!isClipped())
     4546        return QPainterPath();
    31514547
    31524548    const QRectF thisBoundingRect(boundingRect());
    3153     if (thisBoundingRect.isEmpty()) {
    3154         if (d_ptr->flags & ItemClipsChildrenToShape)
    3155             d_ptr->setEmptyCachedClipPathRecursively();
    3156         else
    3157             d_ptr->setEmptyCachedClipPath();
     4549    if (thisBoundingRect.isEmpty())
    31584550        return QPainterPath();
    3159     }
    31604551
    31614552    QPainterPath clip;
     
    31684559
    31694560        // Intersect any in-between clips starting at the top and moving downwards.
    3170         bool foundValidClipPath = false;
    31714561        while ((parent = parent->d_ptr->parent)) {
    31724562            if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
    31734563                // Map clip to the current parent and intersect with its shape/clipPath
    31744564                clip = lastParent->itemTransform(parent).map(clip);
    3175                 if ((foundValidClipPath = !parent->d_ptr->dirtyClipPath && parent->isClipped())) {
    3176                     if (parent->d_ptr->emptyClipPath) {
    3177                         if (d_ptr->flags & ItemClipsChildrenToShape)
    3178                             d_ptr->setEmptyCachedClipPathRecursively();
    3179                         else
    3180                             d_ptr->setEmptyCachedClipPath();
    3181                         return QPainterPath();
    3182                     }
    3183                     clip = clip.intersected(parent->d_ptr->cachedClipPath);
    3184                     if (!(parent->d_ptr->flags & ItemClipsToShape))
    3185                         clip = clip.intersected(parent->shape());
    3186                 } else {
    3187                     clip = clip.intersected(parent->shape());
    3188                 }
    3189 
    3190                 if (clip.isEmpty()) {
    3191                     if (d_ptr->flags & ItemClipsChildrenToShape)
    3192                         d_ptr->setEmptyCachedClipPathRecursively();
    3193                     else
    3194                         d_ptr->setEmptyCachedClipPath();
     4565                clip = clip.intersected(parent->shape());
     4566                if (clip.isEmpty())
    31954567                    return clip;
    3196                 }
    31974568                lastParent = parent;
    31984569            }
    31994570
    3200             if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
    3201                 || foundValidClipPath) {
     4571            if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
    32024572                break;
    3203             }
    32044573        }
    32054574
     
    32144583        clip = clip.intersected(shape());
    32154584
    3216     d_ptr->setCachedClipPath(clip);
    32174585    return clip;
    32184586}
     
    32364604
    32374605/*!
    3238     Returns true if this item collides with \a other; otherwise returns false.
    3239     The ways items collide is determined by \a mode. The default value for \a
    3240     mode is Qt::IntersectsItemShape; \a other collides with this item if it
    3241     either intersects, contains, or is contained by this item's shape.
     4606
     4607    Returns true if this item collides with \a other; otherwise
     4608    returns false.
     4609
     4610    The \a mode is applied to \a other, and the resulting shape or
     4611    bounding rectangle is then compared to this item's shape. The
     4612    default value for \a mode is Qt::IntersectsItemShape; \a other
     4613    collides with this item if it either intersects, contains, or is
     4614    contained by this item's shape (see Qt::ItemSelectionMode for
     4615    details).
    32424616
    32434617    The default implementation is based on shape intersection, and it calls
     
    32944668    intersects, contains, or is contained by this item's shape.
    32954669
     4670
     4671
     4672
     4673
     4674
    32964675    \sa collidesWithItem(), contains(), shape()
    32974676*/
     
    33344713    Returns a list of all items that collide with this item.
    33354714
    3336     The way collisions are detected is determined by \a mode. The default
    3337     value for \a mode is Qt::IntersectsItemShape; All items whose shape
    3338     intersects or is contained by this item's shape are returned.
    3339 
    3340     \sa QGraphicsScene::collidingItems(), collidesWithItem()
     4715    The way collisions are detected is determined by applying \a mode
     4716    to items that are compared to this item, i.e., each item's shape
     4717    or bounding rectangle is checked against this item's shape. The
     4718    default value for \a mode is Qt::IntersectsItemShape.
     4719
     4720    \sa collidesWithItem()
    33414721*/
    33424722QList<QGraphicsItem *> QGraphicsItem::collidingItems(Qt::ItemSelectionMode mode) const
     
    34334813    if (!item)
    34344814        return false;
    3435     return QGraphicsScenePrivate::closestItemFirst_withoutCache(item, this)
     4815    return (item, this)
    34364816        && qt_QGraphicsItem_isObscured(this, item, boundingRect());
    34374817}
     
    35184898
    35194899    // Transform QRegion back to device space
    3520     QTransform unscale;
    3521     unscale.scale(1 / granularity, 1 / granularity);
     4900    QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity);
    35224901    QRegion r;
    35234902    QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0));
     
    36154994    All painting is done in local coordinates.
    36164995
    3617     \sa setCacheMode(), QPen::width(), {Item Coordinates}
     4996    \sa setCacheMode(), QPen::width(), {Item Coordinates}
    36184997*/
    36194998
     
    36225001    Returns true if we can discard an update request; otherwise false.
    36235002*/
    3624 bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping,
    3625                                                 bool ignoreVisibleBit,
    3626                                                 bool ignoreDirtyBit) const
     5003bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreVisibleBit, bool ignoreDirtyBit,
     5004                                                bool ignoreOpacity) const
    36275005{
    36285006    // No scene, or if the scene is updating everything, means we have nothing
    36295007    // to do. The only exception is if the scene tracks the growing scene rect.
    3630     return (!visible && !ignoreVisibleBit)
    3631            || (dirty && !ignoreDirtyBit)
    3632            || !scene
    3633            || (scene->d_func()->updateAll && scene->d_func()->hasSceneRect)
    3634            || (!ignoreClipping && (childrenClippedToShape() && isClippedAway()))
    3635            || (childrenCombineOpacity() && isFullyTransparent());
     5008    return !scene
     5009           || (!visible && !ignoreVisibleBit && !this->ignoreVisible)
     5010           || (!ignoreDirtyBit && fullUpdatePending)
     5011           || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent());
    36365012}
    36375013
    36385014/*!
    36395015    \internal
    3640 
    3641     Asks the scene to mark this item's scene rect as dirty, requesting a
    3642     redraw.  This does not invalidate any cache.
    3643 
    3644     The \a force argument is for the update call in setVisible(), which is the
    3645     only case where the item's background should be marked as dirty even when
    3646     the item isn't visible.
    3647 */
    3648 void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool maybeDirtyClipPath)
    3649 {
    3650     // No scene, or if the scene is updating everything, means we have nothing
    3651     // to do. The only exception is if the scene tracks the growing scene rect.
    3652     if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, /*ignoreVisibleBit=*/force))
     5016*/
     5017int QGraphicsItemPrivate::depth() const
     5018{
     5019    if (itemDepth == -1)
     5020        const_cast<QGraphicsItemPrivate *>(this)->resolveDepth();
     5021
     5022    return itemDepth;
     5023}
     5024
     5025/*!
     5026    \internal
     5027*/
     5028#ifndef QT_NO_GRAPHICSEFFECT
     5029void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively()
     5030{
     5031    QGraphicsItemPrivate *itemPrivate = this;
     5032    do {
     5033        if (itemPrivate->graphicsEffect) {
     5034            itemPrivate->notifyInvalidated = 1;
     5035
     5036            if (!itemPrivate->updateDueToGraphicsEffect)
     5037                static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
     5038        }
     5039    } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
     5040}
     5041#endif //QT_NO_GRAPHICSEFFECT
     5042
     5043/*!
     5044    \internal
     5045*/
     5046void QGraphicsItemPrivate::invalidateDepthRecursively()
     5047{
     5048    if (itemDepth == -1)
    36535049        return;
    36545050
    3655     if (rect.isNull())
    3656         dirty = 1;
    3657     scene->itemUpdated(q_ptr, rect);
     5051    i
     5052   
     5053    );
    36585054}
    36595055
     
    36615057    \internal
    36625058
    3663     Propagates updates to \a item and all its children.
    3664 */
    3665 void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyClipPath)
    3666 {
    3667     if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath,
    3668                              /*ignoreVisibleBit=*/false,
    3669                              /*ignoreDirtyBit=*/true)) {
    3670         return;
    3671     }
    3672 
    3673     if (!childrenOnly && !dirty) {
    3674         // Effectively the same as updateHelper(QRectF(), false, maybeDirtyClipPath).
    3675         dirty = 1;
    3676         scene->itemUpdated(q_ptr, QRectF());
    3677     }
    3678 
    3679     if (dirtyChildren || childrenClippedToShape()) {
    3680         // Unnecessary to update children as well.
    3681         return;
    3682     }
    3683 
    3684     if (ancestorFlags & AncestorClipsChildren) {
    3685         Q_Q(QGraphicsItem);
    3686         // Check if we can avoid updating all children.
    3687         QGraphicsItem *p = parent;
    3688         QRectF br = q->boundingRect();
    3689         while (p) {
    3690             if (p->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) {
    3691                 bool ok;
    3692                 QTransform x = q->itemTransform(p, &ok);
    3693                 if (!ok)
    3694                     break;
    3695                 if (x.mapRect(br).contains(p->boundingRect()))
    3696                     return;
    3697             }
    3698             p = p->d_ptr->parent;
    3699             if (!p || !(p->d_ptr->ancestorFlags & AncestorClipsChildren))
    3700                 break;
    3701             // ### check one level only
    3702             break;
    3703         }
    3704     }
    3705     foreach (QGraphicsItem *child, children)
    3706         child->d_ptr->fullUpdateHelper(false, maybeDirtyClipPath);
    3707     dirtyChildren = 1;
    3708 }
    3709 
    3710 static inline bool qt_allChildrenCombineOpacity(QGraphicsItem *parent)
    3711 {
    3712     Q_ASSERT(parent);
    3713     if (parent->flags() & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
    3714         return false;
    3715 
    3716     const QList<QGraphicsItem *> children(parent->childItems());
    3717     for (int i = 0; i < children.size(); ++i) {
    3718         if (children.at(i)->flags() & QGraphicsItem::ItemIgnoresParentOpacity)
    3719             return false;
    3720     }
    3721     return true;
    3722 }
    3723 
    3724 void QGraphicsItemPrivate::updateEffectiveOpacity()
    3725 {
    3726     Q_Q(QGraphicsItem);
    3727     if (parent) {
    3728         resolveEffectiveOpacity(parent->effectiveOpacity());
    3729         parent->d_ptr->allChildrenCombineOpacity = qt_allChildrenCombineOpacity(parent);
    3730     } else {
    3731         resolveEffectiveOpacity(1.0);
    3732     }
    3733     allChildrenCombineOpacity = qt_allChildrenCombineOpacity(q);
     5059    Resolves the stacking depth of this object and all its ancestors.
     5060*/
     5061void QGraphicsItemPrivate::resolveDepth()
     5062{
     5063    if (!parent)
     5064        itemDepth = 0;
     5065    else {
     5066        if (parent->d_ptr->itemDepth == -1)
     5067            parent->d_ptr->resolveDepth();
     5068        itemDepth = parent->d_ptr->itemDepth + 1;
     5069    }
    37345070}
    37355071
     
    37375073    \internal
    37385074
    3739     Resolves and propagates this item's effective opacity to its children.
    3740 */
    3741 void QGraphicsItemPrivate::resolveEffectiveOpacity(qreal parentEffectiveOpacity)
    3742 {
    3743     Q_Q(QGraphicsItem);
    3744     QGraphicsItem::GraphicsItemFlags myFlags = q->flags();
    3745     QGraphicsItem::GraphicsItemFlags parentFlags = parent ? parent->flags() : QGraphicsItem::GraphicsItemFlags(0);
    3746 
    3747     // My local opacity is always part of my effective opacity.
    3748     qreal myEffectiveOpacity = q->opacity();
    3749 
    3750     // If I have a parent, and I don't ignore my parent's opacity, and my
    3751     // parent propagates to me, then combine my local opacity with my parent's
    3752     // effective opacity into my effective opacity.
    3753     if (parent
    3754         && !(myFlags & QGraphicsItem::ItemIgnoresParentOpacity)
    3755         && !(parentFlags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
    3756         myEffectiveOpacity *= parentEffectiveOpacity;
    3757     }
    3758 
    3759     // Set this item's resolved opacity.
    3760     if (qFuzzyCompare(myEffectiveOpacity, qreal(1.0))) {
    3761         // Opaque, unset effective opacity.
    3762         hasEffectiveOpacity = 0;
    3763         unsetExtra(ExtraEffectiveOpacity);
    3764     } else {
    3765         hasEffectiveOpacity = 1;
    3766         setExtra(ExtraEffectiveOpacity, myEffectiveOpacity);
    3767     }
    3768 
    3769     // Resolve children always.
    3770     for (int i = 0; i < children.size(); ++i)
    3771         children.at(i)->d_ptr->resolveEffectiveOpacity(myEffectiveOpacity);
     5075    ### This function is almost identical to
     5076    QGraphicsScenePrivate::registerTopLevelItem().
     5077*/
     5078void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
     5079{
     5080    // Remove all holes from the sibling index list. Now the max index
     5081    // number is equal to the size of the children list.
     5082    ensureSequentialSiblingIndex();
     5083    needSortChildren = 1; // ### maybe 0
     5084    child->d_ptr->siblingIndex = children.size();
     5085    children.append(child);
    37725086}
    37735087
     
    37755089    \internal
    37765090
    3777     Resolves the stacking depth of this object and all its children.
    3778 */
    3779 void QGraphicsItemPrivate::resolveDepth(int parentDepth)
    3780 {
    3781     depth = parentDepth + 1;
    3782     for (int i = 0; i < children.size(); ++i)
    3783         children.at(i)->d_ptr->resolveDepth(depth);
     5091    ### This function is almost identical to
     5092    QGraphicsScenePrivate::unregisterTopLevelItem().
     5093*/
     5094void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
     5095{
     5096    // When removing elements in the middle of the children list,
     5097    // there will be a "gap" in the list of sibling indexes (0,1,3,4).
     5098    if (!holesInSiblingIndex)
     5099        holesInSiblingIndex = child->d_ptr->siblingIndex != children.size() - 1;
     5100    if (sequentialOrdering && !holesInSiblingIndex)
     5101        children.removeAt(child->d_ptr->siblingIndex);
     5102    else
     5103        children.removeOne(child);
     5104    // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
     5105    // the child is not guaranteed to be at the index after the list is sorted.
     5106    // (see ensureSortedChildren()).
     5107    child->d_ptr->siblingIndex = -1;
    37845108}
    37855109
     
    37875111    \internal
    37885112*/
    3789 void QGraphicsItemPrivate::invalidateSceneTransformCache()
    3790 {
    3791     if (!scene || (parent && sceneTransformIndex == -1))
    3792         return;
    3793     if (sceneTransformIndex != -1)
    3794         scene->d_func()->validTransforms.setBit(sceneTransformIndex, 0);
    3795     for (int i = 0; i < children.size(); ++i)
    3796         children.at(i)->d_ptr->invalidateSceneTransformCache();
    3797 }
    3798 
     5113QGraphicsItemCache *QGraphicsItemPrivate::maybeExtraItemCache() const
     5114{
     5115    return (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
     5116}
     5117
     5118/*!
     5119    \internal
     5120*/
    37995121QGraphicsItemCache *QGraphicsItemPrivate::extraItemCache() const
    38005122{
     
    38085130}
    38095131
     5132
     5133
     5134
    38105135void QGraphicsItemPrivate::removeExtraItemCache()
    38115136{
     
    38185143}
    38195144
    3820 void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect)
    3821 {
    3822     setEmptyCachedClipPath();
    3823 
    3824     const bool checkRect = !emptyIfOutsideThisRect.isNull()
    3825                            && !(flags & QGraphicsItem::ItemClipsChildrenToShape);
    3826     for (int i = 0; i < children.size(); ++i) {
    3827         if (!checkRect) {
    3828             children.at(i)->d_ptr->setEmptyCachedClipPathRecursively();
    3829             continue;
     5145// Traverses all the ancestors up to the top-level and updates the pointer to
     5146// always point to the top-most item that has a dirty scene transform.
     5147// It then backtracks to the top-most dirty item and start calculating the
     5148// scene transform by combining the item's transform (+pos) with the parent's
     5149// cached scene transform (which we at this point know for sure is valid).
     5150void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem)
     5151{
     5152    Q_ASSERT(topMostDirtyItem);
     5153
     5154    if (dirtySceneTransform)
     5155        *topMostDirtyItem = q_ptr;
     5156
     5157    if (parent)
     5158        parent->d_ptr->ensureSceneTransformRecursive(topMostDirtyItem);
     5159
     5160    if (*topMostDirtyItem == q_ptr) {
     5161        if (!dirtySceneTransform)
     5162            return; // OK, neither my ancestors nor I have dirty scene transforms.
     5163        *topMostDirtyItem = 0;
     5164    } else if (*topMostDirtyItem) {
     5165        return; // Continue backtrack.
     5166    }
     5167
     5168    // This item and all its descendants have dirty scene transforms.
     5169    // We're about to validate this item's scene transform, so we have to
     5170    // invalidate all the children; otherwise there's no way for the descendants
     5171    // to detect that the ancestor has changed.
     5172    invalidateChildrenSceneTransform();
     5173
     5174    // COMBINE my transform with the parent's scene transform.
     5175    updateSceneTransformFromParent();
     5176    Q_ASSERT(!dirtySceneTransform);
     5177}
     5178
     5179/*!
     5180    \internal
     5181*/
     5182void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem)
     5183{
     5184    // Update focus child chain. Stop at panels, or if this item
     5185    // is hidden, stop at the first item with a visible parent.
     5186    QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
     5187    do {
     5188        // Clear any existing ancestor's subFocusItem.
     5189        if (parent != q_ptr && parent->d_ptr->subFocusItem) {
     5190            if (parent->d_ptr->subFocusItem == q_ptr)
     5191                break;
     5192            parent->d_ptr->subFocusItem->d_ptr->clearSubFocus();
    38305193        }
    3831 
    3832         QGraphicsItem *child = children.at(i);
    3833         const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect);
    3834         if (rect.intersects(child->boundingRect()))
    3835             child->d_ptr->invalidateCachedClipPathRecursively(false, rect);
    3836         else
    3837             child->d_ptr->setEmptyCachedClipPathRecursively(rect);
    3838     }
    3839 }
    3840 
    3841 void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly, const QRectF &emptyIfOutsideThisRect)
    3842 {
    3843     if (!childrenOnly)
    3844         invalidateCachedClipPath();
    3845 
    3846     const bool checkRect = !emptyIfOutsideThisRect.isNull();
    3847     for (int i = 0; i < children.size(); ++i) {
    3848         if (!checkRect) {
    3849             children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false);
    3850             continue;
    3851         }
    3852 
    3853         QGraphicsItem *child = children.at(i);
    3854         const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect);
    3855         if (rect.intersects(child->boundingRect()))
    3856             child->d_ptr->invalidateCachedClipPathRecursively(false, rect);
    3857         else
    3858             child->d_ptr->setEmptyCachedClipPathRecursively(rect);
    3859     }
    3860 }
    3861 
    3862 void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &newPos)
    3863 {
    3864     Q_ASSERT(inSetPosHelper);
    3865 
    3866     if (!(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
    3867         return; // Not clipped by any ancestor.
    3868 
    3869     // Find closest clip ancestor and transform.
    3870     Q_Q(QGraphicsItem);
    3871     QTransform thisToParentTransform = hasTransform
    3872                                        ? q->transform() * QTransform::fromTranslate(newPos.x(), newPos.y())
    3873                                        : QTransform::fromTranslate(newPos.x(), newPos.y());
    3874     QGraphicsItem *clipParent = parent;
    3875     while (clipParent && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) {
    3876         if (clipParent->d_ptr->hasTransform)
    3877             thisToParentTransform *= clipParent->transform();
    3878         if (!clipParent->d_ptr->pos.isNull()) {
    3879             thisToParentTransform *= QTransform::fromTranslate(clipParent->d_ptr->pos.x(),
    3880                                                                clipParent->d_ptr->pos.y());
    3881         }
    3882         clipParent = clipParent->d_ptr->parent;
    3883     }
    3884 
    3885     // thisToParentTransform is now the same as q->itemTransform(clipParent), except
    3886     // that the new position (which is not yet set on the item) is taken into account.
    3887     Q_ASSERT(clipParent);
    3888     Q_ASSERT(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
    3889 
    3890     // From here everything is calculated in clip parent's coordinates.
    3891     const QRectF parentBoundingRect(clipParent->boundingRect());
    3892     const QRectF thisBoundingRect(thisToParentTransform.mapRect(q->boundingRect()));
    3893 
    3894     if (!parentBoundingRect.intersects(thisBoundingRect)) {
    3895         // Item is moved outside the clip parent's bounding rect,
    3896         // i.e. it is fully clipped and the clip path is empty.
    3897         if (flags & QGraphicsItem::ItemClipsChildrenToShape)
    3898             setEmptyCachedClipPathRecursively();
    3899         else
    3900             setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentBoundingRect));
    3901         return;
    3902     }
    3903 
    3904     const QPainterPath parentClip(clipParent->isClipped() ? clipParent->clipPath() : clipParent->shape());
    3905     if (parentClip.contains(thisBoundingRect))
    3906         return; // Item is inside the clip parent's shape. No update required.
    3907 
    3908     const QRectF parentClipRect(parentClip.controlPointRect());
    3909     if (!parentClipRect.intersects(thisBoundingRect)) {
    3910         // Item is moved outside the clip parent's shape,
    3911         // i.e. it is fully clipped and the clip path is empty.
    3912         if (flags & QGraphicsItem::ItemClipsChildrenToShape)
    3913             setEmptyCachedClipPathRecursively();
    3914         else
    3915             setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentClipRect));
    3916     } else {
    3917         // Item is partially inside the clip parent's shape,
    3918         // i.e. the cached clip path must be invalidated.
    3919         invalidateCachedClipPathRecursively(false, thisToParentTransform.inverted().mapRect(parentClipRect));
    3920     }
     5194        parent->d_ptr->subFocusItem = q_ptr;
     5195        parent->d_ptr->subFocusItemChange();
     5196    } while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
     5197
     5198    if (scene && !scene->isActive())
     5199        scene->d_func()->lastFocusItem = subFocusItem;
     5200}
     5201
     5202/*!
     5203    \internal
     5204*/
     5205void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem)
     5206{
     5207    // Reset sub focus chain.
     5208    QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
     5209    do {
     5210        if (parent->d_ptr->subFocusItem != q_ptr)
     5211            break;
     5212        parent->d_ptr->subFocusItem = 0;
     5213        parent->d_ptr->subFocusItemChange();
     5214    } while (!parent->isPanel() && (parent = parent->d_ptr->parent));
     5215}
     5216
     5217/*!
     5218    \internal
     5219
     5220    Sets the focusProxy pointer to 0 for all items that have this item as their
     5221    focusProxy. ### Qt 5: Use QPointer instead.
     5222*/
     5223void QGraphicsItemPrivate::resetFocusProxy()
     5224{
     5225    for (int i = 0; i < focusProxyRefs.size(); ++i)
     5226        *focusProxyRefs.at(i) = 0;
     5227    focusProxyRefs.clear();
     5228}
     5229
     5230/*!
     5231    \internal
     5232
     5233    Subclasses can reimplement this function to be notified when subFocusItem
     5234    changes.
     5235*/
     5236void QGraphicsItemPrivate::subFocusItemChange()
     5237{
     5238}
     5239
     5240/*!
     5241    \internal
     5242
     5243    Subclasses can reimplement this function to be notified when its
     5244    siblingIndex order is changed.
     5245*/
     5246void QGraphicsItemPrivate::siblingOrderChange()
     5247{
    39215248}
    39225249
     
    39545281        return;
    39555282
     5283
     5284
     5285
     5286
     5287
    39565288    if (CacheMode(d_ptr->cacheMode) != NoCache) {
     5289
    39575290        QGraphicsItemCache *cache = d_ptr->extraItemCache();
    3958         if (d_ptr->discardUpdateRequest(/* ignoreVisibleBit = */ false,
    3959                                         /* ignoreClipping = */ false,
    3960                                         /* ignoreDirtyBit = */ true)) {
    3961             return;
    3962         }
    3963 
    3964         // Invalidate cache.
    3965         if (rect.isNull()) {
    3966             cache->allExposed = true;
    3967             cache->exposed.clear();
    3968         } else {
    3969             cache->exposed.append(rect);
     5291        if (!cache->allExposed) {
     5292            if (rect.isNull()) {
     5293                cache->allExposed = true;
     5294                cache->exposed.clear();
     5295            } else {
     5296                cache->exposed.append(rect);
     5297            }
    39705298        }
    39715299        // Only invalidate cache; item is already dirty.
    3972         if (d_ptr->dirty)
     5300        if (d_ptr->)
    39735301            return;
    3974     } else if (d_ptr->discardUpdateRequest()) {
     5302    }
     5303
     5304    if (d_ptr->discardUpdateRequest())
    39755305        return;
    3976     }
    3977 
    3978     // Effectively the same as updateHelper(rect);
    3979     if (rect.isNull())
    3980         d_ptr->dirty = 1;
    3981     d_ptr->scene->itemUpdated(this, rect);
    3982 }
    3983 
     5306
     5307    if (d_ptr->scene)
     5308        d_ptr->scene->d_func()->markDirty(this, rect);
     5309}
    39845310
    39855311/*!
     
    40105336        return;
    40115337    if (d->cacheMode != NoCache) {
    4012         // ### This is very slow, and can be done much better. If the cache is
    4013         // local and matches the below criteria for rotation and scaling, we
    4014         // can easily scroll. And if the cache is in device coordinates, we
    4015         // can scroll both the viewport and the cache.
    4016         update(rect);
     5338        QGraphicsItemCache *c;
     5339        bool scrollCache = qFuzzyIsNull(dx - int(dx)) && qFuzzyIsNull(dy - int(dy))
     5340                           && (c = (QGraphicsItemCache *)qVariantValue<void *>(d_ptr->extra(QGraphicsItemPrivate::ExtraCacheData)))
     5341                           && (d->cacheMode == ItemCoordinateCache && !c->fixedSize.isValid());
     5342        if (scrollCache) {
     5343            QPixmap pix;
     5344            if (QPixmapCache::find(c->key, &pix)) {
     5345                // Adjust with 2 pixel margin. Notice the loss of precision
     5346                // when converting to QRect.
     5347                int adjust = 2;
     5348                QRectF br = boundingRect().adjusted(-adjust, -adjust, adjust, adjust);
     5349                QRect irect = rect.toRect().translated(-br.x(), -br.y());
     5350
     5351                pix.scroll(dx, dy, irect);
     5352
     5353                QPixmapCache::replace(c->key, pix);
     5354
     5355                // Translate the existing expose.
     5356                foreach (QRectF exposedRect, c->exposed)
     5357                    c->exposed += exposedRect.translated(dx, dy) & rect;
     5358
     5359                // Calculate exposure.
     5360                QRegion exposed;
     5361                QRect r = rect.toRect();
     5362                exposed += r;
     5363                exposed -= r.translated(dx, dy);
     5364                foreach (QRect rect, exposed.rects())
     5365                    update(rect);
     5366                d->scene->d_func()->markDirty(this);
     5367            } else {
     5368                update(rect);
     5369            }
     5370        } else {
     5371            // ### This is very slow, and can be done much better. If the cache is
     5372            // local and matches the below criteria for rotation and scaling, we
     5373            // can easily scroll. And if the cache is in device coordinates, we
     5374            // can scroll both the viewport and the cache.
     5375            update(rect);
     5376        }
    40175377        return;
    40185378    }
     
    40335393        static const QLineF right(0, 0, 1, 0);
    40345394
    4035         QTransform deviceTr;
    4036         if (d->itemIsUntransformable()) {
    4037             deviceTr = deviceTransform(view->viewportTransform());
    4038         } else {
    4039             deviceTr = sceneTransform() * view->viewportTransform();
    4040         }
    4041 
     5395        QTransform deviceTr = deviceTransform(view->viewportTransform());
    40425396        QRect deviceScrollRect = deviceTr.mapRect(scrollRect).toRect();
    40435397        QLineF v1 = deviceTr.map(right);
     
    41715525QPointF QGraphicsItem::mapToParent(const QPointF &point) const
    41725526{
    4173     return d_ptr->pos + (d_ptr->hasTransform ? transform().map(point) : point);
     5527    // COMBINE
     5528    if (!d_ptr->transformData)
     5529        return point + d_ptr->pos;
     5530    return d_ptr->transformToParent().map(point);
    41745531}
    41755532
     
    41915548QPointF QGraphicsItem::mapToScene(const QPointF &point) const
    41925549{
    4193     return sceneTransform().map(point);
     5550    if (d_ptr->hasTranslateOnlySceneTransform())
     5551        return QPointF(point.x() + d_ptr->sceneTransform.dx(), point.y() + d_ptr->sceneTransform.dy());
     5552    return d_ptr->sceneTransform.map(point);
    41945553}
    41955554
     
    42365595QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
    42375596{
    4238     QPolygonF p = !d_ptr->hasTransform ? rect : transform().map(rect);
    4239     p.translate(d_ptr->pos);
    4240     return p;
     5597    // COMBINE
     5598    if (!d_ptr->transformData)
     5599        return rect.translated(d_ptr->pos);
     5600    return d_ptr->transformToParent().map(rect);
    42415601}
    42425602
     
    42575617QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const
    42585618{
    4259     return sceneTransform().map(rect);
     5619    if (d_ptr->hasTranslateOnlySceneTransform())
     5620        return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
     5621    return d_ptr->sceneTransform.map(rect);
    42605622}
    42615623
     
    43055667QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const
    43065668{
    4307     QRectF r = !d_ptr->hasTransform ? rect : transform().mapRect(rect);
    4308     return r.translated(d_ptr->pos);
     5669    // COMBINE
     5670    if (!d_ptr->transformData)
     5671        return rect.translated(d_ptr->pos);
     5672    return d_ptr->transformToParent().mapRect(rect);
    43095673}
    43105674
     
    43285692QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const
    43295693{
    4330     return sceneTransform().mapRect(rect);
     5694    if (d_ptr->hasTranslateOnlySceneTransform())
     5695        return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
     5696    return d_ptr->sceneTransform.mapRect(rect);
    43315697}
    43325698
     
    43775743QRectF QGraphicsItem::mapRectFromParent(const QRectF &rect) const
    43785744{
    4379     QRectF r = rect.translated(-d_ptr->pos);
    4380     return d_ptr->hasTransform ? transform().inverted().mapRect(r) : r;
     5745    // COMBINE
     5746    if (!d_ptr->transformData)
     5747        return rect.translated(-d_ptr->pos);
     5748    return d_ptr->transformToParent().inverted().mapRect(rect);
    43815749}
    43825750
     
    44005768QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const
    44015769{
    4402     return sceneTransform().inverted().mapRect(rect);
     5770    if (d_ptr->hasTranslateOnlySceneTransform())
     5771        return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
     5772    return d_ptr->sceneTransform.inverted().mapRect(rect);
    44035773}
    44045774
     
    44375807QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
    44385808{
    4439     QPolygonF p = !d_ptr->hasTransform ? polygon : transform().map(polygon);
    4440     p.translate(d_ptr->pos);
    4441     return p;
     5809    // COMBINE
     5810    if (!d_ptr->transformData)
     5811        return polygon.translated(d_ptr->pos);
     5812    return d_ptr->transformToParent().map(polygon);
    44425813}
    44435814
     
    44515822QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const
    44525823{
    4453     return sceneTransform().map(polygon);
     5824    if (d_ptr->hasTranslateOnlySceneTransform())
     5825        return polygon.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
     5826    return d_ptr->sceneTransform.map(polygon);
    44545827}
    44555828
     
    44815854QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
    44825855{
    4483     QTransform x = QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y());
    4484     if (d_ptr->hasTransform)
    4485         x = transform() * x;
    4486     return x.map(path);
     5856   
     5857    if ()
     5858        ;
     5859    return .map(path);
    44875860}
    44885861
     
    44965869QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const
    44975870{
    4498     return sceneTransform().map(path);
     5871    if (d_ptr->hasTranslateOnlySceneTransform())
     5872        return path.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
     5873    return d_ptr->sceneTransform.map(path);
    44995874}
    45005875
     
    45335908QPointF QGraphicsItem::mapFromParent(const QPointF &point) const
    45345909{
    4535     if (d_ptr->hasTransform)
    4536         return transform().inverted().map(point - d_ptr->pos);
     5910    // COMBINE
     5911    if (d_ptr->transformData)
     5912        return d_ptr->transformToParent().inverted().map(point);
    45375913    return point - d_ptr->pos;
    45385914}
     
    45565932QPointF QGraphicsItem::mapFromScene(const QPointF &point) const
    45575933{
    4558     return sceneTransform().inverted().map(point);
     5934    if (d_ptr->hasTranslateOnlySceneTransform())
     5935        return QPointF(point.x() - d_ptr->sceneTransform.dx(), point.y() - d_ptr->sceneTransform.dy());
     5936    return d_ptr->sceneTransform.inverted().map(point);
    45595937}
    45605938
     
    46015979QPolygonF QGraphicsItem::mapFromParent(const QRectF &rect) const
    46025980{
    4603     QRectF r = rect.translated(-d_ptr->pos);
    4604     return d_ptr->hasTransform ? transform().inverted().map(r) : r;
     5981    // COMBINE
     5982    if (!d_ptr->transformData)
     5983        return rect.translated(-d_ptr->pos);
     5984    return d_ptr->transformToParent().inverted().map(rect);
    46055985}
    46065986
     
    46226002QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const
    46236003{
    4624     return sceneTransform().inverted().map(rect);
     6004    if (d_ptr->hasTranslateOnlySceneTransform())
     6005        return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
     6006    return d_ptr->sceneTransform.inverted().map(rect);
    46256007}
    46266008
     
    46576039QPolygonF QGraphicsItem::mapFromParent(const QPolygonF &polygon) const
    46586040{
    4659     QPolygonF p = polygon;
    4660     p.translate(-d_ptr->pos);
    4661     return d_ptr->hasTransform ? transform().inverted().map(p) : p;
     6041    // COMBINE
     6042    if (!d_ptr->transformData)
     6043        return polygon.translated(-d_ptr->pos);
     6044    return d_ptr->transformToParent().inverted().map(polygon);
    46626045}
    46636046
     
    46716054QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const
    46726055{
    4673     return sceneTransform().inverted().map(polygon);
     6056    if (d_ptr->hasTranslateOnlySceneTransform())
     6057        return polygon.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
     6058    return d_ptr->sceneTransform.inverted().map(polygon);
    46746059}
    46756060
     
    46996084QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const
    47006085{
    4701     if (d_ptr->parent)
    4702         return d_ptr->parent->itemTransform(this).map(path);
    4703     return mapFromScene(path);
     6086    // COMBINE
     6087    if (!d_ptr->transformData)
     6088            return path.translated(-d_ptr->pos);
     6089    return d_ptr->transformToParent().inverted().map(path);
    47046090}
    47056091
     
    47136099QPainterPath QGraphicsItem::mapFromScene(const QPainterPath &path) const
    47146100{
    4715     return sceneTransform().inverted().map(path);
     6101    if (d_ptr->hasTranslateOnlySceneTransform())
     6102        return path.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
     6103    return d_ptr->sceneTransform.inverted().map(path);
    47166104}
    47176105
     
    47256113{
    47266114    if (!child || child == this)
     6115
     6116
    47276117        return false;
    47286118    const QGraphicsItem *ancestor = child;
     
    47506140    const QGraphicsItem *thisw = this;
    47516141    const QGraphicsItem *otherw = other;
    4752     int thisDepth = d_ptr->depth;
    4753     int otherDepth = other->d_ptr->depth;
     6142    int thisDepth = d_ptr->depth;
     6143    int otherDepth = other->d_ptr->depth;
    47546144    while (thisDepth > otherDepth) {
    47556145        thisw = thisw->d_ptr->parent;
     
    50506440        inputMethodEvent(static_cast<QInputMethodEvent *>(event));
    50516441        break;
     6442
     6443
     6444
     6445
     6446
     6447
     6448
     6449
     6450
     6451
     6452
     6453
     6454
    50526455    default:
    50536456        return false;
     
    51896592    ensureVisible().
    51906593
    5191     \sa focusOutEvent(), sceneEvent()
     6594    \sa focusOutEvent(), sceneEvent()
    51926595*/
    51936596void QGraphicsItem::focusInEvent(QFocusEvent *event)
    51946597{
    51956598    Q_UNUSED(event);
     6599
    51966600}
    51976601
     
    52006604    focus out events for this item. The default implementation does nothing.
    52016605
    5202     \sa focusInEvent(), sceneEvent()
     6606    \sa focusInEvent(), sceneEvent()
    52036607*/
    52046608void QGraphicsItem::focusOutEvent(QFocusEvent *event)
    52056609{
    52066610    Q_UNUSED(event);
     6611
    52076612}
    52086613
     
    52196624{
    52206625    Q_UNUSED(event);
    5221     d_ptr->updateHelper();
     6626    ();
    52226627}
    52236628
     
    52476652{
    52486653    Q_UNUSED(event);
    5249     d_ptr->updateHelper();
     6654    ();
    52506655}
    52516656
     
    53376742        // Qt::Popup closes when you click outside.
    53386743        QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
    5339         if (w->windowFlags() & Qt::Popup) {
     6744        if ( Qt::Popup) {
    53406745            event->accept();
    53416746            if (!w->rect().contains(event->pos()))
     
    55846989    property is queried.
    55856990
    5586     \sa inputMethodEvent()
     6991    \sa inputMethodEvent()
    55876992*/
    55886993QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const
     
    56007005
    56017006/*!
     7007
     7008
     7009
     7010
     7011
     7012
     7013
     7014
     7015
     7016
     7017
     7018
     7019
     7020
     7021
     7022
     7023
     7024
     7025
     7026
     7027
     7028
     7029
     7030
     7031
     7032
     7033
     7034
     7035
     7036
     7037
     7038
     7039
    56027040    This virtual function is called by QGraphicsItem to notify custom items
    56037041    that some part of the item's state changes. By reimplementing this
     
    56767114    }
    56777115    if (d_ptr->scene)
    5678         d_ptr->scene->d_func()->addToIndex(this);
    5679     d_ptr->updateHelper();
     7116        d_ptr->scene->d_func()->index->addItem(this);
    56807117}
    56817118
     
    56937130        return;
    56947131    }
    5695     d_ptr->updateHelper();
    56967132    if (d_ptr->scene)
    5697         d_ptr->scene->d_func()->removeFromIndex(this);
     7133        d_ptr->scene->d_func()->(this);
    56987134}
    56997135
     
    57137149void QGraphicsItem::prepareGeometryChange()
    57147150{
     7151
     7152
    57157153    if (d_ptr->scene) {
    5716         d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper);
     7154        d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true;
     7155        d_ptr->geometryChanged = 1;
     7156        d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
     7157        d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper;
     7158
    57177159        QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
    5718         scenePrivate->removeFromIndex(this);
    5719     }
    5720 
    5721     if (d_ptr->inSetPosHelper)
    5722         return;
    5723 
    5724     if (d_ptr->flags & ItemClipsChildrenToShape)
    5725         d_ptr->invalidateCachedClipPathRecursively();
    5726     else
    5727         d_ptr->invalidateCachedClipPath();
     7160        scenePrivate->index->prepareBoundingRectChange(this);
     7161        scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true);
     7162
     7163        // For compatibility reasons, we have to update the item's old geometry
     7164        // if someone is connected to the changed signal or the scene has no views.
     7165        // Note that this has to be done *after* markDirty to ensure that
     7166        // _q_processDirtyItems is called before _q_emitUpdated.
     7167        if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
     7168            || scenePrivate->views.isEmpty()) {
     7169            if (d_ptr->hasTranslateOnlySceneTransform()) {
     7170                d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
     7171                                                               d_ptr->sceneTransform.dy()));
     7172            } else {
     7173                d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect()));
     7174            }
     7175        }
     7176    }
     7177
     7178    QGraphicsItem *parent = this;
     7179    while ((parent = parent->d_ptr->parent)) {
     7180        QGraphicsItemPrivate *parentp = parent->d_ptr.data();
     7181        parentp->dirtyChildrenBoundingRect = 1;
     7182        // ### Only do this if the parent's effect applies to the entire subtree.
     7183        parentp->notifyBoundingRectChanged = 1;
     7184#ifndef QT_NO_GRAPHICSEFFECT
     7185        if (parentp->scene && parentp->graphicsEffect) {
     7186            parentp->notifyInvalidated = 1;
     7187            static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()->source->d_func())->invalidateCache();
     7188        }
     7189#endif
     7190    }
    57287191}
    57297192
     
    57407203{
    57417204    const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1));
    5742     if (qFuzzyCompare(qMax(murect.width(), murect.height()) + 1, 1))
     7205    if (qFuzzy))
    57437206        return;
    57447207
     
    57907253
    57917254/*!
     7255
     7256
     7257
     7258
     7259
     7260
     7261
     7262
     7263
     7264
     7265
     7266
     7267
     7268
     7269
     7270
     7271
     7272
     7273
     7274
     7275
     7276
     7277
     7278
     7279
     7280
     7281
     7282
     7283
     7284
     7285
     7286
     7287
     7288
     7289
     7290
     7291
     7292
     7293
     7294
     7295
     7296
     7297
     7298
     7299
     7300
     7301
     7302
     7303
     7304
     7305
     7306
     7307
     7308
     7309
     7310
     7311
     7312
     7313
     7314
     7315
     7316
     7317
     7318
     7319
     7320
     7321
     7322
     7323
     7324
     7325
     7326
     7327
     7328
     7329
     7330
     7331
     7332
     7333
     7334
     7335
     7336
     7337
     7338
     7339
     7340
     7341
     7342
     7343
     7344
     7345
     7346
     7347
     7348
     7349
     7350
     7351
     7352
     7353
     7354
     7355
     7356
     7357
     7358
     7359
     7360
     7361
     7362
     7363
     7364
     7365
     7366
     7367
     7368
     7369
     7370
     7371
     7372
     7373
     7374
     7375
     7376
     7377
     7378
     7379
     7380
     7381
     7382
     7383
     7384
     7385
     7386
     7387
     7388
     7389
     7390
     7391
     7392
     7393
     7394
     7395
     7396
     7397
     7398
     7399
     7400
     7401
     7402
     7403
     7404
     7405
     7406
     7407
     7408
     7409
     7410
     7411
     7412
     7413
     7414
     7415
     7416
     7417
     7418
     7419
     7420
     7421
     7422
     7423
     7424
     7425
     7426
     7427
     7428
     7429
     7430
     7431
     7432
     7433
     7434
     7435
     7436
     7437
     7438
     7439
     7440
     7441
     7442
     7443
     7444
     7445
     7446
     7447
     7448
     7449
     7450
     7451
     7452
     7453
     7454
     7455
     7456
     7457
     7458
     7459
     7460
     7461
     7462
     7463
     7464
     7465
     7466
     7467
     7468
     7469
     7470
     7471
     7472
     7473
     7474
     7475
     7476
     7477
     7478
     7479
     7480
     7481
     7482
     7483
     7484
     7485
     7486
     7487
     7488
     7489
     7490
     7491
     7492
     7493
     7494
     7495
     7496
     7497
     7498
     7499
     7500
     7501
     7502
     7503
     7504
     7505
     7506
     7507
     7508
     7509
     7510
     7511
     7512
    57927513    \class QAbstractGraphicsShapeItem
    57937514    \brief The QAbstractGraphicsShapeItem class provides a common base for
    57947515    all path items.
    57957516    \since 4.2
    5796     \ingroup multimedia
     7517    \ingroup
    57977518
    57987519    This class does not fully implement an item by itself; in particular, it
     
    59297650    can add to a QGraphicsScene.
    59307651    \since 4.2
    5931     \ingroup multimedia
    59327652    \ingroup graphicsview-api
    59337653
     
    61327852    can add to a QGraphicsScene.
    61337853    \since 4.2
    6134     \ingroup multimedia
    61357854    \ingroup graphicsview-api
    61367855
     
    63778096    can add to a QGraphicsScene.
    63788097    \since 4.2
    6379     \ingroup multimedia
    63808098    \ingroup graphicsview-api
    63818099
     
    66948412    can add to a QGraphicsScene.
    66958413    \since 4.2
    6696     \ingroup multimedia
    66978414    \ingroup graphicsview-api
    66988415
     
    69288645    QGraphicsScene.
    69298646    \since 4.2
    6930     \ingroup multimedia
    69318647    \ingroup graphicsview-api
    69328648
     
    71908906    a QGraphicsScene.
    71918907    \since 4.2
    7192     \ingroup multimedia
    71938908    \ingroup graphicsview-api
    71948909
     
    73799094    Q_D(QGraphicsPixmapItem);
    73809095    if (mode != d->transformationMode) {
    7381         d_ptr->updateHelper();
    73829096        d->transformationMode = mode;
    73839097        update();
     
    74279141{
    74289142    Q_D(const QGraphicsPixmapItem);
    7429     qreal pw = 1.0;
    74309143    if (d->pixmap.isNull())
    74319144        return QRectF();
    7432     return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
     9145    if (d->flags & ItemIsSelectable) {
     9146        qreal pw = 1.0;
     9147        return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
     9148    } else {
     9149        return QRectF(d->offset, d->pixmap.size());
     9150    }
    74339151}
    74349152
     
    74679185                           (d->transformationMode == Qt::SmoothTransformation));
    74689186
    7469     QRectF exposed = option->exposedRect.adjusted(-1, -1, 1, 1);
    7470     exposed &= QRectF(d->offset.x(), d->offset.y(), d->pixmap.width(), d->pixmap.height());
    7471     painter->drawPixmap(exposed, d->pixmap, exposed.translated(-d->offset));
     9187    painter->drawPixmap(d->offset, d->pixmap);
    74729188
    74739189    if (option->state & QStyle::State_Selected)
     
    75579273    a QGraphicsScene to display formatted text.
    75589274    \since 4.2
    7559     \ingroup multimedia
    75609275    \ingroup graphicsview-api
    75619276
     
    75929307public:
    75939308    QGraphicsTextItemPrivate()
    7594         : control(0), pageNumber(0), useDefaultImpl(false), tabChangesFocus(false)
     9309        : control(0), pageNumber(0), useDefaultImpl(false), tabChangesFocus(false)
    75959310    { }
    75969311
     
    76139328    bool tabChangesFocus;
    76149329
     9330
     9331
    76159332    QGraphicsTextItem *qq;
    76169333};
     9334
    76179335
    76189336/*!
     
    76289346#endif
    76299347    )
    7630     : QGraphicsItem(parent, scene), dd(new QGraphicsTextItemPrivate)
     9348    : QGraphicsparent, scene), dd(new QGraphicsTextItemPrivate)
    76319349{
    76329350    dd->qq = this;
     
    76359353    setAcceptDrops(true);
    76369354    setAcceptHoverEvents(true);
     9355
    76379356}
    76389357
     
    76499368#endif
    76509369    )
    7651     : QGraphicsItem(parent, scene), dd(new QGraphicsTextItemPrivate)
     9370    : QGraphicsparent, scene), dd(new QGraphicsTextItemPrivate)
    76529371{
    76539372    dd->qq = this;
    76549373    setAcceptDrops(true);
    76559374    setAcceptHoverEvents(true);
     9375
    76569376}
    76579377
     
    77439463    QTextControl *c = dd->textControl();
    77449464    QPalette pal = c->palette();
     9465
    77459466    pal.setColor(QPalette::Text, col);
    77469467    c->setPalette(pal);
     9468
     9469
    77479470}
    77489471
     
    79159638        }
    79169639    }
    7917     return QGraphicsItem::sceneEvent(event);
     9640    bool result = QGraphicsItem::sceneEvent(event);
     9641
     9642    // Ensure input context is updated.
     9643    switch (event->type()) {
     9644    case QEvent::ContextMenu:
     9645    case QEvent::FocusIn:
     9646    case QEvent::FocusOut:
     9647    case QEvent::GraphicsSceneDragEnter:
     9648    case QEvent::GraphicsSceneDragLeave:
     9649    case QEvent::GraphicsSceneDragMove:
     9650    case QEvent::GraphicsSceneDrop:
     9651    case QEvent::GraphicsSceneHoverEnter:
     9652    case QEvent::GraphicsSceneHoverLeave:
     9653    case QEvent::GraphicsSceneHoverMove:
     9654    case QEvent::GraphicsSceneMouseDoubleClick:
     9655    case QEvent::GraphicsSceneMousePress:
     9656    case QEvent::GraphicsSceneMouseMove:
     9657    case QEvent::GraphicsSceneMouseRelease:
     9658    case QEvent::KeyPress:
     9659    case QEvent::KeyRelease:
     9660        // Reset the focus widget's input context, regardless
     9661        // of how this item gained or lost focus.
     9662        if (QWidget *fw = qApp->focusWidget()) {
     9663#ifndef QT_NO_IM
     9664            if (QInputContext *qic = fw->inputContext()) {
     9665                if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut)
     9666                    qic->reset();
     9667                else
     9668                    qic->update();
     9669            }
     9670#endif //QT_NO_IM
     9671        }
     9672        break;
     9673    default:
     9674        break;
     9675    }
     9676
     9677    return result;
    79189678}
    79199679
     
    79249684{
    79259685    if ((QGraphicsItem::d_ptr->flags & (ItemIsSelectable | ItemIsMovable))
    7926         && (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) {
    7927         // User left-pressed on edge of selectable/movable item, use
    7928         // base impl.
    7929         dd->useDefaultImpl = true;
     9686&& (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) {
     9687// User left-pressed on edge of selectable/movable item, use
     9688// base impl.
     9689dd->useDefaultImpl = true;
    79309690    } else if (event->buttons() == event->button()
    7931                && dd->control->textInteractionFlags() == Qt::NoTextInteraction) {
    7932         // User pressed first button on non-interactive item.
    7933         dd->useDefaultImpl = true;
     9691       && dd->control->textInteractionFlags() == Qt::NoTextInteraction) {
     9692// User pressed first button on non-interactive item.
     9693dd->useDefaultImpl = true;
    79349694    }
    79359695    if (dd->useDefaultImpl) {
    79369696        QGraphicsItem::mousePressEvent(event);
    7937         if (!event->isAccepted())
    7938             dd->useDefaultImpl = false;
     9697if (!event->isAccepted())
     9698    dd->useDefaultImpl = false;
    79399699        return;
    79409700    }
     9701
    79419702    dd->sendControlEvent(event);
    79429703}
     
    79519712        return;
    79529713    }
     9714
    79539715    dd->sendControlEvent(event);
    79549716}
     
    79619723    if (dd->useDefaultImpl) {
    79629724        QGraphicsItem::mouseReleaseEvent(event);
    7963         if (dd->control->textInteractionFlags() == Qt::NoTextInteraction
    7964             && !event->buttons()) {
    7965             // User released last button on non-interactive item.
     9725if (dd->control->textInteractionFlags() == Qt::NoTextInteraction
     9726    && !event->buttons()) {
     9727    // User released last button on non-interactive item.
    79669728            dd->useDefaultImpl = false;
    7967         } else  if ((event->buttons() & Qt::LeftButton) == 0) {
    7968             // User released the left button on an interactive item.
     9729} else  if ((event->buttons() & Qt::LeftButton) == 0) {
     9730    // User released the left button on an interactive item.
    79699731            dd->useDefaultImpl = false;
    7970         }
     9732}
    79719733        return;
    79729734    }
     9735
     9736
     9737
     9738
     9739
     9740
    79739741    dd->sendControlEvent(event);
    79749742}
     
    80229790{
    80239791    dd->sendControlEvent(event);
     9792
     9793
     9794
    80249795    update();
    80259796}
     
    825810029    input.
    825910030
    8260     The default for a QGraphicsTextItem is Qt::NoTextInteraction. Setting a
    8261     value different to Qt::NoTextInteraction will also set the ItemIsFocusable
    8262     QGraphicsItem flag.
     10031    The default for a QGraphicsTextItem is Qt::NoTextInteraction.
     10032   
     10033    .
    826310034
    826410035    By default, the text is read-only. To transform the item into an editor,
     
    826810039{
    826910040    if (flags == Qt::NoTextInteraction)
    8270         setFlags(this->flags() & ~QGraphicsItem::ItemIsFocusable);
     10041        setFlags(this->flags() & ~);
    827110042    else
    8272         setFlags(this->flags() | QGraphicsItem::ItemIsFocusable);
     10043        setFlags(this->flags() | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod);
     10044
    827310045    dd->textControl()->setTextInteractionFlags(flags);
    827410046}
     
    841910191    that you can add to a QGraphicsScene.
    842010192    \since 4.2
    8421     \ingroup multimedia
    842210193    \ingroup graphicsview-api
    842310194
     
    865510426    one.
    865610427    \since 4.2
    8657     \ingroup multimedia
    865810428    \ingroup graphicsview-api
    865910429
     
    867010440
    867110441    The boundingRect() function of QGraphicsItemGroup returns the
    8672     bounding rectangle of all items in the item group. In addition,
    8673     item groups have handlesChildEvents() enabled by default, so all
    8674     events sent to a member of the group go to the item group (i.e.,
    8675     selecting one item in a group will select them all).
    8676     QGraphicsItemGroup ignores the ItemIgnoresTransformations flag on its
    8677     children (i.e., with respect to the geometry of the group item, the
    8678     children are treated as if they were transformable).
     10442    bounding rectangle of all items in the item group.
     10443    QGraphicsItemGroup ignores the ItemIgnoresTransformations flag on
     10444    its children (i.e., with respect to the geometry of the group
     10445    item, the children are treated as if they were transformable).
    867910446
    868010447    There are two ways to construct an item group. The easiest and
     
    876110528    }
    876210529
    8763     QTransform oldSceneMatrix = item->sceneTransform();
     10530    // COMBINE
     10531    bool ok;
     10532    QTransform itemTransform = item->itemTransform(this, &ok);
     10533
     10534    if (!ok) {
     10535        qWarning("QGraphicsItemGroup::addToGroup: could not find a valid transformation from item to group coordinates");
     10536        return;
     10537    }
     10538
     10539    QTransform newItemTransform(itemTransform);
    876410540    item->setPos(mapFromItem(item, 0, 0));
    876510541    item->setParentItem(this);
    8766     QTransform newItemTransform(oldSceneMatrix);
    8767     newItemTransform *= sceneTransform().inverted();
     10542
     10543   
    876810544    if (!item->pos().isNull())
    876910545        newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
     10546
     10547
     10548
     10549
     10550
     10551
     10552
     10553
     10554
     10555
     10556
     10557
     10558
     10559
     10560
    877010561    item->setTransform(newItemTransform);
    877110562    item->d_func()->setIsMemberOfGroup(true);
    877210563    prepareGeometryChange();
    8773     QTransform itemTransform(item->transform());
    8774     if (!item->pos().isNull())
    8775         itemTransform *= QTransform::fromTranslate(item->x(), item->y());
    877610564    d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
    877710565    update();
     
    879510583
    879610584    QGraphicsItem *newParent = d_ptr->parent;
     10585
     10586
     10587
     10588
     10589
     10590
     10591
     10592
     10593
    879710594    QPointF oldPos = item->mapToItem(newParent, 0, 0);
    879810595    item->setParentItem(newParent);
    8799     // ### This function should remap the item's matrix to keep the item's
    8800     // transformation unchanged relative to the scene.
    880110596    item->setPos(oldPos);
     10597
     10598
     10599
     10600
     10601
     10602
     10603
     10604
     10605
     10606
     10607
     10608
     10609
     10610
     10611
     10612
     10613
     10614
     10615
     10616
     10617
    880210618    item->d_func()->setIsMemberOfGroup(item->group() != 0);
    880310619
     
    885610672}
    885710673
     10674
     10675
     10676
     10677
     10678
     10679
     10680
     10681
     10682
     10683
     10684
     10685
     10686
     10687
     10688
     10689
     10690
     10691
     10692
     10693
     10694
     10695
     10696
     10697
     10698
     10699
     10700
     10701
     10702
     10703
     10704
     10705
     10706
     10707
     10708
     10709
     10710
     10711
     10712
     10713
     10714
     10715
     10716
     10717
     10718
     10719
     10720
     10721
     10722
     10723
     10724
     10725
     10726
     10727
     10728
     10729
     10730
     10731
     10732
     10733
     10734
     10735
     10736
     10737
     10738
     10739
     10740
     10741
     10742
     10743
     10744
     10745
     10746
     10747
     10748
     10749
     10750
     10751
     10752
     10753
     10754
     10755
     10756
     10757
     10758
     10759
     10760
     10761
     10762
     10763
     10764
     10765
     10766
     10767
     10768
     10769
     10770
     10771
     10772
     10773
     10774
     10775
     10776
     10777
     10778
     10779
     10780
     10781
     10782
     10783
     10784
     10785
     10786
     10787
     10788
     10789
     10790
     10791
     10792
     10793
     10794
     10795
     10796
     10797
     10798
     10799
     10800
     10801
     10802
     10803
     10804
     10805
     10806
     10807
     10808
     10809
     10810
     10811
     10812
     10813
     10814
     10815
     10816
     10817
     10818
     10819
     10820
     10821
     10822
     10823
     10824
     10825
     10826
     10827
     10828
    885810829#ifndef QT_NO_DEBUG_STREAM
    885910830QDebug operator<<(QDebug debug, QGraphicsItem *item)
     
    886410835    }
    886510836
    8866     QStringList flags;
    8867     if (item->isVisible()) flags << QLatin1String("isVisible");
    8868     if (item->isEnabled()) flags << QLatin1String("isEnabled");
    8869     if (item->isSelected()) flags << QLatin1String("isSelected");
    8870     if (item->hasFocus()) flags << QLatin1String("HasFocus");
    8871 
    8872     debug << "QGraphicsItem(this =" << ((void*)item)
    8873           << ", parent =" << ((void*)item->parentItem())
     10837    if (QGraphicsObject *o = item->toGraphicsObject())
     10838        debug << o->metaObject()->className();
     10839    else
     10840        debug << "QGraphicsItem";
     10841    debug << "(this =" << (void*)item
     10842          << ", parent =" << (void*)item->parentItem()
    887410843          << ", pos =" << item->pos()
    8875           << ", z =" << item->zValue() << ", flags = {"
    8876           << flags.join(QLatin1String("|")) << " })";
     10844          << ", z =" << item->zValue() << ", flags = "
     10845          << )";
    887710846    return debug;
     10847
     10848
     10849
     10850
     10851
     10852
     10853
     10854
     10855
     10856
     10857
     10858
     10859
     10860
     10861
     10862
     10863
    887810864}
    887910865
     
    896310949        str = "ItemOpacityHasChanged";
    896410950        break;
     10951
     10952
     10953
    896510954    }
    896610955    debug << str;
     
    899910988        str = "ItemStacksBehindParent";
    900010989        break;
     10990
     10991
     10992
     10993
     10994
     10995
     10996
     10997
     10998
     10999
     11000
     11001
     11002
     11003
     11004
     11005
     11006
     11007
     11008
     11009
     11010
     11011
     11012
     11013
    900111014    }
    900211015    debug << str;
     
    900611019QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags)
    900711020{
    9008     debug << "(";
     11021    debug << ;
    900911022    bool f = false;
    9010     for (int i = 0; i < 9; ++i) {
     11023    for (int i = 0; i < ; ++i) {
    901111024        if (flags & (1 << i)) {
    901211025            if (f)
    9013                 debug << "|";
     11026                debug << ;
    901411027            f = true;
    901511028            debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i)));
    901611029        }
    901711030    }
    9018     debug << ")";
     11031    debug << ;
    901911032    return debug;
    902011033}
Note: See TracChangeset for help on using the changeset viewer.