/****************************************************************************
**
** 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 "qquickcombobox_p.h"
#include "qquickcontrol_p_p.h"
#include "qquickabstractbutton_p.h"
#include "qquickabstractbutton_p_p.h"
#include "qquickpopup_p_p.h"
#include "qquickdeferredexecute_p_p.h"

#include <QtCore/qregularexpression.h>
#include <QtCore/qabstractitemmodel.h>
#include <QtCore/qglobal.h>
#include <QtGui/qinputmethod.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qpa/qplatformtheme.h>
#include <QtQml/qjsvalue.h>
#include <QtQml/qqmlcontext.h>
#include <QtQml/private/qlazilyallocated_p.h>
#include <private/qqmldelegatemodel_p.h>
#include <QtQuick/private/qquickevents_p_p.h>
#include <QtQuick/private/qquicktextinput_p.h>
#include <QtQuick/private/qquickitemview_p.h>

QT_BEGIN_NAMESPACE

/*!
    \qmltype ComboBox
    \inherits Control
//!     \instantiates QQuickComboBox
    \inqmlmodule QtQuick.Controls
    \since 5.7
    \ingroup qtquickcontrols2-input
    \ingroup qtquickcontrols2-focusscopes
    \brief Combined button and popup list for selecting options.

    \image qtquickcontrols2-combobox.gif

    ComboBox is a combined button and popup list. It provides a means of
    presenting a list of options to the user in a way that takes up the
    minimum amount of screen space.

    ComboBox is populated with a data model. The data model is commonly
    a JavaScript array, a \l ListModel or an integer, but other types
    of \l {qml-data-models}{data models} are also supported.

    \code
    ComboBox {
        model: ["First", "Second", "Third"]
    }
    \endcode

    \section1 Editable ComboBox

    ComboBox can be made \l editable. An editable combo box auto-completes
    its text based on what is available in the model.

    The following example demonstrates appending content to an editable
    combo box by reacting to the \l accepted signal.

    \snippet qtquickcontrols2-combobox-accepted.qml combobox

    \section1 ComboBox Model Roles

    ComboBox is able to visualize standard \l {qml-data-models}{data models}
    that provide the \c modelData role:
    \list
    \li models that have only one role
    \li models that do not have named roles (JavaScript array, integer)
    \endlist

    When using models that have multiple named roles, ComboBox must be configured
    to use a specific \l {textRole}{text role} for its \l {displayText}{display text}
    and \l delegate instances. If you want to use a role of the model item
    that corresponds to the text role, set \l valueRole. The \l currentValue
    property and \l indexOfValue() method can then be used to get information
    about those values.

    For example:

    \snippet qtquickcontrols2-combobox-valuerole.qml file

    \note If ComboBox is assigned a data model that has multiple named roles, but
    \l textRole is not defined, ComboBox is unable to visualize it and throws a
    \c {ReferenceError: modelData is not defined}.

    \sa {Customizing ComboBox}, {Input Controls}, {Focus Management in Qt Quick Controls}
*/

/*!
    \qmlsignal void QtQuick.Controls::ComboBox::activated(int index)

    This signal is emitted when the item at \a index is activated by the user.

    An item is activated when it is selected while the popup is open,
    causing the popup to close (and \l currentIndex to change),
    or while the popup is closed and the combo box is navigated via
    keyboard, causing the \l currentIndex to change.
    The \l currentIndex property is set to \a index.

    \sa currentIndex
*/

/*!
    \qmlsignal void QtQuick.Controls::ComboBox::highlighted(int index)

    This signal is emitted when the item at \a index in the popup list is highlighted by the user.

    The highlighted signal is only emitted when the popup is open and an item
    is highlighted, but not necessarily \l activated.

    \sa highlightedIndex
*/

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlsignal void QtQuick.Controls::ComboBox::accepted()

    This signal is emitted when the \uicontrol Return or \uicontrol Enter key is pressed
    on an \l editable combo box.

    You can handle this signal in order to add the newly entered
    item to the model, for example:

    \snippet qtquickcontrols2-combobox-accepted.qml combobox

    Before the signal is emitted, a check is done to see if the string
    exists in the model. If it does, \l currentIndex will be set to its index,
    and \l currentText to the string itself.

    After the signal has been emitted, and if the first check failed (that is,
    the item did not exist), another check will be done to see if the item was
    added by the signal handler. If it was, the \l currentIndex and
    \l currentText are updated accordingly. Otherwise, they will be set to
    \c -1 and \c "", respectively.

    \note If there is a \l validator set on the combo box, the signal will only be
          emitted if the input is in an acceptable state.
*/

namespace {
    enum Activation { NoActivate, Activate };
    enum Highlighting { NoHighlight, Highlight };
}

class QQuickComboBoxDelegateModel : public QQmlDelegateModel
{
public:
    explicit QQuickComboBoxDelegateModel(QQuickComboBox *combo);
    QVariant variantValue(int index, const QString &role) override;

private:
    QQuickComboBox *combo = nullptr;
};

QQuickComboBoxDelegateModel::QQuickComboBoxDelegateModel(QQuickComboBox *combo)
    : QQmlDelegateModel(qmlContext(combo), combo),
      combo(combo)
{
}

QVariant QQuickComboBoxDelegateModel::variantValue(int index, const QString &role)
{
    const QVariant model = combo->model();
    if (model.userType() == QMetaType::QVariantList) {
        QVariant object = model.toList().value(index);
        if (object.userType() == QMetaType::QVariantMap) {
            const QVariantMap data = object.toMap();
            if (data.count() == 1 && role == QLatin1String("modelData"))
                return data.first();
            return data.value(role);
        } else if (object.userType() == QMetaType::QObjectStar) {
            const QObject *data = object.value<QObject *>();
            if (data && role != QLatin1String("modelData"))
                return data->property(role.toUtf8());
        }
    }
    return QQmlDelegateModel::variantValue(index, role);
}

class QQuickComboBoxPrivate : public QQuickControlPrivate
{
    Q_DECLARE_PUBLIC(QQuickComboBox)

public:
    bool isPopupVisible() const;
    void showPopup();
    void hidePopup(bool accept);
    void togglePopup(bool accept);
    void popupVisibleChanged();

    void itemClicked();
    void itemHovered();

    void createdItem(int index, QObject *object);
    void modelUpdated();
    void countChanged();

    void updateEditText();
    void updateCurrentText();
    void updateCurrentValue();
    void updateCurrentText(bool hasDelegateModelObject);
    void updateCurrentValue(bool hasDelegateModelObject);
    void updateCurrentTextAndValue();

    bool isValidIndex(int index) const;
    QString fastTextAt(int index) const;
    QVariant fastValueAt(int index) const;

    void acceptInput();
    QString tryComplete(const QString &inputText);

    void incrementCurrentIndex();
    void decrementCurrentIndex();
    void setCurrentIndex(int index, Activation activate);
    void updateHighlightedIndex();
    void setHighlightedIndex(int index, Highlighting highlight);

