diff options
author | Mitch Curtis <mitch.curtis@qt.io> | 2018-04-10 17:40:07 +0200 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@qt.io> | 2018-09-05 14:57:22 +0000 |
commit | d5cb26bc56a3b6f6e99c88654d4f7a65f43551ac (patch) | |
tree | 614cfe06c0cb5ae35202e7e9e57cb1170fb0eff0 /src | |
parent | 65374a95a33a677740f6e6b25c424b4a4b466b3f (diff) |
Menu: ensure the correct delegates are used when created via Component
Don't add items until we're complete, as the delegate could change in
the meantime. Instead, add them to contentData and create them when
we're complete.
Task-number: QTBUG-67559
Change-Id: I5f42129f49de861ff5f15d0069daeda0b4e5017c
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/quicktemplates2/qquickmenu.cpp | 59 | ||||
-rw-r--r-- | src/quicktemplates2/qquickmenu_p_p.h | 3 |
2 files changed, 45 insertions, 17 deletions
diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp index ecdd2825..e321b4c9 100644 --- a/src/quicktemplates2/qquickmenu.cpp +++ b/src/quicktemplates2/qquickmenu.cpp @@ -242,6 +242,41 @@ void QQuickMenuPrivate::removeItem(int index, QQuickItem *item) } } +void QQuickMenuPrivate::createAndAppendItem(QObject *object) +{ + Q_Q(QQuickMenu); + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (!item) { + if (QQuickAction *action = qobject_cast<QQuickAction *>(object)) + item = createItem(action); + else if (QQuickMenu *menu = qobject_cast<QQuickMenu *>(object)) + item = createItem(menu); + } + + if (item) { + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) { + QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::SiblingOrder); + item->setParentItem(contentItem); + } else if (contentModel->indexOf(item, nullptr) == -1) { + q->addItem(item); + } + } else { + contentData.append(object); + } +} + +void QQuickMenuPrivate::recreateItems() +{ + // removeItem() will remove stuff from contentData, so we have to make a copy of it. + const auto originalContentData = contentData; + + while (contentModel->count() > 0) + removeItem(0, itemAt(0)); + + for (QObject *object : originalContentData) + createAndAppendItem(object); +} + QQuickItem *QQuickMenuPrivate::beginCreateItem() { Q_Q(QQuickMenu); @@ -608,24 +643,14 @@ void QQuickMenuPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObj QQuickMenu *q = qobject_cast<QQuickMenu *>(prop->object); QQuickMenuPrivate *p = QQuickMenuPrivate::get(q); - QQuickItem *item = qobject_cast<QQuickItem *>(obj); - if (!item) { - if (QQuickAction *action = qobject_cast<QQuickAction *>(obj)) - item = p->createItem(action); - else if (QQuickMenu *menu = qobject_cast<QQuickMenu *>(obj)) - item = p->createItem(menu); - } - - if (item) { - if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) { - QQuickItemPrivate::get(item)->addItemChangeListener(p, QQuickItemPrivate::SiblingOrder); - item->setParentItem(p->contentItem); - } else if (p->contentModel->indexOf(item, nullptr) == -1) { - q->addItem(item); - } - } else { + if (!p->complete) { + // Don't add items until we're complete, as the delegate could change in the meantime. + // We'll add it to contentData and create it when we're complete. p->contentData.append(obj); + return; } + + p->createAndAppendItem(obj); } int QQuickMenuPrivate::contentData_count(QQmlListProperty<QObject> *prop) @@ -1338,7 +1363,7 @@ void QQuickMenu::componentComplete() { Q_D(QQuickMenu); QQuickPopup::componentComplete(); - d->resizeItems(); + d->recreateItems(); } void QQuickMenu::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) diff --git a/src/quicktemplates2/qquickmenu_p_p.h b/src/quicktemplates2/qquickmenu_p_p.h index 83fe3e36..bcf3d683 100644 --- a/src/quicktemplates2/qquickmenu_p_p.h +++ b/src/quicktemplates2/qquickmenu_p_p.h @@ -78,6 +78,9 @@ public: void moveItem(int from, int to); void removeItem(int index, QQuickItem *item); + void createAndAppendItem(QObject *object); + void recreateItems(); + QQuickItem *beginCreateItem(); void completeCreateItem(); |