/****************************************************************************
**
** 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 <QtGui/qpainterpath.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, nullptr), QGraphicsLayoutItem(nullptr, 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, nullptr), QGraphicsLayoutItem(nullptr, 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 ? nullptr : 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(nullptr);
            }
        }
        d->layout = nullptr;
        delete temp;
    }

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

    // 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();
        const qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, &bar);
        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 != nullptr);
    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 = nullptr;
    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(nullptr, 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(nullptr, 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 = nullptr;
        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, nullptr, 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"
