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 |
796 || (int(childFlag) == -1 && handlesChildEvents) |
809 || (int(childFlag) == -1 && handlesChildEvents) |
797 || (int(childFlag) == -2 && filtersDescendantEvents)) |
810 || (int(childFlag) == -2 && filtersDescendantEvents)) |
798 return; |
811 return; |
799 } |
812 } |
800 |
813 |
801 foreach (QGraphicsItem *child, children) |
814 for (int i = 0; i < children.size(); ++i) |
802 child->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false); |
815 children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false); |
|
816 } |
|
817 |
|
818 void QGraphicsItemPrivate::updateAncestorFlags() |
|
819 { |
|
820 int flags = 0; |
|
821 if (parent) { |
|
822 // Inherit the parent's ancestor flags. |
|
823 QGraphicsItemPrivate *pd = parent->d_ptr.data(); |
|
824 flags = pd->ancestorFlags; |
|
825 |
|
826 // Add in flags from the parent. |
|
827 if (pd->filtersDescendantEvents) |
|
828 flags |= AncestorFiltersChildEvents; |
|
829 if (pd->handlesChildEvents) |
|
830 flags |= AncestorHandlesChildEvents; |
|
831 if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape) |
|
832 flags |= AncestorClipsChildren; |
|
833 if (pd->flags & QGraphicsItem::ItemIgnoresTransformations) |
|
834 flags |= AncestorIgnoresTransformations; |
|
835 } |
|
836 |
|
837 if (ancestorFlags == flags) |
|
838 return; // No change; stop propagation. |
|
839 ancestorFlags = flags; |
|
840 |
|
841 // Propagate to children recursively. |
|
842 for (int i = 0; i < children.size(); ++i) |
|
843 children.at(i)->d_ptr->updateAncestorFlags(); |
803 } |
844 } |
804 |
845 |
805 /*! |
846 /*! |
806 \internal |
847 \internal |
807 |
848 |
982 |
1023 |
983 Make sure not to trigger any pure virtual function calls (e.g., |
1024 Make sure not to trigger any pure virtual function calls (e.g., |
984 prepareGeometryChange) if the item is in its destructor, i.e. |
1025 prepareGeometryChange) if the item is in its destructor, i.e. |
985 inDestructor is 1. |
1026 inDestructor is 1. |
986 */ |
1027 */ |
987 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) |
1028 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant, |
|
1029 const QVariant *thisPointerVariant) |
988 { |
1030 { |
989 Q_Q(QGraphicsItem); |
1031 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) |
1032 if (newParent == parent) |
995 return; |
1033 return; |
996 |
1034 |
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) { |
1035 if (scene) { |
1004 // Deliver the change to the index |
1036 // Deliver the change to the index |
1005 scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant); |
1037 if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex) |
|
1038 scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent); |
1006 |
1039 |
1007 // Disable scene pos notifications for old ancestors |
1040 // Disable scene pos notifications for old ancestors |
1008 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) |
1041 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) |
1009 scene->d_func()->setScenePosItemEnabled(q, false); |
1042 scene->d_func()->setScenePosItemEnabled(q, false); |
1010 } |
1043 } |
1018 // removed from the index at a later stage, and the whole scene will be |
1051 // removed from the index at a later stage, and the whole scene will be |
1019 // updated. |
1052 // updated. |
1020 if (!inDestructor) |
1053 if (!inDestructor) |
1021 q_ptr->prepareGeometryChange(); |
1054 q_ptr->prepareGeometryChange(); |
1022 |
1055 |
1023 const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q)); |
|
1024 if (parent) { |
1056 if (parent) { |
1025 // Remove from current parent |
1057 // Remove from current parent |
1026 parent->d_ptr->removeChild(q); |
1058 parent->d_ptr->removeChild(q); |
1027 parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant); |
1059 if (thisPointerVariant) |
|
1060 parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant); |
1028 } |
1061 } |
1029 |
1062 |
1030 // Update toplevelitem list. If this item is being deleted, its parent |
1063 // 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. |
1064 // will be 0 but we don't want to register/unregister it in the TLI list. |
1032 if (scene && !inDestructor) { |
1065 if (scene && !inDestructor) { |
1040 // Ensure any last parent focus scope does not point to this item or any of |
1073 // Ensure any last parent focus scope does not point to this item or any of |
1041 // its descendents. |
1074 // its descendents. |
1042 QGraphicsItem *p = parent; |
1075 QGraphicsItem *p = parent; |
1043 QGraphicsItem *parentFocusScopeItem = 0; |
1076 QGraphicsItem *parentFocusScopeItem = 0; |
1044 while (p) { |
1077 while (p) { |
1045 if (p->flags() & QGraphicsItem::ItemIsFocusScope) { |
1078 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { |
1046 // If this item's focus scope's focus scope item points |
1079 // If this item's focus scope's focus scope item points |
1047 // to this item or a descendent, then clear it. |
1080 // to this item or a descendent, then clear it. |
1048 QGraphicsItem *fsi = p->d_ptr->focusScopeItem; |
1081 QGraphicsItem *fsi = p->d_ptr->focusScopeItem; |
1049 if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) { |
1082 if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) { |
1050 parentFocusScopeItem = fsi; |
1083 parentFocusScopeItem = fsi; |
1053 break; |
1086 break; |
1054 } |
1087 } |
1055 p = p->d_ptr->parent; |
1088 p = p->d_ptr->parent; |
1056 } |
1089 } |
1057 |
1090 |
|
1091 // Update graphics effect optimization flag |
|
1092 if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect)) |
|
1093 newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively(); |
|
1094 |
1058 // Update focus scope item ptr in new scope. |
1095 // Update focus scope item ptr in new scope. |
1059 QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; |
1096 QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; |
1060 if (newFocusScopeItem && newParent) { |
1097 if (newFocusScopeItem && newParent) { |
1061 if (subFocusItem) { |
1098 if (subFocusItem) { |
1062 // Find the subFocusItem's topmost focus scope. |
1099 // Find the subFocusItem's topmost focus scope. |
1063 QGraphicsItem *ancestorScope = 0; |
1100 QGraphicsItem *ancestorScope = 0; |
1064 QGraphicsItem *p = subFocusItem->d_ptr->parent; |
1101 QGraphicsItem *p = subFocusItem->d_ptr->parent; |
1065 while (p) { |
1102 while (p) { |
1066 if (p->flags() & QGraphicsItem::ItemIsFocusScope) |
1103 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) |
1067 ancestorScope = p; |
1104 ancestorScope = p; |
1068 if (p->isPanel()) |
1105 if (p->d_ptr->flags & QGraphicsItem::ItemIsPanel) |
1069 break; |
1106 break; |
1070 p = p->parentItem(); |
1107 p = p->d_ptr->parent; |
1071 } |
1108 } |
1072 if (ancestorScope) |
1109 if (ancestorScope) |
1073 newFocusScopeItem = ancestorScope; |
1110 newFocusScopeItem = ancestorScope; |
1074 } |
1111 } |
1075 |
1112 |
1076 QGraphicsItem *p = newParent; |
1113 QGraphicsItem *p = newParent; |
1077 while (p) { |
1114 while (p) { |
1078 if (p->flags() & QGraphicsItem::ItemIsFocusScope) { |
1115 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { |
1079 p->d_ptr->focusScopeItem = newFocusScopeItem; |
1116 p->d_ptr->focusScopeItem = newFocusScopeItem; |
1080 // Ensure the new item is no longer the subFocusItem. The |
1117 // Ensure the new item is no longer the subFocusItem. The |
1081 // only way to set focus on a child of a focus scope is |
1118 // only way to set focus on a child of a focus scope is |
1082 // by setting focus on the scope itself. |
1119 // by setting focus on the scope itself. |
1083 if (subFocusItem && !p->focusItem()) |
1120 if (subFocusItem && !p->focusItem()) |
1087 p = p->d_ptr->parent; |
1124 p = p->d_ptr->parent; |
1088 } |
1125 } |
1089 } |
1126 } |
1090 |
1127 |
1091 if ((parent = newParent)) { |
1128 if ((parent = newParent)) { |
1092 bool implicitUpdate = false; |
|
1093 if (parent->d_func()->scene && parent->d_func()->scene != scene) { |
1129 if (parent->d_func()->scene && parent->d_func()->scene != scene) { |
1094 // Move this item to its new parent's scene |
1130 // Move this item to its new parent's scene |
1095 parent->d_func()->scene->addItem(q); |
1131 parent->d_func()->scene->addItem(q); |
1096 implicitUpdate = true; |
|
1097 } else if (!parent->d_func()->scene && scene) { |
1132 } else if (!parent->d_func()->scene && scene) { |
1098 // Remove this item from its former scene |
1133 // Remove this item from its former scene |
1099 scene->removeItem(q); |
1134 scene->removeItem(q); |
1100 } |
1135 } |
1101 |
1136 |
1102 parent->d_ptr->addChild(q); |
1137 parent->d_ptr->addChild(q); |
1103 parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant); |
1138 if (thisPointerVariant) |
|
1139 parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant); |
1104 if (scene) { |
1140 if (scene) { |
1105 if (!implicitUpdate) |
|
1106 scene->d_func()->markDirty(q_ptr); |
|
1107 |
|
1108 // Re-enable scene pos notifications for new ancestors |
1141 // Re-enable scene pos notifications for new ancestors |
1109 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) |
1142 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) |
1110 scene->d_func()->setScenePosItemEnabled(q, true); |
1143 scene->d_func()->setScenePosItemEnabled(q, true); |
1111 } |
1144 } |
1112 |
1145 |
|
1146 // Propagate dirty flags to the new parent |
|
1147 markParentDirty(/*updateBoundingRect=*/true); |
|
1148 |
1113 // Inherit ancestor flags from the new parent. |
1149 // Inherit ancestor flags from the new parent. |
1114 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); |
1150 updateAncestorFlags(); |
1115 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); |
|
1116 updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); |
|
1117 updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); |
|
1118 |
1151 |
1119 // Update item visible / enabled. |
1152 // Update item visible / enabled. |
1120 if (parent->isVisible() != visible) { |
1153 if (parent->d_ptr->visible != visible) { |
1121 if (!parent->isVisible() || !explicitlyHidden) |
1154 if (!parent->d_ptr->visible || !explicitlyHidden) |
1122 setVisibleHelper(parent->isVisible(), /* explicit = */ false, /* update = */ !implicitUpdate); |
1155 setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false); |
1123 } |
1156 } |
1124 if (parent->isEnabled() != enabled) { |
1157 if (parent->isEnabled() != enabled) { |
1125 if (!parent->isEnabled() || !explicitlyDisabled) |
1158 if (!parent->d_ptr->enabled || !explicitlyDisabled) |
1126 setEnabledHelper(parent->isEnabled(), /* explicit = */ false, /* update = */ !implicitUpdate); |
1159 setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false); |
1127 } |
1160 } |
1128 |
1161 |
1129 // Auto-activate if visible and the parent is active. |
1162 // Auto-activate if visible and the parent is active. |
1130 if (q->isVisible() && parent->isActive()) |
1163 if (visible && parent->isActive()) |
1131 q->setActive(true); |
1164 q->setActive(true); |
1132 } else { |
1165 } else { |
1133 // Inherit ancestor flags from the new parent. |
1166 // Inherit ancestor flags from the new parent. |
1134 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); |
1167 updateAncestorFlags(); |
1135 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); |
|
1136 updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); |
|
1137 updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); |
|
1138 |
1168 |
1139 if (!inDestructor) { |
1169 if (!inDestructor) { |
1140 // Update item visible / enabled. |
1170 // Update item visible / enabled. |
1141 if (!visible && !explicitlyHidden) |
1171 if (!visible && !explicitlyHidden) |
1142 setVisibleHelper(true, /* explicit = */ false); |
1172 setVisibleHelper(true, /* explicit = */ false); |
1143 if (!enabled && !explicitlyDisabled) |
1173 if (!enabled && !explicitlyDisabled) |
1144 setEnabledHelper(true, /* explicit = */ false); |
1174 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 } |
1175 } |
1150 } |
1176 } |
1151 |
1177 |
1152 // Resolve depth. |
1178 // Resolve depth. |
1153 invalidateDepthRecursively(); |
1179 invalidateDepthRecursively(); |
1541 { |
1568 { |
1542 return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0; |
1569 return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0; |
1543 } |
1570 } |
1544 |
1571 |
1545 /*! |
1572 /*! |
1546 Sets this item's parent item to \a parent. If this item already has a |
1573 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, |
1574 has a parent, it is first removed from the previous parent. If \a |
1548 this item will become a top-level item. |
1575 newParent is 0, this item will become a top-level item. |
1549 |
1576 |
1550 Note that this implicitly adds this graphics item to the scene of |
1577 Note that this implicitly adds this graphics item to the scene of |
1551 the parent. You should not \l{QGraphicsScene::addItem()}{add} the |
1578 the parent. You should not \l{QGraphicsScene::addItem()}{add} the |
1552 item to the scene yourself. |
1579 item to the scene yourself. |
1553 |
1580 |
1554 Calling this function on an item that is an ancestor of \a parent have undefined behaviour. |
1581 Calling this function on an item that is an ancestor of \a newParent |
1555 |
1582 have undefined behaviour. |
1556 \sa parentItem(), childItems() |
1583 |
1557 */ |
1584 \sa parentItem(), childItems() |
1558 void QGraphicsItem::setParentItem(QGraphicsItem *parent) |
1585 */ |
1559 { |
1586 void QGraphicsItem::setParentItem(QGraphicsItem *newParent) |
1560 d_ptr->setParentItemHelper(parent); |
1587 { |
|
1588 if (newParent == this) { |
|
1589 qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this); |
|
1590 return; |
|
1591 } |
|
1592 if (newParent == d_ptr->parent) |
|
1593 return; |
|
1594 |
|
1595 const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange, |
|
1596 qVariantFromValue<QGraphicsItem *>(newParent))); |
|
1597 newParent = qVariantValue<QGraphicsItem *>(newParentVariant); |
|
1598 if (newParent == d_ptr->parent) |
|
1599 return; |
|
1600 |
|
1601 const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this)); |
|
1602 d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant); |
1561 } |
1603 } |
1562 |
1604 |
1563 /*! |
1605 /*! |
1564 \obsolete |
1606 \obsolete |
1565 |
1607 |
1691 if (quint32(d_ptr->flags) == quint32(flags)) |
1733 if (quint32(d_ptr->flags) == quint32(flags)) |
1692 return; |
1734 return; |
1693 flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt()); |
1735 flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt()); |
1694 if (quint32(d_ptr->flags) == quint32(flags)) |
1736 if (quint32(d_ptr->flags) == quint32(flags)) |
1695 return; |
1737 return; |
1696 if (d_ptr->scene) |
1738 if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) |
1697 d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags)); |
1739 d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags); |
1698 |
1740 |
1699 // Flags that alter the geometry of the item (or its children). |
1741 // Flags that alter the geometry of the item (or its children). |
1700 const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable); |
1742 const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable); |
1701 bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask); |
1743 bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask); |
1702 if (fullUpdate) |
1744 if (fullUpdate) |
1703 d_ptr->paintedViewBoundingRectsNeedRepaint = 1; |
1745 d_ptr->paintedViewBoundingRectsNeedRepaint = 1; |
1704 |
1746 |
1705 // Keep the old flags to compare the diff. |
1747 // Keep the old flags to compare the diff. |
1706 GraphicsItemFlags oldFlags = this->flags(); |
1748 GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags); |
1707 |
1749 |
1708 // Update flags. |
1750 // Update flags. |
1709 d_ptr->flags = flags; |
1751 d_ptr->flags = flags; |
1710 |
1752 |
1711 if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) { |
1753 if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) { |
1730 // Item children clipping changes. Propagate the ancestor flag to |
1772 // Item children clipping changes. Propagate the ancestor flag to |
1731 // all children. |
1773 // all children. |
1732 d_ptr->updateAncestorFlag(ItemIgnoresTransformations); |
1774 d_ptr->updateAncestorFlag(ItemIgnoresTransformations); |
1733 } |
1775 } |
1734 |
1776 |
|
1777 if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) { |
|
1778 // NB! We change the flags directly here, so we must also update d_ptr->flags. |
|
1779 // Note that this has do be done before the ItemStacksBehindParent check |
|
1780 // below; otherwise we will loose the change. |
|
1781 |
|
1782 // Update stack-behind. |
|
1783 if (d_ptr->z < qreal(0.0)) |
|
1784 flags |= ItemStacksBehindParent; |
|
1785 else |
|
1786 flags &= ~ItemStacksBehindParent; |
|
1787 d_ptr->flags = flags; |
|
1788 } |
|
1789 |
1735 if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) { |
1790 if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) { |
|
1791 // NB! This check has to come after the ItemNegativeZStacksBehindParent |
|
1792 // check above. Be careful. |
|
1793 |
1736 // Ensure child item sorting is up to date when toggling this flag. |
1794 // Ensure child item sorting is up to date when toggling this flag. |
1737 if (d_ptr->parent) |
1795 if (d_ptr->parent) |
1738 d_ptr->parent->d_ptr->needSortChildren = 1; |
1796 d_ptr->parent->d_ptr->needSortChildren = 1; |
1739 else if (d_ptr->scene) |
1797 else if (d_ptr->scene) |
1740 d_ptr->scene->d_func()->needSortTopLevelItems = 1; |
1798 d_ptr->scene->d_func()->needSortTopLevelItems = 1; |
2521 itemChange(ItemOpacityHasChanged, newOpacityVariant); |
2575 itemChange(ItemOpacityHasChanged, newOpacityVariant); |
2522 |
2576 |
2523 // Update. |
2577 // Update. |
2524 if (d_ptr->scene) { |
2578 if (d_ptr->scene) { |
2525 #ifndef QT_NO_GRAPHICSEFFECT |
2579 #ifndef QT_NO_GRAPHICSEFFECT |
2526 d_ptr->invalidateGraphicsEffectsRecursively(); |
2580 d_ptr->invalidateParentGraphicsEffectsRecursively(); |
|
2581 if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren)) |
|
2582 d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged); |
2527 #endif //QT_NO_GRAPHICSEFFECT |
2583 #endif //QT_NO_GRAPHICSEFFECT |
2528 d_ptr->scene->d_func()->markDirty(this, QRectF(), |
2584 d_ptr->scene->d_func()->markDirty(this, QRectF(), |
2529 /*invalidateChildren=*/true, |
2585 /*invalidateChildren=*/true, |
2530 /*force=*/false, |
2586 /*force=*/false, |
2531 /*ignoreOpacity=*/true); |
2587 /*ignoreOpacity=*/true); |
5031 |
5102 |
5032 /*! |
5103 /*! |
5033 \internal |
5104 \internal |
5034 */ |
5105 */ |
5035 #ifndef QT_NO_GRAPHICSEFFECT |
5106 #ifndef QT_NO_GRAPHICSEFFECT |
5036 void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively() |
5107 void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively() |
5037 { |
5108 { |
5038 QGraphicsItemPrivate *itemPrivate = this; |
5109 QGraphicsItemPrivate *itemPrivate = this; |
5039 do { |
5110 do { |
5040 if (itemPrivate->graphicsEffect) { |
5111 if (itemPrivate->graphicsEffect) { |
5041 itemPrivate->notifyInvalidated = 1; |
5112 itemPrivate->notifyInvalidated = 1; |
5042 |
5113 |
5043 if (!itemPrivate->updateDueToGraphicsEffect) |
5114 if (!itemPrivate->updateDueToGraphicsEffect) |
5044 static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); |
5115 static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); |
5045 } |
5116 } |
5046 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); |
5117 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); |
|
5118 } |
|
5119 |
|
5120 void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason) |
|
5121 { |
|
5122 if (!mayHaveChildWithGraphicsEffect) |
|
5123 return; |
|
5124 |
|
5125 for (int i = 0; i < children.size(); ++i) { |
|
5126 QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data(); |
|
5127 if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity)) |
|
5128 continue; |
|
5129 if (childPrivate->graphicsEffect) { |
|
5130 childPrivate->notifyInvalidated = 1; |
|
5131 static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); |
|
5132 } |
|
5133 |
|
5134 childPrivate->invalidateChildGraphicsEffectsRecursively(reason); |
|
5135 } |
5047 } |
5136 } |
5048 #endif //QT_NO_GRAPHICSEFFECT |
5137 #endif //QT_NO_GRAPHICSEFFECT |
5049 |
5138 |
5050 /*! |
5139 /*! |
5051 \internal |
5140 \internal |
7163 d_ptr->paintedViewBoundingRectsNeedRepaint = 1; |
7252 d_ptr->paintedViewBoundingRectsNeedRepaint = 1; |
7164 d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper; |
7253 d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper; |
7165 |
7254 |
7166 QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); |
7255 QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); |
7167 scenePrivate->index->prepareBoundingRectChange(this); |
7256 scenePrivate->index->prepareBoundingRectChange(this); |
7168 scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true); |
7257 scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false, |
|
7258 /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false, |
|
7259 /*updateBoundingRect=*/true); |
7169 |
7260 |
7170 // For compatibility reasons, we have to update the item's old geometry |
7261 // For compatibility reasons, we have to update the item's old geometry |
7171 // if someone is connected to the changed signal or the scene has no views. |
7262 // if someone is connected to the changed signal or the scene has no views. |
7172 // Note that this has to be done *after* markDirty to ensure that |
7263 // Note that this has to be done *after* markDirty to ensure that |
7173 // _q_processDirtyItems is called before _q_emitUpdated. |
7264 // _q_processDirtyItems is called before _q_emitUpdated. |