/****************************************************************************
**
** 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 "qgraphicswidget.h"
#include "qgraphicswidget_p.h"
#include "qgraphicslayout.h"
#include "qgraphicslayout_p.h"
#include "qgraphicsscene.h"
#include "qgraphicssceneevent.h"

#ifndef QT_NO_ACTION
#include <private/qaction_p.h>
#endif
#include <private/qapplication_p.h>
#include <private/qgraphicsscene_p.h>
#ifndef QT_NO_SHORTCUT
#include <private/qshortcutmap_p.h>
#endif
#include <QtCore/qmutex.h>
#include <QtWidgets/qapplication.h>
#include <QtWidgets/qgraphicsview.h>
#include <QtWidgets/qgraphicsproxywidget.h>
#include <QtGui/qpalette.h>
#include <QtWidgets/qstyleoption.h>

#include <qdebug.h>

QT_BEGIN_NAMESPACE

/*!
    \class QGraphicsWidget
    \brief The QGraphicsWidget class is the base class for all widget
    items in a QGraphicsScene.
    \since 4.4
    \ingroup graphicsview-api
    \inmodule QtWidgets

    QGraphicsWidget is an extended base item that provides extra functionality
    over QGraphicsItem. It is similar to QWidget in many ways:

    \list
        \li Provides a \l palette, a \l font and a \l style().
        \li Has a defined geometry().
        \li Supports layouts with setLayout() and layout().
        \li Supports shortcuts and actions with grabShortcut() and insertAction()
    \endlist

    Unlike QGraphicsItem, QGraphicsWidget is not an abstract class; you can
    create instances of a QGraphicsWidget without having to subclass it.
    This approach is useful for widgets that only serve the purpose of
    organizing child widgets into a layout.

    QGraphicsWidget can be used as a base item for your own custom item if
    you require advanced input focus handling, e.g., tab focus and activation, or
    layouts.

    Since QGraphicsWidget resembles QWidget and has similar API, it is
    easier to port a widget from QWidget to QGraphicsWidget, instead of
    QGraphicsItem.

    \note QWidget-based widgets can be directly embedded into a
    QGraphicsScene using QGraphicsProxyWidget.

    Noticeable differences between QGraphicsWidget and QWidget are:

    \table
    \header \li QGraphicsWidget
                \li QWidget
    \row      \li Coordinates and geometry are defined with qreals (doubles or
                    floats, depending on the platform).
                \li QWidget uses integer geometry (QPoint, QRect).
    \row      \li The widget is already visible by default; you do not have to
                    call show() to display the widget.
                \li QWidget is hidden by default until you call show().
    \row      \li A subset of widget attributes are supported.
                \li All widget attributes are supported.
    \row      \li A top-level item's style defaults to QGraphicsScene::style
                \li A top-level widget's style defaults to QApplication::style
    \row      \li Graphics View provides a custom drag and drop framework, different
                    from QWidget.
                \li Standard drag and drop framework.
    \row      \li Widget items do not support modality.
                \li Full modality support.
    \endtable

    QGraphicsWidget supports a subset of Qt's widget attributes,
    (Qt::WidgetAttribute), as shown in the table below. Any attributes not
    listed in this table are unsupported, or otherwise unused.

    \table
    \header \li Widget Attribute                         \li Usage
    \row    \li Qt::WA_SetLayoutDirection
                    \li Set by setLayoutDirection(), cleared by
                        unsetLayoutDirection(). You can test this attribute to
                        check if the widget has been explicitly assigned a
                        \l{QGraphicsWidget::layoutDirection()}
                        {layoutDirection}. If the attribute is not set, the
                        \l{QGraphicsWidget::layoutDirection()}
                        {layoutDirection()} is inherited.
    \row    \li Qt::WA_RightToLeft
                    \li Toggled by setLayoutDirection(). Inherited from the
                        parent/scene. If set, the widget's layout will order
                        horizontally arranged widgets from right to left.
    \row    \li Qt::WA_SetStyle
                    \li Set and cleared by setStyle(). If this attribute is
                        set, the widget has been explicitly assigned a style.
                        If it is unset, the widget will use the scene's or the
                        application's style.
    \row    \li Qt::WA_Resized
                    \li Set by setGeometry() and resize().
    \row    \li Qt::WA_SetPalette
                    \li Set by setPalette().
    \row    \li Qt::WA_SetFont
                    \li Set by setFont().
    \row    \li Qt::WA_WindowPropagation
                    \li Enables propagation to window widgets.
    \endtable

    Although QGraphicsWidget inherits from both QObject and QGraphicsItem,
    you should use the functions provided by QGraphicsItem, \e not QObject, to
    manage the relationships between parent and child items. These functions
    control the stacking order of items as well as their ownership.

    \note The QObject::parent() should always return \nullptr for QGraphicsWidgets,
    but this policy is not strictly defined.

    \sa QGraphicsProxyWidget, QGraphicsItem, {Widgets and Layouts}
*/

/*!
    Constructs a QGraphicsWidget instance. The optional \a parent argument is
    passed to QGraphicsItem's constructor. The optional \a wFlags argument
    specifies the widget's window flags (e.g., whether the widget should be a
    window, a tool, a popup, etc).
*/
QGraphicsWidget::QGraphicsWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)
    : QGraphicsObject(*new QGraphicsWidgetPrivate, 0), QGraphicsLayoutItem(0, false)
{
    Q_D(QGraphicsWidget);
    d->init(parent, wFlags);
}

/*!
    \internal

    Constructs a new QGraphicsWidget, using \a dd as parent.
*/
QGraphicsWidget::QGraphicsWidget(QGraphicsWidgetPrivate &dd, QGraphicsItem *parent, Qt::WindowFlags wFlags)
    : QGraphicsObject(dd, 0), QGraphicsLayoutItem(0, false)
{
    Q_D(QGraphicsWidget);
    d->init(parent, wFlags);
}

/*
    \internal
    \class QGraphicsWidgetStyles

    We use this thread-safe class to maintain a hash of styles for widgets
    styles. Note that QApplication::style() itself isn't thread-safe, QStyle
    isn't thread-safe, and we don't have a thread-safe factory for creating
    the default style, nor cloning a style.
*/
class QGraphicsWidgetStyles
{
public:
    QStyle *styleForWidget(const QGraphicsWidget *widget) const
    {
        QMutexLocker locker(&mutex);
        return styles.value(widget, 0);
    }

    void setStyleForWidget(QGraphicsWidget *widget, QStyle *style)
    {
        QMutexLocker locker(&mutex);
        if (style)
            styles[widget] = style;
        else
            styles.remove(widget);
    }

private:
    QHash<const QGraphicsWidget *, QStyle *> styles;
    mutable QMutex mutex;
};
Q_GLOBAL_STATIC(QGraphicsWidgetStyles, widgetStyles)

/*!
    Destroys the QGraphicsWidget instance.
*/
QGraphicsWidget::~QGraphicsWidget()
{
    Q_D(QGraphicsWidget);
#ifndef QT_NO_ACTION
    // Remove all actions from this widget
    for (int i = 0; i < d->actions.size(); ++i) {
        QActionPrivate *apriv = d->actions.at(i)->d_func();
        apriv->graphicsWidgets.removeAll(this);
    }
    d->actions.clear();
#endif

    if (QGraphicsScene *scn = scene()) {
        QGraphicsScenePrivate *sceneD = scn->d_func();
        if (sceneD->tabFocusFirst == this)
            sceneD->tabFocusFirst = (d->focusNext == this ? 0 : d->focusNext);
    }
    d->focusPrev->d_func()->focusNext = d->focusNext;
    d->focusNext->d_func()->focusPrev = d->focusPrev;

    // Play it really safe
    d->focusNext = this;
    d->focusPrev = this;

    clearFocus();

    //we check if we have a layout previously
    if (d->layout) {
        QGraphicsLayout *temp = d->layout;
        const auto items = childItems();
        for (QGraphicsItem *item : items) {
            // In case of a custom layout which doesn't remove and delete items, we ensure that
            // the parent layout item does not point to the deleted layout. This code is here to
            // avoid regression from 4.4 to 4.5, because according to 4.5 docs it is not really needed.
            if (item->isWidget()) {
                QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
                if (widget->parentLayoutItem() == d->layout)
                    widget->setParentLayoutItem(0);
            }
        }
        d->layout = 0;
        delete temp;
    }

    // Remove this graphics widget from widgetStyles
    widgetStyles()->setStyleForWidget(this, 0);

    // Unset the parent here, when we're still a QGraphicsWidget.
    // It is otherwise done in ~QGraphicsItem() where we'd be
    // calling QGraphicsWidget members on an ex-QGraphicsWidget object
    setParentItem(nullptr);
}

/*!
    \property QGraphicsWidget::size
    \brief the size of the widget

    Calling resize() resizes the widget to a \a size bounded by minimumSize()
    and maximumSize(). This property only affects the widget's width and
    height (e.g., its right and bottom edges); the widget's position and
    top-left corner remains unaffected.

    Resizing a widget triggers the widget to immediately receive a
    \l{QEvent::GraphicsSceneResize}{GraphicsSceneResize} event with the
    widget's old and new size.  If the widget has a layout assigned when this
    event arrives, the layout will be activated and it will automatically
    update any child widgets's geometry.

    This property does not affect any layout of the parent widget. If the
    widget itself is managed by a parent layout; e.g., it has a parent widget
    with a layout assigned, that layout will not activate.

    By default, this property contains a size with zero width and height.

    \sa setGeometry(), QGraphicsSceneResizeEvent, QGraphicsLayout
*/
QSizeF QGraphicsWidget::size() const
{
    return QGraphicsLayoutItem::geometry().size();
}

