/****************************************************************************
**
** 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 "qquickdialogbuttonbox_p.h"
#include "qquickdialogbuttonbox_p_p.h"
#include "qquickabstractbutton_p.h"
#include "qquickbutton_p.h"
#include "qquickdialog_p_p.h"

#include <QtCore/qpointer.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qpa/qplatformtheme.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcontext.h>
#include <QtQml/qqmlcomponent.h>

#include <algorithm>

QT_BEGIN_NAMESPACE

/*!
    \qmltype DialogButtonBox
    \inherits Container
//!     \instantiates QQuickDialogButtonBox
    \inqmlmodule QtQuick.Controls
    \ingroup qtquickcontrols2-dialogs
    \brief A button box used in dialogs.
    \since 5.8

    Dialogs and message boxes typically present buttons in an order that
    conforms to the interface guidelines for that platform. Invariably,
    different platforms have their dialog buttons in different orders.
    DialogButtonBox allows a developer to add buttons to it and will
    automatically use the appropriate order for the user's platform.

    Most buttons for a dialog follow certain roles. Such roles include:

    \list
    \li Accepting or rejecting the dialog.
    \li Asking for help.
    \li Performing actions on the dialog itself (such as resetting fields or
       applying changes).
    \endlist

    There can also be alternate ways of dismissing the dialog which may cause
    destructive results.

    Most dialogs have buttons that can almost be considered standard (e.g.
    \uicontrol OK and \uicontrol Cancel buttons). It is sometimes convenient
    to create these buttons in a standard way.

    There are a couple ways of using DialogButtonBox. One way is to specify
    the standard buttons (e.g. \uicontrol OK, \uicontrol Cancel, \uicontrol Save)
    and let the button box setup the buttons.

    \image qtquickcontrols2-dialogbuttonbox.png

    \snippet qtquickcontrols2-dialogbuttonbox.qml 1

    Alternatively, buttons and their roles can be specified by hand:

    \snippet qtquickcontrols2-dialogbuttonbox-attached.qml 1

    You can also mix and match normal buttons and standard buttons.

    When a button is clicked in the button box, the \l clicked() signal is
    emitted for the actual button that is pressed. In addition, the
    following signals are automatically emitted when a button with the
    respective role(s) is pressed:

    \table
    \header
        \li Role
        \li Signal
    \row
        \li \c AcceptRole, \c YesRole
        \li \l accepted()
    \row
        \li \c ApplyRole
        \li \l applied()
    \row
        \li \c DiscardRole
        \li \l discarded()
    \row
        \li \c HelpRole
        \li \l helpRequested()
    \row
        \li \c RejectRole, \c NoRole
        \li \l rejected()
    \row
        \li \c ResetRole
        \li \l reset()
    \endtable

    \sa Dialog
*/

/*!
    \qmlsignal QtQuick.Controls::DialogButtonBox::accepted()

    This signal is emitted when a button defined with the \c AcceptRole or
    \c YesRole is clicked.

    \sa rejected(), clicked(), helpRequested()
*/

/*!
    \qmlsignal QtQuick.Controls::DialogButtonBox::rejected()

    This signal is emitted when a button defined with the \c RejectRole or
    \c NoRole is clicked.

    \sa accepted(), helpRequested(), clicked()
*/

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlsignal QtQuick.Controls::DialogButtonBox::applied()

    This signal is emitted when a button defined with the \c ApplyRole is
    clicked.

    \sa discarded(), reset()
*/

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlsignal QtQuick.Controls::DialogButtonBox::reset()

    This signal is emitted when a button defined with the \c ResetRole is
    clicked.

    \sa discarded(), applied()
*/

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlsignal QtQuick.Controls::DialogButtonBox::discarded()

    This signal is emitted when a button defined with the \c DiscardRole is
    clicked.

    \sa reset(), applied()
*/

/*!
    \qmlsignal QtQuick.Controls::DialogButtonBox::helpRequested()

    This signal is emitted when a button defined with the \c HelpRole is clicked.

    \sa accepted(), rejected(), clicked()
*/

