/****************************************************************************
**
** 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$
**
****************************************************************************/

#include "qglobal.h"

#include "qgraphicslayout.h"
#include "qgraphicsproxywidget.h"
#include "private/qgraphicsproxywidget_p.h"
#include "private/qwidget_p.h"
#include "private/qapplication_p.h"

#include <QtCore/qdebug.h>
#include <QtGui/qevent.h>
#include <QtWidgets/qgraphicsscene.h>
#include <QtWidgets/qgraphicssceneevent.h>
#include <QtWidgets/qlayout.h>
#include <QtGui/qpainter.h>
#include <QtWidgets/qstyleoption.h>
#include <QtWidgets/qgraphicsview.h>
#if QT_CONFIG(lineedit)
#include <QtWidgets/qlineedit.h>
#endif
#if QT_CONFIG(textedit)
#include <QtWidgets/qtextedit.h>
#endif

QT_BEGIN_NAMESPACE

//#define GRAPHICSPROXYWIDGET_DEBUG

/*!
    \class QGraphicsProxyWidget
    \brief The QGraphicsProxyWidget class provides a proxy layer for embedding
    a QWidget in a QGraphicsScene.
    \since 4.4
    \ingroup graphicsview-api
    \inmodule QtWidgets

    QGraphicsProxyWidget embeds QWidget-based widgets, for example, a
    QPushButton, QFontComboBox, or even QFileDialog, into
    QGraphicsScene. It forwards events between the two objects and
    translates between QWidget's integer-based geometry and
    QGraphicsWidget's qreal-based geometry. QGraphicsProxyWidget
    supports all core features of QWidget, including tab focus,
    keyboard input, Drag & Drop, and popups.  You can also embed
    complex widgets, e.g., widgets with subwidgets.

    Example:

    \snippet code/src_gui_graphicsview_qgraphicsproxywidget.cpp 0

    QGraphicsProxyWidget takes care of automatically embedding popup children
    of embedded widgets through creating a child proxy for each popup. This
    means that when an embedded QComboBox shows its popup list, a new
    QGraphicsProxyWidget is created automatically, embedding the popup, and
    positioning it correctly. This only works if the popup is child of the
    embedded widget (for example QToolButton::setMenu() requires the QMenu instance
    to be child of the QToolButton).

    \section1 Embedding a Widget with QGraphicsProxyWidget

    There are two ways to embed a widget using QGraphicsProxyWidget. The most
    common way is to pass a widget pointer to QGraphicsScene::addWidget()
    together with any relevant \l Qt::WindowFlags. This function returns a
    pointer to a QGraphicsProxyWidget. You can then choose to reparent or
    position either the proxy, or the embedded widget itself.

    For example, in the code snippet below, we embed a group box into the proxy:

    \snippet code/src_gui_graphicsview_qgraphicsproxywidget.cpp 1

    The image below is the output obtained with its contents margin and
    contents rect labeled.

    \image qgraphicsproxywidget-embed.png

    Alternatively, you can start by creating a new QGraphicsProxyWidget item,
    and then call setWidget() to embed a QWidget later. The widget() function
    returns a pointer to the embedded widget. QGraphicsProxyWidget shares
    ownership with QWidget, so if either of the two widgets are destroyed, the
    other widget will be automatically destroyed as well.

    \section1 Synchronizing Widget States

    QGraphicsProxyWidget keeps its state in sync with the embedded widget. For
    example, if the proxy is hidden or disabled, the embedded widget will be
    hidden or disabled as well, and vice versa. When the widget is embedded by
    calling addWidget(), QGraphicsProxyWidget copies the state from the widget
    into the proxy, and after that, the two will stay synchronized where
    possible. By default, when you embed a widget into a proxy, both the widget
    and the proxy will be visible because a QGraphicsWidget is visible when
    created (you do not have to call show()). If you explicitly hide the
    embedded widget, the proxy will also become invisible.

    Example:

    \snippet code/src_gui_graphicsview_qgraphicsproxywidget.cpp 2

    QGraphicsProxyWidget maintains symmetry for the following states:

    \table
    \header \li QWidget state       \li QGraphicsProxyWidget state      \li Notes
    \row     \li QWidget::enabled
                    \li QGraphicsProxyWidget::enabled
                        \li
    \row    \li QWidget::visible
                    \li QGraphicsProxyWidget::visible
                        \li The explicit state is also symmetric.
    \row    \li QWidget::geometry
                    \li QGraphicsProxyWidget::geometry
                        \li Geometry is only guaranteed to be symmetric while
                            the embedded widget is visible.
    \row    \li QWidget::layoutDirection
                    \li QGraphicsProxyWidget::layoutDirection
                        \li
    \row    \li QWidget::style
                    \li QGraphicsProxyWidget::style
                        \li
    \row    \li QWidget::palette
                    \li QGraphicsProxyWidget::palette
                        \li
    \row    \li QWidget::font
                    \li QGraphicsProxyWidget::font
                        \li
    \row    \li QWidget::cursor
                    \li QGraphicsProxyWidget::cursor
                        \li The embedded widget overrides the proxy widget
                            cursor. The proxy cursor changes depending on
                            which embedded subwidget is currently under the
                            mouse.
    \row    \li QWidget::sizeHint()
                    \li QGraphicsProxyWidget::sizeHint()
                        \li All size hint functionality from the embedded
                            widget is forwarded by the proxy.
    \row    \li QWidget::getContentsMargins()
                    \li QGraphicsProxyWidget::getContentsMargins()
                        \li Updated once by setWidget().
    \row    \li QWidget::windowTitle
                    \li QGraphicsProxyWidget::windowTitle
                        \li Updated once by setWidget().
    \endtable

    \note QGraphicsScene keeps the embedded widget in a special state that
    prevents it from disturbing other widgets (both embedded and not embedded)
    while the widget is embedded. In this state, the widget may differ slightly
    in behavior from when it is not embedded.

    \warning This class is provided for convenience when bridging
    QWidgets and QGraphicsItems, it should not be used for
    high-performance scenarios.

    \sa QGraphicsScene::addWidget(), QGraphicsWidget
*/

extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);
Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets();