void QGraphicsWidget::resize(const QSizeF &size)
{
    setGeometry(QRectF(pos(), size));
}

/*!
    \fn void QGraphicsWidget::resize(qreal w, qreal h)
    \overload

    Constructs a resize with the given \c width (\a w) and \c height (\a h).
    This convenience function is equivalent to calling resize(QSizeF(w, h)).

    \sa setGeometry(), setTransform()
*/

/*!
    \property QGraphicsWidget::sizePolicy
    \brief the size policy for the widget
    \sa sizePolicy(), setSizePolicy(), QWidget::sizePolicy()
*/

/*!
  \fn QGraphicsWidget::geometryChanged()

  This signal gets emitted whenever the geometry is changed in setGeometry().
*/

/*!
    \property QGraphicsWidget::geometry
    \brief the geometry of the widget

    Sets the item's geometry to \a rect. The item's position and size are
    modified as a result of calling this function. The item is first moved,
    then resized.

    A side effect of calling this function is that the widget will receive
    a move event and a resize event. Also, if the widget has a layout
    assigned, the layout will activate.

    \sa geometry(), resize()
*/
void QGraphicsWidget::setGeometry(const QRectF &rect)
{
    QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func();
    QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr.data();
    QRectF newGeom;
    QPointF oldPos = d->geom.topLeft();
    if (!wd->inSetPos) {
        setAttribute(Qt::WA_Resized);
        newGeom = rect;
        newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
                                   .boundedTo(effectiveSizeHint(Qt::MaximumSize)));

        if (newGeom == d->geom) {
            goto relayoutChildrenAndReturn;
        }

        // setPos triggers ItemPositionChange, which can adjust position
        wd->inSetGeometry = 1;
        setPos(newGeom.topLeft());
        wd->inSetGeometry = 0;
        newGeom.moveTopLeft(pos());

        if (newGeom == d->geom) {
            goto relayoutChildrenAndReturn;
        }

         // Update and prepare to change the geometry (remove from index) if the size has changed.
        if (wd->scene) {
            if (rect.topLeft() == d->geom.topLeft()) {
                prepareGeometryChange();
            }
        }
    }

    // Update the layout item geometry
    {
        bool moved = oldPos != pos();
        if (moved) {
            // Send move event.
            QGraphicsSceneMoveEvent event;
            event.setOldPos(oldPos);
            event.setNewPos(pos());
            QCoreApplication::sendEvent(this, &event);
            if (wd->inSetPos) {
                //set the new pos
                d->geom.moveTopLeft(pos());
                emit geometryChanged();
                goto relayoutChildrenAndReturn;
            }
        }
        QSizeF oldSize = size();
        QGraphicsLayoutItem::setGeometry(newGeom);
        // Send resize event
        bool resized = newGeom.size() != oldSize;
        if (resized) {
            QGraphicsSceneResizeEvent re;
            re.setOldSize(oldSize);
            re.setNewSize(newGeom.size());
            if (oldSize.width() != newGeom.size().width())
                emit widthChanged();
            if (oldSize.height() != newGeom.size().height())
                emit heightChanged();
            QGraphicsLayout *lay = wd->layout;
            if (QGraphicsLayout::instantInvalidatePropagation()) {
                if (!lay || lay->isActivated()) {
                    QCoreApplication::sendEvent(this, &re);
                }
            } else {
                QCoreApplication::sendEvent(this, &re);
            }
        }
    }

    emit geometryChanged();
relayoutChildrenAndReturn:
    if (QGraphicsLayout::instantInvalidatePropagation()) {
        if (QGraphicsLayout *lay = wd->layout) {
            if (!lay->isActivated()) {
                QEvent layoutRequest(QEvent::LayoutRequest);
                QCoreApplication::sendEvent(this, &layoutRequest);
            }
        }
    }
}

/*!
    \fn QRectF QGraphicsWidget::rect() const

    Returns the item's local rect as a QRectF. This function is equivalent
    to QRectF(QPointF(), size()).

    \sa setGeometry(), resize()
*/

/*!
    \fn void QGraphicsWidget::setGeometry(qreal x, qreal y, qreal w, qreal h)

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

    \sa geometry(), resize()
*/

/*!
    \property QGraphicsWidget::minimumSize
    \brief the minimum size of the widget

    \sa setMinimumSize(), minimumSize(), preferredSize, maximumSize
*/

/*!
    \property QGraphicsWidget::preferredSize
    \brief the preferred size of the widget

    \sa setPreferredSize(), preferredSize(), minimumSize, maximumSize
*/

/*!
    \property QGraphicsWidget::maximumSize
    \brief the maximum size of the widget

    \sa setMaximumSize(), maximumSize(), minimumSize, preferredSize
*/

/*!
    \since 5.14

    Sets the widget's contents margins to \a margins.

    Contents margins are used by the assigned layout to define the placement
    of subwidgets and layouts. Margins are particularly useful for widgets
    that constrain subwidgets to only a section of its own geometry. For
    example, a group box with a layout will place subwidgets inside its frame,
    but below the title.

    Changing a widget's contents margins will always trigger an update(), and
    any assigned layout will be activated automatically. The widget will then
    receive a \l{QEvent::ContentsRectChange}{ContentsRectChange} event.

    \sa getContentsMargins(), setGeometry()
*/
void QGraphicsWidget::setContentsMargins(QMarginsF margins)
{
    Q_D(QGraphicsWidget);

    if (!d->margins && margins.isNull())
        return;
    d->ensureMargins();
    if (*d->margins == margins)
        return;

    *d->margins = margins;

    if (QGraphicsLayout *l = d->layout)
        l->invalidate();
    else
        updateGeometry();

    QEvent e(QEvent::ContentsRectChange);
    QCoreApplication::sendEvent(this, &e);
}

/*!
    \overload

    Sets the widget's contents margins to \a left, \a top, \a right and \a
    bottom.
*/
void QGraphicsWidget::setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)
{
    setContentsMargins({left, top, right, bottom});
}

/*!
    Gets the widget's contents margins. The margins are stored in \a left, \a
    top, \a right and \a bottom, as pointers to qreals. Each argument can
    be \e {omitted} by passing \nullptr.

    \sa setContentsMargins()
*/
void QGraphicsWidget::getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
{
    Q_D(const QGraphicsWidget);
    if (left || top || right || bottom)
        d->ensureMargins();
    if (left)
        *left = d->margins->left();
    if (top)
        *top = d->margins->top();
    if (right)
        *right = d->margins->right();
    if (bottom)
        *bottom = d->margins->bottom();
}

/*!
    \since 5.14
    Sets the widget's window frame margins to \a margins.
    The default frame margins are provided by the style, and they
    depend on the current window flags.

    If you would like to draw your own window decoration, you can set your
    own frame margins to override the default margins.

    \sa unsetWindowFrameMargins(), getWindowFrameMargins(), windowFrameRect()
*/
void QGraphicsWidget::setWindowFrameMargins(QMarginsF margins)
{
    Q_D(QGraphicsWidget);

    if (!d->windowFrameMargins && margins.isNull())
        return;
    d->ensureWindowFrameMargins();
    const bool unchanged = *d->windowFrameMargins == margins;
    if (d->setWindowFrameMargins && unchanged)
        return;
    if (!unchanged)
        prepareGeometryChange();
    *d->windowFrameMargins = margins;
    d->setWindowFrameMargins = true;
}

/*!
    \overload
    Sets the widget's window frame margins to \a left, \a top, \a right and
    \a bottom.
*/
void QGraphicsWidget::setWindowFrameMargins(qreal left, qreal top, qreal right, qreal bottom)
{
    setWindowFrameMargins({left, top, right, bottom});
}

/*!
    Gets the widget's window frame margins. The margins are stored in \a left,
    \a top, \a right and \a bottom as pointers to qreals. Each argument can
    be \e {omitted} by passing \nullptr.

    \sa setWindowFrameMargins(), windowFrameRect()
*/
void QGraphicsWidget::getWindowFrameMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
{
    Q_D(const QGraphicsWidget);
    if (left || top || right || bottom)
        d->ensureWindowFrameMargins();
    if (left)
        *left = d->windowFrameMargins->left();
    if (top)
        *top = d->windowFrameMargins->top();
    if (right)
        *right = d->windowFrameMargins->right();
    if (bottom)
        *bottom = d->windowFrameMargins->bottom();
}

/*!
    Resets the window frame margins to the default value, provided by the style.

    \sa setWindowFrameMargins(), getWindowFrameMargins(), windowFrameRect()
*/
void QGraphicsWidget::unsetWindowFrameMargins()
{
    Q_D(QGraphicsWidget);
    if ((d->windowFlags & Qt::Window) && (d->windowFlags & Qt::WindowType_Mask) != Qt::Popup &&
         (d->windowFlags & Qt::WindowType_Mask) != Qt::ToolTip && !(d->windowFlags & Qt::FramelessWindowHint)) {
        QStyleOptionTitleBar bar;
        d->initStyleOptionTitleBar(&bar);
        QStyle *style = this->style();
        qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth);
        qreal titleBarHeight  = d->titleBarHeight(bar);
        setWindowFrameMargins(margin, titleBarHeight, margin, margin);
    } else {
        setWindowFrameMargins(0, 0, 0, 0);
    }
    d->setWindowFrameMargins = false;
}

/*!
    Returns the widget's geometry in parent coordinates including any window
    frame.

    \sa windowFrameRect(), getWindowFrameMargins(), setWindowFrameMargins()
*/
QRectF QGraphicsWidget::windowFrameGeometry() const
{
    Q_D(const QGraphicsWidget);
    return d->windowFrameMargins
        ? geometry().adjusted(-d->windowFrameMargins->left(), -d->windowFrameMargins->top(),
                              d->windowFrameMargins->right(), d->windowFrameMargins->bottom())
        : geometry();
}

/*!
    Returns the widget's local rect including any window frame.

    \sa windowFrameGeometry(), getWindowFrameMargins(), setWindowFrameMargins()
*/
QRectF QGraphicsWidget::windowFrameRect() const
{
    Q_D(const QGraphicsWidget);
    return d->windowFrameMargins
        ? rect().adjusted(-d->windowFrameMargins->left(), -d->windowFrameMargins->top(),
                          d->windowFrameMargins->right(), d->windowFrameMargins->bottom())
        : rect();
}

/*!
    Populates a style option object for this widget based on its current
    state, and stores the output in \a option. The default implementation
    populates \a option with the following properties.

    \table
      \header
        \li Style Option Property
        \li Value
      \row
        \li state & QStyle::State_Enabled
        \li Corresponds to QGraphicsItem::isEnabled().
      \row
        \li state & QStyle::State_HasFocus
        \li Corresponds to QGraphicsItem::hasFocus().
      \row
        \li state & QStyle::State_MouseOver
        \li Corresponds to QGraphicsItem::isUnderMouse().
      \row
        \li direction
        \li Corresponds to QGraphicsWidget::layoutDirection().
      \row
        \li rect
        \li Corresponds to QGraphicsWidget::rect().toRect().
      \row
        \li palette
        \li Corresponds to QGraphicsWidget::palette().
      \row
        \li fontMetrics
        \li Corresponds to QFontMetrics(QGraphicsWidget::font()).
    \endtable

    Subclasses of QGraphicsWidget should call the base implementation, and
    then test the type of \a option using qstyleoption_cast<>() or test
    QStyleOption::Type before storing widget-specific options.

    For example:

    \snippet code/src_gui_graphicsview_qgraphicswidget.cpp 0

    \sa QStyleOption::initFrom()
*/
void QGraphicsWidget::initStyleOption(QStyleOption *option) const
{
    Q_ASSERT(option);

    option->state = QStyle::State_None;
    if (isEnabled())
        option->state |= QStyle::State_Enabled;
    if (hasFocus())
        option->state |= QStyle::State_HasFocus;
    // if (window->testAttribute(Qt::WA_KeyboardFocusChange)) // ### Window
    //     option->state |= QStyle::State_KeyboardFocusChange;
    if (isUnderMouse())
        option->state |= QStyle::State_MouseOver;
    if (QGraphicsWidget *w = window()) {
        if (w->isActiveWindow())
            option->state |= QStyle::State_Active;
    }
    if (isWindow())
        option->state |= QStyle::State_Window;
    /*
      ###
#ifdef QT_KEYPAD_NAVIGATION
    if (widget->hasEditFocus())
        state |= QStyle::State_HasEditFocus;
#endif
    */
    option->direction = layoutDirection();
    option->rect = rect().toRect(); // ### truncation!
    option->palette = palette();
    if (!isEnabled()) {
        option->palette.setCurrentColorGroup(QPalette::Disabled);
    } else if (isActiveWindow()) {
        option->palette.setCurrentColorGroup(QPalette::Active);
    } else {
        option->palette.setCurrentColorGroup(QPalette::Inactive);
    }
    option->fontMetrics = QFontMetrics(font());
    option->styleObject = const_cast<QGraphicsWidget *>(this);
}

/*!
    \reimp
*/
QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
    Q_D(const QGraphicsWidget);
    QSizeF sh;
    if (d->layout) {
        QSizeF marginSize(0,0);
        if (d->margins) {
            marginSize = QSizeF(d->margins->left() + d->margins->right(),
                         d->margins->top() + d->margins->bottom());
        }
        sh = d->layout->effectiveSizeHint(which, constraint - marginSize);
        sh += marginSize;
    } else {
        switch (which) {
            case Qt::MinimumSize:
                sh = QSizeF(0, 0);
                break;
            case Qt::PreferredSize:
                sh = QSizeF(50, 50);    //rather arbitrary
                break;
            case Qt::MaximumSize:
                sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
                break;
            default:
                qWarning("QGraphicsWidget::sizeHint(): Don't know how to handle the value of 'which'");
                break;
        }
    }
    return sh;
}

/*!
    \property QGraphicsWidget::layout
    \brief The layout of the widget

    Any existing layout manager is deleted before the new layout is assigned. If
     \a layout is \nullptr, the widget is left without a layout. Existing subwidgets'
    geometries will remain unaffected.

    QGraphicsWidget takes ownership of \a layout.

    All widgets that are currently managed by \a layout or all of its
    sublayouts, are automatically reparented to this item. The layout is then
    invalidated, and the child widget geometries are adjusted according to
    this item's geometry() and contentsMargins(). Children who are not
    explicitly managed by \a layout remain unaffected by the layout after
    it has been assigned to this widget.

    If no layout is currently managing this widget, layout() will return \nullptr.

*/

/*!
    \fn void QGraphicsWidget::layoutChanged()
    This signal gets emitted whenever the layout of the item changes
    \internal
*/

/*!
    Returns this widget's layout, or \nullptr if no layout is currently
    managing this widget.

    \sa setLayout()
*/
QGraphicsLayout *QGraphicsWidget::layout() const
{
    Q_D(const QGraphicsWidget);
    return d->layout;
}

/*!
    \fn void QGraphicsWidget::setLayout(QGraphicsLayout *layout)

    Sets the layout for this widget to \a layout. Any existing layout manager
    is deleted before the new layout is assigned. If \a layout is \nullptr, the
    widget is left without a layout. Existing subwidgets' geometries will
    remain unaffected.

    All widgets that are currently managed by \a layout or all of its
    sublayouts, are automatically reparented to this item. The layout is then
    invalidated, and the child widget geometries are adjusted according to
    this item's geometry() and contentsMargins(). Children who are not
    explicitly managed by \a layout remain unaffected by the layout after
    it has been assigned to this widget.

    QGraphicsWidget takes ownership of \a layout.

    \sa layout(), QGraphicsLinearLayout::addItem(), QGraphicsLayout::invalidate()
*/
void QGraphicsWidget::setLayout(QGraphicsLayout *l)
{
    Q_D(QGraphicsWidget);
    if (d->layout == l)
        return;
    d->setLayout_helper(l);
    if (!l)
        return;

    // Prevent assigning a layout that is already assigned to another widget.
    QGraphicsLayoutItem *oldParent = l->parentLayoutItem();
    if (oldParent && oldParent != this) {
        qWarning("QGraphicsWidget::setLayout: Attempting to set a layout on %s"
                 " \"%s\", when the layout already has a parent",
                 metaObject()->className(), qPrintable(objectName()));
        return;
    }

    // Install and activate the layout.
    l->setParentLayoutItem(this);
    l->d_func()->reparentChildItems(this);
    l->invalidate();
    emit layoutChanged();
}

/*!
    Adjusts the size of the widget to its effective preferred size hint.

    This function is called implicitly when the item is shown for the first
    time.

    \sa effectiveSizeHint(), Qt::MinimumSize
*/
void QGraphicsWidget::adjustSize()
{
    QSizeF sz = effectiveSizeHint(Qt::PreferredSize);
    // What if sz is not valid?!
    if (sz.isValid())
        resize(sz);
}