/*!
    \qmlsignal QtQuick.Controls::DialogButtonBox::clicked(AbstractButton button)

    This signal is emitted when a \a button inside the button box is clicked.

    \sa accepted(), rejected(), helpRequested()
*/

static QPlatformDialogHelper::ButtonLayout platformButtonLayout()
{
    return QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::DialogButtonBoxLayout).value<QPlatformDialogHelper::ButtonLayout>();
}

void QQuickDialogButtonBoxPrivate::itemImplicitWidthChanged(QQuickItem *item)
{
    QQuickContainerPrivate::itemImplicitWidthChanged(item);
    if (item == contentItem)
        resizeContent();
    else
        updateImplicitContentWidth();
}

void QQuickDialogButtonBoxPrivate::itemImplicitHeightChanged(QQuickItem *item)
{
    QQuickContainerPrivate::itemImplicitHeightChanged(item);
    if (item == contentItem)
        resizeContent();
    else
        updateImplicitContentHeight();
}

// adapted from QStyle::alignedRect()
static QRectF alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSizeF &size, const QRectF &rectangle)
{
    alignment = QGuiApplicationPrivate::visualAlignment(direction, alignment);
    qreal x = rectangle.x();
    qreal y = rectangle.y();
    qreal w = size.width();
    qreal h = size.height();
    if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter || (alignment & Qt::AlignVertical_Mask) == 0)
        y += (rectangle.size().height() - h) / 2;
    else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
        y += rectangle.size().height() - h;
    if ((alignment & Qt::AlignRight) == Qt::AlignRight)
        x += rectangle.size().width() - w;
    else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
        x += (rectangle.size().width() - w) / 2;
    return QRectF(x, y, w, h);
}

void QQuickDialogButtonBoxPrivate::resizeContent()
{
    Q_Q(QQuickDialogButtonBox);
    if (!contentItem)
        return;

    QRectF geometry = q->boundingRect().adjusted(q->leftPadding(), q->topPadding(), -q->rightPadding(), -q->bottomPadding());
    if (alignment != 0)
        geometry = alignedRect(q->isMirrored() ? Qt::RightToLeft : Qt::LeftToRight, alignment, QSizeF(contentWidth, contentHeight), geometry);

    contentItem->setPosition(geometry.topLeft());
    contentItem->setSize(geometry.size());
}

void QQuickDialogButtonBoxPrivate::updateLayout()
{
    Q_Q(QQuickDialogButtonBox);
    const int count = contentModel->count();
    if (count <= 0)
        return;

    const int halign = alignment & Qt::AlignHorizontal_Mask;
    const int valign = alignment & Qt::AlignVertical_Mask;

    QVector<QQuickAbstractButton *> buttons;
    const qreal cw = (alignment & Qt::AlignHorizontal_Mask) == 0 ? q->availableWidth() : contentWidth;
    const qreal itemWidth = (cw - qMax(0, count - 1) * spacing) / count;

    for (int i = 0; i < count; ++i) {
        QQuickItem *item = q->itemAt(i);
        if (item) {
            QQuickItemPrivate *p = QQuickItemPrivate::get(item);
            if (!p->widthValid) {
                if (!halign)
                    item->setWidth(itemWidth);
                else
                    item->resetWidth();
                if (!valign)
                    item->setHeight(contentHeight);
                else
                    item->resetHeight();
                p->widthValid = false;
            }
        }
        buttons += static_cast<QQuickAbstractButton *>(item);
    }

    struct ButtonLayout {
        ButtonLayout(QPlatformDialogHelper::ButtonLayout layout)
            : m_layout(QPlatformDialogHelper::buttonLayout(Qt::Horizontal, layout))
        {
        }

        bool operator()(QQuickAbstractButton *first, QQuickAbstractButton *second)
        {
            const QPlatformDialogHelper::ButtonRole firstRole = QQuickDialogPrivate::buttonRole(first);
            const QPlatformDialogHelper::ButtonRole secondRole = QQuickDialogPrivate::buttonRole(second);

            if (firstRole != secondRole && firstRole != QPlatformDialogHelper::InvalidRole && secondRole != QPlatformDialogHelper::InvalidRole) {
                const int *l = m_layout;
                while (*l != QPlatformDialogHelper::EOL) {
                    // Unset the Reverse flag.
                    const int role = (*l & ~QPlatformDialogHelper::Reverse);
                    if (role == firstRole)
                        return true;
                    if (role == secondRole)
                        return false;
                    ++l;
                }
            }

            if (firstRole == secondRole)
                return false;

            return firstRole != QPlatformDialogHelper::InvalidRole;
        }
        const int *m_layout;
    };

    std::stable_sort(buttons.begin(), buttons.end(), ButtonLayout(static_cast<QPlatformDialogHelper::ButtonLayout>(buttonLayout)));

    for (int i = 0; i < buttons.count() - 1; ++i)
        q->insertItem(i, buttons.at(i));
}

qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
{
    Q_Q(const QQuickDialogButtonBox);
    const int count = contentModel->count();
    const qreal totalSpacing = qMax(0, count - 1) * spacing;
    qreal totalWidth = totalSpacing;
    qreal maxWidth = 0;
    for (int i = 0; i < count; ++i) {
        QQuickItem *item = q->itemAt(i);
        if (item) {
            totalWidth += item->implicitWidth();
            maxWidth = qMax(maxWidth, item->implicitWidth());
        }
    }
    if ((alignment & Qt::AlignHorizontal_Mask) == 0)
        totalWidth = qMax(totalWidth, count * maxWidth + totalSpacing);
    return totalWidth;
}

qreal QQuickDialogButtonBoxPrivate::getContentHeight() const
{
    Q_Q(const QQuickDialogButtonBox);
    const int count = contentModel->count();
    qreal maxHeight = 0;
    for (int i = 0; i < count; ++i) {
        QQuickItem *item = q->itemAt(i);
        if (item)
            maxHeight = qMax(maxHeight, item->implicitHeight());
    }
    return maxHeight;
}

void QQuickDialogButtonBoxPrivate::handleClick()
{
    Q_Q(QQuickDialogButtonBox);
    QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->sender());
    if (!button)
        return;

    // Can't fetch this *after* emitting clicked, as clicked may destroy the button
    // or change its role. Now changing the role is not possible yet, but arguably
    // both clicked and accepted/rejected/etc. should be emitted "atomically"
    // depending on whatever role the button had at the time of the click.
    const QPlatformDialogHelper::ButtonRole role = QQuickDialogPrivate::buttonRole(button);
    QPointer<QQuickDialogButtonBox> guard(q);

    emit q->clicked(button);

    if (!guard)
        return;

    switch (role) {
    case QPlatformDialogHelper::AcceptRole:
    case QPlatformDialogHelper::YesRole:
        emit q->accepted();
        break;
    case QPlatformDialogHelper::RejectRole:
    case QPlatformDialogHelper::NoRole:
        emit q->rejected();
        break;
    case QPlatformDialogHelper::ApplyRole:
        emit q->applied();
        break;
    case QPlatformDialogHelper::ResetRole:
        emit q->reset();
        break;
    case QPlatformDialogHelper::DestructiveRole:
        emit q->discarded();
        break;
    case QPlatformDialogHelper::HelpRole:
        emit q->helpRequested();
        break;
    default:
        break;
    }
}

QQuickAbstractButton *QQuickDialogButtonBoxPrivate::createStandardButton(QPlatformDialogHelper::StandardButton standardButton)
{
    Q_Q(QQuickDialogButtonBox);
    if (!delegate)
        return nullptr;

    QQmlContext *creationContext = delegate->creationContext();
    if (!creationContext)
        creationContext = qmlContext(q);
    QQmlContext *context = new QQmlContext(creationContext, q);
    context->setContextObject(q);

    QObject *object = delegate->beginCreate(context);
    QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(object);
    if (button) {
        QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button, true));
        QQuickDialogButtonBoxAttachedPrivate::get(attached)->standardButton = standardButton;
        attached->setButtonRole(QPlatformDialogHelper::buttonRole(standardButton));
        button->setText(QPlatformTheme::removeMnemonics(QGuiApplicationPrivate::platformTheme()->standardButtonText(standardButton)));
        delegate->completeCreate();
        return button;
    }

    delete object;
    return nullptr;
}

