diff options
author | Mitch Curtis <mitch.curtis@qt.io> | 2018-08-16 10:36:19 +0200 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@qt.io> | 2018-10-02 09:04:56 +0000 |
commit | d923dd467c1aeb3e195a09949b04862084002f88 (patch) | |
tree | 3d2ad3ab4d4989009195094bebd39276912dc5e1 /src | |
parent | e7213c0460788f49ec6c2204bfd5c0517699aa51 (diff) |
MenuBar: 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.
A similar fix was already done for Menu in d5cb26bc.
Task-number: QTBUG-67559
Change-Id: Idb43b7a69fcf1c1ad6396c73a3c090b92e460ab8
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/quicktemplates2/qquickcontainer.cpp | 25 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcontainer_p_p.h | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquickmenubar.cpp | 35 | ||||
-rw-r--r-- | src/quicktemplates2/qquickmenubar_p_p.h | 2 |
4 files changed, 52 insertions, 12 deletions
diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp index 3dfefdc0..b3e7454b 100644 --- a/src/quicktemplates2/qquickcontainer.cpp +++ b/src/quicktemplates2/qquickcontainer.cpp @@ -334,6 +334,21 @@ void QQuickContainerPrivate::reorderItems() } } +// Helper function needed for derived classes such as QQuickMenuBarPrivate. +void QQuickContainerPrivate::addObject(QObject *obj) +{ + Q_Q(QQuickContainer); + QQuickItem *item = qobject_cast<QQuickItem *>(obj); + if (item) { + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + item->setParentItem(effectiveContentItem(contentItem)); + else if (contentModel->indexOf(item, nullptr) == -1) + q->addItem(item); + } else { + contentData.append(obj); + } +} + void QQuickContainerPrivate::_q_currentIndexChanged() { Q_Q(QQuickContainer); @@ -375,15 +390,7 @@ void QQuickContainerPrivate::contentData_append(QQmlListProperty<QObject> *prop, { QQuickContainer *q = static_cast<QQuickContainer *>(prop->object); QQuickContainerPrivate *p = QQuickContainerPrivate::get(q); - QQuickItem *item = qobject_cast<QQuickItem *>(obj); - if (item) { - if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) - item->setParentItem(effectiveContentItem(p->contentItem)); - else if (p->contentModel->indexOf(item, nullptr) == -1) - q->addItem(item); - } else { - p->contentData.append(obj); - } + p->addObject(obj); } int QQuickContainerPrivate::contentData_count(QQmlListProperty<QObject> *prop) diff --git a/src/quicktemplates2/qquickcontainer_p_p.h b/src/quicktemplates2/qquickcontainer_p_p.h index 4e53aa8f..09a89b90 100644 --- a/src/quicktemplates2/qquickcontainer_p_p.h +++ b/src/quicktemplates2/qquickcontainer_p_p.h @@ -74,6 +74,8 @@ public: void removeItem(int index, QQuickItem *item); void reorderItems(); + void addObject(QObject *obj); + void _q_currentIndexChanged(); void itemChildAdded(QQuickItem *item, QQuickItem *child) override; diff --git a/src/quicktemplates2/qquickmenubar.cpp b/src/quicktemplates2/qquickmenubar.cpp index efb83a17..876cc471 100644 --- a/src/quicktemplates2/qquickmenubar.cpp +++ b/src/quicktemplates2/qquickmenubar.cpp @@ -76,6 +76,25 @@ QT_BEGIN_NAMESPACE {Focus Management in Qt Quick Controls 2} */ +void QQuickMenuBarPrivate::createItems() +{ + // removeItem() will remove stuff from contentData, so we have to make a copy of it. + const auto originalContentData = contentData; + // Sanity check that there aren't any items we don't know about. + Q_ASSERT(contentModel->count() == 0); + + for (QObject *object : originalContentData) { + if (QQuickMenu *menu = qobject_cast<QQuickMenu *>(object)) { + // It's a QQuickMenu; create a QQuickMenuBarItem for it. + QQuickItem *menuItem = createItem(menu); + addObject(menuItem); + } else if (qobject_cast<QQuickMenuBarItem *>(object)) { + addObject(object); + } + // If it's neither, skip it because we don't care about it. + } +} + QQuickItem *QQuickMenuBarPrivate::beginCreateItem() { Q_Q(QQuickMenuBar); @@ -259,9 +278,18 @@ void QQuickMenuBarPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChang void QQuickMenuBarPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj) { QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object); - if (QQuickMenu *menu = qobject_cast<QQuickMenu *>(obj)) - obj = QQuickMenuBarPrivate::get(menuBar)->createItem(menu); - QQuickContainerPrivate::contentData_append(prop, obj); + QQuickMenuBarPrivate *menuBarPrivate = QQuickMenuBarPrivate::get(menuBar); + if (!menuBarPrivate->componentComplete) { + // 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. + menuBarPrivate->contentData.append(obj); + return; + } + + if (QQuickMenu *menu = qobject_cast<QQuickMenu *>(obj)) { + QQuickItem *menuItem = menuBarPrivate->createItem(menu); + menuBarPrivate->addObject(menuItem); + } } void QQuickMenuBarPrivate::menus_append(QQmlListProperty<QQuickMenu> *prop, QQuickMenu *obj) @@ -521,6 +549,7 @@ void QQuickMenuBar::componentComplete() { Q_D(QQuickMenuBar); QQuickContainer::componentComplete(); + d->createItems(); d->updateContentSize(); } diff --git a/src/quicktemplates2/qquickmenubar_p_p.h b/src/quicktemplates2/qquickmenubar_p_p.h index b6fdc9eb..24824292 100644 --- a/src/quicktemplates2/qquickmenubar_p_p.h +++ b/src/quicktemplates2/qquickmenubar_p_p.h @@ -66,6 +66,8 @@ public: return menuBar->d_func(); } + void createItems(); + QQuickItem *beginCreateItem(); void completeCreateItem(); |