diff --git a/tests/src/components/contacts/ContactModel.cpp b/tests/src/components/contacts/ContactModel.cpp index c833ef9c3..7f0290355 100644 --- a/tests/src/components/contacts/ContactModel.cpp +++ b/tests/src/components/contacts/ContactModel.cpp @@ -37,9 +37,25 @@ inline shared_ptr findBelCardValue ( // ------------------------------------------------------------------- -ContactModel::ContactModel (shared_ptr linphone_friend) { +ContactModel::ContactModel ( + shared_ptr linphone_friend, + bool is_detached +) { linphone_friend->setData("contact-model", *this); m_linphone_friend = linphone_friend; + m_is_detached = is_detached; +} + +// ------------------------------------------------------------------- + +void ContactModel::edit () { + if (!m_is_detached) + m_linphone_friend->edit(); +} + +void ContactModel::done () { + if (!m_is_detached) + m_linphone_friend->done(); } // ------------------------------------------------------------------- @@ -54,12 +70,12 @@ void ContactModel::setUsername (const QString &username) { if (username.length() == 0 || username == getUsername()) return; - m_linphone_friend->edit(); + edit(); if (!m_linphone_friend->setName(Utils::qStringToLinphoneString(username))) emit contactUpdated(); - m_linphone_friend->done(); + done(); } // ------------------------------------------------------------------- @@ -109,7 +125,7 @@ void ContactModel::setAvatar (const QString &path) { .arg(getUsername()).arg(dest); // 2. Edit vcard. - m_linphone_friend->edit(); + edit(); shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard(); list > photos = belCard->getPhotos(); @@ -136,7 +152,7 @@ void ContactModel::setAvatar (const QString &path) { photo->setValue(VCARD_SCHEME + Utils::qStringToLinphoneString(file_id)); belCard->addPhoto(photo); - m_linphone_friend->done(); + done(); emit contactUpdated(); @@ -167,9 +183,9 @@ bool ContactModel::addSipAddress (const QString &sip_address) { qInfo() << QStringLiteral("Add new sip address: `%1`.").arg(sip_address); - m_linphone_friend->edit(); + edit(); m_linphone_friend->addAddress(address); - m_linphone_friend->done(); + done(); emit contactUpdated(); @@ -201,9 +217,9 @@ void ContactModel::removeSipAddress (const QString &sip_address) { qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address); - m_linphone_friend->edit(); + edit(); m_linphone_friend->removeAddress(*it); - m_linphone_friend->done(); + done(); emit contactUpdated(); @@ -238,9 +254,9 @@ void ContactModel::addCompany (const QString &company) { qInfo() << QStringLiteral("Add new company: `%1`.").arg(company); - m_linphone_friend->edit(); + edit(); belCard->addRole(value); - m_linphone_friend->done(); + done(); emit contactUpdated(); } @@ -256,9 +272,9 @@ void ContactModel::removeCompany (const QString &company) { qInfo() << QStringLiteral("Remove company: `%1`.").arg(company); - m_linphone_friend->edit(); + edit(); belCard->removeRole(value); - m_linphone_friend->done(); + done(); emit contactUpdated(); } @@ -290,9 +306,9 @@ bool ContactModel::addEmail (const QString &email) { qInfo() << QStringLiteral("Add new email: `%1`.").arg(email); - m_linphone_friend->edit(); + edit(); belCard->addEmail(value); - m_linphone_friend->done(); + done(); emit contactUpdated(); @@ -311,9 +327,9 @@ void ContactModel::removeEmail (const QString &email) { qInfo() << QStringLiteral("Remove email: `%1`.").arg(email); - m_linphone_friend->edit(); + edit(); belCard->removeEmail(value); - m_linphone_friend->done(); + done(); emit contactUpdated(); } @@ -332,6 +348,8 @@ bool ContactModel::updateEmail (const QString &old_email, const QString &email) QVariantList ContactModel::getUrls () const { QVariantList list; + qDebug() << "card" << m_linphone_friend->getVcard().get(); + for (const auto &url : m_linphone_friend->getVcard()->getBelcard()->getURLs()) list.append(Utils::linphoneStringToQString(url->getValue())); @@ -346,9 +364,9 @@ bool ContactModel::addUrl (const QString &url) { qInfo() << QStringLiteral("Add new url: `%1`.").arg(url); - m_linphone_friend->edit(); + edit(); belCard->addURL(value); - m_linphone_friend->done(); + done(); emit contactUpdated(); @@ -367,9 +385,9 @@ void ContactModel::removeUrl (const QString &url) { qInfo() << QStringLiteral("Remove url: `%1`.").arg(url); - m_linphone_friend->edit(); + edit(); belCard->removeURL(value); - m_linphone_friend->done(); + done(); emit contactUpdated(); } diff --git a/tests/src/components/contacts/ContactModel.hpp b/tests/src/components/contacts/ContactModel.hpp index d6adbde6d..dda66574f 100644 --- a/tests/src/components/contacts/ContactModel.hpp +++ b/tests/src/components/contacts/ContactModel.hpp @@ -41,9 +41,13 @@ class ContactModel : public QObject { ); public: - ContactModel (std::shared_ptr linphone_friend); + ContactModel ( + std::shared_ptr linphone_friend, + bool is_detached = false + ); public slots: + bool addSipAddress (const QString &sip_address); void removeSipAddress (const QString &sip_address); bool updateSipAddress (const QString &old_sip_address, const QString &sip_address); @@ -64,6 +68,9 @@ signals: void contactUpdated (); private: + void edit (); + void done (); + QString getUsername () const; void setUsername (const QString &username); @@ -84,6 +91,8 @@ private: // TODO: Remove!!! QString getSipAddress () const; + bool m_is_detached; + Presence::PresenceStatus m_presence_status = Presence::Offline; std::shared_ptr m_linphone_friend; diff --git a/tests/src/components/contacts/ContactsListModel.cpp b/tests/src/components/contacts/ContactsListModel.cpp index 0af38c443..a26588af4 100644 --- a/tests/src/components/contacts/ContactsListModel.cpp +++ b/tests/src/components/contacts/ContactsListModel.cpp @@ -16,6 +16,9 @@ ContactsListModel::ContactsListModel (QObject *parent): QAbstractListModel(paren // Init contacts with linphone friends list. for (const auto &friend_ : m_linphone_friends->getFriends()) { ContactModel *contact = new ContactModel(friend_); + + // See: http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#data-ownership + // The returned value must have a explicit parent or a QQmlEngine::CppOwnership. App::getInstance()->getEngine()->setObjectOwnership( contact, QQmlEngine::CppOwnership ); @@ -72,6 +75,13 @@ bool ContactsListModel::removeRows (int row, int count, const QModelIndex &paren // ------------------------------------------------------------------- +ContactModel *ContactsListModel::createDetachedContact () const { + return new ContactModel( + CoreManager::getInstance()->getCore()->createFriend(), + true + ); +} + ContactModel *ContactsListModel::mapSipAddressToContact (const QString &sipAddress) const { // Maybe use a hashtable in future version to get a lower cost? std::shared_ptr friend_ = m_linphone_friends->findFriendByUri( diff --git a/tests/src/components/contacts/ContactsListModel.hpp b/tests/src/components/contacts/ContactsListModel.hpp index d4d3decaa..450b55b4e 100644 --- a/tests/src/components/contacts/ContactsListModel.hpp +++ b/tests/src/components/contacts/ContactsListModel.hpp @@ -25,12 +25,10 @@ public: bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; public slots: - // See: http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#data-ownership - // The returned value must have a explicit parent or a QQmlEngine::CppOwnership. + ContactModel *createDetachedContact () const; ContactModel *mapSipAddressToContact (const QString &sipAddress) const; void removeContact (ContactModel *contact); - private: QList m_list; std::shared_ptr m_linphone_friends; diff --git a/tests/ui/modules/Common/Form/ListForm.qml b/tests/ui/modules/Common/Form/ListForm.qml index 211094810..b8bea4ea5 100644 --- a/tests/ui/modules/Common/Form/ListForm.qml +++ b/tests/ui/modules/Common/Form/ListForm.qml @@ -12,7 +12,9 @@ RowLayout { property alias placeholder: placeholder.text property alias title: text.text + property int inputMethodHints property var defaultData: [] + property var minValues signal changed (int index, string default_value, string new_value) signal removed (int index, string value) @@ -47,15 +49,31 @@ RowLayout { function _handleEditionFinished (index, text) { if (text.length === 0) { + // Remove. var default_value = values.model.get(index).$value + + if (minValues != null && minValues >= values.model.count) { + var model = values.model + + // Unable to set property directly. Qt uses a cache of the value. + model.remove(index) + model.insert(index, { + $isInvalid: false, + $value: default_value + }) + return + } + values.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) } @@ -145,6 +163,7 @@ RowLayout { TransparentTextInput { id: textInput + inputMethodHints: listForm.inputMethodHints isInvalid: $isInvalid text: $value diff --git a/tests/ui/modules/Common/Form/TransparentTextInput.qml b/tests/ui/modules/Common/Form/TransparentTextInput.qml index 77c793805..7921b7fbf 100644 --- a/tests/ui/modules/Common/Form/TransparentTextInput.qml +++ b/tests/ui/modules/Common/Form/TransparentTextInput.qml @@ -10,11 +10,11 @@ import Common.Styles 1.0 Item { property alias color: textInput.color property alias font: textInput.font + property alias inputMethodHints: textInput.inputMethodHints property alias readOnly: textInput.readOnly property alias text: textInput.text property bool isInvalid: false property int padding: TransparentTextInputStyle.padding - signal editingFinished // ----------------------------------------------------------------- diff --git a/tests/ui/views/App/MainWindow/ContactEdit.qml b/tests/ui/views/App/MainWindow/ContactEdit.qml index a2757794a..d7c71080e 100644 --- a/tests/ui/views/App/MainWindow/ContactEdit.qml +++ b/tests/ui/views/App/MainWindow/ContactEdit.qml @@ -62,9 +62,7 @@ ColumnLayout { ? _contact.addSipAddress(new_value) : _contact.updateSipAddress(default_value, new_value) - if (!so_far_so_good) { - addresses.setInvalid(index, true) - } + addresses.setInvalid(index, !so_far_so_good) } function _handleUrlChanged (index, default_value, new_value) { @@ -77,30 +75,16 @@ ColumnLayout { ? url && _contact.addUrl(new_value) : url && _contact.updateUrl(default_value, new_value) - if (!so_far_so_good) { - urls.setInvalid(index, true) - } + urls.setInvalid(index, !so_far_so_good) } // ----------------------------------------------------------------- spacing: 0 - Component.onCompleted: { - var contact = ContactsListModel.mapSipAddressToContact(sipAddress) - - if (contact) { - infoUpdater.connect(contact, 'onContactUpdated', function () { - addresses.setData(contact.sipAddresses) - companies.setData(contact.companies) - emails.setData(contact.emails) - urls.setData(contact.urls) - }) - - _contact = contact - } else { - _contact = sipAddress - } + Component.onCompleted: { + _contact = ContactsListModel.mapSipAddressToContact(sipAddress) + || ContactsListModel.createDetachedContact() } // ----------------------------------------------------------------- @@ -209,10 +193,6 @@ ColumnLayout { width: flick.contentWidth - SmartConnect { - id: infoUpdater - } - ListForm { id: addresses @@ -221,6 +201,7 @@ ColumnLayout { Layout.topMargin: ContactEditStyle.values.topMargin defaultData: _contact.sipAddresses + minValues: 1 placeholder: qsTr('sipAccountsInput') title: qsTr('sipAccounts') @@ -263,6 +244,7 @@ ColumnLayout { Layout.rightMargin: ContactEditStyle.values.rightMargin defaultData: _contact.emails + inputMethodHints: Qt.ImhEmailCharactersOnly placeholder: qsTr('emailsInput') title: qsTr('emails') @@ -285,6 +267,7 @@ ColumnLayout { Layout.rightMargin: ContactEditStyle.values.rightMargin defaultData: _contact.urls + inputMethodHints: Qt.ImhUrlCharactersOnly placeholder: qsTr('webSitesInput') title: qsTr('webSites')