void QQuickDialogButtonBoxPrivate::removeStandardButtons()
{
    Q_Q(QQuickDialogButtonBox);
    int i = q->count() - 1;
    while (i >= 0) {
        QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->itemAt(i));
        if (button) {
            QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(
                qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button, false));
            if (attached) {
                QQuickDialogButtonBoxAttachedPrivate *p = QQuickDialogButtonBoxAttachedPrivate::get(attached);
                if (p->standardButton != QPlatformDialogHelper::NoButton) {
                    q->removeItem(i);
                    button->deleteLater();
                }
            }
        }
        --i;
    }
}

void QQuickDialogButtonBoxPrivate::updateLanguage()
{
    Q_Q(QQuickDialogButtonBox);
    int i = q->count() - 1;
    while (i >= 0) {
        QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(itemAt(i));
        if (button) {
            QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(
                qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button, true));
            const auto boxAttachedPrivate = QQuickDialogButtonBoxAttachedPrivate::get(attached);
            const QPlatformDialogHelper::StandardButton standardButton = boxAttachedPrivate->standardButton;
            const QString buttonText = QGuiApplicationPrivate::platformTheme()->standardButtonText(standardButton);
            button->setText(QPlatformTheme::removeMnemonics(buttonText));
        }
        --i;
    }
}

QQuickDialogButtonBox::QQuickDialogButtonBox(QQuickItem *parent)
    : QQuickContainer(*(new QQuickDialogButtonBoxPrivate), parent)
{
    Q_D(QQuickDialogButtonBox);
    d->changeTypes |= QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight;
    d->buttonLayout = platformButtonLayout();
}

QQuickDialogButtonBox::~QQuickDialogButtonBox()
{
}

/*!
    \qmlproperty enumeration QtQuick.Controls::DialogButtonBox::position

    This property holds the position of the button box.

    \note If the button box is assigned as a header or footer of ApplicationWindow
    or Page, the appropriate position is set automatically.

    Possible values:
    \value DialogButtonBox.Header The button box is at the top, as a window or page header.
    \value DialogButtonBox.Footer The button box is at the bottom, as a window or page header.

    The default value is \c Footer.

    \sa Dialog::header, Dialog::footer
*/
QQuickDialogButtonBox::Position QQuickDialogButtonBox::position() const
{
    Q_D(const QQuickDialogButtonBox);
    return d->position;
}

void QQuickDialogButtonBox::setPosition(Position position)
{
    Q_D(QQuickDialogButtonBox);
    if (d->position == position)
        return;

    d->position = position;
    emit positionChanged();
}

/*!
    \qmlproperty flags QtQuick.Controls::DialogButtonBox::alignment

    This property holds the alignment of the buttons.

    Possible values:
    \value undefined The buttons are resized to fill the available space.
    \value Qt.AlignLeft The buttons are aligned to the left.
    \value Qt.AlignHCenter The buttons are horizontally centered.
    \value Qt.AlignRight The buttons are aligned to the right.
    \value Qt.AlignTop The buttons are aligned to the top.
    \value Qt.AlignVCenter The buttons are vertically centered.
    \value Qt.AlignBottom The buttons are aligned to the bottom.
*/
Qt::Alignment QQuickDialogButtonBox::alignment() const
{
    Q_D(const QQuickDialogButtonBox);
    return d->alignment;
}

void QQuickDialogButtonBox::setAlignment(Qt::Alignment alignment)
{
    Q_D(QQuickDialogButtonBox);
    if (d->alignment == alignment)
        return;

    d->alignment = alignment;
    if (isComponentComplete()) {
        d->resizeContent();
        polish();
    }
    emit alignmentChanged();
}

void QQuickDialogButtonBox::resetAlignment()
{
    setAlignment(0);
}

/*!
    \qmlproperty enumeration QtQuick.Controls::DialogButtonBox::standardButtons

    This property holds a combination of standard buttons that are used by the button box.

    \snippet qtquickcontrols2-dialogbuttonbox.qml 1

    The buttons will be positioned in the appropriate order for the user's platform.

    Possible flags:
    \value DialogButtonBox.Ok An "OK" button defined with the \c AcceptRole.
    \value DialogButtonBox.Open An "Open" button defined with the \c AcceptRole.
    \value DialogButtonBox.Save A "Save" button defined with the \c AcceptRole.
    \value DialogButtonBox.Cancel A "Cancel" button defined with the \c RejectRole.
    \value DialogButtonBox.Close A "Close" button defined with the \c RejectRole.
    \value DialogButtonBox.Discard A "Discard" or "Don't Save" button, depending on the platform, defined with the \c DestructiveRole.
    \value DialogButtonBox.Apply An "Apply" button defined with the \c ApplyRole.
    \value DialogButtonBox.Reset A "Reset" button defined with the \c ResetRole.
    \value DialogButtonBox.RestoreDefaults A "Restore Defaults" button defined with the \c ResetRole.
    \value DialogButtonBox.Help A "Help" button defined with the \c HelpRole.
    \value DialogButtonBox.SaveAll A "Save All" button defined with the \c AcceptRole.
    \value DialogButtonBox.Yes A "Yes" button defined with the \c YesRole.
    \value DialogButtonBox.YesToAll A "Yes to All" button defined with the \c YesRole.
    \value DialogButtonBox.No A "No" button defined with the \c NoRole.
    \value DialogButtonBox.NoToAll A "No to All" button defined with the \c NoRole.
    \value DialogButtonBox.Abort An "Abort" button defined with the \c RejectRole.
    \value DialogButtonBox.Retry A "Retry" button defined with the \c AcceptRole.
    \value DialogButtonBox.Ignore An "Ignore" button defined with the \c AcceptRole.
    \value DialogButtonBox.NoButton An invalid button.

    \sa standardButton()
*/
QPlatformDialogHelper::StandardButtons QQuickDialogButtonBox::standardButtons() const
{
    Q_D(const QQuickDialogButtonBox);
    return d->standardButtons;
}

void QQuickDialogButtonBox::setStandardButtons(QPlatformDialogHelper::StandardButtons buttons)
{
    Q_D(QQuickDialogButtonBox);
    if (d->standardButtons == buttons)
        return;

    d->removeStandardButtons();

    for (int i = QPlatformDialogHelper::FirstButton; i <= QPlatformDialogHelper::LastButton; i<<=1) {
        QPlatformDialogHelper::StandardButton standardButton = static_cast<QPlatformDialogHelper::StandardButton>(i);
        if (standardButton & buttons) {
            QQuickAbstractButton *button = d->createStandardButton(standardButton);
            if (button)
                addItem(button);
        }
    }

    if (isComponentComplete())
        polish();

    d->standardButtons = buttons;
    emit standardButtonsChanged();
}

/*!
    \qmlmethod AbstractButton QtQuick.Controls::DialogButtonBox::standardButton(StandardButton button)

    Returns the specified standard \a button, or \c null if it does not exist.

    \sa standardButtons
*/
QQuickAbstractButton *QQuickDialogButtonBox::standardButton(QPlatformDialogHelper::StandardButton button) const
{
    Q_D(const QQuickDialogButtonBox);
    if (Q_UNLIKELY(!(d->standardButtons & button)))
        return nullptr;
    for (int i = 0, n = count(); i < n; ++i) {
        QQuickAbstractButton *btn = qobject_cast<QQuickAbstractButton *>(d->itemAt(i));
        if (Q_LIKELY(btn)) {
            QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(btn, false));
            if (attached && QQuickDialogButtonBoxAttachedPrivate::get(attached)->standardButton == button)
                return btn;
        }
    }
    return nullptr;
}