/*!
    \internal
*/
QGraphicsProxyWidgetPrivate::QGraphicsProxyWidgetPrivate()
    : QGraphicsWidgetPrivate(),
      dragDropWidget(nullptr),
      posChangeMode(NoMode),
      sizeChangeMode(NoMode),
      visibleChangeMode(NoMode),
      enabledChangeMode(NoMode),
      styleChangeMode(NoMode),
      paletteChangeMode(NoMode),
      tooltipChangeMode(NoMode),
      focusFromWidgetToProxy(false),
      proxyIsGivingFocus(false)
{
}

/*!
    \internal
*/
QGraphicsProxyWidgetPrivate::~QGraphicsProxyWidgetPrivate()
{
}

/*!
    \internal
*/
void QGraphicsProxyWidgetPrivate::init()
{
    Q_Q(QGraphicsProxyWidget);
    q->setFocusPolicy(Qt::WheelFocus);
    q->setAcceptDrops(true);
}

/*!
    \internal
*/
void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneHoverEvent *event)
{
    QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
    mouseEvent.setPos(event->pos());
    mouseEvent.setScreenPos(event->screenPos());
    mouseEvent.setButton(Qt::NoButton);
    mouseEvent.setButtons(0);
    mouseEvent.setModifiers(event->modifiers());
    sendWidgetMouseEvent(&mouseEvent);
    event->setAccepted(mouseEvent.isAccepted());
}

/*!
    \internal
*/
void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent *event)
{
    if (!event || !widget || !widget->isVisible())
        return;
    Q_Q(QGraphicsProxyWidget);

    // Find widget position and receiver.
    QPointF pos = event->pos();
    QPointer<QWidget> alienWidget = widget->childAt(pos.toPoint());
    QPointer<QWidget> receiver =  alienWidget ? alienWidget : widget;

    if (QWidgetPrivate::nearestGraphicsProxyWidget(receiver) != q)
        return; //another proxywidget will handle the events

    // Translate QGraphicsSceneMouse events to QMouseEvents.
    QEvent::Type type = QEvent::None;
    switch (event->type()) {
    case QEvent::GraphicsSceneMousePress:
        type = QEvent::MouseButtonPress;
        if (!embeddedMouseGrabber)
            embeddedMouseGrabber = receiver;
        else
            receiver = embeddedMouseGrabber;
        break;
    case QEvent::GraphicsSceneMouseRelease:
        type = QEvent::MouseButtonRelease;
        if (embeddedMouseGrabber)
            receiver = embeddedMouseGrabber;
        break;
    case QEvent::GraphicsSceneMouseDoubleClick:
        type = QEvent::MouseButtonDblClick;
        if (!embeddedMouseGrabber)
            embeddedMouseGrabber = receiver;
        else
            receiver = embeddedMouseGrabber;
        break;
    case QEvent::GraphicsSceneMouseMove:
        type = QEvent::MouseMove;
        if (embeddedMouseGrabber)
            receiver = embeddedMouseGrabber;
        break;
    default:
        Q_ASSERT_X(false, "QGraphicsProxyWidget", "internal error");
        break;
    }

    if (!lastWidgetUnderMouse) {
        QApplicationPrivate::dispatchEnterLeave(embeddedMouseGrabber ? embeddedMouseGrabber : receiver, 0, event->screenPos());
        lastWidgetUnderMouse = receiver;
    }

    // Map event position from us to the receiver
    pos = mapToReceiver(pos, receiver);

    // Send mouse event.
    QMouseEvent mouseEvent(type, pos, receiver->mapTo(receiver->topLevelWidget(), pos.toPoint()),
                           receiver->mapToGlobal(pos.toPoint()),
                           event->button(), event->buttons(), event->modifiers(), event->source());

    QWidget *embeddedMouseGrabberPtr = (QWidget *)embeddedMouseGrabber;
    QApplicationPrivate::sendMouseEvent(receiver, &mouseEvent, alienWidget, widget,
                                        &embeddedMouseGrabberPtr, lastWidgetUnderMouse, event->spontaneous());
    embeddedMouseGrabber = embeddedMouseGrabberPtr;

    // Handle enter/leave events when last button is released from mouse
    // grabber child widget.
    if (embeddedMouseGrabber && type == QEvent::MouseButtonRelease && !event->buttons()) {
        Q_Q(QGraphicsProxyWidget);
        if (q->rect().contains(event->pos()) && q->acceptHoverEvents())
            lastWidgetUnderMouse = alienWidget ? alienWidget : widget;
        else // released on the frame our outside the item, or doesn't accept hover events.
            lastWidgetUnderMouse = 0;

        QApplicationPrivate::dispatchEnterLeave(lastWidgetUnderMouse, embeddedMouseGrabber, event->screenPos());
        embeddedMouseGrabber = 0;

#ifndef QT_NO_CURSOR
        // ### Restore the cursor, don't override it.
        if (!lastWidgetUnderMouse)
            q->unsetCursor();
#endif
    }

    event->setAccepted(mouseEvent.isAccepted());
}

void QGraphicsProxyWidgetPrivate::sendWidgetKeyEvent(QKeyEvent *event)
{
    Q_Q(QGraphicsProxyWidget);
    if (!event || !widget || !widget->isVisible())
        return;

    QPointer<QWidget> receiver = widget->focusWidget();
    if (!receiver)
        receiver = widget;
    Q_ASSERT(receiver);

    do {
        bool res = QCoreApplication::sendEvent(receiver, event);
        if ((res && event->isAccepted()) || (q->isWindow() && receiver == widget))
            break;
        receiver = receiver->parentWidget();
    } while (receiver);
}

/*!
    \internal
*/
void QGraphicsProxyWidgetPrivate::removeSubFocusHelper(QWidget *widget, Qt::FocusReason reason)
{
    QFocusEvent event(QEvent::FocusOut, reason);
    QPointer<QWidget> widgetGuard = widget;
    QCoreApplication::sendEvent(widget, &event);
    if (widgetGuard && event.isAccepted())
        QCoreApplication::sendEvent(widget->style(), &event);
}

