/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickcontrol_p.h"
#include "qquickcontrol_p_p.h"

#include <QtGui/qstylehints.h>
#include <QtGui/qguiapplication.h>
#include "qquicklabel_p.h"
#include "qquicklabel_p_p.h"
#include "qquicktextarea_p.h"
#include "qquicktextarea_p_p.h"
#include "qquicktextfield_p.h"
#include "qquicktextfield_p_p.h"
#include "qquickpopup_p.h"
#include "qquickpopupitem_p_p.h"
#include "qquickapplicationwindow_p.h"
#include "qquickdeferredexecute_p_p.h"

#if QT_CONFIG(accessibility)
#include <QtQuick/private/qquickaccessibleattached_p.h>
#endif

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(lcItemManagement, "qt.quick.controls.control.itemmanagement")

/*!
    \qmltype Control
    \inherits Item
//!     \instantiates QQuickControl
    \inqmlmodule QtQuick.Controls
    \since 5.7
    \brief Abstract base type providing functionality common to all controls.

    Control is the base type of user interface controls.  It receives input
    events from the window system, and paints a representation of itself on
    the screen.

    \section1 Control Layout

    The following diagram illustrates the layout of a typical control:

    \image qtquickcontrols2-control.png

    The \l {Item::}{implicitWidth} and \l {Item::}{implicitHeight} of a control
    are typically based on the implicit sizes of the background and the content
    item plus any insets and paddings. These properties determine how large
    the control will be when no explicit \l {Item::}{width} or
    \l {Item::}{height} is specified.

    The geometry of the \l {Control::}{contentItem} is determined by the padding.
    The following example reserves 10px padding between the boundaries of the
    control and its content:

    \code
    Control {
        padding: 10

        contentItem: Text {
            text: "Content"
        }
    }
    \endcode

    The \l {Control::}{background} item fills the entire width and height of the
    control, unless insets or an explicit size have been given for it. Background
    insets are useful for extending the touchable/interactive area of a control
    without affecting its visual size. This is often used on touch devices to
    ensure that a control is not too small to be interacted with by the user.
    Insets affect the size of the control, and hence will affect how much space
    they take up in a layout, for example.

    Negative insets can be used to make the background larger than the control.
    The following example uses negative insets to place a shadow outside the
    control's boundaries:

    \code
    Control {
        topInset: -2
        leftInset: -2
        rightInset: -6
        bottomInset: -6

        background: BorderImage {
            source: ":/images/shadowed-background.png"
        }
    }
    \endcode

    \section1 Event Handling

    All controls, except non-interactive indicators, do not let clicks and
    touches through to items below them. For example, the \c console.log()
    call in the example below will never be executed when clicking on the
    Pane, because the \l MouseArea is below it in the scene:

    \code
    MouseArea {
        anchors.fill: parent
        onClicked: console.log("MouseArea was clicked")

        Pane {
            anchors.fill: parent
        }
    }
    \endcode

    \sa ApplicationWindow, Container
*/

const QQuickItemPrivate::ChangeTypes QQuickControlPrivate::ImplicitSizeChanges = QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed;

static bool isKeyFocusReason(Qt::FocusReason reason)
{
    return reason == Qt::TabFocusReason || reason == Qt::BacktabFocusReason || reason == Qt::ShortcutFocusReason;
}

QQuickControlPrivate::QQuickControlPrivate()
{
#if QT_CONFIG(accessibility)
    QAccessible::installActivationObserver(this);
#endif
}

QQuickControlPrivate::~QQuickControlPrivate()
{
#if QT_CONFIG(accessibility)
    QAccessible::removeActivationObserver(this);
#endif
}

void QQuickControlPrivate::init()
{
    Q_Q(QQuickControl);
    QObject::connect(q, &QQuickItem::baselineOffsetChanged, q, &QQuickControl::baselineOffsetChanged);
}

#if QT_CONFIG(quicktemplates2_multitouch)
bool QQuickControlPrivate::acceptTouch(const QTouchEvent::TouchPoint &point)
{
    if (point.id() == touchId)
        return true;

    if (touchId == -1 && point.state() == Qt::TouchPointPressed) {
        touchId = point.id();
        return true;
    }

    // If the control is on a Flickable that has a pressDelay, then the press is never
    // sent as a touch event, therefore we need to check for this case.
    if (touchId == -1 && pressWasTouch && point.state() == Qt::TouchPointReleased &&
        point.pos() == previousPressPos) {
        return true;
    }
    return false;
}
#endif

static void setActiveFocus(QQuickControl *control, Qt::FocusReason reason)
{
    QQuickControlPrivate *d = QQuickControlPrivate::get(control);
    if (d->subFocusItem && d->window && d->flags & QQuickItem::ItemIsFocusScope)
        QQuickWindowPrivate::get(d->window)->clearFocusInScope(control, d->subFocusItem, reason);
    control->forceActiveFocus(reason);
}

void QQuickControlPrivate::handlePress(const QPointF &)
{
    Q_Q(QQuickControl);
    if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && !QGuiApplication::styleHints()->setFocusOnTouchRelease())
        setActiveFocus(q, Qt::MouseFocusReason);
}

void QQuickControlPrivate::handleMove(const QPointF &point)
{
#if QT_CONFIG(quicktemplates2_hover)
    Q_Q(QQuickControl);
    q->setHovered(hoverEnabled && q->contains(point));
#else
    Q_UNUSED(point);
#endif
}

void QQuickControlPrivate::handleRelease(const QPointF &)
{
    Q_Q(QQuickControl);
    if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease())
        setActiveFocus(q, Qt::MouseFocusReason);
    touchId = -1;
    pressWasTouch = false;
    previousPressPos = QPointF();
}

void QQuickControlPrivate::handleUngrab()
{
    touchId = -1;
}

void QQuickControlPrivate::mirrorChange()
{
    Q_Q(QQuickControl);
    if (locale.textDirection() == Qt::LeftToRight)
        q->mirrorChange();
}

void QQuickControlPrivate::setTopPadding(qreal value, bool reset)
{
    Q_Q(QQuickControl);
    const QMarginsF oldPadding = getPadding();
    extra.value().topPadding = value;
    extra.value().hasTopPadding = !reset;
    if ((!reset && !qFuzzyCompare(oldPadding.top(), value)) || (reset && !qFuzzyCompare(oldPadding.top(), getVerticalPadding()))) {
        emit q->topPaddingChanged();
        emit q->availableHeightChanged();
        q->paddingChange(getPadding(), oldPadding);
    }
}

void QQuickControlPrivate::setLeftPadding(qreal value, bool reset)
{
    Q_Q(QQuickControl);
    const QMarginsF oldPadding = getPadding();
    extra.value().leftPadding = value;
    extra.value().hasLeftPadding = !reset;
    if ((!reset && !qFuzzyCompare(oldPadding.left(), value)) || (reset && !qFuzzyCompare(oldPadding.left(), getHorizontalPadding()))) {
        emit q->leftPaddingChanged();
        emit q->availableWidthChanged();
        q->paddingChange(getPadding(), oldPadding);
    }
}

void QQuickControlPrivate::setRightPadding(qreal value, bool reset)
{
    Q_Q(QQuickControl);
    const QMarginsF oldPadding = getPadding();
    extra.value().rightPadding = value;
    extra.value().hasRightPadding = !reset;
    if ((!reset && !qFuzzyCompare(oldPadding.right(), value)) || (reset && !qFuzzyCompare(oldPadding.right(), getHorizontalPadding()))) {
        emit q->rightPaddingChanged();
        emit q->availableWidthChanged();
        q->paddingChange(getPadding(), oldPadding);
    }
}

void QQuickControlPrivate::setBottomPadding(qreal value, bool reset)
{
    Q_Q(QQuickControl);
    const QMarginsF oldPadding = getPadding();
    extra.value().bottomPadding = value;
    extra.value().hasBottomPadding = !reset;
    if ((!reset && !qFuzzyCompare(oldPadding.bottom(), value)) || (reset && !qFuzzyCompare(oldPadding.bottom(), getVerticalPadding()))) {
        emit q->bottomPaddingChanged();
        emit q->availableHeightChanged();
        q->paddingChange(getPadding(), oldPadding);
    }
}