/*!
    \qmlproperty Component QtQuick.Controls::DialogButtonBox::delegate

    This property holds a delegate for creating standard buttons.

    \sa standardButtons
*/
QQmlComponent *QQuickDialogButtonBox::delegate() const
{
    Q_D(const QQuickDialogButtonBox);
    return d->delegate;
}

void QQuickDialogButtonBox::setDelegate(QQmlComponent* delegate)
{
    Q_D(QQuickDialogButtonBox);
    if (d->delegate == delegate)
        return;

    delete d->delegate;
    d->delegate = delegate;
    emit delegateChanged();
}

QQuickDialogButtonBoxAttached *QQuickDialogButtonBox::qmlAttachedProperties(QObject *object)
{
    return new QQuickDialogButtonBoxAttached(object);
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty enumeration QtQuick.Controls::DialogButtonBox::buttonLayout

    This property holds the button layout policy to be used when arranging the buttons contained in the button box.
    The default value is platform-specific.

    Available values:
    \value DialogButtonBox.WinLayout Use a policy appropriate for applications on Windows.
    \value DialogButtonBox.MacLayout Use a policy appropriate for applications on macOS.
    \value DialogButtonBox.KdeLayout Use a policy appropriate for applications on KDE.
    \value DialogButtonBox.GnomeLayout Use a policy appropriate for applications on GNOME.
    \value DialogButtonBox.AndroidLayout Use a policy appropriate for applications on Android.
*/
QPlatformDialogHelper::ButtonLayout QQuickDialogButtonBox::buttonLayout() const
{
    Q_D(const QQuickDialogButtonBox);
    return d->buttonLayout;
}

void QQuickDialogButtonBox::setButtonLayout(QPlatformDialogHelper::ButtonLayout layout)
{
    Q_D(QQuickDialogButtonBox);
    if (d->buttonLayout == layout)
        return;

    d->buttonLayout = layout;
    if (isComponentComplete())
        d->updateLayout();
    emit buttonLayoutChanged();
}

void QQuickDialogButtonBox::resetButtonLayout()
{
    setButtonLayout(platformButtonLayout());
}

void QQuickDialogButtonBox::updatePolish()
{
    Q_D(QQuickDialogButtonBox);
    QQuickContainer::updatePolish();
    d->updateLayout();
}

class LanguageEventFilter : public QObject
{
public:
    LanguageEventFilter(QQuickDialogButtonBoxPrivate *box)
        : QObject(box->q_ptr)
        , boxPrivate(box)
    {
    }

protected:
    bool eventFilter(QObject *, QEvent *event)
    {
        if (event->type() == QEvent::LanguageChange)
            boxPrivate->updateLanguage();
        return false;
    }

private:
    QQuickDialogButtonBoxPrivate *boxPrivate;
};

void QQuickDialogButtonBox::componentComplete()
{
    Q_D(QQuickDialogButtonBox);
    QQuickContainer::componentComplete();
    d->updateLayout();
    // TODO: use the solution in QTBUG-78141 instead, when it's implemented.
    qApp->installEventFilter(new LanguageEventFilter(d));
}

void QQuickDialogButtonBox::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
    Q_D(QQuickDialogButtonBox);
    QQuickContainer::geometryChanged(newGeometry, oldGeometry);
    d->updateLayout();
}

void QQuickDialogButtonBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
{
    Q_D(QQuickDialogButtonBox);
    QQuickContainer::contentItemChange(newItem, oldItem);
    if (oldItem)
        QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight);
    if (newItem)
        QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight);
}

bool QQuickDialogButtonBox::isContent(QQuickItem *item) const
{
    return qobject_cast<QQuickAbstractButton *>(item);
}

