mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-27 16:59:21 +00:00
feat(src/components/sip-addresses/SipAddressesModel): connect to contacts/chat changes
This commit is contained in:
parent
5d5d4fa0e2
commit
2c100ab000
4 changed files with 161 additions and 84 deletions
|
|
@ -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 ();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue