2015-11-26 17:02:15 +00:00
|
|
|
/****************************************************************************
|
|
|
|
**
|
2017-01-09 16:13:48 +00:00
|
|
|
** Copyright (C) 2017 The Qt Company Ltd.
|
2017-02-22 12:59:07 +00:00
|
|
|
** Contact: https://www.qt.io/licensing/
|
2015-11-26 17:02:15 +00:00
|
|
|
**
|
|
|
|
** This file is part of the test suite of the Qt Toolkit.
|
|
|
|
**
|
|
|
|
** $QT_BEGIN_LICENSE:BSD$
|
2017-02-22 12:59:07 +00:00
|
|
|
** 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:
|
2015-11-26 17:02:15 +00:00
|
|
|
**
|
|
|
|
** "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$
|
|
|
|
**
|
|
|
|
****************************************************************************/
|
|
|
|
|
2018-10-23 13:23:58 +00:00
|
|
|
import QtQuick 2.12
|
2016-03-18 10:34:10 +00:00
|
|
|
import QtQuick.Window 2.2
|
2015-11-26 17:02:15 +00:00
|
|
|
import QtTest 1.0
|
2018-10-23 13:23:58 +00:00
|
|
|
import QtQuick.Controls 2.12
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
TestCase {
|
|
|
|
id: testCase
|
2017-04-04 08:47:50 +00:00
|
|
|
width: 400
|
|
|
|
height: 400
|
2016-03-18 10:34:10 +00:00
|
|
|
visible: true
|
|
|
|
when: windowShown
|
2015-11-26 17:02:15 +00:00
|
|
|
name: "ComboBox"
|
|
|
|
|
2016-10-01 21:02:43 +00:00
|
|
|
Component {
|
|
|
|
id: signalSpy
|
|
|
|
SignalSpy { }
|
|
|
|
}
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
Component {
|
|
|
|
id: comboBox
|
2016-10-01 21:02:43 +00:00
|
|
|
ComboBox { }
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: emptyBox
|
2015-11-26 17:02:15 +00:00
|
|
|
ComboBox {
|
|
|
|
delegate: ItemDelegate {
|
2016-11-04 15:45:17 +00:00
|
|
|
width: parent.width
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-23 09:44:05 +00:00
|
|
|
Component {
|
|
|
|
id: mouseArea
|
|
|
|
MouseArea { }
|
|
|
|
}
|
|
|
|
|
2019-03-24 19:54:31 +00:00
|
|
|
Component {
|
|
|
|
id: customPopup
|
|
|
|
Popup {
|
|
|
|
width: 100
|
|
|
|
implicitHeight: contentItem.implicitHeight
|
|
|
|
contentItem: TextInput {
|
|
|
|
anchors.fill: parent
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-22 13:40:06 +00:00
|
|
|
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;
|
|
|
|
}"
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-04 07:36:56 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
function test_defaults() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase)
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(control)
|
|
|
|
|
|
|
|
compare(control.count, 0)
|
|
|
|
compare(control.model, undefined)
|
2016-08-09 11:42:56 +00:00
|
|
|
compare(control.flat, false)
|
2015-11-26 17:02:15 +00:00
|
|
|
compare(control.pressed, false)
|
|
|
|
compare(control.currentIndex, -1)
|
|
|
|
compare(control.highlightedIndex, -1)
|
|
|
|
compare(control.currentText, "")
|
|
|
|
verify(control.delegate)
|
2016-04-28 10:37:58 +00:00
|
|
|
verify(control.indicator)
|
2015-12-08 13:26:51 +00:00
|
|
|
verify(control.popup)
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function test_array() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase)
|
2015-11-26 17:02:15 +00:00
|
|
|
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, "")
|
|
|
|
}
|
|
|
|
|
2016-01-25 16:06:30 +00:00
|
|
|
function test_objects() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(emptyBox, testCase)
|
2016-01-25 16:06:30 +00:00
|
|
|
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, "")
|
|
|
|
}
|
|
|
|
|
2017-06-12 09:11:38 +00:00
|
|
|
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, "")
|
|
|
|
}
|
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
function test_number() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase)
|
2015-11-26 17:02:15 +00:00
|
|
|
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() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase)
|
2015-11-26 17:02:15 +00:00
|
|
|
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" }
|
|
|
|
}
|
|
|
|
|
2016-01-25 16:06:30 +00:00
|
|
|
property var fruitarray: [
|
|
|
|
{ name: "Apple", color: "red" },
|
|
|
|
{ name: "Orange", color: "orange" },
|
|
|
|
{ name: "Banana", color: "yellow" }
|
|
|
|
]
|
|
|
|
|
|
|
|
function test_textRole_data() {
|
|
|
|
return [
|
|
|
|
{ tag: "ListModel", model: fruitmodel },
|
|
|
|
{ tag: "ObjectArray", model: fruitarray }
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_textRole(data) {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(emptyBox, testCase)
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(control)
|
|
|
|
|
2016-01-25 16:06:30 +00:00
|
|
|
control.model = data.model
|
2015-11-26 17:02:15 +00:00
|
|
|
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() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase)
|
2015-11-26 17:02:15 +00:00
|
|
|
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 (MatchRegExp)", term: "B(an)+a", flags: Qt.MatchRegExp, index: 0 },
|
|
|
|
{ tag: "b(an)+a (MatchRegExp|MatchCaseSensitive)", term: "b(an)+a", flags: Qt.MatchRegExp | Qt.MatchCaseSensitive, index: 1 },
|
|
|
|
{ tag: "[coc]+\\w+ (MatchRegExp)", term: "[coc]+\\w+", flags: Qt.MatchRegExp, 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) {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase)
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(control)
|
|
|
|
|
|
|
|
control.model = ["Banana", "banana", "Coconut", "Apple", "Cocomuffin"]
|
|
|
|
|
|
|
|
compare(control.find(data.term, data.flags), data.index)
|
|
|
|
}
|
|
|
|
|
Add valueRole API to ComboBox
This allows the user to conveniently manage data for a role associated with
the text role. A common example of this is an enum stored in a backend with
nicely formatted text displayed to the user. Before this patch, developers
would have to write code like this:
ComboBox {
textRole: "text"
onActivated: backend.modifier = model[currentIndex].value
Component.onCompleted: currentIndex = findValue(backend.modifier)
model: [
{ value: Qt.NoModifier, text: qsTr("No modifier") },
{ value: Qt.ShiftModifier, text: qsTr("Shift") },
{ value: Qt.ControlModifier, text: qsTr("Control") }
]
function findValue(value) {
for (var i = 0; i < model.length; ++i) {
if (model[i].value === value)
return i
}
return -1
}
}
With this patch, the code becomes much simpler:
ComboBox {
textRole: "text"
valueRole: "value"
onActivated: backend.modifier = currentValue
Component.onCompleted: currentIndex = indexOfValue(backend.modifier)
model: [
{ value: Qt.NoModifier, text: qsTr("No modifier") },
{ value: Qt.ShiftModifier, text: qsTr("Shift") },
{ value: Qt.ControlModifier, text: qsTr("Control") }
]
}
[ChangeLog][Controls][ComboBox] Added valueRole, currentValue and
indexOfValue(). These allow convenient management of data for a role
associated with the text role.
Change-Id: I0ed19bd0ba9cf6b044a8113ff1a8782d43065449
Fixes: QTBUG-73491
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
2019-03-04 10:12:05 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2016-01-31 07:32:42 +00:00
|
|
|
|
2016-03-18 10:34:10 +00:00
|
|
|
function test_arrowKeys() {
|
Add valueRole API to ComboBox
This allows the user to conveniently manage data for a role associated with
the text role. A common example of this is an enum stored in a backend with
nicely formatted text displayed to the user. Before this patch, developers
would have to write code like this:
ComboBox {
textRole: "text"
onActivated: backend.modifier = model[currentIndex].value
Component.onCompleted: currentIndex = findValue(backend.modifier)
model: [
{ value: Qt.NoModifier, text: qsTr("No modifier") },
{ value: Qt.ShiftModifier, text: qsTr("Shift") },
{ value: Qt.ControlModifier, text: qsTr("Control") }
]
function findValue(value) {
for (var i = 0; i < model.length; ++i) {
if (model[i].value === value)
return i
}
return -1
}
}
With this patch, the code becomes much simpler:
ComboBox {
textRole: "text"
valueRole: "value"
onActivated: backend.modifier = currentValue
Component.onCompleted: currentIndex = indexOfValue(backend.modifier)
model: [
{ value: Qt.NoModifier, text: qsTr("No modifier") },
{ value: Qt.ShiftModifier, text: qsTr("Shift") },
{ value: Qt.ControlModifier, text: qsTr("Control") }
]
}
[ChangeLog][Controls][ComboBox] Added valueRole, currentValue and
indexOfValue(). These allow convenient management of data for a role
associated with the text role.
Change-Id: I0ed19bd0ba9cf6b044a8113ff1a8782d43065449
Fixes: QTBUG-73491
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
2019-03-04 10:12:05 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase,
|
|
|
|
{ model: fruitmodel, textRole: "name", valueRole: "color" })
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(control)
|
|
|
|
|
2016-10-07 12:51:51 +00:00
|
|
|
var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"})
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(activatedSpy.valid)
|
|
|
|
|
2016-10-07 12:51:51 +00:00
|
|
|
var highlightedSpy = signalSpy.createObject(control, {target: control, signalName: "highlighted"})
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(highlightedSpy.valid)
|
|
|
|
|
2017-04-25 13:22:19 +00:00
|
|
|
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)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
// show popup
|
2015-11-26 17:02:15 +00:00
|
|
|
keyClick(Qt.Key_Space)
|
2017-04-25 13:22:19 +00:00
|
|
|
openedSpy.wait()
|
|
|
|
compare(openedSpy.count, 1)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
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()
|
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
// hide popup
|
2015-11-26 17:02:15 +00:00
|
|
|
keyClick(Qt.Key_Space)
|
2017-04-25 13:22:19 +00:00
|
|
|
closedSpy.wait()
|
|
|
|
compare(closedSpy.count, 1)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
compare(control.currentIndex, 1)
|
2017-04-25 13:22:19 +00:00
|
|
|
compare(control.highlightedIndex, -1)
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
2016-11-03 08:40:47 +00:00
|
|
|
function test_keys_space_enter_escape_data() {
|
2015-11-26 17:02:15 +00:00
|
|
|
return [
|
2016-03-18 10:34:10 +00:00
|
|
|
{ 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 }
|
2015-11-26 17:02:15 +00:00
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2016-11-03 08:40:47 +00:00
|
|
|
function test_keys_space_enter_escape(data) {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 3})
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(control)
|
|
|
|
|
2017-04-25 13:22:19 +00:00
|
|
|
var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"})
|
|
|
|
verify(openedSpy.valid)
|
2016-01-31 07:32:42 +00:00
|
|
|
|
2015-11-26 17:02:15 +00:00
|
|
|
control.forceActiveFocus()
|
|
|
|
verify(control.activeFocus)
|
|
|
|
|
|
|
|
compare(control.pressed, false)
|
2015-12-08 13:26:51 +00:00
|
|
|
compare(control.popup.visible, false)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
// show popup
|
2015-11-26 17:02:15 +00:00
|
|
|
keyPress(data.key1)
|
|
|
|
compare(control.pressed, data.showPress)
|
2015-12-08 13:26:51 +00:00
|
|
|
compare(control.popup.visible, false)
|
2015-11-26 17:02:15 +00:00
|
|
|
keyRelease(data.key1)
|
|
|
|
compare(control.pressed, false)
|
2015-12-08 13:26:51 +00:00
|
|
|
compare(control.popup.visible, data.showPopup)
|
2017-04-25 13:22:19 +00:00
|
|
|
if (data.showPopup)
|
|
|
|
openedSpy.wait()
|
2015-11-26 17:02:15 +00:00
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
// hide popup
|
2015-11-26 17:02:15 +00:00
|
|
|
keyPress(data.key2)
|
|
|
|
compare(control.pressed, data.hidePress)
|
|
|
|
keyRelease(data.key2)
|
|
|
|
compare(control.pressed, false)
|
2015-12-19 22:00:50 +00:00
|
|
|
tryCompare(control.popup, "visible", !data.hidePopup)
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
2016-11-03 08:40:47 +00:00
|
|
|
function test_keys_home_end() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 5})
|
2016-11-03 08:40:47 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2016-11-03 09:07:50 +00:00
|
|
|
function test_keySearch() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {model: ["Banana", "Coco", "Coconut", "Apple", "Cocomuffin"]})
|
2016-11-03 09:07:50 +00:00
|
|
|
verify(control)
|
|
|
|
|
|
|
|
control.forceActiveFocus()
|
|
|
|
verify(control.activeFocus)
|
|
|
|
|
|
|
|
compare(control.currentIndex, 0)
|
|
|
|
compare(control.currentText, "Banana")
|
2018-03-12 12:07:12 +00:00
|
|
|
compare(control.highlightedIndex, -1)
|
2016-11-03 09:07:50 +00:00
|
|
|
|
|
|
|
keyPress(Qt.Key_C)
|
|
|
|
compare(control.currentIndex, 1)
|
|
|
|
compare(control.currentText, "Coco")
|
2018-03-12 12:07:12 +00:00
|
|
|
compare(control.highlightedIndex, -1)
|
2016-11-03 09:07:50 +00:00
|
|
|
|
|
|
|
// no match
|
|
|
|
keyPress(Qt.Key_N)
|
|
|
|
compare(control.currentIndex, 1)
|
|
|
|
compare(control.currentText, "Coco")
|
2018-03-12 12:07:12 +00:00
|
|
|
compare(control.highlightedIndex, -1)
|
2016-11-03 09:07:50 +00:00
|
|
|
|
|
|
|
keyPress(Qt.Key_C)
|
|
|
|
compare(control.currentIndex, 2)
|
|
|
|
compare(control.currentText, "Coconut")
|
2018-03-12 12:07:12 +00:00
|
|
|
compare(control.highlightedIndex, -1)
|
2016-11-03 09:07:50 +00:00
|
|
|
|
|
|
|
keyPress(Qt.Key_C)
|
|
|
|
compare(control.currentIndex, 4)
|
|
|
|
compare(control.currentText, "Cocomuffin")
|
2018-03-12 12:07:12 +00:00
|
|
|
compare(control.highlightedIndex, -1)
|
2016-11-03 09:07:50 +00:00
|
|
|
|
|
|
|
// wrap
|
|
|
|
keyPress(Qt.Key_C)
|
|
|
|
compare(control.currentIndex, 1)
|
|
|
|
compare(control.currentText, "Coco")
|
2018-03-12 12:07:12 +00:00
|
|
|
compare(control.highlightedIndex, -1)
|
2016-11-03 09:07:50 +00:00
|
|
|
|
|
|
|
keyPress(Qt.Key_A)
|
|
|
|
compare(control.currentIndex, 3)
|
|
|
|
compare(control.currentText, "Apple")
|
2018-03-12 12:07:12 +00:00
|
|
|
compare(control.highlightedIndex, -1)
|
2016-11-03 09:07:50 +00:00
|
|
|
|
|
|
|
keyPress(Qt.Key_B)
|
|
|
|
compare(control.currentIndex, 0)
|
|
|
|
compare(control.currentText, "Banana")
|
2018-03-12 12:07:12 +00:00
|
|
|
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)
|
2016-11-03 09:07:50 +00:00
|
|
|
}
|
|
|
|
|
2016-03-18 10:34:10 +00:00
|
|
|
function test_popup() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 3})
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(control)
|
|
|
|
|
|
|
|
// show below
|
|
|
|
mousePress(control)
|
|
|
|
compare(control.pressed, true)
|
2015-12-08 13:26:51 +00:00
|
|
|
compare(control.popup.visible, false)
|
2015-11-26 17:02:15 +00:00
|
|
|
mouseRelease(control)
|
|
|
|
compare(control.pressed, false)
|
2015-12-08 13:26:51 +00:00
|
|
|
compare(control.popup.visible, true)
|
|
|
|
verify(control.popup.contentItem.y >= control.y)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
// hide
|
|
|
|
mouseClick(control)
|
|
|
|
compare(control.pressed, false)
|
2015-12-19 22:00:50 +00:00
|
|
|
tryCompare(control.popup, "visible", false)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
// show above
|
2016-03-18 10:34:10 +00:00
|
|
|
control.y = control.Window.height - control.height
|
2015-11-26 17:02:15 +00:00
|
|
|
mousePress(control)
|
|
|
|
compare(control.pressed, true)
|
2015-12-08 13:26:51 +00:00
|
|
|
compare(control.popup.visible, false)
|
2015-11-26 17:02:15 +00:00
|
|
|
mouseRelease(control)
|
|
|
|
compare(control.pressed, false)
|
2015-12-08 13:26:51 +00:00
|
|
|
compare(control.popup.visible, true)
|
|
|
|
verify(control.popup.contentItem.y < control.y)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
2016-05-09 14:09:07 +00:00
|
|
|
// 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)
|
2018-04-23 10:45:24 +00:00
|
|
|
|
|
|
|
// close the popup when hidden (QTBUG-67684)
|
|
|
|
control.popup.open()
|
|
|
|
tryCompare(control.popup, "opened", true)
|
|
|
|
control.visible = false
|
|
|
|
tryCompare(control.popup, "visible", false)
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
2016-03-18 10:34:10 +00:00
|
|
|
function test_mouse() {
|
2017-10-02 12:52:31 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 3, hoverEnabled: false})
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(control)
|
|
|
|
|
2016-10-07 12:51:51 +00:00
|
|
|
var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"})
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(activatedSpy.valid)
|
|
|
|
|
|
|
|
mouseClick(control)
|
2015-12-08 13:26:51 +00:00
|
|
|
compare(control.popup.visible, true)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
var content = control.popup.contentItem
|
2015-11-26 17:02:15 +00:00
|
|
|
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)
|
2015-12-08 13:26:51 +00:00
|
|
|
compare(control.popup.visible, true)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
|
|
|
// 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)
|
2015-12-19 22:00:50 +00:00
|
|
|
tryCompare(control.popup, "visible", false)
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 11:39:41 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2016-11-04 11:54:38 +00:00
|
|
|
function test_down() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 3})
|
2016-11-04 11:54:38 +00:00
|
|
|
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)
|
|
|
|
|
2017-04-04 08:47:50 +00:00
|
|
|
compare(control.popup.y, control.height)
|
|
|
|
|
2016-11-04 11:54:38 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2016-03-18 10:34:10 +00:00
|
|
|
function test_focus() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 3})
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(control)
|
|
|
|
|
2017-04-25 13:22:19 +00:00
|
|
|
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)
|
2016-01-31 07:32:42 +00:00
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
// click - gain focus - show popup
|
2015-11-26 17:02:15 +00:00
|
|
|
mouseClick(control)
|
|
|
|
verify(control.activeFocus)
|
2017-04-25 13:22:19 +00:00
|
|
|
openedSpy.wait()
|
|
|
|
compare(openedSpy.count, 1)
|
2015-12-08 13:26:51 +00:00
|
|
|
compare(control.popup.visible, true)
|
2015-11-26 17:02:15 +00:00
|
|
|
|
2015-12-08 13:26:51 +00:00
|
|
|
// lose focus - hide popup
|
2016-01-31 07:32:42 +00:00
|
|
|
control.focus = false
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(!control.activeFocus)
|
2017-04-25 13:22:19 +00:00
|
|
|
closedSpy.wait()
|
|
|
|
compare(closedSpy.count, 1)
|
|
|
|
compare(control.popup.visible, false)
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function test_baseline() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase)
|
2015-11-26 17:02:15 +00:00
|
|
|
verify(control)
|
|
|
|
compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset)
|
|
|
|
}
|
2015-12-23 13:32:12 +00:00
|
|
|
|
|
|
|
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() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(displayBox, testCase)
|
2015-12-23 13:32:12 +00:00
|
|
|
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")
|
|
|
|
}
|
2016-02-11 12:09:48 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2016-03-10 16:29:29 +00:00
|
|
|
function test_font() { // QTBUG_50984, QTBUG-51696
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(component, testCase)
|
2016-02-11 12:09:48 +00:00
|
|
|
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)
|
|
|
|
|
2016-03-18 10:34:10 +00:00
|
|
|
// verify(control.combobox.popup)
|
|
|
|
// var popup = control.combobox.popup
|
|
|
|
// popup.open()
|
2016-02-11 12:09:48 +00:00
|
|
|
|
2016-03-18 10:34:10 +00:00
|
|
|
// verify(popup.contentItem)
|
2016-02-11 12:09:48 +00:00
|
|
|
|
2016-03-18 10:34:10 +00:00
|
|
|
// var listview = popup.contentItem
|
|
|
|
// verify(listview.contentItem)
|
|
|
|
// waitForRendering(listview)
|
2016-02-11 12:09:48 +00:00
|
|
|
|
2016-03-18 10:34:10 +00:00
|
|
|
// 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)
|
2016-03-10 16:29:29 +00:00
|
|
|
|
2016-03-18 10:34:10 +00:00
|
|
|
// compare(listview.contentItem.children[idx1].font.pixelSize, 25)
|
|
|
|
// compare(listview.contentItem.children[idx2].font.pixelSize, 25)
|
2016-02-11 12:09:48 +00:00
|
|
|
|
|
|
|
control.font.pixelSize = control.font.pixelSize + 10
|
|
|
|
compare(control.combobox.font.pixelSize, 40)
|
2016-03-18 10:34:10 +00:00
|
|
|
// waitForRendering(listview)
|
|
|
|
// compare(listview.contentItem.children[idx1].font.pixelSize, 25)
|
|
|
|
// compare(listview.contentItem.children[idx2].font.pixelSize, 25)
|
2016-02-11 12:09:48 +00:00
|
|
|
|
|
|
|
control.combobox.font.pixelSize = control.combobox.font.pixelSize + 5
|
|
|
|
compare(control.combobox.font.pixelSize, 45)
|
2016-03-18 10:34:10 +00:00
|
|
|
// waitForRendering(listview)
|
2016-02-11 12:09:48 +00:00
|
|
|
|
2016-03-18 10:34:10 +00:00
|
|
|
// 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)
|
2016-02-11 12:09:48 +00:00
|
|
|
}
|
2016-03-03 13:19:45 +00:00
|
|
|
|
2016-03-18 10:34:10 +00:00
|
|
|
function test_wheel() {
|
2018-03-23 09:44:05 +00:00
|
|
|
var ma = createTemporaryObject(mouseArea, testCase, {width: 100, height: 100})
|
|
|
|
verify(ma)
|
|
|
|
|
|
|
|
var control = comboBox.createObject(ma, {model: 2, wheelEnabled: true})
|
2016-03-03 13:19:45 +00:00
|
|
|
verify(control)
|
|
|
|
|
|
|
|
var delta = 120
|
|
|
|
|
2018-03-23 09:44:05 +00:00
|
|
|
var spy = signalSpy.createObject(ma, {target: ma, signalName: "wheel"})
|
|
|
|
verify(spy.valid)
|
|
|
|
|
2016-03-03 13:19:45 +00:00
|
|
|
mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta)
|
|
|
|
compare(control.currentIndex, 1)
|
2018-03-23 09:44:05 +00:00
|
|
|
compare(spy.count, 0) // no propagation
|
2016-03-03 13:19:45 +00:00
|
|
|
|
|
|
|
// reached bounds -> no change
|
|
|
|
mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta)
|
|
|
|
compare(control.currentIndex, 1)
|
2018-03-23 09:44:05 +00:00
|
|
|
compare(spy.count, 0) // no propagation
|
2016-03-03 13:19:45 +00:00
|
|
|
|
|
|
|
mouseWheel(control, control.width / 2, control.height / 2, delta, delta)
|
|
|
|
compare(control.currentIndex, 0)
|
2018-03-23 09:44:05 +00:00
|
|
|
compare(spy.count, 0) // no propagation
|
2016-03-03 13:19:45 +00:00
|
|
|
|
|
|
|
// reached bounds -> no change
|
|
|
|
mouseWheel(control, control.width / 2, control.height / 2, delta, delta)
|
|
|
|
compare(control.currentIndex, 0)
|
2018-03-23 09:44:05 +00:00
|
|
|
compare(spy.count, 0) // no propagation
|
2016-03-03 13:19:45 +00:00
|
|
|
}
|
2016-03-08 20:52:42 +00:00
|
|
|
|
2016-03-04 15:03:14 +00:00
|
|
|
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) {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {currentIndex: 1, model: ["Apple", "Orange", "Banana"]})
|
2016-03-04 15:03:14 +00:00
|
|
|
verify(control)
|
|
|
|
|
|
|
|
control.forceActiveFocus()
|
|
|
|
verify(control.activeFocus)
|
|
|
|
|
2017-04-25 13:22:19 +00:00
|
|
|
if (data.open) {
|
|
|
|
var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"})
|
|
|
|
verify(openedSpy.valid)
|
|
|
|
|
2016-03-04 15:03:14 +00:00
|
|
|
keyClick(Qt.Key_Space)
|
2017-04-25 13:22:19 +00:00
|
|
|
openedSpy.wait()
|
|
|
|
compare(openedSpy.count, 1)
|
|
|
|
}
|
2016-03-04 15:03:14 +00:00
|
|
|
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")
|
|
|
|
}
|
2016-03-23 09:44:08 +00:00
|
|
|
|
|
|
|
Component {
|
|
|
|
id: asyncLoader
|
|
|
|
Loader {
|
|
|
|
active: false
|
|
|
|
asynchronous: true
|
|
|
|
sourceComponent: ComboBox {
|
|
|
|
model: ["First", "Second", "Third"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// QTBUG-51972
|
|
|
|
function test_async() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var loader = createTemporaryObject(asyncLoader, testCase)
|
2016-03-23 09:44:08 +00:00
|
|
|
verify(loader)
|
|
|
|
|
|
|
|
loader.active = true
|
|
|
|
tryCompare(loader, "status", Loader.Ready)
|
|
|
|
verify(loader.item)
|
|
|
|
compare(loader.item.currentText, "First")
|
|
|
|
compare(loader.item.displayText, "First")
|
|
|
|
}
|
2016-04-17 17:28:17 +00:00
|
|
|
|
|
|
|
// QTBUG-52615
|
|
|
|
function test_currentIndex() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {currentIndex: -1, model: 3})
|
2016-04-17 17:28:17 +00:00
|
|
|
verify(control)
|
|
|
|
|
|
|
|
compare(control.currentIndex, -1)
|
|
|
|
}
|
2016-07-05 14:57:12 +00:00
|
|
|
|
|
|
|
ListModel {
|
|
|
|
id: resetmodel
|
|
|
|
ListElement { text: "First" }
|
|
|
|
ListElement { text: "Second" }
|
|
|
|
ListElement { text: "Third" }
|
|
|
|
}
|
|
|
|
|
|
|
|
// QTBUG-54573
|
|
|
|
function test_modelReset() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {model: resetmodel})
|
2016-07-05 14:57:12 +00:00
|
|
|
verify(control)
|
|
|
|
control.popup.open()
|
|
|
|
|
|
|
|
var listview = control.popup.contentItem
|
|
|
|
verify(listview)
|
|
|
|
|
2016-12-13 12:56:45 +00:00
|
|
|
tryCompare(listview.contentItem.children, "length", resetmodel.count + 1) // + highlight item
|
2016-07-05 14:57:12 +00:00
|
|
|
|
|
|
|
resetmodel.clear()
|
|
|
|
resetmodel.append({text: "Fourth"})
|
|
|
|
resetmodel.append({text: "Fifth"})
|
|
|
|
|
2016-12-13 12:56:45 +00:00
|
|
|
tryCompare(listview.contentItem.children, "length", resetmodel.count + 1) // + highlight item
|
2016-07-05 14:57:12 +00:00
|
|
|
}
|
2016-08-08 22:13:30 +00:00
|
|
|
|
|
|
|
// QTBUG-55118
|
|
|
|
function test_currentText() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {model: listmodel})
|
2016-08-08 22:13:30 +00:00
|
|
|
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")
|
|
|
|
}
|
2016-10-01 21:02:43 +00:00
|
|
|
|
|
|
|
// QTBUG-55030
|
|
|
|
function test_highlightRange() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {model: 100})
|
2016-10-01 21:02:43 +00:00
|
|
|
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)
|
2017-05-22 10:34:03 +00:00
|
|
|
tryVerify(function() { return listview.height > 0 })
|
2016-10-01 21:02:43 +00:00
|
|
|
|
|
|
|
var last = listview.itemAt(0, listview.contentY + listview.height - 1)
|
|
|
|
verify(last)
|
|
|
|
compare(last.text, "99")
|
|
|
|
|
|
|
|
openedSpy.target = null
|
|
|
|
closedSpy.target = null
|
|
|
|
}
|
2016-10-01 19:08:09 +00:00
|
|
|
|
2017-05-16 13:51:40 +00:00
|
|
|
function test_mouseHighlight() {
|
2017-06-05 09:48:40 +00:00
|
|
|
if ((Qt.platform.pluginName === "offscreen")
|
2017-12-15 10:44:26 +00:00
|
|
|
|| (Qt.platform.pluginName === "minimal"))
|
2017-06-05 09:48:40 +00:00
|
|
|
skip("Mouse highlight not functional on offscreen/minimal platforms")
|
2017-05-16 13:51:40 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-01 19:08:09 +00:00
|
|
|
RegExpValidator {
|
|
|
|
id: regExpValidator
|
|
|
|
regExp: /(red|blue|green)?/
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_validator() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {editable: true, validator: regExpValidator})
|
2016-10-01 19:08:09 +00:00
|
|
|
|
|
|
|
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() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(appendFindBox, testCase)
|
2016-10-01 19:08:09 +00:00
|
|
|
|
|
|
|
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() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {editable: true, model: ["Banana", "Coco", "Coconut", "Apple", "Cocomuffin"]})
|
2016-10-01 19:08:09 +00:00
|
|
|
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() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(keysAttachedBox, testCase)
|
2016-10-01 19:08:09 +00:00
|
|
|
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) {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {editable: data.editable, model: ["A", "B", "C"]})
|
2016-10-01 19:08:09 +00:00
|
|
|
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() {
|
2016-12-21 10:22:25 +00:00
|
|
|
var control = createTemporaryObject(comboBox, testCase, {model: ["A", "B", "C"]})
|
2016-10-01 19:08:09 +00:00
|
|
|
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")
|
|
|
|
}
|
ComboBox: fix empty popup being shown after model is cleared
Currently, ComboBox's popup is sized vertically in this way:
implicitHeight: contentItem.implicitHeight
Adding an item to a ComboBox with an empty model and then opening
the popup results in the implicitHeight being used in the line below
(in QQuickPopupPositioner::reposition()):
QRectF rect(p->allowHorizontalMove ? p->x : popupItem->x(),
p->allowVerticalMove ? p->y : popupItem->y(),
!p->hasWidth && iw > 0 ? iw : w,
!p->hasHeight && ih > 0 ? ih : h);
An explicit height was never set on the popup, and ih (the
implicitHeight of the popupItem) is greater than 0. This is fine.
However, when a ComboBox's popup item grows large enough that it has to
be resized to fit within the window, its explicit height is set. The
problem occurs when the model is then cleared, as the implicit height
of the popup item becomes 0. So, while "!p->hasHeight" is still true,
"ih > 0" is not, and the explicit height of the popup item is used,
which is still the previous "let's fill the entire height of the
window" size.
To fix this, we bind the height of the popup to a different expression:
height: Math.min(contentItem.implicitHeight,
control.Window.height - topMargin - bottomMargin)
This ensures that the popup has a zero height when the ListView's
implicitHeight is zero (i.e the model is empty), and a height
that fits within the window in all other cases.
Ideally, we'd have a maximumHeight property that controls this, but
for 5.9, we have to fix it this way.
Task-number: QTBUG-60684
Change-Id: Ied94c79bb7b0e693be34e9c7282d991f6f704770
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
2017-05-31 15:14:49 +00:00
|
|
|
|
|
|
|
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)
|
2017-06-06 18:40:54 +00:00
|
|
|
compare(control.popup.height, control.popup.topPadding + control.popup.bottomPadding)
|
ComboBox: fix empty popup being shown after model is cleared
Currently, ComboBox's popup is sized vertically in this way:
implicitHeight: contentItem.implicitHeight
Adding an item to a ComboBox with an empty model and then opening
the popup results in the implicitHeight being used in the line below
(in QQuickPopupPositioner::reposition()):
QRectF rect(p->allowHorizontalMove ? p->x : popupItem->x(),
p->allowVerticalMove ? p->y : popupItem->y(),
!p->hasWidth && iw > 0 ? iw : w,
!p->hasHeight && ih > 0 ? ih : h);
An explicit height was never set on the popup, and ih (the
implicitHeight of the popupItem) is greater than 0. This is fine.
However, when a ComboBox's popup item grows large enough that it has to
be resized to fit within the window, its explicit height is set. The
problem occurs when the model is then cleared, as the implicit height
of the popup item becomes 0. So, while "!p->hasHeight" is still true,
"ih > 0" is not, and the explicit height of the popup item is used,
which is still the previous "let's fill the entire height of the
window" size.
To fix this, we bind the height of the popup to a different expression:
height: Math.min(contentItem.implicitHeight,
control.Window.height - topMargin - bottomMargin)
This ensures that the popup has a zero height when the ListView's
implicitHeight is zero (i.e the model is empty), and a height
that fits within the window in all other cases.
Ideally, we'd have a maximumHeight property that controls this, but
for 5.9, we have to fix it this way.
Task-number: QTBUG-60684
Change-Id: Ied94c79bb7b0e693be34e9c7282d991f6f704770
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
2017-05-31 15:14:49 +00:00
|
|
|
}
|
2018-04-23 12:05:25 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
2019-03-24 19:54:31 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
2019-05-22 13:40:06 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
2015-11-26 17:02:15 +00:00
|
|
|
}
|