aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-10-05 03:03:27 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-10-05 03:03:27 +0200
commita4ecc76df944cce5152cdfc8fd27436390a4fa62 (patch)
treec840006f08a790bf4c9ce362e98d826009f520fc /src
parent472750be915b7cab88c5daaca1246f58c6bd0f72 (diff)
parenta392194a575653dff3cd21227e6a1a2902b8399f (diff)
Merge remote-tracking branch 'origin/5.14' into 5.15
Diffstat (limited to 'src')
-rw-r--r--src/quicktemplates2/qquickabstractbutton.cpp4
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp119
-rw-r--r--src/quicktemplates2/qquickcombobox_p.h4
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h2
-rw-r--r--src/quicktemplates2/qquicktooltip.cpp3
-rw-r--r--src/quicktemplates2/qquicktumbler.cpp17
6 files changed, 118 insertions, 31 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp
index 983f2651..2099f2db 100644
--- a/src/quicktemplates2/qquickabstractbutton.cpp
+++ b/src/quicktemplates2/qquickabstractbutton.cpp
@@ -105,6 +105,7 @@ QT_BEGIN_NAMESPACE
\qmlsignal QtQuick.Controls::AbstractButton::pressAndHold()
This signal is emitted when the button is interactively pressed and held down by the user via touch or mouse.
+ It is not emitted when \l autoRepeat is enabled.
*/
/*!
@@ -658,6 +659,9 @@ void QQuickAbstractButton::setAutoExclusive(bool exclusive)
This property holds whether the button repeats \l pressed(), \l released()
and \l clicked() signals while the button is pressed and held down.
+ If this property is set to \c true, the \l pressAndHold() signal will not
+ be emitted.
+
The default value is \c false.
The initial delay and the repetition interval are defined in milliseconds
diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp
index 60526a0a..21eecfe1 100644
--- a/src/quicktemplates2/qquickcombobox.cpp
+++ b/src/quicktemplates2/qquickcombobox.cpp
@@ -43,6 +43,7 @@
#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>
@@ -231,6 +232,13 @@ public:
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);
@@ -433,10 +441,34 @@ void QQuickComboBoxPrivate::updateEditText()
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 = q->textAt(currentIndex);
+ 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)
@@ -451,10 +483,19 @@ void QQuickComboBoxPrivate::updateCurrentText()
q->setEditText(currentText);
}
-void QQuickComboBoxPrivate::updateCurrentValue()
+void QQuickComboBoxPrivate::updateCurrentValue(bool hasDelegateModelObject)
{
Q_Q(QQuickComboBox);
- const QVariant value = q->valueAt(currentIndex);
+ 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;
@@ -462,6 +503,38 @@ void QQuickComboBoxPrivate::updateCurrentValue()
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);
@@ -508,10 +581,8 @@ void QQuickComboBoxPrivate::setCurrentIndex(int index, Activation activate)
currentIndex = index;
emit q->currentIndexChanged();
- if (componentComplete) {
- updateCurrentText();
- updateCurrentValue();
- }
+ if (componentComplete)
+ updateCurrentTextAndValue();
if (activate)
emit q->activated(index);
@@ -832,10 +903,14 @@ void QQuickComboBox::setModel(const QVariant& m)
if (d->model == model)
return;
- 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);
+ 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();
@@ -1505,15 +1580,13 @@ QVariant QQuickComboBox::currentValue() const
QVariant QQuickComboBox::valueAt(int index) const
{
Q_D(const QQuickComboBox);
- if (!d->delegateModel || index < 0 || index >= d->delegateModel->count())
+ if (!d->isValidIndex(index))
return QVariant();
- // We use QVariant because the model API uses QVariant.
- QVariant value;
QObject *object = d->delegateModel->object(index);
+ QVariant value;
if (object) {
- const QString role = d->valueRole.isEmpty() ? QStringLiteral("modelData") : d->valueRole;
- value = d->delegateModel->variantValue(index, role);
+ value = d->fastValueAt(index);
d->delegateModel->release(object);
}
return value;
@@ -1550,13 +1623,13 @@ int QQuickComboBox::indexOfValue(const QVariant &value) const
QString QQuickComboBox::textAt(int index) const
{
Q_D(const QQuickComboBox);
- if (!d->delegateModel || index < 0 || index >= d->delegateModel->count())
+ if (!d->isValidIndex(index))
return QString();
- QString text;
QObject *object = d->delegateModel->object(index);
+ QString text;
if (object) {
- text = d->delegateModel->stringValue(index, d->textRole.isEmpty() ? QStringLiteral("modelData") : d->textRole);
+ text = d->fastTextAt(index);
d->delegateModel->release(object);
}
return text;
@@ -1823,12 +1896,10 @@ void QQuickComboBox::componentComplete()
static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete();
if (count() > 0) {
- if (!d->hasCurrentIndex && d->currentIndex == -1) {
+ if (!d->hasCurrentIndex && d->currentIndex == -1)
setCurrentIndex(0);
- } else {
- d->updateCurrentText();
- d->updateCurrentValue();
- }
+ else
+ d->updateCurrentTextAndValue();
}
}
diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h
index a55541d4..c9063d6a 100644
--- a/src/quicktemplates2/qquickcombobox_p.h
+++ b/src/quicktemplates2/qquickcombobox_p.h
@@ -163,8 +163,8 @@ public:
// 2.14 (Qt 5.14)
QVariant currentValue() const;
- Q_INVOKABLE QVariant valueAt(int index) const;
- Q_INVOKABLE int indexOfValue(const QVariant &value) const;
+ Q_REVISION(14) Q_INVOKABLE QVariant valueAt(int index) const;
+ Q_REVISION(14) Q_INVOKABLE int indexOfValue(const QVariant &value) const;
public Q_SLOTS:
void incrementCurrentIndex();
diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h
index e32fdb28..8a85f914 100644
--- a/src/quicktemplates2/qquickpopup_p_p.h
+++ b/src/quicktemplates2/qquickpopup_p_p.h
@@ -187,7 +187,7 @@ public:
QQuickPopup::ClosePolicy closePolicy = DefaultClosePolicy;
QQuickItem *parentItem = nullptr;
QQuickItem *dimmer = nullptr;
- QQuickWindow *window = nullptr;
+ QPointer<QQuickWindow> window;
QQuickTransition *enter = nullptr;
QQuickTransition *exit = nullptr;
QQuickPopupItem *popupItem = nullptr;
diff --git a/src/quicktemplates2/qquicktooltip.cpp b/src/quicktemplates2/qquicktooltip.cpp
index c1271dab..0a36e0c7 100644
--- a/src/quicktemplates2/qquicktooltip.cpp
+++ b/src/quicktemplates2/qquicktooltip.cpp
@@ -238,12 +238,13 @@ void QQuickToolTip::setTimeout(int timeout)
if (d->timeout == timeout)
return;
+ d->timeout = timeout;
+
if (timeout <= 0)
d->stopTimeout();
else if (isVisible())
d->startTimeout();
- d->timeout = timeout;
emit timeoutChanged();
}
diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp
index 8b702c60..85c70b1b 100644
--- a/src/quicktemplates2/qquicktumbler.cpp
+++ b/src/quicktemplates2/qquicktumbler.cpp
@@ -949,9 +949,20 @@ void QQuickTumblerAttachedPrivate::calculateDisplacement()
const qreal contentY = tumblerPrivate->viewContentY;
const qreal delegateH = delegateHeight(tumbler);
const qreal preferredHighlightBegin = tumblerPrivate->view->property("preferredHighlightBegin").toReal();
- // Tumbler's displacement goes from negative at the top to positive towards the bottom, so we must switch this around.
- const qreal reverseDisplacement = (contentY + preferredHighlightBegin) / delegateH;
- displacement = reverseDisplacement - index;
+ const qreal itemY = qobject_cast<QQuickItem*>(parent)->y();
+ qreal currentItemY = 0;
+ auto currentItem = tumblerPrivate->view->property("currentItem").value<QQuickItem*>();
+ if (currentItem)
+ currentItemY = currentItem->y();
+ // Start from the y position of the current item.
+ const qreal topOfCurrentItemInViewport = currentItemY - contentY;
+ // Then, calculate the distance between it and the preferredHighlightBegin.
+ const qreal relativePositionToPreferredHighlightBegin = topOfCurrentItemInViewport - preferredHighlightBegin;
+ // Next, calculate the distance between us and the current item.
+ const qreal distanceFromCurrentItem = currentItemY - itemY;
+ const qreal displacementInPixels = distanceFromCurrentItem - relativePositionToPreferredHighlightBegin;
+ // Convert it from pixels to a floating point index.
+ displacement = displacementInPixels / delegateH;
}
emitIfDisplacementChanged(previousDisplacement, displacement);