/*!
    \internal
    Some of the logic is shared with QApplicationPrivate::focusNextPrevChild_helper
*/
QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next) const
{
    if (!widget)
        return 0;

    // Run around the focus chain until we find a widget that can take tab focus.
    if (!child) {
        child = next ? (QWidget *)widget : widget->d_func()->focus_prev;
    } else {
        child = next ? child->d_func()->focus_next : child->d_func()->focus_prev;
        if ((next && child == widget) || (!next && child == widget->d_func()->focus_prev)) {
             return 0;
        }
    }

    if (!child)
        return 0;

    QWidget *oldChild = child;
    uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus;
    do {
        if (child->isEnabled()
            && child->isVisibleTo(widget)
            && ((child->focusPolicy() & focus_flag) == focus_flag)
            && !(child->d_func()->extra && child->d_func()->extra->focus_proxy)) {
            return child;
        }
        child = next ? child->d_func()->focus_next : child->d_func()->focus_prev;
    } while (child != oldChild && !(next && child == widget) && !(!next && child == widget->d_func()->focus_prev));
    return 0;
}

/*!
    \internal
*/
void QGraphicsProxyWidgetPrivate::_q_removeWidgetSlot()
{
    Q_Q(QGraphicsProxyWidget);
    if (!widget.isNull()) {
        if (const auto &extra = widget->d_func()->extra)
            extra->proxyWidget = 0;
    }
    widget = 0;
    delete q;
}

/*!
    \internal
*/
void QGraphicsProxyWidgetPrivate::updateWidgetGeometryFromProxy()
{
}

/*!
    \internal
*/
void QGraphicsProxyWidgetPrivate::updateProxyGeometryFromWidget()
{
    Q_Q(QGraphicsProxyWidget);
    if (!widget)
        return;

    QRectF widgetGeometry = widget->geometry();
    QWidget *parentWidget = widget->parentWidget();
    if (widget->isWindow()) {
        QGraphicsProxyWidget *proxyParent = 0;
        if (parentWidget && (proxyParent = qobject_cast<QGraphicsProxyWidget *>(q->parentWidget()))) {
            // Nested window proxy (e.g., combobox popup), map widget to the
            // parent widget's global coordinates, and map that to the parent
            // proxy's child coordinates.
            widgetGeometry.moveTo(proxyParent->subWidgetRect(parentWidget).topLeft()
                                  + parentWidget->mapFromGlobal(widget->pos()));
        }
    }

    // Adjust to size hint if the widget has never been resized.
    if (!widget->size().isValid())
        widgetGeometry.setSize(widget->sizeHint());

    // Assign new geometry.
    posChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
    sizeChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
    q->setGeometry(widgetGeometry);
    posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
    sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
}

/*!
    \internal
*/
void QGraphicsProxyWidgetPrivate::updateProxyInputMethodAcceptanceFromWidget()
{
    Q_Q(QGraphicsProxyWidget);
    if (!widget)
        return;

    QWidget *focusWidget = widget->focusWidget();
    if (!focusWidget)
        focusWidget = widget;
    q->setFlag(QGraphicsItem::ItemAcceptsInputMethod,
               focusWidget->testAttribute(Qt::WA_InputMethodEnabled));
}

/*!
    \internal

    Embeds \a subWin as a subwindow of this proxy widget. \a subWin must be a top-level
    widget and a descendant of the widget managed by this proxy. A separate subproxy
    will be created as a child of this proxy widget to manage \a subWin.
*/
void QGraphicsProxyWidgetPrivate::embedSubWindow(QWidget *subWin)
{
    const auto &extra = subWin->d_func()->extra;
    if (!extra || !extra->proxyWidget) {
        QGraphicsProxyWidget *subProxy = new QGraphicsProxyWidget(q_func(), subWin->windowFlags());
        subProxy->d_func()->setWidget_helper(subWin, false);
    }
}

/*!
    \internal

    Removes ("unembeds") \a subWin and deletes the proxy holder item. This can
    happen when QWidget::setParent() reparents the embedded window out of
    "embedded space".
*/
void QGraphicsProxyWidgetPrivate::unembedSubWindow(QWidget *subWin)
{
    foreach (QGraphicsItem *child, children) {
        if (child->isWidget()) {
            if (QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(child))) {
                if (proxy->widget() == subWin) {
                    proxy->setWidget(0);
                    scene->removeItem(proxy);
                    delete proxy;
                    return;
                }
            }
        }
    }
}

bool QGraphicsProxyWidgetPrivate::isProxyWidget() const
{
    return true;
}

/*!
     \internal
*/
QPointF QGraphicsProxyWidgetPrivate::mapToReceiver(const QPointF &pos, const QWidget *receiver) const
{
    QPointF p = pos;
    // Map event position from us to the receiver, preserving its
    // precision (don't use QWidget::mapFrom here).
    while (receiver && receiver != widget) {
        p -= QPointF(receiver->pos());
        receiver = receiver->parentWidget();
    }
    return p;
}

/*!
    Constructs a new QGraphicsProxy widget. \a parent and \a wFlags are passed
    to QGraphicsItem's constructor.
*/
QGraphicsProxyWidget::QGraphicsProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)
    : QGraphicsWidget(*new QGraphicsProxyWidgetPrivate, parent, wFlags)
{
    Q_D(QGraphicsProxyWidget);
    d->init();
}

/*!
    Destroys the proxy widget and any embedded widget.
*/
QGraphicsProxyWidget::~QGraphicsProxyWidget()
{
    Q_D(QGraphicsProxyWidget);
    if (d->widget) {
        d->widget->removeEventFilter(this);
        QObject::disconnect(d->widget, SIGNAL(destroyed()), this, SLOT(_q_removeWidgetSlot()));
        delete d->widget;
    }
}

