From 2c100ab000670698dc87b2fdd7ca705722f58117 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 29 Dec 2016 15:52:16 +0100 Subject: [PATCH] feat(src/components/sip-addresses/SipAddressesModel): connect to contacts/chat changes --- tests/src/components/chat/ChatModel.cpp | 154 ++++++++++-------- tests/src/components/chat/ChatModel.hpp | 12 +- .../sip-addresses/SipAddressesModel.cpp | 75 ++++++++- .../sip-addresses/SipAddressesModel.hpp | 4 + 4 files changed, 161 insertions(+), 84 deletions(-) diff --git a/tests/src/components/chat/ChatModel.cpp b/tests/src/components/chat/ChatModel.cpp index 133cc45d2..9c85fb1ae 100644 --- a/tests/src/components/chat/ChatModel.cpp +++ b/tests/src/components/chat/ChatModel.cpp @@ -13,6 +13,13 @@ using namespace std; // ============================================================================= +ChatModel::ChatModel (QObject *parent) : QAbstractListModel(parent) { + QObject::connect( + this, &ChatModel::allEntriesRemoved, + CoreManager::getInstance()->getSipAddressesModel(), &SipAddressesModel::handleAllHistoryEntriesRemoved + ); +} + QHash ChatModel::roleNames () const { QHash roles; roles[Roles::ChatEntry] = "$chatEntry"; @@ -59,9 +66,83 @@ bool ChatModel::removeRows (int row, int count, const QModelIndex &parent) { endRemoveRows(); + if (m_entries.count() == 0) + emit allEntriesRemoved(); + return true; } +QString ChatModel::getSipAddress () const { + if (!m_chat_room) + return ""; + + return ::Utils::linphoneStringToQString( + m_chat_room->getPeerAddress()->asString() + ); +} + +void ChatModel::setSipAddress (const QString &sip_address) { + if (sip_address == getSipAddress()) + return; + + beginResetModel(); + + // Invalid old sip address entries. + m_entries.clear(); + + shared_ptr core = CoreManager::getInstance()->getCore(); + string std_sip_address = ::Utils::qStringToLinphoneString(sip_address); + + m_chat_room = core->getChatRoomFromUri(std_sip_address); + + // Get messages. + for (auto &message : m_chat_room->getHistory(0)) { + QVariantMap map; + + fillMessageEntry(map, message); + m_entries << qMakePair(map, static_pointer_cast(message)); + } + + // Get calls. + auto insert_entry = [this]( + const ChatEntryData &pair, + const QList::iterator *start = NULL + ) { + auto it = lower_bound( + start ? *start : m_entries.begin(), m_entries.end(), pair, + [](const ChatEntryData &a, const ChatEntryData &b) { + return a.first["timestamp"] < b.first["timestamp"]; + } + ); + + return m_entries.insert(it, pair); + }; + + for (auto &call_log : core->getCallHistoryForAddress(m_chat_room->getPeerAddress())) { + linphone::CallStatus status = call_log->getStatus(); + + // Ignore aborted calls. + if (status == linphone::CallStatusAborted) + continue; + + // Add start call. + QVariantMap start; + fillCallStartEntry(start, call_log); + auto it = insert_entry(qMakePair(start, static_pointer_cast(call_log))); + + // Add end call. (if necessary) + if (status == linphone::CallStatusSuccess) { + QVariantMap end; + fillCallEndEntry(end, call_log); + insert_entry(qMakePair(end, static_pointer_cast(call_log)), &it); + } + } + + endResetModel(); + + emit sipAddressChanged(sip_address); +} + // ----------------------------------------------------------------------------- void ChatModel::removeEntry (int id) { @@ -83,6 +164,8 @@ void ChatModel::removeAllEntries () { m_entries.clear(); endResetModel(); + + emit allEntriesRemoved(); } // ----------------------------------------------------------------------------- @@ -160,74 +243,3 @@ void ChatModel::removeEntry (ChatEntryData &pair) { qWarning() << QStringLiteral("Unknown chat entry type: %1.").arg(type); } } - -QString ChatModel::getSipAddress () const { - if (!m_chat_room) - return ""; - - return ::Utils::linphoneStringToQString( - m_chat_room->getPeerAddress()->asString() - ); -} - -void ChatModel::setSipAddress (const QString &sip_address) { - if (sip_address == getSipAddress()) - return; - - beginResetModel(); - - // Invalid old sip address entries. - m_entries.clear(); - - shared_ptr core = CoreManager::getInstance()->getCore(); - string std_sip_address = ::Utils::qStringToLinphoneString(sip_address); - - m_chat_room = core->getChatRoomFromUri(std_sip_address); - - // Get messages. - for (auto &message : m_chat_room->getHistory(0)) { - QVariantMap map; - - fillMessageEntry(map, message); - m_entries << qMakePair(map, static_pointer_cast(message)); - } - - // Get calls. - auto insert_entry = [this]( - const ChatEntryData &pair, - const QList::iterator *start = NULL - ) { - auto it = lower_bound( - start ? *start : m_entries.begin(), m_entries.end(), pair, - [](const ChatEntryData &a, const ChatEntryData &b) { - return a.first["timestamp"] < b.first["timestamp"]; - } - ); - - return m_entries.insert(it, pair); - }; - - for (auto &call_log : core->getCallHistoryForAddress(m_chat_room->getPeerAddress())) { - linphone::CallStatus status = call_log->getStatus(); - - // Ignore aborted calls. - if (status == linphone::CallStatusAborted) - continue; - - // Add start call. - QVariantMap start; - fillCallStartEntry(start, call_log); - auto it = insert_entry(qMakePair(start, static_pointer_cast(call_log))); - - // Add end call. (if necessary) - if (status == linphone::CallStatusSuccess) { - QVariantMap end; - fillCallEndEntry(end, call_log); - insert_entry(qMakePair(end, static_pointer_cast(call_log)), &it); - } - } - - endResetModel(); - - emit sipAddressChanged(sip_address); -} diff --git a/tests/src/components/chat/ChatModel.hpp b/tests/src/components/chat/ChatModel.hpp index 62b041fef..94a79f831 100644 --- a/tests/src/components/chat/ChatModel.hpp +++ b/tests/src/components/chat/ChatModel.hpp @@ -9,8 +9,6 @@ // ============================================================================= class ChatModel : public QAbstractListModel { - friend class ChatProxyModel; - Q_OBJECT; Q_PROPERTY( @@ -44,7 +42,8 @@ public: Q_ENUM(CallStatus); - ChatModel (QObject *parent = Q_NULLPTR) : QAbstractListModel(parent) {} + ChatModel (QObject *parent = Q_NULLPTR); + ~ChatModel () = default; int rowCount (const QModelIndex &index = QModelIndex()) const override; @@ -54,12 +53,16 @@ public: bool removeRow (int row, const QModelIndex &parent = QModelIndex()); bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; + QString getSipAddress () const; + void setSipAddress (const QString &sip_address); + public slots: void removeEntry (int id); void removeAllEntries (); signals: void sipAddressChanged (const QString &sipAddress); + void allEntriesRemoved (); private: void fillMessageEntry ( @@ -79,9 +82,6 @@ private: void removeEntry (ChatEntryData &pair); - QString getSipAddress () const; - void setSipAddress (const QString &sip_address); - QList m_entries; std::shared_ptr m_chat_room; }; diff --git a/tests/src/components/sip-addresses/SipAddressesModel.cpp b/tests/src/components/sip-addresses/SipAddressesModel.cpp index c9ad8552f..883657110 100644 --- a/tests/src/components/sip-addresses/SipAddressesModel.cpp +++ b/tests/src/components/sip-addresses/SipAddressesModel.cpp @@ -3,6 +3,7 @@ #include #include "../../utils.hpp" +#include "../chat/ChatModel.hpp" #include "../core/CoreManager.hpp" #include "SipAddressesModel.hpp" @@ -23,21 +24,27 @@ SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(pare for (const auto &sip_address : contact->getVcardModel()->getSipAddresses()) { auto it = m_sip_addresses.find(sip_address.toString()); if (it == m_sip_addresses.end()) { - qWarning() << QStringLiteral("Unable to remove contact from sip address: `%1`.").arg( - sip_address.toString() - ); + qWarning() << QStringLiteral("Unable to remove contact from sip address: `%1`.").arg(sip_address.toString()); continue; } - if (it->remove("contact") != 0) { - int row = static_cast(distance(m_sip_addresses.begin(), it)); + if (it->remove("contact") == 0) + 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. + removeRow(row); } } ); - - // TODO: handle data changed from contact } // ----------------------------------------------------------------------------- @@ -74,8 +81,62 @@ ContactModel *SipAddressesModel::mapSipAddressToContact (const QString &sip_addr return it->value("contact").value(); } +void SipAddressesModel::handleAllHistoryEntriesRemoved () { + QObject *sender = QObject::sender(); + if (!sender) + return; + + ChatModel *chat_model = qobject_cast(sender); + if (!chat_model) + return; + + const QString sip_address = chat_model->getSipAddress(); + auto it = m_sip_addresses.find(sip_address); + if (it == m_sip_addresses.end()) { + qWarning() << QStringLiteral("Unable to found sip address: `%1`.").arg(sip_address); + return; + } + + int row = m_refs.indexOf(&(*it)); + Q_ASSERT(row != -1); + + // No history, no contact => Remove sip address from list. + if (!it->contains("contact")) { + removeRow(row); + return; + } + + // Signal changes. + it->remove("timestamp"); + emit dataChanged(index(row, 0), index(row, 0)); +} + // ----------------------------------------------------------------------------- +bool SipAddressesModel::removeRow (int row, const QModelIndex &parent) { + return removeRows(row, 1, parent); +} + +bool SipAddressesModel::removeRows (int row, int count, const QModelIndex &parent) { + int limit = row + count - 1; + + if (row < 0 || count < 0 || limit >= m_sip_addresses.count()) + return false; + + beginRemoveRows(parent, row, limit); + + for (int i = 0; i < count; ++i) { + const QVariantMap *map = m_refs.takeAt(row); + QString sip_address = (*map)["sipAddress"].toString(); + qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address); + m_sip_addresses.remove(sip_address); + } + + endRemoveRows(); + + return true; +} + void SipAddressesModel::updateFromContact (ContactModel *contact) { for (const auto &sip_address : contact->getVcardModel()->getSipAddresses()) { const QString &sip_address_str = sip_address.toString(); diff --git a/tests/src/components/sip-addresses/SipAddressesModel.hpp b/tests/src/components/sip-addresses/SipAddressesModel.hpp index 3c8bc00f0..7d5a83f8d 100644 --- a/tests/src/components/sip-addresses/SipAddressesModel.hpp +++ b/tests/src/components/sip-addresses/SipAddressesModel.hpp @@ -21,8 +21,12 @@ public: public slots: ContactModel *mapSipAddressToContact (const QString &sip_address) const; + void handleAllHistoryEntriesRemoved (); private: + bool removeRow (int row, const QModelIndex &parent = QModelIndex()); + bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; + void updateFromContact (ContactModel *contact); void fetchSipAddresses ();