2015-11-26 17:02:15 +00:00
|
|
|
/****************************************************************************
|
|
|
|
**
|
2016-04-14 05:57:25 +00:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
2015-11-26 17:02:15 +00:00
|
|
|
** Contact: http://www.qt.io/licensing/
|
|
|
|
**
|
2016-04-14 05:57:25 +00:00
|
|
|
** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
|
2015-11-26 17:02:15 +00:00
|
|
|
**
|
|
|
|
** $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"
|
2016-04-23 18:26:35 +00:00
|
|
|
#include "qquickpopup_p_p.h"
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
#include <QtCore/qregexp.h>
|
2016-08-08 22:13:30 +00:00
|
|
|
#include <QtCore/qabstractitemmodel.h>
|
2016-01-15 08:58:53 +00:00
|
|
|
#include <QtGui/qpa/qplatformtheme.h>
|
2015-11-26 17:02:15 +00:00
|
|
|
#include <QtQml/qjsvalue.h>
|
|
|
|
#include <QtQml/qqmlcontext.h>
|
|
|
|
#include <QtQml/private/qqmldelegatemodel_p.h>
|
|
|
|
#include <QtQuick/private/qquickevents_p_p.h>
|
|
|
|
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\qmltype ComboBox
|
|
|
|
\inherits Control
|
|
|
|
\instantiates QQuickComboBox
|
2016-04-21 14:56:59 +00:00
|
|
|
\inqmlmodule QtQuick.Controls
|
2016-05-25 06:41:21 +00:00
|
|
|
\since 5.7
|
2016-04-04 10:29:07 +00:00
|
|
|
\ingroup qtquickcontrols2-input
|
2016-11-02 10:09:35 +00:00
|
|
|
\brief Combined button and popup list for selecting options.
|
2015-11-26 17:02:15 +00:00
|
|
|
|
2016-10-07 11:31:54 +00:00
|
|
|
\image qtquickcontrols2-combobox.gif
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
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
|
2016-10-07 11:31:54 +00:00
|
|
|
a JavaScript array, a \l ListModel or an integer, but other types
|
|
|
|
of \l {qml-data-models}{data models} are also supported.
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
\code
|
|
|
|
ComboBox {
|
|
|
|
model: ["First", "Second", "Third"]
|
|
|
|
}
|
|
|
|
\endcode
|
|
|
|
|
2016-10-07 11:31:54 +00:00
|
|
|
\section1 ComboBox Model Roles
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
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.
|
|
|
|
|
|
|
|
\code
|
|
|
|
ComboBox {
|
|
|
|
textRole: "key"
|
|
|
|
model: ListModel {
|
|
|
|
ListElement { key: "First"; value: 123 }
|
|
|
|
ListElement { key: "Second"; value: 456 }
|
|
|
|
ListElement { key: "Third"; value: 789 }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
\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}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlsignal void QtQuick.Controls::ComboBox::activated(int index)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
This signal is emitted when the item at \a index is activated by the user.
|
|
|
|
|
2016-10-07 11:31:54 +00:00
|
|
|
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.
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
\sa currentIndex
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlsignal void QtQuick.Controls::ComboBox::highlighted(int index)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
This signal is emitted when the item at \a index in the popup list is highlighted by the user.
|
|
|
|
|
2016-10-07 11:31:54 +00:00
|
|
|
The highlighted signal is only emitted when the popup is open and an item
|
|
|
|
is highlighted, but not necessarily \l activated.
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
\sa highlightedIndex
|
|
|
|
*/
|
|
|
|
|
2016-01-25 16:06:30 +00:00
|
|
|
class QQuickComboBoxDelegateModel : public QQmlDelegateModel
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit QQuickComboBoxDelegateModel(QQuickComboBox *combo);
|
2016-01-28 16:20:42 +00:00
|
|
|
QString stringValue(int index, const QString &role) override;
|
2016-01-25 16:06:30 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
QQuickComboBox *combo;
|
|
|
|
};
|
|
|
|
|
|
|
|
QQuickComboBoxDelegateModel::QQuickComboBoxDelegateModel(QQuickComboBox *combo) :
|
|
|
|
QQmlDelegateModel(qmlContext(combo), combo), combo(combo)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QString QQuickComboBoxDelegateModel::stringValue(int index, const QString &role)
|
|
|
|
{
|
|
|
|
QVariant model = combo->model();
|
|
|
|
if (model.userType() == QMetaType::QVariantList) {
|
|
|
|
QVariant object = model.toList().value(index);
|
|
|
|
if (object.userType() == QMetaType::QVariantMap) {
|
2016-03-17 11:01:54 +00:00
|
|
|
const QVariantMap data = object.toMap();
|
2016-01-25 16:06:30 +00:00
|
|
|
if (data.count() == 1 && role == QLatin1String("modelData"))
|
|
|
|
return data.first().toString();
|
|
|
|
return data.value(role).toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return QQmlDelegateModel::stringValue(index, role);
|
|
|
|
}
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
class QQuickComboBoxPrivate : public QQuickControlPrivate
|
|
|
|
{
|
|
|
|
Q_DECLARE_PUBLIC(QQuickComboBox)
|
|
|
|
|
|
|
|
public:
|
2016-04-17 17:28:17 +00:00
|
|
|
QQuickComboBoxPrivate() : pressed(false), ownModel(false), hasDisplayText(false), hasCurrentIndex(false),
|
2016-01-28 16:20:42 +00:00
|
|
|
highlightedIndex(-1), currentIndex(-1), delegateModel(nullptr),
|
2016-04-28 10:37:58 +00:00
|
|
|
delegate(nullptr), indicator(nullptr), popup(nullptr) { }
|
2015-11-26 17:02:15 +00:00
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
bool isPopupVisible() const;
|
|
|
|
void showPopup();
|
|
|
|
void hidePopup(bool accept);
|
|
|
|
void togglePopup(bool accept);
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
void itemClicked();
|
|
|
|
|
2016-03-23 09:44:08 +00:00
|
|
|
void createdItem(int index, QObject *object);
|
2015-11-26 17:02:15 +00:00
|
|
|
void countChanged();
|
|
|
|
void updateCurrentText();
|
2016-05-20 11:50:28 +00:00
|
|
|
void incrementCurrentIndex();
|
|
|
|
void decrementCurrentIndex();
|
2016-10-01 21:02:43 +00:00
|
|
|
void updateHighlightedIndex();
|
2015-11-26 17:02:15 +00:00
|
|
|
void setHighlightedIndex(int index);
|
|
|
|
|
|
|
|
void createDelegateModel();
|
|
|
|
|
|
|
|
bool pressed;
|
|
|
|
bool ownModel;
|
|
|
|
bool hasDisplayText;
|
2016-04-17 17:28:17 +00:00
|
|
|
bool hasCurrentIndex;
|
2015-11-26 17:02:15 +00:00
|
|
|
int highlightedIndex;
|
|
|
|
int currentIndex;
|
|
|
|
QVariant model;
|
|
|
|
QString textRole;
|
|
|
|
QString currentText;
|
|
|
|
QString displayText;
|
|
|
|
QQuickItem *pressedItem;
|
|
|
|
QQmlInstanceModel *delegateModel;
|
|
|
|
QQmlComponent *delegate;
|
2016-04-28 10:37:58 +00:00
|
|
|
QQuickItem *indicator;
|
2015-12-08 13:26:51 +00:00
|
|
|
QQuickPopup *popup;
|
2015-11-26 17:02:15 +00:00
|
|
|
};
|
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
bool QQuickComboBoxPrivate::isPopupVisible() const
|
2015-11-26 17:02:15 +00:00
|
|
|
{
|
2015-12-08 13:26:51 +00:00
|
|
|
return popup && popup->isVisible();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
void QQuickComboBoxPrivate::showPopup()
|
2015-11-26 17:02:15 +00:00
|
|
|
{
|
2015-12-08 13:26:51 +00:00
|
|
|
if (popup && !popup->isVisible())
|
2015-12-11 14:34:55 +00:00
|
|
|
popup->open();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
void QQuickComboBoxPrivate::hidePopup(bool accept)
|
2015-11-26 17:02:15 +00:00
|
|
|
{
|
|
|
|
Q_Q(QQuickComboBox);
|
|
|
|
if (accept) {
|
|
|
|
q->setCurrentIndex(highlightedIndex);
|
|
|
|
emit q->activated(currentIndex);
|
|
|
|
}
|
2016-10-01 21:02:43 +00:00
|
|
|
if (popup && popup->isVisible())
|
|
|
|
popup->close();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
void QQuickComboBoxPrivate::togglePopup(bool accept)
|
2015-11-26 17:02:15 +00:00
|
|
|
{
|
2015-12-08 13:26:51 +00:00
|
|
|
if (!popup)
|
2015-11-26 17:02:15 +00:00
|
|
|
return;
|
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
if (popup->isVisible())
|
|
|
|
hidePopup(accept);
|
2015-11-26 17:02:15 +00:00
|
|
|
else
|
2015-12-08 13:26:51 +00:00
|
|
|
showPopup();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBoxPrivate::itemClicked()
|
|
|
|
{
|
|
|
|
Q_Q(QQuickComboBox);
|
2016-01-20 16:31:18 +00:00
|
|
|
int index = delegateModel->indexOf(q->sender(), nullptr);
|
2015-11-26 17:02:15 +00:00
|
|
|
if (index != -1) {
|
|
|
|
setHighlightedIndex(index);
|
|
|
|
emit q->highlighted(index);
|
2015-12-08 13:26:51 +00:00
|
|
|
hidePopup(true);
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-23 09:44:08 +00:00
|
|
|
void QQuickComboBoxPrivate::createdItem(int index, QObject *object)
|
2015-11-26 17:02:15 +00:00
|
|
|
{
|
|
|
|
QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(object);
|
2016-04-25 14:11:37 +00:00
|
|
|
if (button) {
|
|
|
|
button->setFocusPolicy(Qt::NoFocus);
|
2015-11-26 17:02:15 +00:00
|
|
|
connect(button, &QQuickAbstractButton::clicked, this, &QQuickComboBoxPrivate::itemClicked);
|
2016-04-25 14:11:37 +00:00
|
|
|
}
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
if (index == currentIndex)
|
|
|
|
updateCurrentText();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBoxPrivate::countChanged()
|
|
|
|
{
|
|
|
|
Q_Q(QQuickComboBox);
|
|
|
|
if (q->count() == 0)
|
|
|
|
q->setCurrentIndex(-1);
|
|
|
|
emit q->countChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBoxPrivate::updateCurrentText()
|
|
|
|
{
|
|
|
|
Q_Q(QQuickComboBox);
|
|
|
|
QString text = q->textAt(currentIndex);
|
|
|
|
if (currentText != text) {
|
|
|
|
currentText = text;
|
2016-11-01 19:14:28 +00:00
|
|
|
if (!hasDisplayText)
|
|
|
|
q->setAccessibleName(text);
|
2015-11-26 17:02:15 +00:00
|
|
|
emit q->currentTextChanged();
|
|
|
|
}
|
|
|
|
if (!hasDisplayText && displayText != text) {
|
|
|
|
displayText = text;
|
|
|
|
emit q->displayTextChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-20 11:50:28 +00:00
|
|
|
void QQuickComboBoxPrivate::incrementCurrentIndex()
|
2015-11-26 17:02:15 +00:00
|
|
|
{
|
|
|
|
Q_Q(QQuickComboBox);
|
2015-12-08 13:26:51 +00:00
|
|
|
if (isPopupVisible()) {
|
2015-11-26 17:02:15 +00:00
|
|
|
if (highlightedIndex < q->count() - 1) {
|
|
|
|
setHighlightedIndex(highlightedIndex + 1);
|
|
|
|
emit q->highlighted(highlightedIndex);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (currentIndex < q->count() - 1) {
|
|
|
|
q->setCurrentIndex(currentIndex + 1);
|
|
|
|
emit q->activated(currentIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-20 11:50:28 +00:00
|
|
|
void QQuickComboBoxPrivate::decrementCurrentIndex()
|
2015-11-26 17:02:15 +00:00
|
|
|
{
|
|
|
|
Q_Q(QQuickComboBox);
|
2015-12-08 13:26:51 +00:00
|
|
|
if (isPopupVisible()) {
|
2015-11-26 17:02:15 +00:00
|
|
|
if (highlightedIndex > 0) {
|
|
|
|
setHighlightedIndex(highlightedIndex - 1);
|
|
|
|
emit q->highlighted(highlightedIndex);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (currentIndex > 0) {
|
|
|
|
q->setCurrentIndex(currentIndex - 1);
|
|
|
|
emit q->activated(currentIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-01 21:02:43 +00:00
|
|
|
void QQuickComboBoxPrivate::updateHighlightedIndex()
|
|
|
|
{
|
|
|
|
setHighlightedIndex(popup->isVisible() ? currentIndex : -1);
|
|
|
|
}
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
void QQuickComboBoxPrivate::setHighlightedIndex(int index)
|
|
|
|
{
|
|
|
|
Q_Q(QQuickComboBox);
|
2016-02-11 17:24:18 +00:00
|
|
|
if (highlightedIndex == index)
|
|
|
|
return;
|
|
|
|
|
|
|
|
highlightedIndex = index;
|
|
|
|
emit q->highlightedIndexChanged();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBoxPrivate::createDelegateModel()
|
|
|
|
{
|
|
|
|
Q_Q(QQuickComboBox);
|
2016-01-13 17:03:43 +00:00
|
|
|
bool ownedOldModel = ownModel;
|
|
|
|
QQmlInstanceModel* oldModel = delegateModel;
|
|
|
|
if (oldModel) {
|
|
|
|
disconnect(delegateModel, &QQmlInstanceModel::countChanged, this, &QQuickComboBoxPrivate::countChanged);
|
|
|
|
disconnect(delegateModel, &QQmlInstanceModel::modelUpdated, this, &QQuickComboBoxPrivate::updateCurrentText);
|
2016-03-23 09:44:08 +00:00
|
|
|
disconnect(delegateModel, &QQmlInstanceModel::createdItem, this, &QQuickComboBoxPrivate::createdItem);
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ownModel = false;
|
|
|
|
delegateModel = model.value<QQmlInstanceModel *>();
|
|
|
|
|
|
|
|
if (!delegateModel && model.isValid()) {
|
2016-01-25 16:06:30 +00:00
|
|
|
QQmlDelegateModel *dataModel = new QQuickComboBoxDelegateModel(q);
|
2015-11-26 17:02:15 +00:00
|
|
|
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::updateCurrentText);
|
2016-03-23 09:44:08 +00:00
|
|
|
connect(delegateModel, &QQmlInstanceModel::createdItem, this, &QQuickComboBoxPrivate::createdItem);
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
emit q->delegateModelChanged();
|
2016-01-13 17:03:43 +00:00
|
|
|
|
|
|
|
if (ownedOldModel)
|
|
|
|
delete oldModel;
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QQuickComboBox::QQuickComboBox(QQuickItem *parent) :
|
|
|
|
QQuickControl(*(new QQuickComboBoxPrivate), parent)
|
|
|
|
{
|
2016-02-22 11:57:09 +00:00
|
|
|
setFocusPolicy(Qt::StrongFocus);
|
2015-11-26 17:02:15 +00:00
|
|
|
setFlag(QQuickItem::ItemIsFocusScope);
|
|
|
|
setAcceptedMouseButtons(Qt::LeftButton);
|
|
|
|
}
|
|
|
|
|
2016-01-22 14:20:04 +00:00
|
|
|
QQuickComboBox::~QQuickComboBox()
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
|
|
|
delete d->popup;
|
2016-01-25 10:02:44 +00:00
|
|
|
d->popup = nullptr;
|
2016-01-22 14:20:04 +00:00
|
|
|
}
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
/*!
|
|
|
|
\readonly
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlproperty int QtQuick.Controls::ComboBox::count
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlproperty model QtQuick.Controls::ComboBox::model
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
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();
|
|
|
|
|
2016-02-11 17:24:18 +00:00
|
|
|
if (d->model == model)
|
|
|
|
return;
|
|
|
|
|
2016-08-08 22:13:30 +00:00
|
|
|
if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(d->model))
|
|
|
|
QObjectPrivate::disconnect(aim, &QAbstractItemModel::dataChanged, d, &QQuickComboBoxPrivate::updateCurrentText);
|
|
|
|
if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(model))
|
|
|
|
QObjectPrivate::connect(aim, &QAbstractItemModel::dataChanged, d, &QQuickComboBoxPrivate::updateCurrentText);
|
|
|
|
|
2016-02-11 17:24:18 +00:00
|
|
|
d->model = model;
|
|
|
|
d->createDelegateModel();
|
|
|
|
if (isComponentComplete()) {
|
|
|
|
setCurrentIndex(count() > 0 ? 0 : -1);
|
|
|
|
d->updateCurrentText();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
2016-02-11 17:24:18 +00:00
|
|
|
emit modelChanged();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\internal
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlproperty model QtQuick.Controls::ComboBox::delegateModel
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
This property holds the model providing delegate instances for the combo box.
|
|
|
|
*/
|
|
|
|
QQmlInstanceModel *QQuickComboBox::delegateModel() const
|
|
|
|
{
|
|
|
|
Q_D(const QQuickComboBox);
|
|
|
|
return d->delegateModel;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlproperty bool QtQuick.Controls::ComboBox::pressed
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
This property holds whether the combo box button is pressed.
|
|
|
|
*/
|
|
|
|
bool QQuickComboBox::isPressed() const
|
|
|
|
{
|
|
|
|
Q_D(const QQuickComboBox);
|
|
|
|
return d->pressed;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::setPressed(bool pressed)
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
2016-02-11 17:24:18 +00:00
|
|
|
if (d->pressed == pressed)
|
|
|
|
return;
|
|
|
|
|
|
|
|
d->pressed = pressed;
|
|
|
|
emit pressedChanged();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2016-04-15 18:26:56 +00:00
|
|
|
\readonly
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlproperty int QtQuick.Controls::ComboBox::highlightedIndex
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
This property holds the index of the highlighted item in the combo box popup list.
|
|
|
|
|
2016-10-07 11:31:54 +00:00
|
|
|
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.
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
\sa highlighted(), currentIndex
|
|
|
|
*/
|
|
|
|
int QQuickComboBox::highlightedIndex() const
|
|
|
|
{
|
|
|
|
Q_D(const QQuickComboBox);
|
|
|
|
return d->highlightedIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlproperty int QtQuick.Controls::ComboBox::currentIndex
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
This property holds the index of the current item in the combo box.
|
|
|
|
|
2016-10-07 11:31:54 +00:00
|
|
|
\sa activated(), currentText, highlightedIndex
|
2015-11-26 17:02:15 +00:00
|
|
|
*/
|
|
|
|
int QQuickComboBox::currentIndex() const
|
|
|
|
{
|
|
|
|
Q_D(const QQuickComboBox);
|
|
|
|
return d->currentIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::setCurrentIndex(int index)
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
2016-04-17 17:28:17 +00:00
|
|
|
d->hasCurrentIndex = true;
|
2016-02-11 17:24:18 +00:00
|
|
|
if (d->currentIndex == index)
|
|
|
|
return;
|
|
|
|
|
|
|
|
d->currentIndex = index;
|
|
|
|
emit currentIndexChanged();
|
|
|
|
if (isComponentComplete())
|
|
|
|
d->updateCurrentText();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\readonly
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlproperty string QtQuick.Controls::ComboBox::currentText
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
This property holds the text of the current item in the combo box.
|
|
|
|
|
|
|
|
\sa currentIndex, displayText, textRole
|
|
|
|
*/
|
|
|
|
QString QQuickComboBox::currentText() const
|
|
|
|
{
|
|
|
|
Q_D(const QQuickComboBox);
|
|
|
|
return d->currentText;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlproperty string QtQuick.Controls::ComboBox::displayText
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
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;
|
2016-02-11 17:24:18 +00:00
|
|
|
if (d->displayText == text)
|
|
|
|
return;
|
|
|
|
|
|
|
|
d->displayText = text;
|
2016-11-01 19:14:28 +00:00
|
|
|
setAccessibleName(text);
|
2016-02-11 17:24:18 +00:00
|
|
|
emit displayTextChanged();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::resetDisplayText()
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
2016-02-11 17:24:18 +00:00
|
|
|
if (!d->hasDisplayText)
|
|
|
|
return;
|
|
|
|
|
|
|
|
d->hasDisplayText = false;
|
|
|
|
d->updateCurrentText();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlproperty string QtQuick.Controls::ComboBox::textRole
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
This property holds the model role used for populating the combo box.
|
|
|
|
|
2016-10-07 11:31:54 +00:00
|
|
|
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}
|
2015-11-26 17:02:15 +00:00
|
|
|
*/
|
|
|
|
QString QQuickComboBox::textRole() const
|
|
|
|
{
|
|
|
|
Q_D(const QQuickComboBox);
|
|
|
|
return d->textRole;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::setTextRole(const QString &role)
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
2016-02-11 17:24:18 +00:00
|
|
|
if (d->textRole == role)
|
|
|
|
return;
|
|
|
|
|
|
|
|
d->textRole = role;
|
|
|
|
if (isComponentComplete())
|
|
|
|
d->updateCurrentText();
|
|
|
|
emit textRoleChanged();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlproperty Component QtQuick.Controls::ComboBox::delegate
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
This property holds a delegate that presents an item in the combo box popup.
|
|
|
|
|
2016-10-07 11:31:54 +00:00
|
|
|
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
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
\sa ItemDelegate, {Customizing ComboBox}
|
|
|
|
*/
|
|
|
|
QQmlComponent *QQuickComboBox::delegate() const
|
|
|
|
{
|
|
|
|
Q_D(const QQuickComboBox);
|
|
|
|
return d->delegate;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::setDelegate(QQmlComponent* delegate)
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
2016-02-11 17:24:18 +00:00
|
|
|
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();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
2016-04-28 10:37:58 +00:00
|
|
|
/*!
|
|
|
|
\qmlproperty Item QtQuick.Controls::ComboBox::indicator
|
|
|
|
|
|
|
|
This property holds the drop indicator item.
|
2016-10-07 11:31:54 +00:00
|
|
|
|
|
|
|
\sa {Customizing ComboBox}
|
2016-04-28 10:37:58 +00:00
|
|
|
*/
|
|
|
|
QQuickItem *QQuickComboBox::indicator() const
|
|
|
|
{
|
|
|
|
Q_D(const QQuickComboBox);
|
|
|
|
return d->indicator;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::setIndicator(QQuickItem *indicator)
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
|
|
|
if (d->indicator == indicator)
|
|
|
|
return;
|
|
|
|
|
2016-09-07 13:49:37 +00:00
|
|
|
d->deleteDelegate(d->indicator);
|
2016-04-28 10:37:58 +00:00
|
|
|
d->indicator = indicator;
|
|
|
|
if (indicator) {
|
|
|
|
if (!indicator->parentItem())
|
|
|
|
indicator->setParentItem(this);
|
|
|
|
}
|
|
|
|
emit indicatorChanged();
|
|
|
|
}
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
/*!
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlproperty Popup QtQuick.Controls::ComboBox::popup
|
2015-11-26 17:02:15 +00:00
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
This property holds the popup.
|
2015-11-26 17:02:15 +00:00
|
|
|
|
2016-10-07 11:31:54 +00:00
|
|
|
The popup can be opened or closed manually, if necessary:
|
|
|
|
|
|
|
|
\code
|
|
|
|
onSpecialEvent: comboBox.popup.close()
|
|
|
|
\endcode
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
\sa {Customizing ComboBox}
|
|
|
|
*/
|
2015-12-08 13:26:51 +00:00
|
|
|
QQuickPopup *QQuickComboBox::popup() const
|
2015-11-26 17:02:15 +00:00
|
|
|
{
|
|
|
|
Q_D(const QQuickComboBox);
|
2015-12-08 13:26:51 +00:00
|
|
|
return d->popup;
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
void QQuickComboBox::setPopup(QQuickPopup *popup)
|
2015-11-26 17:02:15 +00:00
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
2016-02-11 17:24:18 +00:00
|
|
|
if (d->popup == popup)
|
|
|
|
return;
|
|
|
|
|
2016-10-01 21:02:43 +00:00
|
|
|
if (d->popup)
|
|
|
|
QObjectPrivate::disconnect(d->popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::updateHighlightedIndex);
|
2016-09-07 13:49:37 +00:00
|
|
|
d->deleteDelegate(d->popup);
|
2016-04-23 18:26:35 +00:00
|
|
|
if (popup) {
|
|
|
|
QQuickPopupPrivate::get(popup)->allowVerticalFlip = true;
|
2016-04-20 13:43:07 +00:00
|
|
|
popup->setClosePolicy(QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent);
|
2016-10-01 21:02:43 +00:00
|
|
|
QObjectPrivate::connect(popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::updateHighlightedIndex);
|
2016-04-23 18:26:35 +00:00
|
|
|
}
|
2016-02-11 17:24:18 +00:00
|
|
|
d->popup = popup;
|
|
|
|
emit popupChanged();
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlmethod string QtQuick.Controls::ComboBox::textAt(int index)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
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);
|
2016-07-05 14:57:12 +00:00
|
|
|
if (!d->delegateModel || index < 0 || index >= d->delegateModel->count())
|
2015-11-26 17:02:15 +00:00
|
|
|
return QString();
|
2016-07-05 14:57:12 +00:00
|
|
|
|
|
|
|
QString text;
|
|
|
|
QObject *object = d->delegateModel->object(index);
|
|
|
|
if (object) {
|
|
|
|
text = d->delegateModel->stringValue(index, d->textRole.isEmpty() ? QStringLiteral("modelData") : d->textRole);
|
|
|
|
d->delegateModel->release(object);
|
|
|
|
}
|
|
|
|
return text;
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2016-04-21 14:56:59 +00:00
|
|
|
\qmlmethod int QtQuick.Controls::ComboBox::find(string text, flags = Qt.MatchExactly)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
{
|
|
|
|
int itemCount = count();
|
|
|
|
uint matchType = flags & 0x0F;
|
|
|
|
Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
|
|
|
|
|
|
|
|
for (int idx = 0; idx < itemCount; ++idx) {
|
|
|
|
QString t = textAt(idx);
|
|
|
|
switch (matchType) {
|
|
|
|
case Qt::MatchExactly:
|
|
|
|
if (t == text)
|
|
|
|
return idx;
|
|
|
|
break;
|
|
|
|
case Qt::MatchRegExp:
|
|
|
|
if (QRegExp(text, cs).exactMatch(t))
|
|
|
|
return idx;
|
|
|
|
break;
|
|
|
|
case Qt::MatchWildcard:
|
|
|
|
if (QRegExp(text, cs, QRegExp::Wildcard).exactMatch(t))
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-03-04 10:48:03 +00:00
|
|
|
/*!
|
2016-05-20 11:50:28 +00:00
|
|
|
\qmlmethod void QtQuick.Controls::ComboBox::incrementCurrentIndex()
|
2016-03-04 10:48:03 +00:00
|
|
|
|
2016-05-20 11:50:28 +00:00
|
|
|
Increments the current index of the combo box, or the highlighted
|
2016-10-07 11:31:54 +00:00
|
|
|
index if the popup list is visible.
|
2016-03-19 06:43:32 +00:00
|
|
|
|
|
|
|
\sa currentIndex, highlightedIndex
|
2016-03-04 10:48:03 +00:00
|
|
|
*/
|
2016-05-20 11:50:28 +00:00
|
|
|
void QQuickComboBox::incrementCurrentIndex()
|
2016-03-04 10:48:03 +00:00
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
2016-05-20 11:50:28 +00:00
|
|
|
d->incrementCurrentIndex();
|
2016-03-04 10:48:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2016-05-20 11:50:28 +00:00
|
|
|
\qmlmethod void QtQuick.Controls::ComboBox::decrementCurrentIndex()
|
2016-03-04 10:48:03 +00:00
|
|
|
|
2016-05-20 11:50:28 +00:00
|
|
|
Decrements the current index of the combo box, or the highlighted
|
2016-10-07 11:31:54 +00:00
|
|
|
index if the popup list is visible.
|
2016-03-19 06:43:32 +00:00
|
|
|
|
|
|
|
\sa currentIndex, highlightedIndex
|
2016-03-04 10:48:03 +00:00
|
|
|
*/
|
2016-05-20 11:50:28 +00:00
|
|
|
void QQuickComboBox::decrementCurrentIndex()
|
2016-03-04 10:48:03 +00:00
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
2016-05-20 11:50:28 +00:00
|
|
|
d->decrementCurrentIndex();
|
2016-03-04 10:48:03 +00:00
|
|
|
}
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
void QQuickComboBox::focusOutEvent(QFocusEvent *event)
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
2015-12-12 11:35:28 +00:00
|
|
|
QQuickControl::focusOutEvent(event);
|
2015-12-08 13:26:51 +00:00
|
|
|
d->hidePopup(false);
|
2015-11-26 17:02:15 +00:00
|
|
|
setPressed(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::keyPressEvent(QKeyEvent *event)
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
|
|
|
QQuickControl::keyPressEvent(event);
|
2015-12-08 13:26:51 +00:00
|
|
|
if (!d->popup)
|
2015-11-26 17:02:15 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
switch (event->key()) {
|
2016-01-30 16:21:55 +00:00
|
|
|
case Qt::Key_Escape:
|
2016-05-18 03:47:36 +00:00
|
|
|
case Qt::Key_Back:
|
2016-01-30 16:21:55 +00:00
|
|
|
if (d->isPopupVisible())
|
|
|
|
event->accept();
|
|
|
|
break;
|
2015-11-26 17:02:15 +00:00
|
|
|
case Qt::Key_Space:
|
|
|
|
if (!event->isAutoRepeat())
|
|
|
|
setPressed(true);
|
|
|
|
event->accept();
|
|
|
|
break;
|
|
|
|
case Qt::Key_Enter:
|
|
|
|
case Qt::Key_Return:
|
2015-12-08 13:26:51 +00:00
|
|
|
if (d->isPopupVisible())
|
2015-11-26 17:02:15 +00:00
|
|
|
setPressed(true);
|
|
|
|
event->accept();
|
|
|
|
break;
|
|
|
|
case Qt::Key_Up:
|
2016-05-20 11:50:28 +00:00
|
|
|
d->decrementCurrentIndex();
|
2015-11-26 17:02:15 +00:00
|
|
|
event->accept();
|
|
|
|
break;
|
|
|
|
case Qt::Key_Down:
|
2016-05-20 11:50:28 +00:00
|
|
|
d->incrementCurrentIndex();
|
2015-11-26 17:02:15 +00:00
|
|
|
event->accept();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::keyReleaseEvent(QKeyEvent *event)
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
|
|
|
QQuickControl::keyReleaseEvent(event);
|
2015-12-08 13:26:51 +00:00
|
|
|
if (!d->popup || event->isAutoRepeat())
|
2015-11-26 17:02:15 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
switch (event->key()) {
|
|
|
|
case Qt::Key_Space:
|
2015-12-08 13:26:51 +00:00
|
|
|
d->togglePopup(true);
|
2015-11-26 17:02:15 +00:00
|
|
|
setPressed(false);
|
|
|
|
event->accept();
|
|
|
|
break;
|
|
|
|
case Qt::Key_Enter:
|
|
|
|
case Qt::Key_Return:
|
2016-03-04 15:03:14 +00:00
|
|
|
d->hidePopup(d->isPopupVisible());
|
2015-11-26 17:02:15 +00:00
|
|
|
setPressed(false);
|
|
|
|
event->accept();
|
|
|
|
break;
|
|
|
|
case Qt::Key_Escape:
|
2016-05-18 03:47:36 +00:00
|
|
|
case Qt::Key_Back:
|
2015-12-08 13:26:51 +00:00
|
|
|
d->hidePopup(false);
|
2015-11-26 17:02:15 +00:00
|
|
|
setPressed(false);
|
|
|
|
event->accept();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::mousePressEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
QQuickControl::mousePressEvent(event);
|
|
|
|
setPressed(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::mouseMoveEvent(QMouseEvent* event)
|
|
|
|
{
|
|
|
|
QQuickControl::mouseMoveEvent(event);
|
|
|
|
setPressed(contains(event->pos()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::mouseReleaseEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
|
|
|
QQuickControl::mouseReleaseEvent(event);
|
|
|
|
if (d->pressed) {
|
|
|
|
setPressed(false);
|
2015-12-08 13:26:51 +00:00
|
|
|
d->togglePopup(false);
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::mouseUngrabEvent()
|
|
|
|
{
|
|
|
|
QQuickControl::mouseUngrabEvent();
|
|
|
|
setPressed(false);
|
|
|
|
}
|
|
|
|
|
2016-03-03 13:19:45 +00:00
|
|
|
void QQuickComboBox::wheelEvent(QWheelEvent *event)
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
|
|
|
QQuickControl::wheelEvent(event);
|
|
|
|
if (d->wheelEnabled && !d->isPopupVisible()) {
|
|
|
|
const int oldIndex = d->currentIndex;
|
|
|
|
if (event->angleDelta().y() > 0)
|
2016-05-20 11:50:28 +00:00
|
|
|
d->decrementCurrentIndex();
|
2016-03-03 13:19:45 +00:00
|
|
|
else
|
2016-05-20 11:50:28 +00:00
|
|
|
d->incrementCurrentIndex();
|
2016-03-03 13:19:45 +00:00
|
|
|
event->setAccepted(d->currentIndex != oldIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
void QQuickComboBox::componentComplete()
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
|
|
|
QQuickControl::componentComplete();
|
|
|
|
|
|
|
|
if (d->delegateModel && d->ownModel)
|
|
|
|
static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete();
|
|
|
|
|
|
|
|
if (count() > 0) {
|
2016-04-17 17:28:17 +00:00
|
|
|
if (!d->hasCurrentIndex && d->currentIndex == -1)
|
2015-11-26 17:02:15 +00:00
|
|
|
setCurrentIndex(0);
|
|
|
|
else
|
|
|
|
d->updateCurrentText();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-15 08:58:53 +00:00
|
|
|
QFont QQuickComboBox::defaultFont() const
|
|
|
|
{
|
|
|
|
return QQuickControlPrivate::themeFont(QPlatformTheme::ComboMenuItemFont);
|
|
|
|
}
|
|
|
|
|
2016-11-01 19:14:28 +00:00
|
|
|
#ifndef QT_NO_ACCESSIBILITY
|
|
|
|
QAccessible::Role QQuickComboBox::accessibleRole() const
|
|
|
|
{
|
|
|
|
return QAccessible::ComboBox;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QQuickComboBox::accessibilityActiveChanged(bool active)
|
|
|
|
{
|
|
|
|
Q_D(QQuickComboBox);
|
|
|
|
QQuickControl::accessibilityActiveChanged(active);
|
|
|
|
|
|
|
|
if (active)
|
|
|
|
setAccessibleName(d->hasDisplayText ? d->displayText : d->currentText);
|
|
|
|
}
|
|
|
|
#endif // QT_NO_ACCESSIBILITY
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
QT_END_NAMESPACE
|