    void keySearch(const QString &text);
    int match(int start, const QString &text, Qt::MatchFlags flags) const;

    void createDelegateModel();

    void handlePress(const QPointF &point) override;
    void handleMove(const QPointF &point) override;
    void handleRelease(const QPointF &point) override;
    void handleUngrab() override;

    void cancelIndicator();
    void executeIndicator(bool complete = false);

    void cancelPopup();
    void executePopup(bool complete = false);

    void itemImplicitWidthChanged(QQuickItem *item) override;
    void itemImplicitHeightChanged(QQuickItem *item) override;

    bool flat = false;
    bool down = false;
    bool hasDown = false;
    bool pressed = false;
    bool ownModel = false;
    bool keyNavigating = false;
    bool hasDisplayText = false;
    bool hasCurrentIndex = false;
    int highlightedIndex = -1;
    int currentIndex = -1;
    QVariant model;
    QString textRole;
    QString currentText;
    QString displayText;
    QString valueRole;
    QVariant currentValue;
    QQuickItem *pressedItem = nullptr;
    QQmlInstanceModel *delegateModel = nullptr;
    QQmlComponent *delegate = nullptr;
    QQuickDeferredPointer<QQuickItem> indicator;
    QQuickDeferredPointer<QQuickPopup> popup;

    struct ExtraData {
        bool editable = false;
        bool accepting = false;
        bool allowComplete = false;
        Qt::InputMethodHints inputMethodHints = Qt::ImhNone;
        QString editText;
        QValidator *validator = nullptr;
    };
    QLazilyAllocated<ExtraData> extra;
};

bool QQuickComboBoxPrivate::isPopupVisible() const
{
    return popup && popup->isVisible();
}

void QQuickComboBoxPrivate::showPopup()
{
    if (!popup)
        executePopup(true);

    if (popup && !popup->isVisible())
        popup->open();
}

void QQuickComboBoxPrivate::hidePopup(bool accept)
{
    Q_Q(QQuickComboBox);
    if (accept) {
        q->setCurrentIndex(highlightedIndex);
        emit q->activated(currentIndex);
    }
    if (popup && popup->isVisible())
        popup->close();
}

void QQuickComboBoxPrivate::togglePopup(bool accept)
{
    if (!popup || !popup->isVisible())
        showPopup();
    else
        hidePopup(accept);
}

void QQuickComboBoxPrivate::popupVisibleChanged()
{
    Q_Q(QQuickComboBox);
    if (isPopupVisible())
        QGuiApplication::inputMethod()->reset();

    QQuickItemView *itemView = popup->findChild<QQuickItemView *>();
    if (itemView)
        itemView->setHighlightRangeMode(QQuickItemView::NoHighlightRange);

    updateHighlightedIndex();

    if (itemView)
        itemView->positionViewAtIndex(highlightedIndex, QQuickItemView::Beginning);

    if (!hasDown) {
        q->setDown(pressed || isPopupVisible());
        hasDown = false;
    }
}

void QQuickComboBoxPrivate::itemClicked()
{
    Q_Q(QQuickComboBox);
    int index = delegateModel->indexOf(q->sender(), nullptr);
    if (index != -1) {
        setHighlightedIndex(index, Highlight);
        hidePopup(true);
    }
}

void QQuickComboBoxPrivate::itemHovered()
{
    Q_Q(QQuickComboBox);
    if (keyNavigating)
        return;

    QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->sender());
    if (!button || !button->isHovered() || QQuickAbstractButtonPrivate::get(button)->touchId != -1)
        return;

    int index = delegateModel->indexOf(button, nullptr);
    if (index != -1) {
        setHighlightedIndex(index, Highlight);

        if (QQuickItemView *itemView = popup->findChild<QQuickItemView *>())
            itemView->positionViewAtIndex(index, QQuickItemView::Contain);
    }
}

void QQuickComboBoxPrivate::createdItem(int index, QObject *object)
{
    Q_Q(QQuickComboBox);
    QQuickItem *item = qobject_cast<QQuickItem *>(object);
    if (item && !item->parentItem()) {
        if (popup)
            item->setParentItem(popup->contentItem());
        else
            item->setParentItem(q);
        QQuickItemPrivate::get(item)->setCulled(true);
    }

    QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(object);
    if (button) {
        button->setFocusPolicy(Qt::NoFocus);
        connect(button, &QQuickAbstractButton::clicked, this, &QQuickComboBoxPrivate::itemClicked);
        connect(button, &QQuickAbstractButton::hoveredChanged, this, &QQuickComboBoxPrivate::itemHovered);
    }

    if (index == currentIndex && !q->isEditable())
        updateCurrentText();
}

void QQuickComboBoxPrivate::modelUpdated()
{
    if (!extra.isAllocated() || !extra->accepting)
        updateCurrentText();
}

void QQuickComboBoxPrivate::countChanged()
{
    Q_Q(QQuickComboBox);
    if (q->count() == 0)
        q->setCurrentIndex(-1);
    emit q->countChanged();
}

void QQuickComboBoxPrivate::updateEditText()
{
    Q_Q(QQuickComboBox);
    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(contentItem);
    if (!input)
        return;

    const QString text = input->text();

    if (extra.isAllocated() && extra->allowComplete && !text.isEmpty()) {
        const QString completed = tryComplete(text);
        if (completed.length() > text.length()) {
            input->setText(completed);
            input->select(completed.length(), text.length());
            return;
        }
    }
    q->setEditText(text);
}

// We have these two rather than just using default arguments
// because QObjectPrivate::connect() doesn't accept lambdas.
void QQuickComboBoxPrivate::updateCurrentText()
{
    updateCurrentText(false);
}

void QQuickComboBoxPrivate::updateCurrentValue()
{
    updateCurrentValue(false);
}

void QQuickComboBoxPrivate::updateCurrentText(bool hasDelegateModelObject)
{
    Q_Q(QQuickComboBox);
    QString text;
    // If a delegate model object was passed in, it means the calling code
    // has decided to reuse it for several function calls to speed things up.
    // So, use the faster (private) version in that case.
    // For other cases, we use the version that creates the delegate model object
    // itself in order to have neater, more convenient calling code.
    if (isValidIndex(currentIndex)) {
        if (hasDelegateModelObject)
            text = fastTextAt(currentIndex);
        else
            text = q->textAt(currentIndex);
    }

    if (currentText != text) {
        currentText = text;
        if (!hasDisplayText)
           q->maybeSetAccessibleName(text);
        emit q->currentTextChanged();
    }
    if (!hasDisplayText && displayText != text) {
        displayText = text;
        emit q->displayTextChanged();
    }
    if (!extra.isAllocated() || !extra->accepting)
        q->setEditText(currentText);
}

