aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2017-12-15 11:44:26 +0100
committerJ-P Nurmi <jpnurmi@qt.io>2017-12-15 11:44:26 +0100
commit1fcec5bf1e208a4f32ef4f3afa54684358a11a1d (patch)
treefebc62851b20cfc485f875e3a6303ac2791b1119 /src/quicktemplates2
parent6767d789b3544c6ff7717250e1c0dee02ad91fd4 (diff)
parent6b89293b99e763589181fd1f75470712f52cee3c (diff)
Merge remote-tracking branch 'origin/5.9' into 5.10
Conflicts: .qmake.conf examples/quickcontrols2/quickcontrols2.pro src/imports/controls/ComboBox.qml src/quicktemplates2/qquickabstractbutton.cpp src/quicktemplates2/qquickabstractbutton_p.h src/quicktemplates2/qquickapplicationwindow_p.h src/quicktemplates2/qquickcombobox.cpp src/quicktemplates2/qquickcontainer.cpp src/quicktemplates2/qquickcontrol.cpp src/quicktemplates2/qquickcontrol_p.h src/quicktemplates2/qquickcontrol_p_p.h src/quicktemplates2/qquicklabel_p.h src/quicktemplates2/qquicklabel_p_p.h src/quicktemplates2/qquickslider_p.h src/quicktemplates2/qquickspinbox.cpp src/quicktemplates2/qquicktextarea_p.h src/quicktemplates2/qquicktextarea_p_p.h src/quicktemplates2/qquicktextfield_p.h src/quicktemplates2/qquicktextfield_p_p.h tests/auto/auto.pro tests/auto/controls/data/tst_combobox.qml Change-Id: I34cdd5a9794e34e0f38f70353f2a2d04dfc11074
Diffstat (limited to 'src/quicktemplates2')
-rw-r--r--src/quicktemplates2/qquickabstractbutton.cpp31
-rw-r--r--src/quicktemplates2/qquickabstractbutton_p.h3
-rw-r--r--src/quicktemplates2/qquickabstractbutton_p_p.h4
-rw-r--r--src/quicktemplates2/qquickapplicationwindow.cpp30
-rw-r--r--src/quicktemplates2/qquickapplicationwindow_p.h1
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp96
-rw-r--r--src/quicktemplates2/qquickcombobox_p.h1
-rw-r--r--src/quicktemplates2/qquickcontainer.cpp3
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp46
-rw-r--r--src/quicktemplates2/qquickcontrol_p.h1
-rw-r--r--src/quicktemplates2/qquickcontrol_p_p.h8
-rw-r--r--src/quicktemplates2/qquickdeferredexecute.cpp131
-rw-r--r--src/quicktemplates2/qquickdeferredexecute_p_p.h85
-rw-r--r--src/quicktemplates2/qquickdeferredpointer_p_p.h189
-rw-r--r--src/quicktemplates2/qquickdial.cpp29
-rw-r--r--src/quicktemplates2/qquickdial_p.h1
-rw-r--r--src/quicktemplates2/qquickgroupbox.cpp37
-rw-r--r--src/quicktemplates2/qquickgroupbox_p.h3
-rw-r--r--src/quicktemplates2/qquicklabel.cpp25
-rw-r--r--src/quicktemplates2/qquicklabel_p.h1
-rw-r--r--src/quicktemplates2/qquicklabel_p_p.h5
-rw-r--r--src/quicktemplates2/qquickpage.cpp6
-rw-r--r--src/quicktemplates2/qquickpane.cpp6
-rw-r--r--src/quicktemplates2/qquickpopupitem.cpp6
-rw-r--r--src/quicktemplates2/qquickrangeslider.cpp46
-rw-r--r--src/quicktemplates2/qquickrangeslider_p.h2
-rw-r--r--src/quicktemplates2/qquickscrollview.cpp2
-rw-r--r--src/quicktemplates2/qquickshortcutcontext.cpp3
-rw-r--r--src/quicktemplates2/qquickslider.cpp29
-rw-r--r--src/quicktemplates2/qquickslider_p.h1
-rw-r--r--src/quicktemplates2/qquickspinbox.cpp74
-rw-r--r--src/quicktemplates2/qquickspinbox_p.h2
-rw-r--r--src/quicktemplates2/qquicktextarea.cpp25
-rw-r--r--src/quicktemplates2/qquicktextarea_p.h1
-rw-r--r--src/quicktemplates2/qquicktextarea_p_p.h5
-rw-r--r--src/quicktemplates2/qquicktextfield.cpp25
-rw-r--r--src/quicktemplates2/qquicktextfield_p.h1
-rw-r--r--src/quicktemplates2/qquicktextfield_p_p.h5
-rw-r--r--src/quicktemplates2/qquicktumbler_p.h1
-rw-r--r--src/quicktemplates2/quicktemplates2.pri3
40 files changed, 877 insertions, 96 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp
index cc918c0c..a7fe720a 100644
--- a/src/quicktemplates2/qquickabstractbutton.cpp
+++ b/src/quicktemplates2/qquickabstractbutton.cpp
@@ -40,6 +40,7 @@
#include "qquickaction_p.h"
#include "qquickaction_p_p.h"
#include "qquickshortcutcontext_p_p.h"
+#include "qquickdeferredexecute_p_p.h"
#include <QtGui/qstylehints.h>
#include <QtGui/qguiapplication.h>
@@ -308,6 +309,20 @@ void QQuickAbstractButtonPrivate::toggle(bool value)
emit q->toggled();
}
+static inline QString indicatorName() { return QStringLiteral("indicator"); }
+
+void QQuickAbstractButtonPrivate::executeIndicator(bool complete)
+{
+ Q_Q(QQuickControl);
+ if (indicator.wasExecuted())
+ return;
+
+ if (!indicator)
+ quickBeginDeferred(q, indicatorName(), indicator);
+ if (complete)
+ quickCompleteDeferred(q, indicatorName(), indicator);
+}
+
QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const
{
Q_Q(const QQuickAbstractButton);
@@ -604,7 +619,9 @@ void QQuickAbstractButton::setAutoRepeat(bool repeat)
*/
QQuickItem *QQuickAbstractButton::indicator() const
{
- Q_D(const QQuickAbstractButton);
+ QQuickAbstractButtonPrivate *d = const_cast<QQuickAbstractButtonPrivate *>(d_func());
+ if (!d->indicator)
+ d->executeIndicator();
return d->indicator;
}
@@ -614,14 +631,15 @@ void QQuickAbstractButton::setIndicator(QQuickItem *indicator)
if (d->indicator == indicator)
return;
- QQuickControlPrivate::destroyDelegate(d->indicator, this);
+ delete d->indicator;
d->indicator = indicator;
if (indicator) {
if (!indicator->parentItem())
indicator->setParentItem(this);
indicator->setAcceptedMouseButtons(Qt::LeftButton);
}
- emit indicatorChanged();
+ if (!d->indicator.isExecuting())
+ emit indicatorChanged();
}
/*!
@@ -791,6 +809,13 @@ void QQuickAbstractButton::toggle()
setChecked(!d->checked);
}
+void QQuickAbstractButton::componentComplete()
+{
+ Q_D(QQuickAbstractButton);
+ d->executeIndicator(true);
+ QQuickControl::componentComplete();
+}
+
bool QQuickAbstractButton::event(QEvent *event)
{
Q_D(QQuickAbstractButton);
diff --git a/src/quicktemplates2/qquickabstractbutton_p.h b/src/quicktemplates2/qquickabstractbutton_p.h
index ecce4299..cc3cce91 100644
--- a/src/quicktemplates2/qquickabstractbutton_p.h
+++ b/src/quicktemplates2/qquickabstractbutton_p.h
@@ -70,6 +70,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickAbstractButton : public QQuickContr
Q_PROPERTY(QQuickIcon icon READ icon WRITE setIcon NOTIFY iconChanged FINAL REVISION 3)
Q_PROPERTY(Display display READ display WRITE setDisplay NOTIFY displayChanged FINAL REVISION 3)
Q_PROPERTY(QQuickAction *action READ action WRITE setAction NOTIFY actionChanged FINAL REVISION 3)
+ Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,indicator")
public:
explicit QQuickAbstractButton(QQuickItem *parent = nullptr);
@@ -150,6 +151,8 @@ Q_SIGNALS:
protected:
QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQuickItem *parent);
+ void componentComplete() override;
+
bool event(QEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h
index 659846e5..2436d242 100644
--- a/src/quicktemplates2/qquickabstractbutton_p_p.h
+++ b/src/quicktemplates2/qquickabstractbutton_p_p.h
@@ -94,6 +94,8 @@ public:
void trigger();
void toggle(bool value);
+ void executeIndicator(bool complete = false);
+
QString text;
bool down;
bool explicitDown;
@@ -114,7 +116,7 @@ public:
QQuickIcon icon;
QPointF pressPoint;
Qt::MouseButtons pressButtons;
- QQuickItem *indicator;
+ QQuickDeferredPointer<QQuickItem> indicator;
QQuickButtonGroup *group;
QQuickAbstractButton::Display display;
QPointer<QQuickAction> action;
diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp
index d579afb2..94b0de98 100644
--- a/src/quicktemplates2/qquickapplicationwindow.cpp
+++ b/src/quicktemplates2/qquickapplicationwindow.cpp
@@ -43,6 +43,8 @@
#include "qquicktoolbar_p.h"
#include "qquicktabbar_p.h"
#include "qquickdialogbuttonbox_p.h"
+#include "qquickdeferredexecute_p_p.h"
+#include "qquickdeferredpointer_p_p.h"
#include <QtCore/private/qobject_p.h>
#include <QtQuick/private/qquickitem_p.h>
@@ -164,8 +166,10 @@ public:
static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj);
+ void executeBackground(bool complete = false);
+
bool complete;
- QQuickItem *background;
+ QQuickDeferredPointer<QQuickItem> background;
QQuickItem *contentItem;
QQuickItem *menuBar;
QQuickItem *header;
@@ -328,6 +332,20 @@ void QQuickApplicationWindowPrivate::contentData_append(QQmlListProperty<QObject
QQuickPopupPrivate::get(popup)->setWindow(static_cast<QQuickApplicationWindow *>(prop->data));
}
+static inline QString backgroundName() { return QStringLiteral("background"); }
+
+void QQuickApplicationWindowPrivate::executeBackground(bool complete)
+{
+ Q_Q(QQuickApplicationWindow);
+ if (background.wasExecuted())
+ return;
+
+ if (!background)
+ quickBeginDeferred(q, backgroundName(), background);
+ if (complete)
+ quickCompleteDeferred(q, backgroundName(), background);
+}
+
QQuickApplicationWindow::QQuickApplicationWindow(QWindow *parent)
: QQuickWindowQmlImpl(parent), d_ptr(new QQuickApplicationWindowPrivate)
{
@@ -374,7 +392,9 @@ QQuickApplicationWindowAttached *QQuickApplicationWindow::qmlAttachedProperties(
*/
QQuickItem *QQuickApplicationWindow::background() const
{
- Q_D(const QQuickApplicationWindow);
+ QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func());
+ if (!d->background)
+ d->executeBackground();
return d->background;
}
@@ -384,7 +404,7 @@ void QQuickApplicationWindow::setBackground(QQuickItem *background)
if (d->background == background)
return;
- QQuickControlPrivate::destroyDelegate(d->background, this);
+ delete d->background;
d->background = background;
if (background) {
background->setParentItem(QQuickWindow::contentItem());
@@ -393,7 +413,8 @@ void QQuickApplicationWindow::setBackground(QQuickItem *background)
if (isComponentComplete())
d->relayout();
}
- emit backgroundChanged();
+ if (!d->background.isExecuting())
+ emit backgroundChanged();
}
/*!
@@ -812,6 +833,7 @@ void QQuickApplicationWindow::componentComplete()
{
Q_D(QQuickApplicationWindow);
d->complete = true;
+ d->executeBackground(true);
QQuickWindowQmlImpl::componentComplete();
d->relayout();
}
diff --git a/src/quicktemplates2/qquickapplicationwindow_p.h b/src/quicktemplates2/qquickapplicationwindow_p.h
index 4e24009f..d74d3c9d 100644
--- a/src/quicktemplates2/qquickapplicationwindow_p.h
+++ b/src/quicktemplates2/qquickapplicationwindow_p.h
@@ -76,6 +76,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickApplicationWindow : public QQuickWi
// 2.3 (Qt 5.10)
Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3)
Q_PROPERTY(QQuickItem *menuBar READ menuBar WRITE setMenuBar NOTIFY menuBarChanged FINAL REVISION 3)
+ Q_CLASSINFO("DeferredPropertyNames", "background")
Q_CLASSINFO("DefaultProperty", "contentData")
public:
diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp
index 6b20e6a5..3b37900d 100644
--- a/src/quicktemplates2/qquickcombobox.cpp
+++ b/src/quicktemplates2/qquickcombobox.cpp
@@ -39,6 +39,7 @@
#include "qquickabstractbutton_p.h"
#include "qquickabstractbutton_p_p.h"
#include "qquickpopup_p_p.h"
+#include "qquickdeferredexecute_p_p.h"
#include <QtCore/qregexp.h>
#include <QtCore/qabstractitemmodel.h>
@@ -255,6 +256,9 @@ public:
void handleRelease(const QPointF &point) override;
void handleUngrab() override;
+ void executeIndicator(bool complete = false);
+ void executePopup(bool complete = false);
+
bool flat;
bool down;
bool hasDown;
@@ -272,8 +276,8 @@ public:
QQuickItem *pressedItem;
QQmlInstanceModel *delegateModel;
QQmlComponent *delegate;
- QQuickItem *indicator;
- QQuickPopup *popup;
+ QQuickDeferredPointer<QQuickItem> indicator;
+ QQuickDeferredPointer<QQuickPopup> popup;
struct ExtraData {
ExtraData()
@@ -318,6 +322,9 @@ bool QQuickComboBoxPrivate::isPopupVisible() const
void QQuickComboBoxPrivate::showPopup()
{
+ if (!popup)
+ executePopup(true);
+
if (popup && !popup->isVisible())
popup->open();
}
@@ -335,13 +342,10 @@ void QQuickComboBoxPrivate::hidePopup(bool accept)
void QQuickComboBoxPrivate::togglePopup(bool accept)
{
- if (!popup)
- return;
-
- if (popup->isVisible())
- hidePopup(accept);
- else
+ if (!popup || !popup->isVisible())
showPopup();
+ else
+ hidePopup(accept);
}
void QQuickComboBoxPrivate::popupVisibleChanged()
@@ -398,8 +402,11 @@ void QQuickComboBoxPrivate::createdItem(int index, QObject *object)
{
Q_Q(QQuickComboBox);
QQuickItem *item = qobject_cast<QQuickItem *>(object);
- if (popup && item && !item->parentItem()) {
- item->setParentItem(popup->contentItem());
+ if (item && !item->parentItem()) {
+ if (popup)
+ item->setParentItem(popup->contentItem());
+ else
+ item->setParentItem(q);
QQuickItemPrivate::get(item)->setCulled(true);
}
@@ -695,6 +702,34 @@ void QQuickComboBoxPrivate::handleUngrab()
q->setPressed(false);
}
+static inline QString indicatorName() { return QStringLiteral("indicator"); }
+
+void QQuickComboBoxPrivate::executeIndicator(bool complete)
+{
+ Q_Q(QQuickComboBox);
+ if (indicator.wasExecuted())
+ return;
+
+ if (!indicator)
+ quickBeginDeferred(q, indicatorName(), indicator);
+ if (complete)
+ quickCompleteDeferred(q, indicatorName(), indicator);
+}
+
+static inline QString popupName() { return QStringLiteral("popup"); }
+
+void QQuickComboBoxPrivate::executePopup(bool complete)
+{
+ Q_Q(QQuickComboBox);
+ if (popup.wasExecuted())
+ return;
+
+ if (!popup)
+ quickBeginDeferred(q, popupName(), popup);
+ if (complete)
+ quickCompleteDeferred(q, popupName(), popup);
+}
+
QQuickComboBox::QQuickComboBox(QQuickItem *parent)
: QQuickControl(*(new QQuickComboBoxPrivate), parent)
{
@@ -710,14 +745,13 @@ QQuickComboBox::QQuickComboBox(QQuickItem *parent)
QQuickComboBox::~QQuickComboBox()
{
Q_D(QQuickComboBox);
- // Disconnect visibleChanged() to avoid a spurious highlightedIndexChanged() signal
- // emission during the destruction of the (visible) popup. (QTBUG-57650)
- QObjectPrivate::disconnect(d->popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged);
-
- // Delete the popup directly instead of calling setPopup(nullptr) to avoid calling
- // destroyDelegate(popup) and potentially accessing a destroyed QML context. (QTBUG-50992)
- delete d->popup;
- d->popup = nullptr;
+ 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;
+ }
}
/*!
@@ -1002,7 +1036,9 @@ void QQuickComboBox::setDelegate(QQmlComponent* delegate)
*/
QQuickItem *QQuickComboBox::indicator() const
{
- Q_D(const QQuickComboBox);
+ QQuickComboBoxPrivate *d = const_cast<QQuickComboBoxPrivate *>(d_func());
+ if (!d->indicator)
+ d->executeIndicator();
return d->indicator;
}
@@ -1012,13 +1048,14 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator)
if (d->indicator == indicator)
return;
- QQuickControlPrivate::destroyDelegate(d->indicator, this);
+ delete d->indicator;
d->indicator = indicator;
if (indicator) {
if (!indicator->parentItem())
indicator->setParentItem(this);
}
- emit indicatorChanged();
+ if (!d->indicator.isExecuting())
+ emit indicatorChanged();
}
/*!
@@ -1036,7 +1073,9 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator)
*/
QQuickPopup *QQuickComboBox::popup() const
{
- Q_D(const QQuickComboBox);
+ QQuickComboBoxPrivate *d = const_cast<QQuickComboBoxPrivate *>(d_func());
+ if (!d->popup)
+ d->executePopup(isComponentComplete());
return d->popup;
}
@@ -1047,8 +1086,8 @@ void QQuickComboBox::setPopup(QQuickPopup *popup)
return;
if (d->popup) {
- QObjectPrivate::disconnect(d->popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged);
- QQuickControlPrivate::destroyDelegate(d->popup, this);
+ QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged);
+ delete d->popup;
}
if (popup) {
QQuickPopupPrivate::get(popup)->allowVerticalFlip = true;
@@ -1059,7 +1098,8 @@ void QQuickComboBox::setPopup(QQuickPopup *popup)
itemView->setHighlightRangeMode(QQuickItemView::NoHighlightRange);
}
d->popup = popup;
- emit popupChanged();
+ if (!d->popup.isExecuting())
+ emit popupChanged();
}
/*!
@@ -1537,9 +1577,8 @@ void QQuickComboBox::keyReleaseEvent(QKeyEvent *event)
{
Q_D(QQuickComboBox);
QQuickControl::keyReleaseEvent(event);
-
d->keyNavigating = false;
- if (!d->popup || event->isAutoRepeat())
+ if (event->isAutoRepeat())
return;
switch (event->key()) {
@@ -1586,6 +1625,9 @@ void QQuickComboBox::wheelEvent(QWheelEvent *event)
void QQuickComboBox::componentComplete()
{
Q_D(QQuickComboBox);
+ d->executeIndicator(true);
+ if (d->popup)
+ d->executePopup(true);
QQuickControl::componentComplete();
if (d->delegateModel && d->ownModel)
diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h
index dd1e1d4f..ee926daf 100644
--- a/src/quicktemplates2/qquickcombobox_p.h
+++ b/src/quicktemplates2/qquickcombobox_p.h
@@ -82,6 +82,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickComboBox : public QQuickControl
Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints NOTIFY inputMethodHintsChanged FINAL REVISION 2)
Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged FINAL REVISION 2)
Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged FINAL REVISION 2)
+ Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,indicator,popup")
public:
explicit QQuickComboBox(QQuickItem *parent = nullptr);
diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp
index 07fe04d2..048cfdfa 100644
--- a/src/quicktemplates2/qquickcontainer.cpp
+++ b/src/quicktemplates2/qquickcontainer.cpp
@@ -634,6 +634,9 @@ QVariant QQuickContainer::contentModel() const
*/
QQmlListProperty<QObject> QQuickContainer::contentData()
{
+ Q_D(QQuickContainer);
+ if (!d->contentItem)
+ d->executeContentItem();
return QQmlListProperty<QObject>(this, nullptr,
QQuickContainerPrivate::contentData_append,
QQuickContainerPrivate::contentData_count,
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index 1db8932b..76d6a688 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -48,6 +48,7 @@
#include "qquickpopup_p.h"
#include "qquickpopupitem_p_p.h"
#include "qquickapplicationwindow_p.h"
+#include "qquickdeferredexecute_p_p.h"
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qpa/qplatformtheme.h>
@@ -279,6 +280,8 @@ void QQuickControlPrivate::resizeContent()
QQuickItem *QQuickControlPrivate::getContentItem()
{
+ if (!contentItem)
+ executeContentItem();
return contentItem;
}
@@ -289,7 +292,7 @@ void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify)
return;
q->contentItemChange(item, contentItem);
- destroyDelegate(contentItem, q);
+ delete contentItem;
contentItem = item;
if (item) {
@@ -299,7 +302,7 @@ void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify)
resizeContent();
}
- if (notify)
+ if (notify && !contentItem.isExecuting())
emit q->contentItemChanged();
}
@@ -644,6 +647,34 @@ bool QQuickControlPrivate::calcHoverEnabled(const QQuickItem *item)
}
#endif
+static inline QString contentItemName() { return QStringLiteral("contentItem"); }
+
+void QQuickControlPrivate::executeContentItem(bool complete)
+{
+ Q_Q(QQuickControl);
+ if (contentItem.wasExecuted())
+ return;
+
+ if (!contentItem)
+ quickBeginDeferred(q, contentItemName(), contentItem);
+ if (complete)
+ quickCompleteDeferred(q, contentItemName(), contentItem);
+}
+
+static inline QString backgroundName() { return QStringLiteral("background"); }
+
+void QQuickControlPrivate::executeBackground(bool complete)
+{
+ Q_Q(QQuickControl);
+ if (background.wasExecuted())
+ return;
+
+ if (!background)
+ quickBeginDeferred(q, backgroundName(), background);
+ if (complete)
+ quickCompleteDeferred(q, backgroundName(), background);
+}
+
/*
Cancels incubation recursively to avoid "Object destroyed during incubation" (QTBUG-50992)
*/
@@ -1270,7 +1301,9 @@ void QQuickControl::setWheelEnabled(bool enabled)
*/
QQuickItem *QQuickControl::background() const
{
- Q_D(const QQuickControl);
+ QQuickControlPrivate *d = const_cast<QQuickControlPrivate *>(d_func());
+ if (!d->background)
+ d->executeBackground();
return d->background;
}
@@ -1280,7 +1313,7 @@ void QQuickControl::setBackground(QQuickItem *background)
if (d->background == background)
return;
- QQuickControlPrivate::destroyDelegate(d->background, this);
+ delete d->background;
d->background = background;
if (background) {
background->setParentItem(this);
@@ -1289,7 +1322,8 @@ void QQuickControl::setBackground(QQuickItem *background)
if (isComponentComplete())
d->resizeBackground();
}
- emit backgroundChanged();
+ if (!d->background.isExecuting())
+ emit backgroundChanged();
}
/*!
@@ -1414,6 +1448,8 @@ void QQuickControl::classBegin()
void QQuickControl::componentComplete()
{
Q_D(QQuickControl);
+ d->executeBackground(true);
+ d->executeContentItem(true);
QQuickItem::componentComplete();
d->resizeContent();
if (!d->hasLocale)
diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h
index 7dd1deb3..6b2d48d6 100644
--- a/src/quicktemplates2/qquickcontrol_p.h
+++ b/src/quicktemplates2/qquickcontrol_p.h
@@ -81,6 +81,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControl : public QQuickItem
Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL)
// 2.3 (Qt 5.10)
Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3)
+ Q_CLASSINFO("DeferredPropertyNames", "background,contentItem")
public:
explicit QQuickControl(QQuickItem *parent = nullptr);
diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h
index e7e9d46f..f159c96d 100644
--- a/src/quicktemplates2/qquickcontrol_p_p.h
+++ b/src/quicktemplates2/qquickcontrol_p_p.h
@@ -49,6 +49,7 @@
//
#include <QtQuickTemplates2/private/qquickcontrol_p.h>
+#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQml/private/qlazilyallocated_p.h>
@@ -139,6 +140,9 @@ public:
static bool calcHoverEnabled(const QQuickItem *item);
#endif
+ void executeContentItem(bool complete = false);
+ void executeBackground(bool complete = false);
+
static void destroyDelegate(QObject *object, QObject *parent);
struct ExtraData {
@@ -170,8 +174,8 @@ public:
QPalette resolvedPalette;
Qt::FocusPolicy focusPolicy;
Qt::FocusReason focusReason;
- QQuickItem *background;
- QQuickItem *contentItem;
+ QQuickDeferredPointer<QQuickItem> background;
+ QQuickDeferredPointer<QQuickItem> contentItem;
};
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickdeferredexecute.cpp b/src/quicktemplates2/qquickdeferredexecute.cpp
new file mode 100644
index 00000000..802ed3d0
--- /dev/null
+++ b/src/quicktemplates2/qquickdeferredexecute.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** 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 "qquickdeferredexecute_p_p.h"
+
+#include <QtCore/qhash.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/private/qqmldata_p.h>
+#include <QtQml/private/qqmlcomponent_p.h>
+#include <QtQml/private/qqmlobjectcreator_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtQuickPrivate {
+
+typedef QHash<uint, QQmlComponentPrivate::DeferredState *> DeferredStates;
+
+static inline uint qHash(QObject *object, const QString &propertyName)
+{
+ return ::qHash(object) + ::qHash(propertyName);
+}
+
+Q_GLOBAL_STATIC(DeferredStates, deferredStates)
+
+static void beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &property, QQmlComponentPrivate::DeferredState *deferredState)
+{
+ QObject *object = property.object();
+ QQmlData *ddata = QQmlData::get(object);
+ Q_ASSERT(!ddata->deferredData.isEmpty());
+
+ int propertyIndex = property.index();
+
+ for (auto dit = ddata->deferredData.rbegin(); dit != ddata->deferredData.rend(); ++dit) {
+ QQmlData::DeferredData *deferData = *dit;
+
+ auto range = deferData->bindings.equal_range(propertyIndex);
+ if (range.first == deferData->bindings.end())
+ continue;
+
+ QQmlComponentPrivate::ConstructionState *state = new QQmlComponentPrivate::ConstructionState;
+ state->completePending = true;
+
+ QQmlContextData *creationContext = nullptr;
+ state->creator.reset(new QQmlObjectCreator(deferData->context->parent, deferData->compilationUnit, creationContext));
+
+ enginePriv->inProgressCreations++;
+
+ typedef QMultiHash<int, const QV4::CompiledData::Binding *> QV4PropertyBindingHash;
+ auto it = std::reverse_iterator<QV4PropertyBindingHash::iterator>(range.second);
+ auto last = std::reverse_iterator<QV4PropertyBindingHash::iterator>(range.first);
+ while (it != last) {
+ if (!state->creator->populateDeferredBinding(property, deferData, *it))
+ state->errors << state->creator->errors;
+ ++it;
+ }
+
+ deferredState->constructionStates += state;
+
+ // Cleanup any remaining deferred bindings for this property, also in inner contexts,
+ // to avoid executing them later and overriding the property that was just populated.
+ while (dit != ddata->deferredData.rend()) {
+ (*dit)->bindings.remove(propertyIndex);
+ ++dit;
+ }
+ break;
+ }
+}
+
+void beginDeferred(QObject *object, const QString &property)
+{
+ QQmlData *data = QQmlData::get(object);
+ if (data && !data->deferredData.isEmpty() && !data->wasDeleted(object)) {
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine);
+
+ QQmlComponentPrivate::DeferredState *state = new QQmlComponentPrivate::DeferredState;
+ beginDeferred(ep, QQmlProperty(object, property), state);
+
+ // Release deferred data for those compilation units that no longer have deferred bindings
+ data->releaseDeferredData();
+
+ deferredStates()->insert(qHash(object, property), state);
+ }
+}
+
+void completeDeferred(QObject *object, const QString &property)
+{
+ QQmlData *data = QQmlData::get(object);
+ QQmlComponentPrivate::DeferredState *state = deferredStates()->take(qHash(object, property));
+ if (data && state && !data->wasDeleted(object)) {
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine);
+ QQmlComponentPrivate::completeDeferred(ep, state);
+ }
+ delete state;
+}
+
+} // QtQuickPrivate
+
+QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickdeferredexecute_p_p.h b/src/quicktemplates2/qquickdeferredexecute_p_p.h
new file mode 100644
index 00000000..87124e48
--- /dev/null
+++ b/src/quicktemplates2/qquickdeferredexecute_p_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QQUICKDEFERREDEXECUTE_P_P_H
+#define QQUICKDEFERREDEXECUTE_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+class QObject;
+
+namespace QtQuickPrivate {
+ void beginDeferred(QObject *object, const QString &property);
+ void completeDeferred(QObject *object, const QString &property);
+}
+
+template<typename T>
+void quickBeginDeferred(QObject *object, const QString &property, QQuickDeferredPointer<T> &delegate)
+{
+ Q_ASSERT(delegate.isNull());
+ delegate.setExecuting(true);
+ QtQuickPrivate::beginDeferred(object, property);
+ delegate.setExecuting(false);
+}
+
+template<typename T>
+void quickCompleteDeferred(QObject *object, const QString &property, QQuickDeferredPointer<T> &delegate)
+{
+ Q_ASSERT(!delegate.wasExecuted());
+ delegate.setExecuting(true);
+ QtQuickPrivate::completeDeferred(object, property);
+ delegate.setExecuting(false);
+ delegate.setExecuted();
+}
+
+QT_END_NAMESPACE
+
+#endif // QQUICKDEFERREDEXECUTE_P_P_H
diff --git a/src/quicktemplates2/qquickdeferredpointer_p_p.h b/src/quicktemplates2/qquickdeferredpointer_p_p.h
new file mode 100644
index 00000000..c793964f
--- /dev/null
+++ b/src/quicktemplates2/qquickdeferredpointer_p_p.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QQUICKDEFERREDPOINTER_P_P_H
+#define QQUICKDEFERREDPOINTER_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+template<typename T>
+class QQuickDeferredPointer
+{
+public:
+ inline QQuickDeferredPointer();
+ inline QQuickDeferredPointer(T *);
+ inline QQuickDeferredPointer(const QQuickDeferredPointer<T> &o);
+
+ inline bool isNull() const;
+
+ inline bool wasExecuted() const;
+ inline void setExecuted();
+
+ inline bool isExecuting() const;
+ inline void setExecuting(bool);
+
+ inline operator T*() const;
+ inline operator bool() const;
+
+ inline T *data() const;
+ inline T *operator*() const;
+ inline T *operator->() const;
+
+ inline QQuickDeferredPointer<T> &operator=(T *);
+ inline QQuickDeferredPointer<T> &operator=(const QQuickDeferredPointer &o);
+
+private:
+ quintptr ptr_value;
+
+ static const quintptr WasExecutedBit = 0x1;
+ static const quintptr IsExecutingBit = 0x2;
+ static const quintptr FlagsMask = WasExecutedBit | IsExecutingBit;
+};
+
+template<typename T>
+QQuickDeferredPointer<T>::QQuickDeferredPointer()
+: ptr_value(0)
+{
+}
+
+template<typename T>
+QQuickDeferredPointer<T>::QQuickDeferredPointer(T *v)
+: ptr_value(quintptr(v))
+{
+ Q_ASSERT((ptr_value & FlagsMask) == 0);
+}
+
+template<typename T>
+QQuickDeferredPointer<T>::QQuickDeferredPointer(const QQuickDeferredPointer<T> &o)
+: ptr_value(o.ptr_value)
+{
+}
+
+template<typename T>
+bool QQuickDeferredPointer<T>::isNull() const
+{
+ return 0 == (ptr_value & (~FlagsMask));
+}
+
+template<typename T>
+bool QQuickDeferredPointer<T>::wasExecuted() const
+{
+ return ptr_value & WasExecutedBit;
+}
+
+template<typename T>
+void QQuickDeferredPointer<T>::setExecuted()
+{
+ ptr_value |= WasExecutedBit;
+}
+
+template<typename T>
+bool QQuickDeferredPointer<T>::isExecuting() const
+{
+ return ptr_value & IsExecutingBit;
+}
+
+template<typename T>
+void QQuickDeferredPointer<T>::setExecuting(bool b)
+{
+ if (b)
+ ptr_value |= IsExecutingBit;
+ else
+ ptr_value &= ~IsExecutingBit;
+}
+
+template<typename T>
+QQuickDeferredPointer<T>::operator T*() const
+{
+ return data();
+}
+
+template<typename T>
+QQuickDeferredPointer<T>::operator bool() const
+{
+ return !isNull();
+}
+
+template<typename T>
+T *QQuickDeferredPointer<T>::data() const
+{
+ return (T *)(ptr_value & ~FlagsMask);
+}
+
+template<typename T>
+T *QQuickDeferredPointer<T>::operator*() const
+{
+ return (T *)(ptr_value & ~FlagsMask);
+}
+
+template<typename T>
+T *QQuickDeferredPointer<T>::operator->() const
+{
+ return (T *)(ptr_value & ~FlagsMask);
+}
+
+template<typename T>
+QQuickDeferredPointer<T> &QQuickDeferredPointer<T>::operator=(T *o)
+{
+ Q_ASSERT((quintptr(o) & FlagsMask) == 0);
+
+ ptr_value = quintptr(o) | (ptr_value & FlagsMask);
+ return *this;
+}
+
+template<typename T>
+QQuickDeferredPointer<T> &QQuickDeferredPointer<T>::operator=(const QQuickDeferredPointer &o)
+{
+ ptr_value = o.ptr_value;
+ return *this;
+}
+
+QT_END_NAMESPACE
+
+#endif // QQUICKDEFERREDPOINTER_P_P_H
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
index c0e2c8ed..964cefe1 100644
--- a/src/quicktemplates2/qquickdial.cpp
+++ b/src/quicktemplates2/qquickdial.cpp
@@ -35,6 +35,7 @@
****************************************************************************/
#include "qquickdial_p.h"
+#include "qquickdeferredexecute_p_p.h"
#include <QtCore/qmath.h>
#include <QtQuick/private/qquickflickable_p.h>
@@ -122,6 +123,8 @@ public:
void handleRelease(const QPointF &point) override;
void handleUngrab() override;
+ void executeHandle(bool complete = false);
+
qreal from;
qreal to;
qreal value;
@@ -133,7 +136,7 @@ public:
QQuickDial::SnapMode snapMode;
bool wrap;
bool live;
- QQuickItem *handle;
+ QQuickDeferredPointer<QQuickItem> handle;
};
qreal QQuickDialPrivate::valueAt(qreal position) const
@@ -253,6 +256,20 @@ void QQuickDialPrivate::handleUngrab()
q->setPressed(false);
}
+static inline QString handleName() { return QStringLiteral("handle"); }
+
+void QQuickDialPrivate::executeHandle(bool complete)
+{
+ Q_Q(QQuickDial);
+ if (handle.wasExecuted())
+ return;
+
+ if (!handle)
+ quickBeginDeferred(q, handleName(), handle);
+ if (complete)
+ quickCompleteDeferred(q, handleName(), handle);
+}
+
QQuickDial::QQuickDial(QQuickItem *parent)
: QQuickControl(*(new QQuickDialPrivate), parent)
{
@@ -524,7 +541,9 @@ void QQuickDial::setPressed(bool pressed)
*/
QQuickItem *QQuickDial::handle() const
{
- Q_D(const QQuickDial);
+ QQuickDialPrivate *d = const_cast<QQuickDialPrivate *>(d_func());
+ if (!d->handle)
+ d->executeHandle();
return d->handle;
}
@@ -534,11 +553,12 @@ void QQuickDial::setHandle(QQuickItem *handle)
if (handle == d->handle)
return;
- QQuickControlPrivate::destroyDelegate(d->handle, this);
+ delete d->handle;
d->handle = handle;
if (d->handle && !d->handle->parentItem())
d->handle->setParentItem(this);
- emit handleChanged();
+ if (!d->handle.isExecuting())
+ emit handleChanged();
}
/*!
@@ -730,6 +750,7 @@ void QQuickDial::mirrorChange()
void QQuickDial::componentComplete()
{
Q_D(QQuickDial);
+ d->executeHandle(true);
QQuickControl::componentComplete();
setValue(d->value);
d->updatePosition();
diff --git a/src/quicktemplates2/qquickdial_p.h b/src/quicktemplates2/qquickdial_p.h
index 296f7986..d7bab0ad 100644
--- a/src/quicktemplates2/qquickdial_p.h
+++ b/src/quicktemplates2/qquickdial_p.h
@@ -72,6 +72,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDial : public QQuickControl
Q_PROPERTY(QQuickItem *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL)
// 2.2 (Qt 5.9)
Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION 2)
+ Q_CLASSINFO("DeferredPropertyNames", "background,handle")
public:
explicit QQuickDial(QQuickItem *parent = nullptr);
diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp
index c227afdc..c127192c 100644
--- a/src/quicktemplates2/qquickgroupbox.cpp
+++ b/src/quicktemplates2/qquickgroupbox.cpp
@@ -36,6 +36,7 @@
#include "qquickgroupbox_p.h"
#include "qquickframe_p_p.h"
+#include "qquickdeferredexecute_p_p.h"
#include <QtGui/qpa/qplatformtheme.h>
@@ -85,13 +86,31 @@ QT_BEGIN_NAMESPACE
class QQuickGroupBoxPrivate : public QQuickFramePrivate
{
+ Q_DECLARE_PUBLIC(QQuickGroupBox)
+
public:
QQuickGroupBoxPrivate() : label(nullptr) { }
+ void executeLabel(bool complete = false);
+
QString title;
- QQuickItem *label;
+ QQuickDeferredPointer<QQuickItem> label;
};
+static inline QString labelName() { return QStringLiteral("label"); }
+
+void QQuickGroupBoxPrivate::executeLabel(bool complete)
+{
+ Q_Q(QQuickGroupBox);
+ if (label.wasExecuted())
+ return;
+
+ if (!label)
+ quickBeginDeferred(q, labelName(), label);
+ if (complete)
+ quickCompleteDeferred(q, labelName(), label);
+}
+
QQuickGroupBox::QQuickGroupBox(QQuickItem *parent)
: QQuickFrame(*(new QQuickGroupBoxPrivate), parent)
{
@@ -131,7 +150,9 @@ void QQuickGroupBox::setTitle(const QString &title)
*/
QQuickItem *QQuickGroupBox::label() const
{
- Q_D(const QQuickGroupBox);
+ QQuickGroupBoxPrivate *d = const_cast<QQuickGroupBoxPrivate *>(d_func());
+ if (!d->label)
+ d->executeLabel();
return d->label;
}
@@ -141,11 +162,19 @@ void QQuickGroupBox::setLabel(QQuickItem *label)
if (d->label == label)
return;
- QQuickControlPrivate::destroyDelegate(d->label, this);
+ delete d->label;
d->label = label;
if (label && !label->parentItem())
label->setParentItem(this);
- emit labelChanged();
+ if (!d->label.isExecuting())
+ emit labelChanged();
+}
+
+void QQuickGroupBox::componentComplete()
+{
+ Q_D(QQuickGroupBox);
+ d->executeLabel(true);
+ QQuickFrame::componentComplete();
}
QFont QQuickGroupBox::defaultFont() const
diff --git a/src/quicktemplates2/qquickgroupbox_p.h b/src/quicktemplates2/qquickgroupbox_p.h
index b74389e4..b46d91fd 100644
--- a/src/quicktemplates2/qquickgroupbox_p.h
+++ b/src/quicktemplates2/qquickgroupbox_p.h
@@ -59,6 +59,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickGroupBox : public QQuickFrame
Q_OBJECT
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL)
Q_PROPERTY(QQuickItem *label READ label WRITE setLabel NOTIFY labelChanged FINAL)
+ Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,label")
public:
explicit QQuickGroupBox(QQuickItem *parent = nullptr);
@@ -74,6 +75,8 @@ Q_SIGNALS:
void labelChanged();
protected:
+ void componentComplete() override;
+
QFont defaultFont() const override;
QPalette defaultPalette() const override;
diff --git a/src/quicktemplates2/qquicklabel.cpp b/src/quicktemplates2/qquicklabel.cpp
index 724fd086..d27393ae 100644
--- a/src/quicktemplates2/qquicklabel.cpp
+++ b/src/quicktemplates2/qquicklabel.cpp
@@ -38,6 +38,7 @@
#include "qquicklabel_p_p.h"
#include "qquickcontrol_p.h"
#include "qquickcontrol_p_p.h"
+#include "qquickdeferredexecute_p_p.h"
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquicktext_p.h>
@@ -202,6 +203,20 @@ QAccessible::Role QQuickLabelPrivate::accessibleRole() const
}
#endif
+static inline QString backgroundName() { return QStringLiteral("background"); }
+
+void QQuickLabelPrivate::executeBackground(bool complete)
+{
+ Q_Q(QQuickLabel);
+ if (background.wasExecuted())
+ return;
+
+ if (!background)
+ quickBeginDeferred(q, backgroundName(), background);
+ if (complete)
+ quickCompleteDeferred(q, backgroundName(), background);
+}
+
QQuickLabel::QQuickLabel(QQuickItem *parent)
: QQuickText(*(new QQuickLabelPrivate), parent)
{
@@ -237,7 +252,9 @@ void QQuickLabel::setFont(const QFont &font)
*/
QQuickItem *QQuickLabel::background() const
{
- Q_D(const QQuickLabel);
+ QQuickLabelPrivate *d = const_cast<QQuickLabelPrivate *>(d_func());
+ if (!d->background)
+ d->executeBackground();
return d->background;
}
@@ -247,14 +264,15 @@ void QQuickLabel::setBackground(QQuickItem *background)
if (d->background == background)
return;
- QQuickControlPrivate::destroyDelegate(d->background, this);
+ delete d->background;
d->background = background;
if (background) {
background->setParentItem(this);
if (qFuzzyIsNull(background->z()))
background->setZ(-1);
}
- emit backgroundChanged();
+ if (!d->background.isExecuting())
+ emit backgroundChanged();
}
/*!
@@ -300,6 +318,7 @@ void QQuickLabel::classBegin()
void QQuickLabel::componentComplete()
{
Q_D(QQuickLabel);
+ d->executeBackground(true);
QQuickText::componentComplete();
#if QT_CONFIG(accessibility)
if (QAccessible::isActive())
diff --git a/src/quicktemplates2/qquicklabel_p.h b/src/quicktemplates2/qquicklabel_p.h
index 937c57eb..5486d311 100644
--- a/src/quicktemplates2/qquicklabel_p.h
+++ b/src/quicktemplates2/qquicklabel_p.h
@@ -63,6 +63,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickLabel : public QQuickText
Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL)
// 2.3 (Qt 5.10)
Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3)
+ Q_CLASSINFO("DeferredPropertyNames", "background")
public:
explicit QQuickLabel(QQuickItem *parent = nullptr);
diff --git a/src/quicktemplates2/qquicklabel_p_p.h b/src/quicktemplates2/qquicklabel_p_p.h
index a8214d77..5f432a22 100644
--- a/src/quicktemplates2/qquicklabel_p_p.h
+++ b/src/quicktemplates2/qquicklabel_p_p.h
@@ -50,6 +50,7 @@
#include <QtQml/private/qlazilyallocated_p.h>
#include <QtQuick/private/qquicktext_p_p.h>
+#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h>
#if QT_CONFIG(accessibility)
#include <QtGui/qaccessible.h>
@@ -98,6 +99,8 @@ public:
QAccessible::Role accessibleRole() const override;
#endif
+ void executeBackground(bool complete = false);
+
struct ExtraData {
QFont requestedFont;
QPalette requestedPalette;
@@ -105,7 +108,7 @@ public:
QLazilyAllocated<ExtraData> extra;
QPalette resolvedPalette;
- QQuickItem *background;
+ QQuickDeferredPointer<QQuickItem> background;
};
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp
index 50050df3..907b01e9 100644
--- a/src/quicktemplates2/qquickpage.cpp
+++ b/src/quicktemplates2/qquickpage.cpp
@@ -106,9 +106,9 @@ QQuickPagePrivate::QQuickPagePrivate()
QQuickItem *QQuickPagePrivate::getContentItem()
{
Q_Q(QQuickPage);
- if (!contentItem)
- return new QQuickItem(q);
- return contentItem;
+ if (QQuickItem *item = QQuickControlPrivate::getContentItem())
+ return item;
+ return new QQuickItem(q);
}
QQuickPage::QQuickPage(QQuickItem *parent)
diff --git a/src/quicktemplates2/qquickpane.cpp b/src/quicktemplates2/qquickpane.cpp
index b89131c4..4c3e1422 100644
--- a/src/quicktemplates2/qquickpane.cpp
+++ b/src/quicktemplates2/qquickpane.cpp
@@ -113,9 +113,9 @@ QQuickPanePrivate::QQuickPanePrivate()
QQuickItem *QQuickPanePrivate::getContentItem()
{
Q_Q(QQuickPane);
- if (!contentItem)
- return new QQuickItem(q);
- return contentItem;
+ if (QQuickItem *item = QQuickControlPrivate::getContentItem())
+ return item;
+ return new QQuickItem(q);
}
QQuickPane::QQuickPane(QQuickItem *parent)
diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp
index 27528f2f..af4d03a4 100644
--- a/src/quicktemplates2/qquickpopupitem.cpp
+++ b/src/quicktemplates2/qquickpopupitem.cpp
@@ -104,9 +104,9 @@ void QQuickPopupItemPrivate::resolvePalette()
QQuickItem *QQuickPopupItemPrivate::getContentItem()
{
Q_Q(QQuickPopupItem);
- if (!contentItem)
- return new QQuickItem(q);
- return contentItem;
+ if (QQuickItem *item = QQuickControlPrivate::getContentItem())
+ return item;
+ return new QQuickItem(q);
}
QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup)
diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp
index d16cd3b4..937de9c9 100644
--- a/src/quicktemplates2/qquickrangeslider.cpp
+++ b/src/quicktemplates2/qquickrangeslider.cpp
@@ -36,6 +36,7 @@
#include "qquickrangeslider_p.h"
#include "qquickcontrol_p_p.h"
+#include "qquickdeferredexecute_p_p.h"
#include <QtCore/qscopedpointer.h>
#include <QtQuick/private/qquickwindow_p.h>
@@ -109,13 +110,15 @@ public:
void setPosition(qreal position, bool ignoreOtherPosition = false);
void updatePosition(bool ignoreOtherPosition = false);
+ void executeHandle(bool complete = false);
+
static QQuickRangeSliderNodePrivate *get(QQuickRangeSliderNode *node);
qreal value;
bool isPendingValue;
qreal pendingValue;
qreal position;
- QQuickItem *handle;
+ QQuickDeferredPointer<QQuickItem> handle;
QQuickRangeSlider *slider;
bool pressed;
bool hovered;
@@ -149,6 +152,20 @@ void QQuickRangeSliderNodePrivate::updatePosition(bool ignoreOtherPosition)
setPosition(pos, ignoreOtherPosition);
}
+static inline QString handleName() { return QStringLiteral("handle"); }
+
+void QQuickRangeSliderNodePrivate::executeHandle(bool complete)
+{
+ Q_Q(QQuickRangeSliderNode);
+ if (handle.wasExecuted())
+ return;
+
+ if (!handle)
+ quickBeginDeferred(q, handleName(), handle);
+ if (complete)
+ quickCompleteDeferred(q, handleName(), handle);
+}
+
QQuickRangeSliderNodePrivate *QQuickRangeSliderNodePrivate::get(QQuickRangeSliderNode *node)
{
return node->d_func();
@@ -227,7 +244,9 @@ qreal QQuickRangeSliderNode::visualPosition() const
QQuickItem *QQuickRangeSliderNode::handle() const
{
- Q_D(const QQuickRangeSliderNode);
+ QQuickRangeSliderNodePrivate *d = const_cast<QQuickRangeSliderNodePrivate *>(d_func());
+ if (!d->handle)
+ d->executeHandle();
return d->handle;
}
@@ -237,7 +256,7 @@ void QQuickRangeSliderNode::setHandle(QQuickItem *handle)
if (d->handle == handle)
return;
- QQuickControlPrivate::destroyDelegate(d->handle, d->slider);
+ delete d->handle;
d->handle = handle;
if (handle) {
if (!handle->parentItem())
@@ -263,7 +282,8 @@ void QQuickRangeSliderNode::setHandle(QQuickItem *handle)
handle->setActiveFocusOnTab(true);
}
- emit handleChanged();
+ if (!d->handle.isExecuting())
+ emit handleChanged();
}
bool QQuickRangeSliderNode::isPressed() const
@@ -1077,13 +1097,27 @@ void QQuickRangeSlider::mirrorChange()
emit d->second->visualPositionChanged();
}
-void QQuickRangeSlider::componentComplete()
+void QQuickRangeSlider::classBegin()
{
Q_D(QQuickRangeSlider);
- QQuickControl::componentComplete();
+ QQuickControl::classBegin();
+ QQmlContext *context = qmlContext(this);
+ if (context) {
+ QQmlEngine::setContextForObject(d->first, context);
+ QQmlEngine::setContextForObject(d->second, context);
+ }
+}
+
+void QQuickRangeSlider::componentComplete()
+{
+ Q_D(QQuickRangeSlider);
QQuickRangeSliderNodePrivate *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first);
QQuickRangeSliderNodePrivate *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second);
+ firstPrivate->executeHandle(true);
+ secondPrivate->executeHandle(true);
+
+ QQuickControl::componentComplete();
if (firstPrivate->isPendingValue || secondPrivate->isPendingValue
|| !qFuzzyCompare(d->from, defaultFrom) || !qFuzzyCompare(d->to, defaultTo)) {
diff --git a/src/quicktemplates2/qquickrangeslider_p.h b/src/quicktemplates2/qquickrangeslider_p.h
index ef6e5677..a6326441 100644
--- a/src/quicktemplates2/qquickrangeslider_p.h
+++ b/src/quicktemplates2/qquickrangeslider_p.h
@@ -131,6 +131,7 @@ protected:
void touchEvent(QTouchEvent *event) override;
#endif
void mirrorChange() override;
+ void classBegin() override;
void componentComplete() override;
#if QT_CONFIG(accessibility)
@@ -156,6 +157,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRangeSliderNode : public QObject
Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL)
// 2.1 (Qt 5.8)
Q_PROPERTY(bool hovered READ isHovered WRITE setHovered NOTIFY hoveredChanged FINAL REVISION 1)
+ Q_CLASSINFO("DeferredPropertyNames", "handle")
public:
explicit QQuickRangeSliderNode(qreal value, QQuickRangeSlider *slider);
diff --git a/src/quicktemplates2/qquickscrollview.cpp b/src/quicktemplates2/qquickscrollview.cpp
index fa9a6c3b..254a90d7 100644
--- a/src/quicktemplates2/qquickscrollview.cpp
+++ b/src/quicktemplates2/qquickscrollview.cpp
@@ -146,6 +146,8 @@ QQuickScrollViewPrivate::QQuickScrollViewPrivate()
QQuickItem *QQuickScrollViewPrivate::getContentItem()
{
+ if (!contentItem)
+ executeContentItem();
return ensureFlickable(false);
}
diff --git a/src/quicktemplates2/qquickshortcutcontext.cpp b/src/quicktemplates2/qquickshortcutcontext.cpp
index b44c723b..b491cab2 100644
--- a/src/quicktemplates2/qquickshortcutcontext.cpp
+++ b/src/quicktemplates2/qquickshortcutcontext.cpp
@@ -42,6 +42,7 @@
#include "qquickmenubaritem_p.h"
#include <QtGui/qguiapplication.h>
+#include <QtQuick/qquickrendercontrol.h>
QT_BEGIN_NAMESPACE
@@ -84,6 +85,8 @@ bool QQuickShortcutContext::matcher(QObject *obj, Qt::ShortcutContext context)
item = popup->popupItem();
}
}
+ if (QWindow *renderWindow = QQuickRenderControl::renderWindowFor(qobject_cast<QQuickWindow *>(obj)))
+ obj = renderWindow;
return obj && obj == QGuiApplication::focusWindow() && !isBlockedByPopup(item);
default:
return false;
diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp
index b358663d..21aeda39 100644
--- a/src/quicktemplates2/qquickslider.cpp
+++ b/src/quicktemplates2/qquickslider.cpp
@@ -36,6 +36,7 @@
#include "qquickslider_p.h"
#include "qquickcontrol_p_p.h"
+#include "qquickdeferredexecute_p_p.h"
#include <QtQuick/private/qquickwindow_p.h>
@@ -112,6 +113,8 @@ public:
void handleRelease(const QPointF &point) override;
void handleUngrab() override;
+ void executeHandle(bool complete = false);
+
qreal from;
qreal to;
qreal value;
@@ -122,7 +125,7 @@ public:
QPointF pressPoint;
Qt::Orientation orientation;
QQuickSlider::SnapMode snapMode;
- QQuickItem *handle;
+ QQuickDeferredPointer<QQuickItem> handle;
};
qreal QQuickSliderPrivate::snapPosition(qreal position) const
@@ -235,6 +238,20 @@ void QQuickSliderPrivate::handleUngrab()
q->setPressed(false);
}
+static inline QString handleName() { return QStringLiteral("handle"); }
+
+void QQuickSliderPrivate::executeHandle(bool complete)
+{
+ Q_Q(QQuickSlider);
+ if (handle.wasExecuted())
+ return;
+
+ if (!handle)
+ quickBeginDeferred(q, handleName(), handle);
+ if (complete)
+ quickCompleteDeferred(q, handleName(), handle);
+}
+
QQuickSlider::QQuickSlider(QQuickItem *parent)
: QQuickControl(*(new QQuickSliderPrivate), parent)
{
@@ -517,7 +534,9 @@ void QQuickSlider::setOrientation(Qt::Orientation orientation)
*/
QQuickItem *QQuickSlider::handle() const
{
- Q_D(const QQuickSlider);
+ QQuickSliderPrivate *d = const_cast<QQuickSliderPrivate *>(d_func());
+ if (!d->handle)
+ d->executeHandle();
return d->handle;
}
@@ -527,11 +546,12 @@ void QQuickSlider::setHandle(QQuickItem *handle)
if (d->handle == handle)
return;
- QQuickControlPrivate::destroyDelegate(d->handle, this);
+ delete d->handle;
d->handle = handle;
if (handle && !handle->parentItem())
handle->setParentItem(this);
- emit handleChanged();
+ if (!d->handle.isExecuting())
+ emit handleChanged();
}
/*!
@@ -736,6 +756,7 @@ void QQuickSlider::mirrorChange()
void QQuickSlider::componentComplete()
{
Q_D(QQuickSlider);
+ d->executeHandle(true);
QQuickControl::componentComplete();
setValue(d->value);
d->updatePosition();
diff --git a/src/quicktemplates2/qquickslider_p.h b/src/quicktemplates2/qquickslider_p.h
index b2f4897c..95545462 100644
--- a/src/quicktemplates2/qquickslider_p.h
+++ b/src/quicktemplates2/qquickslider_p.h
@@ -71,6 +71,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSlider : public QQuickControl
// 2.3 (Qt 5.10)
Q_PROPERTY(bool horizontal READ isHorizontal NOTIFY orientationChanged FINAL REVISION 3)
Q_PROPERTY(bool vertical READ isVertical NOTIFY orientationChanged FINAL REVISION 3)
+ Q_CLASSINFO("DeferredPropertyNames", "background,handle")
public:
explicit QQuickSlider(QQuickItem *parent = nullptr);
diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp
index ef1c9d97..27dd0d5e 100644
--- a/src/quicktemplates2/qquickspinbox.cpp
+++ b/src/quicktemplates2/qquickspinbox.cpp
@@ -36,6 +36,7 @@
#include "qquickspinbox_p.h"
#include "qquickcontrol_p_p.h"
+#include "qquickdeferredexecute_p_p.h"
#include <QtGui/qguiapplication.h>
#include <QtGui/qstylehints.h>
@@ -162,6 +163,30 @@ public:
Qt::InputMethodHints inputMethodHints;
};
+class QQuickSpinButtonPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickSpinButton)
+
+public:
+ QQuickSpinButtonPrivate()
+ : pressed(false),
+ hovered(false),
+ indicator(nullptr)
+ {
+ }
+
+ static QQuickSpinButtonPrivate *get(QQuickSpinButton *button)
+ {
+ return button->d_func();
+ }
+
+ void executeIndicator(bool complete = false);
+
+ bool pressed;
+ bool hovered;
+ QQuickDeferredPointer<QQuickItem> indicator;
+};
+
int QQuickSpinBoxPrivate::boundValue(int value, bool wrap) const
{
bool inverted = from > to;
@@ -880,9 +905,24 @@ void QQuickSpinBox::wheelEvent(QWheelEvent *event)
}
#endif
+void QQuickSpinBox::classBegin()
+{
+ Q_D(QQuickSpinBox);
+ QQuickControl::classBegin();
+
+ QQmlContext *context = qmlContext(this);
+ if (context) {
+ QQmlEngine::setContextForObject(d->up, context);
+ QQmlEngine::setContextForObject(d->down, context);
+ }
+}
+
void QQuickSpinBox::componentComplete()
{
Q_D(QQuickSpinBox);
+ QQuickSpinButtonPrivate::get(d->up)->executeIndicator(true);
+ QQuickSpinButtonPrivate::get(d->down)->executeIndicator(true);
+
QQuickControl::componentComplete();
if (!d->setValue(d->value, /* allowWrap = */ false, /* modified = */ false)) {
d->updateUpEnabled();
@@ -906,6 +946,8 @@ void QQuickSpinBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
if (newItem) {
newItem->setActiveFocusOnTab(true);
+ if (d->activeFocus)
+ newItem->forceActiveFocus(d->focusReason);
#if QT_CONFIG(cursor)
if (d->editable)
newItem->setCursor(Qt::IBeamCursor);
@@ -942,20 +984,19 @@ void QQuickSpinBox::accessibilityActiveChanged(bool active)
}
#endif
-class QQuickSpinButtonPrivate : public QObjectPrivate
+static inline QString indicatorName() { return QStringLiteral("indicator"); }
+
+void QQuickSpinButtonPrivate::executeIndicator(bool complete)
{
-public:
- QQuickSpinButtonPrivate()
- : pressed(false),
- hovered(false),
- indicator(nullptr)
- {
- }
+ Q_Q(QQuickSpinButton);
+ if (indicator.wasExecuted())
+ return;
- bool pressed;
- bool hovered;
- QQuickItem *indicator;
-};
+ if (!indicator)
+ quickBeginDeferred(q, indicatorName(), indicator);
+ if (complete)
+ quickCompleteDeferred(q, indicatorName(), indicator);
+}
QQuickSpinButton::QQuickSpinButton(QQuickSpinBox *parent)
: QObject(*(new QQuickSpinButtonPrivate), parent)
@@ -980,7 +1021,9 @@ void QQuickSpinButton::setPressed(bool pressed)
QQuickItem *QQuickSpinButton::indicator() const
{
- Q_D(const QQuickSpinButton);
+ QQuickSpinButtonPrivate *d = const_cast<QQuickSpinButtonPrivate *>(d_func());
+ if (!d->indicator)
+ d->executeIndicator();
return d->indicator;
}
@@ -990,14 +1033,15 @@ void QQuickSpinButton::setIndicator(QQuickItem *indicator)
if (d->indicator == indicator)
return;
- QQuickControlPrivate::destroyDelegate(d->indicator, d->parent);
+ delete d->indicator;
d->indicator = indicator;
if (indicator) {
if (!indicator->parentItem())
indicator->setParentItem(static_cast<QQuickItem *>(parent()));
}
- emit indicatorChanged();
+ if (!d->indicator.isExecuting())
+ emit indicatorChanged();
}
bool QQuickSpinButton::isHovered() const
diff --git a/src/quicktemplates2/qquickspinbox_p.h b/src/quicktemplates2/qquickspinbox_p.h
index 6485c053..524930a2 100644
--- a/src/quicktemplates2/qquickspinbox_p.h
+++ b/src/quicktemplates2/qquickspinbox_p.h
@@ -149,6 +149,7 @@ protected:
void wheelEvent(QWheelEvent *event) override;
#endif
+ void classBegin() override;
void componentComplete() override;
void itemChange(ItemChange change, const ItemChangeData &value) override;
void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override;
@@ -173,6 +174,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSpinButton : public QObject
Q_PROPERTY(QQuickItem *indicator READ indicator WRITE setIndicator NOTIFY indicatorChanged FINAL)
// 2.1 (Qt 5.8)
Q_PROPERTY(bool hovered READ isHovered WRITE setHovered NOTIFY hoveredChanged FINAL REVISION 1)
+ Q_CLASSINFO("DeferredPropertyNames", "indicator")
public:
explicit QQuickSpinButton(QQuickSpinBox *parent);
diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp
index 02e84a35..d2458c24 100644
--- a/src/quicktemplates2/qquicktextarea.cpp
+++ b/src/quicktemplates2/qquicktextarea.cpp
@@ -39,6 +39,7 @@
#include "qquickcontrol_p.h"
#include "qquickcontrol_p_p.h"
#include "qquickscrollview_p.h"
+#include "qquickdeferredexecute_p_p.h"
#include <QtQml/qqmlinfo.h>
#include <QtQuick/private/qquickitem_p.h>
@@ -437,6 +438,20 @@ QAccessible::Role QQuickTextAreaPrivate::accessibleRole() const
}
#endif
+static inline QString backgroundName() { return QStringLiteral("background"); }
+
+void QQuickTextAreaPrivate::executeBackground(bool complete)
+{
+ Q_Q(QQuickTextArea);
+ if (background.wasExecuted())
+ return;
+
+ if (!background)
+ quickBeginDeferred(q, backgroundName(), background);
+ if (complete)
+ quickCompleteDeferred(q, backgroundName(), background);
+}
+
QQuickTextArea::QQuickTextArea(QQuickItem *parent)
: QQuickTextEdit(*(new QQuickTextAreaPrivate), parent)
{
@@ -490,7 +505,9 @@ void QQuickTextArea::setFont(const QFont &font)
*/
QQuickItem *QQuickTextArea::background() const
{
- Q_D(const QQuickTextArea);
+ QQuickTextAreaPrivate *d = const_cast<QQuickTextAreaPrivate *>(d_func());
+ if (!d->background)
+ d->executeBackground();
return d->background;
}
@@ -500,7 +517,7 @@ void QQuickTextArea::setBackground(QQuickItem *background)
if (d->background == background)
return;
- QQuickControlPrivate::destroyDelegate(d->background, this);
+ delete d->background;
d->background = background;
if (background) {
background->setParentItem(this);
@@ -509,7 +526,8 @@ void QQuickTextArea::setBackground(QQuickItem *background)
if (isComponentComplete())
d->resizeBackground();
}
- emit backgroundChanged();
+ if (!d->background.isExecuting())
+ emit backgroundChanged();
}
/*!
@@ -686,6 +704,7 @@ void QQuickTextArea::classBegin()
void QQuickTextArea::componentComplete()
{
Q_D(QQuickTextArea);
+ d->executeBackground(true);
QQuickTextEdit::componentComplete();
#if QT_CONFIG(quicktemplates2_hover)
if (!d->explicitHoverEnabled)
diff --git a/src/quicktemplates2/qquicktextarea_p.h b/src/quicktemplates2/qquicktextarea_p.h
index 26799532..5482ceae 100644
--- a/src/quicktemplates2/qquicktextarea_p.h
+++ b/src/quicktemplates2/qquicktextarea_p.h
@@ -73,6 +73,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextArea : public QQuickTextEdit
Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1)
// 2.3 (Qt 5.10)
Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3)
+ Q_CLASSINFO("DeferredPropertyNames", "background")
public:
explicit QQuickTextArea(QQuickItem *parent = nullptr);
diff --git a/src/quicktemplates2/qquicktextarea_p_p.h b/src/quicktemplates2/qquicktextarea_p_p.h
index 32f53c4f..d27af8f6 100644
--- a/src/quicktemplates2/qquicktextarea_p_p.h
+++ b/src/quicktemplates2/qquicktextarea_p_p.h
@@ -52,6 +52,7 @@
#include <QtQuick/private/qquicktextedit_p_p.h>
#include <QtQuick/private/qquickitemchangelistener_p.h>
#include <QtQuickTemplates2/private/qquickpresshandler_p_p.h>
+#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h>
#include <QtQuickTemplates2/private/qquicktextarea_p.h>
@@ -124,6 +125,8 @@ public:
QAccessible::Role accessibleRole() const override;
#endif
+ void executeBackground(bool complete = false);
+
#if QT_CONFIG(quicktemplates2_hover)
bool hovered;
bool explicitHoverEnabled;
@@ -136,7 +139,7 @@ public:
QLazilyAllocated<ExtraData> extra;
QPalette resolvedPalette;
- QQuickItem *background;
+ QQuickDeferredPointer<QQuickItem> background;
QString placeholder;
Qt::FocusReason focusReason;
QQuickPressHandler pressHandler;
diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp
index fba0e67c..03da9323 100644
--- a/src/quicktemplates2/qquicktextfield.cpp
+++ b/src/quicktemplates2/qquicktextfield.cpp
@@ -38,6 +38,7 @@
#include "qquicktextfield_p_p.h"
#include "qquickcontrol_p.h"
#include "qquickcontrol_p_p.h"
+#include "qquickdeferredexecute_p_p.h"
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquicktextinput_p.h>
@@ -311,6 +312,20 @@ QAccessible::Role QQuickTextFieldPrivate::accessibleRole() const
}
#endif
+static inline QString backgroundName() { return QStringLiteral("background"); }
+
+void QQuickTextFieldPrivate::executeBackground(bool complete)
+{
+ Q_Q(QQuickTextField);
+ if (background.wasExecuted())
+ return;
+
+ if (!background)
+ quickBeginDeferred(q, backgroundName(), background);
+ if (complete)
+ quickCompleteDeferred(q, backgroundName(), background);
+}
+
QQuickTextField::QQuickTextField(QQuickItem *parent)
: QQuickTextInput(*(new QQuickTextFieldPrivate), parent)
{
@@ -352,7 +367,9 @@ void QQuickTextField::setFont(const QFont &font)
*/
QQuickItem *QQuickTextField::background() const
{
- Q_D(const QQuickTextField);
+ QQuickTextFieldPrivate *d = const_cast<QQuickTextFieldPrivate *>(d_func());
+ if (!d->background)
+ d->executeBackground();
return d->background;
}
@@ -362,7 +379,7 @@ void QQuickTextField::setBackground(QQuickItem *background)
if (d->background == background)
return;
- QQuickControlPrivate::destroyDelegate(d->background, this);
+ delete d->background;
d->background = background;
if (background) {
background->setParentItem(this);
@@ -371,7 +388,8 @@ void QQuickTextField::setBackground(QQuickItem *background)
if (isComponentComplete())
d->resizeBackground();
}
- emit backgroundChanged();
+ if (!d->background.isExecuting())
+ emit backgroundChanged();
}
/*!
@@ -540,6 +558,7 @@ void QQuickTextField::classBegin()
void QQuickTextField::componentComplete()
{
Q_D(QQuickTextField);
+ d->executeBackground(true);
QQuickTextInput::componentComplete();
#if QT_CONFIG(quicktemplates2_hover)
if (!d->explicitHoverEnabled)
diff --git a/src/quicktemplates2/qquicktextfield_p.h b/src/quicktemplates2/qquicktextfield_p.h
index 7dab0caf..4757bd2d 100644
--- a/src/quicktemplates2/qquicktextfield_p.h
+++ b/src/quicktemplates2/qquicktextfield_p.h
@@ -72,6 +72,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextField : public QQuickTextInput
Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION 1)
// 2.3 (Qt 5.10)
Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3)
+ Q_CLASSINFO("DeferredPropertyNames", "background")
public:
explicit QQuickTextField(QQuickItem *parent = nullptr);
diff --git a/src/quicktemplates2/qquicktextfield_p_p.h b/src/quicktemplates2/qquicktextfield_p_p.h
index 65767452..5ae79b7f 100644
--- a/src/quicktemplates2/qquicktextfield_p_p.h
+++ b/src/quicktemplates2/qquicktextfield_p_p.h
@@ -51,6 +51,7 @@
#include <QtQml/private/qlazilyallocated_p.h>
#include <QtQuick/private/qquicktextinput_p_p.h>
#include <QtQuickTemplates2/private/qquickpresshandler_p_p.h>
+#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h>
#include <QtQuickTemplates2/private/qquicktextfield_p.h>
@@ -112,6 +113,8 @@ public:
QAccessible::Role accessibleRole() const override;
#endif
+ void executeBackground(bool complete = false);
+
#if QT_CONFIG(quicktemplates2_hover)
bool hovered;
bool explicitHoverEnabled;
@@ -124,7 +127,7 @@ public:
QLazilyAllocated<ExtraData> extra;
QPalette resolvedPalette;
- QQuickItem *background;
+ QQuickDeferredPointer<QQuickItem> background;
QString placeholder;
Qt::FocusReason focusReason;
QQuickPressHandler pressHandler;
diff --git a/src/quicktemplates2/qquicktumbler_p.h b/src/quicktemplates2/qquicktumbler_p.h
index 5d4df4a7..c388c28d 100644
--- a/src/quicktemplates2/qquicktumbler_p.h
+++ b/src/quicktemplates2/qquicktumbler_p.h
@@ -70,6 +70,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTumbler : public QQuickControl
Q_PROPERTY(bool wrap READ wrap WRITE setWrap RESET resetWrap NOTIFY wrapChanged FINAL REVISION 1)
// 2.2 (Qt 5.9)
Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged FINAL REVISION 2)
+ Q_CLASSINFO("DeferredPropertyNames", "background")
public:
explicit QQuickTumbler(QQuickItem *parent = nullptr);
diff --git a/src/quicktemplates2/quicktemplates2.pri b/src/quicktemplates2/quicktemplates2.pri
index a90b4f94..ee51f995 100644
--- a/src/quicktemplates2/quicktemplates2.pri
+++ b/src/quicktemplates2/quicktemplates2.pri
@@ -17,6 +17,8 @@ HEADERS += \
$$PWD/qquickcontainer_p_p.h \
$$PWD/qquickcontrol_p.h \
$$PWD/qquickcontrol_p_p.h \
+ $$PWD/qquickdeferredexecute_p_p.h \
+ $$PWD/qquickdeferredpointer_p_p.h \
$$PWD/qquickdelaybutton_p.h \
$$PWD/qquickdial_p.h \
$$PWD/qquickdialog_p.h \
@@ -102,6 +104,7 @@ SOURCES += \
$$PWD/qquickcombobox.cpp \
$$PWD/qquickcontainer.cpp \
$$PWD/qquickcontrol.cpp \
+ $$PWD/qquickdeferredexecute.cpp \
$$PWD/qquickdelaybutton.cpp \
$$PWD/qquickdial.cpp \
$$PWD/qquickdialog.cpp \