/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

static const int QGRAPHICSVIEW_REGION_RECT_THRESHOLD = 50;

static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime < 2^9

/*!
    \class QGraphicsView
    \brief The QGraphicsView class provides a widget for displaying the
    contents of a QGraphicsScene.
    \since 4.2
    \ingroup graphicsview-api
    \inmodule QtWidgets

    QGraphicsView visualizes the contents of a QGraphicsScene in a scrollable
    viewport. To create a scene with geometrical items, see QGraphicsScene's
    documentation. QGraphicsView is part of the \l{Graphics View Framework}.

    To visualize a scene, you start by constructing a QGraphicsView object,
    passing the address of the scene you want to visualize to QGraphicsView's
    constructor. Alternatively, you can call setScene() to set the scene at a
    later point. After you call show(), the view will by default scroll to the
    center of the scene and display any items that are visible at this
    point. For example:

    \snippet code/src_gui_graphicsview_qgraphicsview.cpp 0

    You can explicitly scroll to any position on the scene by using the
    scroll bars, or by calling centerOn(). By passing a point to centerOn(),
    QGraphicsView will scroll its viewport to ensure that the point is
    centered in the view. An overload is provided for scrolling to a
    QGraphicsItem, in which case QGraphicsView will see to that the center of
    the item is centered in the view. If all you want is to ensure that a
    certain area is visible, (but not necessarily centered,) you can call
    ensureVisible() instead.

    QGraphicsView can be used to visualize a whole scene, or only parts of it.
    The visualized area is by default detected automatically when the view is
    displayed for the first time (by calling
    QGraphicsScene::itemsBoundingRect()). To set the visualized area rectangle
    yourself, you can call setSceneRect(). This will adjust the scroll bars'
    ranges appropriately. Note that although the scene supports a virtually
    unlimited size, the range of the scroll bars will never exceed the range of
    an integer (INT_MIN, INT_MAX).

    QGraphicsView visualizes the scene by calling render(). By default, the
    items are drawn onto the viewport by using a regular QPainter, and using
    default render hints. To change the default render hints that
    QGraphicsView passes to QPainter when painting items, you can call
    setRenderHints().

    By default, QGraphicsView provides a regular QWidget for the viewport
    widget. You can access this widget by calling viewport(), or you can
    replace it by calling setViewport(). To render using OpenGL, simply call
    setViewport(new QOpenGLWidget). QGraphicsView takes ownership of the
    viewport widget.

    QGraphicsView supports affine transformations, using QTransform. You can
    either pass a matrix to setTransform(), or you can call one of the
    convenience functions rotate(), scale(), translate() or shear(). The most
    two common transformations are scaling, which is used to implement
    zooming, and rotation. QGraphicsView keeps the center of the view fixed
    during a transformation. Because of the scene alignment (setAligment()),
    translating the view will have no visual impact.

    You can interact with the items on the scene by using the mouse and
    keyboard. QGraphicsView translates the mouse and key events into \e scene
    events, (events that inherit QGraphicsSceneEvent,), and forward them to
    the visualized scene. In the end, it's the individual item that handles
    the events and reacts to them. For example, if you click on a selectable
    item, the item will typically let the scene know that it has been
    selected, and it will also redraw itself to display a selection
    rectangle. Similiary, if you click and drag the mouse to move a movable
    item, it's the item that handles the mouse moves and moves itself.  Item
    interaction is enabled by default, and you can toggle it by calling
    setInteractive().

    You can also provide your own custom scene interaction, by creating a
    subclass of QGraphicsView, and reimplementing the mouse and key event
    handlers. To simplify how you programmatically interact with items in the
    view, QGraphicsView provides the mapping functions mapToScene() and
    mapFromScene(), and the item accessors items() and itemAt(). These
    functions allow you to map points, rectangles, polygons and paths between
    view coordinates and scene coordinates, and to find items on the scene
    using view coordinates.

    \image graphicsview-view.png

    \note Using an OpenGL viewport limits the ability to use QGraphicsProxyWidget.
    Not all combinations of widgets and styles can be supported with such a setup.
    You should carefully test your UI and make the necessary adjustments.

    \sa QGraphicsScene, QGraphicsItem, QGraphicsSceneEvent
*/

/*!
    \enum QGraphicsView::ViewportAnchor

    This enums describe the possible anchors that QGraphicsView can
    use when the user resizes the view or when the view is
    transformed.

    \value NoAnchor No anchor, i.e. the view leaves the scene's
                    position unchanged.
    \value AnchorViewCenter The scene point at the center of the view
                            is used as the anchor.
    \value AnchorUnderMouse The point under the mouse is used as the anchor.

    \sa resizeAnchor, transformationAnchor
*/

/*!
    \enum QGraphicsView::ViewportUpdateMode

    \since 4.3

    This enum describes how QGraphicsView updates its viewport when the scene
    contents change or are exposed.

    \value FullViewportUpdate When any visible part of the scene changes or is
    reexposed, QGraphicsView will update the entire viewport. This approach is
    fastest when QGraphicsView spends more time figuring out what to draw than
    it would spend drawing (e.g., when very many small items are repeatedly
    updated). This is the preferred update mode for viewports that do not
    support partial updates, such as QOpenGLWidget, and for viewports that
    need to disable scroll optimization.

    \value MinimalViewportUpdate QGraphicsView will determine the minimal
    viewport region that requires a redraw, minimizing the time spent drawing
    by avoiding a redraw of areas that have not changed. This is
    QGraphicsView's default mode. Although this approach provides the best
    performance in general, if there are many small visible changes on the
    scene, QGraphicsView might end up spending more time finding the minimal
    approach than it will spend drawing.

    \value SmartViewportUpdate QGraphicsView will attempt to find an optimal
    update mode by analyzing the areas that require a redraw.

    \value BoundingRectViewportUpdate The bounding rectangle of all changes in
    the viewport will be redrawn. This mode has the advantage that
    QGraphicsView searches only one region for changes, minimizing time spent
    determining what needs redrawing. The disadvantage is that areas that have
    not changed also need to be redrawn.

    \value NoViewportUpdate QGraphicsView will never update its viewport when
    the scene changes; the user is expected to control all updates. This mode
    disables all (potentially slow) item visibility testing in QGraphicsView,
    and is suitable for scenes that either require a fixed frame rate, or where
    the viewport is otherwise updated externally.

    \sa viewportUpdateMode
*/

/*!
    \enum QGraphicsView::OptimizationFlag

    \since 4.3

    This enum describes flags that you can enable to improve rendering
    performance in QGraphicsView. By default, none of these flags are set.
    Note that setting a flag usually imposes a side effect, and this effect
    can vary between paint devices and platforms.

    \value DontClipPainter This value is obsolete and has no effect.

    \value DontSavePainterState When rendering, QGraphicsView protects the
    painter state (see QPainter::save()) when rendering the background or
    foreground, and when rendering each item. This allows you to leave the
    painter in an altered state (i.e., you can call QPainter::setPen() or
    QPainter::setBrush() without restoring the state after painting). However,
    if the items consistently do restore the state, you should enable this
    flag to prevent QGraphicsView from doing the same.

    \value DontAdjustForAntialiasing Disables QGraphicsView's antialiasing
    auto-adjustment of exposed areas. Items that render antialiased lines on
    the boundaries of their QGraphicsItem::boundingRect() can end up rendering
    parts of the line outside. To prevent rendering artifacts, QGraphicsView
    expands all exposed regions by 2 pixels in all directions. If you enable
    this flag, QGraphicsView will no longer perform these adjustments,
    minimizing the areas that require redrawing, which improves performance. A
    common side effect is that items that do draw with antialiasing can leave
    painting traces behind on the scene as they are moved.

    \value IndirectPainting Since Qt 4.6, restore the old painting algorithm
    that calls QGraphicsView::drawItems() and QGraphicsScene::drawItems().
    To be used only for compatibility with old code.
*/

/*!
    \enum QGraphicsView::CacheModeFlag

    This enum describes the flags that you can set for a QGraphicsView's cache
    mode.

    \value CacheNone All painting is done directly onto the viewport.

    \value CacheBackground The background is cached. This affects both custom
    backgrounds, and backgrounds based on the backgroundBrush property. When
    this flag is enabled, QGraphicsView will allocate one pixmap with the full
    size of the viewport.

    \sa cacheMode
*/

/*!
    \enum QGraphicsView::DragMode

    This enum describes the default action for the view when pressing and
    dragging the mouse over the viewport.

    \value NoDrag Nothing happens; the mouse event is ignored.

    \value ScrollHandDrag The cursor changes into a pointing hand, and
    dragging the mouse around will scroll the scrolbars. This mode works both
    in \l{QGraphicsView::interactive}{interactive} and non-interactive mode.

    \value RubberBandDrag A rubber band will appear. Dragging the mouse will
    set the rubber band geometry, and all items covered by the rubber band are
    selected. This mode is disabled for non-interactive views.

    \sa dragMode, QGraphicsScene::setSelectionArea()
*/

/*!
    \since 5.1

    \fn void QGraphicsView::rubberBandChanged(QRect rubberBandRect, QPointF fromScenePoint, QPointF toScenePoint)

    This signal is emitted when the rubber band rect is changed. The viewport Rect is specified by \a rubberBandRect.
    The drag start position and drag end position are provided in scene points with \a fromScenePoint and \a toScenePoint.

    When rubberband selection ends this signal will be emitted with null vales.

    \sa rubberBandRect()
*/


#include "qgraphicsview.h"
#include "qgraphicsview_p.h"

#include "qgraphicsitem.h"
#include "qgraphicsitem_p.h"
#include "qgraphicsscene.h"
#include "qgraphicsscene_p.h"
#include "qgraphicssceneevent.h"
#include "qgraphicswidget.h"

#include <QtCore/qdatetime.h>
#include <QtCore/qdebug.h>
#include <QtCore/qmath.h>
#include <QtCore/qscopedvaluerollback.h>
#include <QtWidgets/qapplication.h>
#include <QtWidgets/qdesktopwidget.h>
#include <private/qdesktopwidget_p.h>
#include <QtGui/qevent.h>
#include <QtWidgets/qlayout.h>
#include <QtGui/qtransform.h>
#include <QtGui/qmatrix.h>
#include <QtGui/qpainter.h>
#include <QtGui/qpainterpath.h>
#include <QtWidgets/qscrollbar.h>
#include <QtWidgets/qstyleoption.h>

#include <private/qevent_p.h>

QT_BEGIN_NAMESPACE

bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);

inline int q_round_bound(qreal d) //### (int)(qreal) INT_MAX != INT_MAX for single precision
{
    if (d <= (qreal) INT_MIN)
        return INT_MIN;
    else if (d >= (qreal) INT_MAX)
        return INT_MAX;
    return d >= 0.0 ? int(d + 0.5) : int(d - int(d-1) + 0.5) + int(d-1);
}

void QGraphicsViewPrivate::translateTouchEvent(QGraphicsViewPrivate *d, QTouchEvent *touchEvent)
{
    QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
    for (int i = 0; i < touchPoints.count(); ++i) {
        QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
        const QSizeF ellipseDiameters = touchPoint.ellipseDiameters();
        // the scene will set the item local pos, startPos, lastPos, and rect before delivering to
        // an item, but for now those functions are returning the view's local coordinates
        touchPoint.setScenePos(d->mapToScene(touchPoint.pos()));
        touchPoint.setStartScenePos(d->mapToScene(touchPoint.startPos()));
        touchPoint.setLastScenePos(d->mapToScene(touchPoint.lastPos()));
        touchPoint.setEllipseDiameters(ellipseDiameters);

        // screenPos, startScreenPos, and lastScreenPos are already set
    }

    touchEvent->setTouchPoints(touchPoints);
}

/*!
    \internal
*/
QGraphicsViewPrivate::QGraphicsViewPrivate()
    : renderHints(QPainter::TextAntialiasing),
      dragMode(QGraphicsView::NoDrag),
      sceneInteractionAllowed(true), hasSceneRect(false),
      connectedToScene(false),
      useLastMouseEvent(false),
      identityMatrix(true),
      dirtyScroll(true),
      accelerateScrolling(true),
      keepLastCenterPoint(true),
      transforming(false),
      handScrolling(false),
      mustAllocateStyleOptions(false),
      mustResizeBackgroundPixmap(true),
      fullUpdatePending(true),
      hasUpdateClip(false),
      mousePressButton(Qt::NoButton),
      leftIndent(0), topIndent(0),
      lastMouseEvent(QEvent::None, QPointF(), QPointF(), QPointF(), Qt::NoButton, { }, { }),
      alignment(Qt::AlignCenter),
      transformationAnchor(QGraphicsView::AnchorViewCenter), resizeAnchor(QGraphicsView::NoAnchor),
      viewportUpdateMode(QGraphicsView::MinimalViewportUpdate),
      scene(nullptr),
#if QT_CONFIG(rubberband)
      rubberBanding(false),
      rubberBandSelectionMode(Qt::IntersectsItemShape),
      rubberBandSelectionOperation(Qt::ReplaceSelection),
#endif
      handScrollMotions(0),
#ifndef QT_NO_CURSOR
      hasStoredOriginalCursor(false),
#endif
      lastDragDropEvent(nullptr),
      updateSceneSlotReimplementedChecked(false)
{
    styleOptions.reserve(QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS);
}

QGraphicsViewPrivate::~QGraphicsViewPrivate()
{
}

/*!
    \internal
*/
void QGraphicsViewPrivate::recalculateContentSize()
{
    Q_Q(QGraphicsView);

    QSize maxSize = q->maximumViewportSize();
    int width = maxSize.width();
    int height = maxSize.height();
    QRectF viewRect = matrix.mapRect(q->sceneRect());

    bool frameOnlyAround = (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, nullptr, q));
    if (frameOnlyAround) {
        if (hbarpolicy == Qt::ScrollBarAlwaysOn)
            height -= frameWidth * 2;
        if (vbarpolicy == Qt::ScrollBarAlwaysOn)
            width -= frameWidth * 2;
    }

    // Adjust the maximum width and height of the viewport based on the width
    // of visible scroll bars.
    int scrollBarExtent = q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, nullptr, q);
    if (frameOnlyAround)
        scrollBarExtent += frameWidth * 2;

    // We do not need to subtract the width scrollbars whose policy is
    // Qt::ScrollBarAlwaysOn, this was already done by maximumViewportSize().
    bool useHorizontalScrollBar = (viewRect.width() > width) && hbarpolicy == Qt::ScrollBarAsNeeded;
    bool useVerticalScrollBar = (viewRect.height() > height) && vbarpolicy == Qt::ScrollBarAsNeeded;
    if (useHorizontalScrollBar && vbarpolicy == Qt::ScrollBarAsNeeded) {
        if (viewRect.height() > height - scrollBarExtent)
            useVerticalScrollBar = true;
    }
    if (useVerticalScrollBar && hbarpolicy == Qt::ScrollBarAsNeeded) {
        if (viewRect.width() > width - scrollBarExtent)
            useHorizontalScrollBar = true;
    }
    if (useHorizontalScrollBar)
        height -= scrollBarExtent;
    if (useVerticalScrollBar)
        width -= scrollBarExtent;

    // Setting the ranges of these scroll bars can/will cause the values to
    // change, and scrollContentsBy() will be called correspondingly. This
    // will reset the last center point.
    QPointF savedLastCenterPoint = lastCenterPoint;

    // Remember the former indent settings
    qreal oldLeftIndent = leftIndent;
    qreal oldTopIndent = topIndent;

    // If the whole scene fits horizontally, we center the scene horizontally,
    // and ignore the horizontal scroll bars.
    int left =  q_round_bound(viewRect.left());
    int right = q_round_bound(viewRect.right() - width);
    if (left >= right) {
        hbar->setRange(0, 0);

        switch (alignment & Qt::AlignHorizontal_Mask) {
        case Qt::AlignLeft:
            leftIndent = -viewRect.left();
            break;
        case Qt::AlignRight:
            leftIndent = width - viewRect.width() - viewRect.left() - 1;
            break;
        case Qt::AlignHCenter:
        default:
            leftIndent = width / 2 - (viewRect.left() + viewRect.right()) / 2;
            break;
        }
    } else {
        hbar->setRange(left, right);
        hbar->setPageStep(width);
        hbar->setSingleStep(width / 20);
        leftIndent = 0;
    }

    // If the whole scene fits vertically, we center the scene vertically, and
    // ignore the vertical scroll bars.
    int top = q_round_bound(viewRect.top());
    int bottom = q_round_bound(viewRect.bottom()  - height);
    if (top >= bottom) {
        vbar->setRange(0, 0);

        switch (alignment & Qt::AlignVertical_Mask) {
        case Qt::AlignTop:
            topIndent = -viewRect.top();
            break;
        case Qt::AlignBottom:
            topIndent = height - viewRect.height() - viewRect.top() - 1;
            break;
        case Qt::AlignVCenter:
        default:
            topIndent = height / 2 - (viewRect.top() + viewRect.bottom()) / 2;
            break;
        }
    } else {
        vbar->setRange(top, bottom);
        vbar->setPageStep(height);
        vbar->setSingleStep(height / 20);
        topIndent = 0;
    }

    // Restorethe center point from before the ranges changed.
    lastCenterPoint = savedLastCenterPoint;

    // Issue a full update if the indents change.
    // ### If the transform is still the same, we can get away with just a
    // scroll instead.
    if (oldLeftIndent != leftIndent || oldTopIndent != topIndent) {
        dirtyScroll = true;
        updateAll();
    } else if (q->isRightToLeft() && !leftIndent) {
        // In reverse mode, the horizontal scroll always changes after the content
        // size has changed, as the scroll is calculated by summing the min and
        // max values of the range and subtracting the current value. In normal
        // mode the scroll remains unchanged unless the indent has changed.
        dirtyScroll = true;
    }

    if (cacheMode & QGraphicsView::CacheBackground) {
        // Invalidate the background pixmap
        mustResizeBackgroundPixmap = true;
    }
}