void QQuickControlPrivate::setHorizontalPadding(qreal value, bool reset)
{
    Q_Q(QQuickControl);
    const QMarginsF oldPadding = getPadding();
    const qreal oldHorizontalPadding = getHorizontalPadding();
    horizontalPadding = value;
    hasHorizontalPadding = !reset;
    if ((!reset && !qFuzzyCompare(oldHorizontalPadding, value)) || (reset && !qFuzzyCompare(oldHorizontalPadding, padding))) {
        const QMarginsF newPadding = getPadding();
        if (!qFuzzyCompare(newPadding.left(), oldPadding.left()))
            emit q->leftPaddingChanged();
        if (!qFuzzyCompare(newPadding.right(), oldPadding.right()))
            emit q->rightPaddingChanged();
        emit q->horizontalPaddingChanged();
        emit q->availableWidthChanged();
        q->paddingChange(newPadding, oldPadding);
    }
}

void QQuickControlPrivate::setVerticalPadding(qreal value, bool reset)
{
    Q_Q(QQuickControl);
    const QMarginsF oldPadding = getPadding();
    const qreal oldVerticalPadding = getVerticalPadding();
    verticalPadding = value;
    hasVerticalPadding = !reset;
    if ((!reset && !qFuzzyCompare(oldVerticalPadding, value)) || (reset && !qFuzzyCompare(oldVerticalPadding, padding))) {
        const QMarginsF newPadding = getPadding();
        if (!qFuzzyCompare(newPadding.top(), oldPadding.top()))
            emit q->topPaddingChanged();
        if (!qFuzzyCompare(newPadding.bottom(), oldPadding.bottom()))
            emit q->bottomPaddingChanged();
        emit q->verticalPaddingChanged();
        emit q->availableHeightChanged();
        q->paddingChange(newPadding, oldPadding);
    }
}

void QQuickControlPrivate::setTopInset(qreal value, bool reset)
{
    Q_Q(QQuickControl);
    const QMarginsF oldInset = getInset();
    extra.value().topInset = value;
    extra.value().hasTopInset = !reset;
    if (!qFuzzyCompare(oldInset.top(), value)) {
        emit q->topInsetChanged();
        q->insetChange(getInset(), oldInset);
    }
}

void QQuickControlPrivate::setLeftInset(qreal value, bool reset)
{
    Q_Q(QQuickControl);
    const QMarginsF oldInset = getInset();
    extra.value().leftInset = value;
    extra.value().hasLeftInset = !reset;
    if (!qFuzzyCompare(oldInset.left(), value)) {
        emit q->leftInsetChanged();
        q->insetChange(getInset(), oldInset);
    }
}

void QQuickControlPrivate::setRightInset(qreal value, bool reset)
{
    Q_Q(QQuickControl);
    const QMarginsF oldInset = getInset();
    extra.value().rightInset = value;
    extra.value().hasRightInset = !reset;
    if (!qFuzzyCompare(oldInset.right(), value)) {
        emit q->rightInsetChanged();
        q->insetChange(getInset(), oldInset);
    }
}

void QQuickControlPrivate::setBottomInset(qreal value, bool reset)
{
    Q_Q(QQuickControl);
    const QMarginsF oldInset = getInset();
    extra.value().bottomInset = value;
    extra.value().hasBottomInset = !reset;
    if (!qFuzzyCompare(oldInset.bottom(), value)) {
        emit q->bottomInsetChanged();
        q->insetChange(getInset(), oldInset);
    }
}

void QQuickControlPrivate::resizeBackground()
{
    if (!background)
        return;

    resizingBackground = true;

    QQuickItemPrivate *p = QQuickItemPrivate::get(background);
    if (((!p->widthValid || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(background->x()))
            || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) {
        background->setX(getLeftInset());
        background->setWidth(width - getLeftInset() - getRightInset());
    }
    if (((!p->heightValid || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y()))
            || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) {
        background->setY(getTopInset());
        background->setHeight(height - getTopInset() - getBottomInset());
    }

    resizingBackground = false;
}

void QQuickControlPrivate::resizeContent()
{
    Q_Q(QQuickControl);
    if (contentItem) {
        contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding()));
        contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight()));
    }
}

QQuickItem *QQuickControlPrivate::getContentItem()
{
    if (!contentItem)
        executeContentItem();
    return contentItem;
}

void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify)
{
    Q_Q(QQuickControl);
    if (contentItem == item)
        return;

    if (!contentItem.isExecuting())
        cancelContentItem();

    QQuickItem *oldContentItem = contentItem;
    if (oldContentItem) {
        disconnect(oldContentItem, &QQuickItem::baselineOffsetChanged, this, &QQuickControlPrivate::updateBaselineOffset);
        removeImplicitSizeListener(oldContentItem);
    }

    contentItem = item;
    q->contentItemChange(item, oldContentItem);
    QQuickControlPrivate::hideOldItem(oldContentItem);

    if (item) {
        connect(contentItem.data(), &QQuickItem::baselineOffsetChanged, this, &QQuickControlPrivate::updateBaselineOffset);
        if (!item->parentItem())
            item->setParentItem(q);
        if (componentComplete)
            resizeContent();
        addImplicitSizeListener(contentItem);
    }

    updateImplicitContentSize();
    updateBaselineOffset();

    if (notify && !contentItem.isExecuting())
        emit q->contentItemChanged();
}

qreal QQuickControlPrivate::getContentWidth() const
{
    return contentItem ? contentItem->implicitWidth() : 0;
}

qreal QQuickControlPrivate::getContentHeight() const
{
    return contentItem ? contentItem->implicitHeight() : 0;
}

void QQuickControlPrivate::updateImplicitContentWidth()
{
    Q_Q(QQuickControl);
    const qreal oldWidth = implicitContentWidth;
    implicitContentWidth = getContentWidth();
    if (!qFuzzyCompare(implicitContentWidth, oldWidth))
        emit q->implicitContentWidthChanged();
}

void QQuickControlPrivate::updateImplicitContentHeight()
{
    Q_Q(QQuickControl);
    const qreal oldHeight = implicitContentHeight;
    implicitContentHeight = getContentHeight();
    if (!qFuzzyCompare(implicitContentHeight, oldHeight))
        emit q->implicitContentHeightChanged();
}

void QQuickControlPrivate::updateImplicitContentSize()
{
    Q_Q(QQuickControl);
    const qreal oldWidth = implicitContentWidth;
    const qreal oldHeight = implicitContentHeight;
    implicitContentWidth = getContentWidth();
    implicitContentHeight = getContentHeight();
    if (!qFuzzyCompare(implicitContentWidth, oldWidth))
        emit q->implicitContentWidthChanged();
    if (!qFuzzyCompare(implicitContentHeight, oldHeight))
        emit q->implicitContentHeightChanged();
}

#if QT_CONFIG(accessibility)
void QQuickControlPrivate::accessibilityActiveChanged(bool active)
{
    Q_Q(QQuickControl);
    return q->accessibilityActiveChanged(active);
}

QAccessible::Role QQuickControlPrivate::accessibleRole() const
{
    Q_Q(const QQuickControl);
    return q->accessibleRole();
}

QQuickAccessibleAttached *QQuickControlPrivate::accessibleAttached(const QObject *object)
{
    if (!QAccessible::isActive())
        return nullptr;
    return QQuickAccessibleAttached::attachedProperties(object);
}
#endif

/*!
    \internal

    Returns the font that the control w inherits from its ancestors and
    QGuiApplication::font.
*/
QFont QQuickControlPrivate::parentFont(const QQuickItem *item)
{
    QQuickItem *p = item->parentItem();
    while (p) {
        if (QQuickControl *control = qobject_cast<QQuickControl *>(p))
            return control->font();
        else if (QQuickLabel *label = qobject_cast<QQuickLabel *>(p))
            return label->font();
        else if (QQuickTextField *textField = qobject_cast<QQuickTextField *>(p))
            return textField->font();
        else if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(p))
            return textArea->font();

        p = p->parentItem();
    }

    if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(item->window()))
        return window->font();

    return QQuickTheme::font(QQuickTheme::System);
}

