Changeset 651 for trunk/src/gui/graphicsview/qgraphicsitem.cpp
- Timestamp:
- Mar 8, 2010, 12:52:58 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.6.2 (added) merged: 650 /branches/vendor/nokia/qt/current merged: 649 /branches/vendor/nokia/qt/4.6.1 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/graphicsview/qgraphicsitem.cpp
r561 r651 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 20 09Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 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 282 \variable QGraphicsItem::UserType 272 283 … … 277 288 278 289 \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1 290 291 \note UserType = 65536 279 292 */ 280 293 … … 799 812 } 800 813 801 foreach (QGraphicsItem *child, children) 802 child->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false); 814 for (int i = 0; i < children.size(); ++i) 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 … … 985 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 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 1032 if (newParent == parent) 995 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 1035 if (scene) { 1004 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 1040 // Disable scene pos notifications for old ancestors … … 1021 1054 q_ptr->prepareGeometryChange(); 1022 1055 1023 const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q));1024 1056 if (parent) { 1025 1057 // Remove from current parent 1026 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 … … 1043 1076 QGraphicsItem *parentFocusScopeItem = 0; 1044 1077 while (p) { 1045 if (p-> flags()& QGraphicsItem::ItemIsFocusScope) {1078 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { 1046 1079 // If this item's focus scope's focus scope item points 1047 1080 // to this item or a descendent, then clear it. … … 1056 1089 } 1057 1090 1091 // Update graphics effect optimization flag 1092 if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect)) 1093 newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively(); 1094 1058 1095 // Update focus scope item ptr in new scope. 1059 1096 QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; … … 1064 1101 QGraphicsItem *p = subFocusItem->d_ptr->parent; 1065 1102 while (p) { 1066 if (p-> flags()& QGraphicsItem::ItemIsFocusScope)1103 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) 1067 1104 ancestorScope = p; 1068 if (p-> isPanel())1105 if (p->d_ptr->flags & QGraphicsItem::ItemIsPanel) 1069 1106 break; 1070 p = p-> parentItem();1107 p = p->d_ptr->parent; 1071 1108 } 1072 1109 if (ancestorScope) … … 1076 1113 QGraphicsItem *p = newParent; 1077 1114 while (p) { 1078 if (p-> flags()& QGraphicsItem::ItemIsFocusScope) {1115 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { 1079 1116 p->d_ptr->focusScopeItem = newFocusScopeItem; 1080 1117 // Ensure the new item is no longer the subFocusItem. The … … 1090 1127 1091 1128 if ((parent = newParent)) { 1092 bool implicitUpdate = false;1093 1129 if (parent->d_func()->scene && parent->d_func()->scene != scene) { 1094 1130 // Move this item to its new parent's scene 1095 1131 parent->d_func()->scene->addItem(q); 1096 implicitUpdate = true;1097 1132 } else if (!parent->d_func()->scene && scene) { 1098 1133 // Remove this item from its former scene … … 1101 1136 1102 1137 parent->d_ptr->addChild(q); 1103 parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant); 1138 if (thisPointerVariant) 1139 parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant); 1104 1140 if (scene) { 1105 if (!implicitUpdate)1106 scene->d_func()->markDirty(q_ptr);1107 1108 1141 // Re-enable scene pos notifications for new ancestors 1109 1142 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) … … 1111 1144 } 1112 1145 1146 // Propagate dirty flags to the new parent 1147 markParentDirty(/*updateBoundingRect=*/true); 1148 1113 1149 // Inherit ancestor flags from the new parent. 1114 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); 1115 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); 1116 updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); 1117 updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); 1150 updateAncestorFlags(); 1118 1151 1119 1152 // Update item visible / enabled. 1120 if (parent-> isVisible()!= visible) {1121 if (!parent-> isVisible()|| !explicitlyHidden)1122 setVisibleHelper(parent-> isVisible(), /* explicit = */ false, /* update = */ !implicitUpdate);1153 if (parent->d_ptr->visible != visible) { 1154 if (!parent->d_ptr->visible || !explicitlyHidden) 1155 setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false); 1123 1156 } 1124 1157 if (parent->isEnabled() != enabled) { 1125 if (!parent-> isEnabled()|| !explicitlyDisabled)1126 setEnabledHelper(parent-> isEnabled(), /* explicit = */ false, /* update = */ !implicitUpdate);1158 if (!parent->d_ptr->enabled || !explicitlyDisabled) 1159 setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false); 1127 1160 } 1128 1161 1129 1162 // Auto-activate if visible and the parent is active. 1130 if ( q->isVisible()&& parent->isActive())1163 if (visible && parent->isActive()) 1131 1164 q->setActive(true); 1132 1165 } else { 1133 1166 // Inherit ancestor flags from the new parent. 1134 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); 1135 updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); 1136 updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); 1137 updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); 1167 updateAncestorFlags(); 1138 1168 1139 1169 if (!inDestructor) { … … 1143 1173 if (!enabled && !explicitlyDisabled) 1144 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 } … … 1162 1188 1163 1189 // Deliver post-change notification 1164 q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); 1190 if (newParentVariant) 1191 q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant); 1165 1192 1166 1193 if (isObject) … … 1351 1378 } else { 1352 1379 d_ptr->resetFocusProxy(); 1353 d_ptr->setParentItemHelper(0);1380 setParentItem(0); 1354 1381 } 1355 1382 … … 1556 1583 \sa parentItem(), childItems() 1557 1584 */ 1558 void QGraphicsItem::setParentItem(QGraphicsItem *parent) 1559 { 1560 d_ptr->setParentItemHelper(parent); 1585 void QGraphicsItem::setParentItem(QGraphicsItem *newParent) 1586 { 1587 if (newParent == this) { 1588 qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this); 1589 return; 1590 } 1591 if (newParent == d_ptr->parent) 1592 return; 1593 1594 const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange, 1595 qVariantFromValue<QGraphicsItem *>(newParent))); 1596 newParent = qVariantValue<QGraphicsItem *>(newParentVariant); 1597 if (newParent == d_ptr->parent) 1598 return; 1599 1600 const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this)); 1601 d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant); 1561 1602 } 1562 1603 … … 1608 1649 bool QGraphicsItem::isWindow() const 1609 1650 { 1610 return isWidget()&& (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);1651 return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window); 1611 1652 } 1612 1653 … … 1645 1686 { 1646 1687 if (enabled) 1647 setFlags( flags() | flag);1688 setFlags(GraphicsItemFlags(d_ptr->flags) | flag); 1648 1689 else 1649 setFlags( flags() & ~flag);1690 setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag); 1650 1691 } 1651 1692 … … 1694 1735 if (quint32(d_ptr->flags) == quint32(flags)) 1695 1736 return; 1696 if (d_ptr->scene )1697 d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags));1737 if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) 1738 d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags); 1698 1739 1699 1740 // Flags that alter the geometry of the item (or its children). … … 1704 1745 1705 1746 // Keep the old flags to compare the diff. 1706 GraphicsItemFlags oldFlags = this->flags();1747 GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags); 1707 1748 1708 1749 // Update flags. … … 1733 1774 } 1734 1775 1776 if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) { 1777 // NB! We change the flags directly here, so we must also update d_ptr->flags. 1778 // Note that this has do be done before the ItemStacksBehindParent check 1779 // below; otherwise we will loose the change. 1780 1781 // Update stack-behind. 1782 if (d_ptr->z < qreal(0.0)) 1783 flags |= ItemStacksBehindParent; 1784 else 1785 flags &= ~ItemStacksBehindParent; 1786 d_ptr->flags = flags; 1787 } 1788 1735 1789 if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) { 1790 // NB! This check has to come after the ItemNegativeZStacksBehindParent 1791 // check above. Be careful. 1792 1736 1793 // Ensure child item sorting is up to date when toggling this flag. 1737 1794 if (d_ptr->parent) … … 1747 1804 } 1748 1805 1749 if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {1750 // Update stack-behind.1751 setFlag(ItemStacksBehindParent, d_ptr->z < qreal(0.0));1752 }1753 1806 1754 1807 if ((d_ptr->panelModality != NonModal) … … 2516 2569 return; 2517 2570 2571 bool wasFullyTransparent = d_ptr->isOpacityNull(); 2518 2572 d_ptr->opacity = newOpacity; 2519 2573 … … 2524 2578 if (d_ptr->scene) { 2525 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 2583 #endif //QT_NO_GRAPHICSEFFECT 2528 2584 d_ptr->scene->d_func()->markDirty(this, QRectF(), 2529 2585 /*invalidateChildren=*/true, 2530 2586 /*force=*/false, 2531 /*ignoreOpacity=*/true); 2587 /*ignoreOpacity=*/d_ptr->isOpacityNull()); 2588 if (wasFullyTransparent) 2589 d_ptr->paintedViewBoundingRectsNeedRepaint = 1; 2532 2590 } 2533 2591 … … 2569 2627 delete d_ptr->graphicsEffect; 2570 2628 d_ptr->graphicsEffect = 0; 2629 } else if (d_ptr->parent) { 2630 d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively(); 2571 2631 } 2572 2632 … … 2581 2641 } 2582 2642 #endif //QT_NO_GRAPHICSEFFECT 2643 2644 void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively() 2645 { 2646 #ifndef QT_NO_GRAPHICSEFFECT 2647 QGraphicsItemPrivate *itemPrivate = this; 2648 do { 2649 // parent chain already notified? 2650 if (itemPrivate->mayHaveChildWithGraphicsEffect) 2651 return; 2652 itemPrivate->mayHaveChildWithGraphicsEffect = 1; 2653 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); 2654 #endif 2655 } 2583 2656 2584 2657 /*! … … 2998 3071 bool QGraphicsItem::hasFocus() const 2999 3072 { 3073 if (!d_ptr->scene || !d_ptr->scene->isActive()) 3074 return false; 3075 3000 3076 if (d_ptr->focusProxy) 3001 3077 return d_ptr->focusProxy->hasFocus(); 3002 return isActive() && (d_ptr->scene && d_ptr->scene->focusItem() == this); 3078 3079 if (d_ptr->scene->d_func()->focusItem != this) 3080 return false; 3081 3082 return panel() == d_ptr->scene->d_func()->activePanel; 3003 3083 } 3004 3084 … … 4258 4338 return; 4259 4339 4260 if (d_ptr->scene ) {4340 if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) { 4261 4341 // Z Value has changed, we have to notify the index. 4262 d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant);4342 d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ); 4263 4343 } 4264 4344 … … 5027 5107 */ 5028 5108 #ifndef QT_NO_GRAPHICSEFFECT 5029 void QGraphicsItemPrivate::invalidate GraphicsEffectsRecursively()5109 void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively() 5030 5110 { 5031 5111 QGraphicsItemPrivate *itemPrivate = this; … … 5038 5118 } 5039 5119 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); 5120 } 5121 5122 void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason) 5123 { 5124 if (!mayHaveChildWithGraphicsEffect) 5125 return; 5126 5127 for (int i = 0; i < children.size(); ++i) { 5128 QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data(); 5129 if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity)) 5130 continue; 5131 if (childPrivate->graphicsEffect) { 5132 childPrivate->notifyInvalidated = 1; 5133 static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); 5134 } 5135 5136 childPrivate->invalidateChildGraphicsEffectsRecursively(reason); 5137 } 5040 5138 } 5041 5139 #endif //QT_NO_GRAPHICSEFFECT … … 5283 5381 // Make sure we notify effects about invalidated source. 5284 5382 #ifndef QT_NO_GRAPHICSEFFECT 5285 d_ptr->invalidate GraphicsEffectsRecursively();5383 d_ptr->invalidateParentGraphicsEffectsRecursively(); 5286 5384 #endif //QT_NO_GRAPHICSEFFECT 5287 5385 … … 7176 7274 } 7177 7275 7178 QGraphicsItem *parent = this; 7179 while ((parent = parent->d_ptr->parent)) { 7180 QGraphicsItemPrivate *parentp = parent->d_ptr.data(); 7181 parentp->dirtyChildrenBoundingRect = 1; 7182 // ### Only do this if the parent's effect applies to the entire subtree. 7183 parentp->notifyBoundingRectChanged = 1; 7184 #ifndef QT_NO_GRAPHICSEFFECT 7185 if (parentp->scene && parentp->graphicsEffect) { 7186 parentp->notifyInvalidated = 1; 7187 static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()->source->d_func())->invalidateCache(); 7188 } 7189 #endif 7190 } 7276 d_ptr->markParentDirty(/*updateBoundingRect=*/true); 7191 7277 } 7192 7278 … … 10716 10802 } 10717 10803 10718 QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset, 10719 QGraphicsEffect::PixmapPadMode mode) const 10720 { 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); 10804 QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const 10805 { 10732 10806 QRectF effectRectF; 10733 10807 10734 bool unpadded = false; 10808 if (unpadded) 10809 *unpadded = false; 10810 10735 10811 if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) { 10736 10812 if (info) { 10737 10813 effectRectF = item->graphicsEffect()->boundingRectFor(boundingRect(Qt::DeviceCoordinates)); 10738 unpadded = (effectRectF.size() == sourceRect.size()); 10814 if (unpadded) 10815 *unpadded = (effectRectF.size() == sourceRect.size()); 10739 10816 if (info && system == Qt::LogicalCoordinates) 10740 10817 effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF); … … 10748 10825 } else { 10749 10826 effectRectF = sourceRect; 10750 unpadded = true; 10751 } 10752 10753 QRect effectRect = effectRectF.toAlignedRect(); 10827 if (unpadded) 10828 *unpadded = true; 10829 } 10830 10831 return effectRectF.toAlignedRect(); 10832 } 10833 10834 QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset, 10835 QGraphicsEffect::PixmapPadMode mode) const 10836 { 10837 const bool deviceCoordinates = (system == Qt::DeviceCoordinates); 10838 if (!info && deviceCoordinates) { 10839 // Device coordinates without info not yet supported. 10840 qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context"); 10841 return QPixmap(); 10842 } 10843 if (!item->d_ptr->scene) 10844 return QPixmap(); 10845 QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func(); 10846 10847 bool unpadded; 10848 const QRectF sourceRect = boundingRect(system); 10849 QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded); 10754 10850 10755 10851 if (offset)
Note:
See TracChangeset
for help on using the changeset viewer.