/*!
    \internal
*/
void QGraphicsViewPrivate::centerView(QGraphicsView::ViewportAnchor anchor)
{
    Q_Q(QGraphicsView);
    switch (anchor) {
    case QGraphicsView::AnchorUnderMouse: {
        if (q->underMouse()) {
            // Last scene pos: lastMouseMoveScenePoint
            // Current mouse pos:
            QPointF transformationDiff = q->mapToScene(viewport->rect().center())
                                         - q->mapToScene(viewport->mapFromGlobal(QCursor::pos()));
            q->centerOn(lastMouseMoveScenePoint + transformationDiff);
        } else {
            q->centerOn(lastCenterPoint);
        }
        break;
    }
    case QGraphicsView::AnchorViewCenter:
        q->centerOn(lastCenterPoint);
        break;
    case QGraphicsView::NoAnchor:
        break;
    }
}

/*!
    \internal
*/
void QGraphicsViewPrivate::updateLastCenterPoint()
{
    Q_Q(QGraphicsView);
    lastCenterPoint = q->mapToScene(viewport->rect().center());
}

/*!
    \internal

    Returns the horizontal scroll value (the X value of the left edge of the
    viewport).
*/
qint64 QGraphicsViewPrivate::horizontalScroll() const
{
    if (dirtyScroll)
        const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
    return scrollX;
}

/*!
    \internal

    Returns the vertical scroll value (the X value of the top edge of the
    viewport).
*/
qint64 QGraphicsViewPrivate::verticalScroll() const
{
    if (dirtyScroll)
        const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
    return scrollY;
}

/*!
    \internal

    Maps the given rectangle to the scene using QTransform::mapRect()
*/
QRectF QGraphicsViewPrivate::mapRectToScene(const QRect &rect) const
{
    if (dirtyScroll)
        const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
    QRectF scrolled = QRectF(rect.translated(scrollX, scrollY));
    return identityMatrix ? scrolled : matrix.inverted().mapRect(scrolled);
}


/*!
    \internal

    Maps the given rectangle from the scene using QTransform::mapRect()
*/
QRectF QGraphicsViewPrivate::mapRectFromScene(const QRectF &rect) const
{
    if (dirtyScroll)
        const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
    return (identityMatrix ? rect : matrix.mapRect(rect)).translated(-scrollX, -scrollY);
}

/*!
    \internal
*/
void QGraphicsViewPrivate::updateScroll()
{
    Q_Q(QGraphicsView);
    scrollX = qint64(-leftIndent);
    if (q->isRightToLeft()) {
        if (!leftIndent) {
            scrollX += hbar->minimum();
            scrollX += hbar->maximum();
            scrollX -= hbar->value();
        }
    } else {
        scrollX += hbar->value();
    }

    scrollY = qint64(vbar->value() - topIndent);

    dirtyScroll = false;
}

/*!
    \internal
*/
void QGraphicsViewPrivate::replayLastMouseEvent()
{
    if (!useLastMouseEvent || !scene)
        return;
    mouseMoveEventHandler(&lastMouseEvent);
}

/*!
    \internal
*/
void QGraphicsViewPrivate::storeMouseEvent(QMouseEvent *event)
{
    useLastMouseEvent = true;
    lastMouseEvent = QMouseEvent(QEvent::MouseMove, event->localPos(), event->windowPos(), event->screenPos(),
                                 event->button(), event->buttons(), event->modifiers());
}

void QGraphicsViewPrivate::mouseMoveEventHandler(QMouseEvent *event)
{
    Q_Q(QGraphicsView);

#if QT_CONFIG(rubberband)
    updateRubberBand(event);
#endif

    storeMouseEvent(event);
    lastMouseEvent.setAccepted(false);

    if (!sceneInteractionAllowed)
        return;
    if (handScrolling)
        return;
    if (!scene)
        return;

    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
    mouseEvent.setWidget(viewport);
    mouseEvent.setButtonDownScenePos(mousePressButton, mousePressScenePoint);
    mouseEvent.setButtonDownScreenPos(mousePressButton, mousePressScreenPoint);
    mouseEvent.setScenePos(q->mapToScene(event->pos()));
    mouseEvent.setScreenPos(event->globalPos());
    mouseEvent.setLastScenePos(lastMouseMoveScenePoint);
    mouseEvent.setLastScreenPos(lastMouseMoveScreenPoint);
    mouseEvent.setButtons(event->buttons());
    mouseEvent.setButton(event->button());
    mouseEvent.setModifiers(event->modifiers());
    mouseEvent.setSource(event->source());
    mouseEvent.setFlags(event->flags());
    lastMouseMoveScenePoint = mouseEvent.scenePos();
    lastMouseMoveScreenPoint = mouseEvent.screenPos();
    mouseEvent.setAccepted(false);
    if (event->spontaneous())
        qt_sendSpontaneousEvent(scene, &mouseEvent);
    else
        QCoreApplication::sendEvent(scene, &mouseEvent);

    // Remember whether the last event was accepted or not.
    lastMouseEvent.setAccepted(mouseEvent.isAccepted());

    if (mouseEvent.isAccepted() && mouseEvent.buttons() != 0) {
        // The event was delivered to a mouse grabber; the press is likely to
        // have set a cursor, and we must not change it.
        return;
    }

#ifndef QT_NO_CURSOR
    // If all the items ignore hover events, we don't look-up any items
    // in QGraphicsScenePrivate::dispatchHoverEvent, hence the
    // cachedItemsUnderMouse list will be empty. We therefore do the look-up
    // for cursor items here if not all items use the default cursor.
    if (scene->d_func()->allItemsIgnoreHoverEvents && !scene->d_func()->allItemsUseDefaultCursor
        && scene->d_func()->cachedItemsUnderMouse.isEmpty()) {
        scene->d_func()->cachedItemsUnderMouse = scene->d_func()->itemsAtPosition(mouseEvent.screenPos(),
                                                                                  mouseEvent.scenePos(),
                                                                                  mouseEvent.widget());
    }
    // Find the topmost item under the mouse with a cursor.
    foreach (QGraphicsItem *item, scene->d_func()->cachedItemsUnderMouse) {
        if (item->isEnabled() && item->hasCursor()) {
            _q_setViewportCursor(item->cursor());
            return;
        }
    }

    // No items with cursors found; revert to the view cursor.
    if (hasStoredOriginalCursor) {
        // Restore the original viewport cursor.
        hasStoredOriginalCursor = false;
        viewport->setCursor(originalCursor);
    }
#endif
}

/*!
    \internal
*/
#if QT_CONFIG(rubberband)
QRegion QGraphicsViewPrivate::rubberBandRegion(const QWidget *widget, const QRect &rect) const
{
    QStyleHintReturnMask mask;
    QStyleOptionRubberBand option;
    option.initFrom(widget);
    option.rect = rect;
    option.opaque = false;
    option.shape = QRubberBand::Rectangle;

    QRegion tmp;
    tmp += rect;
    if (widget->style()->styleHint(QStyle::SH_RubberBand_Mask, &option, widget, &mask))
        tmp &= mask.region;
    return tmp;
}

void QGraphicsViewPrivate::updateRubberBand(const QMouseEvent *event)
{
    Q_Q(QGraphicsView);
    if (dragMode != QGraphicsView::RubberBandDrag || !sceneInteractionAllowed || !rubberBanding)
        return;
    // Check for enough drag distance
    if ((mousePressViewPoint - event->pos()).manhattanLength() < QApplication::startDragDistance())
        return;

    // Update old rubberband
    if (viewportUpdateMode != QGraphicsView::NoViewportUpdate && !rubberBandRect.isEmpty()) {
        if (viewportUpdateMode != QGraphicsView::FullViewportUpdate)
            q->viewport()->update(rubberBandRegion(q->viewport(), rubberBandRect));
        else
            updateAll();
    }

    // Stop rubber banding if the user has let go of all buttons (even
    // if we didn't get the release events).
    if (!event->buttons()) {
        rubberBanding = false;
        rubberBandSelectionOperation = Qt::ReplaceSelection;
        if (!rubberBandRect.isNull()) {
            rubberBandRect = QRect();
            emit q->rubberBandChanged(rubberBandRect, QPointF(), QPointF());
        }
        return;
    }

    QRect oldRubberband = rubberBandRect;

    // Update rubberband position
    const QPoint mp = q->mapFromScene(mousePressScenePoint);
    const QPoint ep = event->pos();
    rubberBandRect = QRect(qMin(mp.x(), ep.x()), qMin(mp.y(), ep.y()),
                           qAbs(mp.x() - ep.x()) + 1, qAbs(mp.y() - ep.y()) + 1);

    if (rubberBandRect != oldRubberband || lastRubberbandScenePoint != lastMouseMoveScenePoint) {
        lastRubberbandScenePoint = lastMouseMoveScenePoint;
        oldRubberband = rubberBandRect;
        emit q->rubberBandChanged(rubberBandRect, mousePressScenePoint, lastRubberbandScenePoint);
    }

    // Update new rubberband
    if (viewportUpdateMode != QGraphicsView::NoViewportUpdate) {
        if (viewportUpdateMode != QGraphicsView::FullViewportUpdate)
            q->viewport()->update(rubberBandRegion(q->viewport(), rubberBandRect));
        else
            updateAll();
    }
            // Set the new selection area
    QPainterPath selectionArea;
    selectionArea.addPolygon(q->mapToScene(rubberBandRect));
    selectionArea.closeSubpath();
    if (scene)
        scene->setSelectionArea(selectionArea, rubberBandSelectionOperation, rubberBandSelectionMode, q->viewportTransform());
}

void QGraphicsViewPrivate::clearRubberBand()
{
    Q_Q(QGraphicsView);
    if (dragMode != QGraphicsView::RubberBandDrag || !sceneInteractionAllowed || !rubberBanding)
        return;

    if (viewportUpdateMode != QGraphicsView::NoViewportUpdate) {
        if (viewportUpdateMode != QGraphicsView::FullViewportUpdate)
            q->viewport()->update(rubberBandRegion(q->viewport(), rubberBandRect));
        else
            updateAll();
    }

    rubberBanding = false;
    rubberBandSelectionOperation = Qt::ReplaceSelection;
    if (!rubberBandRect.isNull()) {
        rubberBandRect = QRect();
        emit q->rubberBandChanged(rubberBandRect, QPointF(), QPointF());
    }
}
#endif

/*!
    \internal
*/
#ifndef QT_NO_CURSOR
void QGraphicsViewPrivate::_q_setViewportCursor(const QCursor &cursor)
{
    if (!hasStoredOriginalCursor) {
        hasStoredOriginalCursor = true;
        originalCursor = viewport->cursor();
    }
    viewport->setCursor(cursor);
}
#endif

/*!
    \internal
*/
#ifndef QT_NO_CURSOR
void QGraphicsViewPrivate::_q_unsetViewportCursor()
{
    Q_Q(QGraphicsView);
    const auto items = q->items(lastMouseEvent.pos());
    for (QGraphicsItem *item : items) {
        if (item->isEnabled() && item->hasCursor()) {
            _q_setViewportCursor(item->cursor());
            return;
        }
    }

    // Restore the original viewport cursor.
    if (hasStoredOriginalCursor) {
        hasStoredOriginalCursor = false;
        if (dragMode == QGraphicsView::ScrollHandDrag)
            viewport->setCursor(Qt::OpenHandCursor);
        else
            viewport->setCursor(originalCursor);
    }
}
#endif

/*!
    \internal
*/
void QGraphicsViewPrivate::storeDragDropEvent(const QGraphicsSceneDragDropEvent *event)
{
    delete lastDragDropEvent;
    lastDragDropEvent = new QGraphicsSceneDragDropEvent(event->type());
    lastDragDropEvent->setScenePos(event->scenePos());
    lastDragDropEvent->setScreenPos(event->screenPos());
    lastDragDropEvent->setButtons(event->buttons());
    lastDragDropEvent->setModifiers(event->modifiers());
    lastDragDropEvent->setPossibleActions(event->possibleActions());
    lastDragDropEvent->setProposedAction(event->proposedAction());
    lastDragDropEvent->setDropAction(event->dropAction());
    lastDragDropEvent->setMimeData(event->mimeData());
    lastDragDropEvent->setWidget(event->widget());
    lastDragDropEvent->setSource(event->source());
}

/*!
    \internal
*/
void QGraphicsViewPrivate::populateSceneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
                                                      QDropEvent *source)
{
#if QT_CONFIG(draganddrop)
    Q_Q(QGraphicsView);
    dest->setScenePos(q->mapToScene(source->pos()));
    dest->setScreenPos(q->mapToGlobal(source->pos()));
    dest->setButtons(source->mouseButtons());
    dest->setModifiers(source->keyboardModifiers());
    dest->setPossibleActions(source->possibleActions());
    dest->setProposedAction(source->proposedAction());
    dest->setDropAction(source->dropAction());
    dest->setMimeData(source->mimeData());
    dest->setWidget(viewport);
    dest->setSource(qobject_cast<QWidget *>(source->source()));
#else
    Q_UNUSED(dest)
    Q_UNUSED(source)
#endif
}

/*!
    \internal
*/
QRect QGraphicsViewPrivate::mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const
{
    Q_Q(const QGraphicsView);
    if (dirtyScroll)
        const_cast<QGraphicsViewPrivate *>(this)->updateScroll();

    if (item->d_ptr->itemIsUntransformable()) {
        QTransform itv = item->deviceTransform(q->viewportTransform());
        return itv.mapRect(rect).toAlignedRect();
    }

    // Translate-only
    // COMBINE
    QPointF offset;
    const QGraphicsItem *parentItem = item;
    const QGraphicsItemPrivate *itemd;
    do {
        itemd = parentItem->d_ptr.data();
        if (itemd->transformData)
            break;
        offset += itemd->pos;
    } while ((parentItem = itemd->parent));

    QRectF baseRect = rect.translated(offset.x(), offset.y());
    if (!parentItem) {
        if (identityMatrix) {
            baseRect.translate(-scrollX, -scrollY);
            return baseRect.toAlignedRect();
        }
        return matrix.mapRect(baseRect).translated(-scrollX, -scrollY).toAlignedRect();
    }

    QTransform tr = parentItem->sceneTransform();
    if (!identityMatrix)
        tr *= matrix;
    QRectF r = tr.mapRect(baseRect);
    r.translate(-scrollX, -scrollY);
    return r.toAlignedRect();
}

/*!
    \internal
*/
QRegion QGraphicsViewPrivate::mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const
{
    Q_Q(const QGraphicsView);
    if (dirtyScroll)
        const_cast<QGraphicsViewPrivate *>(this)->updateScroll();

    // Accurate bounding region
    QTransform itv = item->deviceTransform(q->viewportTransform());
    return item->boundingRegion(itv) & itv.mapRect(rect).toAlignedRect();
}

/*!
    \internal
*/
void QGraphicsViewPrivate::processPendingUpdates()
{
    if (!scene)
        return;

    if (fullUpdatePending) {
        viewport->update();
    } else if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) {
        viewport->update(dirtyBoundingRect);
    } else {
        viewport->update(dirtyRegion); // Already adjusted in updateRect/Region.
    }

    dirtyBoundingRect = QRect();
    dirtyRegion = QRegion();
}

static inline bool intersectsViewport(const QRect &r, int width, int height)
{ return !(r.left() > width) && !(r.right() < 0) && !(r.top() >= height) && !(r.bottom() < 0); }

static inline bool containsViewport(const QRect &r, int width, int height)
{ return r.left() <= 0 && r.top() <= 0 && r.right() >= width - 1 && r.bottom() >= height - 1; }

static inline void QRect_unite(QRect *rect, const QRect &other)
{
    if (rect->isEmpty()) {
        *rect = other;
    } else {
        rect->setCoords(qMin(rect->left(), other.left()), qMin(rect->top(), other.top()),
                        qMax(rect->right(), other.right()), qMax(rect->bottom(), other.bottom()));
    }
}

/*
   Calling this function results in update rects being clipped to the item's
   bounding rect. Note that updates prior to this function call is not clipped.
   The clip is removed by passing \nullptr.
*/
void QGraphicsViewPrivate::setUpdateClip(QGraphicsItem *item)
{
    Q_Q(QGraphicsView);
    // We simply ignore the request if the update mode is either FullViewportUpdate
    // or NoViewportUpdate; in that case there's no point in clipping anything.
    if (!item || viewportUpdateMode == QGraphicsView::NoViewportUpdate
        || viewportUpdateMode == QGraphicsView::FullViewportUpdate) {
        hasUpdateClip = false;
        return;
    }

    // Calculate the clip (item's bounding rect in view coordinates).
    // Optimized version of:
    // QRect clip = item->deviceTransform(q->viewportTransform())
    //              .mapRect(item->boundingRect()).toAlignedRect();
    QRect clip;
    if (item->d_ptr->itemIsUntransformable()) {
        QTransform xform = item->deviceTransform(q->viewportTransform());
        clip = xform.mapRect(item->boundingRect()).toAlignedRect();
    } else if (item->d_ptr->sceneTransformTranslateOnly && identityMatrix) {
        QRectF r(item->boundingRect());
        r.translate(item->d_ptr->sceneTransform.dx() - horizontalScroll(),
                    item->d_ptr->sceneTransform.dy() - verticalScroll());
        clip = r.toAlignedRect();
    } else if (!q->isTransformed()) {
        clip = item->d_ptr->sceneTransform.mapRect(item->boundingRect()).toAlignedRect();
    } else {
        QTransform xform = item->d_ptr->sceneTransform;
        xform *= q->viewportTransform();
        clip = xform.mapRect(item->boundingRect()).toAlignedRect();
    }

    if (hasUpdateClip) {
        // Intersect with old clip.
        updateClip &= clip;
    } else {
        updateClip = clip;
        hasUpdateClip = true;
    }
}

bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xform)
{
    if (rect.isEmpty())
        return false;

    if (viewportUpdateMode != QGraphicsView::MinimalViewportUpdate
        && viewportUpdateMode != QGraphicsView::SmartViewportUpdate) {
        // No point in updating with QRegion granularity; use the rect instead.
        return updateRectF(xform.mapRect(rect));
    }

    // Update mode is either Minimal or Smart, so we have to do a potentially slow operation,
    // which is clearly documented here: QGraphicsItem::setBoundingRegionGranularity.
    const QRegion region = xform.map(QRegion(rect.toAlignedRect()));
    QRect viewRect = region.boundingRect();
    const bool dontAdjustForAntialiasing = optimizationFlags & QGraphicsView::DontAdjustForAntialiasing;
    if (dontAdjustForAntialiasing)
        viewRect.adjust(-1, -1, 1, 1);
    else
        viewRect.adjust(-2, -2, 2, 2);
    if (!intersectsViewport(viewRect, viewport->width(), viewport->height()))
        return false; // Update region for sure outside viewport.

    for (QRect viewRect : region) {
        if (dontAdjustForAntialiasing)
            viewRect.adjust(-1, -1, 1, 1);
        else
            viewRect.adjust(-2, -2, 2, 2);
        if (hasUpdateClip)
            viewRect &= updateClip;
        dirtyRegion += viewRect;
    }

    return true;
}

// NB! Assumes the rect 'r' is already aligned and adjusted for antialiasing.
// For QRectF use updateRectF(const QRectF &) to ensure proper adjustments.
bool QGraphicsViewPrivate::updateRect(const QRect &r)
{
    if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate
        || !intersectsViewport(r, viewport->width(), viewport->height())) {
        return false;
    }

    switch (viewportUpdateMode) {
    case QGraphicsView::FullViewportUpdate:
        fullUpdatePending = true;
        viewport->update();
        break;
    case QGraphicsView::BoundingRectViewportUpdate:
        if (hasUpdateClip)
            QRect_unite(&dirtyBoundingRect, r & updateClip);
        else
            QRect_unite(&dirtyBoundingRect, r);
        if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) {
            fullUpdatePending = true;
            viewport->update();
        }
        break;
    case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
    case QGraphicsView::MinimalViewportUpdate:
        if (hasUpdateClip)
            dirtyRegion += r & updateClip;
        else
            dirtyRegion += r;
        break;
    default:
        break;
    }

    return true;
}

QStyleOptionGraphicsItem *QGraphicsViewPrivate::allocStyleOptionsArray(int numItems)
{
    if (mustAllocateStyleOptions || (numItems > styleOptions.capacity()))
        // too many items, let's allocate on-the-fly
        return new QStyleOptionGraphicsItem[numItems];

    // expand only whenever necessary
    if (numItems > styleOptions.size())
        styleOptions.resize(numItems);

    mustAllocateStyleOptions = true;
    return styleOptions.data();
}

void QGraphicsViewPrivate::freeStyleOptionsArray(QStyleOptionGraphicsItem *array)
{
    mustAllocateStyleOptions = false;
    if (array != styleOptions.data())
        delete [] array;
}

extern QPainterPath qt_regionToPath(const QRegion &region);

/*!
    ### Adjustments in findItems: mapToScene(QRect) forces us to adjust the
    input rectangle by (0, 0, 1, 1), because it uses QRect::bottomRight()
    (etc) when mapping the rectangle to a polygon (which is _wrong_). In
    addition, as QGraphicsItem::boundingRect() is defined in logical space,
    but the default pen for QPainter is cosmetic with a width of 0, QPainter
    is at risk of painting 1 pixel outside the bounding rect. Therefore we
    must search for items with an adjustment of (-1, -1, 1, 1).
*/
QList<QGraphicsItem *> QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems,
                                                       const QTransform &viewTransform) const
{
    Q_Q(const QGraphicsView);

    // Step 1) If all items are contained within the expose region, then
    // return a list of all visible items. ### the scene's growing bounding
    // rect does not take into account untransformable items.
    const QRectF exposedRegionSceneBounds = q->mapToScene(exposedRegion.boundingRect().adjusted(-1, -1, 1, 1))
                                            .boundingRect();
    if (exposedRegionSceneBounds.contains(scene->sceneRect())) {
        Q_ASSERT(allItems);
        *allItems = true;

        // All items are guaranteed within the exposed region.
        return scene->items(Qt::AscendingOrder);
    }

    // Step 2) If the expose region is a simple rect and the view is only
    // translated or scaled, search for items using
    // QGraphicsScene::items(QRectF).
    bool simpleRectLookup =  exposedRegion.rectCount() == 1 && matrix.type() <= QTransform::TxScale;
    if (simpleRectLookup) {
        return scene->items(exposedRegionSceneBounds,
                            Qt::IntersectsItemBoundingRect,
                            Qt::AscendingOrder, viewTransform);
    }

    // If the region is complex or the view has a complex transform, adjust
    // the expose region, convert it to a path, and then search for items
    // using QGraphicsScene::items(QPainterPath);
    QRegion adjustedRegion;
    for (const QRect &r : exposedRegion)
        adjustedRegion += r.adjusted(-1, -1, 1, 1);

    const QPainterPath exposedScenePath(q->mapToScene(qt_regionToPath(adjustedRegion)));
    return scene->items(exposedScenePath, Qt::IntersectsItemBoundingRect,
                        Qt::AscendingOrder, viewTransform);
}

/*!
    \internal

    Enables input methods for the view if and only if the current focus item of
    the scene accepts input methods. Call function whenever that condition has
    potentially changed.
*/
void QGraphicsViewPrivate::updateInputMethodSensitivity()
{
    Q_Q(QGraphicsView);
    QGraphicsItem *focusItem = nullptr;
    bool enabled = scene && (focusItem = scene->focusItem())
                   && (focusItem->d_ptr->flags & QGraphicsItem::ItemAcceptsInputMethod);
    q->setAttribute(Qt::WA_InputMethodEnabled, enabled);
    q->viewport()->setAttribute(Qt::WA_InputMethodEnabled, enabled);

    if (!enabled) {
        q->setInputMethodHints({ });
        return;
    }

    QGraphicsProxyWidget *proxy = focusItem->d_ptr->isWidget && focusItem->d_ptr->isProxyWidget()
                                    ? static_cast<QGraphicsProxyWidget *>(focusItem) : nullptr;
    if (!proxy) {
        q->setInputMethodHints(focusItem->inputMethodHints());
    } else if (QWidget *widget = proxy->widget()) {
        if (QWidget *fw = widget->focusWidget())
            widget = fw;
        q->setInputMethodHints(widget->inputMethodHints());
    } else {
        q->setInputMethodHints({ });
    }
}

/*!
    Constructs a QGraphicsView. \a parent is passed to QWidget's constructor.
*/
QGraphicsView::QGraphicsView(QWidget *parent)
    : QAbstractScrollArea(*new QGraphicsViewPrivate, parent)
{
    setViewport(nullptr);
    setAcceptDrops(true);
    setBackgroundRole(QPalette::Base);
    // Investigate leaving these disabled by default.
    setAttribute(Qt::WA_InputMethodEnabled);
    viewport()->setAttribute(Qt::WA_InputMethodEnabled);
}

/*!
    Constructs a QGraphicsView and sets the visualized scene to \a
    scene. \a parent is passed to QWidget's constructor.
*/
QGraphicsView::QGraphicsView(QGraphicsScene *scene, QWidget *parent)
    : QAbstractScrollArea(*new QGraphicsViewPrivate, parent)
{
    setScene(scene);
    setViewport(nullptr);
    setAcceptDrops(true);
    setBackgroundRole(QPalette::Base);
    // Investigate leaving these disabled by default.
    setAttribute(Qt::WA_InputMethodEnabled);
    viewport()->setAttribute(Qt::WA_InputMethodEnabled);
}

/*!
  \internal
 */
QGraphicsView::QGraphicsView(QGraphicsViewPrivate &dd, QWidget *parent)
  : QAbstractScrollArea(dd, parent)
{
    setViewport(nullptr);
    setAcceptDrops(true);
    setBackgroundRole(QPalette::Base);
    // Investigate leaving these disabled by default.
    setAttribute(Qt::WA_InputMethodEnabled);
    viewport()->setAttribute(Qt::WA_InputMethodEnabled);
}

/*!
    Destructs the QGraphicsView object.
*/
QGraphicsView::~QGraphicsView()
{
    Q_D(QGraphicsView);
    if (d->scene)
        d->scene->d_func()->views.removeAll(this);
    delete d->lastDragDropEvent;
}

/*!
    \reimp
*/
QSize QGraphicsView::sizeHint() const
{
    Q_D(const QGraphicsView);
    if (d->scene) {
        QSizeF baseSize = d->matrix.mapRect(sceneRect()).size();
        baseSize += QSizeF(d->frameWidth * 2, d->frameWidth * 2);
        return baseSize.boundedTo((3 * QDesktopWidgetPrivate::size()) / 4).toSize();
    }
    return QAbstractScrollArea::sizeHint();
}

/*!
    \property QGraphicsView::renderHints
    \brief the default render hints for the view

    These hints are
    used to initialize QPainter before each visible item is drawn. QPainter
    uses render hints to toggle rendering features such as antialiasing and
    smooth pixmap transformation.

    QPainter::TextAntialiasing is enabled by default.

    Example:

    \snippet code/src_gui_graphicsview_qgraphicsview.cpp 1
*/
QPainter::RenderHints QGraphicsView::renderHints() const
{
    Q_D(const QGraphicsView);
    return d->renderHints;
}
void QGraphicsView::setRenderHints(QPainter::RenderHints hints)
{
    Q_D(QGraphicsView);
    if (hints == d->renderHints)
        return;
    d->renderHints = hints;
    d->updateAll();
}

/*!
    If \a enabled is true, the render hint \a hint is enabled; otherwise it
    is disabled.

    \sa renderHints
*/
void QGraphicsView::setRenderHint(QPainter::RenderHint hint, bool enabled)
{
    Q_D(QGraphicsView);
    QPainter::RenderHints oldHints = d->renderHints;
    d->renderHints.setFlag(hint, enabled);
    if (oldHints != d->renderHints)
        d->updateAll();
}

/*!
    \property QGraphicsView::alignment
    \brief the alignment of the scene in the view when the whole
    scene is visible.

    If the whole scene is visible in the view, (i.e., there are no visible
    scroll bars,) the view's alignment will decide where the scene will be
    rendered in the view. For example, if the alignment is Qt::AlignCenter,
    which is default, the scene will be centered in the view, and if the
    alignment is (Qt::AlignLeft | Qt::AlignTop), the scene will be rendered in
    the top-left corner of the view.
*/
Qt::Alignment QGraphicsView::alignment() const
{
    Q_D(const QGraphicsView);
    return d->alignment;
}
void QGraphicsView::setAlignment(Qt::Alignment alignment)
{
    Q_D(QGraphicsView);
    if (d->alignment != alignment) {
        d->alignment = alignment;
        d->recalculateContentSize();
    }
}

/*!
    \property QGraphicsView::transformationAnchor
    \brief how the view should position the scene during transformations.

    QGraphicsView uses this property to decide how to position the scene in
    the viewport when the transformation matrix changes, and the coordinate
    system of the view is transformed. The default behavior, AnchorViewCenter,
    ensures that the scene point at the center of the view remains unchanged
    during transformations (e.g., when rotating, the scene will appear to
    rotate around the center of the view).

    Note that the effect of this property is noticeable when only a part of the
    scene is visible (i.e., when there are scroll bars). Otherwise, if the
    whole scene fits in the view, QGraphicsScene uses the view \l alignment to
    position the scene in the view.

    \sa alignment, resizeAnchor
*/
QGraphicsView::ViewportAnchor QGraphicsView::transformationAnchor() const
{
    Q_D(const QGraphicsView);
    return d->transformationAnchor;
}
void QGraphicsView::setTransformationAnchor(ViewportAnchor anchor)
{
    Q_D(QGraphicsView);
    d->transformationAnchor = anchor;

    // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
    // in order to have up-to-date information for centering the view.
    if (d->transformationAnchor == AnchorUnderMouse)
        d->viewport->setMouseTracking(true);
}

/*!
    \property QGraphicsView::resizeAnchor
    \brief how the view should position the scene when the view is resized.

    QGraphicsView uses this property to decide how to position the scene in
    the viewport when the viewport widget's size changes. The default
    behavior, NoAnchor, leaves the scene's position unchanged during a resize;
    the top-left corner of the view will appear to be anchored while resizing.

    Note that the effect of this property is noticeable when only a part of the
    scene is visible (i.e., when there are scroll bars). Otherwise, if the
    whole scene fits in the view, QGraphicsScene uses the view \l alignment to
    position the scene in the view.

    \sa alignment, transformationAnchor
*/
QGraphicsView::ViewportAnchor QGraphicsView::resizeAnchor() const
{
    Q_D(const QGraphicsView);
    return d->resizeAnchor;
}
void QGraphicsView::setResizeAnchor(ViewportAnchor anchor)
{
    Q_D(QGraphicsView);
    d->resizeAnchor = anchor;

    // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
    // in order to have up-to-date information for centering the view.
    if (d->resizeAnchor == AnchorUnderMouse)
        d->viewport->setMouseTracking(true);
}