/*!
    \property QGraphicsWidget::layoutDirection
    \brief the layout direction for this widget.

    This property modifies this widget's and all of its descendants'
    Qt::WA_RightToLeft attribute. It also sets this widget's
    Qt::WA_SetLayoutDirection attribute.

    The widget's layout direction determines the order in which the layout
    manager horizontally arranges subwidgets of this widget. The default
    value depends on the language and locale of the application, and is
    typically in the same direction as words are read and written. With
    Qt::LeftToRight, the layout starts placing subwidgets from the left
    side of this widget towards the right. Qt::RightToLeft does the opposite -
    the layout will place widgets starting from the right edge moving towards
    the left.

    Subwidgets inherit their layout direction from the parent. Top-level
    widget items inherit their layout direction from
    QGraphicsScene::layoutDirection. If you change a widget's layout direction
    by calling setLayoutDirection(), the widget will send itself a
    \l{QEvent::LayoutDirectionChange}{LayoutDirectionChange} event, and then
    propagate the new layout direction to all its descendants.

    \sa QWidget::layoutDirection, QApplication::layoutDirection
*/
Qt::LayoutDirection QGraphicsWidget::layoutDirection() const
{
    return testAttribute(Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight;
}
void QGraphicsWidget::setLayoutDirection(Qt::LayoutDirection direction)
{
    Q_D(QGraphicsWidget);
    setAttribute(Qt::WA_SetLayoutDirection, true);
    d->setLayoutDirection_helper(direction);
}
void QGraphicsWidget::unsetLayoutDirection()
{
    Q_D(QGraphicsWidget);
    setAttribute(Qt::WA_SetLayoutDirection, false);
    d->resolveLayoutDirection();
}

/*!
    Returns a pointer to the widget's style. If this widget does not have any
    explicitly assigned style, the scene's style is returned instead. In turn,
    if the scene does not have any assigned style, this function returns
    QApplication::style().

    \sa setStyle()
*/
QStyle *QGraphicsWidget::style() const
{
    if (QStyle *style = widgetStyles()->styleForWidget(this))
        return style;
    // ### This is not thread-safe. QApplication::style() is not thread-safe.
    return scene() ? scene()->style() : QApplication::style();
}

/*!
    Sets the widget's style to \a style. QGraphicsWidget does \e not take
    ownership of \a style.

    If no style is assigned, or \a style is \nullptr, the widget will use
    QGraphicsScene::style() (if this has been set). Otherwise the widget will
    use QApplication::style().

    This function sets the Qt::WA_SetStyle attribute if \a style is not \nullptr;
    otherwise it clears the attribute.

    \sa style()
*/
void QGraphicsWidget::setStyle(QStyle *style)
{
    setAttribute(Qt::WA_SetStyle, style != 0);
    widgetStyles()->setStyleForWidget(this, style);

    // Deliver StyleChange to the widget itself (doesn't propagate).
    QEvent event(QEvent::StyleChange);
    QCoreApplication::sendEvent(this, &event);
}

/*!
    \property QGraphicsWidget::font
    \brief the widgets' font

    This property provides the widget's font.

    QFont consists of font properties that have been explicitly defined and
    properties implicitly inherited from the widget's parent. Hence, font()
    can return a different font compared to the one set with setFont().
    This scheme allows you to define single entries in a font without
    affecting the font's inherited entries.

    When a widget's font changes, it resolves its entries against its
    parent widget. If the widget does not have a parent widget, it resolves
    its entries against the scene. The widget then sends itself a
    \l{QEvent::FontChange}{FontChange} event and notifies all its
    descendants so that they can resolve their fonts as well.

    By default, this property contains the application's default font.

    \sa QApplication::font(), QGraphicsScene::font, QFont::resolve()
*/
QFont QGraphicsWidget::font() const
{
    Q_D(const QGraphicsWidget);
    QFont fnt = d->font;
    fnt.resolve(fnt.resolve() | d->inheritedFontResolveMask);
    return fnt;
}
void QGraphicsWidget::setFont(const QFont &font)
{
    Q_D(QGraphicsWidget);
    setAttribute(Qt::WA_SetFont, font.resolve() != 0);

    QFont naturalFont = d->naturalWidgetFont();
    QFont resolvedFont = font.resolve(naturalFont);
    d->setFont_helper(resolvedFont);
}

/*!
    \property QGraphicsWidget::palette
    \brief the widget's palette

    This property provides the widget's palette. The palette provides colors
    and brushes for color groups (e.g., QPalette::Button) and states (e.g.,
    QPalette::Inactive), loosely defining the general look of the widget and
    its children.

    QPalette consists of color groups that have been explicitly defined, and
    groups that are implicitly inherited from the widget's parent. Because of
    this, palette() can return a different palette than what has been set with
    setPalette(). This scheme allows you to define single entries in a palette
    without affecting the palette's inherited entries.

    When a widget's palette changes, it resolves its entries against its
    parent widget, or if it doesn't have a parent widget, it resolves against
    the scene. It then sends itself a \l{QEvent::PaletteChange}{PaletteChange}
    event, and notifies all its descendants so they can resolve their palettes
    as well.

    By default, this property contains the application's default palette.

    \sa QGuiApplication::palette(), QGraphicsScene::palette, QPalette::resolve()
*/
QPalette QGraphicsWidget::palette() const
{
    Q_D(const QGraphicsWidget);
    return d->palette;
}
void QGraphicsWidget::setPalette(const QPalette &palette)
{
    Q_D(QGraphicsWidget);
    setAttribute(Qt::WA_SetPalette, palette.resolve() != 0);

    QPalette naturalPalette = d->naturalWidgetPalette();
    QPalette resolvedPalette = palette.resolve(naturalPalette);
    d->setPalette_helper(resolvedPalette);
}

/*!
    \property QGraphicsWidget::autoFillBackground
    \brief whether the widget background is filled automatically
    \since 4.7

    If enabled, this property will cause Qt to fill the background of the
    widget before invoking the paint() method. The color used is defined by the
    QPalette::Window color role from the widget's \l{QPalette}{palette}.

    In addition, Windows are always filled with QPalette::Window, unless the
    WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set.

    By default, this property is \c false.

    \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground,
*/
bool QGraphicsWidget::autoFillBackground() const
{
    Q_D(const QGraphicsWidget);
    return d->autoFillBackground;
}
void QGraphicsWidget::setAutoFillBackground(bool enabled)
{
    Q_D(QGraphicsWidget);
    if (d->autoFillBackground != enabled) {
        d->autoFillBackground = enabled;
        update();
    }
}

/*!
    If this widget is currently managed by a layout, this function notifies
    the layout that the widget's size hints have changed and the layout
    may need to resize and reposition the widget accordingly.

    Call this function if the widget's sizeHint() has changed.

    \sa QGraphicsLayout::invalidate()
*/
void QGraphicsWidget::updateGeometry()
{
    QGraphicsLayoutItem::updateGeometry();
    QGraphicsLayoutItem *parentItem = parentLayoutItem();

    if (parentItem && parentItem->isLayout()) {
        if (QGraphicsLayout::instantInvalidatePropagation()) {
            static_cast<QGraphicsLayout *>(parentItem)->invalidate();
        } else {
            parentItem->updateGeometry();
        }
    } else {
        if (parentItem) {
            // This is for custom layouting
            QGraphicsWidget *parentWid = parentWidget();    //###
            if (parentWid->isVisible())
                QCoreApplication::postEvent(parentWid, new QEvent(QEvent::LayoutRequest));
        } else {
            /**
             * If this is the topmost widget, post a LayoutRequest event to the widget.
             * When the event is received, it will start flowing all the way down to the leaf
             * widgets in one go. This will make a relayout flicker-free.
             */
            if (QGraphicsLayout::instantInvalidatePropagation())
                QCoreApplication::postEvent(static_cast<QGraphicsWidget *>(this), new QEvent(QEvent::LayoutRequest));
        }
        if (!QGraphicsLayout::instantInvalidatePropagation()) {
            bool wasResized = testAttribute(Qt::WA_Resized);
            resize(size()); // this will restrict the size
            setAttribute(Qt::WA_Resized, wasResized);
        }
    }
}

/*!
    \reimp

    QGraphicsWidget uses the base implementation of this function to catch and
    deliver events related to state changes in the item. Because of this, it is
    very important that subclasses call the base implementation.

    \a change specifies the type of change, and \a value is the new value.

    For example, QGraphicsWidget uses ItemVisibleChange to deliver
    \l{QEvent::Show} {Show} and \l{QEvent::Hide}{Hide} events,
    ItemPositionHasChanged to deliver \l{QEvent::Move}{Move} events,
    and ItemParentChange both to deliver \l{QEvent::ParentChange}
    {ParentChange} events, and for managing the focus chain.

    QGraphicsWidget enables the ItemSendsGeometryChanges flag by default in
    order to track position changes.

    \sa QGraphicsItem::itemChange()
*/
QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value)
{
    Q_D(QGraphicsWidget);
    switch (change) {
    case ItemEnabledHasChanged: {
        // Send EnabledChange after the enabled state has changed.
        QEvent event(QEvent::EnabledChange);
        QCoreApplication::sendEvent(this, &event);
        break;
    }
    case ItemVisibleChange:
        if (value.toBool()) {
            // Send Show event before the item has been shown.
            QShowEvent event;
            QCoreApplication::sendEvent(this, &event);
            bool resized = testAttribute(Qt::WA_Resized);
            if (!resized) {
                adjustSize();
                setAttribute(Qt::WA_Resized, false);
            }
        }

        // layout size hint only changes if an item changes from/to explicitly hidden state
        if (value.toBool() || d->explicitlyHidden)
            updateGeometry();
        break;
    case ItemVisibleHasChanged:
        if (!value.toBool()) {
            // Send Hide event after the item has been hidden.
            QHideEvent event;
            QCoreApplication::sendEvent(this, &event);
        }
        break;
    case ItemPositionHasChanged:
        d->setGeometryFromSetPos();
        break;
    case ItemParentChange: {
        // Deliver ParentAboutToChange.
        QEvent event(QEvent::ParentAboutToChange);
        QCoreApplication::sendEvent(this, &event);
        break;
    }
    case ItemParentHasChanged: {
        // Deliver ParentChange.
        QEvent event(QEvent::ParentChange);
        QCoreApplication::sendEvent(this, &event);
        break;
    }
    case ItemCursorHasChanged: {
        // Deliver CursorChange.
        QEvent event(QEvent::CursorChange);
        QCoreApplication::sendEvent(this, &event);
        break;
    }
    case ItemToolTipHasChanged: {
        // Deliver ToolTipChange.
        QEvent event(QEvent::ToolTipChange);
        QCoreApplication::sendEvent(this, &event);
        break;
    }
    default:
        break;
    }
    return QGraphicsItem::itemChange(change, value);
}

/*!
    \internal

    This virtual function is used to notify changes to any property (both
    dynamic properties, and registered with Q_PROPERTY) in the
    widget. Depending on the property itself, the notification can be
    delivered before or after the value has changed.

    \a propertyName is the name of the property (e.g., "size" or "font"), and
    \a value is the (proposed) new value of the property. The function returns
    the new value, which may be different from \a value if the notification
    supports adjusting the property value. The base implementation simply
    returns \a value for any \a propertyName.

    QGraphicsWidget delivers notifications for the following properties:

    \table
    \header    \li propertyName        \li Property
    \row       \li layoutDirection     \li QGraphicsWidget::layoutDirection
    \row       \li size                \li QGraphicsWidget::size
    \row       \li font                \li QGraphicsWidget::font
    \row       \li palette             \li QGraphicsWidget::palette
    \endtable

    \sa itemChange()
*/
QVariant QGraphicsWidget::propertyChange(const QString &propertyName, const QVariant &value)
{
    Q_UNUSED(propertyName);
    return value;
}