void QQuickComboBoxPrivate::updateCurrentValue(bool hasDelegateModelObject)
{
    Q_Q(QQuickComboBox);
    QVariant value;
    // If a delegate model object was passed in, it means the calling code
    // has decided to reuse it for several function calls to speed things up.
    // So, use the faster (private) version in that case.
    if (isValidIndex(currentIndex)) {
        if (hasDelegateModelObject)
            value = fastValueAt(currentIndex);
        else
            value = q->valueAt(currentIndex);
    }
    if (currentValue == value)
        return;

    currentValue = value;
    emit q->currentValueChanged();
}

void QQuickComboBoxPrivate::updateCurrentTextAndValue()
{
    QObject *object = nullptr;
    // For performance reasons, we reuse the same delegate model object: QTBUG-76029.
    if (isValidIndex(currentIndex))
        object = delegateModel->object(currentIndex);
    const bool hasDelegateModelObject = object != nullptr;
    updateCurrentText(hasDelegateModelObject);
    updateCurrentValue(hasDelegateModelObject);
    if (object)
        delegateModel->release(object);
}

bool QQuickComboBoxPrivate::isValidIndex(int index) const
{
    return delegateModel && index >= 0 && index < delegateModel->count();
}

// For performance reasons (QTBUG-76029), both this and valueAt assume that
// the index is valid and delegateModel->object(index) has been called.
QString QQuickComboBoxPrivate::fastTextAt(int index) const
{
    const QString effectiveTextRole = textRole.isEmpty() ? QStringLiteral("modelData") : textRole;
    return delegateModel->stringValue(index, effectiveTextRole);
}

QVariant QQuickComboBoxPrivate::fastValueAt(int index) const
{
    const QString effectiveValueRole = valueRole.isEmpty() ? QStringLiteral("modelData") : valueRole;
    return delegateModel->variantValue(index, effectiveValueRole);
}

void QQuickComboBoxPrivate::acceptInput()
{
    Q_Q(QQuickComboBox);
    int idx = q->find(extra.value().editText, Qt::MatchFixedString);
    if (idx > -1)
        q->setCurrentIndex(idx);

    extra.value().accepting = true;
    emit q->accepted();

    if (idx == -1)
        q->setCurrentIndex(q->find(extra.value().editText, Qt::MatchFixedString));
    extra.value().accepting = false;
}

QString QQuickComboBoxPrivate::tryComplete(const QString &input)
{
    Q_Q(QQuickComboBox);
    QString match;

    const int itemCount = q->count();
    for (int idx = 0; idx < itemCount; ++idx) {
        const QString text = q->textAt(idx);
        if (!text.startsWith(input, Qt::CaseInsensitive))
            continue;

        // either the first or the shortest match
        if (match.isEmpty() || text.length() < match.length())
            match = text;
    }

    if (match.isEmpty())
        return input;

    return input + match.mid(input.length());
}

void QQuickComboBoxPrivate::setCurrentIndex(int index, Activation activate)
{
    Q_Q(QQuickComboBox);
    if (currentIndex == index)
        return;

    currentIndex = index;
    emit q->currentIndexChanged();

    if (componentComplete)
        updateCurrentTextAndValue();

    if (activate)
        emit q->activated(index);
}

void QQuickComboBoxPrivate::incrementCurrentIndex()
{
    Q_Q(QQuickComboBox);
    if (extra.isAllocated())
        extra->allowComplete = false;
    if (isPopupVisible()) {
        if (highlightedIndex < q->count() - 1)
            setHighlightedIndex(highlightedIndex + 1, Highlight);
    } else {
        if (currentIndex < q->count() - 1)
            setCurrentIndex(currentIndex + 1, Activate);
    }
    if (extra.isAllocated())
        extra->allowComplete = true;
}

void QQuickComboBoxPrivate::decrementCurrentIndex()
{
    if (extra.isAllocated())
        extra->allowComplete = false;
    if (isPopupVisible()) {
        if (highlightedIndex > 0)
            setHighlightedIndex(highlightedIndex - 1, Highlight);
    } else {
        if (currentIndex > 0)
            setCurrentIndex(currentIndex - 1, Activate);
    }
    if (extra.isAllocated())
        extra->allowComplete = true;
}

void QQuickComboBoxPrivate::updateHighlightedIndex()
{
    setHighlightedIndex(popup->isVisible() ? currentIndex : -1, NoHighlight);
}

void QQuickComboBoxPrivate::setHighlightedIndex(int index, Highlighting highlight)
{
    Q_Q(QQuickComboBox);
    if (highlightedIndex == index)
        return;

    highlightedIndex = index;
    emit q->highlightedIndexChanged();

    if (highlight)
        emit q->highlighted(index);
}

void QQuickComboBoxPrivate::keySearch(const QString &text)
{
    const int startIndex = isPopupVisible() ? highlightedIndex : currentIndex;
    const int index = match(startIndex + 1, text, Qt::MatchStartsWith | Qt::MatchWrap);
    if (index != -1) {
        if (isPopupVisible())
            setHighlightedIndex(index, Highlight);
        else
            setCurrentIndex(index, Activate);
    }
}

int QQuickComboBoxPrivate::match(int start, const QString &text, Qt::MatchFlags flags) const
{
    Q_Q(const QQuickComboBox);
    uint matchType = flags & 0x0F;
    bool wrap = flags & Qt::MatchWrap;
    Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
    QRegularExpression::PatternOptions options = flags & Qt::MatchCaseSensitive ? QRegularExpression::NoPatternOption
                                                                                : QRegularExpression::CaseInsensitiveOption;
    int from = start;
    int to = q->count();

    // iterates twice if wrapping
    for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
        for (int idx = from; idx < to; ++idx) {
            QString t = q->textAt(idx);
            switch (matchType) {
            case Qt::MatchExactly:
                if (t == text)
                    return idx;
                break;
            case Qt::MatchRegExp: {
                QRegularExpression rx(QRegularExpression::anchoredPattern(text), options);
                if (rx.match(t).hasMatch())
                    return idx;
                break;
            }
            case Qt::MatchWildcard: {
                QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(text),
                                      options);
                if (rx.match(t).hasMatch())
                    return idx;
                break;
            }
            case Qt::MatchStartsWith:
                if (t.startsWith(text, cs))
                    return idx;
                break;
            case Qt::MatchEndsWith:
                if (t.endsWith(text, cs))
                    return idx;
                break;
            case Qt::MatchFixedString:
                if (t.compare(text, cs) == 0)
                    return idx;
                break;
            case Qt::MatchContains:
            default:
                if (t.contains(text, cs))
                    return idx;
                break;
            }
        }
        // prepare for the next iteration
        from = 0;
        to = start;
    }
    return -1;
}