/*!
    \property QGraphicsView::viewportUpdateMode
    \brief how the viewport should update its contents.

    \since 4.3

    QGraphicsView uses this property to decide how to update areas of the
    scene that have been reexposed or changed. Usually you do not need to
    modify this property, but there are some cases where doing so can improve
    rendering performance. See the ViewportUpdateMode documentation for
    specific details.

    The default value is MinimalViewportUpdate, where QGraphicsView will
    update as small an area of the viewport as possible when the contents
    change.

    \sa ViewportUpdateMode, cacheMode
*/
QGraphicsView::ViewportUpdateMode QGraphicsView::viewportUpdateMode() const
{
    Q_D(const QGraphicsView);
    return d->viewportUpdateMode;
}
void QGraphicsView::setViewportUpdateMode(ViewportUpdateMode mode)
{
    Q_D(QGraphicsView);
    d->viewportUpdateMode = mode;
}

/*!
    \property QGraphicsView::optimizationFlags
    \brief flags that can be used to tune QGraphicsView's performance.

    \since 4.3

    QGraphicsView uses clipping, extra bounding rect adjustments, and certain
    other aids to improve rendering quality and performance for the common
    case graphics scene. However, depending on the target platform, the scene,
    and the viewport in use, some of these operations can degrade performance.

    The effect varies from flag to flag; see the OptimizationFlags
    documentation for details.

    By default, no optimization flags are enabled.

    \sa setOptimizationFlag()
*/
QGraphicsView::OptimizationFlags QGraphicsView::optimizationFlags() const
{
    Q_D(const QGraphicsView);
    return d->optimizationFlags;
}
void QGraphicsView::setOptimizationFlags(OptimizationFlags flags)
{
    Q_D(QGraphicsView);
    d->optimizationFlags = flags;
}

/*!
    Enables \a flag if \a enabled is true; otherwise disables \a flag.

    \sa optimizationFlags
*/
void QGraphicsView::setOptimizationFlag(OptimizationFlag flag, bool enabled)
{
    Q_D(QGraphicsView);
    d->optimizationFlags.setFlag(flag, enabled);
}

/*!
    \property QGraphicsView::dragMode
    \brief the behavior for dragging the mouse over the scene while
    the left mouse button is pressed.

    This property defines what should happen when the user clicks on the scene
    background and drags the mouse (e.g., scrolling the viewport contents
    using a pointing hand cursor, or selecting multiple items with a rubber
    band). The default value, NoDrag, does nothing.

    This behavior only affects mouse clicks that are not handled by any item.
    You can define a custom behavior by creating a subclass of QGraphicsView
    and reimplementing mouseMoveEvent().
*/
QGraphicsView::DragMode QGraphicsView::dragMode() const
{
    Q_D(const QGraphicsView);
    return d->dragMode;
}
void QGraphicsView::setDragMode(DragMode mode)
{
    Q_D(QGraphicsView);
    if (d->dragMode == mode)
        return;

#if QT_CONFIG(rubberband)
    d->clearRubberBand();
#endif

#ifndef QT_NO_CURSOR
    if (d->dragMode == ScrollHandDrag)
        viewport()->unsetCursor();
#endif

    // If dragMode is unset while dragging, e.g. via a keyEvent, we
    // don't unset the handScrolling state. When enabling scrolling
    // again the mouseMoveEvent will automatically start scrolling,
    // without a mousePress
    if (d->dragMode == ScrollHandDrag && mode == NoDrag && d->handScrolling)
        d->handScrolling = false;

    d->dragMode = mode;

#ifndef QT_NO_CURSOR
    if (d->dragMode == ScrollHandDrag) {
        // Forget the stored viewport cursor when we enter scroll hand drag mode.
        d->hasStoredOriginalCursor = false;
        viewport()->setCursor(Qt::OpenHandCursor);
    }
#endif
}

#if QT_CONFIG(rubberband)
/*!
    \property QGraphicsView::rubberBandSelectionMode
    \brief the behavior for selecting items with a rubber band selection rectangle.
    \since 4.3

    This property defines how items are selected when using the RubberBandDrag
    drag mode.

    The default value is Qt::IntersectsItemShape; all items whose shape
    intersects with or is contained by the rubber band are selected.

    \sa dragMode, items(), rubberBandRect()
*/
Qt::ItemSelectionMode QGraphicsView::rubberBandSelectionMode() const
{
    Q_D(const QGraphicsView);
    return d->rubberBandSelectionMode;
}
void QGraphicsView::setRubberBandSelectionMode(Qt::ItemSelectionMode mode)
{
    Q_D(QGraphicsView);
    d->rubberBandSelectionMode = mode;
}

/*!
   \since 5.1
   This functions returns the current rubber band area (in viewport coordinates) if the user
   is currently doing an itemselection with rubber band. When the user is not using the
   rubber band this functions returns (a null) QRectF().

   Notice that part of this QRect can be outise the visual viewport. It can e.g
   contain negative values.

   \sa rubberBandSelectionMode, rubberBandChanged()
*/

QRect QGraphicsView::rubberBandRect() const
{
    Q_D(const QGraphicsView);
    if (d->dragMode != QGraphicsView::RubberBandDrag || !d->sceneInteractionAllowed || !d->rubberBanding)
        return QRect();

    return d->rubberBandRect;
}
#endif

/*!
    \property QGraphicsView::cacheMode
    \brief which parts of the view are cached

    QGraphicsView can cache pre-rendered content in a QPixmap, which is then
    drawn onto the viewport. The purpose of such caching is to speed up the
    total rendering time for areas that are slow to render.  Texture, gradient
    and alpha blended backgrounds, for example, can be notibly slow to render;
    especially with a transformed view. The CacheBackground flag enables
    caching of the view's background. For example:

    \snippet code/src_gui_graphicsview_qgraphicsview.cpp 2

    The cache is invalidated every time the view is transformed. However, when
    scrolling, only partial invalidation is required.

    By default, nothing is cached.

    \sa resetCachedContent(), QPixmapCache
*/
QGraphicsView::CacheMode QGraphicsView::cacheMode() const
{
    Q_D(const QGraphicsView);
    return d->cacheMode;
}
void QGraphicsView::setCacheMode(CacheMode mode)
{
    Q_D(QGraphicsView);
    if (mode == d->cacheMode)
        return;
    d->cacheMode = mode;
    resetCachedContent();
}

/*!
    Resets any cached content. Calling this function will clear
    QGraphicsView's cache. If the current cache mode is \l CacheNone, this
    function does nothing.

    This function is called automatically for you when the backgroundBrush or
    QGraphicsScene::backgroundBrush properties change; you only need to call
    this function if you have reimplemented QGraphicsScene::drawBackground()
    or QGraphicsView::drawBackground() to draw a custom background, and need
    to trigger a full redraw.

    \sa cacheMode()
*/
void QGraphicsView::resetCachedContent()
{
    Q_D(QGraphicsView);
    if (d->cacheMode == CacheNone)
        return;

    if (d->cacheMode & CacheBackground) {
        // Background caching is enabled.
        d->mustResizeBackgroundPixmap = true;
        d->updateAll();
    } else if (d->mustResizeBackgroundPixmap) {
        // Background caching is disabled.
        // Cleanup, free some resources.
        d->mustResizeBackgroundPixmap = false;
        d->backgroundPixmap = QPixmap();
        d->backgroundPixmapExposed = QRegion();
    }
}

/*!
    Invalidates and schedules a redraw of \a layers inside \a rect. \a rect is
    in scene coordinates. Any cached content for \a layers inside \a rect is
    unconditionally invalidated and redrawn.

    You can call this function to notify QGraphicsView of changes to the
    background or the foreground of the scene. It is commonly used for scenes
    with tile-based backgrounds to notify changes when QGraphicsView has
    enabled background caching.

    Note that QGraphicsView currently supports background caching only (see
    QGraphicsView::CacheBackground). This function is equivalent to calling update() if any
    layer but QGraphicsScene::BackgroundLayer is passed.

    \sa QGraphicsScene::invalidate(), update()
*/
void QGraphicsView::invalidateScene(const QRectF &rect, QGraphicsScene::SceneLayers layers)
{
    Q_D(QGraphicsView);
    if ((layers & QGraphicsScene::BackgroundLayer) && !d->mustResizeBackgroundPixmap) {
        QRect viewRect = mapFromScene(rect).boundingRect();
        if (viewport()->rect().intersects(viewRect)) {
            // The updated background area is exposed; schedule this area for
            // redrawing.
            d->backgroundPixmapExposed += viewRect;
            if (d->scene)
                d->scene->update(rect);
        }
    }
}

/*!
    \property QGraphicsView::interactive
    \brief whether the view allows scene interaction.

    If enabled, this view is set to allow scene interaction. Otherwise, this
    view will not allow interaction, and any mouse or key events are ignored
    (i.e., it will act as a read-only view).

    By default, this property is \c true.
*/
bool QGraphicsView::isInteractive() const
{
    Q_D(const QGraphicsView);
    return d->sceneInteractionAllowed;
}
void QGraphicsView::setInteractive(bool allowed)
{
    Q_D(QGraphicsView);
    d->sceneInteractionAllowed = allowed;
}

/*!
    Returns a pointer to the scene that is currently visualized in the
    view. If no scene is currently visualized, \nullptr is returned.

    \sa setScene()
*/
QGraphicsScene *QGraphicsView::scene() const
{
    Q_D(const QGraphicsView);
    return d->scene;
}

/*!
    Sets the current scene to \a scene. If \a scene is already being
    viewed, this function does nothing.

    When a scene is set on a view, the QGraphicsScene::changed() signal
    is automatically connected to this view's updateScene() slot, and the
    view's scroll bars are adjusted to fit the size of the scene.

    The view does not take ownership of \a scene.
*/
void QGraphicsView::setScene(QGraphicsScene *scene)
{
    Q_D(QGraphicsView);
    if (d->scene == scene)
        return;

    // Always update the viewport when the scene changes.
    d->updateAll();

    // Remove the previously assigned scene.
    if (d->scene) {
        disconnect(d->scene, SIGNAL(changed(QList<QRectF>)),
                   this, SLOT(updateScene(QList<QRectF>)));
        disconnect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
                   this, SLOT(updateSceneRect(QRectF)));
        d->scene->d_func()->removeView(this);
        d->connectedToScene = false;

        if (isActiveWindow() && isVisible()) {
            QEvent windowDeactivate(QEvent::WindowDeactivate);
            QCoreApplication::sendEvent(d->scene, &windowDeactivate);
        }
        if(hasFocus())
            d->scene->clearFocus();
    }

    // Assign the new scene and update the contents (scrollbars, etc.)).
    if ((d->scene = scene)) {
        connect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
                this, SLOT(updateSceneRect(QRectF)));
        d->updateSceneSlotReimplementedChecked = false;
        d->scene->d_func()->addView(this);
        d->recalculateContentSize();
        d->lastCenterPoint = sceneRect().center();
        d->keepLastCenterPoint = true;
        // We are only interested in mouse tracking if items accept
        // hover events or use non-default cursors.
        if (!d->scene->d_func()->allItemsIgnoreHoverEvents
            || !d->scene->d_func()->allItemsUseDefaultCursor) {
            d->viewport->setMouseTracking(true);
        }

        // enable touch events if any items is interested in them
        if (!d->scene->d_func()->allItemsIgnoreTouchEvents)
            d->viewport->setAttribute(Qt::WA_AcceptTouchEvents);

        if (isActiveWindow() && isVisible()) {
            QEvent windowActivate(QEvent::WindowActivate);
            QCoreApplication::sendEvent(d->scene, &windowActivate);
        }
    } else {
        d->recalculateContentSize();
    }

    d->updateInputMethodSensitivity();

    if (d->scene && hasFocus())
        d->scene->setFocus();
}

/*!
    \property QGraphicsView::sceneRect
    \brief the area of the scene visualized by this view.

    The scene rectangle defines the extent of the scene, and in the view's case,
    this means the area of the scene that you can navigate using the scroll
    bars.

    If unset, or if a null QRectF is set, this property has the same value as
    QGraphicsScene::sceneRect, and it changes with
    QGraphicsScene::sceneRect. Otherwise, the view's scene rect is unaffected
    by the scene.

    Note that, although the scene supports a virtually unlimited size, the
    range of the scroll bars will never exceed the range of an integer
    (INT_MIN, INT_MAX). When the scene is larger than the scroll bars' values,
    you can choose to use translate() to navigate the scene instead.

    By default, this property contains a rectangle at the origin with zero
    width and height.

    \sa QGraphicsScene::sceneRect
*/
QRectF QGraphicsView::sceneRect() const
{
    Q_D(const QGraphicsView);
    if (d->hasSceneRect)
        return d->sceneRect;
    if (d->scene)
        return d->scene->sceneRect();
    return QRectF();
}
void QGraphicsView::setSceneRect(const QRectF &rect)
{
    Q_D(QGraphicsView);
    d->hasSceneRect = !rect.isNull();
    d->sceneRect = rect;
    d->recalculateContentSize();
}

#if QT_DEPRECATED_SINCE(5, 15)

/*!
    \obsolete

    Use transform() instead.

    Returns the current transformation matrix for the view. If no current
    transformation is set, the identity matrix is returned.

    \sa setMatrix(), transform(), rotate(), scale(), shear(), translate()
*/
QMatrix QGraphicsView::matrix() const
{
    Q_D(const QGraphicsView);
    return d->matrix.toAffine();
}

/*!
    \obsolete

    Use setTransform() instead.

    Sets the view's current transformation matrix to \a matrix.

    If \a combine is true, then \a matrix is combined with the current matrix;
    otherwise, \a matrix \e replaces the current matrix. \a combine is false
    by default.

    The transformation matrix tranforms the scene into view coordinates. Using
    the default transformation, provided by the identity matrix, one pixel in
    the view represents one unit in the scene (e.g., a 10x10 rectangular item
    is drawn using 10x10 pixels in the view). If a 2x2 scaling matrix is
    applied, the scene will be drawn in 1:2 (e.g., a 10x10 rectangular item is
    then drawn using 20x20 pixels in the view).

    Example:

    \snippet code/src_gui_graphicsview_qgraphicsview.cpp 3

    To simplify interation with items using a transformed view, QGraphicsView
    provides mapTo... and mapFrom... functions that can translate between
    scene and view coordinates. For example, you can call mapToScene() to map
    a view coordinate to a floating point scene coordinate, or mapFromScene()
    to map from floating point scene coordinates to view coordinates.

    \sa matrix(), setTransform(), rotate(), scale(), shear(), translate()
*/
void QGraphicsView::setMatrix(const QMatrix &matrix, bool combine)
{
    setTransform(QTransform(matrix), combine);
}

/*!
    \obsolete

    Use resetTransform() instead.

    Resets the view transformation matrix to the identity matrix.

    \sa resetTransform()
*/
void QGraphicsView::resetMatrix()
{
    resetTransform();
}

#endif // QT_DEPRECATED_SINCE(5, 15)

/*!
    Rotates the current view transformation \a angle degrees clockwise.

    \sa setTransform(), transform(), scale(), shear(), translate()
*/
void QGraphicsView::rotate(qreal angle)
{
    Q_D(QGraphicsView);
    QTransform matrix = d->matrix;
    matrix.rotate(angle);
    setTransform(matrix);
}

/*!
    Scales the current view transformation by (\a sx, \a sy).

    \sa setTransform(), transform(), rotate(), shear(), translate()
*/
void QGraphicsView::scale(qreal sx, qreal sy)
{
    Q_D(QGraphicsView);
    QTransform matrix = d->matrix;
    matrix.scale(sx, sy);
    setTransform(matrix);
}

/*!
    Shears the current view transformation by (\a sh, \a sv).

    \sa setTransform(), transform(), rotate(), scale(), translate()
*/
void QGraphicsView::shear(qreal sh, qreal sv)
{
    Q_D(QGraphicsView);
    QTransform matrix = d->matrix;
    matrix.shear(sh, sv);
    setTransform(matrix);
}

/*!
    Translates the current view transformation by (\a dx, \a dy).

    \sa setTransform(), transform(), rotate(), shear()
*/
void QGraphicsView::translate(qreal dx, qreal dy)
{
    Q_D(QGraphicsView);
    QTransform matrix = d->matrix;
    matrix.translate(dx, dy);
    setTransform(matrix);
}

