diff --git a/tests/assets/images/edit_hovered.svg b/tests/assets/images/edit_hovered.svg
new file mode 100644
index 000000000..573854bd0
--- /dev/null
+++ b/tests/assets/images/edit_hovered.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/tests/assets/images/edit_normal.svg b/tests/assets/images/edit_normal.svg
new file mode 100644
index 000000000..c3b080307
--- /dev/null
+++ b/tests/assets/images/edit_normal.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/tests/assets/images/edit_pressed.svg b/tests/assets/images/edit_pressed.svg
new file mode 100644
index 000000000..7046014e8
--- /dev/null
+++ b/tests/assets/images/edit_pressed.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/tests/resources.qrc b/tests/resources.qrc
index e32ddb67e..ca2d2825b 100644
--- a/tests/resources.qrc
+++ b/tests/resources.qrc
@@ -53,6 +53,9 @@
assets/images/delete_hovered.svg
assets/images/delete_normal.svg
assets/images/delete_pressed.svg
+ assets/images/edit_hovered.svg
+ assets/images/edit_normal.svg
+ assets/images/edit_pressed.svg
assets/images/ended_call.svg
assets/images/filter.svg
assets/images/fullscreen_hovered.svg
diff --git a/tests/src/components/contact/ContactModel.cpp b/tests/src/components/contact/ContactModel.cpp
index 19d7406b0..3485777a1 100644
--- a/tests/src/components/contact/ContactModel.cpp
+++ b/tests/src/components/contact/ContactModel.cpp
@@ -1,3 +1,5 @@
+#include
+
#include "../../app/App.hpp"
#include "ContactModel.hpp"
@@ -16,6 +18,18 @@ ContactModel::ContactModel (shared_ptr linphone_friend) {
App::getInstance()->getEngine()->setObjectOwnership(m_vcard.get(), QQmlEngine::CppOwnership);
}
+ContactModel::ContactModel (VcardModel *vcard) {
+ QQmlEngine *engine = App::getInstance()->getEngine();
+ if (engine->objectOwnership(vcard) == QQmlEngine::CppOwnership)
+ throw std::invalid_argument("A contact is already linked to this vcard.");
+
+ m_linphone_friend = linphone::Friend::newFromVcard(vcard->m_vcard);
+ m_linphone_friend->setData(NAME, *this);
+ m_vcard.reset(vcard);
+
+ engine->setObjectOwnership(vcard, QQmlEngine::CppOwnership);
+}
+
Presence::PresenceStatus ContactModel::getPresenceStatus () const {
return Presence::PresenceStatus::Offline;
}
diff --git a/tests/src/components/contact/ContactModel.hpp b/tests/src/components/contact/ContactModel.hpp
index e166e649e..9ce99789e 100644
--- a/tests/src/components/contact/ContactModel.hpp
+++ b/tests/src/components/contact/ContactModel.hpp
@@ -22,6 +22,7 @@ class ContactModel : public QObject {
public:
ContactModel (std::shared_ptr linphone_friend);
+ ContactModel (VcardModel *vcard);
static const char *NAME;
diff --git a/tests/src/components/contact/VcardModel.cpp b/tests/src/components/contact/VcardModel.cpp
index 0ec6d8700..a082fdc31 100644
--- a/tests/src/components/contact/VcardModel.cpp
+++ b/tests/src/components/contact/VcardModel.cpp
@@ -109,8 +109,7 @@ bool VcardModel::setAvatar (const QString &path) {
}
// 4. Update.
- shared_ptr photo =
- belcard::BelCardGeneric::create();
+ shared_ptr photo = belcard::BelCardGeneric::create();
photo->setValue(VCARD_SCHEME + ::Utils::qStringToLinphoneString(file_id));
if (!belcard->addPhoto(photo))
@@ -145,8 +144,7 @@ bool VcardModel::setAddress (const QVariantMap &address) {
while (!addresses.empty())
belcard->removeAddress(addresses.front());
- shared_ptr belcard_address =
- belcard::BelCardGeneric::create();
+ shared_ptr belcard_address = belcard::BelCardGeneric::create();
belcard_address->setStreet(::Utils::qStringToLinphoneString(address["street"].toString()));
belcard_address->setLocality(::Utils::qStringToLinphoneString(address["locality"].toString()));
@@ -163,42 +161,35 @@ bool VcardModel::setAddress (const QVariantMap &address) {
QVariantList VcardModel::getSipAddresses () const {
QVariantList list;
- for (const auto &address : m_vcard->getSipAddresses())
- list.append(::Utils::linphoneStringToQString(address->asString()));
+ for (const auto &address : m_vcard->getBelcard()->getImpp())
+ list.append(::Utils::linphoneStringToQString(address->getValue()));
return list;
}
bool VcardModel::addSipAddress (const QString &sip_address) {
- shared_ptr address = CoreManager::getInstance()->getCore()->createAddress(
- ::Utils::qStringToLinphoneString(sip_address)
- );
-
- if (!address) {
- qWarning() << QStringLiteral("Unable to add invalid sip address: `%1`.").arg(sip_address);
- return false;
- }
+ shared_ptr belcard = m_vcard->getBelcard();
+ shared_ptr value = belcard::BelCardGeneric::create();
+ value->setValue(::Utils::qStringToLinphoneString(sip_address));
qInfo() << QStringLiteral("Add new sip address: `%1`.").arg(sip_address);
- m_vcard->addSipAddress(address->asStringUriOnly());
+
+ if (!belcard->addImpp(value)) {
+ qWarning() << QStringLiteral("Unable to add sip address: `%1`.").arg(sip_address);
+ return false;
+ }
emit vcardUpdated();
return true;
}
void VcardModel::removeSipAddress (const QString &sip_address) {
- list > addresses = m_vcard->getSipAddresses();
- string match = ::Utils::qStringToLinphoneString(sip_address);
+ shared_ptr belcard = m_vcard->getBelcard();
+ list > addresses = belcard->getImpp();
+ shared_ptr value = findBelCardValue(addresses, sip_address);
- auto it = find_if(
- addresses.cbegin(), addresses.cend(), [&match](const shared_ptr &address) {
- return match == address->asString();
- }
- );
-
- if (it == addresses.cend()) {
- qWarning() << QStringLiteral("Unable to found sip address: `%1`.")
- .arg(sip_address);
+ if (!value) {
+ qWarning() << QStringLiteral("Unable to remove sip address: `%1`.").arg(sip_address);
return;
}
@@ -209,7 +200,7 @@ void VcardModel::removeSipAddress (const QString &sip_address) {
}
qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address);
- m_vcard->removeSipAddress((*it)->asStringUriOnly());
+ belcard->removeImpp(value);
emit vcardUpdated();
}
@@ -241,8 +232,10 @@ bool VcardModel::addCompany (const QString &company) {
qInfo() << QStringLiteral("Add new company: `%1`.").arg(company);
- if (!belcard->addRole(value))
+ if (!belcard->addRole(value)) {
+ qWarning() << QStringLiteral("Unable to add company: `%1`.").arg(company);
return false;
+ }
emit vcardUpdated();
return true;
@@ -285,14 +278,15 @@ QVariantList VcardModel::getEmails () const {
bool VcardModel::addEmail (const QString &email) {
shared_ptr belcard = m_vcard->getBelcard();
- shared_ptr value =
- belcard::BelCardGeneric::create();
+ shared_ptr value = belcard::BelCardGeneric::create();
value->setValue(::Utils::qStringToLinphoneString(email));
qInfo() << QStringLiteral("Add new email: `%1`.").arg(email);
- if (!belcard->addEmail(value))
+ if (!belcard->addEmail(value)) {
+ qWarning() << QStringLiteral("Unable to add email: `%1`.").arg(email);
return false;
+ }
emit vcardUpdated();
return true;
@@ -340,8 +334,10 @@ bool VcardModel::addUrl (const QString &url) {
qInfo() << QStringLiteral("Add new url: `%1`.").arg(url);
- if (!belcard->addURL(value))
+ if (!belcard->addURL(value)) {
+ qWarning() << QStringLiteral("Unable to add url: `%1`.").arg(url);
return false;
+ }
emit vcardUpdated();
return true;
diff --git a/tests/src/components/contact/VcardModel.hpp b/tests/src/components/contact/VcardModel.hpp
index 709641d12..3606fca63 100644
--- a/tests/src/components/contact/VcardModel.hpp
+++ b/tests/src/components/contact/VcardModel.hpp
@@ -17,11 +17,13 @@ class VcardModel : public QObject {
Q_PROPERTY(QVariantList emails READ getEmails NOTIFY vcardUpdated);
Q_PROPERTY(QVariantList urls READ getUrls NOTIFY vcardUpdated);
- friend class ContactsListProxyModel;
+ friend class ContactModel;
public:
VcardModel (std::shared_ptr vcard) : m_vcard(vcard) {}
+ QString getUsername () const;
+
~VcardModel () = default;
public slots:
@@ -45,7 +47,6 @@ signals:
void vcardUpdated ();
private:
- QString getUsername () const;
void setUsername (const QString &username);
QString getAvatar () const;
diff --git a/tests/src/components/contacts/ContactsListModel.cpp b/tests/src/components/contacts/ContactsListModel.cpp
index aba27f5b5..fd6b38a48 100644
--- a/tests/src/components/contacts/ContactsListModel.cpp
+++ b/tests/src/components/contacts/ContactsListModel.cpp
@@ -27,7 +27,7 @@ ContactsListModel::ContactsListModel (QObject *parent) : QAbstractListModel(pare
}
}
-int ContactsListModel::rowCount (const QModelIndex&) const {
+int ContactsListModel::rowCount (const QModelIndex &) const {
return m_list.count();
}
@@ -49,8 +49,8 @@ QVariant ContactsListModel::data (const QModelIndex &index, int role) const {
return QVariant();
}
-bool ContactsListModel::removeRow (int row, const QModelIndex&) {
- return removeRows(row, 1);
+bool ContactsListModel::removeRow (int row, const QModelIndex &parent) {
+ return removeRows(row, 1, parent);
}
bool ContactsListModel::removeRows (int row, int count, const QModelIndex &parent) {
@@ -76,19 +76,38 @@ bool ContactsListModel::removeRows (int row, int count, const QModelIndex &paren
// -----------------------------------------------------------------------------
ContactModel *ContactsListModel::mapSipAddressToContact (const QString &sipAddress) const {
- // TODO: Maybe use a hashtable in future version to get a lower cost?
shared_ptr friend_ = m_linphone_friends->findFriendByUri(
::Utils::qStringToLinphoneString(sipAddress)
);
- if (!friend_) {
- qInfo() << QStringLiteral("Unable to map sip address: `%1`.").arg(sipAddress);
+ if (!friend_)
return nullptr;
- }
return &friend_->getData(ContactModel::NAME);
}
+void ContactsListModel::addContact (VcardModel *vcard) {
+ ContactModel *contact = new ContactModel(vcard);
+ App::getInstance()->getEngine()->setObjectOwnership(contact, QQmlEngine::CppOwnership);
+
+ qInfo() << "Add contact:" << contact;
+
+ if (
+ m_linphone_friends->addFriend(contact->m_linphone_friend) !=
+ linphone::FriendListStatus::FriendListStatusOK
+ ) {
+ qWarning() << "Unable to add friend from vcard:" << vcard;
+ delete contact;
+ return;
+ }
+
+ int row = rowCount();
+
+ beginInsertRows(QModelIndex(), row, row);
+ m_list << contact;
+ endInsertRows();
+}
+
void ContactsListModel::removeContact (ContactModel *contact) {
qInfo() << "Removing contact:" << contact;
diff --git a/tests/src/components/contacts/ContactsListModel.hpp b/tests/src/components/contacts/ContactsListModel.hpp
index 3c2af153b..524a984d6 100644
--- a/tests/src/components/contacts/ContactsListModel.hpp
+++ b/tests/src/components/contacts/ContactsListModel.hpp
@@ -27,6 +27,7 @@ public:
public slots:
ContactModel *mapSipAddressToContact (const QString &sipAddress) const;
+ void addContact (VcardModel *vcard);
void removeContact (ContactModel *contact);
private:
diff --git a/tests/src/components/core/CoreManager.cpp b/tests/src/components/core/CoreManager.cpp
index 184a8941c..4132187b3 100644
--- a/tests/src/components/core/CoreManager.cpp
+++ b/tests/src/components/core/CoreManager.cpp
@@ -6,12 +6,15 @@
CoreManager *CoreManager::m_instance = nullptr;
-CoreManager::CoreManager (QObject *parent) : QObject(parent), m_core(
- linphone::Factory::get()->createCore(nullptr, "", "", nullptr)
-) {
+CoreManager::CoreManager (QObject *parent) : QObject(parent),
+ m_core(linphone::Factory::get()->createCore(nullptr, "", "", nullptr)) {
setDatabasesPaths();
}
+VcardModel *CoreManager::createDetachedVcardModel () {
+ return new VcardModel(linphone::Factory::get()->createVcard());
+}
+
void CoreManager::setDatabasesPaths () {
std::string database_path;
diff --git a/tests/src/components/core/CoreManager.hpp b/tests/src/components/core/CoreManager.hpp
index 02e0e24d2..cb6b26a62 100644
--- a/tests/src/components/core/CoreManager.hpp
+++ b/tests/src/components/core/CoreManager.hpp
@@ -4,6 +4,8 @@
#include
#include
+#include "../contact/VcardModel.hpp"
+
// ===================================================================
class CoreManager : public QObject {
@@ -24,14 +26,16 @@ public:
return m_core;
}
+public slots:
+ VcardModel *createDetachedVcardModel ();
+
private:
CoreManager (QObject *parent = Q_NULLPTR);
void setDatabasesPaths ();
- static CoreManager *m_instance;
-
std::shared_ptr m_core;
+ static CoreManager *m_instance;
};
#endif // CORE_MANAGER_H_
diff --git a/tests/ui/modules/Common/Colors.qml b/tests/ui/modules/Common/Colors.qml
index f0ed65003..c8253c54e 100644
--- a/tests/ui/modules/Common/Colors.qml
+++ b/tests/ui/modules/Common/Colors.qml
@@ -1,13 +1,11 @@
pragma Singleton
import QtQuick 2.7
-// ===================================================================
+// =============================================================================
QtObject {
property color a: 'transparent'
- property color o: '#232323' // TextButtonA Hovered.
-
property color q: '#E6E6E6'
property color d: '#5A585B'
@@ -24,6 +22,7 @@ QtObject {
property color g20: '#336B7A86'
property color h: '#687680'
property color i: '#FE5E00'
+ property color i30: '#4DFE5E00'
property color j: '#4B5964'
property color j75: '#BF4B5964'
property color k: '#FFFFFF'
@@ -31,6 +30,7 @@ QtObject {
property color l: '#000000'
property color m: '#D1D1D1'
property color n: '#C0C0C0'
+ property color o: '#232323'
property color p: '#E2E9EF'
property color r: '#595759'
property color s: '#D64D00'
diff --git a/tests/ui/modules/Common/Form/AbstractTextButton.qml b/tests/ui/modules/Common/Form/AbstractTextButton.qml
index b8b397685..255fc14ea 100644
--- a/tests/ui/modules/Common/Form/AbstractTextButton.qml
+++ b/tests/ui/modules/Common/Form/AbstractTextButton.qml
@@ -3,48 +3,79 @@ import QtQuick.Controls 2.0
import Common.Styles 1.0
-// ===================================================================
+// =============================================================================
-Button {
- id: button
+Item {
+ id: wrappedButton
+ property color colorDisabled
property color colorHovered
property color colorNormal
property color colorPressed
// By default textColorNormal is the hovered/pressed text color.
+ property color textColorDisabled
property color textColorHovered: textColorNormal
property color textColorNormal
property color textColorPressed: textColorNormal
- background: Rectangle {
- color: button.down
- ? colorPressed
- : (button.hovered
- ? colorHovered
- : colorNormal
- )
- implicitHeight: AbstractTextButtonStyle.background.height
- implicitWidth: AbstractTextButtonStyle.background.width
- radius: AbstractTextButtonStyle.background.radius
- }
- contentItem: Text {
- color: button.down
- ? textColorPressed
- : (button.hovered
- ? textColorHovered
- : textColorNormal
- )
+ property alias text: button.text
+ property bool enabled: true
- font {
- bold: true
- pointSize: AbstractTextButtonStyle.text.fontSize
+ signal clicked
+
+ // ---------------------------------------------------------------------------
+
+ function _getBackgroundColor () {
+ if (!wrappedButton.enabled) {
+ return colorDisabled
}
- elide: Text.ElideRight
- horizontalAlignment: Text.AlignHCenter
- text: button.text
- verticalAlignment: Text.AlignVCenter
+ return button.down
+ ? colorPressed
+ : (button.hovered ? colorHovered : colorNormal)
+ }
+
+ function _getTextColor () {
+ if (!wrappedButton.enabled) {
+ return textColorDisabled
+ }
+
+ return button.down
+ ? textColorPressed
+ : (button.hovered ? textColorHovered : textColorNormal)
+ }
+
+ // ---------------------------------------------------------------------------
+
+ implicitHeight: button.height
+ implicitWidth: button.width
+
+ // ---------------------------------------------------------------------------
+
+ Button {
+ id: button
+
+ background: Rectangle {
+ color: _getBackgroundColor()
+ implicitHeight: AbstractTextButtonStyle.background.height
+ implicitWidth: AbstractTextButtonStyle.background.width
+ radius: AbstractTextButtonStyle.background.radius
+ }
+ contentItem: Text {
+ color: _getTextColor()
+ font {
+ bold: true
+ pointSize: AbstractTextButtonStyle.text.fontSize
+ }
+
+ elide: Text.ElideRight
+ horizontalAlignment: Text.AlignHCenter
+ text: button.text
+ verticalAlignment: Text.AlignVCenter
+ }
+ hoverEnabled: true
+
+ onClicked: wrappedButton.enabled && parent.clicked()
}
- hoverEnabled: true
}
diff --git a/tests/ui/modules/Common/Form/ListForm.qml b/tests/ui/modules/Common/Form/ListForm.qml
index b8bea4ea5..36999c0be 100644
--- a/tests/ui/modules/Common/Form/ListForm.qml
+++ b/tests/ui/modules/Common/Form/ListForm.qml
@@ -5,21 +5,23 @@ import Common 1.0
import Common.Styles 1.0
import Utils 1.0
-// ===================================================================
+// =============================================================================
RowLayout {
id: listForm
property alias placeholder: placeholder.text
property alias title: text.text
+ property bool readOnly: false
property int inputMethodHints
property var defaultData: []
property var minValues
+ readonly property int count: values.count
- signal changed (int index, string default_value, string new_value)
+ signal changed (int index, string defaultValue, string newValue)
signal removed (int index, string value)
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
function setInvalid (index, status) {
Utils.assert(
@@ -48,47 +50,41 @@ RowLayout {
}
function _handleEditionFinished (index, text) {
+ var model = values.model
+ var defaultValue = model.get(index).$value
+
if (text.length === 0) {
- // Remove.
- var default_value = values.model.get(index).$value
-
- if (minValues != null && minValues >= values.model.count) {
- var model = values.model
-
+ // No changes. It must exists at least n min values.
+ if (minValues != null && minValues >= model.count) {
// Unable to set property directly. Qt uses a cache of the value.
model.remove(index)
model.insert(index, {
$isInvalid: false,
- $value: default_value
+ $value: defaultValue
})
return
}
- values.model.remove(index)
+ model.remove(index)
- if (default_value.length !== 0) {
- listForm.removed(index, default_value)
- }
- } else {
- // Update.
- var default_value = values.model.get(index).$value
-
- // If no changes, no signal.
- if (text !== default_value) {
- listForm.changed(index, default_value, text)
+ if (defaultValue.length !== 0) {
+ listForm.removed(index, defaultValue)
}
+ } else if (text !== defaultValue) {
+ // Update changes.
+ listForm.changed(index, defaultValue, text)
}
addButton.enabled = true
}
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
spacing: 0
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
// Title area.
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
RowLayout {
Layout.alignment: Qt.AlignTop
@@ -100,8 +96,9 @@ RowLayout {
icon: 'add'
iconSize: ListFormStyle.titleArea.iconSize
+ opacity: _edition ? 1 : 0
- onClicked: _addValue('')
+ onClicked: _edition && _addValue('')
}
Text {
@@ -118,9 +115,9 @@ RowLayout {
}
}
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
// Placeholder.
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
Text {
id: placeholder
@@ -135,7 +132,7 @@ RowLayout {
}
padding: ListFormStyle.value.text.padding
- visible: values.model.count === 0
+ visible: values.model.count === 0 && !listForm.readOnly
verticalAlignment: Text.AlignVCenter
MouseArea {
@@ -144,9 +141,9 @@ RowLayout {
}
}
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
// Values.
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
ListView {
id: values
@@ -165,6 +162,7 @@ RowLayout {
inputMethodHints: listForm.inputMethodHints
isInvalid: $isInvalid
+ readOnly: listForm.readOnly
text: $value
height: ListFormStyle.lineHeight
@@ -190,16 +188,14 @@ RowLayout {
model: ListModel {}
- // ---------------------------------------------------------------
+ // -------------------------------------------------------------------------
// Init values.
- // ---------------------------------------------------------------
+ // -------------------------------------------------------------------------
Component.onCompleted: {
- if (!defaultData) {
- return
+ if (defaultData) {
+ setData(defaultData)
}
-
- setData(defaultData)
}
}
}
diff --git a/tests/ui/modules/Common/Form/TextButtonA.qml b/tests/ui/modules/Common/Form/TextButtonA.qml
index e07d31786..e290716f4 100644
--- a/tests/ui/modules/Common/Form/TextButtonA.qml
+++ b/tests/ui/modules/Common/Form/TextButtonA.qml
@@ -1,12 +1,14 @@
import Common.Styles 1.0
-// ===================================================================
+// =============================================================================
AbstractTextButton {
+ colorDisabled: TextButtonAStyle.backgroundColor.disabled
colorHovered: TextButtonAStyle.backgroundColor.hovered
colorNormal: TextButtonAStyle.backgroundColor.normal
colorPressed: TextButtonAStyle.backgroundColor.pressed
+ textColorDisabled: TextButtonAStyle.textColor.disabled
textColorHovered: TextButtonAStyle.textColor.hovered
textColorNormal: TextButtonAStyle.textColor.normal
textColorPressed: TextButtonAStyle.textColor.pressed
diff --git a/tests/ui/modules/Common/Form/TextButtonB.qml b/tests/ui/modules/Common/Form/TextButtonB.qml
index aacaf6c22..f11f6e196 100644
--- a/tests/ui/modules/Common/Form/TextButtonB.qml
+++ b/tests/ui/modules/Common/Form/TextButtonB.qml
@@ -1,12 +1,14 @@
import Common.Styles 1.0
-// ===================================================================
+// =============================================================================
AbstractTextButton {
+ colorDisabled: TextButtonBStyle.backgroundColor.disabled
colorHovered: TextButtonBStyle.backgroundColor.hovered
colorNormal: TextButtonBStyle.backgroundColor.normal
colorPressed: TextButtonBStyle.backgroundColor.pressed
+ textColorDisabled: TextButtonBStyle.textColor.disabled
textColorHovered: TextButtonBStyle.textColor.hovered
textColorNormal: TextButtonBStyle.textColor.normal
textColorPressed: TextButtonBStyle.textColor.pressed
diff --git a/tests/ui/modules/Common/Styles/Form/TextButtonAStyle.qml b/tests/ui/modules/Common/Styles/Form/TextButtonAStyle.qml
index 4cb056cdd..73a8e3059 100644
--- a/tests/ui/modules/Common/Styles/Form/TextButtonAStyle.qml
+++ b/tests/ui/modules/Common/Styles/Form/TextButtonAStyle.qml
@@ -3,16 +3,18 @@ import QtQuick 2.7
import Common 1.0
-// ===================================================================
+// =============================================================================
QtObject {
property QtObject backgroundColor: QtObject {
+ property color disabled: Colors.o
property color hovered: Colors.o
property color normal: Colors.j
property color pressed: Colors.i
}
property QtObject textColor: QtObject {
+ property color disabled: Colors.k
property color hovered: Colors.k
property color normal: Colors.k
property color pressed: Colors.k
diff --git a/tests/ui/modules/Common/Styles/Form/TextButtonBStyle.qml b/tests/ui/modules/Common/Styles/Form/TextButtonBStyle.qml
index 25ae38053..5ea66f2a6 100644
--- a/tests/ui/modules/Common/Styles/Form/TextButtonBStyle.qml
+++ b/tests/ui/modules/Common/Styles/Form/TextButtonBStyle.qml
@@ -3,16 +3,18 @@ import QtQuick 2.7
import Common 1.0
-// ===================================================================
+// =============================================================================
QtObject {
property QtObject backgroundColor: QtObject {
+ property color disabled: Colors.i30
property color hovered: Colors.s
property color normal: Colors.i
property color pressed: Colors.t
}
property QtObject textColor: QtObject {
+ property color disabled: Colors.k
property color hovered: Colors.k
property color normal: Colors.k
property color pressed: Colors.k
diff --git a/tests/ui/views/App/MainWindow/ContactEdit.qml b/tests/ui/views/App/MainWindow/ContactEdit.qml
index cf8d471b9..17028c3d2 100644
--- a/tests/ui/views/App/MainWindow/ContactEdit.qml
+++ b/tests/ui/views/App/MainWindow/ContactEdit.qml
@@ -5,22 +5,45 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
-import LinphoneUtils 1.0
import Utils 1.0
import App.Styles 1.0
-// ===================================================================
+// =============================================================================
ColumnLayout {
id: contactEdit
- property string sipAddress: ''
+ property string sipAddress
+ property bool _edition: false
property var _contact
property var _vcard
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
+
+ function _editContact () {
+ _contact.startEdit()
+ _edition = true
+ }
+
+ function _save () {
+ if (_contact) {
+ _contact.endEdit()
+ _edition = false
+ } else {
+ _contact = ContactsListModel.addContact(_vcard)
+ }
+ }
+
+ function _cancel () {
+ if (_contact) {
+ _contact.abortEdit()
+ _edition = false
+ } else {
+ window.setView('Contacts')
+ }
+ }
function _removeContact () {
Utils.openConfirmDialog(window, {
@@ -46,45 +69,55 @@ ColumnLayout {
usernameInput.text = _vcard.username
}
- function _handleSipAddressChanged (index, default_value, new_value) {
- if (!Utils.startsWith(new_value, 'sip:')) {
- new_value = 'sip:' + new_value
+ function _handleSipAddressChanged (index, defaultValue, newValue) {
+ if (!Utils.startsWith(newValue, 'sip:')) {
+ newValue = 'sip:' + newValue
- if (new_value === default_value) {
+ if (newValue === defaultValue) {
return
}
}
- var so_far_so_good = (default_value.length === 0)
- ? _vcard.addSipAddress(new_value)
- : _vcard.updateSipAddress(default_value, new_value)
+ var so_far_so_good = (defaultValue.length === 0)
+ ? _vcard.addSipAddress(newValue)
+ : _vcard.updateSipAddress(defaultValue, newValue)
addresses.setInvalid(index, !so_far_so_good)
}
- function _handleUrlChanged (index, default_value, new_value) {
- var url = Utils.extractFirstUri(new_value)
- if (url === default_value) {
+ function _handleUrlChanged (index, defaultValue, newValue) {
+ var url = Utils.extractFirstUri(newValue)
+ if (url === defaultValue) {
return
}
- var so_far_so_good = (default_value.length === 0)
- ? url && _vcard.addUrl(new_value)
- : url && _vcard.updateUrl(default_value, new_value)
+ var so_far_so_good = (defaultValue.length === 0)
+ ? url && _vcard.addUrl(newValue)
+ : url && _vcard.updateUrl(defaultValue, newValue)
urls.setInvalid(index, !so_far_so_good)
}
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
spacing: 0
Component.onCompleted: {
_contact = ContactsListModel.mapSipAddressToContact(sipAddress)
- _vcard = _contact.vcard
+
+ if (!_contact) {
+ _vcard = CoreManager.createDetachedVcardModel()
+ _edition = true
+ } else {
+ _vcard = _contact.vcard
+ }
}
- // -----------------------------------------------------------------
+ Component.onDestruction: {
+ // TODO: Remove photo if contact not created.
+ }
+
+ // ---------------------------------------------------------------------------
FileDialog {
id: avatarChooser
@@ -95,9 +128,9 @@ ColumnLayout {
onAccepted: _setAvatar(fileUrls[0])
}
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
// Info bar.
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
Rectangle {
Layout.fillWidth: true
@@ -124,7 +157,7 @@ ColumnLayout {
anchors.fill: parent
image: _vcard.avatar
- username: LinphoneUtils.getContactUsername(_contact) || 'John Doe'
+ username: _vcard.username
visible: isLoaded() && !parent.hovered
}
}
@@ -155,22 +188,30 @@ ColumnLayout {
ActionButton {
icon: 'history'
+
onClicked: window.setView('Conversation', {
sipAddress: contactEdit.sipAddress
})
}
+ ActionButton {
+ icon: 'edit'
+ visible: !_edition
+ onClicked: _editContact()
+ }
+
ActionButton {
icon: 'delete'
+
onClicked: _removeContact()
}
}
}
}
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
// Info list.
- // -----------------------------------------------------------------
+ // ---------------------------------------------------------------------------
Flickable {
id: flick
@@ -197,12 +238,13 @@ ColumnLayout {
Layout.rightMargin: ContactEditStyle.values.rightMargin
Layout.topMargin: ContactEditStyle.values.topMargin
- defaultData: _vcard.sipAddresses
- minValues: 1
+ defaultData: _vcard.sipAddresses
+ minValues: _contact ? 1 : 0
placeholder: qsTr('sipAccountsInput')
+ readOnly: !_edition
title: qsTr('sipAccounts')
- onChanged: _handleSipAddressChanged(index, default_value, new_value)
+ onChanged: _handleSipAddressChanged(index, defaultValue, newValue)
onRemoved: _vcard.removeSipAddress(value)
}
@@ -220,11 +262,12 @@ ColumnLayout {
defaultData: _vcard.companies
placeholder: qsTr('companiesInput')
+ readOnly: !_edition
title: qsTr('companies')
- onChanged: default_value.length === 0
- ? _vcard.addCompany(new_value)
- : _vcard.updateCompany(default_value, new_value)
+ onChanged: defaultValue.length === 0
+ ? _vcard.addCompany(newValue)
+ : _vcard.updateCompany(defaultValue, newValue)
onRemoved: _vcard.removeCompany(value)
}
@@ -243,11 +286,12 @@ ColumnLayout {
defaultData: _vcard.emails
inputMethodHints: Qt.ImhEmailCharactersOnly
placeholder: qsTr('emailsInput')
+ readOnly: !_edition
title: qsTr('emails')
- onChanged: default_value.length === 0
- ? _vcard.addEmail(new_value)
- : _vcard.updateEmail(default_value, new_value)
+ onChanged: defaultValue.length === 0
+ ? _vcard.addEmail(newValue)
+ : _vcard.updateEmail(defaultValue, newValue)
onRemoved: _vcard.removeEmail(value)
}
@@ -266,9 +310,10 @@ ColumnLayout {
defaultData: _vcard.urls
inputMethodHints: Qt.ImhUrlCharactersOnly
placeholder: qsTr('webSitesInput')
+ readOnly: !_edition
title: qsTr('webSites')
- onChanged: _handleUrlChanged(index, default_value, new_value)
+ onChanged: _handleUrlChanged(index, defaultValue, newValue)
onRemoved: _vcard.removeUrl(value)
}
@@ -278,20 +323,21 @@ ColumnLayout {
color: ContactEditStyle.values.separator.color
}
- Loader {
+ Row {
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: ContactEditStyle.buttons.topMargin
+ spacing: ContactEditStyle.buttons.spacing
+ visible: _edition
- sourceComponent: Row {
- spacing: ContactEditStyle.buttons.spacing
+ TextButtonB {
+ enabled: _vcard.sipAddresses.length > 0
+ text: qsTr('save')
+ onClicked: _save()
+ }
- TextButtonB {
- text: qsTr('save')
- }
-
- TextButtonA {
- text: qsTr('cancel')
- }
+ TextButtonA {
+ text: qsTr('cancel')
+ onClicked: _cancel()
}
}