/****************************************************************************
**
** 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 "qlayout.h"

#include "qapplication.h"
#include "qlayoutengine_p.h"
#if QT_CONFIG(menubar)
#include "qmenubar.h"
#endif
#if QT_CONFIG(toolbar)
#include "qtoolbar.h"
#endif
#include "qevent.h"
#include "qstyle.h"
#include "qvariant.h"
#include "qwidget_p.h"

QT_BEGIN_NAMESPACE

inline static QRect fromLayoutItemRect(QWidgetPrivate *priv, const QRect &rect)
{
    return rect.adjusted(priv->leftLayoutItemMargin, priv->topLayoutItemMargin,
                         -priv->rightLayoutItemMargin, -priv->bottomLayoutItemMargin);
}

inline static QSize fromLayoutItemSize(QWidgetPrivate *priv, const QSize &size)
{
    return fromLayoutItemRect(priv, QRect(QPoint(0, 0), size)).size();
}

inline static QRect toLayoutItemRect(QWidgetPrivate *priv, const QRect &rect)
{
    return rect.adjusted(-priv->leftLayoutItemMargin, -priv->topLayoutItemMargin,
                         priv->rightLayoutItemMargin, priv->bottomLayoutItemMargin);
}

inline static QSize toLayoutItemSize(QWidgetPrivate *priv, const QSize &size)
{
    return toLayoutItemRect(priv, QRect(QPoint(0, 0), size)).size();
}

/*!
    \class QLayoutItem
    \brief The QLayoutItem class provides an abstract item that a
    QLayout manipulates.

    \ingroup geomanagement
    \inmodule QtWidgets

    This is used by custom layouts.

    Pure virtual functions are provided to return information about
    the layout, including, sizeHint(), minimumSize(), maximumSize()
    and expanding().

    The layout's geometry can be set and retrieved with setGeometry()
    and geometry(), and its alignment with setAlignment() and
    alignment().

    isEmpty() returns whether the layout item is empty. If the
    concrete item is a QWidget, it can be retrieved using widget().
    Similarly for layout() and spacerItem().

    Some layouts have width and height interdependencies. These can
    be expressed using hasHeightForWidth(), heightForWidth(), and
    minimumHeightForWidth(). For more explanation see the \e{Qt
    Quarterly} article
    \l{http://doc.qt.io/archives/qq/qq04-height-for-width.html}{Trading
    Height for Width}.

    \sa QLayout
*/

/*!
    \class QSpacerItem
    \ingroup geomanagement
    \brief The QSpacerItem class provides blank space in a layout.

    \inmodule QtWidgets

    Normally, you don't need to use this class directly. Qt's
    built-in layout managers provide the following functions for
    manipulating empty space in layouts:

    \table
    \header \li Class
            \li Functions
    \row    \li QHBoxLayout
            \li \l{QBoxLayout::addSpacing()}{addSpacing()},
               \l{QBoxLayout::addStretch()}{addStretch()},
               \l{QBoxLayout::insertSpacing()}{insertSpacing()},
               \l{QBoxLayout::insertStretch()}{insertStretch()}
    \row    \li QGridLayout
            \li \l{QGridLayout::setRowMinimumHeight()}{setRowMinimumHeight()},
               \l{QGridLayout::setRowStretch()}{setRowStretch()},
               \l{QGridLayout::setColumnMinimumWidth()}{setColumnMinimumWidth()},
               \l{QGridLayout::setColumnStretch()}{setColumnStretch()}
    \endtable

    \sa QLayout, QWidgetItem, QLayoutItem::spacerItem()
*/