void QQuickComboBoxPrivate::createDelegateModel()
{
    Q_Q(QQuickComboBox);
    bool ownedOldModel = ownModel;
    QQmlInstanceModel* oldModel = delegateModel;
    if (oldModel) {
        disconnect(delegateModel, &QQmlInstanceModel::countChanged, this, &QQuickComboBoxPrivate::countChanged);
        disconnect(delegateModel, &QQmlInstanceModel::modelUpdated, this, &QQuickComboBoxPrivate::modelUpdated);
        disconnect(delegateModel, &QQmlInstanceModel::createdItem, this, &QQuickComboBoxPrivate::createdItem);
    }

    ownModel = false;
    delegateModel = model.value<QQmlInstanceModel *>();

    if (!delegateModel && model.isValid()) {
        QQmlDelegateModel *dataModel = new QQuickComboBoxDelegateModel(q);
        dataModel->setModel(model);
        dataModel->setDelegate(delegate);
        if (q->isComponentComplete())
            dataModel->componentComplete();

        ownModel = true;
        delegateModel = dataModel;
    }

    if (delegateModel) {
        connect(delegateModel, &QQmlInstanceModel::countChanged, this, &QQuickComboBoxPrivate::countChanged);
        connect(delegateModel, &QQmlInstanceModel::modelUpdated, this, &QQuickComboBoxPrivate::modelUpdated);
        connect(delegateModel, &QQmlInstanceModel::createdItem, this, &QQuickComboBoxPrivate::createdItem);
    }

    emit q->delegateModelChanged();

    if (ownedOldModel)
        delete oldModel;
}

void QQuickComboBoxPrivate::handlePress(const QPointF &point)
{
    Q_Q(QQuickComboBox);
    QQuickControlPrivate::handlePress(point);
    q->setPressed(true);
}

void QQuickComboBoxPrivate::handleMove(const QPointF &point)
{
    Q_Q(QQuickComboBox);
    QQuickControlPrivate::handleMove(point);
    q->setPressed(q->contains(point));
}

void QQuickComboBoxPrivate::handleRelease(const QPointF &point)
{
    Q_Q(QQuickComboBox);
    QQuickControlPrivate::handleRelease(point);
    if (pressed) {
        q->setPressed(false);
        togglePopup(false);
    }
}

void QQuickComboBoxPrivate::handleUngrab()
{
    Q_Q(QQuickComboBox);
    QQuickControlPrivate::handleUngrab();
    q->setPressed(false);
}

static inline QString indicatorName() { return QStringLiteral("indicator"); }

void QQuickComboBoxPrivate::cancelIndicator()
{
    Q_Q(QQuickComboBox);
    quickCancelDeferred(q, indicatorName());
}

void QQuickComboBoxPrivate::executeIndicator(bool complete)
{
    Q_Q(QQuickComboBox);
    if (indicator.wasExecuted())
        return;

    if (!indicator || complete)
        quickBeginDeferred(q, indicatorName(), indicator);
    if (complete)
        quickCompleteDeferred(q, indicatorName(), indicator);
}

static inline QString popupName() { return QStringLiteral("popup"); }

void QQuickComboBoxPrivate::cancelPopup()
{
    Q_Q(QQuickComboBox);
    quickCancelDeferred(q, popupName());
}

void QQuickComboBoxPrivate::executePopup(bool complete)
{
    Q_Q(QQuickComboBox);
    if (popup.wasExecuted())
        return;

    if (!popup || complete)
        quickBeginDeferred(q, popupName(), popup);
    if (complete)
        quickCompleteDeferred(q, popupName(), popup);
}

void QQuickComboBoxPrivate::itemImplicitWidthChanged(QQuickItem *item)
{
    Q_Q(QQuickComboBox);
    QQuickControlPrivate::itemImplicitWidthChanged(item);
    if (item == indicator)
        emit q->implicitIndicatorWidthChanged();
}

void QQuickComboBoxPrivate::itemImplicitHeightChanged(QQuickItem *item)
{
    Q_Q(QQuickComboBox);
    QQuickControlPrivate::itemImplicitHeightChanged(item);
    if (item == indicator)
        emit q->implicitIndicatorHeightChanged();
}

QQuickComboBox::QQuickComboBox(QQuickItem *parent)
    : QQuickControl(*(new QQuickComboBoxPrivate), parent)
{
    setFocusPolicy(Qt::StrongFocus);
    setFlag(QQuickItem::ItemIsFocusScope);
    setAcceptedMouseButtons(Qt::LeftButton);
#if QT_CONFIG(cursor)
    setCursor(Qt::ArrowCursor);
#endif
    setInputMethodHints(Qt::ImhNoPredictiveText);
}

QQuickComboBox::~QQuickComboBox()
{
    Q_D(QQuickComboBox);
    d->removeImplicitSizeListener(d->indicator);
    if (d->popup) {
        // Disconnect visibleChanged() to avoid a spurious highlightedIndexChanged() signal
        // emission during the destruction of the (visible) popup. (QTBUG-57650)
        QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged);
        delete d->popup;
        d->popup = nullptr;
    }
}

/*!
    \readonly
    \qmlproperty int QtQuick.Controls::ComboBox::count

    This property holds the number of items in the combo box.
*/
int QQuickComboBox::count() const
{
    Q_D(const QQuickComboBox);
    return d->delegateModel ? d->delegateModel->count() : 0;
}

/*!
    \qmlproperty model QtQuick.Controls::ComboBox::model

    This property holds the model providing data for the combo box.

    \code
    ComboBox {
        textRole: "key"
        model: ListModel {
            ListElement { key: "First"; value: 123 }
            ListElement { key: "Second"; value: 456 }
            ListElement { key: "Third"; value: 789 }
        }
    }
    \endcode

    \sa textRole, {qml-data-models}{Data Models}
*/
QVariant QQuickComboBox::model() const
{
    Q_D(const QQuickComboBox);
    return d->model;
}

void QQuickComboBox::setModel(const QVariant& m)
{
    Q_D(QQuickComboBox);
    QVariant model = m;
    if (model.userType() == qMetaTypeId<QJSValue>())
        model = model.value<QJSValue>().toVariant();

    if (d->model == model)
        return;

    if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(d->model)) {
        QObjectPrivate::disconnect(aim, &QAbstractItemModel::dataChanged,
            d, QOverload<>::of(&QQuickComboBoxPrivate::updateCurrentText));
    }
    if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(model)) {
        QObjectPrivate::connect(aim, &QAbstractItemModel::dataChanged,
            d, QOverload<>::of(&QQuickComboBoxPrivate::updateCurrentText));
    }

    d->model = model;
    d->createDelegateModel();
    emit countChanged();
    if (isComponentComplete()) {
        setCurrentIndex(count() > 0 ? 0 : -1);
        d->updateCurrentText();
    }
    emit modelChanged();
}

/*!
    \internal
    \qmlproperty model QtQuick.Controls::ComboBox::delegateModel

    This property holds the model providing delegate instances for the combo box.
*/
QQmlInstanceModel *QQuickComboBox::delegateModel() const
{
    Q_D(const QQuickComboBox);
    return d->delegateModel;
}


/*!
    \qmlproperty bool QtQuick.Controls::ComboBox::pressed

    This property holds whether the combo box button is physically pressed.
    A button can be pressed by either touch or key events.

    \sa down
*/
bool QQuickComboBox::isPressed() const
{
    Q_D(const QQuickComboBox);
    return d->pressed;
}

