diff --git a/tests/assets/images/generic_error.svg b/tests/assets/images/generic_error.svg
new file mode 100644
index 000000000..1a9838722
--- /dev/null
+++ b/tests/assets/images/generic_error.svg
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/tests/assets/languages/en.ts b/tests/assets/languages/en.ts
index 15241168c..9f9b8563b 100644
--- a/tests/assets/languages/en.ts
+++ b/tests/assets/languages/en.ts
@@ -144,11 +144,19 @@
companiesInput
-
+ Company
companies
-
+ COMPANIES
+
+
+ save
+ SAVE
+
+
+ cancel
+ CANCEL
diff --git a/tests/assets/languages/fr.ts b/tests/assets/languages/fr.ts
index b43aa3256..3f06d9d8c 100644
--- a/tests/assets/languages/fr.ts
+++ b/tests/assets/languages/fr.ts
@@ -142,6 +142,14 @@
companies
+
+ save
+
+
+
+ cancel
+ ANNULER
+
Contacts
diff --git a/tests/resources.qrc b/tests/resources.qrc
index 6fb7514eb..e32ddb67e 100644
--- a/tests/resources.qrc
+++ b/tests/resources.qrc
@@ -58,6 +58,7 @@
assets/images/fullscreen_hovered.svg
assets/images/fullscreen_normal.svg
assets/images/fullscreen_pressed.svg
+ assets/images/generic_error.svg
assets/images/hangup_hovered.svg
assets/images/hangup_normal.svg
assets/images/hangup_pressed.svg
diff --git a/tests/src/components/contacts/ContactModel.cpp b/tests/src/components/contacts/ContactModel.cpp
index 743f74e3d..c833ef9c3 100644
--- a/tests/src/components/contacts/ContactModel.cpp
+++ b/tests/src/components/contacts/ContactModel.cpp
@@ -154,7 +154,7 @@ QVariantList ContactModel::getSipAddresses () const {
return list;
}
-void ContactModel::addSipAddress (const QString &sip_address) {
+bool ContactModel::addSipAddress (const QString &sip_address) {
shared_ptr address =
CoreManager::getInstance()->getCore()->createAddress(
Utils::qStringToLinphoneString(sip_address)
@@ -162,7 +162,7 @@ void ContactModel::addSipAddress (const QString &sip_address) {
if (!address) {
qWarning() << QStringLiteral("Unable to add invalid sip address: `%1`.").arg(sip_address);
- return;
+ return false;
}
qInfo() << QStringLiteral("Add new sip address: `%1`.").arg(sip_address);
@@ -172,9 +172,11 @@ void ContactModel::addSipAddress (const QString &sip_address) {
m_linphone_friend->done();
emit contactUpdated();
+
+ return true;
}
-bool ContactModel::removeSipAddress (const QString &sip_address) {
+void ContactModel::removeSipAddress (const QString &sip_address) {
list > addresses = m_linphone_friend->getAddresses();
string match = Utils::qStringToLinphoneString(sip_address);
@@ -188,13 +190,13 @@ bool ContactModel::removeSipAddress (const QString &sip_address) {
if (it == addresses.cend()) {
qWarning() << QStringLiteral("Unable to found sip address: `%1`.")
.arg(sip_address);
- return false;
+ return;
}
if (addresses.size() == 1) {
qWarning() << QStringLiteral("Unable to remove the only existing sip address: `%1`.")
.arg(sip_address);
- return false;
+ return;
}
qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address);
@@ -205,14 +207,16 @@ bool ContactModel::removeSipAddress (const QString &sip_address) {
emit contactUpdated();
- return true;
+ return;
}
-void ContactModel::updateSipAddress (const QString &old_sip_address, const QString &sip_address) {
- if (old_sip_address == sip_address || !removeSipAddress(old_sip_address))
- return;
+bool ContactModel::updateSipAddress (const QString &old_sip_address, const QString &sip_address) {
+ if (old_sip_address == sip_address || !addSipAddress(sip_address))
+ return false;
- addSipAddress(sip_address);
+ removeSipAddress(old_sip_address);
+
+ return true;
}
// -------------------------------------------------------------------
@@ -241,13 +245,13 @@ void ContactModel::addCompany (const QString &company) {
emit contactUpdated();
}
-bool ContactModel::removeCompany (const QString &company) {
+void ContactModel::removeCompany (const QString &company) {
shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard();
shared_ptr value = findBelCardValue(belCard->getRoles(), company);
if (!value) {
qWarning() << QStringLiteral("Unable to remove company: `%1`.").arg(company);
- return false;
+ return;
}
qInfo() << QStringLiteral("Remove company: `%1`.").arg(company);
@@ -257,15 +261,14 @@ bool ContactModel::removeCompany (const QString &company) {
m_linphone_friend->done();
emit contactUpdated();
-
- return true;
}
void ContactModel::updateCompany (const QString &old_company, const QString &company) {
- if (old_company == company || !removeCompany(old_company))
+ if (old_company == company)
return;
addCompany(company);
+ removeCompany(old_company);
}
// -------------------------------------------------------------------
@@ -279,7 +282,7 @@ QVariantList ContactModel::getEmails () const {
return list;
}
-void ContactModel::addEmail (const QString &email) {
+bool ContactModel::addEmail (const QString &email) {
shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard();
shared_ptr value =
belcard::BelCardGeneric::create();
@@ -292,15 +295,18 @@ void ContactModel::addEmail (const QString &email) {
m_linphone_friend->done();
emit contactUpdated();
+
+ // TODO: Check if email is valid.
+ return true;
}
-bool ContactModel::removeEmail (const QString &email) {
+void ContactModel::removeEmail (const QString &email) {
shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard();
shared_ptr value = findBelCardValue(belCard->getEmails(), email);
if (!value) {
qWarning() << QStringLiteral("Unable to remove email: `%1`.").arg(email);
- return false;
+ return;
}
qInfo() << QStringLiteral("Remove email: `%1`.").arg(email);
@@ -310,15 +316,15 @@ bool ContactModel::removeEmail (const QString &email) {
m_linphone_friend->done();
emit contactUpdated();
-
- return true;
}
-void ContactModel::updateEmail (const QString &old_email, const QString &email) {
- if (old_email == email || !removeEmail(old_email))
- return;
+bool ContactModel::updateEmail (const QString &old_email, const QString &email) {
+ if (old_email == email || !addEmail(email))
+ return false;
- addEmail(email);
+ removeEmail(old_email);
+
+ return true;
}
// -------------------------------------------------------------------
@@ -332,7 +338,7 @@ QVariantList ContactModel::getUrls () const {
return list;
}
-void ContactModel::addUrl (const QString &url) {
+bool ContactModel::addUrl (const QString &url) {
shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard();
shared_ptr value =
belcard::BelCardGeneric::create();
@@ -345,15 +351,18 @@ void ContactModel::addUrl (const QString &url) {
m_linphone_friend->done();
emit contactUpdated();
+
+ // TODO: Check if url is valid.
+ return true;
}
-bool ContactModel::removeUrl (const QString &url) {
+void ContactModel::removeUrl (const QString &url) {
shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard();
shared_ptr value = findBelCardValue(belCard->getURLs(), url);
if (!value) {
qWarning() << QStringLiteral("Unable to remove url: `%1`.").arg(url);
- return false;
+ return;
}
qInfo() << QStringLiteral("Remove url: `%1`.").arg(url);
@@ -363,20 +372,25 @@ bool ContactModel::removeUrl (const QString &url) {
m_linphone_friend->done();
emit contactUpdated();
+}
+
+bool ContactModel::updateUrl (const QString &old_url, const QString &url) {
+ if (old_url == url || !addUrl(url))
+ return false;
+
+ removeUrl(old_url);
return true;
}
-void ContactModel::updateUrl (const QString &old_url, const QString &url) {
- if (old_url == url || !removeUrl(old_url))
- return;
-
- addUrl(url);
-}
-
// -------------------------------------------------------------------
-QList ContactModel::getAddresses () const {
+QVariantMap ContactModel::getAddress () const {
+
+}
+
+void ContactModel::setAddress (const QVariantMap &address) {
+
}
diff --git a/tests/src/components/contacts/ContactModel.hpp b/tests/src/components/contacts/ContactModel.hpp
index f337673ee..d6adbde6d 100644
--- a/tests/src/components/contacts/ContactModel.hpp
+++ b/tests/src/components/contacts/ContactModel.hpp
@@ -20,12 +20,7 @@ class ContactModel : public QObject {
Q_PROPERTY(QVariantList companies READ getCompanies NOTIFY contactUpdated);
Q_PROPERTY(QVariantList emails READ getEmails NOTIFY contactUpdated);
Q_PROPERTY(QVariantList urls READ getUrls NOTIFY contactUpdated);
-
- Q_PROPERTY(
- QList addresses
- READ getAddresses
- NOTIFY contactUpdated
- );
+ Q_PROPERTY(QVariantMap address READ getAddress WRITE setAddress NOTIFY contactUpdated);
Q_PROPERTY(
Presence::PresenceStatus presenceStatus
@@ -49,21 +44,21 @@ public:
ContactModel (std::shared_ptr linphone_friend);
public slots:
- void addSipAddress (const QString &sip_address);
- bool removeSipAddress (const QString &sip_address);
- void updateSipAddress (const QString &old_sip_address, const QString &sip_address);
+ bool addSipAddress (const QString &sip_address);
+ void removeSipAddress (const QString &sip_address);
+ bool updateSipAddress (const QString &old_sip_address, const QString &sip_address);
void addCompany (const QString &company);
- bool removeCompany (const QString &company);
+ void removeCompany (const QString &company);
void updateCompany (const QString &old_company, const QString &company);
- void addEmail (const QString &email);
- bool removeEmail (const QString &email);
- void updateEmail (const QString &old_email, const QString &email);
+ bool addEmail (const QString &email);
+ void removeEmail (const QString &email);
+ bool updateEmail (const QString &old_email, const QString &email);
- void addUrl (const QString &url);
- bool removeUrl (const QString &url);
- void updateUrl (const QString &old_url, const QString &url);
+ bool addUrl (const QString &url);
+ void removeUrl (const QString &url);
+ bool updateUrl (const QString &old_url, const QString &url);
signals:
void contactUpdated ();
@@ -80,12 +75,13 @@ private:
QVariantList getEmails () const;
QVariantList getUrls () const;
- QList getAddresses () const;
- void setAddresses (const QList &addresses);
+ QVariantMap getAddress () const;
+ void setAddress (const QVariantMap &address);
Presence::PresenceStatus getPresenceStatus () const;
Presence::PresenceLevel getPresenceLevel () const;
+ // TODO: Remove!!!
QString getSipAddress () const;
Presence::PresenceStatus m_presence_status = Presence::Offline;
diff --git a/tests/ui/modules/Common/Form/ListForm.qml b/tests/ui/modules/Common/Form/ListForm.qml
index 07f0248d8..211094810 100644
--- a/tests/ui/modules/Common/Form/ListForm.qml
+++ b/tests/ui/modules/Common/Form/ListForm.qml
@@ -14,22 +14,31 @@ RowLayout {
property alias title: text.text
property var defaultData: []
- signal changed (int id, string default_value, string new_value)
- signal removed (int id, string value)
+ signal changed (int index, string default_value, string new_value)
+ signal removed (int index, string value)
// -----------------------------------------------------------------
+ function setInvalid (index, status) {
+ Utils.assert(
+ index >= 0 && index < values.model.count,
+ 'Index ' + index + 'not exists.'
+ )
+
+ values.model.setProperty(index, '$isInvalid', status)
+ }
+
function setData (data) {
var model = values.model
model.clear()
data.forEach(function (data) {
- model.append({ $value: data })
+ model.append({ $value: data, $isInvalid: false })
})
}
function _addValue (value) {
- values.model.append({ $value: value })
+ values.model.append({ $value: value, $isInvalid: false })
if (value.length === 0) {
addButton.enabled = false
@@ -46,7 +55,10 @@ RowLayout {
}
} else {
var default_value = values.model.get(index).$value
- listForm.changed(index, default_value, text)
+
+ if (text !== default_value) {
+ listForm.changed(index, default_value, text)
+ }
}
addButton.enabled = true
@@ -130,12 +142,14 @@ RowLayout {
implicitHeight: textInput.height
width: parent.width
- TransparentTextInput {
+ TransparentTextInput {
id: textInput
+ isInvalid: $isInvalid
text: $value
- width: parent.width
+
height: ListFormStyle.lineHeight
+ width: parent.width
onEditingFinished: _handleEditionFinished(index, text)
}
diff --git a/tests/ui/modules/Common/Form/TransparentTextInput.qml b/tests/ui/modules/Common/Form/TransparentTextInput.qml
index c6aa53be3..77c793805 100644
--- a/tests/ui/modules/Common/Form/TransparentTextInput.qml
+++ b/tests/ui/modules/Common/Form/TransparentTextInput.qml
@@ -12,6 +12,7 @@ Item {
property alias font: textInput.font
property alias readOnly: textInput.readOnly
property alias text: textInput.text
+ property bool isInvalid: false
property int padding: TransparentTextInputStyle.padding
signal editingFinished
@@ -25,6 +26,8 @@ Item {
}
Rectangle {
+ id: background
+
color: textInput.activeFocus && !textInput.readOnly
? TransparentTextInputStyle.backgroundColor
: // No Style constant, see component name.
@@ -44,6 +47,16 @@ Item {
}
}
+ Icon {
+ id: icon
+
+ anchors.left: background.right
+ height: background.height
+ icon: 'generic_error'
+ iconSize: 12
+ visible: parent.isInvalid
+ }
+
TextInput {
id: textInput
diff --git a/tests/ui/modules/Common/SmartConnect.qml b/tests/ui/modules/Common/SmartConnect.qml
index bd9fa3a4e..6869c9b33 100644
--- a/tests/ui/modules/Common/SmartConnect.qml
+++ b/tests/ui/modules/Common/SmartConnect.qml
@@ -8,7 +8,7 @@ Item {
property bool _connected: false
function connect (emitter, signalName, handler) {
- Utils.assert(!_connected, 'Smart connect is already connected!')
+ Utils.assert(!_connected, 'SmartConnect is already connected!')
emitter[signalName].connect(handler)
_connected = true
diff --git a/tests/ui/scripts/Utils/utils.js b/tests/ui/scripts/Utils/utils.js
index b8e35f26a..c8e59722a 100644
--- a/tests/ui/scripts/Utils/utils.js
+++ b/tests/ui/scripts/Utils/utils.js
@@ -74,6 +74,13 @@ function encodeTextToQmlRichFormat (text, options) {
return images.concat('' + text + '
')
}
+function extractFirstUri (str) {
+ var res = str.match(UriTools.URI_REGEX)
+ return res == null || startsWith(res[0], 'www')
+ ? undefined
+ : res[0]
+}
+
// -------------------------------------------------------------------
// Returns the top (root) parent of one object.
diff --git a/tests/ui/views/App/MainWindow/ContactEdit.qml b/tests/ui/views/App/MainWindow/ContactEdit.qml
index 3208c0849..a2757794a 100644
--- a/tests/ui/views/App/MainWindow/ContactEdit.qml
+++ b/tests/ui/views/App/MainWindow/ContactEdit.qml
@@ -49,6 +49,39 @@ ColumnLayout {
}
}
+ function _handleSipAddressChanged (index, default_value, new_value) {
+ if (!Utils.startsWith(new_value, 'sip:')) {
+ new_value = 'sip:' + new_value
+
+ if (new_value === default_value) {
+ return
+ }
+ }
+
+ var so_far_so_good = (default_value.length === 0)
+ ? _contact.addSipAddress(new_value)
+ : _contact.updateSipAddress(default_value, new_value)
+
+ if (!so_far_so_good) {
+ addresses.setInvalid(index, true)
+ }
+ }
+
+ function _handleUrlChanged (index, default_value, new_value) {
+ var url = Utils.extractFirstUri(new_value)
+ if (url === default_value) {
+ return
+ }
+
+ var so_far_so_good = (default_value.length === 0)
+ ? url && _contact.addUrl(new_value)
+ : url && _contact.updateUrl(default_value, new_value)
+
+ if (!so_far_so_good) {
+ urls.setInvalid(index, true)
+ }
+ }
+
// -----------------------------------------------------------------
spacing: 0
@@ -168,13 +201,9 @@ ColumnLayout {
boundsBehavior: Flickable.StopAtBounds
clip: true
contentHeight: infoList.height
- contentWidth: width - ScrollBar.vertical.width - leftMargin - rightMargin
+ contentWidth: width - ScrollBar.vertical.width
flickableDirection: Flickable.VerticalFlick
- leftMargin: ContactEditStyle.values.leftMargin
- rightMargin: ContactEditStyle.values.rightMargin
- topMargin: ContactEditStyle.values.topMargin
-
ColumnLayout {
id: infoList
@@ -187,19 +216,30 @@ ColumnLayout {
ListForm {
id: addresses
+ Layout.leftMargin: ContactEditStyle.values.leftMargin
+ Layout.rightMargin: ContactEditStyle.values.rightMargin
+ Layout.topMargin: ContactEditStyle.values.topMargin
+
defaultData: _contact.sipAddresses
placeholder: qsTr('sipAccountsInput')
title: qsTr('sipAccounts')
- onChanged: default_value.length === 0
- ? _contact.addSipAddress(new_value)
- : _contact.updateSipAddress(default_value, new_value)
+ onChanged: _handleSipAddressChanged(index, default_value, new_value)
onRemoved: _contact.removeSipAddress(value)
}
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.preferredHeight: ContactEditStyle.values.separator.height
+ color: ContactEditStyle.values.separator.color
+ }
+
ListForm {
id: companies
+ Layout.leftMargin: ContactEditStyle.values.leftMargin
+ Layout.rightMargin: ContactEditStyle.values.rightMargin
+
defaultData: _contact.companies
placeholder: qsTr('companiesInput')
title: qsTr('companies')
@@ -210,9 +250,18 @@ ColumnLayout {
onRemoved: _contact.removeCompany(value)
}
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.preferredHeight: ContactEditStyle.values.separator.height
+ color: ContactEditStyle.values.separator.color
+ }
+
ListForm {
id: emails
+ Layout.leftMargin: ContactEditStyle.values.leftMargin
+ Layout.rightMargin: ContactEditStyle.values.rightMargin
+
defaultData: _contact.emails
placeholder: qsTr('emailsInput')
title: qsTr('emails')
@@ -223,23 +272,52 @@ ColumnLayout {
onRemoved: _contact.removeEmail(value)
}
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.preferredHeight: ContactEditStyle.values.separator.height
+ color: ContactEditStyle.values.separator.color
+ }
+
ListForm {
id: urls
+ Layout.leftMargin: ContactEditStyle.values.leftMargin
+ Layout.rightMargin: ContactEditStyle.values.rightMargin
+
defaultData: _contact.urls
placeholder: qsTr('webSitesInput')
title: qsTr('webSites')
- onChanged: default_value.length === 0
- ? _contact.addUrl(new_value)
- : _contact.updateUrl(default_value, new_value)
+ onChanged: _handleUrlChanged(index, default_value, new_value)
onRemoved: _contact.removeUrl(value)
}
+
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.preferredHeight: ContactEditStyle.values.separator.height
+ color: ContactEditStyle.values.separator.color
+ }
+
+ Loader {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.topMargin: ContactEditStyle.buttons.topMargin
+
+ sourceComponent: Row {
+ spacing: ContactEditStyle.buttons.spacing
+
+ TextButtonB {
+ text: qsTr('save')
+ }
+
+ TextButtonA {
+ text: qsTr('cancel')
+ }
+ }
+ }
+
+ Item {
+ Layout.bottomMargin: ContactEditStyle.values.bottomMargin
+ }
}
}
}
-
-/* ListForm { */
-/* title: qsTr('address') */
-/* placeholder: qsTr('addressInput') */
-/* } */
diff --git a/tests/ui/views/App/Styles/MainWindow/ContactEditStyle.qml b/tests/ui/views/App/Styles/MainWindow/ContactEditStyle.qml
index 1f2ce88cc..9fbbc29d2 100644
--- a/tests/ui/views/App/Styles/MainWindow/ContactEditStyle.qml
+++ b/tests/ui/views/App/Styles/MainWindow/ContactEditStyle.qml
@@ -25,9 +25,20 @@ QtObject {
}
}
+ property QtObject buttons: QtObject {
+ property int spacing: 20
+ property int topMargin: 20
+ }
+
property QtObject values: QtObject {
+ property int bottomMargin: 20
property int leftMargin: 40
property int rightMargin: 20
- property int topMargin: 40
+ property int topMargin: 20
+
+ property QtObject separator: QtObject {
+ property color color: '#E8E8E8'
+ property int height: 1
+ }
}
}