/*!
    \class QWidgetItem
    \ingroup geomanagement
    \brief The QWidgetItem class is a layout item that represents a widget.

    \inmodule QtWidgets

    Normally, you don't need to use this class directly. Qt's
    built-in layout managers provide the following functions for
    manipulating widgets in layouts:

    \table
    \header \li Class
            \li Functions
    \row    \li QBoxLayout
            \li \l{QBoxLayout::addWidget()}{addWidget()},
               \l{QBoxLayout::insertWidget()}{insertWidget()},
               \l{QBoxLayout::setStretchFactor()}{setStretchFactor()}
    \row    \li QGridLayout
            \li \l{QGridLayout::addWidget()}{addWidget()}
    \row    \li QStackedLayout
            \li \l{QStackedLayout::addWidget()}{addWidget()},
               \l{QStackedLayout::insertWidget()}{insertWidget()},
               \l{QStackedLayout::currentWidget()}{currentWidget()},
               \l{QStackedLayout::setCurrentWidget()}{setCurrentWidget()},
               \l{QStackedLayout::widget()}{widget()}
    \endtable

    \sa QLayout, QSpacerItem, QLayoutItem::widget()
*/

/*!
    \fn QLayoutItem::QLayoutItem(Qt::Alignment alignment)

    Constructs a layout item with an \a alignment.
    Not all subclasses support alignment.
*/

/*!
    \fn Qt::Alignment QLayoutItem::alignment() const

    Returns the alignment of this item.
*/

/*!
    Sets the alignment of this item to \a alignment.

    \b{Note:} Item alignment is only supported by QLayoutItem subclasses
    where it would have a visual effect. Except for QSpacerItem, which provides
    blank space for layouts, all public Qt classes that inherit QLayoutItem
    support item alignment.
*/
void QLayoutItem::setAlignment(Qt::Alignment alignment)
{
    align = alignment;
}

/*!
    \fn QSize QLayoutItem::maximumSize() const

    Implemented in subclasses to return the maximum size of this item.
*/

/*!
    \fn QSize QLayoutItem::minimumSize() const

    Implemented in subclasses to return the minimum size of this item.
*/

/*!
    \fn QSize QLayoutItem::sizeHint() const

    Implemented in subclasses to return the preferred size of this item.
*/

/*!
    \fn Qt::Orientations QLayoutItem::expandingDirections() const

    Returns whether this layout item can make use of more space than
    sizeHint(). A value of Qt::Vertical or Qt::Horizontal means that
    it wants to grow in only one dimension, whereas Qt::Vertical |
    Qt::Horizontal means that it wants to grow in both dimensions.
*/

/*!
    \fn void QLayoutItem::setGeometry(const QRect &r)

    Implemented in subclasses to set this item's geometry to \a r.

    \sa geometry()
*/

/*!
    \fn QRect QLayoutItem::geometry() const

    Returns the rectangle covered by this layout item.

    \sa setGeometry()
*/

/*!
    \fn virtual bool QLayoutItem::isEmpty() const

    Implemented in subclasses to return whether this item is empty,
    i.e. whether it contains any widgets.
*/

/*!
    \fn QSpacerItem::QSpacerItem(int w, int h, QSizePolicy::Policy hPolicy, QSizePolicy::Policy vPolicy)

    Constructs a spacer item with preferred width \a w, preferred
    height \a h, horizontal size policy \a hPolicy and vertical size
    policy \a vPolicy.

    The default values provide a gap that is able to stretch if
    nothing else wants the space.
*/

/*!
    Destructor.
*/
QSpacerItem::~QSpacerItem() {}

/*!
    Changes this spacer item to have preferred width \a w, preferred
    height \a h, horizontal size policy \a hPolicy and vertical size
    policy \a vPolicy.

    The default values provide a gap that is able to stretch if
    nothing else wants the space.

    Note that if changeSize() is called after the spacer item has been added
    to a layout, it is necessary to invalidate the layout in order for the
    spacer item's new size to take effect.

    \sa QSpacerItem::invalidate()
*/
void QSpacerItem::changeSize(int w, int h, QSizePolicy::Policy hPolicy,
                             QSizePolicy::Policy vPolicy)
{
    width = w;
    height = h;
    sizeP = QSizePolicy(hPolicy, vPolicy);
}

/*!
    \fn QWidgetItem::QWidgetItem(QWidget *widget)

    Creates an item containing the given \a widget.
*/

/*!
    Destructor.
*/
QWidgetItem::~QWidgetItem() {}