/*!
    Embeds \a widget into this proxy widget. The embedded widget must reside
    exclusively either inside or outside of Graphics View. You cannot embed a
    widget as long as it is is visible elsewhere in the UI, at the same time.

    \a widget must be a top-level widget whose parent is \nullptr.

    When the widget is embedded, its state (e.g., visible, enabled, geometry,
    size hints) is copied into the proxy widget. If the embedded widget is
    explicitly hidden or disabled, the proxy widget will become explicitly
    hidden or disabled after embedding is complete. The class documentation
    has a full overview over the shared state.

    QGraphicsProxyWidget's window flags determine whether the widget, after
    embedding, will be given window decorations or not.

    After this function returns, QGraphicsProxyWidget will keep its state
    synchronized with that of \a widget whenever possible.

    If a widget is already embedded by this proxy when this function is
    called, that widget will first be automatically unembedded. Passing 0 for
    the \a widget argument will only unembed the widget, and the ownership of
    the currently embedded widget will be passed on to the caller.
    Every child widget that are embedded will also be embedded and their proxy
    widget destroyed.

    Note that widgets with the Qt::WA_PaintOnScreen widget attribute
    set and widgets that wrap an external application or controller
    cannot be embedded. Examples are QGLWidget and QAxWidget.

    \sa widget()
*/
void QGraphicsProxyWidget::setWidget(QWidget *widget)
{
    Q_D(QGraphicsProxyWidget);
    d->setWidget_helper(widget, true);
}

void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool autoShow)
{
    Q_Q(QGraphicsProxyWidget);
    if (newWidget == widget)
        return;
    if (widget) {
        QObject::disconnect(widget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot()));
        widget->removeEventFilter(q);
        widget->setAttribute(Qt::WA_DontShowOnScreen, false);
        widget->d_func()->extra->proxyWidget = 0;
        resolveFont(inheritedFontResolveMask);
        resolvePalette(inheritedPaletteResolveMask);
        widget->update();

        const auto childItems = q->childItems();
        for (QGraphicsItem *child : childItems) {
            if (child->d_ptr->isProxyWidget()) {
                QGraphicsProxyWidget *childProxy = static_cast<QGraphicsProxyWidget *>(child);
                QWidget *parent = childProxy->widget();
                while (parent && parent->parentWidget()) {
                    if (parent == widget)
                        break;
                    parent = parent->parentWidget();
                }
                if (!childProxy->widget() || parent != widget)
                    continue;
                childProxy->setWidget(nullptr);
                delete childProxy;
            }
        }

        widget = nullptr;
#ifndef QT_NO_CURSOR
        q->unsetCursor();
#endif
        q->setAcceptHoverEvents(false);
        if (!newWidget)
            q->update();
    }
    if (!newWidget)
        return;
    if (!newWidget->isWindow()) {
        const auto &extra = newWidget->parentWidget()->d_func()->extra;
        if (!extra || !extra->proxyWidget)  {
            qWarning("QGraphicsProxyWidget::setWidget: cannot embed widget %p "
                     "which is not a toplevel widget, and is not a child of an embedded widget", newWidget);
            return;
        }
    }

    // Register this proxy within the widget's private.
    // ### This is a bit backdoorish
    QWExtra *extra = newWidget->d_func()->extra.get();
    if (!extra) {
        newWidget->d_func()->createExtra();
        extra = newWidget->d_func()->extra.get();
    }
    QGraphicsProxyWidget **proxyWidget = &extra->proxyWidget;
    if (*proxyWidget) {
        if (*proxyWidget != q) {
            qWarning("QGraphicsProxyWidget::setWidget: cannot embed widget %p"
                        "; already embedded", newWidget);
        }
        return;
    }
    *proxyWidget = q;

    newWidget->setAttribute(Qt::WA_DontShowOnScreen);
    newWidget->ensurePolished();
    // Do not wait for this widget to close before the app closes ###
    // shouldn't this widget inherit the attribute?
    newWidget->setAttribute(Qt::WA_QuitOnClose, false);
    q->setAcceptHoverEvents(true);

    if (newWidget->testAttribute(Qt::WA_NoSystemBackground))
        q->setAttribute(Qt::WA_NoSystemBackground);
    if (newWidget->testAttribute(Qt::WA_OpaquePaintEvent))
        q->setAttribute(Qt::WA_OpaquePaintEvent);

    widget = newWidget;

    // Changes only go from the widget to the proxy.
    enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
    visibleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
    posChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
    sizeChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;

    if ((autoShow && !newWidget->testAttribute(Qt::WA_WState_ExplicitShowHide)) || !newWidget->testAttribute(Qt::WA_WState_Hidden)) {
        newWidget->show();
    }

    // Copy the state from the widget onto the proxy.
#ifndef QT_NO_CURSOR
    if (newWidget->testAttribute(Qt::WA_SetCursor))
        q->setCursor(widget->cursor());
#endif
    q->setEnabled(newWidget->isEnabled());
    q->setVisible(newWidget->isVisible());
    q->setLayoutDirection(newWidget->layoutDirection());
    if (newWidget->testAttribute(Qt::WA_SetStyle))
        q->setStyle(widget->style());

    resolveFont(inheritedFontResolveMask);
    resolvePalette(inheritedPaletteResolveMask);

    if (!newWidget->testAttribute(Qt::WA_Resized))
        newWidget->adjustSize();

    q->setContentsMargins(newWidget->contentsMargins());
    q->setWindowTitle(newWidget->windowTitle());

    // size policies and constraints..
    q->setSizePolicy(newWidget->sizePolicy());
    QSize sz = newWidget->minimumSize();
    q->setMinimumSize(sz.isNull() ? QSizeF() : QSizeF(sz));
    sz = newWidget->maximumSize();
    q->setMaximumSize(sz.isNull() ? QSizeF() : QSizeF(sz));

    updateProxyGeometryFromWidget();

    updateProxyInputMethodAcceptanceFromWidget();

    // Hook up the event filter to keep the state up to date.
    newWidget->installEventFilter(q);
    QObject::connect(newWidget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot()));

    // Changes no longer go only from the widget to the proxy.
    enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
    visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
    posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
    sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
}

/*!
    Returns a pointer to the embedded widget.

    \sa setWidget()
*/
QWidget *QGraphicsProxyWidget::widget() const
{
    Q_D(const QGraphicsProxyWidget);
    return d->widget;
}

