src/gui/graphicsview/qgraphicsitem.cpp
changeset 30 5dc02b23752f
parent 25 e24348a560a6
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    48     \ingroup graphicsview-api
    48     \ingroup graphicsview-api
    49 
    49 
    50     It provides a light-weight foundation for writing your own custom items.
    50     It provides a light-weight foundation for writing your own custom items.
    51     This includes defining the item's geometry, collision detection, its
    51     This includes defining the item's geometry, collision detection, its
    52     painting implementation and item interaction through its event handlers.
    52     painting implementation and item interaction through its event handlers.
    53     QGraphicsItem is part of \l{The Graphics View Framework}
    53     QGraphicsItem is part of the \l{Graphics View Framework}
    54 
    54 
    55     \image graphicsview-items.png
    55     \image graphicsview-items.png
    56 
    56 
    57     For convenience, Qt provides a set of standard graphics items for the most
    57     For convenience, Qt provides a set of standard graphics items for the most
    58     common shapes. These are:
    58     common shapes. These are:
   262     in it using a key-value pair (the key being an integer, and the value is a
   262     in it using a key-value pair (the key being an integer, and the value is a
   263     QVariant). To get custom data from an item, call data(). This
   263     QVariant). To get custom data from an item, call data(). This
   264     functionality is completely untouched by Qt itself; it is provided for the
   264     functionality is completely untouched by Qt itself; it is provided for the
   265     user's convenience.
   265     user's convenience.
   266 
   266 
   267     \sa QGraphicsScene, QGraphicsView, {The Graphics View Framework}
   267     \sa QGraphicsScene, QGraphicsView, {Graphics View Framework}
   268 */
   268 */
   269 
   269 
   270 /*!
   270 /*!
   271     \variable QGraphicsItem::Type
   271     \variable QGraphicsItem::Type
   272 
   272 
   379     do not need to be painted to ensure that Graphics View avoids unnecessary
   379     do not need to be painted to ensure that Graphics View avoids unnecessary
   380     painting preparations. This flag was introduced in Qt 4.6.
   380     painting preparations. This flag was introduced in Qt 4.6.
   381 
   381 
   382     \value ItemSendsGeometryChanges The item enables itemChange()
   382     \value ItemSendsGeometryChanges The item enables itemChange()
   383     notifications for ItemPositionChange, ItemPositionHasChanged,
   383     notifications for ItemPositionChange, ItemPositionHasChanged,
   384     ItemMatrixChange, ItemTransformChange, and ItemTransformHasChanged. For
   384     ItemMatrixChange, ItemTransformChange, ItemTransformHasChanged,
       
   385     ItemRotationChange, ItemRotationHasChanged, ItemScaleChange, ItemScaleHasChanged,
       
   386     ItemTransformOriginPointChange, and ItemTransformOriginPointHasChanged. For
   385     performance reasons, these notifications are disabled by default. You must
   387     performance reasons, these notifications are disabled by default. You must
   386     enable this flag to receive notifications for position and transform
   388     enable this flag to receive notifications for position and transform
   387     changes. This flag was introduced in Qt 4.6.
   389     changes. This flag was introduced in Qt 4.6.
   388 
   390 
   389     \value ItemAcceptsInputMethod The item supports input methods typically
   391     \value ItemAcceptsInputMethod The item supports input methods typically
   472     transformation properties is changed. This notification is sent if the
   474     transformation properties is changed. This notification is sent if the
   473     ItemSendsGeometryChanges flag is enabled, and after the item's local
   475     ItemSendsGeometryChanges flag is enabled, and after the item's local
   474     transformation matrix has changed. The value argument is the new matrix
   476     transformation matrix has changed. The value argument is the new matrix
   475     (same as transform()), and QGraphicsItem ignores the return value for this
   477     (same as transform()), and QGraphicsItem ignores the return value for this
   476     notification (i.e., a read-only notification).
   478     notification (i.e., a read-only notification).
       
   479 
       
   480     \value ItemRotationChange The item's rotation property changes. This
       
   481     notification is sent if the ItemSendsGeometryChanges flag is enabled, and
       
   482     when the item's rotation property changes (i.e., as a result of calling
       
   483     setRotation()). The value argument is the new rotation (i.e., a double);
       
   484     to get the old rotation, call rotation(). Do not call setRotation() in
       
   485     itemChange() as this notification is delivered; instead, you can return
       
   486     the new rotation from itemChange().
       
   487 
       
   488     \value ItemRotationHasChanged The item's rotation property has changed.
       
   489     This notification is sent if the ItemSendsGeometryChanges flag is enabled,
       
   490     and after the item's rotation property has changed. The value argument is
       
   491     the new rotation (i.e., a double), and QGraphicsItem ignores the return
       
   492     value for this notification (i.e., a read-only notification). Do not call
       
   493     setRotation() in itemChange() as this notification is delivered.
       
   494 
       
   495     \value ItemScaleChange The item's scale property changes. This notification
       
   496     is sent if the ItemSendsGeometryChanges flag is enabled, and when the item's
       
   497     scale property changes (i.e., as a result of calling setScale()). The value
       
   498     argument is the new scale (i.e., a double); to get the old scale, call
       
   499     scale(). Do not call setScale() in itemChange() as this notification is
       
   500     delivered; instead, you can return the new scale from itemChange().
       
   501 
       
   502     \value ItemScaleHasChanged The item's scale property has changed. This
       
   503     notification is sent if the ItemSendsGeometryChanges flag is enabled, and
       
   504     after the item's scale property has changed. The value argument is the new
       
   505     scale (i.e., a double), and QGraphicsItem ignores the return value for this
       
   506     notification (i.e., a read-only notification). Do not call setScale() in
       
   507     itemChange() as this notification is delivered.
       
   508 
       
   509     \value ItemTransformOriginPointChange The item's transform origin point
       
   510     property changes. This notification is sent if the ItemSendsGeometryChanges
       
   511     flag is enabled, and when the item's transform origin point property changes
       
   512     (i.e., as a result of calling setTransformOriginPoint()). The value argument
       
   513     is the new origin point (i.e., a QPointF); to get the old origin point, call
       
   514     transformOriginPoint(). Do not call setTransformOriginPoint() in itemChange()
       
   515     as this notification is delivered; instead, you can return the new transform
       
   516     origin point from itemChange().
       
   517 
       
   518     \value ItemTransformOriginPointHasChanged The item's transform origin point
       
   519     property has changed. This notification is sent if the ItemSendsGeometryChanges
       
   520     flag is enabled, and after the item's transform origin point property has
       
   521     changed. The value argument is the new origin point (i.e., a QPointF), and
       
   522     QGraphicsItem ignores the return value for this notification (i.e., a read-only
       
   523     notification). Do not call setTransformOriginPoint() in itemChange() as this
       
   524     notification is delivered.
   477 
   525 
   478     \value ItemSelectedChange The item's selected state changes. If the item is
   526     \value ItemSelectedChange The item's selected state changes. If the item is
   479     presently selected, it will become unselected, and vice verca. The value
   527     presently selected, it will become unselected, and vice verca. The value
   480     argument is the new selected state (i.e., true or false). Do not call
   528     argument is the new selected state (i.e., true or false). Do not call
   481     setSelected() in itemChange() as this notification is delivered; instead, you
   529     setSelected() in itemChange() as this notification is delivered; instead, you
   671 #include <QtCore/qpoint.h>
   719 #include <QtCore/qpoint.h>
   672 #include <QtCore/qstack.h>
   720 #include <QtCore/qstack.h>
   673 #include <QtCore/qtimer.h>
   721 #include <QtCore/qtimer.h>
   674 #include <QtCore/qvariant.h>
   722 #include <QtCore/qvariant.h>
   675 #include <QtCore/qvarlengtharray.h>
   723 #include <QtCore/qvarlengtharray.h>
       
   724 #include <QtCore/qnumeric.h>
   676 #include <QtGui/qapplication.h>
   725 #include <QtGui/qapplication.h>
   677 #include <QtGui/qbitmap.h>
   726 #include <QtGui/qbitmap.h>
   678 #include <QtGui/qpainter.h>
   727 #include <QtGui/qpainter.h>
   679 #include <QtGui/qpainterpath.h>
   728 #include <QtGui/qpainterpath.h>
   680 #include <QtGui/qpixmapcache.h>
   729 #include <QtGui/qpixmapcache.h>
   681 #include <QtGui/qstyleoption.h>
   730 #include <QtGui/qstyleoption.h>
   682 #include <QtGui/qevent.h>
   731 #include <QtGui/qevent.h>
   683 #include <QtGui/qinputcontext.h>
   732 #include <QtGui/qinputcontext.h>
   684 #include <QtGui/qgraphicseffect.h>
   733 #include <QtGui/qgraphicseffect.h>
       
   734 #ifndef QT_NO_ACCESSIBILITY
       
   735 # include "qaccessible.h"
       
   736 #endif
   685 
   737 
   686 #include <private/qgraphicsitem_p.h>
   738 #include <private/qgraphicsitem_p.h>
   687 #include <private/qgraphicswidget_p.h>
   739 #include <private/qgraphicswidget_p.h>
   688 #include <private/qtextcontrol_p.h>
   740 #include <private/qtextcontrol_p.h>
   689 #include <private/qtextdocumentlayout_p.h>
   741 #include <private/qtextdocumentlayout_p.h>
   690 #include <private/qtextengine_p.h>
   742 #include <private/qtextengine_p.h>
   691 #include <private/qwidget_p.h>
   743 #include <private/qwidget_p.h>
       
   744 #include <private/qapplication_p.h>
   692 
   745 
   693 #ifdef Q_WS_X11
   746 #ifdef Q_WS_X11
   694 #include <private/qt_x11_p.h>
   747 #include <private/qt_x11_p.h>
   695 #include <private/qpixmap_x11_p.h>
   748 #include <private/qpixmap_x11_p.h>
   696 #endif
   749 #endif
  1035 {
  1088 {
  1036     Q_Q(QGraphicsItem);
  1089     Q_Q(QGraphicsItem);
  1037     if (newParent == parent)
  1090     if (newParent == parent)
  1038         return;
  1091         return;
  1039 
  1092 
       
  1093     if (isWidget)
       
  1094         static_cast<QGraphicsWidgetPrivate *>(this)->fixFocusChainBeforeReparenting((newParent &&
       
  1095                                                         newParent->isWidget()) ? static_cast<QGraphicsWidget *>(newParent) : 0,
       
  1096                                                         scene);
  1040     if (scene) {
  1097     if (scene) {
  1041         // Deliver the change to the index
  1098         // Deliver the change to the index
  1042         if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
  1099         if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
  1043             scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
  1100             scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
  1044 
  1101 
  1182                 setEnabledHelper(true, /* explicit = */ false);
  1239                 setEnabledHelper(true, /* explicit = */ false);
  1183         }
  1240         }
  1184     }
  1241     }
  1185 
  1242 
  1186     dirtySceneTransform = 1;
  1243     dirtySceneTransform = 1;
       
  1244     if (!inDestructor && (transformData || (newParent && newParent->d_ptr->transformData)))
       
  1245         transformChanged();
  1187 
  1246 
  1188     // Restore the sub focus chain.
  1247     // Restore the sub focus chain.
  1189     if (subFocusItem) {
  1248     if (subFocusItem) {
  1190         subFocusItem->d_ptr->setSubFocus(newParent);
  1249         subFocusItem->d_ptr->setSubFocus(newParent);
  1191         if (parent && parent->isActive())
  1250         if (parent && parent->isActive())
  1353     \note It is more efficient to remove the item from the QGraphicsScene before
  1412     \note It is more efficient to remove the item from the QGraphicsScene before
  1354     destroying the item.
  1413     destroying the item.
  1355 */
  1414 */
  1356 QGraphicsItem::~QGraphicsItem()
  1415 QGraphicsItem::~QGraphicsItem()
  1357 {
  1416 {
  1358     if (d_ptr->isObject)
  1417     if (d_ptr->isObject) {
  1359         QObjectPrivate::get(static_cast<QGraphicsObject *>(this))->wasDeleted = true;
  1418         QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
       
  1419         QObjectPrivate *p = QObjectPrivate::get(o);
       
  1420         p->wasDeleted = true;
       
  1421         if (p->declarativeData) {
       
  1422             QAbstractDeclarativeData::destroyed(p->declarativeData, o);
       
  1423             p->declarativeData = 0;
       
  1424         }
       
  1425     }
       
  1426 
  1360     d_ptr->inDestructor = 1;
  1427     d_ptr->inDestructor = 1;
  1361     d_ptr->removeExtraItemCache();
  1428     d_ptr->removeExtraItemCache();
       
  1429 
       
  1430     if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) {
       
  1431         QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
       
  1432         QGestureManager *manager = QGestureManager::instance();
       
  1433         foreach (Qt::GestureType type, d_ptr->gestureContext.keys())
       
  1434             manager->cleanupCachedGestures(o, type);
       
  1435     }
  1362 
  1436 
  1363     clearFocus();
  1437     clearFocus();
  1364 
  1438 
  1365     // Update focus scope item ptr.
  1439     // Update focus scope item ptr.
  1366     QGraphicsItem *p = d_ptr->parent;
  1440     QGraphicsItem *p = d_ptr->parent;
  1731 
  1805 
  1732     \sa flags(), setFlag()
  1806     \sa flags(), setFlag()
  1733 */
  1807 */
  1734 void QGraphicsItem::setFlags(GraphicsItemFlags flags)
  1808 void QGraphicsItem::setFlags(GraphicsItemFlags flags)
  1735 {
  1809 {
  1736     if (isWindow())
       
  1737         flags |= ItemIsPanel;
       
  1738 
       
  1739     // Notify change and check for adjustment.
  1810     // Notify change and check for adjustment.
  1740     if (quint32(d_ptr->flags) == quint32(flags))
  1811     if (quint32(d_ptr->flags) == quint32(flags))
  1741         return;
  1812         return;
  1742     flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
  1813     flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
  1743     if (quint32(d_ptr->flags) == quint32(flags))
  1814     if (quint32(d_ptr->flags) == quint32(flags))
  1747 
  1818 
  1748     // Flags that alter the geometry of the item (or its children).
  1819     // Flags that alter the geometry of the item (or its children).
  1749     const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
  1820     const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
  1750     bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
  1821     bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
  1751     if (fullUpdate)
  1822     if (fullUpdate)
  1752         d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
  1823         d_ptr->updatePaintedViewBoundingRects(/*children=*/true);
  1753 
  1824 
  1754     // Keep the old flags to compare the diff.
  1825     // Keep the old flags to compare the diff.
  1755     GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
  1826     GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
  1756 
  1827 
  1757     // Update flags.
  1828     // Update flags.
  3482 void QGraphicsItem::setX(qreal x)
  3553 void QGraphicsItem::setX(qreal x)
  3483 {
  3554 {
  3484     if (d_ptr->inDestructor)
  3555     if (d_ptr->inDestructor)
  3485         return;
  3556         return;
  3486 
  3557 
  3487     d_ptr->setPosHelper(QPointF(x, d_ptr->pos.y()));
  3558     if (qIsNaN(x))
       
  3559         return;
       
  3560 
       
  3561     setPos(QPointF(x, d_ptr->pos.y()));
  3488 }
  3562 }
  3489 
  3563 
  3490 /*!
  3564 /*!
  3491     \fn QGraphicsItem::y() const
  3565     \fn QGraphicsItem::y() const
  3492 
  3566 
  3506 void QGraphicsItem::setY(qreal y)
  3580 void QGraphicsItem::setY(qreal y)
  3507 {
  3581 {
  3508     if (d_ptr->inDestructor)
  3582     if (d_ptr->inDestructor)
  3509         return;
  3583         return;
  3510 
  3584 
  3511     d_ptr->setPosHelper(QPointF(d_ptr->pos.x(), y));
  3585     if (qIsNaN(y))
       
  3586         return;
       
  3587 
       
  3588     setPos(QPointF(d_ptr->pos.x(), y));
  3512 }
  3589 }
  3513 
  3590 
  3514 /*!
  3591 /*!
  3515     Returns the item's position in scene coordinates. This is
  3592     Returns the item's position in scene coordinates. This is
  3516     equivalent to calling \c mapToScene(0, 0).
  3593     equivalent to calling \c mapToScene(0, 0).
  3553 void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
  3630 void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
  3554 {
  3631 {
  3555     q_ptr->prepareGeometryChange();
  3632     q_ptr->prepareGeometryChange();
  3556     transformData->transform = transform;
  3633     transformData->transform = transform;
  3557     dirtySceneTransform = 1;
  3634     dirtySceneTransform = 1;
       
  3635     transformChanged();
  3558 }
  3636 }
  3559 
  3637 
  3560 /*!
  3638 /*!
  3561     Sets the position of the item to \a pos, which is in parent
  3639     Sets the position of the item to \a pos, which is in parent
  3562     coordinates.  For items with no parent, \a pos is in scene
  3640     coordinates.  For items with no parent, \a pos is in scene
  3574 
  3652 
  3575     if (d_ptr->inDestructor)
  3653     if (d_ptr->inDestructor)
  3576         return;
  3654         return;
  3577 
  3655 
  3578     // Update and repositition.
  3656     // Update and repositition.
  3579     if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
  3657     if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
  3580         d_ptr->setPosHelper(pos);
  3658         d_ptr->setPosHelper(pos);
  3581         if (d_ptr->isWidget)
  3659         if (d_ptr->isWidget)
  3582             static_cast<QGraphicsWidget *>(this)->d_func()->setGeometryFromSetPos();
  3660             static_cast<QGraphicsWidget *>(this)->d_func()->setGeometryFromSetPos();
  3583         return;
  3661         return;
  3584     }
  3662     }
  3721     \sa rotation(), setTransformOriginPoint(), {Transformations}
  3799     \sa rotation(), setTransformOriginPoint(), {Transformations}
  3722 */
  3800 */
  3723 void QGraphicsItem::setRotation(qreal angle)
  3801 void QGraphicsItem::setRotation(qreal angle)
  3724 {
  3802 {
  3725     prepareGeometryChange();
  3803     prepareGeometryChange();
       
  3804     qreal newRotation = angle;
       
  3805 
       
  3806     if (d_ptr->flags & ItemSendsGeometryChanges) {
       
  3807         // Notify the item that the rotation is changing.
       
  3808         const QVariant newRotationVariant(itemChange(ItemRotationChange, angle));
       
  3809         newRotation = newRotationVariant.toReal();
       
  3810     }
       
  3811 
  3726     if (!d_ptr->transformData)
  3812     if (!d_ptr->transformData)
  3727         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
  3813         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
  3728     d_ptr->transformData->rotation = angle;
  3814 
       
  3815     if (d_ptr->transformData->rotation == newRotation)
       
  3816         return;
       
  3817 
       
  3818     d_ptr->transformData->rotation = newRotation;
  3729     d_ptr->transformData->onlyTransform = false;
  3819     d_ptr->transformData->onlyTransform = false;
  3730     d_ptr->dirtySceneTransform = 1;
  3820     d_ptr->dirtySceneTransform = 1;
  3731 
  3821 
       
  3822     // Send post-notification.
       
  3823     if (d_ptr->flags & ItemSendsGeometryChanges)
       
  3824         itemChange(ItemRotationHasChanged, newRotation);
       
  3825 
  3732     if (d_ptr->isObject)
  3826     if (d_ptr->isObject)
  3733         emit static_cast<QGraphicsObject *>(this)->rotationChanged();
  3827         emit static_cast<QGraphicsObject *>(this)->rotationChanged();
       
  3828 
       
  3829     d_ptr->transformChanged();
  3734 }
  3830 }
  3735 
  3831 
  3736 /*!
  3832 /*!
  3737     \since 4.6
  3833     \since 4.6
  3738 
  3834 
  3769     \sa scale(), setTransformOriginPoint(), {Transformations}
  3865     \sa scale(), setTransformOriginPoint(), {Transformations}
  3770 */
  3866 */
  3771 void QGraphicsItem::setScale(qreal factor)
  3867 void QGraphicsItem::setScale(qreal factor)
  3772 {
  3868 {
  3773     prepareGeometryChange();
  3869     prepareGeometryChange();
       
  3870     qreal newScale = factor;
       
  3871 
       
  3872     if (d_ptr->flags & ItemSendsGeometryChanges) {
       
  3873         // Notify the item that the scale is changing.
       
  3874         const QVariant newScaleVariant(itemChange(ItemScaleChange, factor));
       
  3875         newScale = newScaleVariant.toReal();
       
  3876     }
       
  3877 
  3774     if (!d_ptr->transformData)
  3878     if (!d_ptr->transformData)
  3775         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
  3879         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
  3776     d_ptr->transformData->scale = factor;
  3880 
       
  3881     if (d_ptr->transformData->scale == newScale)
       
  3882         return;
       
  3883 
       
  3884     d_ptr->transformData->scale = newScale;
  3777     d_ptr->transformData->onlyTransform = false;
  3885     d_ptr->transformData->onlyTransform = false;
  3778     d_ptr->dirtySceneTransform = 1;
  3886     d_ptr->dirtySceneTransform = 1;
  3779 
  3887 
       
  3888     // Send post-notification.
       
  3889     if (d_ptr->flags & ItemSendsGeometryChanges)
       
  3890         itemChange(ItemScaleHasChanged, newScale);
       
  3891 
  3780     if (d_ptr->isObject)
  3892     if (d_ptr->isObject)
  3781         emit static_cast<QGraphicsObject *>(this)->scaleChanged();
  3893         emit static_cast<QGraphicsObject *>(this)->scaleChanged();
       
  3894 
       
  3895     d_ptr->transformChanged();
  3782 }
  3896 }
  3783 
  3897 
  3784 
  3898 
  3785 /*!
  3899 /*!
  3786     \since 4.6
  3900     \since 4.6
  3832     d_ptr->transformData->graphicsTransforms = transformations;
  3946     d_ptr->transformData->graphicsTransforms = transformations;
  3833     for (int i = 0; i < transformations.size(); ++i)
  3947     for (int i = 0; i < transformations.size(); ++i)
  3834         transformations.at(i)->d_func()->setItem(this);
  3948         transformations.at(i)->d_func()->setItem(this);
  3835     d_ptr->transformData->onlyTransform = false;
  3949     d_ptr->transformData->onlyTransform = false;
  3836     d_ptr->dirtySceneTransform = 1;
  3950     d_ptr->dirtySceneTransform = 1;
       
  3951     d_ptr->transformChanged();
       
  3952 }
       
  3953 
       
  3954 /*!
       
  3955     \internal
       
  3956 */
       
  3957 void QGraphicsItemPrivate::prependGraphicsTransform(QGraphicsTransform *t)
       
  3958 {
       
  3959     if (!transformData)
       
  3960         transformData = new QGraphicsItemPrivate::TransformData;
       
  3961     if (!transformData->graphicsTransforms.contains(t))
       
  3962         transformData->graphicsTransforms.prepend(t);
       
  3963 
       
  3964     Q_Q(QGraphicsItem);
       
  3965     t->d_func()->setItem(q);
       
  3966     transformData->onlyTransform = false;
       
  3967     dirtySceneTransform = 1;
       
  3968     transformChanged();
  3837 }
  3969 }
  3838 
  3970 
  3839 /*!
  3971 /*!
  3840     \internal
  3972     \internal
  3841 */
  3973 */
  3848 
  3980 
  3849     Q_Q(QGraphicsItem);
  3981     Q_Q(QGraphicsItem);
  3850     t->d_func()->setItem(q);
  3982     t->d_func()->setItem(q);
  3851     transformData->onlyTransform = false;
  3983     transformData->onlyTransform = false;
  3852     dirtySceneTransform = 1;
  3984     dirtySceneTransform = 1;
       
  3985     transformChanged();
  3853 }
  3986 }
  3854 
  3987 
  3855 /*!
  3988 /*!
  3856     \since 4.6
  3989     \since 4.6
  3857 
  3990 
  3876     \sa transformOriginPoint(), {Transformations}
  4009     \sa transformOriginPoint(), {Transformations}
  3877 */
  4010 */
  3878 void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
  4011 void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
  3879 {
  4012 {
  3880     prepareGeometryChange();
  4013     prepareGeometryChange();
       
  4014     QPointF newOrigin = origin;
       
  4015 
       
  4016     if (d_ptr->flags & ItemSendsGeometryChanges) {
       
  4017         // Notify the item that the origin point is changing.
       
  4018         const QVariant newOriginVariant(itemChange(ItemTransformOriginPointChange,
       
  4019                                                    qVariantFromValue<QPointF>(origin)));
       
  4020         newOrigin = newOriginVariant.toPointF();
       
  4021     }
       
  4022 
  3881     if (!d_ptr->transformData)
  4023     if (!d_ptr->transformData)
  3882         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
  4024         d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
  3883     d_ptr->transformData->xOrigin = origin.x();
  4025 
  3884     d_ptr->transformData->yOrigin = origin.y();
  4026     if (d_ptr->transformData->xOrigin == newOrigin.x()
       
  4027         && d_ptr->transformData->yOrigin == newOrigin.y()) {
       
  4028         return;
       
  4029     }
       
  4030 
       
  4031     d_ptr->transformData->xOrigin = newOrigin.x();
       
  4032     d_ptr->transformData->yOrigin = newOrigin.y();
  3885     d_ptr->transformData->onlyTransform = false;
  4033     d_ptr->transformData->onlyTransform = false;
  3886     d_ptr->dirtySceneTransform = 1;
  4034     d_ptr->dirtySceneTransform = 1;
       
  4035 
       
  4036     // Send post-notification.
       
  4037     if (d_ptr->flags & ItemSendsGeometryChanges)
       
  4038         itemChange(ItemTransformOriginPointHasChanged, qVariantFromValue<QPointF>(newOrigin));
  3887 }
  4039 }
  3888 
  4040 
  3889 /*!
  4041 /*!
  3890     \fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y)
  4042     \fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y)
  3891 
  4043 
  5225     // number is equal to the size of the children list.
  5377     // number is equal to the size of the children list.
  5226     ensureSequentialSiblingIndex();
  5378     ensureSequentialSiblingIndex();
  5227     needSortChildren = 1; // ### maybe 0
  5379     needSortChildren = 1; // ### maybe 0
  5228     child->d_ptr->siblingIndex = children.size();
  5380     child->d_ptr->siblingIndex = children.size();
  5229     children.append(child);
  5381     children.append(child);
       
  5382     if (isObject)
       
  5383         emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
  5230 }
  5384 }
  5231 
  5385 
  5232 /*!
  5386 /*!
  5233     \internal
  5387     \internal
  5234 
  5388 
  5247         children.removeOne(child);
  5401         children.removeOne(child);
  5248     // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
  5402     // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
  5249     // the child is not guaranteed to be at the index after the list is sorted.
  5403     // the child is not guaranteed to be at the index after the list is sorted.
  5250     // (see ensureSortedChildren()).
  5404     // (see ensureSortedChildren()).
  5251     child->d_ptr->siblingIndex = -1;
  5405     child->d_ptr->siblingIndex = -1;
       
  5406     if (isObject)
       
  5407         emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
  5252 }
  5408 }
  5253 
  5409 
  5254 /*!
  5410 /*!
  5255     \internal
  5411     \internal
  5256 */
  5412 */
  5282     if (c) {
  5438     if (c) {
  5283         c->purge();
  5439         c->purge();
  5284         delete c;
  5440         delete c;
  5285     }
  5441     }
  5286     unsetExtra(ExtraCacheData);
  5442     unsetExtra(ExtraCacheData);
       
  5443 }
       
  5444 
       
  5445 void QGraphicsItemPrivate::updatePaintedViewBoundingRects(bool updateChildren)
       
  5446 {
       
  5447     if (!scene)
       
  5448         return;
       
  5449 
       
  5450     for (int i = 0; i < scene->d_func()->views.size(); ++i) {
       
  5451         QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func();
       
  5452         QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport);
       
  5453         rect.translate(viewPrivate->dirtyScrollOffset);
       
  5454         viewPrivate->updateRect(rect);
       
  5455     }
       
  5456 
       
  5457     if (updateChildren) {
       
  5458         for (int i = 0; i < children.size(); ++i)
       
  5459             children.at(i)->d_ptr->updatePaintedViewBoundingRects(true);
       
  5460     }
  5287 }
  5461 }
  5288 
  5462 
  5289 // Traverses all the ancestors up to the top-level and updates the pointer to
  5463 // Traverses all the ancestors up to the top-level and updates the pointer to
  5290 // always point to the top-most item that has a dirty scene transform.
  5464 // always point to the top-most item that has a dirty scene transform.
  5291 // It then backtracks to the top-most dirty item and start calculating the
  5465 // It then backtracks to the top-most dirty item and start calculating the
  5467     After scrolling, the item will issue an update for the newly exposed
  5641     After scrolling, the item will issue an update for the newly exposed
  5468     areas. If scrolling is not supported (e.g., you are rendering to an OpenGL
  5642     areas. If scrolling is not supported (e.g., you are rendering to an OpenGL
  5469     viewport, which does not benefit from scroll optimizations), this function
  5643     viewport, which does not benefit from scroll optimizations), this function
  5470     is equivalent to calling update(\a rect).
  5644     is equivalent to calling update(\a rect).
  5471 
  5645 
       
  5646     \bold{Note:} Scrolling is only supported when QGraphicsItem::ItemCoordinateCache
       
  5647     is enabled; in all other cases calling this function is equivalent to calling
       
  5648     update(\a rect). If you for sure know that the item is opaque and not overlapped
       
  5649     by other items, you can map the \a rect to viewport coordinates and scroll the
       
  5650     viewport.
       
  5651 
       
  5652     \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 19
       
  5653 
  5472     \sa boundingRect()
  5654     \sa boundingRect()
  5473 */
  5655 */
  5474 void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
  5656 void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
  5475 {
  5657 {
  5476     Q_D(QGraphicsItem);
  5658     Q_D(QGraphicsItem);
  5477     if (dx == 0.0 && dy == 0.0)
  5659     if (dx == 0.0 && dy == 0.0)
  5478         return;
  5660         return;
  5479     if (!d->scene)
  5661     if (!d->scene)
  5480         return;
  5662         return;
  5481     if (d->cacheMode != NoCache) {
  5663 
  5482         QGraphicsItemCache *c;
  5664     // Accelerated scrolling means moving pixels from one location to another
  5483         bool scrollCache = qFuzzyIsNull(dx - int(dx)) && qFuzzyIsNull(dy - int(dy))
  5665     // and only redraw the newly exposed area. The following requirements must
  5484                            && (c = (QGraphicsItemCache *)qVariantValue<void *>(d_ptr->extra(QGraphicsItemPrivate::ExtraCacheData)))
  5666     // be fulfilled in order to do that:
  5485                            && (d->cacheMode == ItemCoordinateCache && !c->fixedSize.isValid());
  5667     //
  5486         if (scrollCache) {
  5668     // 1) Item is opaque.
  5487             QPixmap pix;
  5669     // 2) Item is not overlapped by other items.
  5488             if (QPixmapCache::find(c->key, &pix)) {
  5670     //
  5489                 // Adjust with 2 pixel margin. Notice the loss of precision
  5671     // There's (yet) no way to detect whether an item is opaque or not, which means
  5490                 // when converting to QRect.
  5672     // we cannot do accelerated scrolling unless the cache is enabled. In case of using
  5491                 int adjust = 2;
  5673     // DeviceCoordinate cache we also have to take the device transform into account in
  5492                 QRectF br = boundingRect().adjusted(-adjust, -adjust, adjust, adjust);
  5674     // order to determine whether we can do accelerated scrolling or not. That's left out
  5493                 QRect irect = rect.toRect().translated(-br.x(), -br.y());
  5675     // for simplicity here, but it is definitely something we can consider in the future
  5494 
  5676     // as a performance improvement.
  5495                 pix.scroll(dx, dy, irect);
  5677     if (d->cacheMode != QGraphicsItem::ItemCoordinateCache
  5496 
  5678         || !qFuzzyIsNull(dx - int(dx)) || !qFuzzyIsNull(dy - int(dy))) {
  5497                 QPixmapCache::replace(c->key, pix);
  5679         update(rect);
  5498 
       
  5499                 // Translate the existing expose.
       
  5500                 foreach (QRectF exposedRect, c->exposed)
       
  5501                     c->exposed += exposedRect.translated(dx, dy) & rect;
       
  5502 
       
  5503                 // Calculate exposure.
       
  5504                 QRegion exposed;
       
  5505                 QRect r = rect.toRect();
       
  5506                 exposed += r;
       
  5507                 exposed -= r.translated(dx, dy);
       
  5508                 foreach (QRect rect, exposed.rects())
       
  5509                     update(rect);
       
  5510                 d->scene->d_func()->markDirty(this);
       
  5511             } else {
       
  5512                 update(rect);
       
  5513             }
       
  5514         } else {
       
  5515             // ### This is very slow, and can be done much better. If the cache is
       
  5516             // local and matches the below criteria for rotation and scaling, we
       
  5517             // can easily scroll. And if the cache is in device coordinates, we
       
  5518             // can scroll both the viewport and the cache.
       
  5519             update(rect);
       
  5520         }
       
  5521         return;
  5680         return;
  5522     }
  5681     }
  5523 
  5682 
  5524     QRectF scrollRect = !rect.isNull() ? rect : boundingRect();
  5683     QGraphicsItemCache *cache = d->extraItemCache();
  5525     int couldntScroll = d->scene->views().size();
  5684     if (cache->allExposed || cache->fixedSize.isValid()) {
  5526     foreach (QGraphicsView *view, d->scene->views()) {
  5685         // Cache is either invalidated or item is scaled (see QGraphicsItem::setCacheMode).
  5527         if (view->viewport()->inherits("QGLWidget")) {
  5686         update(rect);
  5528             // ### Please replace with a widget attribute; any widget that
  5687         return;
  5529             // doesn't support partial updates / doesn't support scrolling
  5688     }
  5530             // should be skipped in this code. Qt::WA_NoPartialUpdates or so.
  5689 
       
  5690     QPixmap cachedPixmap;
       
  5691     if (!QPixmapCache::find(cache->key, &cachedPixmap)) {
       
  5692         update(rect);
       
  5693         return;
       
  5694     }
       
  5695 
       
  5696     QRegion exposed;
       
  5697     const bool scrollEntirePixmap = rect.isNull();
       
  5698     if (scrollEntirePixmap) {
       
  5699         // Scroll entire pixmap.
       
  5700         cachedPixmap.scroll(dx, dy, cachedPixmap.rect(), &exposed);
       
  5701     } else {
       
  5702         if (!rect.intersects(cache->boundingRect))
       
  5703             return; // Nothing to scroll.
       
  5704         // Scroll sub-rect of pixmap. The rect is in item coordinates
       
  5705         // so we have to translate it to pixmap coordinates.
       
  5706         QRect scrollRect = rect.toAlignedRect();
       
  5707         cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed);
       
  5708     }
       
  5709 
       
  5710     QPixmapCache::replace(cache->key, cachedPixmap);
       
  5711 
       
  5712     // Translate the existing expose.
       
  5713     for (int i = 0; i < cache->exposed.size(); ++i) {
       
  5714         QRectF &e = cache->exposed[i];
       
  5715         if (!scrollEntirePixmap && !e.intersects(rect))
  5531             continue;
  5716             continue;
  5532         }
  5717         e.translate(dx, dy);
  5533 
  5718     }
  5534         static const QLineF up(0, 0, 0, -1);
  5719 
  5535         static const QLineF down(0, 0, 0, 1);
  5720     // Append newly exposed areas. Note that the exposed region is currently
  5536         static const QLineF left(0, 0, -1, 0);
  5721     // in pixmap coordinates, so we have to translate it to item coordinates.
  5537         static const QLineF right(0, 0, 1, 0);
  5722     exposed.translate(cache->boundingRect.topLeft());
  5538 
  5723     const QVector<QRect> exposedRects = exposed.rects();
  5539         QTransform deviceTr = deviceTransform(view->viewportTransform());
  5724     for (int i = 0; i < exposedRects.size(); ++i)
  5540         QRect deviceScrollRect = deviceTr.mapRect(scrollRect).toRect();
  5725         cache->exposed += exposedRects.at(i);
  5541         QLineF v1 = deviceTr.map(right);
  5726 
  5542         QLineF v2 = deviceTr.map(down);
  5727     // Trigger update. This will redraw the newly exposed area and make sure
  5543         QLineF u1 = v1.unitVector(); u1.translate(-v1.p1());
  5728     // the pixmap is re-blitted in case there are overlapping items.
  5544         QLineF u2 = v2.unitVector(); u2.translate(-v2.p1());
  5729     d->scene->d_func()->markDirty(this, rect);
  5545         bool noScroll = false;
       
  5546 
       
  5547         // Check if the delta resolves to ints in device space.
       
  5548         QPointF deviceDelta = deviceTr.map(QPointF(dx, dy));
       
  5549         if ((deviceDelta.x() - int(deviceDelta.x()))
       
  5550             || (deviceDelta.y() - int(deviceDelta.y()))) {
       
  5551             noScroll = true;
       
  5552         } else {
       
  5553             // Check if the unit vectors have no fraction in device space.
       
  5554             qreal v1l = v1.length();
       
  5555             if (v1l - int(v1l)) {
       
  5556                 noScroll = true;
       
  5557             } else {
       
  5558                 dx *= v1.length();
       
  5559             }
       
  5560             qreal v2l = v2.length();
       
  5561             if (v2l - int(v2l)) {
       
  5562                 noScroll = true;
       
  5563             } else {
       
  5564                 dy *= v2.length();
       
  5565             }
       
  5566         }
       
  5567 
       
  5568         if (!noScroll) {
       
  5569             if (u1 == right) {
       
  5570                 if (u2 == up) {
       
  5571                     // flipped
       
  5572                     dy = -dy;
       
  5573                 } else if (u2 == down) {
       
  5574                     // normal
       
  5575                 } else {
       
  5576                     noScroll = true;
       
  5577                 }
       
  5578             } else if (u1 == left) {
       
  5579                 if (u2 == up) {
       
  5580                     // mirrored & flipped / rotated 180 degrees
       
  5581                     dx = -dx;
       
  5582                     dy = -dy;
       
  5583                 } else if (u2 == down) {
       
  5584                     // mirrored
       
  5585                     dx = -dx;
       
  5586                 } else {
       
  5587                     noScroll = true;
       
  5588                 }
       
  5589             } else if (u1 == up) {
       
  5590                 if (u2 == left) {
       
  5591                     // rotated -90 & mirrored
       
  5592                     qreal tmp = dy;
       
  5593                     dy = -dx;
       
  5594                     dx = -tmp;
       
  5595                 } else if (u2 == right) {
       
  5596                     // rotated -90
       
  5597                     qreal tmp = dy;
       
  5598                     dy = -dx;
       
  5599                     dx = tmp;
       
  5600                 } else {
       
  5601                     noScroll = true;
       
  5602                 }
       
  5603             } else if (u1 == down) {
       
  5604                 if (u2 == left) {
       
  5605                     // rotated 90
       
  5606                     qreal tmp = dy;
       
  5607                     dy = dx;
       
  5608                     dx = -tmp;
       
  5609                 } else if (u2 == right) {
       
  5610                     // rotated 90 & mirrored
       
  5611                     qreal tmp = dy;
       
  5612                     dy = dx;
       
  5613                     dx = tmp;
       
  5614                 } else {
       
  5615                     noScroll = true;
       
  5616                 }
       
  5617             }
       
  5618         }
       
  5619 
       
  5620         if (!noScroll) {
       
  5621             view->viewport()->scroll(int(dx), int(dy), deviceScrollRect);
       
  5622             --couldntScroll;
       
  5623         }
       
  5624     }
       
  5625     if (couldntScroll)
       
  5626         update(rect);
       
  5627 }
  5730 }
  5628 
  5731 
  5629 /*!
  5732 /*!
  5630     \fn void QGraphicsItem::update(qreal x, qreal y, qreal width, qreal height)
  5733     \fn void QGraphicsItem::update(qreal x, qreal y, qreal width, qreal height)
  5631     \overload
  5734     \overload
  6982                     buttonDownParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))));
  7085                     buttonDownParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))));
  6983                 } else if (item->flags() & ItemIgnoresTransformations) {
  7086                 } else if (item->flags() & ItemIgnoresTransformations) {
  6984                     // Root items that ignore transformations need to
  7087                     // Root items that ignore transformations need to
  6985                     // calculate their diff by mapping viewport coordinates
  7088                     // calculate their diff by mapping viewport coordinates
  6986                     // directly to parent coordinates.
  7089                     // directly to parent coordinates.
  6987                     QTransform viewToParentTransform = (item->transform().translate(item->d_ptr->pos.x(), item->d_ptr->pos.y()))
  7090                     // COMBINE
       
  7091                     QTransform itemTransform;
       
  7092                     if (item->d_ptr->transformData)
       
  7093                         itemTransform = item->d_ptr->transformData->computedFullTransform();
       
  7094                     itemTransform.translate(item->d_ptr->pos.x(), item->d_ptr->pos.y());
       
  7095                     QTransform viewToParentTransform = itemTransform
  6988                                                        * (item->sceneTransform() * view->viewportTransform()).inverted();
  7096                                                        * (item->sceneTransform() * view->viewportTransform()).inverted();
  6989                     currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos())));
  7097                     currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos())));
  6990                     buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton))));
  7098                     buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton))));
  6991                 } else {
  7099                 } else {
  6992                     // All other items simply map from the scene.
  7100                     // All other items simply map from the scene.
  7176 */
  7284 */
  7177 void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
  7285 void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
  7178 {
  7286 {
  7179     Q_D(QGraphicsItem);
  7287     Q_D(QGraphicsItem);
  7180     d->imHints = hints;
  7288     d->imHints = hints;
       
  7289     if (!hasFocus())
       
  7290         return;
       
  7291     d->scene->d_func()->updateInputMethodSensitivityInViews();
       
  7292 #if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
       
  7293     QWidget *fw = QApplication::focusWidget();
       
  7294     if (!fw)
       
  7295         return;
       
  7296     for (int i = 0 ; i < scene()->views().count() ; ++i)
       
  7297         if (scene()->views().at(i) == fw)
       
  7298             if (QInputContext *inputContext = fw->inputContext())
       
  7299                 inputContext->update();
       
  7300 #endif
       
  7301 }
       
  7302 
       
  7303 /*!
       
  7304     Updates the item's micro focus.
       
  7305 
       
  7306     \since 4.7
       
  7307 
       
  7308     \sa QInputContext
       
  7309 */
       
  7310 void QGraphicsItem::updateMicroFocus()
       
  7311 {
       
  7312 #if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
       
  7313     if (QWidget *fw = QApplication::focusWidget()) {
       
  7314         for (int i = 0 ; i < scene()->views().count() ; ++i)
       
  7315             if (scene()->views().at(i) == fw)
       
  7316                 if (QInputContext *inputContext = fw->inputContext())
       
  7317                     inputContext->update();
       
  7318 #ifndef QT_NO_ACCESSIBILITY
       
  7319         // ##### is this correct
       
  7320         QAccessible::updateAccessibility(fw, 0, QAccessible::StateChanged);
       
  7321 #endif
       
  7322     }
       
  7323 #endif
  7181 }
  7324 }
  7182 
  7325 
  7183 /*!
  7326 /*!
  7184     This virtual function is called by QGraphicsItem to notify custom items
  7327     This virtual function is called by QGraphicsItem to notify custom items
  7185     that some part of the item's state changes. By reimplementing this
  7328     that some part of the item's state changes. By reimplementing this
  7435 
  7578 
  7436     \sa ungrabGesture(), QGestureEvent
  7579     \sa ungrabGesture(), QGestureEvent
  7437 */
  7580 */
  7438 void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
  7581 void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
  7439 {
  7582 {
  7440     QGraphicsItemPrivate * const d = QGraphicsItem::d_func();
  7583     bool contains = QGraphicsItem::d_ptr->gestureContext.contains(gesture);
  7441     d->gestureContext.insert(gesture, flags);
  7584     QGraphicsItem::d_ptr->gestureContext.insert(gesture, flags);
  7442     (void)QGestureManager::instance(); // create a gesture manager
  7585     if (!contains && QGraphicsItem::d_ptr->scene)
       
  7586         QGraphicsItem::d_ptr->scene->d_func()->grabGesture(this, gesture);
  7443 }
  7587 }
  7444 
  7588 
  7445 /*!
  7589 /*!
  7446     Unsubscribes the graphics object from the given \a gesture.
  7590     Unsubscribes the graphics object from the given \a gesture.
  7447 
  7591 
  7448     \sa grabGesture(), QGestureEvent
  7592     \sa grabGesture(), QGestureEvent
  7449 */
  7593 */
  7450 void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
  7594 void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
  7451 {
  7595 {
  7452     QGraphicsItemPrivate * const d = QGraphicsItem::d_func();
  7596     if (QGraphicsItem::d_ptr->gestureContext.remove(gesture) && QGraphicsItem::d_ptr->scene)
  7453     if (d->gestureContext.remove(gesture)) {
  7597         QGraphicsItem::d_ptr->scene->d_func()->ungrabGesture(this, gesture);
  7454         QGestureManager *manager = QGestureManager::instance();
  7598 }
  7455         manager->cleanupCachedGestures(this, gesture);
  7599 /*!
  7456     }
  7600     Updates the item's micro focus. This is slot for convenience.
       
  7601 
       
  7602     \since 4.7
       
  7603 
       
  7604     \sa QInputContext
       
  7605 */
       
  7606 void QGraphicsObject::updateMicroFocus()
       
  7607 {
       
  7608     QGraphicsItem::updateMicroFocus();
       
  7609 }
       
  7610 
       
  7611 void QGraphicsItemPrivate::children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item)
       
  7612 {
       
  7613     QGraphicsItemPrivate::get(item)->setParentItemHelper(static_cast<QGraphicsObject *>(list->object), /*newParentVariant=*/0, /*thisPointerVariant=*/0);
       
  7614 }
       
  7615 
       
  7616 int QGraphicsItemPrivate::children_count(QDeclarativeListProperty<QGraphicsObject> *list)
       
  7617 {
       
  7618     QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
       
  7619     return d->children.count();
       
  7620 }
       
  7621 
       
  7622 QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGraphicsObject> *list, int index)
       
  7623 {
       
  7624     QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
       
  7625     if (index >= 0 && index < d->children.count()) 
       
  7626         return d->children.at(index)->toGraphicsObject();
       
  7627     else 
       
  7628         return 0;
       
  7629 }
       
  7630 
       
  7631 /*!
       
  7632     Returns a list of this item's children.
       
  7633 
       
  7634     The items are sorted by stacking order. This takes into account both the
       
  7635     items' insertion order and their Z-values.
       
  7636 
       
  7637 */
       
  7638 QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList()
       
  7639 {
       
  7640     Q_Q(QGraphicsItem);
       
  7641     if (isObject) {
       
  7642         QGraphicsObject *that = static_cast<QGraphicsObject *>(q);
       
  7643         return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append,
       
  7644                                                          children_count, children_at);
       
  7645     } else {
       
  7646         //QGraphicsItem is not supported for this property
       
  7647         return QDeclarativeListProperty<QGraphicsObject>();
       
  7648     }
       
  7649 }
       
  7650 
       
  7651 /*!
       
  7652   \internal
       
  7653   Returns the width of the item
       
  7654   Reimplemented by QGraphicsWidget
       
  7655 */
       
  7656 qreal QGraphicsItemPrivate::width() const
       
  7657 {
       
  7658     return 0;
       
  7659 }
       
  7660 
       
  7661 /*!
       
  7662   \internal
       
  7663   Set the width of the item
       
  7664   Reimplemented by QGraphicsWidget
       
  7665 */
       
  7666 void QGraphicsItemPrivate::setWidth(qreal w)
       
  7667 {
       
  7668     Q_UNUSED(w);
       
  7669 }
       
  7670 
       
  7671 /*!
       
  7672   \internal
       
  7673   Reset the width of the item
       
  7674   Reimplemented by QGraphicsWidget
       
  7675 */
       
  7676 void QGraphicsItemPrivate::resetWidth()
       
  7677 {
       
  7678 }
       
  7679 
       
  7680 /*!
       
  7681   \internal
       
  7682   Returns the height of the item
       
  7683   Reimplemented by QGraphicsWidget
       
  7684 */
       
  7685 qreal QGraphicsItemPrivate::height() const
       
  7686 {
       
  7687     return 0;
       
  7688 }
       
  7689 
       
  7690 /*!
       
  7691   \internal
       
  7692   Set the height of the item
       
  7693   Reimplemented by QGraphicsWidget
       
  7694 */
       
  7695 void QGraphicsItemPrivate::setHeight(qreal h)
       
  7696 {
       
  7697     Q_UNUSED(h);
       
  7698 }
       
  7699 
       
  7700 /*!
       
  7701   \internal
       
  7702   Reset the height of the item
       
  7703   Reimplemented by QGraphicsWidget
       
  7704 */
       
  7705 void QGraphicsItemPrivate::resetHeight()
       
  7706 {
  7457 }
  7707 }
  7458 
  7708 
  7459 /*!
  7709 /*!
  7460   \property QGraphicsObject::parent
  7710   \property QGraphicsObject::parent
  7461   \brief the parent of the item
  7711   \brief the parent of the item
  7640   origin for scale and rotation.
  7890   origin for scale and rotation.
  7641 
  7891 
  7642   \sa scale, rotation, QGraphicsItem::transformOriginPoint()
  7892   \sa scale, rotation, QGraphicsItem::transformOriginPoint()
  7643 */
  7893 */
  7644 
  7894 
       
  7895 /*!
       
  7896     \fn void QGraphicsObject::widthChanged()
       
  7897     \internal
       
  7898 */
       
  7899 
       
  7900 /*!
       
  7901     \fn void QGraphicsObject::heightChanged()
       
  7902     \internal
       
  7903 */
       
  7904 
       
  7905 /*!
       
  7906 
       
  7907   \fn QGraphicsObject::childrenChanged()
       
  7908 
       
  7909   This signal gets emitted whenever the children list changes
       
  7910   \internal
       
  7911 */
       
  7912 
       
  7913 /*!
       
  7914   \property QGraphicsObject::effect
       
  7915   \brief the effect attached to this item
       
  7916 
       
  7917   \sa QGraphicsItem::setGraphicsEffect(), QGraphicsItem::graphicsEffect()
       
  7918 */
  7645 
  7919 
  7646 /*!
  7920 /*!
  7647     \class QAbstractGraphicsShapeItem
  7921     \class QAbstractGraphicsShapeItem
  7648     \brief The QAbstractGraphicsShapeItem class provides a common base for
  7922     \brief The QAbstractGraphicsShapeItem class provides a common base for
  7649     all path items.
  7923     all path items.
  7657     You can subclass this item to provide a simple base implementation of
  7931     You can subclass this item to provide a simple base implementation of
  7658     accessors for the item's pen and brush.
  7932     accessors for the item's pen and brush.
  7659 
  7933 
  7660     \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPathItem,
  7934     \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPathItem,
  7661     QGraphicsPolygonItem, QGraphicsTextItem, QGraphicsLineItem,
  7935     QGraphicsPolygonItem, QGraphicsTextItem, QGraphicsLineItem,
  7662     QGraphicsPixmapItem, {The Graphics View Framework}
  7936     QGraphicsPixmapItem, {Graphics View Framework}
  7663 */
  7937 */
  7664 
  7938 
  7665 class QAbstractGraphicsShapeItemPrivate : public QGraphicsItemPrivate
  7939 class QAbstractGraphicsShapeItemPrivate : public QGraphicsItemPrivate
  7666 {
  7940 {
  7667     Q_DECLARE_PUBLIC(QAbstractGraphicsShapeItem)
  7941     Q_DECLARE_PUBLIC(QAbstractGraphicsShapeItem)
  7796     paint() function draws the path using the item's associated pen
  8070     paint() function draws the path using the item's associated pen
  7797     and brush, which you can set by calling the setPen() and
  8071     and brush, which you can set by calling the setPen() and
  7798     setBrush() functions.
  8072     setBrush() functions.
  7799 
  8073 
  7800     \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
  8074     \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
  7801     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {The Graphics
  8075     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
  7802     View Framework}
  8076     View Framework}
  7803 */
  8077 */
  7804 
  8078 
  7805 class QGraphicsPathItemPrivate : public QAbstractGraphicsShapeItemPrivate
  8079 class QGraphicsPathItemPrivate : public QAbstractGraphicsShapeItemPrivate
  7806 {
  8080 {
  8005     rectangles using data from an unreliable source) then you should
  8279     rectangles using data from an unreliable source) then you should
  8006     use QRectF::normalized() to create normalized rectangles, and use
  8280     use QRectF::normalized() to create normalized rectangles, and use
  8007     those instead.
  8281     those instead.
  8008 
  8282 
  8009     \sa QGraphicsPathItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
  8283     \sa QGraphicsPathItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
  8010     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {The Graphics
  8284     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
  8011     View Framework}
  8285     View Framework}
  8012 */
  8286 */
  8013 
  8287 
  8014 class QGraphicsRectItemPrivate : public QAbstractGraphicsShapeItemPrivate
  8288 class QGraphicsRectItemPrivate : public QAbstractGraphicsShapeItemPrivate
  8015 {
  8289 {
  8249     reasonable implementation of boundingRect(), shape(), and contains(). The
  8523     reasonable implementation of boundingRect(), shape(), and contains(). The
  8250     paint() function draws the ellipse using the item's associated pen and
  8524     paint() function draws the ellipse using the item's associated pen and
  8251     brush, which you can set by calling setPen() and setBrush().
  8525     brush, which you can set by calling setPen() and setBrush().
  8252 
  8526 
  8253     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsPolygonItem,
  8527     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsPolygonItem,
  8254     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {The Graphics
  8528     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
  8255     View Framework}
  8529     View Framework}
  8256 */
  8530 */
  8257 
  8531 
  8258 class QGraphicsEllipseItemPrivate : public QAbstractGraphicsShapeItemPrivate
  8532 class QGraphicsEllipseItemPrivate : public QAbstractGraphicsShapeItemPrivate
  8259 {
  8533 {
  8558     contains(). The paint() function draws the polygon using the
  8832     contains(). The paint() function draws the polygon using the
  8559     item's associated pen and brush, which you can set by calling the
  8833     item's associated pen and brush, which you can set by calling the
  8560     setPen() and setBrush() functions.
  8834     setPen() and setBrush() functions.
  8561 
  8835 
  8562     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
  8836     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
  8563     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {The Graphics
  8837     QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
  8564     View Framework}
  8838     View Framework}
  8565 */
  8839 */
  8566 
  8840 
  8567 class QGraphicsPolygonItemPrivate : public QAbstractGraphicsShapeItemPrivate
  8841 class QGraphicsPolygonItemPrivate : public QAbstractGraphicsShapeItemPrivate
  8568 {
  8842 {
  8790     QGraphicsLineItem uses the line and the pen width to provide a reasonable
  9064     QGraphicsLineItem uses the line and the pen width to provide a reasonable
  8791     implementation of boundingRect(), shape(), and contains(). The paint()
  9065     implementation of boundingRect(), shape(), and contains(). The paint()
  8792     function draws the line using the item's associated pen.
  9066     function draws the line using the item's associated pen.
  8793 
  9067 
  8794     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
  9068     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
  8795     QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsPixmapItem, {The
  9069     QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsPixmapItem,
  8796     Graphics View Framework}
  9070     {Graphics View Framework}
  8797 */
  9071 */
  8798 
  9072 
  8799 class QGraphicsLineItemPrivate : public QGraphicsItemPrivate
  9073 class QGraphicsLineItemPrivate : public QGraphicsItemPrivate
  8800 {
  9074 {
  8801     Q_DECLARE_PUBLIC(QGraphicsLineItem)
  9075     Q_DECLARE_PUBLIC(QGraphicsLineItem)
  9060     the platform and viewport. The result is usually not as good as calling
  9334     the platform and viewport. The result is usually not as good as calling
  9061     QPixmap::scale() directly. Call transformationMode() to get the current
  9335     QPixmap::scale() directly. Call transformationMode() to get the current
  9062     transformation mode for the item.
  9336     transformation mode for the item.
  9063 
  9337 
  9064     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
  9338     \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
  9065     QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsLineItem, {The
  9339     QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsLineItem,
  9066     Graphics View Framework}
  9340     {Graphics View Framework}
  9067 */
  9341 */
  9068 
  9342 
  9069 /*!
  9343 /*!
  9070     \enum QGraphicsPixmapItem::ShapeMode
  9344     \enum QGraphicsPixmapItem::ShapeMode
  9071 
  9345 
  9431     \note QGraphicsTextItem accepts \l{QGraphicsItem::acceptHoverEvents()}{hover events}
  9705     \note QGraphicsTextItem accepts \l{QGraphicsItem::acceptHoverEvents()}{hover events}
  9432           by default. You can change this with \l{QGraphicsItem::}{setAcceptHoverEvents()}.
  9706           by default. You can change this with \l{QGraphicsItem::}{setAcceptHoverEvents()}.
  9433 
  9707 
  9434     \sa QGraphicsSimpleTextItem, QGraphicsPathItem, QGraphicsRectItem,
  9708     \sa QGraphicsSimpleTextItem, QGraphicsPathItem, QGraphicsRectItem,
  9435         QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
  9709         QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
  9436         QGraphicsLineItem, {The Graphics View Framework}
  9710         QGraphicsLineItem, {Graphics View Framework}
  9437 */
  9711 */
  9438 
  9712 
  9439 class QGraphicsTextItemPrivate
  9713 class QGraphicsTextItemPrivate
  9440 {
  9714 {
  9441 public:
  9715 public:
  9802                     qic->update();
 10076                     qic->update();
  9803             }
 10077             }
  9804 #endif //QT_NO_IM
 10078 #endif //QT_NO_IM
  9805         }
 10079         }
  9806         break;
 10080         break;
       
 10081     case QEvent::ShortcutOverride:
       
 10082         dd->sendControlEvent(event);
       
 10083         return true;
  9807     default:
 10084     default:
  9808         break;
 10085         break;
  9809     }
 10086     }
  9810 
 10087 
  9811     return result;
 10088     return result;
 10344     QGraphicsSimpleText does not display rich text; instead, you can use
 10621     QGraphicsSimpleText does not display rich text; instead, you can use
 10345     QGraphicsTextItem, which provides full text control capabilities.
 10622     QGraphicsTextItem, which provides full text control capabilities.
 10346 
 10623 
 10347     \img graphicsview-simpletextitem.png
 10624     \img graphicsview-simpletextitem.png
 10348 
 10625 
 10349     \sa QGraphicsTextItem, QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
 10626     \sa QGraphicsTextItem, QGraphicsPathItem, QGraphicsRectItem,
 10350     QGraphicsPixmapItem, QGraphicsPolygonItem, QGraphicsLineItem, {The
 10627     QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
 10351     Graphics View Framework}
 10628     QGraphicsLineItem, {Graphics View Framework}
 10352 */
 10629 */
 10353 
 10630 
 10354 /*!
 10631 /*!
 10355     Constructs a QGraphicsSimpleTextItem.
 10632     Constructs a QGraphicsSimpleTextItem.
 10356 
 10633 
 10607     The removeFromGroup() function has similar semantics to
 10884     The removeFromGroup() function has similar semantics to
 10608     setParentItem(); it reparents the item to the parent item of the
 10885     setParentItem(); it reparents the item to the parent item of the
 10609     item group. As with addToGroup(), the item's scene-relative
 10886     item group. As with addToGroup(), the item's scene-relative
 10610     position and transformation remain intact.
 10887     position and transformation remain intact.
 10611 
 10888 
 10612     \sa QGraphicsItem, {The Graphics View Framework}
 10889     \sa QGraphicsItem, {Graphics View Framework}
 10613 */
 10890 */
 10614 
 10891 
 10615 class QGraphicsItemGroupPrivate : public QGraphicsItemPrivate
 10892 class QGraphicsItemGroupPrivate : public QGraphicsItemPrivate
 10616 {
 10893 {
 10617 public:
 10894 public:
 10928         newEffectTransform *= effectTransform;
 11205         newEffectTransform *= effectTransform;
 10929         scened->draw(item, &pixmapPainter, 0, &sceneTransform, 0, 0, qreal(1.0),
 11206         scened->draw(item, &pixmapPainter, 0, &sceneTransform, 0, 0, qreal(1.0),
 10930                      &newEffectTransform, false, true);
 11207                      &newEffectTransform, false, true);
 10931     } else if (deviceCoordinates) {
 11208     } else if (deviceCoordinates) {
 10932         // Device coordinates with info.
 11209         // Device coordinates with info.
 10933         scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, info->exposedRegion,
 11210         scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
 10934                      info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
 11211                      info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
 10935                      info->drawItem);
 11212                      info->drawItem);
 10936     } else {
 11213     } else {
 10937         // Item coordinates with info.
 11214         // Item coordinates with info.
 10938         QTransform newEffectTransform = info->transformPtr->inverted();
 11215         QTransform newEffectTransform = info->transformPtr->inverted();
 10939         newEffectTransform *= effectTransform;
 11216         newEffectTransform *= effectTransform;
 10940         scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, info->exposedRegion,
 11217         scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
 10941                      info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform,
 11218                      info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform,
 10942                      info->drawItem);
 11219                      info->drawItem);
 10943     }
 11220     }
 10944 
 11221 
 10945     pixmapPainter.end();
 11222     pixmapPainter.end();
 11071         str = "ItemOpacityHasChanged";
 11348         str = "ItemOpacityHasChanged";
 11072         break;
 11349         break;
 11073     case QGraphicsItem::ItemScenePositionHasChanged:
 11350     case QGraphicsItem::ItemScenePositionHasChanged:
 11074         str = "ItemScenePositionHasChanged";
 11351         str = "ItemScenePositionHasChanged";
 11075         break;
 11352         break;
       
 11353     case QGraphicsItem::ItemRotationChange:
       
 11354         str = "ItemRotationChange";
       
 11355         break;
       
 11356     case QGraphicsItem::ItemRotationHasChanged:
       
 11357         str = "ItemRotationHasChanged";
       
 11358         break;
       
 11359     case QGraphicsItem::ItemScaleChange:
       
 11360         str = "ItemScaleChange";
       
 11361         break;
       
 11362     case QGraphicsItem::ItemScaleHasChanged:
       
 11363         str = "ItemScaleHasChanged";
       
 11364         break;
       
 11365     case QGraphicsItem::ItemTransformOriginPointChange:
       
 11366         str = "ItemTransformOriginPointChange";
       
 11367         break;
       
 11368     case QGraphicsItem::ItemTransformOriginPointHasChanged:
       
 11369         str = "ItemTransformOriginPointHasChanged";
       
 11370         break;
 11076     }
 11371     }
 11077     debug << str;
 11372     debug << str;
 11078     return debug;
 11373     return debug;
 11079 }
 11374 }
 11080 
 11375 
 11140 
 11435 
 11141 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags)
 11436 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags)
 11142 {
 11437 {
 11143     debug << '(';
 11438     debug << '(';
 11144     bool f = false;
 11439     bool f = false;
 11145     for (int i = 0; i < 16; ++i) {
 11440     for (int i = 0; i < 17; ++i) {
 11146         if (flags & (1 << i)) {
 11441         if (flags & (1 << i)) {
 11147             if (f)
 11442             if (f)
 11148                 debug << '|';
 11443                 debug << '|';
 11149             f = true;
 11444             f = true;
 11150             debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i)));
 11445             debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i)));