/*!
    Destroys the QLayoutItem.
*/
QLayoutItem::~QLayoutItem()
{
}

/*!
    Invalidates any cached information in this layout item.
*/
void QLayoutItem::invalidate()
{
}

/*!
    If this item is a QLayout, it is returned as a QLayout; otherwise
    \nullptr is returned. This function provides type-safe casting.

    \sa spacerItem(), widget()
*/
QLayout *QLayoutItem::layout()
{
    return nullptr;
}

/*!
    If this item is a QSpacerItem, it is returned as a QSpacerItem;
    otherwise \nullptr is returned. This function provides type-safe casting.

    \sa layout(), widget()
*/
QSpacerItem *QLayoutItem::spacerItem()
{
    return nullptr;
}

/*!
    \reimp
*/
QLayout * QLayout::layout()
{
    return this;
}

/*!
    Returns a pointer to this object.
*/
QSpacerItem * QSpacerItem::spacerItem()
{
    return this;
}

/*!
    \fn QSizePolicy QSpacerItem::sizePolicy() const
    \since 5.5

    Returns the size policy of this item.
*/

/*!
    If this item manages a QWidget, returns that widget. Otherwise,
    \nullptr is returned.

    \note While the functions layout() and spacerItem() perform casts, this
    function returns another object: QLayout and QSpacerItem inherit QLayoutItem,
    while QWidget does not.

    \sa layout(), spacerItem()
*/
QWidget *QLayoutItem::widget()
{
    return nullptr;
}

/*!
    Returns the widget managed by this item.
*/
QWidget *QWidgetItem::widget()
{
    return wid;
}

/*!
    Returns \c true if this layout's preferred height depends on its
    width; otherwise returns \c false. The default implementation returns
    false.

    Reimplement this function in layout managers that support height
    for width.

    \sa heightForWidth(), QWidget::heightForWidth()
*/
bool QLayoutItem::hasHeightForWidth() const
{
    return false;
}

/*!
    Returns the minimum height this widget needs for the given width,
    \a w. The default implementation simply returns heightForWidth(\a
    w).
*/
int QLayoutItem::minimumHeightForWidth(int w) const
{
    return heightForWidth(w);
}


/*!
    Returns the preferred height for this layout item, given the
    width, which is not used in this default implementation.

    The default implementation returns -1, indicating that the
    preferred height is independent of the width of the item. Using
    the function hasHeightForWidth() will typically be much faster
    than calling this function and testing for -1.

    Reimplement this function in layout managers that support height
    for width. A typical implementation will look like this:
    \snippet code/src_gui_kernel_qlayoutitem.cpp 0

    Caching is strongly recommended; without it layout will take
    exponential time.

    \sa hasHeightForWidth()
*/
int QLayoutItem::heightForWidth(int /* w */) const
{
    return -1;
}

/*!
    Returns the control type(s) for the layout item. For a
    QWidgetItem, the control type comes from the widget's size
    policy; for a QLayoutItem, the control types is derived from the
    layout's contents.

    \sa QSizePolicy::controlType()
*/
QSizePolicy::ControlTypes QLayoutItem::controlTypes() const
{
    return QSizePolicy::DefaultType;
}

/*!
    \reimp
*/
void QSpacerItem::setGeometry(const QRect &r)
{
    rect = r;
}