/*!
    Returns the rectangle for \a widget, which must be a descendant of
    widget(), or widget() itself, in this proxy item's local coordinates.

    If no widget is embedded, \a widget is \nullptr, or \a widget is not a
    descendant of the embedded widget, this function returns an empty QRectF.

    \sa widget()
*/
QRectF QGraphicsProxyWidget::subWidgetRect(const QWidget *widget) const
{
    Q_D(const QGraphicsProxyWidget);
    if (!widget || !d->widget)
        return QRectF();
    if (d->widget == widget || d->widget->isAncestorOf(widget))
        return QRectF(widget->mapTo(d->widget, QPoint(0, 0)), widget->size());
    return QRectF();
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::setGeometry(const QRectF &rect)
{
    Q_D(QGraphicsProxyWidget);
    bool proxyResizesWidget = !d->posChangeMode && !d->sizeChangeMode;
    if (proxyResizesWidget) {
        d->posChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
        d->sizeChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
    }
    QGraphicsWidget::setGeometry(rect);
    if (proxyResizesWidget) {
        d->posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
        d->sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
    }
}

/*!
    \reimp
*/
QVariant QGraphicsProxyWidget::itemChange(GraphicsItemChange change,
                                          const QVariant &value)
{
    Q_D(QGraphicsProxyWidget);

    switch (change) {
    case ItemPositionChange:
        // The item's position is either changed directly on the proxy, in
        // which case the position change should propagate to the widget,
        // otherwise it happens as a side effect when filtering QEvent::Move.
        if (!d->posChangeMode)
            d->posChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
        break;
    case ItemPositionHasChanged:
        // Move the internal widget if we're in widget-to-proxy
        // mode. Otherwise the widget has already moved.
        if (d->widget && d->posChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
            d->widget->move(value.toPoint());
        if (d->posChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
            d->posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
        break;
    case ItemVisibleChange:
        if (!d->visibleChangeMode)
            d->visibleChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
        break;
    case ItemVisibleHasChanged:
        if (d->widget && d->visibleChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
            d->widget->setVisible(isVisible());
        if (d->visibleChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
            d->visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
        break;
    case ItemEnabledChange:
        if (!d->enabledChangeMode)
            d->enabledChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
        break;
    case ItemEnabledHasChanged:
        if (d->widget && d->enabledChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
            d->widget->setEnabled(isEnabled());
        if (d->enabledChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
            d->enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
        break;
    default:
        break;
    }
    return QGraphicsWidget::itemChange(change, value);
}

/*!
    \reimp
*/
bool QGraphicsProxyWidget::event(QEvent *event)
{
    Q_D(QGraphicsProxyWidget);
    if (!d->widget)
        return QGraphicsWidget::event(event);

    switch (event->type()) {
    case QEvent::StyleChange:
        // Propagate style changes to the embedded widget.
        if (!d->styleChangeMode) {
            d->styleChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
            d->widget->setStyle(style());
            d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
        }
        break;
    case QEvent::FontChange: {
        // Propagate to widget.
        QWidgetPrivate *wd = d->widget->d_func();
        int mask = d->font.resolve() | d->inheritedFontResolveMask;
        wd->inheritedFontResolveMask = mask;
        wd->resolveFont();
        break;
    }
    case QEvent::PaletteChange: {
        // Propagate to widget.
        QWidgetPrivate *wd = d->widget->d_func();
        int mask = d->palette.resolve() | d->inheritedPaletteResolveMask;
        wd->inheritedPaletteResolveMask = mask;
        wd->resolvePalette();
        break;
    }
    case QEvent::InputMethod: {
        inputMethodEvent(static_cast<QInputMethodEvent *>(event));
        if (event->isAccepted())
            return true;
        return false;
    }
    case QEvent::ShortcutOverride: {
        QWidget *focusWidget = d->widget->focusWidget();
        while (focusWidget) {
            QCoreApplication::sendEvent(focusWidget, event);
            if (event->isAccepted())
                return true;
            focusWidget = focusWidget->parentWidget();
        }
        return false;
    }
    case QEvent::KeyPress: {
        QKeyEvent *k = static_cast<QKeyEvent *>(event);
        if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
            if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) {  //### Add MetaModifier?
                QWidget *focusWidget = d->widget->focusWidget();
                while (focusWidget) {
                    const bool res = QCoreApplication::sendEvent(focusWidget, event);
                    if ((res && event->isAccepted()) || (isWindow() && focusWidget == d->widget)) {
                        event->accept();
                        break;
                    }
                    focusWidget = focusWidget->parentWidget();
                }
                return true;
            }
        }
        break;
    }
#ifndef QT_NO_TOOLTIP
    case QEvent::GraphicsSceneHelp: {
        // Propagate the help event (for tooltip) to the widget under mouse
        if (d->lastWidgetUnderMouse) {
            QGraphicsSceneHelpEvent *he = static_cast<QGraphicsSceneHelpEvent *>(event);
            QPoint pos = d->mapToReceiver(mapFromScene(he->scenePos()), d->lastWidgetUnderMouse).toPoint();
            QHelpEvent e(QEvent::ToolTip, pos, he->screenPos());
            QCoreApplication::sendEvent(d->lastWidgetUnderMouse, &e);
            event->setAccepted(e.isAccepted());
            return e.isAccepted();
        }
        break;
    }
    case QEvent::ToolTipChange: {
        // Propagate tooltip change to the widget
        if (!d->tooltipChangeMode) {
            d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
            d->widget->setToolTip(toolTip());
            d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
        }
        break;
    }
#endif
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate:
    case QEvent::TouchEnd: {
        if (event->spontaneous())
            qt_sendSpontaneousEvent(d->widget, event);
        else
            QCoreApplication::sendEvent(d->widget, event);

        if (event->isAccepted())
            return true;

        break;
   }
    default:
        break;
    }
    return QGraphicsWidget::event(event);
}

/*!
    \reimp
*/
bool QGraphicsProxyWidget::eventFilter(QObject *object, QEvent *event)
{
    Q_D(QGraphicsProxyWidget);

    if (object == d->widget) {
        switch (event->type()) {
        case QEvent::LayoutRequest:
            updateGeometry();
            break;
         case QEvent::Resize:
             // If the widget resizes itself, we resize the proxy too.
             // Prevent feed-back by checking the geometry change mode.
             if (!d->sizeChangeMode)
                 d->updateProxyGeometryFromWidget();
            break;
         case QEvent::Move:
             // If the widget moves itself, we move the proxy too.  Prevent
             // feed-back by checking the geometry change mode.
             if (!d->posChangeMode)
                 d->updateProxyGeometryFromWidget();
            break;
        case QEvent::Hide:
        case QEvent::Show:
            // If the widget toggles its visible state, the proxy will follow.
            if (!d->visibleChangeMode) {
                d->visibleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
                setVisible(event->type() == QEvent::Show);
                d->visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
            }
            break;
        case QEvent::EnabledChange:
            // If the widget toggles its enabled state, the proxy will follow.
            if (!d->enabledChangeMode) {
                d->enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
                setEnabled(d->widget->isEnabled());
                d->enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
            }
            break;
        case QEvent::StyleChange:
            // Propagate style changes to the proxy.
            if (!d->styleChangeMode) {
                d->styleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
                setStyle(d->widget->style());
                d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
            }
            break;
#ifndef QT_NO_TOOLTIP
        case QEvent::ToolTipChange:
            // Propagate tooltip change to the proxy.
            if (!d->tooltipChangeMode) {
                d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
                setToolTip(d->widget->toolTip());
                d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
            }
            break;
#endif
        default:
            break;
        }
    }
    return QGraphicsWidget::eventFilter(object, event);
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::showEvent(QShowEvent *event)
{
    Q_UNUSED(event);
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::hideEvent(QHideEvent *event)
{
    Q_UNUSED(event);
}

#ifndef QT_NO_CONTEXTMENU
/*!
    \reimp
*/
void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    Q_D(QGraphicsProxyWidget);
    if (!event || !d->widget || !d->widget->isVisible() || !hasFocus())
        return;

    // Find widget position and receiver.
    QPointF pos = event->pos();
    QPointer<QWidget> alienWidget = d->widget->childAt(pos.toPoint());
    QPointer<QWidget> receiver =  alienWidget ? alienWidget : d->widget;

    // Map event position from us to the receiver
    pos = d->mapToReceiver(pos, receiver);

    QPoint globalPos = receiver->mapToGlobal(pos.toPoint());
    //If the receiver by-pass the proxy its popups
    //will be top level QWidgets therefore they need
    //the screen position. mapToGlobal expect the widget to
    //have proper coordinates in regards of the windowing system
    //but it's not true because the widget is embedded.
    if (bypassGraphicsProxyWidget(receiver))
        globalPos = event->screenPos();

    // Send mouse event. ### Doesn't propagate the event.
    QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()),
                                       pos.toPoint(), globalPos, event->modifiers());
    QCoreApplication::sendEvent(receiver, &contextMenuEvent);

    event->setAccepted(contextMenuEvent.isAccepted());
}
#endif // QT_NO_CONTEXTMENU

#if QT_CONFIG(draganddrop)
/*!
    \reimp
*/
void QGraphicsProxyWidget::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
#if !QT_CONFIG(draganddrop)
    Q_UNUSED(event);
#else
    Q_D(QGraphicsProxyWidget);
    if (!d->widget)
        return;

    QDragEnterEvent proxyDragEnter(event->pos().toPoint(), event->dropAction(), event->mimeData(), event->buttons(), event->modifiers());
    proxyDragEnter.setAccepted(event->isAccepted());
    QCoreApplication::sendEvent(d->widget, &proxyDragEnter);
    event->setAccepted(proxyDragEnter.isAccepted());
    if (proxyDragEnter.isAccepted())    // we discard answerRect
        event->setDropAction(proxyDragEnter.dropAction());
#endif
}
/*!
    \reimp
*/
void QGraphicsProxyWidget::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
{
    Q_UNUSED(event);
#if QT_CONFIG(draganddrop)
    Q_D(QGraphicsProxyWidget);
    if (!d->widget || !d->dragDropWidget)
        return;
    QDragLeaveEvent proxyDragLeave;
    QCoreApplication::sendEvent(d->dragDropWidget, &proxyDragLeave);
    d->dragDropWidget = 0;
#endif
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
{
#if !QT_CONFIG(draganddrop)
    Q_UNUSED(event);
#else
    Q_D(QGraphicsProxyWidget);
    if (!d->widget)
        return;
    QPointF p = event->pos();
    event->ignore();
    QPointer<QWidget> subWidget = d->widget->childAt(p.toPoint());
    QPointer<QWidget> receiver =  subWidget ? subWidget : d->widget;
    bool eventDelivered = false;
    for (; receiver; receiver = receiver->parentWidget()) {
        if (!receiver->isEnabled() || !receiver->acceptDrops())
            continue;
        // Map event position from us to the receiver
        QPoint receiverPos = d->mapToReceiver(p, receiver).toPoint();
        if (receiver != d->dragDropWidget) {
            // Try to enter before we leave
            QDragEnterEvent dragEnter(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
            dragEnter.setDropAction(event->proposedAction());
            QCoreApplication::sendEvent(receiver, &dragEnter);
            event->setAccepted(dragEnter.isAccepted());
            event->setDropAction(dragEnter.dropAction());
            if (!event->isAccepted()) {
                // propagate to the parent widget
                continue;
            }

            d->lastDropAction = event->dropAction();

            if (d->dragDropWidget) {
                QDragLeaveEvent dragLeave;
                QCoreApplication::sendEvent(d->dragDropWidget, &dragLeave);
            }
            d->dragDropWidget = receiver;
        }

        QDragMoveEvent dragMove(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
        event->setDropAction(d->lastDropAction);
        QCoreApplication::sendEvent(receiver, &dragMove);
        event->setAccepted(dragMove.isAccepted());
        event->setDropAction(dragMove.dropAction());
        if (event->isAccepted())
            d->lastDropAction = event->dropAction();
        eventDelivered = true;
        break;
    }

    if (!eventDelivered) {
        if (d->dragDropWidget) {
            // Leave the last drag drop item
            QDragLeaveEvent dragLeave;
            QCoreApplication::sendEvent(d->dragDropWidget, &dragLeave);
            d->dragDropWidget = 0;
        }
        // Propagate
        event->setDropAction(Qt::IgnoreAction);
    }
#endif
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::dropEvent(QGraphicsSceneDragDropEvent *event)
{
#if !QT_CONFIG(draganddrop)
    Q_UNUSED(event);
#else
    Q_D(QGraphicsProxyWidget);
    if (d->widget && d->dragDropWidget) {
        QPoint widgetPos = d->mapToReceiver(event->pos(), d->dragDropWidget).toPoint();
        QDropEvent dropEvent(widgetPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
        QCoreApplication::sendEvent(d->dragDropWidget, &dropEvent);
        event->setAccepted(dropEvent.isAccepted());
        d->dragDropWidget = 0;
    }
#endif
}
#endif

/*!
    \reimp
*/
void QGraphicsProxyWidget::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    Q_UNUSED(event);
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    Q_UNUSED(event);
    Q_D(QGraphicsProxyWidget);
    // If hoverMove was compressed away, make sure we update properly here.
    if (d->lastWidgetUnderMouse) {
        QApplicationPrivate::dispatchEnterLeave(0, d->lastWidgetUnderMouse, event->screenPos());
        d->lastWidgetUnderMouse = 0;
    }
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    Q_D(QGraphicsProxyWidget);
#ifdef GRAPHICSPROXYWIDGET_DEBUG
    qDebug("QGraphicsProxyWidget::hoverMoveEvent");
#endif
    // Ignore events on the window frame.
    if (!d->widget || !rect().contains(event->pos())) {
        if (d->lastWidgetUnderMouse) {
            QApplicationPrivate::dispatchEnterLeave(0, d->lastWidgetUnderMouse, event->screenPos());
            d->lastWidgetUnderMouse = 0;
        }
        return;
    }

    d->embeddedMouseGrabber = 0;
    d->sendWidgetMouseEvent(event);
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::grabMouseEvent(QEvent *event)
{
    Q_UNUSED(event);
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::ungrabMouseEvent(QEvent *event)
{
    Q_D(QGraphicsProxyWidget);
    Q_UNUSED(event);
    d->embeddedMouseGrabber = 0;
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QGraphicsProxyWidget);
#ifdef GRAPHICSPROXYWIDGET_DEBUG
    qDebug("QGraphicsProxyWidget::mouseMoveEvent");
#endif
    d->sendWidgetMouseEvent(event);
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QGraphicsProxyWidget);
#ifdef GRAPHICSPROXYWIDGET_DEBUG
    qDebug("QGraphicsProxyWidget::mousePressEvent");
#endif
    d->sendWidgetMouseEvent(event);
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QGraphicsProxyWidget);
#ifdef GRAPHICSPROXYWIDGET_DEBUG
    qDebug("QGraphicsProxyWidget::mouseDoubleClickEvent");
#endif
    d->sendWidgetMouseEvent(event);
}

/*!
    \reimp
*/
#if QT_CONFIG(wheelevent)
void QGraphicsProxyWidget::wheelEvent(QGraphicsSceneWheelEvent *event)
{
    Q_D(QGraphicsProxyWidget);
#ifdef GRAPHICSPROXYWIDGET_DEBUG
    qDebug("QGraphicsProxyWidget::wheelEvent");
#endif
    if (!d->widget)
        return;

    QPointF pos = event->pos();
    QPointer<QWidget> receiver = d->widget->childAt(pos.toPoint());
    if (!receiver)
        receiver = d->widget;

    // Map event position from us to the receiver
    pos = d->mapToReceiver(pos, receiver);

    // Send mouse event.
    QPoint angleDelta;
    if (event->orientation() == Qt::Horizontal)
        angleDelta.setX(event->delta());
    else
        angleDelta.setY(event->delta());
    // pixelDelta, inverted, scrollPhase and source from the original QWheelEvent
    // were not preserved in the QGraphicsSceneWheelEvent unfortunately
    QWheelEvent wheelEvent(pos, event->screenPos(), QPoint(), angleDelta,
                    event->buttons(), event->modifiers(), Qt::NoScrollPhase, false);
    QPointer<QWidget> focusWidget = d->widget->focusWidget();
    extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);
    qt_sendSpontaneousEvent(receiver, &wheelEvent);
    event->setAccepted(wheelEvent.isAccepted());

    // ### Remove, this should be done by proper focusIn/focusOut events.
    if (focusWidget && !focusWidget->hasFocus()) {
        focusWidget->update();
        focusWidget = d->widget->focusWidget();
        if (focusWidget && focusWidget->hasFocus())
            focusWidget->update();
    }
}
#endif

/*!
    \reimp
*/
void QGraphicsProxyWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QGraphicsProxyWidget);
#ifdef GRAPHICSPROXYWIDGET_DEBUG
    qDebug("QGraphicsProxyWidget::mouseReleaseEvent");
#endif
    d->sendWidgetMouseEvent(event);
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::keyPressEvent(QKeyEvent *event)
{
    Q_D(QGraphicsProxyWidget);
#ifdef GRAPHICSPROXYWIDGET_DEBUG
    qDebug("QGraphicsProxyWidget::keyPressEvent");
#endif
    d->sendWidgetKeyEvent(event);
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::keyReleaseEvent(QKeyEvent *event)
{
    Q_D(QGraphicsProxyWidget);
#ifdef GRAPHICSPROXYWIDGET_DEBUG
    qDebug("QGraphicsProxyWidget::keyReleaseEvent");
#endif
    d->sendWidgetKeyEvent(event);
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event)
{
#ifdef GRAPHICSPROXYWIDGET_DEBUG
    qDebug("QGraphicsProxyWidget::focusInEvent");
#endif
    Q_D(QGraphicsProxyWidget);

    if (d->focusFromWidgetToProxy) {
        // Prevent recursion when the proxy autogains focus through the
        // embedded widget calling setFocus(). ### Could be done with event
        // filter on FocusIn instead?
        return;
    }

    d->proxyIsGivingFocus = true;

    switch (event->reason()) {
    case Qt::TabFocusReason: {
        if (QWidget *focusChild = d->findFocusChild(0, true))
            focusChild->setFocus(event->reason());
        break;
    }
    case Qt::BacktabFocusReason:
        if (QWidget *focusChild = d->findFocusChild(0, false))
            focusChild->setFocus(event->reason());
        break;
    default:
        if (d->widget && d->widget->focusWidget()) {
            d->widget->focusWidget()->setFocus(event->reason());
        }
        break;
    }

    d->proxyIsGivingFocus = false;
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::focusOutEvent(QFocusEvent *event)
{
#ifdef GRAPHICSPROXYWIDGET_DEBUG
    qDebug("QGraphicsProxyWidget::focusOutEvent");
#endif
    Q_D(QGraphicsProxyWidget);
    if (d->widget) {
        // We need to explicitly remove subfocus from the embedded widget's
        // focus widget.
        if (QWidget *focusWidget = d->widget->focusWidget())
            d->removeSubFocusHelper(focusWidget, event->reason());
    }
}

/*!
    \reimp
*/
bool QGraphicsProxyWidget::focusNextPrevChild(bool next)
{
    Q_D(QGraphicsProxyWidget);
    if (!d->widget || !d->scene)
        return QGraphicsWidget::focusNextPrevChild(next);

    Qt::FocusReason reason = next ? Qt::TabFocusReason : Qt::BacktabFocusReason;
    QWidget *lastFocusChild = d->widget->focusWidget();
    if (QWidget *newFocusChild = d->findFocusChild(lastFocusChild, next)) {
        newFocusChild->setFocus(reason);
        return true;
    }

    return QGraphicsWidget::focusNextPrevChild(next);
}

/*!
    \reimp
*/
QVariant QGraphicsProxyWidget::inputMethodQuery(Qt::InputMethodQuery query) const
{
    Q_D(const QGraphicsProxyWidget);

    if (!d->widget || !hasFocus())
        return QVariant();

    QWidget *focusWidget = widget()->focusWidget();
    if (!focusWidget)
        focusWidget = d->widget;
    QVariant v = focusWidget->inputMethodQuery(query);
    QPointF focusWidgetPos = subWidgetRect(focusWidget).topLeft();
    switch (v.type()) {
    case QVariant::RectF:
        v = v.toRectF().translated(focusWidgetPos);
        break;
    case QVariant::PointF:
        v = v.toPointF() + focusWidgetPos;
        break;
    case QVariant::Rect:
        v = v.toRect().translated(focusWidgetPos.toPoint());
        break;
    case QVariant::Point:
        v = v.toPoint() + focusWidgetPos.toPoint();
        break;
    default:
        break;
    }
    return v;
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::inputMethodEvent(QInputMethodEvent *event)
{
    // Forward input method events if the focus widget enables input methods.
    Q_D(const QGraphicsProxyWidget);
    QWidget *focusWidget = d->widget->focusWidget();
    if (focusWidget && focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
        QCoreApplication::sendEvent(focusWidget, event);
}

/*!
    \reimp
*/
QSizeF QGraphicsProxyWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
    Q_D(const QGraphicsProxyWidget);
    if (!d->widget)
        return QGraphicsWidget::sizeHint(which, constraint);

    QSizeF sh;
    switch (which) {
    case Qt::PreferredSize:
        if (QLayout *l = d->widget->layout())
            sh = l->sizeHint();
        else
            sh = d->widget->sizeHint();
        break;
    case Qt::MinimumSize:
        if (QLayout *l = d->widget->layout())
            sh = l->minimumSize();
        else
            sh = d->widget->minimumSizeHint();
        break;
    case Qt::MaximumSize:
        if (QLayout *l = d->widget->layout())
            sh = l->maximumSize();
        else
            sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
        break;
    case Qt::MinimumDescent:
        sh = constraint;
        break;
    default:
        break;
    }
    return sh;
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
{
    Q_D(QGraphicsProxyWidget);
    if (d->widget) {
        if (d->sizeChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
            d->widget->resize(event->newSize().toSize());
    }
    QGraphicsWidget::resizeEvent(event);
}

/*!
    \reimp
*/
void QGraphicsProxyWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_D(QGraphicsProxyWidget);
    Q_UNUSED(widget);
    if (!d->widget || !d->widget->isVisible())
        return;

    // Filter out repaints on the window frame.
    const QRect exposedWidgetRect = (option->exposedRect & rect()).toAlignedRect();
    if (exposedWidgetRect.isEmpty())
        return;

    d->widget->render(painter, exposedWidgetRect.topLeft(), exposedWidgetRect);
}

/*!
  \enum QGraphicsProxyWidget::anonymous

  The value returned by the virtual type() function.

  \value Type A graphics proxy widget
*/

/*!
    \reimp
*/
int QGraphicsProxyWidget::type() const
{
    return Type;
}

/*!
  \since 4.5

  Creates a proxy widget for the given \a child of the widget
  contained in this proxy.

  This function makes it possible to acquire proxies for
  non top-level widgets. For instance, you can embed a dialog,
  and then transform only one of its widgets.

  If the widget is already embedded, return the existing proxy widget.

  \sa newProxyWidget(), QGraphicsScene::addWidget()
*/
QGraphicsProxyWidget *QGraphicsProxyWidget::createProxyForChildWidget(QWidget *child)
{
    QGraphicsProxyWidget *proxy = child->graphicsProxyWidget();
    if (proxy)
        return proxy;
    if (!child->parentWidget()) {
        qWarning("QGraphicsProxyWidget::createProxyForChildWidget: top-level widget not in a QGraphicsScene");
        return 0;
    }

    QGraphicsProxyWidget *parentProxy = createProxyForChildWidget(child->parentWidget());
    if (!parentProxy)
        return 0;

    if (!QMetaObject::invokeMethod(parentProxy, "newProxyWidget",  Qt::DirectConnection,
         Q_RETURN_ARG(QGraphicsProxyWidget*, proxy), Q_ARG(const QWidget*, child)))
        return 0;
    proxy->setParent(parentProxy);
    proxy->setWidget(child);
    return proxy;
}

/*!
  \fn QGraphicsProxyWidget *QGraphicsProxyWidget::newProxyWidget(const QWidget *child)
  \since 4.5

  Creates a proxy widget for the given \a child of the widget contained in this
  proxy.

  You should not call this function directly; use
  QGraphicsProxyWidget::createProxyForChildWidget() instead.

  This function is a fake virtual slot that you can reimplement in
  your subclass in order to control how new proxy widgets are
  created. The default implementation returns a proxy created with
  the QGraphicsProxyWidget() constructor with this proxy widget as
  the parent.

  \sa createProxyForChildWidget()
*/
QGraphicsProxyWidget *QGraphicsProxyWidget::newProxyWidget(const QWidget *)
{
    return new QGraphicsProxyWidget(this);
}



QT_END_NAMESPACE

#include "moc_qgraphicsproxywidget.cpp"