/*!
    \internal

    Determine which font is implicitly imposed on this control by its ancestors
    and QGuiApplication::font, resolve this against its own font (attributes from
    the implicit font are copied over). Then propagate this font to this
    control's children.
*/
void QQuickControlPrivate::resolveFont()
{
    Q_Q(QQuickControl);
    inheritFont(parentFont(q));
}

void QQuickControlPrivate::inheritFont(const QFont &font)
{
    Q_Q(QQuickControl);
    QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font;
    parentFont.resolve(extra.isAllocated() ? extra->requestedFont.resolve() | font.resolve() : font.resolve());

    const QFont defaultFont = q->defaultFont();
    QFont resolvedFont = parentFont.resolve(defaultFont);
    // Since resolving the font will put the family() into the
    // families() list if it is empty then we need to unset it
    // so it does not act as if the font has changed (when it
    // has not actually changed)
    if (defaultFont.families().isEmpty())
        resolvedFont.setFamilies(QStringList());

    setFont_helper(resolvedFont);
}

/*!
    \internal

    Assign \a font to this control, and propagate it to all children.
*/
void QQuickControlPrivate::updateFont(const QFont &font)
{
    Q_Q(QQuickControl);
    QFont oldFont = resolvedFont;
    resolvedFont = font;

    if (oldFont != font)
        q->fontChange(font, oldFont);

    QQuickControlPrivate::updateFontRecur(q, font);

    if (oldFont != font)
        emit q->fontChanged();
}

void QQuickControlPrivate::updateFontRecur(QQuickItem *item, const QFont &font)
{
    const auto childItems = item->childItems();
    for (QQuickItem *child : childItems) {
        if (QQuickControl *control = qobject_cast<QQuickControl *>(child))
            QQuickControlPrivate::get(control)->inheritFont(font);
        else if (QQuickLabel *label = qobject_cast<QQuickLabel *>(child))
            QQuickLabelPrivate::get(label)->inheritFont(font);
        else if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(child))
            QQuickTextAreaPrivate::get(textArea)->inheritFont(font);
        else if (QQuickTextField *textField = qobject_cast<QQuickTextField *>(child))
            QQuickTextFieldPrivate::get(textField)->inheritFont(font);
        else
            QQuickControlPrivate::updateFontRecur(child, font);
    }
}

/*!
    \internal

    Returns the palette that the item inherits from its ancestors and
    QGuiApplication::palette.
*/
QPalette QQuickControlPrivate::parentPalette(const QQuickItem *item)
{
    QQuickItem *p = item->parentItem();
    while (p) {
        if (QQuickControl *control = qobject_cast<QQuickControl *>(p))
            return control->palette();
        else if (QQuickLabel *label = qobject_cast<QQuickLabel *>(p))
            return label->palette();
        else if (QQuickTextField *textField = qobject_cast<QQuickTextField *>(p))
            return textField->palette();
        else if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(p))
            return textArea->palette();

        p = p->parentItem();
    }

    if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(item->window()))
        return window->palette();

    return QQuickTheme::palette(QQuickTheme::System);
}

/*!
    \internal

    Determine which palette is implicitly imposed on this control by its ancestors
    and QGuiApplication::palette, resolve this against its own palette (attributes from
    the implicit palette are copied over). Then propagate this palette to this
    control's children.
*/
void QQuickControlPrivate::resolvePalette()
{
    Q_Q(QQuickControl);
    inheritPalette(parentPalette(q));
}

void QQuickControlPrivate::inheritPalette(const QPalette &palette)
{
    Q_Q(QQuickControl);
    QPalette parentPalette = extra.isAllocated() ? extra->requestedPalette.resolve(palette) : palette;
    parentPalette.resolve(extra.isAllocated() ? extra->requestedPalette.resolve() | palette.resolve() : palette.resolve());

    const QPalette defaultPalette = q->defaultPalette();
    const QPalette resolvedPalette = parentPalette.resolve(defaultPalette);

    setPalette_helper(resolvedPalette);
}

/*!
    \internal

    Assign \a palette to this control, and propagate it to all children.
*/
void QQuickControlPrivate::updatePalette(const QPalette &palette)
{
    Q_Q(QQuickControl);
    QPalette oldPalette = resolvedPalette;
    resolvedPalette = palette;

    if (oldPalette != palette)
        q->paletteChange(palette, oldPalette);

    QQuickControlPrivate::updatePaletteRecur(q, palette);

    if (oldPalette != palette)
        emit q->paletteChanged();
}

void QQuickControlPrivate::updatePaletteRecur(QQuickItem *item, const QPalette &palette)
{
    const auto childItems = item->childItems();
    for (QQuickItem *child : childItems) {
        if (QQuickControl *control = qobject_cast<QQuickControl *>(child))
            QQuickControlPrivate::get(control)->inheritPalette(palette);
        else if (QQuickLabel *label = qobject_cast<QQuickLabel *>(child))
            QQuickLabelPrivate::get(label)->inheritPalette(palette);
        else if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(child))
            QQuickTextAreaPrivate::get(textArea)->inheritPalette(palette);
        else if (QQuickTextField *textField = qobject_cast<QQuickTextField *>(child))
            QQuickTextFieldPrivate::get(textField)->inheritPalette(palette);
        else
            QQuickControlPrivate::updatePaletteRecur(child, palette);
    }
}

QLocale QQuickControlPrivate::calcLocale(const QQuickItem *item)
{
    const QQuickItem *p = item;
    while (p) {
        if (const QQuickControl *control = qobject_cast<const QQuickControl *>(p))
            return control->locale();

        QVariant v = p->property("locale");
        if (v.isValid() && v.userType() == QMetaType::QLocale)
            return v.toLocale();

        p = p->parentItem();
    }

    if (item) {
        if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(item->window()))
            return window->locale();
    }

    return QLocale();
}

void QQuickControlPrivate::updateLocale(const QLocale &l, bool e)
{
    Q_Q(QQuickControl);
    if (!e && hasLocale)
        return;

    QLocale old = q->locale();
    hasLocale = e;
    if (old != l) {
        bool wasMirrored = q->isMirrored();
        locale = l;
        q->localeChange(l, old);
        QQuickControlPrivate::updateLocaleRecur(q, l);
        emit q->localeChanged();
        if (wasMirrored != q->isMirrored())
            q->mirrorChange();
    }
}

void QQuickControlPrivate::updateLocaleRecur(QQuickItem *item, const QLocale &l)
{
    const auto childItems = item->childItems();
    for (QQuickItem *child : childItems) {
        if (QQuickControl *control = qobject_cast<QQuickControl *>(child))
            QQuickControlPrivate::get(control)->updateLocale(l, false);
        else
            updateLocaleRecur(child, l);
    }
}

#if QT_CONFIG(quicktemplates2_hover)
void QQuickControlPrivate::updateHoverEnabled(bool enabled, bool xplicit)
{
    Q_Q(QQuickControl);
    if (!xplicit && explicitHoverEnabled)
        return;

    bool wasEnabled = q->isHoverEnabled();
    explicitHoverEnabled = xplicit;
    if (wasEnabled != enabled) {
        q->setAcceptHoverEvents(enabled);
        QQuickControlPrivate::updateHoverEnabledRecur(q, enabled);
        emit q->hoverEnabledChanged();
    }
}

void QQuickControlPrivate::updateHoverEnabledRecur(QQuickItem *item, bool enabled)
{
    const auto childItems = item->childItems();
    for (QQuickItem *child : childItems) {
        if (QQuickControl *control = qobject_cast<QQuickControl *>(child))
            QQuickControlPrivate::get(control)->updateHoverEnabled(enabled, false);
        else
            updateHoverEnabledRecur(child, enabled);
    }
}

bool QQuickControlPrivate::calcHoverEnabled(const QQuickItem *item)
{
    const QQuickItem *p = item;
    while (p) {
        // QQuickPopupItem accepts hover events to avoid leaking them through.
        // Don't inherit that to the children of the popup, but fallback to the
        // environment variable or style hint.
        if (qobject_cast<const QQuickPopupItem *>(p))
            break;

        if (const QQuickControl *control = qobject_cast<const QQuickControl *>(p))
            return control->isHoverEnabled();

        QVariant v = p->property("hoverEnabled");
        if (v.isValid() && v.userType() == QMetaType::Bool)
            return v.toBool();

        p = p->parentItem();
    }

    bool ok = false;
    int env = qEnvironmentVariableIntValue("QT_QUICK_CONTROLS_HOVER_ENABLED", &ok);
    if (ok)
        return env != 0;

    // TODO: QQuickApplicationWindow::isHoverEnabled()

    return QGuiApplication::styleHints()->useHoverEffects();
}
#endif

