diff options
Diffstat (limited to 'tests/auto/quickcontrols2/controls/data/tst_popup.qml')
-rw-r--r-- | tests/auto/quickcontrols2/controls/data/tst_popup.qml | 1393 |
1 files changed, 1393 insertions, 0 deletions
diff --git a/tests/auto/quickcontrols2/controls/data/tst_popup.qml b/tests/auto/quickcontrols2/controls/data/tst_popup.qml new file mode 100644 index 00000000..145f5552 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_popup.qml @@ -0,0 +1,1393 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, 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 +import QtTest +import QtQuick.Controls +import QtQuick.Templates as T + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Popup" + + ApplicationWindow { + id: applicationWindow + width: 480 + height: 360 + } + + Component { + id: popupTemplate + T.Popup { } + } + + Component { + id: popupControl + Popup { } + } + + Component { + id: rect + Rectangle { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_padding() { + var control = createTemporaryObject(popupTemplate, testCase) + verify(control) + + var paddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "paddingChanged"}) + verify(paddingSpy.valid) + + var topPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "topPaddingChanged"}) + verify(topPaddingSpy.valid) + + var leftPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "leftPaddingChanged"}) + verify(leftPaddingSpy.valid) + + var rightPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "rightPaddingChanged"}) + verify(rightPaddingSpy.valid) + + var bottomPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "bottomPaddingChanged"}) + verify(bottomPaddingSpy.valid) + + var paddingChanges = 0 + var topPaddingChanges = 0 + var leftPaddingChanges = 0 + var rightPaddingChanges = 0 + var bottomPaddingChanges = 0 + + compare(control.padding, 0) + compare(control.topPadding, 0) + compare(control.leftPadding, 0) + compare(control.rightPadding, 0) + compare(control.bottomPadding, 0) + compare(control.availableWidth, 0) + compare(control.availableHeight, 0) + + control.width = 100 + control.height = 100 + + control.padding = 10 + compare(control.padding, 10) + compare(control.topPadding, 10) + compare(control.leftPadding, 10) + compare(control.rightPadding, 10) + compare(control.bottomPadding, 10) + compare(paddingSpy.count, ++paddingChanges) + compare(topPaddingSpy.count, ++topPaddingChanges) + compare(leftPaddingSpy.count, ++leftPaddingChanges) + compare(rightPaddingSpy.count, ++rightPaddingChanges) + compare(bottomPaddingSpy.count, ++bottomPaddingChanges) + + control.topPadding = 20 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 10) + compare(control.rightPadding, 10) + compare(control.bottomPadding, 10) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, ++topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + + control.leftPadding = 30 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 10) + compare(control.bottomPadding, 10) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, ++leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + + control.rightPadding = 40 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 10) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, ++rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + + control.bottomPadding = 50 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 50) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, ++bottomPaddingChanges) + + control.padding = 60 + compare(control.padding, 60) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 50) + compare(paddingSpy.count, ++paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + } + + function test_availableSize() { + var control = createTemporaryObject(popupTemplate, testCase) + verify(control) + + var availableWidthSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "availableWidthChanged"}) + verify(availableWidthSpy.valid) + + var availableHeightSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "availableHeightChanged"}) + verify(availableHeightSpy.valid) + + var availableWidthChanges = 0 + var availableHeightChanges = 0 + + control.width = 100 + compare(control.availableWidth, 100) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.height = 100 + compare(control.availableHeight, 100) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.padding = 10 + compare(control.availableWidth, 80) + compare(control.availableHeight, 80) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.topPadding = 20 + compare(control.availableWidth, 80) + compare(control.availableHeight, 70) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.leftPadding = 30 + compare(control.availableWidth, 60) + compare(control.availableHeight, 70) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.rightPadding = 40 + compare(control.availableWidth, 30) + compare(control.availableHeight, 70) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.bottomPadding = 50 + compare(control.availableWidth, 30) + compare(control.availableHeight, 30) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.padding = 60 + compare(control.availableWidth, 30) + compare(control.availableHeight, 30) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.width = 0 + compare(control.availableWidth, 0) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.height = 0 + compare(control.availableHeight, 0) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + } + + function test_position() { + var control = createTemporaryObject(popupControl, testCase, {visible: true, leftMargin: 10, topMargin: 20, width: 100, height: 100}) + verify(control) + verify(control.visible) + + var xSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "xChanged"}) + verify(xSpy.valid) + + var ySpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "yChanged"}) + verify(ySpy.valid) + + // moving outside margins does not trigger change notifiers + control.x = -100 + compare(control.x, 10) + compare(control.y, 20) + compare(xSpy.count, 0) + compare(ySpy.count, 0) + + control.y = -200 + compare(control.x, 10) + compare(control.y, 20) + compare(xSpy.count, 0) + compare(ySpy.count, 0) + + // moving within margins triggers change notifiers + control.x = 30 + compare(control.x, 30) + compare(control.y, 20) + compare(xSpy.count, 1) + compare(ySpy.count, 0) + + control.y = 40 + compare(control.x, 30) + compare(control.y, 40) + compare(xSpy.count, 1) + compare(ySpy.count, 1) + + // re-parent and reset the position + control.parent = createTemporaryObject(rect, testCase, {color: "red", width: 100, height: 100}) + control.x = 0 + control.y = 0 + compare(xSpy.count, 2) + compare(ySpy.count, 2) + + // moving parent outside margins triggers change notifiers + control.parent.x = -50 + compare(control.x, 50 + control.leftMargin) + compare(xSpy.count, 3) + compare(ySpy.count, 2) + + control.parent.y = -60 + compare(control.y, 60 + control.topMargin) + compare(xSpy.count, 3) + compare(ySpy.count, 3) + } + + function test_resetSize() { + var control = createTemporaryObject(popupControl, testCase, {visible: true, margins: 0}) + verify(control) + + control.scale = 1.0 + control.width = control.implicitWidth = testCase.width + 10 + control.height = control.implicitHeight = testCase.height + 10 + + compare(control.width, testCase.width + 10) + compare(control.height, testCase.height + 10) + + control.width = undefined + control.height = undefined + compare(control.width, testCase.width) + compare(control.height, testCase.height) + } + + function test_negativeMargins() { + var control = createTemporaryObject(popupControl, testCase, {implicitWidth: testCase.width, implicitHeight: testCase.height}) + verify(control) + + control.open() + verify(control.visible) + + compare(control.x, 0) + compare(control.y, 0) + + compare(control.margins, -1) + compare(control.topMargin, -1) + compare(control.leftMargin, -1) + compare(control.rightMargin, -1) + compare(control.bottomMargin, -1) + + control.x = -10 + control.y = -10 + compare(control.x, 0) + compare(control.y, 0) + } + + function test_margins() { + var control = createTemporaryObject(popupTemplate, testCase, {width: 100, height: 100}) + verify(control) + + control.open() + verify(control.visible) + + control.margins = 10 + compare(control.margins, 10) + compare(control.topMargin, 10) + compare(control.leftMargin, 10) + compare(control.rightMargin, 10) + compare(control.bottomMargin, 10) + compare(control.contentItem.parent.x, 10) + compare(control.contentItem.parent.y, 10) + + control.topMargin = 20 + compare(control.margins, 10) + compare(control.topMargin, 20) + compare(control.leftMargin, 10) + compare(control.rightMargin, 10) + compare(control.bottomMargin, 10) + compare(control.contentItem.parent.x, 10) + compare(control.contentItem.parent.y, 20) + + control.leftMargin = 20 + compare(control.margins, 10) + compare(control.topMargin, 20) + compare(control.leftMargin, 20) + compare(control.rightMargin, 10) + compare(control.bottomMargin, 10) + compare(control.contentItem.parent.x, 20) + compare(control.contentItem.parent.y, 20) + + control.x = testCase.width + control.y = testCase.height + compare(control.contentItem.parent.x, testCase.width - control.width - 10) + compare(control.contentItem.parent.y, testCase.height - control.height - 10) + + control.rightMargin = 20 + compare(control.margins, 10) + compare(control.topMargin, 20) + compare(control.leftMargin, 20) + compare(control.rightMargin, 20) + compare(control.bottomMargin, 10) + compare(control.contentItem.parent.x, testCase.width - control.width - 20) + compare(control.contentItem.parent.y, testCase.height - control.height - 10) + + control.bottomMargin = 20 + compare(control.margins, 10) + compare(control.topMargin, 20) + compare(control.leftMargin, 20) + compare(control.rightMargin, 20) + compare(control.bottomMargin, 20) + compare(control.contentItem.parent.x, testCase.width - control.width - 20) + compare(control.contentItem.parent.y, testCase.height - control.height - 20) + + control.margins = undefined + compare(control.margins, -1) + + control.bottomMargin = undefined + compare(control.bottomMargin, -1) + compare(control.contentItem.parent.x, testCase.width - control.width - 20) + compare(control.contentItem.parent.y, testCase.height) + + control.rightMargin = undefined + compare(control.rightMargin, -1) + compare(control.contentItem.parent.x, testCase.width) + compare(control.contentItem.parent.y, testCase.height) + + control.x = -testCase.width + control.y = -testCase.height + compare(control.contentItem.parent.x, 20) + compare(control.contentItem.parent.y, 20) + + control.topMargin = undefined + compare(control.topMargin, -1) + compare(control.contentItem.parent.x, 20) + compare(control.contentItem.parent.y, -testCase.height) + + control.leftMargin = undefined + compare(control.leftMargin, -1) + compare(control.contentItem.parent.x, -testCase.width) + compare(control.contentItem.parent.y, -testCase.height) + } + + function test_background() { + var control = createTemporaryObject(popupTemplate, testCase) + verify(control) + + control.background = rect.createObject(testCase) + + // background has no x or width set, so its width follows control's width + control.width = 320 + compare(control.background.width, control.width) + + // background has no y or height set, so its height follows control's height + compare(control.background.height, control.height) + control.height = 240 + + // has width => width does not follow + control.background.width /= 2 + control.width += 20 + verify(control.background.width !== control.width) + + // reset width => width follows again + control.background.width = undefined + control.width += 20 + compare(control.background.width, control.width) + + // has x => width does not follow + control.background.x = 10 + control.width += 20 + verify(control.background.width !== control.width) + + // has height => height does not follow + control.background.height /= 2 + control.height -= 20 + verify(control.background.height !== control.height) + + // reset height => height follows again + control.background.height = undefined + control.height -= 20 + compare(control.background.height, control.height) + + // has y => height does not follow + control.background.y = 10 + control.height -= 20 + verify(control.background.height !== control.height) + } + + function getChild(control, objname, idx) { + var index = idx + for (var i = index+1; i < control.children.length; i++) + { + if (control.children[i].objectName === objname) { + index = i + break + } + } + return index + } + + Component { + id: component + ApplicationWindow { + id: _window + width: 400 + height: 400 + visible: true + font.pixelSize: 40 + property alias pane: _pane + property alias popup: _popup + property SignalSpy fontspy: SignalSpy { target: _window; signalName: "fontChanged" } + Pane { + id: _pane + property alias button: _button + font.pixelSize: 30 + property SignalSpy fontspy: SignalSpy { target: _pane; signalName: "fontChanged" } + Column { + Button { + id: _button + text: "Button" + font.pixelSize: 20 + property SignalSpy fontspy: SignalSpy { target: _button; signalName: "fontChanged" } + Popup { + id: _popup + property alias button: _button2 + property alias listview: _listview + y: _button.height + implicitHeight: Math.min(396, _listview.contentHeight) + property SignalSpy fontspy: SignalSpy { target: _popup; signalName: "fontChanged" } + contentItem: Column { + Button { + id: _button2 + text: "Button" + property SignalSpy fontspy: SignalSpy { target: _button2; signalName: "fontChanged" } + } + ListView { + id: _listview + height: _button.height * 20 + model: 2 + delegate: Button { + id: _button3 + objectName: "delegate" + width: _button.width + height: _button.height + text: "N: " + index + checkable: true + autoExclusive: true + property SignalSpy fontspy: SignalSpy { target: _button3; signalName: "fontChanged" } + } + } + } + } + } + } + } + } + } + + function test_font() { // QTBUG_50984, QTBUG-51696 + var window = createTemporaryObject(component, testCase) + verify(window) + + compare(window.font.pixelSize, 40) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.button.font.pixelSize, 20) + compare(window.popup.font.pixelSize, 40) + compare(window.popup.button.font.pixelSize, 40) + + var idx1 = getChild(window.popup.listview.contentItem, "delegate", -1) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 40) + var idx2 = getChild(window.popup.listview.contentItem, "delegate", idx1) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 40) + + window.pane.button.font.pixelSize = 30 + compare(window.font.pixelSize, 40) + compare(window.fontspy.count, 0) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 40) + compare(window.popup.fontspy.count, 0) + compare(window.popup.button.font.pixelSize, 40) + compare(window.popup.button.fontspy.count, 0) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 40) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 0) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 40) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 0) + + window.font.pixelSize = 50 + compare(window.font.pixelSize, 50) + compare(window.fontspy.count, 1) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 50) + compare(window.popup.fontspy.count, 1) + compare(window.popup.button.font.pixelSize, 50) + compare(window.popup.button.fontspy.count, 1) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 1) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 1) + + window.popup.button.font.pixelSize = 10 + compare(window.font.pixelSize, 50) + compare(window.fontspy.count, 1) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 50) + compare(window.popup.fontspy.count, 1) + compare(window.popup.button.font.pixelSize, 10) + compare(window.popup.button.fontspy.count, 2) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 1) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 1) + + window.popup.font.pixelSize = 60 + compare(window.font.pixelSize, 50) + compare(window.fontspy.count, 1) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 60) + compare(window.popup.fontspy.count, 2) + compare(window.popup.button.font.pixelSize, 10) + compare(window.popup.button.fontspy.count, 2) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 60) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 2) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 60) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 2) + } + + Component { + id: localeComponent + Pane { + property alias button: _button + property alias popup: _popup + locale: Qt.locale("en_US") + Column { + Button { + id: _button + text: "Button" + locale: Qt.locale("nb_NO") + Popup { + id: _popup + property alias button1: _button1 + property alias button2: _button2 + y: _button.height + locale: Qt.locale("fi_FI") + implicitHeight: Math.min(396, _column.contentHeight) + contentItem: Column { + id: _column + Button { + id: _button1 + text: "Button 1" + objectName: "1" + } + Button { + id: _button2 + text: "Button 2" + locale: Qt.locale("nb_NO") + objectName: "2" + } + } + } + } + } + } + } + + function test_locale() { // QTBUG_50984 + // test looking up natural locale from ancestors + var control = createTemporaryObject(localeComponent, applicationWindow.contentItem) + verify(control) + + compare(control.locale.name, "en_US") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "fi_FI") + compare(control.popup.button1.locale.name, "fi_FI") + compare(control.popup.button2.locale.name, "nb_NO") + + control.ApplicationWindow.window.locale = undefined + } + + Component { + id: localeChangeComponent + Pane { + id: _pane + property alias button: _button + property alias popup: _popup + property SignalSpy localespy: SignalSpy { + target: _pane + signalName: "localeChanged" + } + property SignalSpy mirrorspy: SignalSpy { + target: _pane + signalName: "mirroredChanged" + } + Column { + Button { + id: _button + text: "Button" + property SignalSpy localespy: SignalSpy { + target: _button + signalName: "localeChanged" + } + property SignalSpy mirrorspy: SignalSpy { + target: _button + signalName: "mirroredChanged" + } + Popup { + id: _popup + property alias button1: _button1 + property alias button2: _button2 + y: _button.height + implicitHeight: Math.min(396, _column.contentHeight) + property SignalSpy localespy: SignalSpy { + target: _popup + signalName: "localeChanged" + } + contentItem: Column { + id: _column + Button { + id: _button1 + text: "Button 1" + property SignalSpy localespy: SignalSpy { + target: _button1 + signalName: "localeChanged" + } + property SignalSpy mirrorspy: SignalSpy { + target: _button1 + signalName: "mirroredChanged" + } + } + Button { + id: _button2 + text: "Button 2" + property SignalSpy localespy: SignalSpy { + target: _button2 + signalName: "localeChanged" + } + property SignalSpy mirrorspy: SignalSpy { + target: _button2 + signalName: "mirroredChanged" + } + } + } + } + } + } + } + } + + function test_locale_changes() { // QTBUG_50984 + // test default locale and locale inheritance + var control = createTemporaryObject(localeChangeComponent, applicationWindow.contentItem) + verify(control) + + var defaultLocale = Qt.locale() + compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) + compare(control.locale.name, defaultLocale.name) + compare(control.button.locale.name, defaultLocale.name) + compare(control.popup.locale.name, defaultLocale.name) + compare(control.popup.button1.locale.name, defaultLocale.name) + compare(control.popup.button2.locale.name, defaultLocale.name) + + control.ApplicationWindow.window.locale = Qt.locale("nb_NO") + compare(control.ApplicationWindow.window.locale.name, "nb_NO") + compare(control.locale.name, "nb_NO") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "nb_NO") + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, "nb_NO") + compare(control.localespy.count, 1) + compare(control.button.localespy.count, 1) + compare(control.popup.localespy.count, 1) + compare(control.popup.button1.localespy.count, 1) + compare(control.popup.button2.localespy.count, 1) + + control.ApplicationWindow.window.locale = undefined + compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) + compare(control.locale.name, defaultLocale.name) + compare(control.button.locale.name, defaultLocale.name) + compare(control.popup.locale.name, defaultLocale.name) + compare(control.popup.button1.locale.name, defaultLocale.name) + compare(control.popup.button2.locale.name, defaultLocale.name) + compare(control.localespy.count, 2) + compare(control.button.localespy.count, 2) + compare(control.popup.localespy.count, 2) + compare(control.popup.button1.localespy.count, 2) + compare(control.popup.button2.localespy.count, 2) + + control.locale = Qt.locale("ar_EG") + compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "ar_EG") + compare(control.popup.locale.name, defaultLocale.name) + compare(control.popup.button1.locale.name, defaultLocale.name) + compare(control.popup.button2.locale.name, defaultLocale.name) + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 3) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 2) + compare(control.popup.button1.localespy.count, 2) + compare(control.popup.button2.localespy.count, 2) + + control.ApplicationWindow.window.locale = Qt.locale("ar_EG") + compare(control.ApplicationWindow.window.locale.name, "ar_EG") + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "ar_EG") + compare(control.popup.locale.name, "ar_EG") + compare(control.popup.button1.locale.name, "ar_EG") + compare(control.popup.button2.locale.name, "ar_EG") + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 3) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 3) + compare(control.popup.button1.localespy.count, 3) + compare(control.popup.button1.mirrorspy.count, 0) + compare(control.popup.button2.localespy.count, 3) + compare(control.popup.button2.mirrorspy.count, 0) + + control.button.locale = Qt.locale("nb_NO") + compare(control.ApplicationWindow.window.locale.name, "ar_EG") + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "ar_EG") + compare(control.popup.button1.locale.name, "ar_EG") + compare(control.popup.button2.locale.name, "ar_EG") + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 3) + compare(control.popup.button1.localespy.count, 3) + compare(control.popup.button2.localespy.count, 3) + + control.locale = undefined + compare(control.ApplicationWindow.window.locale.name, "ar_EG") + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "ar_EG") + compare(control.popup.button1.locale.name, "ar_EG") + compare(control.popup.button2.locale.name, "ar_EG") + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 3) + compare(control.popup.button1.localespy.count, 3) + compare(control.popup.button2.localespy.count, 3) + + control.popup.button1.locale = Qt.locale("nb_NO") + compare(control.ApplicationWindow.window.locale.name, "ar_EG") + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "ar_EG") + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, "ar_EG") + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 3) + compare(control.popup.button1.localespy.count, 4) + compare(control.popup.button1.mirrorspy.count, 0) + compare(control.popup.button2.localespy.count, 3) + compare(control.popup.button2.mirrorspy.count, 0) + + control.popup.locale = Qt.locale("fi_FI") + compare(control.ApplicationWindow.window.locale.name, "ar_EG") + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "fi_FI") + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, "fi_FI") + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 4) + compare(control.popup.button1.localespy.count, 4) + compare(control.popup.button1.mirrorspy.count, 0) + compare(control.popup.button2.localespy.count, 4) + compare(control.popup.button2.mirrorspy.count, 0) + + control.ApplicationWindow.window.locale = undefined + compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) + compare(control.locale.name, defaultLocale.name) + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "fi_FI") + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, "fi_FI") + compare(control.localespy.count, 4) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 4) + compare(control.popup.button1.localespy.count, 4) + compare(control.popup.button1.mirrorspy.count, 0) + compare(control.popup.button2.localespy.count, 4) + compare(control.popup.button2.mirrorspy.count, 0) + + control.popup.locale = undefined + compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) + compare(control.locale.name, defaultLocale.name) + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, defaultLocale.name) + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, defaultLocale.name) + compare(control.localespy.count, 4) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 5) + compare(control.popup.button1.localespy.count, 4) + compare(control.popup.button1.mirrorspy.count, 0) + compare(control.popup.button2.localespy.count, 5) + compare(control.popup.button2.mirrorspy.count, 0) + } + + function test_size() { + var control = createTemporaryObject(popupControl, testCase) + verify(control) + + var openedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "opened"}) + verify(openedSpy.valid) + + control.open() + openedSpy.wait() + compare(openedSpy.count, 1) + verify(control.visible) + + // remove the background so that it won't affect the implicit size of the popup, + // so the implicit sizes tested below are entirely based on the content size + control.background = null + + // implicit size of the content + control.contentItem.implicitWidth = 10 + compare(control.implicitWidth, 10 + control.leftPadding + control.rightPadding) + compare(control.width, control.implicitWidth) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.contentItem.implicitHeight = 20 + compare(control.implicitHeight, 20 + control.topPadding + control.bottomPadding) + compare(control.height, control.implicitHeight) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) + + // implicit size of the popup + control.implicitWidth = 30 + compare(control.implicitWidth, 30) + compare(control.width, 30) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.implicitHeight = 40 + compare(control.implicitHeight, 40) + compare(control.height, 40) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) + + // set explicit size + control.width = 50 + compare(control.implicitWidth, 30) + compare(control.width, 50) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.height = 60 + compare(control.implicitHeight, 40) + compare(control.height, 60) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) + + // reset explicit size + control.width = undefined + compare(control.implicitWidth, 30) + compare(control.width, 30) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + + control.height = undefined + compare(control.implicitHeight, 40) + compare(control.height, 40) + compare(control.contentItem.height, control.height - control.topPadding - control.bottomPadding) + } + + function test_visible() { + var control = createTemporaryObject(popupTemplate, testCase, {visible: true}) + verify(control) + + // QTBUG-51989 + tryCompare(control, "visible", true) + + // QTBUG-55347 + control.parent = null + verify(!control.visible) + } + + Component { + id: overlayTest + ApplicationWindow { + property alias firstDrawer: firstDrawer + property alias secondDrawer: secondDrawer + property alias modalPopup: modalPopup + property alias modelessPopup: modelessPopup + property alias plainPopup: plainPopup + property alias modalPopupWithoutDim: modalPopupWithoutDim + visible: true + Drawer { + z: 0 + id: firstDrawer + } + Drawer { + z: 1 + id: secondDrawer + } + Popup { + id: modalPopup + z: 2 + modal: true + exit: Transition { PauseAnimation { duration: 200 } } + } + Popup { + id: modelessPopup + z: 3 + dim: true + exit: Transition { PauseAnimation { duration: 200 } } + } + Popup { + id: plainPopup + z: 4 + enter: Transition { PauseAnimation { duration: 200 } } + exit: Transition { PauseAnimation { duration: 200 } } + } + Popup { + id: modalPopupWithoutDim + z: 5 + dim: false + modal: true + exit: Transition { PauseAnimation { duration: 200 } } + } + } + } + + function indexOf(array, item) { + for (var idx = 0; idx < array.length; ++idx) { + if (item === array[idx]) + return idx; + } + return -1 + } + + function findOverlay(window, popup) { + var item = popup.contentItem.parent + var idx = indexOf(window.Overlay.overlay.children, item) + return window.Overlay.overlay.children[idx - 1] + } + + function test_overlay() { + var window = createTemporaryObject(overlayTest, testCase) + verify(window) + + window.requestActivate() + tryCompare(window, "active", true) + + compare(window.Overlay.overlay.children.length, 0) + + var firstOverlay = findOverlay(window, window.firstDrawer) + verify(!firstOverlay) + window.firstDrawer.open() + compare(window.Overlay.overlay.children.length, 2) // 1 drawer + 1 overlay + firstOverlay = findOverlay(window, window.firstDrawer) + verify(firstOverlay) + compare(firstOverlay.z, window.firstDrawer.z) + compare(indexOf(window.Overlay.overlay.children, firstOverlay), + indexOf(window.Overlay.overlay.children, window.firstDrawer.contentItem.parent) - 1) + tryCompare(firstOverlay, "opacity", 1.0) + + var secondOverlay = findOverlay(window, window.secondDrawer) + verify(!secondOverlay) + window.secondDrawer.open() + compare(window.Overlay.overlay.children.length, 4) // 2 drawers + 2 overlays + secondOverlay = findOverlay(window, window.secondDrawer) + verify(secondOverlay) + compare(secondOverlay.z, window.secondDrawer.z) + compare(indexOf(window.Overlay.overlay.children, secondOverlay), + indexOf(window.Overlay.overlay.children, window.secondDrawer.contentItem.parent) - 1) + tryCompare(secondOverlay, "opacity", 1.0) + + window.firstDrawer.close() + tryCompare(window.firstDrawer, "visible", false) + firstOverlay = findOverlay(window, window.firstDrawer) + verify(!firstOverlay) + compare(window.Overlay.overlay.children.length, 2) // 1 drawer + 1 overlay + + window.secondDrawer.close() + tryCompare(window.secondDrawer, "visible", false) + secondOverlay = findOverlay(window, window.secondDrawer) + verify(!secondOverlay) + compare(window.Overlay.overlay.children.length, 0) + + var modalOverlay = findOverlay(window, window.modalPopup) + verify(!modalOverlay) + window.modalPopup.open() + modalOverlay = findOverlay(window, window.modalPopup) + verify(modalOverlay) + compare(modalOverlay.z, window.modalPopup.z) + compare(window.modalPopup.visible, true) + tryCompare(modalOverlay, "opacity", 1.0) + compare(window.Overlay.overlay.children.length, 2) // 1 popup + 1 overlay + + var modelessOverlay = findOverlay(window, window.modelessPopup) + verify(!modelessOverlay) + window.modelessPopup.open() + modelessOverlay = findOverlay(window, window.modelessPopup) + verify(modelessOverlay) + compare(modelessOverlay.z, window.modelessPopup.z) + compare(window.modelessPopup.visible, true) + tryCompare(modelessOverlay, "opacity", 1.0) + compare(window.Overlay.overlay.children.length, 4) // 2 popups + 2 overlays + + window.modelessPopup.close() + tryCompare(window.modelessPopup, "visible", false) + modelessOverlay = findOverlay(window, window.modelessPopup) + verify(!modelessOverlay) + compare(window.Overlay.overlay.children.length, 2) // 1 popup + 1 overlay + + compare(window.modalPopup.visible, true) + compare(modalOverlay.opacity, 1.0) + + window.modalPopup.close() + tryCompare(window.modalPopup, "visible", false) + modalOverlay = findOverlay(window, window.modalPopup) + verify(!modalOverlay) + compare(window.Overlay.overlay.children.length, 0) + + window.plainPopup.open() + tryCompare(window.plainPopup, "visible", true) + compare(window.Overlay.overlay.children.length, 1) // only popup added, no overlays involved + + window.plainPopup.modal = true + compare(window.Overlay.overlay.children.length, 2) // overlay added + + window.plainPopup.close() + tryCompare(window.plainPopup, "visible", false) + compare(window.Overlay.overlay.children.length, 0) // popup + overlay removed + + window.modalPopupWithoutDim.open() + tryCompare(window.modalPopupWithoutDim, "visible", true) + compare(window.Overlay.overlay.children.length, 1) // only popup added, no overlays involved + + window.modalPopupWithoutDim.dim = true + compare(window.Overlay.overlay.children.length, 2) // overlay added + + window.modalPopupWithoutDim.close() + tryCompare(window.modalPopupWithoutDim, "visible", false) + compare(window.Overlay.overlay.children.length, 0) // popup + overlay removed + } + + function test_attached_applicationwindow() { + var control = createTemporaryObject(popupControl, applicationWindow.contentItem) + verify(control) + + var child = rect.createObject(control.contentItem) + + compare(control.ApplicationWindow.window, applicationWindow) + compare(control.contentItem.ApplicationWindow.window, applicationWindow) + compare(child.ApplicationWindow.window, applicationWindow) + + control.parent = null + compare(control.ApplicationWindow.window, null) + compare(control.contentItem.ApplicationWindow.window, null) + compare(child.ApplicationWindow.window, null) + } + + Component { + id: pausePopup + Popup { + enter: Transition { PauseAnimation { duration: 200 } } + exit: Transition { PauseAnimation { duration: 200 } } + } + } + + function test_openedClosed() { + var control = createTemporaryObject(pausePopup, testCase) + verify(control) + + var openedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "opened"}) + verify(openedSpy.valid) + var closedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "closed"}) + verify(closedSpy.valid) + var openedChangeSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "openedChanged"}) + verify(openedChangeSpy.valid) + + control.open() + compare(control.visible, true) + compare(control.opened, false) + compare(openedChangeSpy.count, 0) + compare(openedSpy.count, 0) + tryCompare(openedSpy, "count", 1) + compare(control.opened, true) + compare(openedChangeSpy.count, 1) + compare(closedSpy.count, 0) + + control.close() + compare(control.visible, true) + compare(control.opened, false) + compare(openedChangeSpy.count, 2) + compare(openedSpy.count, 1) + compare(closedSpy.count, 0) + tryCompare(closedSpy, "count", 1) + compare(control.opened, false) + compare(openedChangeSpy.count, 2) + compare(control.visible, false) + } + + Component { + id: xyBindingLoop + ApplicationWindow { + id: window + width: 360 + height: 360 + visible: true + property alias popup: popup + + Popup { + id: popup + visible: true + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + Label { + text: "Content" + anchors.fill: parent + } + } + } + } + + function test_xyBindingLoop() { + var window = createTemporaryObject(xyBindingLoop, testCase) + var control = window.popup + waitForRendering(control.contentItem) + compare(control.x, (control.parent.width - control.width) / 2) + compare(control.y, (control.parent.height - control.height) / 2) + } + + function test_windowParent() { + var control = createTemporaryObject(popupControl, applicationWindow, {width: 100, height: 100}) + verify(control) + + control.open() + verify(control.visible) + } + + function test_deferredBackgroundSize() { + var control = createTemporaryObject(popupControl, testCase, {width: 200, height: 100}) + verify(control) + + compare(control.background.width, 200 + (control.background.leftInset || 0) + (control.background.rightInset || 0)) + compare(control.background.height, 100 + (control.background.topInset || 0) + (control.background.bottomInset || 0)) + } + + function test_anchors() { + var control = createTemporaryObject(popupControl, applicationWindow.contentItem.Overlay.overlay, + { visible: true, width: 100, height: 100 }) + verify(control) + verify(control.visible) + // If there is a transition then make sure it is finished + if (control.enter !== null) + tryCompare(control.enter, "running", false) + compare(control.parent, control.Overlay.overlay) + compare(control.x, 0) + compare(control.y, 0) + + var overlay = control.Overlay.overlay + verify(overlay) + + var centerInSpy = createTemporaryObject(signalSpy, testCase, { target: control.anchors, signalName: "centerInChanged" }) + verify(centerInSpy.valid) + + applicationWindow.visible = true + verify(waitForRendering(applicationWindow.contentItem)) + verify(overlay.width > 0) + verify(overlay.height > 0) + + // Center the popup in the window via the overlay. + control.anchors.centerIn = Qt.binding(function() { return control.parent; }) + compare(centerInSpy.count, 1) + compare(control.x, (overlay.width - (control.width * control.scale)) / 2) + compare(control.y, (overlay.height - (control.width * control.scale)) / 2) + + // Ensure that it warns when trying to set it to an item that's not its parent. + var anotherItem = createTemporaryObject(rect, applicationWindow.contentItem, { x: 100, y: 100, width: 50, height: 50 }) + verify(anotherItem) + + ignoreWarning(Qt.resolvedUrl("tst_popup.qml") + ":77:9: QML Popup: Popup can only be centered within its immediate parent or Overlay.overlay") + control.anchors.centerIn = anotherItem + // The property will change, because we can't be sure that the parent + // in QQuickPopupAnchors::setCenterIn() is the final parent, as some reparenting can happen. + // We still expect the warning from QQuickPopupPositioner::reposition() though. + compare(centerInSpy.count, 2) + compare(control.anchors.centerIn, anotherItem) + + // The binding to the popup's parent was broken above, so restore it. + control.anchors.centerIn = Qt.binding(function() { return control.parent; }) + compare(centerInSpy.count, 3) + + // Change the popup's parent and ensure that it's anchored accordingly. + control.parent = Qt.binding(function() { return anotherItem; }) + compare(control.parent, anotherItem) + compare(control.anchors.centerIn, anotherItem) + compare(centerInSpy.count, 4) + compare(control.x, (anotherItem.width - (control.width * control.scale)) / 2) + compare(control.y, (anotherItem.height - (control.height * control.scale)) / 2) + + // Check that anchors.centerIn beats x and y coordinates as it does in QQuickItem. + control.x = 33; + control.y = 44; + compare(control.x, (anotherItem.width - (control.width * control.scale)) / 2) + compare(control.y, (anotherItem.height - (control.height * control.scale)) / 2) + + // Check that the popup's x and y coordinates are restored when it's no longer centered. + control.anchors.centerIn = undefined + compare(centerInSpy.count, 5) + compare(control.x, 33) + compare(control.y, 44) + + // Test centering in the overlay while having a different parent (anotherItem). + control.anchors.centerIn = overlay + compare(centerInSpy.count, 6) + compare(control.x, (overlay.width - (control.width * control.scale)) / 2) + compare(control.y, (overlay.height - (control.height * control.scale)) / 2) + + // TODO: do this properly by creating a component or something + applicationWindow.visible = false + } + + Component { + id: shortcutWindowComponent + ApplicationWindow { + id: window + width: 360 + height: 360 + visible: true + + property alias popup: popup + property alias shortcut: shortcut + + Popup { + id: popup + + Shortcut { + id: shortcut + sequence: "A" + onActivated: popup.visible = !popup.visible + } + } + } + } + + function test_shortcut() { + // Tests that a Shortcut with Qt.WindowShortcut context + // that is declared within a Popup is activated. + var window = createTemporaryObject(shortcutWindowComponent, testCase) + var control = window.popup + + window.requestActivate() + tryCompare(window, "active", true) + + var shortcutActivatedSpy = createTemporaryObject(signalSpy, testCase, + { target: window.shortcut, signalName: "activated"} ) + verify(shortcutActivatedSpy.valid) + + waitForRendering(window.contentItem) + keyClick(Qt.Key_A) + compare(shortcutActivatedSpy.count, 1) + tryCompare(control, "visible", true) + + keyClick(Qt.Key_A) + compare(shortcutActivatedSpy.count, 2) + tryCompare(control, "visible", false) + } +} |