/*!
    QGraphicsWidget's implementation of sceneEvent() simply passes \a event to
    QGraphicsWidget::event(). You can handle all events for your widget in
    event() or in any of the convenience functions; you should not have to
    reimplement this function in a subclass of QGraphicsWidget.

    Returns \c true if \a event has been recognized and processed; otherwise,
    returns \c false.

    \sa QGraphicsItem::sceneEvent()
*/
bool QGraphicsWidget::sceneEvent(QEvent *event)
{
    return QGraphicsItem::sceneEvent(event);
}

/*!
    This event handler, for \a event, receives events for the window frame if
    this widget is a window. Its base implementation provides support for
    default window frame interaction such as moving, resizing, etc.

    You can reimplement this handler in a subclass of QGraphicsWidget to
    provide your own custom window frame interaction support.

    Returns \c true if \a event has been recognized and processed; otherwise,
    returns \c false.

    \sa event()
*/
bool QGraphicsWidget::windowFrameEvent(QEvent *event)
{
    Q_D(QGraphicsWidget);
    switch (event->type()) {
    case QEvent::GraphicsSceneMousePress:
        d->windowFrameMousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
        break;
    case QEvent::GraphicsSceneMouseMove:
        d->ensureWindowData();
        if (d->windowData->grabbedSection != Qt::NoSection) {
            d->windowFrameMouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
            event->accept();
        }
        break;
    case QEvent::GraphicsSceneMouseRelease:
        d->windowFrameMouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
        break;
    case QEvent::GraphicsSceneHoverMove:
        d->windowFrameHoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
        break;
    case QEvent::GraphicsSceneHoverLeave:
        d->windowFrameHoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
        break;
    default:
        break;
    }
    return event->isAccepted();
}

/*!
    \since 4.4

    Returns the window frame section at position \a pos, or
    Qt::NoSection if there is no window frame section at this
    position.

    This function is used in QGraphicsWidget's base implementation for window
    frame interaction.

    You can reimplement this function if you want to customize how a window
    can be interactively moved or resized.  For instance, if you only want to
    allow a window to be resized by the bottom right corner, you can
    reimplement this function to return Qt::NoSection for all sections except
    Qt::BottomRightSection.

    \sa windowFrameEvent(), paintWindowFrame(), windowFrameGeometry()
*/
Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) const
{
    Q_D(const QGraphicsWidget);

    const QRectF r = windowFrameRect();
    if (!r.contains(pos))
        return Qt::NoSection;

    const qreal left = r.left();
    const qreal top = r.top();
    const qreal right = r.right();
    const qreal bottom = r.bottom();
    const qreal x = pos.x();
    const qreal y = pos.y();

    const qreal cornerMargin = 20;
    //### Not sure of this one, it should be the same value for all edges.
    const qreal windowFrameWidth = d->windowFrameMargins
        ? d->windowFrameMargins->left() : 0;

    Qt::WindowFrameSection s = Qt::NoSection;
    if (x <= left + cornerMargin) {
        if (y <= top + windowFrameWidth || (x <= left + windowFrameWidth && y <= top + cornerMargin)) {
            s = Qt::TopLeftSection;
        } else if (y >= bottom - windowFrameWidth || (x <= left + windowFrameWidth && y >= bottom - cornerMargin)) {
            s = Qt::BottomLeftSection;
        } else if (x <= left + windowFrameWidth) {
            s = Qt::LeftSection;
        }
    } else if (x >= right - cornerMargin) {
        if (y <= top + windowFrameWidth || (x >= right - windowFrameWidth && y <= top + cornerMargin)) {
            s = Qt::TopRightSection;
        } else if (y >= bottom - windowFrameWidth || (x >= right - windowFrameWidth && y >= bottom - cornerMargin)) {
            s = Qt::BottomRightSection;
        } else if (x >= right - windowFrameWidth) {
            s = Qt::RightSection;
        }
    } else if (y <= top + windowFrameWidth) {
        s = Qt::TopSection;
    } else if (y >= bottom - windowFrameWidth) {
        s = Qt::BottomSection;
    }
    if (s == Qt::NoSection) {
        QRectF r1 = r;
        r1.setHeight(d->windowFrameMargins
                     ? d->windowFrameMargins->top() : 0);
        if (r1.contains(pos))
            s = Qt::TitleBarArea;
    }
    return s;
}

/*!
    \reimp

    Handles the \a event.  QGraphicsWidget handles the following
    events:

    \table
    \header  \li Event                 \li Usage
    \row     \li Polish
                    \li Delivered to the widget some time after it has been
                        shown.
    \row     \li GraphicsSceneMove
                    \li Delivered to the widget after its local position has
                        changed.
    \row     \li GraphicsSceneResize
                    \li Delivered to the widget after its size has changed.
    \row     \li Show
                    \li Delivered to the widget before it has been shown.
    \row     \li Hide
                    \li Delivered to the widget after it has been hidden.
    \row     \li PaletteChange
                    \li Delivered to the widget after its palette has changed.
    \row     \li FontChange
                    \li Delivered to the widget after its font has changed.
    \row     \li EnabledChange
                    \li Delivered to the widget after its enabled state has
                        changed.
    \row     \li StyleChange
                    \li Delivered to the widget after its style has changed.
    \row     \li LayoutDirectionChange
                    \li Delivered to the widget after its layout direction has
                        changed.
    \row     \li ContentsRectChange
                    \li Delivered to the widget after its contents margins/
                        contents rect has changed.
    \endtable
*/
bool QGraphicsWidget::event(QEvent *event)
{
    Q_D(QGraphicsWidget);
    // Forward the event to the layout first.
    if (d->layout)
        d->layout->widgetEvent(event);

    // Handle the event itself.
    switch (event->type()) {
    case QEvent::GraphicsSceneMove:
        moveEvent(static_cast<QGraphicsSceneMoveEvent *>(event));
        break;
    case QEvent::GraphicsSceneResize:
        resizeEvent(static_cast<QGraphicsSceneResizeEvent *>(event));
        break;
    case QEvent::Show:
        showEvent(static_cast<QShowEvent *>(event));
        break;
    case QEvent::Hide:
        hideEvent(static_cast<QHideEvent *>(event));
        break;
    case QEvent::Polish:
        polishEvent();
        d->polished = true;
        if (!d->font.isCopyOf(QApplication::font()))
            d->updateFont(d->font);
        break;
    case QEvent::WindowActivate:
    case QEvent::WindowDeactivate:
        update();
        break;
    case QEvent::StyleAnimationUpdate:
        if (isVisible()) {
            event->accept();
            update();
        }
        break;
        // Taken from QWidget::event
    case QEvent::ActivationChange:
    case QEvent::EnabledChange:
    case QEvent::FontChange:
    case QEvent::StyleChange:
    case QEvent::PaletteChange:
    case QEvent::ParentChange:
    case QEvent::ContentsRectChange:
    case QEvent::LayoutDirectionChange:
        changeEvent(event);
        break;
    case QEvent::Close:
        closeEvent((QCloseEvent *)event);
        break;
    case QEvent::GrabMouse:
        grabMouseEvent(event);
        break;
    case QEvent::UngrabMouse:
        ungrabMouseEvent(event);
        break;
    case QEvent::GrabKeyboard:
        grabKeyboardEvent(event);
        break;
    case QEvent::UngrabKeyboard:
        ungrabKeyboardEvent(event);
        break;
    case QEvent::GraphicsSceneMousePress:
        if (d->hasDecoration() && windowFrameEvent(event))
            return true;
        break;
    case QEvent::GraphicsSceneMouseMove:
    case QEvent::GraphicsSceneMouseRelease:
    case QEvent::GraphicsSceneMouseDoubleClick:
        d->ensureWindowData();
        if (d->hasDecoration() && d->windowData->grabbedSection != Qt::NoSection)
            return windowFrameEvent(event);
        break;
    case QEvent::GraphicsSceneHoverEnter:
    case QEvent::GraphicsSceneHoverMove:
    case QEvent::GraphicsSceneHoverLeave:
        if (d->hasDecoration()) {
            windowFrameEvent(event);
            // Filter out hover events if they were sent to us only because of the
            // decoration (special case in QGraphicsScenePrivate::dispatchHoverEvent).
            if (!acceptHoverEvents())
                return true;
        }
        break;
    default:
        break;
    }
    return QObject::event(event);
}

/*!
   This event handler can be reimplemented to handle state changes.

   The state being changed in this event can be retrieved through \a event.

   Change events include: QEvent::ActivationChange, QEvent::EnabledChange,
   QEvent::FontChange, QEvent::StyleChange, QEvent::PaletteChange,
   QEvent::ParentChange, QEvent::LayoutDirectionChange, and
   QEvent::ContentsRectChange.
*/
void QGraphicsWidget::changeEvent(QEvent *event)
{
    Q_D(QGraphicsWidget);
    switch (event->type()) {
    case QEvent::StyleChange:
        // ### Don't unset if the margins are explicitly set.
        unsetWindowFrameMargins();
        if (d->layout)
            d->layout->invalidate();
        Q_FALLTHROUGH();
    case QEvent::FontChange:
        update();
        updateGeometry();
        break;
    case QEvent::PaletteChange:
        update();
        break;
    case QEvent::ParentChange:
        d->resolveFont(d->inheritedFontResolveMask);
        d->resolvePalette(d->inheritedPaletteResolveMask);
        break;
    default:
        break;
    }
}

