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

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/graphicsview/qgraphicsitem_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4848//
    4949// This file is not part of the Qt API.  It exists for the convenience
    50 // of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp.  This header
    51 // file may change from version to version without notice, or even be removed.
     50// of other Qt classes.  This header file may change from version to
     51// version without notice, or even be removed.
    5252//
    5353// We mean it.
     
    5555
    5656#include "qgraphicsitem.h"
     57#include "qset.h"
     58#include "qpixmapcache.h"
     59#include <private/qgraphicsview_p.h>
     60#include "qgraphicstransform.h"
     61#include <private/qgraphicstransform_p.h>
     62
     63#include <private/qgraphicseffect_p.h>
     64#include <qgraphicseffect.h>
     65
     66#include <QtCore/qpoint.h>
    5767
    5868#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
     
    7080    QRect boundingRect;
    7181    QSize fixedSize;
    72     QString key;
     82    QPixmapCache::Key key;
    7383
    7484    // DeviceCoordinateCache only
    7585    struct DeviceData {
     86        DeviceData() {}
    7687        QTransform lastTransform;
    7788        QPoint cacheIndent;
    78         QString key;
     89        QPixmapCache::Key key;
    7990    };
    8091    QMap<QPaintDevice *, DeviceData> deviceData;
     
    8899};
    89100
    90 class Q_AUTOTEST_EXPORT QGraphicsItemPrivate
     101class Q_GUI_EXPORT QGraphicsItemPrivate
    91102{
    92103    Q_DECLARE_PUBLIC(QGraphicsItem)
    93104public:
    94105    enum Extra {
    95         ExtraTransform,
    96106        ExtraToolTip,
    97107        ExtraCursor,
    98108        ExtraCacheData,
    99109        ExtraMaxDeviceCoordCacheSize,
    100         ExtraBoundingRegionGranularity,
    101         ExtraOpacity,
    102         ExtraEffectiveOpacity
     110        ExtraBoundingRegionGranularity
    103111    };
    104112
     
    107115        AncestorHandlesChildEvents = 0x1,
    108116        AncestorClipsChildren = 0x2,
    109         AncestorIgnoresTransformations = 0x4
     117        AncestorIgnoresTransformations = 0x4,
     118        AncestorFiltersChildEvents = 0x8
    110119    };
    111120
    112121    inline QGraphicsItemPrivate()
    113122        : z(0),
     123        opacity(1.),
    114124        scene(0),
    115125        parent(0),
     126        transformData(0),
     127        graphicsEffect(0),
    116128        index(-1),
    117         depth(0),
     129        siblingIndex(-1),
     130        itemDepth(-1),
     131        focusProxy(0),
     132        subFocusItem(0),
     133        focusScopeItem(0),
     134        imHints(Qt::ImhNone),
     135        panelModality(QGraphicsItem::NonModal),
    118136        acceptedMouseButtons(0x1f),
    119137        visible(1),
     
    127145        handlesChildEvents(0),
    128146        itemDiscovered(0),
    129         hasTransform(0),
    130147        hasCursor(0),
    131148        ancestorFlags(0),
    132149        cacheMode(0),
    133150        hasBoundingRegionGranularity(0),
    134         flags(0),
    135         hasOpacity(0),
    136         hasEffectiveOpacity(0),
    137151        isWidget(0),
    138152        dirty(0),
    139153        dirtyChildren(0),
    140154        localCollisionHack(0),
    141         dirtyClipPath(1),
    142         emptyClipPath(0),
    143155        inSetPosHelper(0),
    144         allChildrenCombineOpacity(1),
     156        needSortChildren(1), // ### can be 0 by default?
     157        allChildrenDirty(0),
     158        fullUpdatePending(0),
     159        flags(0),
     160        dirtyChildrenBoundingRect(1),
     161        paintedViewBoundingRectsNeedRepaint(0),
     162        dirtySceneTransform(1),
     163        geometryChanged(1),
     164        inDestructor(0),
     165        isObject(0),
     166        ignoreVisible(0),
     167        ignoreOpacity(0),
     168        acceptTouchEvents(0),
     169        acceptedTouchBeginEvent(0),
     170        filtersDescendantEvents(0),
     171        sceneTransformTranslateOnly(0),
     172        notifyBoundingRectChanged(0),
     173        notifyInvalidated(0),
     174        mouseSetsFocus(1),
     175        explicitActivate(0),
     176        wantsActive(0),
     177        holesInSiblingIndex(0),
     178        sequentialOrdering(1),
     179        updateDueToGraphicsEffect(0),
     180        scenePosDescendants(0),
    145181        globalStackingOrder(-1),
    146         sceneTransformIndex(-1),
    147182        q_ptr(0)
    148183    {
     
    151186    inline virtual ~QGraphicsItemPrivate()
    152187    { }
     188
     189    static const QGraphicsItemPrivate *get(const QGraphicsItem *item)
     190    {
     191        return item->d_ptr.data();
     192    }
     193    static QGraphicsItemPrivate *get(QGraphicsItem *item)
     194    {
     195        return item->d_ptr.data();
     196    }
    153197
    154198    void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
     
    157201    void remapItemPos(QEvent *event, QGraphicsItem *item);
    158202    QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const;
    159     bool itemIsUntransformable() const;
     203    inline bool itemIsUntransformable() const
     204    {
     205        return (flags & QGraphicsItem::ItemIgnoresTransformations)
     206            || (ancestorFlags & AncestorIgnoresTransformations);
     207    }
     208
     209    void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const;
     210    void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const;
     211    virtual void updateSceneTransformFromParent();
    160212
    161213    // ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4.
     
    163215    static bool movableAncestorIsSelected(const QGraphicsItem *item);
    164216
    165     void setPosHelper(const QPointF &pos);
     217    virtual void setPosHelper(const QPointF &pos);
     218    void setTransformHelper(const QTransform &transform);
     219    void appendGraphicsTransform(QGraphicsTransform *t);
    166220    void setVisibleHelper(bool newVisible, bool explicitly, bool update = true);
    167221    void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
    168     bool discardUpdateRequest(bool ignoreClipping = false,
    169                               bool ignoreVisibleBit = false,
    170                               bool ignoreDirtyBit = false) const;
    171     void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false);
    172     void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false);
    173     void updateEffectiveOpacity();
    174     void resolveEffectiveOpacity(qreal effectiveParentOpacity);
    175     void resolveDepth(int parentDepth);
    176     void invalidateSceneTransformCache();
     222    bool discardUpdateRequest(bool ignoreVisibleBit = false,
     223                              bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
     224    int depth() const;
     225#ifndef QT_NO_GRAPHICSEFFECT
     226    void invalidateGraphicsEffectsRecursively();
     227#endif //QT_NO_GRAPHICSEFFECT
     228    void invalidateDepthRecursively();
     229    void resolveDepth();
     230    void addChild(QGraphicsItem *child);
     231    void removeChild(QGraphicsItem *child);
     232    void setParentItemHelper(QGraphicsItem *parent);
     233    void childrenBoundingRectHelper(QTransform *x, QRectF *rect);
     234    void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
     235                         const QRegion &exposedRegion, bool allItems = false) const;
     236    QRectF effectiveBoundingRect() const;
     237    QRectF sceneEffectiveBoundingRect() const;
     238
     239    QRectF effectiveBoundingRect(const QRectF &rect) const;
    177240
    178241    virtual void resolveFont(uint inheritedMask)
     
    238301        { return type < extra; }
    239302    };
     303
    240304    QList<ExtraStruct> extras;
    241305
     306    QGraphicsItemCache *maybeExtraItemCache() const;
    242307    QGraphicsItemCache *extraItemCache() const;
    243308    void removeExtraItemCache();
    244309
    245     inline void setCachedClipPath(const QPainterPath &path)
    246     {
    247         cachedClipPath = path;
    248         dirtyClipPath = 0;
    249         emptyClipPath = 0;
    250     }
    251 
    252     inline void setEmptyCachedClipPath()
    253     {
    254         emptyClipPath = 1;
    255         dirtyClipPath = 0;
    256     }
    257 
    258     void setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect = QRectF());
    259 
    260     inline void invalidateCachedClipPath()
    261     { /*static int count = 0 ;qWarning("%i", ++count);*/ dirtyClipPath = 1; emptyClipPath = 0; }
    262 
    263     void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF());
    264     void updateCachedClipPathFromSetPosHelper(const QPointF &newPos);
     310    void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem);
     311    inline void ensureSceneTransform()
     312    {
     313        QGraphicsItem *that = q_func();
     314        ensureSceneTransformRecursive(&that);
     315    }
     316
     317    inline bool hasTranslateOnlySceneTransform()
     318    {
     319        ensureSceneTransform();
     320        return sceneTransformTranslateOnly;
     321    }
     322
     323    inline void invalidateChildrenSceneTransform()
     324    {
     325        for (int i = 0; i < children.size(); ++i)
     326            children.at(i)->d_ptr->dirtySceneTransform = 1;
     327    }
     328
     329    inline qreal calcEffectiveOpacity() const
     330    {
     331        qreal o = opacity;
     332        QGraphicsItem *p = parent;
     333        int myFlags = flags;
     334        while (p) {
     335            int parentFlags = p->d_ptr->flags;
     336
     337            // If I have a parent, and I don't ignore my parent's opacity, and my
     338            // parent propagates to me, then combine my local opacity with my parent's
     339            // effective opacity into my effective opacity.
     340            if ((myFlags & QGraphicsItem::ItemIgnoresParentOpacity)
     341                || (parentFlags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
     342                break;
     343            }
     344
     345            o *= p->d_ptr->opacity;
     346            p = p->d_ptr->parent;
     347            myFlags = parentFlags;
     348        }
     349        return o;
     350    }
    265351
    266352    inline bool isFullyTransparent() const
    267     { return hasEffectiveOpacity && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0)); }
     353    {
     354        if (opacity < 0.001)
     355            return true;
     356        if (!parent)
     357            return false;
     358
     359        return calcEffectiveOpacity() < 0.001;
     360    }
     361
     362    inline qreal effectiveOpacity() const {
     363        if (!parent || !opacity)
     364            return opacity;
     365
     366        return calcEffectiveOpacity();
     367    }
     368
     369    inline qreal combineOpacityFromParent(qreal parentOpacity) const
     370    {
     371        if (parent && !(flags & QGraphicsItem::ItemIgnoresParentOpacity)
     372            && !(parent->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
     373            return parentOpacity * opacity;
     374        }
     375        return opacity;
     376    }
    268377
    269378    inline bool childrenCombineOpacity() const
    270     { return allChildrenCombineOpacity || children.isEmpty(); }
    271 
    272     inline bool isClippedAway() const
    273     { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); }
     379    {
     380        if (!children.size())
     381            return true;
     382        if (flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
     383            return false;
     384
     385        for (int i = 0; i < children.size(); ++i) {
     386            if (children.at(i)->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)
     387                return false;
     388        }
     389        return true;
     390    }
    274391
    275392    inline bool childrenClippedToShape() const
     
    278395    inline bool isInvisible() const
    279396    {
    280         return !visible
    281                || (childrenClippedToShape() && isClippedAway())
    282                || (childrenCombineOpacity() && isFullyTransparent());
    283     }
    284 
    285     QPainterPath cachedClipPath;
     397        return !visible || (childrenCombineOpacity() && isFullyTransparent());
     398    }
     399
     400    void setFocusHelper(Qt::FocusReason focusReason, bool climb);
     401    void setSubFocus(QGraphicsItem *rootItem = 0);
     402    void clearSubFocus(QGraphicsItem *rootItem = 0);
     403    void resetFocusProxy();
     404    virtual void subFocusItemChange();
     405
     406    inline QTransform transformToParent() const;
     407    inline void ensureSortedChildren();
     408    static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b);
     409    void ensureSequentialSiblingIndex();
     410    inline void sendScenePosChange();
     411    virtual void siblingOrderChange();
     412
     413    QRectF childrenBoundingRect;
     414    QRectF needsRepaint;
     415    QMap<QWidget *, QRect> paintedViewBoundingRects;
    286416    QPointF pos;
    287417    qreal z;
     418    qreal opacity;
    288419    QGraphicsScene *scene;
    289420    QGraphicsItem *parent;
    290421    QList<QGraphicsItem *> children;
     422    struct TransformData;
     423    TransformData *transformData;
     424    QGraphicsEffect *graphicsEffect;
     425    QTransform sceneTransform;
    291426    int index;
    292     int depth;
    293 
    294     // Packed 32 bytes
     427    int siblingIndex;
     428    int itemDepth;  // Lazily calculated when calling depth().
     429    QGraphicsItem *focusProxy;
     430    QList<QGraphicsItem **> focusProxyRefs;
     431    QGraphicsItem *subFocusItem;
     432    QGraphicsItem *focusScopeItem;
     433    Qt::InputMethodHints imHints;
     434    QGraphicsItem::PanelModality panelModality;
     435    QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
     436
     437    // Packed 32 bits
    295438    quint32 acceptedMouseButtons : 5;
    296439    quint32 visible : 1;
     
    304447    quint32 handlesChildEvents : 1;
    305448    quint32 itemDiscovered : 1;
    306     quint32 hasTransform : 1;
    307449    quint32 hasCursor : 1;
    308     quint32 ancestorFlags : 3;
     450    quint32 ancestorFlags : 4;
    309451    quint32 cacheMode : 2;
    310452    quint32 hasBoundingRegionGranularity : 1;
    311     quint32 flags : 9;
    312 
    313     // New 32 bytes
    314     quint32 hasOpacity : 1;
    315     quint32 hasEffectiveOpacity : 1;
    316453    quint32 isWidget : 1;
    317     quint32 dirty : 1;   
    318     quint32 dirtyChildren : 1;   
     454    quint32 dirty : 1;
     455    quint32 dirtyChildren : 1;
    319456    quint32 localCollisionHack : 1;
    320     quint32 dirtyClipPath : 1;
    321     quint32 emptyClipPath : 1;
    322457    quint32 inSetPosHelper : 1;
    323     quint32 allChildrenCombineOpacity : 1;
     458    quint32 needSortChildren : 1;
     459    quint32 allChildrenDirty : 1;
     460
     461    // Packed 32 bits
     462    quint32 fullUpdatePending : 1;
     463    quint32 flags : 17;
     464    quint32 dirtyChildrenBoundingRect : 1;
     465    quint32 paintedViewBoundingRectsNeedRepaint : 1;
     466    quint32 dirtySceneTransform : 1;
     467    quint32 geometryChanged : 1;
     468    quint32 inDestructor : 1;
     469    quint32 isObject : 1;
     470    quint32 ignoreVisible : 1;
     471    quint32 ignoreOpacity : 1;
     472    quint32 acceptTouchEvents : 1;
     473    quint32 acceptedTouchBeginEvent : 1;
     474    quint32 filtersDescendantEvents : 1;
     475    quint32 sceneTransformTranslateOnly : 1;
     476    quint32 notifyBoundingRectChanged : 1;
     477    quint32 notifyInvalidated : 1;
     478
     479    // New 32 bits
     480    quint32 mouseSetsFocus : 1;
     481    quint32 explicitActivate : 1;
     482    quint32 wantsActive : 1;
     483    quint32 holesInSiblingIndex : 1;
     484    quint32 sequentialOrdering : 1;
     485    quint32 updateDueToGraphicsEffect : 1;
     486    quint32 scenePosDescendants : 1;
    324487
    325488    // Optional stacking order
    326489    int globalStackingOrder;
    327     int sceneTransformIndex;
    328 
    329490    QGraphicsItem *q_ptr;
    330491};
    331492
     493struct QGraphicsItemPrivate::TransformData
     494{
     495    QTransform transform;
     496    qreal scale;
     497    qreal rotation;
     498    qreal xOrigin;
     499    qreal yOrigin;
     500    QList<QGraphicsTransform *> graphicsTransforms;
     501    bool onlyTransform;
     502
     503    TransformData() :
     504        scale(1.0), rotation(0.0),
     505        xOrigin(0.0), yOrigin(0.0),
     506        onlyTransform(true)
     507    { }
     508
     509    QTransform computedFullTransform(QTransform *postmultiplyTransform = 0) const
     510    {
     511        if (onlyTransform) {
     512            if (!postmultiplyTransform || postmultiplyTransform->isIdentity())
     513                return transform;
     514            if (transform.isIdentity())
     515                return *postmultiplyTransform;
     516            return transform * *postmultiplyTransform;
     517        }
     518
     519        QTransform x(transform);
     520        if (!graphicsTransforms.isEmpty()) {
     521            QMatrix4x4 m;
     522            for (int i = 0; i < graphicsTransforms.size(); ++i)
     523                graphicsTransforms.at(i)->applyTo(&m);
     524            x *= m.toTransform();
     525        }
     526        x.translate(xOrigin, yOrigin);
     527        x.rotate(rotation);
     528        x.scale(scale, scale);
     529        x.translate(-xOrigin, -yOrigin);
     530        if (postmultiplyTransform)
     531            x *= *postmultiplyTransform;
     532        return x;
     533    }
     534};
     535
     536struct QGraphicsItemPaintInfo
     537{
     538    inline QGraphicsItemPaintInfo(const QTransform *const xform1, const QTransform *const xform2,
     539                                  const QTransform *const xform3,
     540                                  QRegion *r, QWidget *w, QStyleOptionGraphicsItem *opt,
     541                                  QPainter *p, qreal o, bool b1, bool b2)
     542        : viewTransform(xform1), transformPtr(xform2), effectTransform(xform3), exposedRegion(r), widget(w),
     543          option(opt), painter(p), opacity(o), wasDirtySceneTransform(b1), drawItem(b2)
     544    {}
     545
     546    const QTransform *viewTransform;
     547    const QTransform *transformPtr;
     548    const QTransform *effectTransform;
     549    QRegion *exposedRegion;
     550    QWidget *widget;
     551    QStyleOptionGraphicsItem *option;
     552    QPainter *painter;
     553    qreal opacity;
     554    quint32 wasDirtySceneTransform : 1;
     555    quint32 drawItem : 1;
     556};
     557
     558#ifndef QT_NO_GRAPHICSEFFECT
     559class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate
     560{
     561public:
     562    QGraphicsItemEffectSourcePrivate(QGraphicsItem *i)
     563        : QGraphicsEffectSourcePrivate(), item(i), info(0)
     564    {}
     565
     566    inline void detach()
     567    {
     568        item->d_ptr->graphicsEffect = 0;
     569        item->prepareGeometryChange();
     570    }
     571
     572    inline const QGraphicsItem *graphicsItem() const
     573    { return item; }
     574
     575    inline const QWidget *widget() const
     576    { return 0; }
     577
     578    inline void update() {
     579        item->d_ptr->updateDueToGraphicsEffect = true;
     580        item->update();
     581        item->d_ptr->updateDueToGraphicsEffect = false;
     582    }
     583
     584    inline void effectBoundingRectChanged()
     585    { item->prepareGeometryChange(); }
     586
     587    inline bool isPixmap() const
     588    {
     589        return item->type() == QGraphicsPixmapItem::Type
     590               && !(item->flags() & QGraphicsItem::ItemIsSelectable)
     591               && item->d_ptr->children.size() == 0;
     592            //|| (item->d_ptr->isObject && qobject_cast<QmlGraphicsImage *>(q_func()));
     593    }
     594
     595    inline const QStyleOption *styleOption() const
     596    { return info ? info->option : 0; }
     597
     598    inline QRect deviceRect() const
     599    {
     600        if (!info || !info->widget) {
     601            qWarning("QGraphicsEffectSource::deviceRect: Not yet implemented, lacking device context");
     602            return QRect();
     603        }
     604        return info->widget->rect();
     605    }
     606
     607    QRectF boundingRect(Qt::CoordinateSystem system) const;
     608    void draw(QPainter *);
     609    QPixmap pixmap(Qt::CoordinateSystem system,
     610                   QPoint *offset,
     611                   QGraphicsEffect::PixmapPadMode mode) const;
     612
     613    QGraphicsItem *item;
     614    QGraphicsItemPaintInfo *info;
     615    QTransform lastEffectTransform;
     616};
     617#endif //QT_NO_GRAPHICSEFFECT
     618
     619/*!
     620    Returns true if \a item1 is on top of \a item2.
     621    The items dont need to be siblings.
     622
     623    \internal
     624*/
     625inline bool qt_closestItemFirst(const QGraphicsItem *item1, const QGraphicsItem *item2)
     626{
     627    // Siblings? Just check their z-values.
     628    const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
     629    const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
     630    if (d1->parent == d2->parent)
     631        return qt_closestLeaf(item1, item2);
     632
     633    // Find common ancestor, and each item's ancestor closest to the common
     634    // ancestor.
     635    int item1Depth = d1->depth();
     636    int item2Depth = d2->depth();
     637    const QGraphicsItem *p = item1;
     638    const QGraphicsItem *t1 = item1;
     639    while (item1Depth > item2Depth && (p = p->d_ptr->parent)) {
     640        if (p == item2) {
     641            // item2 is one of item1's ancestors; item1 is on top
     642            return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
     643        }
     644        t1 = p;
     645        --item1Depth;
     646    }
     647    p = item2;
     648    const QGraphicsItem *t2 = item2;
     649    while (item2Depth > item1Depth && (p = p->d_ptr->parent)) {
     650        if (p == item1) {
     651            // item1 is one of item2's ancestors; item1 is not on top
     652            return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
     653        }
     654        t2 = p;
     655        --item2Depth;
     656    }
     657
     658    // item1Ancestor is now at the same level as item2Ancestor, but not the same.
     659    const QGraphicsItem *p1 = t1;
     660    const QGraphicsItem *p2 = t2;
     661    while (t1 && t1 != t2) {
     662        p1 = t1;
     663        p2 = t2;
     664        t1 = t1->d_ptr->parent;
     665        t2 = t2->d_ptr->parent;
     666    }
     667
     668    // in case we have a common ancestor, we compare the immediate children in the ancestor's path.
     669    // otherwise we compare the respective items' topLevelItems directly.
     670    return qt_closestLeaf(p1, p2);
     671}
     672
     673/*!
     674    Returns true if \a item2 is on top of \a item1.
     675    The items dont need to be siblings.
     676
     677    \internal
     678*/
     679inline bool qt_closestItemLast(const QGraphicsItem *item1, const QGraphicsItem *item2)
     680{
     681    return qt_closestItemFirst(item2, item1);
     682}
     683
     684/*!
     685    \internal
     686*/
     687inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
     688{
     689    // Return true if sibling item1 is on top of item2.
     690    const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
     691    const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
     692    bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent;
     693    bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent;
     694    if (f1 != f2)
     695        return f2;
     696    if (d1->z != d2->z)
     697        return d1->z > d2->z;
     698    return d1->siblingIndex > d2->siblingIndex;
     699}
     700
     701/*!
     702    \internal
     703*/
     704inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
     705{ return qt_closestLeaf(item2, item1); }
     706
     707/*
     708   return the full transform of the item to the parent.  This include the position and all the transform data
     709*/
     710inline QTransform QGraphicsItemPrivate::transformToParent() const
     711{
     712    QTransform matrix;
     713    combineTransformToParent(&matrix);
     714    return matrix;
     715}
     716
     717/*!
     718    \internal
     719*/
     720inline void QGraphicsItemPrivate::ensureSortedChildren()
     721{
     722    if (needSortChildren) {
     723        qSort(children.begin(), children.end(), qt_notclosestLeaf);
     724        needSortChildren = 0;
     725        sequentialOrdering = 1;
     726        for (int i = 0; i < children.size(); ++i) {
     727            if (children[i]->d_ptr->siblingIndex != i) {
     728                sequentialOrdering = 0;
     729                break;
     730            }
     731        }
     732    }
     733}
     734
     735/*!
     736    \internal
     737*/
     738inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem *b)
     739{
     740    return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex;
     741}
     742
    332743QT_END_NAMESPACE
    333744
Note: See TracChangeset for help on using the changeset viewer.