static inline QString contentItemName() { return QStringLiteral("contentItem"); }

void QQuickControlPrivate::cancelContentItem()
{
    Q_Q(QQuickControl);
    quickCancelDeferred(q, contentItemName());
}

void QQuickControlPrivate::executeContentItem(bool complete)
{
    Q_Q(QQuickControl);
    if (contentItem.wasExecuted())
        return;

    if (!contentItem || complete)
        quickBeginDeferred(q, contentItemName(), contentItem);
    if (complete)
        quickCompleteDeferred(q, contentItemName(), contentItem);
}

static inline QString backgroundName() { return QStringLiteral("background"); }

void QQuickControlPrivate::cancelBackground()
{
    Q_Q(QQuickControl);
    quickCancelDeferred(q, backgroundName());
}

void QQuickControlPrivate::executeBackground(bool complete)
{
    Q_Q(QQuickControl);
    if (background.wasExecuted())
        return;

    if (!background || complete)
        quickBeginDeferred(q, backgroundName(), background);
    if (complete)
        quickCompleteDeferred(q, backgroundName(), background);
}

void QQuickControlPrivate::hideOldItem(QQuickItem *item)
{
    if (!item)
        return;

    qCDebug(lcItemManagement) << "hiding old item" << item;

    item->setVisible(false);
    item->setParentItem(nullptr);

#if QT_CONFIG(accessibility)
    // Remove the item from the accessibility tree.
    QQuickAccessibleAttached *accessible = accessibleAttached(item);
    if (accessible)
        accessible->setIgnored(true);
#endif
}

void QQuickControlPrivate::updateBaselineOffset()
{
    Q_Q(QQuickControl);
    if (extra.isAllocated() && extra.value().hasBaselineOffset)
        return;

    if (!contentItem)
        q->QQuickItem::setBaselineOffset(0);
    else
        q->QQuickItem::setBaselineOffset(getTopPadding() + contentItem->baselineOffset());
}

void QQuickControlPrivate::addImplicitSizeListener(QQuickItem *item, ChangeTypes changes)
{
    addImplicitSizeListener(item, this, changes);
}

void QQuickControlPrivate::removeImplicitSizeListener(QQuickItem *item, ChangeTypes changes)
{
    removeImplicitSizeListener(item, this, changes);
}

void QQuickControlPrivate::addImplicitSizeListener(QQuickItem *item, QQuickItemChangeListener *listener, ChangeTypes changes)
{
    if (!item || !listener)
        return;
    QQuickItemPrivate::get(item)->addItemChangeListener(listener, changes);
}

void QQuickControlPrivate::removeImplicitSizeListener(QQuickItem *item, QQuickItemChangeListener *listener, ChangeTypes changes)
{
    if (!item || !listener)
        return;
    QQuickItemPrivate::get(item)->removeItemChangeListener(listener, changes);
}

void QQuickControlPrivate::itemImplicitWidthChanged(QQuickItem *item)
{
    Q_Q(QQuickControl);
    if (item == background)
        emit q->implicitBackgroundWidthChanged();
    else if (item == contentItem)
        updateImplicitContentWidth();
}

void QQuickControlPrivate::itemImplicitHeightChanged(QQuickItem *item)
{
    Q_Q(QQuickControl);
    if (item == background)
        emit q->implicitBackgroundHeightChanged();
    else if (item == contentItem)
        updateImplicitContentHeight();
}

void QQuickControlPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff)
{
    Q_UNUSED(diff);
    if (resizingBackground || item != background || !change.sizeChange())
        return;

    QQuickItemPrivate *p = QQuickItemPrivate::get(item);
    // Only set hasBackgroundWidth/Height if it was a width/height change,
    // otherwise we're prevented from setting a width/height in the future.
    if (change.widthChange())
        extra.value().hasBackgroundWidth = p->widthValid;
    if (change.heightChange())
        extra.value().hasBackgroundHeight = p->heightValid;
    resizeBackground();
}

void QQuickControlPrivate::itemDestroyed(QQuickItem *item)
{
    Q_Q(QQuickControl);
    if (item == background) {
        background = nullptr;
        emit q->implicitBackgroundWidthChanged();
        emit q->implicitBackgroundHeightChanged();
    } else if (item == contentItem) {
        contentItem = nullptr;
        updateImplicitContentSize();
    }
}

QQuickControl::QQuickControl(QQuickItem *parent)
    : QQuickItem(*(new QQuickControlPrivate), parent)
{
    Q_D(QQuickControl);
    d->init();
}

QQuickControl::QQuickControl(QQuickControlPrivate &dd, QQuickItem *parent)
    : QQuickItem(dd, parent)
{
    Q_D(QQuickControl);
    d->init();
}

QQuickControl::~QQuickControl()
{
    Q_D(QQuickControl);
    d->removeImplicitSizeListener(d->background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
    d->removeImplicitSizeListener(d->contentItem);
}

void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
{
    Q_D(QQuickControl);
    QQuickItem::itemChange(change, value);
    switch (change) {
    case ItemEnabledHasChanged:
        emit paletteChanged();
        enabledChange();
        break;
    case ItemVisibleHasChanged:
#if QT_CONFIG(quicktemplates2_hover)
        if (!value.boolValue)
            setHovered(false);
#endif
        break;
    case ItemSceneChange:
    case ItemParentHasChanged:
        if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) {
            d->resolveFont();
            d->resolvePalette();
            if (!d->hasLocale)
                d->updateLocale(QQuickControlPrivate::calcLocale(d->parentItem), false); // explicit=false
#if QT_CONFIG(quicktemplates2_hover)
            if (!d->explicitHoverEnabled)
                d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false
#endif
        }
        break;
    case ItemActiveFocusHasChanged:
        if (isKeyFocusReason(d->focusReason))
            emit visualFocusChanged();
        break;
    default:
        break;
    }
}

/*!
    \qmlproperty font QtQuick.Controls::Control::font

    This property holds the font currently set for the control.

    This property describes the control's requested font. The font is used by the control's
    style when rendering standard components, and is available as a means to ensure that custom
    controls can maintain consistency with the native platform's native look and feel. It's common
    that different platforms, or different styles, define different fonts for an application.

    The default font depends on the system environment. ApplicationWindow maintains a system/theme
    font which serves as a default for all controls. There may also be special font defaults for
    certain types of controls. You can also set the default font for controls by either:

    \list
    \li passing a custom font to QGuiApplication::setFont(), before loading the QML; or
    \li specifying the fonts in the \l {Qt Quick Controls 2 Configuration File}{qtquickcontrols2.conf file}.
    \endlist

    Finally, the font is matched against Qt's font database to find the best match.

    Control propagates explicit font properties from parent to children. If you change a specific
    property on a control's font, that property propagates to all of the control's children,
    overriding any system defaults for that property.

    \code
    Page {
        font.family: "Courier"

        Column {
            Label {
                text: qsTr("This will use Courier...")
            }

            Switch {
                text: qsTr("... and so will this")
            }
        }
    }
    \endcode

    For the full list of available font properties, see the
    \l [QtQuick]{font}{font QML Basic Type} documentation.
*/
QFont QQuickControl::font() const
{
    Q_D(const QQuickControl);
    return d->resolvedFont;
}

void QQuickControl::setFont(const QFont &font)
{
    Q_D(QQuickControl);
    if (d->extra.value().requestedFont.resolve() == font.resolve() && d->extra.value().requestedFont == font)
        return;

    d->extra.value().requestedFont = font;
    d->resolveFont();
}

void QQuickControl::resetFont()
{
    setFont(QFont());
}

/*!
    \qmlproperty real QtQuick.Controls::Control::availableWidth
    \readonly

    This property holds the width available to the \l contentItem after
    deducting horizontal padding from the \l {Item::}{width} of the control.

    \sa {Control Layout}, padding, leftPadding, rightPadding
*/
qreal QQuickControl::availableWidth() const
{
    return qMax<qreal>(0.0, width() - leftPadding() - rightPadding());
}

