Commit 2c100ab0 authored by Ronan's avatar Ronan

feat(src/components/sip-addresses/SipAddressesModel): connect to contacts/chat changes

parent 5d5d4fa0
......@@ -13,6 +13,13 @@ using namespace std;
// =============================================================================
ChatModel::ChatModel (QObject *parent) : QAbstractListModel(parent) {
QObject::connect(
this, &ChatModel::allEntriesRemoved,
CoreManager::getInstance()->getSipAddressesModel(), &SipAddressesModel::handleAllHistoryEntriesRemoved
);
}
QHash<int, QByteArray> ChatModel::roleNames () const {
QHash<int, QByteArray> 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<linphone::Core> 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<void>(message));
}
// Get calls.
auto insert_entry = [this](
const ChatEntryData &pair,
const QList<ChatEntryData>::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<void>(call_log)));
// Add end call. (if necessary)
if (status == linphone::CallStatusSuccess) {
QVariantMap end;
fillCallEndEntry(end, call_log);
insert_entry(qMakePair(end, static_pointer_cast<void>(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<linphone::Core> 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<void>(message));
}
// Get calls.
auto insert_entry = [this](
const ChatEntryData &pair,
const QList<ChatEntryData>::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<void>(call_log)));
// Add end call. (if necessary)
if (status == linphone::CallStatusSuccess) {
QVariantMap end;
fillCallEndEntry(end, call_log);
insert_entry(qMakePair(end, static_pointer_cast<void>(call_log)), &it);
}
}
endResetModel();
emit sipAddressChanged(sip_address);
}
......@@ -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<ChatEntryData> m_entries;
std::shared_ptr<linphone::ChatRoom> m_chat_room;
};
......
......@@ -3,6 +3,7 @@
#include <QtDebug>
#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<int>(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<ContactModel *>();
}
void SipAddressesModel::handleAllHistoryEntriesRemoved () {
QObject *sender = QObject::sender();
if (!sender)
return;
ChatModel *chat_model = qobject_cast<ChatModel *>(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();
......
......@@ -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 ();
......
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