/*!
    \reimp
*/
void QWidgetItem::setGeometry(const QRect &rect)
{
    if (isEmpty())
        return;

    QRect r = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
            ? fromLayoutItemRect(wid->d_func(), rect)
            : rect;
    const QSize widgetRectSurplus = r.size() - rect.size();

    /*
       For historical reasons, this code is done using widget rect
       coordinates, not layout item rect coordinates. However,
       QWidgetItem's sizeHint(), maximumSize(), and heightForWidth()
       all work in terms of layout item rect coordinates, so we have to
       add or subtract widgetRectSurplus here and there. The code could
       be much simpler if we did everything using layout item rect
       coordinates and did the conversion right before the call to
       QWidget::setGeometry().
     */

    QSize s = r.size().boundedTo(maximumSize() + widgetRectSurplus);
    int x = r.x();
    int y = r.y();
    if (align & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask)) {
        QSize pref(sizeHint());
        QSizePolicy sp = wid->sizePolicy();
        if (sp.horizontalPolicy() == QSizePolicy::Ignored)
            pref.setWidth(wid->sizeHint().expandedTo(wid->minimumSize()).width());
        if (sp.verticalPolicy() == QSizePolicy::Ignored)
            pref.setHeight(wid->sizeHint().expandedTo(wid->minimumSize()).height());
        pref += widgetRectSurplus;
        if (align & Qt::AlignHorizontal_Mask)
            s.setWidth(qMin(s.width(), pref.width()));
        if (align & Qt::AlignVertical_Mask) {
            if (hasHeightForWidth())
                s.setHeight(qMin(s.height(),
                                 heightForWidth(s.width() - widgetRectSurplus.width())
                                 + widgetRectSurplus.height()));
            else
                s.setHeight(qMin(s.height(), pref.height()));
        }
    }
    Qt::Alignment alignHoriz = QStyle::visualAlignment(wid->layoutDirection(), align);
    if (alignHoriz & Qt::AlignRight)
        x = x + (r.width() - s.width());
    else if (!(alignHoriz & Qt::AlignLeft))
        x = x + (r.width() - s.width()) / 2;

    if (align & Qt::AlignBottom)
        y = y + (r.height() - s.height());
    else if (!(align & Qt::AlignTop))
        y = y + (r.height() - s.height()) / 2;

    // Make sure we don't move outside of the parent, e.g when styles demand
    // surplus space that exceeds the available margins (f.ex macOS with QGroupBox)
    if (x < 0) {
        s.rwidth() += x;
        x = 0;
    }
    if (y < 0) {
        s.rheight() += y;
        y = 0;
    }

    wid->setGeometry(x, y, s.width(), s.height());
}

/*!
    \reimp
*/
QRect QSpacerItem::geometry() const
{
    return rect;
}

/*!
    \reimp
*/
QRect QWidgetItem::geometry() const
{
    return !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
           ? toLayoutItemRect(wid->d_func(), wid->geometry())
           : wid->geometry();
}


/*!
    \reimp
*/
bool QWidgetItem::hasHeightForWidth() const
{
    if (isEmpty())
        return false;
    return wid->hasHeightForWidth();
}

/*!
    \reimp
*/
int QWidgetItem::heightForWidth(int w) const
{
    if (isEmpty())
        return -1;

    w = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
      ? fromLayoutItemSize(wid->d_func(), QSize(w, 0)).width()
      : w;

    int hfw;
    if (wid->layout())
        hfw = wid->layout()->totalHeightForWidth(w);
    else
        hfw = wid->heightForWidth(w);

    if (hfw > wid->maximumHeight())
        hfw = wid->maximumHeight();
    if (hfw < wid->minimumHeight())
        hfw = wid->minimumHeight();

    hfw = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
        ? toLayoutItemSize(wid->d_func(), QSize(0, hfw)).height()
        : hfw;

    if (hfw < 0)
        hfw = 0;
    return hfw;
}

/*!
    \reimp
*/
Qt::Orientations QSpacerItem::expandingDirections() const
{
    return sizeP.expandingDirections();
}

/*!
    \reimp
*/
Qt::Orientations QWidgetItem::expandingDirections() const
{
    if (isEmpty())
        return Qt::Orientations(0);

    Qt::Orientations e = wid->sizePolicy().expandingDirections();
    /*
      If the layout is expanding, we make the widget expanding, even if
      its own size policy isn't expanding.
    */
    if (wid->layout()) {
        if (wid->sizePolicy().horizontalPolicy() & QSizePolicy::GrowFlag
                && (wid->layout()->expandingDirections() & Qt::Horizontal))
            e |= Qt::Horizontal;
        if (wid->sizePolicy().verticalPolicy() & QSizePolicy::GrowFlag
                && (wid->layout()->expandingDirections() & Qt::Vertical))
            e |= Qt::Vertical;
    }

    if (align & Qt::AlignHorizontal_Mask)
        e &= ~Qt::Horizontal;
    if (align & Qt::AlignVertical_Mask)
        e &= ~Qt::Vertical;
    return e;
}

