2152 lines
75 KiB
QML
2152 lines
75 KiB
QML
/****************************************************************************
|
|
**
|
|
** 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 2.15
|
|
import QtQuick.Window 2.15
|
|
import QtTest 1.15
|
|
import QtQuick.Controls 2.15
|
|
|
|
TestCase {
|
|
id: testCase
|
|
width: 400
|
|
height: 400
|
|
visible: true
|
|
when: windowShown
|
|
name: "ComboBox"
|
|
|
|
Component {
|
|
id: signalSpy
|
|
SignalSpy { }
|
|
}
|
|
|
|
Component {
|
|
id: comboBox
|
|
ComboBox { }
|
|
}
|
|
|
|
Component {
|
|
id: emptyBox
|
|
ComboBox {
|
|
delegate: ItemDelegate {
|
|
width: parent.width
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: mouseArea
|
|
MouseArea { }
|
|
}
|
|
|
|
Component {
|
|
id: customPopup
|
|
Popup {
|
|
width: 100
|
|
implicitHeight: contentItem.implicitHeight
|
|
contentItem: TextInput {
|
|
anchors.fill: parent
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: comboBoxWithShaderEffect
|
|
ComboBox {
|
|
delegate: Rectangle {
|
|
Text {
|
|
id: txt
|
|
anchors.centerIn: parent
|
|
text: "item" + index
|
|
font.pixelSize: 20
|
|
color: "red"
|
|
}
|
|
id: rect
|
|
objectName: "rect"
|
|
width: parent.width
|
|
height: txt.implicitHeight
|
|
gradient: Gradient {
|
|
GradientStop { color: "lightsteelblue"; position: 0.0 }
|
|
GradientStop { color: "blue"; position: 1.0 }
|
|
}
|
|
layer.enabled: true
|
|
layer.effect: ShaderEffect {
|
|
objectName: "ShaderFX"
|
|
width: rect.width
|
|
height: rect.height
|
|
fragmentShader: "
|
|
uniform lowp sampler2D source; // this item
|
|
uniform lowp float qt_Opacity; // inherited opacity of this item
|
|
varying highp vec2 qt_TexCoord0;
|
|
void main() {
|
|
lowp vec4 p = texture2D(source, qt_TexCoord0);
|
|
lowp float g = dot(p.xyz, vec3(0.344, 0.5, 0.156));
|
|
gl_FragColor = vec4(g, g, g, p.a) * qt_Opacity;
|
|
}"
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function init() {
|
|
// QTBUG-61225: Move the mouse away to avoid QQuickWindowPrivate::flushFrameSynchronousEvents()
|
|
// delivering interfering hover events based on the last mouse position from earlier tests. For
|
|
// example, ComboBox::test_activation() kept receiving hover events for the last mouse position
|
|
// from CheckDelegate::test_checked().
|
|
mouseMove(testCase, testCase.width - 1, testCase.height - 1)
|
|
}
|
|
|
|
function test_defaults() {
|
|
var control = createTemporaryObject(comboBox, testCase)
|
|
verify(control)
|
|
|
|
compare(control.count, 0)
|
|
compare(control.model, undefined)
|
|
compare(control.flat, false)
|
|
compare(control.pressed, false)
|
|
compare(control.currentIndex, -1)
|
|
compare(control.highlightedIndex, -1)
|
|
compare(control.currentText, "")
|
|
verify(control.delegate)
|
|
verify(control.indicator)
|
|
verify(control.popup)
|
|
}
|
|
|
|
function test_array() {
|
|
var control = createTemporaryObject(comboBox, testCase)
|
|
verify(control)
|
|
|
|
var items = [ "Banana", "Apple", "Coconut" ]
|
|
|
|
control.model = items
|
|
compare(control.model, items)
|
|
|
|
compare(control.count, 3)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "Banana")
|
|
|
|
control.currentIndex = 2
|
|
compare(control.currentIndex, 2)
|
|
compare(control.currentText, "Coconut")
|
|
|
|
control.model = null
|
|
compare(control.model, null)
|
|
compare(control.count, 0)
|
|
compare(control.currentIndex, -1)
|
|
compare(control.currentText, "")
|
|
}
|
|
|
|
function test_objects() {
|
|
var control = createTemporaryObject(emptyBox, testCase)
|
|
verify(control)
|
|
|
|
var items = [
|
|
{ text: "Apple" },
|
|
{ text: "Orange" },
|
|
{ text: "Banana" }
|
|
]
|
|
|
|
control.model = items
|
|
compare(control.model, items)
|
|
|
|
compare(control.count, 3)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "Apple")
|
|
|
|
control.currentIndex = 2
|
|
compare(control.currentIndex, 2)
|
|
compare(control.currentText, "Banana")
|
|
|
|
control.model = null
|
|
compare(control.model, null)
|
|
compare(control.count, 0)
|
|
compare(control.currentIndex, -1)
|
|
compare(control.currentText, "")
|
|
}
|
|
|
|
function test_qobjects() {
|
|
var control = createTemporaryObject(emptyBox, testCase, {textRole: "text"})
|
|
verify(control)
|
|
|
|
var obj1 = Qt.createQmlObject("import QtQml 2.0; QtObject { property string text: 'one' }", control)
|
|
var obj2 = Qt.createQmlObject("import QtQml 2.0; QtObject { property string text: 'two' }", control)
|
|
var obj3 = Qt.createQmlObject("import QtQml 2.0; QtObject { property string text: 'three' }", control)
|
|
|
|
control.model = [obj1, obj2, obj3]
|
|
|
|
compare(control.count, 3)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "one")
|
|
|
|
control.currentIndex = 2
|
|
compare(control.currentIndex, 2)
|
|
compare(control.currentText, "three")
|
|
|
|
control.model = null
|
|
compare(control.model, null)
|
|
compare(control.count, 0)
|
|
compare(control.currentIndex, -1)
|
|
compare(control.currentText, "")
|
|
}
|
|
|
|
function test_number() {
|
|
var control = createTemporaryObject(comboBox, testCase)
|
|
verify(control)
|
|
|
|
control.model = 10
|
|
compare(control.model, 10)
|
|
|
|
compare(control.count, 10)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "0")
|
|
|
|
control.currentIndex = 9
|
|
compare(control.currentIndex, 9)
|
|
compare(control.currentText, "9")
|
|
|
|
control.model = 0
|
|
compare(control.model, 0)
|
|
compare(control.count, 0)
|
|
compare(control.currentIndex, -1)
|
|
compare(control.currentText, "")
|
|
}
|
|
|
|
ListModel {
|
|
id: listmodel
|
|
ListElement { text: "First" }
|
|
ListElement { text: "Second" }
|
|
ListElement { text: "Third" }
|
|
ListElement { text: "Fourth" }
|
|
ListElement { text: "Fifth" }
|
|
}
|
|
|
|
function test_listModel() {
|
|
var control = createTemporaryObject(comboBox, testCase)
|
|
verify(control)
|
|
|
|
control.model = listmodel
|
|
compare(control.model, listmodel)
|
|
|
|
compare(control.count, 5)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "First")
|
|
|
|
control.currentIndex = 2
|
|
compare(control.currentIndex, 2)
|
|
compare(control.currentText, "Third")
|
|
|
|
control.model = undefined
|
|
compare(control.model, undefined)
|
|
compare(control.count, 0)
|
|
compare(control.currentIndex, -1)
|
|
compare(control.currentText, "")
|
|
}
|
|
|
|
ListModel {
|
|
id: fruitmodel
|
|
ListElement { name: "Apple"; color: "red" }
|
|
ListElement { name: "Orange"; color: "orange" }
|
|
ListElement { name: "Banana"; color: "yellow" }
|
|
}
|
|
|
|
Component {
|
|
id: fruitModelComponent
|
|
ListModel {
|
|
ListElement { name: "Apple"; color: "red" }
|
|
ListElement { name: "Orange"; color: "orange" }
|
|
ListElement { name: "Banana"; color: "yellow" }
|
|
}
|
|
}
|
|
|
|
property var fruitarray: [
|
|
{ name: "Apple", color: "red" },
|
|
{ name: "Orange", color: "orange" },
|
|
{ name: "Banana", color: "yellow" }
|
|
]
|
|
|
|
Component {
|
|
id: birdModelComponent
|
|
ListModel {
|
|
ListElement { name: "Galah"; color: "pink" }
|
|
ListElement { name: "Kookaburra"; color: "brown" }
|
|
ListElement { name: "Magpie"; color: "black" }
|
|
}
|
|
}
|
|
|
|
function test_textRole_data() {
|
|
return [
|
|
{ tag: "ListModel", model: fruitmodel },
|
|
{ tag: "ObjectArray", model: fruitarray }
|
|
]
|
|
}
|
|
|
|
function test_textRole(data) {
|
|
var control = createTemporaryObject(emptyBox, testCase)
|
|
verify(control)
|
|
|
|
control.model = data.model
|
|
compare(control.count, 3)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "")
|
|
|
|
control.textRole = "name"
|
|
compare(control.currentText, "Apple")
|
|
|
|
control.textRole = "color"
|
|
compare(control.currentText, "red")
|
|
|
|
control.currentIndex = 1
|
|
compare(control.currentIndex, 1)
|
|
compare(control.currentText, "orange")
|
|
|
|
control.textRole = "name"
|
|
compare(control.currentText, "Orange")
|
|
|
|
control.textRole = ""
|
|
compare(control.currentText, "")
|
|
}
|
|
|
|
function test_textAt() {
|
|
var control = createTemporaryObject(comboBox, testCase)
|
|
verify(control)
|
|
|
|
control.model = ["Apple", "Orange", "Banana"]
|
|
compare(control.textAt(0), "Apple")
|
|
compare(control.textAt(1), "Orange")
|
|
compare(control.textAt(2), "Banana")
|
|
compare(control.textAt(-1), "") // TODO: null?
|
|
compare(control.textAt(5), "") // TODO: null?
|
|
}
|
|
|
|
function test_find_data() {
|
|
return [
|
|
{ tag: "Banana (MatchExactly)", term: "Banana", flags: Qt.MatchExactly, index: 0 },
|
|
{ tag: "banana (MatchExactly)", term: "banana", flags: Qt.MatchExactly, index: 1 },
|
|
{ tag: "bananas (MatchExactly)", term: "bananas", flags: Qt.MatchExactly, index: -1 },
|
|
{ tag: "Cocomuffin (MatchExactly)", term: "Cocomuffin", flags: Qt.MatchExactly, index: 4 },
|
|
|
|
{ tag: "b(an)+a (MatchRegularExpression)", term: "B(an)+a", flags: Qt.MatchRegularExpression, index: 0 },
|
|
{ tag: "b(an)+a (MatchRegularExpression|MatchCaseSensitive)", term: "b(an)+a", flags: Qt.MatchRegularExpression | Qt.MatchCaseSensitive, index: 1 },
|
|
{ tag: "[coc]+\\w+ (MatchRegularExpression)", term: "[coc]+\\w+", flags: Qt.MatchRegularExpression, index: 2 },
|
|
|
|
{ tag: "?pp* (MatchWildcard)", term: "?pp*", flags: Qt.MatchWildcard, index: 3 },
|
|
{ tag: "app* (MatchWildcard|MatchCaseSensitive)", term: "app*", flags: Qt.MatchWildcard | Qt.MatchCaseSensitive, index: -1 },
|
|
|
|
{ tag: "Banana (MatchFixedString)", term: "Banana", flags: Qt.MatchFixedString, index: 0 },
|
|
{ tag: "banana (MatchFixedString|MatchCaseSensitive)", term: "banana", flags: Qt.MatchFixedString | Qt.MatchCaseSensitive, index: 1 },
|
|
|
|
{ tag: "coco (MatchStartsWith)", term: "coco", flags: Qt.MatchStartsWith, index: 2 },
|
|
{ tag: "coco (MatchStartsWith|MatchCaseSensitive)", term: "coco", flags: Qt.StartsWith | Qt.MatchCaseSensitive, index: -1 },
|
|
|
|
{ tag: "MUFFIN (MatchEndsWith)", term: "MUFFIN", flags: Qt.MatchEndsWith, index: 4 },
|
|
{ tag: "MUFFIN (MatchEndsWith|MatchCaseSensitive)", term: "MUFFIN", flags: Qt.MatchEndsWith | Qt.MatchCaseSensitive, index: -1 },
|
|
|
|
{ tag: "Con (MatchContains)", term: "Con", flags: Qt.MatchContains, index: 2 },
|
|
{ tag: "Con (MatchContains|MatchCaseSensitive)", term: "Con", flags: Qt.MatchContains | Qt.MatchCaseSensitive, index: -1 },
|
|
]
|
|
}
|
|
|
|
function test_find(data) {
|
|
var control = createTemporaryObject(comboBox, testCase)
|
|
verify(control)
|
|
|
|
control.model = ["Banana", "banana", "Coconut", "Apple", "Cocomuffin"]
|
|
|
|
compare(control.find(data.term, data.flags), data.index)
|
|
}
|
|
|
|
function test_valueRole_data() {
|
|
return [
|
|
{ tag: "ListModel", model: fruitmodel },
|
|
{ tag: "ObjectArray", model: fruitarray }
|
|
]
|
|
}
|
|
|
|
function test_valueRole(data) {
|
|
var control = createTemporaryObject(emptyBox, testCase,
|
|
{ model: data.model, valueRole: "color" })
|
|
verify(control)
|
|
compare(control.count, 3)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentValue, "red")
|
|
|
|
control.valueRole = "name"
|
|
compare(control.currentValue, "Apple")
|
|
|
|
control.currentIndex = 1
|
|
compare(control.currentIndex, 1)
|
|
compare(control.currentValue, "Orange")
|
|
|
|
control.valueRole = "color"
|
|
compare(control.currentValue, "orange")
|
|
|
|
control.model = null
|
|
compare(control.currentIndex, -1)
|
|
// An invalid QVariant is represented as undefined.
|
|
compare(control.currentValue, undefined)
|
|
|
|
control.valueRole = ""
|
|
compare(control.currentValue, undefined)
|
|
}
|
|
|
|
function test_valueAt() {
|
|
var control = createTemporaryObject(comboBox, testCase,
|
|
{ model: fruitmodel, textRole: "name", valueRole: "color" })
|
|
verify(control)
|
|
|
|
compare(control.valueAt(0), "red")
|
|
compare(control.valueAt(1), "orange")
|
|
compare(control.valueAt(2), "yellow")
|
|
compare(control.valueAt(-1), undefined)
|
|
compare(control.valueAt(5), undefined)
|
|
}
|
|
|
|
function test_indexOfValue_data() {
|
|
return [
|
|
{ tag: "red", expectedIndex: 0 },
|
|
{ tag: "orange", expectedIndex: 1 },
|
|
{ tag: "yellow", expectedIndex: 2 },
|
|
{ tag: "brown", expectedIndex: -1 },
|
|
]
|
|
}
|
|
|
|
function test_indexOfValue(data) {
|
|
var control = createTemporaryObject(comboBox, testCase,
|
|
{ model: fruitmodel, textRole: "name", valueRole: "color" })
|
|
verify(control)
|
|
|
|
compare(control.indexOfValue(data.tag), data.expectedIndex)
|
|
}
|
|
|
|
function test_currentValueAfterModelChanged() {
|
|
let fruitModel = createTemporaryObject(fruitModelComponent, testCase)
|
|
verify(fruitModel)
|
|
|
|
let control = createTemporaryObject(comboBox, testCase,
|
|
{ model: fruitModel, textRole: "name", valueRole: "color", currentIndex: 1 })
|
|
verify(control)
|
|
compare(control.currentText, "Orange")
|
|
compare(control.currentValue, "orange")
|
|
|
|
// Remove "Apple"; the current item should now be "Banana", so currentValue should be "yellow".
|
|
fruitModel.remove(0)
|
|
compare(control.currentText, "Banana")
|
|
compare(control.currentValue, "yellow")
|
|
}
|
|
|
|
function test_currentValueAfterNewModelSet() {
|
|
let control = createTemporaryObject(comboBox, testCase,
|
|
{ model: fruitmodel, textRole: "name", valueRole: "color", currentIndex: 0 })
|
|
verify(control)
|
|
compare(control.currentText, "Apple")
|
|
compare(control.currentValue, "red")
|
|
|
|
// Swap the model out entirely. Since the currentIndex was 0 and
|
|
// is reset to 0 when a new model is set, it remains 0.
|
|
let birdModel = createTemporaryObject(birdModelComponent, testCase)
|
|
verify(birdModel)
|
|
control.model = birdModel
|
|
compare(control.currentText, "Galah")
|
|
compare(control.currentValue, "pink")
|
|
}
|
|
|
|
function test_arrowKeys() {
|
|
var control = createTemporaryObject(comboBox, testCase,
|
|
{ model: fruitmodel, textRole: "name", valueRole: "color" })
|
|
verify(control)
|
|
|
|
var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"})
|
|
verify(activatedSpy.valid)
|
|
|
|
var highlightedSpy = signalSpy.createObject(control, {target: control, signalName: "highlighted"})
|
|
verify(highlightedSpy.valid)
|
|
|
|
var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"})
|
|
verify(openedSpy.valid)
|
|
|
|
var closedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "closed"})
|
|
verify(closedSpy.valid)
|
|
|
|
control.forceActiveFocus()
|
|
verify(control.activeFocus)
|
|
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
keyClick(Qt.Key_Down)
|
|
compare(control.currentIndex, 1)
|
|
compare(control.highlightedIndex, -1)
|
|
compare(highlightedSpy.count, 0)
|
|
compare(activatedSpy.count, 1)
|
|
compare(activatedSpy.signalArguments[0][0], 1)
|
|
activatedSpy.clear()
|
|
|
|
keyClick(Qt.Key_Down)
|
|
compare(control.currentIndex, 2)
|
|
compare(control.highlightedIndex, -1)
|
|
compare(highlightedSpy.count, 0)
|
|
compare(activatedSpy.count, 1)
|
|
compare(activatedSpy.signalArguments[0][0], 2)
|
|
activatedSpy.clear()
|
|
|
|
keyClick(Qt.Key_Down)
|
|
compare(control.currentIndex, 2)
|
|
compare(control.highlightedIndex, -1)
|
|
compare(highlightedSpy.count, 0)
|
|
compare(activatedSpy.count, 0)
|
|
|
|
keyClick(Qt.Key_Up)
|
|
compare(control.currentIndex, 1)
|
|
compare(control.highlightedIndex, -1)
|
|
compare(highlightedSpy.count, 0)
|
|
compare(activatedSpy.count, 1)
|
|
compare(activatedSpy.signalArguments[0][0], 1)
|
|
activatedSpy.clear()
|
|
|
|
keyClick(Qt.Key_Up)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, -1)
|
|
compare(highlightedSpy.count, 0)
|
|
compare(activatedSpy.count, 1)
|
|
compare(activatedSpy.signalArguments[0][0], 0)
|
|
activatedSpy.clear()
|
|
|
|
keyClick(Qt.Key_Up)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, -1)
|
|
compare(highlightedSpy.count, 0)
|
|
compare(activatedSpy.count, 0)
|
|
|
|
// show popup
|
|
keyClick(Qt.Key_Space)
|
|
openedSpy.wait()
|
|
compare(openedSpy.count, 1)
|
|
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, 0)
|
|
|
|
keyClick(Qt.Key_Down)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, 1)
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 1)
|
|
compare(highlightedSpy.signalArguments[0][0], 1)
|
|
highlightedSpy.clear()
|
|
|
|
keyClick(Qt.Key_Down)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, 2)
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 1)
|
|
compare(highlightedSpy.signalArguments[0][0], 2)
|
|
highlightedSpy.clear()
|
|
|
|
keyClick(Qt.Key_Down)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, 2)
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 0)
|
|
|
|
keyClick(Qt.Key_Up)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, 1)
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 1)
|
|
compare(highlightedSpy.signalArguments[0][0], 1)
|
|
highlightedSpy.clear()
|
|
|
|
keyClick(Qt.Key_Up)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, 0)
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 1)
|
|
compare(highlightedSpy.signalArguments[0][0], 0)
|
|
highlightedSpy.clear()
|
|
|
|
keyClick(Qt.Key_Up)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, 0)
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 0)
|
|
|
|
keyClick(Qt.Key_Down)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, 1)
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 1)
|
|
compare(highlightedSpy.signalArguments[0][0], 1)
|
|
highlightedSpy.clear()
|
|
|
|
// hide popup
|
|
keyClick(Qt.Key_Space)
|
|
closedSpy.wait()
|
|
compare(closedSpy.count, 1)
|
|
|
|
compare(control.currentIndex, 1)
|
|
compare(control.highlightedIndex, -1)
|
|
}
|
|
|
|
function test_keys_space_enter_escape_data() {
|
|
return [
|
|
{ tag: "space-space", key1: Qt.Key_Space, key2: Qt.Key_Space, showPopup: true, showPress: true, hidePopup: true, hidePress: true },
|
|
{ tag: "space-enter", key1: Qt.Key_Space, key2: Qt.Key_Enter, showPopup: true, showPress: true, hidePopup: true, hidePress: true },
|
|
{ tag: "space-return", key1: Qt.Key_Space, key2: Qt.Key_Return, showPopup: true, showPress: true, hidePopup: true, hidePress: true },
|
|
{ tag: "space-escape", key1: Qt.Key_Space, key2: Qt.Key_Escape, showPopup: true, showPress: true, hidePopup: true, hidePress: false },
|
|
{ tag: "space-0", key1: Qt.Key_Space, key2: Qt.Key_0, showPopup: true, showPress: true, hidePopup: false, hidePress: false },
|
|
{ tag: "enter-enter", key1: Qt.Key_Enter, key2: Qt.Key_Enter, showPopup: false, showPress: false, hidePopup: true, hidePress: false },
|
|
{ tag: "return-return", key1: Qt.Key_Return, key2: Qt.Key_Return, showPopup: false, showPress: false, hidePopup: true, hidePress: false },
|
|
{ tag: "escape-escape", key1: Qt.Key_Escape, key2: Qt.Key_Escape, showPopup: false, showPress: false, hidePopup: true, hidePress: false }
|
|
]
|
|
}
|
|
|
|
function test_keys_space_enter_escape(data) {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 3})
|
|
verify(control)
|
|
|
|
var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"})
|
|
verify(openedSpy.valid)
|
|
|
|
control.forceActiveFocus()
|
|
verify(control.activeFocus)
|
|
|
|
compare(control.pressed, false)
|
|
compare(control.popup.visible, false)
|
|
|
|
// show popup
|
|
keyPress(data.key1)
|
|
compare(control.pressed, data.showPress)
|
|
compare(control.popup.visible, false)
|
|
keyRelease(data.key1)
|
|
compare(control.pressed, false)
|
|
compare(control.popup.visible, data.showPopup)
|
|
if (data.showPopup)
|
|
openedSpy.wait()
|
|
|
|
// hide popup
|
|
keyPress(data.key2)
|
|
compare(control.pressed, data.hidePress)
|
|
keyRelease(data.key2)
|
|
compare(control.pressed, false)
|
|
tryCompare(control.popup, "visible", !data.hidePopup)
|
|
}
|
|
|
|
function test_keys_home_end() {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 5})
|
|
verify(control)
|
|
|
|
control.forceActiveFocus()
|
|
verify(control.activeFocus)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
var activatedCount = 0
|
|
var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"})
|
|
verify(activatedSpy.valid)
|
|
|
|
var highlightedCount = 0
|
|
var highlightedSpy = signalSpy.createObject(control, {target: control, signalName: "highlighted"})
|
|
verify(highlightedSpy.valid)
|
|
|
|
var currentIndexCount = 0
|
|
var currentIndexSpy = signalSpy.createObject(control, {target: control, signalName: "currentIndexChanged"})
|
|
verify(currentIndexSpy.valid)
|
|
|
|
var highlightedIndexCount = 0
|
|
var highlightedIndexSpy = signalSpy.createObject(control, {target: control, signalName: "highlightedIndexChanged"})
|
|
verify(highlightedIndexSpy.valid)
|
|
|
|
// end (popup closed)
|
|
keyClick(Qt.Key_End)
|
|
compare(control.currentIndex, 4)
|
|
compare(currentIndexSpy.count, ++currentIndexCount)
|
|
|
|
compare(control.highlightedIndex, -1)
|
|
compare(highlightedIndexSpy.count, highlightedIndexCount)
|
|
|
|
compare(activatedSpy.count, ++activatedCount)
|
|
compare(activatedSpy.signalArguments[activatedCount-1][0], 4)
|
|
|
|
compare(highlightedSpy.count, highlightedCount)
|
|
|
|
// repeat (no changes/signals)
|
|
keyClick(Qt.Key_End)
|
|
compare(currentIndexSpy.count, currentIndexCount)
|
|
compare(highlightedIndexSpy.count, highlightedIndexCount)
|
|
compare(activatedSpy.count, activatedCount)
|
|
compare(highlightedSpy.count, highlightedCount)
|
|
|
|
// home (popup closed)
|
|
keyClick(Qt.Key_Home)
|
|
compare(control.currentIndex, 0)
|
|
compare(currentIndexSpy.count, ++currentIndexCount)
|
|
|
|
compare(control.highlightedIndex, -1)
|
|
compare(highlightedIndexSpy.count, highlightedIndexCount)
|
|
|
|
compare(activatedSpy.count, ++activatedCount)
|
|
compare(activatedSpy.signalArguments[activatedCount-1][0], 0)
|
|
|
|
compare(highlightedSpy.count, highlightedCount)
|
|
|
|
// repeat (no changes/signals)
|
|
keyClick(Qt.Key_Home)
|
|
compare(currentIndexSpy.count, currentIndexCount)
|
|
compare(highlightedIndexSpy.count, highlightedIndexCount)
|
|
compare(activatedSpy.count, activatedCount)
|
|
compare(highlightedSpy.count, highlightedCount)
|
|
|
|
control.popup.open()
|
|
compare(control.highlightedIndex, 0)
|
|
compare(highlightedIndexSpy.count, ++highlightedIndexCount)
|
|
compare(highlightedSpy.count, highlightedCount)
|
|
|
|
// end (popup open)
|
|
keyClick(Qt.Key_End)
|
|
compare(control.currentIndex, 0)
|
|
compare(currentIndexSpy.count, currentIndexCount)
|
|
|
|
compare(control.highlightedIndex, 4)
|
|
compare(highlightedIndexSpy.count, ++highlightedIndexCount)
|
|
|
|
compare(activatedSpy.count, activatedCount)
|
|
|
|
compare(highlightedSpy.count, ++highlightedCount)
|
|
compare(highlightedSpy.signalArguments[highlightedCount-1][0], 4)
|
|
|
|
// repeat (no changes/signals)
|
|
keyClick(Qt.Key_End)
|
|
compare(currentIndexSpy.count, currentIndexCount)
|
|
compare(highlightedIndexSpy.count, highlightedIndexCount)
|
|
compare(activatedSpy.count, activatedCount)
|
|
compare(highlightedSpy.count, highlightedCount)
|
|
|
|
// home (popup open)
|
|
keyClick(Qt.Key_Home)
|
|
compare(control.currentIndex, 0)
|
|
compare(currentIndexSpy.count, currentIndexCount)
|
|
|
|
compare(control.highlightedIndex, 0)
|
|
compare(highlightedIndexSpy.count, ++highlightedIndexCount)
|
|
|
|
compare(activatedSpy.count, activatedCount)
|
|
|
|
compare(highlightedSpy.count, ++highlightedCount)
|
|
compare(highlightedSpy.signalArguments[highlightedCount-1][0], 0)
|
|
|
|
// repeat (no changes/signals)
|
|
keyClick(Qt.Key_Home)
|
|
compare(currentIndexSpy.count, currentIndexCount)
|
|
compare(highlightedIndexSpy.count, highlightedIndexCount)
|
|
compare(activatedSpy.count, activatedCount)
|
|
compare(highlightedSpy.count, highlightedCount)
|
|
}
|
|
|
|
function test_keySearch() {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: ["Banana", "Coco", "Coconut", "Apple", "Cocomuffin"]})
|
|
verify(control)
|
|
|
|
control.forceActiveFocus()
|
|
verify(control.activeFocus)
|
|
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "Banana")
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
keyPress(Qt.Key_C)
|
|
compare(control.currentIndex, 1)
|
|
compare(control.currentText, "Coco")
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
// no match
|
|
keyPress(Qt.Key_N)
|
|
compare(control.currentIndex, 1)
|
|
compare(control.currentText, "Coco")
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
keyPress(Qt.Key_C)
|
|
compare(control.currentIndex, 2)
|
|
compare(control.currentText, "Coconut")
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
keyPress(Qt.Key_C)
|
|
compare(control.currentIndex, 4)
|
|
compare(control.currentText, "Cocomuffin")
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
// wrap
|
|
keyPress(Qt.Key_C)
|
|
compare(control.currentIndex, 1)
|
|
compare(control.currentText, "Coco")
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
keyPress(Qt.Key_A)
|
|
compare(control.currentIndex, 3)
|
|
compare(control.currentText, "Apple")
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
keyPress(Qt.Key_B)
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "Banana")
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
// popup
|
|
control.popup.open()
|
|
tryCompare(control.popup, "opened", true)
|
|
|
|
compare(control.currentIndex, 0)
|
|
compare(control.highlightedIndex, 0)
|
|
|
|
keyClick(Qt.Key_C)
|
|
compare(control.highlightedIndex, 1) // "Coco"
|
|
compare(control.currentIndex, 0)
|
|
|
|
// no match
|
|
keyClick(Qt.Key_N)
|
|
compare(control.highlightedIndex, 1)
|
|
compare(control.currentIndex, 0)
|
|
|
|
keyClick(Qt.Key_C)
|
|
compare(control.highlightedIndex, 2) // "Coconut"
|
|
compare(control.currentIndex, 0)
|
|
|
|
keyClick(Qt.Key_C)
|
|
compare(control.highlightedIndex, 4) // "Cocomuffin"
|
|
compare(control.currentIndex, 0)
|
|
|
|
// wrap
|
|
keyClick(Qt.Key_C)
|
|
compare(control.highlightedIndex, 1) // "Coco"
|
|
compare(control.currentIndex, 0)
|
|
|
|
keyClick(Qt.Key_B)
|
|
compare(control.highlightedIndex, 0) // "Banana"
|
|
compare(control.currentIndex, 0)
|
|
|
|
keyClick(Qt.Key_A)
|
|
compare(control.highlightedIndex, 3) // "Apple"
|
|
compare(control.currentIndex, 0)
|
|
|
|
verify(control.popup.visible)
|
|
|
|
// accept
|
|
keyClick(Qt.Key_Return)
|
|
tryCompare(control.popup, "visible", false)
|
|
compare(control.currentIndex, 3)
|
|
compare(control.currentText, "Apple")
|
|
compare(control.highlightedIndex, -1)
|
|
}
|
|
|
|
function test_popup() {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 3})
|
|
verify(control)
|
|
|
|
// show below
|
|
mousePress(control)
|
|
compare(control.pressed, true)
|
|
compare(control.popup.visible, false)
|
|
mouseRelease(control)
|
|
compare(control.pressed, false)
|
|
compare(control.popup.visible, true)
|
|
verify(control.popup.contentItem.y >= control.y)
|
|
|
|
// hide
|
|
mouseClick(control)
|
|
compare(control.pressed, false)
|
|
tryCompare(control.popup, "visible", false)
|
|
|
|
// show above
|
|
control.y = control.Window.height - control.height
|
|
mousePress(control)
|
|
compare(control.pressed, true)
|
|
compare(control.popup.visible, false)
|
|
mouseRelease(control)
|
|
compare(control.pressed, false)
|
|
compare(control.popup.visible, true)
|
|
verify(control.popup.contentItem.y < control.y)
|
|
|
|
// follow the control outside the horizontal window bounds
|
|
control.x = -control.width / 2
|
|
compare(control.x, -control.width / 2)
|
|
compare(control.popup.contentItem.parent.x, -control.width / 2)
|
|
control.x = testCase.width - control.width / 2
|
|
compare(control.x, testCase.width - control.width / 2)
|
|
compare(control.popup.contentItem.parent.x, testCase.width - control.width / 2)
|
|
|
|
// close the popup when hidden (QTBUG-67684)
|
|
control.popup.open()
|
|
tryCompare(control.popup, "opened", true)
|
|
control.visible = false
|
|
tryCompare(control.popup, "visible", false)
|
|
}
|
|
|
|
function test_mouse() {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 3, hoverEnabled: false})
|
|
verify(control)
|
|
|
|
var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"})
|
|
verify(activatedSpy.valid)
|
|
|
|
mouseClick(control)
|
|
compare(control.popup.visible, true)
|
|
|
|
var content = control.popup.contentItem
|
|
waitForRendering(content)
|
|
|
|
// press - move - release outside - not activated - not closed
|
|
mousePress(content)
|
|
compare(activatedSpy.count, 0)
|
|
mouseMove(content, content.width * 2)
|
|
compare(activatedSpy.count, 0)
|
|
mouseRelease(content, content.width * 2)
|
|
compare(activatedSpy.count, 0)
|
|
compare(control.popup.visible, true)
|
|
|
|
// press - move - release inside - activated - closed
|
|
mousePress(content)
|
|
compare(activatedSpy.count, 0)
|
|
mouseMove(content, content.width / 2 + 1, content.height / 2 + 1)
|
|
compare(activatedSpy.count, 0)
|
|
mouseRelease(content)
|
|
compare(activatedSpy.count, 1)
|
|
tryCompare(control.popup, "visible", false)
|
|
}
|
|
|
|
function test_touch() {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 3})
|
|
verify(control)
|
|
|
|
var touch = touchEvent(control)
|
|
|
|
var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"})
|
|
verify(activatedSpy.valid)
|
|
|
|
var highlightedSpy = signalSpy.createObject(control, {target: control, signalName: "highlighted"})
|
|
verify(highlightedSpy.valid)
|
|
|
|
touch.press(0, control).commit()
|
|
touch.release(0, control).commit()
|
|
compare(control.popup.visible, true)
|
|
|
|
var content = control.popup.contentItem
|
|
waitForRendering(content)
|
|
|
|
// press - move - release outside - not activated - not closed
|
|
touch.press(0, control).commit()
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 0)
|
|
touch.move(0, control, control.width * 2, control.height / 2).commit()
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 0)
|
|
touch.release(0, control, control.width * 2, control.height / 2).commit()
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 0)
|
|
compare(control.popup.visible, true)
|
|
|
|
// press - move - release inside - activated - closed
|
|
touch.press(0, content).commit()
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 0)
|
|
touch.move(0, content, content.width / 2 + 1, content.height / 2 + 1).commit()
|
|
compare(activatedSpy.count, 0)
|
|
compare(highlightedSpy.count, 0)
|
|
touch.release(0, content).commit()
|
|
compare(activatedSpy.count, 1)
|
|
compare(highlightedSpy.count, 1)
|
|
tryCompare(control.popup, "visible", false)
|
|
}
|
|
|
|
function test_down() {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 3})
|
|
verify(control)
|
|
|
|
// some styles position the popup over the combo button. move it out
|
|
// of the way to avoid stealing mouse presses. we want to test the
|
|
// combinations of the button being pressed and the popup being visible.
|
|
control.popup.y = control.height
|
|
|
|
var downSpy = signalSpy.createObject(control, {target: control, signalName: "downChanged"})
|
|
verify(downSpy.valid)
|
|
|
|
var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"})
|
|
verify(pressedSpy.valid)
|
|
|
|
mousePress(control)
|
|
compare(control.popup.visible, false)
|
|
compare(control.pressed, true)
|
|
compare(control.down, true)
|
|
compare(downSpy.count, 1)
|
|
compare(pressedSpy.count, 1)
|
|
|
|
mouseRelease(control)
|
|
compare(control.popup.visible, true)
|
|
compare(control.pressed, false)
|
|
compare(control.down, true)
|
|
compare(downSpy.count, 3)
|
|
compare(pressedSpy.count, 2)
|
|
|
|
compare(control.popup.y, control.height)
|
|
|
|
control.down = false
|
|
compare(control.down, false)
|
|
compare(downSpy.count, 4)
|
|
|
|
mousePress(control)
|
|
compare(control.popup.visible, true)
|
|
compare(control.pressed, true)
|
|
compare(control.down, false) // explicit false
|
|
compare(downSpy.count, 4)
|
|
compare(pressedSpy.count, 3)
|
|
|
|
control.down = undefined
|
|
compare(control.down, true)
|
|
compare(downSpy.count, 5)
|
|
|
|
mouseRelease(control)
|
|
tryCompare(control.popup, "visible", false)
|
|
compare(control.pressed, false)
|
|
compare(control.down, false)
|
|
compare(downSpy.count, 6)
|
|
compare(pressedSpy.count, 4)
|
|
|
|
control.popup.open()
|
|
compare(control.popup.visible, true)
|
|
compare(control.pressed, false)
|
|
compare(control.down, true)
|
|
compare(downSpy.count, 7)
|
|
compare(pressedSpy.count, 4)
|
|
|
|
control.popup.close()
|
|
tryCompare(control.popup, "visible", false)
|
|
compare(control.pressed, false)
|
|
compare(control.down, false)
|
|
compare(downSpy.count, 8)
|
|
compare(pressedSpy.count, 4)
|
|
}
|
|
|
|
function test_focus() {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 3})
|
|
verify(control)
|
|
|
|
var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"})
|
|
verify(openedSpy.valid)
|
|
|
|
var closedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "closed"})
|
|
verify(openedSpy.valid)
|
|
|
|
// click - gain focus - show popup
|
|
mouseClick(control)
|
|
verify(control.activeFocus)
|
|
openedSpy.wait()
|
|
compare(openedSpy.count, 1)
|
|
compare(control.popup.visible, true)
|
|
|
|
// lose focus - hide popup
|
|
control.focus = false
|
|
verify(!control.activeFocus)
|
|
closedSpy.wait()
|
|
compare(closedSpy.count, 1)
|
|
compare(control.popup.visible, false)
|
|
}
|
|
|
|
function test_baseline() {
|
|
var control = createTemporaryObject(comboBox, testCase)
|
|
verify(control)
|
|
compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset)
|
|
}
|
|
|
|
Component {
|
|
id: displayBox
|
|
ComboBox {
|
|
textRole: "key"
|
|
model: ListModel {
|
|
ListElement { key: "First"; value: 123 }
|
|
ListElement { key: "Second"; value: 456 }
|
|
ListElement { key: "Third"; value: 789 }
|
|
}
|
|
}
|
|
}
|
|
|
|
function test_displayText() {
|
|
var control = createTemporaryObject(displayBox, testCase)
|
|
verify(control)
|
|
|
|
compare(control.displayText, "First")
|
|
control.currentIndex = 1
|
|
compare(control.displayText, "Second")
|
|
control.textRole = "value"
|
|
compare(control.displayText, "456")
|
|
control.displayText = "Display"
|
|
compare(control.displayText, "Display")
|
|
control.currentIndex = 2
|
|
compare(control.displayText, "Display")
|
|
control.displayText = undefined
|
|
compare(control.displayText, "789")
|
|
}
|
|
|
|
Component {
|
|
id: component
|
|
Pane {
|
|
id: panel
|
|
property alias button: _button;
|
|
property alias combobox: _combobox;
|
|
font.pixelSize: 30
|
|
Column {
|
|
Button {
|
|
id: _button
|
|
text: "Button"
|
|
font.pixelSize: 20
|
|
}
|
|
ComboBox {
|
|
id: _combobox
|
|
model: ["ComboBox", "With"]
|
|
delegate: ItemDelegate {
|
|
width: _combobox.width
|
|
text: _combobox.textRole ? (Array.isArray(_combobox.model) ? modelData[_combobox.textRole] : model[_combobox.textRole]) : modelData
|
|
objectName: "delegate"
|
|
autoExclusive: true
|
|
checked: _combobox.currentIndex === index
|
|
highlighted: _combobox.highlightedIndex === index
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
function test_font() { // QTBUG_50984, QTBUG-51696
|
|
var control = createTemporaryObject(component, testCase)
|
|
verify(control)
|
|
verify(control.button)
|
|
verify(control.combobox)
|
|
|
|
compare(control.font.pixelSize, 30)
|
|
compare(control.button.font.pixelSize, 20)
|
|
compare(control.combobox.font.pixelSize, 30)
|
|
|
|
// verify(control.combobox.popup)
|
|
// var popup = control.combobox.popup
|
|
// popup.open()
|
|
|
|
// verify(popup.contentItem)
|
|
|
|
// var listview = popup.contentItem
|
|
// verify(listview.contentItem)
|
|
// waitForRendering(listview)
|
|
|
|
// var idx1 = getChild(listview.contentItem, "delegate", -1)
|
|
// compare(listview.contentItem.children[idx1].font.pixelSize, 25)
|
|
// var idx2 = getChild(listview.contentItem, "delegate", idx1)
|
|
// compare(listview.contentItem.children[idx2].font.pixelSize, 25)
|
|
|
|
// compare(listview.contentItem.children[idx1].font.pixelSize, 25)
|
|
// compare(listview.contentItem.children[idx2].font.pixelSize, 25)
|
|
|
|
control.font.pixelSize = control.font.pixelSize + 10
|
|
compare(control.combobox.font.pixelSize, 40)
|
|
// waitForRendering(listview)
|
|
// compare(listview.contentItem.children[idx1].font.pixelSize, 25)
|
|
// compare(listview.contentItem.children[idx2].font.pixelSize, 25)
|
|
|
|
control.combobox.font.pixelSize = control.combobox.font.pixelSize + 5
|
|
compare(control.combobox.font.pixelSize, 45)
|
|
// waitForRendering(listview)
|
|
|
|
// idx1 = getChild(listview.contentItem, "delegate", -1)
|
|
// compare(listview.contentItem.children[idx1].font.pixelSize, 25)
|
|
// idx2 = getChild(listview.contentItem, "delegate", idx1)
|
|
// compare(listview.contentItem.children[idx2].font.pixelSize, 25)
|
|
}
|
|
|
|
function test_wheel() {
|
|
var ma = createTemporaryObject(mouseArea, testCase, {width: 100, height: 100})
|
|
verify(ma)
|
|
|
|
var control = comboBox.createObject(ma, {model: 2, wheelEnabled: true})
|
|
verify(control)
|
|
|
|
var delta = 120
|
|
|
|
var spy = signalSpy.createObject(ma, {target: ma, signalName: "wheel"})
|
|
verify(spy.valid)
|
|
|
|
mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta)
|
|
compare(control.currentIndex, 1)
|
|
compare(spy.count, 0) // no propagation
|
|
|
|
// reached bounds -> no change
|
|
mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta)
|
|
compare(control.currentIndex, 1)
|
|
compare(spy.count, 0) // no propagation
|
|
|
|
mouseWheel(control, control.width / 2, control.height / 2, delta, delta)
|
|
compare(control.currentIndex, 0)
|
|
compare(spy.count, 0) // no propagation
|
|
|
|
// reached bounds -> no change
|
|
mouseWheel(control, control.width / 2, control.height / 2, delta, delta)
|
|
compare(control.currentIndex, 0)
|
|
compare(spy.count, 0) // no propagation
|
|
}
|
|
|
|
function test_activation_data() {
|
|
return [
|
|
{ tag: "open:enter", key: Qt.Key_Enter, open: true },
|
|
{ tag: "open:return", key: Qt.Key_Return, open: true },
|
|
{ tag: "closed:enter", key: Qt.Key_Enter, open: false },
|
|
{ tag: "closed:return", key: Qt.Key_Return, open: false }
|
|
]
|
|
}
|
|
|
|
// QTBUG-51645
|
|
function test_activation(data) {
|
|
var control = createTemporaryObject(comboBox, testCase, {currentIndex: 1, model: ["Apple", "Orange", "Banana"]})
|
|
verify(control)
|
|
|
|
control.forceActiveFocus()
|
|
verify(control.activeFocus)
|
|
|
|
if (data.open) {
|
|
var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"})
|
|
verify(openedSpy.valid)
|
|
|
|
keyClick(Qt.Key_Space)
|
|
openedSpy.wait()
|
|
compare(openedSpy.count, 1)
|
|
}
|
|
compare(control.popup.visible, data.open)
|
|
|
|
compare(control.currentIndex, 1)
|
|
compare(control.currentText, "Orange")
|
|
compare(control.displayText, "Orange")
|
|
|
|
keyClick(data.key)
|
|
|
|
compare(control.currentIndex, 1)
|
|
compare(control.currentText, "Orange")
|
|
compare(control.displayText, "Orange")
|
|
}
|
|
|
|
Component {
|
|
id: asyncLoader
|
|
Loader {
|
|
active: false
|
|
asynchronous: true
|
|
sourceComponent: ComboBox {
|
|
model: ["First", "Second", "Third"]
|
|
}
|
|
}
|
|
}
|
|
|
|
// QTBUG-51972
|
|
function test_async() {
|
|
var loader = createTemporaryObject(asyncLoader, testCase)
|
|
verify(loader)
|
|
|
|
loader.active = true
|
|
tryCompare(loader, "status", Loader.Ready)
|
|
verify(loader.item)
|
|
compare(loader.item.currentText, "First")
|
|
compare(loader.item.displayText, "First")
|
|
}
|
|
|
|
// QTBUG-52615
|
|
function test_currentIndex() {
|
|
var control = createTemporaryObject(comboBox, testCase, {currentIndex: -1, model: 3})
|
|
verify(control)
|
|
|
|
compare(control.currentIndex, -1)
|
|
}
|
|
|
|
ListModel {
|
|
id: resetmodel
|
|
ListElement { text: "First" }
|
|
ListElement { text: "Second" }
|
|
ListElement { text: "Third" }
|
|
}
|
|
|
|
// QTBUG-54573
|
|
function test_modelReset() {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: resetmodel})
|
|
verify(control)
|
|
control.popup.open()
|
|
|
|
var listview = control.popup.contentItem
|
|
verify(listview)
|
|
|
|
tryCompare(listview.contentItem.children, "length", resetmodel.count + 1) // + highlight item
|
|
|
|
resetmodel.clear()
|
|
resetmodel.append({text: "Fourth"})
|
|
resetmodel.append({text: "Fifth"})
|
|
|
|
tryCompare(listview.contentItem.children, "length", resetmodel.count + 1) // + highlight item
|
|
}
|
|
|
|
// QTBUG-55118
|
|
function test_currentText() {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: listmodel})
|
|
verify(control)
|
|
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "First")
|
|
|
|
listmodel.setProperty(0, "text", "1st")
|
|
compare(control.currentText, "1st")
|
|
|
|
control.currentIndex = 1
|
|
compare(control.currentText, "Second")
|
|
|
|
listmodel.setProperty(0, "text", "First")
|
|
compare(control.currentText, "Second")
|
|
}
|
|
|
|
// QTBUG-55030
|
|
function test_highlightRange() {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 100})
|
|
verify(control)
|
|
|
|
control.currentIndex = 50
|
|
compare(control.currentIndex, 50)
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"})
|
|
verify(openedSpy.valid)
|
|
|
|
control.popup.open()
|
|
compare(control.highlightedIndex, 50)
|
|
tryCompare(openedSpy, "count", 1)
|
|
|
|
var listview = control.popup.contentItem
|
|
verify(listview)
|
|
|
|
var first = listview.itemAt(0, listview.contentY)
|
|
verify(first)
|
|
compare(first.text, "50")
|
|
|
|
var closedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "closed"})
|
|
verify(closedSpy.valid)
|
|
|
|
control.popup.close()
|
|
tryCompare(closedSpy, "count", 1)
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
control.currentIndex = 99
|
|
compare(control.currentIndex, 99)
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
control.popup.open()
|
|
compare(control.highlightedIndex, 99)
|
|
tryCompare(openedSpy, "count", 2)
|
|
tryVerify(function() { return listview.height > 0 })
|
|
|
|
var last = listview.itemAt(0, listview.contentY + listview.height - 1)
|
|
verify(last)
|
|
compare(last.text, "99")
|
|
|
|
openedSpy.target = null
|
|
closedSpy.target = null
|
|
}
|
|
|
|
function test_mouseHighlight() {
|
|
if ((Qt.platform.pluginName === "offscreen")
|
|
|| (Qt.platform.pluginName === "minimal"))
|
|
skip("Mouse highlight not functional on offscreen/minimal platforms")
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 20})
|
|
verify(control)
|
|
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"})
|
|
verify(openedSpy.valid)
|
|
|
|
control.popup.open()
|
|
compare(control.highlightedIndex, 0)
|
|
tryCompare(openedSpy, "count", 1)
|
|
|
|
var listview = control.popup.contentItem
|
|
verify(listview)
|
|
waitForRendering(listview)
|
|
|
|
// hover-highlight through all visible list items one by one
|
|
var hoverIndex = -1
|
|
var prevHoverItem = null
|
|
for (var y = 0; y < listview.height; ++y) {
|
|
var hoverItem = listview.itemAt(0, listview.contentY + y)
|
|
if (!hoverItem || !hoverItem.visible || hoverItem === prevHoverItem)
|
|
continue
|
|
mouseMove(hoverItem, 0, 0)
|
|
tryCompare(control, "highlightedIndex", ++hoverIndex)
|
|
prevHoverItem = hoverItem
|
|
}
|
|
|
|
mouseMove(listview, listview.width / 2, listview.height / 2)
|
|
|
|
// wheel-highlight the rest of the items
|
|
var delta = 120
|
|
var prevWheelItem = null
|
|
while (!listview.atYEnd) {
|
|
var prevContentY = listview.contentY
|
|
mouseWheel(listview, listview.width / 2, listview.height / 2, -delta, -delta)
|
|
tryCompare(listview, "moving", false)
|
|
verify(listview.contentY > prevContentY)
|
|
|
|
var wheelItem = listview.itemAt(listview.width / 2, listview.contentY + listview.height / 2)
|
|
if (!wheelItem || !wheelItem.visible || wheelItem === prevWheelItem)
|
|
continue
|
|
|
|
tryCompare(control, "highlightedIndex", parseInt(wheelItem.text))
|
|
prevWheelItem = wheelItem
|
|
}
|
|
}
|
|
|
|
RegularExpressionValidator {
|
|
id: regExpValidator
|
|
regularExpression: /(red|blue|green)?/
|
|
}
|
|
|
|
function test_validator() {
|
|
var control = createTemporaryObject(comboBox, testCase, {editable: true, validator: regExpValidator})
|
|
|
|
control.editText = "blu"
|
|
compare(control.acceptableInput, false)
|
|
control.editText = "blue"
|
|
compare(control.acceptableInput, true)
|
|
control.editText = "bluee"
|
|
compare(control.acceptableInput, false)
|
|
control.editText = ""
|
|
compare(control.acceptableInput, true)
|
|
control.editText = ""
|
|
control.forceActiveFocus()
|
|
keyPress(Qt.Key_A)
|
|
compare(control.editText, "")
|
|
keyPress(Qt.Key_A)
|
|
compare(control.editText, "")
|
|
keyPress(Qt.Key_R)
|
|
compare(control.editText, "r")
|
|
keyPress(Qt.Key_A)
|
|
compare(control.editText, "r")
|
|
compare(control.acceptableInput, false)
|
|
keyPress(Qt.Key_E)
|
|
compare(control.editText, "re")
|
|
compare(control.acceptableInput, false)
|
|
keyPress(Qt.Key_D)
|
|
compare(control.editText, "red")
|
|
compare(control.acceptableInput, true)
|
|
}
|
|
|
|
Component {
|
|
id: appendFindBox
|
|
ComboBox {
|
|
editable: true
|
|
model: ListModel {
|
|
ListElement { text:"first" }
|
|
}
|
|
onAccepted: {
|
|
if (find(editText) === -1)
|
|
model.append({text: editText})
|
|
}
|
|
}
|
|
}
|
|
|
|
function test_append_find() {
|
|
var control = createTemporaryObject(appendFindBox, testCase)
|
|
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "first")
|
|
control.forceActiveFocus()
|
|
compare(control.activeFocus, true)
|
|
|
|
control.selectAll()
|
|
keyPress(Qt.Key_T)
|
|
keyPress(Qt.Key_H)
|
|
keyPress(Qt.Key_I)
|
|
keyPress(Qt.Key_R)
|
|
keyPress(Qt.Key_D)
|
|
compare(control.count, 1)
|
|
compare(control.currentText, "first")
|
|
compare(control.editText, "third")
|
|
|
|
keyPress(Qt.Key_Enter)
|
|
compare(control.count, 2)
|
|
compare(control.currentIndex, 1)
|
|
compare(control.currentText, "third")
|
|
}
|
|
|
|
function test_editable() {
|
|
var control = createTemporaryObject(comboBox, testCase, {editable: true, model: ["Banana", "Coco", "Coconut", "Apple", "Cocomuffin"]})
|
|
verify(control)
|
|
|
|
control.forceActiveFocus()
|
|
verify(control.activeFocus)
|
|
|
|
var acceptCount = 0
|
|
|
|
var acceptSpy = signalSpy.createObject(control, {target: control, signalName: "accepted"})
|
|
verify(acceptSpy.valid)
|
|
|
|
compare(control.editText, "Banana")
|
|
compare(control.currentText, "Banana")
|
|
compare(control.currentIndex, 0)
|
|
compare(acceptSpy.count, 0)
|
|
control.editText = ""
|
|
|
|
keyPress(Qt.Key_C)
|
|
compare(control.editText, "coco")
|
|
compare(control.currentText, "Banana")
|
|
compare(control.currentIndex, 0)
|
|
|
|
keyPress(Qt.Key_Right)
|
|
keyPress(Qt.Key_N)
|
|
compare(control.editText, "coconut")
|
|
compare(control.currentText, "Banana")
|
|
compare(control.currentIndex, 0)
|
|
|
|
keyPress(Qt.Key_Enter) // Accept
|
|
compare(control.editText, "Coconut")
|
|
compare(control.currentText, "Coconut")
|
|
compare(control.currentIndex, 2)
|
|
compare(acceptSpy.count, ++acceptCount)
|
|
|
|
keyPress(Qt.Key_Backspace)
|
|
keyPress(Qt.Key_Backspace)
|
|
keyPress(Qt.Key_Backspace)
|
|
keyPress(Qt.Key_M)
|
|
compare(control.editText, "Cocomuffin")
|
|
compare(control.currentText, "Coconut")
|
|
compare(control.currentIndex, 2)
|
|
|
|
keyPress(Qt.Key_Enter) // Accept
|
|
compare(control.editText, "Cocomuffin")
|
|
compare(control.currentText, "Cocomuffin")
|
|
compare(control.currentIndex, 4)
|
|
compare(acceptSpy.count, ++acceptCount)
|
|
|
|
keyPress(Qt.Key_Return) // Accept
|
|
compare(control.editText, "Cocomuffin")
|
|
compare(control.currentText, "Cocomuffin")
|
|
compare(control.currentIndex, 4)
|
|
compare(acceptSpy.count, ++acceptCount)
|
|
|
|
control.editText = ""
|
|
compare(control.editText, "")
|
|
compare(control.currentText, "Cocomuffin")
|
|
compare(control.currentIndex, 4)
|
|
|
|
keyPress(Qt.Key_A)
|
|
compare(control.editText, "apple")
|
|
compare(control.currentText, "Cocomuffin")
|
|
compare(control.currentIndex, 4)
|
|
|
|
keyPress(Qt.Key_Return) // Accept
|
|
compare(control.editText, "Apple")
|
|
compare(control.currentText, "Apple")
|
|
compare(control.currentIndex, 3)
|
|
compare(acceptSpy.count, ++acceptCount)
|
|
|
|
control.editText = ""
|
|
keyPress(Qt.Key_A)
|
|
keyPress(Qt.Key_B)
|
|
compare(control.editText, "ab")
|
|
compare(control.currentText, "Apple")
|
|
compare(control.currentIndex, 3)
|
|
|
|
keyPress(Qt.Key_Return) // Accept
|
|
compare(control.editText, "ab")
|
|
compare(control.currentText, "")
|
|
compare(control.currentIndex, -1)
|
|
compare(acceptSpy.count, ++acceptCount)
|
|
|
|
control.editText = ""
|
|
compare(control.editText, "")
|
|
compare(control.currentText, "")
|
|
compare(control.currentIndex, -1)
|
|
|
|
keyPress(Qt.Key_C)
|
|
keyPress(Qt.Key_Return) // Accept
|
|
compare(control.editText, "Coco")
|
|
compare(control.currentText, "Coco")
|
|
compare(control.currentIndex, 1)
|
|
compare(acceptSpy.count, ++acceptCount)
|
|
|
|
keyPress(Qt.Key_Down)
|
|
compare(control.editText, "Coconut")
|
|
compare(control.currentText, "Coconut")
|
|
compare(control.currentIndex, 2)
|
|
|
|
keyPress(Qt.Key_Up)
|
|
compare(control.editText, "Coco")
|
|
compare(control.currentText, "Coco")
|
|
compare(control.currentIndex, 1)
|
|
|
|
control.editText = ""
|
|
compare(control.editText, "")
|
|
compare(control.currentText, "Coco")
|
|
compare(control.currentIndex, 1)
|
|
|
|
keyPress(Qt.Key_C)
|
|
keyPress(Qt.Key_O)
|
|
keyPress(Qt.Key_C) // autocompletes "coco"
|
|
keyPress(Qt.Key_Backspace)
|
|
keyPress(Qt.Key_Return) // Accept "coc"
|
|
compare(control.editText, "coc")
|
|
compare(control.currentText, "")
|
|
compare(control.currentIndex, -1)
|
|
compare(acceptSpy.count, ++acceptCount)
|
|
|
|
control.editText = ""
|
|
compare(control.editText, "")
|
|
compare(control.currentText, "")
|
|
compare(control.currentIndex, -1)
|
|
|
|
keyPress(Qt.Key_C)
|
|
keyPress(Qt.Key_O)
|
|
keyPress(Qt.Key_C) // autocompletes "coc"
|
|
keyPress(Qt.Key_Space)
|
|
keyPress(Qt.Key_Return) // Accept "coc "
|
|
compare(control.editText, "coc ")
|
|
compare(control.currentText, "")
|
|
compare(control.currentIndex, -1)
|
|
compare(acceptSpy.count, ++acceptCount)
|
|
}
|
|
|
|
Component {
|
|
id: keysAttachedBox
|
|
ComboBox {
|
|
editable: true
|
|
property bool gotit: false
|
|
Keys.onPressed: {
|
|
if (!gotit && event.key === Qt.Key_B) {
|
|
gotit = true
|
|
event.accepted = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function test_keys_attached() {
|
|
var control = createTemporaryObject(keysAttachedBox, testCase)
|
|
verify(control)
|
|
|
|
control.forceActiveFocus()
|
|
verify(control.activeFocus)
|
|
|
|
verify(!control.gotit)
|
|
compare(control.editText, "")
|
|
|
|
keyPress(Qt.Key_A)
|
|
verify(control.activeFocus)
|
|
verify(!control.gotit)
|
|
compare(control.editText, "a")
|
|
|
|
keyPress(Qt.Key_B)
|
|
verify(control.activeFocus)
|
|
verify(control.gotit)
|
|
compare(control.editText, "a")
|
|
|
|
keyPress(Qt.Key_B)
|
|
verify(control.activeFocus)
|
|
verify(control.gotit)
|
|
compare(control.editText, "ab")
|
|
}
|
|
|
|
function test_minusOneIndexResetsSelection_QTBUG_35794_data() {
|
|
return [
|
|
{ tag: "editable", editable: true },
|
|
{ tag: "non-editable", editable: false }
|
|
]
|
|
}
|
|
|
|
function test_minusOneIndexResetsSelection_QTBUG_35794(data) {
|
|
var control = createTemporaryObject(comboBox, testCase, {editable: data.editable, model: ["A", "B", "C"]})
|
|
verify(control)
|
|
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "A")
|
|
control.currentIndex = -1
|
|
compare(control.currentIndex, -1)
|
|
compare(control.currentText, "")
|
|
control.currentIndex = 1
|
|
compare(control.currentIndex, 1)
|
|
compare(control.currentText, "B")
|
|
}
|
|
|
|
function test_minusOneToZeroSelection_QTBUG_38036() {
|
|
var control = createTemporaryObject(comboBox, testCase, {model: ["A", "B", "C"]})
|
|
verify(control)
|
|
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "A")
|
|
control.currentIndex = -1
|
|
compare(control.currentIndex, -1)
|
|
compare(control.currentText, "")
|
|
control.currentIndex = 0
|
|
compare(control.currentIndex, 0)
|
|
compare(control.currentText, "A")
|
|
}
|
|
|
|
function test_emptyPopupAfterModelCleared() {
|
|
var control = createTemporaryObject(comboBox, testCase, { model: 1 })
|
|
verify(control)
|
|
compare(control.popup.implicitHeight, 0)
|
|
|
|
// Ensure that it's open so that the popup's implicitHeight changes when we increase the model count.
|
|
control.popup.open()
|
|
tryCompare(control.popup, "visible", true)
|
|
|
|
// Add lots of items to the model. The popup should take up the entire height of the window.
|
|
control.model = 100
|
|
compare(control.popup.height, control.Window.height - control.popup.topMargin - control.popup.bottomMargin)
|
|
|
|
control.popup.close()
|
|
|
|
// Clearing the model should result in a zero height.
|
|
control.model = 0
|
|
control.popup.open()
|
|
tryCompare(control.popup, "visible", true)
|
|
compare(control.popup.height, control.popup.topPadding + control.popup.bottomPadding)
|
|
}
|
|
|
|
Component {
|
|
id: keysMonitor
|
|
Item {
|
|
property int pressedKeys: 0
|
|
property int releasedKeys: 0
|
|
property int lastPressedKey: 0
|
|
property int lastReleasedKey: 0
|
|
property alias comboBox: comboBox
|
|
|
|
width: 200
|
|
height: 200
|
|
|
|
Keys.onPressed: { ++pressedKeys; lastPressedKey = event.key }
|
|
Keys.onReleased: { ++releasedKeys; lastReleasedKey = event.key }
|
|
|
|
ComboBox {
|
|
id: comboBox
|
|
}
|
|
}
|
|
}
|
|
|
|
function test_keyClose_data() {
|
|
return [
|
|
{ tag: "Escape", key: Qt.Key_Escape },
|
|
{ tag: "Back", key: Qt.Key_Back }
|
|
]
|
|
}
|
|
|
|
function test_keyClose(data) {
|
|
var container = createTemporaryObject(keysMonitor, testCase)
|
|
verify(container)
|
|
|
|
var control = comboBox.createObject(container)
|
|
verify(control)
|
|
|
|
control.forceActiveFocus()
|
|
verify(control.activeFocus)
|
|
|
|
var pressedKeys = 0
|
|
var releasedKeys = 0
|
|
|
|
// popup not visible -> propagates
|
|
keyPress(data.key)
|
|
compare(container.pressedKeys, ++pressedKeys)
|
|
compare(container.lastPressedKey, data.key)
|
|
|
|
keyRelease(data.key)
|
|
compare(container.releasedKeys, ++releasedKeys)
|
|
compare(container.lastReleasedKey, data.key)
|
|
|
|
verify(control.activeFocus)
|
|
|
|
// popup visible -> handled -> does not propagate
|
|
control.popup.open()
|
|
tryCompare(control.popup, "opened", true)
|
|
|
|
keyPress(data.key)
|
|
compare(container.pressedKeys, pressedKeys)
|
|
|
|
keyRelease(data.key)
|
|
// Popup receives the key release event if it has an exit transition, but
|
|
// not if it has been immediately closed on press, without a transition.
|
|
// ### TODO: Should Popup somehow always block the key release event?
|
|
if (!control.popup.exit)
|
|
++releasedKeys
|
|
compare(container.releasedKeys, releasedKeys)
|
|
|
|
tryCompare(control.popup, "visible", false)
|
|
verify(control.activeFocus)
|
|
|
|
// popup not visible -> propagates
|
|
keyPress(data.key)
|
|
compare(container.pressedKeys, ++pressedKeys)
|
|
compare(container.lastPressedKey, data.key)
|
|
|
|
keyRelease(data.key)
|
|
compare(container.releasedKeys, ++releasedKeys)
|
|
compare(container.lastReleasedKey, data.key)
|
|
}
|
|
|
|
function test_popupFocus_QTBUG_74661() {
|
|
var control = createTemporaryObject(comboBox, testCase)
|
|
verify(control)
|
|
|
|
var popup = createTemporaryObject(customPopup, testCase)
|
|
verify(popup)
|
|
|
|
control.popup = popup
|
|
|
|
var openedSpy = signalSpy.createObject(control, {target: popup, signalName: "opened"})
|
|
verify(openedSpy.valid)
|
|
|
|
var closedSpy = signalSpy.createObject(control, {target: popup, signalName: "closed"})
|
|
verify(closedSpy.valid)
|
|
|
|
control.forceActiveFocus()
|
|
verify(control.activeFocus)
|
|
|
|
// show popup
|
|
keyClick(Qt.Key_Space)
|
|
openedSpy.wait()
|
|
compare(openedSpy.count, 1)
|
|
|
|
popup.contentItem.forceActiveFocus()
|
|
verify(popup.contentItem.activeFocus)
|
|
|
|
// type something in the text field
|
|
keyClick(Qt.Key_Space)
|
|
keyClick(Qt.Key_H)
|
|
keyClick(Qt.Key_I)
|
|
compare(popup.contentItem.text, " hi")
|
|
|
|
compare(closedSpy.count, 0)
|
|
|
|
// hide popup
|
|
keyClick(Qt.Key_Escape)
|
|
closedSpy.wait()
|
|
compare(closedSpy.count, 1)
|
|
}
|
|
|
|
function test_comboBoxWithShaderEffect() {
|
|
var control = createTemporaryObject(comboBoxWithShaderEffect, testCase, {model: 9})
|
|
verify(control)
|
|
waitForRendering(control)
|
|
control.forceActiveFocus()
|
|
var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"})
|
|
verify(openedSpy.valid)
|
|
|
|
var closedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "closed"})
|
|
verify(closedSpy.valid)
|
|
|
|
control.popup.open()
|
|
openedSpy.wait()
|
|
compare(openedSpy.count, 1)
|
|
control.popup.close()
|
|
closedSpy.wait()
|
|
compare(closedSpy.count, 1)
|
|
}
|
|
|
|
function test_comboBoxSelectTextByMouse() {
|
|
let control = createTemporaryObject(comboBox, testCase,
|
|
{ editable: true, selectTextByMouse: true, model: [ "Some text" ], width: parent.width })
|
|
verify(control)
|
|
waitForRendering(control)
|
|
control.forceActiveFocus()
|
|
|
|
// Position the text cursor at the beginning of the text.
|
|
mouseClick(control, control.leftPadding, control.height / 2)
|
|
// Select all of the text.
|
|
mousePress(control, control.leftPadding, control.height / 2)
|
|
mouseMove(control, control.leftPadding + control.contentItem.width, control.height / 2)
|
|
mouseRelease(control, control.leftPadding + control.contentItem.width, control.height / 2)
|
|
compare(control.contentItem.selectedText, "Some text")
|
|
}
|
|
|
|
// QTBUG-78885: When the edit text is changed on an editable ComboBox,
|
|
// and then that ComboBox loses focus, its currentIndex should change
|
|
// to the index of the edit text (assuming a match is found).
|
|
function test_currentIndexChangeOnLostFocus() {
|
|
if (Qt.styleHints.tabFocusBehavior !== Qt.TabFocusAllControls)
|
|
skip("This platform only allows tab focus for text controls")
|
|
|
|
let theModel = []
|
|
for (let i = 0; i < 10; ++i)
|
|
theModel.push("Item " + (i + 1))
|
|
|
|
let comboBox1 = createTemporaryObject(comboBox, testCase,
|
|
{ objectName: "comboBox1", editable: true, model: theModel })
|
|
verify(comboBox1)
|
|
compare(comboBox1.currentIndex, 0)
|
|
|
|
let comboBox2 = createTemporaryObject(comboBox, testCase, { objectName: "comboBox2" })
|
|
verify(comboBox2)
|
|
|
|
// Give the first ComboBox focus and type in 0 to select "Item 10" (default is "Item 1").
|
|
waitForRendering(comboBox1)
|
|
comboBox1.forceActiveFocus()
|
|
verify(comboBox1.activeFocus)
|
|
keyClick(Qt.Key_0)
|
|
compare(comboBox1.editText, "Item 10")
|
|
|
|
let currentIndexSpy = signalSpy.createObject(comboBox1,
|
|
{ target: comboBox1, signalName: "currentIndexChanged" })
|
|
verify(currentIndexSpy.valid)
|
|
|
|
// Give focus to the other ComboBox so that the first one loses it.
|
|
// The first ComboBox's currentIndex should change to that of "Item 10".
|
|
keyClick(Qt.Key_Tab)
|
|
verify(comboBox2.activeFocus)
|
|
compare(comboBox1.currentIndex, 9)
|
|
compare(currentIndexSpy.count, 1)
|
|
|
|
// Give focus back to the first ComboBox, and try the same thing except
|
|
// with non-existing text; the currentIndex should not change.
|
|
comboBox1.forceActiveFocus()
|
|
verify(comboBox1.activeFocus)
|
|
keySequence(StandardKey.SelectAll)
|
|
compare(comboBox1.contentItem.selectedText, "Item 10")
|
|
keyClick(Qt.Key_N)
|
|
keyClick(Qt.Key_O)
|
|
keyClick(Qt.Key_P)
|
|
keyClick(Qt.Key_E)
|
|
compare(comboBox1.editText, "nope")
|
|
compare(comboBox1.currentIndex, 9)
|
|
compare(currentIndexSpy.count, 1)
|
|
}
|
|
|
|
Component {
|
|
id: appFontTextFieldComponent
|
|
TextField {
|
|
objectName: "appFontTextField"
|
|
font: Qt.application.font
|
|
// We don't want the background's implicit width to interfere with our tests,
|
|
// which are about implicit width of the contentItem of ComboBox, which is by default TextField.
|
|
background: null
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: appFontContentItemComboBoxComponent
|
|
ComboBox {
|
|
// Override the contentItem so that the font doesn't vary between styles.
|
|
contentItem: TextField {
|
|
objectName: "appFontContentItemTextField"
|
|
// We do this just to be extra sure that the font never comes from the control,
|
|
// as we want it to match that of the TextField in the appFontTextFieldComponent.
|
|
font: Qt.application.font
|
|
background: null
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: twoItemListModelComponent
|
|
|
|
ListModel {
|
|
ListElement { display: "Short" }
|
|
ListElement { display: "Kinda long" }
|
|
}
|
|
}
|
|
|
|
function appendedToModel(model, item) {
|
|
if (Array.isArray(model)) {
|
|
let newModel = model
|
|
newModel.push(item)
|
|
return newModel
|
|
}
|
|
|
|
if (model.hasOwnProperty("append")) {
|
|
model.append({ display: item })
|
|
// To account for the fact that changes to a JS array are not seen by the QML engine,
|
|
// we need to reassign the entire model and hence return it. For simplicity in the
|
|
// calling code, we do it for the ListModel code path too. It should be a no-op.
|
|
return model
|
|
}
|
|
|
|
console.warn("appendedToModel: unrecognised model")
|
|
return undefined
|
|
}
|
|
|
|
function removedFromModel(model, index, count) {
|
|
if (Array.isArray(model)) {
|
|
let newModel = model
|
|
newModel.splice(index, count)
|
|
return newModel
|
|
}
|
|
|
|
if (model.hasOwnProperty("remove")) {
|
|
model.remove(index, count)
|
|
return model
|
|
}
|
|
|
|
console.warn("removedFromModel: unrecognised model")
|
|
return undefined
|
|
}
|
|
|
|
// We don't use a data-driven test for the policy because the checks vary a lot based on which enum we're testing.
|
|
function test_implicitContentWidthPolicy_ContentItemImplicitWidth() {
|
|
// Set ContentItemImplicitWidth and ensure that implicitContentWidth is as wide as the current item
|
|
// by comparing it against the implicitWidth of an identical TextField
|
|
let control = createTemporaryObject(appFontContentItemComboBoxComponent, testCase, {
|
|
model: ["Short", "Kinda long"],
|
|
implicitContentWidthPolicy: ComboBox.ContentItemImplicitWidth
|
|
})
|
|
verify(control)
|
|
compare(control.implicitContentWidthPolicy, ComboBox.ContentItemImplicitWidth)
|
|
|
|
let textField = createTemporaryObject(appFontTextFieldComponent, testCase)
|
|
verify(textField)
|
|
// Don't set any text on textField because we're not accounting for the widest
|
|
// text here, so we want to compare it against an empty TextField.
|
|
compare(control.implicitContentWidth, textField.implicitWidth)
|
|
|
|
textField.font.pixelSize *= 2
|
|
control.font.pixelSize *= 2
|
|
compare(control.implicitContentWidth, textField.implicitWidth)
|
|
}
|
|
|
|
function test_implicitContentWidthPolicy_WidestText_data() {
|
|
return [
|
|
{ tag: "Array", model: ["Short", "Kinda long"] },
|
|
{ tag: "ListModel", model: twoItemListModelComponent.createObject(testCase) },
|
|
]
|
|
}
|
|
|
|
function test_implicitContentWidthPolicy_WidestText(data) {
|
|
let control = createTemporaryObject(appFontContentItemComboBoxComponent, testCase, {
|
|
model: data.model,
|
|
implicitContentWidthPolicy: ComboBox.WidestText
|
|
})
|
|
verify(control)
|
|
compare(control.implicitContentWidthPolicy, ComboBox.WidestText)
|
|
|
|
let textField = createTemporaryObject(appFontTextFieldComponent, testCase)
|
|
verify(textField)
|
|
textField.text = "Kinda long"
|
|
// Note that we don't need to change the current index here, as the implicitContentWidth
|
|
// is set to the implicitWidth of the TextField within the ComboBox as if it had the largest
|
|
// text from the model set on it.
|
|
// We use Math.ceil because TextInput uses qCeil internally, whereas the implicitWidth
|
|
// binding for TextField does not.
|
|
compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth))
|
|
|
|
// Add a longer item; it should affect the implicit content width.
|
|
let modifiedModel = appendedToModel(data.model, "Moderately long")
|
|
control.model = modifiedModel
|
|
textField.text = "Moderately long"
|
|
compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth))
|
|
|
|
// Remove the last two items; it should use the only remaining item's width.
|
|
modifiedModel = removedFromModel(data.model, 1, 2)
|
|
control.model = modifiedModel
|
|
compare(control.count, 1)
|
|
compare(control.currentText, "Short")
|
|
textField.text = "Short"
|
|
compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth))
|
|
|
|
// Changes in font should result in the implicitContentWidth being updated.
|
|
textField.font.pixelSize *= 2
|
|
// We have to change the contentItem's font size manually since we break the
|
|
// style's binding to the control's font when we set Qt.application.font to it.
|
|
control.contentItem.font.pixelSize *= 2
|
|
control.font.pixelSize *= 2
|
|
compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth))
|
|
}
|
|
|
|
function test_implicitContentWidthPolicy_WidestTextWhenCompleted_data() {
|
|
return test_implicitContentWidthPolicy_WidestText_data()
|
|
}
|
|
|
|
function test_implicitContentWidthPolicy_WidestTextWhenCompleted(data) {
|
|
let control = createTemporaryObject(appFontContentItemComboBoxComponent, testCase, {
|
|
model: data.model,
|
|
implicitContentWidthPolicy: ComboBox.WidestTextWhenCompleted
|
|
})
|
|
verify(control)
|
|
compare(control.implicitContentWidthPolicy, ComboBox.WidestTextWhenCompleted)
|
|
|
|
let textField = createTemporaryObject(appFontTextFieldComponent, testCase)
|
|
verify(textField)
|
|
textField.text = "Kinda long"
|
|
compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth))
|
|
|
|
// Add a longer item; it should not affect the implicit content width
|
|
// since we've already accounted for it once.
|
|
let modifiedModel = appendedToModel(data.model, "Moderately long")
|
|
control.model = modifiedModel
|
|
compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth))
|
|
|
|
// Remove the last two items; it should still not affect the implicit content width.
|
|
modifiedModel = removedFromModel(data.model, 1, 2)
|
|
control.model = modifiedModel
|
|
compare(control.count, 1)
|
|
compare(control.currentText, "Short")
|
|
compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth))
|
|
|
|
// Changes in font should not result in the implicitContentWidth being updated.
|
|
let oldTextFieldImplicitWidth = textField.implicitWidth
|
|
// Changes in font should result in the implicitContentWidth being updated.
|
|
textField.font.pixelSize *= 2
|
|
control.contentItem.font.pixelSize *= 2
|
|
control.font.pixelSize *= 2
|
|
compare(Math.ceil(control.implicitContentWidth), Math.ceil(oldTextFieldImplicitWidth))
|
|
}
|
|
}
|