diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2017-06-07 19:43:58 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2017-06-13 14:02:04 +0000 |
commit | 474ded7679be0eca0513ec11f33b6dc2501ed2fa (patch) | |
tree | 2ce40283f046b3baf6a42508cf3b8d801d28dcd7 | |
parent | 0673dd4ff18bbc8d530a4dd08e394cc04c6711ca (diff) |
Add QQuickMenu::add/insert/remove/takeMenu()
[ChangeLog][Controls][Menu] Added addMenu(), insertMenu(),
removeMenu(), and takeMenu() methods for adding and removing
sub-menus programmatically.
Change-Id: Ibf39448cdf528f64695b1ee5f0781384b754ba22
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r-- | src/quicktemplates2/qquickmenu.cpp | 76 | ||||
-rw-r--r-- | src/quicktemplates2/qquickmenu_p.h | 5 | ||||
-rw-r--r-- | tests/auto/menu/tst_menu.cpp | 53 |
3 files changed, 134 insertions, 0 deletions
diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp index 1b2ed841..356f5cf3 100644 --- a/src/quicktemplates2/qquickmenu.cpp +++ b/src/quicktemplates2/qquickmenu.cpp @@ -687,6 +687,82 @@ QQuickItem *QQuickMenu::takeItem(int index) } /*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::addMenu(Menu menu) + + Adds \a menu as a sub-menu to the end of this menu. +*/ +void QQuickMenu::addMenu(QQuickMenu *menu) +{ + Q_D(QQuickMenu); + insertMenu(d->contentModel->count(), menu); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::insertMenu(int index, Menu menu) + + Inserts \a menu as a sub-menu at \a index. The index is within all items in the menu. +*/ +void QQuickMenu::insertMenu(int index, QQuickMenu *menu) +{ + Q_D(QQuickMenu); + if (!menu) + return; + + insertItem(index, d->createItem(menu)); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::removeMenu(Menu menu) + + Removes and destroys the specified \a menu. +*/ +void QQuickMenu::removeMenu(QQuickMenu *menu) +{ + Q_D(QQuickMenu); + if (!menu) + return; + + const int count = d->contentModel->count(); + for (int i = 0; i < count; ++i) { + QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(i)); + if (!item || item->subMenu() != menu) + continue; + + removeItem(item); + break; + } + + menu->deleteLater(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod Menu QtQuick.Controls::Menu::takeMenu(int index) + + Removes and returns the menu at \a index. The index is within all items in the menu. + + \note The ownership of the menu is transferred to the caller. +*/ +QQuickMenu *QQuickMenu::takeMenu(int index) +{ + Q_D(QQuickMenu); + QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(index)); + if (!item) + return nullptr; + + QQuickMenu *subMenu = item->subMenu(); + if (!subMenu) + return nullptr; + + d->removeItem(index, item); + item->deleteLater(); + return subMenu; +} + +/*! \qmlproperty model QtQuick.Controls::Menu::contentModel \readonly diff --git a/src/quicktemplates2/qquickmenu_p.h b/src/quicktemplates2/qquickmenu_p.h index 356798b9..005e1ef4 100644 --- a/src/quicktemplates2/qquickmenu_p.h +++ b/src/quicktemplates2/qquickmenu_p.h @@ -81,6 +81,11 @@ public: void removeItem(QQuickItem *item); // ### Qt 6: Q_INVOKABLE Q_REVISION(3) Q_INVOKABLE QQuickItem *takeItem(int index); + Q_REVISION(3) Q_INVOKABLE void addMenu(QQuickMenu *menu); + Q_REVISION(3) Q_INVOKABLE void insertMenu(int index, QQuickMenu *menu); + Q_REVISION(3) Q_INVOKABLE void removeMenu(QQuickMenu *menu); + Q_REVISION(3) Q_INVOKABLE QQuickMenu *takeMenu(int index); + QVariant contentModel() const; QQmlListProperty<QObject> contentData(); diff --git a/tests/auto/menu/tst_menu.cpp b/tests/auto/menu/tst_menu.cpp index 836b0ef1..ce0628fb 100644 --- a/tests/auto/menu/tst_menu.cpp +++ b/tests/auto/menu/tst_menu.cpp @@ -79,6 +79,7 @@ private slots: void subMenuKeyboard(); void subMenuPosition_data(); void subMenuPosition(); + void addRemoveSubMenus(); }; void tst_menu::defaults() @@ -919,6 +920,58 @@ void tst_menu::subMenuPosition() } } +void tst_menu::addRemoveSubMenus() +{ + QQuickApplicationHelper helper(this, QLatin1String("subMenus.qml")); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>(); + QVERIFY(mainMenu); + + QPointer<QQuickMenu> subMenu1 = window->property("subMenu1").value<QQuickMenu *>(); + QVERIFY(!subMenu1.isNull()); + + QPointer<QQuickMenu> subMenu2 = window->property("subMenu2").value<QQuickMenu *>(); + QVERIFY(!subMenu2.isNull()); + + QPointer<QQuickMenu> subSubMenu1 = window->property("subSubMenu1").value<QQuickMenu *>(); + QVERIFY(!subSubMenu1.isNull()); + + // takeMenu(int) does not destroy the menu, but does destroy the respective item in the parent menu + QPointer<QQuickMenuItem> subSubMenu1Item = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(2)); + QVERIFY(subSubMenu1Item); + QCOMPARE(subSubMenu1Item->subMenu(), subSubMenu1.data()); + QCOMPARE(subMenu1->takeMenu(2), subSubMenu1.data()); + QVERIFY(!subMenu1->itemAt(2)); + QCoreApplication::sendPostedEvents(subSubMenu1, QEvent::DeferredDelete); + QVERIFY(!subSubMenu1.isNull()); + QCoreApplication::sendPostedEvents(subSubMenu1Item, QEvent::DeferredDelete); + QVERIFY(subSubMenu1Item.isNull()); + + // takeMenu(int) does not destroy an item that doesn't present a menu + QPointer<QQuickMenuItem> subMenuItem1 = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(0)); + QVERIFY(subMenuItem1); + QVERIFY(!subMenuItem1->subMenu()); + QVERIFY(!subMenu1->takeMenu(0)); + QCoreApplication::sendPostedEvents(subMenuItem1, QEvent::DeferredDelete); + QVERIFY(!subMenuItem1.isNull()); + + // addMenu(Menu) re-creates the respective item in the parent menu + subMenu1->addMenu(subSubMenu1); + subSubMenu1Item = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(2)); + QVERIFY(!subSubMenu1Item.isNull()); + + // removeMenu(Menu) destroys both the menu and the respective item in the parent menu + subMenu1->removeMenu(subSubMenu1); + QVERIFY(!subMenu1->itemAt(2)); + QCoreApplication::sendPostedEvents(subSubMenu1, QEvent::DeferredDelete); + QVERIFY(subSubMenu1.isNull()); + QCoreApplication::sendPostedEvents(subSubMenu1Item, QEvent::DeferredDelete); + QVERIFY(subSubMenu1Item.isNull()); +} + QTEST_MAIN(tst_menu) #include "tst_menu.moc" |