Ignore:
Timestamp:
Mar 8, 2010, 12:52:58 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.2 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

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

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    269269
    270270/*!
     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/*!
    271282    \variable QGraphicsItem::UserType
    272283
     
    277288
    278289    \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1
     290
     291    \note UserType = 65536
    279292*/
    280293
     
    799812    }
    800813
    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
     818void 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();
    803844}
    804845
     
    9851026    inDestructor is 1.
    9861027*/
    987 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
     1028void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant,
     1029                                               const QVariant *thisPointerVariant)
    9881030{
    9891031    Q_Q(QGraphicsItem);
    990     if (newParent == q) {
    991         qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
    992         return;
    993     }
    9941032    if (newParent == parent)
    9951033        return;
    9961034
    997     const QVariant newParentVariant(q->itemChange(QGraphicsItem::ItemParentChange,
    998                                                   qVariantFromValue<QGraphicsItem *>(newParent)));
    999     newParent = qVariantValue<QGraphicsItem *>(newParentVariant);
    1000     if (newParent == parent)
    1001         return;
    1002 
    10031035    if (scene) {
    10041036        // 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);
    10061039
    10071040        // Disable scene pos notifications for old ancestors
     
    10211054        q_ptr->prepareGeometryChange();
    10221055
    1023     const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q));
    10241056    if (parent) {
    10251057        // Remove from current parent
    10261058        parent->d_ptr->removeChild(q);
    1027         parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant);
     1059        if (thisPointerVariant)
     1060            parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant);
    10281061    }
    10291062
     
    10431076    QGraphicsItem *parentFocusScopeItem = 0;
    10441077    while (p) {
    1045         if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
     1078        if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
    10461079            // If this item's focus scope's focus scope item points
    10471080            // to this item or a descendent, then clear it.
     
    10561089    }
    10571090
     1091    // Update graphics effect optimization flag
     1092    if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect))
     1093        newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
     1094
    10581095    // Update focus scope item ptr in new scope.
    10591096    QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
     
    10641101            QGraphicsItem *p = subFocusItem->d_ptr->parent;
    10651102            while (p) {
    1066                 if (p->flags() & QGraphicsItem::ItemIsFocusScope)
     1103                if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
    10671104                    ancestorScope = p;
    1068                 if (p->isPanel())
     1105                if (p->d_ptr->flags & QGraphicsItem::ItemIsPanel)
    10691106                    break;
    1070                 p = p->parentItem();
     1107                p = p->d_ptr->parent;
    10711108            }
    10721109            if (ancestorScope)
     
    10761113        QGraphicsItem *p = newParent;
    10771114        while (p) {
    1078             if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
     1115            if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
    10791116                p->d_ptr->focusScopeItem = newFocusScopeItem;
    10801117                // Ensure the new item is no longer the subFocusItem. The
     
    10901127
    10911128    if ((parent = newParent)) {
    1092         bool implicitUpdate = false;
    10931129        if (parent->d_func()->scene && parent->d_func()->scene != scene) {
    10941130            // Move this item to its new parent's scene
    10951131            parent->d_func()->scene->addItem(q);
    1096             implicitUpdate = true;
    10971132        } else if (!parent->d_func()->scene && scene) {
    10981133            // Remove this item from its former scene
     
    11011136
    11021137        parent->d_ptr->addChild(q);
    1103         parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant);
     1138        if (thisPointerVariant)
     1139            parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant);
    11041140        if (scene) {
    1105             if (!implicitUpdate)
    1106                 scene->d_func()->markDirty(q_ptr);
    1107 
    11081141            // Re-enable scene pos notifications for new ancestors
    11091142            if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
     
    11111144        }
    11121145
     1146        // Propagate dirty flags to the new parent
     1147        markParentDirty(/*updateBoundingRect=*/true);
     1148
    11131149        // 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();
    11181151
    11191152        // 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);
    11231156        }
    11241157        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);
    11271160        }
    11281161
    11291162        // Auto-activate if visible and the parent is active.
    1130         if (q->isVisible() && parent->isActive())
     1163        if (visible && parent->isActive())
    11311164            q->setActive(true);
    11321165    } else {
    11331166        // 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();
    11381168
    11391169        if (!inDestructor) {
     
    11431173            if (!enabled && !explicitlyDisabled)
    11441174                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);
    11491175        }
    11501176    }
     
    11621188
    11631189    // Deliver post-change notification
    1164     q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant);
     1190    if (newParentVariant)
     1191        q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant);
    11651192
    11661193    if (isObject)
     
    13511378    } else {
    13521379        d_ptr->resetFocusProxy();
    1353         d_ptr->setParentItemHelper(0);
     1380        setParentItem(0);
    13541381    }
    13551382
     
    15561583    \sa parentItem(), childItems()
    15571584*/
    1558 void QGraphicsItem::setParentItem(QGraphicsItem *parent)
    1559 {
    1560     d_ptr->setParentItemHelper(parent);
     1585void 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);
    15611602}
    15621603
     
    16081649bool QGraphicsItem::isWindow() const
    16091650{
    1610     return isWidget() && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
     1651    return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
    16111652}
    16121653
     
    16451686{
    16461687    if (enabled)
    1647         setFlags(flags() | flag);
     1688        setFlags(GraphicsItemFlags(d_ptr->flags) | flag);
    16481689    else
    1649         setFlags(flags() & ~flag);
     1690        setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag);
    16501691}
    16511692
     
    16941735    if (quint32(d_ptr->flags) == quint32(flags))
    16951736        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);
    16981739
    16991740    // Flags that alter the geometry of the item (or its children).
     
    17041745
    17051746    // Keep the old flags to compare the diff.
    1706     GraphicsItemFlags oldFlags = this->flags();
     1747    GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
    17071748
    17081749    // Update flags.
     
    17331774    }
    17341775
     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
    17351789    if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
     1790        // NB! This check has to come after the ItemNegativeZStacksBehindParent
     1791        // check above. Be careful.
     1792
    17361793        // Ensure child item sorting is up to date when toggling this flag.
    17371794        if (d_ptr->parent)
     
    17471804    }
    17481805
    1749     if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
    1750         // Update stack-behind.
    1751         setFlag(ItemStacksBehindParent, d_ptr->z < qreal(0.0));
    1752     }
    17531806
    17541807    if ((d_ptr->panelModality != NonModal)
     
    25162569        return;
    25172570
     2571    bool wasFullyTransparent = d_ptr->isOpacityNull();
    25182572    d_ptr->opacity = newOpacity;
    25192573
     
    25242578    if (d_ptr->scene) {
    25252579#ifndef QT_NO_GRAPHICSEFFECT
    2526         d_ptr->invalidateGraphicsEffectsRecursively();
     2580        d_ptr->invalidateParentGraphicsEffectsRecursively();
     2581        if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren))
     2582            d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged);
    25272583#endif //QT_NO_GRAPHICSEFFECT
    25282584        d_ptr->scene->d_func()->markDirty(this, QRectF(),
    25292585                                          /*invalidateChildren=*/true,
    25302586                                          /*force=*/false,
    2531                                           /*ignoreOpacity=*/true);
     2587                                          /*ignoreOpacity=*/d_ptr->isOpacityNull());
     2588        if (wasFullyTransparent)
     2589            d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
    25322590    }
    25332591
     
    25692627        delete d_ptr->graphicsEffect;
    25702628        d_ptr->graphicsEffect = 0;
     2629    } else if (d_ptr->parent) {
     2630        d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
    25712631    }
    25722632
     
    25812641}
    25822642#endif //QT_NO_GRAPHICSEFFECT
     2643
     2644void 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}
    25832656
    25842657/*!
     
    29983071bool QGraphicsItem::hasFocus() const
    29993072{
     3073    if (!d_ptr->scene || !d_ptr->scene->isActive())
     3074        return false;
     3075
    30003076    if (d_ptr->focusProxy)
    30013077        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;
    30033083}
    30043084
     
    42584338        return;
    42594339
    4260     if (d_ptr->scene) {
     4340    if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
    42614341        // 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);
    42634343    }
    42644344
     
    50275107*/
    50285108#ifndef QT_NO_GRAPHICSEFFECT
    5029 void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively()
     5109void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
    50305110{
    50315111    QGraphicsItemPrivate *itemPrivate = this;
     
    50385118        }
    50395119    } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
     5120}
     5121
     5122void 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    }
    50405138}
    50415139#endif //QT_NO_GRAPHICSEFFECT
     
    52835381    // Make sure we notify effects about invalidated source.
    52845382#ifndef QT_NO_GRAPHICSEFFECT
    5285     d_ptr->invalidateGraphicsEffectsRecursively();
     5383    d_ptr->invalidateParentGraphicsEffectsRecursively();
    52865384#endif //QT_NO_GRAPHICSEFFECT
    52875385
     
    71767274    }
    71777275
    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);
    71917277}
    71927278
     
    1071610802}
    1071710803
    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);
     10804QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
     10805{
    1073210806    QRectF effectRectF;
    1073310807
    10734     bool unpadded = false;
     10808    if (unpadded)
     10809        *unpadded = false;
     10810
    1073510811    if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
    1073610812        if (info) {
    1073710813            effectRectF = item->graphicsEffect()->boundingRectFor(boundingRect(Qt::DeviceCoordinates));
    10738             unpadded = (effectRectF.size() == sourceRect.size());
     10814            if (unpadded)
     10815                *unpadded = (effectRectF.size() == sourceRect.size());
    1073910816            if (info && system == Qt::LogicalCoordinates)
    1074010817                effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
     
    1074810825    } else {
    1074910826        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
     10834QPixmap 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);
    1075410850
    1075510851    if (offset)
Note: See TracChangeset for help on using the changeset viewer.