/*!
    Scrolls the contents of the viewport to ensure that the scene
    coordinate \a pos, is centered in the view.

    Because \a pos is a floating point coordinate, and the scroll bars operate
    on integer coordinates, the centering is only an approximation.

    \note If the item is close to or outside the border, it will be visible
    in the view, but not centered.

    \sa ensureVisible()
*/
void QGraphicsView::centerOn(const QPointF &pos)
{
    Q_D(QGraphicsView);
    qreal width = viewport()->width();
    qreal height = viewport()->height();
    QPointF viewPoint = d->matrix.map(pos);
    QPointF oldCenterPoint = pos;

    if (!d->leftIndent) {
        if (isRightToLeft()) {
            qint64 horizontal = 0;
            horizontal += horizontalScrollBar()->minimum();
            horizontal += horizontalScrollBar()->maximum();
            horizontal -= int(viewPoint.x() - width / 2.0);
            horizontalScrollBar()->setValue(horizontal);
        } else {
            horizontalScrollBar()->setValue(int(viewPoint.x() - width / 2.0));
        }
    }
    if (!d->topIndent)
        verticalScrollBar()->setValue(int(viewPoint.y() - height / 2.0));
    d->lastCenterPoint = oldCenterPoint;
}

/*!
    \fn QGraphicsView::centerOn(qreal x, qreal y)
    \overload

    This function is provided for convenience. It's equivalent to calling
    centerOn(QPointF(\a x, \a y)).
*/

/*!
    \overload

    Scrolls the contents of the viewport to ensure that \a item
    is centered in the view.

    \sa ensureVisible()
*/
void QGraphicsView::centerOn(const QGraphicsItem *item)
{
    centerOn(item->sceneBoundingRect().center());
}

/*!
    Scrolls the contents of the viewport so that the scene rectangle \a rect
    is visible, with margins specified in pixels by \a xmargin and \a
    ymargin. If the specified rect cannot be reached, the contents are
    scrolled to the nearest valid position. The default value for both margins
    is 50 pixels.

    \sa centerOn()
*/
void QGraphicsView::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
{
    Q_D(QGraphicsView);
    qreal width = viewport()->width();
    qreal height = viewport()->height();
    QRectF viewRect = d->matrix.mapRect(rect);

    qreal left = d->horizontalScroll();
    qreal right = left + width;
    qreal top = d->verticalScroll();
    qreal bottom = top + height;

    if (viewRect.left() <= left + xmargin) {
        // need to scroll from the left
        if (!d->leftIndent)
            horizontalScrollBar()->setValue(int(viewRect.left() - xmargin - 0.5));
    }
    if (viewRect.right() >= right - xmargin) {
        // need to scroll from the right
        if (!d->leftIndent)
            horizontalScrollBar()->setValue(int(viewRect.right() - width + xmargin + 0.5));
    }
    if (viewRect.top() <= top + ymargin) {
        // need to scroll from the top
        if (!d->topIndent)
            verticalScrollBar()->setValue(int(viewRect.top() - ymargin - 0.5));
    }
    if (viewRect.bottom() >= bottom - ymargin) {
        // need to scroll from the bottom
        if (!d->topIndent)
            verticalScrollBar()->setValue(int(viewRect.bottom() - height + ymargin + 0.5));
    }
}

/*!
    \fn QGraphicsView::ensureVisible(qreal x, qreal y, qreal w, qreal h,
    int xmargin, int ymargin)
    \overload

    This function is provided for convenience. It's equivalent to calling
    ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin).
*/

/*!
    \overload

    Scrolls the contents of the viewport so that the center of item \a item is
    visible, with margins specified in pixels by \a xmargin and \a ymargin. If
    the specified point cannot be reached, the contents are scrolled to the
    nearest valid position. The default value for both margins is 50 pixels.

    \sa centerOn()
*/
void QGraphicsView::ensureVisible(const QGraphicsItem *item, int xmargin, int ymargin)
{
    ensureVisible(item->sceneBoundingRect(), xmargin, ymargin);
}

/*!
    Scales the view matrix and scrolls the scroll bars to ensure that the
    scene rectangle \a rect fits inside the viewport. \a rect must be inside
    the scene rect; otherwise, fitInView() cannot guarantee that the whole
    rect is visible.

    This function keeps the view's rotation, translation, or shear. The view
    is scaled according to \a aspectRatioMode. \a rect will be centered in the
    view if it does not fit tightly.

    It's common to call fitInView() from inside a reimplementation of
    resizeEvent(), to ensure that the whole scene, or parts of the scene,
    scales automatically to fit the new size of the viewport as the view is
    resized. Note though, that calling fitInView() from inside resizeEvent()
    can lead to unwanted resize recursion, if the new transformation toggles
    the automatic state of the scrollbars. You can toggle the scrollbar
    policies to always on or always off to prevent this (see
    horizontalScrollBarPolicy() and verticalScrollBarPolicy()).

    If \a rect is empty, or if the viewport is too small, this
    function will do nothing.

    \sa setTransform(), ensureVisible(), centerOn()
*/
void QGraphicsView::fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRatioMode)
{
    Q_D(QGraphicsView);
    if (!d->scene || rect.isNull())
        return;

    // Reset the view scale to 1:1.
    QRectF unity = d->matrix.mapRect(QRectF(0, 0, 1, 1));
    if (unity.isEmpty())
        return;
    scale(1 / unity.width(), 1 / unity.height());

    // Find the ideal x / y scaling ratio to fit \a rect in the view.
    int margin = 2;
    QRectF viewRect = viewport()->rect().adjusted(margin, margin, -margin, -margin);
    if (viewRect.isEmpty())
        return;
    QRectF sceneRect = d->matrix.mapRect(rect);
    if (sceneRect.isEmpty())
        return;
    qreal xratio = viewRect.width() / sceneRect.width();
    qreal yratio = viewRect.height() / sceneRect.height();

    // Respect the aspect ratio mode.
    switch (aspectRatioMode) {
    case Qt::KeepAspectRatio:
        xratio = yratio = qMin(xratio, yratio);
        break;
    case Qt::KeepAspectRatioByExpanding:
        xratio = yratio = qMax(xratio, yratio);
        break;
    case Qt::IgnoreAspectRatio:
        break;
    }

    // Scale and center on the center of \a rect.
    scale(xratio, yratio);
    centerOn(rect.center());
}

/*!
    \fn void QGraphicsView::fitInView(qreal x, qreal y, qreal w, qreal h,
    Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio)

    \overload

    This convenience function is equivalent to calling
    fitInView(QRectF(\a x, \a y, \a w, \a h), \a aspectRatioMode).

    \sa ensureVisible(), centerOn()
*/

/*!
    \overload

    Ensures that \a item fits tightly inside the view, scaling the view
    according to \a aspectRatioMode.

    \sa ensureVisible(), centerOn()
*/
void QGraphicsView::fitInView(const QGraphicsItem *item, Qt::AspectRatioMode aspectRatioMode)
{
    QPainterPath path = item->isClipped() ? item->clipPath() : item->shape();
    if (item->d_ptr->hasTranslateOnlySceneTransform()) {
        path.translate(item->d_ptr->sceneTransform.dx(), item->d_ptr->sceneTransform.dy());
        fitInView(path.boundingRect(), aspectRatioMode);
    } else {
        fitInView(item->d_ptr->sceneTransform.map(path).boundingRect(), aspectRatioMode);
    }
}

/*!
    Renders the \a source rect, which is in view coordinates, from the scene
    into \a target, which is in paint device coordinates, using \a
    painter. This function is useful for capturing the contents of the view
    onto a paint device, such as a QImage (e.g., to take a screenshot), or for
    printing to QPrinter. For example:

    \snippet code/src_gui_graphicsview_qgraphicsview.cpp 4

    If \a source is a null rect, this function will use viewport()->rect() to
    determine what to draw. If \a target is a null rect, the full dimensions
    of \a painter's paint device (e.g., for a QPrinter, the page size) will be
    used.

    The source rect contents will be transformed according to \a
    aspectRatioMode to fit into the target rect. By default, the aspect ratio
    is kept, and \a source is scaled to fit in \a target.

    \sa QGraphicsScene::render()
*/
void QGraphicsView::render(QPainter *painter, const QRectF &target, const QRect &source,
                           Qt::AspectRatioMode aspectRatioMode)
{
    // ### Switch to using the recursive rendering algorithm instead.

    Q_D(QGraphicsView);
    if (!d->scene || !(painter && painter->isActive()))
        return;

    // Default source rect = viewport rect
    QRect sourceRect = source;
    if (source.isNull())
        sourceRect = viewport()->rect();

    // Default target rect = device rect
    QRectF targetRect = target;
    if (target.isNull()) {
        if (painter->device()->devType() == QInternal::Picture)
            targetRect = sourceRect;
        else
            targetRect.setRect(0, 0, painter->device()->width(), painter->device()->height());
    }

    // Find the ideal x / y scaling ratio to fit \a source into \a target.
    qreal xratio = targetRect.width() / sourceRect.width();
    qreal yratio = targetRect.height() / sourceRect.height();

    // Scale according to the aspect ratio mode.
    switch (aspectRatioMode) {
    case Qt::KeepAspectRatio:
        xratio = yratio = qMin(xratio, yratio);
        break;
    case Qt::KeepAspectRatioByExpanding:
        xratio = yratio = qMax(xratio, yratio);
        break;
    case Qt::IgnoreAspectRatio:
        break;
    }

    // Find all items to draw, and reverse the list (we want to draw
    // in reverse order).
    QPolygonF sourceScenePoly = mapToScene(sourceRect.adjusted(-1, -1, 1, 1));
    QList<QGraphicsItem *> itemList = d->scene->items(sourceScenePoly,
                                                      Qt::IntersectsItemBoundingRect);
    QGraphicsItem **itemArray = new QGraphicsItem *[itemList.size()];
    int numItems = itemList.size();
    for (int i = 0; i < numItems; ++i)
        itemArray[numItems - i - 1] = itemList.at(i);
    itemList.clear();

    // Setup painter matrix.
    QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
    QTransform painterMatrix = d->matrix * moveMatrix;
    painterMatrix *= QTransform()
                     .translate(targetRect.left(), targetRect.top())
                     .scale(xratio, yratio)
                     .translate(-sourceRect.left(), -sourceRect.top());

    // Generate the style options
    QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
    for (int i = 0; i < numItems; ++i)
        itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], painterMatrix, targetRect.toRect());

    painter->save();

    // Clip in device coordinates to avoid QRegion transformations.
    painter->setClipRect(targetRect);
    QPainterPath path;
    path.addPolygon(sourceScenePoly);
    path.closeSubpath();
    painter->setClipPath(painterMatrix.map(path), Qt::IntersectClip);

    // Transform the painter.
    painter->setTransform(painterMatrix, true);

    // Render the scene.
    QRectF sourceSceneRect = sourceScenePoly.boundingRect();
    drawBackground(painter, sourceSceneRect);
    drawItems(painter, numItems, itemArray, styleOptionArray);
    drawForeground(painter, sourceSceneRect);

    delete [] itemArray;
    d->freeStyleOptionsArray(styleOptionArray);

    painter->restore();
}

/*!
    Returns a list of all the items in the associated scene, in descending
    stacking order (i.e., the first item in the returned list is the uppermost
    item).

    \sa QGraphicsScene::items(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsView::items() const
{
    Q_D(const QGraphicsView);
    if (!d->scene)
        return QList<QGraphicsItem *>();
    return d->scene->items();
}

/*!
    Returns a list of all the items at the position \a pos in the view. The
    items are listed in descending stacking order (i.e., the first item in the
    list is the uppermost item, and the last item is the lowermost item). \a
    pos is in viewport coordinates.

    This function is most commonly called from within mouse event handlers in
    a subclass in QGraphicsView. \a pos is in untransformed viewport
    coordinates, just like QMouseEvent::pos().

    \snippet code/src_gui_graphicsview_qgraphicsview.cpp 5

    \sa QGraphicsScene::items(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsView::items(const QPoint &pos) const
{
    Q_D(const QGraphicsView);
    if (!d->scene)
        return QList<QGraphicsItem *>();
    // ### Unify these two, and use the items(QPointF) version in
    // QGraphicsScene instead. The scene items function could use the viewport
    // transform to map the point to a rect/polygon.
    if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) {
        // Use the rect version
        QTransform xinv = viewportTransform().inverted();
        return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1)),
                               Qt::IntersectsItemShape,
                               Qt::DescendingOrder,
                               viewportTransform());
    }
    // Use the polygon version
    return d->scene->items(mapToScene(pos.x(), pos.y(), 1, 1),
                           Qt::IntersectsItemShape,
                           Qt::DescendingOrder,
                           viewportTransform());
}

/*!
    \fn QGraphicsView::items(int x, int y) const

    This function is provided for convenience. It's equivalent to calling
    items(QPoint(\a x, \a y)).
*/

/*!
    \overload

    Returns a list of all the items that, depending on \a mode, are either
    contained by or intersect with \a rect. \a rect is in viewport
    coordinates.

    The default value for \a mode is Qt::IntersectsItemShape; all items whose
    exact shape intersects with or is contained by \a rect are returned.

    The items are sorted in descending stacking order (i.e., the first item in
    the returned list is the uppermost item).

    \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsView::items(const QRect &rect, Qt::ItemSelectionMode mode) const
{
    Q_D(const QGraphicsView);
    if (!d->scene)
        return QList<QGraphicsItem *>();
    return d->scene->items(mapToScene(rect), mode, Qt::DescendingOrder, viewportTransform());
}

/*!
    \fn QList<QGraphicsItem *> QGraphicsView::items(int x, int y, int w, int h, Qt::ItemSelectionMode mode) const
    \since 4.3

    This convenience function is equivalent to calling items(QRectF(\a x, \a
    y, \a w, \a h), \a mode).
*/

/*!
    \overload

    Returns a list of all the items that, depending on \a mode, are either
    contained by or intersect with \a polygon. \a polygon is in viewport
    coordinates.

    The default value for \a mode is Qt::IntersectsItemShape; all items whose
    exact shape intersects with or is contained by \a polygon are returned.

    The items are sorted by descending stacking order (i.e., the first item in
    the returned list is the uppermost item).

    \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsView::items(const QPolygon &polygon, Qt::ItemSelectionMode mode) const
{
    Q_D(const QGraphicsView);
    if (!d->scene)
        return QList<QGraphicsItem *>();
    return d->scene->items(mapToScene(polygon), mode, Qt::DescendingOrder, viewportTransform());
}

/*!
    \overload

    Returns a list of all the items that, depending on \a mode, are either
    contained by or intersect with \a path. \a path is in viewport
    coordinates.

    The default value for \a mode is Qt::IntersectsItemShape; all items whose
    exact shape intersects with or is contained by \a path are returned.

    \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsView::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
{
    Q_D(const QGraphicsView);
    if (!d->scene)
        return QList<QGraphicsItem *>();
    return d->scene->items(mapToScene(path), mode, Qt::DescendingOrder, viewportTransform());
}

/*!
    Returns the item at position \a pos, which is in viewport coordinates.
    If there are several items at this position, this function returns
    the topmost item.

    Example:

    \snippet code/src_gui_graphicsview_qgraphicsview.cpp 6

    \sa items(), {QGraphicsItem#Sorting}{Sorting}
*/
QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const
{
    Q_D(const QGraphicsView);
    if (!d->scene)
        return nullptr;
    const QList<QGraphicsItem *> itemsAtPos = items(pos);
    return itemsAtPos.isEmpty() ? 0 : itemsAtPos.first();
}

/*!
    \overload
    \fn QGraphicsItem *QGraphicsView::itemAt(int x, int y) const

    This function is provided for convenience. It's equivalent to
    calling itemAt(QPoint(\a x, \a y)).
*/

/*!
    Returns the viewport coordinate \a point mapped to scene coordinates.

    Note: It can be useful to map the whole rectangle covered by the pixel at
    \a point instead of the point itself. To do this, you can call
    mapToScene(QRect(\a point, QSize(2, 2))).

    \sa mapFromScene()
*/
QPointF QGraphicsView::mapToScene(const QPoint &point) const
{
    Q_D(const QGraphicsView);
    QPointF p = point;
    p.rx() += d->horizontalScroll();
    p.ry() += d->verticalScroll();
    return d->identityMatrix ? p : d->matrix.inverted().map(p);
}

/*!
    \fn QGraphicsView::mapToScene(int x, int y) const

    This function is provided for convenience. It's equivalent to calling
    mapToScene(QPoint(\a x, \a y)).
*/

/*!
    Returns the viewport rectangle \a rect mapped to a scene coordinate
    polygon.

    \sa mapFromScene()
*/
QPolygonF QGraphicsView::mapToScene(const QRect &rect) const
{
    Q_D(const QGraphicsView);
    if (!rect.isValid())
        return QPolygonF();

    QPointF scrollOffset(d->horizontalScroll(), d->verticalScroll());
    QRect r = rect.adjusted(0, 0, 1, 1);
    QPointF tl = scrollOffset + r.topLeft();
    QPointF tr = scrollOffset + r.topRight();
    QPointF br = scrollOffset + r.bottomRight();
    QPointF bl = scrollOffset + r.bottomLeft();

    QPolygonF poly(4);
    if (!d->identityMatrix) {
        QTransform x = d->matrix.inverted();
        poly[0] = x.map(tl);
        poly[1] = x.map(tr);
        poly[2] = x.map(br);
        poly[3] = x.map(bl);
    } else {
        poly[0] = tl;
        poly[1] = tr;
        poly[2] = br;
        poly[3] = bl;
    }
    return poly;
}

/*!
    \fn QGraphicsView::mapToScene(int x, int y, int w, int h) const

    This function is provided for convenience. It's equivalent to calling
    mapToScene(QRect(\a x, \a y, \a w, \a h)).
*/

/*!
    Returns the viewport polygon \a polygon mapped to a scene coordinate
    polygon.

    \sa mapFromScene()
*/
QPolygonF QGraphicsView::mapToScene(const QPolygon &polygon) const
{
    QPolygonF poly;
    poly.reserve(polygon.count());
    for (const QPoint &point : polygon)
        poly << mapToScene(point);
    return poly;
}

/*!
    Returns the viewport painter path \a path mapped to a scene coordinate
    painter path.

    \sa mapFromScene()
*/
QPainterPath QGraphicsView::mapToScene(const QPainterPath &path) const
{
    Q_D(const QGraphicsView);
    QTransform matrix = QTransform::fromTranslate(d->horizontalScroll(), d->verticalScroll());
    matrix *= d->matrix.inverted();
    return matrix.map(path);
}

/*!
    Returns the scene coordinate \a point to viewport coordinates.

    \sa mapToScene()
*/
QPoint QGraphicsView::mapFromScene(const QPointF &point) const
{
    Q_D(const QGraphicsView);
    QPointF p = d->identityMatrix ? point : d->matrix.map(point);
    p.rx() -= d->horizontalScroll();
    p.ry() -= d->verticalScroll();
    return p.toPoint();
}

/*!
    \fn QGraphicsView::mapFromScene(qreal x, qreal y) const

    This function is provided for convenience. It's equivalent to
    calling mapFromScene(QPointF(\a x, \a y)).
*/

/*!
    Returns the scene rectangle \a rect to a viewport coordinate
    polygon.

    \sa mapToScene()
*/
QPolygon QGraphicsView::mapFromScene(const QRectF &rect) const
{
    Q_D(const QGraphicsView);
    QPointF tl;
    QPointF tr;
    QPointF br;
    QPointF bl;
    if (!d->identityMatrix) {
        const QTransform &x = d->matrix;
        tl = x.map(rect.topLeft());
        tr = x.map(rect.topRight());
        br = x.map(rect.bottomRight());
        bl = x.map(rect.bottomLeft());
    } else {
        tl = rect.topLeft();
        tr = rect.topRight();
        br = rect.bottomRight();
        bl = rect.bottomLeft();
    }
    QPointF scrollOffset(d->horizontalScroll(), d->verticalScroll());
    tl -= scrollOffset;
    tr -= scrollOffset;
    br -= scrollOffset;
    bl -= scrollOffset;

    QPolygon poly(4);
    poly[0] = tl.toPoint();
    poly[1] = tr.toPoint();
    poly[2] = br.toPoint();
    poly[3] = bl.toPoint();
    return poly;
}

/*!
    \fn QGraphicsView::mapFromScene(qreal x, qreal y, qreal w, qreal h) const

    This function is provided for convenience. It's equivalent to
    calling mapFromScene(QRectF(\a x, \a y, \a w, \a h)).
*/

/*!
    Returns the scene coordinate polygon \a polygon to a viewport coordinate
    polygon.

    \sa mapToScene()
*/
QPolygon QGraphicsView::mapFromScene(const QPolygonF &polygon) const
{
    QPolygon poly;
    poly.reserve(polygon.count());
    for (const QPointF &point : polygon)
        poly << mapFromScene(point);
    return poly;
}

/*!
    Returns the scene coordinate painter path \a path to a viewport coordinate
    painter path.

    \sa mapToScene()
*/
QPainterPath QGraphicsView::mapFromScene(const QPainterPath &path) const
{
    Q_D(const QGraphicsView);
    QTransform matrix = d->matrix;
    matrix *= QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
    return matrix.map(path);
}

/*!
    \reimp
*/
QVariant QGraphicsView::inputMethodQuery(Qt::InputMethodQuery query) const
{
    Q_D(const QGraphicsView);
    if (!d->scene)
        return QVariant();

    QVariant value = d->scene->inputMethodQuery(query);
    if (value.userType() == QMetaType::QRectF)
        value = d->mapRectFromScene(value.toRectF());
    else if (value.userType() == QMetaType::QPointF)
        value = mapFromScene(value.toPointF());
    else if (value.userType() == QMetaType::QRect)
        value = d->mapRectFromScene(value.toRect()).toRect();
    else if (value.userType() == QMetaType::QPoint)
        value = mapFromScene(value.toPoint());
    return value;
}

/*!
    \property QGraphicsView::backgroundBrush
    \brief the background brush of the scene.

    This property sets the background brush for the scene in this view. It is
    used to override the scene's own background, and defines the behavior of
    drawBackground(). To provide custom background drawing for this view, you
    can reimplement drawBackground() instead.

    By default, this property contains a brush with the Qt::NoBrush pattern.

    \sa QGraphicsScene::backgroundBrush, foregroundBrush
*/
QBrush QGraphicsView::backgroundBrush() const
{
    Q_D(const QGraphicsView);
    return d->backgroundBrush;
}
void QGraphicsView::setBackgroundBrush(const QBrush &brush)
{
    Q_D(QGraphicsView);
    d->backgroundBrush = brush;
    d->updateAll();

    if (d->cacheMode & CacheBackground) {
        // Invalidate the background pixmap
        d->mustResizeBackgroundPixmap = true;
    }
}

/*!
    \property QGraphicsView::foregroundBrush
    \brief the foreground brush of the scene.

    This property sets the foreground brush for the scene in this view. It is
    used to override the scene's own foreground, and defines the behavior of
    drawForeground(). To provide custom foreground drawing for this view, you
    can reimplement drawForeground() instead.

    By default, this property contains a brush with the Qt::NoBrush pattern.

    \sa QGraphicsScene::foregroundBrush, backgroundBrush
*/
QBrush QGraphicsView::foregroundBrush() const
{
    Q_D(const QGraphicsView);
    return d->foregroundBrush;
}
void QGraphicsView::setForegroundBrush(const QBrush &brush)
{
    Q_D(QGraphicsView);
    d->foregroundBrush = brush;
    d->updateAll();
}

/*!
    Schedules an update of the scene rectangles \a rects.

    \sa QGraphicsScene::changed()
*/
void QGraphicsView::updateScene(const QList<QRectF> &rects)
{
    // ### Note: Since 4.5, this slot is only called if the user explicitly
    // establishes a connection between the scene and the view, as the scene
    // and view are no longer connected. We need to keep it working (basically
    // leave it as it is), but the new delivery path is through
    // QGraphicsScenePrivate::itemUpdate().
    Q_D(QGraphicsView);
    if (d->fullUpdatePending || d->viewportUpdateMode == QGraphicsView::NoViewportUpdate)
        return;

    // Extract and reset dirty scene rect info.
    QVector<QRect> dirtyViewportRects;
    dirtyViewportRects.reserve(d->dirtyRegion.rectCount() + rects.count());
    for (const QRect &dirtyRect : d->dirtyRegion)
        dirtyViewportRects += dirtyRect;
    d->dirtyRegion = QRegion();
    d->dirtyBoundingRect = QRect();

    bool fullUpdate = !d->accelerateScrolling || d->viewportUpdateMode == QGraphicsView::FullViewportUpdate;
    bool boundingRectUpdate = (d->viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate)
                              || (d->viewportUpdateMode == QGraphicsView::SmartViewportUpdate
                                  && ((dirtyViewportRects.size() + rects.size()) >= QGRAPHICSVIEW_REGION_RECT_THRESHOLD));

    QRegion updateRegion;
    QRect boundingRect;
    QRect viewportRect = viewport()->rect();
    bool redraw = false;
    QTransform transform = viewportTransform();

    // Convert scene rects to viewport rects.
    for (const QRectF &rect : rects) {
        QRect xrect = transform.mapRect(rect).toAlignedRect();
        if (!(d->optimizationFlags & DontAdjustForAntialiasing))
            xrect.adjust(-2, -2, 2, 2);
        else
            xrect.adjust(-1, -1, 1, 1);
        if (!viewportRect.intersects(xrect))
            continue;
        dirtyViewportRects << xrect;
    }

    for (const QRect &rect : qAsConst(dirtyViewportRects)) {
        // Add the exposed rect to the update region. In rect update
        // mode, we only count the bounding rect of items.
        if (!boundingRectUpdate) {
            updateRegion += rect;
        } else {
            boundingRect |= rect;
        }
        redraw = true;
        if (fullUpdate) {
            // If fullUpdate is true and we found a visible dirty rect,
            // we're done.
            break;
        }
    }

    if (!redraw)
        return;

    if (fullUpdate)
        viewport()->update();
    else if (boundingRectUpdate)
        viewport()->update(boundingRect);
    else
        viewport()->update(updateRegion);
}

/*!
    Notifies QGraphicsView that the scene's scene rect has changed.  \a rect
    is the new scene rect. If the view already has an explicitly set scene
    rect, this function does nothing.

    \sa sceneRect, QGraphicsScene::sceneRectChanged()
*/
void QGraphicsView::updateSceneRect(const QRectF &rect)
{
    Q_D(QGraphicsView);
    if (!d->hasSceneRect) {
        d->sceneRect = rect;
        d->recalculateContentSize();
    }
}

/*!
    This slot is called by QAbstractScrollArea after setViewport() has been
    called. Reimplement this function in a subclass of QGraphicsView to
    initialize the new viewport \a widget before it is used.

    \sa setViewport()
*/
void QGraphicsView::setupViewport(QWidget *widget)
{
    Q_D(QGraphicsView);

    if (!widget) {
        qWarning("QGraphicsView::setupViewport: cannot initialize null widget");
        return;
    }

    const bool isGLWidget = widget->inherits("QGLWidget") || widget->inherits("QOpenGLWidget");

    d->accelerateScrolling = !(isGLWidget);

    widget->setFocusPolicy(Qt::StrongFocus);

    if (!isGLWidget) {
        // autoFillBackground enables scroll acceleration.
        widget->setAutoFillBackground(true);
    }

    // We are only interested in mouse tracking if items
    // accept hover events or use non-default cursors or if
    // AnchorUnderMouse is used as transformation or resize anchor.
    if ((d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents
                     || !d->scene->d_func()->allItemsUseDefaultCursor))
        || d->transformationAnchor == AnchorUnderMouse
        || d->resizeAnchor == AnchorUnderMouse) {
        widget->setMouseTracking(true);
    }

    // enable touch events if any items is interested in them
    if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents)
        widget->setAttribute(Qt::WA_AcceptTouchEvents);

#ifndef QT_NO_GESTURES
    if (d->scene) {
        const auto gestures = d->scene->d_func()->grabbedGestures.keys();
        for (Qt::GestureType gesture : gestures)
            widget->grabGesture(gesture);
    }
#endif

    widget->setAcceptDrops(acceptDrops());
}

/*!
    \reimp
*/
bool QGraphicsView::event(QEvent *event)
{
    Q_D(QGraphicsView);

    if (d->sceneInteractionAllowed) {
        switch (event->type()) {
        case QEvent::ShortcutOverride:
            if (d->scene)
                return QCoreApplication::sendEvent(d->scene, event);
            break;
        case QEvent::KeyPress:
            if (d->scene) {
                QKeyEvent *k = static_cast<QKeyEvent *>(event);
                if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
                    // Send the key events to the scene. This will invoke the
                    // scene's tab focus handling, and if the event is
                    // accepted, we return (prevent further event delivery),
                    // and the base implementation will call QGraphicsView's
                    // focusNextPrevChild() function. If the event is ignored,
                    // we fall back to standard tab focus handling.
                    QCoreApplication::sendEvent(d->scene, event);
                    if (event->isAccepted())
                        return true;
                    // Ensure the event doesn't propagate just because the
                    // scene ignored it. If the event propagates, then tab
                    // handling will be called twice (this and parent).
                    event->accept();
                }
            }
            break;
        default:
            break;
        }
    }

    return QAbstractScrollArea::event(event);
}

/*!
    \reimp
*/
bool QGraphicsView::viewportEvent(QEvent *event)
{
    Q_D(QGraphicsView);
    if (!d->scene)
        return QAbstractScrollArea::viewportEvent(event);

    switch (event->type()) {
    case QEvent::Enter:
        QCoreApplication::sendEvent(d->scene, event);
        break;
    case QEvent::WindowActivate:
        QCoreApplication::sendEvent(d->scene, event);
        break;
    case QEvent::WindowDeactivate:
        // ### This is a temporary fix for until we get proper mouse
        // grab events. mouseGrabberItem should be set to 0 if we lose
        // the mouse grab.
        // Remove all popups when the scene loses focus.
        if (!d->scene->d_func()->popupWidgets.isEmpty())
            d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.constFirst());
        QCoreApplication::sendEvent(d->scene, event);
        break;
    case QEvent::Show:
        if (d->scene && isActiveWindow()) {
            QEvent windowActivate(QEvent::WindowActivate);
            QCoreApplication::sendEvent(d->scene, &windowActivate);
        }
        break;
    case QEvent::Hide:
        // spontaneous event will generate a WindowDeactivate.
        if (!event->spontaneous() && d->scene && isActiveWindow()) {
            QEvent windowDeactivate(QEvent::WindowDeactivate);
            QCoreApplication::sendEvent(d->scene, &windowDeactivate);
        }
        break;
    case QEvent::Leave: {
        // ### This is a temporary fix for until we get proper mouse grab
        // events. activeMouseGrabberItem should be set to 0 if we lose the
        // mouse grab.
        if ((QApplication::activePopupWidget() && QApplication::activePopupWidget() != window())
            || (QApplication::activeModalWidget() && QApplication::activeModalWidget() != window())
            || (QApplication::activeWindow() != window())) {
            if (!d->scene->d_func()->popupWidgets.isEmpty())
                d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.constFirst());
        }
        d->useLastMouseEvent = false;
        // a hack to pass a viewport pointer to the scene inside the leave event
        Q_ASSERT(event->d == nullptr);
        QScopedValueRollback<QEventPrivate *> rb(event->d);
        event->d = reinterpret_cast<QEventPrivate *>(viewport());
        QCoreApplication::sendEvent(d->scene, event);
        break;
    }
#ifndef QT_NO_TOOLTIP
    case QEvent::ToolTip: {
        QHelpEvent *toolTip = static_cast<QHelpEvent *>(event);
        QGraphicsSceneHelpEvent helpEvent(QEvent::GraphicsSceneHelp);
        helpEvent.setWidget(viewport());
        helpEvent.setScreenPos(toolTip->globalPos());
        helpEvent.setScenePos(mapToScene(toolTip->pos()));
        QCoreApplication::sendEvent(d->scene, &helpEvent);
        toolTip->setAccepted(helpEvent.isAccepted());
        return true;
    }
#endif
    case QEvent::Paint:
        // Reset full update
        d->fullUpdatePending = false;
        d->dirtyScrollOffset = QPoint();
        if (d->scene) {
            // Check if this view reimplements the updateScene slot; if it
            // does, we can't do direct update delivery and have to fall back
            // to connecting the changed signal.
            if (!d->updateSceneSlotReimplementedChecked) {
                d->updateSceneSlotReimplementedChecked = true;
                const QMetaObject *mo = metaObject();
                if (mo != &QGraphicsView::staticMetaObject) {
                    if (mo->indexOfSlot("updateScene(QList<QRectF>)")
                        != QGraphicsView::staticMetaObject.indexOfSlot("updateScene(QList<QRectF>)")) {
                        connect(d->scene, SIGNAL(changed(QList<QRectF>)),
                                this, SLOT(updateScene(QList<QRectF>)));
                    }
                }
            }
        }
        break;
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate:
    case QEvent::TouchEnd:
    {
        if (!isEnabled())
            return false;

        if (d->scene && d->sceneInteractionAllowed) {
            // Convert and deliver the touch event to the scene.
            QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
            touchEvent->setTarget(viewport());
            QGraphicsViewPrivate::translateTouchEvent(d, touchEvent);
            QCoreApplication::sendEvent(d->scene, touchEvent);
        } else {
            event->ignore();
        }

        return true;
    }
#ifndef QT_NO_GESTURES
    case QEvent::Gesture:
    case QEvent::GestureOverride:
    {
        if (!isEnabled())
            return false;

        if (d->scene && d->sceneInteractionAllowed) {
            QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(event);
            gestureEvent->setWidget(viewport());
            QCoreApplication::sendEvent(d->scene, gestureEvent);
        }
        return true;
    }
#endif // QT_NO_GESTURES
    default:
        break;
    }

    return QAbstractScrollArea::viewportEvent(event);
}

#ifndef QT_NO_CONTEXTMENU
/*!
    \reimp
*/
void QGraphicsView::contextMenuEvent(QContextMenuEvent *event)
{
    Q_D(QGraphicsView);
    if (!d->scene || !d->sceneInteractionAllowed)
        return;

    d->mousePressViewPoint = event->pos();
    d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
    d->mousePressScreenPoint = event->globalPos();
    d->lastMouseMoveScenePoint = d->mousePressScenePoint;
    d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;

    QGraphicsSceneContextMenuEvent contextEvent(QEvent::GraphicsSceneContextMenu);
    contextEvent.setWidget(viewport());
    contextEvent.setScenePos(d->mousePressScenePoint);
    contextEvent.setScreenPos(d->mousePressScreenPoint);
    contextEvent.setModifiers(event->modifiers());
    contextEvent.setReason((QGraphicsSceneContextMenuEvent::Reason)(event->reason()));
    contextEvent.setAccepted(event->isAccepted());
    QCoreApplication::sendEvent(d->scene, &contextEvent);
    event->setAccepted(contextEvent.isAccepted());
}
#endif // QT_NO_CONTEXTMENU

#if QT_CONFIG(draganddrop)
/*!
    \reimp
*/
void QGraphicsView::dropEvent(QDropEvent *event)
{
    Q_D(QGraphicsView);
    if (!d->scene || !d->sceneInteractionAllowed)
        return;

    // Generate a scene event.
    QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDrop);
    d->populateSceneDragDropEvent(&sceneEvent, event);

    // Send it to the scene.
    QCoreApplication::sendEvent(d->scene, &sceneEvent);

    // Accept the originating event if the scene accepted the scene event.
    event->setAccepted(sceneEvent.isAccepted());
    if (sceneEvent.isAccepted())
        event->setDropAction(sceneEvent.dropAction());

    delete d->lastDragDropEvent;
    d->lastDragDropEvent = nullptr;
}

/*!
    \reimp
*/
void QGraphicsView::dragEnterEvent(QDragEnterEvent *event)
{
    Q_D(QGraphicsView);
    if (!d->scene || !d->sceneInteractionAllowed)
        return;

    // Disable replaying of mouse move events.
    d->useLastMouseEvent = false;

    // Generate a scene event.
    QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDragEnter);
    d->populateSceneDragDropEvent(&sceneEvent, event);

    // Store it for later use.
    d->storeDragDropEvent(&sceneEvent);

    // Send it to the scene.
    QCoreApplication::sendEvent(d->scene, &sceneEvent);

    // Accept the originating event if the scene accepted the scene event.
    if (sceneEvent.isAccepted()) {
        event->setAccepted(true);
        event->setDropAction(sceneEvent.dropAction());
    }
}

/*!
    \reimp
*/
void QGraphicsView::dragLeaveEvent(QDragLeaveEvent *event)
{
    Q_D(QGraphicsView);
    if (!d->scene || !d->sceneInteractionAllowed)
        return;
    if (!d->lastDragDropEvent) {
        qWarning("QGraphicsView::dragLeaveEvent: drag leave received before drag enter");
        return;
    }

    // Generate a scene event.
    QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDragLeave);
    sceneEvent.setScenePos(d->lastDragDropEvent->scenePos());
    sceneEvent.setScreenPos(d->lastDragDropEvent->screenPos());
    sceneEvent.setButtons(d->lastDragDropEvent->buttons());
    sceneEvent.setModifiers(d->lastDragDropEvent->modifiers());
    sceneEvent.setPossibleActions(d->lastDragDropEvent->possibleActions());
    sceneEvent.setProposedAction(d->lastDragDropEvent->proposedAction());
    sceneEvent.setDropAction(d->lastDragDropEvent->dropAction());
    sceneEvent.setMimeData(d->lastDragDropEvent->mimeData());
    sceneEvent.setWidget(d->lastDragDropEvent->widget());
    sceneEvent.setSource(d->lastDragDropEvent->source());
    delete d->lastDragDropEvent;
    d->lastDragDropEvent = nullptr;

    // Send it to the scene.
    QCoreApplication::sendEvent(d->scene, &sceneEvent);

    // Accept the originating event if the scene accepted the scene event.
    if (sceneEvent.isAccepted())
        event->setAccepted(true);
}

/*!
    \reimp
*/
void QGraphicsView::dragMoveEvent(QDragMoveEvent *event)
{
    Q_D(QGraphicsView);
    if (!d->scene || !d->sceneInteractionAllowed)
        return;

    // Generate a scene event.
    QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDragMove);
    d->populateSceneDragDropEvent(&sceneEvent, event);

    // Store it for later use.
    d->storeDragDropEvent(&sceneEvent);

    // Send it to the scene.
    QCoreApplication::sendEvent(d->scene, &sceneEvent);

    // Ignore the originating event if the scene ignored the scene event.
    event->setAccepted(sceneEvent.isAccepted());
    if (sceneEvent.isAccepted())
        event->setDropAction(sceneEvent.dropAction());
}
#endif // QT_CONFIG(draganddrop)

/*!
    \reimp
*/
void QGraphicsView::focusInEvent(QFocusEvent *event)
{
    Q_D(QGraphicsView);
    d->updateInputMethodSensitivity();
    QAbstractScrollArea::focusInEvent(event);
    if (d->scene)
        QCoreApplication::sendEvent(d->scene, event);
    // Pass focus on if the scene cannot accept focus.
    if (!d->scene || !event->isAccepted())
        QAbstractScrollArea::focusInEvent(event);
}

/*!
    \reimp
*/
bool QGraphicsView::focusNextPrevChild(bool next)
{
    return QAbstractScrollArea::focusNextPrevChild(next);
}

/*!
    \reimp
*/
void QGraphicsView::focusOutEvent(QFocusEvent *event)
{
    Q_D(QGraphicsView);
    QAbstractScrollArea::focusOutEvent(event);
    if (d->scene)
        QCoreApplication::sendEvent(d->scene, event);
}

/*!
    \reimp
*/
void QGraphicsView::keyPressEvent(QKeyEvent *event)
{
    Q_D(QGraphicsView);
    if (!d->scene || !d->sceneInteractionAllowed) {
        QAbstractScrollArea::keyPressEvent(event);
        return;
    }
    QCoreApplication::sendEvent(d->scene, event);
    if (!event->isAccepted())
        QAbstractScrollArea::keyPressEvent(event);
}

/*!
    \reimp
*/
void QGraphicsView::keyReleaseEvent(QKeyEvent *event)
{
    Q_D(QGraphicsView);
    if (!d->scene || !d->sceneInteractionAllowed)
        return;
    QCoreApplication::sendEvent(d->scene, event);
    if (!event->isAccepted())
        QAbstractScrollArea::keyReleaseEvent(event);
}

/*!
    \reimp
*/
void QGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
{
    Q_D(QGraphicsView);
    if (!d->scene || !d->sceneInteractionAllowed)
        return;

    d->storeMouseEvent(event);
    d->mousePressViewPoint = event->pos();
    d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
    d->mousePressScreenPoint = event->globalPos();
    d->lastMouseMoveScenePoint = d->mousePressScenePoint;
    d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;
    d->mousePressButton = event->button();

    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseDoubleClick);
    mouseEvent.setWidget(viewport());
    mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
    mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
    mouseEvent.setScenePos(mapToScene(d->mousePressViewPoint));
    mouseEvent.setScreenPos(d->mousePressScreenPoint);
    mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
    mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
    mouseEvent.setButtons(event->buttons());
    mouseEvent.setAccepted(false);
    mouseEvent.setButton(event->button());
    mouseEvent.setModifiers(event->modifiers());
    mouseEvent.setSource(event->source());
    mouseEvent.setFlags(event->flags());
    if (event->spontaneous())
        qt_sendSpontaneousEvent(d->scene, &mouseEvent);
    else
        QCoreApplication::sendEvent(d->scene, &mouseEvent);

    // Update the original mouse event accepted state.
    const bool isAccepted = mouseEvent.isAccepted();
    event->setAccepted(isAccepted);

    // Update the last mouse event accepted state.
    d->lastMouseEvent.setAccepted(isAccepted);
}

/*!
    \reimp
*/
void QGraphicsView::mousePressEvent(QMouseEvent *event)
{
    Q_D(QGraphicsView);

    // Store this event for replaying, finding deltas, and for
    // scroll-dragging; even in non-interactive mode, scroll hand dragging is
    // allowed, so we store the event at the very top of this function.
    d->storeMouseEvent(event);
    d->lastMouseEvent.setAccepted(false);

    if (d->sceneInteractionAllowed) {
        // Store some of the event's button-down data.
        d->mousePressViewPoint = event->pos();
        d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
        d->mousePressScreenPoint = event->globalPos();
        d->lastMouseMoveScenePoint = d->mousePressScenePoint;
        d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;
        d->mousePressButton = event->button();

        if (d->scene) {
            // Convert and deliver the mouse event to the scene.
            QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
            mouseEvent.setWidget(viewport());
            mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
            mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
            mouseEvent.setScenePos(d->mousePressScenePoint);
            mouseEvent.setScreenPos(d->mousePressScreenPoint);
            mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
            mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
            mouseEvent.setButtons(event->buttons());
            mouseEvent.setButton(event->button());
            mouseEvent.setModifiers(event->modifiers());
            mouseEvent.setSource(event->source());
            mouseEvent.setFlags(event->flags());
            mouseEvent.setAccepted(false);
            if (event->spontaneous())
                qt_sendSpontaneousEvent(d->scene, &mouseEvent);
            else
                QCoreApplication::sendEvent(d->scene, &mouseEvent);

            // Update the original mouse event accepted state.
            bool isAccepted = mouseEvent.isAccepted();
            event->setAccepted(isAccepted);

            // Update the last mouse event accepted state.
            d->lastMouseEvent.setAccepted(isAccepted);

            if (isAccepted)
                return;
        }
    }

#if QT_CONFIG(rubberband)
    if (d->dragMode == QGraphicsView::RubberBandDrag && !d->rubberBanding) {
        if (d->sceneInteractionAllowed) {
            // Rubberbanding is only allowed in interactive mode.
            event->accept();
            d->rubberBanding = true;
            d->rubberBandRect = QRect();
            if (d->scene) {
                bool extendSelection = (event->modifiers() & Qt::ControlModifier) != 0;

                if (extendSelection) {
                    d->rubberBandSelectionOperation = Qt::AddToSelection;
                } else {
                    d->rubberBandSelectionOperation = Qt::ReplaceSelection;
                    d->scene->clearSelection();
                }
            }
        }
    } else
#endif
        if (d->dragMode == QGraphicsView::ScrollHandDrag && event->button() == Qt::LeftButton) {
            // Left-button press in scroll hand mode initiates hand scrolling.
            event->accept();
            d->handScrolling = true;
            d->handScrollMotions = 0;
#ifndef QT_NO_CURSOR
            viewport()->setCursor(Qt::ClosedHandCursor);
#endif
        }
}

/*!
    \reimp
*/
void QGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    Q_D(QGraphicsView);

    if (d->dragMode == QGraphicsView::ScrollHandDrag) {
        if (d->handScrolling) {
            QScrollBar *hBar = horizontalScrollBar();
            QScrollBar *vBar = verticalScrollBar();
            QPoint delta = event->pos() - d->lastMouseEvent.pos();
            hBar->setValue(hBar->value() + (isRightToLeft() ? delta.x() : -delta.x()));
            vBar->setValue(vBar->value() - delta.y());

            // Detect how much we've scrolled to disambiguate scrolling from
            // clicking.
            ++d->handScrollMotions;
        }
    }

    d->mouseMoveEventHandler(event);
}

/*!
    \reimp
*/
void QGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
    Q_D(QGraphicsView);

#if QT_CONFIG(rubberband)
    if (d->dragMode == QGraphicsView::RubberBandDrag && d->sceneInteractionAllowed && !event->buttons()) {
        d->clearRubberBand();
    } else
#endif
    if (d->dragMode == QGraphicsView::ScrollHandDrag && event->button() == Qt::LeftButton) {
#ifndef QT_NO_CURSOR
        // Restore the open hand cursor. ### There might be items
        // under the mouse that have a valid cursor at this time, so
        // we could repeat the steps from mouseMoveEvent().
        viewport()->setCursor(Qt::OpenHandCursor);
#endif
        d->handScrolling = false;

        if (d->scene && d->sceneInteractionAllowed && !d->lastMouseEvent.isAccepted() && d->handScrollMotions <= 6) {
            // If we've detected very little motion during the hand drag, and
            // no item accepted the last event, we'll interpret that as a
            // click to the scene, and reset the selection.
            d->scene->clearSelection();
        }
    }

    d->storeMouseEvent(event);

    if (!d->sceneInteractionAllowed)
        return;

    if (!d->scene)
        return;

    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
    mouseEvent.setWidget(viewport());
    mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
    mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
    mouseEvent.setScenePos(mapToScene(event->pos()));
    mouseEvent.setScreenPos(event->globalPos());
    mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
    mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
    mouseEvent.setButtons(event->buttons());
    mouseEvent.setButton(event->button());
    mouseEvent.setModifiers(event->modifiers());
    mouseEvent.setSource(event->source());
    mouseEvent.setFlags(event->flags());
    mouseEvent.setAccepted(false);
    if (event->spontaneous())
        qt_sendSpontaneousEvent(d->scene, &mouseEvent);
    else
        QCoreApplication::sendEvent(d->scene, &mouseEvent);

    // Update the last mouse event selected state.
    d->lastMouseEvent.setAccepted(mouseEvent.isAccepted());

#ifndef QT_NO_CURSOR
    if (mouseEvent.isAccepted() && mouseEvent.buttons() == 0 && viewport()->testAttribute(Qt::WA_SetCursor)) {
        // The last mouse release on the viewport will trigger clearing the cursor.
        d->_q_unsetViewportCursor();
    }
#endif
}

#if QT_CONFIG(wheelevent)
/*!
    \reimp
*/
void QGraphicsView::wheelEvent(QWheelEvent *event)
{
    Q_D(QGraphicsView);
    if (!d->scene || !d->sceneInteractionAllowed) {
        QAbstractScrollArea::wheelEvent(event);
        return;
    }

    event->ignore();

    QGraphicsSceneWheelEvent wheelEvent(QEvent::GraphicsSceneWheel);
    wheelEvent.setWidget(viewport());
    wheelEvent.setScenePos(mapToScene(event->position().toPoint()));
    wheelEvent.setScreenPos(event->globalPosition().toPoint());
    wheelEvent.setButtons(event->buttons());
    wheelEvent.setModifiers(event->modifiers());
    const bool horizontal = qAbs(event->angleDelta().x()) > qAbs(event->angleDelta().y());
    wheelEvent.setDelta(horizontal ? event->angleDelta().x() : event->angleDelta().y());
    wheelEvent.setOrientation(horizontal ? Qt::Horizontal : Qt::Vertical);
    wheelEvent.setAccepted(false);
    QCoreApplication::sendEvent(d->scene, &wheelEvent);
    event->setAccepted(wheelEvent.isAccepted());
    if (!event->isAccepted())
        QAbstractScrollArea::wheelEvent(event);
}
#endif // QT_CONFIG(wheelevent)

/*!
    \reimp
*/
void QGraphicsView::paintEvent(QPaintEvent *event)
{
    Q_D(QGraphicsView);
    if (!d->scene) {
        QAbstractScrollArea::paintEvent(event);
        return;
    }

    // Set up painter state protection.
    d->scene->d_func()->painterStateProtection = !(d->optimizationFlags & DontSavePainterState);

    // Determine the exposed region
    d->exposedRegion = event->region();
    QRectF exposedSceneRect = mapToScene(d->exposedRegion.boundingRect()).boundingRect();

    // Set up the painter
    QPainter painter(viewport());
#if QT_CONFIG(rubberband)
    if (d->rubberBanding && !d->rubberBandRect.isEmpty())
        painter.save();
#endif
    // Set up render hints
    painter.setRenderHints(painter.renderHints(), false);
    painter.setRenderHints(d->renderHints, true);

    // Set up viewport transform
    const bool viewTransformed = isTransformed();
    if (viewTransformed)
        painter.setWorldTransform(viewportTransform());
    const QTransform viewTransform = painter.worldTransform();

    // Draw background
    if (d->cacheMode & CacheBackground) {
        // Recreate the background pixmap, and flag the whole background as
        // exposed.
        if (d->mustResizeBackgroundPixmap) {
            const qreal dpr = d->viewport->devicePixelRatioF();
            d->backgroundPixmap = QPixmap(viewport()->size() * dpr);
            d->backgroundPixmap.setDevicePixelRatio(dpr);
            QBrush bgBrush = viewport()->palette().brush(viewport()->backgroundRole());
            if (!bgBrush.isOpaque())
                d->backgroundPixmap.fill(Qt::transparent);
            QPainter p(&d->backgroundPixmap);
            p.fillRect(0, 0, d->backgroundPixmap.width(), d->backgroundPixmap.height(), bgBrush);
            d->backgroundPixmapExposed = QRegion(viewport()->rect());
            d->mustResizeBackgroundPixmap = false;
        }

        // Redraw exposed areas
        if (!d->backgroundPixmapExposed.isEmpty()) {
            QPainter backgroundPainter(&d->backgroundPixmap);
            backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip);
            if (viewTransformed)
                backgroundPainter.setTransform(viewTransform);
            QRectF backgroundExposedSceneRect = mapToScene(d->backgroundPixmapExposed.boundingRect()).boundingRect();
            drawBackground(&backgroundPainter, backgroundExposedSceneRect);
            d->backgroundPixmapExposed = QRegion();
        }

        // Blit the background from the background pixmap
        if (viewTransformed) {
            painter.setWorldTransform(QTransform());
            painter.drawPixmap(QPoint(), d->backgroundPixmap);
            painter.setWorldTransform(viewTransform);
        } else {
            painter.drawPixmap(QPoint(), d->backgroundPixmap);
        }
    } else {
        if (!(d->optimizationFlags & DontSavePainterState))
            painter.save();
        drawBackground(&painter, exposedSceneRect);
        if (!(d->optimizationFlags & DontSavePainterState))
            painter.restore();
    }

    // Items
    if (!(d->optimizationFlags & IndirectPainting)) {
        const quint32 oldRectAdjust = d->scene->d_func()->rectAdjust;
        if (d->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
            d->scene->d_func()->rectAdjust = 1;
        else
            d->scene->d_func()->rectAdjust = 2;
        d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : nullptr,
                                      &d->exposedRegion, viewport());
        d->scene->d_func()->rectAdjust = oldRectAdjust;
        // Make sure the painter's world transform is restored correctly when
        // drawing without painter state protection (DontSavePainterState).
        // We only change the worldTransform() so there's no need to do a full-blown
        // save() and restore(). Also note that we don't have to do this in case of
        // IndirectPainting (the else branch), because in that case we always save()
        // and restore() in QGraphicsScene::drawItems().
        if (!d->scene->d_func()->painterStateProtection)
            painter.setOpacity(1.0);
        painter.setWorldTransform(viewTransform);
    } else {
        // Make sure we don't have unpolished items before we draw
        if (!d->scene->d_func()->unpolishedItems.isEmpty())
            d->scene->d_func()->_q_polishItems();
        // We reset updateAll here (after we've issued polish events)
        // so that we can discard update requests coming from polishEvent().
        d->scene->d_func()->updateAll = false;

        // Find all exposed items
        bool allItems = false;
        QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems, viewTransform);
        if (!itemList.isEmpty()) {
            // Generate the style options.
            const int numItems = itemList.size();
            QGraphicsItem **itemArray = &itemList[0]; // Relies on QList internals, but is perfectly valid.
            QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
            QTransform transform(Qt::Uninitialized);
            for (int i = 0; i < numItems; ++i) {
                QGraphicsItem *item = itemArray[i];
                QGraphicsItemPrivate *itemd = item->d_ptr.data();
                itemd->initStyleOption(&styleOptionArray[i], viewTransform, d->exposedRegion, allItems);
                // Cache the item's area in view coordinates.
                // Note that we have to do this here in case the base class implementation
                // (QGraphicsScene::drawItems) is not called. If it is, we'll do this
                // operation twice, but that's the price one has to pay for using indirect
                // painting :-/.
                const QRectF brect = adjustedItemEffectiveBoundingRect(item);
                if (!itemd->itemIsUntransformable()) {
                    transform = item->sceneTransform();
                    if (viewTransformed)
                        transform *= viewTransform;
                } else {
                    transform = item->deviceTransform(viewTransform);
                }
                itemd->paintedViewBoundingRects.insert(d->viewport, transform.mapRect(brect).toRect());
            }
            // Draw the items.
            drawItems(&painter, numItems, itemArray, styleOptionArray);
            d->freeStyleOptionsArray(styleOptionArray);
        }
    }

    // Foreground
    drawForeground(&painter, exposedSceneRect);

#if QT_CONFIG(rubberband)
    // Rubberband
    if (d->rubberBanding && !d->rubberBandRect.isEmpty()) {
        painter.restore();
        QStyleOptionRubberBand option;
        option.initFrom(viewport());
        option.rect = d->rubberBandRect;
        option.shape = QRubberBand::Rectangle;

        QStyleHintReturnMask mask;
        if (viewport()->style()->styleHint(QStyle::SH_RubberBand_Mask, &option, viewport(), &mask)) {
            // painter clipping for masked rubberbands
            painter.setClipRegion(mask.region, Qt::IntersectClip);
        }

        viewport()->style()->drawControl(QStyle::CE_RubberBand, &option, &painter, viewport());
    }
#endif

    painter.end();

    // Restore painter state protection.
    d->scene->d_func()->painterStateProtection = true;
}

/*!
    \reimp
*/
void QGraphicsView::resizeEvent(QResizeEvent *event)
{
    Q_D(QGraphicsView);
    // Save the last center point - the resize may scroll the view, which
    // changes the center point.
    QPointF oldLastCenterPoint = d->lastCenterPoint;

    QAbstractScrollArea::resizeEvent(event);
    d->recalculateContentSize();

    // Restore the center point again.
    if (d->resizeAnchor == NoAnchor && !d->keepLastCenterPoint) {
        d->updateLastCenterPoint();
    } else {
        d->lastCenterPoint = oldLastCenterPoint;
    }
    d->centerView(d->resizeAnchor);
    d->keepLastCenterPoint = false;

    if (d->cacheMode & CacheBackground) {
        // Invalidate the background pixmap
        d->mustResizeBackgroundPixmap = true;
    }
}

/*!
    \reimp
*/
void QGraphicsView::scrollContentsBy(int dx, int dy)
{
    Q_D(QGraphicsView);
    d->dirtyScroll = true;
    if (d->transforming)
        return;
    if (isRightToLeft())
        dx = -dx;

    if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate) {
        if (d->viewportUpdateMode != QGraphicsView::FullViewportUpdate) {
            if (d->accelerateScrolling) {
#if QT_CONFIG(rubberband)
                // Update new and old rubberband regions
                if (!d->rubberBandRect.isEmpty()) {
                    QRegion rubberBandRegion(d->rubberBandRegion(viewport(), d->rubberBandRect));
                    rubberBandRegion += rubberBandRegion.translated(-dx, -dy);
                    viewport()->update(rubberBandRegion);
                }
#endif
                d->dirtyScrollOffset.rx() += dx;
                d->dirtyScrollOffset.ry() += dy;
                d->dirtyRegion.translate(dx, dy);
                viewport()->scroll(dx, dy);
            } else {
                d->updateAll();
            }
        } else {
            d->updateAll();
        }
    }

    d->updateLastCenterPoint();

    if (d->cacheMode & CacheBackground) {
        // Below, QPixmap::scroll() works in device pixels, while the delta values
        // and backgroundPixmapExposed are in device independent pixels.
        const qreal dpr = d->backgroundPixmap.devicePixelRatio();
        const qreal inverseDpr = qreal(1) / dpr;

        // Scroll the background pixmap
        QRegion exposed;
        if (!d->backgroundPixmap.isNull())
            d->backgroundPixmap.scroll(dx * dpr, dy * dpr, d->backgroundPixmap.rect(), &exposed);

        // Invalidate the background pixmap
        d->backgroundPixmapExposed.translate(dx, dy);
        const QRegion exposedScaled = QTransform::fromScale(inverseDpr, inverseDpr).map(exposed);
        d->backgroundPixmapExposed += exposedScaled;
    }

    // Always replay on scroll.
    if (d->sceneInteractionAllowed)
        d->replayLastMouseEvent();
}

/*!
    \reimp
*/
void QGraphicsView::showEvent(QShowEvent *event)
{
    Q_D(QGraphicsView);
    d->recalculateContentSize();
    d->centerView(d->transformationAnchor);
    QAbstractScrollArea::showEvent(event);
}

/*!
    \reimp
*/
void QGraphicsView::inputMethodEvent(QInputMethodEvent *event)
{
    Q_D(QGraphicsView);
    if (d->scene)
        QCoreApplication::sendEvent(d->scene, event);
}

/*!
    Draws the background of the scene using \a painter, before any items and
    the foreground are drawn. Reimplement this function to provide a custom
    background for this view.

    If all you want is to define a color, texture or gradient for the
    background, you can call setBackgroundBrush() instead.

    All painting is done in \e scene coordinates. \a rect is the exposed
    rectangle.

    The default implementation fills \a rect using the view's backgroundBrush.
    If no such brush is defined (the default), the scene's drawBackground()
    function is called instead.

    \sa drawForeground(), QGraphicsScene::drawBackground()
*/
void QGraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
{
    Q_D(QGraphicsView);
    if (d->scene && d->backgroundBrush.style() == Qt::NoBrush) {
        d->scene->drawBackground(painter, rect);
        return;
    }

    painter->fillRect(rect, d->backgroundBrush);
}

/*!
    Draws the foreground of the scene using \a painter, after the background
    and all items are drawn. Reimplement this function to provide a custom
    foreground for this view.

    If all you want is to define a color, texture or gradient for the
    foreground, you can call setForegroundBrush() instead.

    All painting is done in \e scene coordinates. \a rect is the exposed
    rectangle.

    The default implementation fills \a rect using the view's foregroundBrush.
    If no such brush is defined (the default), the scene's drawForeground()
    function is called instead.

    \sa drawBackground(), QGraphicsScene::drawForeground()
*/
void QGraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
{
    Q_D(QGraphicsView);
    if (d->scene && d->foregroundBrush.style() == Qt::NoBrush) {
        d->scene->drawForeground(painter, rect);
        return;
    }

    painter->fillRect(rect, d->foregroundBrush);
}

/*!
    \obsolete

    Draws the items \a items in the scene using \a painter, after the
    background and before the foreground are drawn. \a numItems is the number
    of items in \a items and options in \a options. \a options is a list of
    styleoptions; one for each item. Reimplement this function to provide
    custom item drawing for this view.

    The default implementation calls the scene's drawItems() function.

    Since Qt 4.6, this function is not called anymore unless
    the QGraphicsView::IndirectPainting flag is given as an Optimization
    flag.

    \sa drawForeground(), drawBackground(), QGraphicsScene::drawItems()
*/
void QGraphicsView::drawItems(QPainter *painter, int numItems,
                              QGraphicsItem *items[],
                              const QStyleOptionGraphicsItem options[])
{
    Q_D(QGraphicsView);
    if (d->scene) {
        QWidget *widget = painter->device() == viewport() ? viewport() : nullptr;
        d->scene->drawItems(painter, numItems, items, options, widget);
    }
}

/*!
    Returns the current transformation matrix for the view. If no current
    transformation is set, the identity matrix is returned.

    \sa setTransform(), rotate(), scale(), shear(), translate()
*/
QTransform QGraphicsView::transform() const
{
    Q_D(const QGraphicsView);
    return d->matrix;
}

/*!
    Returns a matrix that maps scene coordinates to viewport coordinates.

    \sa mapToScene(), mapFromScene()
*/
QTransform QGraphicsView::viewportTransform() const
{
    Q_D(const QGraphicsView);
    QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
    return d->identityMatrix ? moveMatrix : d->matrix * moveMatrix;
}

/*!
    \since 4.6

    Returns \c true if the view is transformed (i.e., a non-identity transform
    has been assigned, or the scrollbars are adjusted).

    \sa setTransform(), horizontalScrollBar(), verticalScrollBar()
*/
bool QGraphicsView::isTransformed() const
{
    Q_D(const QGraphicsView);
    return !d->identityMatrix || d->horizontalScroll() || d->verticalScroll();
}

/*!
    Sets the view's current transformation matrix to \a matrix.

    If \a combine is true, then \a matrix is combined with the current matrix;
    otherwise, \a matrix \e replaces the current matrix. \a combine is false
    by default.

    The transformation matrix tranforms the scene into view coordinates. Using
    the default transformation, provided by the identity matrix, one pixel in
    the view represents one unit in the scene (e.g., a 10x10 rectangular item
    is drawn using 10x10 pixels in the view). If a 2x2 scaling matrix is
    applied, the scene will be drawn in 1:2 (e.g., a 10x10 rectangular item is
    then drawn using 20x20 pixels in the view).

    Example:

    \snippet code/src_gui_graphicsview_qgraphicsview.cpp 7

    To simplify interation with items using a transformed view, QGraphicsView
    provides mapTo... and mapFrom... functions that can translate between
    scene and view coordinates. For example, you can call mapToScene() to map
    a view coordiate to a floating point scene coordinate, or mapFromScene()
    to map from floating point scene coordinates to view coordinates.

    \sa transform(), rotate(), scale(), shear(), translate()
*/
void QGraphicsView::setTransform(const QTransform &matrix, bool combine )
{
    Q_D(QGraphicsView);
    QTransform oldMatrix = d->matrix;
    if (!combine)
        d->matrix = matrix;
    else
        d->matrix = matrix * d->matrix;
    if (oldMatrix == d->matrix)
        return;

    d->identityMatrix = d->matrix.isIdentity();
    d->transforming = true;
    if (d->scene) {
        d->recalculateContentSize();
        d->centerView(d->transformationAnchor);
    } else {
        d->updateLastCenterPoint();
    }

    if (d->sceneInteractionAllowed)
        d->replayLastMouseEvent();
    d->transforming = false;

    // Any matrix operation requires a full update.
    d->updateAll();
}

/*!
    Resets the view transformation to the identity matrix.

    \sa transform(), setTransform()
*/
void QGraphicsView::resetTransform()
{
    setTransform(QTransform());
}

QPointF QGraphicsViewPrivate::mapToScene(const QPointF &point) const
{
    QPointF p = point;
    p.rx() += horizontalScroll();
    p.ry() += verticalScroll();
    return identityMatrix ? p : matrix.inverted().map(p);
}

QRectF QGraphicsViewPrivate::mapToScene(const QRectF &rect) const
{
    QPointF scrollOffset(horizontalScroll(), verticalScroll());
    QPointF tl = scrollOffset + rect.topLeft();
    QPointF tr = scrollOffset + rect.topRight();
    QPointF br = scrollOffset + rect.bottomRight();
    QPointF bl = scrollOffset + rect.bottomLeft();

    QPolygonF poly(4);
    if (!identityMatrix) {
        QTransform x = matrix.inverted();
        poly[0] = x.map(tl);
        poly[1] = x.map(tr);
        poly[2] = x.map(br);
        poly[3] = x.map(bl);
    } else {
        poly[0] = tl;
        poly[1] = tr;
        poly[2] = br;
        poly[3] = bl;
    }
    return poly.boundingRect();
}

QT_END_NAMESPACE

#include "moc_qgraphicsview.cpp"