void QQuickDialogButtonBox::itemAdded(int index, QQuickItem *item)
{
    Q_D(QQuickDialogButtonBox);
    Q_UNUSED(index);
    if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(item))
        QObjectPrivate::connect(button, &QQuickAbstractButton::clicked, d, &QQuickDialogButtonBoxPrivate::handleClick);
    if (QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(item, false)))
        QQuickDialogButtonBoxAttachedPrivate::get(attached)->setButtonBox(this);
    d->updateImplicitContentSize();
    if (isComponentComplete())
        polish();
}

void QQuickDialogButtonBox::itemRemoved(int index, QQuickItem *item)
{
    Q_D(QQuickDialogButtonBox);
    Q_UNUSED(index);
    if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(item))
        QObjectPrivate::disconnect(button, &QQuickAbstractButton::clicked, d, &QQuickDialogButtonBoxPrivate::handleClick);
    if (QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(item, false)))
        QQuickDialogButtonBoxAttachedPrivate::get(attached)->setButtonBox(nullptr);
    d->updateImplicitContentSize();
    if (isComponentComplete())
        polish();
}

#if QT_CONFIG(accessibility)
QAccessible::Role QQuickDialogButtonBox::accessibleRole() const
{
    return QAccessible::PageTabList;
}
#endif

void QQuickDialogButtonBoxAttachedPrivate::setButtonBox(QQuickDialogButtonBox *box)
{
    Q_Q(QQuickDialogButtonBoxAttached);
    if (buttonBox == box)
        return;

    buttonBox = box;
    emit q->buttonBoxChanged();
}

QQuickDialogButtonBoxAttached::QQuickDialogButtonBoxAttached(QObject *parent)
    : QObject(*(new QQuickDialogButtonBoxAttachedPrivate), parent)
{
    Q_D(QQuickDialogButtonBoxAttached);
    QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent);
    while (parentItem && !d->buttonBox) {
        d->buttonBox = qobject_cast<QQuickDialogButtonBox *>(parentItem);
        parentItem = parentItem->parentItem();
    }
}

/*!
    \qmlattachedproperty DialogButtonBox QtQuick.Controls::DialogButtonBox::buttonBox
    \readonly

    This attached property holds the button box that manages this button, or
    \c null if the button is not in a button box.
*/
QQuickDialogButtonBox *QQuickDialogButtonBoxAttached::buttonBox() const
{
    Q_D(const QQuickDialogButtonBoxAttached);
    return d->buttonBox;
}

/*!
    \qmlattachedproperty enumeration QtQuick.Controls::DialogButtonBox::buttonRole

    This attached property holds the role of each button in a button box.

    \snippet qtquickcontrols2-dialogbuttonbox-attached.qml 1

    Available values:
    \value DialogButtonBox.InvalidRole The button is invalid.
    \value DialogButtonBox.AcceptRole Clicking the button causes the dialog to be accepted (e.g. \uicontrol OK).
    \value DialogButtonBox.RejectRole Clicking the button causes the dialog to be rejected (e.g. \uicontrol Cancel).
    \value DialogButtonBox.DestructiveRole Clicking the button causes a destructive change (e.g. for discarding changes) and closes the dialog.
    \value DialogButtonBox.ActionRole Clicking the button causes changes to the elements within the dialog.
    \value DialogButtonBox.HelpRole The button can be clicked to request help.
    \value DialogButtonBox.YesRole The button is a "Yes"-like button.
    \value DialogButtonBox.NoRole The button is a "No"-like button.
    \value DialogButtonBox.ResetRole The button resets the dialog's fields to default values.
    \value DialogButtonBox.ApplyRole The button applies current changes.
*/
QPlatformDialogHelper::ButtonRole QQuickDialogButtonBoxAttached::buttonRole() const
{
    Q_D(const QQuickDialogButtonBoxAttached);
    return d->buttonRole;
}

void QQuickDialogButtonBoxAttached::setButtonRole(QPlatformDialogHelper::ButtonRole role)
{
    Q_D(QQuickDialogButtonBoxAttached);
    if (d->buttonRole == role)
        return;

    d->buttonRole = role;
    emit buttonRoleChanged();
}

QT_END_NAMESPACE