/*!
    \qmlproperty real QtQuick.Controls::Control::availableHeight
    \readonly

    This property holds the height available to the \l contentItem after
    deducting vertical padding from the \l {Item::}{height} of the control.

    \sa {Control Layout}, padding, topPadding, bottomPadding
*/
qreal QQuickControl::availableHeight() const
{
    return qMax<qreal>(0.0, height() - topPadding() - bottomPadding());
}

/*!
    \qmlproperty real QtQuick.Controls::Control::padding

    This property holds the default padding.

    Padding adds a space between each edge of the content item and the
    background item, effectively controlling the size of the content item. To
    specify a padding value for a specific edge of the control, set its
    relevant property:

    \list
    \li \l {Control::}{leftPadding}
    \li \l {Control::}{rightPadding}
    \li \l {Control::}{topPadding}
    \li \l {Control::}{bottomPadding}
    \endlist

    \note Different styles may specify the default padding for certain controls
    in different ways, and these ways may change over time as the design
    guidelines that the style is based on evolve. To ensure that these changes
    don't affect the padding values you have specified, it is best to use the
    most specific properties available. For example, rather than setting
    the \l padding property:

    \code
    padding: 0
    \endcode

    set each specific property instead:

    \code
    leftPadding: 0
    rightPadding: 0
    topPadding: 0
    bottomPadding: 0
    \endcode

    \sa {Control Layout}, availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding
*/
qreal QQuickControl::padding() const
{
    Q_D(const QQuickControl);
    return d->padding;
}

void QQuickControl::setPadding(qreal padding)
{
    Q_D(QQuickControl);
    if (qFuzzyCompare(d->padding, padding))
        return;

    const QMarginsF oldPadding = d->getPadding();
    const qreal oldVerticalPadding = d->getVerticalPadding();
    const qreal oldHorizontalPadding = d->getHorizontalPadding();

    d->padding = padding;
    emit paddingChanged();

    const QMarginsF newPadding = d->getPadding();
    const qreal newVerticalPadding = d->getVerticalPadding();
    const qreal newHorizontalPadding = d->getHorizontalPadding();

    if (!qFuzzyCompare(newPadding.top(), oldPadding.top()))
        emit topPaddingChanged();
    if (!qFuzzyCompare(newPadding.left(), oldPadding.left()))
        emit leftPaddingChanged();
    if (!qFuzzyCompare(newPadding.right(), oldPadding.right()))
        emit rightPaddingChanged();
    if (!qFuzzyCompare(newPadding.bottom(), oldPadding.bottom()))
        emit bottomPaddingChanged();
    if (!qFuzzyCompare(newVerticalPadding, oldVerticalPadding))
        emit verticalPaddingChanged();
    if (!qFuzzyCompare(newHorizontalPadding, oldHorizontalPadding))
        emit horizontalPaddingChanged();
    if (!qFuzzyCompare(newPadding.top(), oldPadding.top()) || !qFuzzyCompare(newPadding.bottom(), oldPadding.bottom()))
        emit availableHeightChanged();
    if (!qFuzzyCompare(newPadding.left(), oldPadding.left()) || !qFuzzyCompare(newPadding.right(), oldPadding.right()))
        emit availableWidthChanged();

    paddingChange(newPadding, oldPadding);
}

void QQuickControl::resetPadding()
{
    setPadding(0);
}

/*!
    \qmlproperty real QtQuick.Controls::Control::topPadding

    This property holds the top padding. Unless explicitly set, the value
    is equal to \c verticalPadding.

    \sa {Control Layout}, padding, bottomPadding, verticalPadding, availableHeight
*/
qreal QQuickControl::topPadding() const
{
    Q_D(const QQuickControl);
    return d->getTopPadding();
}

void QQuickControl::setTopPadding(qreal padding)
{
    Q_D(QQuickControl);
    d->setTopPadding(padding);
}

void QQuickControl::resetTopPadding()
{
    Q_D(QQuickControl);
    d->setTopPadding(0, true);
}

/*!
    \qmlproperty real QtQuick.Controls::Control::leftPadding

    This property holds the left padding. Unless explicitly set, the value
    is equal to \c horizontalPadding.

    \sa {Control Layout}, padding, rightPadding, horizontalPadding, availableWidth
*/
qreal QQuickControl::leftPadding() const
{
    Q_D(const QQuickControl);
    return d->getLeftPadding();
}

void QQuickControl::setLeftPadding(qreal padding)
{
    Q_D(QQuickControl);
    d->setLeftPadding(padding);
}

void QQuickControl::resetLeftPadding()
{
    Q_D(QQuickControl);
    d->setLeftPadding(0, true);
}

/*!
    \qmlproperty real QtQuick.Controls::Control::rightPadding

    This property holds the right padding. Unless explicitly set, the value
    is equal to \c horizontalPadding.

    \sa {Control Layout}, padding, leftPadding, horizontalPadding, availableWidth
*/
qreal QQuickControl::rightPadding() const
{
    Q_D(const QQuickControl);
    return d->getRightPadding();
}

void QQuickControl::setRightPadding(qreal padding)
{
    Q_D(QQuickControl);
    d->setRightPadding(padding);
}

void QQuickControl::resetRightPadding()
{
    Q_D(QQuickControl);
    d->setRightPadding(0, true);
}

/*!
    \qmlproperty real QtQuick.Controls::Control::bottomPadding

    This property holds the bottom padding. Unless explicitly set, the value
    is equal to \c verticalPadding.

    \sa {Control Layout}, padding, topPadding, verticalPadding, availableHeight
*/
qreal QQuickControl::bottomPadding() const
{
    Q_D(const QQuickControl);
    return d->getBottomPadding();
}

void QQuickControl::setBottomPadding(qreal padding)
{
    Q_D(QQuickControl);
    d->setBottomPadding(padding);
}

void QQuickControl::resetBottomPadding()
{
    Q_D(QQuickControl);
    d->setBottomPadding(0, true);
}

/*!
    \qmlproperty real QtQuick.Controls::Control::spacing

    This property holds the spacing.

    Spacing is useful for controls that have multiple or repetitive building
    blocks. For example, some styles use spacing to determine the distance
    between the text and indicator of \l CheckBox. Spacing is not enforced by
    Control, so each style may interpret it differently, and some may ignore it
    altogether.
*/
qreal QQuickControl::spacing() const
{
    Q_D(const QQuickControl);
    return d->spacing;
}

void QQuickControl::setSpacing(qreal spacing)
{
    Q_D(QQuickControl);
    if (qFuzzyCompare(d->spacing, spacing))
        return;

    qreal oldSpacing = d->spacing;
    d->spacing = spacing;
    emit spacingChanged();
    spacingChange(spacing, oldSpacing);
}

void QQuickControl::resetSpacing()
{
    setSpacing(0);
}

/*!
    \qmlproperty Locale QtQuick.Controls::Control::locale

    This property holds the locale of the control.

    It contains locale specific properties for formatting data and numbers.
    Unless a special locale has been set, this is either the parent's locale
    or the default locale.

    Control propagates the locale from parent to children. If you change the
    control's locale, that locale propagates to all of the control's children,
    overriding the system default locale.

    \sa mirrored, {LayoutMirroring}{LayoutMirroring}
*/
QLocale QQuickControl::locale() const
{
    Q_D(const QQuickControl);
    return d->locale;
}

void QQuickControl::setLocale(const QLocale &locale)
{
    Q_D(QQuickControl);
    if (d->hasLocale && d->locale == locale)
        return;

    d->updateLocale(locale, true); // explicit=true
}

void QQuickControl::resetLocale()
{
    Q_D(QQuickControl);
    if (!d->hasLocale)
        return;

    d->hasLocale = false;
    d->updateLocale(QQuickControlPrivate::calcLocale(d->parentItem), false); // explicit=false
}

/*!
    \qmlproperty bool QtQuick.Controls::Control::mirrored
    \readonly

    This property holds whether the control is mirrored.

    This property is provided for convenience. A control is considered mirrored
    when its visual layout direction is right-to-left; that is, when using a
    right-to-left locale or when \l {LayoutMirroring::enabled}{LayoutMirroring.enabled}
    is \c true.

    \sa locale, {LayoutMirroring}{LayoutMirroring}, {Right-to-left User Interfaces}
*/
bool QQuickControl::isMirrored() const
{
    Q_D(const QQuickControl);
    return d->isMirrored() || d->locale.textDirection() == Qt::RightToLeft;
}