void QQuickComboBox::setPressed(bool pressed)
{
    Q_D(QQuickComboBox);
    if (d->pressed == pressed)
        return;

    d->pressed = pressed;
    emit pressedChanged();

    if (!d->hasDown) {
        setDown(d->pressed || d->isPopupVisible());
        d->hasDown = false;
    }
}

/*!
    \readonly
    \qmlproperty int QtQuick.Controls::ComboBox::highlightedIndex

    This property holds the index of the highlighted item in the combo box popup list.

    When a highlighted item is activated, the popup is closed, \l currentIndex
    is set to \c highlightedIndex, and the value of this property is reset to
    \c -1, as there is no longer a highlighted item.

    \sa highlighted(), currentIndex
*/
int QQuickComboBox::highlightedIndex() const
{
    Q_D(const QQuickComboBox);
    return d->highlightedIndex;
}

/*!
    \qmlproperty int QtQuick.Controls::ComboBox::currentIndex

    This property holds the index of the current item in the combo box.

    The default value is \c -1 when \l count is \c 0, and \c 0 otherwise.

    \sa activated(), currentText, highlightedIndex
*/
int QQuickComboBox::currentIndex() const
{
    Q_D(const QQuickComboBox);
    return d->currentIndex;
}

void QQuickComboBox::setCurrentIndex(int index)
{
    Q_D(QQuickComboBox);
    d->hasCurrentIndex = true;
    d->setCurrentIndex(index, NoActivate);
}

/*!
    \readonly
    \qmlproperty string QtQuick.Controls::ComboBox::currentText

    This property holds the text of the current item in the combo box.

    \sa currentIndex, displayText, textRole, editText
*/
QString QQuickComboBox::currentText() const
{
    Q_D(const QQuickComboBox);
    return d->currentText;
}

/*!
    \qmlproperty string QtQuick.Controls::ComboBox::displayText

    This property holds the text that is displayed on the combo box button.

    By default, the display text presents the current selection. That is,
    it follows the text of the current item. However, the default display
    text can be overridden with a custom value.

    \code
    ComboBox {
        currentIndex: 1
        displayText: "Size: " + currentText
        model: ["S", "M", "L"]
    }
    \endcode

    \sa currentText, textRole
*/
QString QQuickComboBox::displayText() const
{
    Q_D(const QQuickComboBox);
    return d->displayText;
}

void QQuickComboBox::setDisplayText(const QString &text)
{
    Q_D(QQuickComboBox);
    d->hasDisplayText = true;
    if (d->displayText == text)
        return;

    d->displayText = text;
    maybeSetAccessibleName(text);
    emit displayTextChanged();
}

void QQuickComboBox::resetDisplayText()
{
    Q_D(QQuickComboBox);
    if (!d->hasDisplayText)
        return;

    d->hasDisplayText = false;
    d->updateCurrentText();
}


/*!
    \qmlproperty string QtQuick.Controls::ComboBox::textRole

    This property holds the model role used for populating the combo box.

    When the model has multiple roles, \c textRole can be set to determine
    which role should be displayed.

    \sa model, currentText, displayText, {ComboBox Model Roles}
*/
QString QQuickComboBox::textRole() const
{
    Q_D(const QQuickComboBox);
    return d->textRole;
}

void QQuickComboBox::setTextRole(const QString &role)
{
    Q_D(QQuickComboBox);
    if (d->textRole == role)
        return;

    d->textRole = role;
    if (isComponentComplete())
        d->updateCurrentText();
    emit textRoleChanged();
}

/*!
    \since QtQuick.Controls 2.14 (Qt 5.14)
    \qmlproperty string QtQuick.Controls::ComboBox::valueRole

    This property holds the model role used for storing the value associated
    with each item in the model.

    For an example of how to use this property, see \l {ComboBox Model Roles}.

    \sa model, currentValue
*/
QString QQuickComboBox::valueRole() const
{
    Q_D(const QQuickComboBox);
    return d->valueRole;
}

void QQuickComboBox::setValueRole(const QString &role)
{
    Q_D(QQuickComboBox);
    if (d->valueRole == role)
        return;

    d->valueRole = role;
    if (isComponentComplete())
        d->updateCurrentValue();
    emit valueRoleChanged();
}

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

    This property holds a delegate that presents an item in the combo box popup.

    It is recommended to use \l ItemDelegate (or any other \l AbstractButton
    derivatives) as the delegate. This ensures that the interaction works as
    expected, and the popup will automatically close when appropriate. When
    other types are used as the delegate, the popup must be closed manually.
    For example, if \l MouseArea is used:

    \code
    delegate: Rectangle {
        // ...
        MouseArea {
            // ...
            onClicked: comboBox.popup.close()
        }
    }
    \endcode

    \sa ItemDelegate, {Customizing ComboBox}
*/
QQmlComponent *QQuickComboBox::delegate() const
{
    Q_D(const QQuickComboBox);
    return d->delegate;
}

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

    delete d->delegate;
    d->delegate = delegate;
    QQmlDelegateModel *delegateModel = qobject_cast<QQmlDelegateModel*>(d->delegateModel);
    if (delegateModel)
        delegateModel->setDelegate(d->delegate);
    emit delegateChanged();
}

/*!
    \qmlproperty Item QtQuick.Controls::ComboBox::indicator

    This property holds the drop indicator item.

    \sa {Customizing ComboBox}
*/
QQuickItem *QQuickComboBox::indicator() const
{
    QQuickComboBoxPrivate *d = const_cast<QQuickComboBoxPrivate *>(d_func());
    if (!d->indicator)
        d->executeIndicator();
    return d->indicator;
}

void QQuickComboBox::setIndicator(QQuickItem *indicator)
{
    Q_D(QQuickComboBox);
    if (d->indicator == indicator)
        return;

    if (!d->indicator.isExecuting())
        d->cancelIndicator();

    const qreal oldImplicitIndicatorWidth = implicitIndicatorWidth();
    const qreal oldImplicitIndicatorHeight = implicitIndicatorHeight();

    d->removeImplicitSizeListener(d->indicator);
    delete d->indicator;
    d->indicator = indicator;
    if (indicator) {
        if (!indicator->parentItem())
            indicator->setParentItem(this);
        d->addImplicitSizeListener(indicator);
    }

    if (!qFuzzyCompare(oldImplicitIndicatorWidth, implicitIndicatorWidth()))
        emit implicitIndicatorWidthChanged();
    if (!qFuzzyCompare(oldImplicitIndicatorHeight, implicitIndicatorHeight()))
        emit implicitIndicatorHeightChanged();
    if (!d->indicator.isExecuting())
        emit indicatorChanged();
}

/*!
    \qmlproperty Popup QtQuick.Controls::ComboBox::popup

    This property holds the popup.

    The popup can be opened or closed manually, if necessary:

    \code
    onSpecialEvent: comboBox.popup.close()
    \endcode

    \sa {Customizing ComboBox}
*/
QQuickPopup *QQuickComboBox::popup() const
{
    QQuickComboBoxPrivate *d = const_cast<QQuickComboBoxPrivate *>(d_func());
    if (!d->popup)
        d->executePopup(isComponentComplete());
    return d->popup;
}