/*!
    \reimp
*/
QSize QSpacerItem::minimumSize() const
{
    return QSize(sizeP.horizontalPolicy() & QSizePolicy::ShrinkFlag ? 0 : width,
                 sizeP.verticalPolicy() & QSizePolicy::ShrinkFlag ? 0 : height);
}

/*!
    \reimp
*/
QSize QWidgetItem::minimumSize() const
{
    if (isEmpty())
        return QSize(0, 0);
    return !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
           ? toLayoutItemSize(wid->d_func(), qSmartMinSize(this))
           : qSmartMinSize(this);
}

/*!
    \reimp
*/
QSize QSpacerItem::maximumSize() const
{
    return QSize(sizeP.horizontalPolicy() & QSizePolicy::GrowFlag ? QLAYOUTSIZE_MAX : width,
                 sizeP.verticalPolicy() & QSizePolicy::GrowFlag ? QLAYOUTSIZE_MAX : height);
}

/*!
    \reimp
*/
QSize QWidgetItem::maximumSize() const
{
    if (isEmpty()) {
        return QSize(0, 0);
    } else {
        return !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
               ? toLayoutItemSize(wid->d_func(), qSmartMaxSize(this, align))
               : qSmartMaxSize(this, align);
    }
}

/*!
    \reimp
*/
QSize QSpacerItem::sizeHint() const
{
    return QSize(width, height);
}

/*!
    \reimp
*/
QSize QWidgetItem::sizeHint() const
{
    QSize s(0, 0);
    if (!isEmpty()) {
        s = wid->sizeHint().expandedTo(wid->minimumSizeHint());
        s = s.boundedTo(wid->maximumSize())
             .expandedTo(wid->minimumSize());
        s = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect)
           ? toLayoutItemSize(wid->d_func(), s)
           : s;

        if (wid->sizePolicy().horizontalPolicy() == QSizePolicy::Ignored)
            s.setWidth(0);
        if (wid->sizePolicy().verticalPolicy() == QSizePolicy::Ignored)
            s.setHeight(0);
    }
    return s;
}

/*!
    Returns \c true.
*/
bool QSpacerItem::isEmpty() const
{
    return true;
}

/*!
    Returns \c true if the widget is hidden; otherwise returns \c false.

    \sa QWidget::isHidden()
*/
bool QWidgetItem::isEmpty() const
{
    return (wid->isHidden() && !wid->sizePolicy().retainSizeWhenHidden()) || wid->isWindow();
}

/*!
    Returns the control type associated with the widget for which
    this size policy applies.

    \sa QSizePolicy::controlType()
 */
QSizePolicy::ControlTypes QWidgetItem::controlTypes() const
{
    return wid->sizePolicy().controlType();
}

/*!
    \class QWidgetItemV2
    \internal
*/

inline bool QWidgetItemV2::useSizeCache() const
{
    return wid->d_func()->widgetItem == this;
}

void QWidgetItemV2::updateCacheIfNecessary() const
{
    if (q_cachedMinimumSize.width() != Dirty)
        return;

    const QSize sizeHint(wid->sizeHint());
    const QSize minimumSizeHint(wid->minimumSizeHint());
    const QSize minimumSize(wid->minimumSize());
    const QSize maximumSize(wid->maximumSize());
    const QSizePolicy sizePolicy(wid->sizePolicy());
    const QSize expandedSizeHint(sizeHint.expandedTo(minimumSizeHint));

    const QSize smartMinSize(qSmartMinSize(sizeHint, minimumSizeHint, minimumSize, maximumSize, sizePolicy));
    const QSize smartMaxSize(qSmartMaxSize(expandedSizeHint, minimumSize, maximumSize, sizePolicy, align));

    const bool useLayoutItemRect = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect);

    q_cachedMinimumSize = useLayoutItemRect
           ? toLayoutItemSize(wid->d_func(), smartMinSize)
           : smartMinSize;

    q_cachedSizeHint = expandedSizeHint;
    q_cachedSizeHint = q_cachedSizeHint.boundedTo(maximumSize)
                                       .expandedTo(minimumSize);
    q_cachedSizeHint = useLayoutItemRect
           ? toLayoutItemSize(wid->d_func(), q_cachedSizeHint)
           : q_cachedSizeHint;

    if (wid->sizePolicy().horizontalPolicy() == QSizePolicy::Ignored)
        q_cachedSizeHint.setWidth(0);
    if (wid->sizePolicy().verticalPolicy() == QSizePolicy::Ignored)
        q_cachedSizeHint.setHeight(0);

    q_cachedMaximumSize = useLayoutItemRect
               ? toLayoutItemSize(wid->d_func(), smartMaxSize)
               : smartMaxSize;
}