/*!
    \qmlproperty enumeration QtQuick.Controls::Control::focusPolicy

    This property determines the way the control accepts focus.

    \value Qt.TabFocus    The control accepts focus by tabbing.
    \value Qt.ClickFocus  The control accepts focus by clicking.
    \value Qt.StrongFocus The control accepts focus by both tabbing and clicking.
    \value Qt.WheelFocus  The control accepts focus by tabbing, clicking, and using the mouse wheel.
    \value Qt.NoFocus     The control does not accept focus.
*/
Qt::FocusPolicy QQuickControl::focusPolicy() const
{
    Q_D(const QQuickControl);
    uint policy = d->focusPolicy;
    if (activeFocusOnTab())
        policy |= Qt::TabFocus;
    return static_cast<Qt::FocusPolicy>(policy);
}

void QQuickControl::setFocusPolicy(Qt::FocusPolicy policy)
{
    Q_D(QQuickControl);
    if (d->focusPolicy == policy)
        return;

    d->focusPolicy = policy;
    setActiveFocusOnTab(policy & Qt::TabFocus);
    emit focusPolicyChanged();
}

/*!
    \qmlproperty enumeration QtQuick.Controls::Control::focusReason
    \readonly

    \include qquickcontrol-focusreason.qdocinc

    \sa visualFocus
*/
Qt::FocusReason QQuickControl::focusReason() const
{
    Q_D(const QQuickControl);
    return d->focusReason;
}

void QQuickControl::setFocusReason(Qt::FocusReason reason)
{
    Q_D(QQuickControl);
    if (d->focusReason == reason)
        return;

    Qt::FocusReason oldReason = d->focusReason;
    d->focusReason = reason;
    emit focusReasonChanged();
    if (isKeyFocusReason(oldReason) != isKeyFocusReason(reason))
        emit visualFocusChanged();
}

/*!
    \qmlproperty bool QtQuick.Controls::Control::visualFocus
    \readonly

    This property holds whether the control has visual focus. This property
    is \c true when the control has active focus and the focus reason is either
    \c Qt.TabFocusReason, \c Qt.BacktabFocusReason, or \c Qt.ShortcutFocusReason.

    In general, for visualizing key focus, this property is preferred over
    \l Item::activeFocus. This ensures that key focus is only visualized when
    interacting with keys - not when interacting via touch or mouse.

    \sa focusReason, Item::activeFocus
*/
bool QQuickControl::hasVisualFocus() const
{
    Q_D(const QQuickControl);
    return d->activeFocus && isKeyFocusReason(d->focusReason);
}

/*!
    \qmlproperty bool QtQuick.Controls::Control::hovered
    \readonly

    This property holds whether the control is hovered.

    \sa hoverEnabled
*/
bool QQuickControl::isHovered() const
{
#if QT_CONFIG(quicktemplates2_hover)
    Q_D(const QQuickControl);
    return d->hovered;
#else
    return false;
#endif
}

void QQuickControl::setHovered(bool hovered)
{
#if QT_CONFIG(quicktemplates2_hover)
    Q_D(QQuickControl);
    if (hovered == d->hovered)
        return;

    d->hovered = hovered;
    emit hoveredChanged();
    hoverChange();
#else
    Q_UNUSED(hovered);
#endif
}

/*!
    \qmlproperty bool QtQuick.Controls::Control::hoverEnabled

    This property determines whether the control accepts hover events. The default value
    is \c Qt.styleHints.useHoverEffects.

    Setting this property propagates the value to all child controls that do not have
    \c hoverEnabled explicitly set.

    You can also enable or disable hover effects for all Qt Quick Controls applications
    by setting the \c QT_QUICK_CONTROLS_HOVER_ENABLED \l {Supported Environment Variables
    in Qt Quick Controls}{environment variable}.

    \sa hovered
*/
bool QQuickControl::isHoverEnabled() const
{
#if QT_CONFIG(quicktemplates2_hover)
    Q_D(const QQuickControl);
    return d->hoverEnabled;
#else
    return false;
#endif
}

void QQuickControl::setHoverEnabled(bool enabled)
{
#if QT_CONFIG(quicktemplates2_hover)
    Q_D(QQuickControl);
    if (d->explicitHoverEnabled && enabled == d->hoverEnabled)
        return;

    d->updateHoverEnabled(enabled, true); // explicit=true
#else
    Q_UNUSED(enabled)
#endif
}

void QQuickControl::resetHoverEnabled()
{
#if QT_CONFIG(quicktemplates2_hover)
    Q_D(QQuickControl);
    if (!d->explicitHoverEnabled)
        return;

    d->explicitHoverEnabled = false;
    d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false
#endif
}

/*!
    \qmlproperty bool QtQuick.Controls::Control::wheelEnabled

    This property determines whether the control handles wheel events. The default value is \c false.

    \note Care must be taken when enabling wheel events for controls within scrollable items such
    as \l Flickable, as the control will consume the events and hence interrupt scrolling of the
    Flickable.
*/
bool QQuickControl::isWheelEnabled() const
{
    Q_D(const QQuickControl);
    return d->wheelEnabled;
}

void QQuickControl::setWheelEnabled(bool enabled)
{
    Q_D(QQuickControl);
    if (d->wheelEnabled == enabled)
        return;

    d->wheelEnabled = enabled;
    emit wheelEnabledChanged();
}

/*!
    \qmlproperty Item QtQuick.Controls::Control::background

    This property holds the background item.

    \code
    Button {
        id: control
        text: qsTr("Button")
        background: Rectangle {
            implicitWidth: 100
            implicitHeight: 40
            opacity: enabled ? 1 : 0.3
            color: control.down ? "#d0d0d0" : "#e0e0e0"
        }
    }
    \endcode

    \input qquickcontrol-background.qdocinc notes

    \sa {Control Layout}
*/
QQuickItem *QQuickControl::background() const
{
    QQuickControlPrivate *d = const_cast<QQuickControlPrivate *>(d_func());
    if (!d->background)
        d->executeBackground();
    return d->background;
}

