Fix Qt 5 to-do's in QGraphicsProxyWidget
[profile/ivi/qtbase.git] / src / widgets / graphicsview / qgraphicsitem_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
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 #include <qgraphicseffect.h>
65
66 #include <QtCore/qpoint.h>
67
68 #if !defined(QT_NO_GRAPHICSVIEW)
69
70 QT_BEGIN_NAMESPACE
71
72 class QGraphicsItemPrivate;
73
74 #ifndef QDECLARATIVELISTPROPERTY
75 #define QDECLARATIVELISTPROPERTY
76 template<typename T>
77 class QDeclarativeListProperty {
78 public:
79     typedef void (*AppendFunction)(QDeclarativeListProperty<T> *, T*);
80     typedef int (*CountFunction)(QDeclarativeListProperty<T> *);
81     typedef T *(*AtFunction)(QDeclarativeListProperty<T> *, int);
82     typedef void (*ClearFunction)(QDeclarativeListProperty<T> *);
83
84     QDeclarativeListProperty()
85         : object(0), data(0), append(0), count(0), at(0), clear(0), dummy1(0), dummy2(0) {}
86     QDeclarativeListProperty(QObject *o, QList<T *> &list)
87         : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at),
88           clear(qlist_clear), dummy1(0), dummy2(0) {}
89     QDeclarativeListProperty(QObject *o, void *d, AppendFunction a, CountFunction c = 0, AtFunction t = 0,
90                     ClearFunction r = 0)
91         : object(o), data(d), append(a), count(c), at(t), clear(r), dummy1(0), dummy2(0) {}
92
93     bool operator==(const QDeclarativeListProperty &o) const {
94         return object == o.object &&
95                data == o.data &&
96                append == o.append &&
97                count == o.count &&
98                at == o.at &&
99                clear == o.clear;
100     }
101
102     QObject *object;
103     void *data;
104
105     AppendFunction append;
106
107     CountFunction count;
108     AtFunction at;
109
110     ClearFunction clear;
111
112     void *dummy1;
113     void *dummy2;
114
115 private:
116     static void qlist_append(QDeclarativeListProperty *p, T *v) {
117         ((QList<T *> *)p->data)->append(v);
118     }
119     static int qlist_count(QDeclarativeListProperty *p) {
120         return ((QList<T *> *)p->data)->count();
121     }
122     static T *qlist_at(QDeclarativeListProperty *p, int idx) {
123         return ((QList<T *> *)p->data)->at(idx);
124     }
125     static void qlist_clear(QDeclarativeListProperty *p) {
126         return ((QList<T *> *)p->data)->clear();
127     }
128 };
129 #endif
130
131 class QGraphicsItemCache
132 {
133 public:
134     QGraphicsItemCache() : allExposed(false) { }
135
136     // ItemCoordinateCache only
137     QRect boundingRect;
138     QSize fixedSize;
139     QPixmapCache::Key key;
140
141     // DeviceCoordinateCache only
142     struct DeviceData {
143         DeviceData() {}
144         QTransform lastTransform;
145         QPoint cacheIndent;
146         QPixmapCache::Key key;
147     };
148     QHash<QPaintDevice *, DeviceData> deviceData;
149
150     // List of logical exposed rects
151     QVector<QRectF> exposed;
152     bool allExposed;
153
154     // Empty cache
155     void purge();
156 };
157
158 class Q_WIDGETS_EXPORT QGraphicsItemPrivate
159 {
160     Q_DECLARE_PUBLIC(QGraphicsItem)
161 public:
162     enum Extra {
163         ExtraToolTip,
164         ExtraCursor,
165         ExtraCacheData,
166         ExtraMaxDeviceCoordCacheSize,
167         ExtraBoundingRegionGranularity
168     };
169
170     enum AncestorFlag {
171         NoFlag = 0,
172         AncestorHandlesChildEvents = 0x1,
173         AncestorClipsChildren = 0x2,
174         AncestorIgnoresTransformations = 0x4,
175         AncestorFiltersChildEvents = 0x8
176     };
177
178     inline QGraphicsItemPrivate()
179         : z(0),
180         opacity(1.),
181         scene(0),
182         parent(0),
183         transformData(0),
184         graphicsEffect(0),
185         index(-1),
186         siblingIndex(-1),
187         itemDepth(-1),
188         focusProxy(0),
189         subFocusItem(0),
190         focusScopeItem(0),
191         imHints(Qt::ImhNone),
192         panelModality(QGraphicsItem::NonModal),
193         acceptedMouseButtons(0x1f),
194         visible(1),
195         explicitlyHidden(0),
196         enabled(1),
197         explicitlyDisabled(0),
198         selected(0),
199         acceptsHover(0),
200         acceptDrops(0),
201         isMemberOfGroup(0),
202         handlesChildEvents(0),
203         itemDiscovered(0),
204         hasCursor(0),
205         ancestorFlags(0),
206         cacheMode(0),
207         hasBoundingRegionGranularity(0),
208         isWidget(0),
209         dirty(0),
210         dirtyChildren(0),
211         localCollisionHack(0),
212         inSetPosHelper(0),
213         needSortChildren(0),
214         allChildrenDirty(0),
215         fullUpdatePending(0),
216         dirtyChildrenBoundingRect(1),
217         flags(0),
218         paintedViewBoundingRectsNeedRepaint(0),
219         dirtySceneTransform(1),
220         geometryChanged(1),
221         inDestructor(0),
222         isObject(0),
223         ignoreVisible(0),
224         ignoreOpacity(0),
225         acceptTouchEvents(0),
226         acceptedTouchBeginEvent(0),
227         filtersDescendantEvents(0),
228         sceneTransformTranslateOnly(0),
229         notifyBoundingRectChanged(0),
230         notifyInvalidated(0),
231         mouseSetsFocus(1),
232         explicitActivate(0),
233         wantsActive(0),
234         holesInSiblingIndex(0),
235         sequentialOrdering(1),
236         updateDueToGraphicsEffect(0),
237         scenePosDescendants(0),
238         pendingPolish(0),
239         mayHaveChildWithGraphicsEffect(0),
240         isDeclarativeItem(0),
241         sendParentChangeNotification(0),
242         globalStackingOrder(-1),
243         q_ptr(0)
244     {
245     }
246
247     inline virtual ~QGraphicsItemPrivate()
248     { }
249
250     static const QGraphicsItemPrivate *get(const QGraphicsItem *item)
251     {
252         return item->d_ptr.data();
253     }
254     static QGraphicsItemPrivate *get(QGraphicsItem *item)
255     {
256         return item->d_ptr.data();
257     }
258
259     void updateChildWithGraphicsEffectFlagRecursively();
260     void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
261                             AncestorFlag flag = NoFlag, bool enabled = false, bool root = true);
262     void updateAncestorFlags();
263     void setIsMemberOfGroup(bool enabled);
264     void remapItemPos(QEvent *event, QGraphicsItem *item);
265     QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const;
266     inline bool itemIsUntransformable() const
267     {
268         return (flags & QGraphicsItem::ItemIgnoresTransformations)
269             || (ancestorFlags & AncestorIgnoresTransformations);
270     }
271
272     void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const;
273     void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const;
274     virtual void updateSceneTransformFromParent();
275
276     static bool movableAncestorIsSelected(const QGraphicsItem *item);
277
278     virtual void setPosHelper(const QPointF &pos);
279     void setTransformHelper(const QTransform &transform);
280     void prependGraphicsTransform(QGraphicsTransform *t);
281     void appendGraphicsTransform(QGraphicsTransform *t);
282     void setVisibleHelper(bool newVisible, bool explicitly, bool update = true);
283     void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
284     bool discardUpdateRequest(bool ignoreVisibleBit = false,
285                               bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
286     virtual void transformChanged() {}
287     int depth() const;
288 #ifndef QT_NO_GRAPHICSEFFECT
289     enum InvalidateReason {
290         OpacityChanged
291     };
292     void invalidateParentGraphicsEffectsRecursively();
293     void invalidateChildGraphicsEffectsRecursively(InvalidateReason reason);
294 #endif //QT_NO_GRAPHICSEFFECT
295     void invalidateDepthRecursively();
296     void resolveDepth();
297     void addChild(QGraphicsItem *child);
298     void removeChild(QGraphicsItem *child);
299     QDeclarativeListProperty<QGraphicsObject> childrenList();
300     void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant,
301                              const QVariant *thisPointerVariant);
302     void childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem);
303     void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
304                          const QRegion &exposedRegion, bool allItems = false) const;
305     QRectF effectiveBoundingRect(QGraphicsItem *topMostEffectItem = 0) const;
306     QRectF sceneEffectiveBoundingRect() const;
307
308     QRectF effectiveBoundingRect(const QRectF &rect) const;
309
310     virtual void resolveFont(uint inheritedMask)
311     {
312         for (int i = 0; i < children.size(); ++i)
313             children.at(i)->d_ptr->resolveFont(inheritedMask);
314     }
315
316     virtual void resolvePalette(uint inheritedMask)
317     {
318         for (int i = 0; i < children.size(); ++i)
319             children.at(i)->d_ptr->resolveFont(inheritedMask);
320     }
321
322     virtual bool isProxyWidget() const;
323
324     inline QVariant extra(Extra type) const
325     {
326         for (int i = 0; i < extras.size(); ++i) {
327             const ExtraStruct &extra = extras.at(i);
328             if (extra.type == type)
329                 return extra.value;
330         }
331         return QVariant();
332     }
333
334     inline void setExtra(Extra type, const QVariant &value)
335     {
336         int index = -1;
337         for (int i = 0; i < extras.size(); ++i) {
338             if (extras.at(i).type == type) {
339                 index = i;
340                 break;
341             }
342         }
343
344         if (index == -1) {
345             extras << ExtraStruct(type, value);
346         } else {
347             extras[index].value = value;
348         }
349     }
350
351     inline void unsetExtra(Extra type)
352     {
353         for (int i = 0; i < extras.size(); ++i) {
354             if (extras.at(i).type == type) {
355                 extras.removeAt(i);
356                 return;
357             }
358         }
359     }
360
361     struct ExtraStruct {
362         ExtraStruct(Extra type, QVariant value)
363             : type(type), value(value)
364         { }
365
366         Extra type;
367         QVariant value;
368
369         bool operator<(Extra extra) const
370         { return type < extra; }
371     };
372
373     QList<ExtraStruct> extras;
374
375     QGraphicsItemCache *maybeExtraItemCache() const;
376     QGraphicsItemCache *extraItemCache() const;
377     void removeExtraItemCache();
378
379     void updatePaintedViewBoundingRects(bool updateChildren);
380     void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem);
381     inline void ensureSceneTransform()
382     {
383         QGraphicsItem *that = q_func();
384         ensureSceneTransformRecursive(&that);
385     }
386
387     inline bool hasTranslateOnlySceneTransform()
388     {
389         ensureSceneTransform();
390         return sceneTransformTranslateOnly;
391     }
392
393     inline void invalidateChildrenSceneTransform()
394     {
395         for (int i = 0; i < children.size(); ++i)
396             children.at(i)->d_ptr->dirtySceneTransform = 1;
397     }
398
399     inline qreal calcEffectiveOpacity() const
400     {
401         qreal o = opacity;
402         QGraphicsItem *p = parent;
403         int myFlags = flags;
404         while (p) {
405             int parentFlags = p->d_ptr->flags;
406
407             // If I have a parent, and I don't ignore my parent's opacity, and my
408             // parent propagates to me, then combine my local opacity with my parent's
409             // effective opacity into my effective opacity.
410             if ((myFlags & QGraphicsItem::ItemIgnoresParentOpacity)
411                 || (parentFlags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
412                 break;
413             }
414
415             o *= p->d_ptr->opacity;
416             p = p->d_ptr->parent;
417             myFlags = parentFlags;
418         }
419         return o;
420     }
421
422     inline bool isOpacityNull() const
423     { return (opacity < qreal(0.001)); }
424
425     static inline bool isOpacityNull(qreal opacity)
426     { return (opacity < qreal(0.001)); }
427
428     inline bool isFullyTransparent() const
429     {
430         if (isOpacityNull())
431             return true;
432         if (!parent)
433             return false;
434
435         return isOpacityNull(calcEffectiveOpacity());
436     }
437
438     inline qreal effectiveOpacity() const {
439         if (!parent || !opacity)
440             return opacity;
441
442         return calcEffectiveOpacity();
443     }
444
445     inline qreal combineOpacityFromParent(qreal parentOpacity) const
446     {
447         if (parent && !(flags & QGraphicsItem::ItemIgnoresParentOpacity)
448             && !(parent->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
449             return parentOpacity * opacity;
450         }
451         return opacity;
452     }
453
454     inline bool childrenCombineOpacity() const
455     {
456         if (!children.size())
457             return true;
458         if (flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
459             return false;
460
461         for (int i = 0; i < children.size(); ++i) {
462             if (children.at(i)->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)
463                 return false;
464         }
465         return true;
466     }
467
468     inline bool childrenClippedToShape() const
469     { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); }
470
471     inline bool isInvisible() const
472     {
473         return !visible || (childrenCombineOpacity() && isFullyTransparent());
474     }
475
476     inline void markParentDirty(bool updateBoundingRect = false);
477
478     void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide);
479     void clearFocusHelper(bool giveFocusToParent);
480     void setSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0);
481     void clearSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0);
482     void resetFocusProxy();
483     virtual void subFocusItemChange();
484     virtual void focusScopeItemChange(bool isSubFocusItem);
485
486     static void children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item);
487     static int children_count(QDeclarativeListProperty<QGraphicsObject> *list);
488     static QGraphicsObject *children_at(QDeclarativeListProperty<QGraphicsObject> *list, int);
489     static void children_clear(QDeclarativeListProperty<QGraphicsObject> *list);
490
491     inline QTransform transformToParent() const;
492     inline void ensureSortedChildren();
493     static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b);
494     void ensureSequentialSiblingIndex();
495     inline void sendScenePosChange();
496     virtual void siblingOrderChange();
497
498     // Private Properties
499     virtual qreal width() const;
500     virtual void setWidth(qreal);
501     virtual void resetWidth();
502
503     virtual qreal height() const;
504     virtual void setHeight(qreal);
505     virtual void resetHeight();
506
507     QRectF childrenBoundingRect;
508     QRectF needsRepaint;
509     QHash<QWidget *, QRect> paintedViewBoundingRects;
510     QPointF pos;
511     qreal z;
512     qreal opacity;
513     QGraphicsScene *scene;
514     QGraphicsItem *parent;
515     QList<QGraphicsItem *> children;
516     struct TransformData;
517     TransformData *transformData;
518     QGraphicsEffect *graphicsEffect;
519     QTransform sceneTransform;
520     int index;
521     int siblingIndex;
522     int itemDepth;  // Lazily calculated when calling depth().
523     QGraphicsItem *focusProxy;
524     QList<QGraphicsItem **> focusProxyRefs;
525     QGraphicsItem *subFocusItem;
526     QGraphicsItem *focusScopeItem;
527     Qt::InputMethodHints imHints;
528     QGraphicsItem::PanelModality panelModality;
529 #ifndef QT_NO_GESTURES
530     QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
531 #endif
532
533     // Packed 32 bits
534     quint32 acceptedMouseButtons : 5;
535     quint32 visible : 1;
536     quint32 explicitlyHidden : 1;
537     quint32 enabled : 1;
538     quint32 explicitlyDisabled : 1;
539     quint32 selected : 1;
540     quint32 acceptsHover : 1;
541     quint32 acceptDrops : 1;
542     quint32 isMemberOfGroup : 1;
543     quint32 handlesChildEvents : 1;
544     quint32 itemDiscovered : 1;
545     quint32 hasCursor : 1;
546     quint32 ancestorFlags : 4;
547     quint32 cacheMode : 2;
548     quint32 hasBoundingRegionGranularity : 1;
549     quint32 isWidget : 1;
550     quint32 dirty : 1;
551     quint32 dirtyChildren : 1;
552     quint32 localCollisionHack : 1;
553     quint32 inSetPosHelper : 1;
554     quint32 needSortChildren : 1;
555     quint32 allChildrenDirty : 1;
556     quint32 fullUpdatePending : 1;
557     quint32 dirtyChildrenBoundingRect : 1;
558
559     // Packed 32 bits
560     quint32 flags : 19;
561     quint32 paintedViewBoundingRectsNeedRepaint : 1;
562     quint32 dirtySceneTransform : 1;
563     quint32 geometryChanged : 1;
564     quint32 inDestructor : 1;
565     quint32 isObject : 1;
566     quint32 ignoreVisible : 1;
567     quint32 ignoreOpacity : 1;
568     quint32 acceptTouchEvents : 1;
569     quint32 acceptedTouchBeginEvent : 1;
570     quint32 filtersDescendantEvents : 1;
571     quint32 sceneTransformTranslateOnly : 1;
572     quint32 notifyBoundingRectChanged : 1;
573     quint32 notifyInvalidated : 1;
574
575     // New 32 bits
576     quint32 mouseSetsFocus : 1;
577     quint32 explicitActivate : 1;
578     quint32 wantsActive : 1;
579     quint32 holesInSiblingIndex : 1;
580     quint32 sequentialOrdering : 1;
581     quint32 updateDueToGraphicsEffect : 1;
582     quint32 scenePosDescendants : 1;
583     quint32 pendingPolish : 1;
584     quint32 mayHaveChildWithGraphicsEffect : 1;
585     quint32 isDeclarativeItem : 1;
586     quint32 sendParentChangeNotification : 1;
587     quint32 padding : 21;
588
589     // Optional stacking order
590     int globalStackingOrder;
591     QGraphicsItem *q_ptr;
592 };
593
594 struct QGraphicsItemPrivate::TransformData
595 {
596     QTransform transform;
597     qreal scale;
598     qreal rotation;
599     qreal xOrigin;
600     qreal yOrigin;
601     QList<QGraphicsTransform *> graphicsTransforms;
602     bool onlyTransform;
603
604     TransformData() :
605         scale(1.0), rotation(0.0),
606         xOrigin(0.0), yOrigin(0.0),
607         onlyTransform(true)
608     { }
609
610     QTransform computedFullTransform(QTransform *postmultiplyTransform = 0) const
611     {
612         if (onlyTransform) {
613             if (!postmultiplyTransform || postmultiplyTransform->isIdentity())
614                 return transform;
615             if (transform.isIdentity())
616                 return *postmultiplyTransform;
617             return transform * *postmultiplyTransform;
618         }
619
620         QTransform x(transform);
621         if (!graphicsTransforms.isEmpty()) {
622             QMatrix4x4 m;
623             for (int i = 0; i < graphicsTransforms.size(); ++i)
624                 graphicsTransforms.at(i)->applyTo(&m);
625             x *= m.toTransform();
626         }
627         x.translate(xOrigin, yOrigin);
628         x.rotate(rotation);
629         x.scale(scale, scale);
630         x.translate(-xOrigin, -yOrigin);
631         if (postmultiplyTransform)
632             x *= *postmultiplyTransform;
633         return x;
634     }
635 };
636
637 struct QGraphicsItemPaintInfo
638 {
639     inline QGraphicsItemPaintInfo(const QTransform *const xform1, const QTransform *const xform2,
640                                   const QTransform *const xform3,
641                                   QRegion *r, QWidget *w, QStyleOptionGraphicsItem *opt,
642                                   QPainter *p, qreal o, bool b1, bool b2)
643         : viewTransform(xform1), transformPtr(xform2), effectTransform(xform3), exposedRegion(r), widget(w),
644           option(opt), painter(p), opacity(o), wasDirtySceneTransform(b1), drawItem(b2)
645     {}
646
647     const QTransform *viewTransform;
648     const QTransform *transformPtr;
649     const QTransform *effectTransform;
650     QRegion *exposedRegion;
651     QWidget *widget;
652     QStyleOptionGraphicsItem *option;
653     QPainter *painter;
654     qreal opacity;
655     quint32 wasDirtySceneTransform : 1;
656     quint32 drawItem : 1;
657 };
658
659 #ifndef QT_NO_GRAPHICSEFFECT
660 class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate
661 {
662 public:
663     QGraphicsItemEffectSourcePrivate(QGraphicsItem *i)
664         : QGraphicsEffectSourcePrivate(), item(i), info(0)
665     {}
666
667     inline void detach()
668     {
669         item->d_ptr->graphicsEffect = 0;
670         item->prepareGeometryChange();
671     }
672
673     inline const QGraphicsItem *graphicsItem() const
674     { return item; }
675
676     inline const QWidget *widget() const
677     { return 0; }
678
679     inline void update() {
680         item->d_ptr->updateDueToGraphicsEffect = true;
681         item->update();
682         item->d_ptr->updateDueToGraphicsEffect = false;
683     }
684
685     inline void effectBoundingRectChanged()
686     { item->prepareGeometryChange(); }
687
688     inline bool isPixmap() const
689     {
690         return item->type() == QGraphicsPixmapItem::Type
691                && !(item->flags() & QGraphicsItem::ItemIsSelectable)
692                && item->d_ptr->children.size() == 0;
693             //|| (item->d_ptr->isObject && qobject_cast<QDeclarativeImage *>(q_func()));
694     }
695
696     inline const QStyleOption *styleOption() const
697     { return info ? info->option : 0; }
698
699     inline QRect deviceRect() const
700     {
701         if (!info || !info->widget) {
702             qWarning("QGraphicsEffectSource::deviceRect: Not yet implemented, lacking device context");
703             return QRect();
704         }
705         return info->widget->rect();
706     }
707
708     QRectF boundingRect(Qt::CoordinateSystem system) const;
709     void draw(QPainter *);
710     QPixmap pixmap(Qt::CoordinateSystem system,
711                    QPoint *offset,
712                    QGraphicsEffect::PixmapPadMode mode) const;
713     QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = 0) const;
714
715     QGraphicsItem *item;
716     QGraphicsItemPaintInfo *info;
717     QTransform lastEffectTransform;
718 };
719 #endif //QT_NO_GRAPHICSEFFECT
720
721 /*!
722     Returns true if \a item1 is on top of \a item2.
723     The items don't need to be siblings.
724
725     \internal
726 */
727 inline bool qt_closestItemFirst(const QGraphicsItem *item1, const QGraphicsItem *item2)
728 {
729     // Siblings? Just check their z-values.
730     const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
731     const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
732     if (d1->parent == d2->parent)
733         return qt_closestLeaf(item1, item2);
734
735     // Find common ancestor, and each item's ancestor closest to the common
736     // ancestor.
737     int item1Depth = d1->depth();
738     int item2Depth = d2->depth();
739     const QGraphicsItem *p = item1;
740     const QGraphicsItem *t1 = item1;
741     while (item1Depth > item2Depth && (p = p->d_ptr->parent)) {
742         if (p == item2) {
743             // item2 is one of item1's ancestors; item1 is on top
744             return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
745         }
746         t1 = p;
747         --item1Depth;
748     }
749     p = item2;
750     const QGraphicsItem *t2 = item2;
751     while (item2Depth > item1Depth && (p = p->d_ptr->parent)) {
752         if (p == item1) {
753             // item1 is one of item2's ancestors; item1 is not on top
754             return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
755         }
756         t2 = p;
757         --item2Depth;
758     }
759
760     // item1Ancestor is now at the same level as item2Ancestor, but not the same.
761     const QGraphicsItem *p1 = t1;
762     const QGraphicsItem *p2 = t2;
763     while (t1 && t1 != t2) {
764         p1 = t1;
765         p2 = t2;
766         t1 = t1->d_ptr->parent;
767         t2 = t2->d_ptr->parent;
768     }
769
770     // in case we have a common ancestor, we compare the immediate children in the ancestor's path.
771     // otherwise we compare the respective items' topLevelItems directly.
772     return qt_closestLeaf(p1, p2);
773 }
774
775 /*!
776     Returns true if \a item2 is on top of \a item1.
777     The items don't need to be siblings.
778
779     \internal
780 */
781 inline bool qt_closestItemLast(const QGraphicsItem *item1, const QGraphicsItem *item2)
782 {
783     return qt_closestItemFirst(item2, item1);
784 }
785
786 /*!
787     \internal
788 */
789 inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
790 {
791     // Return true if sibling item1 is on top of item2.
792     const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
793     const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
794     bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent;
795     bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent;
796     if (f1 != f2)
797         return f2;
798     if (d1->z != d2->z)
799         return d1->z > d2->z;
800     return d1->siblingIndex > d2->siblingIndex;
801 }
802
803 /*!
804     \internal
805 */
806 inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
807 { return qt_closestLeaf(item2, item1); }
808
809 /*
810    return the full transform of the item to the parent.  This include the position and all the transform data
811 */
812 inline QTransform QGraphicsItemPrivate::transformToParent() const
813 {
814     QTransform matrix;
815     combineTransformToParent(&matrix);
816     return matrix;
817 }
818
819 /*!
820     \internal
821 */
822 inline void QGraphicsItemPrivate::ensureSortedChildren()
823 {
824     if (needSortChildren) {
825         needSortChildren = 0;
826         sequentialOrdering = 1;
827         if (children.isEmpty())
828             return;
829         qSort(children.begin(), children.end(), qt_notclosestLeaf);
830         for (int i = 0; i < children.size(); ++i) {
831             if (children.at(i)->d_ptr->siblingIndex != i) {
832                 sequentialOrdering = 0;
833                 break;
834             }
835         }
836     }
837 }
838
839 /*!
840     \internal
841 */
842 inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem *b)
843 {
844     return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex;
845 }
846
847 /*!
848     \internal
849 */
850 inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect)
851 {
852     QGraphicsItemPrivate *parentp = this;
853 #ifndef QT_NO_GRAPHICSEFFECT
854     if (updateBoundingRect && parentp->graphicsEffect && !parentp->inSetPosHelper) {
855         parentp->notifyInvalidated = 1;
856         static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
857                                                         ->source->d_func())->invalidateCache();
858     }
859 #endif
860     while (parentp->parent) {
861         parentp = parentp->parent->d_ptr.data();
862         parentp->dirtyChildren = 1;
863
864         if (updateBoundingRect) {
865             parentp->dirtyChildrenBoundingRect = 1;
866             // ### Only do this if the parent's effect applies to the entire subtree.
867             parentp->notifyBoundingRectChanged = 1;
868         }
869 #ifndef QT_NO_GRAPHICSEFFECT
870         if (parentp->graphicsEffect) {
871             if (updateBoundingRect) {
872                 static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
873                                                                 ->source->d_func())->invalidateCache();
874                 parentp->notifyInvalidated = 1;
875             }
876             if (parentp->scene && parentp->graphicsEffect->isEnabled()) {
877                 parentp->dirty = 1;
878                 parentp->fullUpdatePending = 1;
879             }
880         }
881 #endif
882     }
883 }
884
885 QT_END_NAMESPACE
886
887 #endif // QT_NO_GRAPHICSVIEW
888
889 #endif