summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2016-12-28 20:24:18 +0100
committerJ-P Nurmi <jpnurmi@qt.io>2017-01-02 13:31:19 +0000
commit406059366f88d4f0d862cd9d0a8d746e8c2335c1 (patch)
tree520e3288a5a1a92197cd318c77b68fe96424d3c2
parent00a7dfd16d4484064bd0e5601720993d0525995a (diff)
QQuickMenu: fix Repeater support
QQuickMenu had itemChildAdded() copied from QQuickContainer, but it did not actually install an item change listener on the content item so itemChildAdded() got never called. Change-Id: Idfe558c7055b9a3df124b1f009941c423ecef4bb Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r--src/quicktemplates2/qquickmenu.cpp7
-rw-r--r--tests/auto/menu/data/order.qml71
-rw-r--r--tests/auto/menu/data/repeater.qml59
-rw-r--r--tests/auto/menu/tst_menu.cpp67
4 files changed, 203 insertions, 1 deletions
diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp
index ab5415d3..74239cf2 100644
--- a/src/quicktemplates2/qquickmenu.cpp
+++ b/src/quicktemplates2/qquickmenu.cpp
@@ -461,8 +461,13 @@ void QQuickMenu::componentComplete()
void QQuickMenu::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
{
Q_D(QQuickMenu);
- Q_UNUSED(oldItem);
QQuickPopup::contentItemChange(newItem, oldItem);
+
+ if (oldItem)
+ QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Children);
+ if (newItem)
+ QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children);
+
d->contentItem = newItem;
}
diff --git a/tests/auto/menu/data/order.qml b/tests/auto/menu/data/order.qml
new file mode 100644
index 00000000..678f27e2
--- /dev/null
+++ b/tests/auto/menu/data/order.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Controls 2.1
+
+ApplicationWindow {
+ width: 200
+ height: 200
+
+ property alias menu: menu
+
+ Component {
+ id: menuItem
+ MenuItem { }
+ }
+
+ Menu {
+ id: menu
+ property alias repeater: repeater
+ MenuItem { text: "static_1" }
+ Repeater {
+ id: repeater
+ model: 2
+ MenuItem { text: "repeated_" + (index + 2) }
+ }
+ MenuItem { text: "static_4" }
+ Component.onCompleted: {
+ addItem(menuItem.createObject(menu.contentItem, {text: "dynamic_5"}))
+ addItem(menuItem.createObject(menu.contentItem, {text: "dynamic_6"}))
+ insertItem(0, menuItem.createObject(menu.contentItem, {text: "dynamic_0"}))
+ }
+ }
+}
diff --git a/tests/auto/menu/data/repeater.qml b/tests/auto/menu/data/repeater.qml
new file mode 100644
index 00000000..e4619053
--- /dev/null
+++ b/tests/auto/menu/data/repeater.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Controls 2.1
+
+ApplicationWindow {
+ width: 200
+ height: 200
+
+ property alias menu: menu
+ property alias repeater: repeater
+
+ Menu {
+ id: menu
+ Repeater {
+ id: repeater
+ model: 5
+ MenuItem { property int idx: index }
+ }
+ }
+}
diff --git a/tests/auto/menu/tst_menu.cpp b/tests/auto/menu/tst_menu.cpp
index 0635ad81..e3133b43 100644
--- a/tests/auto/menu/tst_menu.cpp
+++ b/tests/auto/menu/tst_menu.cpp
@@ -67,6 +67,8 @@ private slots:
void menuButton();
void addItem();
void menuSeparator();
+ void repeater();
+ void order();
};
void tst_menu::defaults()
@@ -317,6 +319,71 @@ void tst_menu::menuSeparator()
QTRY_VERIFY(!menu->isVisible());
}
+void tst_menu::repeater()
+{
+ QQuickApplicationHelper helper(this, QLatin1String("repeater.qml"));
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
+ QVERIFY(menu);
+ menu->open();
+ QVERIFY(menu->isVisible());
+
+ QObject *repeater = window->property("repeater").value<QObject*>();
+ QVERIFY(repeater);
+
+ int count = repeater->property("count").toInt();
+ QCOMPARE(count, 5);
+
+ for (int i = 0; i < count; ++i) {
+ QQuickItem *item = menu->itemAt(i);
+ QVERIFY(item);
+ QCOMPARE(item->property("idx").toInt(), i);
+
+ QQuickItem *repeaterItem = nullptr;
+ QVERIFY(QMetaObject::invokeMethod(repeater, "itemAt", Q_RETURN_ARG(QQuickItem*, repeaterItem), Q_ARG(int, i)));
+ QCOMPARE(item, repeaterItem);
+ }
+
+ repeater->setProperty("model", 3);
+
+ count = repeater->property("count").toInt();
+ QCOMPARE(count, 3);
+
+ for (int i = 0; i < count; ++i) {
+ QQuickItem *item = menu->itemAt(i);
+ QVERIFY(item);
+ QCOMPARE(item->property("idx").toInt(), i);
+
+ QQuickItem *repeaterItem = nullptr;
+ QVERIFY(QMetaObject::invokeMethod(repeater, "itemAt", Q_RETURN_ARG(QQuickItem*, repeaterItem), Q_ARG(int, i)));
+ QCOMPARE(item, repeaterItem);
+ }
+}
+
+void tst_menu::order()
+{
+ QQuickApplicationHelper helper(this, QLatin1String("order.qml"));
+ QQuickWindow *window = helper.window;
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
+ QVERIFY(menu);
+ menu->open();
+ QVERIFY(menu->isVisible());
+
+ const QStringList texts = {"dynamic_0", "static_1", "repeated_2", "repeated_3", "static_4", "dynamic_5", "dynamic_6"};
+
+ for (int i = 0; i < texts.count(); ++i) {
+ QQuickItem *item = menu->itemAt(i);
+ QVERIFY(item);
+ QCOMPARE(item->property("text").toString(), texts.at(i));
+ }
+}
+
QTEST_MAIN(tst_menu)
#include "tst_menu.moc"