void QQuickControl::setBackground(QQuickItem *background)
{
    Q_D(QQuickControl);
    if (d->background == background)
        return;

    if (!d->background.isExecuting())
        d->cancelBackground();

    const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth();
    const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight();

    if (d->extra.isAllocated()) {
        d->extra.value().hasBackgroundWidth = false;
        d->extra.value().hasBackgroundHeight = false;
    }

    d->removeImplicitSizeListener(d->background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
    QQuickControlPrivate::hideOldItem(d->background);
    d->background = background;

    if (background) {
        background->setParentItem(this);
        if (qFuzzyIsNull(background->z()))
            background->setZ(-1);
        QQuickItemPrivate *p = QQuickItemPrivate::get(background);
        if (p->widthValid || p->heightValid) {
            d->extra.value().hasBackgroundWidth = p->widthValid;
            d->extra.value().hasBackgroundHeight = p->heightValid;
        }
        if (isComponentComplete())
            d->resizeBackground();
        d->addImplicitSizeListener(background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
    }

    if (!qFuzzyCompare(oldImplicitBackgroundWidth, implicitBackgroundWidth()))
        emit implicitBackgroundWidthChanged();
    if (!qFuzzyCompare(oldImplicitBackgroundHeight, implicitBackgroundHeight()))
        emit implicitBackgroundHeightChanged();
    if (!d->background.isExecuting())
        emit backgroundChanged();
}

/*!
    \qmlproperty Item QtQuick.Controls::Control::contentItem

    This property holds the visual content item.

    \code
    Button {
        id: control
        text: qsTr("Button")
        contentItem: Label {
            text: control.text
            font: control.font
            verticalAlignment: Text.AlignVCenter
        }
    }
    \endcode

    \note The content item is automatically positioned and resized to fit
    within the \l padding of the control. Bindings to the
    \l[QtQuick]{Item::}{x}, \l[QtQuick]{Item::}{y},
    \l[QtQuick]{Item::}{width}, and \l[QtQuick]{Item::}{height}
    properties of the contentItem are not respected.

    \note Most controls use the implicit size of the content item to calculate
    the implicit size of the control itself. If you replace the content item
    with a custom one, you should also consider providing a sensible implicit
    size for it (unless it is an item like \l Text which has its own implicit
    size).

    \sa {Control Layout}, padding
*/
QQuickItem *QQuickControl::contentItem() const
{
    QQuickControlPrivate *d = const_cast<QQuickControlPrivate *>(d_func());
    if (!d->contentItem)
        d->setContentItem_helper(d->getContentItem(), false);
    return d->contentItem;
}

void QQuickControl::setContentItem(QQuickItem *item)
{
    Q_D(QQuickControl);
    d->setContentItem_helper(item, true);
}

qreal QQuickControl::baselineOffset() const
{
    Q_D(const QQuickControl);
    return d->baselineOffset;
}

void QQuickControl::setBaselineOffset(qreal offset)
{
    Q_D(QQuickControl);
    d->extra.value().hasBaselineOffset = true;
    QQuickItem::setBaselineOffset(offset);
}

void QQuickControl::resetBaselineOffset()
{
    Q_D(QQuickControl);
    if (!d->extra.isAllocated() || !d->extra.value().hasBaselineOffset)
        return;

    if (d->extra.isAllocated())
        d->extra.value().hasBaselineOffset = false;
    d->updateBaselineOffset();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlproperty palette QtQuick.Controls::Control::palette

    This property holds the palette currently set for the control.

    This property describes the control's requested palette. The palette is used by the control's
    style when rendering standard components, and is available as a means to ensure that custom
    controls can maintain consistency with the native platform's native look and feel. It's common
    that different platforms, or different styles, define different palettes for an application.

    The default palette depends on the system environment. ApplicationWindow maintains a system/theme
    palette which serves as a default for all controls. There may also be special palette defaults for
    certain types of controls. You can also set the default palette for controls by either:

    \list
    \li passing a custom palette to QGuiApplication::setPalette(), before loading any QML; or
    \li specifying the colors in the \l {Qt Quick Controls 2 Configuration File}{qtquickcontrols2.conf file}.
    \endlist

    Control propagates explicit palette properties from parent to children. If you change a specific
    property on a control's palette, that property propagates to all of the control's children,
    overriding any system defaults for that property.

    \code
    Page {
        palette.text: "red"

        Column {
            Label {
                text: qsTr("This will use red color...")
            }

            Switch {
                text: qsTr("... and so will this")
            }
        }
    }
    \endcode

    For the full list of available palette colors, see the
    \l {qtquickcontrols2-palette}{palette QML Basic Type} documentation.

    \sa ApplicationWindow::palette, Popup::palette
*/
QPalette QQuickControl::palette() const
{
    Q_D(const QQuickControl);
    QPalette palette = d->resolvedPalette;
    if (!isEnabled())
        palette.setCurrentColorGroup(QPalette::Disabled);
    return palette;
}

void QQuickControl::setPalette(const QPalette &palette)
{
    Q_D(QQuickControl);
    if (d->extra.value().requestedPalette.resolve() == palette.resolve() && d->extra.value().requestedPalette == palette)
        return;

    d->extra.value().requestedPalette = palette;
    d->resolvePalette();
}

void QQuickControl::resetPalette()
{
    setPalette(QPalette());
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Control::horizontalPadding

    This property holds the horizontal padding. Unless explicitly set, the value
    is equal to \c padding.

    \sa {Control Layout}, padding, leftPadding, rightPadding, verticalPadding
*/
qreal QQuickControl::horizontalPadding() const
{
    Q_D(const QQuickControl);
    return d->getHorizontalPadding();
}

void QQuickControl::setHorizontalPadding(qreal padding)
{
    Q_D(QQuickControl);
    d->setHorizontalPadding(padding);
}

void QQuickControl::resetHorizontalPadding()
{
    Q_D(QQuickControl);
    d->setHorizontalPadding(0, true);
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Control::verticalPadding

    This property holds the vertical padding. Unless explicitly set, the value
    is equal to \c padding.

    \sa {Control Layout}, padding, topPadding, bottomPadding, horizontalPadding
*/
qreal QQuickControl::verticalPadding() const
{
    Q_D(const QQuickControl);
    return d->getVerticalPadding();
}

void QQuickControl::setVerticalPadding(qreal padding)
{
    Q_D(QQuickControl);
    d->setVerticalPadding(padding);
}

void QQuickControl::resetVerticalPadding()
{
    Q_D(QQuickControl);
    d->setVerticalPadding(0, true);
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Control::implicitContentWidth
    \readonly

    This property holds the implicit content width.

    For basic controls, the value is equal to \c {contentItem ? contentItem.implicitWidth : 0}.
    For types that inherit Container or Pane, the value is calculated based on the content children.

    This is typically used, together with \l implicitBackgroundWidth, to calculate
    the \l {Item::}{implicitWidth}:

    \code
    Control {
        implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
                                implicitContentWidth + leftPadding + rightPadding)
    }
    \endcode

    \sa implicitContentHeight, implicitBackgroundWidth
*/
qreal QQuickControl::implicitContentWidth() const
{
    Q_D(const QQuickControl);
    return d->implicitContentWidth;
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Control::implicitContentHeight
    \readonly

    This property holds the implicit content height.

    For basic controls, the value is equal to \c {contentItem ? contentItem.implicitHeight : 0}.
    For types that inherit Container or Pane, the value is calculated based on the content children.

    This is typically used, together with \l implicitBackgroundHeight, to calculate
    the \l {Item::}{implicitHeight}:

    \code
    Control {
        implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
                                 implicitContentHeight + topPadding + bottomPadding)
    }
    \endcode

    \sa implicitContentWidth, implicitBackgroundHeight
*/
qreal QQuickControl::implicitContentHeight() const
{
    Q_D(const QQuickControl);
    return d->implicitContentHeight;
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Control::implicitBackgroundWidth
    \readonly

    This property holds the implicit background width.

    The value is equal to \c {background ? background.implicitWidth : 0}.

    This is typically used, together with \l implicitContentWidth, to calculate
    the \l {Item::}{implicitWidth}:

    \code
    Control {
        implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
                                implicitContentWidth + leftPadding + rightPadding)
    }
    \endcode

    \sa implicitBackgroundHeight, implicitContentWidth
*/
qreal QQuickControl::implicitBackgroundWidth() const
{
    Q_D(const QQuickControl);
    if (!d->background)
        return 0;
    return d->background->implicitWidth();
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Control::implicitBackgroundHeight
    \readonly

    This property holds the implicit background height.

    The value is equal to \c {background ? background.implicitHeight : 0}.

    This is typically used, together with \l implicitContentHeight, to calculate
    the \l {Item::}{implicitHeight}:

    \code
    Control {
        implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
                                 implicitContentHeight + topPadding + bottomPadding)
    }
    \endcode

    \sa implicitBackgroundWidth, implicitContentHeight
*/
qreal QQuickControl::implicitBackgroundHeight() const
{
    Q_D(const QQuickControl);
    if (!d->background)
        return 0;
    return d->background->implicitHeight();
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Control::topInset

    This property holds the top inset for the background.

    \sa {Control Layout}, bottomInset
*/
qreal QQuickControl::topInset() const
{
    Q_D(const QQuickControl);
    return d->getTopInset();
}

void QQuickControl::setTopInset(qreal inset)
{
    Q_D(QQuickControl);
    d->setTopInset(inset);
}

void QQuickControl::resetTopInset()
{
    Q_D(QQuickControl);
    d->setTopInset(0, true);
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Control::leftInset

    This property holds the left inset for the background.

    \sa {Control Layout}, rightInset
*/
qreal QQuickControl::leftInset() const
{
    Q_D(const QQuickControl);
    return d->getLeftInset();
}

void QQuickControl::setLeftInset(qreal inset)
{
    Q_D(QQuickControl);
    d->setLeftInset(inset);
}

void QQuickControl::resetLeftInset()
{
    Q_D(QQuickControl);
    d->setLeftInset(0, true);
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Control::rightInset

    This property holds the right inset for the background.

    \sa {Control Layout}, leftInset
*/
qreal QQuickControl::rightInset() const
{
    Q_D(const QQuickControl);
    return d->getRightInset();
}

void QQuickControl::setRightInset(qreal inset)
{
    Q_D(QQuickControl);
    d->setRightInset(inset);
}

void QQuickControl::resetRightInset()
{
    Q_D(QQuickControl);
    d->setRightInset(0, true);
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Control::bottomInset

    This property holds the bottom inset for the background.

    \sa {Control Layout}, topInset
*/
qreal QQuickControl::bottomInset() const
{
    Q_D(const QQuickControl);
    return d->getBottomInset();
}

void QQuickControl::setBottomInset(qreal inset)
{
    Q_D(QQuickControl);
    d->setBottomInset(inset);
}

void QQuickControl::resetBottomInset()
{
    Q_D(QQuickControl);
    d->setBottomInset(0, true);
}

void QQuickControl::classBegin()
{
    Q_D(QQuickControl);
    QQuickItem::classBegin();
    d->resolveFont();
    d->resolvePalette();
}

void QQuickControl::componentComplete()
{
    Q_D(QQuickControl);
    d->executeBackground(true);
    d->executeContentItem(true);
    QQuickItem::componentComplete();
    d->resizeBackground();
    d->resizeContent();
    d->updateBaselineOffset();
    if (!d->hasLocale)
        d->locale = QQuickControlPrivate::calcLocale(d->parentItem);
#if QT_CONFIG(quicktemplates2_hover)
    if (!d->explicitHoverEnabled)
        setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(d->parentItem));
#endif
#if QT_CONFIG(accessibility)
    if (QAccessible::isActive())
        accessibilityActiveChanged(true);
#endif
}

QFont QQuickControl::defaultFont() const
{
    return QQuickTheme::font(QQuickTheme::System);
}

QPalette QQuickControl::defaultPalette() const
{
    return QQuickTheme::palette(QQuickTheme::System);
}

void QQuickControl::focusInEvent(QFocusEvent *event)
{
    QQuickItem::focusInEvent(event);
    setFocusReason(event->reason());
}

void QQuickControl::focusOutEvent(QFocusEvent *event)
{
    QQuickItem::focusOutEvent(event);
    setFocusReason(event->reason());
}

#if QT_CONFIG(quicktemplates2_hover)
void QQuickControl::hoverEnterEvent(QHoverEvent *event)
{
    Q_D(QQuickControl);
    setHovered(d->hoverEnabled);
    event->setAccepted(d->hoverEnabled);
}

void QQuickControl::hoverMoveEvent(QHoverEvent *event)
{
    Q_D(QQuickControl);
    setHovered(d->hoverEnabled && contains(event->pos()));
    event->setAccepted(d->hoverEnabled);
}

void QQuickControl::hoverLeaveEvent(QHoverEvent *event)
{
    Q_D(QQuickControl);
    setHovered(false);
    event->setAccepted(d->hoverEnabled);
}
#endif

void QQuickControl::mousePressEvent(QMouseEvent *event)
{
    Q_D(QQuickControl);
    d->handlePress(event->localPos());
    if (event->source() == Qt::MouseEventSynthesizedByQt) {
        d->pressWasTouch = true;
        d->previousPressPos = event->localPos();
    }
    event->accept();
}

void QQuickControl::mouseMoveEvent(QMouseEvent *event)
{
    Q_D(QQuickControl);
    d->handleMove(event->localPos());
    event->accept();
}

void QQuickControl::mouseReleaseEvent(QMouseEvent *event)
{
    Q_D(QQuickControl);
    d->handleRelease(event->localPos());
    event->accept();
}

void QQuickControl::mouseUngrabEvent()
{
    Q_D(QQuickControl);
    d->handleUngrab();
}

#if QT_CONFIG(quicktemplates2_multitouch)
void QQuickControl::touchEvent(QTouchEvent *event)
{
    Q_D(QQuickControl);
    switch (event->type()) {
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate:
    case QEvent::TouchEnd:
        for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
            if (!d->acceptTouch(point))
                continue;

            switch (point.state()) {
            case Qt::TouchPointPressed:
                d->handlePress(point.pos());
                break;
            case Qt::TouchPointMoved:
                d->handleMove(point.pos());
                break;
            case Qt::TouchPointReleased:
                d->handleRelease(point.pos());
                break;
            default:
                break;
            }
        }
        break;

    case QEvent::TouchCancel:
        d->handleUngrab();
        break;

    default:
        QQuickItem::touchEvent(event);
        break;
    }
}

void QQuickControl::touchUngrabEvent()
{
    Q_D(QQuickControl);
    d->handleUngrab();
}
#endif

#if QT_CONFIG(wheelevent)
void QQuickControl::wheelEvent(QWheelEvent *event)
{
    Q_D(QQuickControl);
    if ((d->focusPolicy & Qt::WheelFocus) == Qt::WheelFocus)
        setActiveFocus(this, Qt::MouseFocusReason);

    event->setAccepted(d->wheelEnabled);
}
#endif

void QQuickControl::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
    Q_D(QQuickControl);
    QQuickItem::geometryChanged(newGeometry, oldGeometry);
    d->resizeBackground();
    d->resizeContent();
    if (!qFuzzyCompare(newGeometry.width(), oldGeometry.width()))
        emit availableWidthChanged();
    if (!qFuzzyCompare(newGeometry.height(), oldGeometry.height()))
        emit availableHeightChanged();
}

void QQuickControl::enabledChange()
{
}

void QQuickControl::fontChange(const QFont &newFont, const QFont &oldFont)
{
    Q_UNUSED(newFont);
    Q_UNUSED(oldFont);
}

#if QT_CONFIG(quicktemplates2_hover)
void QQuickControl::hoverChange()
{
}
#endif

void QQuickControl::mirrorChange()
{
    emit mirroredChanged();
}

void QQuickControl::spacingChange(qreal newSpacing, qreal oldSpacing)
{
    Q_UNUSED(newSpacing);
    Q_UNUSED(oldSpacing);
}

void QQuickControl::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding)
{
    Q_D(QQuickControl);
    Q_UNUSED(newPadding);
    Q_UNUSED(oldPadding);
    d->resizeContent();
    d->updateBaselineOffset();
}

void QQuickControl::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
{
    Q_UNUSED(newItem);
    Q_UNUSED(oldItem);
}

void QQuickControl::localeChange(const QLocale &newLocale, const QLocale &oldLocale)
{
    Q_UNUSED(newLocale);
    Q_UNUSED(oldLocale);
}

void QQuickControl::paletteChange(const QPalette &newPalette, const QPalette &oldPalette)
{
    Q_UNUSED(newPalette);
    Q_UNUSED(oldPalette);
}

void QQuickControl::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset)
{
    Q_D(QQuickControl);
    Q_UNUSED(newInset);
    Q_UNUSED(oldInset);
    d->resizeBackground();
}

#if QT_CONFIG(accessibility)
QAccessible::Role QQuickControl::accessibleRole() const
{
    return QAccessible::NoRole;
}

void QQuickControl::accessibilityActiveChanged(bool active)
{
    if (!active)
        return;

    QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, true));
    Q_ASSERT(accessibleAttached);
    accessibleAttached->setRole(accessibleRole());
}
#endif

QString QQuickControl::accessibleName() const
{
#if QT_CONFIG(accessibility)
    if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this))
        return accessibleAttached->name();
#endif
    return QString();
}

void QQuickControl::maybeSetAccessibleName(const QString &name)
{
#if QT_CONFIG(accessibility)
    if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this)) {
        if (!accessibleAttached->wasNameExplicitlySet())
            accessibleAttached->setNameImplicitly(name);
    }
#else
    Q_UNUSED(name)
#endif
}

QVariant QQuickControl::accessibleProperty(const char *propertyName)
{
#if QT_CONFIG(accessibility)
    if (QAccessible::isActive())
        return QQuickAccessibleAttached::property(this, propertyName);
#endif
    Q_UNUSED(propertyName)
    return QVariant();
}

bool QQuickControl::setAccessibleProperty(const char *propertyName, const QVariant &value)
{
#if QT_CONFIG(accessibility)
    if (QAccessible::isActive())
        return QQuickAccessibleAttached::setProperty(this, propertyName, value);
#endif
    Q_UNUSED(propertyName)
    Q_UNUSED(value)
    return false;
}

QT_END_NAMESPACE
