src/gui/graphicsview/qgraphicsitem.cpp
changeset 7 f7bc934e204c
parent 3 41300fa6a67c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtGui module of the Qt Toolkit.
     7 ** This file is part of the QtGui module of the Qt Toolkit.
     8 **
     8 **
   266 
   266 
   267     \sa QGraphicsScene, QGraphicsView, {The Graphics View Framework}
   267     \sa QGraphicsScene, QGraphicsView, {The Graphics View Framework}
   268 */
   268 */
   269 
   269 
   270 /*!
   270 /*!
       
   271     \variable QGraphicsItem::Type
       
   272 
       
   273     The type value returned by the virtual type() function in standard
       
   274     graphics item classes in Qt. All such standard graphics item
       
   275     classes in Qt are associated with a unique value for Type,
       
   276     e.g. the value returned by QGraphicsPathItem::type() is 2.
       
   277 
       
   278     \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 18
       
   279 */
       
   280 
       
   281 /*!
   271     \variable QGraphicsItem::UserType
   282     \variable QGraphicsItem::UserType
   272 
   283 
   273     The lowest permitted type value for custom items (subclasses
   284     The lowest permitted type value for custom items (subclasses
   274     of QGraphicsItem or any of the standard items). This value is
   285     of QGraphicsItem or any of the standard items). This value is
   275     used in conjunction with a reimplementation of QGraphicsItem::type()
   286     used in conjunction with a reimplementation of QGraphicsItem::type()
   276     and declaring a Type enum value. Example:
   287     and declaring a Type enum value. Example:
   277 
   288 
   278     \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1
   289     \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1
       
   290 
       
   291     \note UserType = 65536
   279 */
   292 */
   280 
   293 
   281 /*!
   294 /*!
   282     \enum QGraphicsItem::GraphicsItemFlag
   295     \enum QGraphicsItem::GraphicsItemFlag
   283 
   296 
   304     an input item). Enabling this flag will allow the item to accept focus,
   317     an input item). Enabling this flag will allow the item to accept focus,
   305     which again allows the delivery of key events to
   318     which again allows the delivery of key events to
   306     QGraphicsItem::keyPressEvent() and QGraphicsItem::keyReleaseEvent().
   319     QGraphicsItem::keyPressEvent() and QGraphicsItem::keyReleaseEvent().
   307 
   320 
   308     \value ItemClipsToShape The item clips to its own shape. The item cannot
   321     \value ItemClipsToShape The item clips to its own shape. The item cannot
   309     draw or receive mouse, tablet, drag and drop or hover events outside ts
   322     draw or receive mouse, tablet, drag and drop or hover events outside its
   310     shape. It is disabled by default. This behavior is enforced by
   323     shape. It is disabled by default. This behavior is enforced by
   311     QGraphicsView::drawItems() or QGraphicsScene::drawItems(). This flag was
   324     QGraphicsView::drawItems() or QGraphicsScene::drawItems(). This flag was
   312     introduced in Qt 4.3.
   325     introduced in Qt 4.3.
   313 
   326 
   314     \value ItemClipsChildrenToShape The item clips the painting of all its
   327     \value ItemClipsChildrenToShape The item clips the painting of all its
   342 
   355 
   343     \value ItemStacksBehindParent The item is stacked behind its parent. By
   356     \value ItemStacksBehindParent The item is stacked behind its parent. By
   344     default, child items are stacked on top of the parent item. But setting
   357     default, child items are stacked on top of the parent item. But setting
   345     this flag, the child will be stacked behind it. This flag is useful for
   358     this flag, the child will be stacked behind it. This flag is useful for
   346     drop shadow effects and for decoration objects that follow the parent
   359     drop shadow effects and for decoration objects that follow the parent
   347     item's geometry without drawing on top of it.
   360     item's geometry without drawing on top of it. This flag was introduced
       
   361     in Qt 4.5.
   348 
   362 
   349     \value ItemUsesExtendedStyleOption The item makes use of either
   363     \value ItemUsesExtendedStyleOption The item makes use of either
   350     \l{QStyleOptionGraphicsItem::}{exposedRect} or
   364     \l{QStyleOptionGraphicsItem::} {exposedRect} or
   351     \l{QStyleOptionGraphicsItem::}{matrix} in QStyleOptionGraphicsItem. By default,
   365     \l{QStyleOptionGraphicsItem::} {matrix} in
   352     the \l{QStyleOptionGraphicsItem::}{exposedRect} is initialized to the item's
   366     QStyleOptionGraphicsItem. By default, the
   353     boundingRect() and the \l{QStyleOptionGraphicsItem::}{matrix} is untransformed.
   367     \l{QStyleOptionGraphicsItem::} {exposedRect} is initialized to the
   354     You can enable this flag for the style options to be set up with more
   368     item's boundingRect() and the
   355     fine-grained values.
   369     \l{QStyleOptionGraphicsItem::}{matrix} is untransformed.  You can
   356     Note that QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag
   370     enable this flag for the style options to be set up with more
       
   371     fine-grained values.  Note that
       
   372     QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag
   357     and always initialized to 1. Use
   373     and always initialized to 1. Use
   358     QStyleOptionGraphicsItem::levelOfDetailFromTransform() if you need a higher
   374     QStyleOptionGraphicsItem::levelOfDetailFromTransform() if you need
   359     value.
   375     a higher value. This flag was introduced in Qt 4.6.
   360 
   376 
   361     \value ItemHasNoContents The item does not paint anything (i.e., calling
   377     \value ItemHasNoContents The item does not paint anything (i.e., calling
   362     paint() on the item has no effect). You should set this flag on items that
   378     paint() on the item has no effect). You should set this flag on items that
   363     do not need to be painted to ensure that Graphics View avoids unnecessary
   379     do not need to be painted to ensure that Graphics View avoids unnecessary
   364     painting preparations. This flag was introduced in Qt 4.6.
   380     painting preparations. This flag was introduced in Qt 4.6.
   372 
   388 
   373     \value ItemAcceptsInputMethod The item supports input methods typically
   389     \value ItemAcceptsInputMethod The item supports input methods typically
   374     used for Asian languages.
   390     used for Asian languages.
   375     This flag was introduced in Qt 4.6.
   391     This flag was introduced in Qt 4.6.
   376 
   392 
   377     \value ItemNegativeZStacksBehindParent The item automatically stacks behind
   393     \value ItemNegativeZStacksBehindParent The item automatically
   378     it's parent if it's z-value is negative. This flag enables setZValue() to
   394     stacks behind it's parent if it's z-value is negative. This flag
   379     toggle ItemStacksBehindParent.
   395     enables setZValue() to toggle ItemStacksBehindParent. This flag
       
   396     was introduced in Qt 4.6.
   380 
   397 
   381     \value ItemIsPanel The item is a panel. A panel provides activation and
   398     \value ItemIsPanel The item is a panel. A panel provides activation and
   382     contained focus handling. Only one panel can be active at a time (see
   399     contained focus handling. Only one panel can be active at a time (see
   383     QGraphicsItem::isActive()). When no panel is active, QGraphicsScene
   400     QGraphicsItem::isActive()). When no panel is active, QGraphicsScene
   384     activates all non-panel items. Window items (i.e.,
   401     activates all non-panel items. Window items (i.e.,
   394     introduced in Qt 4.6.
   411     introduced in Qt 4.6.
   395 */
   412 */
   396 
   413 
   397 /*!
   414 /*!
   398     \enum QGraphicsItem::GraphicsItemChange
   415     \enum QGraphicsItem::GraphicsItemChange
   399 
       
   400         ItemVisibleHasChanged,
       
   401         ItemEnabledHasChanged,
       
   402         ItemSelectedHasChanged,
       
   403         ItemParentHasChanged,
       
   404         ItemSceneHasChanged
       
   405 
   416 
   406     This enum describes the state changes that are notified by
   417     This enum describes the state changes that are notified by
   407     QGraphicsItem::itemChange(). The notifications are sent as the state
   418     QGraphicsItem::itemChange(). The notifications are sent as the state
   408     changes, and in some cases, adjustments can be made (see the documentation
   419     changes, and in some cases, adjustments can be made (see the documentation
   409     for each change for details).
   420     for each change for details).
   628     This enum specifies the behavior of a modal panel. A modal panel
   639     This enum specifies the behavior of a modal panel. A modal panel
   629     is one that blocks input to other panels. Note that items that
   640     is one that blocks input to other panels. Note that items that
   630     are children of a modal panel are not blocked.
   641     are children of a modal panel are not blocked.
   631 
   642 
   632     The values are:
   643     The values are:
   633     \value NonModal   The panel is not modal and does not block input to other panels.
   644 
   634     \value PanelModal The panel is modal to a single item hierarchy and blocks input to its parent pane, all grandparent panels, and all siblings of its parent and grandparent panels.
   645     \value NonModal The panel is not modal and does not block input to
   635     \value SceneModal The window is modal to the entire scene and blocks input to all panels.
   646     other panels. This is the default value for panels.
       
   647 
       
   648     \value PanelModal The panel is modal to a single item hierarchy
       
   649     and blocks input to its parent pane, all grandparent panels, and
       
   650     all siblings of its parent and grandparent panels.
       
   651 
       
   652     \value SceneModal The window is modal to the entire scene and
       
   653     blocks input to all panels.
   636 
   654 
   637     \sa QGraphicsItem::setPanelModality(), QGraphicsItem::panelModality(), QGraphicsItem::ItemIsPanel
   655     \sa QGraphicsItem::setPanelModality(), QGraphicsItem::panelModality(), QGraphicsItem::ItemIsPanel
   638 */
   656 */
   639 
   657 
   640 #include "qgraphicsitem.h"
   658 #include "qgraphicsitem.h"
   796             || (int(childFlag) == -1 && handlesChildEvents)
   814             || (int(childFlag) == -1 && handlesChildEvents)
   797             || (int(childFlag) == -2 && filtersDescendantEvents))
   815             || (int(childFlag) == -2 && filtersDescendantEvents))
   798             return;
   816             return;
   799     }
   817     }
   800 
   818 
   801     foreach (QGraphicsItem *child, children)
   819     for (int i = 0; i < children.size(); ++i)
   802         child->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
   820         children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
       
   821 }
       
   822 
       
   823 void QGraphicsItemPrivate::updateAncestorFlags()
       
   824 {
       
   825     int flags = 0;
       
   826     if (parent) {
       
   827         // Inherit the parent's ancestor flags.
       
   828         QGraphicsItemPrivate *pd = parent->d_ptr.data();
       
   829         flags = pd->ancestorFlags;
       
   830 
       
   831         // Add in flags from the parent.
       
   832         if (pd->filtersDescendantEvents)
       
   833             flags |= AncestorFiltersChildEvents;
       
   834         if (pd->handlesChildEvents)
       
   835             flags |= AncestorHandlesChildEvents;
       
   836         if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape)
       
   837             flags |= AncestorClipsChildren;
       
   838         if (pd->flags & QGraphicsItem::ItemIgnoresTransformations)
       
   839             flags |= AncestorIgnoresTransformations;
       
   840     }
       
   841 
       
   842     if (ancestorFlags == flags)
       
   843         return; // No change; stop propagation.
       
   844     ancestorFlags = flags;
       
   845 
       
   846     // Propagate to children recursively.
       
   847     for (int i = 0; i < children.size(); ++i)
       
   848         children.at(i)->d_ptr->updateAncestorFlags();
   803 }
   849 }
   804 
   850 
   805 /*!
   851 /*!
   806     \internal
   852     \internal
   807 
   853 
   982 
  1028 
   983     Make sure not to trigger any pure virtual function calls (e.g.,
  1029     Make sure not to trigger any pure virtual function calls (e.g.,
   984     prepareGeometryChange) if the item is in its destructor, i.e.
  1030     prepareGeometryChange) if the item is in its destructor, i.e.
   985     inDestructor is 1.
  1031     inDestructor is 1.
   986 */
  1032 */
   987 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
  1033 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant,
       
  1034                                                const QVariant *thisPointerVariant)
   988 {
  1035 {
   989     Q_Q(QGraphicsItem);
  1036     Q_Q(QGraphicsItem);
   990     if (newParent == q) {
       
   991         qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
       
   992         return;
       
   993     }
       
   994     if (newParent == parent)
  1037     if (newParent == parent)
   995         return;
  1038         return;
   996 
  1039 
   997     const QVariant newParentVariant(q->itemChange(QGraphicsItem::ItemParentChange,
       
   998                                                   qVariantFromValue<QGraphicsItem *>(newParent)));
       
   999     newParent = qVariantValue<QGraphicsItem *>(newParentVariant);
       
  1000     if (newParent == parent)
       
  1001         return;
       
  1002 
       
  1003     if (scene) {
  1040     if (scene) {
  1004         // Deliver the change to the index
  1041         // Deliver the change to the index
  1005         scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant);
  1042         if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
       
  1043             scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
  1006 
  1044 
  1007         // Disable scene pos notifications for old ancestors
  1045         // Disable scene pos notifications for old ancestors
  1008         if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
  1046         if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
  1009             scene->d_func()->setScenePosItemEnabled(q, false);
  1047             scene->d_func()->setScenePosItemEnabled(q, false);
  1010     }
  1048     }
  1018     // removed from the index at a later stage, and the whole scene will be
  1056     // removed from the index at a later stage, and the whole scene will be
  1019     // updated.
  1057     // updated.
  1020     if (!inDestructor)
  1058     if (!inDestructor)
  1021         q_ptr->prepareGeometryChange();
  1059         q_ptr->prepareGeometryChange();
  1022 
  1060 
  1023     const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q));
       
  1024     if (parent) {
  1061     if (parent) {
  1025         // Remove from current parent
  1062         // Remove from current parent
  1026         parent->d_ptr->removeChild(q);
  1063         parent->d_ptr->removeChild(q);
  1027         parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant);
  1064         if (thisPointerVariant)
       
  1065             parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant);
  1028     }
  1066     }
  1029 
  1067 
  1030     // Update toplevelitem list. If this item is being deleted, its parent
  1068     // Update toplevelitem list. If this item is being deleted, its parent
  1031     // will be 0 but we don't want to register/unregister it in the TLI list.
  1069     // will be 0 but we don't want to register/unregister it in the TLI list.
  1032     if (scene && !inDestructor) {
  1070     if (scene && !inDestructor) {
  1040     // Ensure any last parent focus scope does not point to this item or any of
  1078     // Ensure any last parent focus scope does not point to this item or any of
  1041     // its descendents.
  1079     // its descendents.
  1042     QGraphicsItem *p = parent;
  1080     QGraphicsItem *p = parent;
  1043     QGraphicsItem *parentFocusScopeItem = 0;
  1081     QGraphicsItem *parentFocusScopeItem = 0;
  1044     while (p) {
  1082     while (p) {
  1045         if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
  1083         if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
  1046             // If this item's focus scope's focus scope item points
  1084             // If this item's focus scope's focus scope item points
  1047             // to this item or a descendent, then clear it.
  1085             // to this item or a descendent, then clear it.
  1048             QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
  1086             QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
  1049             if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
  1087             if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
  1050                 parentFocusScopeItem = fsi;
  1088                 parentFocusScopeItem = fsi;
  1053             break;
  1091             break;
  1054         }
  1092         }
  1055         p = p->d_ptr->parent;
  1093         p = p->d_ptr->parent;
  1056     }
  1094     }
  1057 
  1095 
       
  1096     // Update graphics effect optimization flag
       
  1097     if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect))
       
  1098         newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
       
  1099 
  1058     // Update focus scope item ptr in new scope.
  1100     // Update focus scope item ptr in new scope.
  1059     QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
  1101     QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
  1060     if (newFocusScopeItem && newParent) {
  1102     if (newFocusScopeItem && newParent) {
  1061         if (subFocusItem) {
  1103         if (subFocusItem) {
  1062             // Find the subFocusItem's topmost focus scope.
  1104             // Find the subFocusItem's topmost focus scope.
  1063             QGraphicsItem *ancestorScope = 0;
  1105             QGraphicsItem *ancestorScope = 0;
  1064             QGraphicsItem *p = subFocusItem->d_ptr->parent;
  1106             QGraphicsItem *p = subFocusItem->d_ptr->parent;
  1065             while (p) {
  1107             while (p) {
  1066                 if (p->flags() & QGraphicsItem::ItemIsFocusScope)
  1108                 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
  1067                     ancestorScope = p;
  1109                     ancestorScope = p;
  1068                 if (p->isPanel())
  1110                 if (p->d_ptr->flags & QGraphicsItem::ItemIsPanel)
  1069                     break;
  1111                     break;
  1070                 p = p->parentItem();
  1112                 p = p->d_ptr->parent;
  1071             }
  1113             }
  1072             if (ancestorScope)
  1114             if (ancestorScope)
  1073                 newFocusScopeItem = ancestorScope;
  1115                 newFocusScopeItem = ancestorScope;
  1074         }
  1116         }
  1075 
  1117 
  1076         QGraphicsItem *p = newParent;
  1118         QGraphicsItem *p = newParent;
  1077         while (p) {
  1119         while (p) {
  1078             if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
  1120             if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
  1079                 p->d_ptr->focusScopeItem = newFocusScopeItem;
  1121                 p->d_ptr->focusScopeItem = newFocusScopeItem;
  1080                 // Ensure the new item is no longer the subFocusItem. The
  1122                 // Ensure the new item is no longer the subFocusItem. The
  1081                 // only way to set focus on a child of a focus scope is
  1123                 // only way to set focus on a child of a focus scope is
  1082                 // by setting focus on the scope itself.
  1124                 // by setting focus on the scope itself.
  1083                 if (subFocusItem && !p->focusItem())
  1125                 if (subFocusItem && !p->focusItem())
  1086             }
  1128             }
  1087             p = p->d_ptr->parent;
  1129             p = p->d_ptr->parent;
  1088         }
  1130         }
  1089     }
  1131     }
  1090 
  1132 
       
  1133     // Resolve depth.
       
  1134     invalidateDepthRecursively();
       
  1135 
  1091     if ((parent = newParent)) {
  1136     if ((parent = newParent)) {
  1092         bool implicitUpdate = false;
       
  1093         if (parent->d_func()->scene && parent->d_func()->scene != scene) {
  1137         if (parent->d_func()->scene && parent->d_func()->scene != scene) {
  1094             // Move this item to its new parent's scene
  1138             // Move this item to its new parent's scene
  1095             parent->d_func()->scene->addItem(q);
  1139             parent->d_func()->scene->addItem(q);
  1096             implicitUpdate = true;
       
  1097         } else if (!parent->d_func()->scene && scene) {
  1140         } else if (!parent->d_func()->scene && scene) {
  1098             // Remove this item from its former scene
  1141             // Remove this item from its former scene
  1099             scene->removeItem(q);
  1142             scene->removeItem(q);
  1100         }
  1143         }
  1101 
  1144 
  1102         parent->d_ptr->addChild(q);
  1145         parent->d_ptr->addChild(q);
  1103         parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant);
  1146         if (thisPointerVariant)
       
  1147             parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant);
  1104         if (scene) {
  1148         if (scene) {
  1105             if (!implicitUpdate)
       
  1106                 scene->d_func()->markDirty(q_ptr);
       
  1107 
       
  1108             // Re-enable scene pos notifications for new ancestors
  1149             // Re-enable scene pos notifications for new ancestors
  1109             if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
  1150             if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
  1110                 scene->d_func()->setScenePosItemEnabled(q, true);
  1151                 scene->d_func()->setScenePosItemEnabled(q, true);
  1111         }
  1152         }
  1112 
  1153 
       
  1154         // Propagate dirty flags to the new parent
       
  1155         markParentDirty(/*updateBoundingRect=*/true);
       
  1156 
  1113         // Inherit ancestor flags from the new parent.
  1157         // Inherit ancestor flags from the new parent.
  1114         updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
  1158         updateAncestorFlags();
  1115         updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
       
  1116         updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  1117         updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations);
       
  1118 
  1159 
  1119         // Update item visible / enabled.
  1160         // Update item visible / enabled.
  1120         if (parent->isVisible() != visible) {
  1161         if (parent->d_ptr->visible != visible) {
  1121             if (!parent->isVisible() || !explicitlyHidden)
  1162             if (!parent->d_ptr->visible || !explicitlyHidden)
  1122                 setVisibleHelper(parent->isVisible(), /* explicit = */ false, /* update = */ !implicitUpdate);
  1163                 setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false);
  1123         }
  1164         }
  1124         if (parent->isEnabled() != enabled) {
  1165         if (parent->isEnabled() != enabled) {
  1125             if (!parent->isEnabled() || !explicitlyDisabled)
  1166             if (!parent->d_ptr->enabled || !explicitlyDisabled)
  1126                 setEnabledHelper(parent->isEnabled(), /* explicit = */ false, /* update = */ !implicitUpdate);
  1167                 setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false);
  1127         }
  1168         }
  1128 
  1169 
  1129         // Auto-activate if visible and the parent is active.
  1170         // Auto-activate if visible and the parent is active.
  1130         if (q->isVisible() && parent->isActive())
  1171         if (visible && parent->isActive())
  1131             q->setActive(true);
  1172             q->setActive(true);
  1132     } else {
  1173     } else {
  1133         // Inherit ancestor flags from the new parent.
  1174         // Inherit ancestor flags from the new parent.
  1134         updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
  1175         updateAncestorFlags();
  1135         updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
       
  1136         updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  1137         updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations);
       
  1138 
  1176 
  1139         if (!inDestructor) {
  1177         if (!inDestructor) {
  1140             // Update item visible / enabled.
  1178             // Update item visible / enabled.
  1141             if (!visible && !explicitlyHidden)
  1179             if (!visible && !explicitlyHidden)
  1142                 setVisibleHelper(true, /* explicit = */ false);
  1180                 setVisibleHelper(true, /* explicit = */ false);
  1143             if (!enabled && !explicitlyDisabled)
  1181             if (!enabled && !explicitlyDisabled)
  1144                 setEnabledHelper(true, /* explicit = */ false);
  1182                 setEnabledHelper(true, /* explicit = */ false);
  1145 
       
  1146             // If the item is being deleted, the whole scene will be updated.
       
  1147             if (scene)
       
  1148                 scene->d_func()->markDirty(q_ptr);
       
  1149         }
  1183         }
  1150     }
  1184     }
  1151 
  1185 
  1152     // Resolve depth.
       
  1153     invalidateDepthRecursively();
       
  1154     dirtySceneTransform = 1;
  1186     dirtySceneTransform = 1;
  1155 
  1187 
  1156     // Restore the sub focus chain.
  1188     // Restore the sub focus chain.
  1157     if (subFocusItem) {
  1189     if (subFocusItem) {
  1158         subFocusItem->d_ptr->setSubFocus(newParent);
  1190         subFocusItem->d_ptr->setSubFocus(newParent);
  1159         if (parent && parent->isActive())
  1191         if (parent && parent->isActive())
  1160             subFocusItem->setFocus();
  1192             subFocusItem->setFocus();
  1161     }
  1193     }
  1162 
  1194 
  1163     // Deliver post-change notification
  1195     // Deliver post-change notification
  1164     q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant);
  1196     if (newParentVariant)
       
  1197         q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant);
  1165 
  1198 
  1166     if (isObject)
  1199     if (isObject)
  1167         emit static_cast<QGraphicsObject *>(q)->parentChanged();
  1200         emit static_cast<QGraphicsObject *>(q)->parentChanged();
  1168 }
  1201 }
  1169 
  1202 
  1348 
  1381 
  1349     if (d_ptr->scene) {
  1382     if (d_ptr->scene) {
  1350         d_ptr->scene->d_func()->removeItemHelper(this);
  1383         d_ptr->scene->d_func()->removeItemHelper(this);
  1351     } else {
  1384     } else {
  1352         d_ptr->resetFocusProxy();
  1385         d_ptr->resetFocusProxy();
  1353         d_ptr->setParentItemHelper(0);
  1386         setParentItem(0);
  1354     }
  1387     }
  1355 
  1388 
  1356 #ifndef QT_NO_GRAPHICSEFFECT
  1389 #ifndef QT_NO_GRAPHICSEFFECT
  1357     delete d_ptr->graphicsEffect;
  1390     delete d_ptr->graphicsEffect;
  1358 #endif //QT_NO_GRAPHICSEFFECT
  1391 #endif //QT_NO_GRAPHICSEFFECT
  1363             delete t;
  1396             delete t;
  1364         }
  1397         }
  1365     }
  1398     }
  1366     delete d_ptr->transformData;
  1399     delete d_ptr->transformData;
  1367 
  1400 
  1368     qt_dataStore()->data.remove(this);
  1401     if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore())
       
  1402         dataStore->data.remove(this);
  1369 }
  1403 }
  1370 
  1404 
  1371 /*!
  1405 /*!
  1372     Returns the current scene for the item, or 0 if the item is not stored in
  1406     Returns the current scene for the item, or 0 if the item is not stored in
  1373     a scene.
  1407     a scene.
  1541 {
  1575 {
  1542     return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0;
  1576     return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0;
  1543 }
  1577 }
  1544 
  1578 
  1545 /*!
  1579 /*!
  1546     Sets this item's parent item to \a parent. If this item already has a
  1580   Sets this item's parent item to \a newParent. If this item already
  1547     parent, it is first removed from the previous parent. If \a parent is 0,
  1581   has a parent, it is first removed from the previous parent. If \a
  1548     this item will become a top-level item.
  1582   newParent is 0, this item will become a top-level item.
  1549 
  1583 
  1550     Note that this implicitly adds this graphics item to the scene of
  1584   Note that this implicitly adds this graphics item to the scene of
  1551     the parent. You should not \l{QGraphicsScene::addItem()}{add} the
  1585   the parent. You should not \l{QGraphicsScene::addItem()}{add} the
  1552     item to the scene yourself.
  1586   item to the scene yourself.
  1553 
  1587 
  1554     Calling this function on an item that is an ancestor of \a parent have undefined behaviour.
  1588   Calling this function on an item that is an ancestor of \a newParent
  1555 
  1589   have undefined behaviour.
  1556     \sa parentItem(), childItems()
  1590 
  1557 */
  1591   \sa parentItem(), childItems()
  1558 void QGraphicsItem::setParentItem(QGraphicsItem *parent)
  1592 */
  1559 {
  1593 void QGraphicsItem::setParentItem(QGraphicsItem *newParent)
  1560     d_ptr->setParentItemHelper(parent);
  1594 {
       
  1595     if (newParent == this) {
       
  1596         qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
       
  1597         return;
       
  1598     }
       
  1599     if (newParent == d_ptr->parent)
       
  1600         return;
       
  1601 
       
  1602     const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange,
       
  1603                                                qVariantFromValue<QGraphicsItem *>(newParent)));
       
  1604     newParent = qVariantValue<QGraphicsItem *>(newParentVariant);
       
  1605     if (newParent == d_ptr->parent)
       
  1606         return;
       
  1607 
       
  1608     const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this));
       
  1609     d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant);
  1561 }
  1610 }
  1562 
  1611 
  1563 /*!
  1612 /*!
  1564     \obsolete
  1613     \obsolete
  1565 
  1614 
  1605 
  1654 
  1606     \sa QGraphicsWidget::windowFlags()
  1655     \sa QGraphicsWidget::windowFlags()
  1607 */
  1656 */
  1608 bool QGraphicsItem::isWindow() const
  1657 bool QGraphicsItem::isWindow() const
  1609 {
  1658 {
  1610     return isWidget() && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
  1659     return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
  1611 }
  1660 }
  1612 
  1661 
  1613 /*!
  1662 /*!
  1614     \since 4.6
  1663     \since 4.6
  1615     Returns true if the item is a panel; otherwise returns false.
  1664     Returns true if the item is a panel; otherwise returns false.
  1642     \sa flags(), setFlags()
  1691     \sa flags(), setFlags()
  1643 */
  1692 */
  1644 void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled)
  1693 void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled)
  1645 {
  1694 {
  1646     if (enabled)
  1695     if (enabled)
  1647         setFlags(flags() | flag);
  1696         setFlags(GraphicsItemFlags(d_ptr->flags) | flag);
  1648     else
  1697     else
  1649         setFlags(flags() & ~flag);
  1698         setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag);
  1650 }
  1699 }
  1651 
  1700 
  1652 /*!
  1701 /*!
  1653     \internal
  1702     \internal
  1654 
  1703 
  1691     if (quint32(d_ptr->flags) == quint32(flags))
  1740     if (quint32(d_ptr->flags) == quint32(flags))
  1692         return;
  1741         return;
  1693     flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
  1742     flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
  1694     if (quint32(d_ptr->flags) == quint32(flags))
  1743     if (quint32(d_ptr->flags) == quint32(flags))
  1695         return;
  1744         return;
  1696     if (d_ptr->scene)
  1745     if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
  1697         d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags));
  1746         d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags);
  1698 
  1747 
  1699     // Flags that alter the geometry of the item (or its children).
  1748     // Flags that alter the geometry of the item (or its children).
  1700     const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
  1749     const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
  1701     bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
  1750     bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
  1702     if (fullUpdate)
  1751     if (fullUpdate)
  1703         d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
  1752         d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
  1704 
  1753 
  1705     // Keep the old flags to compare the diff.
  1754     // Keep the old flags to compare the diff.
  1706     GraphicsItemFlags oldFlags = this->flags();
  1755     GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
  1707 
  1756 
  1708     // Update flags.
  1757     // Update flags.
  1709     d_ptr->flags = flags;
  1758     d_ptr->flags = flags;
  1710 
  1759 
  1711     if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
  1760     if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
  1730         // Item children clipping changes. Propagate the ancestor flag to
  1779         // Item children clipping changes. Propagate the ancestor flag to
  1731         // all children.
  1780         // all children.
  1732         d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
  1781         d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
  1733     }
  1782     }
  1734 
  1783 
       
  1784     if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
       
  1785         // NB! We change the flags directly here, so we must also update d_ptr->flags.
       
  1786         // Note that this has do be done before the ItemStacksBehindParent check
       
  1787         // below; otherwise we will loose the change.
       
  1788 
       
  1789         // Update stack-behind.
       
  1790         if (d_ptr->z < qreal(0.0))
       
  1791             flags |= ItemStacksBehindParent;
       
  1792         else
       
  1793             flags &= ~ItemStacksBehindParent;
       
  1794         d_ptr->flags = flags;
       
  1795     }
       
  1796 
  1735     if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
  1797     if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
       
  1798         // NB! This check has to come after the ItemNegativeZStacksBehindParent
       
  1799         // check above. Be careful.
       
  1800 
  1736         // Ensure child item sorting is up to date when toggling this flag.
  1801         // Ensure child item sorting is up to date when toggling this flag.
  1737         if (d_ptr->parent)
  1802         if (d_ptr->parent)
  1738             d_ptr->parent->d_ptr->needSortChildren = 1;
  1803             d_ptr->parent->d_ptr->needSortChildren = 1;
  1739         else if (d_ptr->scene)
  1804         else if (d_ptr->scene)
  1740             d_ptr->scene->d_func()->needSortTopLevelItems = 1;
  1805             d_ptr->scene->d_func()->needSortTopLevelItems = 1;
  1744         // Update input method sensitivity in any views.
  1809         // Update input method sensitivity in any views.
  1745         if (d_ptr->scene)
  1810         if (d_ptr->scene)
  1746             d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
  1811             d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
  1747     }
  1812     }
  1748 
  1813 
  1749     if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
       
  1750         // Update stack-behind.
       
  1751         setFlag(ItemStacksBehindParent, d_ptr->z < qreal(0.0));
       
  1752     }
       
  1753 
  1814 
  1754     if ((d_ptr->panelModality != NonModal)
  1815     if ((d_ptr->panelModality != NonModal)
  1755         && d_ptr->scene
  1816         && d_ptr->scene
  1756         && (flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
  1817         && (flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
  1757         // update the panel's modal state
  1818         // update the panel's modal state
  1820 {
  1881 {
  1821     CacheMode lastMode = CacheMode(d_ptr->cacheMode);
  1882     CacheMode lastMode = CacheMode(d_ptr->cacheMode);
  1822     d_ptr->cacheMode = mode;
  1883     d_ptr->cacheMode = mode;
  1823     bool noVisualChange = (mode == NoCache && lastMode == NoCache)
  1884     bool noVisualChange = (mode == NoCache && lastMode == NoCache)
  1824                           || (mode == NoCache && lastMode == DeviceCoordinateCache)
  1885                           || (mode == NoCache && lastMode == DeviceCoordinateCache)
  1825                           || (mode == DeviceCoordinateCache && lastMode == NoCache);
  1886                           || (mode == DeviceCoordinateCache && lastMode == NoCache)
       
  1887                           || (mode == DeviceCoordinateCache && lastMode == DeviceCoordinateCache);
  1826     if (mode == NoCache) {
  1888     if (mode == NoCache) {
  1827         d_ptr->removeExtraItemCache();
  1889         d_ptr->removeExtraItemCache();
  1828     } else {
  1890     } else {
  1829         QGraphicsItemCache *cache = d_ptr->extraItemCache();
  1891         QGraphicsItemCache *cache = d_ptr->extraItemCache();
  1830 
  1892 
  2114     // Schedule redrawing
  2176     // Schedule redrawing
  2115     if (update) {
  2177     if (update) {
  2116         QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
  2178         QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
  2117         if (c)
  2179         if (c)
  2118             c->purge();
  2180             c->purge();
  2119         if (scene)
  2181         if (scene) {
       
  2182 #ifndef QT_NO_GRAPHICSEFFECT
       
  2183             invalidateParentGraphicsEffectsRecursively();
       
  2184 #endif //QT_NO_GRAPHICSEFFECT
  2120             scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
  2185             scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
       
  2186         }
  2121     }
  2187     }
  2122 
  2188 
  2123     // Certain properties are dropped as an item becomes invisible.
  2189     // Certain properties are dropped as an item becomes invisible.
       
  2190     bool hasFocus = q_ptr->hasFocus();
  2124     if (!newVisible) {
  2191     if (!newVisible) {
  2125         if (scene) {
  2192         if (scene) {
  2126             if (scene->d_func()->mouseGrabberItems.contains(q))
  2193             if (scene->d_func()->mouseGrabberItems.contains(q))
  2127                 q->ungrabMouse();
  2194                 q->ungrabMouse();
  2128             if (scene->d_func()->keyboardGrabberItems.contains(q))
  2195             if (scene->d_func()->keyboardGrabberItems.contains(q))
  2129                 q->ungrabKeyboard();
  2196                 q->ungrabKeyboard();
  2130             if (q->isPanel() && panelModality != QGraphicsItem::NonModal)
  2197             if (q->isPanel() && panelModality != QGraphicsItem::NonModal)
  2131                 scene->d_func()->leaveModal(q_ptr);
  2198                 scene->d_func()->leaveModal(q_ptr);
  2132         }
  2199         }
  2133         if (q_ptr->hasFocus() && scene) {
  2200         if (hasFocus && scene) {
  2134             // Hiding the closest non-panel ancestor of the focus item
  2201             // Hiding the closest non-panel ancestor of the focus item
  2135             QGraphicsItem *focusItem = scene->focusItem();
  2202             QGraphicsItem *focusItem = scene->focusItem();
  2136             bool clear = true;
  2203             bool clear = true;
  2137             if (isWidget && !focusItem->isPanel()) {
  2204             if (isWidget && !focusItem->isPanel()) {
  2138                 do {
  2205                 do {
  2141                         break;
  2208                         break;
  2142                     }
  2209                     }
  2143                 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
  2210                 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
  2144             }
  2211             }
  2145             if (clear)
  2212             if (clear)
  2146                 q_ptr->clearFocus();
  2213                 clearFocusHelper(/* giveFocusToParent = */ false);
  2147         }
  2214         }
  2148         if (q_ptr->isSelected())
  2215         if (q_ptr->isSelected())
  2149             q_ptr->setSelected(false);
  2216             q_ptr->setSelected(false);
  2150     } else {
  2217     } else {
  2151         geometryChanged = 1;
  2218         geometryChanged = 1;
  2179                 scene->setActivePanel(parent);
  2246                 scene->setActivePanel(parent);
  2180         }
  2247         }
  2181     }
  2248     }
  2182 
  2249 
  2183     // Enable subfocus
  2250     // Enable subfocus
  2184     if (scene && newVisible) {
  2251     if (scene) {
  2185         QGraphicsItem *p = parent;
  2252         if (newVisible) {
  2186         bool done = false;
  2253             // Item is shown
  2187         while (p) {
  2254             QGraphicsItem *p = parent;
  2188             if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
  2255             bool done = false;
  2189                 QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
  2256             while (p) {
  2190                 if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
  2257                 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
  2191                     done = true;
  2258                     QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
  2192                     while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
  2259                     if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
  2193                         fsi = fsi->d_ptr->focusScopeItem;
  2260                         done = true;
  2194                     scene->setFocusItem(fsi);
  2261                         while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
       
  2262                             fsi = fsi->d_ptr->focusScopeItem;
       
  2263                         fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
       
  2264                                                    /* focusFromShow = */ true);
       
  2265                     }
       
  2266                     break;
  2195                 }
  2267                 }
  2196                 break;
  2268                 p = p->d_ptr->parent;
  2197             }
  2269             }
  2198             p = p->d_ptr->parent;
  2270             if (!done) {
  2199         }
  2271                 QGraphicsItem *fi = subFocusItem;
  2200         if (!done) {
  2272                 if (fi && fi != scene->focusItem()) {
  2201             QGraphicsItem *fi = subFocusItem;
  2273                     scene->setFocusItem(fi);
  2202             if (fi && fi != scene->focusItem()) {
  2274                 }
  2203                 scene->setFocusItem(fi);
  2275             }
       
  2276         } else {
       
  2277             // Item is hidden
       
  2278             if (hasFocus) {
       
  2279                 QGraphicsItem *p = parent;
       
  2280                 while (p) {
       
  2281                     if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
       
  2282                         if (p->d_ptr->visible) {
       
  2283                             p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
       
  2284                                                      /* focusFromShow = */ true);
       
  2285                         }
       
  2286                         break;
       
  2287                     }
       
  2288                     p = p->d_ptr->parent;
       
  2289                 }
  2204             }
  2290             }
  2205         }
  2291         }
  2206     }
  2292     }
  2207 
  2293 
  2208     // Deliver post-change notification.
  2294     // Deliver post-change notification.
  2513 
  2599 
  2514     // No change? Done.
  2600     // No change? Done.
  2515     if (newOpacity == d_ptr->opacity)
  2601     if (newOpacity == d_ptr->opacity)
  2516         return;
  2602         return;
  2517 
  2603 
       
  2604     bool wasFullyTransparent = d_ptr->isOpacityNull();
  2518     d_ptr->opacity = newOpacity;
  2605     d_ptr->opacity = newOpacity;
  2519 
  2606 
  2520     // Notify change.
  2607     // Notify change.
  2521     itemChange(ItemOpacityHasChanged, newOpacityVariant);
  2608     itemChange(ItemOpacityHasChanged, newOpacityVariant);
  2522 
  2609 
  2523     // Update.
  2610     // Update.
  2524     if (d_ptr->scene) {
  2611     if (d_ptr->scene) {
  2525 #ifndef QT_NO_GRAPHICSEFFECT
  2612 #ifndef QT_NO_GRAPHICSEFFECT
  2526         d_ptr->invalidateGraphicsEffectsRecursively();
  2613         d_ptr->invalidateParentGraphicsEffectsRecursively();
       
  2614         if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren))
       
  2615             d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged);
  2527 #endif //QT_NO_GRAPHICSEFFECT
  2616 #endif //QT_NO_GRAPHICSEFFECT
  2528         d_ptr->scene->d_func()->markDirty(this, QRectF(),
  2617         d_ptr->scene->d_func()->markDirty(this, QRectF(),
  2529                                           /*invalidateChildren=*/true,
  2618                                           /*invalidateChildren=*/true,
  2530                                           /*force=*/false,
  2619                                           /*force=*/false,
  2531                                           /*ignoreOpacity=*/true);
  2620                                           /*ignoreOpacity=*/d_ptr->isOpacityNull());
       
  2621         if (wasFullyTransparent)
       
  2622             d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
  2532     }
  2623     }
  2533 
  2624 
  2534     if (d_ptr->isObject)
  2625     if (d_ptr->isObject)
  2535         emit static_cast<QGraphicsObject *>(this)->opacityChanged();
  2626         emit static_cast<QGraphicsObject *>(this)->opacityChanged();
  2536 }
  2627 }
  2566         return;
  2657         return;
  2567 
  2658 
  2568     if (d_ptr->graphicsEffect) {
  2659     if (d_ptr->graphicsEffect) {
  2569         delete d_ptr->graphicsEffect;
  2660         delete d_ptr->graphicsEffect;
  2570         d_ptr->graphicsEffect = 0;
  2661         d_ptr->graphicsEffect = 0;
       
  2662     } else if (d_ptr->parent) {
       
  2663         d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
  2571     }
  2664     }
  2572 
  2665 
  2573     if (effect) {
  2666     if (effect) {
  2574         // Set new effect.
  2667         // Set new effect.
  2575         QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
  2668         QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
  2578         effect->d_func()->setGraphicsEffectSource(source);
  2671         effect->d_func()->setGraphicsEffectSource(source);
  2579         prepareGeometryChange();
  2672         prepareGeometryChange();
  2580     }
  2673     }
  2581 }
  2674 }
  2582 #endif //QT_NO_GRAPHICSEFFECT
  2675 #endif //QT_NO_GRAPHICSEFFECT
       
  2676 
       
  2677 void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively()
       
  2678 {
       
  2679 #ifndef QT_NO_GRAPHICSEFFECT
       
  2680     QGraphicsItemPrivate *itemPrivate = this;
       
  2681     do {
       
  2682         // parent chain already notified?
       
  2683         if (itemPrivate->mayHaveChildWithGraphicsEffect)
       
  2684             return;
       
  2685         itemPrivate->mayHaveChildWithGraphicsEffect = 1;
       
  2686     } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
       
  2687 #endif
       
  2688 }
  2583 
  2689 
  2584 /*!
  2690 /*!
  2585     \internal
  2691     \internal
  2586     \since 4.6
  2692     \since 4.6
  2587     Returns the effective bounding rect of the given item space rect.
  2693     Returns the effective bounding rect of the given item space rect.
  2995 
  3101 
  2996     \sa focusItem(), setFocus(), QGraphicsScene::setFocusItem(), isActive()
  3102     \sa focusItem(), setFocus(), QGraphicsScene::setFocusItem(), isActive()
  2997 */
  3103 */
  2998 bool QGraphicsItem::hasFocus() const
  3104 bool QGraphicsItem::hasFocus() const
  2999 {
  3105 {
       
  3106     if (!d_ptr->scene || !d_ptr->scene->isActive())
       
  3107         return false;
       
  3108 
  3000     if (d_ptr->focusProxy)
  3109     if (d_ptr->focusProxy)
  3001         return d_ptr->focusProxy->hasFocus();
  3110         return d_ptr->focusProxy->hasFocus();
  3002     return isActive() && (d_ptr->scene && d_ptr->scene->focusItem() == this);
  3111 
       
  3112     if (d_ptr->scene->d_func()->focusItem != this)
       
  3113         return false;
       
  3114 
       
  3115     return panel() == d_ptr->scene->d_func()->activePanel;
  3003 }
  3116 }
  3004 
  3117 
  3005 /*!
  3118 /*!
  3006     Gives keyboard input focus to this item. The \a focusReason argument will
  3119     Gives keyboard input focus to this item. The \a focusReason argument will
  3007     be passed into any \l{QFocusEvent}{focus event} generated by this function;
  3120     be passed into any \l{QFocusEvent}{focus event} generated by this function;
  3022 
  3135 
  3023     \sa clearFocus(), hasFocus(), focusItem(), focusProxy()
  3136     \sa clearFocus(), hasFocus(), focusItem(), focusProxy()
  3024 */
  3137 */
  3025 void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
  3138 void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
  3026 {
  3139 {
  3027     d_ptr->setFocusHelper(focusReason, /* climb = */ true);
  3140     d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromShow = */ false);
  3028 }
  3141 }
  3029 
  3142 
  3030 /*!
  3143 /*!
  3031     \internal
  3144     \internal
  3032 */
  3145 */
  3033 void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb)
  3146 void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromShow)
  3034 {
  3147 {
  3035     // Disabled / unfocusable items cannot accept focus.
  3148     // Disabled / unfocusable items cannot accept focus.
  3036     if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
  3149     if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
  3037         return;
  3150         return;
  3038 
  3151 
  3048     // Update focus scope item ptr.
  3161     // Update focus scope item ptr.
  3049     QGraphicsItem *p = parent;
  3162     QGraphicsItem *p = parent;
  3050     while (p) {
  3163     while (p) {
  3051         if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
  3164         if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
  3052             p->d_ptr->focusScopeItem = q_ptr;
  3165             p->d_ptr->focusScopeItem = q_ptr;
  3053             if (!p->focusItem()) {
  3166             if (!p->focusItem() && !focusFromShow) {
  3054                 // If you call setFocus on a child of a focus scope that
  3167                 // If you call setFocus on a child of a focus scope that
  3055                 // doesn't currently have a focus item, then stop.
  3168                 // doesn't currently have a focus item, then stop.
  3056                 return;
  3169                 return;
  3057             }
  3170             }
  3058             break;
  3171             break;
  3089 
  3202 
  3090     \sa setFocus(), hasFocus(), QGraphicsWidget::focusPolicy
  3203     \sa setFocus(), hasFocus(), QGraphicsWidget::focusPolicy
  3091 */
  3204 */
  3092 void QGraphicsItem::clearFocus()
  3205 void QGraphicsItem::clearFocus()
  3093 {
  3206 {
  3094     // Pass focus to the closest parent focus scope.
  3207     d_ptr->clearFocusHelper(/* giveFocusToParent = */ true);
  3095     if (!d_ptr->inDestructor) {
  3208 }
  3096         QGraphicsItem *p = d_ptr->parent;
  3209 
  3097         while (p) {
  3210 /*!
  3098             if (p->flags() & ItemIsFocusScope) {
  3211     \internal
  3099                 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false);
  3212 */
  3100                 return;
  3213 void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent)
       
  3214 {
       
  3215     if (giveFocusToParent) {
       
  3216         // Pass focus to the closest parent focus scope
       
  3217         if (!inDestructor) {
       
  3218             QGraphicsItem *p = parent;
       
  3219             while (p) {
       
  3220                 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
       
  3221                     p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false,
       
  3222                                              /* focusFromShow = */ false);
       
  3223                     return;
       
  3224                 }
       
  3225                 p = p->d_ptr->parent;
  3101             }
  3226             }
  3102             p = p->d_ptr->parent;
       
  3103         }
  3227         }
  3104     }
  3228     }
  3105 
  3229 
  3106     // Invisible items with focus must explicitly clear subfocus.
  3230     // Invisible items with focus must explicitly clear subfocus.
  3107     d_ptr->clearSubFocus(this);
  3231     clearSubFocus(q_ptr);
  3108 
  3232 
  3109     if (hasFocus()) {
  3233     if (q_ptr->hasFocus()) {
  3110         // If this item has the scene's input focus, clear it.
  3234         // If this item has the scene's input focus, clear it.
  3111         d_ptr->scene->setFocusItem(0);
  3235         scene->setFocusItem(0);
  3112     }
  3236     }
  3113 }
  3237 }
  3114 
  3238 
  3115 /*!
  3239 /*!
  3116     \since 4.6
  3240     \since 4.6
  4255     const QVariant newZVariant(itemChange(ItemZValueChange, z));
  4379     const QVariant newZVariant(itemChange(ItemZValueChange, z));
  4256     qreal newZ = newZVariant.toReal();
  4380     qreal newZ = newZVariant.toReal();
  4257     if (newZ == d_ptr->z)
  4381     if (newZ == d_ptr->z)
  4258         return;
  4382         return;
  4259 
  4383 
  4260     if (d_ptr->scene) {
  4384     if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
  4261         // Z Value has changed, we have to notify the index.
  4385         // Z Value has changed, we have to notify the index.
  4262         d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant);
  4386         d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
  4263     }
  4387     }
  4264 
  4388 
  4265     d_ptr->z = newZ;
  4389     d_ptr->z = newZ;
  4266     if (d_ptr->parent)
  4390     if (d_ptr->parent)
  4267         d_ptr->parent->d_ptr->needSortChildren = 1;
  4391         d_ptr->parent->d_ptr->needSortChildren = 1;
  5024 
  5148 
  5025 /*!
  5149 /*!
  5026     \internal
  5150     \internal
  5027 */
  5151 */
  5028 #ifndef QT_NO_GRAPHICSEFFECT
  5152 #ifndef QT_NO_GRAPHICSEFFECT
  5029 void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively()
  5153 void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
  5030 {
  5154 {
  5031     QGraphicsItemPrivate *itemPrivate = this;
  5155     QGraphicsItemPrivate *itemPrivate = this;
  5032     do {
  5156     do {
  5033         if (itemPrivate->graphicsEffect) {
  5157         if (itemPrivate->graphicsEffect) {
  5034             itemPrivate->notifyInvalidated = 1;
  5158             itemPrivate->notifyInvalidated = 1;
  5035 
  5159 
  5036             if (!itemPrivate->updateDueToGraphicsEffect)
  5160             if (!itemPrivate->updateDueToGraphicsEffect)
  5037                 static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
  5161                 static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
  5038         }
  5162         }
  5039     } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
  5163     } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
       
  5164 }
       
  5165 
       
  5166 void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason)
       
  5167 {
       
  5168     if (!mayHaveChildWithGraphicsEffect)
       
  5169         return;
       
  5170 
       
  5171     for (int i = 0; i < children.size(); ++i) {
       
  5172         QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data();
       
  5173         if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity))
       
  5174             continue;
       
  5175         if (childPrivate->graphicsEffect) {
       
  5176             childPrivate->notifyInvalidated = 1;
       
  5177             static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
       
  5178         }
       
  5179 
       
  5180         childPrivate->invalidateChildGraphicsEffectsRecursively(reason);
       
  5181     }
  5040 }
  5182 }
  5041 #endif //QT_NO_GRAPHICSEFFECT
  5183 #endif //QT_NO_GRAPHICSEFFECT
  5042 
  5184 
  5043 /*!
  5185 /*!
  5044     \internal
  5186     \internal
  5081     // number is equal to the size of the children list.
  5223     // number is equal to the size of the children list.
  5082     ensureSequentialSiblingIndex();
  5224     ensureSequentialSiblingIndex();
  5083     needSortChildren = 1; // ### maybe 0
  5225     needSortChildren = 1; // ### maybe 0
  5084     child->d_ptr->siblingIndex = children.size();
  5226     child->d_ptr->siblingIndex = children.size();
  5085     children.append(child);
  5227     children.append(child);
       
  5228     if (isObject)
       
  5229         emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
  5086 }
  5230 }
  5087 
  5231 
  5088 /*!
  5232 /*!
  5089     \internal
  5233     \internal
  5090 
  5234 
  5103         children.removeOne(child);
  5247         children.removeOne(child);
  5104     // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
  5248     // 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.
  5249     // the child is not guaranteed to be at the index after the list is sorted.
  5106     // (see ensureSortedChildren()).
  5250     // (see ensureSortedChildren()).
  5107     child->d_ptr->siblingIndex = -1;
  5251     child->d_ptr->siblingIndex = -1;
       
  5252     if (isObject)
       
  5253         emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
  5108 }
  5254 }
  5109 
  5255 
  5110 /*!
  5256 /*!
  5111     \internal
  5257     \internal
  5112 */
  5258 */
  5280     if (rect.isEmpty() && !rect.isNull())
  5426     if (rect.isEmpty() && !rect.isNull())
  5281         return;
  5427         return;
  5282 
  5428 
  5283     // Make sure we notify effects about invalidated source.
  5429     // Make sure we notify effects about invalidated source.
  5284 #ifndef QT_NO_GRAPHICSEFFECT
  5430 #ifndef QT_NO_GRAPHICSEFFECT
  5285     d_ptr->invalidateGraphicsEffectsRecursively();
  5431     d_ptr->invalidateParentGraphicsEffectsRecursively();
  5286 #endif //QT_NO_GRAPHICSEFFECT
  5432 #endif //QT_NO_GRAPHICSEFFECT
  5287 
  5433 
  5288     if (CacheMode(d_ptr->cacheMode) != NoCache) {
  5434     if (CacheMode(d_ptr->cacheMode) != NoCache) {
  5289         // Invalidate cache.
  5435         // Invalidate cache.
  5290         QGraphicsItemCache *cache = d_ptr->extraItemCache();
  5436         QGraphicsItemCache *cache = d_ptr->extraItemCache();
  7156         d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
  7302         d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
  7157         d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper;
  7303         d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper;
  7158 
  7304 
  7159         QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
  7305         QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
  7160         scenePrivate->index->prepareBoundingRectChange(this);
  7306         scenePrivate->index->prepareBoundingRectChange(this);
  7161         scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true);
  7307         scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false,
       
  7308                                 /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false,
       
  7309                                 /*updateBoundingRect=*/true);
  7162 
  7310 
  7163         // For compatibility reasons, we have to update the item's old geometry
  7311         // 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.
  7312         // 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
  7313         // Note that this has to be done *after* markDirty to ensure that
  7166         // _q_processDirtyItems is called before _q_emitUpdated.
  7314         // _q_processDirtyItems is called before _q_emitUpdated.
  7173                 d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect()));
  7321                 d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect()));
  7174             }
  7322             }
  7175         }
  7323         }
  7176     }
  7324     }
  7177 
  7325 
  7178     QGraphicsItem *parent = this;
  7326     d_ptr->markParentDirty(/*updateBoundingRect=*/true);
  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     }
       
  7191 }
  7327 }
  7192 
  7328 
  7193 /*!
  7329 /*!
  7194     \internal
  7330     \internal
  7195 
  7331 
  7320         QGestureManager *manager = QGestureManager::instance();
  7456         QGestureManager *manager = QGestureManager::instance();
  7321         manager->cleanupCachedGestures(this, gesture);
  7457         manager->cleanupCachedGestures(this, gesture);
  7322     }
  7458     }
  7323 }
  7459 }
  7324 
  7460 
       
  7461 void QGraphicsItemPrivate::append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item)
       
  7462 {
       
  7463     QGraphicsItemPrivate::get(item)->setParentItemHelper(static_cast<QGraphicsObject *>(list->object), /*newParentVariant=*/0, /*thisPointerVariant=*/0);
       
  7464 }
       
  7465 
       
  7466 /*!
       
  7467     Returns a list of this item's children.
       
  7468 
       
  7469     The items are sorted by stacking order. This takes into account both the
       
  7470     items' insertion order and their Z-values.
       
  7471 
       
  7472 */
       
  7473 QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList()
       
  7474 {
       
  7475     Q_Q(QGraphicsItem);
       
  7476     if (isObject) {
       
  7477         QGraphicsObject *that = static_cast<QGraphicsObject *>(q);
       
  7478         return QDeclarativeListProperty<QGraphicsObject>(that, &children, QGraphicsItemPrivate::append);
       
  7479     } else {
       
  7480         //QGraphicsItem is not supported for this property
       
  7481         return QDeclarativeListProperty<QGraphicsObject>();
       
  7482     }
       
  7483 }
       
  7484 
       
  7485 /*!
       
  7486   \internal
       
  7487   Returns the width of the item
       
  7488   Reimplemented by QGraphicsWidget
       
  7489 */
       
  7490 qreal QGraphicsItemPrivate::width() const
       
  7491 {
       
  7492     return 0;
       
  7493 }
       
  7494 
       
  7495 /*!
       
  7496   \internal
       
  7497   Set the width of the item
       
  7498   Reimplemented by QGraphicsWidget
       
  7499 */
       
  7500 void QGraphicsItemPrivate::setWidth(qreal w)
       
  7501 {
       
  7502     Q_UNUSED(w);
       
  7503 }
       
  7504 
       
  7505 /*!
       
  7506   \internal
       
  7507   Reset the width of the item
       
  7508   Reimplemented by QGraphicsWidget
       
  7509 */
       
  7510 void QGraphicsItemPrivate::resetWidth()
       
  7511 {
       
  7512 }
       
  7513 
       
  7514 /*!
       
  7515   \internal
       
  7516   Returns the height of the item
       
  7517   Reimplemented by QGraphicsWidget
       
  7518 */
       
  7519 qreal QGraphicsItemPrivate::height() const
       
  7520 {
       
  7521     return 0;
       
  7522 }
       
  7523 
       
  7524 /*!
       
  7525   \internal
       
  7526   Set the height of the item
       
  7527   Reimplemented by QGraphicsWidget
       
  7528 */
       
  7529 void QGraphicsItemPrivate::setHeight(qreal h)
       
  7530 {
       
  7531     Q_UNUSED(h);
       
  7532 }
       
  7533 
       
  7534 /*!
       
  7535   \internal
       
  7536   Reset the height of the item
       
  7537   Reimplemented by QGraphicsWidget
       
  7538 */
       
  7539 void QGraphicsItemPrivate::resetHeight()
       
  7540 {
       
  7541 }
       
  7542 
  7325 /*!
  7543 /*!
  7326   \property QGraphicsObject::parent
  7544   \property QGraphicsObject::parent
  7327   \brief the parent of the item
  7545   \brief the parent of the item
  7328 
  7546 
  7329   \note The item's parent is set independently of the parent object returned
  7547   \note The item's parent is set independently of the parent object returned
  7506   origin for scale and rotation.
  7724   origin for scale and rotation.
  7507 
  7725 
  7508   \sa scale, rotation, QGraphicsItem::transformOriginPoint()
  7726   \sa scale, rotation, QGraphicsItem::transformOriginPoint()
  7509 */
  7727 */
  7510 
  7728 
       
  7729 /*!
       
  7730     \fn void QGraphicsObject::widthChanged()
       
  7731     \internal
       
  7732 */
       
  7733 
       
  7734 /*!
       
  7735     \fn void QGraphicsObject::heightChanged()
       
  7736     \internal
       
  7737 */
       
  7738 
       
  7739 /*!
       
  7740 
       
  7741   \fn QGraphicsObject::childrenChanged()
       
  7742 
       
  7743   This signal gets emitted whenever the children list changes
       
  7744   \internal
       
  7745 */
  7511 
  7746 
  7512 /*!
  7747 /*!
  7513     \class QAbstractGraphicsShapeItem
  7748     \class QAbstractGraphicsShapeItem
  7514     \brief The QAbstractGraphicsShapeItem class provides a common base for
  7749     \brief The QAbstractGraphicsShapeItem class provides a common base for
  7515     all path items.
  7750     all path items.
 10713                      info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
 10948                      info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
 10714                      info->drawItem);
 10949                      info->drawItem);
 10715     }
 10950     }
 10716 }
 10951 }
 10717 
 10952 
 10718 QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
 10953 // sourceRect must be in the given coordinate system
 10719                                                  QGraphicsEffect::PixmapPadMode mode) const
 10954 QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
 10720 {
 10955 {
 10721     const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
       
 10722     if (!info && deviceCoordinates) {
       
 10723         // Device coordinates without info not yet supported.
       
 10724         qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
       
 10725         return QPixmap();
       
 10726     }
       
 10727     if (!item->d_ptr->scene)
       
 10728         return QPixmap();
       
 10729     QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
       
 10730 
       
 10731     const QRectF sourceRect = boundingRect(system);
       
 10732     QRectF effectRectF;
 10956     QRectF effectRectF;
 10733 
 10957 
 10734     bool unpadded = false;
 10958     if (unpadded)
       
 10959         *unpadded = false;
       
 10960 
 10735     if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
 10961     if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
 10736         if (info) {
 10962         if (info) {
 10737             effectRectF = item->graphicsEffect()->boundingRectFor(boundingRect(Qt::DeviceCoordinates));
 10963             QRectF deviceRect = system == Qt::DeviceCoordinates ? sourceRect : info->painter->worldTransform().mapRect(sourceRect);
 10738             unpadded = (effectRectF.size() == sourceRect.size());
 10964             effectRectF = item->graphicsEffect()->boundingRectFor(deviceRect);
       
 10965             if (unpadded)
       
 10966                 *unpadded = (effectRectF.size() == sourceRect.size());
 10739             if (info && system == Qt::LogicalCoordinates)
 10967             if (info && system == Qt::LogicalCoordinates)
 10740                 effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
 10968                 effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
 10741         } else {
 10969         } else {
 10742             // no choice but to send a logical coordinate bounding rect to boundingRectFor
 10970             // no choice but to send a logical coordinate bounding rect to boundingRectFor
 10743             effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect);
 10971             effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect);
 10745     } else if (mode == QGraphicsEffect::PadToTransparentBorder) {
 10973     } else if (mode == QGraphicsEffect::PadToTransparentBorder) {
 10746         // adjust by 1.5 to account for cosmetic pens
 10974         // adjust by 1.5 to account for cosmetic pens
 10747         effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
 10975         effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
 10748     } else {
 10976     } else {
 10749         effectRectF = sourceRect;
 10977         effectRectF = sourceRect;
 10750         unpadded = true;
 10978         if (unpadded)
 10751     }
 10979             *unpadded = true;
 10752 
 10980     }
 10753     QRect effectRect = effectRectF.toAlignedRect();
 10981 
       
 10982     return effectRectF.toAlignedRect();
       
 10983 }
       
 10984 
       
 10985 QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
       
 10986                                                  QGraphicsEffect::PixmapPadMode mode) const
       
 10987 {
       
 10988     const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
       
 10989     if (!info && deviceCoordinates) {
       
 10990         // Device coordinates without info not yet supported.
       
 10991         qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
       
 10992         return QPixmap();
       
 10993     }
       
 10994     if (!item->d_ptr->scene)
       
 10995         return QPixmap();
       
 10996     QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
       
 10997 
       
 10998     bool unpadded;
       
 10999     const QRectF sourceRect = boundingRect(system);
       
 11000     QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded);
 10754 
 11001 
 10755     if (offset)
 11002     if (offset)
 10756         *offset = effectRect.topLeft();
 11003         *offset = effectRect.topLeft();
 10757 
 11004 
 10758     bool untransformed = !deviceCoordinates
 11005     bool untransformed = !deviceCoordinates
 10761         if (offset)
 11008         if (offset)
 10762             *offset = boundingRect(system).topLeft().toPoint();
 11009             *offset = boundingRect(system).topLeft().toPoint();
 10763         return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
 11010         return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
 10764     }
 11011     }
 10765 
 11012 
 10766     if (deviceCoordinates) {
       
 10767         // Clip to viewport rect.
       
 10768         int left, top, right, bottom;
       
 10769         effectRect.getCoords(&left, &top, &right, &bottom);
       
 10770         if (left < 0) {
       
 10771             if (offset)
       
 10772                 offset->rx() += -left;
       
 10773             effectRect.setX(0);
       
 10774         }
       
 10775         if (top < 0) {
       
 10776             if (offset)
       
 10777                 offset->ry() += -top;
       
 10778             effectRect.setY(0);
       
 10779         }
       
 10780         // NB! We use +-1 for historical reasons (see QRect documentation).
       
 10781         QPaintDevice *device = info->painter->device();
       
 10782         const int deviceWidth = device->width();
       
 10783         const int deviceHeight = device->height();
       
 10784         if (right + 1 > deviceWidth)
       
 10785             effectRect.setRight(deviceWidth - 1);
       
 10786         if (bottom + 1 > deviceHeight)
       
 10787             effectRect.setBottom(deviceHeight -1);
       
 10788 
       
 10789     }
       
 10790     if (effectRect.isEmpty())
 11013     if (effectRect.isEmpty())
 10791         return QPixmap();
 11014         return QPixmap();
 10792 
 11015 
 10793     QPixmap pixmap(effectRect.size());
 11016     QPixmap pixmap(effectRect.size());
 10794     pixmap.fill(Qt::transparent);
 11017     pixmap.fill(Qt::transparent);