Commit 4ce00a71 authored by Ronan Abhamon's avatar Ronan Abhamon

feat(app): handle correctly sip addresses changes (on contact, from history, ...)

parent 25b69259
#include <QSet>
#include "../../app/App.hpp" #include "../../app/App.hpp"
#include "ContactModel.hpp" #include "ContactModel.hpp"
...@@ -11,7 +13,6 @@ ContactModel::ContactModel (shared_ptr<linphone::Friend> linphone_friend) { ...@@ -11,7 +13,6 @@ ContactModel::ContactModel (shared_ptr<linphone::Friend> linphone_friend) {
m_vcard = make_shared<VcardModel>(linphone_friend->getVcard()); m_vcard = make_shared<VcardModel>(linphone_friend->getVcard());
App::getInstance()->getEngine()->setObjectOwnership(m_vcard.get(), QQmlEngine::CppOwnership); App::getInstance()->getEngine()->setObjectOwnership(m_vcard.get(), QQmlEngine::CppOwnership);
QObject::connect(m_vcard.get(), &VcardModel::vcardUpdated, this, &ContactModel::contactUpdated);
} }
ContactModel::ContactModel (VcardModel *vcard) { ContactModel::ContactModel (VcardModel *vcard) {
...@@ -23,7 +24,53 @@ ContactModel::ContactModel (VcardModel *vcard) { ...@@ -23,7 +24,53 @@ ContactModel::ContactModel (VcardModel *vcard) {
m_vcard.reset(vcard); m_vcard.reset(vcard);
engine->setObjectOwnership(vcard, QQmlEngine::CppOwnership); engine->setObjectOwnership(vcard, QQmlEngine::CppOwnership);
QObject::connect(vcard, &VcardModel::vcardUpdated, this, &ContactModel::contactUpdated); }
void ContactModel::startEdit () {
m_linphone_friend->edit();
m_old_sip_addresses = m_vcard->getSipAddresses();
}
void ContactModel::endEdit () {
m_linphone_friend->done();
QVariantList sip_addresses = m_vcard->getSipAddresses();
QSet<QString> done;
for (const auto &variant_a : m_old_sip_addresses) {
next:
const QString &sip_address = variant_a.toString();
if (done.contains(sip_address))
continue;
done.insert(sip_address);
// Check if old sip address exists in new set => No changes.
for (const auto &variant_b : sip_addresses) {
if (sip_address == variant_b.toString())
goto next;
}
emit sipAddressRemoved(sip_address);
}
m_old_sip_addresses.clear();
for (const auto &variant : sip_addresses) {
const QString &sip_address = variant.toString();
if (done.contains(sip_address))
continue;
done.insert(sip_address);
emit sipAddressAdded(sip_address);
}
emit contactUpdated();
}
void ContactModel::abortEdit () {
// TODO: call linphone friend abort function when available.
// m_linphone_friend->abort();
m_old_sip_addresses.clear();
} }
Presence::PresenceStatus ContactModel::getPresenceStatus () const { Presence::PresenceStatus ContactModel::getPresenceStatus () const {
......
...@@ -27,21 +27,14 @@ public: ...@@ -27,21 +27,14 @@ public:
} }
public slots: public slots:
void startEdit () { void startEdit ();
m_linphone_friend->edit(); void endEdit ();
} void abortEdit ();
void endEdit () {
m_linphone_friend->done();
}
void abortEdit () {
// TODO: call linphone friend abort function.
// m_linphone_friend->abort();
}
signals: signals:
void contactUpdated (); void contactUpdated ();
void sipAddressAdded (const QString &sip_address);
void sipAddressRemoved (const QString &sip_address);
private: private:
Presence::PresenceStatus getPresenceStatus () const; Presence::PresenceStatus getPresenceStatus () const;
...@@ -51,6 +44,8 @@ private: ...@@ -51,6 +44,8 @@ private:
return m_vcard.get(); return m_vcard.get();
} }
QVariantList m_old_sip_addresses;
std::shared_ptr<VcardModel> m_vcard; std::shared_ptr<VcardModel> m_vcard;
std::shared_ptr<linphone::Friend> m_linphone_friend; std::shared_ptr<linphone::Friend> m_linphone_friend;
}; };
......
...@@ -156,7 +156,7 @@ inline shared_ptr<belcard::BelCardAddress> getOrCreateBelCardAddress (shared_ptr ...@@ -156,7 +156,7 @@ inline shared_ptr<belcard::BelCardAddress> getOrCreateBelCardAddress (shared_ptr
if (addresses.empty()) { if (addresses.empty()) {
address = belcard::BelCardGeneric::create<belcard::BelCardAddress>(); address = belcard::BelCardGeneric::create<belcard::BelCardAddress>();
if (!belcard->addAddress(address)) if (!belcard->addAddress(address))
qWarning() << "Unable to create a new address."; qWarning() << "Unable to create a new address on vcard.";
} else } else
address = addresses.front(); address = addresses.front();
...@@ -227,7 +227,7 @@ bool VcardModel::addSipAddress (const QString &sip_address) { ...@@ -227,7 +227,7 @@ bool VcardModel::addSipAddress (const QString &sip_address) {
); );
if (!l_address) { if (!l_address) {
qWarning() << QStringLiteral("Unable to add invalid sip address: `%1`.").arg(sip_address); qWarning() << QStringLiteral("Unable to add invalid sip address on vcard: `%1`.").arg(sip_address);
return false; return false;
} }
...@@ -236,10 +236,10 @@ bool VcardModel::addSipAddress (const QString &sip_address) { ...@@ -236,10 +236,10 @@ bool VcardModel::addSipAddress (const QString &sip_address) {
shared_ptr<belcard::BelCardImpp> value = belcard::BelCardGeneric::create<belcard::BelCardImpp>(); shared_ptr<belcard::BelCardImpp> value = belcard::BelCardGeneric::create<belcard::BelCardImpp>();
value->setValue(l_address->asStringUriOnly()); value->setValue(l_address->asStringUriOnly());
qInfo() << QStringLiteral("Add new sip address: `%1`.").arg(sip_address); qInfo() << QStringLiteral("Add new sip address on vcard: `%1`.").arg(sip_address);
if (!belcard->addImpp(value)) { if (!belcard->addImpp(value)) {
qWarning() << QStringLiteral("Unable to add sip address: `%1`.").arg(sip_address); qWarning() << QStringLiteral("Unable to add sip address on vcard: `%1`.").arg(sip_address);
return false; return false;
} }
...@@ -253,17 +253,17 @@ void VcardModel::removeSipAddress (const QString &sip_address) { ...@@ -253,17 +253,17 @@ void VcardModel::removeSipAddress (const QString &sip_address) {
shared_ptr<belcard::BelCardImpp> value = findBelCardValue(addresses, sip_address); shared_ptr<belcard::BelCardImpp> value = findBelCardValue(addresses, sip_address);
if (!value) { if (!value) {
qWarning() << QStringLiteral("Unable to remove sip address: `%1`.").arg(sip_address); qWarning() << QStringLiteral("Unable to remove sip address on vcard: `%1`.").arg(sip_address);
return; return;
} }
if (addresses.size() == 1) { if (addresses.size() == 1) {
qWarning() << QStringLiteral("Unable to remove the only existing sip address: `%1`.") qWarning() << QStringLiteral("Unable to remove the only existing sip address on vcard: `%1`.")
.arg(sip_address); .arg(sip_address);
return; return;
} }
qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address); qInfo() << QStringLiteral("Remove sip address on vcard: `%1`.").arg(sip_address);
belcard->removeImpp(value); belcard->removeImpp(value);
emit vcardUpdated(); emit vcardUpdated();
...@@ -294,10 +294,10 @@ bool VcardModel::addCompany (const QString &company) { ...@@ -294,10 +294,10 @@ bool VcardModel::addCompany (const QString &company) {
shared_ptr<belcard::BelCardRole> value = belcard::BelCardGeneric::create<belcard::BelCardRole>(); shared_ptr<belcard::BelCardRole> value = belcard::BelCardGeneric::create<belcard::BelCardRole>();
value->setValue(::Utils::qStringToLinphoneString(company)); value->setValue(::Utils::qStringToLinphoneString(company));
qInfo() << QStringLiteral("Add new company: `%1`.").arg(company); qInfo() << QStringLiteral("Add new company on vcard: `%1`.").arg(company);
if (!belcard->addRole(value)) { if (!belcard->addRole(value)) {
qWarning() << QStringLiteral("Unable to add company: `%1`.").arg(company); qWarning() << QStringLiteral("Unable to add company on vcard: `%1`.").arg(company);
return false; return false;
} }
...@@ -310,11 +310,11 @@ void VcardModel::removeCompany (const QString &company) { ...@@ -310,11 +310,11 @@ void VcardModel::removeCompany (const QString &company) {
shared_ptr<belcard::BelCardRole> value = findBelCardValue(belcard->getRoles(), company); shared_ptr<belcard::BelCardRole> value = findBelCardValue(belcard->getRoles(), company);
if (!value) { if (!value) {
qWarning() << QStringLiteral("Unable to remove company: `%1`.").arg(company); qWarning() << QStringLiteral("Unable to remove company on vcard: `%1`.").arg(company);
return; return;
} }
qInfo() << QStringLiteral("Remove company: `%1`.").arg(company); qInfo() << QStringLiteral("Remove company on vcard: `%1`.").arg(company);
belcard->removeRole(value); belcard->removeRole(value);
emit vcardUpdated(); emit vcardUpdated();
...@@ -345,10 +345,10 @@ bool VcardModel::addEmail (const QString &email) { ...@@ -345,10 +345,10 @@ bool VcardModel::addEmail (const QString &email) {
shared_ptr<belcard::BelCardEmail> value = belcard::BelCardGeneric::create<belcard::BelCardEmail>(); shared_ptr<belcard::BelCardEmail> value = belcard::BelCardGeneric::create<belcard::BelCardEmail>();
value->setValue(::Utils::qStringToLinphoneString(email)); value->setValue(::Utils::qStringToLinphoneString(email));
qInfo() << QStringLiteral("Add new email: `%1`.").arg(email); qInfo() << QStringLiteral("Add new email on vcard: `%1`.").arg(email);
if (!belcard->addEmail(value)) { if (!belcard->addEmail(value)) {
qWarning() << QStringLiteral("Unable to add email: `%1`.").arg(email); qWarning() << QStringLiteral("Unable to add email on vcard: `%1`.").arg(email);
return false; return false;
} }
...@@ -361,11 +361,11 @@ void VcardModel::removeEmail (const QString &email) { ...@@ -361,11 +361,11 @@ void VcardModel::removeEmail (const QString &email) {
shared_ptr<belcard::BelCardEmail> value = findBelCardValue(belcard->getEmails(), email); shared_ptr<belcard::BelCardEmail> value = findBelCardValue(belcard->getEmails(), email);
if (!value) { if (!value) {
qWarning() << QStringLiteral("Unable to remove email: `%1`.").arg(email); qWarning() << QStringLiteral("Unable to remove email on vcard: `%1`.").arg(email);
return; return;
} }
qInfo() << QStringLiteral("Remove email: `%1`.").arg(email); qInfo() << QStringLiteral("Remove email on vcard: `%1`.").arg(email);
belcard->removeEmail(value); belcard->removeEmail(value);
emit vcardUpdated(); emit vcardUpdated();
...@@ -396,10 +396,10 @@ bool VcardModel::addUrl (const QString &url) { ...@@ -396,10 +396,10 @@ bool VcardModel::addUrl (const QString &url) {
shared_ptr<belcard::BelCardURL> value = belcard::BelCardGeneric::create<belcard::BelCardURL>(); shared_ptr<belcard::BelCardURL> value = belcard::BelCardGeneric::create<belcard::BelCardURL>();
value->setValue(::Utils::qStringToLinphoneString(url)); value->setValue(::Utils::qStringToLinphoneString(url));
qInfo() << QStringLiteral("Add new url: `%1`.").arg(url); qInfo() << QStringLiteral("Add new url on vcard: `%1`.").arg(url);
if (!belcard->addURL(value)) { if (!belcard->addURL(value)) {
qWarning() << QStringLiteral("Unable to add url: `%1`.").arg(url); qWarning() << QStringLiteral("Unable to add url on vcard: `%1`.").arg(url);
return false; return false;
} }
...@@ -412,11 +412,11 @@ void VcardModel::removeUrl (const QString &url) { ...@@ -412,11 +412,11 @@ void VcardModel::removeUrl (const QString &url) {
shared_ptr<belcard::BelCardURL> value = findBelCardValue(belcard->getURLs(), url); shared_ptr<belcard::BelCardURL> value = findBelCardValue(belcard->getURLs(), url);
if (!value) { if (!value) {
qWarning() << QStringLiteral("Unable to remove url: `%1`.").arg(url); qWarning() << QStringLiteral("Unable to remove url on vcard: `%1`.").arg(url);
return; return;
} }
qInfo() << QStringLiteral("Remove url: `%1`.").arg(url); qInfo() << QStringLiteral("Remove url on vcard: `%1`.").arg(url);
belcard->removeURL(value); belcard->removeURL(value);
emit vcardUpdated(); emit vcardUpdated();
......
...@@ -23,7 +23,7 @@ ContactsListModel::ContactsListModel (QObject *parent) : QAbstractListModel(pare ...@@ -23,7 +23,7 @@ ContactsListModel::ContactsListModel (QObject *parent) : QAbstractListModel(pare
contact, QQmlEngine::CppOwnership contact, QQmlEngine::CppOwnership
); );
m_list << contact; addContact(contact);
} }
} }
...@@ -95,7 +95,7 @@ ContactModel *ContactsListModel::addContact (VcardModel *vcard) { ...@@ -95,7 +95,7 @@ ContactModel *ContactsListModel::addContact (VcardModel *vcard) {
int row = rowCount(); int row = rowCount();
beginInsertRows(QModelIndex(), row, row); beginInsertRows(QModelIndex(), row, row);
m_list << contact; addContact(contact);
endInsertRows(); endInsertRows();
emit contactAdded(contact); emit contactAdded(contact);
...@@ -110,3 +110,24 @@ void ContactsListModel::removeContact (ContactModel *contact) { ...@@ -110,3 +110,24 @@ void ContactsListModel::removeContact (ContactModel *contact) {
if (index == -1 || !removeRow(index)) if (index == -1 || !removeRow(index))
qWarning() << "Unable to remove contact:" << contact; qWarning() << "Unable to remove contact:" << contact;
} }
void ContactsListModel::addContact (ContactModel *contact) {
QObject::connect(
contact, &ContactModel::contactUpdated,
this, [this, contact]() {
emit contactUpdated(contact);
}
);
QObject::connect(
contact, &ContactModel::sipAddressAdded, this, [this, contact](const QString &sip_address) {
emit sipAddressAdded(contact, sip_address);
}
);
QObject::connect(
contact, &ContactModel::sipAddressRemoved, this, [this, contact](const QString &sip_address) {
emit sipAddressRemoved(contact, sip_address);
}
);
m_list << contact;
}
...@@ -32,8 +32,14 @@ public slots: ...@@ -32,8 +32,14 @@ public slots:
signals: signals:
void contactAdded (ContactModel *contact); void contactAdded (ContactModel *contact);
void contactRemoved (const ContactModel *contact); void contactRemoved (const ContactModel *contact);
void contactUpdated (ContactModel *contact);
void sipAddressAdded (ContactModel *contact, const QString &sip_address);
void sipAddressRemoved (ContactModel *contact, const QString &sip_address);
private: private:
void addContact (ContactModel *contact);
QList<ContactModel *> m_list; QList<ContactModel *> m_list;
std::shared_ptr<linphone::FriendList> m_linphone_friends; std::shared_ptr<linphone::FriendList> m_linphone_friends;
}; };
......
...@@ -12,37 +12,39 @@ ...@@ -12,37 +12,39 @@
SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(parent) { SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(parent) {
fetchSipAddresses(); fetchSipAddresses();
ContactsListModel *contacts = CoreManager::getInstance()->getContactsListModel();
QObject::connect(contacts, &ContactsListModel::contactAdded, this, &SipAddressesModel::updateFromNewContact);
QObject::connect( QObject::connect(
CoreManager::getInstance()->getContactsListModel(), &ContactsListModel::contactAdded, contacts, &ContactsListModel::contactRemoved, this, [this](const ContactModel *contact) {
this, &SipAddressesModel::updateFromContact for (const auto &sip_address : contact->getVcardModel()->getSipAddresses())
tryToRemoveSipAddress(sip_address.toString());
}
); );
QObject::connect( QObject::connect(
CoreManager::getInstance()->getContactsListModel(), &ContactsListModel::contactRemoved, contacts, &ContactsListModel::sipAddressAdded, this, [this](ContactModel *contact, const QString &sip_address) {
this, [this](const ContactModel *contact) { // TODO: Avoid the limitation of one contact by sip address.
for (const auto &sip_address : contact->getVcardModel()->getSipAddresses()) { ContactModel *mapped_contact = mapSipAddressToContact(sip_address);
auto it = m_sip_addresses.find(sip_address.toString()); if (mapped_contact) {
if (it == m_sip_addresses.end()) { qWarning() << "Unable to map sip address" << sip_address << "to" << contact << "- already used by" << mapped_contact;
qWarning() << QStringLiteral("Unable to remove contact from sip address: `%1`.").arg(sip_address.toString()); return;
continue;
} }
if (it->remove("contact") == 0) updateFromNewContactSipAddress(contact, sip_address);
qWarning() << QStringLiteral("`contact` field is empty on sip address: `%1`.").arg(sip_address.toString());
int row = m_refs.indexOf(&(*it));
Q_ASSERT(row != -1);
// History exists, signal changes.
if (it->contains("timestamp")) {
emit dataChanged(index(row, 0), index(row, 0));
continue;
} }
);
// Remove sip address if no history. QObject::connect(
removeRow(row); contacts, &ContactsListModel::sipAddressRemoved, this, [this](ContactModel *contact, const QString &sip_address) {
ContactModel *mapped_contact = mapSipAddressToContact(sip_address);
if (contact != mapped_contact) {
qWarning() << "Unable to remove sip address" << sip_address << "of" << contact << "- already used by" << mapped_contact;
return;
} }
tryToRemoveSipAddress(sip_address);
} }
); );
} }
...@@ -137,23 +139,34 @@ bool SipAddressesModel::removeRows (int row, int count, const QModelIndex &paren ...@@ -137,23 +139,34 @@ bool SipAddressesModel::removeRows (int row, int count, const QModelIndex &paren
return true; return true;
} }
void SipAddressesModel::updateFromContact (ContactModel *contact) { void SipAddressesModel::updateFromNewContact (ContactModel *contact) {
for (const auto &sip_address : contact->getVcardModel()->getSipAddresses()) { for (const auto &sip_address : contact->getVcardModel()->getSipAddresses())
const QString &sip_address_str = sip_address.toString(); updateFromNewContactSipAddress(contact, sip_address.toString());
auto it = m_sip_addresses.find(sip_address_str); }
void SipAddressesModel::updateFromNewContactSipAddress (ContactModel *contact, const QString &sip_address) {
auto it = m_sip_addresses.find(sip_address);
// New sip address from contact = new entry. // New sip address.
if (it == m_sip_addresses.end()) { if (it == m_sip_addresses.end()) {
QVariantMap map; QVariantMap map;
map["sipAddress"] = sip_address; map["sipAddress"] = sip_address;
map["contact"] = QVariant::fromValue(contact); map["contact"] = QVariant::fromValue(contact);
m_sip_addresses[sip_address_str] = map; int row = m_refs.count();
m_refs << &m_sip_addresses[sip_address_str];
beginInsertRows(QModelIndex(), row, row);
qInfo() << QStringLiteral("Add sip address: `%1`.").arg(sip_address);
m_sip_addresses[sip_address] = map;
m_refs << &m_sip_addresses[sip_address];
endInsertRows();
int row = m_refs.count() - 1;
emit dataChanged(index(row, 0), index(row, 0)); emit dataChanged(index(row, 0), index(row, 0));
continue;
return;
} }
// Sip address exists, update contact. // Sip address exists, update contact.
...@@ -162,7 +175,29 @@ void SipAddressesModel::updateFromContact (ContactModel *contact) { ...@@ -162,7 +175,29 @@ void SipAddressesModel::updateFromContact (ContactModel *contact) {
int row = m_refs.indexOf(&(*it)); int row = m_refs.indexOf(&(*it));
Q_ASSERT(row != -1); Q_ASSERT(row != -1);
emit dataChanged(index(row, 0), index(row, 0)); emit dataChanged(index(row, 0), index(row, 0));
}
void SipAddressesModel::tryToRemoveSipAddress (const QString &sip_address) {
auto it = m_sip_addresses.find(sip_address);
if (it == m_sip_addresses.end()) {
qWarning() << QStringLiteral("Unable to remove unavailable sip address: `%1`.").arg(sip_address);
return;
} }
if (it->remove("contact") == 0)
qWarning() << QStringLiteral("`contact` field is empty on sip address: `%1`.").arg(sip_address);
int row = m_refs.indexOf(&(*it));
Q_ASSERT(row != -1);
// History exists, signal changes.
if (it->contains("timestamp")) {
emit dataChanged(index(row, 0), index(row, 0));
return;
}
// Remove sip address if no history.
removeRow(row);
} }
void SipAddressesModel::fetchSipAddresses () { void SipAddressesModel::fetchSipAddresses () {
...@@ -213,5 +248,5 @@ void SipAddressesModel::fetchSipAddresses () { ...@@ -213,5 +248,5 @@ void SipAddressesModel::fetchSipAddresses () {
// Get sip addresses from contacts. // Get sip addresses from contacts.
for (auto &contact : CoreManager::getInstance()->getContactsListModel()->m_list) for (auto &contact : CoreManager::getInstance()->getContactsListModel()->m_list)
updateFromContact(contact); updateFromNewContact(contact);
} }
...@@ -27,7 +27,10 @@ private: ...@@ -27,7 +27,10 @@ private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex()); bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
void updateFromContact (ContactModel *contact); void updateFromNewContact (ContactModel *contact);
void updateFromNewContactSipAddress (ContactModel *contact, const QString &sip_address);
void tryToRemoveSipAddress (const QString &sip_address);
void fetchSipAddresses (); void fetchSipAddresses ();
QHash<QString, QVariantMap> m_sip_addresses; QHash<QString, QVariantMap> m_sip_addresses;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment