src/gui/graphicsview/qgraphicsitem_p.h
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    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.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #ifndef QGRAPHICSITEM_P_H
       
    43 #define QGRAPHICSITEM_P_H
       
    44 
       
    45 //
       
    46 //  W A R N I N G
       
    47 //  -------------
       
    48 //
       
    49 // This file is not part of the Qt API.  It exists for the convenience
       
    50 // of other Qt classes.  This header file may change from version to
       
    51 // version without notice, or even be removed.
       
    52 //
       
    53 // We mean it.
       
    54 //
       
    55 
       
    56 #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 
       
    65 #include <QtCore/qpoint.h>
       
    66 
       
    67 #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
       
    68 
       
    69 QT_BEGIN_NAMESPACE
       
    70 
       
    71 class QGraphicsItemPrivate;
       
    72 
       
    73 class QGraphicsItemCache
       
    74 {
       
    75 public:
       
    76     QGraphicsItemCache() : allExposed(false) { }
       
    77 
       
    78     // ItemCoordinateCache only
       
    79     QRect boundingRect;
       
    80     QSize fixedSize;
       
    81     QPixmapCache::Key key;
       
    82 
       
    83     // DeviceCoordinateCache only
       
    84     struct DeviceData {
       
    85         DeviceData() {}
       
    86         QTransform lastTransform;
       
    87         QPoint cacheIndent;
       
    88         QPixmapCache::Key key;
       
    89     };
       
    90     QMap<QPaintDevice *, DeviceData> deviceData;
       
    91 
       
    92     // List of logical exposed rects
       
    93     QVector<QRectF> exposed;
       
    94     bool allExposed;
       
    95 
       
    96     // Empty cache
       
    97     void purge();
       
    98 };
       
    99 
       
   100 class Q_GUI_EXPORT QGraphicsItemPrivate
       
   101 {
       
   102     Q_DECLARE_PUBLIC(QGraphicsItem)
       
   103 public:
       
   104     enum Extra {
       
   105         ExtraToolTip,
       
   106         ExtraCursor,
       
   107         ExtraCacheData,
       
   108         ExtraMaxDeviceCoordCacheSize,
       
   109         ExtraBoundingRegionGranularity
       
   110     };
       
   111 
       
   112     enum AncestorFlag {
       
   113         NoFlag = 0,
       
   114         AncestorHandlesChildEvents = 0x1,
       
   115         AncestorClipsChildren = 0x2,
       
   116         AncestorIgnoresTransformations = 0x4,
       
   117         AncestorFiltersChildEvents = 0x8
       
   118     };
       
   119 
       
   120     inline QGraphicsItemPrivate()
       
   121         : z(0),
       
   122         opacity(1.),
       
   123         scene(0),
       
   124         parent(0),
       
   125         transformData(0),
       
   126         graphicsEffect(0),
       
   127         index(-1),
       
   128         siblingIndex(-1),
       
   129         itemDepth(-1),
       
   130         focusProxy(0),
       
   131         subFocusItem(0),
       
   132         focusScopeItem(0),
       
   133         imHints(Qt::ImhNone),
       
   134         panelModality(QGraphicsItem::NonModal),
       
   135         acceptedMouseButtons(0x1f),
       
   136         visible(1),
       
   137         explicitlyHidden(0),
       
   138         enabled(1),
       
   139         explicitlyDisabled(0),
       
   140         selected(0),
       
   141         acceptsHover(0),
       
   142         acceptDrops(0),
       
   143         isMemberOfGroup(0),
       
   144         handlesChildEvents(0),
       
   145         itemDiscovered(0),
       
   146         hasCursor(0),
       
   147         ancestorFlags(0),
       
   148         cacheMode(0),
       
   149         hasBoundingRegionGranularity(0),
       
   150         isWidget(0),
       
   151         dirty(0),
       
   152         dirtyChildren(0),
       
   153         localCollisionHack(0),
       
   154         dirtyClipPath(1),
       
   155         emptyClipPath(0),
       
   156         inSetPosHelper(0),
       
   157         needSortChildren(1), // ### can be 0 by default?
       
   158         allChildrenDirty(0),
       
   159         fullUpdatePending(0),
       
   160         flags(0),
       
   161         dirtyChildrenBoundingRect(1),
       
   162         paintedViewBoundingRectsNeedRepaint(0),
       
   163         dirtySceneTransform(1),
       
   164         geometryChanged(1),
       
   165         inDestructor(0),
       
   166         isObject(0),
       
   167         ignoreVisible(0),
       
   168         ignoreOpacity(0),
       
   169         acceptTouchEvents(0),
       
   170         acceptedTouchBeginEvent(0),
       
   171         filtersDescendantEvents(0),
       
   172         sceneTransformTranslateOnly(0),
       
   173         notifyBoundingRectChanged(0),
       
   174         notifyInvalidated(0),
       
   175         mouseSetsFocus(1),
       
   176         explicitActivate(0),
       
   177         wantsActive(0),
       
   178         holesInSiblingIndex(0),
       
   179         sequentialOrdering(1),
       
   180         updateDueToGraphicsEffect(0),
       
   181         globalStackingOrder(-1),
       
   182         q_ptr(0)
       
   183     {
       
   184     }
       
   185 
       
   186     inline virtual ~QGraphicsItemPrivate()
       
   187     { }
       
   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     }
       
   197 
       
   198     void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
       
   199                             AncestorFlag flag = NoFlag, bool enabled = false, bool root = true);
       
   200     void setIsMemberOfGroup(bool enabled);
       
   201     void remapItemPos(QEvent *event, QGraphicsItem *item);
       
   202     QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) 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();
       
   212 
       
   213     // ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4.
       
   214     virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const;
       
   215     static bool movableAncestorIsSelected(const QGraphicsItem *item);
       
   216 
       
   217     virtual void setPosHelper(const QPointF &pos);
       
   218     void setTransformHelper(const QTransform &transform);
       
   219     void appendGraphicsTransform(QGraphicsTransform *t);
       
   220     void setVisibleHelper(bool newVisible, bool explicitly, bool update = true);
       
   221     void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
       
   222     bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false,
       
   223                               bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
       
   224     int depth() const;
       
   225     void invalidateGraphicsEffectsRecursively();
       
   226     void invalidateDepthRecursively();
       
   227     void resolveDepth();
       
   228     void addChild(QGraphicsItem *child);
       
   229     void removeChild(QGraphicsItem *child);
       
   230     void setParentItemHelper(QGraphicsItem *parent);
       
   231     void childrenBoundingRectHelper(QTransform *x, QRectF *rect);
       
   232     void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
       
   233                          const QRegion &exposedRegion, bool allItems = false) const;
       
   234     QRectF effectiveBoundingRect() const;
       
   235     QRectF sceneEffectiveBoundingRect() const;
       
   236 
       
   237     virtual void resolveFont(uint inheritedMask)
       
   238     {
       
   239         for (int i = 0; i < children.size(); ++i)
       
   240             children.at(i)->d_ptr->resolveFont(inheritedMask);
       
   241     }
       
   242 
       
   243     virtual void resolvePalette(uint inheritedMask)
       
   244     {
       
   245         for (int i = 0; i < children.size(); ++i)
       
   246             children.at(i)->d_ptr->resolveFont(inheritedMask);
       
   247     }
       
   248 
       
   249     virtual bool isProxyWidget() const;
       
   250 
       
   251     inline QVariant extra(Extra type) const
       
   252     {
       
   253         for (int i = 0; i < extras.size(); ++i) {
       
   254             const ExtraStruct &extra = extras.at(i);
       
   255             if (extra.type == type)
       
   256                 return extra.value;
       
   257         }
       
   258         return QVariant();
       
   259     }
       
   260 
       
   261     inline void setExtra(Extra type, const QVariant &value)
       
   262     {
       
   263         int index = -1;
       
   264         for (int i = 0; i < extras.size(); ++i) {
       
   265             if (extras.at(i).type == type) {
       
   266                 index = i;
       
   267                 break;
       
   268             }
       
   269         }
       
   270 
       
   271         if (index == -1) {
       
   272             extras << ExtraStruct(type, value);
       
   273         } else {
       
   274             extras[index].value = value;
       
   275         }
       
   276     }
       
   277 
       
   278     inline void unsetExtra(Extra type)
       
   279     {
       
   280         for (int i = 0; i < extras.size(); ++i) {
       
   281             if (extras.at(i).type == type) {
       
   282                 extras.removeAt(i);
       
   283                 return;
       
   284             }
       
   285         }
       
   286     }
       
   287 
       
   288     struct ExtraStruct {
       
   289         ExtraStruct(Extra type, QVariant value)
       
   290             : type(type), value(value)
       
   291         { }
       
   292 
       
   293         Extra type;
       
   294         QVariant value;
       
   295 
       
   296         bool operator<(Extra extra) const
       
   297         { return type < extra; }
       
   298     };
       
   299 
       
   300     QList<ExtraStruct> extras;
       
   301 
       
   302     QGraphicsItemCache *maybeExtraItemCache() const;
       
   303     QGraphicsItemCache *extraItemCache() const;
       
   304     void removeExtraItemCache();
       
   305 
       
   306     inline void setCachedClipPath(const QPainterPath &path)
       
   307     {
       
   308         cachedClipPath = path;
       
   309         dirtyClipPath = 0;
       
   310         emptyClipPath = 0;
       
   311     }
       
   312 
       
   313     inline void setEmptyCachedClipPath()
       
   314     {
       
   315         emptyClipPath = 1;
       
   316         dirtyClipPath = 0;
       
   317     }
       
   318 
       
   319     void setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect = QRectF());
       
   320 
       
   321     inline void invalidateCachedClipPath()
       
   322     { /*static int count = 0 ;qWarning("%i", ++count);*/ dirtyClipPath = 1; emptyClipPath = 0; }
       
   323 
       
   324     void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF());
       
   325     void updateCachedClipPathFromSetPosHelper(const QPointF &newPos);
       
   326     void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem);
       
   327     inline void ensureSceneTransform()
       
   328     {
       
   329         QGraphicsItem *that = q_func();
       
   330         ensureSceneTransformRecursive(&that);
       
   331     }
       
   332 
       
   333     inline bool hasTranslateOnlySceneTransform()
       
   334     {
       
   335         ensureSceneTransform();
       
   336         return sceneTransformTranslateOnly;
       
   337     }
       
   338 
       
   339     inline void invalidateChildrenSceneTransform()
       
   340     {
       
   341         for (int i = 0; i < children.size(); ++i)
       
   342             children.at(i)->d_ptr->dirtySceneTransform = 1;
       
   343     }
       
   344 
       
   345     inline qreal calcEffectiveOpacity() const
       
   346     {
       
   347         qreal o = opacity;
       
   348         QGraphicsItem *p = parent;
       
   349         int myFlags = flags;
       
   350         while (p) {
       
   351             int parentFlags = p->d_ptr->flags;
       
   352 
       
   353             // If I have a parent, and I don't ignore my parent's opacity, and my
       
   354             // parent propagates to me, then combine my local opacity with my parent's
       
   355             // effective opacity into my effective opacity.
       
   356             if ((myFlags & QGraphicsItem::ItemIgnoresParentOpacity)
       
   357                 || (parentFlags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
       
   358                 break;
       
   359             }
       
   360 
       
   361             o *= p->d_ptr->opacity;
       
   362             p = p->d_ptr->parent;
       
   363             myFlags = parentFlags;
       
   364         }
       
   365         return o;
       
   366     }
       
   367 
       
   368     inline bool isFullyTransparent() const
       
   369     {
       
   370         if (opacity < 0.001)
       
   371             return true;
       
   372         if (!parent)
       
   373             return false;
       
   374 
       
   375         return calcEffectiveOpacity() < 0.001;
       
   376     }
       
   377 
       
   378     inline qreal effectiveOpacity() const {
       
   379         if (!parent || !opacity)
       
   380             return opacity;
       
   381 
       
   382         return calcEffectiveOpacity();
       
   383     }
       
   384 
       
   385     inline qreal combineOpacityFromParent(qreal parentOpacity) const
       
   386     {
       
   387         if (parent && !(flags & QGraphicsItem::ItemIgnoresParentOpacity)
       
   388             && !(parent->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
       
   389             return parentOpacity * opacity;
       
   390         }
       
   391         return opacity;
       
   392     }
       
   393 
       
   394     inline bool childrenCombineOpacity() const
       
   395     {
       
   396         if (!children.size())
       
   397             return true;
       
   398         if (flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
       
   399             return false;
       
   400 
       
   401         for (int i = 0; i < children.size(); ++i) {
       
   402             if (children.at(i)->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)
       
   403                 return false;
       
   404         }
       
   405         return true;
       
   406     }
       
   407 
       
   408     inline bool isClippedAway() const
       
   409     { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); }
       
   410 
       
   411     inline bool childrenClippedToShape() const
       
   412     { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); }
       
   413 
       
   414     inline bool isInvisible() const
       
   415     {
       
   416         return !visible
       
   417                || (childrenClippedToShape() && isClippedAway())
       
   418                || (childrenCombineOpacity() && isFullyTransparent());
       
   419     }
       
   420 
       
   421     void setFocusHelper(Qt::FocusReason focusReason, bool climb);
       
   422     void setSubFocus(QGraphicsItem *rootItem = 0);
       
   423     void clearSubFocus(QGraphicsItem *rootItem = 0);
       
   424     void resetFocusProxy();
       
   425     virtual void subFocusItemChange();
       
   426 
       
   427     inline QTransform transformToParent() const;
       
   428     inline void ensureSortedChildren();
       
   429     static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b);
       
   430     void ensureSequentialSiblingIndex();
       
   431 
       
   432     QPainterPath cachedClipPath;
       
   433     QRectF childrenBoundingRect;
       
   434     QRectF needsRepaint;
       
   435     QMap<QWidget *, QRect> paintedViewBoundingRects;
       
   436     QPointF pos;
       
   437     qreal z;
       
   438     qreal opacity;
       
   439     QGraphicsScene *scene;
       
   440     QGraphicsItem *parent;
       
   441     QList<QGraphicsItem *> children;
       
   442     struct TransformData;
       
   443     TransformData *transformData;
       
   444     QGraphicsEffect *graphicsEffect;
       
   445     QTransform sceneTransform;
       
   446     int index;
       
   447     int siblingIndex;
       
   448     int itemDepth;  // Lazily calculated when calling depth().
       
   449     QGraphicsItem *focusProxy;
       
   450     QList<QGraphicsItem **> focusProxyRefs;
       
   451     QGraphicsItem *subFocusItem;
       
   452     QGraphicsItem *focusScopeItem;
       
   453     Qt::InputMethodHints imHints;
       
   454     QGraphicsItem::PanelModality panelModality;
       
   455     QMap<Qt::GestureType, Qt::GestureContext> gestureContext;
       
   456 
       
   457     // Packed 32 bits
       
   458     quint32 acceptedMouseButtons : 5;
       
   459     quint32 visible : 1;
       
   460     quint32 explicitlyHidden : 1;
       
   461     quint32 enabled : 1;
       
   462     quint32 explicitlyDisabled : 1;
       
   463     quint32 selected : 1;
       
   464     quint32 acceptsHover : 1;
       
   465     quint32 acceptDrops : 1;
       
   466     quint32 isMemberOfGroup : 1;
       
   467     quint32 handlesChildEvents : 1;
       
   468     quint32 itemDiscovered : 1;
       
   469     quint32 hasCursor : 1;
       
   470     quint32 ancestorFlags : 4;
       
   471     quint32 cacheMode : 2;
       
   472     quint32 hasBoundingRegionGranularity : 1;
       
   473     quint32 isWidget : 1;
       
   474     quint32 dirty : 1;
       
   475     quint32 dirtyChildren : 1;
       
   476     quint32 localCollisionHack : 1;
       
   477     quint32 dirtyClipPath : 1;
       
   478     quint32 emptyClipPath : 1;
       
   479     quint32 inSetPosHelper : 1;
       
   480     quint32 needSortChildren : 1;
       
   481     quint32 allChildrenDirty : 1;
       
   482 
       
   483     // Packed 32 bits
       
   484     quint32 fullUpdatePending : 1;
       
   485     quint32 flags : 16;
       
   486     quint32 dirtyChildrenBoundingRect : 1;
       
   487     quint32 paintedViewBoundingRectsNeedRepaint : 1;
       
   488     quint32 dirtySceneTransform : 1;
       
   489     quint32 geometryChanged : 1;
       
   490     quint32 inDestructor : 1;
       
   491     quint32 isObject : 1;
       
   492     quint32 ignoreVisible : 1;
       
   493     quint32 ignoreOpacity : 1;
       
   494     quint32 acceptTouchEvents : 1;
       
   495     quint32 acceptedTouchBeginEvent : 1;
       
   496     quint32 filtersDescendantEvents : 1;
       
   497     quint32 sceneTransformTranslateOnly : 1;
       
   498     quint32 notifyBoundingRectChanged : 1;
       
   499     quint32 notifyInvalidated : 1;
       
   500     quint32 mouseSetsFocus : 1;
       
   501 
       
   502     // New 32 bits
       
   503     quint32 explicitActivate : 1;
       
   504     quint32 wantsActive : 1;
       
   505     quint32 holesInSiblingIndex : 1;
       
   506     quint32 sequentialOrdering : 1;
       
   507     quint32 updateDueToGraphicsEffect : 1;
       
   508 
       
   509     // Optional stacking order
       
   510     int globalStackingOrder;
       
   511     QGraphicsItem *q_ptr;
       
   512 };
       
   513 
       
   514 struct QGraphicsItemPrivate::TransformData
       
   515 {
       
   516     QTransform transform;
       
   517     qreal scale;
       
   518     qreal rotation;
       
   519     qreal xOrigin;
       
   520     qreal yOrigin;
       
   521     QList<QGraphicsTransform *> graphicsTransforms;
       
   522     bool onlyTransform;
       
   523 
       
   524     TransformData() :
       
   525         scale(1.0), rotation(0.0),
       
   526         xOrigin(0.0), yOrigin(0.0),
       
   527         onlyTransform(true)
       
   528     { }
       
   529 
       
   530     QTransform computedFullTransform(QTransform *postmultiplyTransform = 0) const
       
   531     {
       
   532         if (onlyTransform) {
       
   533             if (!postmultiplyTransform || postmultiplyTransform->isIdentity())
       
   534                 return transform;
       
   535             if (transform.isIdentity())
       
   536                 return *postmultiplyTransform;
       
   537             return transform * *postmultiplyTransform;
       
   538         }
       
   539 
       
   540         QTransform x(transform);
       
   541         if (!graphicsTransforms.isEmpty()) {
       
   542             QMatrix4x4 m;
       
   543             for (int i = 0; i < graphicsTransforms.size(); ++i)
       
   544                 graphicsTransforms.at(i)->applyTo(&m);
       
   545             x *= m.toTransform(0);
       
   546         }
       
   547         x.translate(xOrigin, yOrigin);
       
   548         x.rotate(rotation);
       
   549         x.scale(scale, scale);
       
   550         x.translate(-xOrigin, -yOrigin);
       
   551         if (postmultiplyTransform)
       
   552             x *= *postmultiplyTransform;
       
   553         return x;
       
   554     }
       
   555 };
       
   556 
       
   557 struct QGraphicsItemPaintInfo
       
   558 {
       
   559     inline QGraphicsItemPaintInfo(const QTransform *const xform1, const QTransform *const xform2,
       
   560                                   const QTransform *const xform3,
       
   561                                   QRegion *r, QWidget *w, QStyleOptionGraphicsItem *opt,
       
   562                                   QPainter *p, qreal o, bool b1, bool b2)
       
   563         : viewTransform(xform1), transformPtr(xform2), effectTransform(xform3), exposedRegion(r), widget(w),
       
   564           option(opt), painter(p), opacity(o), wasDirtySceneTransform(b1), drawItem(b2)
       
   565     {}
       
   566 
       
   567     const QTransform *viewTransform;
       
   568     const QTransform *transformPtr;
       
   569     const QTransform *effectTransform;
       
   570     QRegion *exposedRegion;
       
   571     QWidget *widget;
       
   572     QStyleOptionGraphicsItem *option;
       
   573     QPainter *painter;
       
   574     qreal opacity;
       
   575     quint32 wasDirtySceneTransform : 1;
       
   576     quint32 drawItem : 1;
       
   577 };
       
   578 
       
   579 class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate
       
   580 {
       
   581 public:
       
   582     QGraphicsItemEffectSourcePrivate(QGraphicsItem *i)
       
   583         : QGraphicsEffectSourcePrivate(), item(i), info(0)
       
   584     {}
       
   585 
       
   586     inline void detach()
       
   587     { item->setGraphicsEffect(0); }
       
   588 
       
   589     inline const QGraphicsItem *graphicsItem() const
       
   590     { return item; }
       
   591 
       
   592     inline const QWidget *widget() const
       
   593     { return 0; }
       
   594 
       
   595     inline void update() {
       
   596         item->d_ptr->updateDueToGraphicsEffect = true;
       
   597         item->update();
       
   598         item->d_ptr->updateDueToGraphicsEffect = false;
       
   599     }
       
   600 
       
   601     inline void effectBoundingRectChanged()
       
   602     { item->prepareGeometryChange(); }
       
   603 
       
   604     inline bool isPixmap() const
       
   605     {
       
   606         return (item->type() == QGraphicsPixmapItem::Type);
       
   607             //|| (item->d_ptr->isObject && qobject_cast<QFxImage *>(q_func()));
       
   608     }
       
   609 
       
   610     inline const QStyleOption *styleOption() const
       
   611     { return info ? info->option : 0; }
       
   612 
       
   613     inline QRect deviceRect() const
       
   614     {
       
   615         if (!info || !info->widget) {
       
   616             qWarning("QGraphicsEffectSource::deviceRect: Not yet implemented, lacking device context");
       
   617             return QRect();
       
   618         }
       
   619         return info->widget->rect();
       
   620     }
       
   621 
       
   622     QRectF boundingRect(Qt::CoordinateSystem system) const;
       
   623     void draw(QPainter *);
       
   624     QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset) const;
       
   625 
       
   626     QGraphicsItem *item;
       
   627     QGraphicsItemPaintInfo *info;
       
   628     QTransform lastEffectTransform;
       
   629 };
       
   630 
       
   631 
       
   632 /*!
       
   633     Returns true if \a item1 is on top of \a item2.
       
   634     The items dont need to be siblings.
       
   635 
       
   636     \internal
       
   637 */
       
   638 inline bool qt_closestItemFirst(const QGraphicsItem *item1, const QGraphicsItem *item2)
       
   639 {
       
   640     // Siblings? Just check their z-values.
       
   641     const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
       
   642     const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
       
   643     if (d1->parent == d2->parent)
       
   644         return qt_closestLeaf(item1, item2);
       
   645 
       
   646     // Find common ancestor, and each item's ancestor closest to the common
       
   647     // ancestor.
       
   648     int item1Depth = d1->depth();
       
   649     int item2Depth = d2->depth();
       
   650     const QGraphicsItem *p = item1;
       
   651     const QGraphicsItem *t1 = item1;
       
   652     while (item1Depth > item2Depth && (p = p->d_ptr->parent)) {
       
   653         if (p == item2) {
       
   654             // item2 is one of item1's ancestors; item1 is on top
       
   655             return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
       
   656         }
       
   657         t1 = p;
       
   658         --item1Depth;
       
   659     }
       
   660     p = item2;
       
   661     const QGraphicsItem *t2 = item2;
       
   662     while (item2Depth > item1Depth && (p = p->d_ptr->parent)) {
       
   663         if (p == item1) {
       
   664             // item1 is one of item2's ancestors; item1 is not on top
       
   665             return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
       
   666         }
       
   667         t2 = p;
       
   668         --item2Depth;
       
   669     }
       
   670 
       
   671     // item1Ancestor is now at the same level as item2Ancestor, but not the same.
       
   672     const QGraphicsItem *p1 = t1;
       
   673     const QGraphicsItem *p2 = t2;
       
   674     while (t1 && t1 != t2) {
       
   675         p1 = t1;
       
   676         p2 = t2;
       
   677         t1 = t1->d_ptr->parent;
       
   678         t2 = t2->d_ptr->parent;
       
   679     }
       
   680 
       
   681     // in case we have a common ancestor, we compare the immediate children in the ancestor's path.
       
   682     // otherwise we compare the respective items' topLevelItems directly.
       
   683     return qt_closestLeaf(p1, p2);
       
   684 }
       
   685 
       
   686 /*!
       
   687     Returns true if \a item2 is on top of \a item1.
       
   688     The items dont need to be siblings.
       
   689 
       
   690     \internal
       
   691 */
       
   692 inline bool qt_closestItemLast(const QGraphicsItem *item1, const QGraphicsItem *item2)
       
   693 {
       
   694     return qt_closestItemFirst(item2, item1);
       
   695 }
       
   696 
       
   697 /*!
       
   698     \internal
       
   699 */
       
   700 inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
       
   701 {
       
   702     // Return true if sibling item1 is on top of item2.
       
   703     const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
       
   704     const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
       
   705     bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent;
       
   706     bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent;
       
   707     if (f1 != f2)
       
   708         return f2;
       
   709     if (d1->z != d2->z)
       
   710         return d1->z > d2->z;
       
   711     return d1->siblingIndex > d2->siblingIndex;
       
   712 }
       
   713 
       
   714 /*!
       
   715     \internal
       
   716 */
       
   717 inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
       
   718 { return qt_closestLeaf(item2, item1); }
       
   719 
       
   720 /*
       
   721    return the full transform of the item to the parent.  This include the position and all the transform data
       
   722 */
       
   723 inline QTransform QGraphicsItemPrivate::transformToParent() const
       
   724 {
       
   725     QTransform matrix;
       
   726     combineTransformToParent(&matrix);
       
   727     return matrix;
       
   728 }
       
   729 
       
   730 /*!
       
   731     \internal
       
   732 */
       
   733 inline void QGraphicsItemPrivate::ensureSortedChildren()
       
   734 {
       
   735     if (needSortChildren) {
       
   736         qSort(children.begin(), children.end(), qt_notclosestLeaf);
       
   737         needSortChildren = 0;
       
   738         sequentialOrdering = 1;
       
   739         for (int i = 0; i < children.size(); ++i) {
       
   740             if (children[i]->d_ptr->siblingIndex != i) {
       
   741                 sequentialOrdering = 0;
       
   742                 break;
       
   743             }
       
   744         }
       
   745     }
       
   746 }
       
   747 
       
   748 /*!
       
   749     \internal
       
   750 */
       
   751 inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem *b)
       
   752 {
       
   753     return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex;
       
   754 }
       
   755 
       
   756 QT_END_NAMESPACE
       
   757 
       
   758 #endif // QT_NO_GRAPHICSVIEW
       
   759 
       
   760 #endif