QWidgetItemV2::QWidgetItemV2(QWidget *widget)
    : QWidgetItem(widget),
      q_cachedMinimumSize(Dirty, Dirty),
      q_cachedSizeHint(Dirty, Dirty),
      q_cachedMaximumSize(Dirty, Dirty),
      q_firstCachedHfw(0),
      q_hfwCacheSize(0),
      d(0)
{
    QWidgetPrivate *wd = wid->d_func();
    if (!wd->widgetItem)
        wd->widgetItem = this;
}

QWidgetItemV2::~QWidgetItemV2()
{
    if (wid) {
        auto *wd = static_cast<QWidgetPrivate *>(QObjectPrivate::get(wid));
        if (wd->widgetItem == this)
            wd->widgetItem = 0;
    }
}

QSize QWidgetItemV2::sizeHint() const
{
    if (isEmpty())
        return QSize(0, 0);

    if (useSizeCache()) {
        updateCacheIfNecessary();
        return q_cachedSizeHint;
    } else {
        return QWidgetItem::sizeHint();
    }
}

QSize QWidgetItemV2::minimumSize() const
{
    if (isEmpty())
        return QSize(0, 0);

    if (useSizeCache()) {
        updateCacheIfNecessary();
        return q_cachedMinimumSize;
    } else {
        return QWidgetItem::minimumSize();
    }
}

QSize QWidgetItemV2::maximumSize() const
{
    if (isEmpty())
        return QSize(0, 0);

    if (useSizeCache()) {
        updateCacheIfNecessary();
        return q_cachedMaximumSize;
    } else {
        return QWidgetItem::maximumSize();
    }
}

/*
    The height-for-width cache is organized as a circular buffer. The entries

        q_hfwCachedHfws[q_firstCachedHfw],
        ...,
        q_hfwCachedHfws[(q_firstCachedHfw + q_hfwCacheSize - 1) % HfwCacheMaxSize]

    contain the last cached values. When the cache is full, the first entry to
    be erased is the entry before q_hfwCachedHfws[q_firstCachedHfw]. When
    values are looked up, we try to move q_firstCachedHfw to point to that new
    entry (unless the cache is not full, in which case it would leave the cache
    in a broken state), so that the most recently used entry is also the last
    to be erased.
*/

int QWidgetItemV2::heightForWidth(int width) const
{
    if (isEmpty())
        return -1;

    for (int i = 0; i < q_hfwCacheSize; ++i) {
        int offset = q_firstCachedHfw + i;
        const QSize &size = q_cachedHfws[offset % HfwCacheMaxSize];
        if (size.width() == width) {
            if (q_hfwCacheSize == HfwCacheMaxSize)
                q_firstCachedHfw = offset % HfwCacheMaxSize;
            return size.height();
        }
    }

    if (q_hfwCacheSize < HfwCacheMaxSize)
        ++q_hfwCacheSize;
    q_firstCachedHfw = (q_firstCachedHfw + HfwCacheMaxSize - 1) % HfwCacheMaxSize;

    int height = QWidgetItem::heightForWidth(width);
    q_cachedHfws[q_firstCachedHfw] = QSize(width, height);
    return height;
}

QT_END_NAMESPACE
