diff --git a/tests/imgs/add_field.svg b/tests/imgs/add_field.svg
new file mode 100644
index 000000000..1b9cf9ac6
--- /dev/null
+++ b/tests/imgs/add_field.svg
@@ -0,0 +1,19 @@
+
+
diff --git a/tests/resources.qrc b/tests/resources.qrc
index 5836abc61..6910477ef 100644
--- a/tests/resources.qrc
+++ b/tests/resources.qrc
@@ -1,5 +1,6 @@
+ imgs/add_field.svg
imgs/call.svg
imgs/cam.svg
imgs/chat_attachment.svg
@@ -38,12 +39,12 @@
ui/modules/Linphone/Dialog/ConfirmDialog.qml
ui/modules/Linphone/Dialog/DialogDescription.qml
ui/modules/Linphone/Dialog/DialogPlus.qml
+ ui/modules/Linphone/DropZone.qml
ui/modules/Linphone/ForceScrollBar.qml
ui/modules/Linphone/Form/AbstractTextButton.qml
ui/modules/Linphone/Form/ActionBar.qml
ui/modules/Linphone/Form/ActionButton.qml
ui/modules/Linphone/Form/CheckBoxText.qml
- ui/modules/Linphone/Form/DropZone.qml
ui/modules/Linphone/Form/ExclusiveButtons.qml
ui/modules/Linphone/Form/ListForm.qml
ui/modules/Linphone/Form/SmallButton.qml
@@ -65,6 +66,7 @@
ui/modules/Linphone/Styles/Form/ActionBarStyle.qml
ui/modules/Linphone/Styles/Form/CheckBoxTextStyle.qml
ui/modules/Linphone/Styles/Form/ExclusiveButtonsStyle.qml
+ ui/modules/Linphone/Styles/Form/ListFormStyle.qml
ui/modules/Linphone/Styles/Form/SmallButtonStyle.qml
ui/modules/Linphone/Styles/Form/TextButtonAStyle.qml
ui/modules/Linphone/Styles/Form/TextButtonBStyle.qml
diff --git a/tests/src/main.cpp b/tests/src/main.cpp
index a28401278..3af3c3257 100644
--- a/tests/src/main.cpp
+++ b/tests/src/main.cpp
@@ -1,9 +1,9 @@
#include
-#include
#include
#include
#include
+#include
#include
#include
#include
diff --git a/tests/ui/modules/Linphone/Chat/Event.qml b/tests/ui/modules/Linphone/Chat/Event.qml
index 5af08c610..14ccacd3b 100644
--- a/tests/ui/modules/Linphone/Chat/Event.qml
+++ b/tests/ui/modules/Linphone/Chat/Event.qml
@@ -9,7 +9,7 @@ Text {
// Never created.
// Private data for `lupdate`.
Item {
- property variant i18n: [
+ property var i18n: [
QT_TR_NOOP('hangup'),
QT_TR_NOOP('incomingCall'),
QT_TR_NOOP('lostIncomingCall'),
diff --git a/tests/ui/modules/Linphone/Form/DropZone.qml b/tests/ui/modules/Linphone/DropZone.qml
similarity index 97%
rename from tests/ui/modules/Linphone/Form/DropZone.qml
rename to tests/ui/modules/Linphone/DropZone.qml
index 0e8ef23bb..645c5ae56 100644
--- a/tests/ui/modules/Linphone/Form/DropZone.qml
+++ b/tests/ui/modules/Linphone/DropZone.qml
@@ -4,7 +4,7 @@ import QtQuick.Dialogs 1.2
// ===================================================================
Rectangle {
- signal dropped (variant files)
+ signal dropped (var files)
color: '#DDDDDD'
id: dropZone
diff --git a/tests/ui/modules/Linphone/Form/ExclusiveButtons.qml b/tests/ui/modules/Linphone/Form/ExclusiveButtons.qml
index b3269f44d..a8be70843 100644
--- a/tests/ui/modules/Linphone/Form/ExclusiveButtons.qml
+++ b/tests/ui/modules/Linphone/Form/ExclusiveButtons.qml
@@ -5,8 +5,9 @@ import Linphone.Styles 1.0
// ===================================================================
Row {
+ property var texts
+
property int _selectedButton: 0
- property variant texts
signal clicked (int button)
diff --git a/tests/ui/modules/Linphone/Form/ListForm.qml b/tests/ui/modules/Linphone/Form/ListForm.qml
index 1567c6863..f248830d4 100644
--- a/tests/ui/modules/Linphone/Form/ListForm.qml
+++ b/tests/ui/modules/Linphone/Form/ListForm.qml
@@ -1,106 +1,123 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
+import Linphone 1.0
+import Linphone.Styles 1.0
+
+// ===================================================================
+
RowLayout {
- readonly property int lineHeight: 30
+ property alias model: values.model
+ property alias title: text.text
- property alias title: text.text
+ function _addValue (value) {
+ if (model.count === 0 ||
+ model.get(model.count - 1).$value.length !== 0) {
+ model.append({ $value: value })
+ }
+ }
- spacing: 0
+ function _handleEditionFinished (index, text) {
+ if (text.length === 0) {
+ model.remove(index)
+ } else {
+ model.set(index, { $value: text })
+ }
+ }
- RowLayout {
- Layout.alignment: Qt.AlignTop
- Layout.preferredHeight: lineHeight
- spacing: 20
+ spacing: 0
- // Add item in list.
- ActionButton {
- Layout.preferredHeight: 16
- Layout.preferredWidth: 16
- onClicked: {
- if (valuesModel.count === 0 ||
- valuesModel.get(valuesModel.count - 1).$value.length !== 0) {
- valuesModel.append({ $value: '' })
- }
- }
- }
+ // Title area.
+ RowLayout {
+ Layout.alignment: Qt.AlignTop
+ Layout.preferredHeight: ListFormStyle.lineHeight
+ spacing: ListFormStyle.titleArea.spacing
- // List title.
- Text {
- Layout.preferredWidth: 130
- id: text
- }
+ // Button: Add item in list.
+ ActionButton {
+ Layout.preferredHeight: ListFormStyle.titleArea.iconSize
+ Layout.preferredWidth: ListFormStyle.titleArea.iconSize
+ icon: ListFormStyle.titleArea.icon
+
+ onClicked: _addValue('')
}
- // Content list.
- ListView {
- Layout.fillWidth: true
- Layout.preferredHeight: values.count * lineHeight
- id: values
- interactive: false
+ // Title text.
+ Text {
+ id: text
- model: ListModel {
- id: valuesModel
-
- ListElement { $value: 'toto' }
- ListElement { $value: 'abc' }
- ListElement { $value: 'machin' }
- ListElement { $value: 'bidule' }
- ListElement { $value: 'truc' }
- }
-
- delegate: Item {
- implicitHeight: textEdit.height
- width: parent.width
-
- Rectangle {
- color: textEdit.focus ? '#E6E6E6' : 'transparent'
- id: background
- implicitHeight: textEdit.height
- implicitWidth: textEdit.contentWidth +
- textEdit.padding * 2
- }
-
- Text {
- anchors.fill: textEdit
- color: '#5A585B'
- font.italic: true
- padding: textEdit.padding
- text: textEdit.text.length === 0 && !textEdit.focus
- ? qsTr('fillPlaceholder')
- : ''
- verticalAlignment: Text.AlignVCenter
- }
-
- TextEdit {
- color: focus ? '#000000' : '#5A585B'
- font.bold: !focus
- height: lineHeight
- id: textEdit
- padding: 10
- selectByMouse: true
- text: $value
- verticalAlignment: TextEdit.AlignVCenter
- width: parent.width
-
- // To handle editingFinished, it's necessary to set
- // focus on another component.
- Keys.onReturnPressed: parent.forceActiveFocus()
-
- onEditingFinished: {
- if (text.length === 0) {
- valuesModel.remove(index)
- } else {
- // textEdit.text is not the same value than
- // valuesModel.get(index)
- valuesModel.set(index, { $value: text })
- }
-
- // Hack: The edition is finished but the focus
- // can be set.
- focus = false
- }
- }
- }
+ Layout.preferredWidth: ListFormStyle.titleArea.text.width
+ color: ListFormStyle.titleArea.text.color
+ font.pointSize: ListFormStyle.titleArea.text.fontSize
}
+ }
+
+ // Values.
+ ListView {
+ id: values
+
+ Layout.fillWidth: true
+ Layout.preferredHeight: count * ListFormStyle.lineHeight
+ interactive: false
+
+ delegate: Item {
+ implicitHeight: textEdit.height
+ width: parent.width
+
+ // Background.
+ Rectangle {
+ color: textEdit.activeFocus
+ ? ListFormStyle.value.backgroundColor.focused
+ : ListFormStyle.value.backgroundColor.normal
+ implicitHeight: textEdit.height
+ implicitWidth: textEdit.width
+ }
+
+ // Placeholder.
+ Text {
+ anchors.fill: textEdit
+ color: ListFormStyle.value.placeholder.color
+ font.italic: true
+ font.pointSize: ListFormStyle.value.placeholder.fontSize
+ padding: textEdit.padding
+ text: textEdit.text.length === 0 && !textEdit.activeFocus
+ ? qsTr('fillPlaceholder')
+ : ''
+ verticalAlignment: Text.AlignVCenter
+ }
+
+ // Input.
+ TextEdit {
+ id: textEdit
+
+ color: activeFocus
+ ? ListFormStyle.value.text.color.focused
+ : ListFormStyle.value.text.color.normal
+ font.bold: !activeFocus
+ height: ListFormStyle.lineHeight
+ padding: ListFormStyle.value.text.padding
+ selectByMouse: true
+ text: $value
+ verticalAlignment: TextEdit.AlignVCenter
+ width: !activeFocus
+ ? parent.width
+ : contentWidth + padding * 2
+
+ Keys.onEscapePressed: focus = false
+ Keys.onReturnPressed: focus = false
+
+ onEditingFinished: _handleEditionFinished(index, text)
+ }
+
+ // Handle click outside `TextEdit` instance.
+ InvertedMouseArea {
+ enabled: textEdit.activeFocus
+ height: textEdit.height
+ parent: parent
+ width: textEdit.width
+
+ onPressed: textEdit.focus = false
+ }
+ }
+ }
}
diff --git a/tests/ui/modules/Linphone/InvertedMouseArea.qml b/tests/ui/modules/Linphone/InvertedMouseArea.qml
index 518a2f079..cc85fb54f 100644
--- a/tests/ui/modules/Linphone/InvertedMouseArea.qml
+++ b/tests/ui/modules/Linphone/InvertedMouseArea.qml
@@ -2,6 +2,8 @@ import QtQuick 2.7
import Linphone 1.0
+import 'qrc:/ui/scripts/utils.js' as Utils
+
// ===================================================================
// Helper to handle button click outside a component.
// ===================================================================
@@ -39,9 +41,9 @@ Item {
function _isInItem (point) {
return (
point.x >= item.x &&
- point.y >= item.y &&
- point.x <= item.x + item.width &&
- point.y <= item.y + item.height
+ point.y >= item.y &&
+ point.x <= item.x + item.width &&
+ point.y <= item.y + item.height
)
}
@@ -49,7 +51,7 @@ Item {
// See: http://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal
//
// The creation order of components in a view is undefined,
- // so the mouse area must be created only when `enabled == true`.
+ // so the mouse area must be created only when `enabled === true`.
//
// In the first render, `enabled` must be equal to false.
Component.onCompleted: enabled && _createMouseArea()
@@ -67,6 +69,8 @@ Item {
id: builder
MouseArea {
+ property var _timeout
+
anchors.fill: parent
propagateComposedEvents: true
z: Constants.zMax
@@ -75,11 +79,23 @@ Item {
// Propagate event.
mouse.accepted = false
+ // Click is outside or not.
if (!_isInItem(
mapToItem(item.parent, mouse.x, mouse.y)
)) {
- // Outside!!!
- item.pressed()
+ if (_timeout != null) {
+ Utils.clearTimeout(_timeout)
+ }
+
+ // Use a asynchronous call that is executed
+ // after the propagated event.
+ //
+ // It's useful to ensure the window's context is not
+ // modified with the mouse event before the `onPressed`
+ // function.
+ //
+ // The timeout is destroyed with the `MouseArea` component.
+ _timeout = Utils.setTimeout.call(this, 0, item.pressed.bind(this))
}
}
}
diff --git a/tests/ui/modules/Linphone/Menu.qml b/tests/ui/modules/Linphone/Menu.qml
index 2a95f590f..1f22a7ecb 100644
--- a/tests/ui/modules/Linphone/Menu.qml
+++ b/tests/ui/modules/Linphone/Menu.qml
@@ -12,7 +12,7 @@ ColumnLayout {
property int entryHeight
property int entryWidth
- property variant entries
+ property var entries
property int _selectedEntry: 0
diff --git a/tests/ui/modules/Linphone/Popup/DropDownMenu.qml b/tests/ui/modules/Linphone/Popup/DropDownMenu.qml
index ce372db93..66a72c6fa 100644
--- a/tests/ui/modules/Linphone/Popup/DropDownMenu.qml
+++ b/tests/ui/modules/Linphone/Popup/DropDownMenu.qml
@@ -11,6 +11,14 @@ Rectangle {
property int entryHeight
property int maxMenuHeight
+ function show () {
+ visible = true
+ }
+
+ function hide () {
+ visible = false
+ }
+
// Ugly. Just ugly.
// `model` is a reference on a unknown component!
// See usage with SearchBox.
@@ -20,14 +28,6 @@ Rectangle {
}
visible: false
- function show () {
- visible = true
- }
-
- function hide () {
- visible = false
- }
-
Rectangle {
id: content
diff --git a/tests/ui/modules/Linphone/Styles/Form/ListFormStyle.qml b/tests/ui/modules/Linphone/Styles/Form/ListFormStyle.qml
new file mode 100644
index 000000000..f886b24d1
--- /dev/null
+++ b/tests/ui/modules/Linphone/Styles/Form/ListFormStyle.qml
@@ -0,0 +1,44 @@
+pragma Singleton
+import QtQuick 2.7
+
+import Linphone 1.0
+
+QtObject {
+ property int lineHeight: 30
+
+ property QtObject value: QtObject {
+ property QtObject backgroundColor: QtObject {
+ property color focused: '#E6E6E6'
+ property color normal: 'transparent'
+ }
+
+ property QtObject placeholder: QtObject {
+ property color color: '#5A585B'
+
+ property int fontSize: 10
+ }
+
+ property QtObject text: QtObject {
+ property int padding: 10
+
+ property QtObject color: QtObject {
+ property color focused: '#000000'
+ property color normal: '#5A585B'
+ }
+ }
+ }
+
+ property QtObject titleArea: QtObject {
+ property int spacing: 10
+ property int iconSize: 16
+
+ property string icon: 'add_field'
+
+ property QtObject text: QtObject {
+ property color color: '#000000'
+
+ property int fontSize: 10
+ property int width: 130
+ }
+ }
+}
diff --git a/tests/ui/modules/Linphone/Styles/qmldir b/tests/ui/modules/Linphone/Styles/qmldir
index 18f5cae28..4692f3405 100644
--- a/tests/ui/modules/Linphone/Styles/qmldir
+++ b/tests/ui/modules/Linphone/Styles/qmldir
@@ -15,6 +15,7 @@ singleton AbstractTextButtonStyle 1.0 Form/AbstractTextButtonStyle.qml
singleton ActionBarStyle 1.0 Form/ActionBarStyle.qml
singleton CheckBoxTextStyle 1.0 Form/CheckBoxTextStyle.qml
singleton ExclusiveButtonsStyle 1.0 Form/ExclusiveButtonsStyle.qml
+singleton ListFormStyle 1.0 Form/ListFormStyle.qml
singleton SmallButtonStyle 1.0 Form/SmallButtonStyle.qml
singleton TextButtonAStyle 1.0 Form/TextButtonAStyle.qml
singleton TextButtonBStyle 1.0 Form/TextButtonBStyle.qml
diff --git a/tests/ui/modules/Linphone/qmldir b/tests/ui/modules/Linphone/qmldir
index ac275de6b..35670b58e 100644
--- a/tests/ui/modules/Linphone/qmldir
+++ b/tests/ui/modules/Linphone/qmldir
@@ -25,6 +25,9 @@ ContactDescription 1.0 Contact/ContactDescription.qml
# Dialog
DialogPlus 1.0 Dialog/DialogPlus.qml
+# DropZone
+DropZone 1.0 DropZone.qml
+
# ForceScrollBar
ForceScrollBar 1.0 ForceScrollBar.qml
@@ -32,7 +35,6 @@ ForceScrollBar 1.0 ForceScrollBar.qml
ActionBar 1.0 Form/ActionBar.qml
ActionButton 1.0 Form/ActionButton.qml
CheckBoxText 1.0 Form/CheckBoxText.qml
-DropZone 1.0 Form/DropZone.qml
ExclusiveButtons 1.0 Form/ExclusiveButtons.qml
LightButton 1.0 Form/LightButton.qml
ListForm 1.0 Form/ListForm.qml
diff --git a/tests/ui/scripts/utils.js b/tests/ui/scripts/utils.js
index b64b996c6..18ca0acb0 100644
--- a/tests/ui/scripts/utils.js
+++ b/tests/ui/scripts/utils.js
@@ -76,3 +76,28 @@ function snakeToCamel (s) {
return matches[1].toUpperCase()
})
}
+
+// -------------------------------------------------------------------
+
+function Timer (parent) {
+ return Qt.createQmlObject('import QtQuick 2.7; Timer { }', parent)
+}
+
+// A copy of `Window.setTimeout` from js.
+// Use setTimeout.call(parentContext, delayTime, cb) to use it.
+//
+// delay is in milliseconds.
+function setTimeout (delay, cb) {
+ var timer = new Timer(this)
+
+ timer.interval = delay
+ timer.repeat = false
+ timer.triggered.connect(cb)
+ timer.start()
+
+ return timer
+}
+
+function clearTimeout (timer) {
+ timer.destroy() // Not necessary: `timer.stop()`
+}
diff --git a/tests/ui/views/MainWindow/Contact.qml b/tests/ui/views/MainWindow/Contact.qml
index dc465b965..89e0e0e3e 100644
--- a/tests/ui/views/MainWindow/Contact.qml
+++ b/tests/ui/views/MainWindow/Contact.qml
@@ -72,18 +72,33 @@ ColumnLayout {
ListForm {
title: qsTr('sipAccounts')
+ model: ListModel {
+ ListElement { $value: 'merinos@sip.linphone.org' }
+ ListElement { $value: 'elisabeth.pro@sip.linphone.org' }
+ }
}
ListForm {
title: qsTr('address')
+ model: ListModel {
+ ListElement { $value: '312 East 10th Street - New York, NY 1009' }
+ }
}
ListForm {
title: qsTr('emails')
+ model: ListModel {
+ ListElement { $value: 'e.meri@gmail.com' }
+ ListElement { $value: 'toto@truc.machin' }
+ }
}
ListForm {
title: qsTr('webSites')
+ model: ListModel {
+ ListElement { $value: 'www.totogro.com' }
+ ListElement { $value: 'www.404.unknown' }
+ }
}
}
}