/*!
    This event handler, for \a event, can be reimplemented in a subclass to
    receive widget close events.  The default implementation accepts the
    event.

    \sa close(), QCloseEvent
*/
void QGraphicsWidget::closeEvent(QCloseEvent *event)
{
    event->accept();
}

/*!
    \reimp
*/
void QGraphicsWidget::focusInEvent(QFocusEvent *event)
{
    Q_UNUSED(event);
    if (focusPolicy() != Qt::NoFocus)
        update();
}

/*!
    Finds a new widget to give the keyboard focus to, as appropriate for Tab
    and Shift+Tab, and returns \c true if it can find a new widget; returns \c false
    otherwise. If \a next is true, this function searches forward; if \a next
    is false, it searches backward.

    Sometimes, you will want to reimplement this function to provide special
    focus handling for your widget and its subwidgets. For example, a web
    browser might reimplement it to move its current active link forward or
    backward, and call the base implementation only when it reaches the last
    or first link on the page.

    Child widgets call focusNextPrevChild() on their parent widgets, but only
    the window that contains the child widgets decides where to redirect
    focus. By reimplementing this function for an object, you gain control of
    focus traversal for all child widgets.

    \sa focusPolicy()
*/
bool QGraphicsWidget::focusNextPrevChild(bool next)
{
    Q_D(QGraphicsWidget);
    // Let the parent's focusNextPrevChild implementation decide what to do.
    QGraphicsWidget *parent = 0;
    if (!isWindow() && (parent = parentWidget()))
        return parent->focusNextPrevChild(next);
    if (!d->scene)
        return false;
    if (d->scene->focusNextPrevChild(next))
        return true;
    if (isWindow()) {
        setFocus(next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
        if (hasFocus())
            return true;
    }
    return false;
}

/*!
    \reimp
*/
void QGraphicsWidget::focusOutEvent(QFocusEvent *event)
{
    Q_UNUSED(event);
    if (focusPolicy() != Qt::NoFocus)
        update();
}

/*!
    This event handler, for \l{QEvent::Hide}{Hide} events, is delivered after
    the widget has been hidden, for example, setVisible(false) has been called
    for the widget or one of its ancestors when the widget was previously
    shown.

    You can reimplement this event handler to detect when your widget is
    hidden. Calling QEvent::accept() or QEvent::ignore() on \a event has no
    effect.

    \sa showEvent(), QWidget::hideEvent(), ItemVisibleChange
*/
void QGraphicsWidget::hideEvent(QHideEvent *event)
{
    ///### focusNextPrevChild(true), don't lose focus when the focus widget
    // is hidden.
    Q_UNUSED(event);
}

/*!
    This event handler, for \l{QEvent::GraphicsSceneMove}{GraphicsSceneMove}
    events, is delivered after the widget has moved (e.g., its local position
    has changed).

    This event is only delivered when the item is moved locally. Calling
    setTransform() or moving any of the item's ancestors does not affect the
    item's local position.

    You can reimplement this event handler to detect when your widget has
    moved. Calling QEvent::accept() or QEvent::ignore() on \a event has no
    effect.

    \sa ItemPositionChange, ItemPositionHasChanged
*/
void QGraphicsWidget::moveEvent(QGraphicsSceneMoveEvent *event)
{
    // ### Last position is always == current position
    Q_UNUSED(event);
}

/*!
    This event is delivered to the item by the scene at some point after it
    has been constructed, but before it is shown or otherwise accessed through
    the scene. You can use this event handler to do last-minute initializations
    of the widget which require the item to be fully constructed.

    The base implementation does nothing.
*/
void QGraphicsWidget::polishEvent()
{
}

/*!
    This event handler, for
    \l{QEvent::GraphicsSceneResize}{GraphicsSceneResize} events, is
    delivered after the widget has been resized (i.e., its local size has
    changed). \a event contains both the old and the new size.

    This event is only delivered when the widget is resized locally; calling
    setTransform() on the widget or any of its ancestors or view, does not
    affect the widget's local size.

    You can reimplement this event handler to detect when your widget has been
    resized. Calling QEvent::accept() or QEvent::ignore() on \a event has no
    effect.

    \sa geometry(), setGeometry()
*/
void QGraphicsWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
{
    Q_UNUSED(event);
}

/*!
    This event handler, for \l{QEvent::Show}{Show} events, is delivered before
    the widget has been shown, for example, setVisible(true) has been called
    for the widget or one of its ancestors when the widget was previously
    hidden.

    You can reimplement this event handler to detect when your widget is
    shown. Calling QEvent::accept() or QEvent::ignore() on \a event has no
    effect.

    \sa hideEvent(), QWidget::showEvent(), ItemVisibleChange
*/
void QGraphicsWidget::showEvent(QShowEvent *event)
{
    Q_UNUSED(event);
}

/*!
    \reimp
*/
void QGraphicsWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    Q_UNUSED(event);
}

/*!
    \reimp
*/
void QGraphicsWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    QGraphicsObject::hoverLeaveEvent(event);
}

/*!
    This event handler, for \a event, can be reimplemented in a subclass to
    receive notifications for QEvent::GrabMouse events.

    \sa grabMouse(), grabKeyboard()
*/
void QGraphicsWidget::grabMouseEvent(QEvent *event)
{
    Q_UNUSED(event);
}

/*!
    This event handler, for \a event, can be reimplemented in a subclass to
    receive notifications for QEvent::UngrabMouse events.

    \sa ungrabMouse(), ungrabKeyboard()
*/
void QGraphicsWidget::ungrabMouseEvent(QEvent *event)
{
    Q_UNUSED(event);
}

/*!
    This event handler, for \a event, can be reimplemented in a subclass to
    receive notifications for QEvent::GrabKeyboard events.

    \sa grabKeyboard(), grabMouse()
*/
void QGraphicsWidget::grabKeyboardEvent(QEvent *event)
{
    Q_UNUSED(event);
}

/*!
    This event handler, for \a event, can be reimplemented in a subclass to
    receive notifications for QEvent::UngrabKeyboard events.

    \sa ungrabKeyboard(), ungrabMouse()
*/
void QGraphicsWidget::ungrabKeyboardEvent(QEvent *event)
{
    Q_UNUSED(event);
}

/*!
    Returns the widgets window type.

    \sa windowFlags(), isWindow(), isPanel()
*/
Qt::WindowType QGraphicsWidget::windowType() const
{
    return Qt::WindowType(int(windowFlags()) & Qt::WindowType_Mask);
}

/*!
    \property QGraphicsWidget::windowFlags
    \brief the widget's window flags

    Window flags are a combination of a window type (e.g., Qt::Dialog) and
    several flags giving hints on the behavior of the window. The behavior
    is platform-dependent.

    By default, this property contains no window flags.

    Windows are panels. If you set the Qt::Window flag, the ItemIsPanel flag
    will be set automatically. If you clear the Qt::Window flag, the
    ItemIsPanel flag is also cleared. Note that the ItemIsPanel flag can be
    set independently of Qt::Window.

    \sa isWindow(), isPanel()
*/
Qt::WindowFlags QGraphicsWidget::windowFlags() const
{
    Q_D(const QGraphicsWidget);
    return d->windowFlags;
}
void QGraphicsWidget::setWindowFlags(Qt::WindowFlags wFlags)
{
    Q_D(QGraphicsWidget);
    if (d->windowFlags == wFlags)
        return;
    bool wasPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;

    d->adjustWindowFlags(&wFlags);
    d->windowFlags = wFlags;
    if (!d->setWindowFrameMargins)
        unsetWindowFrameMargins();

    setFlag(ItemIsPanel, d->windowFlags & Qt::Window);

    bool isPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
    if (d->scene && isVisible() && wasPopup != isPopup) {
        // Popup state changed; update implicit mouse grab.
        if (!isPopup)
            d->scene->d_func()->removePopup(this);
        else
            d->scene->d_func()->addPopup(this);
    }

    if (d->scene && d->scene->d_func()->allItemsIgnoreHoverEvents && d->hasDecoration()) {
        d->scene->d_func()->allItemsIgnoreHoverEvents = false;
        d->scene->d_func()->enableMouseTrackingOnViews();
    }
}

/*!
    Returns \c true if this widget's window is in the active window, or if the
    widget does not have a window but is in an active scene (i.e., a scene
    that currently has focus).

    The active window is the window that either contains a child widget that
    currently has input focus, or that itself has input focus.

    \sa QGraphicsScene::activeWindow(), QGraphicsScene::setActiveWindow(), isActive()
*/
bool QGraphicsWidget::isActiveWindow() const
{
    return isActive();
}

/*!
    \property QGraphicsWidget::windowTitle
    \brief This property holds the window title (caption).

    This property is only used for windows.

    By default, if no title has been set, this property contains an
    empty string.
*/
void QGraphicsWidget::setWindowTitle(const QString &title)
{
    Q_D(QGraphicsWidget);
    d->ensureWindowData();
    d->windowData->windowTitle = title;
}
QString QGraphicsWidget::windowTitle() const
{
    Q_D(const QGraphicsWidget);
    return d->windowData ? d->windowData->windowTitle : QString();
}

/*!
    \property QGraphicsWidget::focusPolicy
    \brief the way the widget accepts keyboard focus

    The focus policy is Qt::TabFocus if the widget accepts keyboard focus by
    tabbing, Qt::ClickFocus if the widget accepts focus by clicking,
    Qt::StrongFocus if it accepts both, and Qt::NoFocus (the default) if it
    does not accept focus at all.

    You must enable keyboard focus for a widget if it processes keyboard
    events. This is normally done from the widget's constructor. For instance,
    the QLineEdit constructor calls setFocusPolicy(Qt::StrongFocus).

    If you enable a focus policy (i.e., not Qt::NoFocus), QGraphicsWidget will
    automatically enable the ItemIsFocusable flag.  Setting Qt::NoFocus on a
    widget will clear the ItemIsFocusable flag. If the widget currently has
    keyboard focus, the widget will automatically lose focus.

    \sa focusInEvent(), focusOutEvent(), keyPressEvent(), keyReleaseEvent(), enabled
*/
Qt::FocusPolicy QGraphicsWidget::focusPolicy() const
{
    Q_D(const QGraphicsWidget);
    return d->focusPolicy;
}
void QGraphicsWidget::setFocusPolicy(Qt::FocusPolicy policy)
{
    Q_D(QGraphicsWidget);
    if (d->focusPolicy == policy)
        return;
    d->focusPolicy = policy;
    if (hasFocus() && policy == Qt::NoFocus)
        clearFocus();
    setFlag(ItemIsFocusable, policy != Qt::NoFocus);
}

/*!
    If this widget, a child or descendant of this widget currently has input
    focus, this function will return a pointer to that widget. If
    no descendant widget has input focus, \nullptr is returned.

    \sa QGraphicsItem::focusItem(), QWidget::focusWidget()
*/
QGraphicsWidget *QGraphicsWidget::focusWidget() const
{
    Q_D(const QGraphicsWidget);
    if (d->subFocusItem && d->subFocusItem->d_ptr->isWidget)
        return static_cast<QGraphicsWidget *>(d->subFocusItem);
    return nullptr;
}

#ifndef QT_NO_SHORTCUT
/*!
    \since 4.5

    Adds a shortcut to Qt's shortcut system that watches for the given key \a
    sequence in the given \a context. If the \a context is
    Qt::ApplicationShortcut, the shortcut applies to the application as a
    whole. Otherwise, it is either local to this widget, Qt::WidgetShortcut,
    or to the window itself, Qt::WindowShortcut. For widgets that are not part
    of a window (i.e., top-level widgets and their children),
    Qt::WindowShortcut shortcuts apply to the scene.

    If the same key \a sequence has been grabbed by several widgets,
    when the key \a sequence occurs a QEvent::Shortcut event is sent
    to all the widgets to which it applies in a non-deterministic
    order, but with the ``ambiguous'' flag set to true.

    \warning You should not normally need to use this function;
    instead create \l{QAction}s with the shortcut key sequences you
    require (if you also want equivalent menu options and toolbar
    buttons), or create \l{QShortcut}s if you just need key sequences.
    Both QAction and QShortcut handle all the event filtering for you,
    and provide signals which are triggered when the user triggers the
    key sequence, so are much easier to use than this low-level
    function.

    \sa releaseShortcut(), setShortcutEnabled(), QWidget::grabShortcut()
*/
int QGraphicsWidget::grabShortcut(const QKeySequence &sequence, Qt::ShortcutContext context)
{
    Q_ASSERT(qApp);
    if (sequence.isEmpty())
        return 0;
    // ### setAttribute(Qt::WA_GrabbedShortcut);
    return QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(this, sequence, context, qWidgetShortcutContextMatcher);
}

/*!
    \since 4.5

    Removes the shortcut with the given \a id from Qt's shortcut
    system. The widget will no longer receive QEvent::Shortcut events
    for the shortcut's key sequence (unless it has other shortcuts
    with the same key sequence).

    \warning You should not normally need to use this function since
    Qt's shortcut system removes shortcuts automatically when their
    parent widget is destroyed. It is best to use QAction or
    QShortcut to handle shortcuts, since they are easier to use than
    this low-level function. Note also that this is an expensive
    operation.

    \sa grabShortcut(), setShortcutEnabled(), QWidget::releaseShortcut()
*/
void QGraphicsWidget::releaseShortcut(int id)
{
    Q_ASSERT(qApp);
    if (id)
        QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(id, this, 0);
}

/*!
    \since 4.5

    If \a enabled is true, the shortcut with the given \a id is
    enabled; otherwise the shortcut is disabled.

    \warning You should not normally need to use this function since
    Qt's shortcut system enables/disables shortcuts automatically as
    widgets become hidden/visible and gain or lose focus. It is best
    to use QAction or QShortcut to handle shortcuts, since they are
    easier to use than this low-level function.

    \sa grabShortcut(), releaseShortcut(), QWidget::setShortcutEnabled()
*/
void QGraphicsWidget::setShortcutEnabled(int id, bool enabled)
{
    Q_ASSERT(qApp);
    if (id)
        QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enabled, id, this, 0);
}

/*!
    \since 4.5

    If \a enabled is true, auto repeat of the shortcut with the
    given \a id is enabled; otherwise it is disabled.

    \sa grabShortcut(), releaseShortcut(), QWidget::setShortcutAutoRepeat()
*/
void QGraphicsWidget::setShortcutAutoRepeat(int id, bool enabled)
{
    Q_ASSERT(qApp);
    if (id)
        QGuiApplicationPrivate::instance()->shortcutMap.setShortcutAutoRepeat(enabled, id, this, 0);
}
#endif

#ifndef QT_NO_ACTION
/*!
    \since 4.5

    Appends the action \a action to this widget's list of actions.

    All QGraphicsWidgets have a list of \l{QAction}s, however they can be
    represented graphically in many different ways. The default use of the
    QAction list (as returned by actions()) is to create a context QMenu.

    A QGraphicsWidget should only have one of each action and adding an action
    it already has will not cause the same action to be in the widget twice.

    \sa removeAction(), insertAction(), actions(), QWidget::addAction()
*/
void QGraphicsWidget::addAction(QAction *action)
{
    insertAction(0, action);
}

/*!
    \since 4.5

    Appends the actions \a actions to this widget's list of actions.

    \sa removeAction(), QMenu, addAction(), QWidget::addActions()
*/
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
void QGraphicsWidget::addActions(const QList<QAction *> &actions)
#else
void QGraphicsWidget::addActions(QList<QAction *> actions)
#endif
{
    for (int i = 0; i < actions.count(); ++i)
        insertAction(0, actions.at(i));
}

/*!
    \since 4.5

    Inserts the action \a action to this widget's list of actions,
    before the action \a before. It appends the action if \a before is \nullptr or
    \a before is not a valid action for this widget.

    A QGraphicsWidget should only have one of each action.

    \sa removeAction(), addAction(), QMenu, actions(),
    QWidget::insertActions()
*/
void QGraphicsWidget::insertAction(QAction *before, QAction *action)
{
    if (!action) {
        qWarning("QWidget::insertAction: Attempt to insert null action");
        return;
    }

    Q_D(QGraphicsWidget);
    int index = d->actions.indexOf(action);
    if (index != -1)
        d->actions.removeAt(index);

    int pos = d->actions.indexOf(before);
    if (pos < 0) {
        before = 0;
        pos = d->actions.size();
    }
    d->actions.insert(pos, action);

    if (index == -1) {
        QActionPrivate *apriv = action->d_func();
        apriv->graphicsWidgets.append(this);
    }

    QActionEvent e(QEvent::ActionAdded, action, before);
    QCoreApplication::sendEvent(this, &e);
}

/*!
    \since 4.5

    Inserts the actions \a actions to this widget's list of actions,
    before the action \a before. It appends the action if \a before is \nullptr or
    \a before is not a valid action for this widget.

    A QGraphicsWidget can have at most one of each action.

    \sa removeAction(), QMenu, insertAction(), QWidget::insertActions()
*/
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
void QGraphicsWidget::insertActions(QAction *before, const QList<QAction *> &actions)
#else
void QGraphicsWidget::insertActions(QAction *before, QList<QAction *> actions)
#endif
{
    for (int i = 0; i < actions.count(); ++i)
        insertAction(before, actions.at(i));
}

/*!
    \since 4.5

    Removes the action \a action from this widget's list of actions.

    \sa insertAction(), actions(), insertAction(), QWidget::removeAction()
*/
void QGraphicsWidget::removeAction(QAction *action)
{
    if (!action)
        return;

    Q_D(QGraphicsWidget);

    QActionPrivate *apriv = action->d_func();
    apriv->graphicsWidgets.removeAll(this);

    if (d->actions.removeAll(action)) {
        QActionEvent e(QEvent::ActionRemoved, action);
        QCoreApplication::sendEvent(this, &e);
    }
}

/*!
    \since 4.5

    Returns the (possibly empty) list of this widget's actions.

    \sa insertAction(), removeAction(), QWidget::actions(),
    QAction::associatedWidgets(), QAction::associatedGraphicsWidgets()
*/
QList<QAction *> QGraphicsWidget::actions() const
{
    Q_D(const QGraphicsWidget);
    return d->actions;
}
#endif

/*!
    Moves the \a second widget around the ring of focus widgets so that
    keyboard focus moves from the \a first widget to the \a second widget when
    the Tab key is pressed.

    Note that since the tab order of the \a second widget is changed, you
    should order a chain like this:

    \snippet code/src_gui_graphicsview_qgraphicswidget.cpp 1

    \e not like this:

    \snippet code/src_gui_graphicsview_qgraphicswidget.cpp 2

    If \a first is \nullptr, this indicates that \a second should be the first widget
    to receive input focus should the scene gain Tab focus (i.e., the user
    hits Tab so that focus passes into the scene). If \a second is \nullptr, this
    indicates that \a first should be the first widget to gain focus if the
    scene gained BackTab focus.

    By default, tab order is defined implicitly using widget creation order.

    \sa focusPolicy, {Keyboard Focus in Widgets}
*/
void QGraphicsWidget::setTabOrder(QGraphicsWidget *first, QGraphicsWidget *second)
{
    if (!first && !second) {
        qWarning("QGraphicsWidget::setTabOrder(0, 0) is undefined");
        return;
    }
    if ((first && second) && first->scene() != second->scene()) {
        qWarning("QGraphicsWidget::setTabOrder: scenes %p and %p are different",
                 first->scene(), second->scene());
        return;
    }
    QGraphicsScene *scene = first ? first->scene() : second->scene();
    if (!scene && (!first || !second)) {
        qWarning("QGraphicsWidget::setTabOrder: assigning tab order from/to the"
                 " scene requires the item to be in a scene.");
        return;
    }

    // If either first or second are 0, the scene's tabFocusFirst is updated
    // to point to the first item in the scene's focus chain. Then first or
    // second are set to point to tabFocusFirst.
    QGraphicsScenePrivate *sceneD = scene->d_func();
    if (!first) {
        sceneD->tabFocusFirst = second;
        return;
    }
    if (!second) {
        sceneD->tabFocusFirst = first->d_func()->focusNext;
        return;
    }

    // Both first and second are != 0.
    QGraphicsWidget *firstFocusNext = first->d_func()->focusNext;
    if (firstFocusNext == second) {
        // Nothing to do.
        return;
    }

    // Update the focus chain.
    QGraphicsWidget *secondFocusPrev = second->d_func()->focusPrev;
    QGraphicsWidget *secondFocusNext = second->d_func()->focusNext;
    firstFocusNext->d_func()->focusPrev = second;
    first->d_func()->focusNext = second;
    second->d_func()->focusNext = firstFocusNext;
    second->d_func()->focusPrev = first;
    secondFocusPrev->d_func()->focusNext = secondFocusNext;
    secondFocusNext->d_func()->focusPrev = secondFocusPrev;

    Q_ASSERT(first->d_func()->focusNext->d_func()->focusPrev == first);
    Q_ASSERT(first->d_func()->focusPrev->d_func()->focusNext == first);

    Q_ASSERT(second->d_func()->focusNext->d_func()->focusPrev == second);
    Q_ASSERT(second->d_func()->focusPrev->d_func()->focusNext == second);

}

/*!
    If \a on is true, this function enables \a attribute; otherwise
    \a attribute is disabled.

    See the class documentation for QGraphicsWidget for a complete list of
    which attributes are supported, and what they are for.

    \sa testAttribute(), QWidget::setAttribute()
*/
void QGraphicsWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
{
    Q_D(QGraphicsWidget);
    // ### most flags require some immediate action
    // ### we might want to qWarn use of unsupported attributes
    // ### we might want to not use Qt::WidgetAttribute, but roll our own instead
    d->setAttribute(attribute, on);
}

/*!
    Returns \c true if \a attribute is enabled for this widget; otherwise,
    returns \c false.

    \sa setAttribute()
*/
bool QGraphicsWidget::testAttribute(Qt::WidgetAttribute attribute) const
{
    Q_D(const QGraphicsWidget);
    return d->testAttribute(attribute);
}

/*!
  \enum QGraphicsWidget::anonymous

  The value returned by the virtual type() function.

  \value Type A graphics widget item
*/

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

/*!
    \reimp
*/
void QGraphicsWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(painter);
    Q_UNUSED(option);
    Q_UNUSED(widget);
}

/*!
    This virtual function is called by QGraphicsScene to draw the window frame
    for windows using \a painter, \a option, and \a widget, in local
    coordinates. The base implementation uses the current style to render the
    frame and title bar.

    You can reimplement this function in a subclass of QGraphicsWidget to
    provide custom rendering of the widget's window frame.

    \sa QGraphicsItem::paint()
*/
void QGraphicsWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option,
                                       QWidget *widget)
{
    const bool fillBackground = !testAttribute(Qt::WA_OpaquePaintEvent)
                                && !testAttribute(Qt::WA_NoSystemBackground);
    QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(this);
    const bool embeddedWidgetFillsOwnBackground = proxy && proxy->widget();

    if (rect().contains(option->exposedRect)) {
        if (fillBackground && !embeddedWidgetFillsOwnBackground)
            painter->fillRect(option->exposedRect, palette().window());
        return;
    }

    Q_D(QGraphicsWidget);

    QRect windowFrameRect = QRect(QPoint(), windowFrameGeometry().size().toSize());
    QStyleOptionTitleBar bar;
    bar.QStyleOption::operator=(*option);
    d->initStyleOptionTitleBar(&bar);   // this clear flags in bar.state
    d->ensureWindowData();
    bar.state.setFlag(QStyle::State_MouseOver, d->windowData->buttonMouseOver);
    bar.state.setFlag(QStyle::State_Sunken, d->windowData->buttonSunken);
    bar.rect = windowFrameRect;

    // translate painter to make the style happy
    const QPointF styleOrigin = this->windowFrameRect().topLeft();
    painter->translate(styleOrigin);

#ifdef Q_OS_MAC
    const QSize pixmapSize = windowFrameRect.size();
    if (pixmapSize.width() <= 0 || pixmapSize.height() <= 0)
        return;
    QPainter *realPainter = painter;
    QPixmap pm(pixmapSize);
    painter = new QPainter(&pm);
#endif

    // Fill background
    QStyleHintReturnMask mask;
    bool setMask = style()->styleHint(QStyle::SH_WindowFrame_Mask, &bar, widget, &mask) && !mask.region.isEmpty();
    bool hasBorder = !style()->styleHint(QStyle::SH_TitleBar_NoBorder, &bar, widget);
    int frameWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, &bar, widget);
    if (setMask) {
        painter->save();
        painter->setClipRegion(mask.region, Qt::IntersectClip);
    }
    if (fillBackground) {
        if (embeddedWidgetFillsOwnBackground) {
            // Don't fill the background twice.
            QPainterPath windowFrameBackground;
            windowFrameBackground.addRect(windowFrameRect);
            // Adjust with 0.5 to avoid border artifacts between
            // widget background and frame background.
            windowFrameBackground.addRect(rect().translated(-styleOrigin).adjusted(0.5, 0.5, -0.5, -0.5));
            painter->fillPath(windowFrameBackground, palette().window());
        } else {
            painter->fillRect(windowFrameRect, palette().window());
        }
    }

    // Draw title
    int height = (int)d->titleBarHeight(bar);
    bar.rect.setHeight(height);
    if (hasBorder) // Frame is painted by PE_FrameWindow
        bar.rect.adjust(frameWidth, frameWidth, -frameWidth, 0);

    painter->save();
    painter->setFont(QApplication::font("QMdiSubWindowTitleBar"));
    style()->drawComplexControl(QStyle::CC_TitleBar, &bar, painter, widget);
    painter->restore();
    if (setMask)
        painter->restore();
    // Draw window frame
    QStyleOptionFrame frameOptions;
    frameOptions.QStyleOption::operator=(*option);
    initStyleOption(&frameOptions);
    if (!hasBorder)
        painter->setClipRect(windowFrameRect.adjusted(0, +height, 0, 0), Qt::IntersectClip);
    frameOptions.state.setFlag(QStyle::State_HasFocus, hasFocus());
    bool isActive = isActiveWindow();
    frameOptions.state.setFlag(QStyle::State_Active, isActive);

    frameOptions.palette.setCurrentColorGroup(isActive ? QPalette::Active : QPalette::Normal);
    frameOptions.rect = windowFrameRect;
    frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, widget);
    frameOptions.midLineWidth = 1;
    style()->drawPrimitive(QStyle::PE_FrameWindow, &frameOptions, painter, widget);

#ifdef Q_OS_MAC
    realPainter->drawPixmap(QPoint(), pm);
    delete painter;
#endif
}

/*!
    \reimp
*/
QRectF QGraphicsWidget::boundingRect() const
{
    return windowFrameRect();
}

/*!
    \reimp
*/
QPainterPath QGraphicsWidget::shape() const
{
    QPainterPath path;
    path.addRect(rect());
    return path;
}

/*!
    Call this function to close the widget.

    Returns \c true if the widget was closed; otherwise returns \c false.
    This slot will first send a QCloseEvent to the widget, which may or may
    not accept the event. If the event was ignored, nothing happens. If the
    event was accepted, it will hide() the widget.

    If the widget has the Qt::WA_DeleteOnClose attribute set it will be
    deleted.
*/
bool QGraphicsWidget::close()
{
    QCloseEvent closeEvent;
    QCoreApplication::sendEvent(this, &closeEvent);
    if (!closeEvent.isAccepted()) {
        return false;
    }
    // hide
    if (isVisible()) {
        hide();
    }
    if (testAttribute(Qt::WA_DeleteOnClose)) {
        deleteLater();
    }
    return true;
}

#if 0
void QGraphicsWidget::dumpFocusChain()
{
    qDebug("=========== Dumping focus chain ==============");
    int i = 0;
    QGraphicsWidget *next = this;
    QSet<QGraphicsWidget*> visited;
    do {
        if (!next) {
            qWarning("Found a focus chain that is not circular, (next == 0)");
            break;
        }
        qDebug() << i++ << QString::number(uint(next), 16) << next->className() << next->data(0) << QString::fromLatin1("focusItem:%1").arg(next->hasFocus() ? '1' : '0') << QLatin1String("next:") << next->d_func()->focusNext->data(0) << QLatin1String("prev:") << next->d_func()->focusPrev->data(0);
        if (visited.contains(next)) {
            qWarning("Already visited this node. However, I expected to dump until I found myself.");
            break;
        }
        visited << next;
        next = next->d_func()->focusNext;
    } while (next != this);
}
#endif

QT_END_NAMESPACE

#include "moc_qgraphicswidget.cpp"