void QQuickComboBox::setPopup(QQuickPopup *popup)
{
    Q_D(QQuickComboBox);
    if (d->popup == popup)
        return;

    if (!d->popup.isExecuting())
        d->cancelPopup();

    if (d->popup) {
        QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged);
        delete d->popup;
    }
    if (popup) {
        QQuickPopupPrivate::get(popup)->allowVerticalFlip = true;
        popup->setClosePolicy(QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent);
        QObjectPrivate::connect(popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged);

        if (QQuickItemView *itemView = popup->findChild<QQuickItemView *>())
            itemView->setHighlightRangeMode(QQuickItemView::NoHighlightRange);
    }
    d->popup = popup;
    if (!d->popup.isExecuting())
        emit popupChanged();
}

/*!
    \since QtQuick.Controls 2.1 (Qt 5.8)
    \qmlproperty bool QtQuick.Controls::ComboBox::flat

    This property holds whether the combo box button is flat.

    A flat combo box button does not draw a background unless it is interacted
    with. In comparison to normal combo boxes, flat combo boxes provide looks
    that make them stand out less from the rest of the UI. For instance, when
    placing a combo box into a tool bar, it may be desirable to make the combo
    box flat so it matches better with the flat looks of tool buttons.

    The default value is \c false.
*/
bool QQuickComboBox::isFlat() const
{
    Q_D(const QQuickComboBox);
    return d->flat;
}

void QQuickComboBox::setFlat(bool flat)
{
    Q_D(QQuickComboBox);
    if (d->flat == flat)
        return;

    d->flat = flat;
    emit flatChanged();
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlproperty bool QtQuick.Controls::ComboBox::down

    This property holds whether the combo box button is visually down.

    Unless explicitly set, this property is \c true when either \c pressed
    or \c popup.visible is \c true. To return to the default value, set this
    property to \c undefined.

    \sa pressed, popup
*/
bool QQuickComboBox::isDown() const
{
    Q_D(const QQuickComboBox);
    return d->down;
}

void QQuickComboBox::setDown(bool down)
{
    Q_D(QQuickComboBox);
    d->hasDown = true;

    if (d->down == down)
        return;

    d->down = down;
    emit downChanged();
}

void QQuickComboBox::resetDown()
{
    Q_D(QQuickComboBox);
    if (!d->hasDown)
        return;

    setDown(d->pressed || d->isPopupVisible());
    d->hasDown = false;
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlproperty bool QtQuick.Controls::ComboBox::editable

    This property holds whether the combo box is editable.

    The default value is \c false.

    \sa validator
*/
bool QQuickComboBox::isEditable() const
{
    Q_D(const QQuickComboBox);
    return d->extra.isAllocated() && d->extra->editable;
}

void QQuickComboBox::setEditable(bool editable)
{
    Q_D(QQuickComboBox);
    if (editable == isEditable())
        return;

    if (d->contentItem) {
        if (editable) {
            d->contentItem->installEventFilter(this);
            if (QQuickTextInput *input = qobject_cast<QQuickTextInput *>(d->contentItem)) {
                QObjectPrivate::connect(input, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText);
                QObjectPrivate::connect(input, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput);
            }
#if QT_CONFIG(cursor)
            d->contentItem->setCursor(Qt::IBeamCursor);
#endif
        } else {
            d->contentItem->removeEventFilter(this);
            if (QQuickTextInput *input = qobject_cast<QQuickTextInput *>(d->contentItem)) {
                QObjectPrivate::disconnect(input, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText);
                QObjectPrivate::disconnect(input, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput);
            }
#if QT_CONFIG(cursor)
            d->contentItem->unsetCursor();
#endif
        }
    }

    d->extra.value().editable = editable;
    setAccessibleProperty("editable", editable);
    emit editableChanged();
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlproperty string QtQuick.Controls::ComboBox::editText

    This property holds the text in the text field of an editable combo box.

    \sa editable, currentText, displayText
*/
QString QQuickComboBox::editText() const
{
    Q_D(const QQuickComboBox);
    return d->extra.isAllocated() ? d->extra->editText : QString();
}

void QQuickComboBox::setEditText(const QString &text)
{
    Q_D(QQuickComboBox);
    if (text == editText())
        return;

    d->extra.value().editText = text;
    emit editTextChanged();
}

void QQuickComboBox::resetEditText()
{
    setEditText(QString());
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlproperty Validator QtQuick.Controls::ComboBox::validator

    This property holds an input text validator for an editable combo box.

    When a validator is set, the text field will only accept input which
    leaves the text property in an intermediate state. The \l accepted signal
    will only be emitted if the text is in an acceptable state when the
    \uicontrol Return or \uicontrol Enter key is pressed.

    The currently supported validators are \l[QtQuick]{IntValidator},
    \l[QtQuick]{DoubleValidator}, and \l[QtQuick]{RegExpValidator}. An
    example of using validators is shown below, which allows input of
    integers between \c 0 and \c 10 into the text field:

    \code
    ComboBox {
        model: 10
        editable: true
        validator: IntValidator {
            top: 9
            bottom: 0
        }
    }
    \endcode

    \sa acceptableInput, accepted, editable
*/
QValidator *QQuickComboBox::validator() const
{
    Q_D(const QQuickComboBox);
    return d->extra.isAllocated() ? d->extra->validator : nullptr;
}

void QQuickComboBox::setValidator(QValidator *validator)
{
    Q_D(QQuickComboBox);
    if (validator == QQuickComboBox::validator())
        return;

    d->extra.value().validator = validator;
#if QT_CONFIG(validator)
    if (validator)
        validator->setLocale(d->locale);
#endif
    emit validatorChanged();
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlproperty flags QtQuick.Controls::ComboBox::inputMethodHints

    Provides hints to the input method about the expected content of the combo box and how it
    should operate.

    The default value is \c Qt.ImhNoPredictiveText.

    \include inputmethodhints.qdocinc
*/
Qt::InputMethodHints QQuickComboBox::inputMethodHints() const
{
    Q_D(const QQuickComboBox);
    return d->extra.isAllocated() ? d->extra->inputMethodHints : Qt::ImhNoPredictiveText;
}

void QQuickComboBox::setInputMethodHints(Qt::InputMethodHints hints)
{
    Q_D(QQuickComboBox);
    if (hints == inputMethodHints())
        return;

    d->extra.value().inputMethodHints = hints;
    emit inputMethodHintsChanged();
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlproperty bool QtQuick.Controls::ComboBox::inputMethodComposing
    \readonly

    This property holds whether an editable combo box has partial text input from an input method.

    While it is composing, an input method may rely on mouse or key events from the combo box to
    edit or commit the partial text. This property can be used to determine when to disable event
    handlers that may interfere with the correct operation of an input method.
*/
bool QQuickComboBox::isInputMethodComposing() const
{
    Q_D(const QQuickComboBox);
    return d->contentItem && d->contentItem->property("inputMethodComposing").toBool();
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlproperty bool QtQuick.Controls::ComboBox::acceptableInput
    \readonly

    This property holds whether the combo box contains acceptable text in the editable text field.

    If a validator has been set, the value is \c true only if the current text is acceptable
    to the validator as a final string (not as an intermediate string).

    \sa validator, accepted
*/
bool QQuickComboBox::hasAcceptableInput() const
{
    Q_D(const QQuickComboBox);
    return d->contentItem && d->contentItem->property("acceptableInput").toBool();
}

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

    This property holds the implicit indicator width.

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

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

    \sa implicitIndicatorHeight
*/
qreal QQuickComboBox::implicitIndicatorWidth() const
{
    Q_D(const QQuickComboBox);
    if (!d->indicator)
        return 0;
    return d->indicator->implicitWidth();
}

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

    This property holds the implicit indicator height.

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

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

    \sa implicitIndicatorWidth
*/
qreal QQuickComboBox::implicitIndicatorHeight() const
{
    Q_D(const QQuickComboBox);
    if (!d->indicator)
        return 0;
    return d->indicator->implicitHeight();
}

/*!
    \readonly
    \since QtQuick.Controls 2.14 (Qt 5.14)
    \qmlproperty string QtQuick.Controls::ComboBox::currentValue

    This property holds the value of the current item in the combo box.

    For an example of how to use this property, see \l {ComboBox Model Roles}.

    \sa currentIndex, currentText, valueRole
*/
QVariant QQuickComboBox::currentValue() const
{
    Q_D(const QQuickComboBox);
    return d->currentValue;
}

QVariant QQuickComboBox::valueAt(int index) const
{
    Q_D(const QQuickComboBox);
    if (!d->isValidIndex(index))
        return QVariant();

    QObject *object = d->delegateModel->object(index);
    QVariant value;
    if (object) {
        value = d->fastValueAt(index);
        d->delegateModel->release(object);
    }
    return value;
}

/*!
    \since QtQuick.Controls 2.14 (Qt 5.14)
    \qmlmethod int QtQuick.Controls::ComboBox::indexOfValue(object value)

    Returns the index of the specified \a value, or \c -1 if no match is found.

    For an example of how to use this method, see \l {ComboBox Model Roles}.

    \sa find(), currentValue, currentIndex, valueRole
*/
int QQuickComboBox::indexOfValue(const QVariant &value) const
{
    for (int i = 0; i < count(); ++i) {
        const QVariant ourValue = valueAt(i);
        if (value == ourValue)
            return i;
    }
    return -1;
}

/*!
    \qmlmethod string QtQuick.Controls::ComboBox::textAt(int index)

    Returns the text for the specified \a index, or an empty string
    if the index is out of bounds.

    \sa textRole
*/
QString QQuickComboBox::textAt(int index) const
{
    Q_D(const QQuickComboBox);
    if (!d->isValidIndex(index))
        return QString();

    QObject *object = d->delegateModel->object(index);
    QString text;
    if (object) {
        text = d->fastTextAt(index);
        d->delegateModel->release(object);
    }
    return text;
}

/*!
    \qmlmethod int QtQuick.Controls::ComboBox::find(string text, enumeration flags)

    Returns the index of the specified \a text, or \c -1 if no match is found.

    The way the search is performed is defined by the specified match \a flags. By default,
    combo box performs case sensitive exact matching (\c Qt.MatchExactly). All other match
    types are case-insensitive unless the \c Qt.MatchCaseSensitive flag is also specified.

    \value Qt.MatchExactly          The search term matches exactly (default).
    \value Qt.MatchRegExp           The search term matches as a regular expression.
    \value Qt.MatchWildcard         The search term matches using wildcards.
    \value Qt.MatchFixedString      The search term matches as a fixed string.
    \value Qt.MatchStartsWith       The search term matches the start of the item.
    \value Qt.MatchEndsWidth        The search term matches the end of the item.
    \value Qt.MatchContains         The search term is contained in the item.
    \value Qt.MatchCaseSensitive    The search is case sensitive.

    \sa textRole
*/
int QQuickComboBox::find(const QString &text, Qt::MatchFlags flags) const
{
    Q_D(const QQuickComboBox);
    return d->match(0, text, flags);
}

/*!
    \qmlmethod void QtQuick.Controls::ComboBox::incrementCurrentIndex()

    Increments the current index of the combo box, or the highlighted
    index if the popup list is visible.

    \sa currentIndex, highlightedIndex
*/
void QQuickComboBox::incrementCurrentIndex()
{
    Q_D(QQuickComboBox);
    d->incrementCurrentIndex();
}

/*!
    \qmlmethod void QtQuick.Controls::ComboBox::decrementCurrentIndex()

    Decrements the current index of the combo box, or the highlighted
    index if the popup list is visible.

    \sa currentIndex, highlightedIndex
*/
void QQuickComboBox::decrementCurrentIndex()
{
    Q_D(QQuickComboBox);
    d->decrementCurrentIndex();
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlmethod void QtQuick.Controls::ComboBox::selectAll()

    Selects all the text in the editable text field of the combo box.

    \sa editText
*/
void QQuickComboBox::selectAll()
{
    Q_D(QQuickComboBox);
    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(d->contentItem);
    if (!input)
        return;
    input->selectAll();
}

bool QQuickComboBox::eventFilter(QObject *object, QEvent *event)
{
    Q_D(QQuickComboBox);
    switch (event->type()) {
    case QEvent::MouseButtonRelease:
        if (d->isPopupVisible())
            d->hidePopup(false);
        break;
    case QEvent::KeyPress: {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        if (d->filterKeyEvent(ke, false))
            return true;
        event->accept();
        if (d->extra.isAllocated())
            d->extra->allowComplete = ke->key() != Qt::Key_Backspace && ke->key() != Qt::Key_Delete;
        break;
    }
    case QEvent::FocusOut:
        if (qGuiApp->focusObject() != this && (!d->popup || !d->popup->hasActiveFocus())) {
            // Only close the popup if focus was transferred somewhere else
            // than to the popup or the popup button (which normally means that
            // the user clicked on the popup button to open it, not close it).
            d->hidePopup(false);
            setPressed(false);

            // The focus left the text field, so if the edit text matches an item in the model,
            // change our currentIndex to that. This matches widgets' behavior.
            const int indexForEditText = find(d->extra.value().editText, Qt::MatchFixedString);
            if (indexForEditText > -1)
                setCurrentIndex(indexForEditText);
        }
        break;
#if QT_CONFIG(im)
    case QEvent::InputMethod:
        if (d->extra.isAllocated())
            d->extra->allowComplete = !static_cast<QInputMethodEvent*>(event)->commitString().isEmpty();
        break;
#endif
    default:
        break;
    }
    return QQuickControl::eventFilter(object, event);
}

void QQuickComboBox::focusInEvent(QFocusEvent *event)
{
    Q_D(QQuickComboBox);
    QQuickControl::focusInEvent(event);
    if (d->contentItem && isEditable())
        d->contentItem->forceActiveFocus(event->reason());
}

void QQuickComboBox::focusOutEvent(QFocusEvent *event)
{
    Q_D(QQuickComboBox);
    QQuickControl::focusOutEvent(event);

    if (qGuiApp->focusObject() != d->contentItem && (!d->popup || !d->popup->hasActiveFocus())) {
        // Only close the popup if focus was transferred
        // somewhere else than to the popup or the inner line edit (which is
        // normally done from QQuickComboBox::focusInEvent).
        d->hidePopup(false);
        setPressed(false);
    }
}

#if QT_CONFIG(im)
void QQuickComboBox::inputMethodEvent(QInputMethodEvent *event)
{
    Q_D(QQuickComboBox);
    QQuickControl::inputMethodEvent(event);
    if (!isEditable() && !event->commitString().isEmpty())
        d->keySearch(event->commitString());
    else
        event->ignore();
}
#endif

void QQuickComboBox::keyPressEvent(QKeyEvent *event)
{
    Q_D(QQuickComboBox);
    QQuickControl::keyPressEvent(event);

    switch (event->key()) {
    case Qt::Key_Escape:
    case Qt::Key_Back:
        if (d->isPopupVisible())
            event->accept();
        break;
    case Qt::Key_Space:
        if (!event->isAutoRepeat())
            setPressed(true);
        event->accept();
        break;
    case Qt::Key_Enter:
    case Qt::Key_Return:
        if (d->isPopupVisible())
            setPressed(true);
        event->accept();
        break;
    case Qt::Key_Up:
        d->keyNavigating = true;
        d->decrementCurrentIndex();
        event->accept();
        break;
    case Qt::Key_Down:
        d->keyNavigating = true;
        d->incrementCurrentIndex();
        event->accept();
        break;
    case Qt::Key_Home:
        d->keyNavigating = true;
        if (d->isPopupVisible())
            d->setHighlightedIndex(0, Highlight);
        else
            d->setCurrentIndex(0, Activate);
        event->accept();
        break;
    case Qt::Key_End:
        d->keyNavigating = true;
        if (d->isPopupVisible())
            d->setHighlightedIndex(count() - 1, Highlight);
        else
            d->setCurrentIndex(count() - 1, Activate);
        event->accept();
        break;
    default:
        if (!isEditable() && !event->text().isEmpty())
            d->keySearch(event->text());
        else
            event->ignore();
        break;
    }
}

void QQuickComboBox::keyReleaseEvent(QKeyEvent *event)
{
    Q_D(QQuickComboBox);
    QQuickControl::keyReleaseEvent(event);
    d->keyNavigating = false;
    if (event->isAutoRepeat())
        return;

    switch (event->key()) {
    case Qt::Key_Space:
        if (!isEditable())
            d->togglePopup(true);
        setPressed(false);
        event->accept();
        break;
    case Qt::Key_Enter:
    case Qt::Key_Return:
        if (!isEditable() || d->isPopupVisible())
            d->hidePopup(d->isPopupVisible());
        setPressed(false);
        event->accept();
        break;
    case Qt::Key_Escape:
    case Qt::Key_Back:
        if (d->isPopupVisible()) {
            d->hidePopup(false);
            setPressed(false);
            event->accept();
        }
        break;
    default:
        break;
    }
}

#if QT_CONFIG(wheelevent)
void QQuickComboBox::wheelEvent(QWheelEvent *event)
{
    Q_D(QQuickComboBox);
    QQuickControl::wheelEvent(event);
    if (d->wheelEnabled && !d->isPopupVisible()) {
        if (event->angleDelta().y() > 0)
            d->decrementCurrentIndex();
        else
            d->incrementCurrentIndex();
    }
}
#endif

void QQuickComboBox::componentComplete()
{
    Q_D(QQuickComboBox);
    d->executeIndicator(true);
    QQuickControl::componentComplete();
    if (d->popup)
        d->executePopup(true);

    if (d->delegateModel && d->ownModel)
        static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete();

    if (count() > 0) {
        if (!d->hasCurrentIndex && d->currentIndex == -1)
            setCurrentIndex(0);
        else
            d->updateCurrentTextAndValue();
    }
}

void QQuickComboBox::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
{
    Q_D(QQuickComboBox);
    QQuickControl::itemChange(change, value);
    if (change == ItemVisibleHasChanged && !value.boolValue) {
        d->hidePopup(false);
        setPressed(false);
    }
}

void QQuickComboBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
{
    Q_D(QQuickComboBox);
    if (oldItem) {
        oldItem->removeEventFilter(this);
        if (QQuickTextInput *oldInput = qobject_cast<QQuickTextInput *>(oldItem)) {
            QObjectPrivate::disconnect(oldInput, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput);
            QObjectPrivate::disconnect(oldInput, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText);
            disconnect(oldInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickComboBox::inputMethodComposingChanged);
            disconnect(oldInput, &QQuickTextInput::acceptableInputChanged, this, &QQuickComboBox::acceptableInputChanged);
        }
    }
    if (newItem && isEditable()) {
        newItem->installEventFilter(this);
        if (QQuickTextInput *newInput = qobject_cast<QQuickTextInput *>(newItem)) {
            QObjectPrivate::connect(newInput, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput);
            QObjectPrivate::connect(newInput, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText);
            connect(newInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickComboBox::inputMethodComposingChanged);
            connect(newInput, &QQuickTextInput::acceptableInputChanged, this, &QQuickComboBox::acceptableInputChanged);
        }
#if QT_CONFIG(cursor)
        newItem->setCursor(Qt::IBeamCursor);
#endif
    }
}

void QQuickComboBox::localeChange(const QLocale &newLocale, const QLocale &oldLocale)
{
    QQuickControl::localeChange(newLocale, oldLocale);
#if QT_CONFIG(validator)
    if (QValidator *v = validator())
        v->setLocale(newLocale);
#endif
}

QFont QQuickComboBox::defaultFont() const
{
    return QQuickTheme::font(QQuickTheme::ComboBox);
}

QPalette QQuickComboBox::defaultPalette() const
{
    return QQuickTheme::palette(QQuickTheme::ComboBox);
}

#if QT_CONFIG(accessibility)
QAccessible::Role QQuickComboBox::accessibleRole() const
{
    return QAccessible::ComboBox;
}

void QQuickComboBox::accessibilityActiveChanged(bool active)
{
    Q_D(QQuickComboBox);
    QQuickControl::accessibilityActiveChanged(active);

    if (active) {
        maybeSetAccessibleName(d->hasDisplayText ? d->displayText : d->currentText);
        setAccessibleProperty("editable", isEditable());
    }
}
#endif //

QT_END_NAMESPACE
